Index: /sandbox/workflow/branches/993/setup/phpgw_en.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_en.lang	(revision 1710)
+++ /sandbox/workflow/branches/993/setup/phpgw_en.lang	(revision 1710)
@@ -0,0 +1,709 @@
+#	workflow	en	#
+%1 aborted	workflow	en	%1 aborted
+%1 active	workflow	en	%1 active
+%1 completed	workflow	en	%1 completed
+%1 configuration	workflow	en	%1 Configuration
+%1 days, %2:%3:%4	workflow	en	%1 days, %2:%3:%4
+%1 exception	workflow	en	%1 exception
+%1 menu	workflow	en	%1 Menu
+%1 monitoring	workflow	en	%1 Monitoring
+%1 processes (%2 active) (%3 being_run)	workflow	en	%1 processes (%2 active) (%3 being_run)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	en	/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration
+<strong>%owner%</strong> is the instance owner email	workflow	en	<strong>%owner%</strong> is the instance owner email
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	en	<strong>%property_XX%</strong> is the content of the instance's property XX
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	en	<strong>%role_XX%</strong> are all the emails of all users mapped to the role XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	en	<strong>%roles%</strong> are the emails of all users mapped to any role on this activity
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	en	<strong>%signature%</strong> is the agent signature defined in the process configuration
+<strong>%user%</strong> is the instance user email	workflow	en	<strong>%user%</strong> is the instance user email
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	en	<strong>%user_XX%</strong> is the email of the acount XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	en	a please wait message is shown when loading the activity form usefull for long tasks
+abort instance	workflow	en	abort instance
+abort this instance	workflow	en	Abort this instance
+aborted	workflow	en	aborted
+access denied for user %1 on activity %2, no role	workflow	en	Access denied for user %1 on activity %2, no role
+act	workflow	en	act
+act. status	workflow	en	Act. Status
+act. status:	workflow	en	Act. status:
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	en	Action %1 is impossible if we have no activity and no instance designated for it!
+action %1 is impossible, another user is already in place	workflow	en	Action %1 is impossible, another user is already in place
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	en	Action %1 is impossible, there are no user assigned to this activity for this instance
+action %1 needs an activity and activity %2 does not exists	workflow	en	Action %1 needs an activity and activity %2 does not exists
+action %1 needs an instance and instance %2 does not exists	workflow	en	Action %1 needs an instance and instance %2 does not exists
+actions	workflow	en	Actions
+actions right options	common	en	Actions Right Options
+activate	workflow	en	activate
+active	workflow	en	Active
+active:	workflow	en	active:
+activities	workflow	en	Activities
+activities selection	workflow	en	Activities selection
+activities updated	workflow	en	Activities updated
+activity	workflow	en	activity
+activity  status	workflow	en	Activity Status
+activity %1	workflow	en	activity %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	en	Activity %1 (#%2) is associated with a non-existent process (#%3)
+activity %1 code is not avaible	workflow	en	activity %1 code is not avaible
+activity %1 is interactive but has no role assigned	workflow	en	Activity %1 is interactive but has no role assigned
+activity %1 is interactive so it must use the $instance->complete() method	workflow	en	Activity %1 is interactive so it must use the $instance->complete() method
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	en	Activity %1 is non-interactive and non-autorouted but has no role assigned
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	en	Activity %1 is non-interactive so it must not use the $instance->complete() method
+activity %1 is standalone and is using the $instance object	workflow	en	Activity %1 is standalone and is using the $instance object
+activity %1 is standalone but has transitions	workflow	en	Activity %1 is standalone but has transitions
+activity %1 is standalone or view but has transitions	workflow	en	Activity %1 is standalone or view but has transitions
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	en	Activity %1 is switch so it must use $instance->setNextActivity($actname) method
+activity %1 is view and is using the $instance object in write mode	workflow	en	Activity %1 is view and is using the $instance object in write mode
+activity agent removed	workflow	en	Activity agent removed
+activity completed	workflow	en	Activity completed
+activity failure	workflow	en	activity failure
+activity in inexistent process	workflow	en	Activity in inexistent process
+activity is waiting for pending transitions	workflow	en	activity is waiting for pending transitions
+activity name already exists	workflow	en	Activity name already exists
+activity role #%1 removed	workflow	en	Activity role #%1 removed
+activity role removed	workflow	en	Activity role removed
+activity saved	workflow	en	Activity saved
+activity start not avaible, no corresponding activity was found.	workflow	en	activity start not avaible, no corresponding activity was found.
+activity start not set, no corresponding activity was found.	workflow	en	activity start not set, no corresponding activity was found.
+activity status not avaible, no corresponding activity was found.	workflow	en	activity status not avaible, no corresponding activity was found.
+activity:	workflow	en	activity:
+add a transition	workflow	en	Add a transition
+add aborted instances	workflow	en	Add aborted instances
+add advanced actions	workflow	en	Add advanced actions
+add agent	workflow	en	Add agent
+add completed instances	workflow	en	Add completed instances
+add instances in exception	workflow	en	Add instances in exception
+add new	workflow	en	add new
+add new role	workflow	en	Add new role
+add or edit a process	workflow	en	Add or edit a process
+add or edit a role	workflow	en	Add or edit a rol
+add or edit an activity	workflow	en	Add or edit an activity
+add property	workflow	en	Add property
+add role	workflow	en	Add role
+add role to process	workflow	en	Add role to process
+add transition	workflow	en	add transition
+add transitions	workflow	en	Add transitions
+add transitions from	workflow	en	Add transitions from
+add transitions to	workflow	en	Add transitions to
+admin instance	workflow	en	Admin Instance
+admin process activities	workflow	en	Admin Process Activities
+admin process roles	workflow	en	Admin Process Roles
+admin processes	common	en	Admin Processes
+admin processes sources	workflow	en	Admin Processes Sources
+administer instances	admin	en	Administer instances
+administer processes	admin	en	Administer processes
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	en	Agent #%1 of type %2 is associated to an inexistent activity #%3
+agent #%1 of type %2 is not linked with an activity	workflow	en	Agent #%1 of type %2 is not linked with an activity
+agent associated with inexistent activity	workflow	en	Agent associated with inexistent activity
+agent without activity	workflow	en	Agent without activity
+agents assigned to this activity	workflow	en	Agents assigned to this activity
+all	workflow	en	All
+always show advanced actions	workflow	en	Always show advanced actions
+always show advanced mode	workflow	en	Always show advanced mode
+assign me this activity	workflow	en	Assign me this activity
+at least one email address cannot be validated.	workflow	en	at least one email address cannot be validated.
+auto routed	workflow	en	Auto routed
+auto-release on leaving activity	common	en	Auto-release on leaving activity
+automatic	workflow	en	Automatic
+autorouted activities does not need to be sent by any user after their execution	workflow	en	Autorouted activities do not need to be sent by any user after their execution
+bad parameter for setagents, the parameter should be an array	workflow	en	bad parameter for setAgents, the parameter should be an array
+bad role type	workflow	en	Bad role type
+bad user	workflow	en	Bad user
+base directory does not exist, please ask adminstrator to check the global configuration	common	en	Base directory does not exist, please ask adminstrator to check the global configuration
+bcc:	workflow	en	Bcc:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	en	Be carefull with interactive activity, end and start of theses activities are multiple.
+being run	workflow	en	being run
+by running theses links you will create new instances of the related process.	workflow	en	by running theses links you will create new instances of the related process.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	en	Cannot add transition only split or switch activities can have more than one outbound transition
+cannot add transition. only split activities can have more than one outbound transition	workflow	en	Cannot add transition. Only split activities can have more than one outbound transition
+cannot create compiled file %1	workflow	en	cannot create compiled file %1
+cannot retrieve the user running the security check	workflow	en	Cannot retrieve the user running the security check
+cannot run the activity	workflow	en	Cannot run the activity
+cannot run the activity without her process	workflow	en	Cannot run the activity without her process
+cannot run the activity without instance	workflow	en	Cannot run the activity without instance
+cannot run unknown activity	workflow	en	Cannot run unknown activity
+cc:	workflow	en	Cc:
+circular reference found some activity has a transition leading to itself	workflow	en	Circular reference found some activity has a transition leading to itself
+circular reference found. some activity has a transition leading to itself	workflow	en	Circular reference found. Some activity has a transition leading to itself
+cleanup aborted instances	admin	en	Cleanup aborted instances
+cleanup actions	workflow	en	cleanup actions
+close and get back later	workflow	en	Close and get back later
+close printer friendly mode	workflow	en	Close Printer friendly mode
+code	workflow	en	code
+column activity status in instance lists	workflow	en	Column activity status in instance lists
+column category in instance lists	workflow	en	Column category in instance lists
+column instance id in instance lists	workflow	en	Column instance id in instance lists
+column instance name in instance lists	workflow	en	Column instance name in instance lists
+column instance status in instance lists	workflow	en	Column instance status in instance lists
+column owner in instance lists	workflow	en	Column owner in instance lists
+column priority in instance lists	workflow	en	Column priority in instance lists
+column process name in instance lists	workflow	en	Column process name in instance lists
+column start date in instance lists	workflow	en	Column start date in instance lists
+compilation	workflow	en	Compilation
+compiling activity %1 : %2	workflow	en	compiling activity %1 : %2
+complete	workflow	en	Complete
+complete cleanup of aborted instances done	workflow	en	complete cleanup of aborted instances done
+complete cleanup of all instances done	workflow	en	complete cleanup of all instances done
+completed	workflow	en	completed
+config values	common	en	Config values
+confirm delete	workflow	en	Confirm Delete
+consult %1 to get the default values:	workflow	en	Consult %1 to get the default values:
+couldn't add transition	workflow	en	Couldn't add transition
+create	workflow	en	create
+created	workflow	en	Created
+date:	workflow	en	date:
+default config values	common	en	Default config values
+default next user	workflow	en	Default next user
+default owner	workflow	en	Default owner
+default settings for processes	admin	en	Default settings for processes
+default user	workflow	en	Default User
+delete selected	workflow	en	Delete selected
+delete transition	workflow	en	delete transition
+deletion successful	workflow	en	Deletion successful
+delition successful	workflow	en	Delition successful
+description	workflow	en	Description
+display please wait message	common	en	display please wait message
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	en	Do you want the activity status on instances lists. Most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.
+do you want the category column on instances lists, if yout instances use categories you should use it	workflow	en	Do you want the category column on instances lists, if yout instances use categories you should use it
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	en	Do you want the category name column on instances lists, if your instances use categories you should use it
+do you want the category name column on instances lists. if your instances use categories you should use this	workflow	en	Do you want the category name column on instances lists. If your instances use categories you should use this
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	en	Do you want the instance id column on instances lists. This is the unique identifier of an instance
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	en	Do you want the instance name column on instances lists. If your instances have name you should really use this
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	en	Do you want the instance status on instances lists. The instance status is usefull to disting beteween aborted, completed, exception or active instances
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	en	Do you want the owner column on instances lists. This will show you the actual owner, especially usefull if ownership is defined with special rights
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	en	Do you want the priority column on instances lists. Priority can be set with activities forms
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	en	Do you want the process column on instances lists. Usefull if you have different processes and/or versions of theses processes
+do you want the search instance button in the last row of instances list.	workflow	en	Do you want the search instance button in the last row of instances list.
+do you want the started date column on instances lists.	workflow	en	Do you want the started date column on instances lists.
+don't move	workflow	en	Don't move
+draw roles	common	en	Draw roles
+draw roles on the graph beside activity name like [that]	admin	en	Draw roles on the graph beside activity name like [that]
+duration	workflow	en	Duration
+empty agent type	workflow	en	empty agent type
+end	workflow	en	end
+end activity is not reachable from start activity	workflow	en	End activity is not reachable from start activity
+ended	workflow	en	ended
+enter an activity name	workflow	en	Enter an activity name
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	en	Error: nextActivity does not match any candidate in autorouting switch activity
+error: non-deterministic decision for autorouting activity	workflow	en	Error: non-deterministic decision for autorouting activity
+error: removing was not done	workflow	en	error: removing was not done
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	en	Error: trying to send an instance to an activity but it was impossible to get this activity
+error: trying to send an instance to an activity but no transition found	workflow	en	Error: trying to send an instance to an activity but no transition found
+exception	workflow	en	exception
+exception instance	workflow	en	exception instance
+exception raised by %1 %2: %3	workflow	en	exception raised by %1 %2: %3
+exception resumed by %1 %2: %3	workflow	en	exception resumed by %1 %2: %3
+exception this instance	workflow	en	Exception this instance
+exceptions	workflow	en	exceptions
+execute this activity	workflow	en	Execute this activity
+export	workflow	en	Export
+failed to create workitem	workflow	en	failed to create workitem
+failed to execute automatic activity	workflow	en	failed to execute automatic activity
+failed to obtain lock on %1 table	workflow	en	failed to obtain lock on %1 table
+failed to obtain lock on instances table	workflow	en	failed to obtain lock on instances table
+failed to obtain lock on instances_activities table	workflow	en	failed to obtain lock on instances_activities table
+failed to record instance properties	workflow	en	failed to record instance properties
+failed to synchronize instance data with the database	workflow	en	failed to synchronize instance data with the database
+failure	workflow	en	failure
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	en	Fatal error: nextActivity does not match any candidate in autorouting switch activity
+fatal error: non-deterministic decision for autorouting activity	workflow	en	Fatal error: non-deterministic decision for autorouting activity
+fatal error: setting next activity to an unexisting activity	workflow	en	Fatal error: setting next activity to an unexisting activity
+fatal error: trying to send an instance to an activity but no transition found	workflow	en	Fatal error: trying to send an instance to an activity but no transition found
+filter	workflow	en	Filter
+filter instance by id	workflow	en	filter instance by id
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	en	finally you have links with <strong>%link_XX|YY%</strong> syntax, XX is the address part, YY the text part.
+fix	workflow	en	Fix
+fix concistency for selected rows	workflow	en	Fix Concistency for selected rows
+font size	common	en	Font size
+from	workflow	en	From
+from:	workflow	en	From:
+get back to global activities	workflow	en	get back to global activities
+get back to instance creation	workflow	en	get back to instance creation
+get property	workflow	en	Get property
+global activities	workflow	en	Global activities
+global workflow preferences	workflow	en	Global Workflow Preferences
+go	workflow	en	go
+go to same activities for other instances of this process	workflow	en	go to same activities for other instances of this process
+go to same process activities	workflow	en	go to same process activities
+go to the actual state of this instance	workflow	en	go to the actual state of this instance
+grab instance	workflow	en	grab instance
+grant access to the administration and development of workflow processes and activities.	admin	en	Grant access to the administration and development of workflow processes and activities.
+grant access to the administration of workflow elements	admin	en	Grant access to the administration of workflow elements
+grant access to the administration of workflow instances in monitor screens	admin	en	Grant access to the administration of workflow instances in monitor screens
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	admin	en	Grant access to the cleanup/deletion of workflow aborted instances in monitor screens
+grant access to the monitoring of workflow elements	admin	en	Grant access to the monitoring of workflow elements
+graph	workflow	en	Graph
+graphic options	common	en	Graphic options
+group	workflow	en	Group
+id	workflow	en	Id
+if automatic parsing is disabled next options will be useless	admin	en	if automatic parsing is disabled next options will be useless
+if not in debug mail_smtp agent would have sent this email:	workflow	en	if not in debug mail_smtp agent would have sent this email:
+if user is in a role for an activity he will have the right to abort the related instance	admin	en	If user is in a role for an activity he will have the right to abort the related instance
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	en	If user is in a role for an activity he will have the right to exception or resume the related instance
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	en	If user is in a role for an activity he will have the right to release (un-assign) the related instance
+if:setnextact	workflow	en	If:SetNextact
+iframe view height	workflow	en	Frame view height
+import aborted	workflow	en	Import aborted
+import successfull	workflow	en	Import successfull
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	en	In role mappings user #%1 is specified as a "%2" but is MAYBE a "%3"
+inactive	workflow	en	Inactive
+inst.	workflow	en	Inst.
+inst. status	workflow	en	Inst. Status
+instance	workflow	en	Instance
+instance %1	workflow	en	instance %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	en	Instance %1 is in %2 state, action %3 is impossible.
+instance %1 is in exception, action %2 is not possible.	workflow	en	Instance %1 is in exception, action %2 is not possible.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	en	Instance %1 is not associated with activity %2, action %3 is impossible.
+instance history	workflow	en	Instance History
+instance properties	workflow	en	Instance properties
+instance:	workflow	en	instance:
+instance: %1 (process: %2)	workflow	en	Instance: %1 (Process: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	en	Instance: unable to modify %1 [%2], someone has changed it before us
+instance: unable to modify %1, someone has changed it before us	workflow	en	Instance: unable to modify %1, someone has changed it before us
+instances	workflow	en	Instances
+instances selection	workflow	en	Instances selection
+int.	workflow	en	Int.
+interactive	workflow	en	Interactive
+interactive activities show form before being executed	workflow	en	Interactive activities show form before being executed
+interactive instances should not call the complete() method	workflow	en	interactive instances should not call the complete() method
+interactive:	workflow	en	interactive:
+interactivity	workflow	en	Interactivity
+invalid	workflow	en	invalid
+invalid process	workflow	en	Invalid Process
+invalid role name	workflow	en	Invalid role name
+is active	workflow	en	is active
+it seems this activity for this instance is not assigned to you anymore.	workflow	en	It seems this activity for this instance is not assigned to you anymore.
+it was impossible to complete, no activity was given.	workflow	en	it was impossible to complete, no activity was given.
+it was impossible to complete, no corresponding activity was found.	workflow	en	it was impossible to complete, no corresponding activity was found.
+join	workflow	en	join
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	en	Link addresses are considered local if not containing <strong>http://</strong>. They will get appended the configured local prefix and scanned by egroupware link engine
+list of activities	workflow	en	List of activities
+list of all activities with, for each,  counters of instances by status	workflow	en	list of all activities with, for each,  counters of instances by status
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	en	list of all history items made by instances while they travel in the workflow with information about duration and date
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	en	list of all instances with info about current status and activities and link to administration of theses instances
+list of instances	workflow	en	List of instances
+list of mappings	workflow	en	List of mappings
+list of monitors	workflow	en	List of monitors
+list of processes	workflow	en	List of processes
+list of processes (%1)	workflow	en	List of processes (%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	en	list of processes with status and validity and, for each, counters of instances by status
+list of transitions	workflow	en	List of transitions
+list of workitems	workflow	en	List of workitems
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	en	Mail automatically sent by Mail SMTP Agent for eGroupware's Workflow
+mail smtp agent	workflow	en	Mail Smtp Agent
+mail smtp debug	common	en	Mail smtp debug
+mail smtp local link prefix	common	en	Mail smtp local link prefix
+mail smtp profile	common	en	Mail smtp profile
+mail smtp signature	common	en	Mail smtp signature
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	en	Mails can be sent at the begining or at the end of the activity, For interactive activities only it can be sent after completion.
+manual	workflow	en	Manual
+map	workflow	en	map
+map users/groups to roles	workflow	en	Map users/groups to roles
+mapping to inexistent role	workflow	en	Mapping to inexistent role
+mappings deleted	workflow	en	Mappings deleted
+message:	workflow	en	Message:
+monitor activities	workflow	en	Monitor Activities
+monitor instance	workflow	en	monitor instance
+monitor instances	workflow	en	Monitor Instances
+monitor processes	workflow	en	Monitor Processes
+monitor this instance	workflow	en	Monitor this instance
+monitor work items	workflow	en	Monitor Work Items
+monitor workitems	workflow	en	Monitor workitems
+monitoring	admin	en	Monitoring
+monitors	workflow	en	Monitors
+more options?	workflow	en	more options?
+my activities	workflow	en	My Activities
+my instances	workflow	en	My Instances
+my processes	workflow	en	My Processes
+name	workflow	en	Name
+new instance	workflow	en	New Instance
+new major	workflow	en	New major
+new major version created	workflow	en	new major version created
+new mapping added	workflow	en	New mapping added
+new minor	workflow	en	New minor
+new minor version created	workflow	en	new minor version created
+new status not set, no corresponding activity was found.	workflow	en	new status not set, no corresponding activity was found.
+new transition added	workflow	en	New transition added
+next activity	workflow	en	next activity
+next user:	workflow	en	Next user:
+no action avaible because no activity and no instance are given!	workflow	en	no action avaible because no activity and no instance are given!
+no activites	workflow	en	No activites
+no activity indicated	workflow	en	No activity indicated
+no agents associated with this activity	workflow	en	No agents associated with this activity
+no circular transitions allowed.	workflow	en	No circular transitions allowed.
+no corresponding activity was found.	workflow	en	no corresponding activity was found.
+no inbound for start activity	workflow	en	No inbound for start activity
+no inconcistency detected	workflow	en	no inconcistency detected
+no instance avaible	workflow	en	no instance avaible
+no instance given, nothing to show	workflow	en	no instance given, nothing to show
+no instance indicated	workflow	en	No instance indicated
+no outbound for end activity	workflow	en	No outbound for end activity
+no process indicated	workflow	en	No process indicated
+no properties defined	workflow	en	No properties defined
+no roles	workflow	en	no roles
+no roles asociated with this activity	workflow	en	No roles asociated with this activity
+no routage	workflow	en	no routage
+no scan done	workflow	en	no scan done
+no transitions allowed for standalone or view activities	workflow	en	No transitions allowed for standalone or view activities
+no work item indicated	workflow	en	No work item indicated
+nobody	workflow	en	Nobody
+not defined	workflow	en	not defined
+or import a process	workflow	en	Or import a process
+owner	workflow	en	Owner
+owner of the instance will have the right to abort the instance at any time	admin	en	Owner of the instance will have the right to abort the instance at any time
+owner of the instance will have the right to exception or resume the instance at any time	admin	en	Owner of the instance will have the right to exception or resume the instance at any time
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	en	Owner of the instance will have the right to release (un-assign) an activity assigned to an user
+owner:	workflow	en	Owner:
+ownership give abort right	common	en	Ownership give abort right
+ownership give exception right	common	en	Ownership give exception right
+ownership give release right	common	en	Ownership give release right
+please wait, task in progress ...	workflow	en	Please wait, task in progress ...
+post activity %1 code is not avaible	workflow	en	post activity %1 code is not avaible
+post shared code is not avaible	workflow	en	post shared code is not avaible
+post-agent %1 code is not avaible	workflow	en	post-agent %1 code is not avaible
+pr.	workflow	en	Pr.
+pre-activity %1 code is not avaible	workflow	en	pre-activity %1 code is not avaible
+pre-agent %1 code is not avaible	workflow	en	pre-agent %1 code is not avaible
+pre-shared code is not avaible	workflow	en	pre-shared code is not avaible
+printer friendly	workflow	en	Printer friendly
+priority level:	workflow	en	Priority level:
+process	workflow	en	Process
+process %1	workflow	en	process %1
+process %1 %2 is not active, action %3 is impossible	workflow	en	Process %1 %2 is not active, action %3 is impossible
+process %1 v%2 as no related activity	workflow	en	Process %1 v%2 as no related activity
+process %d has been activated	workflow	en	Process %d has been activated
+process %d has been deactivated	workflow	en	Process %d has been deactivated
+process %s %s already exists, the import process was aborted	workflow	en	Process %s %s already exists, the import process was aborted
+process %s %s imported	workflow	en	Process %s %s imported
+process %s has been created	workflow	en	Process %s has been created
+process %s has been updated	workflow	en	Process %s has been updated
+process %s removed	workflow	en	Process %s removed
+process activities	workflow	en	Process activities
+process alone	workflow	en	Process alone
+process does not have a start activity	workflow	en	Process does not have a start activity
+process does not have exactly one end activity	workflow	en	Process does not have exactly one end activity
+process form	workflow	en	Process form
+process name	workflow	en	Process Name
+process name already exists	workflow	en	Process name already exists
+process roles	workflow	en	Process roles
+process saved	workflow	en	Process saved
+process transitions	workflow	en	Process transitions
+process version:	workflow	en	process version:
+process:	workflow	en	process:
+processes	workflow	en	Processes
+properties	workflow	en	Properties
+property	workflow	en	Property
+property %1 already exists	workflow	en	property %1 already exists
+property %1 not found	workflow	en	property %1 not found
+quit without saving	workflow	en	Quit Without Saving
+read-only	workflow	en	read-only
+release access to this activity	workflow	en	Release access to this activity
+release activity for this instance	workflow	en	release activity for this instance
+release instance	workflow	en	release instance
+reload filter	workflow	en	Reload filter
+remove active instances	workflow	en	Remove active instances
+remove all instances for this process	workflow	en	remove all instances for this process
+remove selected roles	workflow	en	remove selected roles
+removing instances and workitems for aborted instances on all processes	workflow	en	removing instances and workitems for aborted instances on all processes
+removing instances and workitems for aborted instances on process #%1	workflow	en	removing instances and workitems for aborted instances on process #%1
+removing instances and workitems for all instances on process #%1	workflow	en	removing instances and workitems for all instances on process #%1
+replyto:	workflow	en	ReplyTo:
+restart	workflow	en	restart
+restart activity	workflow	en	restart activity
+resume this exception instance	workflow	en	Resume this exception instance
+role	workflow	en	Role
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	en	Role #%1 in process %2 has different process (%3) in mapping with user #%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	en	Role %1 (#%2) is associated with a non-existent process (#%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	en	Role %1 is associated in a mapping with user #%2 with a non-existent process (%3)
+role %1 is not mapped	workflow	en	Role %1 is not mapped
+role added to activity	workflow	en	Role added to activity
+role added to process	workflow	en	Role added to process
+role give abort right	common	en	Role give abort right
+role give exception right	common	en	Role give exception right
+role give release right	common	en	Role give release right
+role in inexistent process	workflow	en	Role in inexistent process
+role mapping in inexistent process	workflow	en	Role Mapping in inexistent process
+role name	workflow	en	Role Name
+role not saved (maybe a name collision)	workflow	en	Role not saved (maybe a name collision)
+role process inconcistency in mappings	workflow	en	Role Process inconcistency in mappings
+role saved	workflow	en	Role saved
+roles	workflow	en	Roles
+roles assigned to this activity	workflow	en	Roles assigned to this activity
+roles deleted	workflow	en	Roles deleted
+routing	workflow	en	Routing
+routing:	workflow	en	routing:
+run	workflow	en	run
+run activity	workflow	en	run activity
+run instance	workflow	en	run instance
+running	workflow	en	running
+running activities options	common	en	Running activities options
+running activity	workflow	en	Running Activity
+scan activities	workflow	en	Scan activities
+scan agents	workflow	en	Scan agents
+scan instances	workflow	en	Scan instances
+scan processes	workflow	en	Scan processes
+scan roles	workflow	en	Scan roles
+scan transitions	workflow	en	Scan transitions
+search instance filter in the bottom of instance lists	workflow	en	Search instance filter in the bottom of instance lists
+search:	workflow	en	search:
+security check: cannot understand asked action	workflow	en	Security check: Cannot understand asked action
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	en	see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>
+select a transition to remove	workflow	en	Select a transition to remove
+select source	workflow	en	select source
+send after interactive activity is completed	workflow	en	send after interactive activity is completed
+send all to	workflow	en	Send all to
+send an email	workflow	en	Send an email
+send instance	workflow	en	send instance
+send this instance to the next activity	workflow	en	Send this instance to the next activity
+send transition	workflow	en	send transition
+send when the activity is ending	workflow	en	send when the activity is ending
+send when the activity is starting	workflow	en	send when the activity is starting
+send when wf_agent_mail_smtp['submit_send'] is posted	workflow	en	send when wf_agent_mail_smtp['submit_send'] is posted
+set next act	workflow	en	Set Next act
+set next user	workflow	en	Set next user
+set property	workflow	en	Set property
+setnextuser directives can override it	workflow	en	setNextUser directives can override it
+setting next activity to an unexisting activity	workflow	en	setting next activity to an unexisting activity
+shared code	workflow	en	Shared code
+should we always give you the advanced search row on instances lists?	workflow	en	Should we always give you the advanced search row on instances lists?
+show activity info zone	common	en	show activity info zone
+show activity title	common	en	show activity title
+show code	workflow	en	show code
+show instance name	common	en	Show instance name
+show instance owner	common	en	Show instance owner
+show multiple submit as select	common	en	show multiple submit as select
+show template	workflow	en	show template
+size of the font used on the graph 12 should be a good default value	admin	en	Size of the font used on the graph 12 should be a good default value
+smtp agent has detected some errors when sending email after completion of the activity	workflow	en	Smtp Agent has detected some errors when sending email after completion of the activity
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	en	Smtp Agent has detected some errors when sending email at the beginning of the activity
+smtp agent has detected some errors when sending email at the end of this activity	workflow	en	Smtp Agent has detected some errors when sending email at the end of this activity
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	en	Smtp Agent has detected some errors when sending email on demand whith this activity
+something was wrong while creating the new major version	workflow	en	something was wrong while creating the new major version
+something was wrong while creating the new minor version	workflow	en	something was wrong while creating the new minor version
+source code file for activity %1 is not avaible	workflow	en	source code file for activity %1 is not avaible
+source code for activity %1 is not avaible	workflow	en	source code for activity %1 is not avaible
+source saved	workflow	en	Source saved
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	en	Special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.
+split	workflow	en	split
+standalone	workflow	en	standalone
+start	workflow	en	Start
+start activities must be autorouted	workflow	en	start activities must be autorouted
+start activities must be interactive	workflow	en	start activities must be interactive
+start activity	workflow	en	Start activity
+start process	workflow	en	start process
+started	workflow	en	Started
+started:	workflow	en	started:
+starting page	workflow	en	Starting page
+status	workflow	en	Status
+status:	workflow	en	status:
+stop	workflow	en	stop
+subject:	workflow	en	Subject:
+switch	workflow	en	switch
+switch construct	workflow	en	Switch construct
+template	workflow	en	template
+test concistency	workflow	en	Test Concistency
+test consistency of datas in the database	workflow	en	Test Consistency of datas in the database
+test local installation	workflow	en	Test local installation
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	en	The /workflow directory does not exist and could not be created. Please ask your administrator to check the global configuration
+the activity was not completed	workflow	en	The activity was not completed
+the default user will only be set if he is mapped to a role on the activity	workflow	en	The default user will only be set if he is mapped to a role on the activity
+the following items must be corrected to be able to activate this process	workflow	en	The following items must be corrected to be able to activate this process
+the instance title is shown on top of the form	admin	en	the instance title is shown on top of the form
+the label you want	workflow	en	the label you want
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	en	The SMTP configuration cannot be loaded by the mail_smtp workflow agent
+there are no activities available	workflow	en	There are no activities available
+there are no config value defined	workflow	en	There are no config value defined
+there are no instances available	workflow	en	There are no instances available
+there are no mappings defined for this process	workflow	en	There are no mappings defined for this process
+there are no process available	workflow	en	There are no process available
+there are no processes	workflow	en	There are no processes
+there are no processes available	workflow	en	There are no processes available
+there are no processes defined	workflow	en	There are no processes defined
+there are no processes with the current filter	workflow	en	There are no processes with the current filter
+there are no properties available	workflow	en	There are no properties available
+there are no roles defined for this process	workflow	en	There are no roles defined for this process
+there are no transitions defined	workflow	en	There are no transitions defined
+there are no user activites available	workflow	en	There are no user activites available
+there are no workitems available	workflow	en	There are no workitems available
+there are some undefined preferences associated with this form : %1	workflow	en	there are some undefined preferences associated with this form : %1
+there is an unknown user or group #%1 in role mappings	workflow	en	There is an unknown user or group #%1 in role mappings
+they were problems at the compilation of the source:	workflow	en	They were problems at the compilation of the source:
+this activity for this instance is actually avaible for you.	workflow	en	This activity for this instance is actually avaible for you.
+this activity for this instance is actually only avaible for you.	workflow	en	This activity for this instance is actually only avaible for you.
+this activity for this instance is not specifically assigned to you.	workflow	en	This activity for this instance is not specifically assigned to you.
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	en	This agent gives the activity the possibility to send an SMTP message (mail)
+this form will test your local workflow installation to detect potential issues	workflow	en	This form will test your local workflow installation to detect potential issues
+this is the first screen shown when you click on the workflow application icon	workflow	en	This is the first screen shown when you click on the workflow application icon
+sets the default sorting criteria for the inbox instances.	workflow	pt-br	Sets the default sorting criteria for the inbox instances.
+determines the number of items per page in the user interface.	workflow	pt-br	Determines the number of items per page in the user interface.
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	en	This process has a view activity. Access in view mode is granted only for this view activty.
+this process has no end activity	workflow	en	this process has no end activity
+this will automatically release the instance when leaving an activity without completing	admin	en	This will automatically release the instance when leaving an activity without completing
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	en	this will display an activity footer when any activity is runned with workflow engine related informations
+to	workflow	en	To
+to:	workflow	en	To:
+transition	workflow	en	transition
+transition mode	workflow	en	transition mode
+transition to %1	workflow	en	transition to %1
+transition waiting for human interaction	workflow	en	transition waiting for human interaction
+transitions	workflow	en	transitions
+transitions removed successfully	workflow	en	Transitions removed successfully
+type	workflow	en	type
+type:	workflow	en	type:
+unknow fix instruction :%1	workflow	en	unknow fix instruction :%1
+unknown instruction from the workflow engine: %1	workflow	en	unknown instruction from the workflow engine: %1
+unknown status	workflow	en	unknown status
+update	workflow	en	update
+upload file	workflow	en	Upload file
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	en	Use <a href="%1">EmailAdmin</a> to create mail profiles
+use automatic parsing	common	en	use automatic parsing
+use default	workflow	en	Use Default
+use existing roles	workflow	en	Use existing roles
+user	workflow	en	User
+user #%1 is associated with a non-existent role #%2	workflow	en	User #%1 is associated with a non-existent role #%2
+user activities	workflow	en	User Activities
+user instances	workflow	en	User Instances
+user instances form: columns	workflow	en	User Instances form: columns
+user instances form: filters and actions	workflow	en	User Instances form: filters and actions
+user is not authorized to delete aborted instances	workflow	en	user is not authorized to delete aborted instances
+user is not authorized to delete instances	workflow	en	user is not authorized to delete instances
+user processes	workflow	en	User Processes
+user/group	workflow	en	User/Group
+user:	workflow	en	user:
+users can act on activity before its execution with form and after by sending it to the next activity	workflow	en	Users can act on activity before its execution with form and after by sending it to the next activity
+users/groups	workflow	en	Users/Groups
+valid	workflow	en	Valid
+valid process	workflow	en	Valid Process
+valid:	workflow	en	valid:
+validity:	workflow	en	Validity:
+value	workflow	en	Value
+version	workflow	en	Version
+view details	workflow	en	view details
+view this instance	workflow	en	View this instance
+view workitem	workflow	en	View Workitem
+View Options	workflow	en	View Options
+warning this filter override all others filters	workflow	en	warning this filter override all others filters
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	en	warning: by using this button you will definitively remove all aborted instances AND their history (workitems) for the selected process.
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	en	warning: by using this button you will definitively remove all instances AND their history (workitems) for the selected process, whatever the state they are.
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	en	We cannot run this activity, maybe this instance or this activity do not exists anymore.
+we were not able to build the message	workflow	en	We were not able to build the message
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	en	When in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	en	when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons
+when to send the message:	workflow	en	When to send the Message:
+workflow	common	en	Work-Flow
+workflow configuration	admin	en	Workflow configuration
+workflow navigation	workflow	en	Workflow navigation
+workflow preferences	workflow	en	Workflow Preferences
+workflow site configuration	workflow	en	Workflow Site Configuration
+workitem information	workflow	en	Workitem information
+workitems	workflow	en	Workitems
+you are not allowed to abort instance %1	workflow	en	You are not allowed to abort instance %1
+you are not allowed to exception instance %1	workflow	en	You are not allowed to exception instance %1
+you are not allowed to grab instance %1	workflow	en	You are not allowed to grab instance %1
+you are not allowed to release instance %1	workflow	en	You are not allowed to release instance %1
+you are not allowed to restart instance %1	workflow	en	You are not allowed to restart instance %1
+you are not allowed to resume instance %1	workflow	en	You are not allowed to resume instance %1
+you are not allowed to send instance %1	workflow	en	You are not allowed to send instance %1
+you can use special values with this mail agent:	workflow	en	You can use special values with this mail agent:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	en	You do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.
+you don't have the rights necessary to exception instance %1	workflow	en	You don't have the rights necessary to exception instance %1
+you have not permission to execute this activity	workflow	en	You have not permission to execute this activity
+you were not allowed to complete the activity	workflow	en	you were not allowed to complete the activity
+no role was selected	workflow	en	No role was selected
+new	workflow	en	New
+organization	common	en	Organization
+sector	workflow	en	Sectot
+add participants	workflow	en	Add participants
+loading	workflow	en	Loading workflow
+situation	workflow	en	Situation
+assigned to	workflow	en	Assigned to
+user interface	workflow	en	User interface
+database options for processes	common	en	Database options for processes
+database options	common	en	Database options
+database name	common	en	Database name
+database host	common	en	Database host
+database port	common	en	Database port
+database type	common	en	Database type
+database user	common	en	Database user
+database password	common	en	Database password
+name of the database used to store data from workflow processes	admin	en	Name of the database used to store data from workflow processes
+database server where the database is stored	admin	en	Database server where the database is stored
+port used to connect to database server	admin	en	Port used to connect to database server
+default user to access the database	admin	en	Default user to access the database
+password of the default user	admin	en	Password of the default user
+type of the database	admin	en	Type of the database
+organization chart	workflow	en	Organization chart
+access control list	workflow	en	Access control list
+execute activities in debug mode	workflow	en	Execute activities in debug mode
+there are no external applications	workflow	en	There are no external applications
+inbox sorting	preferences	en	Inbox sorting
+number of items per page	preferences	en	number of items per page
+warnings in this process	workflow	en	Warnings in this process
+disable advanced actions for all users	admin	en	Disable advanced actions for all users
+disable advanced actions	common	en	Disable advanced actions
+user of the ldap	admin	en	User of the LDAP
+ldap user	common	en	LDAP User
+password of the ldap user	admin	en	Password of the LDAP User
+ldap password	common	en	LDAP password
+menu path	common	en	Menu path
+mainframe options	common	en	mainframe options
+ip of the mainframe	common	en	IP address to mainframe
+mainframe ip	common	en	IP address
+port used to connect the mainframe	common	en	Port used to connect the mainframe
+access mainframe port	common	en	Mainframe access port
+key used to access the mainframe	common	en	Key (user) used to access the mainframe
+access mainframe key	common	en	Key (user)
+password used to access the mainframe	common	en	Password used to access the mainframe
+access mainframe password	common	en	Password to the key above
+environment application to mainframe	common	en	Environment application to mainframe (D or P)
+mainframe environment	common	en	Mainframe environment
+this instance doesn't exist in this activity. probably, this instance has already been executed	workflow	en	This instance doesn't exist in this activity. Probably, this instance has already been executed
+external applications	workflow	en	External Applications
+move instances	workflow	en	Move Instances
+show activity complete page	preferences	en	Show activity complete page
+Determines if the activity complete page should be displayed after the completion of the activity	preferences	en	Determines if the activity complete page should be displayed after the completion of the activity.
+External Applications options 	admin	en	External Applications options
+subnetworks of the intranet (separed by ;)	admin	en	Subnetworks of the intranet (separed by ;)
+subnetworks 	admin	en	Subnetworks
+name of the database used to store data of the workflow module	admin	en	Name of the database used to store data of the Workflow module
+user to access the database	admin	pt-br	User to access the database
+user password	admin	pt-br	User password
+host of the ldap	admin	en	Host of the LDAP
+user context of the ldap	admin	en	User context of the LDAP
+ldap user context	admin	en	LDAP user context
+group context of the ldap	admin	en	Group context of the LDAP
+ldap group context	admin	en	LDAP group context
+follow ldap referrals	admin	en	Follow LDAP referrals
+follow referrals	admin	en	Follow referrals
+database options for workflow	common	pt-br	Database options for workflow
+ldap options	common	pt-br	LDAP options
+use light interface	preferences	en	Use light interface
+determines if a lighter version of the interface should be used	preferences	en	Determines if a lighter version of the interface should be used.
+jobs	workflow	en	Jobs
+upload	workflow	pt-br	Upload
+customize the process	workflow	en	Customize the Process
+process version	workflow	en	Process Version
+invalid name specified	workflow	en	Invalid name specified
+invalid version specified	workflow	en	Invalid version specified
+if left blank, the original value will be used	workflow	en	If left blank, the original value will be used
+the activities will be executed using secure connection	admin	en	The activities will be executed using secure connection
+use secure connection	admin	en	use secure connection
+execute activities using secure connection	workflow	en	Execute activities using secure connection
+the following file could not be found: %1	workflow	en	The following file could not be found: %1
+emergency	common	en	Emergency
+alert	common	en	Alert
+critical	common	en	Critical
+error	common	en	Error
+warning	common	en	Warning
+notice	common	en	Notice
+information	common	en	Information
+debug	common	en	Debug
+log options	common	en	Log Options
+log level	common	en	Log Level
+log options for workflow	common	en	Log Options for Workflow
+log level for workflow	common	en	Log Level for Workflow
+allowed log types for workflow	common	en	Allowed Log Types for Workflow
+log types	common	en	Log Types
+file	common	en	File
+firebug	common	en	Firebug
+select only one user	workflow	en	Select only one user
+select one process role	workflow	en	Select one process's role
+default role will be set only if it is mapped on the activity	workflow	en	Default role will be set only if it is mapped on the activity
+without default user	workflow	en	Without default user
Index: /sandbox/workflow/branches/993/setup/phpgw_fr.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_fr.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_fr.lang	(revision 795)
@@ -0,0 +1,543 @@
+#	workflow	fr	#
+%1 aborted	workflow	fr	%1 interrompues
+%1 active	workflow	fr	%1 actives
+%1 completed	workflow	fr	%1 complétées
+%1 configuration	workflow	fr	%1 Configuration
+%1 days, %2:%3:%4	workflow	fr	%1 jours, %2:%3:%4
+%1 exception	workflow	fr	%1 exception
+%1 menu	workflow	fr	%1 Menu
+%1 monitoring	workflow	fr	%1 Surpervision
+%1 processes (%2 active) (%3 being_run)	workflow	fr	%1 processus (%2 actifs) (%3 en cours)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	fr	le répertoire /workflow n'existe pas et n'a pas pu être créé, s'il vous plaît demandez à l'administrateur de vérifier la configuration globale de l'application.
+<strong>%owner%</strong> is the instance owner email	workflow	fr	<strong>%owner%</strong> est l'email du propriétaire de l'instance.
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	fr	<strong>%property_XX%</strong> est le contenu de la propriété XX de l'instance.
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	fr	<strong>%role_XX%</strong> sont les emails de tous les utilisateurs mappés sur le role XX.
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	fr	<strong>%roles%</strong> sont les emails de tous les utilisateurs mappés sur n'importe quel rôle associé à cette activité.
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	fr	<strong>%signature%</strong> est la signature de l'agent définie dans la configuration du processus.
+<strong>%user%</strong> is the instance user email	workflow	fr	<strong>%user%</strong> est l'email de l'utilisateur de l'instance
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	fr	<strong>%user_XX%</strong> est l'email de l'utilisateur XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	fr	un message de type: 'patientez s'il vous plaît' est affiché quand le formulaire d'activité se charge, utile pour les tâches longues.
+abort instance	workflow	fr	interrompre l'instance
+abort this instance	workflow	fr	interrompre cette instance
+aborted	workflow	fr	interrompue
+access denied for user %1 on activity %2, no role	workflow	fr	Accès refusé pour l'utilisateur %1 sur l'activité %2, pas de rôle
+act	workflow	fr	act
+act. status	workflow	fr	Statut Act.
+act. status:	workflow	fr	Statut Act. :
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	fr	L'action %1 est impossible s'il n'y a pas d'activitité et pas d'instance désignées pour cela!
+action %1 is impossible, another user is already in place	workflow	fr	L'action %1 est impossible, un autre utilisateur es déjà en place.
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	fr	L'action %1 est impossible, il n'y a pas d'utilisateur assigné à cette activité pour cette cette instance.
+action %1 needs an activity and activity %2 does not exists	workflow	fr	L'action %1 à besoin d'une activité et l'activité %2 n'existe pas.
+action %1 needs an instance and instance %2 does not exists	workflow	fr	L'action %1 à besoin d'une instance et l'instance %2 n'existe pas.
+actions	workflow	fr	Actions
+actions right options	common	fr	Options sur les Droits des Actions
+activate	workflow	fr	activer
+active	workflow	fr	active
+active:	workflow	fr	actif :
+activities	workflow	fr	Activités
+activities selection	workflow	fr	Sélection des activités
+activities updated	workflow	fr	Activités mises à jour
+activity	workflow	fr	activité
+activity  status	workflow	fr	Statut de l'activité
+activity %1	workflow	fr	activité %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	fr	L'activité %1 (#%2) est associée avec un processus inexistant (#%3)
+activity %1 code is not avaible	workflow	fr	le code de l'activité %1 n'est pas disponible
+activity %1 is interactive but has no role assigned	workflow	fr	L'activité %1 est interactive mais elle ne dispose d'aucune assignation de rôle
+activity %1 is interactive so it must use the $instance->complete() method	workflow	fr	L'activité %1 est interactive, elle doit donc utiliser la méthode $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	fr	L'activité %1 n'est ni interactive, ni auto-transmise mais elle ne dispose d'aucune assignation de rôle
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	fr	L'activité %1 n'est pas interactive, elle ne doit donc pas utiliser la méthode $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	fr	L'activité %1 est en fonctionnement isolé et elle utilise l'objet $instance
+activity %1 is standalone but has transitions	workflow	fr	L'activité %1 est isolée mais elle possède des transitions
+activity %1 is standalone or view but has transitions	workflow	fr	L'activité %1 est de type Isolé ou Vue mais à des transitions.
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	fr	L'activité %1 est une condition donc elle doit utiliser la méthode $instance->setNextActivity($actname)
+activity %1 is view and is using the $instance object in write mode	workflow	fr	L'activité %1 est de type Vue et utilise l'object $instance en mode écriture
+activity agent removed	workflow	fr	Agent de l'activité supprimé
+activity completed	workflow	fr	Activitée terminée
+activity failure	workflow	fr	Echec de l'activité
+activity in inexistent process	workflow	fr	Activité dans un processus inexistant
+activity is waiting for pending transitions	workflow	fr	l'activité en attente de transitions en suspens
+activity name already exists	workflow	fr	Nom déjà utilisé pour une activité
+activity role #%1 removed	workflow	fr	Role #%1 de l'activité supprimé
+activity role removed	workflow	fr	Suppression de rôle sur l'activité
+activity saved	workflow	fr	Activitée sauvegardée
+activity start not avaible, no corresponding activity was found.	workflow	fr	Activité départ non disponible, aucune activité correspondante n'a été trouvée.
+activity start not set, no corresponding activity was found.	workflow	fr	Départ de l'activité non enregistré, aucune activité correspondante n'a été trouvée.
+activity status not avaible, no corresponding activity was found.	workflow	fr	statut de l'activité non disponible, aucune activité correspondante n'a été trouvée.
+activity:	workflow	fr	activité :
+add a transition	workflow	fr	Ajouter une transition
+add aborted instances	workflow	fr	Ajouter les instances interrompues
+add advanced actions	workflow	fr	Ajouter les actions avancées
+add completed instances	workflow	fr	Ajouter les instances complétées
+add instances in exception	workflow	fr	Ajouter les instances en exception
+add new	workflow	fr	Nouveau
+add or edit a process	workflow	fr	Ajouter ou Editer un processus
+add or edit an activity	workflow	fr	Ajouter ou Editer une activité
+add property	workflow	fr	Ajouter une propriété
+add role	workflow	fr	Ajouter un rôle
+add role to process	workflow	fr	Ajouter un rôle au processus
+add transition	workflow	fr	Ajouter une transition
+add transitions	workflow	fr	Ajouter des transitions
+add transitions from	workflow	fr	Activité de départ
+add transitions to	workflow	fr	Activité d'arrivée
+admin instance	workflow	fr	Aministration des instances
+admin process activities	workflow	fr	Administration des activités du processus
+admin process roles	workflow	fr	Administration des rôles du processus
+admin processes	workflow	fr	Administration des processus
+admin processes sources	workflow	fr	Administration des sources des processus
+administer instances	workflow	fr	administrer les instances
+administer processes	workflow	fr	Administrer les processus
+all	workflow	fr	Tout
+always show advanced actions	workflow	fr	Toujours montrer les actions avancées
+always show advanced mode	workflow	fr	Toujours montrer le mode avancé
+assign me this activity	workflow	fr	M'assigner cette activité
+at least one email address cannot be validated.	workflow	fr	au moins une adresse email n'a pas pue être validée
+auto routed	workflow	fr	Auto transmise
+auto-release on leaving activity	common	fr	libérer automatiquement en quittant l'activité
+automatic	workflow	fr	Automatique
+bad parameter for setagents, the parameter should be an array	workflow	fr	mauvais paramètre pour setAgents, le paramètre devrait être un vecteur
+bad role type	workflow	fr	mauvais type de rôle
+bad user	workflow	fr	mauvais utilisateur
+base directory does not exist, please ask adminstrator to check the global configuration	common	fr	Le répertoire de stockage n'existe pas, veuillez contacter l'administrateur pour qu'il vérifie la configuration globale
+bcc:	workflow	fr	Bcc :
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	fr	Attention avec les activité interactives, le début et la fin de ces activités sont multiples.
+being run	workflow	fr	en cours d'éxécution
+by running theses links you will create new instances of the related process.	workflow	fr	En cliquant sur ces liens vous allez créer de nouvelles instances des processus relatifs.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	fr	Impossible d'ajouter la transition, seuls les activités de type 'Découpé" ou "Condition" peuvent avoir plus d'une transition sortante.
+cannot add transition. only split activities can have more than one outbound transition	workflow	fr	Impossible de créée la transition. Seule les activités de type découpées (split) peuvent avoir plusieurs transitions sortantes.
+cannot create compiled file %1	workflow	fr	Impossible de créer le fichier compilé %1
+cannot retrieve the user running the security check	workflow	fr	Impossible de rapatrier l'utilisateur éxécutant la vérification de sécurité
+cannot run the activity	workflow	fr	Impossible d'éxécuter l'activité
+cannot run the activity without her process	workflow	fr	Impossible d'éxécuter l'activité sans son processus
+cannot run the activity without instance	workflow	fr	Impossible d'éxécuter l'activité sans instance
+cannot run unknown activity	workflow	fr	Impossible d'éxécuter une activité inconnue
+cc:	workflow	fr	Cc :
+circular reference found some activity has a transition leading to itself	workflow	fr	Référence circulaire trouvée, une activité possède une transition menant à elle-même.
+circular reference found. some activity has a transition leading to itself	workflow	fr	Attention Référence circulaire. Une activité dispose de transitions qui permettent de revenir sur elle-même
+cleanup aborted instances	workflow	fr	nettoyer les instances interrompues
+cleanup actions	workflow	fr	Actions de nettoyage
+close printer friendly mode	workflow	fr	Fermer le mode d'impression
+code	workflow	fr	code
+column activity status in instance lists	workflow	fr	Colonne Statut de l'activité dans la liste d'instances
+column category in instance lists	workflow	fr	Colonne Categorie dans la liste d'instances
+column instance id in instance lists	workflow	fr	Colonne Id de l'instance dans les listes d'instances
+column instance name in instance lists	workflow	fr	Colonne Nom de l'instance dans les listes d'instances
+column instance status in instance lists	workflow	fr	Colonne Statut de l'instance dans les listes d'instances
+column owner in instance lists	workflow	fr	Colonne Propriétaire dans les listes d'instances
+column priority in instance lists	workflow	fr	Colonne Priorité dans les listes d'instances
+column process name in instance lists	workflow	fr	Colonne Nom du processus dans les listes d'instances
+column start date in instance lists	workflow	fr	Colonne date de départ dans les listes d'instances
+compiling activity %1 : %2	workflow	fr	Compilation de l'activité %1 : %2
+complete	workflow	fr	terminer
+complete cleanup of aborted instances done	workflow	fr	Nettoyage complet des instances interrompues effectué
+complete cleanup of all instances done	workflow	fr	Nettoyage complet de toutes les instances effectué
+completed	workflow	fr	Terminé
+config values	common	fr	Valeurs de Configuration
+confirm delete	workflow	fr	Confirmez-vous la suppression?
+consult %1 to get the default values:	workflow	fr	Consultez %1 pour avoir les valeurs par défaut
+couldn't add transition	workflow	fr	Impossible d'ajouter une transition
+create	workflow	fr	Créer
+created	workflow	fr	Créée
+date:	workflow	fr	date:
+default config values	common	fr	Configuration valeures par défaut
+default next user	workflow	fr	Utilisateur suivant par défaut
+default owner	workflow	fr	Propriétaire par défaut
+default settings for processes	admin	fr	configuration par défaut pour les processus
+default user	workflow	fr	Utilisateur par défaut
+delete selected	workflow	fr	Supprimer la sélection
+delete transition	workflow	fr	supprimer la transition
+deletion successful	workflow	fr	Suppression Réussie
+delition successful	workflow	fr	Suppression Réussie
+description	workflow	fr	Description
+display please wait message	common	fr	afficher un message de patience
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	fr	Voulez-vous la colonne statut de l'activité dans les listes d'instances. La plupart du temps c'est "en cours" mais si vous utilisez des transitions non-autoroutées vous saurez quelques activités complétées.
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	fr	Voulez-vous la colonne catégorie dans les listes d'instances. Si vos instances utilisent les catégories vous devriez l'utiliser.
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	fr	Voulez-vous la colonne id de l'instance dans les listes d'instances. Ceci est l'identifiant unique de l'instance.
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	fr	Voulez-vous la colonne nom de l'instance dans les listes d'instances. Si vos instances ont des noms vous devriez l'utiliser.
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	fr	Voulez-vous la colonne statut de l'instance dans les listes d'instances. Le statut de l'instance est utile pour faire la distinction entre les instances interrompues, complétées, en exception ou bien actives.
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	fr	Voulez-vous la colonne propriétaire dans les listes d'instances. Cela vous montrera le propriétaire actuel ce qui est spécialement utile quand le proriétaire hérite de droits spéciaux.
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	fr	Voulez-vous la colonne priorité de l'instance dans les listes d'instances. La priorité peut être définie via les formulaires des activités.
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	fr	Voulez-vous la colonne processus dans les listes d'instances. utile si vous avez plusieurs processus et/ou versions de ces processus.
+do you want the search instance button in the last row of instances list.	workflow	fr	Voulez-vous afficher le bouton de recherche d'instance qui se trouve sur la dernière ligne des listes d'instances.
+do you want the started date column on instances lists.	workflow	fr	Voulez-vous la colonne date de départ de l'instance dans les listes d'instances.
+don't move	workflow	fr	Ne pas déplacer
+draw roles	common	fr	afficher les rôles
+draw roles on the graph beside activity name like [that]	admin	fr	affiche les roles sur le graphique sous les noms d'activités comme [cela]
+duration	workflow	fr	Durée
+end	workflow	fr	fin
+end activity is not reachable from start activity	workflow	fr	L'activité de fin ne peut pas être atteinte par l'activité de départ
+enter an activity name	workflow	fr	Entrez un nom d'activité
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	fr	Erreur: nextActivity ne trouve aucun candidat dans l'activité autoroutée de type Condition
+error: non-deterministic decision for autorouting activity	workflow	fr	Erreur: décision non-déterministe pour l'activité autoroutée
+error: removing was not done	workflow	fr	erreur, la suppression ne s'est pas faite
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	fr	Erreur: le moteur essayait d'envoyer une instance vers une activité mais il fut impossible d'avoir cette activité
+error: trying to send an instance to an activity but no transition found	workflow	fr	Erreur: le moteur essayait d'envoyer une instance vers une activité mais aucune transition n'a été trouvée
+exception	workflow	fr	exception
+exception instance	workflow	fr	instance en exception
+exception this instance	workflow	fr	mettre l'instance en exception
+exceptions	workflow	fr	exceptions
+execute this activity	workflow	fr	Exécuter cette activité
+export	workflow	fr	Exporter
+failed to create workitem	workflow	fr	Echec de la création de l'élément d'historique
+failed to execute automatic activity	workflow	fr	Echec de l'éxécution de l'activité automatique
+failed to obtain lock on %1 table	workflow	fr	Echec de l'obtention d'un lock sur la table %1
+failed to record instance properties	workflow	fr	Echec de l'enregistrement des propriétés de l'instance
+failed to synchronize instance data with the database	workflow	fr	Echec de la synchronisation des données de l'instance avec la base de données
+failure	workflow	fr	Echec
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	fr	Erreur Fatale : Dans une activité Condition auto-routée nextActivity ne correspond à aucune activité candidate
+fatal error: non-deterministic decision for autorouting activity	workflow	fr	Erreur Fatale : Décision non-déterministe pour une activité auto-routée
+fatal error: setting next activity to an unexisting activity	workflow	fr	Erreur Fatale : L'activité suivante est affectée à une action inexistante
+fatal error: trying to send an instance to an activity but no transition found	workflow	fr	Erreur Fatale : Impossible d'envoyer une instance à une activité car aucune transition n'a été trouvée
+filter	workflow	fr	Filtre
+filter instance by id	workflow	fr	filtrer les instances par id
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	fr	Et pour finir vous avez des liens avec la syntaxe <strong>%link_XX|YY%</strong>, XX est la partie adresse, YY la partie textuelle.
+font size	workflow	fr	taille de fonte
+from	workflow	fr	Depuis
+from:	workflow	fr	Exp :
+get back to global activities	workflow	fr	retourner aux activités globales
+get back to instance creation	workflow	fr	retourner à la création d'instance
+global activities	workflow	fr	Activités Globales
+global workflow preferences	workflow	fr	Préférences Globales du Workflow
+go to same activities for other instances of this process	workflow	fr	aller à la même activité pour d'autres instances de ce processus
+go to same process activities	workflow	fr	aller aux activités du même processus
+go to the actual state of this instance	workflow	fr	aller à l'état actuel de l'instance
+grab instance	workflow	fr	capturer l'instance
+grant access to the administration and development of workflow processes and activities.	workflow	fr	Donner l'accès à l'administration et au développement des processus et activités du workflow
+grant access to the administration of workflow elements	workflow	fr	Permettre l'accès à l'administration des éléments du workflow
+grant access to the administration of workflow instances in monitor screens	workflow	fr	Donner l'accès à l'administration des instances du workflow dans les écrans de supervision
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	workflow	fr	Donner l'accès au nettoyage/suppression des instances interrompues dans les écrans de supervision
+grant access to the monitoring of workflow elements	workflow	fr	Permettre l'accès à la supervision des éléments du workflow
+graph	workflow	fr	Graphique
+graphic options	common	fr	Options du graphique
+group	workflow	fr	Groupe
+id	workflow	fr	Id
+if automatic parsing is disabled next options will be useless	admin	fr	si l'analyse automatique n'est pas activée les options suivantes seront inutiles
+if not in debug mail_smtp agent would have sent this email:	workflow	fr	S'il n'était pas en mode debug l'agent mail_smtp aurait envoyé cet email:
+if user is in a role for an activity he will have the right to abort the related instance	admin	fr	Si l'utilisateur est dans un des rôles d'une activité il aura le droit d'interrompre l'instance relative à cette activité.
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	fr	Si l'utilisateur est dans un des rôles d'une activité il aura le droit de passer en exception l'instance relative à cette activité.
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	fr	Si l'utilisateur est dans un des rôles d'une activité il aura le droit de libérer (désassigner) l'instance relative à cette activité.
+import aborted	workflow	fr	Importation abandonnée
+import successfull	workflow	fr	Importation réussie
+inactive	workflow	fr	Inactive
+inst.	workflow	fr	inst.
+inst. status	workflow	fr	Statut inst.
+instance	workflow	fr	Instance
+instance %1	workflow	fr	instance %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	fr	L'instance %1 est dans l'état %2, l'action %3 est impossible.
+instance %1 is in exception, action %2 is not possible.	workflow	fr	L'instance %1 est en exception, l'action %2 est impossible.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	fr	L'instance %1 n'est dpas associée avec l'activité %2, l'action %3 est impossible.
+instance history	workflow	fr	Historique de l'instance
+instance properties	workflow	fr	Propriétés de l'instance
+instance:	workflow	fr	instance:
+instance: %1 (process: %2)	workflow	fr	Instance: %1 (Processus: %2)
+instances	workflow	fr	Instances
+instances selection	workflow	fr	selection des instances
+interactive	workflow	fr	Interactive
+interactive:	workflow	fr	Interactive :
+interactivity	workflow	fr	Interactivité
+invalid	workflow	fr	Invalide
+invalid process	workflow	fr	Processus invalide
+invalid role name	workflow	fr	Nom de role invalide
+is active	workflow	fr	est actif
+it seems this activity for this instance is not assigned to you anymore.	workflow	fr	Il semble que cette activité, pour cette instance, ne vous est plus assignée.
+it was impossible to complete, no activity was given.	workflow	fr	Il était impossible de compléter, aucune activitié n'avait été donnée
+it was impossible to complete, no corresponding activity was found.	workflow	fr	Il était impossible de compléter, aucune activitié correspondante n'a été trouvée
+join	workflow	fr	joindre
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	fr	Les adresses de liens sont considérées comme locales si elle ne contiennent pas <strong>http://</strong>. Le prefix local configuré leur sera ajouté et elles seront scannées par le moteur de liens de egroupware
+list of activities	workflow	fr	Liste des activités
+list of all activities with, for each,  counters of instances by status	workflow	fr	liste de toutes les activités avec, pour chacune, des compteurs d'instances par statut
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	fr	liste de tous les éléments d'historique laissés par les instances pendant leur parcours du workflosw, avec des informations sur la durée et la date.
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	fr	liste de toutes les instances avec des informations sur le statut courant et les activités, et un lien vers l'administration de ces instances
+list of instances	workflow	fr	Liste des instances
+list of mappings	workflow	fr	Liste des mappings
+list of monitors	workflow	fr	Liste des Superviseurs
+list of processes	workflow	fr	Liste des processus
+list of processes (%1)	workflow	fr	Liste des processus (%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	fr	liste des processus avec statut et validité et, pour chacun, des compteurs d'instances par statut
+list of transitions	workflow	fr	Liste des transitions
+list of workitems	workflow	fr	Liste des éléments de travail
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	fr	Ce mail est envoyé automatiquement par l'Agent Mail SMTP du Workflow de eGroupware
+mail smtp agent	workflow	fr	Agent Mail SMTP
+mail smtp debug	common	fr	Mail smtp: debug
+mail smtp local link prefix	common	fr	Mail smtp: préfixe pour liens locaux
+mail smtp profile	common	fr	Mail smtp: Profil
+mail smtp signature	common	fr	Mail smtp: signature
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	fr	Les mails peuvent être envoyés au début ou à la fin d'une activité. Ils ne peuvent être envoyés après la completion que pour les activités interactives.
+manual	workflow	fr	Manuel
+map	workflow	fr	mapper
+map users/groups to roles	workflow	fr	Mapper les utilisateurs/groupes vers les rôles
+mapping to inexistent role	workflow	fr	Mapping vers un rôle inexistant
+mappings deleted	workflow	fr	mappings effacés
+message:	workflow	fr	Message :
+monitor activities	workflow	fr	Superviseur d'activités
+monitor instance	workflow	fr	superviser l'instance
+monitor instances	workflow	fr	Superviseur d'instances
+monitor processes	workflow	fr	Superviseur de processus
+monitor this instance	workflow	fr	Superviser cette instance
+monitor work items	workflow	fr	Superviseur des éléments d'historique
+monitor workitems	workflow	fr	Superviseur des éléments d'historique
+monitoring	workflow	fr	supervision
+monitors	workflow	fr	Superviseurs
+more options?	workflow	fr	plus d'options?
+my activities	workflow	fr	Mes activités
+my instances	workflow	fr	Mes instances
+my processes	workflow	fr	Mes processus
+name	workflow	fr	Nom
+new instance	workflow	fr	Nouvelle instance
+new major	workflow	fr	Nouvelle version majeure
+new major version created	workflow	fr	nouvelle version majeure créée
+new mapping added	workflow	fr	Nouveau mapping ajouté
+new minor	workflow	fr	Nouvelle version mineure
+new minor version created	workflow	fr	nouvelle version mineure créée
+new status not set, no corresponding activity was found.	workflow	fr	Le nouveau statut n'a pas été enregistré, aucune activité correspondante n'a été trouvée
+new transition added	workflow	fr	Nouvelle transition ajoutée
+next activity	workflow	fr	Activité suivante
+next user:	workflow	fr	Utilisateur suivant :
+no action avaible because no activity and no instance are given!	workflow	fr	Aucune action disponible car aucune instance et aucune activité n'ont été fournies!
+no activites	workflow	fr	Pas d'activités
+no activity indicated	workflow	fr	Aucune activité indiquée
+no agents associated with this activity	workflow	fr	Pas d'agents associés à cette activité
+no circular transitions allowed.	workflow	fr	Transitions circulaires non autorisées
+no corresponding activity was found.	workflow	fr	aucune activité correspondante n'a été trouvée.
+no inbound for start activity	workflow	fr	Pas de transitions entrantes pour les activité départ
+no instance avaible	workflow	fr	Pas d'instance disponible
+no instance given, nothing to show	workflow	fr	Pas d'instance donnée, rien à montrer
+no instance indicated	workflow	fr	Aucune instance indiquée
+no outbound for end activity	workflow	fr	Pas de transitions sortantes pour les activités fin
+no process indicated	workflow	fr	Aucun processus indiqué
+no properties defined	workflow	fr	Aucune propriété définie
+no roles	workflow	fr	Pas de rôles
+no roles asociated with this activity	workflow	fr	Aucun rôle associé à cette activité
+no routage	workflow	fr	Pas de routage
+no transitions allowed for standalone or view activities	workflow	fr	Pas de transitions autorisées pour les activités de type Isolé ou Vue.
+no work item indicated	workflow	fr	Aucun élément de travail indiqué
+nobody	workflow	fr	Personne
+not defined	workflow	fr	non défini
+or import a process	workflow	fr	Ou importer un processus
+owner	workflow	fr	Propriétaire
+owner of the instance will have the right to abort the instance at any time	admin	fr	le propriétaire de l'instance aura le droit d'interrompre l'instance à tout moment.
+owner of the instance will have the right to exception or resume the instance at any time	admin	fr	le propriétaire de l'instance aura le droit de passer l'instance en exception ou de la remettre en cours à tout moment.
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	fr	le propriétaire de l'instance aura le droit de libérer (désassigner) une activité de l'instance assignée à un utilisateur.
+owner:	workflow	fr	Propriétaire:
+ownership give abort right	common	fr	la propriété donne le droit d'interrompre
+ownership give exception right	common	fr	la propriété donne le droit d'exception
+ownership give release right	common	fr	la propriété donne le droit de libération
+please wait, task in progress ...	workflow	fr	Patientez s'il vous plaît, tâche en cours
+post activity %1 code is not avaible	workflow	fr	le code suivant l'activité %1 n'est pas disponible
+post shared code is not avaible	workflow	fr	le code suivant le code partagé n'est pas disponible
+post-agent %1 code is not avaible	workflow	fr	le code suivant l'agent %1 n'est pas disponible
+pr.	workflow	fr	Pr.
+pre-activity %1 code is not avaible	workflow	fr	le code précédant l'activité %1 n'est pas disponible
+pre-agent %1 code is not avaible	workflow	fr	le code précédant l'agent %1 n'est pas disponible
+pre-shared code is not avaible	workflow	fr	le code précédant le code partagé n'est pas disponible
+printer friendly	workflow	fr	Mode impression
+priority level:	workflow	fr	Niveau de Priorité:
+process	workflow	fr	Processus
+process %1	workflow	fr	processus %1
+process %1 %2 is not active, action %3 is impossible	workflow	fr	Le processus %1 %2 n'est pas actif, l'action %3 est impossible.
+process %1 v%2 as no related activity	workflow	fr	Le processus %1 v%2 n'a aucune activité reliées
+process %d has been activated	workflow	fr	Le processus %d a été activé
+process %d has been deactivated	workflow	fr	Le processus %d a été désactivé
+process %s %s already exists, the import process was aborted	workflow	fr	Le processus %s %s existe déjà, Le processus d'import a été interrompu.
+process %s %s imported	workflow	fr	Processus %s %s importé
+process %s has been created	workflow	fr	Le processus %s a été créée
+process %s has been updated	workflow	fr	Le processus %s a été mis à jour
+process %s removed	workflow	fr	Processus %s supprimé
+process activities	workflow	fr	Activités du processus
+process does not have a start activity	workflow	fr	Le processus n'a pas d'activité de départ
+process does not have exactly one end activity	workflow	fr	Le processus ne dispose pas d'exactement une fin
+process form	workflow	fr	Formulaire du Processus
+process name	workflow	fr	Nom du Processus
+process name already exists	workflow	fr	Le nom du processus est déjà utilisé
+process roles	workflow	fr	Rôles du processus
+process saved	workflow	fr	Processus enregistré
+process transitions	workflow	fr	Transitions du processus
+process version:	workflow	fr	version processus :
+process:	workflow	fr	processus :
+processes	workflow	fr	Les processus
+properties	workflow	fr	Propriétés
+property	workflow	fr	Propriété
+property %1 already exists	workflow	fr	la propriété %1 existe déjà
+property %1 not found	workflow	fr	Propriété %1 non trouvée
+read-only	workflow	fr	lecture-seule
+release access to this activity	workflow	fr	Libérer l'accès à cette activité
+release activity for this instance	workflow	fr	libérer l'activité pour cette instance
+release instance	workflow	fr	libérer l'instance
+reload filter	workflow	fr	Relancer le filtre
+remove active instances	workflow	fr	Enlever les instances actives
+remove all instances for this process	workflow	fr	Supprimer toutes les instances pour ce processus
+remove selected roles	workflow	fr	supprimer les rôles sélectionés
+removing instances and workitems for aborted instances on all processes	workflow	fr	Suppression des instances et des éléments d'historique pour les instances interrompues sur tous les processus
+removing instances and workitems for aborted instances on process #%1	workflow	fr	Suppression des instances et des éléments d'historique pour les instances interrompues sur tous le processus numéro %1
+removing instances and workitems for all instances on process #%1	workflow	fr	Suppression des instances et des éléments d'historique pour toutes les instances le processus numéro %1
+replyto:	workflow	fr	Répondre à:
+restart	workflow	fr	redémarrer
+restart activity	workflow	fr	redémarrer l'activité
+resume this exception instance	workflow	fr	Reprise de cette instance en exception
+role	workflow	fr	Rôle
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	fr	Le rôle #%1 dans le processus %2 possède un processus différent (%3) dans le mapping avec l'utilisateur #%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	fr	Le rôle %1 (#%2) est associé avec un processus inexistant (#%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	fr	Le rôle %1 est associé dans un mapping avec l'utilisateur #%2 avec un processus inexistant (%3)
+role %1 is not mapped	workflow	fr	Le rôle %1 n'est pas mappé
+role added to activity	workflow	fr	Rôle ajouté à cette activité
+role added to process	workflow	fr	Rôle ajouté au processus
+role give abort right	common	fr	le rôle donne les droits d'interruption
+role give exception right	common	fr	le rôle donne les droits d'exception
+role give release right	common	fr	le rôle donne les droits de libération
+role name	workflow	fr	Nom du rôle
+role not saved (maybe a name collision)	workflow	fr	Rôle non enregistré (peut-être une collision de noms)
+role saved	workflow	fr	Rôle sauvegardé
+roles	workflow	fr	Rôles
+roles assigned to this activity	workflow	fr	Rôles attribués à cette activité
+roles deleted	workflow	fr	Rôles supprimés
+routing	workflow	fr	Mode de routage
+routing:	workflow	fr	Mode de routage :
+run	workflow	fr	démarrer
+run activity	workflow	fr	démarrer l'activité
+run instance	workflow	fr	éxécuter l'instance
+running	workflow	fr	En cours
+running activities options	common	fr	Options d'éxécution des activités
+running activity	workflow	fr	Activité en cours
+search instance filter in the bottom of instance lists	workflow	fr	Filtre de recherche d'instance dans le bas des listes d'instances
+search:	workflow	fr	Chercher :
+security check: cannot understand asked action	workflow	fr	Vérification de sécurité: Impossible de comprendre l'action demandée
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	fr	voir aussi <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>
+select a transition to remove	workflow	fr	Choisissez une transition à supprimer
+select source	workflow	fr	Choisir la source
+send after interactive activity is completed	workflow	fr	envoyé après que l'activité interactive soit complétée
+send all to	workflow	fr	Envoyer à tous
+send an email	workflow	fr	Envoyer un email
+send instance	workflow	fr	envoyer l'instance
+send this instance to the next activity	workflow	fr	Envoyer cette instance à l'activité suivante
+send transition	workflow	fr	envoyer la transition
+send when the activity is ending	workflow	fr	envoyer quand l'activité se termine
+send when the activity is starting	workflow	fr	envoyer quand l'activité commence
+shared code	workflow	fr	Code partagé du processus
+should we always give you the advanced search row on instances lists?	workflow	fr	Devons nous toujours vous afficher la ligne de recherche avancée dans les listes d'instances?
+show activity info zone	common	fr	montrer la zone d'information de l'activité
+show activity title	common	fr	montrer le titre de l'activité
+show code	workflow	fr	montrer le code
+show instance name	common	fr	Montrer le nom de l'instance
+show instance owner	common	fr	Montrer le propriétaire de l'instance
+show multiple submit as select	common	fr	montrer les multiples boutons de validation dans une liste déroulante
+show template	workflow	fr	montrer le template
+size of the font used on the graph 12 should be a good default value	admin	fr	taille de la fonte utilisée sur le graphique. 12 devrait être une bonne valeur par défaut.
+smtp agent has detected some errors when sending email after completion of the activity	workflow	fr	L'agent Smtp a détecté quelques erreurs quand il voulait envoyer un mail après la completion de l'activité.
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	fr	L'agent Smtp a détecté quelques erreurs quand il voulait envoyer un mail au départ de l'activité.
+smtp agent has detected some errors when sending email at the end of this activity	workflow	fr	L'agent Smtp a détecté quelques erreurs quand il voulait envoyer un mail lors de la terminaison de l'activité.
+something was wrong while creating the new major version	workflow	fr	Quelque chose s'est mal passé pendant la création de la nouvelle version majeure.
+something was wrong while creating the new minor version	workflow	fr	Quelque chose s'est mal passé pendant la création de la nouvelle version mineure.
+source code file for activity %1 is not avaible	workflow	fr	Le fichier de code source pour l'activité %1 n'est pas disponible
+source code for activity %1 is not avaible	workflow	fr	Le code source pour l'activité %1 n'est pas disponible
+source saved	workflow	fr	Source sauvegardée
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	fr	Des valeurs spéciales sont connues pour les adresses de liens locaux : <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> et <strong>admininstance</strong>.
+split	workflow	fr	découpé
+standalone	workflow	fr	isolé
+start	workflow	fr	Départ
+start activities must be autorouted	workflow	fr	les activités de type départ doivent être autoroutées
+start activities must be interactive	workflow	fr	les activités de type départ doivent être interactives
+start activity	workflow	fr	Activité Départ
+start process	workflow	fr	démarrer le processus
+started	workflow	fr	Démarré
+started:	workflow	fr	démarré :
+starting page	workflow	fr	Page de démarrage
+status	workflow	fr	Statut
+status:	workflow	fr	Statut :
+stop	workflow	fr	Fin
+subject:	workflow	fr	Sujet :
+switch	workflow	fr	Condition
+switch construct	workflow	fr	Constructeur de Condition
+template	workflow	fr	template
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	fr	Le répertoire de stockage des fichiers du workflow (/workflow) n'existe pas et ne peut être créée. Veuillez demander à l'administrateur de vérifier le configuration globale
+the activity was not completed	workflow	fr	l'activité n'a pas été complétée
+the following items must be corrected to be able to activate this process	workflow	fr	Les éléments suivants doivents être corrigés pour pouvoir activer ce processus
+the instance title is shown on top of the form	admin	fr	le titre de l'instance est montré en haut du formulaire
+the label you want	workflow	fr	l'étiquette désirée
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	fr	La configuration SMTP ne peut être chargée par l'agent mail_smtp du workflow
+there are no activities available	workflow	fr	Il n'y a aucune activité disponible
+there are no config value defined	workflow	fr	il n'y a pas de valeur de configuration définies
+there are no instances available	workflow	fr	Il n'y a aucune instance disponible
+there are no mappings defined for this process	workflow	fr	Il n'y a aucun mapping défini pour ce processus
+there are no process available	workflow	fr	Il n'y a aucun processus disponible
+there are no processes	workflow	fr	Il n'y a aucun processus
+there are no processes available	workflow	fr	Il n'y a aucun processus disponible
+there are no processes defined	workflow	fr	Il n'y a aucun processus défini
+there are no processes with the current filter	workflow	fr	Il n'y a aucun processus avec le filtre actuel
+there are no properties available	workflow	fr	Il n'y a aucune propriété disponible
+there are no roles defined for this process	workflow	fr	Il n'y a aucun rôle défini pour ce processus
+there are no transitions defined	workflow	fr	il n'y a aucune transition définie
+there are no user activites available	workflow	fr	Il n'y a aucune activité utilisateur disponible
+there are no workitems available	workflow	fr	Il n'y a aucun élément de travail disponible
+there are some undefined preferences associated with this form : %1	workflow	fr	il y a quelques préférences non définies associées à ce formulaire : %1
+they were problems at the compilation of the source:	workflow	fr	Il y a eu des problèmes lors de la compilation des sources:
+this activity for this instance is actually avaible for you.	workflow	fr	Cette activité pour cette instance est actuellement disponible pour vous.
+this activity for this instance is actually only avaible for you.	workflow	fr	Cette activité pour cette instance est actuellement disponible uniquement pour vous.
+this activity for this instance is not specifically assigned to you.	workflow	fr	Cette activité pour cette instance ne vous est pas spécifiquement attribuée.
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	fr	Cet agent donne à l'activité la possibilité d'envoyer un message SMTP (mail)
+this is the first screen shown when you click on the workflow application icon	workflow	fr	Ceci est le premier écran affiché quand vous cliquez sur l'icône de l'application workflow
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	fr	Ce processus possède une activité de type Vue. L'accès en mode lecture seul est autorisé uniquement pour cette activité de type Vue.
+this process has no end activity	workflow	fr	ce processus n'a pas d'activité de fin
+this will automatically release the instance when leaving an activity without completing	admin	fr	ceci va automatiquement libérer l'instance quand vous quitterez une activité sans la compléter
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	fr	Cela va afficher un pied de page aux activités lorsqu'elles seront éxécutées contenant des informations relatives au moteur de workflow.
+to	workflow	fr	Vers
+to:	workflow	fr	Pour:
+transition	workflow	fr	transition
+transition mode	workflow	fr	mode de transition
+transition to %1	workflow	fr	transition vers %1
+transition waiting for human interaction	workflow	fr	Transition en attente d'interaction humaine
+transitions	workflow	fr	transitions
+transitions removed successfully	workflow	fr	Transitions supprimées avec succès
+type	workflow	fr	type
+type:	workflow	fr	type :
+unknown instruction from the workflow engine: %1	workflow	fr	instruction inconnue depuis le moteur de workflow: %1
+unknown status	workflow	fr	Statut inconnu
+update	workflow	fr	Mettre à jour
+upload file	workflow	fr	Télécharger fichier
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	fr	Utilisez <a href="%1">EmailAdmin</a> pour créer les profils email
+use automatic parsing	common	fr	utiliser l'affichage automatique
+use default	workflow	fr	Utiliser le défaut
+use existing roles	workflow	fr	Utiliser un rôle existant
+user	workflow	fr	Utilisateur
+user activities	workflow	fr	Activités utilisateur
+user instances	workflow	fr	Instances utilisateur
+user instances form: columns	workflow	fr	Formulaire instances utilisateur : colonnes
+user instances form: filters and actions	workflow	fr	Formulaire instances utilisateur : filtres et actions
+user is not authorized to delete aborted instances	workflow	fr	l'utilisateur n'est pas autorisé à supprimer les instances interrompues
+user is not authorized to delete instances	workflow	fr	l'utilisateur n'est pas autorisé à supprimer les instances
+user processes	workflow	fr	Processus utilisateur
+user/group	workflow	fr	Utilisateur/Groupe
+user:	workflow	fr	utilisateur :
+users/groups	workflow	fr	Utilisateurs/Groupes
+valid	workflow	fr	Valider
+valid process	workflow	fr	Valider le processus
+valid:	workflow	fr	validité :
+value	workflow	fr	Valeur
+version	workflow	fr	Version
+view details	workflow	fr	voir détails
+view this instance	workflow	fr	Voir cette instance
+view workitem	workflow	fr	Voir l'élément d'historique
+warning this filter override all others filters	workflow	fr	attention ce filtre supplante tout les autres filtres
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	fr	Attention: en utilisant ce bouton vous allez définitivement effacer toutes les instances interrompues ET leur historique (élements d'historiques) sur le processus sélectionné
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	fr	Attention: en utilisant ce bouton vous allez définitivement effacer toutes les instances ET leur historique (élements d'historiques) sur le processus sélectionné, quelquesoit leur état actuel.
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	fr	Impossible d'éxécuter cette activité, peut-être cette instance ou cette activité n'existe-t-elle plus dans cet état.
+we were not able to build the message	workflow	fr	Nous n'avons pas été capables de construire le message
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	fr	Dans le mode avancé, devons nous vous montrer les actions avancées par défaut (reprise, exception, capture, etc.) ?
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	fr	Quand plusieurs options submit sont disponibles nous dessinons une liste déroulante plutôt que plusieurs boutons submit.
+when to send the message:	workflow	fr	Quand envoyer le message
+workflow	common	fr	Workflow
+workflow configuration	admin	fr	Configuration du workflow
+workflow navigation	workflow	fr	Navigation dans le workflow
+workflow preferences	workflow	fr	Préférences du Workflow
+workflow site configuration	workflow	fr	Configuration du site pour le workflow
+workitem information	workflow	fr	Information sur l'élément de travail
+workitems	workflow	fr	Eléments de travail
+you are not allowed to abort instance %1	workflow	fr	Vous n'êtes pas autorisé à interrompre l'instance %1
+you are not allowed to exception instance %1	workflow	fr	Vous n'êtes pas autorisé à mettre l'instance %1 en exception
+you are not allowed to grab instance %1	workflow	fr	Vous n'êtes pas autorisé à capturer l'instance %1
+you are not allowed to release instance %1	workflow	fr	Vous n'êtes pas autorisé à libérer l'instance %1
+you are not allowed to restart instance %1	workflow	fr	Vous n'êtes pas autorisé à redémarrer l'instance %1
+you are not allowed to resume instance %1	workflow	fr	Vous n'êtes pas autorisé à reprendre l'instance %1
+you are not allowed to send instance %1	workflow	fr	Vous n'êtes pas autorisé à envoyer l'instance %1
+you can use special values with this mail agent:	workflow	fr	Vous pouvez utiliser des valeurs spéciales avec cet agent mail:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	fr	Vous n'avez plus actuellement le droit d'éxécuter cette activité, peut-être s'agit-il d'un problème d'accès concurrent, rafraichissez vos données.
+you have not permission to execute this activity	workflow	fr	Vous n'avez pas les droits nécéssaires pour exécuter cette activité
+you were not allowed to complete the activity	workflow	fr	Vous n'avez pas été autorisé à compléter l'activité
Index: /sandbox/workflow/branches/993/setup/setup.inc.php
===================================================================
--- /sandbox/workflow/branches/993/setup/setup.inc.php	(revision 2042)
+++ /sandbox/workflow/branches/993/setup/setup.inc.php	(revision 2042)
@@ -0,0 +1,67 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - PHPBrain                                                    *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+	/* Basic information about this app */
+	$setup_info['workflow']['name']			= 'workflow';
+	$setup_info['workflow']['title']		= 'Workflow management';
+	$setup_info['workflow']['version']		= '2.2.000';
+	$setup_info['workflow']['app_order']	= 10;
+	$setup_info['workflow']['enable']		= 1;
+	$setup_info['workflow']['author']		= 'Ported from tikiwiki, modified by regis_glc alpeb & mbartz<br>Customized to ExpressoLivre by viani, rodrigolira, mariceli, drovetto, carloseduardo, rufino, asaikawa, gbisotto, julianadelgado & rodsouza<br>See changeLog for full names.';
+	$setup_info['workflow']['note']			= 'Workflow engine';
+	$setup_info['workflow']['license']		= 'GPL';
+	$setup_info['workflow']['description']		= 'Workflow Management';
+	$setup_info['workflow']['maintainer']		= 'Mauricio Luiz Viani';
+	$setup_info['workflow']['maintainer_email']	= 'viani@celepar.pr.gov.br';
+	$setup_info['workflow']['tables']		= array(
+								'egw_wf_activities',
+								'egw_wf_activity_roles',
+								'egw_wf_instance_activities',
+								'egw_wf_instances',
+								'egw_wf_processes',
+								'egw_wf_roles',
+								'egw_wf_transitions',
+								'egw_wf_user_roles',
+								'egw_wf_workitems',
+								'egw_wf_process_config',
+								'egw_wf_activity_agents',
+								'egw_wf_agent_mail_smtp',
+								'egw_wf_interinstance_relations',
+								'egw_wf_external_application',
+								'egw_wf_admin_access',
+								'egw_wf_user_cache',
+								'egw_wf_jobs',
+								'egw_wf_job_logs'
+							);
+
+	/* The hooks this app includes, needed for hooks registration */
+	$setup_info['workflow']['hooks'][] = 'about';
+	$setup_info['workflow']['hooks'][] = 'admin';
+	$setup_info['workflow']['hooks'][] = 'add_def_pref';
+	$setup_info['workflow']['hooks'][] = 'config';
+	$setup_info['workflow']['hooks'][] = 'manual';
+	$setup_info['workflow']['hooks'][] = 'preferences';
+	$setup_info['workflow']['hooks'][] = 'settings';
+	$setup_info['workflow']['hooks'][] = 'sidebox_menu';
+	$setup_info['workflow']['hooks'][] = 'acl_manager';
+	$setup_info['workflow']['hooks'][] = 'deleteaccount';
+	$setup_info['workflow']['hooks'][] = 'home';
+
+	/* Dependencies for this app to work */
+	$setup_info['workflow']['depends'][] = array(
+		'appname' => 'phpgwapi',
+		'versions' => Array('1.0.0','1.0.1','1.2', '2.0', '2.1')
+	);
+	$setup_info['workflow']['depends'][] = array(
+		'appname' => 'preferences',
+		'versions' => Array('1.0.0', '0.9.13.002', '2.0', '2.1')
+	);
+?>
Index: /sandbox/workflow/branches/993/setup/phpgw_zh-tw.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_zh-tw.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_zh-tw.lang	(revision 795)
@@ -0,0 +1,799 @@
+#	workflow	zh-tw	ç·šè
+%1 aborted	workflow	zh-tw	%1 äž­æ­¢äº
+%1 active	workflow	zh-tw	%1 åçšäž­
+%1 completed	workflow	zh-tw	%1 å®æäº
+%1 configuration	workflow	zh-tw	%1 èš­å®
+%1 days, %2:%3:%4	workflow	zh-tw	%1 å€©ïŒ %2:%3:%4
+%1 exception	workflow	zh-tw	%1 åäŸå€
+%1 menu	workflow	zh-tw	%1 åéžå®
+%1 monitoring	workflow	zh-tw	%1 åèšé±äž­
+%1 processes (%2 active) (%3 being_run)	workflow	zh-tw	%1 åæµçšïŒ%2 åçšäž­ïŒ%3  å·è¡äž­ïŒ
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	zh-tw	/workflow è³æå€Ÿäžå­åšèäžç¡æ³å»ºç«ïŒè«è©¢åç³»çµ±ç®¡çå¡ç¶²ç«èš­å®æ¯åŠæ­£ç¢º
+<strong>%owner%</strong> is the instance owner email	workflow	zh-tw	<strong>%owner%</strong> æ¯å¯ŠäŸææäººçä¿¡ç®±
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	zh-tw	<strong>%property_XX%</strong> æ¯å¯ŠäŸçå±¬æ§å
+§å®¹ XX
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	zh-tw	<strong>%role_XX%</strong> æ¯ææå°æå°è§è² XX çäœ¿çšè
+ä¿¡ç®±
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	zh-tw	<strong>%roles%</strong> æ¯ææå°æå°éåæŽ»åä»»æè§è²çäœ¿çšè
+ä¿¡ç®±
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	zh-tw	<strong>%signature%</strong>æ¯åšæµçšèš­å®äž­å®çŸ©çä»£çäººç°œå
+<strong>%user%</strong> is the instance user email	workflow	zh-tw	<strong>%user%</strong>æ¯å¯ŠäŸçäœ¿çšè
+ä¿¡ç®±
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	zh-tw	<strong>%user_XX%</strong>æ¯åž³è XX çä¿¡ç®±
+a please wait message is shown when loading the activity form usefull for long tasks	admin	zh-tw	äžåæç€ºç­åçèšæ¯åšè®åèŒå€ä»»åçæŽ»åè¡šå®ææçžç¶æçš
+abort instance	workflow	zh-tw	éæŒéæ®µ
+abort this instance	workflow	zh-tw	éæŒéåå¯ŠäŸ
+aborted	workflow	zh-tw	äž­æ­¢
+access denied for user %1 on activity %2, no role	workflow	zh-tw	äœ¿çšè
+ %1 åšæŽ»å %2 æ²æå­åæ¬éïŒçŒºå°è§è²
+act	workflow	zh-tw	é²è¡äž­
+act. status	workflow	zh-tw	åäœçæ
+
+act. status:	workflow	zh-tw	åäœçæ
+ïŒ
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	zh-tw	åäœ %1 ç¡æ³åšæ²ææŽ»åèå¯ŠäŸè¢«æå®æé²è¡ïŒ
+action %1 is impossible, another user is already in place	workflow	zh-tw	åäœ %1 ç¡æ³é²è¡ïŒåŠäžåäœ¿çšè
+é
+çœ®äž­
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	zh-tw	åäœ %1 ç¡æ³é²è¡ïŒéåå¯ŠäŸæ²æææŽŸä»»äœäººå°éåæŽ»å
+action %1 needs an activity and activity %2 does not exists	workflow	zh-tw	åäœ %1 éèŠäžåæŽ»åèæŽ»å %2 äžå­åš
+action %1 needs an instance and instance %2 does not exists	workflow	zh-tw	åäœ %1 éèŠäžåå¯ŠäŸèå¯ŠäŸ %2 äžå­åš
+actions	workflow	zh-tw	åäœ
+actions right options	common	zh-tw	åäœæ¬ééžé 
+
+activate	workflow	zh-tw	é²è¡äž­
+active	workflow	zh-tw	æŽ»å
+active:	workflow	zh-tw	æŽ»åïŒ
+activities	workflow	zh-tw	æŽ»å
+activities selection	workflow	zh-tw	éžææŽ»å
+activities updated	workflow	zh-tw	æŽ»åæŽæ°äº
+activity	workflow	zh-tw	æŽ»å
+activity  status	workflow	zh-tw	æŽ»åçæ
+
+activity %1	workflow	zh-tw	æŽ»å %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	zh-tw	æŽ»å %1 (ç·šè %2 ïŒæ­žé¡æŒäžå­åšçæµçšïŒç·šè %3 ïŒ
+activity %1 code is not avaible	workflow	zh-tw	æŽ»å %1 ä»£ç¢Œç¡æ³äœ¿çš
+activity %1 is interactive but has no role assigned	workflow	zh-tw	æŽ»å %1 æ¯äºåé¡åïŒäœæ¯æ²ææå®è§è²
+activity %1 is interactive so it must use the $instance->complete() method	workflow	zh-tw	æŽ»å %1 æ¯äºåé¡åïŒæä»¥å¿
+é äœ¿çšæ¹æ³  $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	zh-tw	æŽ»å %1 æ¯éäºåé¡åäžéèªåé
+çœ®ïŒäœæ¯æ²ææå®è§è²
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	zh-tw	æŽ»å %1 æ¯éäºåé¡åïŒæä»¥å¿
+é äœ¿çšæ¹æ³  $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	zh-tw	æŽ»å %1 æ¯çšç«çäžäœ¿çšç©ä»¶ $instance
+activity %1 is standalone but has transitions	workflow	zh-tw	æŽ»å %1 æ¯çšç«çäœæéäº€
+activity %1 is standalone or view but has transitions	workflow	zh-tw	æŽ»å %1 æ¯çšç«çæå¯ä»¥çèŠœäœå¿
+é éäº€
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	zh-tw	æŽ»å %1 æ¯äº€æåŒçïŒæä»¥å¿
+é äœ¿çšæ¹æ³$instance->setNextActivity($actname)
+activity %1 is view and is using the $instance object in write mode	workflow	zh-tw	æŽ»å %1 å¯ä»¥çèŠœäžæ­£äœ¿çš $instance ç©ä»¶æŒå¯«å
+¥æš¡åŒ
+activity agent removed	workflow	zh-tw	æŽ»åä»£çäººç§»é€äº
+activity completed	workflow	zh-tw	æŽ»åå®æ
+activity failure	workflow	zh-tw	æŽ»åå€±æ
+activity in inexistent process	workflow	zh-tw	æŽ»åå±¬æŒäžå­åšçæµçš
+activity is waiting for pending transitions	workflow	zh-tw	æŽ»ååšç­åå¿
+èŠçéäº€
+activity name already exists	workflow	zh-tw	æŽ»ååçš±å·²ç¶å­åš
+activity role #%1 removed	workflow	zh-tw	æŽ»åè§è² #%1 ç§»é€äº
+activity role removed	workflow	zh-tw	æŽ»åè§è²ç§»é€äº
+activity saved	workflow	zh-tw	æŽ»åå²å­äº
+activity start not avaible, no corresponding activity was found.	workflow	zh-tw	æŽ»åéå§æ¥æç¡æïŒæ²ææŸå°äžèŽçæŽ»åã
+activity start not set, no corresponding activity was found.	workflow	zh-tw	æŽ»åéå§æ¥æçºèš­å®ïŒæ²ææŸå°äžèŽçæŽ»åã
+activity status not avaible, no corresponding activity was found.	workflow	zh-tw	æŽ»åçæ
+ç¡æïŒæ²ææŸå°äžèŽçæŽ»åã
+activity:	workflow	zh-tw	æŽ»åïŒ
+add a transition	workflow	zh-tw	æ°å¢éäº€
+add aborted instances	workflow	zh-tw	æ°å¢åçšçå¯ŠäŸ
+add advanced actions	workflow	zh-tw	æ°å¢é²éåäœ
+add agent	workflow	zh-tw	æ°å¢ä»£çäºº
+add completed instances	workflow	zh-tw	æ°å¢å®æçå¯ŠäŸ
+add instances in exception	workflow	zh-tw	æ°å¢äŸå€çå¯ŠäŸ
+add new	workflow	zh-tw	æ°å¢
+add new role	workflow	zh-tw	æ°å¢è§è²
+add or edit a process	workflow	zh-tw	æ°å¢æç·šèŒ¯äžåèçéçš
+add or edit a role	workflow	zh-tw	æ°å¢æç·šèŒ¯äžåè§è²
+add or edit an activity	workflow	zh-tw	æ°å¢æç·šèŒ¯äžåæŽ»å
+add property	workflow	zh-tw	æ°å¢å±¬æ§
+add role	workflow	zh-tw	æ°å¢è§è²
+add role to process	workflow	zh-tw	æ°å¢è§è²å°èçéçšäž­
+add transition	workflow	zh-tw	æ°å¢éäº€
+add transitions	workflow	zh-tw	æ°å¢éäº€
+add transitions from	workflow	zh-tw	æ°å¢éäº€äŸæº
+add transitions to	workflow	zh-tw	æ°å¢éäº€ç®ç
+admin instance	workflow	zh-tw	ç®¡çéæ®µ
+admin process activities	workflow	zh-tw	ç®¡çæŽ»åèçéçš
+admin process roles	workflow	zh-tw	ç®¡çè§è²èçéçš
+admin processes	workflow	zh-tw	ç®¡çèçéçš
+admin processes sources	workflow	zh-tw	ç®¡çèçéçšè³æº
+administer instances	workflow	zh-tw	ç®¡çå¯ŠäŸ
+administer processes	workflow	zh-tw	ç®¡çæµçš
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	zh-tw	ä»£çäºº #%1 æŒé¡å %2 è¢«æ­žé¡å°äžåäžå­åšçæŽ»å #%3
+agent #%1 of type %2 is not linked with an activity	workflow	zh-tw	ä»£çäºº #%1 æŒé¡å %2 æ²æè¢«ä»»äœæŽ»åé£çµ
+agent associated with inexistent activity	workflow	zh-tw	ä»£çäººè¢«æ­žé¡å°äžåäžå­åšçæŽ»å
+agent without activity	workflow	zh-tw	æ²ææŽ»åçä»£çäºº
+agents assigned to this activity	workflow	zh-tw	ææŽŸå°éåæŽ»åçä»£çäºº
+all	workflow	zh-tw	å
+šéš
+always show advanced actions	workflow	zh-tw	æ°žé é¡¯ç€ºé²éåäœ
+always show advanced mode	workflow	zh-tw	æ°žé é¡¯ç€ºé²éæš¡åŒ
+assign me this activity	workflow	zh-tw	å°éåæŽ»åææŽŸçµŠæ
+at least one email address cannot be validated.	workflow	zh-tw	äžåä»¥äžçä¿¡ç®±ç¡æ³ééé©è­
+auto routed	workflow	zh-tw	èªåææŽŸ
+auto-release on leaving activity	common	zh-tw	åšé¢éæŽ»åæèªåéåº
+automatic	workflow	zh-tw	èªå
+autorouted activities does not need to be sent by any user after their execution	workflow	zh-tw	èªååµæž¬çæŽ»ååšä»åå·è¡åŸäžéèŠç±ä»»äœäœ¿çšè
+å¯åº
+bad parameter for setagents, the parameter should be an array	workflow	zh-tw	setAgentsçåæžé¯èª€ïŒåæžå¿
+é æ¯äžåé£å
+bad role type	workflow	zh-tw	é¯èª€çè§è²é¡å
+bad user	workflow	zh-tw	é¯èª€çäœ¿çšè
+
+base directory does not exist, please ask adminstrator to check the global configuration	common	zh-tw	äž»èŠç®éäžå­åšïŒè«è¯çµ¡ç®¡çäººå¡æ°å¢å
+šåèš­å®
+bcc:	workflow	zh-tw	å¯ä»¶å¯æ¬ïŒ
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	zh-tw	åšäºåçæŽ»åäž­è«å°å¿ïŒéäºæŽ»åå¯èœæå€åéå§èçµææéã
+being run	workflow	zh-tw	éå§å·è¡
+by running theses links you will create new instances of the related process.	workflow	zh-tw	ééå·è¡éäºé£çµïŒæšå°æå»ºç«çžéæµçšçæ°å¯ŠäŸ
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	zh-tw	ç¡æ³æ°å¢éäº€ïŒåªæåå²ææ¯åææŽ»åå¯ä»¥æè¶
+éäžåçå°å€éäº€
+cannot add transition. only split activities can have more than one outbound transition	workflow	zh-tw	ç¡æ³æ°å¢ç°åïŒåªæåå²åºäŸçæŽ»åå¯ä»¥æäžåä»¥äžçå€äŸç°å
+cannot create compiled file %1	workflow	zh-tw	ç¡æ³å»ºç«ç·šè­¯éçæªæ¡ %1
+cannot retrieve the user running the security check	workflow	zh-tw	ç¡æ³ååŸ©å·è¡å®å
+šæª¢æ¥çäœ¿çšè
+
+cannot run the activity	workflow	zh-tw	ç¡æ³å·è¡æŽ»å
+cannot run the activity without her process	workflow	zh-tw	ç¡æ³å·è¡æ²ææå®æµçšçæŽ»å
+cannot run the activity without instance	workflow	zh-tw	ç¡æ³å·è¡æ²ææå®å¯ŠäŸçæŽ»å
+cannot run unknown activity	workflow	zh-tw	ç¡æ³å·è¡äžç¥åçæŽ»å
+cc:	workflow	zh-tw	å¯æ¬ïŒ
+circular reference found some activity has a transition leading to itself	workflow	zh-tw	çŒçŸåŸªç°åç
+§ïŒéšåæŽ»åæéäº€èçæŒèªå·±æ¬èº«
+circular reference found. some activity has a transition leading to itself	workflow	zh-tw	çŒçŸåŸªç°åç
+§ïŒéšåæŽ»åæéäº€èçæŒèªå·±æ¬èº«
+cleanup aborted instances	workflow	zh-tw	æž
+é€äž­æ­¢çå¯ŠäŸ
+cleanup actions	workflow	zh-tw	æž
+é€åäœ
+close and get back later	workflow	zh-tw	ééäžæé»åç
+close printer friendly mode	workflow	zh-tw	ééåååå°æš¡åŒ
+code	workflow	zh-tw	çšåŒç¢Œ
+column activity status in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çæŽ»åæ¬äœçæ
+
+column category in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çé¡å¥æ¬äœ
+column instance id in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çå¯ŠäŸä»£ç¢Œæ¬äœ
+column instance name in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çå¯ŠäŸåçš±æ¬äœ
+column instance status in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çå¯ŠäŸçæ
+æ¬äœ
+column owner in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çææè
+æ¬äœ
+column priority in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çå±¬æ§æ¬äœ
+column process name in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çæµçšåçš±æ¬äœ
+column start date in instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­çéå§æ¥ææ¬äœ
+compilation	workflow	zh-tw	ç·šè­¯
+compiling activity %1 : %2	workflow	zh-tw	ç·šè­¯äž­æŽ»å %1 : %2
+complete	workflow	zh-tw	å®æ
+complete cleanup of aborted instances done	workflow	zh-tw	å®æŽæž
+é€äž­æ­¢çå¯ŠäŸå®æ
+complete cleanup of all instances done	workflow	zh-tw	å®æŽæž
+é€ææå¯ŠäŸå®æ
+completed	workflow	zh-tw	å®æ
+config values	common	zh-tw	èš­å®åŒ
+confirm delete	workflow	zh-tw	ç¢ºèªåªé€
+consult %1 to get the default values:	workflow	zh-tw	è©¢å %1 äŸååŸé èš­åŒïŒ
+couldn't add transition	workflow	zh-tw	ç¡æ³æ°å¢ç°å
+create	workflow	zh-tw	å»ºç«
+created	workflow	zh-tw	å·²å»ºç«
+date:	workflow	zh-tw	æ¥æïŒ
+default config values	common	zh-tw	é èš­èš­å®åŒ
+default next user	workflow	zh-tw	é èš­çäžäžåäœ¿çšè
+
+default owner	workflow	zh-tw	é èš­ææè
+
+default settings for processes	admin	zh-tw	é èš­æµçšèš­å®
+default user	workflow	zh-tw	é èš­äœ¿çšè
+
+delete selected	workflow	zh-tw	åªé€éžæç
+delete transition	workflow	zh-tw	åªé€éäº€
+deletion successful	workflow	zh-tw	åªé€æå
+delition successful	workflow	zh-tw	åªé€æå
+description	workflow	zh-tw	èªªæ
+display please wait message	common	zh-tw	é¡¯ç€ºæç€ºç­åèšæ¯
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºæŽ»åçæ
+ïŒå€§éšåæ
+æ³äžå®éœæ¯ "å·è¡äž­" ïŒäœæ¯åŠææšäœ¿çšéèªåééæ¹åŒå³èŒžïŒææéšä»œé¡¯ç€ºå®æçæ
+çæŽ»åã
+do you want the category column on instances lists, if yout instances use categories you should use it	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºé¡å¥æ¬äœïŒåŠææšçå¯Šé«æé²è¡åé¡ïŒå»ºè­°æ¡çšã
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºé¡å¥åçš±æ¬äœïŒåŠææšçå¯Šé«æé²è¡åé¡ïŒå»ºè­°æ¡çšã
+do you want the category name column on instances lists. if your instances use categories you should use this	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºé¡å¥åçš±æ¬äœïŒåŠææšçå¯Šé«æé²è¡åé¡ïŒå»ºè­°æ¡çšã
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºå¯Šé«ç·šèæ¬äœïŒæ¯åå¯Šé«ææäžåäžéè€çç·šèã
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºå¯Šé«åçš±æ¬äœïŒåŠææšæèš­å®åçš±ïŒå»ºè­°æ¡çšã
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºå¯Šé«çæ
+ïŒå¯Šé«çæ
+å¯ä»¥æ¹äŸ¿ååäž­æ­¢ãå®æãäŸå€ææŽ»åå¯Šé«ã
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºææäººæ¬äœïŒéå°æé¡¯ç€ºå¯Šéçææè
+ïŒåšéäºææè
+è¢«å®çŸ©äºç¹æ®æ¬éæéåé 
+ç®çžç¶å¯Šçšã
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºåªå
+é åºæ¬äœïŒåªå
+é åºå¯ä»¥åšæŽ»åè¡šå®äž­èš­å®ã
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	zh-tw	åšå¯Šé«æž
+å®äž­æ¯åŠèŠé¡¯ç€ºæµçšæ¬äœïŒåŠææšæäžåçæµçšäž/æçæ¬ïŒéæçžç¶å¯Šçšã
+do you want the search instance button in the last row of instances list.	workflow	zh-tw	åšå¯Šé«æž
+å®æåŸäžåæ¯åŠèŠé¡¯ç€ºæå°å¯Šé«çæéïŒ
+do you want the started date column on instances lists.	workflow	zh-tw	åšå¯Šé«æž
+å®æ¯åŠèŠé¡¯ç€ºéå§æ¥ææ¬äœïŒ
+don't move	workflow	zh-tw	äžèœç§»å
+draw roles	common	zh-tw	ç¹ªè£œè§è²
+draw roles on the graph beside activity name like [that]	admin	zh-tw	ç¹ªè£œè§è²æŒååœ¢äžïŒåšåæ¯ [that] çæŽ»ååçš±æã
+duration	workflow	zh-tw	æé
+empty agent type	workflow	zh-tw	æž
+é€ä»£çäººé¡å
+end	workflow	zh-tw	çµæ
+end activity is not reachable from start activity	workflow	zh-tw	çµææŽ»åç¡æ³åŸèµ·å§æŽ»åæŸå°
+ended	workflow	zh-tw	çµæ
+enter an activity name	workflow	zh-tw	èŒžå
+¥æŽ»ååçš±
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	zh-tw	é¯èª€ïŒ åšèªåå°åŒåææŽ»åäž­æŸäžå°ç¬Šååéžé 
+ç®çäžäžåæŽ»å
+error: non-deterministic decision for autorouting activity	workflow	zh-tw	é¯èª€ïŒ åšèªåå°åŒæŽ»åæ²æååºæ±ºå®
+error: removing was not done	workflow	zh-tw	é¯èª€ïŒ ç§»åå€±æ
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	zh-tw	é¯èª€ïŒ åè©Šå³éäžåå¯Šé«å°äžåç¡æ³å­åçæŽ»å
+error: trying to send an instance to an activity but no transition found	workflow	zh-tw	é¯èª€ïŒ åè©Šå³éäžåå¯Šé«å°äžåæŸäžå°ç§»èœçæŽ»å
+exception	workflow	zh-tw	äŸå€
+exception instance	workflow	zh-tw	äŸå€éæ®µ
+exception raised by %1 %2: %3	workflow	zh-tw	äŸå€æé«æŒ %1 %2ïŒ %3
+exception resumed by %1 %2: %3	workflow	zh-tw	äŸå€ç¹ŒçºæŒ %1 %2ïŒ %3
+exception this instance	workflow	zh-tw	æé€éåå¯Šé«
+exceptions	workflow	zh-tw	äŸå€
+execute this activity	workflow	zh-tw	å·è¡éåæŽ»å
+export	workflow	zh-tw	å¯åº
+failed to create workitem	workflow	zh-tw	å»ºç«å·¥äœé 
+ç®æçŒçé¯èª€
+failed to execute automatic activity	workflow	zh-tw	å·è¡èªåæŽ»åæçŒçé¯èª€
+failed to obtain lock on %1 table	workflow	zh-tw	åæ¶ %1 è³æè¡šéå®æçŒçé¯èª€
+failed to obtain lock on instances table	workflow	zh-tw	åšå¯Šé«è³æè¡šåæ¶éå®æçŒçé¯èª€
+failed to obtain lock on instances_activities table	workflow	zh-tw	åšå¯Šé«æŽ»åè³æè¡šåæ¶éå®æçŒçé¯èª€
+failed to record instance properties	workflow	zh-tw	èšéå¯Šé«å±¬æ§æçŒçé¯èª€
+failed to synchronize instance data with the database	workflow	zh-tw	åšè³æåº«åæ­¥å¯Šé«è³ææçŒçé¯èª€
+failure	workflow	zh-tw	é¯èª€
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	zh-tw	é¯èª€ïŒ äžäžåæŽ»åäžç¬Šåä»»äœèªåé
+çœ®çæŽ»ååææž
+å®
+fatal error: non-deterministic decision for autorouting activity	workflow	zh-tw	é¯èª€ïŒ èªåé
+çœ®æŽ»åæ²æé æçæ±ºå®
+fatal error: setting next activity to an unexisting activity	workflow	zh-tw	é¯èª€ïŒ äžäžåæŽ»åèš­å®å°äžå­åšçæŽ»åäž­
+fatal error: trying to send an instance to an activity but no transition found	workflow	zh-tw	é¯èª€ïŒ åè©Šéåºéæ®µå°æ²æç°åçæŽ»å
+filter	workflow	zh-tw	èŠå
+filter instance by id	workflow	zh-tw	ééç·šèéæ¿Ÿå¯Šé«
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	zh-tw	æåŸæšçé£çµèªæ³çº <strong>%link_XX|YY%</strong>ïŒ XXæ¯ç¶²è·¯äœåïŒ YYæ¯èªªææå­ã
+fix	workflow	zh-tw	ä¿®æ­£
+fix concistency for selected rows	workflow	zh-tw	ä¿®æ­£éžåè³æçéèŠæ§
+font size	workflow	zh-tw	å­åå€§å°
+from	workflow	zh-tw	äŸèª
+from:	workflow	zh-tw	å¯ä»¶äººïŒ
+get back to global activities	workflow	zh-tw	åå°å
+šåæŽ»å
+get back to instance creation	workflow	zh-tw	åå°å»ºç«å¯Šé«
+get property	workflow	zh-tw	ååŸå±¬æ§
+global activities	workflow	zh-tw	å
+šåæŽ»å
+global workflow preferences	workflow	zh-tw	å
+šåå·¥äœæµçšèš­å®
+go	workflow	zh-tw	ååŸ
+go to same activities for other instances of this process	workflow	zh-tw	ååŸéåæµçšå
+¶ä»å¯Šé«çåæš£æŽ»å
+go to same process activities	workflow	zh-tw	ååŸåæš£æµçšçæŽ»å
+go to the actual state of this instance	workflow	zh-tw	ååŸéåå¯Šé«çå¯Šéçæ
+
+grab instance	workflow	zh-tw	éèŠéæ®µ
+grant access to the administration and development of workflow processes and activities.	workflow	zh-tw	ååŸå·¥äœæµçšèæŽ»åçç®¡çèéçŒæ¬éã
+grant access to the administration of workflow elements	workflow	zh-tw	ååŸå·¥äœæµçšå
+ä»¶çç®¡çæ¬éã
+grant access to the administration of workflow instances in monitor screens	workflow	zh-tw	ååŸåšèšé±èŠçªäž­å·¥äœæµçšå¯Šé«çç®¡çæ¬éã
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	workflow	zh-tw	ååŸåšèšé±èŠçªäž­åçšå·¥äœæµçšçæž
+é€ãåªé€æ¬éã
+grant access to the monitoring of workflow elements	workflow	zh-tw	ååŸå·¥äœæµçšå
+ä»¶çèšé±æ¬éã
+graph	workflow	zh-tw	ååœ¢
+graphic options	common	zh-tw	ååœ¢éžé 
+
+group	workflow	zh-tw	çŸ€çµ
+id	workflow	zh-tw	ç·šè
+if automatic parsing is disabled next options will be useless	admin	zh-tw	åŠæèªååæåçšïŒäžäžåéžé 
+å°±æ²çšäº
+if not in debug mail_smtp agent would have sent this email:	workflow	zh-tw	åŠæäžæ¯åšé²è¡éµä»¶ smtp é€é¯ïŒä¿¡ä»¶æè¢«å¯å°ïŒ
+if user is in a role for an activity he will have the right to abort the related instance	admin	zh-tw	åŠæäœ¿çšè
+æ¯äžåæŽ»åäž­çè§è²ïŒä»å°±ææ¬éäž­æ­¢çžéå¯Šé«
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	zh-tw	åŠæäœ¿çšè
+æ¯äžåæŽ»åäž­çè§è²ïŒä»å°±ææ¬éæé€æç¹Œçºçžéå¯Šé«
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	zh-tw	åŠæäœ¿çšè
+æ¯äžåæŽ»åäž­çè§è²ïŒä»å°±ææ¬ééåºïŒåæ¶ææŽŸïŒçžéå¯Šé«
+if:setnextact	workflow	zh-tw	If:SetNextact
+import aborted	workflow	zh-tw	å¯å
+¥äž­æ­¢äº
+import successfull	workflow	zh-tw	å¯å
+¥æå
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	zh-tw	åšè§è²å°æè¡šäž­ïŒäœ¿çšè
+ #%1 è¢«å®çŸ©çºäžå "%2" ïŒäœä»ä¹èš±æ¯äžå "%3"
+inactive	workflow	zh-tw	åæ­¢äž­
+inst.	workflow	zh-tw	å¯ŠäŸ
+inst. status	workflow	zh-tw	å¯ŠäŸçæ
+
+instance	workflow	zh-tw	å¯ŠäŸ
+instance %1	workflow	zh-tw	å¯ŠäŸ %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	zh-tw	å¯ŠäŸ %1 ç®åèæŒ %2 çæ
+ïŒç¡æ³å·è¡ %3 åäœ
+instance %1 is in exception, action %2 is not possible.	workflow	zh-tw	å¯ŠäŸ %1 ç®åæ¯äŸå€ïŒç¡æ³å·è¡ %2 åäœ
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	zh-tw	å¯ŠäŸ %1 æ²ææ­žé¡æŒæŽ»å %2 ïŒç¡æ³å·è¡ %3 åäœ
+instance history	workflow	zh-tw	å¯ŠäŸçŽé
+instance properties	workflow	zh-tw	éæ®µå±¬æ§
+instance:	workflow	zh-tw	å¯ŠäŸïŒ
+instance: %1 (process: %2)	workflow	zh-tw	å¯ŠäŸïŒ %1 (èççšåºïŒ %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	zh-tw	å¯ŠäŸïŒ ç¡æ³ä¿®æ¹%1 [%2]ïŒæäººåšæåä¹åä¿®æ¹é
+instance: unable to modify %1, someone has changed it before us	workflow	zh-tw	å¯ŠäŸïŒ ç¡æ³ä¿®æ¹%1ïŒæäººåšæåä¹åä¿®æ¹é
+instances	workflow	zh-tw	å¯ŠäŸ
+instances selection	workflow	zh-tw	å¯ŠäŸéžæ
+int.	workflow	zh-tw	å¯ŠäŸ
+interactive	workflow	zh-tw	äºåæš¡åŒ
+interactive activities show form before being executed	workflow	zh-tw	äºåæŽ»åæåšè¢«å·è¡åé¡¯ç€ºè¡šå®
+interactive instances should not call the complete() method	workflow	zh-tw	äºåå¯ŠäŸäžæè©²äœ¿çš complete() æ¹æ³
+interactive:	workflow	zh-tw	äºåïŒ
+interactivity	workflow	zh-tw	äºåæŽ»å
+invalid	workflow	zh-tw	é¯èª€
+invalid process	workflow	zh-tw	é¯èª€çèççšåº
+invalid role name	workflow	zh-tw	é¯èª€çè§è²åçš±
+is active	workflow	zh-tw	é²è¡äž­
+it seems this activity for this instance is not assigned to you anymore.	workflow	zh-tw	éåå¯ŠäŸçæŽ»åäŒŒä¹äžåæ¯ææŽŸçµŠæšã
+it was impossible to complete, no activity was given.	workflow	zh-tw	ç¡æ³å·è¡å®æïŒæ²æéžææŽ»åã
+it was impossible to complete, no corresponding activity was found.	workflow	zh-tw	ç¡æ³å·è¡å®æïŒæ²ææŸå°ç¬ŠåçæŽ»åã
+join	workflow	zh-tw	å å
+¥
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	zh-tw	é£çµäœçœ®åŠæäžå
+å« <strong>http://</strong> å°±æè¢«èŠçºæ¬å°ç«¯ïŒä»åå°æè¢«éå èš­å®äž­çæ¬å°ç«¯åçœ®å­å
+äžŠäžç± egroupware é£çµåŒæææã
+list of activities	workflow	zh-tw	æŽ»åæž
+å®
+list of all activities with, for each,  counters of instances by status	workflow	zh-tw	ååºæææŽ»åïŒå
+å«æ¯ç­è³æçå¯ŠäŸèšæžåš
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	zh-tw	ç¶ä»åçèŠœå·¥äœæµçšçæéèæ¥ææïŒååºææç±å¯ŠäŸç¢çççŽé
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	zh-tw	ååºææå¯ŠäŸïŒå
+å«ç®åçæ
+èæŽ»åè³èšä»¥åååŸéäºå¯ŠäŸçç®¡çé£çµ
+list of instances	workflow	zh-tw	éæ®µæž
+å®
+list of mappings	workflow	zh-tw	å°ææž
+å®
+list of monitors	workflow	zh-tw	ååºèšé±
+list of processes	workflow	zh-tw	æµçšæž
+å®
+list of processes (%1)	workflow	zh-tw	æµçšæž
+å®(%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	zh-tw	æµçšæž
+å®ïŒå
+å«çæ
+ãæææ§èæ¯ç­è³æäŸæçæ
+ç¢ççå¯ŠäŸèšæžåš
+list of transitions	workflow	zh-tw	ç°åæž
+å®
+list of workitems	workflow	zh-tw	å·¥äœé 
+ç®æž
+å®
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	zh-tw	éµä»¶ç± eGroupware å·¥äœæµçšçéµä»¶å¯éçšåŒèªåéåº
+mail smtp agent	workflow	zh-tw	SMTPéµä»¶å¯éä»£çäºº
+mail smtp debug	common	zh-tw	SMTPéµä»¶å¯éåµé¯
+mail smtp local link prefix	common	zh-tw	SMTPéµä»¶æ¬å°ç«¯é£çµåçœ®å­å
+ïŒsmtpïŒ
+mail smtp profile	common	zh-tw	SMTPéµä»¶è³æ
+mail smtp signature	common	zh-tw	SMTPéµä»¶ç°œå
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	zh-tw	éµä»¶å¯ä»¥åšæŽ»åéå§æçµææå¯åºïŒäºååŒçæŽ»ååªèœå€ åšå®æåŸå¯åº
+manual	workflow	zh-tw	æå
+map	workflow	zh-tw	å°æ
+map users/groups to roles	workflow	zh-tw	å°äœ¿çšè
+/çŸ€çµå°æå°è§è²
+mapping to inexistent role	workflow	zh-tw	å°æå°äžå­åšçè§è²
+mappings deleted	workflow	zh-tw	å°æåªé€äº
+message:	workflow	zh-tw	èšæ¯ïŒ
+monitor activities	workflow	zh-tw	èšé±æŽ»å
+monitor instance	workflow	zh-tw	èšé±å¯ŠäŸ
+monitor instances	workflow	zh-tw	èšé±ç°å
+monitor processes	workflow	zh-tw	èšé±èççšåº
+monitor this instance	workflow	zh-tw	èšé±éåå¯ŠäŸ
+monitor work items	workflow	zh-tw	èšé±å·¥äœé 
+ç®
+monitor workitems	workflow	zh-tw	èšé±å·¥äœé 
+ç®
+monitoring	workflow	zh-tw	èšé±äž­
+monitors	workflow	zh-tw	èšé±
+more options?	workflow	zh-tw	æŽå€éžé 
+ïŒ
+my activities	workflow	zh-tw	æçæŽ»å
+my instances	workflow	zh-tw	æçå¯ŠäŸ
+my processes	workflow	zh-tw	æçæµçš
+name	workflow	zh-tw	åçš±
+new instance	workflow	zh-tw	æ°å¢å¯ŠäŸ
+new major	workflow	zh-tw	æ°å¢äž»èŠ
+new major version created	workflow	zh-tw	å»ºç«æ°äž»èŠçæ¬
+new mapping added	workflow	zh-tw	æ°å°æç¢ç
+new minor	workflow	zh-tw	æ°å¢æ¬¡èŠ
+new minor version created	workflow	zh-tw	å»ºç«æ°æ¬¡èŠçæ¬
+new status not set, no corresponding activity was found.	workflow	zh-tw	æ²æèš­å®æ°çæ
+ïŒæ²ææŸå°ç¬ŠåçæŽ»åã
+new transition added	workflow	zh-tw	æ°ç°åç¢ç
+next activity	workflow	zh-tw	äžäžåæŽ»å
+next user:	workflow	zh-tw	äžäžåäœ¿çšè
+ïŒ
+no action avaible because no activity and no instance are given!	workflow	zh-tw	æ²ææå®æŽ»åèå¯ŠäŸïŒå æ­€æ²æèœå€ é²è¡çåäœ
+no activites	workflow	zh-tw	æ²ææŽ»å
+no activity indicated	workflow	zh-tw	æ²æå
+å«åšä»»äœæŽ»å
+no agents associated with this activity	workflow	zh-tw	éåæŽ»åæ²ææ­žé¡æŒä»»äœä»£çäºº
+no circular transitions allowed.	workflow	zh-tw	ç¡æ³äœ¿çšåŸªç°éé
+no corresponding activity was found.	workflow	zh-tw	æŸäžå°ç¬ŠåçæŽ»åã
+no inbound for start activity	workflow	zh-tw	æ²æéå§æŽ»åçèŒžå
+¥
+no inconcistency detected	workflow	zh-tw	æ²æéèŠæ§åªé€
+no instance avaible	workflow	zh-tw	æ²æå¯ŠäŸ
+no instance given, nothing to show	workflow	zh-tw	æ²ææå®å¯ŠäŸïŒç¡æ³é¡¯ç€º
+no instance indicated	workflow	zh-tw	æ²æå
+å«ä»»äœéæ®µ
+no outbound for end activity	workflow	zh-tw	æ²æçµææŽ»åçèŒžåº
+no process indicated	workflow	zh-tw	æ²æå
+å«ä»»äœèççšåº
+no properties defined	workflow	zh-tw	æ²æå®çŸ©å±¬æ§
+no roles	workflow	zh-tw	æ²æè§è²
+no roles asociated with this activity	workflow	zh-tw	éåæŽ»åæ²æä»»äœè§è²
+no routage	workflow	zh-tw	æ²æéå§
+no scan done	workflow	zh-tw	æ²æå·è¡ææ
+no transitions allowed for standalone or view activities	workflow	zh-tw	çšç«æçèŠœæŽ»åæ²æå¯çšçéäº€
+no work item indicated	workflow	zh-tw	æ²æå
+å«ä»»äœå·¥äœé 
+ç®
+nobody	workflow	zh-tw	æ²æäºº
+not defined	workflow	zh-tw	æªå®çŸ©
+or import a process	workflow	zh-tw	ææ¯å¯å
+¥èçéçš
+owner	workflow	zh-tw	ææè
+
+owner of the instance will have the right to abort the instance at any time	admin	zh-tw	å¯ŠäŸçææè
+ææ¬éšæäž­æ­¢éåå¯ŠäŸ
+owner of the instance will have the right to exception or resume the instance at any time	admin	zh-tw	å¯ŠäŸçææè
+ææ¬éšææé€æç¹Œçºéåå¯ŠäŸ
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	zh-tw	å¯ŠäŸçææè
+ææ¬éåºïŒåæ¶ææŽŸïŒææŽŸçµŠäœ¿çšè
+çæŽ»å
+owner:	workflow	zh-tw	ææè
+ïŒ
+ownership give abort right	common	zh-tw	ææè
+æäž­æ­¢æ¬é
+ownership give exception right	common	zh-tw	ææè
+ææé€æ¬é
+ownership give release right	common	zh-tw	ææè
+æéåºæ¬é
+please wait, task in progress ...	workflow	zh-tw	è«çšåïŒä»»åèçäž­...
+post activity %1 code is not avaible	workflow	zh-tw	äžäžæŽ»å %1 ä»£ç¢Œäžå­åš
+post shared code is not avaible	workflow	zh-tw	äžäžåäº«ä»£ç¢Œäžå­åš
+post-agent %1 code is not avaible	workflow	zh-tw	äžäžä»£çäºº %1 ä»£ç¢Œäžå­åš
+pr.	workflow	zh-tw	äžäž
+pre-activity %1 code is not avaible	workflow	zh-tw	äžäžæŽ»å %1 ä»£ç¢Œäžå­åš
+pre-agent %1 code is not avaible	workflow	zh-tw	äžäžä»£çäºº %1 ä»£ç¢Œäžå­åš
+pre-shared code is not avaible	workflow	zh-tw	äžäžåäº«ä»£ç¢Œäžå­åš
+printer friendly	workflow	zh-tw	åååå°
+priority level:	workflow	zh-tw	åªå
+é åºïŒ
+process	workflow	zh-tw	èççšåº
+process %1	workflow	zh-tw	èççšåº %1
+process %1 %2 is not active, action %3 is impossible	workflow	zh-tw	æµçš %1 %2 åçšäž­ïŒç¡æ³å·è¡ %3 åäœ
+process %1 v%2 as no related activity	workflow	zh-tw	èççšåº %1 %2 æ²æçžéæŽ»å
+process %d has been activated	workflow	zh-tw	èççšåº &d é²è¡äž­
+process %d has been deactivated	workflow	zh-tw	èççšåº &d åæ­¢äž­
+process %s %s already exists, the import process was aborted	workflow	zh-tw	èççšåº %s %s å·²ç¶å­åšïŒå¯å
+¥åäœäž­æ­¢
+process %s %s imported	workflow	zh-tw	å¯å
+¥èççšåº %s %s
+process %s has been created	workflow	zh-tw	èççšåº %s å»ºç«äº
+process %s has been updated	workflow	zh-tw	èççšåº %s æŽæ°äº
+process %s removed	workflow	zh-tw	èççšåº %s ç§»é€äº
+process activities	workflow	zh-tw	èççšåºçæŽ»å
+process alone	workflow	zh-tw	çšç«èççšåº
+process does not have a start activity	workflow	zh-tw	èççšåºæ²æåå§æŽ»å
+process does not have exactly one end activity	workflow	zh-tw	èççšåºæ²æç¢ºå®ççµææŽ»å
+process form	workflow	zh-tw	èççšåºè¡šå®
+process name	workflow	zh-tw	èççšåºåçš±
+process name already exists	workflow	zh-tw	èççšåºåçš±éè€
+process roles	workflow	zh-tw	èççšåºè§è²
+process saved	workflow	zh-tw	èççšåºå²å­äº
+process transitions	workflow	zh-tw	èççšåºç°å
+process version:	workflow	zh-tw	èççšåºçæ¬ïŒ
+process:	workflow	zh-tw	èççšåºïŒ
+processes	workflow	zh-tw	èççšåº
+properties	workflow	zh-tw	å±¬æ§
+property	workflow	zh-tw	å±¬æ§
+property %1 already exists	workflow	zh-tw	å±¬æ§ %1 å·²ç¶å­åš
+property %1 not found	workflow	zh-tw	æŸäžå°å±¬æ§ %1
+quit without saving	workflow	zh-tw	é¢éäžäžå²å­
+read-only	workflow	zh-tw	å¯è®
+release access to this activity	workflow	zh-tw	éåæŽ»åçéåºæ¬é
+release activity for this instance	workflow	zh-tw	éåå¯ŠäŸçéåºæŽ»å
+release instance	workflow	zh-tw	éåºéæ®µ
+reload filter	workflow	zh-tw	éæ°è®åéæ¿ŸèŠå
+remove active instances	workflow	zh-tw	ç§»é€åçšçå¯ŠäŸ
+remove all instances for this process	workflow	zh-tw	ç§»é€éåèççšåºçææå¯ŠäŸ
+remove selected roles	workflow	zh-tw	ç§»é€éžæçè§è²
+removing instances and workitems for aborted instances on all processes	workflow	zh-tw	åšææèççšåºäž­ç§»é€äž­æ­¢å¯ŠäŸçå¯ŠäŸèå·¥äœé 
+ç®
+removing instances and workitems for aborted instances on process #%1	workflow	zh-tw	åšèççšåº #%1 äž­ç§»é€äž­æ­¢å¯ŠäŸçå¯ŠäŸèå·¥äœé 
+ç®
+removing instances and workitems for all instances on process #%1	workflow	zh-tw	åšèççšåº #%1 äž­ç§»é€ææå¯ŠäŸçå¯ŠäŸèå·¥äœé 
+ç®
+replyto:	workflow	zh-tw	åä¿¡ä¿¡ç®±ïŒ
+restart	workflow	zh-tw	éæ°éå§
+restart activity	workflow	zh-tw	éæ°éå§æŽ»å
+resume this exception instance	workflow	zh-tw	ååŸ©éåæé€çå¯ŠäŸ
+role	workflow	zh-tw	è§è²
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	zh-tw	è§è² #%1 æŒèççšåº %2 åšäœ¿çšè
+ #%4 å°æäžæäžåçèççšåº %3
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	zh-tw	è§è² #%1 (#%2) æ­žé¡æŒäžå­åšçèççšåº (#%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	zh-tw	æ­žé¡æŒäœ¿çšè
+ #%2 çè§è² %1 å°æå°äžå­åšçèççšåº (#%3)
+role %1 is not mapped	workflow	zh-tw	è§è² %1 æªå°æ
+role added to activity	workflow	zh-tw	è§è²æ°å¢å°æŽ»å
+role added to process	workflow	zh-tw	è§è²æ°å¢å°èççšåº
+role give abort right	common	zh-tw	è§è²æäž­æ­¢æ¬é
+role give exception right	common	zh-tw	è§è²ææé€æ¬é
+role give release right	common	zh-tw	è§è²æéåºæ¬é
+role in inexistent process	workflow	zh-tw	è§è²åšäžå­åšçèççšåºäž­
+role mapping in inexistent process	workflow	zh-tw	è§è²å°æå°äžå­åšçèççšåº
+role name	workflow	zh-tw	è§è²åçš±
+role not saved (maybe a name collision)	workflow	zh-tw	è§è²æªå²å­ïŒä¹èš±æ¯åçš±éè€ïŒ
+role process inconcistency in mappings	workflow	zh-tw	è§è²èçå°æäžäžèŽ
+role saved	workflow	zh-tw	è§è²å²å­äº
+roles	workflow	zh-tw	è§è²
+roles assigned to this activity	workflow	zh-tw	ææŽŸå°éåæŽ»åçè§è²
+roles deleted	workflow	zh-tw	è§è²åªé€äº
+routing	workflow	zh-tw	åé
+
+routing:	workflow	zh-tw	åé
+ïŒ
+run	workflow	zh-tw	å·è¡
+run activity	workflow	zh-tw	å·è¡æŽ»å
+run instance	workflow	zh-tw	å·è¡ç°å
+running	workflow	zh-tw	å·è¡äž­
+running activities options	common	zh-tw	å·è¡äž­æŽ»åéžé 
+
+running activity	workflow	zh-tw	å·è¡äž­æŽ»å
+scan activities	workflow	zh-tw	æææŽ»å
+scan agents	workflow	zh-tw	ææä»£çäºº
+scan instances	workflow	zh-tw	ææå¯ŠäŸ
+scan processes	workflow	zh-tw	ææèççšåº
+scan roles	workflow	zh-tw	ææè§è²
+scan transitions	workflow	zh-tw	ææèœæ
+search instance filter in the bottom of instance lists	workflow	zh-tw	åšå¯ŠäŸæž
+å®åºéšé¡¯ç€ºæå°èŠå
+search:	workflow	zh-tw	æå°ïŒ
+security check: cannot understand asked action	workflow	zh-tw	å®å
+šæª¢æ¥ïŒäžç¥åçåäœ
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	zh-tw	çèŠœå
+¶ä» <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>
+select a transition to remove	workflow	zh-tw	éžæèŠç§»é€çèœæ
+select source	workflow	zh-tw	éžæäŸæº
+send after interactive activity is completed	workflow	zh-tw	åšäºåæŽ»åå®æåŸå¯é
+send all to	workflow	zh-tw	å
+šéšéå°
+send an email	workflow	zh-tw	å¯éä¿¡ä»¶
+send instance	workflow	zh-tw	éåºå¯ŠäŸ
+send this instance to the next activity	workflow	zh-tw	å°éåå¯ŠäŸéåºå°äžåæŽ»å
+send transition	workflow	zh-tw	å¯éèœæ
+send when the activity is ending	workflow	zh-tw	åšæŽ»åçµææå¯é
+send when the activity is starting	workflow	zh-tw	åšæŽ»åéå§æå¯é
+send when wf_agent_mail_smtp['submit_send'] is posted	workflow	zh-tw	åš wf_agent_mail_smtp['submit_send'] çŒäœæå¯é
+set next act	workflow	zh-tw	èš­å®äžåæŽ»å
+set next user	workflow	zh-tw	èš­å®äžåäœ¿çšè
+
+set property	workflow	zh-tw	èš­å®å±¬æ§
+setnextuser directives can override it	workflow	zh-tw	setNextUser æèŠèå®
+setting next activity to an unexisting activity	workflow	zh-tw	èš­å®çäžåæŽ»åäžå­åš
+shared code	workflow	zh-tw	å
+±äº«çšåŒç¢Œ
+should we always give you the advanced search row on instances lists?	workflow	zh-tw	åšå¯ŠäŸæž
+å®äž­æ¯åŠæ°žé é¡¯ç€ºé²æ¥æå°è³æåïŒ
+show activity info zone	common	zh-tw	é¡¯ç€ºæŽ»åè³èšåå
+show activity title	common	zh-tw	é¡¯ç€ºæŽ»åæšé¡
+show code	workflow	zh-tw	é¡¯ç€ºçšåŒç¢Œ
+show instance name	common	zh-tw	é¡¯ç€ºå¯Šé«åçš±
+show instance owner	common	zh-tw	é¡¯ç€ºå¯Šé«ææè
+
+show multiple submit as select	common	zh-tw	é¡¯ç€ºéžåçå€åé 
+ç®
+show template	workflow	zh-tw	é¡¯ç€ºæš£æ¿
+size of the font used on the graph 12 should be a good default value	admin	zh-tw	åšååœ¢äž­äœ¿çšçæå­å€§å°ïŒé èš­åŒ 12
+smtp agent has detected some errors when sending email after completion of the activity	workflow	zh-tw	åšæŽ»åå®æåŸå¯ééµä»¶æçŒçé¯èª€
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	zh-tw	åšæŽ»åéå§æåŸå¯ééµä»¶çŒçé¯èª€
+smtp agent has detected some errors when sending email at the end of this activity	workflow	zh-tw	åšæŽ»åçµææå¯ééµä»¶çŒçé¯èª€
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	zh-tw	åšéåæŽ»åäž­æ ¹æéæ±å¯ééµä»¶æçŒçé¯èª€
+something was wrong while creating the new major version	workflow	zh-tw	å»ºç«æ°çäž»èŠçæ¬æçŒçé¯èª€
+something was wrong while creating the new minor version	workflow	zh-tw	å»ºç«æ°çæ¬¡èŠçæ¬æçŒçé¯èª€
+source code file for activity %1 is not avaible	workflow	zh-tw	æŽ»å  %1 åå§ç¢Œæªæ¡ç¡æ³äœ¿çš
+source code for activity %1 is not avaible	workflow	zh-tw	æŽ»å  %1 åå§ç¢Œç¡æ³äœ¿çš
+source saved	workflow	zh-tw	äŸæºå²å­äº
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	zh-tw	æ¬å°ç«¯äœåäœ¿çšçç¹æ®é£çµçº <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> è <strong>admininstance</strong>.
+split	workflow	zh-tw	åå²
+standalone	workflow	zh-tw	çšç«
+start	workflow	zh-tw	éå§
+start activities must be autorouted	workflow	zh-tw	éå§çæŽ»åå¿
+é æ¯èªåéé
+start activities must be interactive	workflow	zh-tw	éå§çæŽ»åå¿
+é æ¯äºååŒ
+start activity	workflow	zh-tw	éå§æŽ»å
+start process	workflow	zh-tw	éå§çšåº
+started	workflow	zh-tw	éå§äº
+started:	workflow	zh-tw	éå§ïŒ
+starting page	workflow	zh-tw	éå§é é¢
+status	workflow	zh-tw	çæ
+
+status:	workflow	zh-tw	çæ
+ïŒ
+stop	workflow	zh-tw	åæ­¢
+subject:	workflow	zh-tw	äž»æšïŒ
+switch	workflow	zh-tw	åæ
+switch construct	workflow	zh-tw	åæçµæ§
+template	workflow	zh-tw	æš£æ¿
+test concistency	workflow	zh-tw	æž¬è©ŠäžèŽæ§
+test consistency of datas in the database	workflow	zh-tw	æž¬è©Šè³æåº«çè³æäžèŽæ§
+test local installation	workflow	zh-tw	æž¬è©Šæ¬å°å®è£
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	zh-tw	è³æå€Ÿ /workflow äžå­åšäžç¡æ³å»ºç«ïŒè«è¯çµ¡ç®¡çå¡äŸæª¢æ¥å
+šåèš­å®
+the activity was not completed	workflow	zh-tw	éåæŽ»åæ²æå®æ
+the default user will only be set if he is mapped to a role on the activity	workflow	zh-tw	é èš­äœ¿çšè
+å°åªæåšå°æå°æŽ»åè§è²æè¢«èš­å®
+the following items must be corrected to be able to activate this process	workflow	zh-tw	é²è¡éåèççšåºåå¿
+é å
+ä¿®æ­£äžé¢éäºé 
+ç®
+the instance title is shown on top of the form	admin	zh-tw	å¯ŠäŸæšé¡æé¡¯ç€ºåšè¡šå®äžæ¹
+the label you want	workflow	zh-tw	èŠäœ¿çšçæšç±€
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	zh-tw	å·¥äœæµçšç¡æ³è®å SMTP èš­å®
+there are no activities available	workflow	zh-tw	ç®åæ²æä»»äœæŽ»å
+there are no config value defined	workflow	zh-tw	æ²æå®çŸ©èš­å®åŒ
+there are no instances available	workflow	zh-tw	ç®åæ²æä»»äœéæ®µ
+there are no mappings defined for this process	workflow	zh-tw	éåèççšåºç®åæ²æå®çŸ©ä»»äœå°æ
+there are no process available	workflow	zh-tw	æ²æèççšåº
+there are no processes	workflow	zh-tw	æ²æèççšåº
+there are no processes available	workflow	zh-tw	æ²æèççšåº
+there are no processes defined	workflow	zh-tw	ç®åæ²æå®çŸ©ä»»äœèççšåº
+there are no processes with the current filter	workflow	zh-tw	éåèŠåæŸäžå°ä»»äœèççšåº
+there are no properties available	workflow	zh-tw	ç®åæ²æä»»äœå±¬æ§
+there are no roles defined for this process	workflow	zh-tw	éåèççšåºç®åæ²æå®çŸ©ä»»äœè§è²
+there are no transitions defined	workflow	zh-tw	ç®åæ²æå®çŸ©ä»»äœç°å
+there are no user activites available	workflow	zh-tw	ç®åæ²æä»»äœäœ¿çšè
+æŽ»å
+there are no workitems available	workflow	zh-tw	ç®åæ²æä»»äœå·¥äœé 
+ç®
+there are some undefined preferences associated with this form : %1	workflow	zh-tw	éåè¡šå®æäžäºæªå®çŸ©çèš­å®ïŒ %1
+there is an unknown user or group #%1 in role mappings	workflow	zh-tw	åšè§è²å°ææçŒçŸæäžåæªç¥çäœ¿çšè
+æçŸ€çµ #%1
+they were problems at the compilation of the source:	workflow	zh-tw	ç·šè­¯çšåŒç¢ŒæçŒçé¯èª€ïŒ
+this activity for this instance is actually avaible for you.	workflow	zh-tw	æšå¯ä»¥äœ¿çšéåå¯ŠäŸçæŽ»å
+this activity for this instance is actually only avaible for you.	workflow	zh-tw	åªææšå¯ä»¥äœ¿çšéåå¯ŠäŸçæŽ»å
+this activity for this instance is not specifically assigned to you.	workflow	zh-tw	éåå¯ŠäŸçæŽ»åäžŠæ²æææŽŸçµŠæš
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	zh-tw	éåä»£çäººå¯ä»¥è®æŽ»åå¯é SMTP èšæ¯ïŒä¹å°±æ¯éµä»¶ïŒ
+this form will test your local workflow installation to detect potential issues	workflow	zh-tw	éåè¡šå®ææž¬è©Šæšçå·¥äœæµçšç³»çµ±äžŠäžåµæž¬å¯èœçåé¡
+this is the first screen shown when you click on the workflow application icon	workflow	zh-tw	éæ¯ç¶æšé»éžå·¥äœæµçšåç€ºæé¡¯ç€ºçç¬¬äžåç«é¢
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	zh-tw	éåèççšåºæåçèŠœæŽ»åïŒçèŠœæš¡åŒåªå
+èš±åéåçèŠœæŽ»åäž­ååŸã
+this process has no end activity	workflow	zh-tw	éåèççšåºæ²æçµææŽ»å
+this will automatically release the instance when leaving an activity without completing	admin	zh-tw	éå°æåšé¢éæªå®ææŽ»åæèªåéåºå¯ŠäŸ
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	zh-tw	éå°æé¡¯ç€ºåšæ¯åééå·¥äœæµçšåŒæå·è¡çæŽ»åè³èšäžæ¹
+to	workflow	zh-tw	æ¶ä»¶äºº
+to:	workflow	zh-tw	æ¶ä»¶äººïŒ
+transition	workflow	zh-tw	éäº€
+transition mode	workflow	zh-tw	éäº€æš¡åŒ
+transition to %1	workflow	zh-tw	éäº€çµŠ %1
+transition waiting for human interaction	workflow	zh-tw	éäº€ç­åäººåçäºå
+transitions	workflow	zh-tw	éäº€
+transitions removed successfully	workflow	zh-tw	æåç§»é€ç°å
+type	workflow	zh-tw	é¡å
+type:	workflow	zh-tw	é¡åïŒ
+unknow fix instruction :%1	workflow	zh-tw	äžç¥åçä¿®æ­£æä»€ïŒ %1
+unknown instruction from the workflow engine: %1	workflow	zh-tw	äžç¥åçæä»€äŸèªå·¥äœæµçšåŒæïŒ %1
+unknown status	workflow	zh-tw	äžç¥åççæ
+
+update	workflow	zh-tw	æŽæ°
+upload file	workflow	zh-tw	äžå³æªæ¡
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	zh-tw	äœ¿çš<a href="%1">éµä»¶ç®¡ç</a>äŸå»ºç«éµä»¶è³æ
+use automatic parsing	common	zh-tw	äœ¿çšèªåè§£æ
+use default	workflow	zh-tw	äœ¿çšé èš­åŒ
+use existing roles	workflow	zh-tw	äœ¿çšå·²ç¶å­åšçè§è²
+user	workflow	zh-tw	äœ¿çšè
+
+user #%1 is associated with a non-existent role #%2	workflow	zh-tw	äœ¿çšè
+ #%1 æ­žé¡æŒäžå­åšçè§è² #%2
+user activities	workflow	zh-tw	äœ¿çšè
+æŽ»å
+user instances	workflow	zh-tw	äœ¿çšè
+å¯ŠäŸ
+user instances form: columns	workflow	zh-tw	äœ¿çšè
+å¯ŠäŸè¡šå®ïŒ æ¬äœ
+user instances form: filters and actions	workflow	zh-tw	äœ¿çšè
+å¯ŠäŸè¡šå®ïŒ èŠåèåäœ
+user is not authorized to delete aborted instances	workflow	zh-tw	äœ¿çšè
+æ²æè¢«ææ¬äŸåªé€äž­æ­¢çå¯ŠäŸ
+user is not authorized to delete instances	workflow	zh-tw	äœ¿çšè
+æ²æè¢«ææ¬äŸåªé€å¯ŠäŸ
+user processes	workflow	zh-tw	äœ¿çšè
+èççšåº
+user/group	workflow	zh-tw	äœ¿çšè
+/çŸ€çµ
+user:	workflow	zh-tw	äœ¿çšè
+ïŒ
+users can act on activity before its execution with form and after by sending it to the next activity	workflow	zh-tw	äœ¿çšè
+å¯ä»¥åšæŽ»åå·è¡åä»¥ååšå¯éå®å°äžäžåæŽ»ååŸééè¡šå®æäœ
+users/groups	workflow	zh-tw	äœ¿çšè
+/çŸ€çµ
+valid	workflow	zh-tw	æ­£ç¢º
+valid process	workflow	zh-tw	æ­£ç¢ºèççšåº
+valid:	workflow	zh-tw	æ­£ç¢ºïŒ
+validity:	workflow	zh-tw	æææ§ïŒ
+value	workflow	zh-tw	åŒ
+version	workflow	zh-tw	çæ¬
+view details	workflow	zh-tw	çèŠœçŽ°ç¯
+view this instance	workflow	zh-tw	çèŠœéåå¯ŠäŸ
+view workitem	workflow	zh-tw	çèŠœå·¥äœé 
+ç®
+warning this filter override all others filters	workflow	zh-tw	è­ŠåïŒéåèŠåèŠèäºææçå
+¶ä»èŠå
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	zh-tw	è­ŠåïŒäœ¿çšéåæéæšå°æåšéžæççšåºäž­åªé€ææäž­æ­¢çå¯ŠäŸèä»åççŽéïŒå·¥äœé 
+ç®ïŒ
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	zh-tw	è­ŠåïŒäœ¿çšéåæéæšå°æåšéžæççšåºäž­åªé€ææçå¯ŠäŸèä»åççŽéïŒå·¥äœé 
+ç®ïŒïŒç¡è«ä»åççæ
+çºäœ
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	zh-tw	ç¡æ³å·è¡éåæŽ»åïŒä¹èš±éåå¯ŠäŸææŽ»åå·²ç¶äžå­åšäºã
+we were not able to build the message	workflow	zh-tw	ç¡æ³å»ºç«éåèšæ¯
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	zh-tw	åšé²éæš¡åŒæïŒæ¯åŠé èš­èŠé¡¯ç€ºé²éåäœïŒåèŠãæé€ãååŸç­ïŒïŒ
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	zh-tw	ç¶èœå€ äœ¿çšå€ééžå®æïŒç³»çµ±æç¹ªè£œäžåäžæéžå®ïŒå
+¶äž­åªå
+å«äžåé 
+ç®ïŒèäžæ¯å€åæé
+when to send the message:	workflow	zh-tw	å¯éèšæ¯çææ©ïŒ
+workflow	common	zh-tw	å·¥äœæµçš
+workflow configuration	admin	zh-tw	å·¥äœæµçšèš­å®
+workflow navigation	workflow	zh-tw	å·¥äœæµçšå°èŠœ
+workflow preferences	workflow	zh-tw	å·¥äœæµçšåå¥œ
+workflow site configuration	workflow	zh-tw	å·¥äœæµçšç¶²ç«èš­å®
+workflow.ui_useractivities	workflow	zh-tw	workflow.ui_useractivities
+workitem information	workflow	zh-tw	å·¥äœé 
+ç®è³èš
+workitems	workflow	zh-tw	å·¥äœé 
+ç®
+you are not allowed to abort instance %1	workflow	zh-tw	æšæ²ææ¬éäž­æ­¢å¯ŠäŸ %1
+you are not allowed to exception instance %1	workflow	zh-tw	æšæ²ææ¬éæé€å¯ŠäŸ %1
+you are not allowed to grab instance %1	workflow	zh-tw	æšæ²ææ¬éååŸå¯ŠäŸ %1
+you are not allowed to release instance %1	workflow	zh-tw	æšæ²ææ¬ééåºå¯ŠäŸ %1
+you are not allowed to restart instance %1	workflow	zh-tw	æšæ²ææ¬ééæ°éå§å¯ŠäŸ %1
+you are not allowed to resume instance %1	workflow	zh-tw	æšæ²ææ¬éååŸ©å·è¡å¯ŠäŸ %1
+you are not allowed to send instance %1	workflow	zh-tw	æšæ²ææ¬éå¯éå¯ŠäŸ %1
+you can use special values with this mail agent:	workflow	zh-tw	æšå¯ä»¥éééåéµä»¶ä»£ççšåŒäœ¿çšç¹æ®åŒïŒ
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	zh-tw	æšäžåæå·è¡éåæŽ»åçæ¬éïŒä¹èš±æ¯åæå­åé æçåé¡ïŒå¯ä»¥éæ°æŽçè³æè©Šè©Šã
+you don't have the rights necessary to exception instance %1	workflow	zh-tw	æšæ²ææé€å¯ŠäŸ %1 çå¿
+èŠæ¬é
+you have not permission to execute this activity	workflow	zh-tw	æšæ²ææ¬éå·è¡éåæŽ»å
+you were not allowed to complete the activity	workflow	zh-tw	æšæ²æå®æéåæŽ»åçæ¬é
Index: /sandbox/workflow/branches/993/setup/phpgw_eu.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_eu.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_eu.lang	(revision 795)
@@ -0,0 +1,402 @@
+%1 aborted	workflow	eu	%1 bertan behera utzita
+%1 active	workflow	eu	%1 aktibatuta
+%1 completed	workflow	eu	%1 osatuta
+%1 configuration	workflow	eu	%1en konfigurazioa
+%1 days, %2:%3:%4	workflow	eu	%1 egun, %2: %3: %4
+%1 exception	workflow	eu	%1 salbuespen
+%1 menu	workflow	eu	%1 menu
+%1 monitoring	workflow	eu	%1en monitorizazioa
+%1 processes (%2 active) (%3 being_run)	workflow	eu	%1 prozesuak (%2 aktibatuta) (%3 gauzatzen)
+abort instance	workflow	eu	bertan behera utzi instantzia
+abort this instance	workflow	eu	Bertan behera utzi instantzia hau
+aborted	workflow	eu	Bertan behera utzia
+act	workflow	eu	aktibitate
+act. status	workflow	eu	Ekintzaren egoera
+act. status:	workflow	eu	Ekintzaren egoera:
+action %1 is impossible, another user is already in place	workflow	eu	%1 ekintza ezinezkoa da, beste erabiltzaile bat dago lekuan
+action %1 needs an activity and activity %2 does not exists	workflow	eu	%1 ekintzak aktibitate bat behar du, eta %2 aktibitatea ez da existitzen
+action %1 needs an instance and instance %2 does not exists	workflow	eu	%1 ekintzak instantzia bat behar du, eta %2 instantzia ez da existitzen
+actions	workflow	eu	Ekintzak
+activate	workflow	eu	aktibatu
+active	workflow	eu	Aktibatua
+active:	workflow	eu	aktibatua:
+activities	workflow	eu	Aktibitateak
+activities selection	workflow	eu	Aktibitateen aukeraketa
+activities updated	workflow	eu	Aktibitateak eguneratu dira
+activity	workflow	eu	aktibitatea
+activity  status	workflow	eu	Aktibitatearen egoera
+activity %1	workflow	eu	%1 aktibitatea
+activity %1 code is not avaible	workflow	eu	%1 aktibitatearen kodea ez dago erabilgarri
+activity %1 is interactive but has no role assigned	workflow	eu	%1 aktibitatea interaktiboa da baina ez du rolik esleituta
+activity %1 is standalone but has transitions	workflow	eu	%1 aktibitatea independientea da baina trantsizioa du
+activity agent removed	workflow	eu	Aktibitatearen agentea ezabatua
+activity completed	workflow	eu	Aktibitate osatua
+activity failure	workflow	eu	hutsegitea aktibitatean
+activity in inexistent process	workflow	eu	Aktibitatea existitzen ez den prozesu batean
+activity name already exists	workflow	eu	Aktibitatearen izena existitzen da
+activity role removed	workflow	eu	Aktibitatearen rola ezabatua izan da
+activity saved	workflow	eu	Aktibitatea gorde da
+activity:	workflow	eu	aktibitatea:
+add a transition	workflow	eu	Trantsizioa gehitu
+add aborted instances	workflow	eu	Bertan behera utzitako instantziak gehitu
+add advanced actions	workflow	eu	Aurreratutako ekintzak gehitu
+add agent	workflow	eu	Agentea gehitu
+add completed instances	workflow	eu	Osatutako instantziak gehitu
+add instances in exception	workflow	eu	Salbuespenean dauden instantziak gehitu
+add new	workflow	eu	berria gehitu
+add new role	workflow	eu	Rol berri bat gehitu
+add or edit a process	workflow	eu	Prozesu bat editatu edo gehitu
+add or edit a role	workflow	eu	Rol bat editatu edo gehitu
+add or edit an activity	workflow	eu	Aktibitate bat editatu edo gehitu
+add property	workflow	eu	Propietatea gehitu
+add role	workflow	eu	Rola gehitu
+add role to process	workflow	eu	Prozesuari rol bat gehitu
+add transition	workflow	eu	trantsizioa gehitu
+add transitions	workflow	eu	Trantsizioak gehitu
+admin instance	workflow	eu	Instantzia kudeatu
+admin process activities	workflow	eu	Prozesuaren aktibitateak kudeatu
+admin process roles	workflow	eu	Prozesuaren rolak kudeatu
+admin processes	workflow	eu	Prozesuak kudeatu
+administer instances	admin	eu	Instantziak kudeatu
+administer processes	admin	eu	Prozesuak kudeatu
+agent without activity	workflow	eu	Agenteak ez du aktibitaterik
+agents assigned to this activity	workflow	eu	Aktibitate hau esleitu zaien agenteak
+all	workflow	eu	Guztiak
+always show advanced actions	workflow	eu	Ekintza aurreratuak beti erakutsi
+always show advanced mode	workflow	eu	Modu aurreratuak beti erakutsi
+assign me this activity	workflow	eu	Aktibitate hau niri esleitu
+automatic	workflow	eu	Automatikoa
+bad role type	workflow	eu	Rol mota ezegokia
+bad user	workflow	eu	Erabiltzaile ezegokia
+being run	workflow	eu	exekutatua izaten ari da
+cannot run the activity	workflow	eu	Aktibitatea ezin da exekutatu
+cannot run the activity without instance	workflow	eu	Instantziarik gabe ezin da aktibitatea exekutatu
+cannot run unknown activity	workflow	eu	Ezezaguna den aktibitate bat ezin da exekutatu
+cc:	workflow	eu	Cc:
+cleanup aborted instances	admin	eu	Bertan behera utzitako instantziak garbitu
+cleanup actions	workflow	eu	ekintzak garbitu
+close and get back later	workflow	eu	Itxi eta geroago itzuli
+close printer friendly mode	workflow	eu	Inprimitzera zuzendutako modua itxi
+code	workflow	eu	kodea
+compilation	workflow	eu	Konpilazio
+compiling activity %1 : %2	workflow	eu	%1 aktibitatea konpilatzen : %2
+complete	workflow	eu	Osatua
+completed	workflow	eu	osatua
+config values	common	eu	Konfigurazaio balioak
+confirm delete	workflow	eu	Berretsi Ezabatu
+consult %1 to get the default values:	workflow	eu	%1 kontsultatu lehenetsitako balioak lortzeko:
+couldn't add transition	workflow	eu	Trantsizioa ezin izan da gehitu
+create	workflow	eu	sortu
+created	workflow	eu	Sortua
+date:	workflow	eu	data:
+default config values	common	eu	Konfigurazio baloreak lehenetsiak
+default next user	workflow	eu	Hurrengo erabiltzailea lehenetsi
+default owner	workflow	eu	Jabe lehenetsia
+default settings for processes	admin	eu	Prozesuetara lehenetsitako konfigurazioa
+default user	workflow	eu	Erabiltzaile lehenetsia
+delete selected	workflow	eu	Aukeraketa ezabatu
+delete transition	workflow	eu	trantsizioa ezabatu
+deletion successful	workflow	eu	Ezabatze zuzena
+delition successful	workflow	eu	Ezabatze zuzena
+description	workflow	eu	Deskribapena
+display please wait message	common	eu	mesedez itxaron mezua bistaratu
+don't move	workflow	eu	Ez mugitu
+draw roles	common	eu	Rolak marraztu
+draw roles on the graph beside activity name like [that]	admin	eu	rol grafikoan marraztu izenaren ondoan [horrela]
+duration	workflow	eu	Iraupena
+empty agent type	workflow	eu	agente mota hustu
+end	workflow	eu	amaiera
+ended	workflow	eu	bukatua
+enter an activity name	workflow	eu	Aktibitate izen bat sartu
+error: removing was not done	workflow	eu	errorea: ez da ezabatzea egin
+exception	workflow	eu	sabulespena
+exception instance	workflow	eu	salbuespeneko instantzia
+exception raised by %1 %2: %3	workflow	eu	salbuespena %1 %2 %3 eragin du
+exception resumed by %1 %2: %3	workflow	eu	salbuespena %1 %2 %3 jarraitu du
+exception this instance	workflow	eu	Salbuespena instantzia honetan
+exceptions	workflow	eu	salbuespenak
+execute this activity	workflow	eu	Aktibitate hau exekutatu
+export	workflow	eu	Esportatu
+failed to create workitem	workflow	eu	lan elementua sortzerakoan huts egitea
+failed to execute automatic activity	workflow	eu	aktibitate automatikoa exekutatzerakoan huts egitea
+failed to obtain lock on %1 table	workflow	eu	%1 bat taulan blokeoa lortzerakoan huts egitea
+failed to obtain lock on instances table	workflow	eu	Instantzien taulan blokeoa lortzerakoan huts egitea
+failed to record instance properties	workflow	eu	huts egitea instatzearen propietateak grabatzerakoan
+failure	workflow	eu	huts egitea
+filter	workflow	eu	Iragazkia
+filter instance by id	workflow	eu	Instatzia id-tik irazi
+fix	workflow	eu	Zuzendu
+font size	workflow	eu	Letraren tamaina
+get back to global activities	workflow	eu	aktibitate orokorretara itzuli
+get back to instance creation	workflow	eu	instantziaren sorkuntzara itzuli
+get property	workflow	eu	Propietatea eskuratu
+global activities	workflow	eu	Aktibitate orokorrak
+global workflow preferences	workflow	eu	Lan fluxuen hobespen orokorrak
+go	workflow	eu	joan
+go to same process activities	workflow	eu	prozesuko aktibitate berdinetara joan
+go to the actual state of this instance	workflow	eu	instantziren momentuko egoerara joan
+grab instance	workflow	eu	instantzia hartu
+graph	workflow	eu	Grafikoa
+graphic options	common	eu	Grafikoaren aukerak
+group	workflow	eu	Taldea
+id	workflow	eu	Id
+import aborted	workflow	eu	Inportazioa abortatua
+import successfull	workflow	eu	Inportazioa zuzen egin da
+inactive	workflow	eu	Ez-aktiboa
+inst.	workflow	eu	Inst.
+inst. status	workflow	eu	Instantziaren egoera
+instance	workflow	eu	Instantzia
+instance %1	workflow	eu	%1 instantzia
+instance history	workflow	eu	Instantziaren historia
+instance properties	workflow	eu	Instantziaren propietateak
+instance:	workflow	eu	Instantzia:
+instance: %1 (process: %2)	workflow	eu	Instantzia: %1 (Prozesua: %2)
+instances	workflow	eu	Instantziak
+instances selection	workflow	eu	Instantziaren aukeraketa
+int.	workflow	eu	Int.
+interactive	workflow	eu	Interaktiboa
+interactive:	workflow	eu	Instantziak
+interactivity	workflow	eu	Interaktibitatea
+invalid	workflow	eu	ez baliozkoa
+invalid process	workflow	eu	Prozesua ez da baliozekoa
+invalid role name	workflow	eu	Rolaren izena ez da baliozkoa
+is active	workflow	eu	aktibatua dago
+list of activities	workflow	eu	Aktibitateen zerrenda
+list of instances	workflow	eu	Instantzien zerrenda
+list of mappings	workflow	eu	Mapaketen zerrenda
+list of monitors	workflow	eu	Monitoreen zerrenda
+list of processes	workflow	eu	Prozesuen zerrenda
+list of processes (%1)	workflow	eu	Prozesuen zerrenda (%1)
+list of transitions	workflow	eu	Trantsizioen zerrenda
+list of workitems	workflow	eu	Lan elementuen zerrenda
+mail smtp debug	common	eu	smtp posta araztailea
+mail smtp profile	common	eu	smpt posta perfila
+mail smtp signature	common	eu	smpt posta sinadura
+map	workflow	eu	mapa
+map users/groups to roles	workflow	eu	Erabiltzaileak mapeatu/taldeetatik roletara
+mapping to inexistent role	workflow	eu	Existitzen ez den rol bat mapeatuz
+mappings deleted	workflow	eu	Mapaketak ezbatuak
+message:	workflow	eu	Mezua:
+monitor activities	workflow	eu	Aktibitateak monitorizatu
+monitor instance	workflow	eu	instantziak monitorizatu
+monitor instances	workflow	eu	Instantziak monitorizatu
+monitor processes	workflow	eu	Prozesuak monitorizatu
+monitor this instance	workflow	eu	Instantzia hau monitorizatu
+monitor work items	workflow	eu	Lan elementuak monitorizatu
+monitor workitems	workflow	eu	Lan elementuak monitorizatu
+monitoring	admin	eu	Monitorizatu
+monitors	workflow	eu	Monitoreak
+more options?	workflow	eu	aukera gehiago?
+my activities	workflow	eu	Nire aktibitateak
+my instances	workflow	eu	Nire instantziak
+my processes	workflow	eu	Nire prozesuak
+name	workflow	eu	Izena
+new instance	workflow	eu	Instantzia berria
+new transition added	workflow	eu	Trantsizio berri bat gehitu da
+next activity	workflow	eu	hurrengo aktibitatea
+next user:	workflow	eu	Hurrengo erabiltzailea
+no activites	workflow	eu	Ez dago aktibitaterik
+no activity indicated	workflow	eu	Ez da aktibitate bat adierazi
+no agents associated with this activity	workflow	eu	Ez dago agenteik aktibitate honi elkartua
+no circular transitions allowed.	workflow	eu	Ez da trantsizio biribilik onartzen
+no corresponding activity was found.	workflow	eu	Ez da aurkitu tokatzen den aktibitaterik
+no inbound for start activity	workflow	eu	Ez dago sarrererik hasierako aktibitatearentzat
+no instance avaible	workflow	eu	Ez dago instantziarik eskuragarri
+no instance indicated	workflow	eu	Ez da instantzia bat adierazi
+no outbound for end activity	workflow	eu	Es dago irteerarik bukaerako aktibitatearentzat
+no process indicated	workflow	eu	Ez da prozesurik adierazi
+no properties defined	workflow	eu	Ez dira propietateak definitu
+no roles	workflow	eu	Ez dago rolik
+no roles asociated with this activity	workflow	eu	Ez dago rolik aktibitate honi elkartua
+no scan done	workflow	eu	Ez da arakatzerik egin
+no work item indicated	workflow	eu	Ez da lan elementurik adierazi
+nobody	workflow	eu	Inor
+not defined	workflow	eu	definitu gabe
+or import a process	workflow	eu	Edo prozesu bat inportatu
+owner	workflow	eu	Jabea
+owner:	workflow	eu	Jabea:
+ownership give abort right	common	eu	Jabea izateak abortatzeko eskubidea ematen du
+ownership give exception right	common	eu	Jabea izateak salbuespenentzeko eskubidea ematen du
+ownership give release right	common	eu	Jabea izateak askatzeko eskubidea ematen du
+please wait, task in progress ...	workflow	eu	Mesedez, itxaron egitekoa aurrerapenean...
+pr.	workflow	eu	Lehentasuna
+printer friendly	workflow	eu	Inprimitzera zuzendua
+priority level:	workflow	eu	Lehentasun maila:
+process	workflow	eu	Prozesua
+process %1	workflow	eu	%1 prozesua
+process %1 %2 is not active, action %3 is impossible	workflow	eu	%1 %2 prozesua ez dago aktibatua, %3 ekintza ez da posible
+process %1 v%2 as no related activity	workflow	eu	%1v%2 prozesuak ez du aktibitaterik lotuta
+process %d has been activated	workflow	eu	%d prozesua aktibatua izan da
+process %d has been deactivated	workflow	eu	%d prozesua desaktibatua izan da
+process %s %s imported	workflow	eu	%s %s prozesua inportatua
+process %s has been created	workflow	eu	%s prozesua sortua izan da
+process %s has been updated	workflow	eu	%s prozesua eguneratua izan da
+process %s removed	workflow	eu	%s prozesua ezabatua izan da
+process activities	workflow	eu	Aktibitateak prozesatu
+process alone	workflow	eu	Bereizita prozesatu
+process does not have a start activity	workflow	eu	Prozesuak ez hasiera aktibitate bat
+process does not have exactly one end activity	workflow	eu	Prozesuak ez du zehazki bukaera aktibitate bat
+process form	workflow	eu	Formularioa prozesatu
+process name	workflow	eu	Prozesuaren izena
+process name already exists	workflow	eu	Prozesuaren izena existitzen da
+process roles	workflow	eu	Prozesuko rolak
+process saved	workflow	eu	Prozesua gorde da
+process transitions	workflow	eu	Prozesuko trantsizioak
+process version:	workflow	eu	prozesuaren bertsioa:
+process:	workflow	eu	prozesua:
+processes	workflow	eu	Prozesuak
+properties	workflow	eu	Propietateak
+property	workflow	eu	Propietatea
+property %1 already exists	workflow	eu	%1 propietatea existitzen da
+property %1 not found	workflow	eu	%1 propietatea ez da aurkitu
+quit without saving	workflow	eu	Irten gorde gabe
+read-only	workflow	eu	irakurtzeko soilik
+release access to this activity	workflow	eu	Aktibitate honetarako sarbidea liberatu
+release activity for this instance	workflow	eu	aktibitatea instantzia honetarako liberatu
+release instance	workflow	eu	instantzia liberatu
+reload filter	workflow	eu	Iragazkia kargatu
+remove active instances	workflow	eu	Instantzia aktiboak ezabatu
+remove all instances for this process	workflow	eu	porzesu honetarako instantzia guztiak ezabatu
+remove selected roles	workflow	eu	aukeratutako rolak ezabatu
+replyto:	workflow	eu	Erantzun honi:
+restart	workflow	eu	berabiarazi
+restart activity	workflow	eu	aktibitatea berabiarazi
+resume this exception instance	workflow	eu	Salbuespenezko instantzia hau jarraitu
+role	workflow	eu	Rola
+role %1 is not mapped	workflow	eu	%1 rola ez dago mapeatuta
+role added to activity	workflow	eu	Aktibitateari rola gehitu zaio
+role added to process	workflow	eu	Prozesuari rola gehitu zaio
+role give abort right	common	eu	Rolak abortatzeko eskubidea ematen du
+role give exception right	common	eu	Rolak salbuespenetarako eskubidea ematen du
+role give release right	common	eu	Rolak askatzeko eskubidea ematen du
+role in inexistent process	workflow	eu	Rola existitzen ez den prozesu batean
+role mapping in inexistent process	workflow	eu	Rolaren mapeaketa existitzen ez den prozesu batean
+role name	workflow	eu	Rolaren izena
+role not saved (maybe a name collision)	workflow	eu	Rola ez da gorde (baliteke izenararekin talka egiten egotea)
+role saved	workflow	eu	Rola gorde da
+roles	workflow	eu	Rolak
+roles assigned to this activity	workflow	eu	Aktibitate honi esleitutako rolak
+roles deleted	workflow	eu	Rolak ezabatuta
+run	workflow	eu	exekutatu
+run activity	workflow	eu	aktibitatea exekutatu
+run instance	workflow	eu	instantzia exekutatu
+running	workflow	eu	exekutatzen
+running activities options	common	eu	Aktibitateen aukerak exekutatzen
+running activity	workflow	eu	Aktibitatea exekutatu
+scan activities	workflow	eu	Aktibitatea eskaneatu
+scan agents	workflow	eu	Agenteak eskaneatu
+scan instances	workflow	eu	Instantziak eskaneatu
+scan processes	workflow	eu	Prozesuak eskaneatu
+scan roles	workflow	eu	Rolak eskaneatu
+scan transitions	workflow	eu	Trantsizioak eskaneatu
+search:	workflow	eu	bilatu:
+select a transition to remove	workflow	eu	Trantsizio bat aukeratu ezabatzeko
+select source	workflow	eu	aukeratu iturburu-kodea
+send all to	workflow	eu	Guztiei bidali
+send an email	workflow	eu	e-posta bat bidali
+send instance	workflow	eu	instantzia bidali
+send this instance to the next activity	workflow	eu	Instantzia hau hurrengo aktibitatera bidali
+send transition	workflow	eu	trantsizioa bidali
+send when the activity is ending	workflow	eu	bidali aktibitatea bukatzeko dagoenean
+send when the activity is starting	workflow	eu	bidali aktibitatea hasteko dagoenean
+set next act	workflow	eu	Hurrengo aktibitatea ezarri
+set next user	workflow	eu	Hurrengo erabiltzailea ezarri
+set property	workflow	eu	Jabetza ezarri
+shared code	workflow	eu	Partekatutako kodea
+show activity info zone	common	eu	Aktibitatearen informazio gunea erakutsi
+show activity title	common	eu	Aktibitatearen izenburua erakutsi
+show code	workflow	eu	kodea erakutsi
+show instance name	common	eu	Instantziaren izena erakutsi
+show instance owner	common	eu	Instantziaren jabea erakutsi
+show template	workflow	eu	plantilla erakutsi
+source code file for activity %1 is not avaible	workflow	eu	%1 aktibitatearen kode-iturburuaren fitxategia ez dago erabilgarri
+source code for activity %1 is not avaible	workflow	eu	%1 aktibitatearentzeko kode iturburua ez dago erabilgarri
+source saved	workflow	eu	Jatorria gordeta
+split	workflow	eu	adarkatzea
+standalone	workflow	eu	independientea
+start	workflow	eu	Hasiera
+start activities must be interactive	workflow	eu	Hasiera aktibitateak interaktiboak izan behar dira
+start activity	workflow	eu	Hasiera aktibitatea
+start process	workflow	eu	prozesua hasi
+started	workflow	eu	Hasita
+started:	workflow	eu	Hasita:
+starting page	workflow	eu	Hasierako orria
+status	workflow	eu	Egoera
+status:	workflow	eu	egoera:
+stop	workflow	eu	gelditu
+subject:	workflow	eu	Gaia:
+template	workflow	eu	plantilla
+test concistency	workflow	eu	Koherentzia froga
+test consistency of datas in the database	workflow	eu	Koherentzia froga egin datu baseko datuetan
+test local installation	workflow	eu	Instalazio lokala frogatu
+the activity was not completed	workflow	eu	Aktibitatea ez da osatu
+the label you want	workflow	eu	nahi duzun etiketa
+there are no activities available	workflow	eu	Ez dago aktibitaterik erabilgarri
+there are no config value defined	workflow	eu	Ez dago konfigurazio balio bat definituta
+there are no instances available	workflow	eu	Ez dago instantziarik erabilgarri
+there are no mappings defined for this process	workflow	eu	Ez dago mapeaketarik definituta prozesu honetarako
+there are no process available	workflow	eu	Ez dago prozesurik erabilgarri
+there are no processes	workflow	eu	Ez dago prozesurik
+there are no processes available	workflow	eu	Ez dago prozesurik erabilgarri
+there are no processes defined	workflow	eu	Ez dago prozesurik definituta
+there are no processes with the current filter	workflow	eu	Ez dago prozesurik momentuko iragazkiarekin
+there are no properties available	workflow	eu	Ez dago propietaterik erabilgarri
+there are no roles defined for this process	workflow	eu	Ez dago rolik definituta prozesu honetarako
+there are no transitions defined	workflow	eu	Ez dago trantsiziorik definituta
+there are no user activites available	workflow	eu	Ez dago erabiltzaile aktibitaterik erabilgarri
+there are no workitems available	workflow	eu	Ez dago lan elementurik erabilgarri
+this process has no end activity	workflow	eu	prozesu honek ez du bukaera aktibitaterik
+to	workflow	eu	Nori
+to:	workflow	eu	Norentzako:
+transition	workflow	eu	trantsizioa
+transition mode	workflow	eu	trantsizio modua
+transition to %1	workflow	eu	trantsizioa %1entzat
+transition waiting for human interaction	workflow	eu	trantsizioa giza interakzioaren zain
+transitions	workflow	eu	trantsizioak
+transitions removed successfully	workflow	eu	Trantsizioak zuzen ezabatu dira
+type	workflow	eu	mota
+type:	workflow	eu	mota:
+unknow fix instruction :%1	workflow	eu	zuzenketa jarraibide ezezaguna: %1
+unknown status	workflow	eu	egoera ezezaguna
+update	workflow	eu	eguneratu
+upload file	workflow	eu	Fitxategia igo
+use automatic parsing	common	eu	ezagutze-froga automatikoa erabili
+use default	workflow	eu	Lehenetsia erabili
+use existing roles	workflow	eu	Existitzen diren rolak erabili
+user	workflow	eu	Erabiltzailea
+user activities	workflow	eu	Erabiltzaile aktibitateak
+user instances	workflow	eu	Erabiltzaile instantziak
+user instances form: columns	workflow	eu	Erabiltzaile instantzien formularioa: zutabeak
+user instances form: filters and actions	workflow	eu	Erabiltzaile instantzien formularioa: iragazkiak eta ekintzak
+user is not authorized to delete instances	workflow	eu	Erabiltzaileak ez du instantziak ezabatzeko baimenik
+user processes	workflow	eu	Erabiltzaile prozesuak
+user/group	workflow	eu	Erabiltzailea/Taldea
+user:	workflow	eu	erabiltzailea:
+users/groups	workflow	eu	Erabiltzaileak/Taldeak
+valid	workflow	eu	Baliozkoa
+valid process	workflow	eu	Bliozko prozesua
+valid:	workflow	eu	baliozkoa:
+validity:	workflow	eu	Baliagarritasuna:
+value	workflow	eu	Balioa
+version	workflow	eu	Bertsioa
+view details	workflow	eu	detaileak ikusi
+view this instance	workflow	eu	Instantzia hau ikusi
+view workitem	workflow	eu	Laneko elementua ikusi
+warning this filter override all others filters	workflow	eu	abisua: iragazki honek gainontzeko iragazkiei ezikusiarena egiten die
+we were not able to build the message	workflow	eu	Ezin izan dugu mezua eraiki
+when to send the message:	workflow	eu	Noiz bidali mezua:
+workflow	common	eu	Lan-Fluxuak
+workflow configuration	admin	eu	Lan fxuen konfigurazioa
+workflow navigation	workflow	eu	Lan flxuetatik nabigatu
+workflow preferences	workflow	eu	Lan fluxuetako hobespenak
+workitem information	workflow	eu	Lan elementuen informazioa
+workitems	workflow	eu	Lan elementuak
+you are not allowed to abort instance %1	workflow	eu	Ez duzu baimenik %1 instantzia abortatzeko
+you are not allowed to exception instance %1	workflow	eu	Ez duzu baimenik %1 salbuespeneko instantzia askatzeko
+you are not allowed to grab instance %1	workflow	eu	Ez duzu baimenik %1 instantzia hartzeko
+you are not allowed to release instance %1	workflow	eu	Ez duzu baimenik %1 instantzia askatzeko
+you are not allowed to restart instance %1	workflow	eu	Ez duzu baimenik %1 instantzia berabiarazteko
+you are not allowed to resume instance %1	workflow	eu	Ez duzu baimenik %1 instantzia jarraitzeko
+you are not allowed to send instance %1	workflow	eu	Ez duzu baimenik %1 instantzia bidaltzeko
+you have not permission to execute this activity	workflow	eu	Ez duzu baimenik aktibitate hau exekutatzeko
+you were not allowed to complete the activity	workflow	eu	Ez duzu baimenik aktibitatea osatzeko
Index: /sandbox/workflow/branches/993/setup/phpgw_nl.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_nl.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_nl.lang	(revision 795)
@@ -0,0 +1,605 @@
+#	workflow	nl	#
+%1 aborted	workflow	nl	%1 afgebroken
+%1 active	workflow	nl	%1 actief
+%1 completed	workflow	nl	%1 voltooid
+%1 configuration	workflow	nl	%1 configuratie
+%1 days, %2:%3:%4	workflow	nl	%1 dagen, %2:%3:%4
+%1 exception	workflow	nl	%1 uitzondering
+%1 menu	workflow	nl	%1 Menu
+%1 monitoring	workflow	nl	%1 Volgen
+%1 processes (%2 active) (%3 being_run)	workflow	nl	%1 processen (%2 actief) (%3 in uitvoering)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	nl	/workflow directory bestaat niet en kon niet worden aangemaakt. Vraag a.u.b. de beheerder om de globale configuratie te controleren
+<strong>%owner%</strong> is the instance owner email	workflow	nl	<strong%owner%</strong> is het emailadres van de instantie eigenaar
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	nl	<strong>%property_XX%</strong> is de inhoud van instantie-eigenschap XX
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	nl	<strong>%role_XX%</strong> zijn alle emails van alle gebruikers die gekoppeld zijn aan de rol XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	nl	<strong>%roles%</strong> zijn de emails van alle gebruikers die verbonden zijn aan willekeurig welke rol van deze activiteit
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	nl	<strong>%signature%</strong> is de agent ondertekening zoals gedefinieerd in de proces configuratie
+<strong>%user%</strong> is the instance user email	workflow	nl	<strong>%user%</strong> is de instantiegebruiker's emailadres
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	nl	<strong>%user_XX%</strong> is de email van het acount XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	nl	een "even geduld a.u.b." melding wordt getoond terwijl het formulier geladen wordt, nuttig bij lange taken
+abort instance	workflow	nl	instantie afbreken
+abort this instance	workflow	nl	Deze instantie afbreken
+aborted	workflow	nl	afgebroken
+access denied for user %1 on activity %2, no role	workflow	nl	Toegang geweiger voor gebruiker %1 op activiteit %2, geen rol
+act	workflow	nl	act
+act. status	workflow	nl	Act. status
+act. status:	workflow	nl	Act. status:
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	nl	Actie %1 is onmogelijk als we geen activiteit en geen instantie hiervoor hebben aangewezen!
+action %1 is impossible, another user is already in place	workflow	nl	Actie %1 is onmogelijk, een andere gebruiker is reeds bezig
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	nl	Actie %1 is onmogelijk, er zijn geen gebruikers toegewezen aan deze activiteit voor deze instantie
+action %1 needs an activity and activity %2 does not exists	workflow	nl	Actie %1 vereist een activiteit en activiteit %2 bestaat niet
+action %1 needs an instance and instance %2 does not exists	workflow	nl	Actie %1 veriest een instantie en instantie %2 bestaat niet
+actions	workflow	nl	Acties
+actions right options	common	nl	Acties rechts opties
+activate	workflow	nl	activeren
+active	workflow	nl	Actief
+active:	workflow	nl	actief:
+activities	workflow	nl	Activiteiten
+activities selection	workflow	nl	Activiteiten selectie
+activities updated	workflow	nl	Activiteiten bijgewerkt
+activity	workflow	nl	activiteit
+activity  status	workflow	nl	Activiteitsstatus
+activity %1	workflow	nl	activiteit %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	nl	Activiteit %1 (#%2) is geassocieerd met een nietbestaand proces (#%3)
+activity %1 code is not avaible	workflow	nl	activiteitscode %1 is niet beschikbaar
+activity %1 is interactive but has no role assigned	workflow	nl	Activiteit %1 is interactief maar heeft geen rol toegewezen
+activity %1 is interactive so it must use the $instance->complete() method	workflow	nl	Activiteit %1 is interactief en moet daarom de $instance->complete() methode gebruiken
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	nl	Activiteit %1 is niet-interactief en niet-zelfrouterend maar heeft geen rol toegewezen
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	nl	Activiteit %1 is niet-interactief en mag daarom de $instance->complete() methode niet gebruiken
+activity %1 is standalone and is using the $instance object	workflow	nl	Activiteit %1 is alleenstaand en gebruikt het $instance object
+activity %1 is standalone but has transitions	workflow	nl	Activiteit %1 is alleenstaand maar heeft transities
+activity %1 is standalone or view but has transitions	workflow	nl	Activiteit %1 is alleenstaand of een presentatie maar heeft transities
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	nl	Activiteit %1 is een schakelpunt en moet daarom de $instance->setNextActivity($actname) methode gebruiken
+activity %1 is view and is using the $instance object in write mode	workflow	nl	Activiteit %1 is een presentatie en gebruikt het $instance object in schrijfmodus
+activity agent removed	workflow	nl	Activiteitsagent verwijderd
+activity completed	workflow	nl	Activiteit voltooid
+activity failure	workflow	nl	activiteit mislukt
+activity in inexistent process	workflow	nl	Activiteit in nietbestaand proces
+activity is waiting for pending transitions	workflow	nl	activiteit wacht op lopende transities
+activity name already exists	workflow	nl	Activiteitsnaam bestaat reeds
+activity role #%1 removed	workflow	nl	Activiteitsrol #%1 verwijderd
+activity role removed	workflow	nl	Activiteitsrol verwijderd
+activity saved	workflow	nl	Activiteit opgeslagen
+activity start not avaible, no corresponding activity was found.	workflow	nl	activiteitsbeginpunt niet beschikbaar, geen overeenkomende activiteit gevonden.
+activity start not set, no corresponding activity was found.	workflow	nl	activiteitsstartpunt is niet ingesteld, geen overeenkomende activiteit gevonden.
+activity status not avaible, no corresponding activity was found.	workflow	nl	activiteitsstatus is niet beschikbaar, geen overeenkomende activiteit gevonden.
+activity:	workflow	nl	activiteit:
+add a transition	workflow	nl	Transitie toevoegen
+add aborted instances	workflow	nl	Afgebroken instanties toevoegen
+add advanced actions	workflow	nl	Geavanceerde instanties toevoegen
+add agent	workflow	nl	Agent toevoegen
+add completed instances	workflow	nl	Voltooide instanties toegevoegen
+add instances in exception	workflow	nl	Instanties in uitzonder toevoegen
+add new	workflow	nl	nieuwse toevoegen
+add new role	workflow	nl	Nieuwe rol toevoegen
+add or edit a process	workflow	nl	Een proces toevoegen of bewerken
+add or edit a role	workflow	nl	Een rol toevoegen of bewerken
+add or edit an activity	workflow	nl	Een activiteit toevoegen of bewerken
+add property	workflow	nl	Eigenschap toevoegen
+add role	workflow	nl	Rol toevoegen
+add role to process	workflow	nl	Rol aan proces toevoegen
+add transition	workflow	nl	transitie toevoegen
+add transitions	workflow	nl	Transities toevoegen
+add transitions from	workflow	nl	Transities toevoegen van
+add transitions to	workflow	nl	Transities toevoegen aan
+admin instance	workflow	nl	Beheerder instantie
+admin process activities	workflow	nl	Beheerder procesactiviteiten
+admin process roles	workflow	nl	Beheerder procesrollen
+admin processes	workflow	nl	Beheerder processen
+admin processes sources	workflow	nl	Beheerder processen bronnen
+administer instances	admin	nl	beheer instanties
+administer processes	admin	nl	beheer processen
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	nl	Agent #%1 van type %2 is geassocieerd met een nietbestaande activiteti #%3
+agent #%1 of type %2 is not linked with an activity	workflow	nl	Agent #%1 van type %2 is niet gekoppeld aan een activiteit
+agent associated with inexistent activity	workflow	nl	Agent geassocieerd met een nietbestaande activiteit
+agent without activity	workflow	nl	Agent zonder activiteit
+agents assigned to this activity	workflow	nl	Agenten die aan deze activiteit zijn toegewezen
+all	workflow	nl	Alle
+always show advanced actions	workflow	nl	Altijd de geavanceerde acties weergeven
+always show advanced mode	workflow	nl	Altijd de geavanceerde modus weergeven
+assign me this activity	workflow	nl	Wijs mij deze activiteit toe
+at least one email address cannot be validated.	workflow	nl	minstens één emailadres kon niet gevalideerd worden.
+auto routed	workflow	nl	Automatisch gerouteerd
+auto-release on leaving activity	common	nl	automatisch vrijgeven als de activiteit verlaten wordt
+automatic	workflow	nl	Automatisch
+autorouted activities does not need to be sent by any user after their execution	workflow	nl	Automatisch gerouteerde activiteiten hoeven niet door een gebruiker verzonden te worden nadat ze zijn uitgevoerd
+bad parameter for setagents, the parameter should be an array	workflow	nl	verkeerde parameter voor setAgents, de parameter moet een array zijn
+bad role type	workflow	nl	Verkeerd roltype
+bad user	workflow	nl	Verkeerde gebruiker
+base directory does not exist, please ask adminstrator to check the global configuration	common	nl	Basisdirectory bestaat niet, vraag a.u.b. de beheerder om de globale configuratie te controleren
+bcc:	workflow	nl	BCC:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	nl	Wees voorzichtig met de interactieve activiteit, eind en begin van deze activiteiten zijn meervoudig.
+being run	workflow	nl	wordt uitgevoerd
+by running theses links you will create new instances of the related process.	workflow	nl	door het uitvoeren van deze links maakt u nieuwe instanties van het gerelateerde proces aan.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	nl	Kan transitie niet toevoegen, alleen splitsende of schakelende activiteiten kunnen meer dan één uitgaande transitie hebben
+cannot add transition. only split activities can have more than one outbound transition	workflow	nl	Kan transitie niet toevoegen. Alleen splitsende activiteiten kunnen meer dan één uitgaande transitie hebben
+cannot create compiled file %1	workflow	nl	kan het gecompileerde bestand %1 niet aanmaken
+cannot retrieve the user running the security check	workflow	nl	Kan de gebruiker voor de beveiligingscontrole niet ophalen
+cannot run the activity	workflow	nl	Kan de activiteit niet uitvoeren
+cannot run the activity without her process	workflow	nl	Kan de activiteit niet uitvoeren zonder haar proces
+cannot run the activity without instance	workflow	nl	Kan de activiteit niet uitvoeren zonder instantie
+cannot run unknown activity	workflow	nl	Kan onbekende activiteit niet uitvoeren
+cc:	workflow	nl	CC:
+circular reference found some activity has a transition leading to itself	workflow	nl	Circulaire referentie gevonden, een activiteit heeft een transitie die naar zichzelf verwijst
+circular reference found. some activity has a transition leading to itself	workflow	nl	Circulaire referentie gevonden. Een activiteit heeft een transitie die naar zichzelf verwijst
+cleanup aborted instances	admin	nl	afgebroken instanties opruimen
+cleanup actions	workflow	nl	acties opruimen
+close and get back later	workflow	nl	Sluit af en kom later terug
+close printer friendly mode	workflow	nl	Printervriendelijke modus sluiten
+code	workflow	nl	code
+column activity status in instance lists	workflow	nl	Kolom activiteitsstatus in instantie lijsten
+column category in instance lists	workflow	nl	Kolom categorie in instantie lijsten
+column instance id in instance lists	workflow	nl	Kolom instantie ID in instantie lijsten
+column instance name in instance lists	workflow	nl	Kolom instantie naam in instantie lijsten
+column instance status in instance lists	workflow	nl	Kolom instantie status in instantie lijsten
+column owner in instance lists	workflow	nl	Kolom eigenaar in instantie lijsten
+column priority in instance lists	workflow	nl	Kolom prioriteit in instantie lijsten
+column process name in instance lists	workflow	nl	Kolom procesnaam in instantie lijsten
+column start date in instance lists	workflow	nl	Kolom startdatum in instantie lijsten
+compilation	workflow	nl	Compilatie
+compiling activity %1 : %2	workflow	nl	compileert activiteit %1 : %2
+complete	workflow	nl	Voltooid
+complete cleanup of aborted instances done	workflow	nl	volledige opruiming van afgebroken instanties voltooid
+complete cleanup of all instances done	workflow	nl	volledige opruiming van alle instanties voltooid
+completed	workflow	nl	voltooid
+config values	common	nl	Configuratie waardes
+confirm delete	workflow	nl	Bevest verwijdering
+consult %1 to get the default values:	workflow	nl	Raadpleeg %1 voor de standaard waardes:
+couldn't add transition	workflow	nl	Kon transitie niet toevoegen
+create	workflow	nl	aanmaken
+created	workflow	nl	Aangemaakt
+date:	workflow	nl	datum:
+default config values	common	nl	Standaard configuratie waardes:
+default next user	workflow	nl	Standaard volgende gebruiker
+default owner	workflow	nl	Standaard eigenaar
+default settings for processes	admin	nl	Standaard instellingen voor processen
+default user	workflow	nl	Standaard gebruiker
+delete selected	workflow	nl	Verwijder geselecteerde
+delete transition	workflow	nl	verwijder transitie
+deletion successful	workflow	nl	Verwijdering succesvol
+delition successful	workflow	nl	Verwijdering succesvol
+description	workflow	nl	Beschrijving
+display please wait message	common	nl	toon het even geduld bericht
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	nl	Wilt u de activiteitsstatus op instanties lijsten weergeven? Meestal is dit 'lopend' maar indien u nietzelfrouterende transities gebruik zult u enkele voltooide activiteiten hebben.
+do you want the category column on instances lists, if yout instances use categories you should use it	workflow	nl	Wilt u de categorie kolom op instanties lijsten weergeven? Indien uw instanties categorieën gebruiken zou u dit moeten inschakelen
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	nl	Wilt u de categorienaam kolom op instanties lijsten weergeven? Indien uw instanties categorieën gebruiken zou u dit moeten inschakelen
+do you want the category name column on instances lists. if your instances use categories you should use this	workflow	nl	Wilt u de categorienaam kolom op instanties lijsten weergeven? Indien uw instanties categorieën gebruiken zou u dit moeten inschakelen
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	nl	Wilt u de instantie ID kolom op instanties lijsten weergeven? Dit is de unieke identifier van een instantie
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	nl	Wilt u de instantienaam kolom op instanties lijsten weergeven? Indien uw instanties namen gebruiken zou u dit zeker moeten doen.
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	nl	Wilt u de instantiestatus kolom op instanties lijsten weergeven? De instantiestatus is nuttig om onderscheid te maken tussen afgebroken, voltooid, uitzondering of actieve instanties
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	nl	Wilt u de eigenaar kolom op instanties lijsten weergeven? Dit toont u de werkelijke eigenaar, bijzonder handig indien eigendommen met speciale rechten zijn gedefinieerd
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	nl	Wilt u de prioriteiten kolom op instanties lijsten weergeven? Prioriteit kan worden ingesteld in het activiteitenformulier
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	nl	Wilt u de proces kolom op instantieslijsten weergeven? Nuttig indien u verschillende processen en/of versies van deze processen heeft
+do you want the search instance button in the last row of instances list.	workflow	nl	Wilt u de zoekinstantieknop in de laatste rij van de instanties lijst weergeven?
+do you want the started date column on instances lists.	workflow	nl	Wilt u de startdatum kolom op instanties lijsten weergeven?
+don't move	workflow	nl	Niet verplaatsen
+draw roles	common	nl	teken rollen
+draw roles on the graph beside activity name like [that]	admin	nl	teken rollen op de grafiek naast activiteitsnaam zoals [dit]
+duration	workflow	nl	Duur
+empty agent type	workflow	nl	leeg agent type
+end	workflow	nl	einde
+end activity is not reachable from start activity	workflow	nl	Eind activiteit is niet bereikbaar vanaf de start activiteit
+ended	workflow	nl	geeindigd
+enter an activity name	workflow	nl	Vul een activiteitnaam in
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	nl	Fout: nextActivity komt niet overeen met enige kandidaat in de zelfrouterende schakel activiteit
+error: non-deterministic decision for autorouting activity	workflow	nl	Fout: onbepaalde beslissing voor zelfrouterende activiteit
+error: removing was not done	workflow	nl	fout: verwijdering is niet uitgevoerd
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	nl	Fout: geprobeerd een instantie naar een activiteit te verzenden maar het was onmogelijk om de activiteit op te halen
+error: trying to send an instance to an activity but no transition found	workflow	nl	Fout: probeerde een instantie naar een activiteit te sturen maar er is geen transitie gevonden
+exception	workflow	nl	uitzondering
+exception instance	workflow	nl	uitzondering instantie
+exception raised by %1 %2: %3	workflow	nl	uitzondering opgetreden bij %1 %2: %3
+exception resumed by %1 %2: %3	workflow	nl	uitzondering is hervat door %1 %2: %3
+exception this instance	workflow	nl	Uitzondering deze instantie
+exceptions	workflow	nl	uitzonderingen
+execute this activity	workflow	nl	Deze activiteit uitvoeren
+export	workflow	nl	Exporteren
+failed to create workitem	workflow	nl	aanmaken van werkonderdeel is mislukt
+failed to execute automatic activity	workflow	nl	uitvoeren van automatische activiteit is mislukt
+failed to obtain lock on %1 table	workflow	nl	het verkrijgen van een lock op %1 tabel is mislukt
+failed to obtain lock on instances table	workflow	nl	het verkrijgen van een lock op de instanties tabel is mislukt
+failed to obtain lock on instances_activities table	workflow	nl	het verkrijgen van een lock op de instanties-activiteiten tabel is mislukt
+failed to record instance properties	workflow	nl	het vastleggen van instantie eigenschappen is mislukt
+failed to synchronize instance data with the database	workflow	nl	het synchroniseren van instantie data met de database is mislukt
+failure	workflow	nl	fout
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	nl	Fatale fout: netxActivity komt niet overeen met enige kandidaat in zelfrouterende schakel activiteit
+fatal error: non-deterministic decision for autorouting activity	workflow	nl	Fatale fout: onbepaalde beslissing voor zelfrouterende activiteit
+fatal error: setting next activity to an unexisting activity	workflow	nl	Fatale fout: volgende activiteit instellen op een nietbestaande activiteit
+fatal error: trying to send an instance to an activity but no transition found	workflow	nl	Fatale fout: probeerde een instantie naar een activiteit te sturen maar er is geen transitie gevonden
+filter	workflow	nl	Filter
+filter instance by id	workflow	nl	filter instantie op ID
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	nl	tenslotten heeft u links met <strong>%link_XX|YY%</strong> syntax, XX is het adres deel, YY het tekst deel.
+fix	workflow	nl	Herstel
+fix concistency for selected rows	workflow	nl	Herstel consistentie voor de geselecteerde rijen
+font size	workflow	nl	lettergrootte
+from	workflow	nl	Van
+from:	workflow	nl	Van:
+get back to global activities	workflow	nl	ga terug naar globale activiteiten
+get back to instance creation	workflow	nl	ga terug naar instantie aanmaak
+get property	workflow	nl	Verkrijg eigenschap
+global activities	workflow	nl	Globale activiteiten
+global workflow preferences	workflow	nl	Globale werkstroomvoorkeuren
+go	workflow	nl	ga
+go to same activities for other instances of this process	workflow	nl	ga naar dezelfde activiteiten voor andere instanties van dit proces
+go to same process activities	workflow	nl	ga naar dezelfde procesactiviteiten
+go to the actual state of this instance	workflow	nl	ga naar de werkelijke staat van deze instantie
+grab instance	workflow	nl	grijp instantie
+grant access to the administration and development of workflow processes and activities.	admin	nl	Verleen toegang aan beheer en ontwikkeling van werkstroomprocessen en activiteiten.
+grant access to the administration of workflow elements	admin	nl	Verleen toegang aan de beheerder van werkstroomelementen.
+grant access to the administration of workflow instances in monitor screens	admin	nl	Verleen toegang aan de beheerder van werkstroominstanties in monitor pagina's.
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	admin	nl	Verleeg toegang aan het opruimen/verwijderen van afgebroken werkstroom instanties in monitor pagina's
+grant access to the monitoring of workflow elements	admin	nl	Verleen toegang tot het monitoren van werkstroomelementen
+graph	workflow	nl	Grafiek
+graphic options	common	nl	Grafiek opties
+group	workflow	nl	Groep
+id	workflow	nl	ID
+if automatic parsing is disabled next options will be useless	admin	nl	indien automatisch parsen uitgeschakeld is zijn de volgende opties onbruikbaar
+if not in debug mail_smtp agent would have sent this email:	workflow	nl	indien je niet in debug modus was zou de mail_smtp agent deze email verzonden hebben:
+if user is in a role for an activity he will have the right to abort the related instance	admin	nl	indien gebruiker een rol bij een activiteit heeft, zal hij de rechten hebben om de gerelateerd instantie af te breken
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	nl	indien gebruiker een rol heeft in een activiteit, zal hij de rechten hebben om de gerelateerd instantie in een uitzondering te laten lopen of te laten doorgaan
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	nl	indien gebruiker een rol heeft in een activiteit, dan heeft hij ook het recht om de gerelateerde instantie vrij te geven (un-assign)
+if:setnextact	workflow	nl	If:SetNextact
+import aborted	workflow	nl	Importeren afgebroken
+import successfull	workflow	nl	Importeren met succes voltooid
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	nl	In de rol mapping is gebruiker #%1 gespecificeerd als een "%2" maar is MISSCHIEN een "%3"
+inactive	workflow	nl	Inactief
+inst.	workflow	nl	Instantie
+inst. status	workflow	nl	Instantiestatus
+instance	workflow	nl	Instantie
+instance %1	workflow	nl	instantie %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	nl	Instantie %1 is in %2 staat, actie %3 is onmogelijk.
+instance %1 is in exception, action %2 is not possible.	workflow	nl	Instantie %1 is in uitzondering, actie %2 is niet mogelijk.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	nl	Instantie %1 is niet geassocieerd met activiteit %2, actie %3 is onmogelijk.
+instance history	workflow	nl	Instantie historie
+instance properties	workflow	nl	Instantie eigenschappen
+instance:	workflow	nl	instantie:
+instance: %1 (process: %2)	workflow	nl	Instantie: %1 (Proces: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	nl	Instantie: onmogelijk om %1 [%2] te wijzigen, iemand heeft het vlak voor ons gewijzigd
+instance: unable to modify %1, someone has changed it before us	workflow	nl	Instantie: onmogelijk om %1 te wijzigen, iemand heeft het vlak voor ons gewijzigd
+instances	workflow	nl	Instanties
+instances selection	workflow	nl	Instanties selectie
+int.	workflow	nl	Int.
+interactive	workflow	nl	Interactief
+interactive activities show form before being executed	workflow	nl	Interactieve activiteiten tonen het formulier voordat ze worden uitgevoerd
+interactive instances should not call the complete() method	workflow	nl	interactieve instanties zouden de complete() methode niet moeten aanroepen
+interactive:	workflow	nl	interactief:
+interactivity	workflow	nl	Interactiviteit
+invalid	workflow	nl	ongeldig
+invalid process	workflow	nl	Ongeldig proces
+invalid role name	workflow	nl	Ongeldige rolnaam
+is active	workflow	nl	is actief
+it seems this activity for this instance is not assigned to you anymore.	workflow	nl	Het lijkt erop dat deze activiteit voor deze instantie niet langer aan u is toegewezen.
+it was impossible to complete, no activity was given.	workflow	nl	het was onmogelijk om dit te voltooien, er werd geen activiteit opgegeven.
+it was impossible to complete, no corresponding activity was found.	workflow	nl	het was onmogelijk om dit te voltooien, er werd geen overeenkomstige activiteit gevonden.
+join	workflow	nl	neem deel aan
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	nl	Link adressen worden geacht lokaal te zijn als ze niet <strong>http://</strong> bevatten. Ze zullen de ingestelde lokale prefix toegevoegd krijgen en door de eGroupWare linkmachine gescand worden.
+list of activities	workflow	nl	Lijst van activiteiten
+list of all activities with, for each,  counters of instances by status	workflow	nl	lijst van alle activiteiten met, voor elk, aantallen van de instanties per status
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	nl	lijst van alle historische items die zijn aangemaakt door instantie terwijl ze zich in de werkstroom bewegen met informatie over duur en datum
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	nl	lijst van alle instanties met informatie over de huidige status en activiteiten en een link naar het beheer van deze instanties
+list of instances	workflow	nl	Lijst van instanties
+list of mappings	workflow	nl	Lijst van mappings
+list of monitors	workflow	nl	Lijst van monitors
+list of processes	workflow	nl	Lijst van processen
+list of processes (%1)	workflow	nl	Lijst van processen (%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	nl	lijst van processen met status en geldigheid en, voor elk, aantal van instanties per status
+list of transitions	workflow	nl	Lijst van transities
+list of workitems	workflow	nl	Lijst van werkonderdelen
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	nl	Mail automatisch verzonden door de Mail SMTP Agent voor eGroupWare's werkstroom
+mail smtp agent	workflow	nl	Mail SMTP Agent
+mail smtp debug	common	nl	Mail SMTP debug
+mail smtp local link prefix	common	nl	Mail SMTP lokale link prefix
+mail smtp profile	common	nl	Mail SMTP profiel
+mail smtp signature	common	nl	Mail SMTP ondertekening
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	nl	Mails kunnen worden verzonden aan het begin of aan het einde van een activiteit. Voor interactieve instanties kan er alleen aan het eind verzonden worden.
+manual	workflow	nl	Handboek
+map	workflow	nl	map
+map users/groups to roles	workflow	nl	Koppel gebruikers/groepen aan rollen
+mapping to inexistent role	workflow	nl	Koppeling aan nietbestaande rol
+mappings deleted	workflow	nl	Koppelingen verwijderd
+message:	workflow	nl	Bericht:
+monitor activities	workflow	nl	Activiteiten monitoren
+monitor instance	workflow	nl	monitor instantie
+monitor instances	workflow	nl	Instanties monitoren
+monitor processes	workflow	nl	Processen monitoren
+monitor this instance	workflow	nl	Deze instantie monitoren
+monitor work items	workflow	nl	Werkonderdelen monitoren
+monitor workitems	workflow	nl	Werkonderdelen monitoren
+monitoring	admin	nl	aan het monitoren
+monitors	workflow	nl	Monitors
+more options?	workflow	nl	meer opties?
+my activities	workflow	nl	Mijn activiteiten
+my instances	workflow	nl	Mijn instanties
+my processes	workflow	nl	Mijn processen
+name	workflow	nl	Naam
+new instance	workflow	nl	Nieuwe instantie
+new major	workflow	nl	Nieuwe majeure
+new major version created	workflow	nl	nieuwe majeure versie aangemaakt
+new mapping added	workflow	nl	Nieuwe koppeling toegevoegd
+new minor	workflow	nl	Nieuwe mineure
+new minor version created	workflow	nl	Nieuwe minuere versie aangemaakt
+new status not set, no corresponding activity was found.	workflow	nl	nieuwe status is niet ingesteld, geen overeenkomstige activiteit gevonden.
+new transition added	workflow	nl	Nieuwe transitie toegevoegd
+next activity	workflow	nl	volgende activiteit
+next user:	workflow	nl	Volgende gebruiker:
+no action avaible because no activity and no instance are given!	workflow	nl	geen actie beschikbaar omdat er geen activiteit en geen instantie zijn opgegeven!
+no activites	workflow	nl	Geen activiteiten
+no activity indicated	workflow	nl	Geen activiteit aangegeven
+no agents associated with this activity	workflow	nl	Er zijn geen agenten met deze activiteit geassocieerd
+no circular transitions allowed.	workflow	nl	Circulaire transities zijn niet toegestaan.
+no corresponding activity was found.	workflow	nl	geen overeenkomstige activiteit gevonden.
+no inbound for start activity	workflow	nl	Geen ingang voor de start activiteit
+no inconcistency detected	workflow	nl	geen inconsistentie gevonden
+no instance avaible	workflow	nl	geen instantie beschikbaar
+no instance given, nothing to show	workflow	nl	geen instantie opgegeven, niets weer te geven
+no instance indicated	workflow	nl	Geen instantie opgegeven
+no outbound for end activity	workflow	nl	Geen uitgang voor de eind activiteit
+no process indicated	workflow	nl	Geen proces opgegeven
+no properties defined	workflow	nl	Geen eigenschappen gedefinieerd
+no roles	workflow	nl	geen rollen
+no roles asociated with this activity	workflow	nl	Er zijn geen rollen geassocieerd met deze activiteit
+no routage	workflow	nl	geen routering
+no scan done	workflow	nl	geen scan gedaan
+no transitions allowed for standalone or view activities	workflow	nl	Geen transities toegestaan voor zelfstandige of weergave activiteiten
+no work item indicated	workflow	nl	Geen werkitem aangegeven
+nobody	workflow	nl	Niemand
+not defined	workflow	nl	niet gedefinieerd
+or import a process	workflow	nl	Of importeer een proces
+owner	workflow	nl	Eigenaar
+owner of the instance will have the right to abort the instance at any time	admin	nl	eigenaar van de instantie heeft het recht de instantie op ieder gewenst tijdstip af te breken
+owner of the instance will have the right to exception or resume the instance at any time	admin	nl	eigenaar van de instantie heeft het recht om de instantie op ieder tijdstip in een uitzondering te laten lopen of om hem door te laten gaan
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	nl	eigenaar van de instantie heef het recht om op ieder tijdstip een aan een gebruiker toegewezen activiteit vrij te geven (un-assign)
+owner:	workflow	nl	Eigenaar:
+ownership give abort right	common	nl	eigenaarschap geeft afbreek rechten
+ownership give exception right	common	nl	eigenaarschap geeft uitzondering rechten
+ownership give release right	common	nl	eigenaarschap geeft vrijgave rechten
+please wait, task in progress ...	workflow	nl	Even wachten, taak wordt uitgevoerd ...
+post activity %1 code is not avaible	workflow	nl	na-activiteit %1 code is niet beschikbaar
+post shared code is not avaible	workflow	nl	na-gedeelde code is niet beschikbaar
+post-agent %1 code is not avaible	workflow	nl	na-agent %1 code is niet beschikbaar
+pr.	workflow	nl	Pr.
+pre-activity %1 code is not avaible	workflow	nl	pre-activiteit %1 code is niet beschikbaar
+pre-agent %1 code is not avaible	workflow	nl	pre-agent %1 code is niet beschikbaar
+pre-shared code is not avaible	workflow	nl	pre-gedeelde code is niet beschikbaar
+printer friendly	workflow	nl	Printervriendelijk
+priority level:	workflow	nl	Prioriteitsniveau:
+process	workflow	nl	Proces
+process %1	workflow	nl	proces %1
+process %1 %2 is not active, action %3 is impossible	workflow	nl	Proces %1 %2 is niet actief, actie %3 is onmogelijk
+process %1 v%2 as no related activity	workflow	nl	Proces %1 v%2 heeft geen gerelateerde activiteit
+process %d has been activated	workflow	nl	Proces %d is geactiveerd
+process %d has been deactivated	workflow	nl	Proces %d is gedeactiveerd
+process %s %s already exists, the import process was aborted	workflow	nl	Proces %s %s bestaat reeds, het importproces is afgebroken
+process %s %s imported	workflow	nl	Proces %s %s geimporteerd
+process %s has been created	workflow	nl	Proces %s is aangemaakt
+process %s has been updated	workflow	nl	Proces %s is bijgewerkt
+process %s removed	workflow	nl	Proces %s is verwijderd
+process activities	workflow	nl	Proces activiteiten
+process alone	workflow	nl	Proces alleen
+process does not have a start activity	workflow	nl	Proces heeft geen startactiviteit
+process does not have exactly one end activity	workflow	nl	Proces heeft niet precies één eind activiteit
+process form	workflow	nl	Procesformulier
+process name	workflow	nl	Procesnaam
+process name already exists	workflow	nl	Procesnaam bestaat reeds
+process roles	workflow	nl	Procesrollen
+process saved	workflow	nl	Proces opgeslagen
+process transitions	workflow	nl	Proces transities
+process version:	workflow	nl	proces versie:
+process:	workflow	nl	proces:
+processes	workflow	nl	Processen
+properties	workflow	nl	Eigenschappen
+property	workflow	nl	Eigenschap
+property %1 already exists	workflow	nl	Eigenschap %1 bestaat reeds
+property %1 not found	workflow	nl	eigenschap %1 niet gevonden
+quit without saving	workflow	nl	Einde zonder opslaan
+read-only	workflow	nl	alleen-lezen
+release access to this activity	workflow	nl	Toegang tot deze activiteit vrijgeven
+release activity for this instance	workflow	nl	activiteit voor deze instantie vrijgeven
+release instance	workflow	nl	instantie vrijgeven
+reload filter	workflow	nl	Filter herladen
+remove active instances	workflow	nl	Actieve instanties verwijderen
+remove all instances for this process	workflow	nl	verwijder alle instanties voor dit proces
+remove selected roles	workflow	nl	geselecteerde rollen verwijderen
+removing instances and workitems for aborted instances on all processes	workflow	nl	bezig met verwijderen van instanties en werkonderdelen voor afgebroken instanties op alle processen
+removing instances and workitems for aborted instances on process #%1	workflow	nl	bezig met verwijderen van instanties en werkonderdelen voor afgebroken instanties op proces #%1
+removing instances and workitems for all instances on process #%1	workflow	nl	bezig met verwijderen van instanties en werkonderdelen voor alle instanties op proces #%1
+replyto:	workflow	nl	Antwoord-Aan:
+restart	workflow	nl	herstarten
+restart activity	workflow	nl	activiteit herstarten
+resume this exception instance	workflow	nl	Hervat deze uitgezonderde instantie
+role	workflow	nl	Rol
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	nl	Rol #%1 in proces %s heeft een ander proces (%3) in koppeling met gebruiker #%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	nl	Rol %1 (#%2) is verbonden met een niet bestaand proces (#%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	nl	Rol %1 is verbonden in een koppeling aan gebruiker #%2 met een niet bestaand proces (%3)
+role %1 is not mapped	workflow	nl	Rol %1 is niet gekoppeld
+role added to activity	workflow	nl	Rol toegevoegd aan activiteit
+role added to process	workflow	nl	Rol toegevoegd aan proces
+role give abort right	common	nl	rol geeft recht tot afbreken
+role give exception right	common	nl	rol geeft recht tot uitzondering
+role give release right	common	nl	rol geeft recht tot vrijgave
+role in inexistent process	workflow	nl	Rol in nietbestaand proces
+role mapping in inexistent process	workflow	nl	Rol koppeling in niet bestaand proces
+role name	workflow	nl	Rol naam
+role not saved (maybe a name collision)	workflow	nl	Rol niet opgeslagen (mogelijk een naam conflict)
+role process inconcistency in mappings	workflow	nl	Rol proces inconsistentie in kopellingen
+role saved	workflow	nl	Rol opgeslagen
+roles	workflow	nl	Rollen
+roles assigned to this activity	workflow	nl	Rollen toegewezen aan deze activiteit
+roles deleted	workflow	nl	Rollen verwijderd
+routing	workflow	nl	Routeren
+routing:	workflow	nl	routeren:
+run	workflow	nl	uitvoeren
+run activity	workflow	nl	activiteit uitvoeren
+run instance	workflow	nl	instantie uitvoeren
+running	workflow	nl	wordt uitgevoerd
+running activities options	common	nl	Activiteiten opties worden uitgevoerd
+running activity	workflow	nl	Activiteit wordt uitgevoerd
+scan activities	workflow	nl	Activiteiten scannen
+scan agents	workflow	nl	Scan agenten
+scan instances	workflow	nl	Scan instanties
+scan processes	workflow	nl	Scan processen
+scan roles	workflow	nl	Scan rollen
+scan transitions	workflow	nl	Scan transities
+search instance filter in the bottom of instance lists	workflow	nl	Zoek instantie filter aan de onderzijde van de instantie lijsten
+search:	workflow	nl	zoeken:
+security check: cannot understand asked action	workflow	nl	Veiligheidscontrole: Begrijp de gevraagde actie niet
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	nl	zie ook <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> en <strong>%process_id%</strong>
+select a transition to remove	workflow	nl	Selecteer een transitie die verwijderd moet worden
+select source	workflow	nl	selecteer bron
+send after interactive activity is completed	workflow	nl	het verzenden na een interactieve activiteit is voltooid
+send all to	workflow	nl	Verzend naar alle
+send an email	workflow	nl	Verzend een emailbericht
+send instance	workflow	nl	verzend instantie
+send this instance to the next activity	workflow	nl	Verzend deze instantie naar de volgende activiteitq
+send transition	workflow	nl	verzend transitie
+send when the activity is ending	workflow	nl	verzenden wanneer de activiteit eindigt
+send when the activity is starting	workflow	nl	verzenden wanneer de activiteit begint
+send when wf_agent_mail_smtp['submit_send'] is posted	workflow	nl	verzenden wanneer wf_agent_mail_smtp['submit_send'] is geplaatst
+set next act	workflow	nl	Volgende activiteit instellen
+set next user	workflow	nl	Volgende gebruiker instellen
+set property	workflow	nl	Eigenschap instellen
+setnextuser directives can override it	workflow	nl	setNextUser parameters kunnen het overheersen
+setting next activity to an unexisting activity	workflow	nl	volgende activiteit instellen op een niet bestaande activiteit
+shared code	workflow	nl	Gedeelde code
+should we always give you the advanced search row on instances lists?	workflow	nl	Moeten we u altijd de geavanceerd zoeken rij tonen in instantie lijsten?
+show activity info zone	common	nl	activiteit informatie zone weergeven
+show activity title	common	nl	activiteit titel weergeven
+show code	workflow	nl	code weergeven
+show instance name	common	nl	Instanatienaam weergeven
+show instance owner	common	nl	Instantie eigenaar weergeven
+show multiple submit as select	common	nl	meervoudige invoer als keuzelijst weergeven
+show template	workflow	nl	sjabloon weergeven
+size of the font used on the graph 12 should be a good default value	admin	nl	de lettergrootte die in de grafiek gebruikt wordt, 12 is een geschikte standaard waarde
+smtp agent has detected some errors when sending email after completion of the activity	workflow	nl	SMTP agent heeft enkele fouten geconstateerd tijdens het verzenden van email nadat de activiteit voltooid was
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	nl	SMTP agent heeft enkele fouten geconstateerd tijdens het verzenden van email aan het begin van de activiteit
+smtp agent has detected some errors when sending email at the end of this activity	workflow	nl	SMTP agent heeft enkele fouten geconstateerd tijdens het verzenden van email nadat deze activiteit voltooid was
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	nl	SMTP agent heeft enkele fouten geconstateerd tijdens het verzenden van email op verzoek van   deze activiteit
+something was wrong while creating the new major version	workflow	nl	er ging iets fout bij het aanmaken van de nieuwe boven versie
+something was wrong while creating the new minor version	workflow	nl	er ging is fout bij het aanmaken van de nieuwe onder versie
+source code file for activity %1 is not avaible	workflow	nl	broncode bestand voor activiteit %1 is niet beschikbaar
+source code for activity %1 is not avaible	workflow	nl	broncode voor activiteit %1 is niet beschikbaar
+source saved	workflow	nl	Bron opgeslagen
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	nl	Bijzondere bekende waarden voor lokale links adressen zijn <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> en <strong>admininstance</strong>.
+split	workflow	nl	splitsen
+standalone	workflow	nl	alleenstaand
+start	workflow	nl	Begin
+start activities must be autorouted	workflow	nl	begin activiteiten moeten zelfrouterend zijn
+start activities must be interactive	workflow	nl	begin activiteiten moeten interactief zijn
+start activity	workflow	nl	Activiteit beginnen
+start process	workflow	nl	proces beginnen
+started	workflow	nl	Begonnen
+started:	workflow	nl	begonnen:
+starting page	workflow	nl	Beginpagina
+status	workflow	nl	Status
+status:	workflow	nl	status:
+stop	workflow	nl	stoppen
+subject:	workflow	nl	Onderwerp:
+switch	workflow	nl	afwisselen
+switch construct	workflow	nl	Constructie afwisselen
+template	workflow	nl	sjabloon
+test concistency	workflow	nl	Consistentie testen
+test consistency of datas in the database	workflow	nl	Consistentie van gegevens in de database testen
+test local installation	workflow	nl	Lokale installatie testen
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	nl	De /workflow map bestaat niet en kon niet worden aangemaakt. Vraag uw beheerder om de globale configuratie te controleren
+the activity was not completed	workflow	nl	De activiteit werd niet voltooid
+the default user will only be set if he is mapped to a role on the activity	workflow	nl	De standaard gebruiker wordt alleen ingesteld als hij is gekoppeld aan een rol van de activiteit
+the following items must be corrected to be able to activate this process	workflow	nl	De volgende items moeten gecorrigeerd worden voordat dit proces geactiveerd kan worden
+the instance title is shown on top of the form	admin	nl	de instantietitel wordt weergegeven aan de bovenzijde van het formulier
+the label you want	workflow	nl	het label dat u wilt
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	nl	De SMTP configuratie kan niet door de mail_smtp_workflow agent geladen worden
+there are no activities available	workflow	nl	Er zijn geen activiteiten beschikbaar
+there are no config value defined	workflow	nl	Er is geen configuratie waarde gedefinieerd
+there are no instances available	workflow	nl	Er zijn geen instanties beschikbaar
+there are no mappings defined for this process	workflow	nl	Er zijn geen koppelingen voor dit proces gedefinieerd
+there are no process available	workflow	nl	Er zijn geen processen beschikbaar
+there are no processes	workflow	nl	Er zijn geen processen
+there are no processes available	workflow	nl	Er zijn geen processen beschikbaar
+there are no processes defined	workflow	nl	Er zijn geen processen gedefinieerd
+there are no processes with the current filter	workflow	nl	Er zijn geen processen binnen het huidige filter
+there are no properties available	workflow	nl	Er zijn geen eigenschappen beschikbaar
+there are no roles defined for this process	workflow	nl	Er zijn geen rollen voor dit proces gedefinieerd
+there are no transitions defined	workflow	nl	Er zijn geen transities gedefinieerd
+there are no user activites available	workflow	nl	Er zijn geen gebruiker activiteiten beschikbaar
+there are no workitems available	workflow	nl	Er zijn geen werkitems beschikbaar
+there are some undefined preferences associated with this form : %1	workflow	nl	er zijn enkele ongedefinieerde voorkeuren verbonden met dit formulier : %1
+there is an unknown user or group #%1 in role mappings	workflow	nl	Er is een onbekende gebruiker of groep #%1 in de rol koppelingen
+they were problems at the compilation of the source:	workflow	nl	Er waren problemen bij het compileren van de bron:
+this activity for this instance is actually avaible for you.	workflow	nl	Deze activiteit voor deze instantie is feitelijk voor u beschikbaar.
+this activity for this instance is actually only avaible for you.	workflow	nl	Deze activiteit voor deze instantie is feitelijk uitsluitend voor u beschikbaar.
+this activity for this instance is not specifically assigned to you.	workflow	nl	Deze activiteit voor deze instantie is niet speciaal aan u toegewezen.
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	nl	Deze agent geeft de activiteit de mogelijkheid een emailbericht te verzenden
+this form will test your local workflow installation to detect potential issues	workflow	nl	Dit formulier zal uw lokale werkstroom installatie controleren op potentiele problemen
+this is the first screen shown when you click on the workflow application icon	workflow	nl	Dit is het eerste scherm dat getoond wordt als u de werkstroom toepassing opstart
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	nl	Dit proces heeft een weergave activiteit. Toegang tot de weergave modus wordt alleen verleend voor deze weergave activiteit.
+this process has no end activity	workflow	nl	dit proces heeft geen eind activiteit
+this will automatically release the instance when leaving an activity without completing	admin	nl	dit zal automatisch de instantie vrijgeven zodra een activiteit wordt verlaten zonder 'm te voltooien
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	nl	dit zal een activiteit voettekst tonen indien een activiteit met werkstroom gerelateerde informatie wordt uitgevoerd
+to	workflow	nl	Aan
+to:	workflow	nl	Aan:
+transition	workflow	nl	transitie
+transition mode	workflow	nl	transitie modus
+transition to %1	workflow	nl	transitie naar %1
+transition waiting for human interaction	workflow	nl	transitie wacht op menselijke interactie
+transitions	workflow	nl	transities
+transitions removed successfully	workflow	nl	Transities zijn verwijderd
+type	workflow	nl	type
+type:	workflow	nl	type:
+unknow fix instruction :%1	workflow	nl	onbekende fix instructie : %1
+unknown instruction from the workflow engine: %1	workflow	nl	onbekende instructie vanuit de werkstroom machine : %1
+unknown status	workflow	nl	onbekende status
+update	workflow	nl	bijwerken
+upload file	workflow	nl	Bestand verzenden
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	nl	Gebruik <a href="%1">EmailAdmin</a> om emailprofielen aan te maken
+use automatic parsing	common	nl	gebruik automatische parsing
+use default	workflow	nl	Gebruik standaard
+use existing roles	workflow	nl	Gebruik bestaande rollen
+user	workflow	nl	Gebruiker
+user #%1 is associated with a non-existent role #%2	workflow	nl	Gebruiker $%1 is verbonden aan een niet bestaande rol $%2
+user activities	workflow	nl	Gebruikersactiviteiten
+user instances	workflow	nl	Gebruikersinstanties
+user instances form: columns	workflow	nl	Gebruikersinstanties formulier: kolommen
+user instances form: filters and actions	workflow	nl	Gebruikersinstanties formulier: filters en acties
+user is not authorized to delete aborted instances	workflow	nl	gebruiker is niet bevoegd om afgebroken instanties te verwijderen
+user is not authorized to delete instances	workflow	nl	gebruiker is niet bevoegd om instanties te verwijderen
+user processes	workflow	nl	Gebruikersprocessen
+user/group	workflow	nl	Gebruiker/groep
+user:	workflow	nl	gebruiker:
+users can act on activity before its execution with form and after by sending it to the next activity	workflow	nl	Gebruikers kunnen met een formulier reageren op een activiteit voordat deze wordt uitgevoerd en nadat ze hem naar de volgende activiteit hebben verzonden
+users/groups	workflow	nl	Gebruikers/groepen
+valid	workflow	nl	Geldig
+valid process	workflow	nl	Geldig proces
+valid:	workflow	nl	geldig:
+validity:	workflow	nl	Geldigheid:
+value	workflow	nl	Waarde
+version	workflow	nl	Versie
+view details	workflow	nl	details bekijken
+view this instance	workflow	nl	Deze instantie bekijken
+view workitem	workflow	nl	Werkitem bekijken
+warning this filter override all others filters	workflow	nl	waarschuwing: dit filter overschrijft alle andere filters
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	nl	waarschuwing: door deze knop te gebruiken verwijdert u alle afgebroken instanties EN hun historie (werkitems) van het geselecteerde proces.
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	nl	waarschuwing: door deze knop te gebruiken verwijdert u alle instanties EN hun historie (werkitems) van het geselecteerde proces, ongeacht de staat waarin ze zich bevinden.
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	nl	We konden deze activiteit niet uitvoeren, misschien bestaat deze instantie of deze activiteit niet meer.
+we were not able to build the message	workflow	nl	We konden het bericht niet samenstellen
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	nl	Indien in geavanceerde modus, moeten we u dan standaard de geavanceerde acties tonen (doorgaan, uitzonderen, oppakken, enz.)?
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	nl	indien meerdere verzend opties beschikbaar zijn tonen we een keuzelijst met slechts één verzendknop in plaats van meerdere knoppen
+when to send the message:	workflow	nl	Wanneer het bericht verzenden:
+workflow	common	nl	Werkstroom
+workflow configuration	admin	nl	Werkstroom configuratie
+workflow navigation	workflow	nl	Werkstroom navigatie
+workflow preferences	workflow	nl	Werkstroom voorkeuren
+workflow site configuration	workflow	nl	Werkstroom site configuratie
+workflow.ui_useractivities	workflow	nl	workflow.ui_useractivities
+workitem information	workflow	nl	Werkitem informatie
+workitems	workflow	nl	Werkitems
+you are not allowed to abort instance %1	workflow	nl	U mag instantie %1 niet afbreken
+you are not allowed to exception instance %1	workflow	nl	U mag instantie%1 niet laten uitzonderen
+you are not allowed to grab instance %1	workflow	nl	U mag instantie %1 niet benaderen
+you are not allowed to release instance %1	workflow	nl	U mag instantie %1 niet vrijgeven
+you are not allowed to restart instance %1	workflow	nl	U mag instantie %1 niet herstarten
+you are not allowed to resume instance %1	workflow	nl	U mag instantie %1 niet laten doorgaan
+you are not allowed to send instance %1	workflow	nl	U mag instantie %1 niet verzenden
+you can use special values with this mail agent:	workflow	nl	U moet speciale waardes gebruiken met deze mail agent:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	nl	U heeft niet meer het recht om deze activiteit uit te voeren, misschien een gelijktijdige toegang probleem, ververs uw gegevens.
+you don't have the rights necessary to exception instance %1	workflow	nl	U heeft geen rechten om instantie %1 te laten uitzonderen
+you have not permission to execute this activity	workflow	nl	U heeft geen rechten om deze activiteit uit te laten voeren
+you were not allowed to complete the activity	workflow	nl	u was niet bevoegd om deze activiteit te voltooien
Index: /sandbox/workflow/branches/993/setup/phpgw_es-es.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_es-es.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_es-es.lang	(revision 795)
@@ -0,0 +1,604 @@
+#	workflow	es-es	nº
+%1 aborted	workflow	es-es	%1 abortado
+%1 active	workflow	es-es	%1 activos
+%1 completed	workflow	es-es	%1 completados
+%1 configuration	workflow	es-es	Configuración de %1
+%1 days, %2:%3:%4	workflow	es-es	%1 días, %2:%3:%4
+%1 exception	workflow	es-es	excepción %1
+%1 menu	workflow	es-es	Menú %1
+%1 monitoring	workflow	es-es	Monitorización de %1
+%1 processes (%2 active) (%3 being_run)	workflow	es-es	%1 procesos (%2 activos) (%3 en ejecución)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	es-es	El directorio /workflow no existe y no se pudo crear. Por favor, pida al administrador que compruebe la configuración global
+<strong>%owner%</strong> is the instance owner email	workflow	es-es	<strong>%owner%</strong> es el correo del propietario de la instancia
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	es-es	<strong>%property_XX%</strong> es el contenido de la propiedad XX de la instancia
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	es-es	<strong>%role_XX%</strong> son todos los correos de todos los usuarios mapeados al rol XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	es-es	<strong>%roles%</strong> son los correos de todos los usuarios mapeados a cualquier rol en esta actividad
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	es-es	<strong>%signature%</strong> es la firma del agente definida en la configuración del proceso
+<strong>%user%</strong> is the instance user email	workflow	es-es	<strong>%user%</strong> es el correo del usuario de la instancia
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	es-es	<strong>%user_XX%</strong> es el correo de la cuenta XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	es-es	al cargar el formulario de actividad, se muestra un mensaje de espera, útil para tareas largas
+abort instance	workflow	es-es	abortar instancia
+abort this instance	workflow	es-es	Abortar esta instancia
+aborted	workflow	es-es	abortada
+access denied for user %1 on activity %2, no role	workflow	es-es	Acceso denegado para el usuario %1 en la actividad %2, sin rol
+act	workflow	es-es	actividad
+act. status	workflow	es-es	Estado de la actividad
+act. status:	workflow	es-es	Estado de la actividad:
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	es-es	La acción %1 es imposible si no tenemos actividad y no hay instancia designada para ella
+action %1 is impossible, another user is already in place	workflow	es-es	La acción %1 es imposible, otro usuario ya está en el lugar
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	es-es	La acción %1 es imposible, no hay ningún usuario asignado a esta actividad para esta instancia
+action %1 needs an activity and activity %2 does not exists	workflow	es-es	La acción %1 necesita una actividad, y la actividad %2 no existe
+action %1 needs an instance and instance %2 does not exists	workflow	es-es	La acción %1 necesita una instancia, y la instancia %2 no existe
+actions	workflow	es-es	Acciones
+actions right options	common	es-es	Opciones para derechos de acciones
+activate	workflow	es-es	activar
+active	workflow	es-es	Activo
+active:	workflow	es-es	Activo:
+activities	workflow	es-es	Actividades
+activities selection	workflow	es-es	Selección de actividades
+activities updated	workflow	es-es	Se han actualizado las actividades
+activity	workflow	es-es	actividad
+activity  status	workflow	es-es	Estado de la actividad
+activity %1	workflow	es-es	actividad %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	es-es	La actividad %1 (nº%2) está asociada con un proceso inexistente (nº%3)
+activity %1 code is not avaible	workflow	es-es	El código de la actividad %1 no está disponible
+activity %1 is interactive but has no role assigned	workflow	es-es	La actividad %1 es interactiva pero no tiene rol asignado
+activity %1 is interactive so it must use the $instance->complete() method	workflow	es-es	La actividad %1 es interactiva, así que debe usar el método $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	es-es	La actividad %1 no es interactiva ni autoenrutada, pero no tiene rol asignado
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	es-es	La actividad %1 no es interactiva, por lo que no debe usar el método $instance->complete() method
+activity %1 is standalone and is using the $instance object	workflow	es-es	La actividad %1 es independiente y está usando el objeto $instance
+activity %1 is standalone but has transitions	workflow	es-es	La actividad %1 es independiente pero tiene transiciones
+activity %1 is standalone or view but has transitions	workflow	es-es	La actividad %1 es independiente o vista pero tiene transiciones
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	es-es	La actividad %1 es una decisión, por lo que debe usar el método $instance->setNextActivity($actname)
+activity %1 is view and is using the $instance object in write mode	workflow	es-es	La actividad %1 es una vista y está usando el objeto $instance en modo de escritura
+activity agent removed	workflow	es-es	Agente de actividad eliminado
+activity completed	workflow	es-es	Actividad completada
+activity failure	workflow	es-es	fallo en la actividad
+activity in inexistent process	workflow	es-es	Actividad en un proceso inexistente
+activity is waiting for pending transitions	workflow	es-es	la actividad está esperando transiciones pendientes
+activity name already exists	workflow	es-es	El nombre de la actividad ya existe
+activity role #%1 removed	workflow	es-es	Rol de actividad nº%1 ha sido eliminado
+activity role removed	workflow	es-es	El rol de la actividad ha sido eliminado
+activity saved	workflow	es-es	La actividad ha sido guardada
+activity start not avaible, no corresponding activity was found.	workflow	es-es	El comienzo de la actividad no está disponible, no se encontró ninguna actividad correspondiente.
+activity start not set, no corresponding activity was found.	workflow	es-es	No se estableció la actividad de inicio, no se encontró ninguna actividad correspondiente.
+activity status not avaible, no corresponding activity was found.	workflow	es-es	El estado de la actividad no está disponible, no se encontró ninguna actividad correspondiente.
+activity:	workflow	es-es	actividad:
+add a transition	workflow	es-es	Añadir una transición
+add aborted instances	workflow	es-es	Añadir instancias abortadas
+add advanced actions	workflow	es-es	Añadir acciones avanzadas
+add agent	workflow	es-es	Añadir agente
+add completed instances	workflow	es-es	Añadir instancias completadas
+add instances in exception	workflow	es-es	Añadir instancias en excepción
+add new	workflow	es-es	añadir nueva
+add new role	workflow	es-es	Añadir nuevo rol
+add or edit a process	workflow	es-es	Añadir o editar un proceso
+add or edit a role	workflow	es-es	Añadir o editar un rol
+add or edit an activity	workflow	es-es	Añadir o editar una actividad
+add property	workflow	es-es	Añadir propiedad
+add role	workflow	es-es	Añadir rol
+add role to process	workflow	es-es	Añadir rol al proceso
+add transition	workflow	es-es	añadir transición
+add transitions	workflow	es-es	Añadir transiciones
+add transitions from	workflow	es-es	Añadir transiciones de
+add transitions to	workflow	es-es	Añadir transiciones a
+admin instance	workflow	es-es	Admnistrar instancia
+admin process activities	workflow	es-es	Administrar actividades del proceso
+admin process roles	workflow	es-es	Administrar roles del proceso
+admin processes	common	es-es	Administrar procesos
+admin processes sources	workflow	es-es	Administrar código fuente de los procesos
+administer instances	admin	es-es	Administrar instancias
+administer processes	admin	es-es	Administrar procesos
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	es-es	El agente nº%1 del tipo %2 está asociado a una actividad inexistente nº%3
+agent #%1 of type %2 is not linked with an activity	workflow	es-es	El agente nº%1 de tipo %2 no está vinculado con una actividad
+agent associated with inexistent activity	workflow	es-es	El agente asociado con una actividad inexistente
+agent without activity	workflow	es-es	El agente no tiene actividad
+agents assigned to this activity	workflow	es-es	Agentes asignados a esta actividad
+all	workflow	es-es	Todos
+always show advanced actions	workflow	es-es	Mostrar siempre las acciones avanzadas
+always show advanced mode	workflow	es-es	Mostrar siempre el modo avanzado
+assign me this activity	workflow	es-es	Asignarme esta actividad
+at least one email address cannot be validated.	workflow	es-es	Al menos un dirección de correo no se pudo validar
+auto routed	workflow	es-es	Autoenrutado
+auto-release on leaving activity	common	es-es	Liberar automáticamente al abandonar la actividad
+automatic	workflow	es-es	Automático
+autorouted activities does not need to be sent by any user after their execution	workflow	es-es	Las actividades autorutadas no necesitan que ningún usuario las envíe después de su ejecución
+bad parameter for setagents, the parameter should be an array	workflow	es-es	parámetro erróneo para setAgents. El parámetro debe ser un array
+bad role type	workflow	es-es	Tipo de rol incorrecto
+bad user	workflow	es-es	Usuario incorrecto
+base directory does not exist, please ask adminstrator to check the global configuration	common	es-es	El directorio base no existe. Por favor, pida al administrador que compruebe la configuración global
+bcc:	workflow	es-es	Cco:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	es-es	Tenga cuidado con la actividad interactiva, porque el fin y el inicio de estas actividades son múltiples.
+being run	workflow	es-es	siendo ejecutado
+by running theses links you will create new instances of the related process.	workflow	es-es	Al ejecutar estos enlaces, creará nuevas instancias del proceso relacionado.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	es-es	No se puede añadir la transición. Sólo las actividades divididas o de cambio pueden tener más de una transición saliente
+cannot add transition. only split activities can have more than one outbound transition	workflow	es-es	No se puede añadir la transición. Sólo las actividades de bifurcación pueden tener más una transición saliente
+cannot create compiled file %1	workflow	es-es	no se puede crear el fichero compilado %1
+cannot retrieve the user running the security check	workflow	es-es	No se puede recuperar el usuario que ejecuta la comprobación de seguridad
+cannot run the activity	workflow	es-es	No se puede ejecutar la actividad
+cannot run the activity without her process	workflow	es-es	No se puede ejecutar la actividad sin su proceso
+cannot run the activity without instance	workflow	es-es	No se puede ejecutar la actividad sin instancia
+cannot run unknown activity	workflow	es-es	No se puede ejecutar una actividad desconocida
+cc:	workflow	es-es	Cc:
+circular reference found some activity has a transition leading to itself	workflow	es-es	La referencia circular encontró alguna actividad que tiene una transición que vuelve a ella misma
+circular reference found. some activity has a transition leading to itself	workflow	es-es	Se encontró una referencia circular. Alguna actividad tiene una transición apuntando a sí misma
+cleanup aborted instances	admin	es-es	Limpiar las instancias abortadas
+cleanup actions	workflow	es-es	limpiar acciones
+close and get back later	workflow	es-es	Cerrar y volver más tarde
+close printer friendly mode	workflow	es-es	Cerrar modo orientado para impresión
+code	workflow	es-es	código
+column activity status in instance lists	workflow	es-es	Columna de estado de la actividad en listas de la instancia
+column category in instance lists	workflow	es-es	Columna Categoría en listas de instancias
+column instance id in instance lists	workflow	es-es	Columna Id de instancia en listas de ia instancia
+column instance name in instance lists	workflow	es-es	Columna nombre de la instancia en listas de la instancia
+column instance status in instance lists	workflow	es-es	Columna estado de la instancia en listas de la instancia
+column owner in instance lists	workflow	es-es	Columna propietario en listas de la instancia
+column priority in instance lists	workflow	es-es	Columna prioridad en listas de la instancia
+column process name in instance lists	workflow	es-es	Columna nombre del proceso en listas de la instancia
+column start date in instance lists	workflow	es-es	Columna fecha de inicio en listas de la instancia
+compilation	workflow	es-es	Compilación
+compiling activity %1 : %2	workflow	es-es	compilando actividad %1 : %2
+complete	workflow	es-es	Completo
+complete cleanup of aborted instances done	workflow	es-es	se terminó el borrado completo de instancias abortadas
+complete cleanup of all instances done	workflow	es-es	se terminó el borrado completo de todas las instancias
+completed	workflow	es-es	completado
+config values	common	es-es	Valores de configuración
+confirm delete	workflow	es-es	Confirmar borrar
+consult %1 to get the default values:	workflow	es-es	Consultar %1 para obtener los valores predeterminados:
+couldn't add transition	workflow	es-es	No se pudo añadir la transición
+create	workflow	es-es	crear
+created	workflow	es-es	Creada
+date:	workflow	es-es	fecha:
+default config values	common	es-es	Valores de configuración predeterminados
+default next user	workflow	es-es	Usuario siguiente predeterminado
+default owner	workflow	es-es	Propietario predeterminado
+default settings for processes	admin	es-es	Configuración predeterminada para los procesos
+default user	workflow	es-es	Usuario predeterminado
+delete selected	workflow	es-es	Borrar lo seleccionado
+delete transition	workflow	es-es	Borrar transición
+deletion successful	workflow	es-es	Borrado correcto
+delition successful	workflow	es-es	Borrado correcto
+description	workflow	es-es	Descripción
+display please wait message	common	es-es	mostrar mensaje "por favor, espere"
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	es-es	¿Desea el estado de la actividad en las listas de instancias? La mayoría del tiempo está "en ejecución", pero si usa transiciones no autorutadas tendrá algunas actividades completadas.
+do you want the category column on instances lists, if yout instances use categories you should use it	workflow	es-es	¿Desea la columna de categoría en las listas de instancias? Si sus instancias usan categorías, debería usarla.
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	es-es	¿Desea la columna de nombre de la categoría en las listas de instancias? Si sus instancias usan categorías, debería usarla.
+do you want the category name column on instances lists. if your instances use categories you should use this	workflow	es-es	¿Desea la columna nombre de categoria en las listas de instancias? Si sus instancias usan categorías, debería usarla.
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	es-es	¿Desea la columna id de instancia en las listas de instancias? Es el único identificador de una instancia.
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	es-es	¿Desea la columna nombre de la instancia en las listas de instancias? Si sus instancias tienen nombre, debe usarla.
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	es-es	¿Desea el estado de la instancia en las listas de instancia? El estado de la instancia es útil para distinguir entre instancias abortadas, completadas, excepción o activa.
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	es-es	¿Desea la columna propietario en las listas de instancias? Esto mostrará el propietario actual, especialmente útil si el propietario está definido con derechos especiales.
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	es-es	¿Desea la columna prioridad en las listas de instancias? La prioridad puede establecerse con formularios de actividades.
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	es-es	¿Desea la columna proceso en las listas de instancias? Es útil si se tienen distintos procesos y/o versiones de estos procesos
+do you want the search instance button in the last row of instances list.	workflow	es-es	¿Desea el botón de buscar instancia en la última fila de la lista de instancias?
+do you want the started date column on instances lists.	workflow	es-es	¿Desea la columna de fecha de inicio en las listas de instancias?
+don't move	workflow	es-es	No mover
+draw roles	common	es-es	Dibujar roles
+draw roles on the graph beside activity name like [that]	admin	es-es	Dibujar roles en el gráfico junto al nombre, [así]
+duration	workflow	es-es	Duración
+empty agent type	workflow	es-es	vaciar el tipo de agente
+end	workflow	es-es	fin
+end activity is not reachable from start activity	workflow	es-es	La actividad de fin no se puede alcanzar desde la actividad de inicio
+ended	workflow	es-es	finalizado
+enter an activity name	workflow	es-es	Introduzca un nombre de actividad
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	es-es	Error: nextActivity no coincide con ningún candidato en la actividad de cambio de autorutado
+error: non-deterministic decision for autorouting activity	workflow	es-es	Error: decisión no determinante para actividad de autorutado
+error: removing was not done	workflow	es-es	error: no se realizó el borrado
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	es-es	Error: intentando enviar una instancia a una actividad pero fue imposible obtener esta actividad
+error: trying to send an instance to an activity but no transition found	workflow	es-es	Error: intentando enviar una instancia a una actividad pero no se encontró ninguna transición
+exception	workflow	es-es	excepción
+exception instance	workflow	es-es	instancia de excepción
+exception raised by %1 %2: %3	workflow	es-es	excepción originada por %1 %2: %3
+exception resumed by %1 %2: %3	workflow	es-es	excepción continuada por %1 %2: %3
+exception this instance	workflow	es-es	Excepción en esta instancia
+exceptions	workflow	es-es	excepciones
+execute this activity	workflow	es-es	Ejecutar esta actividad
+export	workflow	es-es	Exportar
+failed to create workitem	workflow	es-es	fallo al crear elemento de trabajo
+failed to execute automatic activity	workflow	es-es	fallo al ejecutar actividad automática
+failed to obtain lock on %1 table	workflow	es-es	fallo al obtener bloqueo en la tabla %1
+failed to obtain lock on instances table	workflow	es-es	fallo al obtener bloqueo en la tabla de instancias
+failed to obtain lock on instances_activities table	workflow	es-es	fallo al obtener bloqueo en la tabla instances_activities
+failed to record instance properties	workflow	es-es	fallo al grabar las propiedades de la instancia
+failed to synchronize instance data with the database	workflow	es-es	fallo al sincronizar los datos de la instancia con la base de datos
+failure	workflow	es-es	fallo
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	es-es	Error fatal: la siguiente actividad no coincide con ningún candidato en la actividad de cambio de enrutado automático
+fatal error: non-deterministic decision for autorouting activity	workflow	es-es	Error falta: decisión no determinante para la actividad de enrutado automático
+fatal error: setting next activity to an unexisting activity	workflow	es-es	Error fatal: estableciendo la actividad sigiuente a una actividad inexistente
+fatal error: trying to send an instance to an activity but no transition found	workflow	es-es	Error fatal: intentando enviar una instancia a una actividad, pero no se encontró transición
+filter	workflow	es-es	Filtro
+filter instance by id	workflow	es-es	Filtrar instancia por id
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	es-es	finalmente tiene enlaces con la sintaxis <strong>%link_XX|YY%</strong>, donde XX es la parte de la dirección, e YY la parte de texto.
+fix	workflow	es-es	Corregir
+fix concistency for selected rows	workflow	es-es	Corregir consistencia para las filas seleccionadas
+font size	workflow	es-es	Tamaño de la letra
+from	workflow	es-es	De
+from:	workflow	es-es	De:
+get back to global activities	workflow	es-es	volver a las actividades globales
+get back to instance creation	workflow	es-es	volver a la creación de la instancia
+get property	workflow	es-es	Obtener propiedad
+global activities	workflow	es-es	Actividades globales
+global workflow preferences	workflow	es-es	Preferencias globales de flujos de trabajo
+go	workflow	es-es	ir
+go to same activities for other instances of this process	workflow	es-es	ir a las mismas actividades para otras instancias de este proceso
+go to same process activities	workflow	es-es	ir a las mismas actividades del proceso
+go to the actual state of this instance	workflow	es-es	ir al estado actual de esta instancia
+grab instance	workflow	es-es	coger instancia
+grant access to the administration and development of workflow processes and activities.	admin	es-es	Conceder acceso a la administración y desarrollo de procesos y actividades de flujos de trabajo.
+grant access to the administration of workflow elements	admin	es-es	Conceder acceso a la administración de los elementos del flujo del tabajo
+grant access to the administration of workflow instances in monitor screens	admin	es-es	Conceder acceso para la administración de instancias de flujos de trabajo en pantallas de monitorización
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	admin	es-es	Conceder acceso a la limpieza y/o borrado de las instancias abortadas de flujos de trabajo en las pantallas de monitorización
+grant access to the monitoring of workflow elements	admin	es-es	Conceder acceso para monitorizar elementos de flujos de trabajo
+graph	workflow	es-es	Gráfico
+graphic options	common	es-es	Opciones de gráfico
+group	workflow	es-es	Grupo
+id	workflow	es-es	Id
+if automatic parsing is disabled next options will be useless	admin	es-es	Si la interpretación automática está desactivada, las siguientes opciones no tienen efecto
+if not in debug mail_smtp agent would have sent this email:	workflow	es-es	si no se está depurando, el agente mail_smtp habría enviado este correo:
+if user is in a role for an activity he will have the right to abort the related instance	admin	es-es	Si el usuario está en un rol para una actividad, tendrá el derecho de abortar la instancia relacionada
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	es-es	Si un usuario está en un rol para una actividad, tendrá el derecho para una excepción o continuar la instancia relacionada
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	es-es	Si un usuario está en un rol para una actividad, tendrá el derecho para liberar (desasignar) la instancia relacionada.
+if:setnextact	workflow	es-es	Si:Establecer actividad siguiente
+import aborted	workflow	es-es	Importación abortada
+import successfull	workflow	es-es	Importación realizada correctamente
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	es-es	En mapeos de rol, el usuario nº%1 está especificado como '%2', pero QUIZAS sea '%3'
+inactive	workflow	es-es	Inactivo
+inst.	workflow	es-es	Inst.
+inst. status	workflow	es-es	Estado de la instancia
+instance	workflow	es-es	Instancia
+instance %1	workflow	es-es	Instancia %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	es-es	La instancia %1 está en estado %2, la acción %3 es imposible.
+instance %1 is in exception, action %2 is not possible.	workflow	es-es	La instancia %1 está en excepción, la acción %2 no es posible.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	es-es	La instancia %1 no está asociada con la actividad %2, la acción %3 es imposible.
+instance history	workflow	es-es	Historial de la instancia
+instance properties	workflow	es-es	Propiedades de la instancia
+instance:	workflow	es-es	Instancia:
+instance: %1 (process: %2)	workflow	es-es	Instancia: %1 (Proceso: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	es-es	Instancia: no se puede modificar %1 [%2], alguien lo ha cambiado antes que nosotros.
+instance: unable to modify %1, someone has changed it before us	workflow	es-es	Instancia: no se puede modificar %1, alguien lo ha cambiado antes que nosotros.
+instances	workflow	es-es	Instancias
+instances selection	workflow	es-es	Selección de instancias
+int.	workflow	es-es	Inr
+interactive	workflow	es-es	Interactiva
+interactive activities show form before being executed	workflow	es-es	Las actividades interactivas muestran un formulario antes de ejecutarse
+interactive instances should not call the complete() method	workflow	es-es	Las instancias interactivas no deben llamar al método complete()
+interactive:	workflow	es-es	interactiva:
+interactivity	workflow	es-es	Interactividad
+invalid	workflow	es-es	no válida
+invalid process	workflow	es-es	El proceso no es válido
+invalid role name	workflow	es-es	El nombre del rol no es válido
+is active	workflow	es-es	¿Está activo
+it seems this activity for this instance is not assigned to you anymore.	workflow	es-es	Parece que esta actividad para esta instancia ya no está asignada a usted.
+it was impossible to complete, no activity was given.	workflow	es-es	No se pudo completar, no se proporcionó la actividad.
+it was impossible to complete, no corresponding activity was found.	workflow	es-es	No se pudo completar, no se encontró una actividad correspondiente.
+join	workflow	es-es	reunificación
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	es-es	Las direcciones de los enlaces se consideran locales si no contienen <strong>http://</strong>. Se añadirán al prefijo local configurado y el motor de enlaces de egroupware las comprobará.
+list of activities	workflow	es-es	Lista de actividades
+list of all activities with, for each,  counters of instances by status	workflow	es-es	lista de todas las actividades con contadores de instancias por estado para cada una
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	es-es	lista de todos los elementos del historial hechos por instancias mientras viajan por flujos de trabajo con información sobre la duración y la fecha
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	es-es	lista de todas las instancias con información sobre el estado actual y actividades y enlaces a la administración de estas instancias
+list of instances	workflow	es-es	Lista de instancias
+list of mappings	workflow	es-es	Lista de mapeos
+list of monitors	workflow	es-es	Lista de monitores
+list of processes	workflow	es-es	Lista de procesos
+list of processes (%1)	workflow	es-es	Lista de procesos (%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	es-es	lista de procesos con estado y validez y contadores de instancias por estado para cada uno
+list of transitions	workflow	es-es	Lista de transiciones
+list of workitems	workflow	es-es	Lista de elementos de trabajo
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	es-es	Correo enviado automáticamente por el agente SMTP para Flujos de trabajo de eGroupware
+mail smtp agent	workflow	es-es	Agente de correo SMTP
+mail smtp debug	common	es-es	Depurar correo smtp
+mail smtp local link prefix	common	es-es	Prefijo del enlace local de correo smtp
+mail smtp profile	common	es-es	Perfil de correo smtp
+mail smtp signature	common	es-es	Firma de correo smtp
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	es-es	Los correos se pueden enviar al principio o al final de la actividad. Para actividades interactivas, sólo se puede enviar después de completarse.
+manual	workflow	es-es	Manual
+map	workflow	es-es	mapa
+map users/groups to roles	workflow	es-es	Mapear usuarios/grupos a roles
+mapping to inexistent role	workflow	es-es	Mapeando a un rol inexistente
+mappings deleted	workflow	es-es	Mapeos borrados
+message:	workflow	es-es	Mensaje:
+monitor activities	workflow	es-es	Monitorizar actividades
+monitor instance	workflow	es-es	monitorizar instancia
+monitor instances	workflow	es-es	Monitorizar instancias
+monitor processes	workflow	es-es	Monitorizar procesos
+monitor this instance	workflow	es-es	Monitorizar esta instancia
+monitor work items	workflow	es-es	Monitorizar elementos de trabajo
+monitor workitems	workflow	es-es	Monitorizar elementos de trabajo
+monitoring	admin	es-es	Monitorizar
+monitors	workflow	es-es	Monitores
+more options?	workflow	es-es	¿Más opciones?
+my activities	workflow	es-es	Mis actividades
+my instances	workflow	es-es	Mis instancias
+my processes	workflow	es-es	Mis procesos
+name	workflow	es-es	Nombre
+new instance	workflow	es-es	Nueva instancia
+new major	workflow	es-es	Nuevo mayor
+new major version created	workflow	es-es	Se ha creado una nueva version mayor
+new mapping added	workflow	es-es	Se ha añadido un nuevo mapeo
+new minor	workflow	es-es	Nuevo menor
+new minor version created	workflow	es-es	Se ha creado una nueva version menor
+new status not set, no corresponding activity was found.	workflow	es-es	El nuevo estado no está establecido. No se encontró ninguna actividad.
+new transition added	workflow	es-es	Se ha añadido una nueva transición
+next activity	workflow	es-es	actividad siguiente
+next user:	workflow	es-es	Usuario siguiente:
+no action avaible because no activity and no instance are given!	workflow	es-es	No hay acción disponible porque no se indicaron actividades ni instancias
+no activites	workflow	es-es	No hay actividades
+no activity indicated	workflow	es-es	No se ha indicado una actividad
+no agents associated with this activity	workflow	es-es	No hay agentes asociados con esta actividad
+no circular transitions allowed.	workflow	es-es	No se permiten transiciones circulares
+no corresponding activity was found.	workflow	es-es	No se encontró una actividad correspondiente.
+no inbound for start activity	workflow	es-es	No hay entrada para la actividad de inicio
+no inconcistency detected	workflow	es-es	No se detectaron inconsistencias
+no instance avaible	workflow	es-es	No hay instancias disponibles
+no instance given, nothing to show	workflow	es-es	no se ha indicado ninguna instancia, no se muestra nada
+no instance indicated	workflow	es-es	No se ha indicado una instancia
+no outbound for end activity	workflow	es-es	No hay salida para la actividad de fin
+no process indicated	workflow	es-es	No se ha indicado ningún proceso
+no properties defined	workflow	es-es	No se han definido propiedades
+no roles	workflow	es-es	No hay roles
+no roles asociated with this activity	workflow	es-es	No hay roles asociados con esta actividad
+no routage	workflow	es-es	sin enrutado
+no scan done	workflow	es-es	No se realizó exploración
+no transitions allowed for standalone or view activities	workflow	es-es	No se permiten transiciones para actividades independientes o vistas
+no work item indicated	workflow	es-es	No se ha indicado elemento de trabajo
+nobody	workflow	es-es	Nadie
+not defined	workflow	es-es	sin definir
+or import a process	workflow	es-es	O importar un proceso
+owner	workflow	es-es	Propietario
+owner of the instance will have the right to abort the instance at any time	admin	es-es	El propietario de la instancia tendrá el derecho de abortar la instancia en cualquier momento
+owner of the instance will have the right to exception or resume the instance at any time	admin	es-es	El propietario de la instancia tendrá el derecho de crear excepciones o continuar la instancia en cualquier momento
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	es-es	El propietario de la instancia tendrá el derecho de liberar (desasignar) una actividad asignada a un usuario
+owner:	workflow	es-es	Propietario:
+ownership give abort right	common	es-es	Ser propietario da derecho de abortar
+ownership give exception right	common	es-es	Ser propietario da derecho para excepciones
+ownership give release right	common	es-es	Ser propietario da derecho para liberar
+please wait, task in progress ...	workflow	es-es	Por favor, espere. Tarea en progreso...
+post activity %1 code is not avaible	workflow	es-es	el código de la actividad posterior %1 no está disponible
+post shared code is not avaible	workflow	es-es	el código compartido posterior no está disponible
+post-agent %1 code is not avaible	workflow	es-es	el código de agente posterior %1 no está disponible
+pr.	workflow	es-es	Prioridad
+pre-activity %1 code is not avaible	workflow	es-es	el código de la actividad previa %1 no está disponible
+pre-agent %1 code is not avaible	workflow	es-es	el código compartido previo no está disponible
+pre-shared code is not avaible	workflow	es-es	el código de agente previo %1 no está disponible
+printer friendly	workflow	es-es	Orientado para impresión
+priority level:	workflow	es-es	Nivel de prioridad:
+process	workflow	es-es	Proceso
+process %1	workflow	es-es	proceso %1
+process %1 %2 is not active, action %3 is impossible	workflow	es-es	El proceso %1 %2 no está activo, la acción %3 es imposible
+process %1 v%2 as no related activity	workflow	es-es	El proceso %1 v%2 no tiene actividad relacionada
+process %d has been activated	workflow	es-es	El proceso %d ha sido activado
+process %d has been deactivated	workflow	es-es	El proceso %d ha sido activado
+process %s %s already exists, the import process was aborted	workflow	es-es	El proceso %s %s ya existe. Se ha abortado el proceso de importación
+process %s %s imported	workflow	es-es	El proceso %s %s ha sido importado
+process %s has been created	workflow	es-es	El proceso %s ha sido creado
+process %s has been updated	workflow	es-es	El proceso %s ha sido actualizado
+process %s removed	workflow	es-es	El proceso %s ha sido eliminado
+process activities	workflow	es-es	Procesar actividades
+process alone	workflow	es-es	Procesar por separado
+process does not have a start activity	workflow	es-es	El proceso no tiene una actividad de inicio
+process does not have exactly one end activity	workflow	es-es	El proceso no tiene exactamente una actividad de fin
+process form	workflow	es-es	Procesar formulario
+process name	workflow	es-es	Nombre del proceso
+process name already exists	workflow	es-es	El nombre del proceso ya existe
+process roles	workflow	es-es	Roles del proceso
+process saved	workflow	es-es	Proceso guardado
+process transitions	workflow	es-es	Transiciones del proceso
+process version:	workflow	es-es	versión del proceso:
+process:	workflow	es-es	Proceso:
+processes	workflow	es-es	Procesos
+properties	workflow	es-es	Propiedades
+property	workflow	es-es	Propiedad
+property %1 already exists	workflow	es-es	La propiedad %1 ya existe
+property %1 not found	workflow	es-es	No se encontró la propiedad %1
+quit without saving	workflow	es-es	Salir sin guardar
+read-only	workflow	es-es	sólo lectura
+release access to this activity	workflow	es-es	Liberar el acceso a esta actividad
+release activity for this instance	workflow	es-es	liberar actividad para esta instancia
+release instance	workflow	es-es	liberar instancia
+reload filter	workflow	es-es	Recargar filtro
+remove active instances	workflow	es-es	Eliminar instancias activas
+remove all instances for this process	workflow	es-es	eliminar todas las instancias para este proceso
+remove selected roles	workflow	es-es	eliminar roles seleccionados
+removing instances and workitems for aborted instances on all processes	workflow	es-es	eliminando instancias y elementos de trabajo para las instancias abortadas en todos los procesos
+removing instances and workitems for aborted instances on process #%1	workflow	es-es	eliminando instancias y elementos de trabajo paras las instancias abortadas en el proceso nº%1
+removing instances and workitems for all instances on process #%1	workflow	es-es	eliminando instancias y elementos de trabajo paras las instancias en el proceso nº%1
+replyto:	workflow	es-es	Responder a:
+restart	workflow	es-es	reiniciar
+restart activity	workflow	es-es	reiniciar actividad
+resume this exception instance	workflow	es-es	Continuar esta instancia de excepción
+role	workflow	es-es	Rol
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	es-es	El rol nº%1 en el proceso %2 tiene distintos procesos (%2) al mapearlo con el usuario nº%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	es-es	El rol %1 (nº%2) está asociado con un proceso inexistente (nº%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	es-es	El rol %1 está asociado con el usuario nº%2 con un proceso inexistente (%3)
+role %1 is not mapped	workflow	es-es	El rol %1 no está mapeado
+role added to activity	workflow	es-es	Se ha añadido el rol a la actividad
+role added to process	workflow	es-es	Se ha añadido el rol al proceso
+role give abort right	common	es-es	El rol da derecho de abortar
+role give exception right	common	es-es	El rol da derecho para excepciones
+role give release right	common	es-es	El rol da derecho para liberar
+role in inexistent process	workflow	es-es	Rol en un proceso inexistente
+role mapping in inexistent process	workflow	es-es	Mapeo de rol en un proceso inexistente
+role name	workflow	es-es	Nombre del rol
+role not saved (maybe a name collision)	workflow	es-es	Rol no guardado (quizás haya una colisión en el nombre)
+role process inconcistency in mappings	workflow	es-es	Inconsistencia al procesar rol en los mapeos
+role saved	workflow	es-es	El rol se ha guardado
+roles	workflow	es-es	Roles
+roles assigned to this activity	workflow	es-es	Roles asignados a esta actividad
+roles deleted	workflow	es-es	Roles borrados
+routing	workflow	es-es	Enrutado
+routing:	workflow	es-es	enrutado:
+run	workflow	es-es	ejecutar
+run activity	workflow	es-es	ejecutar actividad
+run instance	workflow	es-es	ejecutar instancia
+running	workflow	es-es	en ejecución
+running activities options	common	es-es	Opciones de las actividades en ejecución
+running activity	workflow	es-es	Ejecutando actividad
+scan activities	workflow	es-es	Explorar actividades
+scan agents	workflow	es-es	Explorar agentes
+scan instances	workflow	es-es	Explorar instancias
+scan processes	workflow	es-es	Explorar procesos
+scan roles	workflow	es-es	Explorar roles
+scan transitions	workflow	es-es	Explorar transiciones
+search instance filter in the bottom of instance lists	workflow	es-es	Filtro de búsqueda al final de las listas de instancias
+search:	workflow	es-es	Buscar:
+security check: cannot understand asked action	workflow	es-es	Comprobación de seguridad: no se puede comprender la acción solicitada
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	es-es	ver también <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> y <strong>%process_id%</strong>
+select a transition to remove	workflow	es-es	Seleccionar una transicion para eliminar
+select source	workflow	es-es	seleccionar código fuente
+send after interactive activity is completed	workflow	es-es	enviar después de completar la actividad interactiva
+send all to	workflow	es-es	Enviar a todos
+send an email	workflow	es-es	Enviar un correo
+send instance	workflow	es-es	enviar instancia
+send this instance to the next activity	workflow	es-es	Enviar esta instancia a la siguiente actividad
+send transition	workflow	es-es	enviar transición
+send when the activity is ending	workflow	es-es	enviar cuando la actividad esté finalizando
+send when the activity is starting	workflow	es-es	enviar cuando la actividad esté comenzando
+send when wf_agent_mail_smtp['submit_send'] is posted	workflow	es-es	enviar cuando se envie wf_agent_mail_smtp['submit_send']
+set next act	workflow	es-es	Establecer actividad siguiente
+set next user	workflow	es-es	Establecer usuario siguiente
+set property	workflow	es-es	Establecer propiedad
+setnextuser directives can override it	workflow	es-es	Las directivas setNextUser pueden ignorarlo
+setting next activity to an unexisting activity	workflow	es-es	estableciendo la siguiente actividad a una actividad inexistente
+shared code	workflow	es-es	Código compartido
+should we always give you the advanced search row on instances lists?	workflow	es-es	Debemos mostrar siempre la fila de búsqueda avanzada en las listas de instancias?
+show activity info zone	common	es-es	Mostrar zona de información de actividad
+show activity title	common	es-es	Mostrar el título de la actividad
+show code	workflow	es-es	Mostrar código
+show instance name	common	es-es	Mostrar nombre de la instancia
+show instance owner	common	es-es	Mostrar propietario de la instancia
+show multiple submit as select	common	es-es	Mostrar multiples submit como selección
+show template	workflow	es-es	Mostrar plantilla
+size of the font used on the graph 12 should be a good default value	admin	es-es	El tamaño del tipo de letra usado en el gráfico 12 debe ser un buen valor predeterminado
+smtp agent has detected some errors when sending email after completion of the activity	workflow	es-es	El agente smtp ha detectado algunos errores al enviar correo después de completar la actividad
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	es-es	El agente smtp ha detectado algunos errores al enviar correo al principio de la actividad
+smtp agent has detected some errors when sending email at the end of this activity	workflow	es-es	El agente smtp ha detectado algunos errores al enviar correo al final de la actividad
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	es-es	El agente smtp ha detectado algunos errores al enviar correo bajo demanda con esta actividad
+something was wrong while creating the new major version	workflow	es-es	Ocurrió algo extraño al crear la nueva versión mayor
+something was wrong while creating the new minor version	workflow	es-es	Ocurrió algo extraño al crear la nueva versión menor
+source code file for activity %1 is not avaible	workflow	es-es	el fichero de código fuente para la actividad %1 no está disponible
+source code for activity %1 is not avaible	workflow	es-es	el código fuente para la actividad %1 no está disponible
+source saved	workflow	es-es	Origen guardado
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	es-es	Los valores especiales conocidos para las direcciones de enlaces locales son <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> y <strong>admininstance</strong>.
+split	workflow	es-es	bifurcación
+standalone	workflow	es-es	independiente
+start	workflow	es-es	Inicio
+start activities must be autorouted	workflow	es-es	Las actividades de inicio deben ser autorutadas
+start activities must be interactive	workflow	es-es	Las actividades de inicio deben ser interactivo
+start activity	workflow	es-es	Actividad de inicio
+start process	workflow	es-es	iniciar proceso
+started	workflow	es-es	Iniciado
+started:	workflow	es-es	iniciado:
+starting page	workflow	es-es	Página de inicio
+status	workflow	es-es	Estado
+status:	workflow	es-es	estado:
+stop	workflow	es-es	parar
+subject:	workflow	es-es	Asunto:
+switch	workflow	es-es	decisión
+switch construct	workflow	es-es	Intercambiar constructor
+template	workflow	es-es	plantilla
+test concistency	workflow	es-es	Probar consistencia
+test consistency of datas in the database	workflow	es-es	Probar consistencia de los datos en la base de datos
+test local installation	workflow	es-es	Probar instalación local
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	es-es	El directorio /workflow no existe y no se pudo crear. Por favor, pida a su administrador que compruebe la configuración global
+the activity was not completed	workflow	es-es	No se completó la actividad
+the default user will only be set if he is mapped to a role on the activity	workflow	es-es	Sólo se establecerá el usuario predeterminado si tiene asignado un rol en la actividad
+the following items must be corrected to be able to activate this process	workflow	es-es	Deben corregirse los siguientes elementos para poder activar este proceso
+the instance title is shown on top of the form	admin	es-es	El título de la instancia se muestra en la parte superior del formulario
+the label you want	workflow	es-es	la etiqueta que desea
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	es-es	El agente mail_smtp de flujos del trabajo no puede cargar la configuración SMTP
+there are no activities available	workflow	es-es	No hay actividades disponibles
+there are no config value defined	workflow	es-es	No hay definido un valor de configuración
+there are no instances available	workflow	es-es	No hay instancias disponibles
+there are no mappings defined for this process	workflow	es-es	No hay mapeos definidos para este proceso
+there are no process available	workflow	es-es	No hay procesos disponibles
+there are no processes	workflow	es-es	No hay procesos
+there are no processes available	workflow	es-es	No hay procesos disponibles
+there are no processes defined	workflow	es-es	No hay procesos definidos
+there are no processes with the current filter	workflow	es-es	No hay procesos con el filtro actual
+there are no properties available	workflow	es-es	No hay propiedades disponibles
+there are no roles defined for this process	workflow	es-es	No hay roles definidos para este proceso
+there are no transitions defined	workflow	es-es	No hay transiciones definidas
+there are no user activites available	workflow	es-es	No hay actividades de usuario disponibles
+there are no workitems available	workflow	es-es	No hay elementos de trabajo disponibles
+there are some undefined preferences associated with this form : %1	workflow	es-es	hay algunas preferencias sin definir asociadas con este formulario: %1
+there is an unknown user or group #%1 in role mappings	workflow	es-es	Hay un usuario o grupo desconocido nº%1 en los mapeos de rol
+they were problems at the compilation of the source:	workflow	es-es	Hubo problemas con la compilación del código fuente:
+this activity for this instance is actually avaible for you.	workflow	es-es	Esta actividad para esta instancia actualmente está disponible para usted.
+this activity for this instance is actually only avaible for you.	workflow	es-es	Esta actividad para esta instancia sólo está disponible actualmente para usted.
+this activity for this instance is not specifically assigned to you.	workflow	es-es	Esta actividad para esta instancia no está asignada específicamente a usted
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	es-es	Este agente proporciona a la actividad la posibilidad de enviar un mensaje SMTP (correo electrónico)
+this form will test your local workflow installation to detect potential issues	workflow	es-es	Este formulario realizará una prueba en su instalación local de flujos de trabajo para detectar problemas potenciales
+this is the first screen shown when you click on the workflow application icon	workflow	es-es	Esta es la primera pantalla que se muestra al pulsar en el icono de la aplicación flujos de trabajo
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	es-es	Este proceso tiene una actividad de vista. El acceso en modo vista se concede sólo para esta actividad de vista.
+this process has no end activity	workflow	es-es	este proceso no tiene actividad de fin
+this will automatically release the instance when leaving an activity without completing	admin	es-es	Esto liberará automáticamente la instancia al abandonar una actividad sin completarla
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	es-es	Esto mostrará un pie de actividad cuando cualquier actividad se ejecute con información relacionada con el motor de flujos de trabajo
+to	workflow	es-es	A
+to:	workflow	es-es	Para:
+transition	workflow	es-es	transición
+transition mode	workflow	es-es	modo de transición
+transition to %1	workflow	es-es	transición a %1
+transition waiting for human interaction	workflow	es-es	transición esperando interacción humana
+transitions	workflow	es-es	transiciones
+transitions removed successfully	workflow	es-es	Las transiciones se han eliminado correctamente
+type	workflow	es-es	tipo
+type:	workflow	es-es	tipo:
+unknow fix instruction :%1	workflow	es-es	instrucción de corrección desconocida: %1
+unknown instruction from the workflow engine: %1	workflow	es-es	instrucción desconocida para el motor de flujo del trabajo: %1
+unknown status	workflow	es-es	estado desconocido
+update	workflow	es-es	actualizar
+upload file	workflow	es-es	Subir fichero
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	es-es	Usar <a href="%1">EmailAdmin</a> para crear perfiles de correo
+use automatic parsing	common	es-es	Usar reconocimiento automático
+use default	workflow	es-es	Usar predeterminado
+use existing roles	workflow	es-es	Usar roles existentes
+user	workflow	es-es	Usuario
+user #%1 is associated with a non-existent role #%2	workflow	es-es	El usuario nº%1 está asociado con un rol inexistente nº%2
+user activities	workflow	es-es	Actividades del usuario
+user instances	workflow	es-es	Instancias del usuario
+user instances form: columns	workflow	es-es	Formulario de instancias de usuario: columnas
+user instances form: filters and actions	workflow	es-es	Formulario de instancias de usuario: filtros y acciones
+user is not authorized to delete aborted instances	workflow	es-es	El usuario no está autorizado a borrar las instancias abortadas
+user is not authorized to delete instances	workflow	es-es	El usuario no está autorizado a borrar instancias
+user processes	workflow	es-es	Procesos del usuario
+user/group	workflow	es-es	Usuario/Grupo
+user:	workflow	es-es	usuario:
+users can act on activity before its execution with form and after by sending it to the next activity	workflow	es-es	Los usuarios pueden actuar en la actividad antes de su ejecución con el formulario y después enviándolo a la siguiente actividad
+users/groups	workflow	es-es	Usuarios/Grupos
+valid	workflow	es-es	Válido
+valid process	workflow	es-es	Validar proceso
+valid:	workflow	es-es	Válido:
+validity:	workflow	es-es	Validez:
+value	workflow	es-es	Valor
+version	workflow	es-es	Versión
+view details	workflow	es-es	ver detalles
+view this instance	workflow	es-es	Ver esta instancia
+view workitem	workflow	es-es	Ver elemento de trabajo
+warning this filter override all others filters	workflow	es-es	aviso: este filtro ignora todos los demás filtros
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	es-es	aviso: al usar este botón eliminará definitivamente todas las instancias abortadas Y su historial (elementos de trabajo) para el proceso seleccionado.
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	es-es	aviso: al usar este botón eliminará definitivamente todas las instancias Y su historial (elementos de trabajo) para el proceso seleccionado, cualquiera que sea su estado.
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	es-es	No podemos ejecutar esta actividad. Puede que la instancia o esta actividad ya no exista.
+we were not able to build the message	workflow	es-es	No pudimos construir el mensaje
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	es-es	Cuando se está en modo avanzado, ¿debemos mostrar las acciones avanzadas por defecto (continuar, excepción, tomar, etc)?
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	es-es	Cuando hay múltiples opciones de envío, dibujamos un cuadro de selección con un único botón de envío en vez de múltiples botones
+when to send the message:	workflow	es-es	Cuándo enviar el mensaje:
+workflow	common	es-es	Flujos de trabajo
+workflow configuration	admin	es-es	Configuración de flujos de trabajo
+workflow navigation	workflow	es-es	Navegación por los flujos de trabajo
+workflow preferences	workflow	es-es	Preferencias del flujos de trabajo
+workflow site configuration	workflow	es-es	Configuración del sitio de flujos de trabajo
+workitem information	workflow	es-es	Información del elemento de trabajo
+workitems	workflow	es-es	Elementos de trabajo
+you are not allowed to abort instance %1	workflow	es-es	No tiene permiso para abortar la instancia %1
+you are not allowed to exception instance %1	workflow	es-es	No tiene permiso para una excepción en la instancia %1
+you are not allowed to grab instance %1	workflow	es-es	No tiene permiso para tomar la instancia %1
+you are not allowed to release instance %1	workflow	es-es	No tiene permiso para liberar la instancia %1
+you are not allowed to restart instance %1	workflow	es-es	No tiene permiso para reiniciar la instancia %1
+you are not allowed to resume instance %1	workflow	es-es	No tiene permiso para continuar la instancia %1
+you are not allowed to send instance %1	workflow	es-es	No tiene permiso para enviar la instancia %1
+you can use special values with this mail agent:	workflow	es-es	Puede usar valores especiales con este agente de correo:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	es-es	Ya no tiene permiso para volver a ejecutar esta actividad. Quizás sea un problema de acceso concurrente, refresque sus datos.
+you don't have the rights necessary to exception instance %1	workflow	es-es	No tiene los permisos necesarios para crear una excepción en la instancia %1
+you have not permission to execute this activity	workflow	es-es	No tiene permiso para ejecutar esta actividad
+you were not allowed to complete the activity	workflow	es-es	No tiene permiso para completar la actividad
Index: /sandbox/workflow/branches/993/setup/phpgw_it.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_it.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_it.lang	(revision 795)
@@ -0,0 +1,503 @@
+#	workflow	it	n.
+%1 aborted	workflow	it	%1 annullata
+%1 active	workflow	it	%1 attiva
+%1 completed	workflow	it	%1 completata
+%1 configuration	workflow	it	Configurazione di %1
+%1 days, %2:%3:%4	workflow	it	%1 giorni, %2:%3:%4
+%1 exception	workflow	it	%1 eccezione
+%1 menu	workflow	it	Menu %1
+%1 monitoring	workflow	it	Monitorizzazione %1
+%1 processes (%2 active) (%3 being_run)	workflow	it	%1 processi (%2 attivi) (%3 in_esecuzione)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	it	la directory /workflow non esiste e non può essere creata, prego chiedi all'amministratore di controllare la configurazione globale
+<strong>%owner%</strong> is the instance owner email	workflow	it	<strong>%proprietario%</strong> è l'email del proprietario dell'istanza
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	it	<strong>%proprietà_XX%</strong> è il contenuto della proprietà XX dell'istanza
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	it	<strong>%ruolo_XX%</strong> sono le email di tutti gli utenti mappati al ruolo XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	it	<strong>%ruoli%</strong> sono le email di tutti gli utenti mappati a qualunque ruolo di questa attività
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	it	<strong>%firma%</strong> è la firma dell'agente definita nella configurazione del processo
+<strong>%user%</strong> is the instance user email	workflow	it	<strong>%utente%</strong> è l'email dell'utente dell'istanza
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	it	<strong>%utente_XX%</strong> è l'email dell'account XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	it	viene visualizzato un messaggio del tipo 'attendere prego' quando viene caricato il form per l'attività. Utile per i task lunghi
+abort instance	workflow	it	annulla istanza
+abort this instance	workflow	it	Annulla questa istanza
+aborted	workflow	it	annullato
+access denied for user %1 on activity %2, no role	workflow	it	Accesso negato per l'utente %1 all'attività %2, nessun ruolo
+act	workflow	it	att
+act. status	workflow	it	Stato Att.
+act. status:	workflow	it	Stato Att:
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	it	L'azione %1 è impossibile se non c'è un'attività e un'istanza progettata per essa!
+action %1 is impossible, another user is already in place	workflow	it	L'azione %1 è impossibile, un altro utente è già in posizione
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	it	L'azione %1 è impossibile, non ci sono utenti assegnati a questa attività per questa istanza
+action %1 needs an activity and activity %2 does not exists	workflow	it	L'azione %1 necessita di un'attività e l'attività %2 non esiste
+action %1 needs an instance and instance %2 does not exists	workflow	it	L'azione %1 necessita un'istanza e l'istanza %2 non esiste
+actions	workflow	it	Azioni
+actions right options	common	it	Opzioni Diritti Azione
+activate	workflow	it	attiva
+active	workflow	it	Attivo
+active:	workflow	it	attivo:
+activities	workflow	it	Attività
+activities selection	workflow	it	Selezione attività
+activities updated	workflow	it	Attività aggiornate
+activity	workflow	it	attività
+activity  status	workflow	it	Stato Attività
+activity %1	workflow	it	attività %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	it	L'attività %1 (n.%2) è associata a un processo inesistente (n.%3)
+activity %1 code is not avaible	workflow	it	Il codice dell'attività %1 non è disponibile
+activity %1 is interactive but has no role assigned	workflow	it	L'Attività %1 è Interattiva ma non ha ruoli assegnati
+activity %1 is interactive so it must use the $instance->complete() method	workflow	it	L'Attività %1 è interattiva cosicché deve usare il metodo $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	it	L'Attività %1 è non-interattiva e non-autoindirizzante ma non ha ruoli assegnati
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	it	L'attività %1 è non-interattiva, quindi non deve usare il metodo $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	it	L'attività %1 è standalone e sta usando $instance object
+activity %1 is standalone but has transitions	workflow	it	L'attività %1 è standalone ma ha transizioni
+activity %1 is standalone or view but has transitions	workflow	it	L'attività %1 è standalone o vista ma ha transizioni
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	it	L'attività %1 è switch, quindi deve usare il metodo $instance->setNextActivity($actname)
+activity %1 is view and is using the $instance object in write mode	workflow	it	L'attività %1 è vista e sta utilizzando l'oggetto $instance in modalità scrittura
+activity agent removed	workflow	it	Agente attività rimosso
+activity completed	workflow	it	Attività completata
+activity failure	workflow	it	fallimento attività
+activity in inexistent process	workflow	it	Attività in processo inesistente
+activity is waiting for pending transitions	workflow	it	l'attività è in attesa di transizioni in corso
+activity name already exists	workflow	it	Il nome Attività esiste già
+activity role #%1 removed	workflow	it	Ruolo attività #%1 rimosso
+activity role removed	workflow	it	Ruolo Attività rimosso
+activity saved	workflow	it	Attività salvata
+activity start not avaible, no corresponding activity was found.	workflow	it	inizio attività non disponibile, nessuna attività corrispondente trovata.
+activity start not set, no corresponding activity was found.	workflow	it	inizio attività non impostato, nessuna attività corrispondente trovata.
+activity status not avaible, no corresponding activity was found.	workflow	it	stato attività non disponibile, nessuna attività corrispondente trovata.
+activity:	workflow	it	attività:
+add a transition	workflow	it	Aggiungi una transizione
+add aborted instances	workflow	it	Aggiungi istanze interrotte
+add advanced actions	workflow	it	Aggiungi azioni avanzate
+add agent	workflow	it	Aggiungi agente
+add completed instances	workflow	it	Aggiungi istanze completate
+add instances in exception	workflow	it	Aggiungi istanze in eccezione
+add new	workflow	it	aggiungi nuovo
+add new role	workflow	it	Aggiungi nuovo ruolo
+add or edit a process	workflow	it	Aggiungi o modifica un processo
+add or edit a role	workflow	it	Aggiungi o modifica un ruolo
+add or edit an activity	workflow	it	Aggiungi o modifica un'attività
+add property	workflow	it	Aggiungi proprietà
+add role	workflow	it	Aggiungi ruolo
+add role to process	workflow	it	Aggiungi ruolo al processo
+add transition	workflow	it	aggiungi transizione
+add transitions	workflow	it	Aggiungi transizioni
+add transitions from	workflow	it	Aggiungi transizioni da
+add transitions to	workflow	it	Aggiungi transizioni a
+admin instance	workflow	it	Gestione Istanza
+admin process activities	workflow	it	Gestione Attività Processo
+admin process roles	workflow	it	Gestione Ruoli Processo
+admin processes	workflow	it	Gestione Processi
+admin processes sources	workflow	it	Gestione Sorgenti Processi
+administer instances	admin	it	gestisci istanze
+administer processes	admin	it	gestisci processi
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	it	L'agente n.%1 di tipo %2 è associato ad una attività inesistente n.%3
+agent #%1 of type %2 is not linked with an activity	workflow	it	L'agente n.%1 di tipo %2 non è collegato con un'attività
+agent associated with inexistent activity	workflow	it	Agente associato ad un'attività inesistente
+agent without activity	workflow	it	Agente senza attività
+agents assigned to this activity	workflow	it	Agenti assegnati a questa attività
+all	workflow	it	tutto
+always show advanced actions	workflow	it	Mostra sempre azioni avanzate
+always show advanced mode	workflow	it	Mostra sempre modalità avanzata
+assign me this activity	workflow	it	Assegnami questa attività
+at least one email address cannot be validated.	workflow	it	almeno un indirizzo email non può essere convalidato
+auto routed	workflow	it	Auto-instradata
+auto-release on leaving activity	common	it	auto-rilascio in uscita attività
+automatic	workflow	it	Automatico
+autorouted activities does not need to be sent by any user after their execution	workflow	it	Le attività auto-instradanti non necessitano di essere inviate da un utente dopo la loro esecuzione
+bad parameter for setagents, the parameter should be an array	workflow	it	parametro non corretto per setAgents, il parametro deve essere un array
+bad role type	workflow	it	Tipo ruolo errato
+bad user	workflow	it	Utente errato
+base directory does not exist, please ask adminstrator to check the global configuration	common	it	La directory base non esiste, prego chiedi all'amministratore di controllare la configurazione globale.
+bcc:	workflow	it	Ccn:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	it	Fai attenzione alle attività interattive, la partenza e la fine di queste attività sono multiple
+being run	workflow	it	in esecuzione
+by running theses links you will create new instances of the related process.	workflow	it	Cliccando questi link creerai delle nuove istanze dei processi correlati.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	it	Impossibile aggiungere transizione. Solo le attività split o switch possono avere più di una transizione in uscita
+cannot add transition. only split activities can have more than one outbound transition	workflow	it	Impossibile aggiungere transizione. Solo le attività split possono avere più di una transizione in uscita
+cannot create compiled file %1	workflow	it	impossibile creare il file compilato %1
+cannot retrieve the user running the security check	workflow	it	Impossibile recuperare l'utente che sta eseguendo il controllo di sicurezza
+cannot run the activity	workflow	it	Impossibile eseguire l'attività
+cannot run the activity without her process	workflow	it	Impossibile eseguire l'attività senza il suo processo
+cannot run the activity without instance	workflow	it	Impossibile eseguire l'attività senza istanza
+cannot run unknown activity	workflow	it	Impossibile eseguire attività sconosciuta
+cc:	workflow	it	Cc:
+circular reference found some activity has a transition leading to itself	workflow	it	Riferimento circolare trovato: qualche attività ha una transizione che riconduce a sé stessa
+circular reference found. some activity has a transition leading to itself	workflow	it	E' stato trovato un riferimento circolare. Qualche attività ha una transizione che conduce a sé stessa.
+cleanup aborted instances	admin	it	ripulisci istanze annullate
+cleanup actions	workflow	it	azioni di pulitira
+close and get back later	workflow	it	Chiudi e ritorna più tardi
+close printer friendly mode	workflow	it	Chiudi modalità anteprima stampa
+code	workflow	it	codice
+column activity status in instance lists	workflow	it	Colonna Stato Attività in elenco istanze
+column category in instance lists	workflow	it	Colonna Categoria in elenco istanze
+column instance id in instance lists	workflow	it	Colonna ID Istanza in elenco istanze
+column instance name in instance lists	workflow	it	Colonna Nome Istanza in elenco istanze
+column instance status in instance lists	workflow	it	Colonna Stato Istanza in elenco istanze
+column owner in instance lists	workflow	it	Colonna Proprietario in elenco istanze
+column priority in instance lists	workflow	it	Colonna Priorità in elenco istanze
+column process name in instance lists	workflow	it	Colonna Nome Processo in elenco istanze
+column start date in instance lists	workflow	it	Colonna data inizio in elenco istanze
+compilation	workflow	it	Compilazione
+compiling activity %1 : %2	workflow	it	compilazione attività %1 : %2
+complete	workflow	it	Completa
+complete cleanup of aborted instances done	workflow	it	pulizia completa delle istanze annullate eseguita
+complete cleanup of all instances done	workflow	it	pulizia completa di tutte le istanze completate
+completed	workflow	it	completata
+config values	common	it	Configura valori
+confirm delete	workflow	it	Conferma Elimina
+consult %1 to get the default values:	workflow	it	Consulta %1 per ottenere i valori predefiniti:
+couldn't add transition	workflow	it	Impossibile aggiungere transizione
+create	workflow	it	crea
+created	workflow	it	Creato
+date:	workflow	it	data:
+default config values	common	it	Valori di configurazione predefiniti
+default next user	workflow	it	Utente successivo predefinito
+default owner	workflow	it	Proprietario predefinito
+default settings for processes	admin	it	Impostazioni predefinite per i processi
+default user	workflow	it	Utente Predefinito
+delete selected	workflow	it	Elimina selezione
+delete transition	workflow	it	elimina transizione
+deletion successful	workflow	it	Cancellazione effettuata
+delition successful	workflow	it	Cancellazione effettuata
+description	workflow	it	Descrizione
+display please wait message	common	it	mostra messaggio di attesa
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	it	Vuoi lo stato attività in elenco istanze. La maggior parte del tempo è "in esecuzione" ma se utilizzi transizioni non-auto-instradate avrai alcune attività completate.
+don't move	workflow	it	Non spostare
+draw roles	common	it	traccia i ruoli
+draw roles on the graph beside activity name like [that]	admin	it	traccia i ruoli sul grafico accanto al nome dell'attività come [quello]
+duration	workflow	it	Durata
+empty agent type	workflow	it	tipo agente vuoto
+end	workflow	it	fine
+end activity is not reachable from start activity	workflow	it	L'attività finale non è raggiungibile dall'attività iniziale
+ended	workflow	it	terminato
+enter an activity name	workflow	it	Inserisci un nome per l'attività
+error: removing was not done	workflow	it	errore: rimozione non effettuata
+exception	workflow	it	eccezione
+exception instance	workflow	it	Istanza eccezione
+exception raised by %1 %2: %3	workflow	it	eccezione sollevata da %1 %2: %3
+exception resumed by %1 %2: %3	workflow	it	eccezione ripresa da %1 %2: %3
+exception this instance	workflow	it	Eccezione per questa istanza
+exceptions	workflow	it	eccezioni
+execute this activity	workflow	it	Esegui questa attività
+export	workflow	it	Esporta
+failed to create workitem	workflow	it	fallita creazione unità lavorativa
+failed to execute automatic activity	workflow	it	fallita esecuzione attività automatica
+failed to obtain lock on %1 table	workflow	it	fallito blocco su tabella %1
+failed to obtain lock on instances table	workflow	it	fallito blocco su tabella istanze
+failed to obtain lock on instances_activities table	workflow	it	fallito blocco su tabella istanze_attività
+failed to record instance properties	workflow	it	fallita registrazione proprietà istanza
+failed to synchronize instance data with the database	workflow	it	fallita sincronizzazione dati istanza con database
+failure	workflow	it	fallimento
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	it	Errore Fatale: nextActivity non corrisponde a nessuna candidata nell'instradamento dell'attività Switch
+fatal error: non-deterministic decision for autorouting activity	workflow	it	Errore Fatale: decisione non-deterministica per instradamento attività
+fatal error: setting next activity to an unexisting activity	workflow	it	Errore fatale: impostazione attività successiva verso un'attività inesistente
+fatal error: trying to send an instance to an activity but no transition found	workflow	it	Errore Fatale: cercando di inviare un'istanza ad una attività, ma nessuna transizione trovata
+filter	workflow	it	Filtro
+filter instance by id	workflow	it	filtra istanze per id
+fix	workflow	it	Fissa
+fix concistency for selected rows	workflow	it	Fissa Consistenza per le righe selezionate
+font size	workflow	it	grandezza font
+from	workflow	it	Da
+from:	workflow	it	Da:
+get back to global activities	workflow	it	torna alle attività globali
+get back to instance creation	workflow	it	torna alla creazione dell'istanza
+get property	workflow	it	Ottieni proprietà
+global activities	workflow	it	Attività globali
+global workflow preferences	workflow	it	Preferenze Workflow Globali
+go	workflow	it	vai
+go to same activities for other instances of this process	workflow	it	vai alle stesse attività di altre istanze per questo processo
+go to same process activities	workflow	it	vai alle attività dello stesso processo
+go to the actual state of this instance	workflow	it	vai allo stato attuale di questa istanza
+grab instance	workflow	it	afferra istanza
+grant access to the administration and development of workflow processes and activities.	admin	it	Permetti l'accesso alla gestione e allo sviluppo di processi e attività workflow.
+grant access to the administration of workflow elements	admin	it	Permetti l'accesso alla gestione degli elementi di workflow
+grant access to the administration of workflow instances in monitor screens	admin	it	Permetti l'accesso alla gestione delle istanze di workflow in videate monitoraggio
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	admin	it	Permetti l'accesso alla pulizia/eliminazione delle istanze di workflow annullate in videate monitoraggio
+grant access to the monitoring of workflow elements	admin	it	Permetti l'accesso alla monitorizzazione degli elementi di workflow
+graph	workflow	it	Grafico
+graphic options	common	it	Opzioni grafico
+group	workflow	it	Gruppo
+id	workflow	it	Id
+if automatic parsing is disabled next options will be useless	admin	it	Se il parsing automatico è disabilitato, le opzioni successive sono inutili
+if not in debug mail_smtp agent would have sent this email:	workflow	it	se non fosse stato in debug l'agente mail_smtp avrebbe inviato questa email:
+if user is in a role for an activity he will have the right to abort the related instance	admin	it	se un utente ha un ruolo in un'attività, avrà i diritti per annullare l'istanza correlata
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	it	se un utente ha un ruolo in un'attività, avrà i diritti per sollevare un'eccezione o riprendere l'istanza correlata
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	it	se l'utente è in un ruolo per un'attività avrà il diritto di rilasciare (de-assegnare) la relativa istanza
+if:setnextact	workflow	it	If:SetNextact
+import aborted	workflow	it	Importazione annullata
+import successfull	workflow	it	Importazione effettuata
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	it	Nella mappatura dei ruoli l'utente n°%1 è specificato come un "%2" ma è FORSE un "%3"
+inactive	workflow	it	Inattiva
+inst.	workflow	it	Ist.
+inst. status	workflow	it	Stato Istanza
+instance	workflow	it	Istanza
+instance %1	workflow	it	istanza %1
+instance history	workflow	it	Cronologia Istanza
+instance properties	workflow	it	Proprietà Istanza
+instance:	workflow	it	istanza:
+instance: %1 (process: %2)	workflow	it	Istanza: %1 (processo: %2)
+instances	workflow	it	Istanze
+instances selection	workflow	it	Selezione istanze
+int.	workflow	it	Int.
+interactive	workflow	it	Interattiva
+interactive activities show form before being executed	workflow	it	Le attività interattive mostrano un modulo prima di essere eseguite
+interactive:	workflow	it	interattiva:
+interactivity	workflow	it	Interattività
+invalid	workflow	it	non valido
+invalid process	workflow	it	Processo non valido
+invalid role name	workflow	it	Nome ruolo non valido
+is active	workflow	it	è attiva
+it seems this activity for this instance is not assigned to you anymore.	workflow	it	Questa attività per questa istanza non è più assegnata a te.
+join	workflow	it	unisci
+list of activities	workflow	it	Elenco attività
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	it	elenco di tutte le istanze con informazioni sullo status attuale, attività e link alla gestione di queste istanze
+list of instances	workflow	it	Elenco istanze
+list of mappings	workflow	it	Elenco mappature
+list of processes	workflow	it	Elenco processi
+list of processes (%1)	workflow	it	Elenco processi (%1)
+list of transitions	workflow	it	Elenco transizioni
+list of workitems	workflow	it	Elenco Entità Lavorative
+manual	workflow	it	Manuale
+map	workflow	it	mappa
+map users/groups to roles	workflow	it	Mappa utenti/gruppi ai ruoli
+mapping to inexistent role	workflow	it	Mappatura a ruolo inesistente
+mappings deleted	workflow	it	Mappature eliminate
+message:	workflow	it	Messaggio:
+monitor activities	workflow	it	Monitorizza Attività
+monitor instance	workflow	it	monitorizza istanza
+monitor instances	workflow	it	Monitorizza Istanze
+monitor processes	workflow	it	Monitorizza Processi
+monitor this instance	workflow	it	Monitorizza questa istanza
+monitor work items	workflow	it	Monitorizza Entità Lavorative
+monitor workitems	workflow	it	Monitorizza entità lavorative
+monitoring	admin	it	Monitorizzazione in corso
+monitors	workflow	it	Monitor
+more options?	workflow	it	altre opzioni?
+my activities	workflow	it	Mie Attività
+my instances	workflow	it	Mie Istanze
+my processes	workflow	it	Miei Processi
+name	workflow	it	Nome
+new instance	workflow	it	Nuova Istanza
+new major	workflow	it	Nuova maggiore
+new major version created	workflow	it	creata nuova versione maggiore
+new mapping added	workflow	it	Nuova mappatura aggiunta
+new minor	workflow	it	Nuova minore
+new minor version created	workflow	it	creata nuova versine minore
+new transition added	workflow	it	Nuova transizione aggiunta
+next activity	workflow	it	attività seguente
+next user:	workflow	it	Utente seguente:
+no activites	workflow	it	Nessuna attività
+no activity indicated	workflow	it	Nessuna attività indicata
+no agents associated with this activity	workflow	it	Nessun agente associato a questa attività
+no circular transitions allowed.	workflow	it	Transizioni circolari non permesse.
+no corresponding activity was found.	workflow	it	nessuna attività corrispondente trovata.
+no inconcistency detected	workflow	it	nessuna inconsistenza individuata
+no instance avaible	workflow	it	nessuna istanza disponibile
+no instance given, nothing to show	workflow	it	nessuna istanza data, nulla da mostrare
+no instance indicated	workflow	it	Nessuna istanza indicata
+no process indicated	workflow	it	Nessun processo indicato
+no properties defined	workflow	it	Nessuna proprietà definita
+no roles	workflow	it	nessun ruolo
+no roles asociated with this activity	workflow	it	Nessun ruolo associato a questa attività
+no routage	workflow	it	nessun instradamento
+no scan done	workflow	it	nessuna scansione eseguita
+no transitions allowed for standalone or view activities	workflow	it	Nessuna transizione permessa per attività standalone o vista
+no work item indicated	workflow	it	Nessuna Entità Lavorativa indicata
+nobody	workflow	it	Nessuno
+not defined	workflow	it	non definito
+or import a process	workflow	it	O importa un processo
+owner	workflow	it	Proprietario
+owner of the instance will have the right to abort the instance at any time	admin	it	il proprietario dell'istanza avrà il diritto di annullare l'istanza in qualunque momento
+owner of the instance will have the right to exception or resume the instance at any time	admin	it	il proprietario dell'istanza avrà il diritto di sollevare un'eccezione o riprendere un'istanza in qualunque momento
+owner:	workflow	it	Proprietario:
+ownership give abort right	common	it	proprietà dà diritto di annullare
+ownership give exception right	common	it	proprietà dà diritto di sollevare eccezione
+ownership give release right	common	it	proprietà dà diritto di rilascio
+please wait, task in progress ...	workflow	it	Prego attendere, elaborazione in corso ...
+pr.	workflow	it	Pr.
+priority level:	workflow	it	Livello priorità:
+process	workflow	it	Processo
+process %1	workflow	it	processo %1
+process %d has been activated	workflow	it	Il processo %d è stato attivato
+process %d has been deactivated	workflow	it	Il processo %d è stato disattivato
+process %s %s imported	workflow	it	Processo %s %s importato
+process %s has been created	workflow	it	Il processo %s è stato creato
+process %s has been updated	workflow	it	Il processo %s è stato aggiornato
+process %s removed	workflow	it	Processo %s rimosso
+process activities	workflow	it	Attività Processo
+process alone	workflow	it	Processo solo
+process does not have a start activity	workflow	it	Il processo non ha un'attività iniziale
+process does not have exactly one end activity	workflow	it	Il processo non ha esattamente una attività finale
+process form	workflow	it	Modulo Processo
+process name	workflow	it	Nome Processo
+process name already exists	workflow	it	Il nome processo esiste già
+process roles	workflow	it	Ruoli Processo
+process saved	workflow	it	Processo salvato
+process transitions	workflow	it	Transizioni Processo
+process version:	workflow	it	versione processo:
+process:	workflow	it	processo:
+processes	workflow	it	Processi
+properties	workflow	it	Proprietà
+property	workflow	it	Proprietà
+property %1 already exists	workflow	it	la proprietà %1 esiste già
+property %1 not found	workflow	it	proprietà %1 non trovata
+quit without saving	workflow	it	Esci Senza Salvare
+read-only	workflow	it	sola-lettura
+release access to this activity	workflow	it	Rilascia accesso a questa attività
+release activity for this instance	workflow	it	rilasci l'attività per questa istanza
+release instance	workflow	it	rilascia istanza
+reload filter	workflow	it	Ricarica filtro
+remove active instances	workflow	it	Rimuovi istanze attive
+remove all instances for this process	workflow	it	rimuovi tutte le istanze per questo processo
+remove selected roles	workflow	it	rimuovi ruoli selezionati
+replyto:	workflow	it	Rispondi A:
+restart	workflow	it	riavvia
+restart activity	workflow	it	riavvia attività
+resume this exception instance	workflow	it	Riprendi questa istanza eccezione
+role	workflow	it	Ruolo
+role %1 is not mapped	workflow	it	Il ruolo %1 non è mappato
+role added to activity	workflow	it	Ruolo aggiunto all'attività
+role added to process	workflow	it	Ruolo aggiunto al processo
+role give abort right	common	it	il ruolo dà diritto di annullare
+role give exception right	common	it	il ruolo dà diritto di sollevare eccezione
+role give release right	common	it	il ruolo dà diritto di rilascio
+role in inexistent process	workflow	it	Ruolo in processo inesistente
+role mapping in inexistent process	workflow	it	Mappatura Ruolo in processo inesistente
+role name	workflow	it	Nome Ruolo
+role not saved (maybe a name collision)	workflow	it	Ruolo non salvato (probabile collisione di nomi)
+role process inconcistency in mappings	workflow	it	Inconsistenza Ruolo Processo in mappature
+role saved	workflow	it	Ruolo salvato
+roles	workflow	it	Ruoli
+roles assigned to this activity	workflow	it	Ruoli assegnati a questa attività
+roles deleted	workflow	it	Ruoli cancellati
+routing	workflow	it	Instradamento
+routing:	workflow	it	instradamento:
+run	workflow	it	esegui
+run activity	workflow	it	esegui attività
+run instance	workflow	it	esegui istanza
+running	workflow	it	in corso
+running activities options	common	it	Opzioni attività in corso
+running activity	workflow	it	Attività in corso
+scan activities	workflow	it	Scansiona attività
+scan agents	workflow	it	Scansiona agenti
+scan instances	workflow	it	Scansiona istanze
+scan processes	workflow	it	Scansiona processi
+scan roles	workflow	it	Scansiona ruoli
+scan transitions	workflow	it	Scansiona transizioni
+search:	workflow	it	cerca:
+security check: cannot understand asked action	workflow	it	Controllo di sicurezza: Non comprensibile azione richiesta
+select a transition to remove	workflow	it	Seleziona una transizione da rimuovere
+select source	workflow	it	seleziona sorgente
+send after interactive activity is completed	workflow	it	invia al completamento dell'attività interattiva
+send all to	workflow	it	Invia tutto a
+send an email	workflow	it	Invia email
+send instance	workflow	it	invia istanza
+send this instance to the next activity	workflow	it	Invia questa istanza all'attività successiva
+send transition	workflow	it	invia transizione
+send when the activity is ending	workflow	it	invia quando l'attività sta finendo
+send when the activity is starting	workflow	it	invia quando l'attività sta iniziando
+set next act	workflow	it	Imposta atto Seguente
+set next user	workflow	it	Imposta utente Seguente
+set property	workflow	it	Imposta proprietà
+shared code	workflow	it	Codice condiviso
+show activity info zone	common	it	mostra area info dell'attività
+show activity title	common	it	mostra titolo attività
+show code	workflow	it	mostra codice
+show instance name	common	it	Mostra nome istanza
+show instance owner	common	it	Mostra proprietario istanza
+show multiple submit as select	common	it	mostra invii multipli come selezione
+show template	workflow	it	mostra template
+size of the font used on the graph 12 should be a good default value	admin	it	la grandezza del font utilizzata sul grafico (12) dovrebbe essere un buon valore di default
+something was wrong while creating the new major version	workflow	it	qualcosa non ha funzionato durante la creazione della nuova versione maggiore
+something was wrong while creating the new minor version	workflow	it	qualcosa non ha funzionato durante la creazione della nuova versione minore
+source saved	workflow	it	Sorgente salvata
+split	workflow	it	dividi
+standalone	workflow	it	standalone
+start	workflow	it	Inizia
+start activity	workflow	it	Inizia attività
+start process	workflow	it	inizia processo
+started	workflow	it	Iniziato
+started:	workflow	it	iniziato:
+starting page	workflow	it	Pagina iniziale
+status	workflow	it	Stato
+status:	workflow	it	stato:
+stop	workflow	it	stop
+subject:	workflow	it	Oggetto:
+switch	workflow	it	scambia
+switch construct	workflow	it	Scambia costrutto
+template	workflow	it	template
+test concistency	workflow	it	Test Consistenza
+test consistency of datas in the database	workflow	it	Test Consistenza dei dati nel database
+test local installation	workflow	it	Test installazione locale
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	it	La directory /workflow non esiste e non può essere creata. Prego chiedi al tuo amministratore di controllare la configurazione globale
+the activity was not completed	workflow	it	L'attività non è stata completata
+the following items must be corrected to be able to activate this process	workflow	it	Le seguenti entità devono essere corrette per poter attivare questo processo
+the instance title is shown on top of the form	admin	it	il titolo dell'istanza è mostrato nella parte superiore del form
+the label you want	workflow	it	l'etichetta che desideri
+there are no activities available	workflow	it	Non ci sono attività disponibili
+there are no config value defined	workflow	it	Non ci sono valori di configurazione definiti
+there are no instances available	workflow	it	Non ci sono istanze disponibili
+there are no mappings defined for this process	workflow	it	Non ci sono mappature definite per questo processo
+there are no process available	workflow	it	Non ci sono processi disponibili
+there are no processes	workflow	it	Non ci sono processi
+there are no processes available	workflow	it	Non ci sono processi disponibili
+there are no processes defined	workflow	it	Non ci sono processi definiti
+there are no processes with the current filter	workflow	it	Non ci sono processi con il filtro utilizzato
+there are no properties available	workflow	it	Non ci sono proprietà disponibili
+there are no roles defined for this process	workflow	it	Non ci sono ruoli definiti per questo processo
+there are no transitions defined	workflow	it	Non ci sono transizioni definite
+there are no user activites available	workflow	it	Non ci sono attività utente disponibili
+there are no workitems available	workflow	it	Non ci sono entità lavorative disponibili
+there are some undefined preferences associated with this form : %1	workflow	it	ci sono delle preferenze non definita associate a questo form: %1
+this activity for this instance is actually avaible for you.	workflow	it	Questa attività per questa istanza, al momento, è disponibile per te.
+to	workflow	it	A
+to:	workflow	it	A:
+transition	workflow	it	transizione
+transition mode	workflow	it	modalità transizione
+transition to %1	workflow	it	transizione a %1
+transitions	workflow	it	transizioni
+transitions removed successfully	workflow	it	Transizioni rimosse con successo
+type	workflow	it	tipo
+type:	workflow	it	tipo:
+unknown instruction from the workflow engine: %1	workflow	it	istruzione sconosciuta dal motore workflow: %1
+unknown status	workflow	it	stato sconosciuto
+update	workflow	it	aggiorna
+upload file	workflow	it	Carica file
+use automatic parsing	common	it	utilizza parsing automatico
+use default	workflow	it	Usa Predefinito
+use existing roles	workflow	it	Usa ruoli esistenti
+user	workflow	it	Utente
+user activities	workflow	it	Attività Utente
+user instances	workflow	it	Istanze Utente
+user instances form: columns	workflow	it	Maschera Istanze Utente: colonne
+user instances form: filters and actions	workflow	it	Maschera Istanze Utente: filtri e azioni
+user processes	workflow	it	Processi Utente
+user/group	workflow	it	Utente/Gruppo
+user:	workflow	it	utente:
+users/groups	workflow	it	Utenti/Gruppi
+valid	workflow	it	Valido
+valid process	workflow	it	Processo Valido
+valid:	workflow	it	valido:
+validity:	workflow	it	Validità:
+value	workflow	it	Valore
+version	workflow	it	Versione
+view details	workflow	it	visualizza dettagli
+view this instance	workflow	it	Vedi questa istanza
+view workitem	workflow	it	Vedi unità lavorativa
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	it	Non è possibile eseguire questa attività, probabilmente questa istanza o questa attività non esiste più.
+we were not able to build the message	workflow	it	Impossibile costruire il messaggio
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	it	quando sono disponibili opzioni di invio multiplo tracciamo un box di selezione con un solo bottone di invio
+when to send the message:	workflow	it	Quando inviare il Messaggio:
+workflow	common	it	Work-Flow
+workflow configuration	admin	it	Configurazione Workflow
+workflow navigation	workflow	it	Navigazione Workflow
+workflow preferences	workflow	it	Preferenze Workflow
+workflow site configuration	workflow	it	Configurazione Workflow per tutto il sito
+workitem information	workflow	it	Informazione entità lavorative
+workitems	workflow	it	Entità lavorative
+you are not allowed to abort instance %1	workflow	it	Non hai il permesso di annullare l'istanza %1
+you are not allowed to release instance %1	workflow	it	Non hai il permesso di rilasciare l'istanza %1
+you are not allowed to resume instance %1	workflow	it	Non hai il permesso di riprendere l'istanza %1
+you can use special values with this mail agent:	workflow	it	Puoi usare valori speciali con questo agente di posta:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	it	Non hai più il permesso di eseguire questa attività, probabilmente a causa di un problema di accesso simultaneo, effettua un refresh dei dati
+you don't have the rights necessary to exception instance %1	workflow	it	Non hai i diritti necessari per sollevare un'eccezione per l'istanza %1
+you have not permission to execute this activity	workflow	it	Non hai il permesso di eseguire questa attività
Index: /sandbox/workflow/branches/993/setup/phpgw_no.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_no.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_no.lang	(revision 795)
@@ -0,0 +1,486 @@
+#	workflow	no	Nr.
+%1 aborted	workflow	no	%1 abortert
+%1 active	workflow	no	% 1 aktiv
+%1 completed	workflow	no	%1 fullført
+%1 configuration	workflow	no	%1 Konfigurasjon
+%1 days, %2:%3:%4	workflow	no	%1 dager, %2:%3:%4
+%1 exception	workflow	no	%1 unntak
+%1 menu	workflow	no	%1 Meny
+%1 monitoring	workflow	no	%1 overvåkes
+%1 processes (%2 active) (%3 being_run)	workflow	no	%1 prosesser (%2 aktive ) (%3 being_run)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	no	/arbeidsflytskatalogen eksisterer ikke og kunne ikke skapes.  Få edb-ansvarlig til å kontrollere konfigurasjonen.
+<strong>%owner%</strong> is the instance owner email	workflow	no	<strong>%owner%</strong> er e-maildresse til eier av instansen
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	no	<strong>%property_XX%</strong> er innholdet i instansens tilhørigheter XX
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	no	<strong>%role_XX%</strong> er alle emailer til alle brukere mappet til denne rollen XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	no	<strong>%roles%</strong> er emailer fra alle brukere som er mappet til noen rolle ved denne aktiviteten.
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	no	<strong>%signature%</strong> er agentsignaturen definert i prosesskonfigurasjonen
+<strong>%user%</strong> is the instance user email	workflow	no	<strong>%user%</strong> er instansens bruker e-mailadresse
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	no	<strong>%user_XX%</strong> er e-mailadressen til konto XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	no	En Vennligst vent melding vises ved lasting av skjermbildet.  Fint for tunge jobber.
+abort instance	workflow	no	Avbryt instanse
+abort this instance	workflow	no	Avbryt denne instanse
+aborted	workflow	no	Avbrutt
+access denied for user %1 on activity %2, no role	workflow	no	Tilgang nektet for bruker %1 for aktivitet %2, ingen rolle
+act	workflow	no	akt
+act. status	workflow	no	Akt. status
+act. status:	workflow	no	Akt. status :
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	no	Aksjon %1 er ikke mulig så lenge det ikke er tilegnet noen aktivitet eller instanse.
+action %1 is impossible, another user is already in place	workflow	no	Aksjon %1 er ikke mulig, en annen bruker er allerede på plass
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	no	Aksjon %1 er ikke mulig, det er ingen bruker tilknyttet denne aktiviteten for instansen.
+action %1 needs an activity and activity %2 does not exists	workflow	no	Aksjon %1 trenger en aktivitet og aktivitet %2 eksisterer ikke
+action %1 needs an instance and instance %2 does not exists	workflow	no	Aksjon %1 trenger en instanse og instanse %2 eksisterer ikke
+actions	workflow	no	Aksjoner
+actions right options	admin	no	Aksjoner Rettigheter Valg
+activate	workflow	no	aktiver
+active	workflow	no	Aktiv
+active:	workflow	no	aktiv :
+activities	workflow	no	Aktiviteter
+activities selection	workflow	no	Valg av aktiviteter
+activities updated	workflow	no	Aktiviteter oppdatert
+activity	workflow	no	aktivitet
+activity  status	workflow	no	Aktivitetsstatus
+activity %1	workflow	no	aktivitet %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	no	Aktivitet %1 (#%2) er assosiert med en ikke eksisterende prosess (#%3)
+activity %1 code is not avaible	workflow	no	aktivitet %1 kode er ikke tilgjengelig
+activity %1 is interactive but has no role assigned	workflow	no	Aktivitet %1 er interaktiv men har ingen rolle tilknyttet
+activity %1 is interactive so it must use the $instance->complete() method	workflow	no	Aktivitet %1 er interaktiv slik at den må benytte $instance->complete() metode.
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	no	Aktivitet %1 er ikke interaktiv og ikke automatis ført, men har ingen rolle tilordnet
+activity %1 is standalone but has transitions	workflow	no	Aktivitet %1 er frittstående men har overganger
+activity %1 is standalone or view but has transitions	workflow	no	Aktivitet %1 er frittstående eller vises men har overganger
+activity agent removed	workflow	no	Aktivitetsagent fjernet
+activity completed	workflow	no	Aktivitet fullført
+activity failure	workflow	no	Aktivitet feil
+activity in inexistent process	workflow	no	Aktivitet i ikke eksisterende prosess
+activity is waiting for pending transitions	workflow	no	Aktivitet venter i påvente av overganger
+activity name already exists	workflow	no	Aktivitetsnavn eksisterer allerede
+activity role #%1 removed	workflow	no	Aktivitetsrolle #%1 fjernet
+activity role removed	workflow	no	Aktivitetsrolle fjernet
+activity saved	workflow	no	Aktivitet ble lagret
+activity start not avaible, no corresponding activity was found.	workflow	no	aktivitetsstart ikke mulig, ingen korresponderende aktivitet ble funnet.
+activity start not set, no corresponding activity was found.	workflow	no	aktivitetsstart ikke satt, ingen korresponderene aktivitet ble funnet.
+activity status not avaible, no corresponding activity was found.	workflow	no	aktivitetsstatus ikke tilgjengelig, ingen korresponderene aktivitet ble funnet.
+activity:	workflow	no	aktivitet :
+add a transition	workflow	no	Legg til en overgang
+add aborted instances	workflow	no	Legg til avbrutte instanser
+add advanced actions	workflow	no	Legg til avanserte aksjoner
+add completed instances	workflow	no	Legg til fullførte instanser
+add instances in exception	workflow	no	Legg til instanser unntatt
+add new	workflow	no	opprett ny
+add or edit a process	workflow	no	Legg til eller endre en prosess
+add or edit an activity	workflow	no	Legg til eller endre en aktivitet
+add property	workflow	no	Legg til eiendel
+add role	workflow	no	Legg til rolle
+add role to process	workflow	no	Legg rolle til prosess
+add transition	workflow	no	Legg til overgang
+add transitions	workflow	no	Legg til overganger
+add transitions from	workflow	no	Legg til overganger fra
+add transitions to	workflow	no	Legg til overganger til
+admin instance	workflow	no	Administrer instanse
+admin process activities	workflow	no	Administrer prosessaktiviteter
+admin process roles	workflow	no	Administrer prosessroller
+admin processes	workflow	no	Administrer prosesser
+admin processes sources	workflow	no	Administrer prosesskilder
+administer instances	workflow	no	Administrer instanser
+administer processes	workflow	no	Adminsitrer prosesser
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	no	Agent nr.%1 av type %2 er assosiert med en ikkeeksisterende aktivitet nr.%3
+agent #%1 of type %2 is not linked with an activity	workflow	no	Agent nr.%1 av type %2 er ikke tilknyttet noen aktivitet.
+agent associated with inexistent activity	workflow	no	Agent assisiert med ikkeeksisterende aktivitet
+agent without activity	workflow	no	Agent uten aktivitet
+all	workflow	no	Alle
+always show advanced actions	workflow	no	Vis alltid avanserte aksjoner
+always show advanced mode	workflow	no	Vis alltid avansert modus
+assign me this activity	workflow	no	Tilordne meg denne aktiviteten
+at least one email address cannot be validated.	workflow	no	minst en e-mailadresse kunne ikke gjenkjennes
+auto routed	workflow	no	Føres automatisk
+auto-release on leaving activity	admin	no	Frigjør automatisk når aktivitet forlates
+automatic	workflow	no	Automatisk
+bad role type	workflow	no	Feil rolletype
+bad user	workflow	no	Feil bruker
+base directory does not exist, please ask adminstrator to check the global configuration	common	no	Basekatalogen eksisterer ikke; be edb-ansvarlig om å kontrollere den globale konfigurasjonen.
+bcc:	workflow	no	Bcc:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	no	Vær forsiktig med interaktiv aktivitet, slutt og start på disse aktivitene er fler enn en.
+being run	workflow	no	kjøres nå
+by running theses links you will create new instances of the related process.	workflow	no	ved å følge disse lenkene vil du skape nye instanser av den relaterte prosess.
+cannot create compiled file %1	workflow	no	kan ikke skape kompilert fil %1
+cannot run the activity	workflow	no	Kan ikke starte aktivieten
+cannot run the activity without her process	workflow	no	Kan ikke starte aktiviteten uten dennes prosess
+cannot run the activity without instance	workflow	no	Kan ikke starte aktiviteten uten en instanse
+cannot run unknown activity	workflow	no	Kan ikke starte ukjent aktivitet
+cc:	workflow	no	Cc:
+circular reference found some activity has a transition leading to itself	workflow	no	Sirkulær referanse funner. En eller annen aktivitet har en overgang som leder til seg selv.
+circular reference found. some activity has a transition leading to itself	workflow	no	Sirkulær referanse funner. En eller annen aktivitet har en overgang som leder til seg selv.
+cleanup aborted instances	workflow	no	fjerning av avbrutte instanser
+cleanup actions	workflow	no	oppryddingsaksjoner
+close and get back later	workflow	no	Lukk og kom tilbake senere
+close printer friendly mode	workflow	no	Lukk printervennlig modus
+code	workflow	no	kode
+column activity status in instance lists	workflow	no	Kolonne aktivitetsstatus i instanselister
+column category in instance lists	workflow	no	Kolonne kategori i instanselister
+column instance id in instance lists	workflow	no	Kolonne instanseident i instanselister
+column instance name in instance lists	workflow	no	Kolonne instansenavn i instanselister
+column instance status in instance lists	workflow	no	Kolonne status i instanselister
+column owner in instance lists	workflow	no	Kolonne eier i instanselister
+column priority in instance lists	workflow	no	Kolonne prioritet i instanseliser
+column process name in instance lists	workflow	no	Kolonne prosessnavn i instanselister
+column start date in instance lists	workflow	no	Kolonne startdato i instanselister
+compiling activity %1 : %2	workflow	no	kompilerer aktivitet %1 : %2
+complete	workflow	no	Ferdig
+complete cleanup of aborted instances done	workflow	no	komplett fjerning av avbrutte instanser utført
+complete cleanup of all instances done	workflow	no	komplett fjerning av alle instanser utført
+completed	workflow	no	fullført
+confirm delete	workflow	no	Bekreft sletting
+consult %1 to get the default values:	workflow	no	Konsulter %1 for standard verdier
+couldn't add transition	workflow	no	Kunne ikke legge til overgang
+create	workflow	no	skape
+created	workflow	no	Skapt
+date:	workflow	no	dato:
+default config values	common	no	Standard konfigurasjonsverdier
+default next user	workflow	no	Standard neste bruker
+default owner	workflow	no	Standard eier
+default settings for processes	admin	no	Standard instillinger for prosesser
+default user	workflow	no	Standard bruker
+delete selected	workflow	no	Slette valgte
+delete transition	workflow	no	Slette overgang
+deletion successful	workflow	no	Sletting utført
+delition successful	workflow	no	Sletting utført
+description	workflow	no	Beskrivelse
+display please wait message	admin	no	Vise vennligst vent melding
+don't move	workflow	no	Ikke flytt
+draw roles	admin	no	tegne roller
+draw roles on the graph beside activity name like [that]	admin	no	Tegne rollene på den grafiske fremstillingen ved siden av aktivitetsnavn som [that]
+duration	workflow	no	Varighet
+end	workflow	no	Slutt
+end activity is not reachable from start activity	workflow	no	Avslutningsaktivitet kan ikke nåes fra startaktivitet.
+ended	workflow	no	Avsluttet
+enter an activity name	workflow	no	Registrer et aktivitetsnavn
+error: removing was not done	workflow	no	Feil: Fjerning ble ikke utført
+exception	workflow	no	Unntak
+exception instance	workflow	no	Unntatt instanse
+exception this instance	workflow	no	Unntatt denne instansen
+exceptions	workflow	no	unntakene
+execute this activity	workflow	no	Utfør denne aktivitet
+export	workflow	no	Eksporter
+failed to create workitem	workflow	no	kunne ikke opprette arbeidselement
+failed to execute automatic activity	workflow	no	feil i utførelse av automatisk aktivitet
+fatal error: setting next activity to an unexisting activity	workflow	no	Fatal feil: Neste aktivitet ble satt til en ikke eksisterende aktivitet
+fatal error: trying to send an instance to an activity but no transition found	workflow	no	Fatal feil: Prøver å sende en instanse til en aktivitet med ingen overgang funnet.
+filter	workflow	no	Filter
+filter instance by id	workflow	no	filtrer instanse etter ident
+fix	workflow	no	Rett
+fix concistency for selected rows	workflow	no	Rett konsistens for valgte rader
+font size	admin	no	font str.
+from	workflow	no	Fra
+from:	workflow	no	Fra:
+get back to global activities	workflow	no	gå tilbake til globale aktiviteter
+get back to instance creation	workflow	no	gå tilbake til opprettelse av instanser
+get property	workflow	no	Få egenskap
+global activities	workflow	no	Globale aktiviteter
+global workflow preferences	workflow	no	Globale arbeidsflytspreferanser
+go	workflow	no	Gå til
+go to same activities for other instances of this process	workflow	no	gå til samme aktivitet for andre instanser av denne prosessen
+go to same process activities	workflow	no	Gå til de samme prosessaktiviteter
+go to the actual state of this instance	workflow	no	Gå til aktuell status for denne instanse
+grant access to the administration and development of workflow processes and activities.	workflow	no	Gi tilgang til administrasjon og utvikling av arbeidsflytsprosesser og aktiviteter.
+grant access to the administration of workflow elements	workflow	no	Gi tilgang til administrasjon av arbeidsflytselementer.
+grant access to the monitoring of workflow elements	workflow	no	Gi adgang til å overvåke arbeidsflytselementer
+graph	workflow	no	Graf
+graphic options	admin	no	Grafiske valg
+group	workflow	no	Gruppe
+id	workflow	no	Ident
+if automatic parsing is disabled next options will be useless	admin	no	Dersom automatisk analyse ikke er i bruk er de neste valgene uten mening.
+import aborted	workflow	no	Import avbrutt
+import successfull	workflow	no	Import vellykket
+inactive	workflow	no	Inaktive
+inst.	workflow	no	Inst.
+inst. status	workflow	no	Inst. status
+instance	workflow	no	Instanse
+instance %1	workflow	no	Instanse %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	no	Instanse % 1 er i status %2, aksjon %3 er derfor umulig
+instance %1 is in exception, action %2 is not possible.	workflow	no	Instanse %1 er i unntakstilstand, aksjon %2 er derfor ikke mulig.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	no	Instanse %1 er ikke assosiert med aktivitet %2, aksjon %3 er der umulig
+instance history	workflow	no	Instanse historikk
+instance properties	workflow	no	Instanse egenskaper
+instance:	workflow	no	Instanse:
+instance: %1 (process: %2)	workflow	no	Instanse: %1 (Prosess: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	no	Instanse: kan ikke endre %1[%2], noen andre har endret denne før oss
+instance: unable to modify %1, someone has changed it before us	workflow	no	Instanse: kan ikke endre %1, noen andre har endret denne før oss
+instances	workflow	no	Instanser
+instances selection	workflow	no	Valgte instanser
+int.	workflow	no	Int.
+interactive	workflow	no	Interaktiv
+interactive instances should not call the complete() method	workflow	no	interaktive instanser skal ikke kunne kalle metoden complete()
+interactive:	workflow	no	Interaktiv:
+interactivity	workflow	no	Interaktivitet
+invalid	workflow	no	Ikke gyldig
+invalid process	workflow	no	Ikke gyldig prosess
+invalid role name	workflow	no	Ikke gyldig rollenavn
+is active	workflow	no	er aktiv
+it seems this activity for this instance is not assigned to you anymore.	workflow	no	Det ser ikke ut til at aktiviteten for denne instansen er tilknyttet deg lenger.
+it was impossible to complete, no activity was given.	workflow	no	den kunne ikke avsluttes, ingen aktivitet var angitt.
+it was impossible to complete, no corresponding activity was found.	workflow	no	denne kunne ikke avsluttes, ingen korresponderende aktivitet ble funnet.
+join	workflow	no	tilknytte
+list of activities	workflow	no	Liste over aktivitetene
+list of all activities with, for each,  counters of instances by status	workflow	no	Liste over alle aktiviterer, med for hver, teller og instanser etter status.
+list of instances	workflow	no	Liste over instanser
+list of mappings	workflow	no	Liste over tilordninger
+list of monitors	workflow	no	Lite over monitorer
+list of processes	workflow	no	Liste over prosesser
+list of processes (%1)	workflow	no	Liste over prosesser (%1)
+list of transitions	workflow	no	Liste over overganger
+list of workitems	workflow	no	Liste over arbeidselementer
+mail smtp agent	workflow	no	E-mail SMTP agent
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	no	Mail kan sendes ved oppstart og avslutning av en aktivitet.  Kun for interaktive aktiviteter kan det sendes etter ferdigstillelse.
+manual	workflow	no	Manuell
+map	workflow	no	Tilordne
+map users/groups to roles	workflow	no	Tilordne brukere/grupper til roller
+mapping to inexistent role	workflow	no	Tilordnet ikke eksisterende rolle
+mappings deleted	workflow	no	Tilordninger slettet
+message:	workflow	no	Melding:
+monitor activities	workflow	no	Overvåk aktiviteter
+monitor instance	workflow	no	Overvåk instanse
+monitor instances	workflow	no	Overvåk instanser
+monitor processes	workflow	no	Overvåk prosesser
+monitor this instance	workflow	no	Overvåk denne instansen
+monitor work items	workflow	no	Overvåk arbeidselementer
+monitor workitems	workflow	no	Overvåk arbeidselementer
+monitoring	workflow	no	Overvåker
+monitors	workflow	no	Monitorer
+more options?	workflow	no	flere valg ?
+my activities	workflow	no	Mine aktiviteter
+my instances	workflow	no	Mine instanser
+my processes	workflow	no	Mine prosesser
+name	workflow	no	Navn
+new instance	workflow	no	Ny instanse
+new major	workflow	no	Ny hoved
+new major version created	workflow	no	Ny hovedversjon laget
+new mapping added	workflow	no	Ny tilordning opprettet
+new minor	workflow	no	Ny mindre
+new minor version created	workflow	no	Ny mindre versjon laget
+new status not set, no corresponding activity was found.	workflow	no	Ny status ble ikke satt, ingen korresponderende aktivitet ble funnet.
+new transition added	workflow	no	Ny overgang lagt til
+next activity	workflow	no	neste aktivitet
+next user:	workflow	no	Neste bruker:
+no action avaible because no activity and no instance are given!	workflow	no	Ingen aksjon tilgjengelig da ingen aktivitet og ingen innstanse er angitt!
+no activites	workflow	no	Ingen aktiviteter
+no activity indicated	workflow	no	Ingen aktivitet indikert
+no agents associated with this activity	workflow	no	Ingen agent assosiert med denne aktivitet
+no circular transitions allowed.	workflow	no	Ingen sirkulære overganger tillatt
+no corresponding activity was found.	workflow	no	Ingen korresponderende aktivitet ble funnet.
+no inconcistency detected	workflow	no	Ingen inkonstinens oppdaget
+no instance avaible	workflow	no	Ingen instanse tilgjengelig
+no instance given, nothing to show	workflow	no	Ingen instanse angitt, heller ikke noe å vise
+no instance indicated	workflow	no	Ingen instanse indikert
+no process indicated	workflow	no	Ingen prosess indikert
+no properties defined	workflow	no	Ingen egenskaper er definert
+no roles	workflow	no	Ingen roller
+no roles asociated with this activity	workflow	no	Ingen roller tilknyttet denne aktivtet
+no routage	workflow	no	Ingen rute angitt
+no transitions allowed for standalone or view activities	workflow	no	Ingen overganger tillatt for alenestående eller visningsaktiviteter
+no work item indicated	workflow	no	Ingen arbeidselement indikert
+nobody	workflow	no	Ingen
+not defined	workflow	no	ikke definert
+or import a process	workflow	no	Eller importer en prosess
+owner	workflow	no	Eier
+owner of the instance will have the right to abort the instance at any time	admin	no	eier av instansen vil ha rett til å avbryte instansen når som helst
+owner:	workflow	no	Eier:
+ownership give abort right	admin	no	eierskap gir rett til å avbryte
+ownership give exception right	admin	no	eierskap gir rett til å unnta
+ownership give release right	admin	no	eierskap gir rett til å frigi
+pr.	workflow	no	Pr.
+pre-activity %1 code is not avaible	workflow	no	Preaktivitet %1 kode ikke tilgjengelig
+pre-agent %1 code is not avaible	workflow	no	Preagent %1 kode er ikke tilgjengelig
+pre-shared code is not avaible	workflow	no	Pre-delt kode er ikke tilgjengelig
+printer friendly	workflow	no	Utskriftsvennlig
+priority level:	workflow	no	Prioriteringsnivå:
+process	workflow	no	Prosess
+process %1	workflow	no	Prosess %1
+process %1 %2 is not active, action %3 is impossible	workflow	no	Prosess %1 %2 er ikke aktiv, aksjon %3 er derfor umulig
+process %1 v%2 as no related activity	workflow	no	Prosess %1 v%2 har ingen relatert aktivitet
+process %d has been activated	workflow	no	Prosess %d er nå aktivert
+process %d has been deactivated	workflow	no	Prosess %d er nå dekativert
+process %s %s already exists, the import process was aborted	workflow	no	Prosess %s %s eksisterer allerede, import av prosess ble derfor avbrutt
+process %s %s imported	workflow	no	Prosess %s %s ble importert
+process %s has been created	workflow	no	Prosess %s har blitt opprettet
+process %s has been updated	workflow	no	Prosess %s har blitt oppdatert
+process %s removed	workflow	no	Prosess %s fjernet
+process activities	workflow	no	Prosessaktiviteter
+process alone	workflow	no	Alenestående prosess
+process does not have a start activity	workflow	no	Prosessen har ikke en startaktivitet
+process does not have exactly one end activity	workflow	no	Prosessen har ikke en eksakt avslutningsaktivitet
+process form	workflow	no	Prosessskjema
+process name	workflow	no	Prosessnavn
+process name already exists	workflow	no	Prosessnavn allerede opprettet
+process roles	workflow	no	Prosessroller
+process saved	workflow	no	Prosess lagret
+process transitions	workflow	no	Prosessoverganger
+process version:	workflow	no	Prosess versjon:
+process:	workflow	no	Prosess:
+processes	workflow	no	Prosesser
+properties	workflow	no	Egenskaper
+property	workflow	no	Eiendel
+property %1 already exists	workflow	no	Eiendel %1 er allerede opprettet
+property %1 not found	workflow	no	Eiendel % 1 ikke funnet
+quit without saving	workflow	no	Avslutt uten lagring
+read-only	workflow	no	kun lesbar
+release access to this activity	workflow	no	Frigjør aksess til denne aktiviteten
+release activity for this instance	workflow	no	Frigjør aktiviteten for denne instansen
+release instance	workflow	no	Frigjør instansen
+reload filter	workflow	no	Last inn filter på nytt
+remove active instances	workflow	no	Fjern aktive instanser
+remove all instance for this process	workflow	no	Fjern alle instanser for denne prosessen
+remove selected roles	workflow	no	Fjern valgte roller
+removing instances and workitems for aborted instances on all processes	workflow	no	fjerner instanser og arbeidselementer på avbrutte instanser for alle prosesser
+removing instances and workitems for aborted instances on process #%1	workflow	no	fjerner instanser og arbeidselementer på avbrutte instanser for prosess #%1
+removing instances and workitems for all instances on process #%1	workflow	no	fjerner instanser og arbeidselementer på alle instanser for prosess #%1
+replyto:	workflow	no	Svar til
+restart	workflow	no	Start på nytt
+restart activity	workflow	no	Start aktivitet på ny
+resume this exception instance	workflow	no	Gjennopta dette unntakets instanse
+role %1 is not mapped	workflow	no	Rolle %1 er ikke tilordnet
+role added to activity	workflow	no	Rolle lagt til aktiviteten
+role added to process	workflow	no	Rolle lagt til prosessen
+role give abort right	admin	no	Rolle gir rett til å avbryte
+role give exception right	admin	no	Rolle gir rett til unntak
+role give release right	admin	no	Rolle gir rett til å frigi
+role in inexistent process	workflow	no	Rolle i ikke-eksisterende prosess
+role mapping in inexistent process	workflow	no	Rolletilordning i ikke-eksisterende prosess
+role name	workflow	no	Rollenavn
+role not saved (maybe a name collision)	workflow	no	Rolle ikke lagret (kan være en navnkollisjon)
+role process inconcistency in mappings	workflow	no	Rolle prosess inkonsistent i tilordninger
+role saved	workflow	no	Rolle lagret
+roles	workflow	no	Roller
+roles assigned to this activity	workflow	no	Roller tilordnet denne aktiviteten
+roles deleted	workflow	no	Roller slettet
+run	workflow	no	start
+run activity	workflow	no	start aktivitet
+run instance	workflow	no	start instanse
+running	workflow	no	kjører
+running activities options	admin	no	Valg for startede aktiviteter
+running activity	workflow	no	Startede aktiviteter
+search instance filter in the bottom of instance lists	workflow	no	Søk for instansefilter i bunnen av instanselistene
+search:	workflow	no	Søk:
+security check: cannot understand asked action	workflow	no	Sikkerhetskontroll: Forstår ikke forespurt aksjon
+select a transition to remove	workflow	no	Velg en overgang som skal fjernes
+select source	workflow	no	velg kilde
+send after interactive activity is completed	workflow	no	send etter at interaktiv aktivitet er fullført.
+send all to	workflow	no	Send til alle
+send an email	workflow	no	Send en e-mail
+send instance	workflow	no	send instanse
+send this instance to the next activity	workflow	no	Send denne instansen til neste aktivitet
+send transition	workflow	no	Send overgang
+send when the activity is ending	workflow	no	Send når aktivitet avsluttes
+send when the activity is starting	workflow	no	Send når aktivitet påbegynnes
+set next act	workflow	no	Sett neste aktivitet
+set next user	workflow	no	Sett neste bruker
+set property	workflow	no	Sett egenskaper
+setting next activity to an unexisting activity	workflow	no	setter neste aktivitet til en ikkeeksisterende aktivitet
+shared code	workflow	no	Delt kode
+show activity title	admin	no	Vis aktivitetstittel
+show code	workflow	no	Vis kode
+show template	workflow	no	Vis mal
+size of the font used on the graph 12 should be a good default value	admin	no	Str. 12 på de brukte fontene skal være en grei standard verdi
+source code file for activity %1 is not avaible	workflow	no	Kildekodefilen for aktivitet %1 er ikke tilgjengelig
+source code for activity %1 is not avaible	workflow	no	Kildekoden for aktivitet %1 er ikke tilgjengelig
+source saved	workflow	no	Kilden lagret
+split	workflow	no	splitt
+standalone	workflow	no	frittstående
+start	workflow	no	Start
+start activities must be interactive	workflow	no	Startaktiviteter må være interaktive
+start activity	workflow	no	Start aktivitet
+start process	workflow	no	Start prosess
+started	workflow	no	Startet
+started:	workflow	no	startet:
+starting page	workflow	no	Startside
+status	workflow	no	Status
+status:	workflow	no	status:
+stop	workflow	no	stopp
+subject:	workflow	no	Emne:
+switch	workflow	no	Bryter
+switch construct	workflow	no	Bryterkonstruksjon
+template	workflow	no	mal
+test concistency	workflow	no	Test for konsistens
+test consistency of datas in the database	workflow	no	Test for konsistens av data i databasen
+test local installation	workflow	no	Test lokal installasjon
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	no	Arbeidsflytskatalogen eksisterer ikke og kunne ikke opprettes.  Kontakt edb-ansvarlig og be vedkommende kontrollere den globale konfigurasjonen.
+the activity was not completed	workflow	no	Aktiviteten ble ikke fullført
+the following items must be corrected to be able to activate this process	workflow	no	Følgende enheter må korrigeres for at vi skal kunne aktivisere denne prosessen
+the instance title is shown on top of the form	admin	no	Navn på instansen vises i toppen av skjermbildet
+the label you want	workflow	no	Ledeteksten du ønsker.
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	no	SMTP Konfigurasjonen kan ikke lastes av mail_smtp arbeidsflytsagent.
+there are no activities available	workflow	no	Det er ingen aktiviteter tilgjengelig
+there are no config value defined	workflow	no	Det er ikke definert noen konfigurasjonsverdi
+there are no instances available	workflow	no	Det er ingen instanser tilgjengelig
+there are no mappings defined for this process	workflow	no	Det er ingen tilordninger definert for denne prosessen
+there are no process available	workflow	no	Det er ingen prosess tilgjengelig
+there are no processes	workflow	no	Det er ingen prosesser
+there are no processes available	workflow	no	Det er ingen prosesser tilgjengelig
+there are no processes defined	workflow	no	Det er ingen definerte prosesser
+there are no processes with the current filter	workflow	no	Det er ingen prosesser med gjeldende filter
+there are no properties available	workflow	no	Det er ingen tilgjengelige egenskaper
+there are no roles defined for this process	workflow	no	Det er ikke definert roller for denne prosessen
+there are no transitions defined	workflow	no	Det er ikke definert noen overganger
+there are no user activites available	workflow	no	Det er ingen brukeraktiviteter tilgjengelig
+there are no workitems available	workflow	no	Det er ingen arbeidselementer tilgjengelig
+there are some undefined preferences associated with this form : %1	workflow	no	Det er noen udefinerte preferanser assosiert med dette skjermbildet: %1
+there is an unknown user or group #%1 in role mappings	workflow	no	Det er en ukjent bruker eller gruppe nr.%1 i tilordningen av rolle
+they were problems at the compilation of the source:	workflow	no	Det er problemer med kompilering av kildekoden:
+this process has no end activity	workflow	no	denne prosessen har ingen avslutningsaktivitet
+this will automatically release the instance when leaving an activity without completing	admin	no	dette vil automatisk frigjøre instansen når en prosess forlates uten at den fullføres
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	no	Dette vil vise en aktivitets bunn når en aktivitet kjøres med relatert arbeidsflytsinformasjon.
+to	workflow	no	Til
+to:	workflow	no	Til :
+transition	workflow	no	Overgang
+transition mode	workflow	no	Overgangsmodus
+transition to %1	workflow	no	Overgang til %1
+transitions	workflow	no	Overganger
+transitions removed successfully	workflow	no	Overgangene ble fjernet
+type	workflow	no	type
+type:	workflow	no	type :
+unknown status	workflow	no	ukjent status
+update	workflow	no	oppdater
+upload file	workflow	no	last opp fil
+use automatic parsing	admin	no	Benytt automatisk analyse
+use default	workflow	no	Bruk standard
+use existing roles	workflow	no	Bruk eksisterende roller
+user	workflow	no	Bruker
+user #%1 is associated with a non-existent role #%2	workflow	no	Bruker nr.%1 er assosiert med en ikkeeksisterende rolle nr.%2
+user activities	workflow	no	Brukeraktiviteter
+user instances	workflow	no	Brukerinstanser
+user instances form: columns	workflow	no	Bruker Instanseskjermbilde: kolonner
+user instances form: filters and actions	workflow	no	Bruker instanseskjermbilde: filtre og aksjoner
+user is not authorized to delete aborted instances	workflow	no	Bruker er ikke autorisert til å slette avbrutte instanser
+user is not authorized to delete instances	workflow	no	Bruker er ikke autorsisert til å slette instanser
+user processes	workflow	no	Brukerprosesser
+user/group	workflow	no	Bruker/Gruppe
+user:	workflow	no	bruker :
+users/groups	workflow	no	Brukere/Grupper
+valid	workflow	no	Gyldig
+valid process	workflow	no	Valideringsprosess
+valid:	workflow	no	gyldig :
+value	workflow	no	Verdi
+version	workflow	no	Versjon
+view details	workflow	no	Vis detaljer
+view this instance	workflow	no	Vis denne instansen
+view workitem	workflow	no	Vis arbeidsenhet
+warning this filter override all others filters	workflow	no	Advarsel: Dette filteret overstyrer alle andre filtere
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	no	Vi kan ikke starte denne aktiviteten, kontroller om det fortsatt finnes instanser tilknyttet aktiviteten.
+we were not able to build the message	workflow	no	Vi er ikke istand til å lage meldingen
+when to send the message:	workflow	no	Når skal melding sendes :
+workflow	common	no	Arbeidsflyt
+workflow configuration	admin	no	Arbeidsflyt Konfigurasjon
+workflow preferences	workflow	no	Arbeidsflyt Preferanser
+workflow site configuration	workflow	no	Konfigurering av nettstedet for arbeidsflyt
+workflow.ui_useractivities	workflow	no	workflow.ui_useractivities
+workitem information	workflow	no	Informasjon om arbeidselementet
+workitems	workflow	no	Arbeidselementer
+you are not allowed to abort instance %1	workflow	no	Du har ikke tillatelse til å avbryte instanse %1
+you are not allowed to exception instance %1	workflow	no	Du har ikke tillatelse til å unnta instanse %1
+you are not allowed to grab instance %1	workflow	no	Du har ikke tillatelse til å ta fatt i instanse %1
+you are not allowed to release instance %1	workflow	no	Du har ikke tillatelse til å frigjøre instanse %1
+you are not allowed to restart instance %1	workflow	no	Du har ikke tillatelse til å starte instanse %1 på nytt
+you are not allowed to resume instance %1	workflow	no	Du har ikke tillatelse til å gjennoppta instanse %1
+you are not allowed to send instance %1	workflow	no	Du har ikke tillatelse til å videresende instanse %1
+you can use special values with this mail agent:	workflow	no	Du kan benytte spesialverdier med denne e-mailklienten
+you don't have the rights necessary to exception instance %1	workflow	no	Du har ikke de nødvendige rettigheter for å unnta instanse %1
+you have not permission to execute this activity	workflow	no	Du har ikke tillatelse til å utføre denne aktiviteten
+you were not allowed to complete the activity	workflow	no	Du har ikke tillatelse til å fullføre denne aktiviteten
Index: /sandbox/workflow/branches/993/setup/phpgw_sk.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_sk.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_sk.lang	(revision 795)
@@ -0,0 +1,593 @@
+#	workflow	sk	#
+%1 aborted	workflow	sk	%1 zru¹ené
+%1 active	workflow	sk	%1 aktívne
+%1 completed	workflow	sk	%1 hotovo
+%1 configuration	workflow	sk	%1 nastavenie
+%1 days, %2:%3:%4	workflow	sk	%1 dní, %2:%3:%4
+%1 exception	workflow	sk	%1 výnimka
+%1 menu	workflow	sk	%1 Menu
+%1 monitoring	workflow	sk	%1 Sledovanie
+%1 processes (%2 active) (%3 being_run)	workflow	sk	%1 procesov (%2 aktívnych) (%3 spustených)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	sk	Adresár /workflow neexistuje a nedá sa vytvori», prosím poŸiadajte správcu aby skontroloval globálne nastavenia
+<strong>%owner%</strong> is the instance owner email	workflow	sk	<strong>%owner%</strong> je email vlastníka sedenia
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	sk	<strong>%property_XX%</strong> je obsah náleŸitosi XX sedenia
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	sk	<strong>%role_XX%</strong> sú v¹etko emaily v¹etkých pouŸívateµov mapovaných do úlohy XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	sk	<strong>%roles%</strong> sú emaily v¹etkých pouŸívateµov mapovaných do akejkoµvek úlohy tejto aktivity
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	sk	<strong>%signature%</strong> je signatúra agenta, definovaná v nastaveniach procesu
+<strong>%user%</strong> is the instance user email	workflow	sk	<strong>%user%</strong> je email pouŸívateµa sedenia
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	sk	<strong>%user_XX%</strong> je email úètu XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	sk	správa typu Prosím èakajte sa zobrazuje poèas nahrávania formulára aktivít vhodné pre dlhé úlohy
+abort instance	workflow	sk	zru¹i» sedenie
+abort this instance	workflow	sk	Zru¹i» toto sedenie
+aborted	workflow	sk	Zru¹ené
+access denied for user %1 on activity %2, no role	workflow	sk	Prístup odopretý pre pouŸívateµa %1 pre aktivitu %2, bez úloh
+act	workflow	sk	akt
+act. status	workflow	sk	Stav akt.
+act. status:	workflow	sk	Stav akt.:
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	sk	Akcia %1 je vylúèená, ak pre òu nemáme Ÿiadnu aktivitu ani sedenie.
+action %1 is impossible, another user is already in place	workflow	sk	Akcia %1 je vylúèená, uŸ je tam iný pouŸívateµ
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	sk	Akcia %1 je vylúèená, Ÿiadny pouŸívateµ nie je priradený k tejto aktivite pre toto sedenie
+action %1 needs an activity and activity %2 does not exists	workflow	sk	Akcia %1 vyŸaduje aktivitu, a aktivita %2 neexistuje
+action %1 needs an instance and instance %2 does not exists	workflow	sk	Akcia %1 vyŸaduje sedenie, a sedenie %2 neexistuje
+actions	workflow	sk	Akcie
+actions right options	common	sk	Pravé predvoµby akcií
+activate	workflow	sk	Aktivova»
+active	workflow	sk	Aktívne
+active:	workflow	sk	Aktívne:
+activities	workflow	sk	Aktivity
+activities selection	workflow	sk	Výber aktivít
+activities updated	workflow	sk	Aktivity aktualizované
+activity	workflow	sk	Aktivita
+activity  status	workflow	sk	Stav aktivity
+activity %1	workflow	sk	aktivita %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	sk	Aktivita %1 (#%2) je priradená k neexistujúcemu procesu (#%3)
+activity %1 code is not avaible	workflow	sk	kód aktivity %1 je nedostupný
+activity %1 is interactive but has no role assigned	workflow	sk	Aktivita %1 je interaktívna, ale nemá priradenú Ÿiadnu úlohu
+activity %1 is interactive so it must use the $instance->complete() method	workflow	sk	Aktivita %1 je interaktívna, takŸe musí pouŸíva» metódu $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	sk	Aktivita %1 nie je interaktívna a nie je automaticky smerovaná, ale nemá priradenú Ÿiadnu úlohu
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	sk	Aktivita %1 nie je interaktívna, takŸe nesmie pouŸíva» metódu $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	sk	Aktivita %1 je samostatná a pouŸíva objekt $instance
+activity %1 is standalone but has transitions	workflow	sk	Aktivita %1 je samostatná, ale má prechody
+activity %1 is standalone or view but has transitions	workflow	sk	Aktivita %1 je samostatná alebo zobrazenie, ale má prechody
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	sk	Aktivita %1 je prepínaè, takŸe musí pouŸíva» metódu $instance->setNextActivity($actname)
+activity %1 is view and is using the $instance object in write mode	workflow	sk	Aktivita %1 je zobrazením a pouŸíva objekt $instance v reŸime zapisovania
+activity agent removed	workflow	sk	Agent aktivity odstránený
+activity completed	workflow	sk	Aktivita dokonèená
+activity failure	workflow	sk	Zlyhanie aktivity
+activity in inexistent process	workflow	sk	Aktivita v neexistujúcom procese
+activity is waiting for pending transitions	workflow	sk	Aktivita èaká na e¹te vybavované prechody
+activity name already exists	workflow	sk	Takýto názov aktivity uŸ existuje
+activity role #%1 removed	workflow	sk	Úloha #%1 aktivity odstránená
+activity role removed	workflow	sk	Úloha aktivity odstránená
+activity saved	workflow	sk	Aktivita uloŸená
+activity start not avaible, no corresponding activity was found.	workflow	sk	Zaèiatok aktivity je nedostupný, Ÿiadna zodpovedajúca aktivita sa nena¹la.
+activity start not set, no corresponding activity was found.	workflow	sk	Zaèiatok aktivity nebol zadaný, Ÿiadna zodpovedajúca aktivita sa nena¹la.
+activity status not avaible, no corresponding activity was found.	workflow	sk	Stav aktivity je nedostupný, Ÿiadna zodpovedajúca aktivita sa nena¹la.
+activity:	workflow	sk	Aktivita:
+add a transition	workflow	sk	Prida» prechod
+add aborted instances	workflow	sk	Prida» zru¹ené sedenia
+add advanced actions	workflow	sk	Prida» pokroèilé akcie
+add agent	workflow	sk	Prida» agenta
+add completed instances	workflow	sk	Prida» dokonèené sedenia
+add instances in exception	workflow	sk	Prida» sedenia vo výnimke
+add new	workflow	sk	Prida» nový
+add new role	workflow	sk	Prida» novú úlohu
+add or edit a process	workflow	sk	Prida» alebo upravi» proces
+add or edit a role	workflow	sk	Prida» alebo upravi» úlohu
+add or edit an activity	workflow	sk	Prida» alebo upravi» aktivitu
+add property	workflow	sk	Prida» náleŸitos»
+add role	workflow	sk	Prida» úlohu
+add role to process	workflow	sk	Prida» úlohu k procesu
+add transition	workflow	sk	Prida» prechod
+add transitions	workflow	sk	Prida» prechody
+add transitions from	workflow	sk	Prida» prechody z
+add transitions to	workflow	sk	Prida» prechody do
+admin instance	workflow	sk	Správcovské sedenie
+admin process activities	workflow	sk	Správcovské aktivity procesu
+admin process roles	workflow	sk	Správcovské úlohy procesu
+admin processes	common	sk	Správcovské procesy
+admin processes sources	workflow	sk	Správcovské zdroje procesov
+administer instances	admin	sk	Správa sedení
+administer processes	admin	sk	Správa procesov
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	sk	Agent #%1 typu %2 je priradený k neexistujúcej aktivite #%3
+agent #%1 of type %2 is not linked with an activity	workflow	sk	Agent #%1 typu %2 nie je pripojený k Ÿiadnej aktivite
+agent associated with inexistent activity	workflow	sk	Agent priradený k neexistujúcej aktivite
+agent without activity	workflow	sk	Agent bez aktivity
+agents assigned to this activity	workflow	sk	Agenti priradení k tejto aktivite
+all	workflow	sk	V¹etko
+always show advanced actions	workflow	sk	VŸdy zobrazi» pokroèilé akcie
+always show advanced mode	workflow	sk	VŸdy zobrazi» pokroèilý reŸim
+assign me this activity	workflow	sk	Priraïte mi túto aktivitu
+at least one email address cannot be validated.	workflow	sk	Najmenej jedna emailová adresa sa nedá overi»
+auto routed	workflow	sk	Automaticky smerované
+auto-release on leaving activity	common	sk	Automaticky uvoµni» pri opustení aktivity
+automatic	workflow	sk	Automatické
+autorouted activities does not need to be sent by any user after their execution	workflow	sk	Automaticky smerované aktivity nemusí Ÿiadny pouŸívateµ posiela», keï sa vykonajú
+bad parameter for setagents, the parameter should be an array	workflow	sk	chybný parameter pre setAgents, parametrom musí by» pole
+bad role type	workflow	sk	Chybný typ úlohy
+bad user	workflow	sk	Chybný pouŸívateµ
+base directory does not exist, please ask adminstrator to check the global configuration	common	sk	Základný adresár neexistuje, prosím poŸiadajte správcu aby skontroloval globálne nastavenia
+bcc:	workflow	sk	Skrytá kópia:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	sk	Bud»e opatrní pri interaktívnych aktivitách, majú viacero koncov a zaèiatkov.
+being run	workflow	sk	práve prebiehajúce
+by running theses links you will create new instances of the related process.	workflow	sk	Spustením týchto odkazov vytvoríte nové sedenia k zodpovedajúcim procesom.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	sk	Nedá sa prida» prechod, iba rozdelenie alebo prehodenie aktivít môŸe ma» viac neŸ jeden odchodzí prechod
+cannot add transition. only split activities can have more than one outbound transition	workflow	sk	Nedá sa prida» prechod. Iba rozdelené aktivity môŸu ma» viac neŸ jeden odchodzí prechod
+cannot create compiled file %1	workflow	sk	Nedá sa vytvori» kompilovaný súbor %1
+cannot run the activity	workflow	sk	NemôŸem spusti» túto aktivitu
+cannot run the activity without her process	workflow	sk	NemôŸem spusti» túto aktivitu bez jej procesu
+cannot run the activity without instance	workflow	sk	NemôŸem spusti» túto aktivitu bez sedenia
+cannot run unknown activity	workflow	sk	NemôŸem spusti» neznámu aktivitu
+cc:	workflow	sk	Kópia:
+circular reference found some activity has a transition leading to itself	workflow	sk	Vyskytlo sa prepojenie do kruhu, nejaká aktivita má prechod smerujúci na seba
+circular reference found. some activity has a transition leading to itself	workflow	sk	Vyskytlo sa prepojenie do kruhu, nejaká aktivita má prechod smerujúci na seba
+cleanup aborted instances	admin	sk	Vyèisti» zru¹ené sedenia
+cleanup actions	workflow	sk	Vyèisti» akcie
+close and get back later	workflow	sk	Zavrie» a vráti» sa neskôr
+close printer friendly mode	workflow	sk	Zavrie» reŸim pre tlaè
+code	workflow	sk	Kód
+column activity status in instance lists	workflow	sk	Ståpec stavu aktivity v zoznamoch sedení
+column category in instance lists	workflow	sk	Ståpec kategórie v zoznamoch sedení
+column instance id in instance lists	workflow	sk	Ståpec ID sedenia v zoznamoch sedení
+column instance name in instance lists	workflow	sk	Ståpec názov sedenia v zoznamoch sedení
+column instance status in instance lists	workflow	sk	Ståpec stav sedenia v zoznamoch sedení
+column owner in instance lists	workflow	sk	Ståpec vlastník v zoznamoch sedení
+column priority in instance lists	workflow	sk	Ståpec priorita v zoznamoch sedení
+column process name in instance lists	workflow	sk	Ståpec názov procesu v zoznamoch sedení
+column start date in instance lists	workflow	sk	Ståpec dátum zaèiatku v zoznamoch sedení
+compilation	workflow	sk	Kompilácia
+compiling activity %1 : %2	workflow	sk	Kompilujem aktivitu %1 : %2
+complete cleanup of aborted instances done	workflow	sk	Úplné èistenie zru¹ených sedení dokonèené
+complete cleanup of all instances done	workflow	sk	Úplné èistenie v¹etkých sedení dokonèené
+completed	workflow	sk	Hotovo
+config values	common	sk	Hodnoty nastavení
+confirm delete	workflow	sk	Potvrdi» zmazanie
+consult %1 to get the default values:	workflow	sk	Konzultova» %1 pre získanie predvolených hodnôt:
+couldn't add transition	workflow	sk	Nepodarilo sa prida» prechod
+create	workflow	sk	Vytvori»
+created	workflow	sk	Vytvorené
+date:	workflow	sk	Dátum:
+default config values	common	sk	Predvolené hodnoty nastavení
+default next user	workflow	sk	Predvolený ïal¹í pouŸívateµ
+default owner	workflow	sk	Predvolený vlastník
+default settings for processes	admin	sk	Predvolené nastavenia pre procesy
+default user	workflow	sk	Predvolený pouŸívateµ
+delete selected	workflow	sk	Vymaza» vybrané
+delete transition	workflow	sk	Vymaza» prechod
+deletion successful	workflow	sk	Mazanie úspe¹ne dokonèené
+delition successful	workflow	sk	Mazanie úspe¹ne dokonèené
+description	workflow	sk	Opis
+display please wait message	common	sk	zobrazi» správu prosím èakajte
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	sk	Chcete stav aktivity na zoznamoch sedení? Po väè¹inu èasu je "vykonáva sa" ale ak pouŸívate nie automaticky smerované prechody, budete ma» nejaké dokonèené aktivity.
+do you want the category column on instances lists, if yout instances use categories you should use it	workflow	sk	Chcete ståpec kategórie v zoznamoch sedení? Ak va¹e sedenia pouŸívajú kategórie, mali by ste to pouŸi».
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	sk	Chcete ståpec názvu kategórie v zoznamoch sedení? Ak va¹e sedenia pouŸívajú kategórie, mali by ste to pouŸi».
+do you want the category name column on instances lists. if your instances use categories you should use this	workflow	sk	Chcete ståpec názov kategórie v zoznamoch sedení? Ak va¹e sedenia pouŸívajú kategórie, mali by ste to pouŸi».
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	sk	Chcete ståpec ID sedenia v zoznamoch sedení? Je to jedineèný identifikátor sedenia.
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	sk	Chcete ståpec názvu sedenia v zoznamoch sedení? Ak va¹e sedenia majú názov, mali by ste to pouŸi».
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	sk	Chcete ståpec stavu sedenia v zoznamoch sedení? Stav sedenia je vhodný na rozlí¹enie medzi zru¹enými, dokonèenými, výnimkami alebo aktívnymi sedeniami.
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	sk	Chcete ståpec vlastníka v zoznamoch sedení? Zobrazuje súèasného vlastníka. Veµmi vhodné v prípade, Ÿe vlastníctvo je definované so ¹peciálnymi oprávneniami.
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	sk	Chcete ståpec priority v zoznamoch sedení? Priorita sa nastavuje vo formulároch aktivít.
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	sk	Chcete ståpec procesu v zoznamoch sedení? Vhodné ak máte rozlièné procesy a/alebo verzie týchto procesov.
+do you want the search instance button in the last row of instances list.	workflow	sk	Chcete tlaèítko hµadania sedení v poslednom riadku zoznamu sedení?
+do you want the started date column on instances lists.	workflow	sk	Chcete ståpec Dátum skutoèného zaèiatku v zoznamoch sedení?
+don't move	workflow	sk	Nepresúva»
+draw roles	common	sk	Nakresli» úlohy
+draw roles on the graph beside activity name like [that]	admin	sk	Nakresli» úlohy v grafe vedµa názvu aktivity ako [toto]
+duration	workflow	sk	Trvanie
+empty agent type	workflow	sk	prázdny typ agenta
+end	workflow	sk	Koniec
+end activity is not reachable from start activity	workflow	sk	Koncová aktivita je nedosiahnuteµná zo zaèiatoènej aktivity
+ended	workflow	sk	Skonèilo
+enter an activity name	workflow	sk	Zadajte názov aktivity
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	sk	Chyba: ïal¹iaAktivita (nextActivity) sa nezhoduje so Ÿiadnym kandidátom v automaticky smerovanom prepínaní aktivity
+error: non-deterministic decision for autorouting activity	workflow	sk	Chyba: nepredvídateµné rozhodnutie pre automaticky smerovanú aktivitu
+error: removing was not done	workflow	sk	Chyba: odstraòovanie sa neuskutoènilo
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	sk	Chyba: pokus o odoslanie sedenia k aktivite, ale nedá sa dosta» k tejto aktivite
+error: trying to send an instance to an activity but no transition found	workflow	sk	Chyba: pokus o odoslanie sedenia k aktivite, ale nena¹iel sa Ÿiadny prechod
+exception	workflow	sk	Výnimka
+exception instance	workflow	sk	Sedenie výnimky
+exception raised by %1 %2: %3	workflow	sk	Výnimka zvý¹ená o %1 %2: %3
+exception resumed by %1 %2: %3	workflow	sk	Výnimka poníŸená o %1 %2: %3
+exception this instance	workflow	sk	Prideli» výnimku tomuto sedeniu
+exceptions	workflow	sk	Výnimky
+execute this activity	workflow	sk	Vykona» túto aktivitu
+export	workflow	sk	Export
+failed to create workitem	workflow	sk	Nepodarilo sa vytvori» pracovnú poloŸku
+failed to execute automatic activity	workflow	sk	Nepodarilo sa vykona» automatickú aktivitu
+failed to obtain lock on %1 table	workflow	sk	Nepodarilo sa získa» zámok na tabuµke %1
+failed to obtain lock on instances table	workflow	sk	Nepodarilo sa získa» zámok na tabuµke sedení
+failed to obtain lock on instances_activities table	workflow	sk	Nepodarilo sa získa» zámok na tabuµke aktivít_sedení
+failed to record instance properties	workflow	sk	Nepodarilo sa zaznamena» náleŸitosti sedenia
+failed to synchronize instance data with the database	workflow	sk	Neporadilo sa synchronizova» dáta sedenia s databázou
+failure	workflow	sk	zlyhanie
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	sk	Fatálna chyba: ïal¹iaAktivita (nextActivity) sa nezhoduje so Ÿiadnym kandidátom  v automaticky smerovanom prepínaní aktivity
+fatal error: non-deterministic decision for autorouting activity	workflow	sk	Fatálna chyba: nepredvídateµné rozhodnutie pre automaticky smerovanú aktivitu
+fatal error: setting next activity to an unexisting activity	workflow	sk	Fatálna chyba: nastavujeme ïal¹iu aktivitu na neexistujúcu aktivitu
+fatal error: trying to send an instance to an activity but no transition found	workflow	sk	Fatálna chyba: pokus o odoslanie sedenia k aktivite, ale nena¹iel sa Ÿiadny prechod
+filter	workflow	sk	Filter
+filter instance by id	workflow	sk	Filtrova» sedenie pomocou ID
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	sk	Napokon máte odkazy so syntaxou <strong>%link_XX|YY%</strong>, XX je èas» adresy, YY je èas» textu.
+fix	workflow	sk	Opravi»
+fix concistency for selected rows	workflow	sk	Opravi» konzistenciu pre vybrané riadky
+font size	workflow	sk	Veµkos» písma
+from	workflow	sk	Od
+from:	workflow	sk	Od:
+get back to global activities	workflow	sk	návrat na globálne aktivity
+get back to instance creation	workflow	sk	návrat na vytváranie sedenia
+get property	workflow	sk	Získa» náleŸitos»
+global activities	workflow	sk	Globálne aktivity
+global workflow preferences	workflow	sk	Globálne nastavenia Pracovného denníka
+go	workflow	sk	choï
+go to same activities for other instances of this process	workflow	sk	choï na rovnaké aktivity pre iné sedenia tohto procesu
+go to same process activities	workflow	sk	choï na rovnaké aktivity procesu
+go to the actual state of this instance	workflow	sk	choï na súèasný stav tohto sedenia
+grab instance	workflow	sk	Prevzia» sedenie
+grant access to the administration and development of workflow processes and activities.	admin	sk	Prideli» prístup na správu a vývoj procesov a aktivít Pracovného denníka.
+grant access to the administration of workflow elements	admin	sk	Prideli» prístup na správu elementov Pracovného denníka
+grant access to the administration of workflow instances in monitor screens	admin	sk	Prideli» prístup na správu sedení Pracovného denníka na sledovacích stránkach (monitor screens)
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	admin	sk	Prideli» prístup na èistenie/mazanie zru¹ených sedení Pracovného denníka na sledovacích stránkach (monitor screens)
+grant access to the monitoring of workflow elements	admin	sk	Prideli» prístup na sledovanie elementov Pracovného denníka
+graph	workflow	sk	Graf
+graphic options	common	sk	Grafické predvoµby
+group	workflow	sk	Skupina
+id	workflow	sk	ID
+if automatic parsing is disabled next options will be useless	admin	sk	Ak je vypnuté automatické parsovanie, nasledujúce voµby budú bezpredmetné
+if not in debug mail_smtp agent would have sent this email:	workflow	sk	Ak nie v debug mail_smtp, agent má odosla» tento email:
+if user is in a role for an activity he will have the right to abort the related instance	admin	sk	Ak pouŸívateµ je v úlohe k aktivite, dostáva právo zru¹i» zodpovedajúce sedenie
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	sk	Ak pouŸívateµ je v úlohe k aktivite, dostáva právo udeli» výnimku alebo poníŸi» zodpovedajúce sedenie
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	sk	Ak pouŸívateµ je v úlohe k aktivite, dostáva právo uvoµni» (zru¹i» priradenie) zodpovedajúce sedenie
+import aborted	workflow	sk	Import zru¹ený
+import successfull	workflow	sk	Import úspe¹ný
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	sk	V mapovaní úloh, pouŸívateµ #%1 je uvedený ako "%2" ale MO®NO je "%3"
+inactive	workflow	sk	Neaktívne
+inst.	workflow	sk	Sed.
+inst. status	workflow	sk	Stav Sed.
+instance	workflow	sk	Sedenie
+instance %1	workflow	sk	Sedenie %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	sk	Sedenie %1 je v stave %2, akcia %3 je nemoŸná.
+instance %1 is in exception, action %2 is not possible.	workflow	sk	Sedenie %1 je vo výnimke, akcia %2 je nemoŸná.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	sk	Sedenie %1 nie je priradené k aktivite %2, akcia %3 je nemoŸná.
+instance history	workflow	sk	História sedení
+instance properties	workflow	sk	NáleŸitosti sedení
+instance:	workflow	sk	Sedenie:
+instance: %1 (process: %2)	workflow	sk	Sedenie: %1 (Proces: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	sk	Sedenie: nepodarilo sa zmeni» %1 [%2], niekto to uŸ stihol zmeni» pred nami
+instance: unable to modify %1, someone has changed it before us	workflow	sk	Sedenie: nepodarilo sa zmeni» %1, niekto to uŸ stihol zmeni» pred nami
+instances	workflow	sk	Sedenia
+instances selection	workflow	sk	Výber sedení
+int.	workflow	sk	Int.
+interactive	workflow	sk	Interaktívne
+interactive activities show form before being executed	workflow	sk	Interaktívne aktivity zobrazia formulár, neŸ sa spustia
+interactive instances should not call the complete() method	workflow	sk	Interaktívne sedenia by nemali vola» metódu complete()
+interactive:	workflow	sk	Interaktívne:
+interactivity	workflow	sk	Interaktívnos»
+invalid	workflow	sk	Chybné
+invalid process	workflow	sk	Chybný proces
+invalid role name	workflow	sk	Chybný názov úlohy
+is active	workflow	sk	Je aktívne
+it seems this activity for this instance is not assigned to you anymore.	workflow	sk	Zdá sa, Ÿe táto aktivity pre toto sedenie vám uŸ nie je priradená.
+it was impossible to complete, no activity was given.	workflow	sk	Nedalo sa dokonèi», nebola zadaná aktivita.
+it was impossible to complete, no corresponding activity was found.	workflow	sk	Nedalo sa dokonèi», nena¹la sa Ÿiadna zodpovedajúca aktivita.
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	sk	Adresy odkazov sú povaŸované za lokálne, ak neobsahujú <strong>http://</strong>. Dostávajú prednastavenú lokálnu predponu a skenujú sa odkazovým mechanizmom eGroupWare
+list of activities	workflow	sk	Zoznam aktivít
+list of all activities with, for each,  counters of instances by status	workflow	sk	zoznam aktivít, zahàòajúci pre kaŸdú aj poèítadlá sedení podµa stavov
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	sk	zoznam v¹etkých poloŸiek histórie vytvorených sedeniami poèas ich putovania v Pracovnom denníku, s informáciami o trvaní a èase
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	sk	zoznam v¹etkých sedení s informáciami o súèasnom stave a aktivitách a odkazu na správu týchto sedení
+list of instances	workflow	sk	Zoznam sedení
+list of mappings	workflow	sk	Zoznam mapovaní
+list of monitors	workflow	sk	Zoznam sledovaní
+list of processes	workflow	sk	Zoznam procesov
+list of processes (%1)	workflow	sk	Zoznam procesov (%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	sk	zoznam procesov so stavom, platnos»ou a pre kaŸdú, poèítadlami sedení podµa stavu
+list of transitions	workflow	sk	Zoznam prechodov
+list of workitems	workflow	sk	Zoznam pracovných poloŸiek
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	sk	Mail automaticky odoslaný po¹tovým SMTP agentom pre Pracovný denník v eGroupWare
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	sk	Správy sa dajú posiela» na zaèiatku alebo konci aktivity. Pri interaktívnych aktivitách sa dajú posiela» len po dokonèení.
+manual	workflow	sk	Manuál
+map	workflow	sk	mapova»
+map users/groups to roles	workflow	sk	Mapova» pouŸívateµov/skupiny do úloh
+mapping to inexistent role	workflow	sk	Mapuje sa do neexistujúcej úlohy
+mappings deleted	workflow	sk	Mapovania zmazané
+message:	workflow	sk	Správa:
+monitor activities	workflow	sk	Sledova» aktivity
+monitor instance	workflow	sk	Sledova» sedenie
+monitor instances	workflow	sk	Sledova» sedenia
+monitor processes	workflow	sk	Sledova» procesy
+monitor this instance	workflow	sk	Sledova» toto sedenie
+monitor work items	workflow	sk	Sledova» pracovné poloŸky
+monitor workitems	workflow	sk	Sledova» pracovné poloŸky
+monitoring	admin	sk	Sledovanie
+monitors	workflow	sk	Sledovaèe
+more options?	workflow	sk	Viac moŸností?
+my activities	workflow	sk	Moje aktivity
+my instances	workflow	sk	Moje sedenia
+my processes	workflow	sk	Moje procesy
+name	workflow	sk	Názov
+new instance	workflow	sk	Nové sedenie
+new major	workflow	sk	Nové hlavné
+new major version created	workflow	sk	Nová hlavná verzia vytvorená
+new mapping added	workflow	sk	Pridané nové mapovanie
+new minor	workflow	sk	Nová malá
+new minor version created	workflow	sk	Nová malá verzia vytvorená
+new status not set, no corresponding activity was found.	workflow	sk	Nový stav nebol nastavený, nena¹li sa Ÿiadne zodpovedajúce aktivity.
+new transition added	workflow	sk	Nové prechody pridané
+next activity	workflow	sk	Ïal¹ia aktivita
+next user:	workflow	sk	Ïal¹í pouŸívateµ:
+no action avaible because no activity and no instance are given!	workflow	sk	®iadna akcia nie je dostupná, pretoŸe nebola zadaná ani aktivita, ani sedenie!
+no activites	workflow	sk	®iadne aktivity
+no activity indicated	workflow	sk	®iadna indikovaná aktivita
+no agents associated with this activity	workflow	sk	®iadni agenti priradení k tejto aktivite
+no circular transitions allowed.	workflow	sk	Neboli dovolené Ÿiadne kruhové prechody.
+no corresponding activity was found.	workflow	sk	®iadna zodpovedajúca aktivita sa nena¹la.
+no inbound for start activity	workflow	sk	®iadny vstup pre zaèiatok aktivity
+no inconcistency detected	workflow	sk	Neboli objavené Ÿiadne nekonzistencie
+no instance avaible	workflow	sk	Ÿiadne sedenie nie je dostupné
+no instance given, nothing to show	workflow	sk	Ÿiadne sedenie nebolo zadané, niet èo zobrazi»
+no instance indicated	workflow	sk	®iadne indikované sedenie
+no outbound for end activity	workflow	sk	®iadny výstup pre koniec aktivity
+no process indicated	workflow	sk	®iadny indikovaný proces
+no properties defined	workflow	sk	®iadne náleŸitosti neboli definované
+no roles	workflow	sk	®iadne úlohy
+no roles asociated with this activity	workflow	sk	K tejto aktivite nie sú priradené Ÿiadne úlohy
+no routage	workflow	sk	®iadne smerovanie
+no scan done	workflow	sk	®iadny sken nebol vykonaný
+no transitions allowed for standalone or view activities	workflow	sk	®iadne prechody nie sú povolené pre samostatné alebo zobrazovacie aktivity
+no work item indicated	workflow	sk	®iadna indikovaná pracovná poloŸka
+nobody	workflow	sk	Nikto
+not defined	workflow	sk	nedefinované
+or import a process	workflow	sk	Alebo importova» proces
+owner	workflow	sk	Vlastník
+owner of the instance will have the right to abort the instance at any time	admin	sk	Vlastník sedenia dostane právo kedykoµvek zru¹i» sedenie
+owner of the instance will have the right to exception or resume the instance at any time	admin	sk	Vlastník sedenia dostane právo kedykoµvek udeli» výnimku alebo poníŸi» sedenie
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	sk	Vlastník sedenia dostane právo zru¹i» pridelenie aktivity k pouŸívateµovi
+owner:	workflow	sk	Vlastník:
+ownership give abort right	common	sk	prideli» právo zru¹enia na základe vlastníctva
+ownership give exception right	common	sk	prideli» právo výnimky na základe vlastníctva
+ownership give release right	common	sk	prideli» právo zru¹enia pridelenia na základe vlastníctva
+please wait, task in progress ...	workflow	sk	Prosím èakajte, úloha sa vykonáva...
+post activity %1 code is not avaible	workflow	sk	kód %1 po skonèení aktivity nie je dostupný
+post shared code is not avaible	workflow	sk	kód po skonèení zdieµania nie je dostupný
+post-agent %1 code is not avaible	workflow	sk	kód %1 po agentovi nie je dostupný
+pr.	workflow	sk	Pr.
+pre-activity %1 code is not avaible	workflow	sk	kód %1 pred aktivitou nie je dostupný
+pre-agent %1 code is not avaible	workflow	sk	kód %1 pred agentom nie je dostupný
+pre-shared code is not avaible	workflow	sk	kód pred zdieµaním nie je dostupný
+printer friendly	workflow	sk	Verzia pre tlaè
+priority level:	workflow	sk	Úroveò priority:
+process	workflow	sk	Proces
+process %1	workflow	sk	proces %1
+process %1 %2 is not active, action %3 is impossible	workflow	sk	Proces %1 %2 nie je aktívny, akcia %3 nie je moŸná
+process %1 v%2 as no related activity	workflow	sk	Proces %1 v%2 nemá zodpovedajúcu aktivitu
+process %d has been activated	workflow	sk	Proces %d bol aktivovaný
+process %d has been deactivated	workflow	sk	Proces %d bol deaktivovaný
+process %s %s already exists, the import process was aborted	workflow	sk	Proces %s %s uŸ existuje, importný proces bol zru¹ený
+process %s %s imported	workflow	sk	Proces %s %s naimportovaný
+process %s has been created	workflow	sk	Proces %s bol vytvorený
+process %s has been updated	workflow	sk	Proces %s bol aktualizovaný
+process %s removed	workflow	sk	Proces %s bol odstránený
+process activities	workflow	sk	Aktivity procesu
+process alone	workflow	sk	Samotný proces
+process does not have a start activity	workflow	sk	Proces nemá zaèiatoènú aktivitu
+process does not have exactly one end activity	workflow	sk	Proces nemá jednu jasnú cieµovú aktivitu
+process form	workflow	sk	Formulár procesu
+process name	workflow	sk	Názov procesu
+process name already exists	workflow	sk	Tento názov procesu uŸ existuje
+process roles	workflow	sk	Úlohy procesu
+process saved	workflow	sk	Proces uloŸený
+process transitions	workflow	sk	Prechody procesu
+process version:	workflow	sk	Verzia procesu:
+process:	workflow	sk	Proces:
+processes	workflow	sk	Procesy
+properties	workflow	sk	NáleŸitosti
+property	workflow	sk	NáleŸitos»
+property %1 already exists	workflow	sk	NáleŸitos» %1 uŸ existuje
+property %1 not found	workflow	sk	NáleŸitos» %1 sa nena¹la
+quit without saving	workflow	sk	Skonèi» bez uloŸenia
+read-only	workflow	sk	len na èítanie
+release access to this activity	workflow	sk	Uvoµni» prístup k tejto aktivite
+release activity for this instance	workflow	sk	Uvoµni» aktivitu pre toto sedenie
+release instance	workflow	sk	Uvoµni» sedenie
+reload filter	workflow	sk	Znovunaèíta» filter
+remove active instances	workflow	sk	Odstráni» aktívne sedenia
+remove all instances for this process	workflow	sk	Odstráni» v¹etky sedenia k tomuto procesu
+remove selected roles	workflow	sk	Odstráni» vybrané úlohy
+removing instances and workitems for aborted instances on all processes	workflow	sk	Odstráni» sedenia a pracovné poloŸky pre zru¹ené sedenia na v¹etkých procesoch
+removing instances and workitems for aborted instances on process #%1	workflow	sk	Odstraòujú sa sedenia a pracovné poloŸky pre zru¹ené sedenia na procese #%1
+removing instances and workitems for all instances on process #%1	workflow	sk	Odstraòujú sa sedenia a pracovné poloŸky pre v¹etky sedenia na procese #%1
+replyto:	workflow	sk	Odpoveda»(komu):
+restart	workflow	sk	re¹tartova»
+restart activity	workflow	sk	re¹tartova» aktivitu
+resume this exception instance	workflow	sk	PoníŸi» toto výnimoèné sedenie
+role	workflow	sk	Úloha
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	sk	Úloha #%1 v procese %2 má iný proces (%3) v mapovaní s pouŸívateµom #%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	sk	Úloha %1 (#%2) je prradená k neexistujúcemu procesu (#%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	sk	Úloha %1 je priradená v mapovaní s pouŸívateµom #%2 k neexistujúcemu procesu (%3)
+role %1 is not mapped	workflow	sk	Úloha %1 nie je mapovaná
+role added to activity	workflow	sk	Úloha pridaná k aktivite
+role added to process	workflow	sk	Úloha pridaná k procesu
+role give abort right	common	sk	da» úlohou právo zru¹enia
+role give exception right	common	sk	da» úlohou právo výnimky
+role give release right	common	sk	da» úlohou právo zru¹enia priradenia
+role in inexistent process	workflow	sk	Úloha v neexistujúcom procese
+role mapping in inexistent process	workflow	sk	Mapovanie úlohy v neexistujúcom procese
+role name	workflow	sk	Názov úlohy
+role not saved (maybe a name collision)	workflow	sk	Úloha nebola uloŸená
+role process inconcistency in mappings	workflow	sk	Nekonzistentnos» v mapovaniach úlohy procesu
+role saved	workflow	sk	Úloha uloŸená
+roles	workflow	sk	Úlohy
+roles assigned to this activity	workflow	sk	Úlohy priradené k tejto aktivite
+roles deleted	workflow	sk	Úlohy vymazané
+routing	workflow	sk	Smerovanie
+routing:	workflow	sk	smerovanie:
+run	workflow	sk	spusti»
+run activity	workflow	sk	spusti» aktivitu
+run instance	workflow	sk	spusti» sedenie
+running	workflow	sk	beŸiace
+running activities options	common	sk	Nastavenia beŸiacich aktivít
+running activity	workflow	sk	BeŸiace aktivity
+scan activities	workflow	sk	Skenova» aktivity
+scan agents	workflow	sk	Skenova» agentov
+scan instances	workflow	sk	Skenova» sedenia
+scan processes	workflow	sk	Skenova» procesy
+scan roles	workflow	sk	Skenova» úlohy
+scan transitions	workflow	sk	Skenova» prechody
+search instance filter in the bottom of instance lists	workflow	sk	Vyhµadávanie cez filter sedení na spodku zoznamov sedení
+search:	workflow	sk	hµada»:
+security check: cannot understand asked action	workflow	sk	Bezpeènostná kontrola: Nerozumiem zadanej akecii
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	sk	taktieŸ pozrite <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> a <strong>%process_id%</strong>
+select a transition to remove	workflow	sk	Vyberte, ktorý prechod odstráni»
+select source	workflow	sk	vyberte zdroj
+send after interactive activity is completed	workflow	sk	posla» po dokonèení interaktívnej aktivity
+send all to	workflow	sk	Posla» p¹etko (kam)
+send an email	workflow	sk	Posla» email
+send instance	workflow	sk	Posla» sedenie
+send this instance to the next activity	workflow	sk	Posla» toto sedenie ïal¹ej aktivite
+send transition	workflow	sk	Posla» prechod
+send when the activity is ending	workflow	sk	Posla» keï sa konèí aktivita
+send when the activity is starting	workflow	sk	Posla» keï sa zaèína aktivita
+send when wf_agent_mail_smtp['submit_send'] is posted	workflow	sk	Posla» keï wf_agent_mail_smtp['submit_send'] je odoslaný
+set next act	workflow	sk	Nastav Ïal¹iu aktivitu
+set next user	workflow	sk	Nastav ïal¹ieho pouŸívateµa
+set property	workflow	sk	Nastav náleŸitos»
+setnextuser directives can override it	workflow	sk	direktívy setNextUser to môŸu prebi»
+setting next activity to an unexisting activity	workflow	sk	ïal¹ia aktivita sa nastavuje na neexistujúcu aktivitu
+shared code	workflow	sk	Zdieµaný kód
+should we always give you the advanced search row on instances lists?	workflow	sk	Chcete ma» vŸdy k dispozícii riadok pre roz¹írené hµadanie v zoznamoch sedení?
+show activity info zone	common	sk	UkáŸ info zónu aktivít
+show activity title	common	sk	UkáŸ titul aktivity
+show code	workflow	sk	UkáŸ kód
+show instance name	common	sk	UkáŸ názov sedenia
+show instance owner	common	sk	UkáŸ vlastníka sedenia
+show multiple submit as select	common	sk	UkáŸ viacnásobné potvrdenie ako výber
+show template	workflow	sk	UkáŸ ¹ablónu
+size of the font used on the graph 12 should be a good default value	admin	sk	Veµkos» fontu pouŸitého v grafe 12 by mala by» vhodnou predvolenou hodnotou
+smtp agent has detected some errors when sending email after completion of the activity	workflow	sk	SMTP agent zistil nejaké chyby poèas odosielania email-u po dokonèení aktivity
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	sk	SMTP agent zistil nejaké chyby poèas odosielania email-u pred zaèatím aktivity
+smtp agent has detected some errors when sending email at the end of this activity	workflow	sk	SMTP agent zistil nejaké chyby poèas odosielania email-u na konci tejto aktivity
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	sk	SMTP agent zistil nejaké chyby poèas odosielania email-u na vyŸiadanie poèas tejto aktivity
+something was wrong while creating the new major version	workflow	sk	Nieèo sa nepodarilo poèas vytvárania novej hlavnej verzie
+something was wrong while creating the new minor version	workflow	sk	Nieèo sa nepodarilo poèas vytvárania novej malej verzie
+source code file for activity %1 is not avaible	workflow	sk	Súbor zdrojového kódu pre aktivitu %1 nie je dostupný
+source code for activity %1 is not avaible	workflow	sk	Zdrojový kód pre aktivitu %1 nie je dostupný
+source saved	workflow	sk	Zdroj uloŸený
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	sk	©peciálne známe hodnoty pre adresy lokálnych odkazov sú <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> a <strong>admininstance</strong>.
+split	workflow	sk	Rozdeli»
+standalone	workflow	sk	samostatné
+start	workflow	sk	Zaèiatok
+start activities must be autorouted	workflow	sk	Zaèiatoèné aktivity musia by» automaticky smerované
+start activities must be interactive	workflow	sk	Zaèiatoèné aktivity musia by» interaktívne
+start activity	workflow	sk	Zaèa» aktivitu
+start process	workflow	sk	Zaèa» proces
+started	workflow	sk	Zaèaté
+started:	workflow	sk	Zaèaté:
+starting page	workflow	sk	Zaèiatoèná stránka
+status	workflow	sk	Stav
+status:	workflow	sk	stav:
+stop	workflow	sk	Stop
+subject:	workflow	sk	Predmet:
+switch	workflow	sk	prepnú»
+template	workflow	sk	¹ablóna
+test concistency	workflow	sk	Testova» konzistenciu
+test consistency of datas in the database	workflow	sk	Testova» konzistenciu dát v databáze
+test local installation	workflow	sk	Testova» lokálnu in¹taláciu
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	sk	Adresár /workflow neexistuje a nedá sa vytvori». Prosím poŸiadajte svojho správcu aby skontroloval globálne nastavenia
+the activity was not completed	workflow	sk	Aktivita nebola dokonèená
+the default user will only be set if he is mapped to a role on the activity	workflow	sk	Predvolený pouŸívateµ bude nastavený len ak je namapovaný do nejakej úlohy v aktivite
+the following items must be corrected to be able to activate this process	workflow	sk	Nasledovné poloŸky sa musia opravi», ak chcete aktivova» proces
+the instance title is shown on top of the form	admin	sk	Titulok sedenia sa zobrazuje navrchu formulára
+the label you want	workflow	sk	menovka ktorú chcete
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	sk	SMTP nastavenia sa nepodarilo naèíta» mail_smtp agentovi Pracovného denníka
+there are no activities available	workflow	sk	Nie sú dostupné Ÿiadne aktivity
+there are no config value defined	workflow	sk	Nie je definovaná Ÿiadna hodnota nastavenia
+there are no instances available	workflow	sk	Nie sú dostupné Ÿiadne sedenia
+there are no mappings defined for this process	workflow	sk	Nie sú definované Ÿiadne mapovania pre tento proces
+there are no process available	workflow	sk	Nie je dostupný Ÿiadny proces
+there are no processes	workflow	sk	Neexistujú Ÿiadne procesy
+there are no processes available	workflow	sk	Nie sú dostupné Ÿiadne procesy
+there are no processes defined	workflow	sk	Nie sú definované Ÿiadne procesy
+there are no processes with the current filter	workflow	sk	Neexistujú Ÿiadne procesy so súèasným filtrom
+there are no properties available	workflow	sk	Nie sú dostupné Ÿiadne náleŸitosti
+there are no roles defined for this process	workflow	sk	Nie sú definované Ÿiadne úlohy pre tento proces
+there are no transitions defined	workflow	sk	Nie sú definované Ÿiadne prechody
+there are no user activites available	workflow	sk	Nie sú dostupné Ÿiadne pouŸívateµské aktivity
+there are no workitems available	workflow	sk	Nie sú dostupné Ÿiadne pracovné poloŸky
+there are some undefined preferences associated with this form : %1	workflow	sk	Máme tu nejaké nedefinované náleŸitosti priradené k tomuto formuláru: %1
+there is an unknown user or group #%1 in role mappings	workflow	sk	Máme tu nejakého neznámeho pouŸívateµa alebo skupinu #%1 v mapovaných úlohách
+they were problems at the compilation of the source:	workflow	sk	Poèas kompilácie zdrojov nastali problémy:
+this activity for this instance is actually avaible for you.	workflow	sk	Táto aktivita k tomuto sedeniu je pre Vás v súèasnosti nedostupná.
+this activity for this instance is actually only avaible for you.	workflow	sk	Táto aktivita k tomuto sedeniu je v súèasnosti dostupná len pre Vás.
+this activity for this instance is not specifically assigned to you.	workflow	sk	Táto aktivita k tomuto sedeniu nie je priradená ¹pecificky k Vám.
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	sk	Tento agent dáva aktivite moŸnos» posiela» SMTP správy (mail)
+this form will test your local workflow installation to detect potential issues	workflow	sk	Tento formulár otestuje Va¹u lokálnu in¹taláciu Pracovného denníka pre odhalenie moŸných problémov
+this is the first screen shown when you click on the workflow application icon	workflow	sk	Toto je prvá stránka, ktorá sa zobrazí keï kliknete na ikonku aplikácie Pracovný denník
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	sk	Tento proces má zobrazovaciu aktivitu. Prístup v zobrazovacom reŸime je umoŸnený len pre túto zobrazovaciu aktivitu.
+this process has no end activity	workflow	sk	Tento proces nemá koncovú aktivitu
+this will automatically release the instance when leaving an activity without completing	admin	sk	Týmto sa automaticky zru¹í priradenie sedenia pri opustení aktivity bez dokonèenia
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	sk	Týmto sa zobrazuje zápätie aktivity vtedy, keï je akákoµvek aktivita spustená s informáciami ohµadom mechanizmu Pracovného denníka
+to	workflow	sk	Komu
+to:	workflow	sk	Komu:
+transition	workflow	sk	prechod
+transition mode	workflow	sk	reŸim prechodu
+transition to %1	workflow	sk	prechod na %1
+transition waiting for human interaction	workflow	sk	prechod èaká na zásah èloveka
+transitions	workflow	sk	prechody
+transitions removed successfully	workflow	sk	Prechody úspe¹ne odstránené
+type	workflow	sk	typ
+type:	workflow	sk	typ:
+unknow fix instruction :%1	workflow	sk	neznáma fix in¹trukcia: %1
+unknown instruction from the workflow engine: %1	workflow	sk	neznáma in¹trukcia z mechanizmu Pracovného denníka: %1
+unknown status	workflow	sk	neznámy stav
+update	workflow	sk	aktualiácia
+upload file	workflow	sk	Nahra» súbor
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	sk	Na vytváranie po¹tových profilov pouŸite <a href="%1">EmailAdmin</a>
+use automatic parsing	common	sk	pouŸi» automatické parsovanie
+use default	workflow	sk	PouŸi» predvolené
+use existing roles	workflow	sk	PouŸi» existujúce úlohy
+user	workflow	sk	PouŸívateµ
+user #%1 is associated with a non-existent role #%2	workflow	sk	PouŸívateµ #%1 je priradený k neexistujúcej úlohe #%2
+user activities	workflow	sk	PouŸívateµské aktivity
+user instances	workflow	sk	PouŸívateµské sedenia
+user instances form: columns	workflow	sk	Formulár pouŸívateµských sedení: ståpce
+user instances form: filters and actions	workflow	sk	Formulár pouŸívateµských sedení: filtre a akcie
+user is not authorized to delete aborted instances	workflow	sk	PouŸívateµ nemá oprávnenie maza» zru¹ené sedenia
+user is not authorized to delete instances	workflow	sk	PouŸívateµ nemá oprávnenie maza» sedenia
+user processes	workflow	sk	PouŸívateµské procesy
+user/group	workflow	sk	PouŸívateµ/skupina
+user:	workflow	sk	PouŸívateµ
+users can act on activity before its execution with form and after by sending it to the next activity	workflow	sk	PouŸívateµ môŸe nad aktivitou kona» pred jej spustením pomocou formulára, a potom pomocou jej odoslania na nasledujúcu aktivitu
+users/groups	workflow	sk	PouŸívatelia/skupiny
+valid	workflow	sk	Platné
+valid process	workflow	sk	Platný proces
+valid:	workflow	sk	platné:
+validity:	workflow	sk	Platnos»:
+value	workflow	sk	Hodnota
+version	workflow	sk	Verzia
+view details	workflow	sk	Zobrazi» podrobnosti
+view this instance	workflow	sk	Zobrazi» toto sedenie
+view workitem	workflow	sk	Zobrazi» pracovnú poloŸku
+warning this filter override all others filters	workflow	sk	Varovanie: tento filter prebije v¹etky ostatné filtre
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	sk	Varovanie: stlaèením tohto tlaèitla definitívne odstránite v¹etky zru¹ené sedenia VRÁTANE ich histórie (pracovných poloŸiek) pre vybrané procesy.
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	sk	Varovanie: stlaèením tohto tlaèitla definitívne odstránite v¹etky sedenia VRÁTANE ich histórie (pracovných poloŸiek) pre vybrané procesy, a to nezávisle na stave v ktorom sú.
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	sk	NemôŸeme spusti» túto aktivitu, moŸnoŸe toto sedenie alebo táto aktivita uŸ neexistuje.
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	sk	Majú sa v roz¹írenom reŸime zobrazova» roz¹írené akcie? Napríklad poníŸi», výnimka, prevzia»..
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	sk	Keï sú dostupné voµby pre viacnásobné potvrdenie, vykresµujeme výberové okno kde je iba jedno tlaèítko potvrdenia namiesto viacerých
+when to send the message:	workflow	sk	Kedy posla» túto správu:
+workflow	common	sk	Pracovný denník
+workflow configuration	admin	sk	Nastavenie Pracovného denníka
+workflow navigation	workflow	sk	Navigácia Pracovného denníka
+workflow preferences	workflow	sk	Predvoµby Pracovného denníka
+workflow site configuration	workflow	sk	Nastavenia stránky Pracovného denníka
+workitem information	workflow	sk	Informácie o pracovnej poloŸke
+workitems	workflow	sk	Pracovné poloŸky
+you are not allowed to abort instance %1	workflow	sk	Nemáte právo zru¹i» sedenie %1
+you are not allowed to exception instance %1	workflow	sk	Nemáte právo udeli» výnimku sedeniu %1
+you are not allowed to grab instance %1	workflow	sk	Nemáte právo prevzia» sedenie %1
+you are not allowed to release instance %1	workflow	sk	Nemáte právo uvoµni» sedenie %1
+you are not allowed to restart instance %1	workflow	sk	Nemáte právo re¹tartova» sedenie %1
+you are not allowed to resume instance %1	workflow	sk	Nemáte právo poníŸi» sedenie %1
+you are not allowed to send instance %1	workflow	sk	Nemáte právo posla» sedenie %1
+you can use special values with this mail agent:	workflow	sk	S týmto ¹peciálnym po¹tovým agentom máte k dispozícii ¹peciálne hodnoty:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	sk	Nemáte právo znovu spusti» túto aplikáciu, moŸnoŸe problém konkurenèného prístupu, obnovte svoje dáta.
+you don't have the rights necessary to exception instance %1	workflow	sk	Nemáte právo k udeleniu výnimky sedeniu %1
+you have not permission to execute this activity	workflow	sk	Nemáte právo vykona» túto aktivitu
+you were not allowed to complete the activity	workflow	sk	Nemáte právo dokonèi» túto aktivitu
Index: /sandbox/workflow/branches/993/setup/default_records.inc.php
===================================================================
--- /sandbox/workflow/branches/993/setup/default_records.inc.php	(revision 2042)
+++ /sandbox/workflow/branches/993/setup/default_records.inc.php	(revision 2042)
@@ -0,0 +1,147 @@
+<?php
+  /***************************************************************************\
+  * eGroupWare - Workflow                                                     *
+  * http://www.egroupware.org                                                 *
+  * Written by:                                                               *
+  *  - Sidnei Augusto Drovetto Jr <drovetto@gmail.com>                        *
+  * ------------------------------------------------------------------------- *
+  *  This program is free software; you can redistribute it and/or modify it  *
+  *  under the terms of the GNU General Public License as published by the    *
+  *  Free Software Foundation; either version 2 of the License, or (at your   *
+  *  option) any later version.                                               *
+  \***************************************************************************/
+/* Default Workflow Database */
+
+/* extract the database connection parameters */
+if (!empty($GLOBALS['phpgw']->ADOdb->database))
+{
+	$workflowHostInfo = array(
+		'dbname' => $GLOBALS['phpgw']->ADOdb->database,
+		'host' => $GLOBALS['phpgw']->ADOdb->host,
+		'port' => $GLOBALS['phpgw']->ADOdb->port,
+		'user' => $GLOBALS['phpgw']->ADOdb->user,
+		'password' => $GLOBALS['phpgw']->ADOdb->password);
+}
+else
+{
+	$hostInfo = "dbname= host= password= port= user= " . $GLOBALS['phpgw']->ADOdb->host;
+	$hostInfo = explode(' ', $hostInfo);
+	$workflowHostInfo = array();
+	foreach ($hostInfo as $parameter)
+	{
+		$currentParameter = explode('=', $parameter);
+		$workflowHostInfo[$currentParameter[0]] = isset($currentParameter[1]) ? $currentParameter[1] : "";
+	}
+}
+
+if (($workflowHostInfo['password']{0} == "'") && ($workflowHostInfo['password']{strlen($workflowHostInfo['password'])-1} == "'"))
+	$workflowHostInfo['password'] = substr($workflowHostInfo['password'], 1, strlen($workflowHostInfo['password']) - 2);
+
+/* connect to the egroupware database */
+$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+
+/* create the workflow database */
+$GLOBALS['phpgw']->ADOdb->query("CREATE DATABASE workflow WITH OWNER = postgres TEMPLATE = template0 ENCODING = 'LATIN1'");
+$GLOBALS['phpgw']->ADOdb->query("CREATE USER admin_workflow WITH PASSWORD 'admin_workflow' NOCREATEDB NOCREATEUSER VALID UNTIL 'infinity'");
+$GLOBALS['phpgw']->ADOdb->query("CREATE GROUP workflow");
+$GLOBALS['phpgw']->ADOdb->query("ALTER GROUP workflow ADD USER admin_workflow");
+$GLOBALS['phpgw']->ADOdb->query("GRANT workflow TO admin_workflow");
+
+/* pre-configure the module */
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'workflow_database_type', 'pgsql'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'database_type', 'pgsql'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'database_admin_password', 'admin_workflow'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'database_name', 'workflow'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'database_host', 'localhost'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'database_port', '5432'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'database_admin_user', 'admin_workflow'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'intranet_subnetworks', '10.0.0.0/8'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'log_type_file', 'True'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'log_type_firebug', 'True'));
+$GLOBALS['phpgw']->ADOdb->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES(?, ?, ?)", array('workflow', 'log_level', '7'));
+
+/* connect to the new database */
+$workflowDB = $GLOBALS['phpgw']->ADOdb;
+if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+{
+	/* create a sample application (Music CD Loan) */
+	$workflowDB->query("CREATE USER admin_cds WITH PASSWORD 'admin_cds' NOCREATEDB NOCREATEUSER VALID UNTIL 'infinity'");
+	$workflowDB->query("ALTER GROUP workflow ADD USER admin_cds");
+	$workflowDB->query("CREATE SCHEMA cds AUTHORIZATION admin_cds");
+	$workflowDB->query("GRANT ALL ON SCHEMA cds TO postgres");
+	$workflowDB->query("GRANT ALL ON SCHEMA cds TO admin_cds");
+	$workflowDB->query("CREATE TABLE cds.cdcollection(cdid int4 NOT NULL, title varchar(200), status varchar(40), usuario varchar(200), CONSTRAINT cdcollection_pkey PRIMARY KEY (cdid))");
+	$workflowDB->query("ALTER TABLE cds.cdcollection OWNER TO admin_cds");
+	$workflowDB->query("GRANT ALL ON TABLE cds.cdcollection TO postgres WITH GRANT OPTION");
+	$workflowDB->query("GRANT ALL ON TABLE cds.cdcollection TO admin_cds");
+	$workflowDB->query("COMMENT ON TABLE cds.cdcollection IS 'Exemplo de Empréstimo de CDs'");
+	$workflowDB->query("INSERT INTO cdcollection VALUES (1, 'Xuxa', 'disponivel', '')");
+	$workflowDB->query("INSERT INTO cdcollection VALUES (2, 'Roberto Carlos', 'disponivel', '')");
+	$workflowDB->query("INSERT INTO cdcollection VALUES (3, 'Pink Floyd', 'disponivel', '')");
+
+	/* create the new workflow tables */
+	$workflowDB->query('CREATE TABLE organizacao (organizacao_id serial NOT NULL, nome character varying(20) NOT NULL, descricao character varying(100) NOT NULL, url_imagem character varying(200), ativa character varying(1) NOT NULL, sitio CHARACTER VARYING(100))');
+	$workflowDB->query('CREATE TABLE area_status (area_status_id serial NOT NULL, organizacao_id integer NOT NULL, descricao character varying(50) NOT NULL, nivel integer NOT NULL)');
+	$workflowDB->query('CREATE TABLE centro_custo (organizacao_id integer NOT NULL, centro_custo_id serial NOT NULL, nm_centro_custo integer NOT NULL, grupo character varying(30), descricao character varying(100) NOT NULL)');
+	$workflowDB->query('CREATE TABLE localidade (organizacao_id integer NOT NULL, localidade_id serial NOT NULL, centro_custo_id integer, descricao character varying(50) NOT NULL, empresa CHARACTER VARYING(100), endereco CHARACTER VARYING(100), complemento CHARACTER VARYING(50), cep CHARACTER VARYING(9), bairro CHARACTER VARYING(30), cidade CHARACTER VARYING(50), uf CHARACTER(2))');
+	$workflowDB->query('CREATE TABLE funcionario (funcionario_id int4 NOT NULL, area_id integer NOT NULL, localidade_id integer NOT NULL, centro_custo_id integer, organizacao_id integer NOT NULL, funcionario_status_id integer NOT NULL, cargo_id int4, nivel int2, funcionario_categoria_id int4, titulo CHARACTER VARYING(30))');
+	$workflowDB->query('CREATE TABLE area (organizacao_id integer NOT NULL, area_id serial NOT NULL, area_status_id integer NOT NULL, areasup_organizacao_id integer, superior_area_id integer, centro_custo_id integer, titular_funcionario_id int4, sigla character varying(20) NOT NULL, descricao character varying(100) NOT NULL, ativa character varying(1) NOT NULL, auxiliar_funcionario_id int4)');
+	$workflowDB->query('CREATE TABLE funcionario_status (funcionario_status_id serial NOT NULL, descricao character varying(50) NOT NULL, exibir character varying(1) NOT NULL, organizacao_id integer NOT NULL)');
+	$workflowDB->query('CREATE TABLE cargo (cargo_id serial NOT NULL, descricao character varying(150), organizacao_id int4)');
+	$workflowDB->query('CREATE TABLE funcionario_categoria (funcionario_categoria_id serial NOT NULL, descricao character varying(150), organizacao_id int4)');
+	$workflowDB->query('CREATE TABLE telefone (telefone_id serial NOT NULL, descricao character varying(50) NOT NULL, numero character varying(50) NOT NULL, organizacao_id integer NOT NULL)');
+	$workflowDB->query('CREATE TABLE substituicao (substituicao_id serial NOT NULL, area_id integer NOT NULL, funcionario_id integer NOT NULL, data_inicio date NOT NULL, data_fim date NOT NULL)');
+
+
+	/* add the constraints */
+
+	/* primary keys */
+	$workflowDB->query('ALTER TABLE ONLY organizacao ADD CONSTRAINT organizacao_pkey PRIMARY KEY (organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY area_status ADD CONSTRAINT areastatus_pkey PRIMARY KEY (area_status_id, organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY centro_custo ADD CONSTRAINT centrocusto_pkey PRIMARY KEY (organizacao_id, centro_custo_id)');
+	$workflowDB->query('ALTER TABLE ONLY localidade ADD CONSTRAINT localidade_pkey PRIMARY KEY (organizacao_id, localidade_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT funcionario_pkey PRIMARY KEY (funcionario_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT area_pkey PRIMARY KEY (area_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario_status ADD CONSTRAINT funcionario_status_pkey PRIMARY KEY (funcionario_status_id)');
+	$workflowDB->query('ALTER TABLE ONLY telefone ADD CONSTRAINT telefone_pkey PRIMARY KEY (telefone_id)');
+	$workflowDB->query('ALTER TABLE ONLY substituicao ADD CONSTRAINT substituicao_pkey PRIMARY KEY (substituicao_id)');
+
+
+	/* foreign keys */
+	$workflowDB->query('ALTER TABLE ONLY funcionario_status ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY area_status ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY centro_custo ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY localidade ADD CONSTRAINT "$1" FOREIGN KEY (centro_custo_id, organizacao_id) REFERENCES centro_custo(centro_custo_id, organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY localidade ADD CONSTRAINT "$2" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id, centro_custo_id) REFERENCES centro_custo(organizacao_id, centro_custo_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$2" FOREIGN KEY (organizacao_id, localidade_id) REFERENCES localidade(organizacao_id, localidade_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$3" FOREIGN KEY (organizacao_id, area_id) REFERENCES area(organizacao_id, area_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$4" FOREIGN KEY (funcionario_status_id) REFERENCES funcionario_status(funcionario_status_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$5" FOREIGN KEY (cargo_id) REFERENCES cargo (cargo_id)');
+	$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$6" FOREIGN KEY (funcionario_categoria_id) REFERENCES funcionario_categoria (funcionario_categoria_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$1" FOREIGN KEY (superior_area_id, areasup_organizacao_id) REFERENCES area(area_id, organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$2" FOREIGN KEY (centro_custo_id, organizacao_id) REFERENCES centro_custo(centro_custo_id, organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$3" FOREIGN KEY (titular_funcionario_id) REFERENCES funcionario(funcionario_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$4" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$5" FOREIGN KEY (area_status_id, organizacao_id) REFERENCES area_status(area_status_id, organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$6" FOREIGN KEY (auxiliar_funcionario_id) REFERENCES funcionario(funcionario_id)');
+	$workflowDB->query('ALTER TABLE ONLY telefone ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+	$workflowDB->query('ALTER TABLE ONLY substituicao ADD CONSTRAINT "$1" FOREIGN KEY (area_id) REFERENCES area(area_id)');
+	$workflowDB->query('ALTER TABLE ONLY substituicao ADD CONSTRAINT "$2" FOREIGN KEY (funcionario_id) REFERENCES funcionario(funcionario_id)');
+
+
+	/* set the permissions to the database objects */
+	$dbObjects = array('organizacao', 'area_status', 'centro_custo', 'localidade', 'funcionario', 'area', 'funcionario_status', 'telefone',	'substituicao', 'organizacao_organizacao_id_seq', 'area_status_area_status_id_seq', 'centro_custo_centro_custo_id_seq', 'localidade_localidade_id_seq', 'area_area_id_seq', 'funcionario_status_funcionario_status_id_seq', 'cargo', 'cargo_cargo_id_seq', 'funcionario_categoria', 'funcionario_categoria_funcionario_categoria_id_seq', 'telefone_telefone_id_seq', 'substituicao_substituicao_id_seq');
+
+	foreach ($dbObjects as $dbObject)
+	{
+		$workflowDB->query("GRANT ALL ON TABLE $dbObject TO admin_workflow");
+		$workflowDB->query("GRANT ALL ON TABLE $dbObject TO postgres");
+		$workflowDB->query("GRANT SELECT ON TABLE $dbObject TO public");
+	}
+}
+
+/* reconnect to the previous database */
+$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+
+?>
Index: /sandbox/workflow/branches/993/setup/phpgw_sl.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_sl.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_sl.lang	(revision 795)
@@ -0,0 +1,197 @@
+abort instance	workflow	sl	prekini primerek
+aborted	workflow	sl	prekinjeno
+act	workflow	sl	delovati
+act. status	workflow	sl	Status aktivnosti
+activate	workflow	sl	aktiviraj
+active	workflow	sl	Dejaven
+activities	workflow	sl	Dejavnosti
+activities updated	workflow	sl	Posodobljene dejavnosti
+activity	workflow	sl	dejavnost
+activity  status	workflow	sl	Status dejavnosti
+activity %1 is interactive but has no role assigned	workflow	sl	Dejavnost %1 je interaktivna, vendar nima prirejene nobene vloge.
+activity %1 is interactive so it must use the $instance->complete() method	workflow	sl	Dejavnost %1 je interaktivna, zato mora uporabiti postopek $instance->complete().
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	sl	Dejavnost %1 je neinteraktivna in ni samodejno usmerjena, vendar ima prirejeno vlogo.
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	sl	Dejavnost %1 je interaktivna, zato ne sme uporabiti postopka $instance->complete().
+activity %1 is standalone and is using the $instance object	workflow	sl	Dejavnost %1 je samostojna in uporablja objekt $instance.
+activity %1 is standalone but has transitions	workflow	sl	Dejavnost %1 je samostojna, vendar uporablja prehode.
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	sl	Dejavnost %1 je stikalo, zato mora uporabiti postopek $instance->setNextActivity($actname).
+activity completed	workflow	sl	Dejavnost dokonÄana
+activity name already exists	workflow	sl	Ime dejavnosti ÅŸe obstaja
+activity role removed	workflow	sl	Vloga dejavnosti odstranjena
+activity saved	workflow	sl	Dejavnost shranjena
+add a transition	workflow	sl	Dodaj prehod
+add new	workflow	sl	dodaj novo
+add or edit a process	workflow	sl	Dodaj ali uredi proces
+add or edit an activity	workflow	sl	Dodaj ali uredi dejavnost
+add property	workflow	sl	Dodaj lastnost
+add role	workflow	sl	Dodaj vlogo
+add role to process	workflow	sl	Dodaj vlogo procesu
+add transitions	workflow	sl	Dodaj prehod
+add transitions from	workflow	sl	Dodaj prehod od
+add transitions to	workflow	sl	Dodaj prehod k
+admin export	workflow	sl	Administrativni izvoz
+admin instance	workflow	sl	Oskrbnikov primerek
+admin process activities	workflow	sl	Dejavnosti oskrbnikovega procesa
+admin process roles	workflow	sl	Vloge oskrbnikovega procesa
+admin processes	workflow	sl	Oskrbnikovi procesi
+admin processes sources	workflow	sl	Viri oskrbnikovih procesov
+all	workflow	sl	Vsi
+auto routed	workflow	sl	Samodejno usmerjen
+automatic	workflow	sl	Samodejen
+base directory does not exist, please ask adminstrator to check the global configuration	common	sl	Osnovna mapa ne obstaja, prosite oskrbnika, da preveri globalno konfiguracijo.
+being run	workflow	sl	teÄe
+cannot add transition. only split activities can have more than one outbound transition	workflow	sl	Ne morem dodati prehoda. Le razcepne aktivnosti imajo lahko veÄ kot en izhodni prehod.
+circular reference found. some activity has a transition leading to itself	workflow	sl	Najdena kroÅŸna referenca. Neka aktivnost vodi sama do sebe.
+code	workflow	sl	koda
+complete	workflow	sl	KonÄano
+completed	workflow	sl	dokonÄano
+couldn't add transition	workflow	sl	Ne morem dodati prehoda
+create	workflow	sl	ustvari
+created	workflow	sl	Ustvarjen
+delete selected	workflow	sl	IzbriÅ¡i oznaÄeno
+deletion successful	workflow	sl	Izbris uspeÅ¡en
+delition successful	workflow	sl	Izbris uspeÅ¡en
+description	workflow	sl	Opis
+don't move	workflow	sl	Ne premakni
+duration	workflow	sl	Trajanje
+end	workflow	sl	konec
+end activity is not reachable from start activity	workflow	sl	ZakljuÄna dejavnost ni dosegljiva iz zaÄetne zadejavnosti
+exception instance	workflow	sl	izjemen primerek
+exceptions	workflow	sl	izjeme
+export	workflow	sl	Izvoz
+export a process	workflow	sl	Izvozi proces
+export file	workflow	sl	Izvozna datoteka
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	sl	Usodna napaka: naslednja dejavnost (nextActivity) se ne ujema z nobenim od kandidatov v samodejno usmerjenih dejavnostih.
+fatal error: non-deterministic decision for autorouting activity	workflow	sl	Usodna napaka: nedeterministiÄna odloÄitev v samodejno usmerjeni dejavnosti.
+fatal error: setting next activity to an unexisting activity	workflow	sl	Usodna napaka: poÅ¡iljanje naslednje dejavnosti v neobstojeÄo dejavnost.
+fatal error: trying to send an instance to an activity but no transition found	workflow	sl	Usodna napaka: poskus poÅ¡iljanja primerka na dejavnost brez vmesnega prehoda.
+filter	workflow	sl	Filter
+from	workflow	sl	Od
+get property	workflow	sl	Pridobi lastnost
+grab instance	workflow	sl	primi primerek
+graph	workflow	sl	Graf
+group	workflow	sl	Skupina
+id	workflow	sl	Å ifra
+if:setnextact	workflow	sl	Äe:DoloÄiNaslednjoAktivnost
+inactive	workflow	sl	Nedejaven
+inst. status	workflow	sl	Status primerka
+instance	workflow	sl	Primerek
+instance properties	workflow	sl	Lastnosti primerka
+instance: %1 (process: %2)	workflow	sl	Primerek: %1 (Proces: %2)
+instances	workflow	sl	Primerki
+interactive	workflow	sl	Interaktiven
+interactivity	workflow	sl	Interaktivnost
+invalid	workflow	sl	neveljaven
+invalid process	workflow	sl	Neveljaven proces
+is active	workflow	sl	je dejaven
+join	workflow	sl	zdruÅŸi
+list of activities	workflow	sl	Seznam dejavnosti
+list of instances	workflow	sl	Seznam primerkov
+list of mappings	workflow	sl	Seznam preslikav
+list of processes	workflow	sl	Seznam procesov
+list of processes (%1)	workflow	sl	Seznam procesov (%1)
+list of transitions	workflow	sl	Seznam prehodov
+list of workitems	workflow	sl	Seznam delovnih elementov
+manual	workflow	sl	PriroÄnik
+map	workflow	sl	preslikaj
+map users/groups to roles	workflow	sl	Preslikaj vloge uporabnikom/skupinam
+mappings deleted	workflow	sl	Preslikave izbrisane
+monitor activities	workflow	sl	Pregled dejavnosti
+monitor instances	workflow	sl	Pregled primerkov
+monitor processes	workflow	sl	Pregled procesov
+monitor work items	workflow	sl	Pregled delovnih elementov
+name	workflow	sl	Ime
+new major	workflow	sl	Nov veÄji
+new mapping added	workflow	sl	Dodana nova preslikava
+new minor	workflow	sl	Nov manjÅ¡i
+new transition added	workflow	sl	Dodan nov prehod
+no activity indicated	workflow	sl	Nobena dejavnost ni oznaÄena
+no instance indicated	workflow	sl	Noben primerek ni oznaÄen
+no process indicated	workflow	sl	Noben proces ni oznaÄen
+no properties defined	workflow	sl	Nobena lastnost ni definirana
+no roles	workflow	sl	ni vlog
+no roles asociated with this activity	workflow	sl	S to dejavnostjo ni povezana nobena vloga
+no work item indicated	workflow	sl	Noben delovni element ni oznaÄen
+or import a process	workflow	sl	Ali uvozi proces
+owner	workflow	sl	Lastnik
+process	workflow	sl	Proces
+process %d has been activated	workflow	sl	Proces %d je bil aktiviran
+process %d has been deactivated	workflow	sl	Proces %d je bil deaktiviran
+process %s %s imported	workflow	sl	Proces %s %s je bil uvoÅŸen
+process %s has been created	workflow	sl	Proces %s je bil ustvarjen
+process %s has been updated	workflow	sl	Proces %s je bil osveÅŸen
+process %s removed	workflow	sl	Proces %s je bil odstranjen
+process activities	workflow	sl	Dejavnosti procesa
+process does not have a start activity	workflow	sl	Proces nima zaÄetne dejavnosti
+process does not have exactly one end activity	workflow	sl	Proces nima natanko ene konÄne dejavnosti
+process form	workflow	sl	Obrazec procesa
+process name already exists	workflow	sl	Ime procesa je ÅŸe uporabljeno
+process roles	workflow	sl	Vloge procesa
+process transitions	workflow	sl	Prehodi procesa
+processes	workflow	sl	Procesi
+properties	workflow	sl	Lastnosti
+property	workflow	sl	Lastnost
+release instance	workflow	sl	sprosti primerek
+role %1 is not mapped	workflow	sl	Vloga %1 ni preslikana
+role added to process	workflow	sl	Vloga je bila dodana k procesu
+role saved	workflow	sl	Vloga je bila shranjena
+roles	workflow	sl	Vloge
+roles assigned to this activity	workflow	sl	Vloge, ki so bile doloÄene tej dejavnosti
+roles deleted	workflow	sl	Vloge so bile izbrisane
+routing	workflow	sl	Preusmerjanje
+run	workflow	sl	tek
+run activity	workflow	sl	poÅŸeni dejavnost
+run instance	workflow	sl	poÅŸeni primerek
+running	workflow	sl	teÄe
+running activity	workflow	sl	TekoÄe dejavnosti
+select source	workflow	sl	izberi vir
+send all to	workflow	sl	PoÅ¡lji vse v
+send instance	workflow	sl	poÅ¡lji primerek
+set next act	workflow	sl	DoloÄi naslednjo aktivnost
+set next user	workflow	sl	DoloÄi naslednjega uporabnika
+set property	workflow	sl	DoloÄi lastnost
+shared code	workflow	sl	Koda v souporabi
+show code	workflow	sl	pokaÅŸi kodo
+show template	workflow	sl	pokaÅŸi predlogo
+source saved	workflow	sl	Vir shranjen
+split	workflow	sl	razcepi
+standalone	workflow	sl	samostojen
+start	workflow	sl	ZaÄetek
+started	workflow	sl	ZaÄet
+status	workflow	sl	Status
+stop	workflow	sl	ustavi
+switch	workflow	sl	preklopi
+switch construct	workflow	sl	Preklopi obliko
+template	workflow	sl	predloga
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	sl	Mapa /workflow ne obstaja in je ni mogoÄe ustvariti. Prosite oskrbnika, da preveri globalno konfiguracijo.
+the following items must be corrected to be able to activate this process	workflow	sl	Naslednje zadeve je potrebno popraviti, da bo aktiviranje procesa mogoÄe:
+there are no activities available	workflow	sl	Ni razpoloÅŸljivih dejavnosti
+there are no instances available	workflow	sl	Ni razpoloÅŸljivih primerkov
+there are no mappings defined for this process	workflow	sl	Za ta proces ni definiranih preslikav
+there are no processes	workflow	sl	Ni procesov
+there are no processes available	workflow	sl	Na voljo ni nobenih procesov
+there are no processes defined	workflow	sl	Noben proces ni definiran
+there are no properties available	workflow	sl	Na razpolago ni nobene lastnosti
+there are no roles defined for this process	workflow	sl	Za ta proces ni definiranih vlog
+there are no transitions defined	workflow	sl	Za ta proces ni definiranih prehodov
+there are no user activites available	workflow	sl	Za ta proces ni razpoloÅŸljivih uporabniÅ¡kih dejavnosti
+there are no workitems available	workflow	sl	Ni razpoloÅŸljivih delovnih elementov
+to	workflow	sl	K
+transitions removed successfully	workflow	sl	Prehodi so bili uspeÅ¡no odstranjeni
+type	workflow	sl	tip
+update	workflow	sl	posodobi
+upload file	workflow	sl	Prenesi datoteko
+user	workflow	sl	Uporabnik
+user activities	workflow	sl	Uporabnikove dejavnosti
+user instances	workflow	sl	Uporabnikovi primerki
+user processes	workflow	sl	Uporabnikovi procesi
+user/group	workflow	sl	Uporabnik/Skupina
+users/groups	workflow	sl	Uporabniki/Skupine
+valid	workflow	sl	Veljaven
+valid process	workflow	sl	Veljaven proces
+value	workflow	sl	Vrednost
+version	workflow	sl	RazliÄica
+workflow	common	sl	Delovni procesi
+workitem information	workflow	sl	Podatki o delovnem elementu
+workitems	workflow	sl	Delovni elementi
+you have not permission to execute this activity	workflow	sl	Za to dejavnost nimate dovoljenja
Index: /sandbox/workflow/branches/993/setup/phpgw_lt.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_lt.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_lt.lang	(revision 795)
@@ -0,0 +1,1 @@
+
Index: /sandbox/workflow/branches/993/setup/phpgw_lv.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_lv.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_lv.lang	(revision 795)
@@ -0,0 +1,463 @@
+#	workflow	lv	#
+%1 aborted	workflow	lv	%1 p?rtraukts
+%1 active	workflow	lv	%1 akt?vs
+%1 completed	workflow	lv	%1 pabeigts
+%1 configuration	workflow	lv	%1 Konfigur?cija
+%1 days, %2:%3:%4	workflow	lv	%1 dienas, %2:%3:%4
+%1 exception	workflow	lv	%1 iz??mums
+%1 menu	workflow	lv	%1 Izv?lne
+%1 monitoring	workflow	lv	%1 Uzraudz??ana
+%1 processes (%2 active) (%3 being_run)	workflow	lv	%1 procesi (%2 akt?vi)(%3 notiek)
+<strong>%owner%</strong> is the instance owner email	workflow	lv	<strong>%?pa?nieks%</strong> ?pa?nieka e-pasta instance
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	lv	<strong>%atrib?ts_XX%</strong> ir instances satura atrib?ts XX
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	lv	<strong>%funkcija_XX%</strong> ir visu lietot?ju v?stules atz?m?ti funkcijai XX
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	lv	<strong>%paraksts%</strong> procesu konfigur?cij? defin?ts paraksta a?ents
+<strong>%user%</strong> is the instance user email	workflow	lv	<strong>%lietot?js%</strong> lietot?ja pasta instance
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	lv	<strong>%lietot?js_XX%</strong> konta XX pasts
+abort instance	workflow	lv	p?rtraukt instanci
+abort this instance	workflow	lv	P?rtraukt ?o instanci
+aborted	workflow	lv	p?rtraukts
+access denied for user %1 on activity %2, no role	workflow	lv	Pieeja liegta lietot?jam %1 darb?bai %2, navfunkciju
+actions	workflow	lv	Darb?bas
+actions right options	admin	lv	Darbbu tiesbu opcijas
+activate	workflow	lv	aktiviz?t
+active	workflow	lv	Akt?vs
+active:	workflow	lv	akt?vs:
+activities	workflow	lv	Darb?bas
+activities selection	workflow	lv	Darb?bu atlase
+activities updated	workflow	lv	Darb?bas atjaunin?tas
+activity	workflow	lv	darb?ba
+activity  status	workflow	lv	Darb?bas statuss
+activity %1	workflow	lv	darb?ba%1
+activity %1 code is not avaible	workflow	lv	darb?bas %1 kods nav pieejams
+activity agent removed	workflow	lv	Darb?bas a?ents p?rvietots
+activity completed	workflow	lv	Darb?ba pabeigta
+activity failure	workflow	lv	darb?a neizdev?s
+activity name already exists	workflow	lv	Darb?bas nosaukums jau eksist?
+activity role #%1 removed	workflow	lv	Darb?bas funkcija #%1 p?rvietota
+activity role removed	workflow	lv	Darb?bas funkcija p?rvietota
+activity saved	workflow	lv	Darb?ba saglab?ta
+activity start not avaible, no corresponding activity was found.	workflow	lv	darb?ba nevar s?kties, netika atrasta atbilsto?a darb?ba
+activity start not set, no corresponding activity was found.	workflow	lv	darb?bas s?kums nav uzst?d?ts, netika atrasta atbilsto?a darb?ba
+activity status not avaible, no corresponding activity was found.	workflow	lv	darb?bas statuss nav pieejams, netika atrasta atbilsto?a darb?ba.
+activity:	workflow	lv	darb?ba
+add a transition	workflow	lv	Pievienot p?reju
+add aborted instances	workflow	lv	Pievienot p?rtraukt?s instances
+add advanced actions	workflow	lv	Pievienot uzlabot?s opcijas
+add completed instances	workflow	lv	Pievienot pabeigt?s instances
+add instances in exception	workflow	lv	Pievienot instances iz?emum?
+add new	workflow	lv	pievienot jaunu
+add or edit a process	workflow	lv	Pievienot vai redi??t procesu
+add or edit an activity	workflow	lv	Pievienot vai redi??t darb?bu
+add property	workflow	lv	Pievienot atrib?tu
+add role	workflow	lv	Pievienot funkciju
+add role to process	workflow	lv	Pievinot procesam funkciju
+add transition	workflow	lv	pievienot p?reju
+add transitions	workflow	lv	Pievienot p?rejas
+add transitions from	workflow	lv	Pievienot p?rejas no
+add transitions to	workflow	lv	Pievienot p?rejas (kam?)
+admin instance	workflow	lv	Administratora instance
+admin process activities	workflow	lv	Administratora procesa darb?bas
+admin process roles	workflow	lv	Administratora procesa funkcijas
+admin processes	workflow	lv	Administratora procesi
+admin processes sources	workflow	lv	Administratora procesu avots
+administer instances	workflow	lv	Vad?bas instances
+administer processes	workflow	lv	vad?bas procesi
+agent without activity	workflow	lv	A?ents bez darb?bas
+all	workflow	lv	Visi
+always show advanced actions	workflow	lv	Vienm?r r?d?t papla?in?t?s darb?bas
+always show advanced mode	workflow	lv	Vienm?r r?d?t papla?in?to re??mu
+at least one email address cannot be validated.	workflow	lv	Vismaz viena e-pasta adrese nevar tikt apstiprin?ta
+auto routed	workflow	lv	Autom?tiski mar?rut?ts
+automatic	workflow	lv	Autom?tisks
+bad role type	workflow	lv	Neder?gs funkcijas tips
+bad user	workflow	lv	Neder?gs lietot?js
+base directory does not exist, please ask adminstrator to check the global configuration	common	lv	Pamata direktorijs neeksist?, pal?dz administratoru p?rbaud?t visp?r?jo konfigur?ciju
+bcc:	workflow	lv	Bcc:
+being run	workflow	lv	notiek
+cannot create compiled file %1	workflow	lv	nevar izveidot pabeigto failu%1
+cannot run the activity	workflow	lv	Nevar palaist darb?bu
+cannot run the activity without her process	workflow	lv	Nevar palaist darb?bu bez t?s procesa
+cannot run the activity without instance	workflow	lv	Nevar palaist darb?bu bez instances
+cannot run unknown activity	workflow	lv	Nevar palaist nezin?mu darb?bu
+cc:	workflow	lv	Cc:
+cleanup aborted instances	workflow	lv	izt?r?t p?rtraukt?s instances
+cleanup actions	workflow	lv	t?r??anas darb?bas
+close and get back later	workflow	lv	Aizv?rt un atgriezties v?l?k
+close printer friendly mode	workflow	lv	Aizv?rt printerim draudz?gu re??mu
+code	workflow	lv	kods
+column activity status in instance lists	workflow	lv	Kolonna dab?bu statuss instan?u sarakst?
+column category in instance lists	workflow	lv	Kolonna kategorija instan?u sarakst?
+column instance id in instance lists	workflow	lv	Kolonna instances id instan?u sarakst?
+column instance name in instance lists	workflow	lv	Kolonna instances nosaukums instan?u sarakst?
+column instance status in instance lists	workflow	lv	Kolonna instances statuss instan?u sarakst?
+column owner in instance lists	workflow	lv	Kolonna ?pa?nieks instan?u sarakst?
+column priority in instance lists	workflow	lv	Kolonna priorit?te instan?u sarakst?
+column process name in instance lists	workflow	lv	Kolonna procesa nosaukums instan?u sarakst?
+column start date in instance lists	workflow	lv	Kolonna s?kuma datums instan?u saraksta
+compiling activity %1 : %2	workflow	lv	kompil? darb?bu %1:%2
+complete	workflow	lv	Pabeigts
+complete cleanup of aborted instances done	workflow	lv	pabeigta p?rtraukto instan?u not?r??ana
+complete cleanup of all instances done	workflow	lv	pabeigta visu instan?u not?r??ana
+completed	workflow	lv	pabeigts
+confirm delete	workflow	lv	Apstiprinat dz??anu
+couldn't add transition	workflow	lv	Nevar pievienot p?reju
+create	workflow	lv	izveidot
+created	workflow	lv	Izveidots
+date:	workflow	lv	datums:
+default config values	common	lv	Noklus?t?s konfigur?cijas v?rt?bas
+default owner	workflow	lv	Noklus?tais ?pa?nieks
+default settings for processes	admin	lv	Noklus?tie uzstad?jumi procesiem
+default user	workflow	lv	Noklus?tais lietot?js
+delete selected	workflow	lv	Dz?st atz?m?tos
+delete transition	workflow	lv	dz?st p?reju
+deletion successful	workflow	lv	D???ana idev?s
+description	workflow	lv	Apraksts
+display please wait message	admin	lv	par?d?t l?dzu uzgaid?t zi?ojumu
+don't move	workflow	lv	Nep?rvietot
+draw roles	admin	lv	noteikt lomas
+duration	workflow	lv	Ilgums
+end	workflow	lv	beigas
+ended	workflow	lv	pabeigts
+enter an activity name	workflow	lv	Ievadi darb?bas nosaukumu
+error: non-deterministic decision for autorouting activity	workflow	lv	K??da: nedetermin?ts l?mums automar?rut??anas darb?bai
+error: removing was not done	workflow	lv	k??da: p?rvieto?ana netika izdar?ta
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	lv	K??da: m??in?ja s?t?t instanci darb?bai, ta?u nebija iesp?jams ieg?t ?o darb?bu
+error: trying to send an instance to an activity but no transition found	workflow	lv	K??da: m??in?ja s?t?t instanci darb?bai, bet netika atrasta pareja
+exception	workflow	lv	iz??mums
+exception instance	workflow	lv	iz??muma instance
+exception raised by %1 %2: %3	workflow	lv	iz?emumu pac?la %1%2:%3
+exception resumed by %1 %2: %3	workflow	lv	iz??mumu ats?ka %1%2:%3
+exceptions	workflow	lv	iz??mumi
+execute this activity	workflow	lv	izpild?t ?o darb?bu
+export	workflow	lv	Eksport?t
+failed to create workitem	workflow	lv	neizdev?s izveidot darba vien?bu
+failed to execute automatic activity	workflow	lv	neizdev?s izveidot autom?tisko darb?bu
+failed to obtain lock on %1 table	workflow	lv	neizdev?s ieg?t sl?dzeni %1 tabul?
+failed to obtain lock on instances table	workflow	lv	neizdev?s ieg?t sl?dzeni instan?u tabul?
+failed to record instance properties	workflow	lv	neizdev?s ierakst?t instan?u atrib?tus
+failure	workflow	lv	neizdo?an?s
+filter	workflow	lv	Filtrs
+filter instance by id	workflow	lv	filtra instance p?c id
+fix	workflow	lv	Noteikt
+fix concistency for selected rows	workflow	lv	Noteikt nepretrun?gumu iez?metajam rind?m
+font size	admin	lv	burtu lielums
+from	workflow	lv	No
+from:	workflow	lv	No:
+get back to global activities	workflow	lv	atg?t visp?r?jas darb?bas
+get back to instance creation	workflow	lv	atg?t instan?u veido?anu
+get property	workflow	lv	Ieg?t rekviz?tu
+global activities	workflow	lv	Visp?r?j?s darb?bas
+global workflow preferences	workflow	lv	Visp?r?jas darbapl?smas izv?les
+go	workflow	lv	aiziet
+go to same activities for other instances of this process	workflow	lv	aiziet uz t?d?m pa??m darb?b?m cit?s ?? procesa instanc?s
+go to same process activities	workflow	lv	aiziet uz t? pa?a procesa aktivit?t?m
+grab instance	workflow	lv	satvert instatnci
+graph	workflow	lv	Grafs
+graphic options	admin	lv	Grafisk?s opcijas
+group	workflow	lv	Grupa
+id	workflow	lv	ID
+import aborted	workflow	lv	Import??ana partraukta
+import successfull	workflow	lv	Import??ana veiksm?ga
+inactive	workflow	lv	Neakt?vs
+inst.	workflow	lv	Inst.
+inst. status	workflow	lv	Inst. statuss
+instance	workflow	lv	Instance
+instance %1	workflow	lv	instance%1
+instance %1 is in %2 state, action %3 is impossible.	workflow	lv	Imstance %1 ir st?vokl?%2, darb?ba %3 nav iesp?jama.
+instance %1 is in exception, action %2 is not possible.	workflow	lv	Instance %1 ir iz??mums, darb?ba %2 nav iesp?jama
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	lv	Instance %1 nav saist?ta ar darb?bu %2, darb?ba %3 nav iesp?jama
+instance history	workflow	lv	Instan?u v?sture
+instance properties	workflow	lv	Instan?u atrib?ti
+instance:	workflow	lv	instance;
+instance: %1 (process: %2)	workflow	lv	Instance:%1 (Process: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	lv	Instance: nevar p?rveidot %1, k?ds to izmain?jis pirms mums
+instance: unable to modify %1, someone has changed it before us	workflow	lv	Instance: nevar p?rveidot %1, k?ds to izmain?jis pirms mums
+instances	workflow	lv	Instances
+instances selection	workflow	lv	Instan?u atlase
+int.	workflow	lv	Int.
+interactive	workflow	lv	Interakt?vs
+interactive:	workflow	lv	interakt?vs:
+interactivity	workflow	lv	Mijiedarb?ba
+invalid	workflow	lv	neder?gs
+invalid process	workflow	lv	Neder?gs process
+invalid role name	workflow	lv	Neder?gs lomas nosaukums
+is active	workflow	lv	ir akt?vs
+it seems this activity for this instance is not assigned to you anymore.	workflow	lv	Izskat?s, ka ?? darb?ba ?ai instancei vair snav jums pieejama
+it was impossible to complete, no activity was given.	workflow	lv	nebija iesp?jams pabeigt, nav dota aktivit?te
+it was impossible to complete, no corresponding activity was found.	workflow	lv	nebija iesp?jams pabeigt, netika atrasta atbilsto?a darb?ba
+join	workflow	lv	pievienoties
+list of activities	workflow	lv	Darb?bu saraksts
+list of instances	workflow	lv	Instan?u saraksts
+list of mappings	workflow	lv	Kart??anas saraksts
+list of monitors	workflow	lv	P?rraugu saraksts
+list of processes	workflow	lv	Procesu saraksts
+list of processes (%1)	workflow	lv	Procesu saraksts(%1)
+list of transitions	workflow	lv	P?reju saraksts
+list of workitems	workflow	lv	Darba vien?bu saraksts
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	lv	V?stuli autom?tiski nos?t?ja eGroupWares darbpl?mas MailSMTP Agent
+mail smtp agent	workflow	lv	Mail SMTP Agent
+manual	workflow	lv	Rokasgr?mata
+map	workflow	lv	karte
+map users/groups to roles	workflow	lv	Kartet lietotajus.grupas lom?m
+mapping to inexistent role	workflow	lv	Kart?sana neeksist?josai lomai
+mappings deleted	workflow	lv	Kart??anas izdz?stas
+message:	workflow	lv	Zi?ojums:
+monitor activities	workflow	lv	P?rrauga darb?bas
+monitor instance	workflow	lv	p?rrauga instance
+monitor instances	workflow	lv	P?rrauga instances
+monitor processes	workflow	lv	P?rrauga procesus
+monitor this instance	workflow	lv	P?rraudz?t ?o instanci
+monitor work items	workflow	lv	P?rraudz?t darba vien?bas
+monitor workitems	workflow	lv	P?rraudz?t darbavien?bas
+monitoring	workflow	lv	P?rraud???ana
+monitors	workflow	lv	P?rrauga
+more options?	workflow	lv	vair?k opciju?
+my activities	workflow	lv	Manas darb?bas
+my instances	workflow	lv	Manas instances
+my processes	workflow	lv	Mani procesi
+name	workflow	lv	V?rds
+new instance	workflow	lv	R?d?t instanci
+new mapping added	workflow	lv	Jauna kart??ana pievienota
+new transition added	workflow	lv	Jauna p?reja pievienota
+next activity	workflow	lv	nakama darb?ba
+next user:	workflow	lv	N?kamai lietotajs:
+no action avaible because no activity and no instance are given!	workflow	lv	nav pieejamu darb?bu, jo nav dotas darb?bas un instances!
+no activites	workflow	lv	Nav darb?bu
+no activity indicated	workflow	lv	Nav nor?d?tas darb?bas
+no circular transitions allowed.	workflow	lv	Nav at?autas cirkul?ras p?rejas
+no corresponding activity was found.	workflow	lv	nav atrasta atbilsto?a darb?ba
+no instance avaible	workflow	lv	nav pieejamas instances
+no instance given, nothing to show	workflow	lv	nav dota instance, nav ko rad?t
+no instance indicated	workflow	lv	Nav nor?d?ta instance
+no process indicated	workflow	lv	Nav nor?d?ts process
+no properties defined	workflow	lv	Nav defin?ti rekviz?ti
+no roles	workflow	lv	nav lomu
+no roles asociated with this activity	workflow	lv	Nav saist?tu lomu ar ?o darb?bu
+no routage	workflow	lv	nav mar?rut?juma
+no scan done	workflow	lv	nav izdar?ta skan??ana
+no work item indicated	workflow	lv	Nav nor?d?ta darba vien?ba
+nobody	workflow	lv	Nekas
+not defined	workflow	lv	nav defin?ts
+or import a process	workflow	lv	Vai import?t procesu
+owner	workflow	lv	?pa?nieks
+owner of the instance will have the right to abort the instance at any time	admin	lv	instances ?pa?niekam b?s ties?bas to p?rtraukt jebkur? br?d?
+owner of the instance will have the right to exception or resume the instance at any time	admin	lv	instances ipa?niekam b?s ties?bas iebilst vai ats?kt instanci jebkura laik?
+owner:	workflow	lv	?pa?nieks
+ownership give abort right	admin	lv	?pasumties?bas dod ties?bas partraukt
+ownership give exception right	admin	lv	?pa?umties?bas dot iz??muma ties?bas
+ownership give release right	admin	lv	?pa?umties?bas dod atbr?vosanas ties?bas
+post activity %1 code is not avaible	workflow	lv	pasta s?t?juma darb?bas  %1 kods nav pieejams
+post shared code is not avaible	workflow	lv	pasta s?t?juma koplieto?anas kodi nav pieejami
+post-agent %1 code is not avaible	workflow	lv	pasta s?t?jumu a?ents %1 kods nav pieejams
+pr.	workflow	lv	Pr.
+printer friendly	workflow	lv	Printerim draudzÄ«gs
+priority level:	workflow	lv	PrioritÄtes lÄ«menis
+process	workflow	lv	Process
+process %1	workflow	lv	process%1
+process %1 %2 is not active, action %3 is impossible	workflow	lv	Process%1%2 nav aktÄ«vs, darbÄ«ba %3 nav iespÄjama
+process %1 v%2 as no related activity	workflow	lv	Process %1v%2 kÄ nesaistÄ«ta darbÄ«ba
+process %d has been activated	workflow	lv	Process %d tika aktivizÄts
+process %d has been deactivated	workflow	lv	Process %d tika deaktivizÄts
+process %s %s already exists, the import process was aborted	workflow	lv	Process %s%s jau eksistÄ, importÄÅ¡anas process tika pÄrtraukts
+process %s %s imported	workflow	lv	Process %s%s importÄts
+process %s has been created	workflow	lv	Process%s izveidots
+process %s has been updated	workflow	lv	Process %s atjauninats
+process %s removed	workflow	lv	Process %sparvietots
+process activities	workflow	lv	Procesa darbÄ«bas
+process alone	workflow	lv	Tikai process
+process does not have a start activity	workflow	lv	Procesam nav sÄkuma darbÄ«bas
+process does not have exactly one end activity	workflow	lv	Procesam nav vienas beigu darbÄ«bas
+process form	workflow	lv	Process no
+process name	workflow	lv	Procesa nosaukums
+process name already exists	workflow	lv	Procesa nosaukums jau eksistÄ
+process roles	workflow	lv	Procesa lomas
+process saved	workflow	lv	Process saglabÄts
+process transitions	workflow	lv	Procesa pÄrejas
+process version:	workflow	lv	procesa versija
+process:	workflow	lv	process:
+processes	workflow	lv	Procesi
+properties	workflow	lv	AtribÅ«ti
+property	workflow	lv	AtribÅ«ts
+property %1 already exists	workflow	lv	atribÅ«ts %1 jau eksistÄ
+property %1 not found	workflow	lv	atribÅ«ts %1 netika atrasts
+quit without saving	workflow	lv	Iziet nesaglabÄjot
+read-only	workflow	lv	tikai lasÄms
+release access to this activity	workflow	lv	Atvieglot pieeju Å¡ai darbÄ«bai
+release activity for this instance	workflow	lv	atbrÄ«vot darbÄ«bu Å¡ai instancei
+release instance	workflow	lv	atbrÄ«vot instanci
+reload filter	workflow	lv	PÄrlÄdÄt filtru
+remove active instances	workflow	lv	PÄrvietot aktÄ«vÄs instances
+remove all instance for this process	workflow	lv	parvieto visas sÄ« procesa instances
+remove selected roles	workflow	lv	parvieto iezÄ«metÄs lomas
+replyto:	workflow	lv	AtbildÄt :
+restart	workflow	lv	restartÄt
+restart activity	workflow	lv	restartÄt darbÄ«bu
+resume this exception instance	workflow	lv	Atjaunot Å¡o izÅÄmuma instanci
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	lv	Lomai #%1 procesÄ %2 ir cits process (%3) kartÄÅ¡anÄ ar lietotÄju #%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	lv	Loma %1(#%2)saistÄ«ta ar neeksistÄjoÅ¡u procesu (#%3)
+role %1 is not mapped	workflow	lv	Loma %1 nav kartÄta
+role added to activity	workflow	lv	Loma pievienota darbÄ«bai
+role added to process	workflow	lv	Loma pievienota procesam
+role give abort right	admin	lv	Loma dod pÄrtraukÅ¡anas tiesÄ«bas
+role give exception right	admin	lv	loma dot izÅÄmuma tiesÄ«bas
+role give release right	admin	lv	loma dot nomeÅ¡anas tiesÄ«bas
+role in inexistent process	workflow	lv	Loma neeksistÄjosa procesÄ
+role mapping in inexistent process	workflow	lv	Lomu kartÄÅ¡ana neeksistÄjosa procesÄ
+role name	workflow	lv	Lomas nosaukums
+role not saved (maybe a name collision)	workflow	lv	Loma netika saglabÄta (iespÄjams sadursmes nosaukums)
+role saved	workflow	lv	Loma saglabÄta
+roles	workflow	lv	Lomas
+roles assigned to this activity	workflow	lv	Lomas pieÅ¡Ä·irtas Å¡ai darbÄ«bai
+roles deleted	workflow	lv	Lomas izdzÄstas
+routing	workflow	lv	MarÅ¡rutÄsana
+routing:	workflow	lv	marÅ¡rutÄÅ¡ana:
+run	workflow	lv	palaist
+run activity	workflow	lv	palaist darbÄ«bu
+run instance	workflow	lv	palaist instanci
+running	workflow	lv	palaists
+running activities options	admin	lv	Palaistas darbÄ«bu opcijas
+running activity	workflow	lv	Palaistas darbÄ«bas
+scan activities	workflow	lv	SkanÄt darbÄ«bas
+scan agents	workflow	lv	SkanÄt aÄ£entus
+scan instances	workflow	lv	SkanÄt instances
+scan processes	workflow	lv	SkanÄt procesus
+scan roles	workflow	lv	SkanÄt lomas
+scan transitions	workflow	lv	SkanÄt pÄrejas
+search instance filter in the bottom of instance lists	workflow	lv	MeklÄt instanÄu filtru  instanÄu saraksta augÅ¡pusÄ
+search:	workflow	lv	meklÄt:
+security check: cannot understand asked action	workflow	lv	DroÅ¡Ä«bas pÄrbaude: nevar saprast prasÄ«to darbÄ«bu
+select a transition to remove	workflow	lv	IezÄ«mÄt pareju, lai pÄrvietotu
+select source	workflow	lv	iezÄ«mÄt avotu
+send after interactive activity is completed	workflow	lv	sÅ«tÄ«t pÄc interaktÄ«vÄs darbÄ«bas beigÄm
+send all to	workflow	lv	SÅ«tÄ«t visu uz
+send an email	workflow	lv	SÅ«tÄ«t e-pastu
+send instance	workflow	lv	sÅ«tÄ«t instanci
+send this instance to the next activity	workflow	lv	SÅ«tÄ«t Å¡o instanci nakoÅ¡ai darbÄ«bai
+send transition	workflow	lv	sÅ«tÄ«t pÄreju
+send when the activity is ending	workflow	lv	sÅ«tÄ«t, kad darbÄ«ba beidzas
+send when the activity is starting	workflow	lv	sÅ«tÄ«t, kad darbÄ«ba sÄkas
+set next act	workflow	lv	UzstÄdÄ«t nÄkamo darbÄ«bu
+set next user	workflow	lv	UzstadÄ«t nakamo lietotÄju
+set property	workflow	lv	UzstÄdÄ«t atribÅ«tu
+setting next activity to an unexisting activity	workflow	lv	uzstÄda nakamo darbÄ«bu neeksistÄjoÅ¡ai  darbÄ«bas
+shared code	workflow	lv	KoplietoÅ¡anas kods
+show activity info zone	admin	lv	rÄdÄ«t darbÄ«bas info zonu
+show activity title	admin	lv	rÄdÄ«t darbÄ«bas virsrakstu
+show code	workflow	lv	rÄdÄ«t kodu
+show template	workflow	lv	rÄdÄ«t veidni
+size of the font used on the graph 12 should be a good default value	admin	lv	grafa 12 izmantotiem fontiem jÄbÅ«t labai noklusÄtai vÄrtÄ«bai
+smtp agent has detected some errors when sending email after completion of the activity	workflow	lv	SMTP Agent konstateja dazas kÄŒÅ«das sÅ«tot e-pastu pec darbÄ«bas beigÅ¡anas
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	lv	SMTP Agent konstatÄja daÅŸas kÄŒÅ«das sÅ«tot e-pastu darbÄ«bas sÄkumÄ
+smtp agent has detected some errors when sending email at the end of this activity	workflow	lv	SMTP Agent konstatÄja daÅŸas kÄŒÅ«das sÅ«tot e-pastu Å¡Ä«s darbÄ«bas beigÄs
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	lv	SMTP Agent konstateja daÅŸas kÄŒÅ«das sÅ«tot e-pastu pÄc Å¡Ä«s darbÄ«bas pieprasÄ«juma
+something was wrong while creating the new major version	workflow	lv	kaut kas nebija pareizi veidojot jauno vecÄko versiju
+something was wrong while creating the new minor version	workflow	lv	kaut kas nebija pareizi veidojot jaunÄko versiju
+source code file for activity %1 is not avaible	workflow	lv	avota koda fails darbÄ«bai %1 na pieejams
+source code for activity %1 is not avaible	workflow	lv	avota kods darbÄ«bai %1 nav pieejams
+source saved	workflow	lv	Avots saglabÄts
+split	workflow	lv	sadalÄ«t
+standalone	workflow	lv	ÄrlÄ«nija
+start	workflow	lv	SÄkt
+start activities must be autorouted	workflow	lv	sÄkuma darbÄ«bÄm jÄbÅ«t automÄtiski marÅ¡rutÄjamam
+start activities must be interactive	workflow	lv	sÄkuma darbÄ«bÄm jÄbÅ«t interaktÄ«vam
+start activity	workflow	lv	SÄkuma darbÄ«ba
+start process	workflow	lv	sÄkuma process
+started	workflow	lv	SÄkts
+started:	workflow	lv	sÄkts
+starting page	workflow	lv	SÄkuma lapa
+status	workflow	lv	Statuss
+status:	workflow	lv	statuss:
+stop	workflow	lv	stop
+subject:	workflow	lv	TÄma:
+switch	workflow	lv	slÄdzis
+template	workflow	lv	veidne
+test concistency	workflow	lv	PÄrbaudÄ«t nepretrunÄ«gumu
+test consistency of datas in the database	workflow	lv	PÄrbaudÄ«t datu nepretrunÄ«gumu datubÄzÄ
+test local installation	workflow	lv	PÄrbaudÄ«t vietejo instalÄsanu
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	lv	DarbplÅ«sma direktorijs neeksistÄ un nevar tikt izveidots. LÅ«dz administratoru pÄrbaudÄ«t vispÄrÄjo konfiguraciju
+the activity was not completed	workflow	lv	DarbÄ«ba netika pabeigta
+the instance title is shown on top of the form	admin	lv	instances virsraksts ir parÄdÄ«ts formas augÅ¡pusÄ
+the label you want	workflow	lv	iezÄ«me, kÄdu vÄlies
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	lv	mail_smtp darbplÅ«smas aÄ£ents nevar ielÄdÄt SMTP konfigurÄciju
+there are no activities available	workflow	lv	Nav pieejamu darbÄ«bu
+there are no config value defined	workflow	lv	Nav defineta konfigurÄsanas vÄrtÄ«bas
+there are no instances available	workflow	lv	Nav pieejamu instanÄu
+there are no mappings defined for this process	workflow	lv	Å im procesam nav definÄtu kartÄjumu
+there are no process available	workflow	lv	Nav pieejamu procesu
+there are no processes	workflow	lv	Nav procesu
+there are no processes available	workflow	lv	Nav pieejamu procesu
+there are no processes defined	workflow	lv	Nav definÄtu procesu
+there are no processes with the current filter	workflow	lv	Nav procesu ar Å¡Ädu filtru
+there are no properties available	workflow	lv	Nav pieejamu atribÅ«tu
+there are no roles defined for this process	workflow	lv	Nav definÄtu lomu Å¡im procesam
+there are no transitions defined	workflow	lv	Nav definÄtu pÄreju
+there are no user activites available	workflow	lv	Nav pieejamas lietotaja darbÄ«bas
+there are no workitems available	workflow	lv	Nav pieejamu darba vienÄ«bu
+there are some undefined preferences associated with this form : %1	workflow	lv	ir daÅŸas nedefinetas iespÄjas Å¡ai formai: %1
+there is an unknown user or group #%1 in role mappings	workflow	lv	Ir nezinÄma lietotÄju grupa #%1 lomu kartÄÅ¡anÄ
+they were problems at the compilation of the source:	workflow	lv	Bija problÄmas kompilÄjot avotu:
+this activity for this instance is actually avaible for you.	workflow	lv	Å Ä« instances darbÄ«ba tev ir pieejama
+this activity for this instance is actually only avaible for you.	workflow	lv	Å Ä« instances darbÄ«ba tev ir tikai pieejama.
+this activity for this instance is not specifically assigned to you.	workflow	lv	Å Ä« instances darbÄ«ba nav tev paredzÄta.
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	lv	Å is aÄ£ents ÄŒauj nosÅ«tÄ«t SMTP vestuli
+this form will test your local workflow installation to detect potential issues	workflow	lv	Å Ä« forma pÄrbaudÄ«s vietÄjo darbplÅ«smas instalÄÅ¡anu, lai konstatÄtu potenciÄlas neveiksmes
+this process has no end activity	workflow	lv	Å¡im procesam nav beigu darbÄ«bas
+to	workflow	lv	Kam
+to:	workflow	lv	Kam:
+transition	workflow	lv	PÄreja
+transition mode	workflow	lv	pÄrejas reÅŸÄ«ms
+transition to %1	workflow	lv	pÄreja uz %1
+transitions	workflow	lv	pÄrejas
+transitions removed successfully	workflow	lv	PÄrejas veiksmÄ«gi parvietotas
+type	workflow	lv	tips
+type:	workflow	lv	tips:
+unknown instruction from the workflow engine: %1	workflow	lv	nezinÄma instrukcija no darbplÅ«smas vadÄ«bas programmas:%1
+unknown status	workflow	lv	nezinÄms statuss
+update	workflow	lv	atjauninÄt
+upload file	workflow	lv	IelÄdÄt failu
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	lv	Lieto <a href="%1">EmailAdmin</a>, lai izveidotu e-pasta profilus
+use automatic parsing	admin	lv	lietot automÄtisko parsÄÅ¡anu
+use default	workflow	lv	Lietot noklusÄjumu
+use existing roles	workflow	lv	Lietot esoÅ¡Äs lomas
+user	workflow	lv	LietotÄjs
+user #%1 is associated with a non-existent role #%2	workflow	lv	LietotÄjs #%1 saistÄ«ts ar neeksistÄjoÅ¡u lomu #%2
+user activities	workflow	lv	LietotÄja darbÄ«bas
+user instances	workflow	lv	LietotÄja instances
+user instances form: columns	workflow	lv	LietotÄju instances no: kolonnas
+user instances form: filters and actions	workflow	lv	LietotÄju instances no: filtri un darbÄ«bas
+user is not authorized to delete aborted instances	workflow	lv	lietotÄjs nav autorizÄjies, lai pÄrtrauktu instances
+user is not authorized to delete instances	workflow	lv	lietotÄs nav autorizÄjies, lai dzÄstu instances
+user processes	workflow	lv	LietotÄja procesi
+user/group	workflow	lv	LietotÄjs/Grupa
+user:	workflow	lv	lietotajs:
+users/groups	workflow	lv	Lietotaji/grupas
+valid	workflow	lv	DerÄ«gs
+valid process	workflow	lv	DerÄ«gs process
+valid:	workflow	lv	derÄ«gs
+value	workflow	lv	VÄrtÄ«ba
+version	workflow	lv	Versija
+view details	workflow	lv	rÄdÄ«t detaÄŒas
+view this instance	workflow	lv	RÄdÄ«t Å¡o instanci
+view workitem	workflow	lv	RÄdÄ«t darba vienÄ«bu
+warning this filter override all others filters	workflow	lv	berÄ«dinajums: Å¡is filtrs neieveros citus filtrus
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	lv	brÄ«dinÄjums: izmantojot Å¡o pogu tu pÄrvietosi visas pÄrtrauktÄs instances un to vÄsturi (darbavienÄ«bas)  iezÄ«mÄtajos procesos.
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	lv	brÄ«dinÄjums: izmantojot Å¡o pogu tu pÄrvietosi visas instances un to vÄsturi (darbavienÄ«bas)  iezÄ«mÄtajos procesos, neievÄrojot to stÄvokli
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	lv	MÄs nevaram palaist Å¡o darbÄ«bu, iespÄjams, Å¡Ä« instance vai darbÄ«ba vairs neeksistÄ
+we were not able to build the message	workflow	lv	MÄs nevarÄjÄm uzrakstÄ«t vÄstuli
+when to send the message:	workflow	lv	Kad sÅ«tÄ«t vÄstuli:
+workflow	common	lv	DarbplÅ«sma
+workflow configuration	admin	lv	DarbplÅ«smas konfigurÄcija
+workflow preferences	workflow	lv	DarbplÅ«smas iespÄjas
+workflow site configuration	workflow	lv	DarbplÅ«smas vietnes konfigurÄcija
+workitem information	workflow	lv	Darba vienÄ«bas informÄcija
+workitems	workflow	lv	Darba vienÄ«bas
+you are not allowed to abort instance %1	workflow	lv	Tev nav tiesÄ«bu pÄrtraukt instanci %1
+you are not allowed to grab instance %1	workflow	lv	Tev nav tiesÄ«bu pÄrtvert instanci %1
+you are not allowed to release instance %1	workflow	lv	Tev nav tiesÄ«bu atbrÄ«vot instanci %1
+you are not allowed to restart instance %1	workflow	lv	Tev nav tiesÄ«bu parstartÄt instanci %1
+you are not allowed to resume instance %1	workflow	lv	Tev nav tiesÄ«bu atsÄkt instanci %1
+you are not allowed to send instance %1	workflow	lv	Tev nav tiesÄ«bu sÅ«tÄ«t instanci %1
+you can use special values with this mail agent:	workflow	lv	Ar Å¡o pasta aÄ£entu tu vari izmantot Ä«paÅ¡as vÄrtÄ«bas
+you have not permission to execute this activity	workflow	lv	Tev nav tiesÄ«bu izpildÄ«t Å¡o darbÄ«bu
+you were not allowed to complete the activity	workflow	lv	Tev nav tiesÄ«bu pabeigt Å¡o darbÄ«bu
Index: /sandbox/workflow/branches/993/setup/phpgw_ca.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_ca.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_ca.lang	(revision 795)
@@ -0,0 +1,201 @@
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	ca	El directori /workflow no existeix i no s'ha pogut crear. Si us plau, demaneu al vostre administrador que comprovi la configuració global
+abort instance	workflow	ca	avortar instància
+aborted	workflow	ca	avortat
+act	workflow	ca	activitat
+act. status	workflow	ca	Estat de l'activitat
+activate	workflow	ca	activar
+active	workflow	ca	Actiu
+activities	workflow	ca	Activitats
+activities updated	workflow	ca	Activitats actualitzades
+activity	workflow	ca	activitat
+activity  status	workflow	ca	Estat de l'Activitat
+activity %1 is interactive but has no role assigned	workflow	ca	L'activitat %1 és interactiva però no té un paper assignat
+activity %1 is interactive so it must use the $instance->complete() method	workflow	ca	L'activitat %1 és interactiva, així que ha d'utilitzar el mètode $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	ca	L'activitat %1 no és interactiva ni autoencaminada però no té un paper assignat
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	ca	L'activitat %1 no és interactiva, per tant no ha d'utilitzar el mètode $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	ca	L'activitat %1 és independent i està utilitzant l'objecte $instance
+activity %1 is standalone but has transitions	workflow	ca	L'activitat %1 és independent però té transicions
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	ca	L'activitat %1 és un commutador, així que s'ha d'utilitzar el mètode $instance->setNextActivity($actname)
+activity completed	workflow	ca	Activitat completada
+activity name already exists	workflow	ca	El nom de l'activitat ja existeix
+activity role removed	workflow	ca	Paper de l'activitat eliminat
+activity saved	workflow	ca	L'activitat s'ha desat
+add a transition	workflow	ca	Afegir una transició
+add new	workflow	ca	afegir nou
+add or edit a process	workflow	ca	Afegir o editar un procés
+add or edit an activity	workflow	ca	Afegir o editar una activitat
+add property	workflow	ca	Afegir propietat
+add role	workflow	ca	Afegir paper
+add role to process	workflow	ca	Afegir paper al procés
+add transitions	workflow	ca	Afegir transicions
+add transitions from	workflow	ca	Afegir transicions de
+add transitions to	workflow	ca	Afegir transicions a
+admin export	workflow	ca	Exportació administrativa
+admin instance	workflow	ca	Instància administrativa
+admin process activities	workflow	ca	Activitats del procés administratiu
+admin process roles	workflow	ca	Papers del procés administratiu
+admin processes	workflow	ca	Processos administratius
+admin processes sources	workflow	ca	Orígens dels processos administratius
+all	workflow	ca	Tots
+auto routed	workflow	ca	Autoencaminat
+automatic	workflow	ca	Automàtic
+base directory does not exist, please ask adminstrator to check the global configuration	common	ca	El directori base no existeix, si us plau, demaneu a l'administrador que comprovi la configuració global
+being run	workflow	ca	s'està executant
+cannot add transition. only split activities can have more than one outbound transition	workflow	ca	No es pot afegir la transició. Només les activitats separades poden tenir més d'una transició de sortida.
+circular reference found. some activity has a transition leading to itself	workflow	ca	S'ha trobat una referència circular. Algunes activitats tenen una transició principal cap a elles mateixes
+code	workflow	ca	codi
+complete	workflow	ca	Complet
+completed	workflow	ca	completat
+couldn't add transition	workflow	ca	No s'ha pogut afegir la transició
+create	workflow	ca	crear
+created	workflow	ca	Creada
+delete selected	workflow	ca	Esborrar la selecció
+deletion successful	workflow	ca	Esborrat correctament
+delition successful	workflow	ca	Esborrat correctament
+description	workflow	ca	Descripció
+don't move	workflow	ca	No moure
+duration	workflow	ca	Duració
+end	workflow	ca	fi
+end activity is not reachable from start activity	workflow	ca	No es pot arribar a l'activitat final des de l'activitat inicial
+exception instance	workflow	ca	instància d'excepció
+exceptions	workflow	ca	excepcions
+export	workflow	ca	Exportar
+export a process	workflow	ca	Exportar un procés
+export file	workflow	ca	Exportar Fitxer
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	ca	Error fatal: l'activitat següent no coincideix amb cap candidata dins l'activitat de canvi d'encaminament automàtic
+fatal error: non-deterministic decision for autorouting activity	workflow	ca	Error fatal: decisió no determinística per a l'activitat d'encaminament automàtic
+fatal error: setting next activity to an unexisting activity	workflow	ca	Error fatal: se vol enrutar la propera activitat cap a una activitat inexistent
+fatal error: trying to send an instance to an activity but no transition found	workflow	ca	Error fatal: intentant enviar una instància a una activitat, però no s'ha trobat cap transició
+filter	workflow	ca	Filtre
+from	workflow	ca	De
+get property	workflow	ca	Obté propietat
+grab instance	workflow	ca	agafar instància
+graph	workflow	ca	Gràfic
+group	workflow	ca	Grup
+id	workflow	ca	Id
+if:setnextact	workflow	ca	Si:EstableixProperaActivitat
+inactive	workflow	ca	Inactiu
+inst. status	workflow	ca	Estat de la instància
+instance	workflow	ca	Instància
+instance properties	workflow	ca	Propietats de la instància
+instance: %1 (process: %2)	workflow	ca	Instància: %1 (Procés: %2)
+instances	workflow	ca	Instàncies
+interactive	workflow	ca	Interactiva
+interactivity	workflow	ca	Interactivitat
+invalid	workflow	ca	invàlid
+invalid process	workflow	ca	Procés invàlid
+is active	workflow	ca	està actiu
+join	workflow	ca	ajuntar
+list of activities	workflow	ca	Llista d'activitats
+list of instances	workflow	ca	Llista d'instàncies
+list of mappings	workflow	ca	Llista de mapatges
+list of processes	workflow	ca	Llista de processos
+list of processes (%1)	workflow	ca	Llista de processos (%1)
+list of transitions	workflow	ca	Llista de transicions
+list of workitems	workflow	ca	Llista d'elements de treball
+manual	workflow	ca	Manual
+map	workflow	ca	mapa
+map users/groups to roles	workflow	ca	Mapar usuaris/grups a papers
+mappings deleted	workflow	ca	Mapatges esborrats
+monitor activities	workflow	ca	Monitorar activitats
+monitor instances	workflow	ca	Monitorar instàncies
+monitor processes	workflow	ca	Monitorar processos
+monitor work items	workflow	ca	Monitorar elements de treball
+name	workflow	ca	Nom
+new	workflow	ca	Nova
+new major	workflow	ca	Nou major
+new mapping added	workflow	ca	S'ha afegit un nou mapatge
+new mayor	workflow	ca	Nou major
+new minor	workflow	ca	Nou menor
+new transition added	workflow	ca	S'ha afegit una nova transició
+no activity indicated	workflow	ca	No s'ha indicat una activitat
+no instance indicated	workflow	ca	No s'ha indicat una instància
+no process indicated	workflow	ca	No s'ha indicat cap procés
+no properties defined	workflow	ca	No s'han definit propietats
+no roles	workflow	ca	No hi ha papers
+no roles asociated with this activity	workflow	ca	No hi ha papers associats amb aquesta activitat
+no work item indicated	workflow	ca	No s'ha indicat cap element de treball
+or import a process	workflow	ca	O importar un procés
+owner	workflow	ca	Propietari
+process	workflow	ca	Procés
+process %d has been activated	workflow	ca	El procés %d ha estat activat
+process %d has been deactivated	workflow	ca	El procés %d ha estat desactivat
+process %s %s imported	workflow	ca	El procés %s %s ha estat importat
+process %s has been created	workflow	ca	El procés %s ha estat creat
+process %s has been updated	workflow	ca	El procés %s ha estat actualitzat
+process %s removed	workflow	ca	El procés %s ha estat eliminat
+process activities	workflow	ca	Processar activitats
+process does not have a start activity	workflow	ca	El procés no té una activitat inicial
+process does not have exactly one end activity	workflow	ca	El procés no té exactament una activitat final
+process form	workflow	ca	Formulari del procés
+process name	workflow	ca	Nom del Procés
+process name already exists	workflow	ca	El nom del procés ja existeix
+process roles	workflow	ca	Processar papers
+process transitions	workflow	ca	Processar transicions
+processes	workflow	ca	Processos
+properties	workflow	ca	Propietats
+property	workflow	ca	Propietat
+release instance	workflow	ca	alliberar instància
+role %1 is not mapped	workflow	ca	El paper %1 no està mapat
+role added to process	workflow	ca	Paper afegit al procés
+role saved	workflow	ca	Paper desat
+roles	workflow	ca	Papers
+roles assigned to this activity	workflow	ca	Papers assignats a aquesta activitat
+roles deleted	workflow	ca	Papers esborrats
+routing	workflow	ca	Encaminament
+run	workflow	ca	executar
+run activity	workflow	ca	executar activitat
+run instance	workflow	ca	executar instància
+running	workflow	ca	executant
+running activity	workflow	ca	Executant activitat
+select source	workflow	ca	selecciona font
+send all to	workflow	ca	Envia'ls tots a
+send instance	workflow	ca	envia instància
+set next act	workflow	ca	Estableix Propera activitat
+set next user	workflow	ca	Estableix proper usuari
+set property	workflow	ca	Estableix propietat
+shared code	workflow	ca	Codi compartit
+show code	workflow	ca	mostra codi
+show template	workflow	ca	mostra plantilla
+source saved	workflow	ca	Font desada
+split	workflow	ca	separa
+standalone	workflow	ca	independent
+start	workflow	ca	Inicia
+started	workflow	ca	Iniciat
+status	workflow	ca	Estat
+stop	workflow	ca	atura
+switch	workflow	ca	commutador
+switch construct	workflow	ca	Constructor del commutador
+template	workflow	ca	plantilla
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	ca	El directori /workflow no existeix i no es pot crear. Si us plau, demaneu al vostre administrador que comprovi la configuració global
+the following items must be corrected to be able to activate this process	workflow	ca	S'han de corregir els següents elements per poder activar aquest procés
+there are no activities available	workflow	ca	No hi ha activitats disponibles
+there are no instances available	workflow	ca	No hi ha instàncies disponibles
+there are no mappings defined for this process	workflow	ca	No hi ha mapatges definits per aquest procés
+there are no processes	workflow	ca	No hi ha processos
+there are no processes available	workflow	ca	No hi ha processos disponibles
+there are no processes defined	workflow	ca	No hi ha processos definits
+there are no properties available	workflow	ca	No hi ha propietats disponibles
+there are no roles defined for this process	workflow	ca	No hi ha papers definits per a aquest procés
+there are no transitions defined	workflow	ca	No hi ha transicions definides
+there are no user activites available	workflow	ca	No hi ha activitats d'usuari disponibles
+there are no workitems available	workflow	ca	No hi ha elements de treball disponibles
+to	workflow	ca	A
+transitions removed successfully	workflow	ca	Les transicions s'han eliminat correctament
+type	workflow	ca	tipus
+update	workflow	ca	actualitza
+upload file	workflow	ca	Penja fitxer
+user	workflow	ca	Usuari
+user activities	workflow	ca	Activitats de l'usuari
+user instances	workflow	ca	Instàncies de l'usuari
+user processes	workflow	ca	Processos de l'usuari
+user/group	workflow	ca	Usuari/Grup
+users/groups	workflow	ca	Usuaris/Grups
+valid	workflow	ca	Vàlid
+valid process	workflow	ca	Procés vàlid
+value	workflow	ca	Valor
+version	workflow	ca	Versió
+workflow	common	ca	Flux de treball
+workitem information	workflow	ca	Informació de l'element de treball
+workitems	workflow	ca	Elements de treball
+you have not permission to execute this activity	workflow	ca	No teniu permís per executar aquesta activitat
Index: /sandbox/workflow/branches/993/setup/phpgw_pt-br.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_pt-br.lang	(revision 1710)
+++ /sandbox/workflow/branches/993/setup/phpgw_pt-br.lang	(revision 1710)
@@ -0,0 +1,709 @@
+#	workflow	pt-br	#
+%1 aborted	workflow	pt-br	%1 abortadas
+%1 active	workflow	pt-br	%1 ativas
+%1 completed	workflow	pt-br	%1 completadas
+%1 configuration	workflow	pt-br	%1 Configuração
+%1 days, %2:%3:%4	workflow	pt-br	%1 dias, %2:%3:%4
+%1 exception	workflow	pt-br	%1 exceções
+%1 menu	workflow	pt-br	%1 Menu
+%1 monitoring	workflow	pt-br	%1 Monitoramento
+%1 processes (%2 active) (%3 being_run)	workflow	pt-br	%1 processos (%2 ativos) (%3 em execução)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	pt-br	O diretório /workflow não existe e não pode ser criado, por favor solicite ao administrador para verificar a configuração global
+<strong>%owner%</strong> is the instance owner email	workflow	pt-br	<strong>%owner%</strong> é o email do proprietário da instância
+<strong>%property_xx%</strong> is the content of the instance's property xx	workflow	pt-br	<strong>%property_XX%</strong> é o conteúdo da propriedade XX da instância
+<strong>%role_xx%</strong> are all the emails of all users mapped to the role xx	workflow	pt-br	<strong>%role_XX%</strong> são os emails de todos os usuários mapeados ao perfil XX
+<strong>%roles%</strong> are the emails of all users mapped to any role on this activity	workflow	pt-br	<strong>%roles%</strong> são os emails de todos os usuários mapeados a qualquer perfil nesta atividade
+<strong>%signature%</strong> is the agent signature defined in the process configuration	workflow	pt-br	<strong>%signature%</strong> é a assinatura do agente definida na configuração do processo
+<strong>%user%</strong> is the instance user email	workflow	pt-br	<strong>%user%</strong> é o email do usuário da instância
+<strong>%user_xx%</strong> is the email of the acount xx	workflow	pt-br	<strong>%user_XX%</strong> é o email da conta XX
+a please wait message is shown when loading the activity form usefull for long tasks	admin	pt-br	uma mensagem por favor aguarde será mostrada quando o formulário da atividade for carregado. Útil para tarefas de londa duração
+abort instance	workflow	pt-br	abortar instância
+abort this instance	workflow	pt-br	Abortar esta instância
+aborted	workflow	pt-br	abortada
+access denied for user %1 on activity %2, no role	workflow	pt-br	Acesso negado ao usuário %1 na atividade %2, nenhum perfil
+act	workflow	pt-br	ativ
+act. status	workflow	pt-br	Estado Ativ.
+act. status:	workflow	pt-br	Estado ativ:
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	pt-br	Ação %1 é impossível se não há atividade e instância designada para ela!
+action %1 is impossible, another user is already in place	workflow	pt-br	Ação %1 é impossível, já foi atribuída para outro usuário
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	pt-br	Ação %1 é impossível, não há usuário designado para esta atividade nesta instância
+action %1 needs an activity and activity %2 does not exists	workflow	pt-br	Ação %1 necessita uma atividade e a atividade %2 não existe
+action %1 needs an instance and instance %2 does not exists	workflow	pt-br	Ação %1 necessita uma instância e a instância %2 não existe
+actions	workflow	pt-br	Ações
+actions right options	common	pt-br	Opções de Direitos para Ações
+activate	workflow	pt-br	ativar
+active	workflow	pt-br	Ativo
+active:	workflow	pt-br	ativo:
+activities	workflow	pt-br	Atividades
+activities selection	workflow	pt-br	Seleção de atividades
+activities updated	workflow	pt-br	Atividades atualizadas
+activity	workflow	pt-br	atividade
+activity  status	workflow	pt-br	Estado da atividade
+activity %1	workflow	pt-br	atividade %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	pt-br	Atividade %1 (#%2) está associada a um processo inexistente (#%3)
+activity %1 code is not avaible	workflow	pt-br	o código da atividade %1 não está disponível
+activity %1 is interactive but has no role assigned	workflow	pt-br	Atividade %1 é interativa mas não tem perfil associado
+activity %1 is interactive so it must use the $instance->complete() method	workflow	pt-br	Atividade %1 é interativa e portanto deve usar o método $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	pt-br	Atividade %1 é não interativa e de rotamento não automático, mas não possui perfil associado
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	pt-br	Atividade %1 é não interativa e portando não pode usar o método $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	pt-br	Atividade %1 é standalone e está usando o objeto $instance
+activity %1 is standalone but has transitions	workflow	pt-br	Atividade %1 é standalone mas possui transições
+activity %1 is standalone or view but has transitions	workflow	pt-br	Atividade %1 é standalone ou view mas possui transições
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	pt-br	Atividade %1 é switch portanto deve usar o método $instance->setNextActivity($actname)
+activity %1 is view and is using the $instance object in write mode	workflow	pt-br	Atividade %1 é view e está usando o objeto $instance em modo edição
+activity agent removed	workflow	pt-br	Agente da atividade removido
+activity completed	workflow	pt-br	Atividade completada
+activity failure	workflow	pt-br	falha na atividade
+activity in inexistent process	workflow	pt-br	Atividade em processo inexistente
+activity is waiting for pending transitions	workflow	pt-br	atividade está aguardando transições pendentes
+activity name already exists	workflow	pt-br	O nome da atividade já existe
+activity role #%1 removed	workflow	pt-br	Perfil da atividade #%1 removido
+activity role removed	workflow	pt-br	Perfil da atividade removido
+activity saved	workflow	pt-br	Atividade salva
+activity start not avaible, no corresponding activity was found.	workflow	pt-br	atividade start não disponível, nenhuma atividade correspondente foi encontrada.
+activity start not set, no corresponding activity was found.	workflow	pt-br	atividade start não definida, nenhuma atividade correspondente foi encontrada.
+activity status not avaible, no corresponding activity was found.	workflow	pt-br	atividade status não disponível, nenhuma atividade correspondente foi encontrada.
+activity:	workflow	pt-br	atividade:
+add a transition	workflow	pt-br	Adicionar uma transição
+add aborted instances	workflow	pt-br	Adicionar instâncias abortadas
+add advanced actions	workflow	pt-br	Adicionar ações avançadas
+add agent	workflow	pt-br	Adicionar agente
+add completed instances	workflow	pt-br	Adicionar instâncias completadas
+add instances in exception	workflow	pt-br	Adicionar instâncias em exceção
+add new	workflow	pt-br	adicionar novo
+add new role	workflow	pt-br	Adicionar novo perfil
+add or edit a process	workflow	pt-br	Adicionar ou editar um processo
+add or edit a role	workflow	pt-br	Adicionar ou editar um perfil
+add or edit an activity	workflow	pt-br	Adicionar ou editar uma atividade
+add property	workflow	pt-br	Adicionar propriedade
+add role	workflow	pt-br	Adicionar perfil
+add role to process	workflow	pt-br	Adicionar perfil a processo
+add transition	workflow	pt-br	adicionar transição
+add transitions	workflow	pt-br	Adicionar transições
+add transitions from	workflow	pt-br	Adicionar transições de
+add transitions to	workflow	pt-br	Adicionar transições para
+admin instance	workflow	pt-br	Administrar Instância
+admin process activities	workflow	pt-br	Administrar Atividades de Processos
+admin process roles	workflow	pt-br	Administrar Perfis de Processos
+admin processes	workflow	pt-br	Administrar Processos
+admin processes sources	workflow	pt-br	Administrar Código Fonte de Processos
+administer instances	admin	pt-br	Administrar instâncias
+administer processes	admin	pt-br	administrar processos
+agent #%1 of type %2 is associated to an inexistent activity #%3	workflow	pt-br	Agente #%1 do tipo %2 está associado a uma atividade inexistente #%3
+agent #%1 of type %2 is not linked with an activity	workflow	pt-br	Agente #%1 do tipo %2 não está associado a uma atividade
+agent associated with inexistent activity	workflow	pt-br	Agente associado a uma atividade inexistente
+agent without activity	workflow	pt-br	Agente sem atividade
+agents assigned to this activity	workflow	pt-br	Agentes assinalados para esta atividade
+all	workflow	pt-br	Todos
+always show advanced actions	workflow	pt-br	Sempre mostrar ações avançadas
+always show advanced mode	workflow	pt-br	Sempre mostrar modo avançado
+assign me this activity	workflow	pt-br	Atribua esta atividade para mim
+at least one email address cannot be validated.	workflow	pt-br	ao menos um endereço de email não pode ser validado.
+auto routed	workflow	pt-br	Roteamento automático
+auto-release on leaving activity	common	pt-br	Liberação automática ao sair da atividade
+automatic	workflow	pt-br	Automática
+autorouted activities does not need to be sent by any user after their execution	workflow	pt-br	Atividades de autoroteamento não necessitam ser enviadas para qualquer usuário após a sua execução
+bad parameter for setagents, the parameter should be an array	workflow	pt-br	parâmetro inválido para setAgents, o parâmetro deve ser um array
+bad role type	workflow	pt-br	Tipo de perfil inválido
+bad user	workflow	pt-br	Usuário inválido
+base directory does not exist, please ask adminstrator to check the global configuration	common	pt-br	Diretório base não existe, por favor solicite ao administrador para verificar a configuração global
+bcc:	workflow	pt-br	Cco:
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	pt-br	Tome cuidado com atividades interativas, início e fim destas atividades são múltiplos.
+being run	workflow	pt-br	em execução
+by running theses links you will create new instances of the related process.	workflow	pt-br	executando estes links você criará novas instâncias dos processos associados.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	pt-br	Impossível adicionar a transição. Apenas atividades split e switch podem ter mais de uma transição de saída
+cannot add transition. only split activities can have more than one outbound transition	workflow	pt-br	Impossível adicionar a transição. Apenas atividades split podem ter mais de uma transição de saída
+cannot create compiled file %1	workflow	pt-br	impossível criar o arquivo compilado %1
+cannot retrieve the user running the security check	workflow	pt-br	Impossível recuperar o usuário que está executando a verificação de segurança
+cannot run the activity	workflow	pt-br	Impossível executar a atividade
+cannot run the activity without her process	workflow	pt-br	Impossível executar a atividade sem o seu processo
+cannot run the activity without instance	workflow	pt-br	Impossível executar a atividade sem a instância
+cannot run unknown activity	workflow	pt-br	Impossível executar atividade desconhecida
+cc:	workflow	pt-br	Cc:
+circular reference found some activity has a transition leading to itself	workflow	pt-br	Loop encontrado. Alguma atividade tem uma transição conduzindo a ela mesma
+circular reference found. some activity has a transition leading to itself	workflow	pt-br	Loop encontrado. Alguma atividade tem uma transição conduzindo a ela mesma
+cleanup aborted instances	admin	pt-br	remover instâncias abortadas
+cleanup actions	workflow	pt-br	ações de remoção
+close and get back later	workflow	pt-br	Fechar e retornar depois
+close printer friendly mode	workflow	pt-br	Fechar o modo de visualização de impressão
+code	workflow	pt-br	código
+column activity status in instance lists	workflow	pt-br	Mostrar coluna de estado das atividades na lista de instâncias
+column category in instance lists	workflow	pt-br	Mostrar coluna de categoria na lista de instâncias
+column instance id in instance lists	workflow	pt-br	Mostrar coluna com id na lista de instãncias
+column instance name in instance lists	workflow	pt-br	Mostrar coluna com nome na lista de instâncias
+column instance status in instance lists	workflow	pt-br	Mostrar coluna com estado da instância na lista de instâncias
+column owner in instance lists	workflow	pt-br	Mostrar coluna com proprietário na lista de instâncias
+column priority in instance lists	workflow	pt-br	Mostrar coluna com prioridade na lista de instâncias
+column process name in instance lists	workflow	pt-br	Mostrar coluna com o nome do processo na lista de instâncias
+column start date in instance lists	workflow	pt-br	Mostrar coluna com a data de início na lista de instâncias
+compilation	workflow	pt-br	Compilação
+compiling activity %1 : %2	workflow	pt-br	compilando atividade %1 : %2
+complete	workflow	pt-br	Completada
+complete cleanup of aborted instances done	workflow	pt-br	remoção total de instâncias abortadas realizada
+complete cleanup of all instances done	workflow	pt-br	remoção total de todas as instâncias realizada
+completed	workflow	pt-br	completada
+config values	common	pt-br	Valores de configuração
+confirm delete	workflow	pt-br	Confirma a Deleção
+consult %1 to get the default values:	workflow	pt-br	Consulte %1 para obter os valores padrão:
+couldn't add transition	workflow	pt-br	Impossível adicionar transição
+create	workflow	pt-br	criar
+created	workflow	pt-br	Criado
+date:	workflow	pt-br	data:
+default config values	common	pt-br	Valores de configuração padrão
+default next user	workflow	pt-br	Próximo usuário padrão
+default owner	workflow	pt-br	Proprietário padrão
+default settings for processes	admin	pt-br	Definições padrão para processos
+default user	workflow	pt-br	Usuário Padrão
+delete selected	workflow	pt-br	Deletar selecionados
+delete transition	workflow	pt-br	deletar transição
+deletion successful	workflow	pt-br	Deleção bem sucedida
+delition successful	workflow	pt-br	Deleção bem sucedida
+description	workflow	pt-br	Descrição
+display please wait message	common	pt-br	mostrar mensagem por favor aguarde
+do you want the activity status on instances lists. most of the time it is "running" but if you use non-autorouted transitions you will have some completed activities.	workflow	pt-br	Você deseja ver o estado das atividades nas listas de instãncias? Na maioria das vezes o estado é "executando", mas se você usa transições de roteamento não automático, você terá algumas atividades completadas.
+do you want the category column on instances lists, if yout instances use categories you should use it	workflow	pt-br	Você deseja a coluna de categoria nas listas de instância? Se as suas instâncias usam categorias você deve usar a coluna
+do you want the category name column on instances lists, if your instances use categories you should use it	workflow	pt-br	Você deseja a coluna com o nome da categoria nas listas de instância? Se as suas instâncias usam categorias você deve usar a coluna
+do you want the category name column on instances lists. if your instances use categories you should use this	workflow	pt-br	Você deseja a coluna do nome da categoria nas listas de instâncias? Se as suas instâncias usam categorias você deve usar a coluna
+do you want the instance id column on instances lists. this is the unique identifier of an instance	workflow	pt-br	Você deseja a coluna com o id da instância, nas listas de instâncias? Este é o identificador único de uma instância
+do you want the instance name column on instances lists. if your instances have name you should really use this	workflow	pt-br	Você deseja a coluna com o nome da instância, nas listas de instâncias? Se as suas instâncias tem nome, você deve usar a coluna
+do you want the instance status on instances lists. the instance status is usefull to disting beteween aborted, completed, exception or active instances	workflow	pt-br	Você deseja ver o estado das instâncias nas listas de instâncias? O estado das instâncias é útil para distinção entre abortadas, completadas, exceções ou instâncias ativas
+do you want the owner column on instances lists. this will show you the actual owner, especially usefull if ownership is defined with special rights	workflow	pt-br	Você deseja a coluna do proprietário nas listas de instâncias? Isto irá mostrar a você o proprietário atual. Especialmente útil se a propriedade estiver definida com direitos especiais
+do you want the priority column on instances lists. priority can be set with activities forms	workflow	pt-br	Você deseja a coluna de prioridade nas listas de instâncias? A prioridade pode ser definida nos formulários de atividades
+do you want the process column on instances lists. usefull if you have different processes and/or versions of theses processes	workflow	pt-br	Você deseja a coluna com o processo nas listas de instância? Útil se você tem diversos processos e/ou versões destes processos
+do you want the search instance button in the last row of instances list.	workflow	pt-br	Você deseja o botão de pesquisa, na última linha da lista de instâncias?
+do you want the started date column on instances lists.	workflow	pt-br	Você deseja a coluna com data de início, nas listas de instância?
+don't move	workflow	pt-br	Não mova
+draw roles	common	pt-br	Mostrar perfis
+draw roles on the graph beside activity name like [that]	admin	pt-br	Mostrar perfis no gráfico, ao lado do nome da atividade, no formato [perfil]
+duration	workflow	pt-br	Duração
+empty agent type	workflow	pt-br	tipo de agente vazio
+end	workflow	pt-br	end
+end activity is not reachable from start activity	workflow	pt-br	Atividade end não é alcançada a partir da atividade start
+ended	workflow	pt-br	finalizada
+enter an activity name	workflow	pt-br	Informe um nome para a atividade
+error: nextactivity does not match any candidate in autorouting switch activity	workflow	pt-br	Erro: nextActivity não confere com qualquer candidato na atividade switch de autoroteamento
+error: non-deterministic decision for autorouting activity	workflow	pt-br	Erro: decisão indeterminada para atividade de autoroteamento
+error: removing was not done	workflow	pt-br	erro: remoção não foi realizada
+error: trying to send an instance to an activity but it was impossible to get this activity	workflow	pt-br	Erro: tentativa de enviar uma instância para uma atividade, mas foi impossível obter esta atividade
+error: trying to send an instance to an activity but no transition found	workflow	pt-br	Erro: tentativa de enviar uma instância para uma atividade, mas nenhuma transição foi encontrada
+exception	workflow	pt-br	exceção
+exception instance	workflow	pt-br	instância da exceção
+exception raised by %1 %2: %3	workflow	pt-br	exceção lançada por %1 %2: %3
+exception resumed by %1 %2: %3	workflow	pt-br	exceção removida por %1 %2: %3
+exception this instance	workflow	pt-br	Lançar exceção para esta instância
+exceptions	workflow	pt-br	exceções
+execute this activity	workflow	pt-br	Executar esta atividade
+export	workflow	pt-br	Exportar
+failed to create workitem	workflow	pt-br	falha ao criar workitem
+failed to execute automatic activity	workflow	pt-br	falha ao executar atividade automática
+failed to obtain lock on %1 table	workflow	pt-br	falha ao tentar bloqueio na tabela %1
+failed to obtain lock on instances table	workflow	pt-br	falha ao tentar bloqueio na tabela de instâncias
+failed to obtain lock on instances_activities table	workflow	pt-br	falha ao tentar bloqueio na tabela instances_activities
+failed to record instance properties	workflow	pt-br	falha ao salvar as propriedades da instância
+failed to synchronize instance data with the database	workflow	pt-br	falha ao sincronizar dados da instância com o banco de dados
+failure	workflow	pt-br	falha
+fatal error: nextactivity does not match any candidate in autorouting switch activity	workflow	pt-br	Erro fatal: nextActivity não confere com qualquer candidato na atividade switch de autoroteamento
+fatal error: non-deterministic decision for autorouting activity	workflow	pt-br	Erro fatal: decisão indeterminada para atividade de autoroteamento
+fatal error: setting next activity to an unexisting activity	workflow	pt-br	Erro fatal: próxima atividade definida para uma atividade que não existe
+fatal error: trying to send an instance to an activity but no transition found	workflow	pt-br	Erro fatal: tentativa de enviar uma instância para uma atividade, mas nenhuma transição foi encontrada
+filter	workflow	pt-br	Filtro
+filter instance by id	workflow	pt-br	filtrar instância por id
+finally you have links with <strong>%link_xx|yy%</strong> syntax, xx is the address part, yy the text part.	workflow	pt-br	por fim, você tem links com a sintaxe <strong>%link_XX|YY%</strong>, XX é a parte do endereço, YY é a parte textual.
+fix	workflow	pt-br	Corrigir
+fix concistency for selected rows	workflow	pt-br	Corrigir a consistência das linhas selecionadas
+font size	common	pt-br	Tamanho da fonte
+from	workflow	pt-br	De
+from:	workflow	pt-br	De:
+get back to global activities	workflow	pt-br	voltar para as atividades globais
+get back to instance creation	workflow	pt-br	voltar para a criação de instância
+get property	workflow	pt-br	Obter propriedade
+global activities	workflow	pt-br	Atividades Globais
+global workflow preferences	workflow	pt-br	Preferências globais do Workflow
+go	workflow	pt-br	ir
+go to same activities for other instances of this process	workflow	pt-br	ir para as mesmas atividades de outras instâncias do mesmo processo
+go to same process activities	workflow	pt-br	ir para as mesmas atividades do processo
+go to the actual state of this instance	workflow	pt-br	ir para o estado atual desta instância
+grab instance	workflow	pt-br	capturar instância
+grant access to the administration and development of workflow processes and activities.	admin	pt-br	Liberar acesso para administração e desenvolvimento de processos e atividades de workflow
+grant access to the administration of workflow elements	admin	pt-br	Liberar acesso para administração de elementos do workflow
+grant access to the administration of workflow instances in monitor screens	admin	pt-br	Liberar acesso para administração de instâncias de workflow, nas janelas de monitoramento
+grant access to the cleanup/deletion of workflow aborted instances in monitor screens	admin	pt-br	Liberar acesso para remover/deletar instâncias abortadas de workflow, nas janelas de monitoramento
+grant access to the monitoring of workflow elements	admin	pt-br	Liberar acesso para monitoramento de elementos do workflow
+graph	workflow	pt-br	Gráfico
+graphic options	common	pt-br	Opções do gráfico
+group	workflow	pt-br	Grupo
+id	workflow	pt-br	Id
+if automatic parsing is disabled next options will be useless	admin	pt-br	se o parsing automático estiver desabilitado, as próximas opções serão desnecessárias
+if not in debug mail_smtp agent would have sent this email:	workflow	pt-br	se não estivesse em modo debug, o agente mail_smtp teria enviado este email:
+if user is in a role for an activity he will have the right to abort the related instance	admin	pt-br	Se o usuário está em um perfil para uma atividade, ele terá o direito de abortar a instância associada
+if user is in a role for an activity he will have the right to exception or resume the related instance	admin	pt-br	Se o usuário está em um perfil para uma atividade, ele terá o direito de lançar uma exceção ou retomar a instância associada
+if user is in a role for an activity he will have the right to release (un-assign) the related instance	admin	pt-br	Se o usuário está em um perfil para uma atividade, ele terá o direito de liberar (desassinalar) a instância associada
+if:setnextact	workflow	pt-br	If:SetNextact
+iframe view height	workflow	pt-br	Altura do frame de Visualização
+import aborted	workflow	pt-br	Importação abortada
+import successfull	workflow	pt-br	Importação realizada com sucesso
+in role mappings user #%1 is specified as a "%2" but is maybe a "%3"	workflow	pt-br	No mapeamento de perfis, o usuário #%1 está especificado como "%2" mas é PROVAVELMENTE "%3"
+inactive	workflow	pt-br	Inativo
+inst.	workflow	pt-br	Inst.
+inst. status	workflow	pt-br	Estado Inst.
+instance	workflow	pt-br	Instância
+instance %1	workflow	pt-br	instância %1
+instance %1 is in %2 state, action %3 is impossible.	workflow	pt-br	Instância %1 está no estado %2, ação %3 é impossível.
+instance %1 is in exception, action %2 is not possible.	workflow	pt-br	Instância %1 está em exceção, ação %2 é impossível.
+instance %1 is not associated with activity %2, action %3 is impossible.	workflow	pt-br	Instância %1 não está associada à atividade %2, ação %3 é impossível.
+instance history	workflow	pt-br	Histórico da Instância
+instance properties	workflow	pt-br	Propriedades da Instância
+instance:	workflow	pt-br	instância:
+instance: %1 (process: %2)	workflow	pt-br	Instância: %1 (Processo: %2)
+instance: unable to modify %1 [%2], someone has changed it before us	workflow	pt-br	Instância: não é possível modificar %1 [%2], alguém a modificou antes que você
+instance: unable to modify %1, someone has changed it before us	workflow	pt-br	Instância: não é possível modificar %1, alguém a modificou antes que você
+instances	workflow	pt-br	Instâncias
+instances selection	workflow	pt-br	Seleção de instâncias
+int.	workflow	pt-br	Int.
+interactive	workflow	pt-br	Interativa
+interactive activities show form before being executed	workflow	pt-br	Atividades interativas exibem um formulário antes de serem executadas
+interactive instances should not call the complete() method	workflow	pt-br	instâncias interativas não devem chamar o método complete()
+interactive:	workflow	pt-br	interativa:
+interactivity	workflow	pt-br	interatividade
+invalid	workflow	pt-br	inválido
+invalid process	workflow	pt-br	Processo Inválido
+invalid role name	workflow	pt-br	Nome de perfil inválido
+is active	workflow	pt-br	está ativo
+it seems this activity for this instance is not assigned to you anymore.	workflow	pt-br	Parece que esta atividade, desta instância, não está assinalada para ninguém.
+it was impossible to complete, no activity was given.	workflow	pt-br	impossível completar, nenhuma atividade foi informada.
+it was impossible to complete, no corresponding activity was found.	workflow	pt-br	impossível completar, nenhuma atividade correspondente foi encontrada.
+join	workflow	pt-br	join
+link addresses are considered local if not containing <strong>http://</strong>. they will get appended the configured local prefix and scanned by egroupware link engine	workflow	pt-br	Links são considerados locais se não contém <strong>http://</strong>. O prefixo local configurado será anexado ao link e ele será rastreado pelo engine de link do egroupware
+list of activities	workflow	pt-br	Lista de atividades
+list of all activities with, for each,  counters of instances by status	workflow	pt-br	lista de todas as atividade, com contadores de instâncias, por estado, para cada uma
+list of all history items made by instances while they travel in the workflow with information about duration and date	workflow	pt-br	lista de todos os ítens históricos gerados pelas instâncias, com informação sobre duração e data, enquanto trafegaram pelo workflow
+list of all instances with info about current status and activities and link to administration of theses instances	workflow	pt-br	lista de todas as instâncias, com informação sobre o estado corrente e atividades, e um link para administrar estas instâncias
+list of instances	workflow	pt-br	Lista de instâncias
+list of mappings	workflow	pt-br	Lista de mapeamentos
+list of monitors	workflow	pt-br	Lista de monitores
+list of processes	workflow	pt-br	Lista de processos
+list of processes (%1)	workflow	pt-br	Lista de processos (%1)
+list of processes with status and validity and, for each, counters of instances by status	workflow	pt-br	lista de processos com estado e validade e, para cada um deles, contadores de instâncias por estado
+list of transitions	workflow	pt-br	Lista de transições
+list of workitems	workflow	pt-br	Lista de workitems
+mail automatically sent by mail smtp agent for egroupware's workflow	workflow	pt-br	Email enviado automaticamente, pelo Agente de Correio SMTP, para o Workflow do eGroupware
+mail smtp agent	workflow	pt-br	Agente de Correio Smtp
+mail smtp debug	common	pt-br	Depurar correio smtp
+mail smtp local link prefix	common	pt-br	Prefixo de link local do correio smtp
+mail smtp profile	common	pt-br	Profile do correio smtp
+mail smtp signature	common	pt-br	Assinatura do correio smtp
+mails can be sent at the begining or at the end of the activity, for interactive activities only it can be sent after completion.	workflow	pt-br	Emails podem ser enviados no início ou no final de uma atividade. Para atividades interativas, podem ser enviados somente depois de completadas.
+manual	workflow	pt-br	Manual
+map	workflow	pt-br	mapear
+map users/groups to roles	workflow	pt-br	Mapear usuários/grupos a perfis
+mapping to inexistent role	workflow	pt-br	Mapeamento para um perfil inexistente
+mappings deleted	workflow	pt-br	Mapeamentos deletados
+message:	workflow	pt-br	Mensagem:
+monitor activities	workflow	pt-br	Monitorar Atividades
+monitor instance	workflow	pt-br	monitor instance
+monitor instances	workflow	pt-br	Monitorar Instâncias
+monitor processes	workflow	pt-br	Monitorar Processos
+monitor this instance	workflow	pt-br	Monitorar esta instância
+monitor work items	workflow	pt-br	Monitorar Workitens
+monitor workitems	workflow	pt-br	Monitorar Workitems
+monitoring	admin	pt-br	monitoring
+monitors	workflow	pt-br	Monitores
+more options?	workflow	pt-br	mais opções?
+my activities	workflow	pt-br	Minhas Atividades
+my instances	workflow	pt-br	Minhas Instâncias
+my processes	workflow	pt-br	Meus Processos
+name	workflow	pt-br	Nome
+new instance	workflow	pt-br	Nova Instância
+new major	workflow	pt-br	Novo nível superior
+new major version created	workflow	pt-br	novo nível superior de versão criado
+new mapping added	workflow	pt-br	Novo mapeamento adicionado
+new minor	workflow	pt-br	Novo nível inferior
+new minor version created	workflow	pt-br	novo nível inferior de versão criado
+new status not set, no corresponding activity was found.	workflow	pt-br	novo estado não definido, nenhuma atividade correspondente foi encontrada.
+new transition added	workflow	pt-br	Nova transição adicionada
+next activity	workflow	pt-br	próxima atividade
+next user:	workflow	pt-br	Próximo usuário:
+no action avaible because no activity and no instance are given!	workflow	pt-br	nenhuma ação disponível porque nenhuma atividade e istância foi apresentada!
+no activites	workflow	pt-br	Nenhuma atividade
+no activity indicated	workflow	pt-br	Nenhuma atividade indicada
+no agents associated with this activity	workflow	pt-br	Nenhuma Agente associado com esta atividade
+no circular transitions allowed.	workflow	pt-br	Nenhuma transição de loop permitida.
+no corresponding activity was found.	workflow	pt-br	nenhuma atividade correspondente foi encontrada.
+no inbound for start activity	workflow	pt-br	Nenhuma entrada para a atividade start
+no inconcistency detected	workflow	pt-br	nenhuma inconsistência detectada
+no instance avaible	workflow	pt-br	nenhuma instância disponível
+no instance given, nothing to show	workflow	pt-br	nenhuma instância apresentada, nada para mostrar
+no instance indicated	workflow	pt-br	Nenhuma instância indicada
+no outbound for end activity	workflow	pt-br	Nenhuma saída para a atividade end
+no process indicated	workflow	pt-br	Nenhum processo indicado
+no properties defined	workflow	pt-br	Nenhuma propriedade definida
+no roles	workflow	pt-br	nenhum perfil
+no roles asociated with this activity	workflow	pt-br	Nenhum perfil assossiado com esta atividade
+no routage	workflow	pt-br	nenhuma rota
+no scan done	workflow	pt-br	nenhum rastreamento realizado
+no transitions allowed for standalone or view activities	workflow	pt-br	Nenhuma transição é permitida para as atividades standalone ou view
+no work item indicated	workflow	pt-br	Nenhum workitem indicado
+nobody	workflow	pt-br	Ninguém
+not defined	workflow	pt-br	não definido
+or import a process	workflow	pt-br	Ou importar um processo
+owner	workflow	pt-br	Proprietário
+owner of the instance will have the right to abort the instance at any time	admin	pt-br	O proprietário da instância terá o direito de abortar a instância a qualquer tempo
+owner of the instance will have the right to exception or resume the instance at any time	admin	pt-br	O proprietário da instância terá o direito de lançar uma exceção ou retomar a instância a qualquer tempo
+owner of the instance will have the right to release (un-assign) an activity assigned to an user	admin	pt-br	O proprietário da instância terá o direito de liberar (desassinalar) uma atividade assinalada a um usuário
+owner:	workflow	pt-br	Proprietário:
+ownership give abort right	common	pt-br	A posse garante o direito de abortar
+ownership give exception right	common	pt-br	A posse garante o direito de lançar exceção
+ownership give release right	common	pt-br	A posse garante o direito de liberar
+please wait, task in progress ...	workflow	pt-br	Por favor aguarde, atividade em execução ...
+post activity %1 code is not avaible	workflow	pt-br	código da pós-atividade %1 não está disponível
+post shared code is not avaible	workflow	pt-br	código pós-compartilhado não está disponível
+post-agent %1 code is not avaible	workflow	pt-br	código do pós-agente %1 não está disponível
+pr.	workflow	pt-br	Pr.
+pre-activity %1 code is not avaible	workflow	pt-br	código da pré-atividade %1 não está disponível
+pre-agent %1 code is not avaible	workflow	pt-br	código do pré-agente %1 não está disponível
+pre-shared code is not avaible	workflow	pt-br	código pré-compartilhado não está disponível
+printer friendly	workflow	pt-br	Versão para impressão
+priority level:	workflow	pt-br	Nível de prioridade:
+process	workflow	pt-br	Processo
+process %1	workflow	pt-br	processo %1
+process %1 %2 is not active, action %3 is impossible	workflow	pt-br	Processo %1 %2 não está ativo, ação %3 é impossível
+process %1 v%2 as no related activity	workflow	pt-br	Processo %1 v%2 não tem atividade relacionada
+process %d has been activated	workflow	pt-br	Processo %d foi ativado
+process %d has been deactivated	workflow	pt-br	Processo %d foi desativado
+process %s %s already exists, the import process was aborted	workflow	pt-br	Processo %s %s já existe, o processo de importação foi abortado
+process %s %s imported	workflow	pt-br	Processo %s %s importado
+process %s has been created	workflow	pt-br	Processo %s foi criado
+process %s has been updated	workflow	pt-br	Processo %s foi atualizado
+process %s removed	workflow	pt-br	Processo %s removido
+process activities	workflow	pt-br	Atividades do processo
+process alone	workflow	pt-br	Processo isolado
+process does not have a start activity	workflow	pt-br	Processo não tem uma atividade start
+process does not have exactly one end activity	workflow	pt-br	Processo não tem uma atividade end exata
+process form	workflow	pt-br	Formulário do processo
+process name	workflow	pt-br	Nome do Processo
+process name already exists	workflow	pt-br	Nome do processo já existe
+process roles	workflow	pt-br	Perfis do processo
+process saved	workflow	pt-br	Processo salvo
+process transitions	workflow	pt-br	Transições do processo
+process version:	workflow	pt-br	versão do processo:
+process:	workflow	pt-br	processos:
+processes	workflow	pt-br	Processos
+properties	workflow	pt-br	Propriedades
+property	workflow	pt-br	Propriedade
+property %1 already exists	workflow	pt-br	propriedade %1 já existe
+property %1 not found	workflow	pt-br	propriedade %1 não encontrada
+quit without saving	workflow	pt-br	Sair sem Salvar
+read-only	workflow	pt-br	somente-leitura
+release access to this activity	workflow	pt-br	Liberar acesso para esta atividade
+release activity for this instance	workflow	pt-br	liberar atividade para esta instância
+release instance	workflow	pt-br	liberar instância
+reload filter	workflow	pt-br	Recarregar filtro
+remove active instances	workflow	pt-br	Remover instâncias ativas
+remove all instances for this process	workflow	pt-br	remover todas as instâncias deste processo
+remove selected roles	workflow	pt-br	remover perfis selecionados
+removing instances and workitems for aborted instances on all processes	workflow	pt-br	removendo instâncias e workitems para instâncias abortadas em todos os processos
+removing instances and workitems for aborted instances on process #%1	workflow	pt-br	removendo instâncias e workitems para instâncias abortadas no processo #%1
+removing instances and workitems for all instances on process #%1	workflow	pt-br	removendo instâncias e workitems para todas as instâncias do processo #%1
+replyto:	workflow	pt-br	Responder para:
+restart	workflow	pt-br	reiniciar
+restart activity	workflow	pt-br	reiniciar atividade
+resume this exception instance	workflow	pt-br	Continuar esta instância em exceção
+role	workflow	pt-br	Perfil
+role #%1 in process %2 has different process (%3) in mapping with user #%4	workflow	pt-br	Perfil #%1 no processo %2 tem processo diferente (%3) no mapeamento com usuário #%4
+role %1 (#%2) is associated with a non-existent process (#%3)	workflow	pt-br	Perfil %1 (#%2) está associado a um processo inexistente (#%3)
+role %1 is associated in a mapping with user #%2 with a non-existent process (%3)	workflow	pt-br	Perfil %1 está associado, em um mapeamento com o usuário #%2, a um processo inexistente (%3)
+role %1 is not mapped	workflow	pt-br	Perfil %1 não está mapeado
+role added to activity	workflow	pt-br	Perfil adicionado à atividade
+role added to process	workflow	pt-br	Perfil adicionado ao processo
+role give abort right	common	pt-br	Perfil garante o direito de abortar
+role give exception right	common	pt-br	Perfil garante o direito de lançar exceção
+role give release right	common	pt-br	Perfil garante o direito de liberar
+role in inexistent process	workflow	pt-br	Perfil em processo inexistente
+role mapping in inexistent process	workflow	pt-br	Mapeamento de Perfil em processo inexistente
+role name	workflow	pt-br	Nome do Perfil
+role not saved (maybe a name collision)	workflow	pt-br	Perfil não foi salvo (possivelmente nomes coincidentes)
+role process inconcistency in mappings	workflow	pt-br	Inconsistência nos mapeamentos dos perfis do processo
+role saved	workflow	pt-br	Perfil salvo
+roles	workflow	pt-br	Perfis
+roles assigned to this activity	workflow	pt-br	Perfis associados a esta atividade
+roles deleted	workflow	pt-br	Perfis deletados
+routing	workflow	pt-br	Roteamento
+routing:	workflow	pt-br	roteamento:
+run	workflow	pt-br	executar
+run activity	workflow	pt-br	executar atividade
+run instance	workflow	pt-br	executar instância
+running	workflow	pt-br	executando
+running activities options	common	pt-br	Opções para atividades em execução
+running activity	workflow	pt-br	Atividade em Execução
+scan activities	workflow	pt-br	Percorrer atividades
+scan agents	workflow	pt-br	Percorrer agentes
+scan instances	workflow	pt-br	Percorrer instâncias
+scan processes	workflow	pt-br	Percorrer processos
+scan roles	workflow	pt-br	Percorrer perfis
+scan transitions	workflow	pt-br	Percorrer transições
+search instance filter in the bottom of instance lists	workflow	pt-br	Filtro de pesquisa de instâncias no final das listas de instância
+search:	workflow	pt-br	pesquisar:
+security check: cannot understand asked action	workflow	pt-br	Verificação de segurança: não pode interpretar ação solicitada
+see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>	workflow	pt-br	veja também <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>
+select a transition to remove	workflow	pt-br	Selecionar uma transição para remover
+select source	workflow	pt-br	selecionar fonte
+send after interactive activity is completed	workflow	pt-br	envio ao final da atividade interativa foi completado
+send all to	workflow	pt-br	Enviar tudo para
+send an email	workflow	pt-br	Enviar um email
+send instance	workflow	pt-br	enviar instância
+send this instance to the next activity	workflow	pt-br	Enviar esta instância para a próxima atividade
+send transition	workflow	pt-br	enviar transição
+send when the activity is ending	workflow	pt-br	enviar quando a atividade finalizar
+send when the activity is starting	workflow	pt-br	enviar quando a atividade iniciar
+send when wf_agent_mail_smtp['submit_send'] is posted	workflow	pt-br	enviar quando wf_agent_mail_smtp['submit_send'] for postado
+set next act	workflow	pt-br	Definir Próxima ativ
+set next user	workflow	pt-br	Definir próximo usuário
+set property	workflow	pt-br	Definir propriedade
+setnextuser directives can override it	workflow	pt-br	diretivas setNextUser podem sobrescrevê-la
+setting next activity to an unexisting activity	workflow	pt-br	definição da próxima atividade aponta para uma atividade inexistente
+shared code	workflow	pt-br	Código compartilhado
+should we always give you the advanced search row on instances lists?	workflow	pt-br	Devemos sempre mostrar a você a linha com pesquisa avançada, nas listas de instância?
+show activity info zone	common	pt-br	mostrar zona de informações das atividades
+show activity title	common	pt-br	mostrar título das atividades
+show code	workflow	pt-br	mostrar código
+show instance name	common	pt-br	Mostrar nome da instância
+show instance owner	common	pt-br	Mostrar proprietário da instância
+show multiple submit as select	common	pt-br	mostrar múltiplos submit como seleção
+show template	workflow	pt-br	mostrar template
+size of the font used on the graph 12 should be a good default value	admin	pt-br	Tamanho da fonte usada nos gráficos. Recomenda-se 12 como valor padrão
+smtp agent has detected some errors when sending email after completion of the activity	workflow	pt-br	Agente Smtp detectou alguns erros quando enviou o email após a finalização da atividade
+smtp agent has detected some errors when sending email at the beginning of the activity	workflow	pt-br	Agente Smtp detectou alguns erros quando enviou o email no início da atividade
+smtp agent has detected some errors when sending email at the end of this activity	workflow	pt-br	Agente Smtp detectou alguns erros quando enviou o email ao final desta atividade
+smtp agent has detected some errors when sending email on demand whith this activity	workflow	pt-br	Agente Smtp detectou alguns erros quando enviou o email sob demanda nesta atividade
+something was wrong while creating the new major version	workflow	pt-br	algo deu errado enquanto criava a versão de nível superior
+something was wrong while creating the new minor version	workflow	pt-br	algo deu errado enquanto criava a versão de nível inferior
+source code file for activity %1 is not avaible	workflow	pt-br	arquivo de código fonte para a atividade %1 não está disponível
+source code for activity %1 is not avaible	workflow	pt-br	código fonte para a atividade %1 não está disponível
+source saved	workflow	pt-br	Fonte salvo
+special known values for local links address are <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.	workflow	pt-br	Valores especiais conhecidos para links locais são <strong>userinstance</strong>, <strong>viewinstance</strong>, <strong>viewniceinstance</strong> and <strong>admininstance</strong>.
+split	workflow	pt-br	split
+standalone	workflow	pt-br	standalone
+start	workflow	pt-br	Start
+start activities must be autorouted	workflow	pt-br	atividades start devem ser de roteamento automático
+start activities must be interactive	workflow	pt-br	atividades start devem ser interativas
+start activity	workflow	pt-br	Atividade inicial
+start process	workflow	pt-br	iniciar processo
+started	workflow	pt-br	Iniciado
+started:	workflow	pt-br	iniciado:
+starting page	workflow	pt-br	Página de início
+status	workflow	pt-br	Estado
+status:	workflow	pt-br	estado:
+stop	workflow	pt-br	parar
+subject:	workflow	pt-br	Assunto:
+switch	workflow	pt-br	switch
+switch construct	workflow	pt-br	Construir o Switch
+template	workflow	pt-br	template
+test concistency	workflow	pt-br	Testar consistência
+test consistency of datas in the database	workflow	pt-br	Testar consistência dos dados no banco
+test local installation	workflow	pt-br	Testar instalação local
+the /workflow directory does not exist and could not be created. please ask your administrator to check the global configuration	common	pt-br	O diretório /workflow não existe e não pode ser criado. Por favor solicite ao administrador para verificar a configuração global
+the activity was not completed	workflow	pt-br	A atividade não completada
+the default user will only be set if he is mapped to a role on the activity	workflow	pt-br	O usuário default somente será assinalado se estiver mapeado a um perfil na atividade
+the following items must be corrected to be able to activate this process	workflow	pt-br	Os itens a seguir devem ser corrigidos para permitir a ativação deste processo
+the instance title is shown on top of the form	admin	pt-br	o título da instância aparecerá no topo do formulário
+the label you want	workflow	pt-br	o rótulo que você quer
+the smtp configuration cannot be loaded by the mail_smtp workflow agent	workflow	pt-br	A configuração de SMTP não pode ser carregada pelo agente de workflow mail_smtp
+there are no activities available	workflow	pt-br	Não existem atividades disponíveis
+there are no config value defined	workflow	pt-br	Não existe valor de configuração definido
+there are no instances available	workflow	pt-br	Não existem instâncias disponíveis
+there are no mappings defined for this process	workflow	pt-br	Não existem mapeamentos definidos para este processo
+there are no process available	workflow	pt-br	Não existe processo disponível
+there are no processes	workflow	pt-br	Não existem processos
+there are no processes available	workflow	pt-br	Não existem processos disponíveis
+there are no processes defined	workflow	pt-br	Não existem processos definidos
+there are no processes with the current filter	workflow	pt-br	Não existem processos com o filtro corrente
+there are no properties available	workflow	pt-br	Não existem propriedades disponíveis
+there are no roles defined for this process	workflow	pt-br	Não existem perfis definidos para este processo
+there are no transitions defined	workflow	pt-br	Não existem transições definidas
+there are no user activites available	workflow	pt-br	Não existem atividades do usuário disponíveis
+there are no workitems available	workflow	pt-br	Não existem workitems disponíveis
+there are some undefined preferences associated with this form : %1	workflow	pt-br	existem algumas preferências não definidas associadas com este formulário : %1
+there is an unknown user or group #%1 in role mappings	workflow	pt-br	Existe um usuário ou grupo desconhecido #%1 nos mapeamentos de perfil
+they were problems at the compilation of the source:	workflow	pt-br	Ocorreram problemas na compilação do fonte:
+this activity for this instance is actually avaible for you.	workflow	pt-br	Esta atividade desta instância está disponível para você.
+this activity for this instance is actually only avaible for you.	workflow	pt-br	Esta atividade desta instância está disponível apenas para você.
+this activity for this instance is not specifically assigned to you.	workflow	pt-br	Esta atividade desta instância não está assinalada especificamento para você.
+this agent gives the activity the possibility to send an smtp message (mail)	workflow	pt-br	Este agente permite que esta atividade possa enviar uma mensagem SMTP (email)
+this form will test your local workflow installation to detect potential issues	workflow	pt-br	Este formulário irá testar a sua instalação local de workflow, para detectar problemas potenciais
+this is the first screen shown when you click on the workflow application icon	workflow	pt-br	Esta é a primeira tela a ser mostrada quando você clicar no ícone do módulo de workflow.
+sets the default sorting criteria for the inbox instances.	workflow	pt-br	Define o critério de ordenação padrão para as instâncias nas tarefas pendentes.
+determines the number of items per page in the user interface.	workflow	pt-br	Determina o número de itens por página na interface do usuário.
+this process has a view activity. access in view mode is granted only for this view activty.	workflow	pt-br	Este processo tem uma atividade view. O acesso em modo visualização é dado apenas para esta atividade view.
+this process has no end activity	workflow	pt-br	este processo não tem uma atividade end
+this will automatically release the instance when leaving an activity without completing	admin	pt-br	Isto irá automaticamente liberar a instância quando sair de uma atividade sem completá-la
+this will display an activity footer when any activity is runned with workflow engine related informations	admin	pt-br	isto irá mostrar um rodapé da atividade quando qualquer atividade for executada com informações relacionadas ao motor de workflow
+to	workflow	pt-br	Para
+to:	workflow	pt-br	Para:
+transition	workflow	pt-br	transição
+transition mode	workflow	pt-br	modo de transição
+transition to %1	workflow	pt-br	transição para %1
+transition waiting for human interaction	workflow	pt-br	transição aguardando interação humana
+transitions	workflow	pt-br	transições
+transitions removed successfully	workflow	pt-br	Transições removidas com sucesso
+type	workflow	pt-br	tipo
+type:	workflow	pt-br	tipo:
+unknow fix instruction :%1	workflow	pt-br	instrução de correção desconhecida :%1
+unknown instruction from the workflow engine: %1	workflow	pt-br	instrução desconhecida vinda do motor de workflow: %1
+unknown status	workflow	pt-br	estado desconhecido
+update	workflow	pt-br	atualizar
+upload file	workflow	pt-br	Carregar arquivo
+use <a href="%1">emailadmin</a> to create mail profiles	workflow	pt-br	Use <a href="%1">EmailAdmin</a> para criar profiles de correio
+use automatic parsing	common	pt-br	usar parsing automático
+use default	workflow	pt-br	Usar Padrão
+use existing roles	workflow	pt-br	Usar perfis existentes
+user	workflow	pt-br	Usuário
+user #%1 is associated with a non-existent role #%2	workflow	pt-br	Usuário #%1 está associado a um perfil inexistente #%2
+user activities	workflow	pt-br	Atividades do Usuário
+user instances	workflow	pt-br	Instâncias do Usuário
+user instances form: columns	workflow	pt-br	Formulário de Instâncias do Usuário: colunas
+user instances form: filters and actions	workflow	pt-br	Formulário de Instâncias do Usuário: filtros e ações
+user is not authorized to delete aborted instances	workflow	pt-br	usuário não autorizado a remover instâncias abortadas
+user is not authorized to delete instances	workflow	pt-br	usuário não autorizado a remover instâncias
+user processes	workflow	pt-br	Processos do Usuário
+user/group	workflow	pt-br	Usuário/Grupo
+user:	workflow	pt-br	usuário:
+users can act on activity before its execution with form and after by sending it to the next activity	workflow	pt-br	Usuários podem agir na atividade antes de sua execução, com um formulário, e depois enviando-a para a próxima atividade
+users/groups	workflow	pt-br	Usuários/Grupos
+valid	workflow	pt-br	Válido
+valid process	workflow	pt-br	Processos Válidos
+valid:	workflow	pt-br	válido:
+validity:	workflow	pt-br	Validade:
+value	workflow	pt-br	Valor
+version	workflow	pt-br	Versão
+view details	workflow	pt-br	visualizar detalhes
+view this instance	workflow	pt-br	Visualizar esta instância
+view workitem	workflow	pt-br	Visualizar Workitem
+View Options	workflow	pt-br	Opções de Visualização
+warning this filter override all others filters	workflow	pt-br	aviso: este filtro sobrescreve todos os outros filtros
+warning: by using this button you will definitively remove all aborted instances and their history (workitems) for the selected process.	workflow	pt-br	aviso: usando este botão, você irá remover definitivamente todas as instâncias abortadas E seus históricos (workitems), para os processos selecionados.
+warning: by using this button you will definitively remove all instances and their history (workitems) for the selected process, whatever the state they are.	workflow	pt-br	aviso: usando este botão, você irá remover definitivamente todas as instâncias E seus históricos (workitems), para os processos selecionados, em qualquer estado que estejam.
+we cannot run this activity, maybe this instance or this activity do not exists anymore.	workflow	pt-br	Não podemos executar esta atividade, talvez esta instância ou esta atividade não existam mais.
+we were not able to build the message	workflow	pt-br	Não somos capazes de construir a mensagem
+when in advanced mode, should we show you advanced actions by default (resume, exception, grab, etc.)?	workflow	pt-br	Quando estivermos em modo avançado, devemos mostrar-lhe ações avançadas por padrão (continuar, exceção, capturar, etc.)?
+when multiple submit options are avaible we draw a select box with only one submit instead of multiple buttons	admin	pt-br	quando múltiplas opções de submissão estiverem disponíveis, será mostrada uma caixa de seleção com uma submissão apenas, ao invés de múltiplos botões
+when to send the message:	workflow	pt-br	Quando enviar a Mensagem:
+workflow	common	pt-br	WorkFlow
+workflow configuration	admin	pt-br	Configuração do Workflow
+workflow navigation	workflow	pt-br	Navegação do Workflow
+workflow preferences	workflow	pt-br	Preferências do Workflow
+workflow site configuration	workflow	pt-br	Configuração do Site Workflow
+workitem information	workflow	pt-br	Informação de Workitem
+workitems	workflow	pt-br	Workitems
+you are not allowed to abort instance %1	workflow	pt-br	Você não tem permissão para abortar a instância %1
+you are not allowed to exception instance %1	workflow	pt-br	Você não tem permissão para colocar a intância %1 em exceção
+you are not allowed to grab instance %1	workflow	pt-br	Você não tem permissão para capturar a instância %1
+you are not allowed to release instance %1	workflow	pt-br	Você não tem permissão para liberar a instância %1
+you are not allowed to restart instance %1	workflow	pt-br	Você não tem permissão para reiniciar a instância %1
+you are not allowed to resume instance %1	workflow	pt-br	Você não tem permissão para retomar a instância %1
+you are not allowed to send instance %1	workflow	pt-br	Você não tem permissão para enviar a instância %1
+you can use special values with this mail agent:	workflow	pt-br	Você pode usar valores especiais com este agente de correio:
+you do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.	workflow	pt-br	Você não tem mais permissão para executar esta atividade, provavelmente um problema de acesso concorrente, atualize seus dados.
+you don't have the rights necessary to exception instance %1	workflow	pt-br	Você não tem direitos de acesso suficientes para colocar a instância %1 em exceção
+you have not permission to execute this activity	workflow	pt-br	Você não tem permissão para executar esta atividade
+you were not allowed to complete the activity	workflow	pt-br	Você não está autorizado a completar esta atividade
+no role was selected	workflow	pt-br	Nenhum perfil foi selecionado
+new	workflow	pt-br	Novo
+organization	common	pt-br	Organização
+sector	workflow	pt-br	Setor
+add participants	workflow	pt-br	Adicionar Participantes
+loading	workflow	pt-br	Carregando
+situation	workflow	pt-br	Situação
+assigned to	workflow	pt-br	Atribuído à
+user interface	workflow	pt-br	Interface do Usuário
+database options for processes	common	pt-br	Opções de Banco de Dados para Processos
+database options	common	pt-br	Opções de banco de dados
+database name	common	pt-br	Nome do banco de dados
+database host	common	pt-br	Servidor de banco de dados
+database port	common	pt-br	Porta de acesso
+database type	common	pt-br	Tipo do banco de dados
+database user	common	pt-br	Usuário
+database password	common	pt-br	Senha
+name of the database used to store data from workflow processes	admin	pt-br	Nome do banco de dados a ser usado para armazenar os dados dos processos
+database server where the database is stored	admin	pt-br	Servidor onde o banco de dados está armazenado
+port used to connect to database server	admin	pt-br	Porta usada para conectar ao servidor de banco de dados
+default user to access the database	admin	pt-br	Usuário padrão para acesso ao banco de dados
+password of the default user	admin	pt-br	Senha do usuário padrão
+type of the database	admin	pt-br	Tipo do banco de dados
+organization chart	workflow	pt-br	Organograma
+access control list	workflow	pt-br	Lista de Controle de Acesso
+execute activities in debug mode	workflow	pt-br	Executar atividade em modo de depuração
+there are no external applications	workflow	pt-br	Não existem aplicações externas
+inbox sorting	preferences	pt-br	Ordenação das tarefas pendentes
+number of items per page	preferences	pt-br	Número de itens por página
+warnings in this process	workflow	pt-br	Avisos neste processo
+disable advanced actions for all users	admin	pt-br	Desabilitar ações avançadas de todos os usuários
+disable advanced actions	common	pt-br	Desabilitar ações avançadas
+user of the ldap	admin	pt-br	Usuário do LDAP
+ldap user	common	pt-br	Usuário
+password of the ldap user	admin	pt-br	Senha do usuário do LDAP
+ldap password	common	pt-br	Senha
+menu path	common	pt-br	Caminho do menu
+mainframe options	common	pt-br	Opções de configuração do mainframe (PHP NatAPI)
+ip of the mainframe	common	pt-br	Endereço IP do mainframe
+mainframe ip	common	pt-br	Endereço IP
+port used to connect the mainframe	common	pt-br	Porta usada para conectar no ambiente mainframe
+access mainframe port	common	pt-br	Porta de acesso no Mainframe
+key used to access the mainframe	common	pt-br	Chave padrão para acessar o mainframe
+access mainframe key	common	pt-br	Chave
+password used to access the mainframe	common	pt-br	Senha relacionada a chave de acesso ao mainframe
+access mainframe password	common	pt-br	Senha
+environment application to mainframe	common	pt-br	Ambiente da aplicação
+mainframe environment	common	pt-br	Ambiente
+this instance doesn't exist in this activity. probably, this instance has already been executed	workflow	pt-br	Esta instância não existe nesta atividade. Provavelmente, esta instância já foi executada anteriormente
+external applications	workflow	pt-br	Aplicações Externas
+move instances	workflow	pt-br	Mover Instâncias
+show activity complete page	preferences	pt-br	Exibir página de atividade concluída
+Determines if the activity complete page should be displayed after the completion of the activity	preferences	pt-br	Determina se a página de atividade concluída deve ser exibida após a conclusão da atividade.
+External Applications options 	admin	pt-br	Opções das Aplicações Externas
+subnetworks of the intranet (separed by ;)	admin	pt-br	Subredes da intranet (separadas por ;)
+subnetworks 	admin	pt-br	Subredes
+name of the database used to store data of the workflow module	admin	pt-br	Nome do banco de dados que será utilizado para armazenar os dados do módulo Workflow
+user to access the database	admin	pt-br	Usuário para acesso ao banco de dados
+user password	admin	pt-br	Senha do usuário
+host of the ldap	admin	pt-br	Servidor do LDAP
+user context of the ldap	admin	pt-br	Contexto de usuários do LDAP
+ldap user context	admin	pt-br	Contexto de usuários
+group context of the ldap	admin	pt-br	Contexto de grupos do LDAP
+ldap group context	admin	pt-br	Contexto de grupos
+follow ldap referrals	admin	pt-br	Seguir as referências do LDAP
+follow referrals	admin	pr-br	Seguir as referências
+database options for workflow	common	pt-br	Opções de Banco de Dados para o Workflow
+ldap options	common	pt-br	Opções para LDAP
+use light interface	preferences	pt-br	Usar interface leve
+determines if a lighter version of the interface should be used	preferences	pt-br	Determina se uma interface mais leve deve ser usada.
+jobs	workflow	pt-br	Jobs
+upload	workflow	pt-br	Upload
+customize the process	workflow	pt-br	Personalizar o Processso
+process version	workflow	pt-br	Versão do Processo
+invalid name specified	workflow	pt-br	Nome inválido especificado
+invalid version specified	workflow	pt-br	Versão inválida especificada
+if left blank, the original value will be used	workflow	pt-br	Se deixado em branco, o valor original será usando
+the activities will be executed using secure connection	admin	pt-br	As atividades serão executadas utilizando conexão segura
+use secure connection	admin	pt-br	utilizar conexão segura
+execute activities using secure connection	workflow	pt-br	Executar atividades utilizando conexão segura
+the following file could not be found: %1	workflow	pt-br	O seguinte arquivo não pode ser encontrado: %1
+emergency	common	pt-br	Emergência
+alert	common	pt-br	Alerta
+critical	common	pt-br	Crítico
+error	common	pt-br	Erro
+warning	common	pt-br	Aviso
+notice	common	pt-br	Notificação
+information	common	pt-br	Informação
+debug	common	pt-br	Debug
+log options	common	pt-br	Opções de Log
+log level	common	pt-br	Nível de Log
+log options for workflow	common	pt-br	Opções de Log para o Workflow
+log level for workflow	common	pt-br	Nível de Log para o Workflow
+allowed log types for workflow	common	pt-br	Tipos de Log Permitidos para o Workflow
+log types	common	pt-br	Tipos de Log
+file	common	pt-br	Arquivo
+firebug	common	pt-br	Firebug
+select only one user	workflow	pt-br	Selecione apenas um Usuário
+select one process role	workflow	pt-br	Selecione um Perfil do Processo
+default role will be set only if it is mapped on the activity	workflow	pt-br	O Perfil Padrão será estabelecido somente se estiver mapeado à atividade
+without default user	workflow	pt-br	Sem usuário padrão
Index: /sandbox/workflow/branches/993/setup/phpgw_da.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_da.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_da.lang	(revision 795)
@@ -0,0 +1,99 @@
+#	workflow	da	Nr.
+%1 aborted	workflow	da	%1 afbrudt
+%1 active	workflow	da	%1 aktiv
+%1 completed	workflow	da	%1 færdig
+%1 configuration	workflow	da	%1 Konfiguration
+%1 days, %2:%3:%4	workflow	da	%1 dage, %2:%3:%4
+%1 exception	workflow	da	%1 undtagelse
+%1 menu	workflow	da	%1 Menu
+%1 monitoring	workflow	da	%1 Monitorering
+%1 processes (%2 active) (%3 being_run)	workflow	da	%1 proces (%2 aktiv) (%3 kørende)
+/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration	common	da	/workflow bibliotek eksisterer ikke og kan ikke dannes, bed administrator om at checke global konfiguration.
+abort instance	workflow	da	afbryd instans
+abort this instance	workflow	da	afbryd denne instans
+aborted	workflow	da	afbrudt
+access denied for user %1 on activity %2, no role	workflow	da	Adgang nægtet for bruger %1 på aktivitet %2, ingen rolle
+action %1 is impossible if we have no activity and no instance designated for it!	workflow	da	Handling %1 er umulig, hvis vi ikke har nogen aktivitet eller nogen instans tilegnet den!
+action %1 is impossible, another user is already in place	workflow	da	Handling %1 er umulig, en anden bruger er igang
+action %1 is impossible, there are no user assigned to this activity for this instance	workflow	da	handling %1 er umulig, der er ingen bruger tilegnet til denne aktivitet for denne instans
+action %1 needs an activity and activity %2 does not exists	workflow	da	Handling %1 behøver en aktivitet og aktivitet %2 eksisterer ikke
+action %1 needs an instance and instance %2 does not exists	workflow	da	handling %1 behøver en instans og instans %2 eksisterer ikke
+actions	workflow	da	Handlinger
+activate	workflow	da	Aktiver
+active	workflow	da	Aktiv
+active:	workflow	da	aktiv:
+activities	workflow	da	Aktiviteter
+activities selection	workflow	da	Vælg aktiviteter
+activities updated	workflow	da	Opdater aktiviteter
+activity	workflow	da	aktivitet
+activity  status	workflow	da	Aktivitets status
+activity %1	workflow	da	aktivitet %1
+activity %1 (#%2) is associated with a non-existent process (#%3)	workflow	da	Aktivitet %1 (#%2) er tilknyttet en ikke-eksisterende proces(#%3)
+activity %1 code is not avaible	workflow	da	aktivitet %1 kode er tilgængelig
+activity %1 is interactive but has no role assigned	workflow	da	Aktivitet %1 er interaktiv, men er ikke tilføjet nogen rolle
+activity %1 is interactive so it must use the $instance->complete() method	workflow	da	Aktivitet %1 er interaktiv, så den må benytte $instance->complete() metoden
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	da	Aktivitet %1 er ikke interaktiv og ikke-autorutet, men ikke tilføjet nogen rolle
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	da	Aktivitet %1 er ikke interaktive, så den må benytte $instance->complete() metoden
+activity %1 is standalone and is using the $instance object	workflow	da	Aktivitet %1 er stand-alone og benytter $instance objektet
+activity %1 is standalone but has transitions	workflow	da	Aktivitet %1 er stand-alone , men har ingen overgange
+activity %1 is standalone or view but has transitions	workflow	da	Aktivitet %1 er stand-alone eller view, men har ingen overgange
+activity saved	workflow	da	Aktivitet gemt
+activity start not avaible, no corresponding activity was found.	workflow	da	Aktivitet's start ikke tilgængelig, ingen korrosponderende aktivitet fundet.
+activity start not set, no corresponding activity was found.	workflow	da	Aktivitet's start ikke sat, ingen korrosponderende aktivitet fundet.
+activity status not avaible, no corresponding activity was found.	workflow	da	Aktivitet's status ikke tilgængelig, ingen korrosponderende aktivitet fundet.
+activity:	workflow	da	aktivitet:
+add a transition	workflow	da	Tilføj en overgang
+add aborted instances	workflow	da	Tilføj afbrudte instanser
+add advanced actions	workflow	da	Tilføj avancerede handlinger
+add agent	workflow	da	Tilføj agenter
+add completed instances	workflow	da	Tilføj færdige instanser
+add instances in exception	workflow	da	Tilføj untagelses instanser
+add new	workflow	da	Tilføj ny
+add new role	workflow	da	Tilføj ny rolle
+add or edit a process	workflow	da	Tilføj eller rediger proces
+add or edit a role	workflow	da	Tilføj eller rediger en rolle
+add or edit an activity	workflow	da	Tilføj eller rediger en aktivitet
+add property	workflow	da	Tilføj egenskab
+add role	workflow	da	Tilføj rolle
+add role to process	workflow	da	Tilføj rolle til proces
+add transition	workflow	da	Tilføj overgang
+add transitions	workflow	da	Tilføj overgange
+add transitions from	workflow	da	Tilføj overgange fra
+add transitions to	workflow	da	Tilføj overgange til
+admin instance	workflow	da	Admin Instans
+admin process activities	workflow	da	Admin proces aktiviteter
+admin process roles	workflow	da	Admin proces roller
+admin processes	workflow	da	Admin processer
+admin processes sources	workflow	da	Admin kilde processer
+administer instances	admin	da	Administrer instanser
+administer processes	admin	da	Administrrer processer
+agent associated with inexistent activity	workflow	da	Agent tilknyttet til ikke-eksiterende aktivitet
+agent without activity	workflow	da	Agent uden aktivitet
+agents assigned to this activity	workflow	da	Agenter tilføjet  til denne aktivitet
+all	workflow	da	Alle
+always show advanced actions	workflow	da	Vis altid avancerede handlinger
+always show advanced mode	workflow	da	Vis altid avanceret 'mode'
+assign me this activity	workflow	da	Tilknyt mig denne aktivitet
+at least one email address cannot be validated.	workflow	da	Mindst en E-mail kan ikke valideres
+auto routed	workflow	da	Automatisk routet
+auto-release on leaving activity	common	da	Frigør automatisk  ved udagnag af aktivitet
+automatic	workflow	da	Automatisk
+autorouted activities does not need to be sent by any user after their execution	workflow	da	Auto-routede aktivitet behøver ikke at blive sendt a nogen bruger efter den er eksekveret
+bad parameter for setagents, the parameter should be an array	workflow	da	Forkert parameter for 'setAgents', parameter skal være et array
+bad role type	workflow	da	Forkert rolle type
+bad user	workflow	da	Forkert bruger
+base directory does not exist, please ask adminstrator to check the global configuration	common	da	Basis biblioteket eksisterer ikke, bed administrator om at checke global konfiguration
+be carefull with interactive activity, end and start of theses activities are multiple.	workflow	da	Vær forsigtig med interakiv aktivitet, slut og start af disse aktiviteter er multiple.
+being run	workflow	da	kørende
+by running theses links you will create new instances of the related process.	workflow	da	ved at køre disse links skaber du nye instanser af den relaterede proces.
+cannot add transition only split or switch activities can have more than one outbound transition	workflow	da	Kan ikke tilføje overgang - kun split og skiftende aktiviteter kan have mere end en udgående overgang
+cannot add transition. only split activities can have more than one outbound transition	workflow	da	Kan ikke tilføje overgang. Kun split og skiftende aktiviteter kan have mere end en udgående overgang
+cannot create compiled file %1	workflow	da	kan ikke danne compileret fil %1
+you are not allowed to abort instance %1	workflow	da	Du har ikke ret til at afbryde instans %1
+you are not allowed to exception instance %1	workflow	da	Du har ikke ret til at undtage instans %1
+you are not allowed to grab instance %1	workflow	da	Du har ikke ret til at  tage instans %1
+you are not allowed to release instance %1	workflow	da	Du har ikke ret til at frigøre instans %1
+you are not allowed to restart instance %1	workflow	da	Du har ikke ret til at  genstarte instans %1
+you are not allowed to resume instance %1	workflow	da	Du har ikke ret til at  gen-optage instans %1
+you are not allowed to send instance %1	workflow	da	Du har ikke ret til at  sende instans %1
+you can use special values with this mail agent:	workflow	da	Du kan bruge specielle værdier med denne mail agent:
Index: /sandbox/workflow/branches/993/setup/tables_current.inc.php
===================================================================
--- /sandbox/workflow/branches/993/setup/tables_current.inc.php	(revision 1229)
+++ /sandbox/workflow/branches/993/setup/tables_current.inc.php	(revision 1229)
@@ -0,0 +1,280 @@
+<?php
+  /**************************************************************************\
+  * E-GroupWare - Setup                                                      *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$phpgw_baseline = array(
+		'egw_wf_activities' => array(
+			'fd' => array(
+				'wf_activity_id'	=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_name'		=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+				'wf_normalized_name'	=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+				'wf_p_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_type'		=> array('type' => 'varchar', 'precision' => '25', 'nullable' => True),
+				'wf_is_autorouted'	=> array('type' => 'char', 'precision' => '1', 'nullable' => True),
+				'wf_flow_num'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_is_interactive'	=> array('type' => 'char', 'precision' => '1', 'nullable' => True),
+				'wf_last_modif'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_description'	=> array('type' => 'text', 'nullable' => True),
+				'wf_default_user'	=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True, 'default'=> '*'),
+				'wf_menu_path'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+			),
+			'pk' => array('wf_activity_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_activity_roles' => array(
+			'fd' => array(
+				'wf_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_role_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_readonly'		=> array('type' => 'int', 'precision' => '1', 'nullable' => False, 'default'=> 0),
+			),
+			'pk' => array('wf_activity_id', 'wf_role_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_instance_activities' => array(
+			'fd' => array(
+				'wf_instance_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_started'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_ended'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_user'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+				'wf_status'		=> array('type' => 'varchar', 'precision' => '25', 'nullable' => True),
+			),
+			'pk' => array('wf_instance_id', 'wf_activity_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_activity_id'),array('wf_instance_id'), array('wf_user')),
+			'uc' => array()
+		),
+		'egw_wf_instances' => array(
+			'fd' => array(
+				'wf_instance_id'	=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_p_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_started'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_owner'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+				'wf_next_activity'	=> array('type' => 'blob', 'nullable' => True),
+				'wf_next_user'		=> array('type' => 'text', 'nullable' => True),
+				'wf_ended'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_status'		=> array('type' => 'varchar', 'precision' => '25', 'nullable' => True),
+				'wf_priority'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default'=> 0),
+				'wf_properties'		=> array('type' => 'blob', 'nullable' => True),
+				'wf_name'		=> array('type' => 'varchar', 'precision'=>'120', 'nullable' => True),
+				'wf_category'		=> array('type' => 'int', 'precision'=>'4', 'nullable' => True),
+			),
+			'pk' => array('wf_instance_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_owner'), array('wf_status'), array('wf_p_id')),
+			'uc' => array()
+		),
+		'egw_wf_processes' => array(
+			'fd' => array(
+				'wf_p_id'		=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_name'		=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+				'wf_is_valid'		=> array('type' => 'char', 'precision' => '1', 'nullable' => True),
+				'wf_is_active'		=> array('type' => 'char', 'precision' => '1', 'nullable' => True),
+				'wf_version'		=> array('type' => 'varchar', 'precision' => '12', 'nullable' => True),
+				'wf_description'	=> array('type' => 'text', 'nullable' => True),
+				'wf_last_modif'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_normalized_name'	=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+			),
+			'pk' => array('wf_p_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_p_id','wf_is_active')),
+			'uc' => array()
+		),
+		'egw_wf_roles' => array(
+			'fd' => array(
+				'wf_role_id'		=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_p_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_last_modif'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_name'		=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+				'wf_description'	=> array('type' => 'text', 'nullable' => True),
+			),
+			'pk' => array('wf_role_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_transitions' => array(
+			'fd' => array(
+				'wf_p_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_act_from_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_act_to_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+			),
+			'pk' => array('wf_act_from_id', 'wf_act_to_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_user_roles' => array(
+			'fd' => array(
+				'wf_role_id'		=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_p_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_user'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => False),
+				'wf_account_type'	=> array('type' => 'char', 'precision' => '1', 'nullable' => True, 'default' => 'u'),
+			),
+			'pk' => array('wf_role_id', 'wf_user', 'wf_account_type'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_workitems' => array(
+			'fd' => array(
+				'wf_item_id'		=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_instance_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_order_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_properties'		=> array('type' => 'blob', 'nullable' => True),
+				'wf_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_started'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_ended'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_user'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+				'wf_note'		=> array('type' => 'text', 'nullable' => True),
+				'wf_action'		=> array('type' => 'text', 'nullable' => True),
+			),
+			'pk' => array('wf_item_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_instance_id')),
+			'uc' => array()
+		),
+		'egw_wf_activity_agents' => array( 
+			'fd' => array(
+				'wf_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_agent_id' 		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_agent_type'		=> array('type' => 'varchar', 'precision' => '15', 'nullable' => False),
+			),
+			'pk' => array('wf_activity_id', 'wf_agent_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_agent_mail_smtp' => array( 
+			'fd' => array(
+				'wf_agent_id'	=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_to' 		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => False, 'default' => '%roles%'),
+				'wf_cc'			=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True),
+				'wf_bcc'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True),
+				'wf_from'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True, 'default' => '%user%'),
+				'wf_replyTo'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True, 'default' => '%user%'),
+				'wf_subject'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True),
+				'wf_message'		=> array('type' => 'text', 'nullable' => True),
+				'wf_send_mode'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0),
+			),
+			'pk' => array('wf_agent_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'egw_wf_process_config' => array(
+			'fd' => array(
+				'wf_p_id'               => array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_config_name' 	=> array('type' => 'varchar', 'precision' => '255', 'nullable' => False),
+				'wf_config_value'	=> array('type' => 'text', 'nullable' => True),
+				'wf_config_value_int'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+			),
+			'pk' => array('wf_p_id','wf_config_name'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+			),
+		'egw_wf_interinstance_relations' => array(
+				'fd' => array(
+					'wf_parent_instance_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_parent_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_child_instance_id' 	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_parent_lock' 		=> array('type' => 'int', 'precision' => '2', 'nullable' => True)
+				),
+				'pk' => array('wf_parent_instance_id', 'wf_parent_activity_id', 'wf_child_instance_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			),
+		'egw_wf_admin_access' => array(
+				'fd' => array(
+					'admin_access_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'tipo'	=> array('type' => 'char', 'precision' => '3', 'nullable' => False),
+					'numvalue'	=> array('type' => 'int', 'precision' => '2', 'nullable' => False),
+					'nivel'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0)
+				),
+				'pk' => array('admin_access_id', 'tipo', 'numvalue'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			),
+		'egw_wf_external_application' => array(
+				'fd' => array(
+					'external_application_id' => array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+					'name' => array('type' => 'varchar', 'precision' => '50', 'nullable' => False),
+					'description' => array('type' => 'text', 'nullable' => True),
+					'image' => array('type' => 'varchar', 'precision' => '100', 'nullable' => True),
+					'address' => array('type' => 'varchar', 'precision' => '120', 'nullable' => False),
+					'authentication' => array('type' => 'bit', 'precision' => '1', 'nullable' => True),
+					'post' => array('type' => 'text', 'nullable' => True),
+					'intranet_only' => array('type' => 'bit', 'precision' => '1', 'nullable' => True)
+				),
+				'pk' => array('external_application_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			),
+		'egw_wf_user_cache' => array(
+				'fd' => array(
+					'uidnumber'			=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'uid'				=> array('type' => 'varchar', 'precision' => '30', 'nullable' => True),
+					'cn'				=> array('type' => 'varchar', 'precision' => '100', 'nullable' => True),
+					'givenname'			=> array('type' => 'varchar', 'precision' => '30', 'nullable' => True),
+					'sn'				=> array('type' => 'varchar', 'precision' => '70', 'nullable' => True),
+					'mail'				=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+					'accountstatus'		=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+					'dn'				=> array('type' => 'varchar', 'precision' => '150', 'nullable' => True),
+					'employeenumber'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'cpf'				=> array('type' => 'varchar', 'precision' => '15', 'nullable' => True),
+					'telephonenumber'	=> array('type' => 'varchar', 'precision' => '50', 'nullable' => True),
+					'last_update'		=> array('type' => 'timestamp without time zone default now()', 'nullable' => True)
+				),
+				'pk' => array('uidnumber'),
+				'fk' => array(),
+				'ix' => array('mail', 'employeenumber', 'cpf'),
+				'uc' => array()
+			),
+		'egw_wf_jobs' => array(
+				'fd' => array(
+					'job_id'			=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+					'wf_process_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'name'				=> array('type' => 'varchar', 'precision' => '100', 'nullable' => False),
+					'description'		=> array('type' => 'text', 'nullable' => True),
+					'time_start'		=> array('type' => 'timestamp without time zone', 'nullable' => False),
+					'interval_value'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'interval_unity'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'date_type'			=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'week_days'			=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0),
+					'month_offset'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0),
+					'active'			=> array('type' => 'bool', 'nullable' => True)
+				),
+				'pk' => array('job_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			),
+		'egw_wf_job_logs' => array(
+				'fd' => array(
+					'job_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'date_time'		=> array('type' => 'timestamp without time zone', 'nullable' => False),
+					'result'		=> array('type' => 'blob', 'nullable' => True),
+					'status'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True)
+				),
+				'pk' => array('job_id', 'date_time'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+	);
Index: /sandbox/workflow/branches/993/setup/tables_update.inc.php
===================================================================
--- /sandbox/workflow/branches/993/setup/tables_update.inc.php	(revision 2042)
+++ /sandbox/workflow/branches/993/setup/tables_update.inc.php	(revision 2042)
@@ -0,0 +1,1268 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - Setup                                                       *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+	function extractDatabaseParameters()
+	{
+		/* extract the database connection parameters */
+
+		$workflowHostInfo = array();
+		if (!empty($GLOBALS['phpgw']->ADOdb->database))
+		{
+			$workflowHostInfo = array(
+				'dbname' => $GLOBALS['phpgw']->ADOdb->database,
+				'host' => $GLOBALS['phpgw']->ADOdb->host,
+				'port' => $GLOBALS['phpgw']->ADOdb->port,
+				'user' => $GLOBALS['phpgw']->ADOdb->user,
+				'password' => $GLOBALS['phpgw']->ADOdb->password);
+		}
+		else
+		{
+			$hostInfo = "dbname= host= password= port= user= " . $GLOBALS['phpgw']->ADOdb->host;
+			$hostInfo = explode(' ', $hostInfo);
+			foreach ($hostInfo as $parameter)
+			{
+				$currentParameter = explode('=', $parameter);
+				$workflowHostInfo[$currentParameter[0]] = isset($currentParameter[1]) ? $currentParameter[1] : "";
+			}
+		}
+		if (($workflowHostInfo['password']{0} == "'") && ($workflowHostInfo['password']{strlen($workflowHostInfo['password'])-1} == "'"))
+			$workflowHostInfo['password'] = substr($workflowHostInfo['password'], 1, strlen($workflowHostInfo['password']) - 2);
+
+		return $workflowHostInfo;
+	}
+
+	$test[] = '1.0.1';
+	function workflow_upgrade1_0_1()
+	{
+		# add an instance_supplements table
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_instance_supplements',
+			array(
+				'fd' => array(
+					'wf_supplement_id' 	=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+					'wf_supplement_type'	=> array('type' => 'varchar', 'precision' => '50', 'nullable' => True),
+					'wf_supplement_name'	=> array('type' => 'varchar', 'precision' => '100', 'nullable' => True),
+					'wf_supplement_value'	=> array('type' => 'text', 'nullable' => True),
+					'wf_workitem_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'wf_supplement_blob'	=> array('type' => 'blob', 'nullable' => True)
+				),
+				'pk' => array('wf_supplement_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		#Add in activities table is_reassign_box, is_report, default_user and default group
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activities' ,'wf_is_reassign_box',array('type' => 'char', 'precision' => 1, 'nullable' => True));
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activities' ,'wf_is_report',array('type' => 'char', 'precision' => 1, 'nullable' => True));
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activities' ,'wf_default_user', array('type' => 'varchar', 'precision' => '200', 'nullable' => True, 'default' => '*'));
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activities' ,'wf_default_group', array('type' => 'varchar', 'precision' => '200', 'nullable' => True, 'default' => '*'));
+
+		#Add in instance_activities table the group field
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_instance_activities' ,'wf_group',array('type' => 'varchar', 'precision' => 200, 'nullable' => True, 'default' => '*'));
+
+		#Add in instance table the name, and the priority, we keep the properties for the moment
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_instances' ,'wf_priority',array('type' => 'int', 'precision' => 4, 'nullable' => True));
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_instances' ,'wf_name',array('type' => 'varchar', 'precision' => 120, 'nullable' => True));
+
+		#Add in workitems table note and action
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_workitems' ,'wf_note',array('type' => 'text', 'precision' => 50, 'nullable' => True));
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_workitems' ,'wf_action',array('type' => 'text', 'precision' => 50, 'nullable' => True));
+
+		#Add in user_roles table the account type
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_user_roles' ,'wf_account_type',array('type' => 'char', 'precision' => 1, 'nullable' => True, 'default' => 'u'));
+			#modifying the sequence as well
+			#we need a RefreshTable
+		$GLOBALS['phpgw_setup']->oProc->RefreshTable('egw_wf_user_roles' ,array(
+		 	'fd' => array(
+				'wf_role_id'            => array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_p_id'               => array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_user'               => array('type' => 'varchar', 'precision' => '200', 'nullable' => False),
+				'wf_account_type'       => array('type' => 'char', 'precision' => '1', 'nullable' => True, 'default' => 'u'),
+			 ),
+			 'pk' => array('wf_role_id', 'wf_user', 'wf_account_type'),
+			 'fk' => array(),
+			 'ix' => array(),
+			 'uc' => array()
+		));
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.1.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.1.00.000';
+	function workflow_upgrade1_1_00_000()
+	{
+		# add a process_config table
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_process_config',
+			array(
+				'fd' => array(
+					'wf_p_id'               => array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_config_name' 	=> array('type' => 'varchar', 'precision' => '255', 'nullable' => False),
+					'wf_config_value'	=> array('type' => 'text', 'nullable' => True),
+					'wf_config_value_int'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				),
+				'pk' => array('wf_p_id','wf_config_name'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		//change de default value for priority
+
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.1.01.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.1.01.000';
+	function workflow_upgrade1_1_01_000()
+	{
+		#remove unused 'new' fields in activity and add a agent key
+ 		$GLOBALS['phpgw_setup']->oProc->DropColumn('egw_wf_activities', '', 'wf_is_reassign_box');
+ 		$GLOBALS['phpgw_setup']->oProc->DropColumn('egw_wf_activities', '', 'wf_is_report');
+ 		$GLOBALS['phpgw_setup']->oProc->DropColumn('egw_wf_activities', '', 'wf_default_group');
+ 		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activities' ,'wf_agent', array('type' => 'int', 'precision' => '4', 'nullable' => True));
+
+		#add a readonly attribute to role/activty mapping
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activity_roles' ,'wf_readonly', array('type' => 'int', 'precision' => '1', 'nullable' => False, 'default'=> 0));
+
+		#add a instance category attribute
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_instances' ,'wf_category', array('type' => 'int', 'precision'=>'4', 'nullable' => True));
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.1.02.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+
+	$test[] = '1.1.02.000';
+	function workflow_upgrade1_1_02_000()
+	{
+ 		//drop the agent key in activity, we need something more complex in fact
+ 		$GLOBALS['phpgw_setup']->oProc->DropColumn('egw_wf_activities','','wf_agent');
+
+		//add the agent table, link between activities and agents
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_activity_agents',
+			array(
+				'fd' => array(
+					'wf_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_agent_id' 		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_agent_type'		=> array('type' => 'varchar', 'precision' => '15', 'nullable' => False),
+				),
+				'pk' => array('wf_activity_id', 'wf_agent_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		// add the mail_smtp agent table
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_agent_mail_smtp',
+			array(
+				'fd' => array(
+					'wf_agent_id'		=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+					'wf_to' 		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => False, 'default' => '%roles%'),
+					'wf_cc'			=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True),
+					'wf_bcc'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True),
+					'wf_from'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True, 'default' => '%user%'),
+					'wf_replyTo'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True, 'default' => '%user%'),
+					'wf_subject'		=> array('type' => 'varchar', 'precision' => '255', 'nullable' => True),
+					'wf_message'		=> array('type' => 'text', 'nullable' => True),
+					'wf_send_mode'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0),
+				),
+				'pk' => array('wf_agent_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.1.03.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.1.03.000';
+	function workflow_upgrade1_1_03_000()
+	{
+		//change type of wf_next_user to handle serialization -> multiple states if instance has multiple activities running
+		//we will loose current wf_next_activity but the update should'nt be made when instances are running and this is
+		//a field needed only at runtime, normally.
+		$GLOBALS['phpgw_setup']->oProc->DropColumn('egw_wf_instances','','wf_next_activity');
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_instances' ,'wf_next_activity', array('type' => 'blob', 'nullable' => True));
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.1.04.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.1.04.000';
+	function workflow_upgrade1_1_04_000()
+	{
+		//unused column. Notice I had to do this manually with MAIN versions of phpgwapi/class.schema_proc.inc.php
+		$GLOBALS['phpgw_setup']->oProc->DropColumn('egw_wf_instance_activities','','wf_group');
+
+		//Adding some indexes on some tables:
+
+		//we need a RefreshTable for that
+		$GLOBALS['phpgw_setup']->oProc->RefreshTable('egw_wf_instance_activities' ,array(
+			'fd' => array(
+				'wf_instance_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_started'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_ended'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_user'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+				'wf_status'		=> array('type' => 'varchar', 'precision' => '25', 'nullable' => True),
+			),
+			'pk' => array('wf_instance_id', 'wf_activity_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_activity_id'),array('wf_instance_id'), array('wf_user')),
+			'uc' => array()
+		));
+		// we change some indexes
+		// we need a RefreshTable
+		$GLOBALS['phpgw_setup']->oProc->RefreshTable('egw_wf_instances' ,array(
+			'fd' => array(
+				'wf_instance_id'	=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_p_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+				'wf_started'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_owner'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+				'wf_next_activity'	=> array('type' => 'blob', 'nullable' => True),
+				'wf_next_user'		=> array('type' => 'varchar', 'precision' => '200', 'nullable' => True),
+				'wf_ended'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_status'		=> array('type' => 'varchar', 'precision' => '25', 'nullable' => True),
+				'wf_priority'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default'=> 0),
+				'wf_properties'		=> array('type' => 'blob', 'nullable' => True),
+				'wf_name'		=> array('type' => 'varchar', 'precision'=>'120', 'nullable' => True),
+				'wf_category'		=> array('type' => 'int', 'precision'=>'4', 'nullable' => True),
+			),
+			'pk' => array('wf_instance_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_owner'), array('wf_status')),
+			'uc' => array()
+		));
+		// we change some indexes
+		// we need a RefreshTable
+		$GLOBALS['phpgw_setup']->oProc->RefreshTable('egw_wf_processes' ,array(
+			'fd' => array(
+				'wf_p_id'		=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+				'wf_name'		=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+				'wf_is_valid'		=> array('type' => 'char', 'precision' => '1', 'nullable' => True),
+				'wf_is_active'		=> array('type' => 'char', 'precision' => '1', 'nullable' => True),
+				'wf_version'		=> array('type' => 'varchar', 'precision' => '12', 'nullable' => True),
+				'wf_description'	=> array('type' => 'text', 'nullable' => True),
+				'wf_last_modif'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+				'wf_normalized_name'	=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+			),
+			'pk' => array('wf_p_id'),
+			'fk' => array(),
+			'ix' => array(array('wf_p_id','wf_is_active')),
+			'uc' => array()
+		));
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.1.05.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.1.05.000';
+	function workflow_upgrade1_1_05_000()
+	{
+		#serialized data is now stored with a Base64 encoding to ensure it work in all case (even with \' for example)
+		//We gonna make our updates manually here:
+		//they were an error (quotes) in the first version of this upgrade, if your database is MySQL you should
+		//set the version to 1.1.05.000 in egw_applications and rerun this upgrade for old properties
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$GLOBALS['phpgw']->ADOdb->SetFetchMode(ADODB_FETCH_ASSOC);
+			$result = $GLOBALS['phpgw']->ADOdb->query('select * from egw_wf_instances');
+			if (!(empty($result)))
+			{
+				while ($res = $result->fetchRow())
+				{
+					$new_props = base64_encode($res['wf_properties']);
+					$new_next = base64_encode($res['wf_next_activity']);
+					$ok =  $GLOBALS['phpgw']->ADOdb->query(
+						'update egw_wf_instances set wf_properties = ?, wf_next_activity=? where wf_instance_id = ?',
+						array($new_props,$new_next, (int)$res['wf_instance_id'])
+					);
+				}
+			}
+			$result = $GLOBALS['phpgw']->ADOdb->query('select * from egw_wf_workitems');
+			if (!(empty($result)))
+			{
+				while ($res = $result->fetchRow())
+				{
+					$new_props = base64_encode($res['wf_properties']);
+					$ok =  $GLOBALS['phpgw']->ADOdb->query(
+						'update egw_wf_workitems set wf_properties = ?  where wf_item_id = ?',
+						array($new_props, (int)$res['wf_item_id'])
+					);
+				}
+			}
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.2.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.2.00.000';
+	function workflow_upgrade1_2_00_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.2.00.001';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+	$test[] = '1.2.00.001';
+	function workflow_upgrade1_2_00_001()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.2.00.002';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+	$test[] = '1.2.00.002';
+	function workflow_upgrade1_2_00_002()
+	{
+		#groups Ids are now negative in egroupware, we need to negative all user id which is positive and of type 'g'
+		#code inspired by phpgwapi/setup/table_update.inc.php
+		// convert all positive group id's to negative ones
+		// this allows duplicate id for users and groups in ldap
+
+		/* Celepar: não realizar esta atualização
+		$where = false;
+		list($table,$col,$where) = $data;
+		$table = 'egw_wf_user_roles';
+		$col = 'wf_user';
+		$where = "wf_account_type='g' and (SUBSTR($col,1,1) <> '-')";
+		$set = $col.'='.$GLOBALS['egw_setup']->db->concat("'-'",$col);
+		$query = "UPDATE $table SET $set WHERE $where";
+		//echo "<p>debug query: $query</p>\n";
+		$GLOBALS['egw_setup']->db->query($query,__LINE__,__FILE__);
+
+		*/
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.2.01.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.2.01.000';
+        function workflow_upgrade1_2_01_000()
+        {
+                #updating the current version
+                $GLOBALS['setup_info']['workflow']['currentver'] = '1.2.01.001';
+                return $GLOBALS['setup_info']['workflow']['currentver'];
+        }
+
+        $test[] = '1.2.01.001';
+        function workflow_upgrade1_2_01_001()
+        {
+                #updating the current version
+                $GLOBALS['setup_info']['workflow']['currentver'] = '1.2.01.002';
+                return $GLOBALS['setup_info']['workflow']['currentver'];
+        }
+
+        $test[] = '1.2.01.002';
+        function workflow_upgrade1_2_01_002()
+        {
+                #updating the current version
+                $GLOBALS['setup_info']['workflow']['currentver'] = '1.2.01.003';
+                return $GLOBALS['setup_info']['workflow']['currentver'];
+        }
+
+	$test[] = '1.2.01.003';
+	function workflow_upgrade1_2_01_003()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.2.01.004';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.2.01.004';
+	function workflow_upgrade1_2_01_004()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.2.01.005';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.2.01.005';
+	function workflow_upgrade1_2_01_005()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* create the workflow database */
+			$GLOBALS['phpgw']->ADOdb->query("CREATE DATABASE workflow WITH OWNER = postgres TEMPLATE = template0 ENCODING = 'LATIN1'");
+			$GLOBALS['phpgw']->ADOdb->query("CREATE USER admin_workflow WITH PASSWORD 'admin_workflow' NOCREATEDB NOCREATEUSER VALID UNTIL 'infinity'");
+			$GLOBALS['phpgw']->ADOdb->query("CREATE GROUP workflow");
+			$GLOBALS['phpgw']->ADOdb->query("ALTER GROUP workflow ADD USER admin_workflow");
+			$GLOBALS['phpgw']->ADOdb->query("GRANT workflow TO admin_workflow");
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* create a sample application (Music CD Loan) */
+				$workflowDB->query("CREATE USER admin_cds WITH PASSWORD 'admin_cds' NOCREATEDB NOCREATEUSER VALID UNTIL 'infinity'");
+				$workflowDB->query("ALTER GROUP workflow ADD USER admin_cds");
+				$workflowDB->query("CREATE SCHEMA cds AUTHORIZATION admin_cds");
+				$workflowDB->query("GRANT ALL ON SCHEMA cds TO admin_cds");
+				$workflowDB->query("GRANT ALL ON SCHEMA cds TO postgres");
+				$workflowDB->query("CREATE TABLE cds.cdcollection(cdid int4 NOT NULL, title varchar(200), status varchar(40), usuario varchar(200), CONSTRAINT cdcollection_pkey PRIMARY KEY (cdid))");
+				$workflowDB->query("ALTER TABLE cds.cdcollection OWNER TO admin_cds");
+				$workflowDB->query("GRANT ALL ON TABLE cds.cdcollection TO postgres WITH GRANT OPTION");
+				$workflowDB->query("GRANT ALL ON TABLE cds.cdcollection TO admin_cds");
+				$workflowDB->query("COMMENT ON TABLE cds.cdcollection IS 'Exemplo de Empréstimo de CDs'");
+				$workflowDB->query("INSERT INTO cdcollection VALUES (1, 'Iron Maiden - Powerslave', 'disponivel', '')");
+				$workflowDB->query("INSERT INTO cdcollection VALUES (2, 'Pink Floyd - The Wall', 'disponivel', '')");
+				$workflowDB->query("INSERT INTO cdcollection VALUES (3, 'Deep Purple - Fireball', 'disponivel', '')");
+
+				/* create the new tables */
+				$workflowDB->query('CREATE TABLE organizacao (organizacao_id serial NOT NULL, nome character varying(20) NOT NULL, descricao character varying(100) NOT NULL)');
+				$workflowDB->query('CREATE TABLE area_status (area_status_id serial NOT NULL, organizacao_id integer NOT NULL, descricao character varying(50) NOT NULL, nivel integer NOT NULL)');
+				$workflowDB->query('CREATE TABLE centro_custo (organizacao_id integer NOT NULL, centro_custo_id serial NOT NULL, nm_centro_custo integer NOT NULL, grupo character varying(30), descricao character varying(100) NOT NULL)');
+				$workflowDB->query('CREATE TABLE localidade (organizacao_id integer NOT NULL, localidade_id serial NOT NULL, centro_custo_id integer, descricao character varying(50) NOT NULL)');
+				$workflowDB->query('CREATE TABLE funcionario (funcionario_id character varying NOT NULL, area_id integer NOT NULL, localidade_id integer NOT NULL, centro_custo_id integer NOT NULL, organizacao_id integer NOT NULL, funcionario_status_id integer NOT NULL)');
+				$workflowDB->query('CREATE TABLE area (organizacao_id integer NOT NULL, area_id serial NOT NULL, area_status_id integer NOT NULL, areasup_organizacao_id integer, superior_area_id integer, centro_custo_id integer, titular_funcionario_id character varying, substituto_funcionario_id character varying, sigla character varying(20) NOT NULL, descricao character varying(100) NOT NULL, ativa character varying(1) NOT NULL)');
+				$workflowDB->query('CREATE TABLE funcionario_status (funcionario_status_id serial NOT NULL, descricao character varying(50) NOT NULL)');
+				$workflowDB->query('CREATE TABLE admin_access (admin_access_id integer NOT NULL, tipo character(3) NOT NULL, numvalue smallint NOT NULL, nivel integer DEFAULT 0)');
+				$workflowDB->query('CREATE TABLE aplicacao_externa (apl_in_id serial NOT NULL, apl_st_nome character varying(50) NOT NULL, apl_st_descricao text, apl_st_imagem character varying(100), apl_st_endereco character varying(120) NOT NULL, apl_bt_autentica bit(1), apl_st_post text, apl_in_responsavel integer NOT NULL, apl_in_area integer NOT NULL)');
+				$workflowDB->query('CREATE TABLE aplicacao_externa_acl (apl_in_id integer NOT NULL, apl_in_uid integer NOT NULL)');
+
+				/* add the constraints */
+				$workflowDB->query('ALTER TABLE ONLY organizacao ADD CONSTRAINT organizacao_pkey PRIMARY KEY (organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY area_status ADD CONSTRAINT areastatus_pkey PRIMARY KEY (area_status_id, organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY centro_custo ADD CONSTRAINT centrocusto_pkey PRIMARY KEY (organizacao_id, centro_custo_id)');
+				$workflowDB->query('ALTER TABLE ONLY localidade ADD CONSTRAINT localidade_pkey PRIMARY KEY (organizacao_id, localidade_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT funcionario_pkey PRIMARY KEY (funcionario_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT area_pkey PRIMARY KEY (area_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario_status ADD CONSTRAINT funcionario_status_pkey PRIMARY KEY (funcionario_status_id)');
+				$workflowDB->query('ALTER TABLE ONLY area_status ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY centro_custo ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY localidade ADD CONSTRAINT "$1" FOREIGN KEY (centro_custo_id, organizacao_id) REFERENCES centro_custo(centro_custo_id, organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY localidade ADD CONSTRAINT "$2" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id, centro_custo_id) REFERENCES centro_custo(organizacao_id, centro_custo_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$2" FOREIGN KEY (organizacao_id, localidade_id) REFERENCES localidade(organizacao_id, localidade_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$1" FOREIGN KEY (superior_area_id, areasup_organizacao_id) REFERENCES area(area_id, organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$2" FOREIGN KEY (centro_custo_id, organizacao_id) REFERENCES centro_custo(centro_custo_id, organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$5" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$6" FOREIGN KEY (area_status_id, organizacao_id) REFERENCES area_status(area_status_id, organizacao_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$3" FOREIGN KEY (organizacao_id, area_id) REFERENCES area(organizacao_id, area_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$4" FOREIGN KEY (funcionario_status_id) REFERENCES funcionario_status(funcionario_status_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$3" FOREIGN KEY (titular_funcionario_id) REFERENCES funcionario(funcionario_id)');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$4" FOREIGN KEY (substituto_funcionario_id) REFERENCES funcionario(funcionario_id)');
+				$workflowDB->query('ALTER TABLE ONLY admin_access ADD CONSTRAINT admin_access_pkey PRIMARY KEY (admin_access_id, tipo, numvalue)');
+				$workflowDB->query('ALTER TABLE ONLY aplicacao_externa ADD CONSTRAINT seq_aplicacao_externa PRIMARY KEY (apl_in_id)');
+				$workflowDB->query('ALTER TABLE ONLY aplicacao_externa_acl ADD CONSTRAINT pk_aplicacao_externa_acl PRIMARY KEY (apl_in_id, apl_in_uid)');
+				$workflowDB->query('ALTER TABLE ONLY aplicacao_externa_acl ADD CONSTRAINT fk01_aplicacao_externa_acl FOREIGN KEY (apl_in_id) REFERENCES aplicacao_externa(apl_in_id) ON UPDATE CASCADE ON DELETE CASCADE');
+
+				/* set the permissions to the database objects */
+				$dbObjects = array('organizacao', 'area_status', 'centro_custo', 'localidade', 'funcionario', 'area', 'funcionario_status', 'organizacao_organizacao_id_seq', 'area_status_area_status_id_seq', 'centro_custo_centro_custo_id_seq', 'localidade_localidade_id_seq', 'area_area_id_seq', 'funcionario_status_funcionario_status_id_seq', 'admin_access', 'aplicacao_externa', 'aplicacao_externa_apl_in_id_seq', 'aplicacao_externa_acl');
+				foreach ($dbObjects as $dbObject)
+				{
+					$workflowDB->query("GRANT ALL ON TABLE $dbObject TO admin_workflow");
+					$workflowDB->query("GRANT ALL ON TABLE $dbObject TO postgres");
+					$workflowDB->query("GRANT SELECT ON TABLE $dbObject TO public");
+				}
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.3.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.3.00.000';
+	function workflow_upgrade1_3_00_000()
+	{
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_interinstance_relations',
+			array(
+				'fd' => array(
+					'wf_parent_instance_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_parent_activity_id'	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_child_instance_id' 	=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'wf_parent_lock' 		=> array('type' => 'int', 'precision' => '2', 'nullable' => True)
+				),
+				'pk' => array('wf_parent_instance_id', 'wf_parent_activity_id', 'wf_child_instance_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the workflow database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* change the type of the employee ID (funcionario_id field) */
+				$workflowDB->query('ALTER TABLE funcionario ALTER COLUMN centro_custo_id DROP NOT NULL');
+				$workflowDB->query('ALTER TABLE area DROP CONSTRAINT "$3"');
+				$workflowDB->query('ALTER TABLE area DROP CONSTRAINT "$4"');
+				$workflowDB->query('ALTER TABLE funcionario ADD COLUMN funcionario_id2 int4');
+				$workflowDB->query('UPDATE funcionario SET funcionario_id2 = int4(funcionario_id)');
+				$workflowDB->query('ALTER TABLE funcionario DROP COLUMN funcionario_id');
+				$workflowDB->query('ALTER TABLE funcionario RENAME COLUMN funcionario_id2 TO funcionario_id');
+				$workflowDB->query('ALTER TABLE funcionario ALTER funcionario_id SET NOT NULL');
+				$workflowDB->query('ALTER TABLE funcionario ADD CONSTRAINT funcionario_pkey PRIMARY KEY (funcionario_id)');
+				$workflowDB->query('ALTER TABLE area ADD titular_funcionario_id2 int4');
+				$workflowDB->query('ALTER TABLE area ADD substituto_funcionario_id2 int4');
+				$workflowDB->query('UPDATE area SET titular_funcionario_id2 = int4(titular_funcionario_id), substituto_funcionario_id2 = int4(substituto_funcionario_id)');
+				$workflowDB->query('ALTER TABLE area DROP COLUMN titular_funcionario_id');
+				$workflowDB->query('ALTER TABLE area DROP COLUMN substituto_funcionario_id');
+				$workflowDB->query('ALTER TABLE area RENAME COLUMN titular_funcionario_id2 TO titular_funcionario_id');
+				$workflowDB->query('ALTER TABLE area RENAME COLUMN substituto_funcionario_id2 TO substituto_funcionario_id');
+				$workflowDB->query('ALTER TABLE area ADD CONSTRAINT "$3" FOREIGN KEY (titular_funcionario_id) REFERENCES funcionario (funcionario_id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION');
+				$workflowDB->query('ALTER TABLE AREA ADD CONSTRAINT "$4" FOREIGN KEY (substituto_funcionario_id) REFERENCES funcionario (funcionario_id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.00.000';
+	function workflow_upgrade1_4_00_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.00.001';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.00.001';
+	function workflow_upgrade1_4_00_001()
+	{
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_activities' ,'wf_menu_path', array('type' => 'varchar', 'precision' => 200, 'nullable' => True));
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.01.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.01.000';
+	function workflow_upgrade1_4_01_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* add a new column to the area table (orgchart) */
+				$workflowDB->query('ALTER TABLE area ADD COLUMN auxiliar_funcionario_id int4');
+				$workflowDB->query('ALTER TABLE ONLY area ADD CONSTRAINT "$7" FOREIGN KEY (auxiliar_funcionario_id) REFERENCES funcionario(funcionario_id)');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.02.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.02.000';
+	function workflow_upgrade1_4_02_000()
+	{
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_admin_access',
+			array(
+				'fd' => array(
+					'admin_access_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'tipo'	=> array('type' => 'char', 'precision' => '3', 'nullable' => False),
+					'numvalue'	=> array('type' => 'int', 'precision' => '2', 'nullable' => False),
+					'nivel'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0)
+				),
+				'pk' => array('admin_access_id', 'tipo', 'numvalue'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_external_application',
+			array(
+				'fd' => array(
+					'external_application_id' => array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+					'name' => array('type' => 'varchar', 'precision' => '50', 'nullable' => False),
+					'description' => array('type' => 'text', 'nullable' => True),
+					'image' => array('type' => 'varchar', 'precision' => '100', 'nullable' => True),
+					'address' => array('type' => 'varchar', 'precision' => '120', 'nullable' => False),
+					'authentication' => array('type' => 'bit', 'precision' => '1', 'nullable' => True),
+					'post' => array('type' => 'text', 'nullable' => True)
+				),
+				'pk' => array('external_application_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$adminAccessData = array();
+			$externalApplicationData = array();
+			$externalApplicationSequence = 1;
+			$externalApplicationACLData = array();
+			$workflowHostInfo = extractDatabaseParameters();
+			$GLOBALS['phpgw']->ADOdb->SetFetchMode(ADODB_FETCH_ASSOC);
+
+			/* connect to the Workflow database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				$result = $GLOBALS['phpgw']->ADOdb->query('SELECT admin_access_id, tipo, numvalue, nivel FROM admin_access');
+				if ($result)
+					while ($row = $result->fetchRow())
+						$adminAccessData[] = array($row['admin_access_id'], $row['tipo'], $row['numvalue'], $row['nivel']);
+
+				$result = $GLOBALS['phpgw']->ADOdb->query('SELECT apl_in_id, apl_st_nome, apl_st_descricao, apl_st_imagem, apl_st_endereco, apl_bt_autentica, apl_st_post FROM aplicacao_externa');
+				if ($result)
+					while ($row = $result->fetchRow())
+						$externalApplicationData[] = array($row['apl_in_id'], $row['apl_st_nome'], $row['apl_st_descricao'], $row['apl_st_imagem'], $row['apl_st_endereco'], $row['apl_bt_autentica'], $row['apl_st_post']);
+				$result = $GLOBALS['phpgw']->ADOdb->query('SELECT last_value FROM aplicacao_externa_apl_in_id_seq');
+				if ($result)
+					if ($row = $result->fetchRow())
+						$externalApplicationSequence = $row['last_value'];
+
+				$result = $GLOBALS['phpgw']->ADOdb->query('SELECT apl_in_uid, apl_in_id FROM aplicacao_externa_acl');
+				if ($result)
+					while ($row = $result->fetchRow())
+						$externalApplicationACLData[] = array($row['apl_in_uid'], $row['apl_in_id']);
+
+				/* remove the unused tables */
+				$GLOBALS['phpgw']->ADOdb->query('DROP TABLE admin_access');
+				$GLOBALS['phpgw']->ADOdb->query('DROP SEQUENCE aplicacao_externa_apl_in_id_seq');
+				$GLOBALS['phpgw']->ADOdb->query('DROP CONSTRAINT fk01_aplicacao_externa_acl');
+				$GLOBALS['phpgw']->ADOdb->query('DROP TABLE aplicacao_externa_acl');
+				$GLOBALS['phpgw']->ADOdb->query('DROP TABLE aplicacao_externa');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+			foreach ($adminAccessData as $newRow)
+				$result = $GLOBALS['phpgw']->ADOdb->query("INSERT INTO egw_wf_admin_access(admin_access_id, tipo, numvalue, nivel) VALUES (?, ?, ?, ?)", $newRow);
+
+			foreach ($externalApplicationData as $newRow)
+				$result = $GLOBALS['phpgw']->ADOdb->query("INSERT INTO egw_wf_external_application(external_application_id, name, description, image, address, authentication, post) VALUES(?, ?, ?, ?, ?, ?, ?)", $newRow);
+			$GLOBALS['phpgw']->ADOdb->query("SELECT pg_catalog.setval('seq_egw_wf_external_application', ?, true)", array($externalApplicationSequence));
+
+			foreach ($externalApplicationACLData as $newRow)
+				$result = $GLOBALS['phpgw']->ADOdb->query("INSERT INTO egw_wf_admin_access(admin_access_id, tipo, numvalue, nivel) VALUES (?, 'APX', ?, 0)", $newRow);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.03.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.03.000';
+	function workflow_upgrade1_4_03_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* add a new column to the funcionario_status table (orgchart) */
+				$workflowDB->query('ALTER TABLE funcionario_status ADD COLUMN exibir character varying(1)');
+				$workflowDB->query('UPDATE funcionario_status SET exibir = ?', array('S'));
+				$workflowDB->query('ALTER TABLE funcionario_status ALTER COLUMN exibir SET NOT NULL');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.04.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.04.000';
+	function workflow_upgrade1_4_04_000()
+	{
+		/* remove unused table */
+		$GLOBALS['phpgw_setup']->oProc->DropTable('egw_wf_instance_supplements');
+
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$GLOBALS['phpgw']->ADOdb->query('ALTER TABLE egw_wf_instances ALTER COLUMN wf_next_user TYPE text');
+			$GLOBALS['phpgw']->ADOdb->SetFetchMode(ADODB_FETCH_ASSOC);
+			$result = $GLOBALS['phpgw']->ADOdb->query('SELECT i.wf_instance_id, ia.wf_activity_id, i.wf_next_user FROM egw_wf_instances i, egw_wf_instance_activities ia WHERE (i.wf_instance_id = ia.wf_instance_id) AND (i.wf_next_user IS NOT NULL)');
+			if (!empty($result))
+			{
+				while ($res = $result->fetchRow())
+				{
+					$newNextUser = base64_encode(serialize(array('*' . $res['wf_activity_id'] => $res['wf_next_user'])));
+					$ok = $GLOBALS['phpgw']->ADOdb->query(
+						'UPDATE egw_wf_instances SET wf_next_user = ? WHERE (wf_instance_id = ?)',
+						array($newNextUser, (int)$res['wf_instance_id'])
+					);
+				}
+			}
+
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* add a new column to the organizacao table (orgchart) */
+				$workflowDB->query('ALTER TABLE organizacao ADD COLUMN url_imagem character varying(200)');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.05.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.05.000';
+	function workflow_upgrade1_4_05_000()
+	{
+		$GLOBALS['phpgw_setup']->oProc->AddColumn('egw_wf_external_application' ,'intranet_only', array('type' => 'bit', 'precision' => '1', 'nullable' => True));
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.4.06.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.4.06.000';
+	function workflow_upgrade1_4_06_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.6.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.6.00.000';
+	function workflow_upgrade1_6_00_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* create the new tables and add the referencial constraints */
+				$workflowDB->query('CREATE TABLE cargo (cargo_id serial NOT NULL, descricao character varying(150), organizacao_id int4)');
+				$workflowDB->query('ALTER TABLE ONLY cargo ADD CONSTRAINT cargo_pkey PRIMARY KEY (cargo_id)');
+				$workflowDB->query('ALTER TABLE ONLY cargo ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao (organizacao_id)');
+				$workflowDB->query('CREATE TABLE funcionario_categoria (funcionario_categoria_id serial NOT NULL, descricao character varying(150), organizacao_id int4)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario_categoria ADD CONSTRAINT funcionario_categoria_pkey PRIMARY KEY (funcionario_categoria_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario_categoria ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao (organizacao_id)');
+
+				/* add a new column to the organizacao table (orgchart) */
+				$workflowDB->query('ALTER TABLE funcionario ADD COLUMN cargo_id int4');
+				$workflowDB->query('ALTER TABLE funcionario ADD COLUMN nivel int2');
+				$workflowDB->query('ALTER TABLE funcionario ADD COLUMN funcionario_categoria_id int4');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$5" FOREIGN KEY (cargo_id) REFERENCES cargo (cargo_id)');
+				$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$6" FOREIGN KEY (funcionario_categoria_id) REFERENCES funcionario_categoria (funcionario_categoria_id)');
+
+				/* set the permissions to the database objects */
+				$dbObjects = array('cargo', 'cargo_cargo_id_seq', 'funcionario_categoria', 'funcionario_categoria_funcionario_categoria_id_seq');
+				foreach ($dbObjects as $dbObject)
+				{
+					$workflowDB->query("GRANT ALL ON TABLE $dbObject TO admin_workflow");
+					$workflowDB->query("GRANT ALL ON TABLE $dbObject TO postgres");
+					$workflowDB->query("GRANT SELECT ON TABLE $dbObject TO public");
+				}
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.6.01.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.6.01.000';
+	function workflow_upgrade1_6_01_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			/* tries to load the 'files_dir' value (usually '/home/expressolivre') */
+			$GLOBALS['phpgw']->ADOdb->SetFetchMode(ADODB_FETCH_ASSOC);
+			$result = $GLOBALS['phpgw']->ADOdb->query('SELECT config_value FROM phpgw_config WHERE config_app = ? AND config_name = ?', array('phpgwapi', 'files_dir'));
+			if (!(empty($result)))
+			{
+				$res = $result->fetchRow();
+
+				/* initialize some variables */
+				$resourcesBase = $res['config_value'];
+				$oldResourcesDir = PHPGW_SERVER_ROOT . '/workflow/resources';
+				$success = true;
+
+				/* if the resources dir exists, move it's subdirectories */
+				if (is_dir($oldResourcesDir))
+				{
+					$success = false;
+					$handle = opendir($oldResourcesDir);
+					if ($handle)
+					{
+						$success = true;
+						$OKToDeleteDir = true;
+
+						/* move all subdirectories (except the '.' and '..' for oubvious reasons) to their new place */
+						while (false !== ($processDir = readdir($handle)))
+						{
+							if (($processDir == '.') || ($processDir == '..'))
+								continue;
+
+							/* check if we are dealing with a directory */
+							if (!is_dir($oldResourcesDir . '/' . $processDir))
+							{
+								$OKToDeleteDir = false;
+								continue;
+							}
+
+							/* special treatment for the workflow directory */
+							if ($processDir == 'workflow')
+							{
+								$success = $success && @rename($oldResourcesDir . '/' . $processDir, $resourcesBase . '/workflow/workflow');
+								continue;
+							}
+
+							/* if the destination directory exists, move it */
+							$newProcessDir = $resourcesBase . '/workflow/' . $processDir;
+							if (is_dir($newProcessDir))
+								$success = $success && @rename($oldResourcesDir . '/' . $processDir, $newProcessDir . '/resources');
+							else
+								$OKToDeleteDir = false;
+						}
+
+						/* close the handler */
+						closedir($handle);
+
+						/* if the directory is empty, remove it */
+						if ($OKToDeleteDir && $success)
+							if (!@rmdir($oldResourcesDir))
+								echo '<font color="red">Não foi possível remover o diretório: ' . $oldResourcesDir . '<br/> Tente removê-lo manualmente.</font>';
+					}
+				}
+
+				/* in case of an unsuccessful attemp to move a directory, warn the system admin */
+				if (!$success)
+					echo '<font color="red">Pelo menos um diretório não pode ser movido. Você precisa mover, manualmente, os diretórios de resources dos processos. Exemplo: <br/><strong>' . $oldResourcesDir . '/PROCESSO_XX</strong> para <strong>' . $resourcesBase . '/workflow/PROCESSO_XX/resources</strong></font>';
+			}
+
+		}
+
+		/* updates the current version */
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.6.02.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.6.02.000';
+	function workflow_upgrade1_6_02_000()
+	{
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_user_cache',
+			array(
+				'fd' => array(
+					'uidnumber'			=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'uid'				=> array('type' => 'varchar', 'precision' => '30', 'nullable' => True),
+					'cn'				=> array('type' => 'varchar', 'precision' => '100', 'nullable' => True),
+					'givenname'			=> array('type' => 'varchar', 'precision' => '30', 'nullable' => True),
+					'sn'				=> array('type' => 'varchar', 'precision' => '70', 'nullable' => True),
+					'mail'				=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+					'accountstatus'		=> array('type' => 'varchar', 'precision' => '80', 'nullable' => True),
+					'dn'				=> array('type' => 'varchar', 'precision' => '150', 'nullable' => True),
+					'employeenumber'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'cpf'				=> array('type' => 'varchar', 'precision' => '15', 'nullable' => True),
+					'telephonenumber'	=> array('type' => 'varchar', 'precision' => '50', 'nullable' => True),
+					'last_update'		=> array('type' => 'timestamp without time zone default now()', 'nullable' => True)
+				),
+				'pk' => array('uidnumber'),
+				'fk' => array(),
+				'ix' => array('mail', 'employeenumber', 'cpf'),
+				'uc' => array()
+			)
+		);
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.6.03.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.6.03.000';
+	function workflow_upgrade1_6_03_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				$result = $workflowDB->query("SELECT 1 FROM pg_tables WHERE (schemaname = 'public') AND (tablename = 'funcionario_status')");
+				$row = array();
+				if (!empty($result))
+					$row = $result->fetchRow();
+
+				/* only some instalations are missing this table */
+				if ($row === false)
+				{
+					$workflowDB->query('CREATE TABLE funcionario_status (funcionario_status_id serial NOT NULL, descricao character varying(50) NOT NULL, exibir character varying(1) NOT NULL)');
+					$workflowDB->query('ALTER TABLE ONLY funcionario_status ADD CONSTRAINT funcionario_status_pkey PRIMARY KEY (funcionario_status_id)');
+					$workflowDB->query('ALTER TABLE ONLY funcionario ADD CONSTRAINT "$4" FOREIGN KEY (funcionario_status_id) REFERENCES funcionario_status(funcionario_status_id)');
+
+					$dbObjects = array('funcionario_status', 'funcionario_status_funcionario_status_id_seq');
+					foreach ($dbObjects as $dbObject)
+					{
+						$workflowDB->query("GRANT ALL ON TABLE $dbObject TO admin_workflow");
+						$workflowDB->query("GRANT ALL ON TABLE $dbObject TO postgres");
+						$workflowDB->query("GRANT SELECT ON TABLE $dbObject TO public");
+					}
+				}
+			}
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.6.03.001';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.6.03.001';
+	function workflow_upgrade1_6_03_001()
+	{
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_jobs',
+			array(
+				'fd' => array(
+					'job_id'			=> array('type' => 'auto', 'precision' => '4', 'nullable' => False),
+					'wf_process_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'name'				=> array('type' => 'varchar', 'precision' => '100', 'nullable' => False),
+					'description'		=> array('type' => 'text', 'nullable' => True),
+					'time_start'		=> array('type' => 'timestamp without time zone', 'nullable' => False),
+					'interval_value'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'interval_unity'	=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'date_type'			=> array('type' => 'int', 'precision' => '4', 'nullable' => True),
+					'week_days'			=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0),
+					'month_offset'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True, 'default' => 0),
+					'active'			=> array('type' => 'bool', 'nullable' => True)
+				),
+				'pk' => array('job_id'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		$GLOBALS['phpgw_setup']->oProc->createTable('egw_wf_job_logs',
+			array(
+				'fd' => array(
+					'job_id'		=> array('type' => 'int', 'precision' => '4', 'nullable' => False),
+					'date_time'		=> array('type' => 'timestamp without time zone', 'nullable' => False),
+					'result'		=> array('type' => 'blob', 'nullable' => True),
+					'status'		=> array('type' => 'int', 'precision' => '4', 'nullable' => True)
+				),
+				'pk' => array('job_id', 'date_time'),
+				'fk' => array(),
+				'ix' => array(),
+				'uc' => array()
+			)
+		);
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.7.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.7.00.000';
+	function workflow_upgrade1_7_00_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.00.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.00.000';
+	function workflow_upgrade1_8_00_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.01.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.01.000';
+	function workflow_upgrade1_8_01_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$GLOBALS['phpgw']->ADOdb->query('CREATE INDEX egw_wf_instances_wf_name_idx ON egw_wf_instances(UPPER(wf_name))');
+			$GLOBALS['phpgw']->ADOdb->query('CREATE INDEX egw_wf_instances_wf_p_id_idx ON egw_wf_instances(wf_p_id)');
+			$GLOBALS['phpgw']->ADOdb->query('DELETE FROM phpgw_config where config_app = \'workflow\' and config_name in (\'database_user\', \'database_password\')');
+
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* add a new column to the area organization (orgchart) */
+				$workflowDB->query('ALTER TABLE organizacao ADD COLUMN ativa character varying(1)');
+				$workflowDB->query('UPDATE organizacao SET ativa = \'S\'');
+				$workflowDB->query('ALTER TABLE organizacao ALTER ativa SET NOT NULL');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.02.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.02.000';
+	function workflow_upgrade1_8_02_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to the new database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* gather some information */
+				$workflowDB->setFetchMode(ADODB_FETCH_ASSOC);
+				$organizations = $workflowDB->GetAll('SELECT organizacao_id FROM organizacao');
+				$employeeStatus = $workflowDB->GetAll('SELECT funcionario_status_id, descricao, exibir FROM funcionario_status');
+
+				/* add the new column */
+				$workflowDB->query('ALTER TABLE funcionario_status ADD COLUMN organizacao_id INTEGER');
+				if (count($organizations) > 0)
+				{
+					/* run update for the first organization */
+					$workflowDB->query('UPDATE funcionario_status SET organizacao_id = ?', array($organizations[0]['organizacao_id']));
+
+					/* replicate the 'funcionario_status' table information for other organizations */
+					for ($i = 1; $i < count($organizations); $i++)
+					{
+						$organizationID = $organizations[$i]['organizacao_id'];
+						foreach ($employeeStatus as $es)
+						{
+							$values = array(
+								$es['descricao'],
+								$es['exibir'],
+								$organizationID
+							);
+
+							/* insert the new status */
+							$workflowDB->query('INSERT INTO funcionario_status (descricao, exibir, organizacao_id) VALUES (?, ?, ?)', $values);
+
+							$values = array(
+								$organizationID,
+								$es['funcionario_status_id']
+							);
+
+							/* update the existing employees */
+							$workflowDB->query('UPDATE funcionario SET funcionario_status_id = (SELECT MAX(funcionario_status_id) FROM funcionario_status) WHERE (organizacao_id = ?) AND (funcionario_status_id = ?)', $values);
+						}
+					}
+				}
+				/* add the new constraint */
+				$workflowDB->query('ALTER TABLE ONLY funcionario_status ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.03.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.03.000';
+	function workflow_upgrade1_8_03_000()
+	{
+		/* setting new default attributes for workflow Logger  */
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$GLOBALS['phpgw']->ADOdb->query('INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES (\'workflow\', \'log_type_file\', \'True\')');
+			$GLOBALS['phpgw']->ADOdb->query('INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES (\'workflow\', \'log_type_firebug\', \'True\')');
+			$GLOBALS['phpgw']->ADOdb->query('INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES (\'workflow\', \'log_level\', \'7\')');
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.04.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.04.000';
+	function workflow_upgrade1_8_04_000()
+	{
+		/* Create index for table egw_wf_workitems  */
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$GLOBALS['phpgw']->ADOdb->query('CREATE INDEX egw_wf_workitems_wf_instance_id_idx ON egw_wf_workitems(wf_instance_id)');
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.05.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.05.000';
+	function workflow_upgrade1_8_05_000()
+	{
+		/* Alter tables of orgchart */
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to workflow database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* add the new columns */
+				$workflowDB->query('ALTER TABLE public.funcionario ADD COLUMN titulo CHARACTER VARYING(30)');
+				$workflowDB->query('ALTER TABLE public.organizacao ADD COLUMN sitio CHARACTER VARYING(100)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN empresa CHARACTER VARYING(100)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN endereco CHARACTER VARYING(100)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN complemento CHARACTER VARYING(50)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN cep CHARACTER VARYING(9)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN bairro CHARACTER VARYING(30)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN cidade CHARACTER VARYING(50)');
+				$workflowDB->query('ALTER TABLE public.localidade ADD COLUMN uf CHARACTER(2)');
+
+				/* create table telefone */
+				$workflowDB->query('CREATE TABLE public.telefone (telefone_id serial NOT NULL, descricao character varying(50) NOT NULL, numero character varying(50) NOT NULL, organizacao_id integer NOT NULL)');
+				$workflowDB->query('ALTER TABLE ONLY public.telefone ADD CONSTRAINT telefone_pkey PRIMARY KEY (telefone_id)');
+				$workflowDB->query('ALTER TABLE ONLY public.telefone ADD CONSTRAINT "$1" FOREIGN KEY (organizacao_id) REFERENCES organizacao(organizacao_id)');
+				$workflowDB->query("GRANT ALL ON TABLE public.telefone TO admin_workflow");
+				$workflowDB->query("GRANT ALL ON TABLE public.telefone TO postgres");
+				$workflowDB->query("GRANT SELECT ON TABLE public.telefone TO public");
+				$workflowDB->query("GRANT ALL ON TABLE public.telefone_telefone_id_seq TO admin_workflow");
+				$workflowDB->query("GRANT ALL ON TABLE public.telefone_telefone_id_seq TO postgres");
+				$workflowDB->query("GRANT SELECT ON TABLE public.telefone_telefone_id_seq TO public");
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'].":".$workflowHostInfo['port'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '1.8.06.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+
+	$test[] = '1.8.06.000';
+	function workflow_upgrade1_8_06_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '2.0.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+	$test[] = '2.0.000';
+	function workflow_upgrade2_0_000()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '2.0.001';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+	$test[] = '2.0.001';
+	function workflow_upgrade2_0_001()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '2.0.002';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+	$test[] = '2.0.002';
+	function workflow_upgrade2_0_002()
+	{
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '2.1.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+	$test[] = '2.1.000';
+	function workflow_upgrade2_1_000()
+	{
+		if (!$GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly)
+		{
+			$workflowHostInfo = extractDatabaseParameters();
+
+			/* connect to workflow database */
+			$workflowDB = $GLOBALS['phpgw']->ADOdb;
+			if ($workflowDB->connect($workflowHostInfo['host'], $workflowHostInfo['user'], $workflowHostInfo['password'], 'workflow'))
+			{
+				/* creating table substitution */
+				$workflowDB->query('CREATE TABLE substituicao (substituicao_id serial NOT NULL, area_id integer NOT NULL, funcionario_id integer NOT NULL, data_inicio date NOT NULL, data_fim date NOT NULL)');
+
+				$workflowDB->query('ALTER TABLE ONLY public.substituicao ADD CONSTRAINT substituicao_pkey PRIMARY KEY (substituicao_id)');
+				$workflowDB->query('ALTER TABLE ONLY public.substituicao ADD CONSTRAINT "$1" FOREIGN KEY (area_id) REFERENCES area(area_id)');
+				$workflowDB->query('ALTER TABLE ONLY public.substituicao ADD CONSTRAINT "$2" FOREIGN KEY (funcionario_id) REFERENCES funcionario(funcionario_id)');
+
+				/* granting privilegies */
+				$workflowDB->query("GRANT ALL ON TABLE public.substituicao TO admin_workflow");
+				$workflowDB->query("GRANT ALL ON TABLE public.substituicao TO postgres");
+				$workflowDB->query("GRANT SELECT ON TABLE public.substituicao TO public");
+				$workflowDB->query("GRANT ALL ON TABLE public.substituicao_substituicao_id_seq TO admin_workflow");
+				$workflowDB->query("GRANT ALL ON TABLE public.substituicao_substituicao_id_seq TO postgres");
+				$workflowDB->query("GRANT SELECT ON TABLE public.substituicao_substituicao_id_seq TO public");
+
+				/* migrating records */
+				$result = $workflowDB->query('SELECT area_id, substituto_funcionario_id FROM area WHERE substituto_funcionario_id IS NOT NULL');
+				if ($result)
+					while ($row = $result->fetchRow()) {
+						$values = array($row['area_id'], $row['substituto_funcionario_id']);
+						$workflowDB->query('INSERT INTO substituicao (area_id, funcionario_id, data_inicio, data_fim) VALUES (?, ?, CURRENT_DATE, CURRENT_DATE+integer \'7\')', $values);
+					}
+
+
+				/* erasing old atributes */
+				$workflowDB->query("ALTER TABLE area DROP COLUMN substituto_funcionario_id");
+			}
+
+			/* reconnect to the previous database */
+			$GLOBALS['phpgw']->ADOdb->connect($workflowHostInfo['host'], $workflowHostInfo['user'], $workflowHostInfo['password'], $workflowHostInfo['dbname']);
+		}
+
+		#updating the current version
+		$GLOBALS['setup_info']['workflow']['currentver'] = '2.2.000';
+		return $GLOBALS['setup_info']['workflow']['currentver'];
+	}
+?>
Index: /sandbox/workflow/branches/993/setup/phpgw_sv.lang
===================================================================
--- /sandbox/workflow/branches/993/setup/phpgw_sv.lang	(revision 795)
+++ /sandbox/workflow/branches/993/setup/phpgw_sv.lang	(revision 795)
@@ -0,0 +1,32 @@
+abort instance	workflow	sv	Avbryt instans
+aborted	workflow	sv	Avbrutet
+act	workflow	sv	handla
+activate	workflow	sv	aktivera
+active	workflow	sv	Aktivera
+activities	workflow	sv	Aktiviteter
+activities updated	workflow	sv	aktiviteter uppdaterade
+activity	workflow	sv	aktivitet
+activity  status	workflow	sv	aktivitetsstatus
+activity %1 is interactive but has no role assigned	workflow	sv	Aktivitet %1 är interaktiv men har saknar rolltilldelning
+activity %1 is interactive so it must use the $instance->complete() method	workflow	sv	Aktivitet %1 är interaktiv så den måste använda metoden $instance->complete()
+activity %1 is non-interactive and non-autorouted but has no role assigned	workflow	sv	Aktivitet %1 är icke-interaktiv och icke-autoroutad men saknar rolltilldelning
+activity %1 is non-interactive so it must not use the $instance->complete() method	workflow	sv	Atktivitet %1 är icke-interaktiv så den får INTE använda metoden $instance->complete()
+activity %1 is standalone and is using the $instance object	workflow	sv	Aktivitet %1 är fristående och använder $instance objektet
+activity %1 is standalone but has transitions	workflow	sv	Aktivitet %1 är fristående men har övergångar
+activity %1 is switch so it must use $instance->setnextactivity($actname) method	workflow	sv	Aktivitet %1 är växel så den måste använda metoden $instance->setNextActivity($actname)
+activity completed	workflow	sv	Aktivitet slutförd
+activity name already exists	workflow	sv	Det aktivitetsnamnet användes redan
+activity role removed	workflow	sv	Aktivitetsroll borttagen
+activity saved	workflow	sv	Aktivitet sparad
+add a transition	workflow	sv	Läggtill övergång
+add new	workflow	sv	lägg till ny
+add or edit a process	workflow	sv	lägg till eller redigera process
+add or edit an activity	workflow	sv	lägg till eller redigera aktivitet
+add property	workflow	sv	lägg till egenskap
+add role	workflow	sv	lägg till roll
+add role to process	workflow	sv	koppla roll till process
+add transitions	workflow	sv	lägg till övergångar
+add transitions from	workflow	sv	lägg till övergånar från
+add transitions to	workflow	sv	lägg till övergångar till
+admin instance	workflow	sv	Administrera instans
+admin process activities	workflow	sv	administrera
Index: /sandbox/workflow/branches/993/showUserPicture.php
===================================================================
--- /sandbox/workflow/branches/993/showUserPicture.php	(revision 2372)
+++ /sandbox/workflow/branches/993/showUserPicture.php	(revision 2372)
@@ -0,0 +1,15 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+require_once 'inc/common.inc.php';
+if (empty($_SESSION))
+	exit(0);
+Factory::getInstance('UserPictureProvider')->serve();
+?>
Index: /sandbox/workflow/branches/993/templateFile.php
===================================================================
--- /sandbox/workflow/branches/993/templateFile.php	(revision 2372)
+++ /sandbox/workflow/branches/993/templateFile.php	(revision 2372)
@@ -0,0 +1,15 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+require_once 'inc/common.inc.php';
+if (empty($_SESSION))
+	exit(0);
+Factory::getInstance('TemplateServer')->redirect();
+?>
Index: /sandbox/workflow/branches/993/doc/change_log.txt
===================================================================
--- /sandbox/workflow/branches/993/doc/change_log.txt	(revision 1712)
+++ /sandbox/workflow/branches/993/doc/change_log.txt	(revision 1712)
@@ -0,0 +1,619 @@
+mbartz is Michael Bartz
+alpeb is Alejandro Pedraza
+regis_glc is Regis Leroy
+viani is Mauricio Luiz Viani
+rodrigolira is Rodrigo Campaner de Lira
+mariceli is Mariceli Duarte Foronda
+drovetto is Sidnei Augusto Drovetto Junior
+carloseduardo is Carlos Eduardo Nogueira Gonçalves
+rufino is Everton Flávio Rufino Seara
+asaikawa is Anderson Tadayuki Saikawa
+cassiomaes is Cassio Maes da Fonseca
+gbisotto is Guilherme Striquer Bisotto
+julianadelgado is Juliana Delgado Santos Hernandez
+rodsouza is Rodrigo Souza dos Santos
+arifragoso is Ari Fragoso de Medeiros Junior
+hermespinheiro is Hermes Pinheiro Neto
+
+Os registros estão listados em ordem decrescente de data de realização.
+
+[2.1.000]
+
+	#794 - Correção de bug de sintaxe na classe Workflow_WfSecurity. (hermespinheiro).
+	#792 - Modificado o atribuito de usuário padrão de uma atividade para aceitar também um perfil padrão. (rufino)
+	#766 - Correção de bug na função wf_get_activity_link_by_id que impedia a geração do link caso não haja instância. (viani)
+	#668 - Modificada a expressão regular que busca por nomes no organograma, para considerar primeiro e último nome. (rodsouza)
+	#659 - Carregamento de valor nas variáveis smarty para os links de tarefas pendentes e processos, no template padrão. (gbisotto)
+	#658 - Correção no alinhamento dos ícones de aplicações externas. Ao redimensionar a janela, o ícones são reorganizados. (gbisotto)
+	#657 - Correção no alinhamento do menu de atividades dos processos. Ao redimensionar a janela, os menus são reorganizados. (gbisotto).
+	#639 - Inclusão de cor em destaque ao passar o mouse sobre uma linha nas visualizações do organograma. (rodsouza)
+	#638 - Mudança na query de busca do organograma para pesquisar também por áreas. (rodsouza)
+	#643 - Criação do método createNewInstance na classe JobBase, que possibilita iniciar uma instância do processo a partir de um job. (rufino)
+	#442 - Criação do plugin wf_autocomplete_input, para listar com autocomplete o resultado de uma busca ajax. (rufino)
+	#637 - Inclusão de click-to-call no organograma e outras melhorias na interface. (rodsouza)
+
+[2.0.000]
+
+	* Correção de bug no método getByUser da classe wf_instance. (hermespinheiro)
+	* Melhorias no organograma, com novas visualizações nas interfaces. (rodsouza)
+
+[1.8.05.000]
+
+	+ Implementada verificação de consistência na entrada do workflow. (viani)
+	* Eliminação do template Celepar no módulo. (viani)
+	+ Criação do método getEntryByUid na classe wf_ldap. (gbisotto)
+	* Correção de bug no método getUsersFromRole da classe wf_role, que não estava recuperando usários de grupos. (viani)
+	* Correção da tradução e adição de frases, identificadas pelo Serpro. (julianadelgado)
+	* Correção de bug na classe Logger que não estava lendo a configuração da tabela phpgw_config. (gbisotto)
+	+ Inclusão do número de telefone na listagem impressa do organograma. (viani)
+	* Alteração para que na visualização da "árvore" do organograma as áreas sejam ordenadas por nível de status. Status com "maior importância" aparecem primeiro. (rufino)
+	+ Criação do método getSubAreasByParentAreaID, que busca as áreas imediatamente inferiores à área solicitada. (gbisotto)
+
+[1.8.04.000]
+	* Acrescentada uma coluna de prioridade na caixa de entrada. (gbisotto)
+	+ Criada uma solução de log para uso do módulo e dos processos. (gbisotto)
+	* Modificação na classe wf_instance, método getChildren(), inserido ORDER BY por instance_id na consulta que retorna as instâncias filhas de uma instância. (rufino)
+	* Modificação nas classes de acesso ao mainframe (natural) para que seja possível acessar outros mainframes/sistemas. (rufino)
+	* Modificação na class.bo_utils.inc.php, método search_ldap_users_by_cn. Agora o bind é feito utilizando o usuário do contact center (expresso-cc) que tem permissão para seguir referrals. (gbisotto)
+	* Modificada a função getEmployeesAreaID para retornar somente usuários ativos quando se queira isto. (gbisotto)
+	* Criação de uma camada de segurança, classes WorkflowSecurity e WorkflowWatcher, para os objetos de acesso restrito. (drovetto)
+	* Criação de método para extração da organização de um usuário a partir de seu DN. Na interface de participantes, agora é feito tratamento para sabser se a OU do usuário existe e, caso não exista, é utilizada a primeira OU da lista de OUs possíveis. (drovetto)
+	* Conversão de algumas interfaces para a engine de templates Smarty (drovetto)
+	* Correção de bug reportado por Diorgenes Felipe Grzesiuk. O bug acontecia ao se tentar editar/apagar/exportar, pela interface de edição de código, um arquivo que contém o caractere espaço em seu nome. (drovetto)
+	* Modificação dos métodos getRequest, updateAttributes, updateInstance, da classe basemodel, para que, ao se trabalhar com atributos de classes/instâncias, seja possível especificar quais atributos se deseja utilizar (o default continua todos os atributos). (drovetto)
+	* Incluída a possibilidade de se passar o mime type de um arquivo para o método 'BaseModel::sendFile'. Código fornecido pelo desenvolvedor Ari Fragoso de Medeiros Junior. (arifragoso)
+	* Correções na 'wf_select_duplex' propostas pelo desenvolvedor Ari Fragoso de Medeiros Junior. (drovetto)
+	* Transferência do template "Celepar" para o template "default". Isto foi feito porque era obrigatório a utilização do template celepar para o correto funcionamento do módulo. (drovetto)
+	+ Criação da classe templateServer para inclusão imagens/js/css de templates. Esta classe tem como objetivo a remoção de referências hard-coded a um determinado template. (drovetto)
+
+[1.8.03.000]
+	+ Nova funcionalidade na interface de Monitoramento que permite encontrar instâncias que estão em um estado inconsistente (drovetto)
+	- Necessidade de compilação de processos. Agora, as alterações nos arquivos PHP das atividades não mais requerem compilação do processo para que tenham efeito (drovetto)
+	+ Possibilidade de busca global na interface de seleção de participantes (normalmente utilizada através de plugins Smarty) (drovetto)
+	+ Criação da categoria 'Administrador de Workflow' que dá acesso privilegiado ao módulo Workflow (drovetto)
+
+[1.8.02.000]
+	+ Possibilidade de forçar as atividades de um processo a serem executadas utilizando conexão segura (HTTPS) (drovetto)
+
+[1.8.01.000]
+	+ Possibilidade de imprimir o organograma inteiro (ou a partir de uma área) (drovetto)
+	+ Possibilidade de importar um processo (a partir de um XML) especificando um novo nome e uma nova versão (drovetto)
+	* Informações adicionais, inclusive a foto, dos funcionários são exibidas ao se passar o cursor do mouse sobre seus nomes na interface de organograma (de usuário e de administração) (drovetto)
+	* Ao se mover instâncias, é possível selecionar as instâncias que serão movidas de acordo com seu status (ativa ou finalizada) (drovetto)
+
+[1.8.00.000]
+	+ Métodos 'setUser' e 'setRole' na classe 'wf_instance'. Estes métodos servem para definir um usuário/perfil como usuário atual da instância (drovetto)
+
+[1.7.00.000]
+	* Alteração no Monitoramento para utilizar o cache de ldap ao listar nome de usuários (drovetto)
+	* Alteração no Organograma para utilizar o cache e ldap e corrigido bug na listagem por vínculo (drovetto)
+	* Alteração no método getUsersFromRole da classe wf_role para permitir que sejam recuperados os usuários dos grupos do perfil (asaikawa)
+	* Possibilidade de tratar sessão expirada em chamadas Ajax feitas pelos processos (drovetto)
+	+ Jobs. Possibilita a execução de código PHP (vinculado a processos) em horários, e com repetições, pré-determinados (drovetto)
+	+ Plugin Smarty (wf_select_ldap_users) que faz busca no Ldap através do nome (atributo cn), ou parte do nome, e apresenta os resultados obtidos em uma combobox (asaikawa)
+		/inc/smarty/wf_plugins/function.wf_select_ldap_users_init.php
+		/inc/smarty/wf_plugins/function.wf_select_ldap_users.php
+		/js/jscode/wf_select_ldap_users.js
+		/inc/class.bo_utils.inc.php (criado método search_ldap_users_by_cn)
+	+ Criado novo estilo chamado input_like_label, em que são removidas as bordas e definido o background para transparente, deixando o input parecido com um label (/templates/celepar/processes/default.css) (asaikawa)
+	* Alterado estilo chamado lightbox para ajustar automaticamente a altura do lightbox de acordo com seu conteúdo, porém, dentro dos limites min-height e max-height definidos no estilo (sugestão da Alessandra Heil) (/templates/celepar/css/lightbox.css) (asaikawa)
+
+[1.6.03.001]
+	* Correção de BUG que não criava a tabela 'funcionario_status' (e dependências relacionadas a ela) em uma nova instalação do Workflow (drovetto)
+
+[1.6.03.000]
+	* Incluído suporte a grupos na 'Lista de Controle de Acesso' para o monitoramento de instâncias de um processo. Quando um usuário possui direitos de acesso oriundos de diferentes "lugares" (e.g. estar em vários grupos com acesso de monitoramento ao mesmo processo; está com acesso relacionado diretamente ao usuário e o usuário também está em um grupo com diferentes acessos), as permissões são acumuladas (drovetto)
+	* Smarty atualizado para a versão 2.6.19 (drovetto)
+	+ Função 'wf_debug' que exibe informações relevantes para o desenvolvedor de processos Workflow (drovetto)
+	+ Classes 'CachedLDAP' e 'wf_cached_ldap' que implementam um sistema de cache de LDAP. Um dos usos destas classes, é a possibilidade de consultar informações de usuários que não mais estão no LDAP (drovetto)
+	+ Inserido uso do cache Ldap nas interfaces de Organograma e Perfis (drovetto)
+	+ Incluido visualizador de imagens na interface de edição de código, aba resources (drovetto)
+	+ Criado link para contrair / expandir a seção de dados cadastrais de processos, na interface de administração. O mesmo foi feito para a insterface de administração de atividades (drovetto)
+	+ Incluída pergunta de confirmação (sim ou não) quando o usuário solicitar a exclusão de um processo (drovetto)
+
+[1.6.02.000]
+	* A query que gera a caixa de entrada foi reescrita para minimizar seu tempo de execução e maximizar a utilização de bind (drovetto)
+	+ Funcionalidade de remoção de instâncias finalizadas que estão listadas na interface de monitoramento (drovetto)
+	+ Possibilidade de monitoramento de instâncias finalizadas (sejam completadas ou abortadas) (drovetto)
+	* Mudança no sistema de arquivos dos processos (e aplicações externas). Agora, cada processo possui seu próprio diretório de 'resources' e os arquivos nele contidos não são "visíveis" diretamente pelo navegador web (drovetto)
+	* A busca pelo nome do usuário na interface do Organograma (tanto a de usuário quanto a administrativa) agora é feita em todas as OUs (drovetto)
+	+ Possibilidade de destacar, por categoria, os funcionários listados na interface de usuário do Organograma (drovetto)
+	+ Listagem de funcionários de acordo com sua categoria na interface de usuário do Organograma (drovetto)
+	+ Funcionalidade de envio de e-mails para os usuários que estão com as instâncias listadas na interface de monitoramento (drovetto)
+	+ Funcionalidade de filtragem na na interface de monitoramento, com 8 filtros diferentes que podem ser combinados como desejado (drovetto)
+	+ Funcionalidade na interface de monitoramento para substituição de um usuário por outro para as instâncias de um determinado processo, incluindo restrição por atividade (drovetto)
+
+[1.6.01.000]
+	+ Inclusão de hook_home, para listar as aplicações externas na página home do Expresso (niltonneto)
+	+ Função 'wf_read_file' para fazer leitura de arquivos no resources dos processos (drovetto)
+	+ Atualizador automático da lista de instâncias da interface de Tarefas Pendentes (drovetto)
+	+ Funcionalidade que permite visualizar a atividade view de um processo (quando houver) na aba de Acompanhamento (drovetto)
+	+ Ação de listagem da lista de centros de custo na interface de Organograma, do usuário (drovetto)
+	+ Interface para administração de categorias de funcionário no Organograma. A interface de funcionário foi modificada para trabalhar com a nova coluna que referencia a categoria a qual o funcionário pertence. Adequação dos métodos da classe 'wf_orgchart' para tratar as novas informações (drovetto)
+	+ Possibilidade de visualizar uma instância na interface de 'Monitoramento' (drovetto)
+	+ Interface para administração de cargos no Organograma. A interface de funcionário foi modificada para trabalhar com duas novas colunas (drovetto)
+	* A interface de 'Monitoramento' foi refeita para que minimizasse a utilização de DOM. Removeu-se dados duplicados e dados não utilizados que eram enviados por Ajax. Disponibilizada a paginação das instâncias listadas nesta interface (drovetto)
+	+ Novo método setInstanceProperty na classe wf_engine (rufino)
+	+ Novo método getRoleIdByName na classe wf_role (rufino)
+	+ Tabela 'cargo' (e alterações na tabela 'funcionario' para incluir chave estrangeira da nova tabela e coluna com informação de níveis) para uso no Organograma. Adequação dos métodos da classe 'wf_orgchart' para tratar as novas informações (rufino)
+
+[1.6.00.000]
+	+ Nova versão da interface de 'Acompanhamento' que não utiliza imagens permitindo uma renderização mais rápida (drovetto)
+	* Interface de 'Acompanhamento' foi reescrita para não utilizar DOM e também para reduzir a quantidade de dados trafegados por Ajax (drovetto)
+	+ Nova versão da interface de 'Tarefas Pendentes' que não utiliza imagens permitindo uma renderização mais rápida (drovetto)
+	* Interface de 'Tarefas Pendentes' foi reescrita para não utilizar DOM e também para reduzir a quantidade de dados trafegados por Ajax (drovetto)
+	* Substituição do termo 'Caixa de Entrada' por 'Tarefas Pendentes' (viani)
+	+ Possibilidade de integração dos Workflows de diferentes instalações do ExpressoLivre. Inclui outras alterações menores (drovetto)
+	+ Classe "BrowserInfo" que obtém informações sobre o navegador e o sistema operacional do usuário. Desenvolvida por Gary White. Foram feitas algumas modificações (drovetto)
+	+ Método "sendFile" na classe "BaseModel" que permite ao desenvolvedor enviar aquivos para download (drovetto)
+	* Correção de bug que, em alguns casos, atribuía um usuário a uma instância que deveria estar disponível para todos, ou seja, '*'. Esta alteração também removeu o comportamento da engine que atribuía uma instância diretamente a um usuário caso ele fosse o único que pudesse executá-la (drovetto e rufino)
+	+ Métodos "getParent" e "unlockParent" na classe "WfRuntime". O primeiro método retorna o ID da instância e da atividade que está travado pela instância atual, se houver. O segundo destrava a instância pai, se houver (drovetto)
+	+ Método "getActivityInformationByID" da classe "wf_engine" que traz informações sobre uma atividade a partir de seu ID (drovetto)
+
+[1.4.06.000]
+	- Arquivos que não estavam sendo utilizados, em sua maioria relacionados à interface antiga (drovetto)
+		inc/class.bo_uiinstance.inc.php
+		inc/class.bo_user_forms.inc.php
+		inc/class.ui_admininstance.inc.php
+		inc/class.ui_adminprocesses.inc.php
+		inc/class.ui_useractivities.inc.php
+		inc/class.ui_useropeninstance.inc.php
+		inc/class.ui_userprocesses.inc.php
+		inc/class.ui_userviewinstance.inc.php
+		inc/fake_translation.inc.php
+		templates/default/user_activities.tpl
+		templates/default/user_instances_advanced.tpl
+		templates/default/user_instances.tpl
+		templates/default/user_openinstance.tpl
+		templates/default/user_processes.tpl
+		templates/default/user_viewinstance.tpl
+	+ Opção para ocultar as aplicações externas que só são acessíveis através da Intranet. Também foi criada uma nova configuração do Workflow onde são especificadas as subredes da Intranet (drovetto)
+	- Opção para dar acesso de administrador de processos Workflow na interface de administração antiga (drovetto)
+	+ Interface para inclusão de administradores de processo, acessível pelo menu "Lista de Controle de Acesso" (drovetto)
+	+ Possibilidade do desenvolvedor exibir mensagens ao final das atividades do processo de Workflow  (drovetto)
+	* Agora o tamanho dos gráficos dos processos é limitado a 2500 pixels para sua maior dimensão (drovetto)
+
+[1.4.05.000]
+	+ Possibilidade de definir a imagem que representa o organograma de uma organização (se estiver em branco, a imagem do organograma é gerada automaticamente) (drovetto)
+	+ Classes PHPlot (para criação de gráficos) e MEM_IMAGE (utilização de imagens em relatórios da FPDF sem necessidade de arquivos temporários), com suas respectivas classes que disponibilizam as funcionalidades para os desenvolvedores de processos Workflow. Contribuição feita por Allan Bomfim (drovetto)
+	- Tabela "egw_wf_instance_supplements" já que não estava sendo utilizada pela engine (drovetto)
+	+ Biblioteca JavaScript, NiftyCube, que arredonda os cantos de elementos XHTML (drovetto)
+	* Corrigida falha que podia permitir que uma instância fosse atribuída a um perfil que não possui acesso à atividade destino (drovetto)
+	+ Opção para que o usuário não veja a tela de "Atividade Concluída". Neste caso, ele é redirecionado para a aba de sua preferência na interface do usuário (drovetto)
+	+ Classe que permite a utilização da engine de templates Smarty no desenvolvimento de interfaces do módulo (drovetto)
+	+ Novo controle dos métodos de definir usuário/perfil para a próxima atividade da instância (inclusive suporte adequado para atividades Split) (drovetto)
+	+ Possibilidade de mover instâncias de um processo para outro. Normalmente, utilizada para o mesmo processo em diferentes versões (drovetto)
+	* O controller para chamadas Ajax do módulo, agora trata sessões expiradas. O método de verificação de erro no JavaScript da interface do usuário, foi modificado (drovetto)
+	+ Alteração da tela de configuração do processo. Incluído um campo para alteração da altura do frame onde é mostrada atividade VIEW na caixa de entrada. (gbisotto)
+	* Alteração da interface da caixa de entrada. Para todas as instancias, somente administradores do processo e administradores do expresso podem ver as properties da instancia. (gbisotto)
+	* Para processos com atividade VIEW, somente é possível vê-la ao clicar no nome do processo. Ao clicar na lupa são mostrados os dados da instancia. (gbisotto)
+	+ Alteração da interface de monitoramento para que sejam mostradas diversas atividades de uma mesma instância (atividades de split), e a possibilidade do usuário poder ordenar de forma ascendente e descendente por todas as colunas, exceto a de ações. (gbisotto)
+	+ Método get_entry_by_email na classe wf_ldap (drovetto)
+	* Utilização de HTTPS (quando suportado pelo servidor) no envio de autenticação para aplicações externas (drovetto)
+	+ Inclusão do método getActivityIdByName na classe wf_role (viani)
+	+ Métodos de gerenciamento de transações (startTrans, completeTrans e failTrans) na classe wf_db (drovetto)
+
+[1.4.04.000]
+	+ Inclusão do arquivo js/jscode/get_form_fields.js que possui uma função para recuperar os campos do formulário cujo id inicia com "_" (asaikawa)
+	* Mudança no layout da interface do usuário, abas Processos e Aplicações Externas (drovetto)
+	+ Coluna no Organograma que permite ocultar funcionários de determinados status (drovetto)
+	* Correção na interface de administração do Organograma que limitava algumas funcionalidades a apenas uma execução (drovetto)
+	* Mudança no comportamento da funcionalidade de continuar instância (forçar fluxo) para que não sejam executadas instâncias onde o dono não está mais no organograma (ou perdeu acesso a ela) (drovetto)
+	+ Busca de instâncias na Caixa de Entrada (drovetto)
+	* Na administração do organograma, lista de usuários e pesquisa, foi incluída a informação de área e uid (drovetto)
+	* Incluído suporte a grupos na lista de controle de acesso - administração de processos (drovetto)
+	* Na interface de usuário, quando fecha uma aba volta para a aba que estava anteriormente (drovetto)
+	* Modificada interface de administração para listar processos em ordem alfabética crescente (drovetto)
+	* Corrigido bug de associação de novo perfil a nova atividade (cassiomaes-viani)
+	- Método "getActivityRoles" da classe "wf_engine". Método equivalente na classe "wf_role" (drovetto)
+	+ Classe "wf_role" que permite ao desenvolvedor manipular os perfis pertencentes ao seu processo (drovetto)
+
+[1.4.03.000]
+	* Alteração na expressão regular para validação de endereço de e-mail (asaikawa)
+	+ Inclusão de expressão regular para validação de telefone com DDI (não obrigatório) e separador podendo ser hífen ou espaço (asaikawa)
+	+ Método get_entry_by_cpf na classe wf_ldap (rufino)
+	- Remoção da ação de monitoramento da lista de ações avançadas da caixa de entrada (cassiomaes)
+	+ Inclusão de ícone para organograma na página de finalização de atividade (cassiomaes)
+	+ Método wf_orgchart::getEmployeesAreaID que recupera todos os funcionários de uma área através do código de identificação dessa área (asaikawa)
+	- Tabela "aplicacao_externa_acl". Estes dados agora são controlados pela tabela "egw_wf_admin_access" (drovetto)
+	* Tabela "aplicacao_externa" migrada para a base de dados do Expresso (drovetto)
+	* Tabela "admin_access" migrada para a base de dados do Expresso (drovetto)
+	+ Interface (Ajax) para controle das Aplicações Externas (drovetto)
+	+ Interface (Ajax) para administração de acesso às Aplicações Externas (drovetto)
+	+ Método ("getActivityRoles") na classe "wf_engine" que retorna os perfis associados a uma atividade (drovetto)
+	* Smarty atualizado para a versão 2.6.18 (drovetto)
+	+ Plugin Smarty (wf_default_template) para inserir cabeçalho e rodapé nos templates dos processos. (rufino, drovetto)
+	+ Inclusão de layout padrão para os processos do workflow abrangendo folhas de estilo (CSS), imagens, cabeçalho e rodapé para os processos (rufino)
+		Inclusão dos arquivos:
+			templates/celepar/processes/default.css
+			templates/celepar/processes/screen.css
+			templates/celepar/processes/header.tpl
+			templates/celepar/processes/footer.tpl
+			templates/celepar/processes/*.{png,gif,jpg}
+	+ Inclusão do método wf_orgchart::getAreas, que recebe por parâmetro uma array de IDs e retorna informações de várias áreas (rufino)
+	- Remoção do pacote SimpleXML (viani)
+	+ Implantação e adaptação do Framework NanoAjax para que seja possível utilizá-lo a partir de processos de Workflow (drovetto)
+	+ Plugin Smarty (wf_ajax_init) que insere os arquivos necessários para a correta utilização do Ajax a partir dos templates (drovetto)
+	+ Função (wf_get_env) que permite ao desenvolvedor do Workflow obter a variável $env (que contém referências às APIs da Engine Workflow), inclusive quando estiver utilizando o Ajax (drovetto)
+	+ Inclusão do método BaseModel::setNameInstance (viani)
+	+ Estatísticas sobre processos na interface de monitoramento (drovetto)
+	+ Plugin Smarty (wf_select_option_multiple) para inserir um componente que trabalhe com multi-inserção de dados categorizados. Os dados podem ser agrupados através de categorias em um selectbox, selecionados e enviados para um listbox (rufino, asaikawa)
+	+ Plugin Smarty (wf_select_duplex) para inserir um componente que facilite a manipulação de varios dados de forma simultânea. O componente trabalha com dois listboxes. Para manipular os dados basta selecioná-los em um listbox e enviá-los para o outro. (asaikawa)
+	+ Médoto wf_db::quote() para realizar tratamento de aspas durante inclusão e alteração de registros quando não for possível a utilizadação do Link_ID do Adodb (rufino)
+	+ Plugin do Smarty para inserir um componente de edição de texto rico (FCKeditor). Foi utilizado, com revisão e alteração de código, o plugin desenvolvido por gazoot (drovetto).
+	+ Nova aba no módulo Workflow para consulta ao organograma (drovetto)
+		inc/class.bo_userinterface.inc.php
+		inc/class.so_userinterface.inc.php
+		inc/class.ui_userinterface.inc.php
+		inc/hook_settings.inc.php
+		js/userinterface/main.js
+		js/userinterface/orgchart.js
+		templates/celepar/userinterface.tpl
+	* Correção de bug que não importava corretamente um processo se o diretório "workflow/resources" não estava criado (drovetto).
+	+ Nova classe para conexão com mainframe (rufino)
+		inc/local/classes/class.wf_natural.php
+		inc/natural/class.natural_resultset.php
+		inc/natural/class.natural.php
+[1.4.02.000]
+	* A listagem de usuários feita pela classe Participants não traz mais os usuários que estão marcados como oculto (drovetto).
+	* Utilização do usuário/senha LDAP do Workflow em conexões com o LDAP para busca de usuários/grupos/listas na classe participants: (drovetto)
+		inc/class.so_participants.inc.php
+	+ Organograma: incluida coluna auxiliar_funcionario_id, na tabela area, para armazenar o código de um usuário encarregado de secretariar a chefia; (drovetto);
+	* Revisada a classe wf_orgchart. Foram modificados os nomes de alguns métodos para algo mais significativo (droveto).
+[1.4.01.000]
+	* A versão de javascript e css utilizada durante a inclusão não é mais definida por um número fixo e sim pelo tamanho de cada arquivo inserido (drovetto)
+	* Modificação da engine do Tigra Menu que possibilita a criação de menus sem tamanho fixo definido (drovetto)
+	* Os menus dos processos Workflow agora podem possuir vários níveis hierárquicos (submenus) (drovetto)
+	* Melhorias no mecanismo de tradução, para eliminar a lentidão na carga das frases. (drovetto)
+	* Modificada a geração do gráfico do processo, para que a seta de transição de uma atividade sem roteamento automático seja grafada em vermelho e no mesmo formato que a seta de atividades de roteamento automático (pretas) (drovetto)
+[1.4.00.001]
+	+ Inclusão de um valor de configuração padrão para o dn e password para conexão com o LDAP (para não utilizar anonymous) (drovetto)
+	* Correção de erro relacionado à falta de configuração (erro de configuração) do banco de dados do Workflow (drovetto)
+	* Atualização da biblioteca js/jscode/wz_dragdrop.js para compatibilidade com o novo módulo Instant Messenger (viani)
+	* Correção de bug na classe inc/class.ui_adminroles.inc.php que gera uma listagem incorreta de nomes e grupos (viani)
+	* Correção na instalação do módulo de Workflow (quando feita pela primeira vez) (drovetto)
+[1.4.00.000]
+	+ Possibilidade de gerar o diagrama do Organograma sob demanda (drovetto)
+	+ Interface de Organograma (Ajax) (drovetto)
+	+ Classe SecurityUtils para proteção contra entrada dos usuários (carloseduardo)
+    + Método BaseController::super() para permitir procedimento comum a camada de controle de um processo (carloseduardo)
+    + Métodos BaseModel::toObject(), BaseModel::fromObject() e BaseModel::inspect() para respectivamente: serializar arrays, desserializar arrays e obter informações sobre classes e objetos (carloseduardo)
+	+ Pacote SimpleXML para PHP 4 que mapeia XML para objetos PHP com flexibilidade (carloseduardo)
+		inc/simplexml
+	+ Classe XmlUtils capaz de mapear XML para e de vetores PHP (carloseduardo)
+		inc/class.utils.xml.php
+	* Atualização da classe Utils com a inclusão do método raiseError para lançamento de erros fatais (carloseduardo)
+		inc/class.utils.php
+	- Removidas opções de monitoramento e instâncias do hook_acl_manager.inc.php (viani)
+	+ Classe "wf_mail" que permite ao desenvolvedor Workflow enviar e-mails em tempo de execução (drovetto)
+		inc/local/classes/class.wf_mail.php
+	+ Plugin do Smarty que insere um campo de texto rico (RTF). Foram feitas modificações no JavaScript para que seja possível inserir mais de um campo deste tipo por página (drovetto)
+		inc/smarty/wf_plugins/function.wf_rtf_init.php
+		inc/smarty/wf_plugins/function.wf_rtf.php
+		js/htmlarea/htmlarea.js
+		js/jscode/rtf.js
+	* Criação de classe gerenciadora de instancias em nível de módulo (carloseduardo)
+		+ /inc/class.factory.inc.php: classe Factory, instancia classes de processo, suportando construtores parametrizados, implementando opcionalmente a unicidade de instâncias por classe (singleton design pattern).
+		* class.basemodel.inc.php: suporte à inclusão da classe Factory.
+		* class.run_activity.inc.php: suporte à inclusão da classe Factory.
+	+ Criação de classes em nível de módulo e processo (carloseduardo)
+		Em nível de módulo:
+			Utils (/inc/class.utils.php): Classe com metodos utilitarios que servem de base para classes mais especificas;
+			StringUtils (/inc/class.utils.string.php): contém funções utilitárias para manipulação de strings;
+			TypeUtils (/inc/class.utils.type.php): Classe que contém funções utilitárias para verificação de tipagem de dados e conversão (cast) entre tipos primitivos de dados no PHP;
+			UrlUtils (/inc/class.utils.url.php): Classe que contém métodos utilitários para a construção e a manipulação de URLs.
+		Em nível de processo:
+			wf_util (/inc/local/classes/class.wf_util.php): subclasse de Utils;
+			wf_string (/inc/local/classes/class.wf_string.php): subclasse de StringUtils;
+			wf_type (/inc/local/classes/class.wf_type.php): subclasse de TypeUtils;
+			wf_url (/inc/local/classes/class.wf_url.php): subclasse de UrlUtils.
+	* Atualização na classe BaseModel (/inc/class.basemodel.inc.php) visando simplificar manutenção ao eliminar a necessidade de declarar constantes para referir-se ao nome das classes de processo, o que levava à necessidade de atualizar a classe toda vez que uma nova classe de processo fosse adicionada (carloseduardo)
+	+ Classe Crontab (/inc/class.crontab.inc.php) agenda jobs para serem executados a partir de um script PHP com o intuito de assegurar, a nível de módulo, que rotinas workflow sejam executadas com precisão (carloseduardo)
+	+ Classe wf_crypt (/inc/local/classes/class.wf_crypt.php), capaz de criptografar e descriptografar strings (carloseduardo)
+	+ Arquivo de configurações do módulo de workflow /inc/config/module.ini começando com a sessão classes e armazenando a chave de criptografia da classe wf_crypt (carloseduardo)
+	+ Possibilidade de adicionar uma descrição detalhada para as instâncias da Caixa de Entrada. Para isto, basta criar uma atividade do tipo "View" (drovetto)
+	* Atualização no padrão de desenvolvimento MVC do módulo de workflow, que agora se encontra organizado em três níveis (carloseduardo)
+		+ módulo: representado pelas classes BaseModel (/inc/class.basemodel.inc.php) e BaseController (/inc/class.basecontroller.inc.php). Neste nível as implementações afetam todos os processos desenvolvidos sob o padrão MVC no módulo de workflow.
+		* processo: representado pelas classes Model e Controller de cada processo workflow MVC, que são subclasses das respectivas classes Base do nível de módulo. Agem somente sobre cada processo individualmente, influenciando portanto as atividades destes processos.
+		* atividade: representado pelas classes Model e Controller de cada atividade dos processos workflow MVC. Responsáveis por receber e atender as requisições do usuário final dos processos.
+	* Fusão das classes do tipo "cel_" com suas respectivas classes (drovetto)
+	* Problemas reportados no processo de compilação, agora são divididos em dois tipos: erros e avisos. Sendo que a ocorrência deste último não invalida um processo (drovetto)
+		inc/class.workflow.inc.php
+		inc/engine/src/common/Base.php
+		inc/engine/src/ProcessManager/ActivityManager.php
+	+ Função "wf_get_next_activity_link" que retorna o link para a próxima atividade da instância que será executada. Caso não seja possível determiná-la, será retornado um link para a Caixa de Entrada (drovetto)
+	* Mudança na engine para permitir que uma atividade (mesmo interativa) seja executada automaticamente e sem interação (drovetto)
+		inc/class.run_activity.inc.php
+	* Adição do método compile na classe cel_ui_adminactivities (/inc/class.cel_ui_adminactivities.inc.php) com a tarefa de validar o código fonte do processo e indicar se houve sucesso ou falhas para o método form (drovetto)
+	+ Classe FsUtils (/inc/class.fsutils.inc.php) com a tarefa de implementar operações com o sistema de arquivos em nível de módulo, inicialmente com os métodos readFolder, para a leitura de diretórios, e getConfig, para leitura de arquivos de configuração (carloseduardo)
+	+ Diretório /inc/config/ para armazenamento de arquivos de configuração *.ini em nível de módulo (carloseduardo)
+	* Envio do conteúdo de /js/local/ para /js/jscode/ e atualizações nos arquivos que os referenciavam (carloseduardo)
+	- Diretório /js/local/. (carloseduardo)
+	+ Classe "wf_engine" que fornece para o desenvolvedor Workflow informações inerentes à engine do Workflow (drovetto)
+		inc/local/classes/class.wf_engine.php
+	* Fusão da classe "cel_run_activity" com a sua superclasse "run_activity". Também foi incrementada a "versão" do JavaScript para 211 (drovetto)
+		inc/class.bo_agent_mail_smtp.inc.php
+		inc/class.cel_run_activity.inc.php
+		inc/class.run_activity.inc.php
+		inc/class.ui_ajaxinterface.inc.php
+		inc/class.ui_monitoractivities.inc.php
+		inc/class.ui_useractivities.inc.php
+		inc/class.ui_userinstances.inc.php
+		inc/class.ui_useropeninstance.inc.php
+		inc/engine/config.egw.inc.php
+		inc/smarty/wf_plugins/function.wf_redir_menu.php
+		inc/smarty/wf_plugins/function.wf_select_city_init.php
+		js/userinterface/inbox.js
+		js/userinterface/processes.js
+		templates/celepar/activity_completed.tpl
+		templates/celepar/leaving_activity.tpl
+	* As permissões de acesso aos procedimentos do monitoramento agora são atribuídas individualmente para cada usuário (drovetto)
+	+ A lista de controle de acesso agora possui um campo que identifica o nível de acesso de um usuário a um recurso (drovetto)
+	* Desenvolvimento de uma nova interface de monitoramento de processos. Também foi criada uma ACL que associa usuários a processos que eles podem monitorar (drovetto)
+	* Migração da tabela admin_access, do banco expresso para workflow. Criada uma nova classe (viani)
+		inc/class.workflow_acl.inc.php
+	+ Plugin do Smarty para abrir página em uma nova janela (viani)
+		inc/smarty/wf_plugins/function.wf_window_open_init.php
+		inc/smarty/wf_plugins/function.wf_window_open.php
+	* Caixa de Entrada agora apresenta uma nova coluna, chamada de "Identificador" (drovetto)
+	+ Plugin do Smarty que insere um campo de formulário para upload de arquivos. Este campo é feito dinamicamente, de forma pode ser utilizado para múltiplos arquivos (drovetto)
+		inc/smarty/wf_plugins/function.wf_file_upload_init.php
+		inc/smarty/wf_plugins/function.wf_file_upload.php
+		js/adminsource/js/wf_file_upload.js
+	* As funções para os processos de Workflow definidas dentro da classe "cel_run_activity" foram movidas para um outro arquivo que agora é incluído na referida classe (drovetto)
+		inc/activity_functions.php
+		inc/class.cel_run_activity.inc.php
+	+ Classe "wf_location" que é acessada nas atividades dos processos do Workflow e que permite ao desenvolvedor obter informações sobre cidades e Estados cadastrados no Banco de Dados (drovetto)
+		js/adminsource/classes/class.wf_location.php
+	+ Plugins do Smarty, "wf_select_state" e "wf_select_city", que permitem a seleção de Estados e cidades do Brasil. No caso das cidades, elas são listadas, através de uma chamada Ajax, de acordo com o Estado selecionado (drovetto)
+		inc/class.bo_utils.inc.php
+		inc/smarty/wf_plugins/function.wf_select_city_init.php
+		inc/smarty/wf_plugins/function.wf_select_city.php
+		inc/smarty/wf_plugins/function.wf_select_state.php
+		js/adminsource/js/wf_select_city.js
+	+ Componente que gera uma lista de seleção de itens que são especificados pelo desenvolvedor de processos Workflow. Composto de dois plugins Smarty ("wf_generic_select" e "wf_generic_select_init") e uma função ("wf_set_generic_select") (drovetto)
+		inc/class.cel_run_activity.inc.php
+		inc/class.ui_generic_select.inc.php
+		inc/smarty/wf_plugins/function.wf_generic_select_init.php
+		inc/smarty/wf_plugins/function.wf_generic_select.php
+		js/adminsource/js/generic_select.js
+		templates/celepar/generic_select.tpl
+	+ Método "exists", disponível nas variáveis "$instance", que verifica se uma dada propriedade existe na instância (drovetto)
+		inc/engine/src/API/Instance.php
+		inc/engine/src/common/WfRuntime.php
+	* Método "get", disponível nas variáveis "$instance", agora aceita um valor padrão para a propriedade requisitada (drovetto)
+		inc/engine/src/API/Instance.php
+		inc/engine/src/common/WfRuntime.php
+	+ Método "clear", disponível nas variáveis "$instance" que tem como função remover atributos da instância (propriedades) que foram definidos com o método "set" (drovetto)
+		inc/engine/src/API/Instance.php
+		inc/engine/src/common/WfRuntime.php
+	+ Classe de paginação "wf_paging" para ser utilizada nos processos de Workflow. Esta classe estende a classe "paging" (drovetto)
+		js/adminsource/classes/class.wf_paging.php
+	* Paginação Ajax da interface de "Caixa de Entrada" e "Acompanhamento" (drovetto)
+		inc/class.bo_userinterface.inc.php
+		js/userinterface/inbox.js
+		js/userinterface/instances_group.js
+		js/userinterface/instances.js
+	+ Classe de paginação "paging". Utilizada para fazer a paginação e gerar seus links (drovetto)
+		inc/class.paging.php
+	+ Plugin do Smarty para gerar um selectbox de atividades start / standalone (viani)
+		inc/smarty/wf_plugins/function.wf_redir_menu.php
+		listagem também incluída nos templates:
+		templates/celepar/activity_completed.tpl
+		templates/celepar/leaving_activity.tpl
+	+ Possibilidade de restringir a próxima atividade de uma instância a somente um perfil e não a todos associados a esta atividade. Esta funcionalidade está disponível através do método "setNextRole", que encontra-se nos objetos "Instance" (drovetto)
+		inc/engine/src/API/Instance.php
+		inc/engine/src/common/WfRuntime.php
+		inc/engine/src/common/WfSecurity.php
+		inc/engine/src/GUI/GUI.php
+	+ Plugin do Smarty para gerar um link genérico ou link de retorno para interface do usuário (viani)
+		inc/smarty/wf_plugins/function.wf_make_link.php
+	+ Plugin do Smarty que insere um componente de seleção vários usuários/grupos (estilo lista) (drovetto)
+		inc/smarty/wf_plugins/function.wf_select_users_init.php
+		inc/smarty/wf_plugins/function.wf_select_users.php
+		js/adminsource/js/userControl.js
+	+ Plugin do Smarty que insere um componente de seleção de usuários (id/e-mail) (drovetto)
+		inc/smarty/wf_plugins/function.wf_select_user_init.php
+		inc/smarty/wf_plugins/function.wf_select_user.php
+	+ Classe "fpdf" para geração de relatórios em PDF (drovetto)
+		inc/fpdf/
+		inc/fpdf/fpdf.php
+		js/adminsource/classes/class.wf_fpdf.php
+	+ Função "wf_handle_download" que gerencia o envio de arquivos para o usuário (drovetto)
+		inc/class.cel_run_activity.inc.php
+	+ Diretório de plugins do Workflow para o Smarty. Incluindo dois plugins: "wf_calendar", que inclui um calendário feito em JavaScript, e "wf_download_link" que gera links de download de arquivos (drovetto)
+		inc/smarty/wf_plugins/
+		inc/smarty/wf_plugins/function.wf_calendar_init.php
+		inc/smarty/wf_plugins/function.wf_calendar.php
+		inc/smarty/wf_plugins/function.wf_download_link.php
+		js/jscalendar/
+		js/jscalendar/calendar.js
+		js/jscalendar/calendar-blue.css
+		js/jscalendar/calendar-br.js
+		js/jscalendar/calendar-en.js
+		js/jscalendar/calendar-setup.js
+	+ Função "wf_write_file" que possibilita a gravação de arquivos dentro do "resources" do processo onde ela é utilizada (drovetto)
+		/inc/class.cel_run_activity.inc.php
+	+ Nova aba no módulo Workflow para acesso a aplicações externas (drovetto)
+		/inc/class.bo_ajaxinterface.inc.php
+		/inc/class.bo_userinterface.inc.php
+		/inc/class.external_bridge.inc.php
+		/inc/class.so_userinterface.inc.php
+		/inc/class.ui_userinterface.inc.php
+		/inc/hook_settings.inc.php
+		/js/userinterface/externals.js
+		/js/userinterface/main.js
+		/templates/celepar/external_bridge.tpl
+		/templates/celepar/userinterface.tpl
+	+ Link para o banco de dados do Workflow (viani)
+		/inc/class.bo_ajaxinterface.inc.php
+	* Reestruturação dos diretórios do Smarty. Cada processo de workflow possui seus diretórios de cache/arquivos compilados (drovetto)
+		/inc/class.cel_run_activity.inc.php
+		/inc/src/ProcessManager/ProcessManager.php
+	- Função "wf_get_uploaded_file" (drovetto)
+		/inc/class.cel_run_activity.inc.php
+	+ Função "wf_get_uploaded_files" que lida com uploads (inclusive múltiplos) nas atividades dos processos (drovetto)
+		/inc/class.cel_run_activity.inc.php
+[1.3.00.000]
+	* Permissão para que uma atividade não interativa defina o usuário para a próxima atividade (drovetto)
+		/inc/engine/src/API/Instance.php
+	+ Consistência de palavras negadas na compilação de atividades (viani)
+		/inc/cel_ui_adminactivities.inc.php
+		/inc/denied_patterns.inc.php
+	+ Parâmetro execute_activities_in_debug_mode no config.tpl (rodrigolira)
+	+ Plugin para caracteres especiais no HtmlArea (rodrigolira)
+		/js/adminsource/js/rtf.js
+		/js/htmlarea/plugins/CharacterMap/
+	* Atualização para a versão 1.3.00.000 (viani)
+	+ Nova funcionalidade para manutenção de organogramas. Inclusão dos arquivos (viani)
+		js/orgchart/
+		templates/celepar/orgchart.tpl
+		inc/class.ui_orgchar.inc.php
+		inc/class.bo_orgchar.inc.php
+		inc/class.so_orgchar.inc.php
+	+ Novo controle de acesso. Inclusão dos arquivos (rodrigolira)
+		js/adminaccess/
+		templates/celepar/adminaccess.tpl
+		inc/class.ui_adminaccess.inc.php
+		inc/class.bo_adminaccess.inc.php
+		inc/class.so_adminaccess.inc.php
+		inc/class.cel_ui_adminprocesses.inc.php
+		inc/class.cel_ui_activities.inc.php
+		Arquivos alterados:
+		inc/cel_workflow_processmanager.inc.php
+		inc/hook_settings.inc.php
+	* Alerta: quando criar uma nova classe cel_ deve-se sobrepor o atributo (rodrigolira)
+		classname, caso haja herança da bo_workflow_forms
+[1.2.01.004]
+	* Atualização para versão 1.2.01.004 (viani)
+	* Permanecem as alterações do release R3, exceto a modificação do config.egw.inc.php que foi
+	  corrigido no projeto original.
+	* Nova inteface de administração de recursos (link 'código' na interface de adm. de processos) (rodrigolira)
+		* inclusão do arquivos:
+			js/adminsource/
+			js/htmleditor/
+			js/phpeditor/
+			js/resourceeditor/
+			inc/class.ajax.inc.php
+			inc/class.bo_editor.inc.php
+			inc/class.cel_bo_adminsource.inc.php
+			inc/class.cel_ui_adminsource.inc.php
+			inc/class.cel_workflow_processmanager.inc.php
+			inc/class.ui_phpeditor.inc.php
+			inc/class.ui_templateeditor.inc.php
+			inc/class.ui_resourceeditor.inc.php
+			templates/celepar/images/ (diversas)
+			templates/celepar/css/editor.css
+			templates/celepar/css/highlight.css
+			templates/celepar/adminsource.tpl
+			templates/celepar/editor_messages.html
+			templates/celepar/editor.html
+			templates/celepar/editor.tpl
+			templates/celepar/templates_editor.tpl
+			templates/celepar/reseditor.html
+			templates/celepar/resource_editor.tpl
+		* alteração dos arquivos:
+			inc/cel_run_activity.inc.php
+			js/jscode/connector.js
+			controller.php
+			cel_workflow_processmanager.inc.php -> inclusão de array para parâmetros de
+				config não exportados (ex. usuário e senha do banco de dados)
+	* Alteração no agente smtp para trocar o nome da atividade pelo nome do processo, no alias do email (rodrigolira)
+		inc\class.cel_bo_agent_mail_smtp.inc.php
+	* Nova interface para associação de usuários/grupos a perfis. Foram incluídas novas frases de
+	  tradução. Incluídos os arquivos (rodrigolira)
+		inc\class.bo_participants.inc.php
+		inc\class.so_participants.inc.php
+		inc\class.ui_participants.inc.php
+		inc\class.cel_ui_adminroles.inc.php
+		js\jscode\participants.js
+	* Inclusão em cel_run_activity (viani)
+		* $GLOBALS['workflow']['wf_user_cnname']
+		* $GLOBALS['workflow']['wf_activity_url']
+		* $GLOBALS['workflow']['wf_workflow_path']
+		* $GLOBALS['workflow']['wf_resources_path']
+		* $GLOBALS['workflow']['wf_normalized_name']
+	* Nova interface do usuário (viani - rodrigolira - mariceli)
+		* Modificado o arquivo inc\engine\src\GUI\GUI.php:
+			* Removidos \n ao final do script (motivo compatibilidade com ajax)
+			* Inclusão do campo gia.wf_started no método gui_list_user_instances (data de inicio da atividade)
+			* Inclusão do método gui_list_intances_by_owner
+		* Novas opções de start_page nas preferências, arquivo inc\hook_settings.inc.php
+		* Novo link para interface do usuário, arquivo inc\hook_sidebox_menu.inc.php
+		* Alteração em index.php para direcionar para a nova interface
+		* Inclusão da chave "loading" na tradução, e outras
+		* movido arquivo js\script_rtf.js para js\jscode\script_rtf.js
+		* Inclusão dos arquivos:
+			controller.php
+			templates\celepar\css\common.css
+			templates\celepar\css\userinterface.css
+			templates\celepar\userinterface.tpl e outros
+			templates\celepar\images\arrow.gif e outras
+			templates\celepar\images\actions\
+			templates\celepar\images\activities\
+			js\jscode\abas.js
+			js\jscode\common_functions.js
+			js\jscode\connector.js
+			js\jscode\doiMenuDOM.js
+			js\jscode\globals.js
+			js\jscode\sniff_browser.js
+			js\userinterface\
+			inc\class.ui_ajaxinterface.inc.php
+			inc\class.ui_userinterface.inc.php
+			inc\class.bo_userinterface.inc.php
+			inc\class.bo_ajaxinterface.inc.php
+			inc\engine\config.ajax.inc.php
+			inc\engine\class.ajax_ldap.inc.php
+			inc\engine\class.ajax_config.inc.php
+	* modificado setup\tables_update.inc.php, na versão 1.2.00.002, para NÃO transformar em negativos os grupos da tabela egw_wf_user_roles	(viani)
+	* alterações na api 0.9.99.015 (viani)
+		inc/class.db.inc.php - inclusão de métodos select, update, delete, etc
+		inc/class.accounts_ldap.inc.php - método read_repository - inclusão do email no vetor de retorno
+		inc/class.schema_proc_pgsql.inc.php - substituido pelo arquivo da versão 1.0.7
+	* inclusão de parâmetros para banco próprio do workflow (viani)
+		/templates/default/config.tpl
+		/inc/class.ui_adminprocesses.inc.php
+		/inc/cel_run_activity.inc.php - incluídas as funções: wf_include wf_get_uploaded_file
+			wf_connect wf_disconnect wf_disconnect_all wf_create_object
+	* alteração em inc/class.bo_editor.inc.php para filtrar strings não permitidas no código do usuário (ex. $GLOBALS fopen fwrite, etc ...) (rodrigolira)
+	* alteração em inc/engine/src/ProcessManager/ProcessManager.php para corrigir bug ao criar arquivo shared.php (rodrigolira)
+[1.2.00.002]
+	* Inclusão do elemento de array $GLOBALS['workflow']['wf_base_url'] no arquivo cel_run_activity (rodrigolira)
+	* Inclusão da variável $wf =& GLOBALS['workflow'] no arquivo cel_run_activity (rodrigolira)
+	* Inclusão do diretório templates/celepar (rodrigolira)
+	* Inclusão do arquivo js/script_rtf.js (funções para iniciar e encerrar htmlarea) (viani)
+    * Adicionada uma linha na api (common_functions.inc.php) para permitir o uso de javascript nas atividades interativas do workflow (vetor egw_unset_var) (rodrigolira)
+	* substituição completa pela versão 1.2.00.002 (viani)
+	* execuçãoo do script unmodernize.php
+	* inclusão do arquivo inc/class.cel_run_activity.inc.php (rodrigolira)
+	* substituição das chamadas a run_activity para cel_run_activity (rodrigolira)
+	* inclusão do Smarty (rodrigolira)
+	* alteração no config.egw.inc.php para buscar grupos do usuário (rodrigolira)
+	* substituição dos hooks
+	* tradução para pt-br (viani)
+	* alteração para buscar grupos do usuário (inc/engine/config.egw.inc.php) (rodrigolira)
+	* alteração para usar smarty (rodrigolira)
+		inc/class.run_activity.php
+		inc/class.workflow_smarty.inc.php
+		inc/smarty/
+[1.2.00.001]
+	* atualização para a versão original do workflow 1.2.00.001 (viani)
+	* executado unmodernize.php nos arquivos abaixo, para compatibilizar com a API 1.0.0 (rodrigolira)
+		index.php
+		inc/*
+		inc/engine/config.egw.inc.php
+	* restaurado os arquivos abaixo, da versão do Workflow 1.1.05.000 (rodrigolira)
+		inc/hook_preferences.inc.php
+		inc/hook_settings.inc.php
+		inc/sidebox_menu.inc.php
+[1.2.00.000]
+	* versão original do workflow 1.2.00.000. Não usar esta versão.
+	* executado unmodernize.php nos arquivos abaixo, para compatibilizar com a API 1.0.0 (rodrigolira)
+		index.php
+		inc/*
+		inc/engine/config.egw.inc.php
+	* restaurado os arquivos abaixo, da versão do Workflow 1.1.05.000 (rodrigolira)
+		inc/hook_preferences.inc.php
+		inc/hook_settings.inc.php
+		inc/sidebox_menu.inc.php
+
Index: /sandbox/workflow/branches/993/doc/readme.txt
===================================================================
--- /sandbox/workflow/branches/993/doc/readme.txt	(revision 795)
+++ /sandbox/workflow/branches/993/doc/readme.txt	(revision 795)
@@ -0,0 +1,12 @@
+Consulte a documentação atualizada do módulo Workflow no endereço:
+
+http://www.expressolivre.org/dev/wiki/WF
+
+Sumário do conteúdo:
+
+    * Bugs
+    * Changelog
+    * Documentação
+    * Links
+    * Propostas
+    * Tarefas e Melhorias
Index: /sandbox/workflow/branches/993/lib/factory/BaseFactory.php
===================================================================
--- /sandbox/workflow/branches/993/lib/factory/BaseFactory.php	(revision 2372)
+++ /sandbox/workflow/branches/993/lib/factory/BaseFactory.php	(revision 2372)
@@ -0,0 +1,184 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Base Factory abstract class.
+ * This class implements all the common behaviour of
+ * it's specialized classes (ProcessFactory and WorkflowFactory).
+ * The only class allowed to use it's methods should be the
+ * Factory frontend.
+ *
+ * @package Factory
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Pedro EugÃªnio Rocha - pedro.eugenio.rocha@gmail.com
+ */
+abstract class BaseFactory {
+
+	/**
+	 * @var array $_fileInfo Store what classes we can instantiate.
+	 * @access private
+	 */
+	private $_fileInfo;
+
+
+	/**
+	 * Registers classes into '$_fileInfo' private
+	 * atribute.
+	 *
+	 * @param string $className Class name.
+	 * @param string $fileName Name of the file that contains the class definition.
+	 * @param string $relativePath The path to the file, relative to $basePath.
+	 * @param string $basePath Base path to append $relativePath. Optional.
+	 * @access protected
+	 * @return void
+	 */
+	protected final function registerFileInfo($className, $fileName, $relativePath, $basePath = WF_SERVER_ROOT) {
+
+		/* default is to override */
+		$this->_fileInfo[$className] = array(	'filename' => $fileName,
+												'path' => $relativePath,
+												'basePath' => $basePath,
+												'instance' => null);
+	}
+
+
+	/**
+	 * Here we should do all the factory stuff.
+	 * The classes instatiated here will be stored
+	 * into our private object cache. If there is no
+	 * object of the given type into the cache, 'newInstance'
+	 * will be called. This method must deal with
+	 * pointers (&) to avoid object duplications.
+	 *
+	 * @param string $className Name of the class.
+	 * @param array $classArgs Parameters to the class's constructor.
+	 * @access public
+	 * @return object
+	 */
+	public function &getInstance($className, $classArgs){
+
+		/* have we a class name? */
+		if (empty($className))
+			return null;
+
+		/* recovering class data */
+		if ($entry = &$this->_getEntry($className)) {
+
+			if (is_null($entry['instance'])) {
+
+				/* we must instantiate it */
+                if (($obj = &$this->newInstance($className, $classArgs)) == null)
+					throw new Exception("Unable to instantiate '".$className."'");
+
+				/* saving the object reference */
+				$this->_setEntryInstance($className, $obj);
+				return $obj;
+			}
+			return $entry['instance'];
+
+		}
+		/* class not allowed */
+		else
+			throw new Exception("You are not allowed to instantiate class '".$className."'.");
+	}
+
+	/**
+	 * Instantiating classes.
+	 *
+	 * @todo Maybe we don't have to use the reflection
+	 *		 class here. Future work...
+	 * @param string $className Name of the class.
+	 * @param array $classArgs Parameters to the class's constructor.
+	 * @access public
+	 * @return object
+	 */
+	public function &newInstance($className, $classArgs){
+
+		/* have we a class name? */
+		if (empty($className))
+			return null;
+
+		/* just to be sure. If this method fails, it will throw an exception anyway... */
+		if(!$this->_import($className))
+			return null;
+
+		/**
+		 * Here we use this big white elephant (by big white elephant I mean php
+		 * reflection interface) just because we have to pass an unknown number
+		 * of parameters to the constructor of the class.
+		 * If you know a better way to do this, please update this code =D
+		 */
+		$reflectionObj = new ReflectionClass($className);
+
+		if (count($classArgs) == 0)
+			return $reflectionObj->newInstance();
+		return $reflectionObj->newInstanceArgs($classArgs);
+	}
+
+
+	/**
+	 * Private stuff. Handles the cache and information
+	 * '$_fileInfo' array.
+	 *
+	 * @param string $className Key to search for into the internal cache.
+	 * @access private
+	 * @return array
+	 */
+	private function &_getEntry($className){
+		return $this->_fileInfo[$className];
+	}
+
+
+	/**
+	 * Stores the given object into the internal cache
+	 * for upcoming requests.
+	 *
+	 * @param string $className Name of the class.
+	 * @param object Object whose reference will be stored.
+	 * @access private
+	 * @return boolean
+	 */
+	private function _setEntryInstance($className, &$obj){
+
+		if (is_array($this->_fileInfo[$className])) {
+			$this->_fileInfo[$className]['instance'] = &$obj;
+			return true;
+		}
+		return false;
+	}
+
+
+	/**
+	 * Including (requiring_once ;P ) the file(s) itself. Ideally,
+	 * it could be the only place to include files.
+	 *
+	 * @param string $className Key to search for into internal cache.
+	 * @access private
+	 * @return boolean
+	 */
+	private function _import($className){
+
+		/* not found */
+		if (!($entry = $this->_getEntry($className)))
+			throw new Exception('You are not allowed to instantiate \''.$className.'\' class.');
+
+		$fullPath = $entry['basePath'] . '/' . $entry['path'] . '/' . $entry['filename'];
+
+		/* file not found */
+		if (!file_exists($fullPath))
+			throw new Exception("File '".$fullPath."' not found.");
+
+		/* including file */
+		require_once $fullPath;
+		return true;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/lib/factory/WorkflowFactory.php
===================================================================
--- /sandbox/workflow/branches/993/lib/factory/WorkflowFactory.php	(revision 2372)
+++ /sandbox/workflow/branches/993/lib/factory/WorkflowFactory.php	(revision 2372)
@@ -0,0 +1,170 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Specialization of the BaseFactory class.
+ * This class is used to instantiate classes by
+ * the workflow module (not by processes). You
+ * cannot access this class directly, but requests
+ * to the Factory frontend class in 'unsecured mode'
+ * will be forwarded to this class.
+ *
+ * @package Factory
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Pedro EugÃªnio Rocha - pedro.eugenio.rocha@gmail.com
+ */
+final class WorkflowFactory extends BaseFactory {
+
+
+	/**
+	 * @var boolean $_instantiated Attribute that stores whether this
+	 *		class was instantiated or not. This is used to limit the
+	 * 		instantiation of this class.
+	 * @access private
+	 * @static
+	 */
+	private static $_instantiated = false;
+
+
+	/**
+	 * Construct the class. This function will inform which classes
+	 * you will be able to instantiate and where to find it.
+	 * This function implements a kind of singleton design pattern too.
+	 * @access public
+	 */
+	public function __construct() {
+
+		/* don't let the user to instantiate this class more than once. */
+		if (self::$_instantiated)
+			throw new Exception("You can't instantiate this class again.");
+
+		/* registering allowed classes */
+		$this->registerFileInfo('WorkflowObjects', 'class.WorkflowObjects.inc.php', 'inc');
+		$this->registerFileInfo('WorkflowWatcher', 'class.WorkflowWatcher.inc.php', 'inc');
+		$this->registerFileInfo('WorkflowLDAP', 'class.WorkflowLDAP.inc.php', 'inc');
+		$this->registerFileInfo('WorkflowSecurity', 'class.WorkflowSecurity.inc.php', 'inc');
+		$this->registerFileInfo('WorkflowMacro', 'class.WorkflowMacro.inc.php', 'inc');
+		$this->registerFileInfo('WorkflowJobManager', 'class.WorkflowJobManager.inc.php', 'inc');
+		$this->registerFileInfo('SecurityUtils', 'class.utils.security.php', 'inc');
+		$this->registerFileInfo('ResourcesRedirector', 'class.ResourcesRedirector.inc.php', 'inc');
+		$this->registerFileInfo('TemplateServer', 'class.TemplateServer.inc.php', 'inc');
+		$this->registerFileInfo('CachedLDAP', 'class.CachedLDAP.inc.php', 'inc');
+		$this->registerFileInfo('BrowserInfo', 'class.BrowserInfo.inc.php', 'inc');
+		$this->registerFileInfo('JobScheduler', 'class.JobScheduler.inc.php', 'inc');
+		$this->registerFileInfo('JobRunner', 'class.JobRunner.inc.php', 'inc');
+		$this->registerFileInfo('Thread', 'class.Thread.inc.php', 'inc');
+		$this->registerFileInfo('Paging', 'class.Paging.inc.php', 'inc');
+		$this->registerFileInfo('FsUtils', 'class.fsutils.inc.php', 'inc');
+		$this->registerFileInfo('UserPictureProvider', 'class.UserPictureProvider.inc.php', 'inc');
+		$this->registerFileInfo('powergraphic', 'class.powergraphic.inc.php', 'inc');
+
+		$this->registerFileInfo('run_activity', 'class.run_activity.inc.php', 'inc');
+		$this->registerFileInfo('process_smarty', 'class.process_smarty.inc.php', 'inc');
+		$this->registerFileInfo('workflow_smarty', 'class.workflow_smarty.inc.php', 'inc');
+		$this->registerFileInfo('workflow_acl', 'class.workflow_acl.inc.php', 'inc');
+		$this->registerFileInfo('workflow_process', 'class.workflow_process.inc.php', 'inc');
+		$this->registerFileInfo('workflow_processmanager', 'class.workflow_processmanager.inc.php', 'inc');
+		$this->registerFileInfo('workflow_wfruntime', 'class.workflow_wfruntime.inc.php', 'inc');
+		$this->registerFileInfo('workflow_gui', 'class.workflow_gui.inc.php', 'inc');
+		$this->registerFileInfo('workflow_rolemanager', 'class.workflow_rolemanager.inc.php', 'inc');
+		$this->registerFileInfo('workflow_baseactivity', 'class.workflow_baseactivity.inc.php', 'inc');
+		$this->registerFileInfo('workflow_activitymanager', 'class.workflow_activitymanager.inc.php', 'inc');
+		$this->registerFileInfo('workflow_instance', 'class.workflow_instance.inc.php', 'inc');
+
+		$this->registerFileInfo('bo_monitors', 'class.bo_monitors.inc.php', 'inc');
+		$this->registerFileInfo('bo_adminaccess', 'class.bo_adminaccess.inc.php', 'inc');
+		$this->registerFileInfo('bo_userinterface', 'class.bo_userinterface.inc.php', 'inc');
+		$this->registerFileInfo('bo_participants', 'class.bo_participants.inc.php', 'inc');
+		$this->registerFileInfo('bo_agent_mail_smtp', 'class.bo_agent_mail_smtp.inc.php', 'inc');
+		$this->registerFileInfo('bo_editor', 'class.bo_editor.inc.php', 'inc');
+		$this->registerFileInfo('bo_utils', 'class.bo_utils.inc.php', 'inc');
+
+		$this->registerFileInfo('so_agent_mail_smtp', 'class.so_agent_mail_smtp.inc.php', 'inc');
+		$this->registerFileInfo('so_external_applications', 'class.so_external_applications.inc.php', 'inc');
+		$this->registerFileInfo('so_adminaccess', 'class.so_adminaccess.inc.php', 'inc');
+		$this->registerFileInfo('so_orgchart', 'class.so_orgchart.inc.php', 'inc');
+		$this->registerFileInfo('so_userinterface', 'class.so_userinterface.inc.php', 'inc');
+		$this->registerFileInfo('so_adminjobs', 'class.so_adminjobs.inc.php', 'inc');
+		$this->registerFileInfo('so_move_instances', 'class.so_move_instances.inc.php', 'inc');
+
+		/* job classes */
+		$this->registerFileInfo('AbsoluteDate', 'class.AbsoluteDate.inc.php', 'inc/jobs');
+		$this->registerFileInfo('RelativeDate', 'class.RelativeDate.inc.php', 'inc/jobs');
+		$this->registerFileInfo('WeekDate', 'class.WeekDate.inc.php', 'inc/jobs');
+
+		/* galaxia engine classes */
+		$this->registerFileInfo('GUI', 'GUI.php', 'inc/engine/src/GUI');
+		$this->registerFileInfo('ProcessManager', 'ProcessManager.php', 'inc/engine/src/ProcessManager');
+		$this->registerFileInfo('ActivityManager', 'ActivityManager.php', 'inc/engine/src/ProcessManager');
+		$this->registerFileInfo('InstanceManager', 'InstanceManager.php', 'inc/engine/src/ProcessManager');
+		$this->registerFileInfo('RoleManager', 'RoleManager.php', 'inc/engine/src/ProcessManager');
+		$this->registerFileInfo('JobManager', 'JobManager.php', 'inc/engine/src/ProcessManager');
+		$this->registerFileInfo('Process_GraphViz', 'GraphViz.php', 'inc/engine/src/ProcessManager');
+		$this->registerFileInfo('ProcessMonitor', 'ProcessMonitor.php', 'inc/engine/src/ProcessMonitor');
+		$this->registerFileInfo('Process', 'Process.php', 'inc/engine/src/API');
+		$this->registerFileInfo('Instance', 'Instance.php', 'inc/engine/src/API');
+		$this->registerFileInfo('Start', 'Start.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('End', 'End.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('Join', 'Join.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('Split', 'Split.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('Standalone', 'Standalone.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('View', 'View.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('SwitchActivity', 'SwitchActivity.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('Activity', 'Activity.php', 'inc/engine/src/API/activities');
+		$this->registerFileInfo('BaseActivity', 'BaseActivity.php', 'inc/engine/src/API');
+
+		$this->registerFileInfo('ajax_ldap', 'class.ajax_ldap.inc.php', 'inc/engine');
+		$this->registerFileInfo('ajax_config', 'class.ajax_config.inc.php', 'inc/engine');
+		$this->registerFileInfo('WfRuntime', 'WfRuntime.php', 'inc/engine/src/common');
+		$this->registerFileInfo('WfSecurity', 'WfSecurity.php', 'inc/engine/src/common');
+
+		/* nano classes */
+		$this->registerFileInfo('Services_JSON', 'JSON.php', 'inc/nano');
+		$this->registerFileInfo('NanoRequest', 'NanoRequest.class.php', 'inc/nano');
+		$this->registerFileInfo('NanoController', 'NanoController.class.php', 'inc/nano');
+		$this->registerFileInfo('NanoJsonConverter', 'NanoJsonConverter.class.php', 'inc/nano');
+		$this->registerFileInfo('NanoSanitizer', 'NanoSanitizer.class.php', 'inc/nano');
+
+		/* registering egw external classes */
+		$this->registerFileInfo('db', 'class.db.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('acl', 'class.acl.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('accounts', 'class.accounts.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('config', 'class.config.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('common', 'class.common.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('session', 'class.session.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('nextmatchs', 'class.nextmatchs.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('categories', 'class.categories.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('listbox', 'class.listbox.inc.php', '', EGW_INC_ROOT);
+		$this->registerFileInfo('phpmailer', 'class.phpmailer.inc.php', '', EGW_INC_ROOT);
+
+		/**
+		 * It can cause some troubles. A class named 'bo' must be instantiated by a
+		 * Factory::getInstance('bo') call, that isn't really intuitive.. Something to
+		 * think about...
+		 */
+		$this->registerFileInfo('bo', 'class.bo.inc.php', 'emailadmin/inc', EGW_SERVER_ROOT);
+
+
+		/**
+		 * TODO - This is a veeery big workaround to maintain compatibility with
+		 * processes that uses the old non-static factory. So, we made this wrapper
+		 * (adapter) that just calls the new and cute static factory class in the
+		 * right way. It should be removed as soon as possible.
+		*/
+		$this->registerFileInfo('ProcessWrapperFactory', 'ProcessWrapperFactory.php', 'lib/factory/');
+
+
+		/* ok. no more instances of this class.. */
+		self::$_instantiated = true;
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/lib/factory/ProcessFactory.php
===================================================================
--- /sandbox/workflow/branches/993/lib/factory/ProcessFactory.php	(revision 2372)
+++ /sandbox/workflow/branches/993/lib/factory/ProcessFactory.php	(revision 2372)
@@ -0,0 +1,78 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Specialization of the BaseFactory class.
+ * This class is used to instantiate classes for
+ * processes. You cannot access this class directly,
+ * but requests to the Factory frontend class in
+ * 'secured mode' will be forwarded to this class.
+ * It should be much more restrictive than its
+ * older brother (or sister), WorkflowFactory...
+ *
+ * @package Factory
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Pedro EugÃªnio Rocha - pedro.eugenio.rocha@gmail.com
+ */
+final class ProcessFactory extends BaseFactory {
+
+
+	/**
+	 * @var boolean $_instantiated Attribute that stores whether this
+	 *		class was instantiated or not. This is used to limit the
+	 * 		instantiation of this class.
+	 * @access private
+	 * @static
+	 */
+	private static $_instantiated = false;
+
+	/**
+	 * Construct the class. This function will inform which classes
+	 * you will be able to instantiate and where to find it.
+	 * This function implements a kind of singleton design pattern too.
+	 * @access public
+	 */
+	public function __construct() {
+
+		/* don't let the user to instantiate this class more than once. */
+		if (self::$_instantiated)
+			throw new Exception("You can't instantiate this class again.");
+
+		/* registering allowed classes */
+		$this->registerFileInfo('wf_cached_ldap', 'class.wf_cached_ldap.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_crypt', 'class.wf_crypt.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_date', 'class.wf_date.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_db', 'class.wf_db.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_engine', 'class.wf_engine.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_fpdf', 'class.wf_fpdf.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_instance', 'class.wf_instance.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_ldap', 'class.wf_ldap.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_location', 'class.wf_location.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_log', 'class.wf_log.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_mail', 'class.wf_mail.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_mem_image', 'class.wf_mem_image.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_natural', 'class.wf_natural.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_orgchart', 'class.wf_orgchart.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_paging', 'class.wf_paging.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_phplot', 'class.wf_phplot.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_regex', 'class.wf_regex.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_role', 'class.wf_role.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_string', 'class.wf_string.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_type', 'class.wf_type.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_url', 'class.wf_url.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_util', 'class.wf_util.php', 'inc/local/classes');
+		$this->registerFileInfo('wf_workitem', 'class.wf_workitem.php', 'inc/local/classes');
+
+		/* ok. no more instances of this class.. */
+		self::$_instantiated = true;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/lib/factory/Factory.php
===================================================================
--- /sandbox/workflow/branches/993/lib/factory/Factory.php	(revision 2372)
+++ /sandbox/workflow/branches/993/lib/factory/Factory.php	(revision 2372)
@@ -0,0 +1,153 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * The Factory frontend class.
+ * This class controls which concrete Factory
+ * will be used, depending on the current
+ * 'security mode'. It lazy instantiates both
+ * factories (process and module) when they are
+ * required, and stores these objects. All the
+ * accesses to factories are done through this class,
+ * implementing a kind of Proxy design pattern.
+ * This class depends on Security frontend class
+ * to decide which factory to call.
+ *
+ * @package Factory
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Pedro EugÃªnio Rocha - pedro.eugenio.rocha@gmail.com
+ */
+class Factory {
+
+
+	/**
+	 * @var object $_unsecuredFactory Stores WorkflowFactory object.
+	 * @access private
+	 * @static
+	 */
+	private static $_unsecuredFactory = null;
+
+
+	/**
+	 * @var object $_securedFactory Stores ProcessFactory object.
+	 * @access private
+	 * @static
+	 */
+	private static $_securedFactory = null;
+
+
+	/**
+	 * Constructor. Just disable direct instantiation.
+	 *
+	 * @access public
+	 * @return void
+	 * @static
+	 */
+	public function __construct() {
+		throw new Exception("Oops! Static only class.");
+	}
+
+
+	/**
+	 * Just forward this call.
+	 *
+	 * @access public
+	 * @return object
+	 * @static
+	 */
+	public static function &getInstance() {
+
+		$args = func_get_args();
+		return self::_callMethod(__FUNCTION__, $args);
+	}
+
+
+	/**
+	 * Just forward this call.
+	 *
+	 * @access public
+	 * @return object
+	 * @static
+	 */
+	public static function &newInstance() {
+
+		$args = func_get_args();
+		return self::_callMethod(__FUNCTION__, $args);
+	}
+
+
+	/**
+	 * Selecting the proper factory to call. This function
+	 * should never be called with a random $methodName. Allowed
+	 * values are 'getInstance' and 'newInstance'.
+	 *
+	 * @param string $methodName Name of the BaseFactory method to call.
+	 * @param array $args Parameters to class's constructor.
+	 * @access private
+	 * @return object
+	 * @static
+	 */
+	private static function &_callMethod($methodName, $args) {
+
+		/* security off (module space) */
+		if (!Security::isEnabled()) {
+
+			/* it must be instatiated */
+			if (is_null(self::$_unsecuredFactory))
+				self::$_unsecuredFactory = new WorkflowFactory();
+
+			$className = array_shift($args);
+			return self::$_unsecuredFactory->$methodName($className, $args);
+		}
+		/* oops. we are in the process space (restricted). */
+		else {
+
+			/* it must be instatiated */
+			if (is_null(self::$_securedFactory))
+				self::$_securedFactory = new ProcessFactory();
+
+			$className = array_shift($args);
+
+			/**
+			 * If the class is not allowed, we must check who is trying
+			 * to instantiate it. If it's a module guy, let's allow him.
+			 * Throw up the exception otherwise.
+			 */
+			try {
+				$obj = &self::$_securedFactory->$methodName($className, $args);
+			}
+
+			/**
+			 * We are erroneously catching any exceptions. We should catch only the 'class not allowed'
+			 * types of exceptions. To do so, a custom exception class must be defined.
+		 	 */
+			catch(Exception $e) {
+
+				/**
+				 * Here we are using depth 2 in isSafeDir method, because we are on a private
+				 * method. Thus, we need to know if the "caller's caller's" function is on a
+				 * safe dir, instead of the direct caller's method.
+				 */
+				if (Security::isSafeDir(2))
+					$obj = &self::$_unsecuredFactory->$methodName($className, $args);
+
+				/* naaasty one. take this! */
+				else
+					throw($e);
+			}
+
+			// finally
+			return $obj;
+		}
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/lib/factory/ProcessWrapperFactory.php
===================================================================
--- /sandbox/workflow/branches/993/lib/factory/ProcessWrapperFactory.php	(revision 2372)
+++ /sandbox/workflow/branches/993/lib/factory/ProcessWrapperFactory.php	(revision 2372)
@@ -0,0 +1,61 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * This class is temporary. We just need to use it until all the
+ * processes are updated and using our new static factory. The
+ * only purpose of this class is to forward the calls to our
+ * frontend factory class. Formally, it's an Adapter Design Pattern.
+ *
+ * @package Factory
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Pedro EugÃªnio Rocha - pedro.eugenio.rocha@gmail.com
+ */
+class ProcessWrapperFactory
+{
+
+	/**
+	 * Just forward the call.
+	 *
+	 * @access public
+	 * @return object
+	 */
+	public function &getInstance() {
+
+		$args = func_get_args();
+
+		/**
+		 * To save memory and processing, we store caches of objects instantiated
+		 * by the factory. When we use this beautiful function (call_user_func_array),
+		 * it makes an unexpected copy of the object. Of course we don't want it.
+		 * For now, we will keep doing copies.
+		 */
+		return call_user_func_array(array(Factory, "getInstance"), $args);
+
+	}
+
+
+	/**
+	 * Just forward the call.
+	 *
+	 * @access public
+	 * @return object
+	 */
+	public function &newInstance() {
+
+		$args = func_get_args();
+
+		/* read the comment above */
+		return call_user_func_array(array(Factory, "newInstance"), $args);
+
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/lib/security/Security.php
===================================================================
--- /sandbox/workflow/branches/993/lib/security/Security.php	(revision 2372)
+++ /sandbox/workflow/branches/993/lib/security/Security.php	(revision 2372)
@@ -0,0 +1,112 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Security class for Workflow module.
+ * You should never forget to call 'enable'
+ * public method to enable security before
+ * executing process code.
+ *
+ * @package Security
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Pedro EugÃªnio Rocha - pedro.eugenio.rocha@gmail.com
+ */
+class Security {
+
+	/**
+	 * @var boolean $_protection Stores the current security mode.
+	 * @access private
+	 * @static
+	 */
+	private static $_protection = false;
+
+
+	/**
+	 * Disallow the instantiation of this class.
+	 * @access public
+	 * @return void
+	 */
+	public function __construct() {
+		throw new Exception("Oops! Static only class.");
+	}
+
+
+	/**
+	 * Returns the current security mode.
+	 * @access public
+	 * @return boolean
+	 * @static
+	 */
+	public static function isEnabled() {
+		return self::$_protection;
+	}
+
+
+	/**
+	 * Change to secured mode.
+	 * @access public
+	 * @return boolean
+	 * @static
+	 */
+	public static function enable() {
+
+		if (self::isSafeDir())
+			self::$_protection = true;
+		else
+			throw new Exception('You are not allowed to change the security mode.');
+		return true;
+	}
+
+	/**
+	 * Change to unsecured mode.
+	 * @access public
+	 * @return boolean
+	 * @static
+	 */
+	public static function disable() {
+
+		if (self::isSafeDir())
+			self::$_protection = false;
+		else
+			throw new Exception('You are not allowed to change the security mode.');
+		return true;
+	}
+
+
+	/**
+	 * Implements the security validation.
+	 * This function tell us if a fileName is on a safe directory.
+	 * For safe dir we mean that no process code exists under it.
+	 * The 'depth' parameter specifies the deepness of the file that
+	 * we are validating. Default value is to validate the imediate
+	 * previous function.
+	 *
+	 * @param integer $depth The deepness of the fileName in backtrace.
+	 * @access public
+	 * @return boolean
+	 * @static
+	 */
+	public static function isSafeDir($depth = 1) {
+
+		/* our backtrace based policy */
+		$backtrace = debug_backtrace();
+		$originFile = $backtrace[$depth]['file'];
+
+		if (empty($originFile))
+			return false;
+
+		/* if $fileName is a file under our server root, then it's safe. */
+		if (substr_compare($originFile, EGW_SERVER_ROOT, 0, strlen(EGW_SERVER_ROOT)) == 0)
+			return true;
+		return false;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/redirect.php
===================================================================
--- /sandbox/workflow/branches/993/redirect.php	(revision 2372)
+++ /sandbox/workflow/branches/993/redirect.php	(revision 2372)
@@ -0,0 +1,15 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+require_once 'inc/common.inc.php';
+if (empty($_SESSION))
+	exit(0);
+Factory::getInstance('ResourcesRedirector')->redirect();
+?>
Index: /sandbox/workflow/branches/993/controller.php
===================================================================
--- /sandbox/workflow/branches/993/controller.php	(revision 2372)
+++ /sandbox/workflow/branches/993/controller.php	(revision 2372)
@@ -0,0 +1,88 @@
+<?php
+	if (file_exists('../header.session.inc.php')) {
+		require_once '../header.session.inc.php';
+	}
+
+	/* if there is no session, abort the Ajax call */
+	if (empty($_SESSION))
+	{
+		$output = array(
+			'error' => 'Sua sessão expirou. É necessário logar-se novamente.',
+			'url' => '../login.php');
+		die(serialize($output));
+	}
+
+	if (!isset($_SESSION['phpgw_info']['workflow']['server_root']))
+	{
+		require_once dirname(__FILE__) . '/inc/common.inc.php';
+		Factory::getInstance('WorkflowMacro')->prepareEnvironment();
+	}
+
+	//	Explode action from cExecuteForm function
+	$cExecuteFormReturn = false;
+ 	
+	if($_POST['_form_data']) { 		
+ 		list($app,$class,$method) = explode('.',@$_POST['_form_data']);
+ 		$cExecuteFormReturn = true;
+ 	}
+	else if($_POST['_action']) { 		
+ 		if($_FILES) {
+ 			$count_files = $_POST['countFiles'];
+			$array_files = array(); 		
+ 			for($idx = 1; $idx <= $count_files; $idx++) { 		
+ 				if($_FILES['file_'.$idx] && !$_FILES['file_'.$idx]['error'])
+ 					$array_files[] = $_FILES['file_'.$idx]; 					 
+ 			}
+ 			$_POST['FILES'] = $array_files;
+ 		} 		  		
+ 		list($app,$class,$method) = explode('.',@$_POST['_action']);
+ 		$cExecuteFormReturn = true;
+ 	}
+ 	//	Explode action from cExecute function
+ 	else if($_GET['action'])
+		list($app,$class,$method) = explode('.',@$_GET['action']);
+	// NO ACTION
+	else
+		return $_SESSION['response'] = 'false';
+	
+	// Load dinamically class file.
+	if($app == '$this')
+		$filename = 'inc/class.'.$class.'.inc.php';
+	else
+		$filename = '../'.$app.'/inc/class.'.$class.'.inc.php';
+		
+	include_once($filename);	
+	
+	// Create new Object  (class loaded).	
+	$obj = new $class;
+	
+	// Prepare parameters for execution.	
+	$params = array();
+	
+	// If array $_POST is not null , the submit method is POST. 
+	if($_POST) {
+		$params = $_POST;
+	}
+	// If array $_POST is null , and the array $_GET > 1, the submit method is GET.
+	else if(count($_GET) > 1)	{		
+		array_shift($_GET);
+		$params = $_GET;
+	}
+
+	$result = array();
+	
+	
+	// if params is not empty, then class method with parameters.	
+	if($params)
+		$result = $obj -> $method($params);
+	else 		
+		$result = $obj -> $method();
+		
+	// Return result serialized.	
+	
+
+	if(!$cExecuteFormReturn)
+		echo serialize($result);
+	else
+		$_SESSION['response'] = $result;
+?>
Index: /sandbox/workflow/branches/993/inc/class.basecontroller.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.basecontroller.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.basecontroller.inc.php	(revision 795)
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Manage workflow module processes providing support for MVC architecture by controlling the process flow.
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.3
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class BaseController 
+{	
+	/* begin attributes declaration */
+
+	/**
+     * @var object $view Holds view layer instance 
+     * @access public
+     */		
+	var $view = null;
+
+	/**
+     * @var string $templateFile Template file reference 
+     * @access public
+     */
+	var $templateFile = null;       
+
+	/**
+     * @var object $model Holds model layer instance
+     * @access public
+     */
+	var $model = null;
+
+	/* ends attributes declaration */
+	/**
+     * Base controller layer constructor
+     * 
+     * @access public
+     * @param object $model Model layer instance for activities business logic
+     * @return void
+     * @param array $env MVC environment settings
+     */
+	function BaseController(&$model , &$env) {
+		/* Gets other layers instances for controlling them */
+		$this->view          =&  $env['view'];
+		$this->templateFile  =&  $env['template_file'];
+		$this->model         =&  $model;
+	}
+	/* begin methods declaration */
+	
+    /**
+     * Shows requested interface (template)
+     * @param string $file Template file to be presented
+     * @return void
+     * @access public
+     */
+	function showForm($file) {
+		$this->templateFile = $file;
+	}
+   /**
+    * Assigns all model's attributes into view layer
+    * @return void.
+    * @access public
+    */
+	function syncVars()	{           
+		/* retrieves only process attributes */		
+		$processVars = $this->model->getAttributes();
+		
+		/* makes synchronization */
+		foreach ( $processVars as $var => $value ) {
+			$this->assign($var, $value);
+		}
+	}
+	
+   /** 
+    * Fills view vars with registered vars from model layer
+    * @return void      
+    * @access public
+    */
+    function loadViewVars() {   	
+		foreach ( $this->model->viewData as $var => $value ) {
+			$this->assign($var, $value);
+		}
+    }
+   
+   /**
+    * Assigns value to a view var
+    * @param string $var Template var name to be assigned
+    * @param mixed $value Value assigned
+    * @return void
+    * @access public 
+    */
+	function assign($var, $value) {   	
+		if (!empty($this->view))
+	        $this->view->assign($var, $value);
+    }   
+    
+   /**
+    * Halts activities execution
+    * @return void
+    * @access public
+    */
+	function cancelar() {		
+		$this->model->setWfProperty($this->model->CANCELAR , true);
+	}    
+
+   /**
+    * Normalizes methods names replacing upper case letters by lower case ones,  
+    * blank spaces by underline chars and non-english chars by english ones.  
+    * @return string normalized method name
+    * @access public
+    */
+	function getNormalizedAction($str) {
+		$ts = array("/[À-Å]/", "/Æ/", "/Ç/", "/[È-Ë]/", "/[Ì-Ï]/", "/Ð/", "/Ñ/", "/[Ò-ÖØ]/", "/×/", "/[Ù-Ü]/", "/Ý/", "/ß/", "/[à-å]/", "/æ/", "/ç/", "/[è-ë]/", "/[ì-ï]/", "/ð/", "/ñ/", "/[ò-öø]/", "/÷/", "/[ù-ü]/", "/[ý-ÿ]/");
+		$tn = array("A", "AE", "C", "E", "I", "D", "N", "O", "X", "U", "Y", "ss", "a", "ae", "c", "e", "i", "d", "n", "o", "x", "u", "y");
+		$output = strtolower(preg_replace($ts, $tn, $str));
+		while ($i = strpos($output, ' '))
+			$output = substr_replace($output, strtoupper($output[$i+1]), $i, 2);
+		return $output;
+	}
+	
+   /**
+    * Searches and runs requested action's implementation in model layer
+    * @param string $action Requested action
+    * @return void
+    * @access public
+    */
+	function dispatch($action)
+	{
+		$action = $this->getNormalizedAction($action);
+    	if (method_exists($this, $action))
+    		$this->{$action}();
+    	else
+    		$this->__default();
+	}
+
+   /**
+    * Default activities action
+    * @return void
+    * @access public
+    */
+	function __default() {}
+	
+   /** 
+    * Runs activity. It must be implemented in activities controller classes 
+    * @abstract
+    * @param string $action Requested action
+    * @return void
+    * @access public
+    */    
+    function run($action) {}
+
+   /**
+    * Provides constructor access to its subclasses for processes startup settings
+    * @param object $model Model layer instance for activities business logic
+    * @param array $env MVC environment settings 
+    * @return void
+    * @access public
+    */
+    function super(&$model , &$env) {
+        BaseController::BaseController(&$model , &$env);
+    } 
+	/* ends method declarations */
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_processmonitor.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_processmonitor.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_processmonitor.inc.php	(revision 2372)
@@ -0,0 +1,22 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessMonitor' . SEP . 'ProcessMonitor.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_processmonitor extends ProcessMonitor
+	{   /**
+		 * Construtor da classe workflow_processmonitor
+		 * @access public
+		 * @return object
+		 */
+		function workflow_processmonitor()
+		{
+			parent::ProcessMonitor(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_utils.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_utils.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_utils.inc.php	(revision 2372)
@@ -0,0 +1,146 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'class.bo_ajaxinterface.inc.php';
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class bo_utils extends bo_ajaxinterface
+{
+	/**
+	 * @var object $db
+	 * @access public
+	 */
+	var $db;
+	/**
+	 * Construtor da classe bo_utils
+	 * @return object
+	 * @access public
+	 */
+	function bo_utils()
+	{
+		parent::bo_ajaxinterface();
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBExpresso();
+	}
+
+	/**
+	 * Retorna as cidades de um estado
+	 * @param array $params parametros
+	 * @return array Array com IDs e nomes das cidades
+	 * @access public
+	 */
+	function get_cities($params)
+	{
+		$output = array();
+		$output['target'] = $params['target'];
+		$state_id = $params['state_id'];
+		$sql = "SELECT id_city, city_name FROM phpgw_cc_city WHERE id_state = $state_id ORDER BY city_name";
+		$result = $this->db->query($sql);
+		$output['cities'] = array();
+		while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
+			$output['cities'][] = array(
+									'id' => $row['id_city'],
+									'name' => $row['city_name']);
+		return $output;
+	}
+
+	/**
+	 * Retorna a lista de registros encontrados no LDAP cujo cn contenha o parâmetro digitado
+	 * @param array $params parametros
+	 * @return array Array com o nome da combo onde devem ser carregados os resultados da busca, com
+	 *				 um array com IDs e names dos registros encontrados e/ou uma mensagem de erro.
+	 * @access public
+	 */
+	function search_ldap_users_by_cn($params)
+	{
+		// parâmetro a ser procurado no ldap
+		$cn = trim(ereg_replace(' +', ' ', $params['cn']));
+
+		$output           = array();
+		$output['target'] = $params['target'];
+		$output['values'] = array();
+		$output['msg']    = "";
+
+		// verifica se o nome digitado contém apenas letras e/ou espaços
+		if(eregi("^[a-z -]*$", $cn)){
+			if (strlen($cn) < 3)
+			{
+				$output['msg'] = 'Por favor, utilize pelo menos 3 caracteres em sua busca.';
+				return $output;
+			}
+			// atributo a ser retornado como id da option, se não for passado este parâmetro, usar 'dn'
+			$ret_id   = empty($params['id']) ? 'dn' : $params['id'];
+
+			// atributo a ser retornado como name da option, se não for passado este parâmetro, usar 'cn'
+			$ret_name = empty($params['name']) ? 'cn' : $params['name'];
+
+			$ajaxConfig = &Factory::newInstance('ajax_config', 'contactcenter');
+			$config = $ajaxConfig->read_repository();
+
+			$ldapconfig['host'] = $config['cc_ldap_host0'];
+			$ldapconfig['basedn'] = $config['cc_ldap_context0'];
+			$usuario = $config['cc_ldap_browse_dn0'];
+			$senha = $config['cc_ldap_pw0'];
+
+			if($usuario != "" && $senha != ""){
+				$ds = ldap_connect($ldapconfig['host']);
+
+				ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
+				ldap_set_option($ds, LDAP_OPT_REFERRALS, 1);
+
+				$lbind = @ldap_bind($ds, $usuario, $senha);
+
+				$filter     = '(&(uid=*)(phpgwAccountType=u)(!(phpgwAccountVisible=-1))(cn=*' . $cn . '*))';
+				$attrib_ret = array('cn', $ret_id, $ret_name);
+
+				$r = ldap_search($ds, $ldapconfig['basedn'], $filter, $attrib_ret, 0, 0, 5);
+
+				if($r){
+					if(ldap_count_entries($ds, $r) == 0){
+						$output['msg'] = 'Não foram encontrados registros.';
+					}
+					elseif(ldap_count_entries($ds, $r) < 200){
+						$result = ldap_get_entries($ds, $r);
+						foreach($result as $value){
+							$output['values'][] = array(
+								'id'   => $value[$ret_id],
+								'name' => trim(ucwords(strtolower($value[$ret_name][0]))));
+						}
+
+
+						foreach ($output['values'] as $key => $value){
+							$nome[$key] = $value['name'];
+							$ids[$key] = $value['id'];
+						}
+						// faz ordenação de um array multidimensional
+						array_multisort($nome, SORT_ASC, $ids, SORT_ASC, $output['values']);
+					}
+					else{
+						$output['msg'] = 'Foram encontrados mais de 200 registros, por favor, refine sua pesquisa.';
+					}
+				}
+				else{
+					$output['msg'] = 'Não foram encontrados registros.';
+				}
+
+				ldap_close($ds);
+			}
+		}
+		else{
+			$output['msg'] = 'Não digite caracteres especiais nem números. Apenas letras e espaços são permitidos.';
+		}
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.run_activity.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.run_activity.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.run_activity.inc.php	(revision 2372)
@@ -0,0 +1,892 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare                                                               *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+	require_once(dirname(__FILE__) . SEP . 'common.inc.php'); 				 /* including common deifinitions */
+	require_once(dirname(__FILE__) . SEP . 'class.WorkflowUtils.inc.php'  ); /* superclass source code       */
+	require_once(dirname(__FILE__) . SEP . 'class.basecontroller.inc.php' ); /* module controller            */
+	require_once(dirname(__FILE__) . SEP . 'class.basemodel.inc.php'      ); /* module logic                 */
+
+	/**
+	 * @package Workflow
+	 * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+	 * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+	 * @author Carlos Eduardo Nogueira Goncalves - cadu.br@gmail.com
+	 * @license GPL
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+     */
+	class run_activity extends WorkflowUtils
+	{  	
+		/**
+		 * @var array  $public_functions func
+		 * @access public
+		 */
+		var $public_functions = array(
+			'go'	=> true,
+			'goAjax'  => true
+		);
+		/**
+		 * @var object $runtime Runtime Object from the workflow engine
+		 * @access public
+		 */
+		var $runtime;
+		// This is the object we'll be running to obtain the rigth activity
+		//var $base_activity;
+		//This is the right activity object
+		/**
+		 * @var object $activity Activity engine object.
+		 * @access public
+		 */
+		var $activity;
+		/**
+		 * @var object $process Process engine object. Used to retrieve at least paths and configuration values
+		 * @access public
+		 */
+		var $process;	
+		/**
+		 * @var object $GUI  GUI engine object. Act carefully with it.
+		 * @access public
+		 */
+		var $GUI;
+		/**
+		 * @var array $message a message array
+		 * @access public
+		 */
+		var $message = Array();
+		/**
+		 * @var object $categories categorie object for categories 
+		 * @access public
+		 */
+		var $categories;
+		/**
+		 * @var array $conf 
+		 * @access public
+		 */
+		var $conf = array();	
+		/**
+		 * @var $wf_template local activity template
+		 * @access public
+		 */
+		var $wf_template;
+		/** 
+		 * @var object $instance
+		 * @access public
+		 */
+		var $instance;
+		/** 
+		 * @var object $activity_type The type of activity
+		 * @access public
+		 */
+		var $activity_type;
+		// then we retain all usefull vars as members, to make them avaible in user's source code
+		// theses are data which can be set before the user code and which are not likely to change because of the user code
+		/** 
+		 * @var int $process_id The process id 
+		 * @access public
+		 */
+		var $process_id;
+		/** 
+		 * @var int $activity_id The activity id 
+		 * @access public
+		 */
+		var $activity_id;
+		/** 
+		 * @var int $process_name The process name
+		 * @access public
+		 */
+		var $process_name;
+		/** 
+		 * @var int $process_version The process_version 
+		 * @access public
+		 */
+		var $process_version;
+		/** 
+		 * @var int $activity_name The process id 
+		 * @access public
+		 */
+		var $activity_name;
+		/** 
+		 * @var int $user_name The user name 
+		 * @access public
+		 */
+		var $user_name;
+		/** 
+		 * @var int $view_activity activity id of the view activity avaible for this process 
+		 * @access public
+		 */
+		var $view_activity;
+		// theses 4 vars aren't avaible for the user code, they're set only after this user code was executed		
+		/** 
+		 * @var int $instance_id Instance id 
+		 * @access public
+		 */
+		var $instance_id=0;
+		/** 
+		 * @var string $instance_name Instance name 
+		 * @access public
+		 */
+		var $instance_name='';
+		/** 
+		 * @var int $instance_owner Instance owner id 
+		 * @access public
+		 */
+		var $instance_owner=0;
+		/** 
+		 * @var string $owner_name Owner name 
+		 * @access public
+		 */
+		var $owner_name='';
+		
+		/**
+		 * @var bool $print_mode print mode
+		 * @access public
+		 */
+		var $print_mode = false;
+		/**
+		 * @var bool $enable_print_mode print mode
+		 * @access public
+		 */
+		var $enable_print_mode = false;
+		
+		/**
+		 * @var array $act_role_names of roles associated with the activity, usefull for lists of users associated with theses roles
+		 * @access public	
+		 */
+		var $act_role_names= Array();
+		
+		/**
+		 * @var array $agents Array of ui_agent objects
+		 * @access public
+		 */
+		var $agents = Array();
+
+		/* CELEPAR */
+		/**
+		 * @var object $smarty holds a Smarty instance
+		 * @access public
+		 */
+		var $smarty;                
+		/**
+		 * @var array $wf holds a global environment vector
+		 * @access public
+		 */
+		var $wf;                    
+		/**
+		 * @var $download_mode activates download mode
+		 * @access public
+		 */
+		var $download_mode;        
+		/**
+		 * @var string $_template_name holds the template's file name
+		 * @access public
+		 */
+		var $_template_name = null; 
+		/**
+		 * @var bool Indicates wether the current instance is a child instance or not
+         * @access public
+         */
+		var $isChildInstance = false;
+
+		private $workflowSmarty = null;
+		/* CELEPAR */
+		/**
+		 * Constructor
+		 * 
+		 * @access public 
+		 */
+		function run_activity()
+		{
+			parent::WorkflowUtils();
+
+			/**
+			 * We should always use newInstance to instantiate
+			 * 'workflow_wfruntime'
+			 */
+			$this->runtime			= &Factory::newInstance('workflow_wfruntime');
+			$this->runtime->setDebug(_DEBUG);
+			//$this->base_activity	= Factory::getInstance('workflow_baseactivity');
+			//$this->process		= Factory::getInstance('workflow_process');
+			$this->GUI				= &Factory::getInstance('workflow_gui');
+			$this->categories 		= &Factory::getInstance('categories');
+
+			$this->workflowSmarty 	= &Factory::getInstance('workflow_smarty', false);
+			// TODO: open a new connection to the database under a different username to allow privilege handling on tables
+			/* CELEPAR */
+			unset($this->db);
+		}
+
+		/**
+		  * This function is used to run all activities for specified instances. it could be interactive activities
+		  * or automatic activities. this second case is the reason why we return some values
+		  * @param int $activityId is the activity_id it run
+		  * @param int $iid is the instance id it run for
+		  * @param $auto is true by default
+		  * @return mixed AN ARRAY, or at least true or false. This array can contain :
+		  * a key 'failure' with an error string the engine will retrieve in instance error messages in case of
+		  *	failure (this will mark your execution as Bad),
+		  * a key 'debug' with a debug string the engine will retrieve in instance error messages,
+		  */
+		function go($activity_id=0, $iid=0, $auto=0)
+		{
+			$result=Array();
+
+			if ($iid)
+			{
+				$_REQUEST['iid'] = $iid;
+			}
+			$iid = $_REQUEST['iid'];
+
+			//$activity_id is set when we are in auto mode. In interactive mode we get if from POST or GET
+			if (!$activity_id)
+			{
+				$activity_id	= (int)get_var('activity_id', array('GET','POST'), 0);
+			}
+
+			// load activity and instance
+			if (!$activity_id)
+			{
+				$result['failure'] =  $this->runtime->fail(lang('Cannot run unknown activity'), true, _DEBUG, $auto);
+				return $result;
+			}
+
+			//initalising activity and instance objects inside the WfRuntime object
+			if (!($this->runtime->loadRuntime($activity_id,$iid)))
+			{
+				$result['failure'] = $this->runtime->fail(lang('Cannot run the activity'), true, _DEBUG, $auto);
+				return $result;
+			}
+
+			$activity =& $this->runtime->getActivity($activity_id, true, true);
+			$this->activity =& $activity;
+			// the instance is avaible with $instance or $this->instance
+			// note that for standalone activities this instance can be an empty instance object, but false is a bad value
+			//$this->instance =& $this->runtime->loadInstance($iid);
+
+			// HERE IS A BIG POINT: we map the instance to a runtime object
+			// user code will manipulate a stance, thinking it's an instance, but it is
+			// in fact a WfRuntime object, mapping all instance functions
+			$this->instance =& $this->runtime;
+			$instance =& $this->instance;
+			$GLOBALS['workflow']['wf_runtime'] =& $this->runtime;
+			if (!($instance))
+			{
+				$result['failure'] = $this->runtime->fail(lang('Cannot run the activity without instance'), true, _DEBUG, $auto);
+				return $result;
+			}
+			$this->instance_id = $instance->getInstanceId();
+
+			// load process
+			$this->process =& $this->runtime->getProcess();
+			if (!($this->process))
+			{
+				$result['failure'] = $this->runtime->fail(lang('Cannot run the activity without her process').$instance, true, _DEBUG, $auto);
+				return $result;
+			}
+
+			//set some global variables needed
+			$GLOBALS['workflow']['__leave_activity']=false;
+			$GLOBALS['user'] = $GLOBALS['phpgw_info']['user']['account_id'];
+
+			//load role names, just an information
+			$this->act_role_names = $activity->getActivityRoleNames();
+
+			//set some other usefull vars
+			$this->activity_type	= $activity->getType();
+			$this->process_id 	= $activity->getProcessId();
+			$this->activity_id 	= $activity_id;
+			$this->process_name	= $this->process->getName();
+			$this->process_version	= $this->process->getVersion();
+			$this->activity_name	= $activity->getName();
+			$this->user_name   		= $GLOBALS['phpgw']->accounts->id2name($GLOBALS['user']);
+			$this->view_activity	= $this->GUI->gui_get_process_view_activity($this->process_id);
+
+			//we set them in $GLOBALS['workflow'] as well
+			$GLOBALS['workflow']['wf_activity_type']			=& $this->activity_type;
+			$GLOBALS['workflow']['wf_process_id'] 				=& $this->process_id;
+			$GLOBALS['workflow']['wf_activity_id'] 				=& $this->activity_id;
+			$GLOBALS['workflow']['wf_process_name']				=& $this->process_name;
+			$GLOBALS['workflow']['wf_normalized_name']			=  $this->process->getNormalizedName();
+			$GLOBALS['workflow']['wf_process_version']			=& $this->process_version;
+			$GLOBALS['workflow']['wf_activity_name']			=& $this->activity_name;
+			$GLOBALS['workflow']['wf_user_name']				=& $this->user_name;
+			$GLOBALS['workflow']['wf_user_id']					=& $GLOBALS['user'];
+			$GLOBALS['workflow']['wf_view_activity']			=& $this->view_activity;
+			$GLOBALS['workflow']['wf_webserver_url'] 			= $GLOBALS['phpgw_info']['server']['webserver_url'];
+			$GLOBALS['workflow']['wf_workflow_path']			= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'workflow';
+			$GLOBALS['workflow']['wf_resources_path']			= $GLOBALS['phpgw_info']['server']['webserver_url'] . SEP . 'workflow/redirect.php?pid=' . $this->process_id . '&file=';
+			$GLOBALS['workflow']['wf_default_resources_path']	= Factory::getInstance('TemplateServer')->generateLink('processes');
+			$GLOBALS['workflow']['wf_workflow_resources_path']	= Factory::getInstance('TemplateServer')->generateLink('');
+			$GLOBALS['workflow']['wf_activity_url']				= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'index.php?menuaction=workflow.'.get_class($this).'.go&activity_id='.$activity_id;
+			$GLOBALS['workflow']['wf_user_cnname']				= Factory::getInstance('WorkflowLDAP')->getName($GLOBALS['user']);
+			$GLOBALS['workflow']['wf_back_link']				= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'workflow'.SEP.'index.php?start_tab=1';
+			$GLOBALS['workflow']['wf_js_path']					= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'workflow'.SEP.'js'.SEP.'jscode';
+			$GLOBALS['workflow']['wf_user_activities']			= $this->GUI->gui_list_user_activities($GLOBALS['user'], '0', '-1', 'ga.wf_name__ASC', '', '', false, true, true, true, '');
+			if ($iid)
+				$GLOBALS['workflow']['wf_instance_url']	= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'index.php?menuaction=workflow.'.get_class($this).'.go&activity_id='.$activity_id."&iid=".$iid;
+			else
+				unset($GLOBALS['workflow']['wf_instance_url']);
+			$wf =& $GLOBALS['workflow'];
+
+			/* CELEPAR */
+			/* path to the local functions developed by Celepar */
+			$functions = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'local' . SEP . 'functions' . SEP . 'local.functions.php';
+
+			/* activate local functions */
+			require_once($functions);
+			/* CELEPAR */
+
+			//get configuration options with default values if no init was done before
+			$myconf = array(
+				'execute_activities_in_debug_mode'	=> 0,
+				'execute_activities_using_secure_connection' => 0
+			);
+			//this will give use asked options and som others used by WfRuntime
+			$this->conf =& $this->runtime->getConfigValues($myconf);
+			if ($this->conf['execute_activities_using_secure_connection'])
+			{
+				if (($GLOBALS['phpgw_info']['server']['use_https'] > 0) && ($_SERVER['HTTPS'] != 'on') && (!isset($GLOBALS['workflow']['job']['processID'])))
+				{
+					header("Location: https://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
+					exit;
+				}
+			}
+
+			if ($auto && (!$this->isChildInstance) && $activity->isInteractive())
+			{
+				$actualUser = $GLOBALS['user'];
+				$actualUserGroups = $_SESSION['phpgw_info']['workflow']['user_groups'];
+				foreach ($instance->instance->activities as $actTmp)
+				{
+					if ($actTmp['wf_activity_id'] == $activity_id)
+					{
+						$newUser = $actTmp['wf_user'];
+						break;
+					}
+				}
+
+				/* pretend to be the user */
+				$_SESSION['phpgw_info']['workflow']['user_groups'] = galaxia_retrieve_user_groups($newUser);
+				$_SESSION['phpgw_info']['workflow']['account_id'] = $newUser;
+				$GLOBALS['phpgw_info']['user']['account_id'] = $newUser;
+				$GLOBALS['workflow']['wf_user_id'] = $newUser;
+				$GLOBALS['user'] = $newUser;
+
+				/* check some permissions */
+				if (($newUser == '*') || (!$this->runtime->checkUserRun($newUser)) || (Factory::getInstance('WorkflowLDAP')->getName($newUser) === false))
+				{
+					$_SESSION['phpgw_info']['workflow']['user_groups'] = $actualUserGroups;
+					$_SESSION['phpgw_info']['workflow']['account_id'] = $actualUser;
+					$GLOBALS['phpgw_info']['user']['account_id'] = $actualUser;
+					$GLOBALS['workflow']['wf_user_id'] = $actualUser;
+					$GLOBALS['user'] = $actualUser;
+
+					return false;
+				}
+				$smarty = Factory::getInstance('process_smarty');
+			}
+
+			// run the activity
+			//interactive section
+			if (!$auto && $activity->isInteractive())
+			{
+
+				$this->print_mode = get_var('print_mode', array('POST','GET'), false);
+				$this->download_mode = get_var('download_mode', array('POST','GET'), false);
+
+				/* #celepar# smarty code*/
+
+				$smarty = Factory::getInstance('process_smarty');
+
+				$smarty->template_dir  = GALAXIA_PROCESSES.SEP.$this->process->getNormalizedName().SEP.'code'.SEP.'templates';
+				$smarty->compile_dir   = GALAXIA_PROCESSES.SEP.$this->process->getNormalizedName().SEP.'smarty'.SEP.'compiled';
+				$smarty->config_dir    = GALAXIA_PROCESSES.SEP.$this->process->getNormalizedName().SEP.'code'.SEP.'templates';
+				$smarty->cache_dir     = GALAXIA_PROCESSES.SEP.$this->process->getNormalizedName().SEP.'smarty'.SEP.'cache';
+				$smarty->plugins_dir[] = PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'smarty'.SEP.'wf_plugins';
+
+				$GLOBALS['phpgw']->template =& $smarty;
+				$this->wf_template =& $smarty;
+				$_template_name = null;
+
+				//set resource path to use in templates
+				$smarty->assign('wf_resources_path',$GLOBALS['workflow']['wf_resources_path']);
+				$smarty->assign('wf_default_resources_path', $GLOBALS['workflow']['wf_default_resources_path']);
+				$smarty->assign('wf_workflow_resources_path', $GLOBALS['workflow']['wf_workflow_resources_path']);
+				$smarty->assign('wf_workflow_path',$GLOBALS['workflow']['wf_workflow_path']);
+				$smarty->assign('wf_js_path',$GLOBALS['workflow']['wf_js_path']);
+				$smarty->assign('wf_back_link',$GLOBALS['workflow']['wf_back_link']);
+				$smarty->assign('wf_activity_url',$GLOBALS['workflow']['wf_activity_url']);
+				
+				/* register the prefilter smarty plugin wf_default_template */
+				$smarty->load_filter('pre', 'wf_default_template');
+			}
+
+			if ($this->conf['execute_activities_in_debug_mode'])
+			{
+				ini_set('display_errors',true);
+				error_reporting(E_ALL & ~E_NOTICE);
+			}
+
+			/* BEGIN WORKFLOW MVC SETTINGS */
+			$env = array( );                                           //create settings vector
+			$env['view']          =& $smarty;                          //view layer instance
+			$env['template_file'] =& $_template_name;                  //template file to be shown
+			$env['dao']           =& wf_create_object('wf_db');        //data access object instance
+			$env['workflow']      =& $GLOBALS['workflow'];             //workflow environment information
+			$env['instance']      =& $instance;                        //process manager instance
+			$env['activity']      =& $activity;                        //activity manager instance
+			$security             =& Factory::newInstance('SecurityUtils');              //input sanitizer class
+			$env['request']       =& $security->process($_REQUEST);    //sanitizes input data from client
+			//$env['factory']       =& new ProcessFactory();             //instantiation controller class
+			$env['factory']       =& Factory::getInstance('ProcessWrapperFactory');  //instantiation controller class
+			$env['natural']		  =& wf_create_object('wf_natural');   //data access object instance for mainframe
+			/* END WORKFLOW MVC SETTINGS */
+
+			$GLOBALS['workflow_env'] = &$env;
+			//echo "<br><br><br><br><br>Including $source <br>In request: <pre>";print_r($_REQUEST);echo "</pre>";
+			//[__leave_activity] is setted if needed in the xxx_pre code or by the user in his code
+			// HERE the user code is 'executed'. Note that we do not use include_once or require_once because
+			//it could the same code several times with automatic activities looping in the graph and it still
+			//need to be executed
+			$_engineProcessCodeDirectory = GALAXIA_PROCESSES . SEP . $this->process->getNormalizedName(). SEP . 'code';
+			$_engineCompilerDirectory = GALAXIA_LIBRARY . SEP . 'compiler';
+			$_engineFiles = array();
+
+			/* generate the list of needed files */
+			$_engineFiles[] = "{$_engineProcessCodeDirectory}/shared.php";
+			$_engineFiles[] = "{$_engineCompilerDirectory}/_shared_pre.php";
+			$_engineFiles[] = "{$_engineCompilerDirectory}/{$activity->getType()}_pre.php";
+			if ($activity->getAgents() !== false)
+				$_engineFiles[] = "{$_engineCompilerDirectory}/agents_pre.php";
+			$_engineFiles[] = "{$_engineProcessCodeDirectory}/activities/{$activity->getNormalizedName()}.php";
+			$_engineFiles[] = "{$_engineCompilerDirectory}/{$activity->getType()}_pos.php";
+			if ($activity->getAgents() !== false)
+				$_engineFiles[] = "{$_engineCompilerDirectory}/agents_pos.php";
+			$_engineFiles[] = "{$_engineCompilerDirectory}/_shared_pos.php";
+
+			/* check if the required files exists */
+			foreach ($_engineFiles as $_engineFile)
+				if (!file_exists($_engineFile))
+					return array('failure' => $this->runtime->fail(lang('the following file could not be found: %1', $_engineFile), true, _DEBUG));
+
+			/* activate the security policy */
+			Factory::getInstance('WorkflowSecurity')->enableSecurityPolicy();
+
+			/**
+			 * XXX
+			 * here we are going to use our new Security static class.
+			 * From now, the factory frontend (static) will forward
+			 * the messages for the process factory instead of Workflow
+			 * factory.
+			 * XXX
+			*/
+			Security::enable();
+
+			/* include the files */
+			foreach ($_engineFiles as $_engineFile)
+				require $_engineFile;
+
+			unset($GLOBALS['workflow_env']);
+
+			/* check if the developer wants to user the download mode */
+			if (isset($GLOBALS['workflow']['downloadMode']) && ($GLOBALS['workflow']['downloadMode'] == true))
+				$this->download_mode = true;
+
+			if ($auto && (!$this->isChildInstance) && $activity->isInteractive() && (!empty($actualUser)))
+			{
+				$_SESSION['phpgw_info']['workflow']['user_groups'] = $actualUserGroups;
+				$_SESSION['phpgw_info']['workflow']['account_id'] = $actualUser;
+				$GLOBALS['phpgw_info']['user']['account_id'] = $actualUser;
+				$GLOBALS['workflow']['wf_user_id'] = $actualUser;
+				$GLOBALS['user'] = $actualUser;
+			}
+
+			//Now that the instance is ready and that user code has maybe change some things
+			// we can catch some others usefull vars
+			$this->instance_id	= $instance->getInstanceId();
+			$this->instance_name	= $instance->getName();
+			$this->instance_owner	= $instance->getOwner();
+			$this->owner_name	= $GLOBALS['phpgw']->accounts->id2name($this->instance_owner);
+			if ($this->owner_name == '')
+			{
+				$this->owner_name = lang('Nobody');
+			}
+			$GLOBALS['workflow']['wf_instance_id'] 	=& $this->instance_id;
+			$GLOBALS['workflow']['wf_instance_name']=& $this->instance_name;
+			$GLOBALS['workflow']['wf_instance_owner']=& $this->instance_owner;
+			$GLOBALS['workflow']['wf_owner_name']=& $this->owner_name;
+
+			//was template changed?
+			if ($_template_name)
+			{
+				$this->_template_name = $_template_name;
+			}
+			else
+			{
+				$this->_template_name = $this->activity->getNormalizedName().'.tpl';
+			}
+
+			// TODO: process instance comments
+
+			$instructions = $this->runtime->handle_postUserCode(_DEBUG);
+			switch($instructions['action'])
+			{
+				//interactive activity completed
+				case 'completed':
+					// re-retrieve instance data which could have been modified by an automatic activity
+					$this->instance_id                = $instance->getInstanceId();
+					$this->instance_name              = $instance->getName();
+					$this->activityCompleteMessage    = $instance->getActivityCompleteMessage();
+
+					if (!$auto)
+					{
+						$this->assignCommonVariables();
+						// and display completed template
+						if ($GLOBALS['phpgw_info']['user']['preferences']['workflow']['show_activity_complete_page'] === '0')
+							header('Location: workflow/index.php');
+						else
+							$this->showCompletedPage();
+					}
+					break;
+				//interactive activity still in interactive mode
+				case 'loop':
+					if (!$auto)
+					{
+						$this->assignCommonVariables();
+						$this->showForm();
+					}
+					break;
+				//nothing more
+				case 'leaving':
+					if (!$auto)
+					{
+						$this->assignCommonVariables();
+						$this->showCancelledPage();
+					}
+					break;
+				//non-interactive activities, auto-mode
+				case 'return':
+					$result=Array();
+					$this->message[] = $this->GUI->get_error(false, _DEBUG);
+					$this->message[] = $this->runtime->get_error(false, _DEBUG);
+					//$this->message[] = $this->process->get_error(false, _DEBUG);
+					$result =& $instructions['engine_info'];
+					$this->message[] = $result['debug'];
+					$result['debug'] = implode('<br />',array_filter($this->message));
+					return $result;
+					break;
+				default:
+					return $this->runtime->fail(lang('unknown instruction from the workflow engine: %1', $instructions['action']), true, _DEBUG);
+					break;
+			}
+		}
+
+		/**
+		 * goajax
+		 *
+		 * @param int $activity_id
+		 * @param int $iid
+		 * @param bool $auto
+		 * @return array
+		 */
+		function goAjax($activity_id=0, $iid=0, $auto=0)
+		{
+			$result=Array();
+
+			if ($iid)
+				$_REQUEST['iid'] = $iid;
+			$iid = $_REQUEST['iid'];
+
+			//$activity_id is set when we are in auto mode. In interactive mode we get if from POST or GET
+			if (!$activity_id)
+				$activity_id	= (int)get_var('activity_id', array('GET','POST'), 0);
+
+			// load activity and instance
+			if (!$activity_id)
+			{
+				$result['failure'] =  $this->runtime->fail(lang('Cannot run unknown activity'), true, _DEBUG, $auto);
+				return $result;
+			}
+
+			//initalising activity and instance objects inside the WfRuntime object
+			if (!($this->runtime->loadRuntime($activity_id,$iid)))
+			{
+				$result['failure'] = $this->runtime->fail(lang('Cannot run the activity'), true, _DEBUG, $auto);
+				return $result;
+			}
+
+			$activity =& $this->runtime->getActivity($activity_id, true, true);
+			$this->activity =& $activity;
+			// the instance is avaible with $instance or $this->instance
+			// note that for standalone activities this instance can be an empty instance object, but false is a bad value
+			// HERE IS A BIG POINT: we map the instance to a runtime object
+			// user code will manipulate a stance, thinking it's an instance, but it is
+			// in fact a WfRuntime object, mapping all instance functions
+			$this->instance =& $this->runtime;
+			$instance =& $this->instance;
+			$GLOBALS['workflow']['wf_runtime'] =& $this->runtime;
+			if (!($instance))
+			{
+				$result['failure'] = $this->runtime->fail(lang('Cannot run the activity without instance'), true, _DEBUG, $auto);
+				return $result;
+			}
+			$this->instance_id = $instance->getInstanceId();
+
+			// load process
+			$this->process =& $this->runtime->getProcess();
+			if (!($this->process))
+			{
+				$result['failure'] = $this->runtime->fail(lang('Cannot run the activity without her process').$instance, true, _DEBUG, $auto);
+				return $result;
+			}
+
+			//set some global variables needed
+			$GLOBALS['user'] = $GLOBALS['phpgw_info']['user']['account_id'];
+
+			//load role names, just an information
+			$this->act_role_names = $activity->getActivityRoleNames();
+
+			//set some other usefull vars
+			$this->activity_type	= $activity->getType();
+			$this->process_id 	= $activity->getProcessId();
+			$this->activity_id 	= $activity_id;
+			$this->process_name	= $this->process->getName();
+			$this->process_version	= $this->process->getVersion();
+			$this->activity_name	= $activity->getName();
+			$this->user_name	= $GLOBALS['phpgw']->accounts->id2name($GLOBALS['user']);
+			$this->view_activity	= $this->GUI->gui_get_process_view_activity($this->process_id);
+
+			//we set them in $GLOBALS['workflow'] as well
+			$GLOBALS['workflow']['wf_activity_type']			=& $this->activity_type;
+			$GLOBALS['workflow']['wf_process_id'] 				=& $this->process_id;
+			$GLOBALS['workflow']['wf_activity_id']		 		=& $this->activity_id;
+			$GLOBALS['workflow']['wf_process_name']				=& $this->process_name;
+			$GLOBALS['workflow']['wf_normalized_name']			=  $this->process->getNormalizedName();
+			$GLOBALS['workflow']['wf_process_version']			=& $this->process_version;
+			$GLOBALS['workflow']['wf_activity_name']			=& $this->activity_name;
+			$GLOBALS['workflow']['wf_user_name']				=& $this->user_name;
+			$GLOBALS['workflow']['wf_user_id']					=& $GLOBALS['user'];
+			$GLOBALS['workflow']['wf_view_activity']			=& $this->view_activity;
+			$GLOBALS['workflow']['wf_workflow_path']			= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'workflow';
+			$GLOBALS['workflow']['wf_resources_path']			= $GLOBALS['phpgw_info']['server']['webserver_url'] . SEP . 'workflow/redirect.php?pid=' . $this->process_id . '&file=';
+			$GLOBALS['workflow']['wf_default_resources_path']	= Factory::getInstance('TemplateServer')->generateLink('processes');
+			$GLOBALS['workflow']['wf_workflow_resources_path']	= Factory::getInstance('TemplateServer')->generateLink('');
+			$GLOBALS['workflow']['wf_activity_url']				= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'index.php?menuaction=workflow.'.get_class($this).'.go&activity_id='.$activity_id;
+			$GLOBALS['workflow']['wf_user_cnname']				= Factory::getInstance('WorkflowLDAP')->getName($GLOBALS['user']);
+			$GLOBALS['workflow']['wf_back_link']				= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'workflow'.SEP.'index.php?start_tab=1';
+			$GLOBALS['workflow']['wf_js_path']					= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'workflow'.SEP.'js'.SEP.'jscode';
+			$GLOBALS['workflow']['wf_user_activities']			= $this->GUI->gui_list_user_activities($GLOBALS['user'], '0', '-1', 'ga.wf_name__ASC', '', '', false, true, true, true, '');
+			if ($iid)
+				$GLOBALS['workflow']['wf_instance_url']	= $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.'index.php?menuaction=workflow.'.get_class($this).'.go&activity_id='.$activity_id."&iid=".$iid;
+			else
+				unset($GLOBALS['workflow']['wf_instance_url']);
+
+			/* CELEPAR */
+			/* activate local functions */
+			require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'local' . SEP . 'functions' . SEP . 'local.functions.php');
+			/* CELEPAR */
+
+			//get configuration options with default values if no init was done before
+			$myconf = array(
+				'execute_activities_in_debug_mode'	=> 0,
+				'execute_activities_using_secure_connection' => 0
+			);
+			//this will give use asked options and som others used by WfRuntime
+			$this->conf =& $this->runtime->getConfigValues($myconf);
+
+			// run the activity
+			if ($this->conf['execute_activities_in_debug_mode'])
+			{
+				ini_set('display_errors',true);
+				error_reporting(E_ALL & ~E_NOTICE);
+			}
+
+			/* BEGIN WORKFLOW MVC SETTINGS */
+			$env = array( );                                           //create settings vector
+			$env['dao']           =& wf_create_object('wf_db');        //data access object instance
+			$env['workflow']      =& $GLOBALS['workflow'];             //workflow environment information
+			$env['instance']      =& $instance;                        //process manager instance
+			$env['activity']      =& $activity;                        //activity manager instance
+			$security             =& Factory::newInstance('SecurityUtils'); //input sanitizer class
+			$env['request']       =& $security->process($_REQUEST); //sanitizes input data from client
+			//$env['factory']       =& new ProcessFactory();			   //instantiation controller class
+			$env['factory']       =& Factory::newInstance('ProcessWrapperFactory');  //instantiation controller class
+			$env['natural']		  =& wf_create_object('wf_natural');   //data access object instance for mainframe
+			/* END WORKFLOW MVC SETTINGS */
+
+			require_once(dirname(__FILE__) . SEP . 'nano' . SEP . 'JSON.php');
+			require_once(dirname(__FILE__) . SEP . 'nano' . SEP . 'NanoUtil.class.php');
+			require_once(dirname(__FILE__) . SEP . 'nano' . SEP . 'NanoJsonConverter.class.php');
+			require_once(dirname(__FILE__) . SEP . 'nano' . SEP . 'NanoRequest.class.php');
+			require_once(dirname(__FILE__) . SEP . 'nano' . SEP . 'NanoController.class.php');
+
+			/* activate the security policy */
+			Factory::getInstance('WorkflowSecurity')->enableSecurityPolicy();
+
+			/**
+			 * XXX
+			 * here we are going to use our new Security static class.
+			 * From now, the factory frontend (static) will forward
+			 * the messages for the process factory instead of Workflow
+			 * factory. Note that this is the same comment as the previous
+			 * function... boooring.. =}
+			 * XXX
+			*/
+			Security::enable();
+
+			$GLOBALS['workflow_env'] = &$env;
+			$nc = &Factory::newInstance('NanoController');
+			$nc->setClassPath(GALAXIA_PROCESSES . SEP . $this->process->getNormalizedName(). SEP . 'code');
+			$nc->iterateOverVirtualRequests();
+			$nc->outputResultData();
+			unset($GLOBALS['workflow_env']);
+
+			if (!is_null($iid))
+				$instance->instance->sync();
+		}
+
+		/**
+		 * Create a child instance
+		 *
+		 * @param int $activityID
+		 * @param mixed $properties
+		 * @param string $user
+		 * @param bool $parentLock
+		 * @return int The instance ID of the just created instance
+		 * @access public
+		 */
+		function goChildInstance($activityID, $properties, $user, $parentLock)
+		{
+			$this->isChildInstance = true;
+			$this->runtime->instance->isChildInstance = true;
+			$this->runtime->instance->activityID = $activityID;
+			$this->runtime->instance->parentLock = $parentLock;
+			$this->runtime->instance->setProperties($properties);
+			if ($user != '*')
+				$this->runtime->setNextUser($user);
+
+			/* run the selected activity */
+			ob_start();
+			$this->go($activityID, 0, true);
+			ob_end_clean();
+
+			/* return the just created child instance */
+			return $this->runtime->instance_id;
+		}
+
+		/**
+		 * Show the page avaible when completing an activity
+		 * @return void
+		 * @access public
+		 */
+		function showCompletedPage()
+		{
+			$this->workflowSmarty->assign('activityEvent', 'completed');
+			$this->showAfterRunningPage();
+		}
+
+		/**
+		 * Show the page avaible when leaving an activity
+		 * @return void
+		 * @access public
+		 */
+		function showCancelledPage()
+		{
+			$this->workflowSmarty->assign('activityEvent', 'cancelled');
+			$this->showAfterRunningPage();
+		}
+
+		/**
+		 * Common code of pages showed after activity pages
+		 * @return void
+		 * @access public
+		 */
+		function showAfterRunningPage()
+		{
+			/* get the header/footer */
+			$this->assignHeader();
+
+			/* generate the activity list */
+			$processActivities = array_filter($GLOBALS['workflow']['wf_user_activities']['data'], create_function('$a', 'return ($a["wf_p_id"] == ' . $GLOBALS['workflow']['wf_process_id'] . ');'));
+			$activityList = array(0 => '-- Selecione uma atividade --');
+			foreach ($processActivities as $processActivity)
+				$activityList[$processActivity['wf_activity_id']] = $processActivity['wf_name'];
+
+			/* assign some variables */
+			$this->workflowSmarty->assign('processName', $this->process_name);
+			$this->workflowSmarty->assign('processVersion', $this->process_version);
+			$this->workflowSmarty->assign('activityName', $this->activity_name);
+			$this->workflowSmarty->assign('activityCompleteMessage', $this->activityCompleteMessage);
+			$this->workflowSmarty->assign('activityBaseURL', $GLOBALS['phpgw_info']['server']['webserver_url']);
+			$this->workflowSmarty->assign('activityList', $activityList);
+
+			/* display the template */
+			$this->workflowSmarty->display('after_running.tpl');
+		}
+
+		/**
+		 * Assign common information of interactive forms (e.g., error messages)
+		 * @return void
+		 * @access public
+		 */
+		function assignCommonVariables()
+		{
+			$this->message[] = $this->GUI->get_error(false, _DEBUG);
+			$this->message[] = $this->runtime->get_error(false, _DEBUG);
+			$activityErrors = array_filter(array_merge(explode('<br />', $this->message[0]), explode('<br />', $this->message[1])));
+			$this->workflowSmarty->assign('activityErrors', $activityErrors);
+		}
+
+		/**
+		 * Show the activity page (workflow template and activity template)
+		 * @return void
+		 * @access public
+		 */
+		function showForm()
+		{
+			/* define the header */
+			$this->assignHeader();
+
+			/* define the variables */
+			$activityOutput = $this->wf_template->fetch($this->_template_name);
+			$actionURL = isset($GLOBALS['workflow']['wf_instance_url']) ? $GLOBALS['workflow']['wf_instance_url'] : $GLOBALS['workflow']['wf_activity_url'];
+			$CSSLink = $this->get_css_link('run_activity', $this->print_mode);
+			$CSSMedia = $this->print_mode ? 'print' : 'all';
+
+			/* assign the variables to smarty */
+			$this->workflowSmarty->assign('activityOutput', $activityOutput);
+			$this->workflowSmarty->assign('actionURL', $actionURL);
+			$this->workflowSmarty->assign('CSSLink', $CSSLink);
+			$this->workflowSmarty->assign('CSSMedia', $CSSMedia);
+
+			$this->workflowSmarty->display('run_activity.tpl');
+			unset($smarty);
+		}
+
+		/**
+		 * Define if the header, footer and navigation bar will be shown
+		 * @return void
+		 * @access public
+		 */
+		function assignHeader()
+		{
+			$headerConfig = 0;
+			if (!$this->download_mode and !$this->print_mode)
+			{
+				$headerConfig |= workflow_smarty::SHOW_HEADER | workflow_smarty::SHOW_FOOTER;
+				if ($this->runtime->activity->child_name != 'View')
+					$headerConfig |= workflow_smarty::SHOW_NAVIGATION_BAR;
+			}
+
+			$this->workflowSmarty->setHeader($headerConfig);
+			$this->workflowSmarty->assign('header', $this->workflowSmarty->expressoHeader);
+			$this->workflowSmarty->assign('footer', $this->workflowSmarty->expressoFooter);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_baseactivity.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_baseactivity.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_baseactivity.inc.php	(revision 2372)
@@ -0,0 +1,22 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'API' . SEP . 'BaseActivity.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */	 
+	class workflow_baseactivity extends BaseActivity
+	{   /**
+		 * Construtor da classe workflow_baseactivity
+		 * @access public
+		 * @return object
+		 */
+		function workflow_baseactivity()
+		{
+			parent::BaseActivity(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_agent_mail_smtp.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_agent_mail_smtp.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_agent_mail_smtp.inc.php	(revision 2372)
@@ -0,0 +1,854 @@
+<?php
+/**************************************************************************\
+* eGroupWare Workflow - Mail SMTP Agent Connector - business layer         *
+* ------------------------------------------------------------------------ *
+* This program is free software; you can redistribute it and/or modify it  *
+* under the terms of the GNU General Public License as published           *
+* by the Free Software Foundation; either version 2 of the License, or     *
+* any later version.                                                       *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.bo_agent.inc.php');
+
+//some define for the send mode
+if (!defined('_SMTP_MAIL_AGENT_SND_COMP')) 		define('_SMTP_MAIL_AGENT_SND_COMP'    , 0);
+if (!defined('_SMTP_MAIL_AGENT_SND_POST')) 		define('_SMTP_MAIL_AGENT_SND_POST'	  , 1);
+if (!defined('_SMTP_MAIL_AGENT_SND_AUTO_PRE')) 	define('_SMTP_MAIL_AGENT_SND_AUTO_PRE', 2);
+if (!defined('_SMTP_MAIL_AGENT_SND_AUTO_POS')) 	define('_SMTP_MAIL_AGENT_SND_AUTO_POS', 3);
+/**
+ * This class connects the workflow agent to the egroupware phpmailer and emailadmin
+ * This let the workflow activities send emails. It contains some logic to replace
+ * known tokens by workflow information (user, owner, activity name, etc...)
+ * 
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author regis.leroy@glconseil.com
+ */	
+class bo_agent_mail_smtp extends bo_agent
+{
+	/**
+	 * @var array $public_functions Public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'bo_agent_mail_smtp'			=> true,
+		'load'							=> true,
+		'save'							=> true,
+		'getAdminActivityOptions'		=> true,
+		'decode_fields_in_final_array' 	=> true,
+	);
+	/**
+	 * @var object $mail the phpmailer object used at runtime to send email
+	 * @access public
+	 */
+	var $mail = null;	
+	/**
+	 * @var object $bo_emailadmin object the emailadmin bo object to retriev egroupware mail configuration
+	 * @access public
+	 */
+	var $bo_emailadmin = null;		
+	/**
+	 * @var integer $profileID profile ID
+	 * @access public
+	 */
+	var $profileID;
+	// some maybe usefull egroupware or engine objects. Vars usefull to create only the first time
+	// to avoid multiple SQL queries
+	/**
+	 * @var object $role_manager Role manager
+	 * @access public
+	 */
+	var $role_manager;
+	/**
+	 * @var object $account The account
+	 * @access public
+	 */
+	var $account;
+	/**
+	 * @var string $process_name The process name 
+	 * @access public
+	 */
+	var $process_name = '';
+	/**
+	 * @var string $process_version The process version 
+	 * @access public
+	 */
+	var $process_version = '';
+	/**
+	 * @var integer $process_id The process id 
+	 * @access public
+	 */
+	var $process_id = '';
+	/**
+	 * @var object $activity_id The activity id
+	 * @access public
+	 */
+	var $activity_id = '';
+	/**
+	 * @var integer $instance_id The instance id
+	 * @access public
+	 */
+	var $instance_id = '';
+	/**
+	 * @var array $final_array array containing part or this->fields recomputed to handle real email address and real values
+	 * @access public
+	 */
+	var $final_array = Array();	
+	/**
+	 * @var boolean $debugmode can be usefull to test mails building without sending them
+	 * @access public
+	 */
+	var $debugmode = false;
+	
+	/**
+	 * Contructor
+	 * @access public
+	 * @return object
+	 */
+	function bo_agent_mail_smtp()
+	{
+		parent::bo_agent();
+		$this->so_agent = Factory::getInstance('so_agent_mail_smtp');
+		$this->bo_emailadmin = Factory::getInstance('bo');
+		//the showProcessConfigurationFields is not done here, quite harder to build
+		$this->ProcessConfigurationFieldsdefault = array(
+			'mail_smtp_profile' 		=> false,
+			'mail_smtp_signature'		=> lang('Mail automatically sent by Mail SMTP Agent for eGroupware\'s Workflow'),
+			'mail_smtp_local_link_prefix'	=> '',
+			'mail_smtp_debug'		=> false,
+		);
+		
+		$this->title = lang('Mail Smtp Agent');
+		$this->description = lang('This agent gives the activity the possibility to send an SMTP message (mail)');
+		$this->help = lang('Use <a href="%1">EmailAdmin</a> to create mail profiles', $GLOBALS['phpgw']->link('/index.php',array('menuaction' => 'emailadmin.ui.listProfiles')));
+		$this->help .= "<br />\n".lang('Mails can be sent at the begining or at the end of the activity, For interactive activities only it can be sent after completion.');
+		$this->help .= "<br />\n".lang('Be carefull with interactive activity, end and start of theses activities are multiple.');
+		$this->help .= "<br />\n".lang('You can use special values with this mail agent:');
+		$this->help .= "<ul>\n";
+		$this->help .=  '<li>'.lang('<strong>%user%</strong> is the instance user email')."\n";
+		$this->help .=  '<li>'.lang('<strong>%owner%</strong> is the instance owner email')."\n";
+		$this->help .=  '<li>'.lang('<strong>%roles%</strong> are the emails of all users mapped to any role on this activity')."\n";
+		$this->help .=  '<li>'.lang('<strong>%role_XX%</strong> are all the emails of all users mapped to the role XX')."\n";
+		$this->help .=  '<li>'.lang('<strong>%user_XX%</strong> is the email of the acount XX')."\n";
+		$this->help .=  '<li>'.lang('<strong>%property_XX%</strong> is the content of the instance\'s property XX')."\n";
+		$this->help .=  '<li>'.lang('<strong>%signature%</strong> is the agent signature defined in the process configuration')."\n";
+		$this->help .=  '<li>'.lang('see as well <strong>%instance_name%</strong>, <strong>%activity_name%</strong>, <strong>%process_name%</strong>,<strong>%process_version%</strong>, <strong>%instance_id%</strong>, <strong>%activity_id%</strong> and <strong>%process_id%</strong>')."\n";
+		$this->help .=  '<li>'.lang('finally you have links with <strong>%link_XX|YY%</strong> syntax, XX is the address part, YY the text part.')."\n";
+		$this->help .= lang('Link addresses are considered local if not containing <strong>http://</strong>. They will get appended the configured local prefix and scanned by egroupware link engine');
+		$this->help .= "</ul>\n";
+		$this->fields = array(
+			'wf_to'		=> array(
+				'type'		=> 'text',
+				'label'		=> lang('To:'),
+				'size'		=> 255,
+				'value'		=> '',
+				),
+			'wf_cc'		=> array(
+				'type'		=> 'text',
+				'label'		=> lang('Cc:'),
+				'size'		=> 255,
+				'value'		=> '',
+				),
+			'wf_bcc'	=> array(
+				'type'		=> 'text',
+				'label'		=> lang('Bcc:'),
+				'size'		=> 255,
+				'value'		=> '',
+				),
+			'wf_from'	=> array(
+				'type'		=> 'text',
+				'label'		=> lang('From:'),
+				'size'		=> 255,
+				'value'		=> '',
+				),
+			'wf_replyto'	=> array(
+				'type'		=> 'text',
+				'label'		=> lang('ReplyTo:'),
+				'size'		=> 255,
+				'value'		=> '',
+				),
+			'wf_subject'	=> array(
+				'type'		=> 'text',
+				'label'		=> lang('Subject:'),
+				'size'		=> 255,
+				'value'		=> '',
+				),
+			'wf_message'	=> array(
+				'type'		=> 'textarea',
+				'label'		=> lang('Message:'),
+				'value'		=> '',
+				),
+			'wf_send_mode'	=> array(
+				'type'	=> 'select',
+				'label'	=> lang('When to send the Message:'),
+				'value' => '',
+				'values'=>  array(
+					_SMTP_MAIL_AGENT_SND_COMP	=> lang('send after interactive activity is completed'),
+					/*_SMTP_MAIL_AGENT_SND_POST	=> lang("send when wf_agent_mail_smtp['submit_send'] is posted"),*/
+					_SMTP_MAIL_AGENT_SND_AUTO_PRE	=> lang("send when the activity is starting"),
+					_SMTP_MAIL_AGENT_SND_AUTO_POS	=> lang("send when the activity is ending"),
+					),
+				),
+		);
+		
+	}
+
+   /**
+	* Factory: Load the agent values stored somewhere in the agent object and retain the agent id
+	* @param int $agent_id is the agent id
+	* @param bool $really_load boolean, true by default, if false the data wont be loaded from database and
+	* the only thing done by this function is storing the agent_id (usefull if you know you wont need actual data)
+	* @return bool  false if the agent cannot be loaded, true else
+	* @access public
+	*/
+	function load($agent_id, $really_load=true)
+	{
+		//read values from the so_object
+		if ($really_load)
+		{
+			$values =& $this->so_agent->read($agent_id);
+			foreach($values as $key => $value)
+			{
+				//load only known fields
+				if (isset($this->fields[$key]))
+				{
+					$this->fields[$key]['value'] = $value;
+					//echo "<br> DEBUG loading value $value for $key";
+				}
+			}
+		}
+		//store the id
+		$this->agent_id = $agent_id;
+	}
+
+	/**
+	 * Save the agent
+	 * @return bool false if the agent cannot be saved, true else
+	 * @access public
+	 */
+	function save()
+	{
+		//make a simplified version of $this->fields with just values
+		$simplefields = Array();
+		foreach ($this->fields as $field => $arrayfield)
+		{
+			$simplefields[$field] = $arrayfield['value'];
+		}
+		return $this->so_agent->save($this->agent_id, $simplefields);
+	}
+	
+	/**
+	 * Lists activity level options avaible for the agent
+	 * @return array an associative array which can be empty
+	 * @access public
+	 */
+	function getAdminActivityOptions ()
+	{
+		return $this->fields;
+	}
+	
+	/**
+	 * This function tell the engine which process level options have to be set
+	 * for the agent. Theses options will be initialized for all processes by the engine
+	 * and can be different for each process.
+	 * @return array an array which can be empty
+	 * @access public
+	 */
+	function listProcessConfigurationFields()
+	{
+		$profile_list = $this->bo_emailadmin->getProfileList();
+		foreach($profile_list as $profile)
+		{
+			$my_profile_list[$profile['profileID']] = $profile['description'];
+		}
+		$this->showProcessConfigurationFields = array(
+			'Mail SMTP Agent' 		=> 'title',
+			'mail_smtp_profile' 		=> $my_profile_list,
+			'mail_smtp_signature'		=> 'text',
+			'mail_smtp_local_link_prefix'	=> 'text',
+			'mail_smtp_debug'		=> 'yesno',
+		);
+		return $this->showProcessConfigurationFields;
+	}
+
+	/**
+	 * Return the SMTP config values stored by the emailadmin egw application
+	 * @return array an associative array containing the'emailConfigValid' token at true if it was ok, and at false else
+	 * @access public
+	 */
+	function getSMTPConfiguration()
+	{
+		$data =Array();
+		$this->profileID = $this->conf['mail_smtp_profile'];
+		$data['emailConfigValid'] = true;
+		//code inspired by felamimail bo_preferences
+		$profileData = $this->bo_emailadmin->getProfile($this->profileID);
+		if(!is_array($profileData))
+		{
+			$data['emailConfigValid'] = false;
+			return $data;
+		}
+		elseif ($this->profileID != $profileData['profileID'])
+		{
+			$this->profileID = $profileData['profileID'];
+		}
+		
+		// set values to the global values
+		$data['defaultDomain']		= $profileData['defaultDomain'];
+		$data['smtpServerAddress']	= $profileData['smtpServer'];
+		$data['smtpPort']		= $profileData['smtpPort'];
+		$data['smtpAuth']		= $profileData['smtpAuth'];
+		$data['smtpType']               = $profileData['smtpType'];
+		$useremail = $this->bo_emailadmin->getAccountEmailAddress($GLOBALS['phpgw_info']['user']['userid'], $this->profileID);
+		$data['emailAddress']           = $useremail[0]['address'];
+		return $data;
+	}
+	
+	/**
+	 * Initialize objects we will need for the mailing and retrieve the conf 
+	 * @return void
+	 * @access public
+	 */
+	function init()
+	{
+		$this->mail = Factory::getInstance('phpmailer');
+		//set the $this->conf
+		$this->getProcessConfigurationFields($this->activity->getProcessId());
+		if ($this->conf['mail_smtp_debug']) $this->debugmode = true;
+		
+	}
+	
+	/**
+	 * Says that we send email on POSTed forms
+	 * @return bool true if the conf says that we send email on POSTed forms, else false.
+	 * @access public
+	 */
+	function sendOnPosted()
+	{
+		return ($this->fields['wf_send_mode']['value']== _SMTP_MAIL_AGENT_SND_POST);
+	}
+	
+	/**
+	 * If this activity is defined as an activity sending the email when starting we'll send it now
+	 * WARNING : on interactive queries the user code is parsed several times and this function is called
+	 * each time you reach the begining of the code, this means at least the first time when you show the form
+	 * and every time you loop on the form + the last time when you complete the code (if the user did not cancel).
+	 * @return bool true if everything was ok, false if something went wrong
+	 * @access public
+	 */
+	function send_start()
+	{
+		if ($this->fields['wf_send_mode']['value']== _SMTP_MAIL_AGENT_SND_AUTO_PRE)
+		{
+			if ($this->debugmode) $this->error[] = 'Sending at the start of the activity';
+			if (!($this->prepare_mail())) return false;
+			return $this->send();
+		}
+		else
+		{
+			if ($this->debugmode) $this->error[] = 'Not sending at the start of the activity';
+			return true;
+		}
+	}
+
+	/**
+	 * If this activity is defined as an activity sending the email when finishing the code we'll send it now
+	 * WARNING : on interactive queries the user code is parsed several times and this function is called
+	 * each time you reach the end of the code without completing, this means at least the first time
+	 * and every time you loop on the form.
+	 * @return bool true if everything was ok, false if something went wrong
+	 * @access public
+	 */
+	function send_end()
+	{
+		if ($this->fields['wf_send_mode']['value']== _SMTP_MAIL_AGENT_SND_AUTO_POS)
+		{
+			if ($this->debugmode) $this->error[] = 'Sending at the end of the activity';
+			if (!($this->prepare_mail())) return false;
+			return $this->send();
+		}
+		else
+		{
+			if ($this->debugmode) $this->error[] = 'Not sending at the end of the activity';
+			return true;
+		}
+	}
+
+	/**
+	 * If this activity is defined as an activity sending the email when the user post a command for it we'll send it now
+	 * @return bool true if everything was ok, false if something went wrong
+	 * @access public
+	 */
+	function send_post()
+	{
+		if ($this->fields['wf_send_mode']['value']== _SMTP_MAIL_AGENT_SND_POST)
+		{
+			if ($this->debugmode) $this->error[] = 'Sending at POST in the activity';
+			if (!($this->prepare_mail())) return false;
+			return $this->send();
+		}
+		else
+		{
+			if ($this->debugmode) $this->error[] = 'Not sending at POST in the activity';
+			return true;
+		}
+	}
+	
+	/**
+	 * If this activity is defined as an activity sending the email when completing we'll send it now
+	 * @return bool true if everything was ok, false if something went wrong
+	 * @access public
+	 */
+	function send_completed()
+	{
+		if ($this->fields['wf_send_mode']['value']== _SMTP_MAIL_AGENT_SND_COMP)
+		{
+			if ($this->debugmode) $this->error[] = 'Sending when completing activity';
+			if (!($this->prepare_mail())) return false;
+			return $this->send();
+		}
+		else
+		{
+			if ($this->debugmode) $this->error[] = 'Not Sending when completing activity';
+			return true;
+		}
+	}
+
+	/**
+	 * Buid the email fields
+	 * @return boolean true ok false error 
+	 * @access public
+	 */
+	function prepare_mail()
+	{
+		$userLang = $GLOBALS['phpgw_info']['user']['preferences']['common']['lang'];
+		$langFile = PHPGW_SERVER_ROOT."/phpgwapi/setup/phpmailer.lang-$userLang.php";
+		if(file_exists($langFile))
+		{
+			$this->mail->SetLanguage($userLang, PHPGW_SERVER_ROOT."/phpgwapi/setup/");
+		}
+		else
+		{
+			$this->mail->SetLanguage("en", PHPGW_SERVER_ROOT."/phpgwapi/setup/");
+		}
+		$this->mail->PluginDir = PHPGW_SERVER_ROOT."/phpgwapi/inc/";
+		$this->mail->IsSMTP();
+		
+		//SMTP Conf
+		$smtpconf =& $this->getSMTPConfiguration();
+		if (!($smtpconf['emailConfigValid']))
+		{
+			$this->error[] = lang('The SMTP configuration cannot be loaded by the mail_smtp workflow agent');
+			return false;
+		}
+		$this->mail->Host 	= $smtpconf['smtpServerAddress'];
+		$this->mail->Port	= $smtpconf['smtpPort'];
+		//SMTP Auth?
+		if ($smtpconf['smtpAuth'])
+		{
+			$this->mail->SMTPAuth	= true;
+			$this->mail->Username	= $GLOBALS['phpgw_info']['user']['userid'];
+			$this->mail->Password	= $GLOBALS['phpgw_info']['user']['passwd'];
+		}
+		
+		$this->mail->Encoding = '8bit';
+		//TODO: handle Charset
+		//$this->mail->CharSet	= $this->displayCharset;
+		$this->mail->AddCustomHeader("X-Mailer: Egroupware Workflow");
+		$this->mail->WordWrap = 76;
+		//we need HTMl for handling nicely links
+		$this->mail->IsHTML(true);
+		//compute $this->final_fields if not done already
+		if (!( $this->decode_fields_in_final_fields($smtpconf['defaultDomain']) ))
+		{
+			$this->error[] = lang('We were not able to build the message');
+			return false;
+		}
+
+		$process = Factory::getInstance('workflow_process');
+		$process->getProcess($this->process_id);
+		$this->process_name = $process->getName();
+		$this->process_version = $process->getVersion();
+		unset ($process);
+		
+		$this->mail->From 	= $this->mail->EncodeHeader($this->final_fields['wf_from']);
+		//$this->mail->FromName 	= $this->activity->getName();
+		$this->mail->FromName 	= $this->process_name;
+		$this->mail->Subject 	= $this->mail->EncodeHeader($this->final_fields['wf_subject']);
+		$this->mail->Body    	= str_replace("\n",'<br />',html_entity_decode($this->final_fields['wf_message']));
+		// if you need compatibility to older email clients (e.g. mutt), uncomment the line below
+		//$this->mail->AltBody	= $this->final_fields['wf_message'];
+		$this->mail->ClearAllRecipients();
+		foreach ($this->final_fields['wf_to'] as $email)
+		{
+			if (!(empty($email))) $this->mail->AddAddress($email);
+		}
+		foreach ($this->final_fields['wf_cc'] as $email)
+		{
+			if (!(empty($email))) $this->mail->AddCC($email);
+		}
+		foreach ($this->final_fields['wf_bcc'] as $email)
+		{
+			if (!(empty($email))) $this->mail->AddBCC($email);
+		}
+		$email = $this->final_fields['wf_replyto'];
+		if (!(empty($email))) $this->mail->AddReplyTo($email);
+		return true;
+	}
+	
+	/**
+	  * This function is used to decode admin instructions about the final value or the activity fields.
+	  * 
+	  *  i.e.: decoding %user% in toto@foo.com for example
+	  *	If you call this function twice the final result will NOT be recalculated. except with the $force 
+	  *	parameter. This is done so that you can call this function sooner than the engine and add or remove
+	  *	emails from final fields. The engine will not recompute automatically theses fields if you done it already.
+	  * @param string $defaultDomain is the default mail Domain, used with empty domains
+	  * @param bool $force is falmse by default, if true the final are recalculated even if they are already there
+	  * @return bool true/false and set the $this->final_fields array containing the fields with the 'real' final value and for 
+	  * the wf_to, wf_bcc and wf_cc fields you'll have arrays with email values.
+	  * @access public
+	 */
+	function decode_fields_in_final_fields($defaultDomain, $force=false)
+	{
+		if ($force || (!(isset($this->final_fields['calculated']))) )
+		{
+			$res = Array();
+			$result = Array();
+			$address_array = Array();
+			$email_list = Array();
+			foreach ($this->fields as $key => $value)
+			{
+				$res[$key] =& $this->replace_tokens($value['value']);
+				//for all adresse fields we make an email array to detect repetitions
+				if (($key=='wf_to') || ($key=='wf_cc') || ($key=='wf_bcc'))
+				{
+					 //_debug_array($res[$key]);//DEBUG
+					 //clean ',,' or ', ,'  or starting or ending by ','
+					 $res[$key] = $this->cleanup_adress_string($res[$key]);
+					//_debug_array($res[$key]);//DEBUG 
+					
+					//warning, need to handle < and > as valid chars for emails
+					$address_array  = imap_rfc822_parse_adrlist(str_replace('&gt;','>',str_replace('&lt;','<',$res[$key])),'');
+					//_debug_array($address_array);//DEBUG
+					if (is_array($address_array) && (!(empty($address_array))))
+					{
+						foreach ($address_array as $val)
+						{
+							//we retain this email is used in To or Bcc or Cc
+							//and we affect this email only the first time
+							//first detect errors
+							if ($val->host == '.SYNTAX-ERROR.')
+							{
+								$this->error[] = lang("at least one email address cannot be validated.");
+								if ($this->debugmode)
+								{
+									$this->error[] = $res[$key];
+								}
+								return false;
+							}
+							//detect empty domains
+							if (empty($val->host))
+							{ 
+								$val->host = $defaultDomain;
+							}
+							//build email adress
+							$his_email = $val->mailbox.'@'. $val->host;
+							if (!isset($email_list[$his_email]))
+							{
+								$email_list[$his_email] = $key;
+								$result[$key][]= $his_email;
+							}
+						}
+					}
+					else
+					{
+						$result[$key] = Array();
+					}
+				}
+				elseif ( ($key=='wf_from') || ($key=='wf_replyto'))
+				{
+					//warning, need to handle < and > as valid chars for emails
+					$result[$key] = str_replace('&gt;','>',str_replace('&lt;','<',$res[$key]));
+				}
+				else
+				{
+					$result[$key] = $res[$key];
+				}
+			}
+			$this->final_fields =& $result;
+			$this->final_fields['calculated']=true;
+		}
+		return true;
+	}
+
+	/**
+	 * This function will clean ',,' or ', ,'  or starting or ending by ',' in the email address string list.
+	 * @param string $address_string is the string we should clean
+	 * @return string the cleaned up string
+	 * @access public
+	 */
+	function cleanup_adress_string($address_string)
+	{
+		//in PHP5 we could ve been using the count parameter to stop recursivity
+		$new = str_replace(array(', ,' , ',,'),array(',', ','),trim(trim($address_string),','));
+		if ($new == $address_string)
+		{
+			//it did nothing, lets stop recursivity
+			return $new;
+		}
+		{
+			//we made sime changes, lets verify the new string is syntaxically correct, recursivity
+			return $this->cleanup_adress_string($new);
+		}
+	}
+
+	/**
+	 * This function is used to find and replace tokens in the fields
+	 * @param string $string is the string to analyse
+     * @return string the modified string
+     * @access public
+	 */
+	function replace_tokens(&$string)
+	{
+		//first we need to escape the \% before the analysis
+		$string = str_replace('\%','&workflowpourcent;',$string);
+		$matches = Array();
+		preg_match_all("/%([^%]+)%/",$string, $matches);
+		$final = $string;
+		if ($this->activity_id =='') $this->activity_id = $this->activity->getActivityId();
+		if ($this->instance_id =='') $this->instance_id = $this->instance->getInstanceId();
+		if ($this->process_id =='') $this->process_id = $this->activity->getProcessId();
+		foreach($matches[1] as $key => $value)
+		{
+			//$value is our %token%
+			switch($value)
+			{
+				case 'signature':
+							$matches[1][$key] = $this->conf['mail_smtp_signature'];
+							break;
+				case 'instance_name' :
+					$matches[1][$key] = $this->instance->getName();
+					break;
+				case 'activity_name' :
+					$matches[1][$key] = $this->activity->getName();
+					break;
+				case 'process_name' :
+					if ($this->process_name=='')
+					{
+						$process = Factory::getInstance('workflow_process');
+						$process->getProcess($this->process_id);
+						$this->process_name = $process->getName();
+						$this->process_version = $process->getVersion();
+						unset ($process);
+					}
+					$matches[1][$key] = $this->process_name;
+					break;
+				case 'process_version' :
+					if ($this->process_version=='')
+					{
+						$process = Factory::getInstance('workflow_process');
+						$process->getProcess($this->process_id);
+						$this->process_name = $process->getName();
+						$this->process_version = $process->getVersion();
+						unset ($process);
+					}
+					$matches[1][$key] = $this->process_version;
+					break;
+				case 'process_id' :
+					$matches[1][$key] = $this->process_id;
+					break;
+				case 'instance_id' :
+					$matches[1][$key] = $this->instance_id;
+					break;
+				case 'activity_id' :
+					$matches[1][$key] = $this->activity_id;
+					break;
+				case 'user' :
+					//the current instance/activity user which is in fact running
+					//this class actually
+					$matches[1][$key] = $GLOBALS['phpgw_info']['user']['email'];
+					break;
+				case 'owner' :
+					//the owner of the instance
+					if (!is_object($this->account))
+					{
+						$this->account = Factory::getInstance('accounts');
+					}
+					$ask_user = $this->instance->getOwner();
+					$matches[1][$key] = $this->account->id2name($ask_user, 'account_email');
+					break;
+				case 'roles' :
+					//all users having at least one role on this activity
+					if (!is_object($this->role_manager))
+					{
+						$this->role_manager = Factory::getInstance('workflow_rolemanager');
+					}
+					if (!is_object($this->account))
+					{
+						$this->account = Factory::getInstance('accounts');
+					}
+					$my_subset = array('wf_activity_name' => $this->activity->getName());
+					$listing =& $this->role_manager->list_mapped_users($this->instance->getProcessId(),true, $my_subset);
+					$matches[1][$key] = '';
+					foreach ($listing as $user_id => $user_name)
+					{
+						$user_email = $this->account->id2name($user_id);
+						if ($matches[1][$key] == '')
+						{
+							$matches[1][$key] = $this->account->id2name($user_id, 'account_email');
+						}
+						else
+						{
+							$matches[1][$key] .= ', '.$this->account->id2name($user_id, 'account_email');
+						}
+					}
+					break;
+				default:
+					//Now we need to handle role_foo or property_bar or user_foobar
+					$matches2 = Array();
+					//echo "<br>2nd analysis on ".$value;
+					preg_match_all("/([^_]+)([_])([A-z0-9\|:\/\.\?\=\'\&\; ]*)/",$value, $matches2);
+					$first_part = $matches2[1][0];
+					$second_part = $matches2[3][0];
+					switch ($first_part)
+					{
+						case 'user' :
+							//we retrieve the asked user email
+							if (!is_object($this->account))
+							{
+								$this->account = Factory::getInstance('accounts');
+							}
+							$ask_user = $this->account->name2id($second_part);
+							$matches[1][$key] = $this->account->id2name($ask_user, 'account_email');
+							break;
+						case 'property' :
+							//we take the content of the given property on the instance
+							$matches[1][$key] = $this->instance->get($second_part);
+							break;
+						case 'role' :
+							//all user mapped to this role
+							if (!is_object($this->role_manager))
+							{
+								$this->role_manager = Factory::getInstance('workflow_rolemanager');
+							}
+							if (!is_object($this->account))
+							{
+								$this->account = Factory::getInstance('accounts');
+							}
+							$my_subset = array('wf_role_name' => $second_part);
+							$listing =& $this->role_manager->list_mapped_users($this->instance->getProcessId(),true, $my_subset);
+							$matches[1][$key] = '';
+							foreach ($listing as $user_id => $user_name)
+							{
+								$user_email = $this->account->id2name($user_id);
+								if ($matches[1][$key] == '')
+								{
+									$matches[1][$key] = $this->account->id2name($user_id, 'account_email');
+								}
+								else
+								{
+									$matches[1][$key] .= ', '.$this->account->id2name($user_id, 'account_email');
+								}
+							}
+							break;
+						case 'link' :
+							//we want a link
+							//the HTML characters are escaped, so we need this function
+							//and we now some usefull links:
+							//$second_part should be in this form link adress|text
+							$matches3 = Array();
+							//echo "<br>3rd analysis on ".$second_part;
+							preg_match_all("/([^\|]+)([\|])([A-z0-9 \'\&\;]*)/",$second_part, $matches3);
+							$link_part = $matches3[1][0];
+							$text_part = $matches3[3][0];
+							//need something in the text
+							if (empty($text_part)) $text_part=$link_part;
+							//and something in the link
+							switch ($link_part)
+							{
+								default:
+									//now it can be an external or local link
+									if (substr($link_part,0,7)=='http://')
+									{//external link
+										$my_link = $link_part;
+									}
+									else
+									{//local link
+										$my_link = $this->conf['mail_smtp_local_link_prefix'].$GLOBALS['phpgw']->link($link_part);
+									}
+							}
+							$matches[1][$key] = '<a href="'.$my_link.'">'.$text_part.'</a>';
+							break;
+						
+						default:
+							$matches[1][$key] = '';
+					}
+			}
+			$final = str_replace($matches[0][$key],$matches[1][$key],$final);
+		}
+		//now get back the % escaped before the analysis
+		$final = str_replace('&workflowpourcent;','%',$final);
+		return $final;
+	}
+	
+	/**
+	 * This function is used to send mail
+	 * @return bool true ok false error
+	 * @access public
+	 */
+	function Send()
+	{
+		//$this->mail->SMTPDebug = 10;
+		if (!($this->debugmode))
+		{
+			if(!$this->mail->Send())
+			{
+				if ($this->mail->ErrorInfo != $this->mail->Lang("data_not_accepted"))
+				{
+					$this->error[] = $this->mail->ErrorInfo;
+					return false;
+				}
+			}
+		}
+		else
+		{
+			//_debug_array($this->mail);
+			$this->error[] = 'DEBUG mode: '.lang('if not in debug mail_smtp agent would have sent this email:');
+			$this->error[] = 'DEBUG mode: Host:'.$this->mail->Host;
+			$this->error[] = 'DEBUG mode: Port:'.$this->mail->Port;
+			$this->error[] = 'DEBUG mode: From:'.htmlentities($this->mail->From);
+			$this->error[] = 'DEBUG mode: FromName:'.htmlentities($this->mail->FromName);
+			$msg = 'DEBUG mode: ReplyTo:';
+			foreach ($this->mail->ReplyTo as $address)
+			{
+				$msg .= htmlentities($address[0]);
+			}
+			$this->error[] = $msg;
+			$msg = 'DEBUG mode: To:';
+			foreach ($this->mail->to as $address)
+			{
+				$msg .= htmlentities($address[0]);
+			}
+			$this->error[] = $msg;
+			$msg = 'DEBUG mode: Cc:';
+			foreach ($this->mail->cc as $address)
+			{
+				$msg .= htmlentities($address[0]);
+			}
+			$this->error[] = $msg;
+			$msg = 'DEBUG mode: Bcc:';
+			foreach ($this->mail->bcc as $address)
+			{
+				$msg .= ' '.htmlentities($address[0]);
+			}
+			$this->error[] = $msg;
+			$this->error[] = 'DEBUG mode: Subject:'.htmlentities($this->mail->Subject);
+			//$this->error[] = 'DEBUG mode: AltBody:'.htmlentities($this->mail->AltBody);
+			$this->error[] = 'DEBUG mode: Body (hmtl):'.$this->mail->Body;
+		}
+		return true;
+	}
+	
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_create_object.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_create_object.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_create_object.php	(revision 795)
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Creates an instance from a class requested by user
+ * @param string $class_name Class' name to be instantiated
+ * @return mixed
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @deprecated 1.4.00.000 - 08/03/2007
+ * @package Workflow 
+ * @subpackage local 
+ * @access public 
+ */ 
+function wf_create_object($class_name)
+{
+	$obj = null;
+	$file_name = PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'local'.SEP.'classes'.SEP.'class.'.$class_name.'.php';
+	if(@file_exists($file_name))
+	{
+		include_once($file_name);
+		$obj = new $class_name; 	
+	}
+	return $obj;
+} 
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_write_file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_write_file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_write_file.php	(revision 795)
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Writes new contents to files.
+ * @param string $filename File's name to be written.
+ * @param string $content New contents to be inserted.
+ * @return boolean
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ * @access public
+ */
+function wf_write_file($filename, $content)
+{
+	/* reject empty file name */
+	if (trim(basename($filename)) == '')
+		return false;
+
+	/* reject "php" extensions */
+	if (strpos(strtolower(strrchr($filename, '.')), 'php') !== false)
+		return false;
+
+	/* check if the file will be stored inside the process resource path */
+	if (strpos($filename, '..') !== false)
+		return false;
+
+	$processPath = GALAXIA_PROCESSES . SEP . $GLOBALS['workflow']['wf_normalized_name'] . SEP . 'resources';
+	$filename = $processPath . SEP . $filename;
+
+	$subDirectories = explode(SEP, substr($filename, strlen($processPath) + 1));
+
+	/* reject directories with empty name */
+	foreach ($subDirectories as $subDir)
+		if (trim($subDir) == "")
+			return false;
+
+	array_pop($subDirectories);
+	$baseDir = $processPath;
+	foreach ($subDirectories as $subDir)
+	{
+		$baseDir .= SEP . $subDir;
+		if (!is_dir($baseDir))
+			@mkdir($baseDir, 0770);
+	}
+
+	$fileHandle = fopen($filename, 'w+');
+	fwrite($fileHandle, $content);
+	fclose($fileHandle);
+
+	return true;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_read_file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_read_file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_read_file.php	(revision 795)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Read file contents.
+ * @param string $filename File's name to be read.
+ * @return mixed String containing the file contents or false in case of error
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ * @access public
+ */
+function wf_read_file($filename)
+{
+	/* reject empty file name */
+	if (trim(basename($filename)) == "")
+		return false;
+
+	/* check if the file is stored within the process resource path */
+	if (strpos($filename, '..') !== false)
+		return false;
+
+	/* complete path of the file */
+	$filename = GALAXIA_PROCESSES . SEP . $GLOBALS['workflow']['wf_normalized_name'] . SEP . 'resources' . SEP . $filename;
+
+	/* check if the file exists */
+	if (!file_exists($filename))
+		return false;
+
+	/* get the file contents */
+	$output = file_get_contents($filename);
+
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_activity_link_by_id.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_activity_link_by_id.php	(revision 1671)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_activity_link_by_id.php	(revision 1671)
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Retorna o link para uma determinada atividade
+ * @param integer $activityId Id da atividade
+ * @return string url para a atividade passada como parametro
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ * @access public
+ * @author Alessandra Heil
+ */
+function wf_get_activity_link_by_id($activityId)
+{
+	/* load some variables */
+	$urlBase = $_SERVER['SERVER_NAME'];
+
+	$output = "http://".$urlBase."/index.php?menuaction=workflow.run_activity.go&activity_id=$activityId";
+
+	return $output ;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_uploaded_files.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_uploaded_files.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_uploaded_files.php	(revision 795)
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Gets uploaded files
+ * @param string $name File's name
+ * @return array
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ * @access public
+ */
+function wf_get_uploaded_files( $name )
+{
+	if (!isset($_FILES[$name]))
+		return array();
+	
+	$filesArray = $_FILES[$name];
+	$fileAtributes = array_keys($filesArray);
+	$numberOfFiles = count($filesArray['name']);
+	$return = array();
+	
+	if ((!is_array($filesArray['name'])))
+	{
+		$return[0] = $filesArray;
+		$return[0]['content'] = file_get_contents($filesArray['tmp_name']);
+	}
+	else
+		for ($i = 0; $i < $numberOfFiles; $i++)
+		{
+			foreach ($fileAtributes as $atribute)
+				$return[$i][$atribute] = $filesArray[$atribute][$i];
+			$return[$i]['content'] = file_get_contents($filesArray['tmp_name'][$i]);
+		}
+	
+	return $return;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/local.functions.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/local.functions.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/local.functions.php	(revision 795)
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Supporting functions set.
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ * @access private
+ */
+require_once 'function.wf_create_object.php';
+require_once 'function.wf_get_uploaded_files.php';
+require_once 'function.wf_handle_download.php';
+require_once 'function.wf_include.php';
+require_once 'function.wf_set_generic_select.php';
+require_once 'function.wf_write_file.php';
+require_once 'function.wf_read_file.php';
+require_once 'function.wf_get_next_activity_link.php';
+require_once 'function.wf_get_activity_link_by_id.php';
+require_once 'function.wf_get_env.php';
+require_once 'function.wf_debug.php';
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_handle_download.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_handle_download.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_handle_download.php	(revision 795)
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Handles download requests based on logic provided by the callback function.
+ * @param array $request Information about HTTP request
+ * @param string $callback Function that provides the logic for the download process.
+ * @return void
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ * @access public
+ */
+function wf_handle_download($request, $callback)
+{
+	/* check if it is in download mode */
+	if (!isset($request['download_mode']))
+		return;
+	else
+		if ($request['download_mode'] != "true")
+			return;
+	
+	/* verify if the callback function exists and is callable */
+	if ((function_exists($callback)) && (is_callable($callback)))
+	{
+		/* prepare the parameters */
+		$params = array();
+		foreach ($request as $key => $value)
+			$params[$key] = $value;
+		
+		/* call the callback function and await the result */
+		$fileResult = call_user_func($callback, $params);
+		
+		/* if everything is ok, then proceed with the download of the file */
+		if (!is_null($fileResult))
+		{
+			if (isset($fileResult['filename']) && isset($fileResult['content']))
+			{
+					if (ereg('Opera(/| )([0-9].[0-9]{1,2})', $_SERVER['HTTP_USER_AGENT']))
+					$UserBrowser = "Opera";
+				elseif (ereg('MSIE ([0-9].[0-9]{1,2})', $_SERVER['HTTP_USER_AGENT']))
+					$UserBrowser = "IE";
+					else
+						$UserBrowser = '';
+				
+				$mime_type = ($UserBrowser == 'IE' || $UserBrowser == 'Opera') ? 'application/octetstream' : 'application/octet-stream';
+				header("Pragma: public");
+				header("Cache-Control: cache, must-revalidate");
+				header("Content-Type: application/force-download");
+				header("Content-Disposition: attachment; filename=\"" . $fileResult['filename'] . "\"");
+				header('Pragma: no-cache');
+				header("Expires: 0");
+		        header("Content-length: " . strlen($fileResult['content']));
+		        echo $fileResult['content'];
+				die();
+			}
+		}
+		else
+			die();
+	}
+} 
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_include.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_include.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_include.php	(revision 795)
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Includes files from the process folder.
+ * @param $file_name File's name to be included.
+ * @return void
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ * @access public
+ */
+function wf_include( $file_name )
+{
+	if ( strpos($file_name,'..' ) === false )
+	{
+		require_once( GALAXIA_PROCESSES.SEP.$GLOBALS['workflow']['wf_normalized_name'].SEP.'code'.SEP.$file_name );
+	}
+} 
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_debug.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_debug.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_debug.php	(revision 795)
@@ -0,0 +1,123 @@
+<?php
+function wf_debug($name = null)
+{
+	/* variable used to avoid the insertion of the same javascript file */
+	static $workflowFunctionsWf_debug = false;
+
+	/* load the backtrace */
+	$backTrace = debug_backtrace();
+
+	/* if no name is supplied, then use de name of the file from which the wf_debug was called */
+	if (is_null($name))
+		$name = substr(strrchr($backTrace[0]['file'], '/'), 1);
+
+	/* prepare the backtrace array */
+	$importantBacktrace = array();
+	for ($i = 0; $i < count($backTrace); $i++)
+	{
+		if (strpos($backTrace[$i]['file'], 'class.run_activity.inc.php') !== false)
+			break;
+		$importantBacktrace[] = $backTrace[$i];
+	}
+	$importantBacktrace = array_reverse($importantBacktrace);
+
+	/* initialize the $output variable */
+	$output = '';
+
+	/* if it's the first time the function is called, then insert the javascript file reference */
+	if (!$workflowFunctionsWf_debug)
+	{
+		$output = '<script language="javascript1.2" src="workflow/js/jscode/debug.js"></script>';
+		$workflowFunctionsWf_debug = true;
+	}
+
+	/* start the visible output */
+	$output .= '<table style="border: 1px solid" width="100%">';
+	$output .= '<tr style="cursor: pointer; background-color: #000000; color: #FFFFFF" onclick="toggleTableDisplay(this.parentNode);"><th colspan="2">Debug: ' . $name . '</th></tr>';
+
+	/* start the backtrace section */
+	$output .= '<tr>';
+	$output .= '<td>Backtrace</td>';
+	$output .= '<td>';
+
+	$i = 1;
+	$output .= '<table>';
+	foreach ($importantBacktrace as $call)
+	{
+		/* show some general information */
+		$output .= '<tr' . ((($i % 2) == 1) ? ' bgcolor="#FFFFFF"' : '') . '><td><font color="red"><strong>' . $i++ . '- </strong></font></td><td>';
+		$output .= '<strong>Arquivo:</strong> ' . $call['file'] . '<br/>';
+		$output .= '<strong>Linha:</strong> ' . $call['line'] . '<br/>';
+
+		/* show different information for methods and functions */
+		if (isset($call['class']))
+			$output .= '<strong>Método:</strong> ' . $call['class'] . $call['type'] . $call['function'] . '()<br/>';
+		else
+			$output .= '<strong>Função:</strong> ' . $call['function'] . '()<br/>';
+
+		/* show the parameters used in the call */
+		$output .= '<strong>Parâmetros:</strong> ';
+		if (empty($call['args']))
+		{
+			$output .= '<i>nenhum</i><br/>';
+		}
+		else
+		{
+			$output .= '<br/>';
+			$j = 1;
+			foreach ($call['args'] as $arg)
+			{
+				if (is_array($arg))
+					$arg = '<i>array</i>';
+				else
+					if (is_object($arg))
+						$arg = '<i>object</i>';
+				$output .= '&nbsp;&nbsp;&nbsp;<strong>#' . $j++ . ':</strong> ' . $arg . '<br/>';
+			}
+		}
+
+		$output .= '</td></tr>';
+	}
+	$output .= '</table>';
+	$output .= '</td></tr>';
+
+	/* start the $_REQUEST section */
+	$randomName = mt_rand() . '_' . mt_rand(); /* unique preffix */
+	$formInput = '';
+	$output .= '<tr><td>$_REQUEST</td><td>';
+	$output .= '<form method="post">';
+	$output .= '<table><tr><th style="font-size: 12px">Propriedade</th><th style="font-size: 12px">Valor</th></tr>';
+	foreach ($_REQUEST as $key => $value)
+	{
+		/* highlight the 'action' and 'params' elements */
+		$showKey = $key;
+		if (($key == 'action') || ($key == 'params'))
+			$showKey = '<font color="red"><strong>' . $key . '</strong></font>';
+		/* generate the table row */
+		$output .= '<tr>';
+		$output .= '<td>' . $showKey . '</td>';
+		$output .= '<td id="' . $randomName . '_' . $key . '_td">' . $value . '</td>';
+
+		/* allow the developer to edit the parameters */
+		$output .= '<td><a href="#" onclick="' . "editField('{$randomName}', '{$key}'); return false;" . '">editar</a></td>';
+		$output .= '</tr>';
+
+		/* generate the form that can be submited at any time */
+		$formInput .= '<input type="hidden" id="' . $randomName . '_' . $key . '" name="' . $key . '" value="' . $value . '"/>';
+	}
+	$output .= '<tr><td colspan="3"><strong>Submeter formulário novamente: </strong>' . $formInput . '<input type="submit" value="enviar"/></td></tr>';
+	$output .= '</table>';
+	$output .= '</form>';
+	$output .= '</td></tr>';
+
+	/* check if exists a database connection */
+	$env = wf_get_env();
+	$output .= '<tr><td>Banco de Dados</td><td>' . (($env['dao']->Link_ID === 0) ? '<font color="red">não conectado</font>' : '<font color="green">conectado</font>') . '</td></tr>';
+
+	/* end the table */
+	$output .= '</table><br/>';
+
+	/* send the output */
+	echo $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_next_activity_link.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_next_activity_link.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_next_activity_link.php	(revision 795)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Retorna o link para a próxima atividade
+ * @return string
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ * @access public
+ */
+function wf_get_next_activity_link()
+{
+	/* load some variables */
+	$instance =& $GLOBALS['workflow']['wf_runtime'];
+	$currentActivity = $instance->activity_id;
+	$instanceId = $instance->instance_id;
+	$urlBase = $GLOBALS['phpgw_info']['server']['webserver_url'];
+
+	/* determine the next activity */
+	if (isset($instance->instance->changed['nextActivity'][$currentActivity]))
+		$nextActivityId = $instance->instance->changed['nextActivity'][$currentActivity];
+	else
+		if (isset($instance->instance->nextActivity[$currentActivity]))
+			$nextActivityId = $instance->instance->nextActivity[$currentActivity];
+	
+	if (isset($nextActivityId) && ($instanceId != 0))
+		$output = "$urlBase/index.php?menuaction=workflow.run_activity.go&activity_id=$nextActivityId&iid=$instanceId";
+	else
+		$output = "$urlBase/workflow/index.php?start_tab=0";
+
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_set_generic_select.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_set_generic_select.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_set_generic_select.php	(revision 795)
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Creates a picker interface based on the items supplied.
+ * @param string $items Picker options.
+ * @param string $containerNumber Identification for retrieving the menu.
+ * @return void
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ * @access public 
+ */
+function wf_set_generic_select($items, $containerNumber = 0)
+{
+	$sessionSection = "generic_select";
+	$digest = md5($_SERVER['REQUEST_URI']);
+	$_SESSION[$sessionSection][$digest][$containerNumber] = $items;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_env.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_env.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/functions/function.wf_get_env.php	(revision 795)
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Returns the environment variable
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @return array
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ * @access public
+ */
+function wf_get_env()
+{
+	if (isset($GLOBALS['workflow_env']))
+		return $GLOBALS['workflow_env'];
+	else
+		return false;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_workitem.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_workitem.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_workitem.php	(revision 795)
@@ -0,0 +1,75 @@
+<?php
+/**
+* Provê métodos que acessam informações relacionadas aos workitems.
+* @author Anderson Tadayuki Saikawa - asaikawa@celepar.pr.gov.br
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+* @subpackage local
+*/
+class wf_workitem
+{
+	/**
+	* @var object $db objeto do banco de dados
+	* @access private
+	*/
+	private $db;
+
+	/**
+	* @var int $processID o ID do processo onde a classe está sendo utilizada
+	* @access private
+	*/
+	private $processID;
+
+	/**
+	* Construtor do wf_workitem.
+	* @return object
+	* @access public
+	*/
+	public function wf_workitem()
+	{
+		$this->db = &$GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID;
+		$this->processID = (int) $GLOBALS['workflow']['wf_runtime']->activity->getProcessId();
+	}
+
+	/**
+	* Busca workitems de uma instância pelo seu nome (identificador).
+	* @param int $instanceName O nome da instância.
+	* @param mixed $activities Uma lista de IDs de atividades das quais se quer os workitems (também pode ser um valor inteiro).
+	* @return array Array onde cada elemento corresponde aos workitens de cada instâncias que satisfaz o critério de seleção.
+	* @access public
+	*/
+	public function getWorkitemsByInstanceName($instanceName, $activities = null)
+	{
+		$output = array();
+
+		if (is_numeric($activities))
+			$activities = array((int) $activities);
+
+		/* build the SQL query */
+		$query  = 'SELECT w.wf_instance_id, w.wf_item_id, w.wf_order_id, w.wf_activity_id, w.wf_started, w.wf_ended, w.wf_user ';
+		$query .= 'FROM egw_wf_workitems w ';
+		$query .= 'INNER JOIN egw_wf_instances i ON w.wf_instance_id = i.wf_instance_id ';
+		$query .= 'WHERE (i.wf_p_id = ?) AND (UPPER(i.wf_name) = UPPER(?)) ';
+
+		$values = array($this->processID, $instanceName);
+
+		/* if there are activities, add a condition */
+		if(is_array($activities) && (count($activities) > 0))
+		{
+			$query .= 'AND (w.wf_activity_id = ANY (?))';
+			$values[] = '{' . implode(', ', $activities) . '}';
+		}
+
+		$result = $this->db->query($query, $values);
+		if ($result !== false)
+		{
+			while (($row = $result->fetchRow()))
+				$output[$row['wf_instance_id']][] = $row;
+			$output = array_values($output);
+		}
+
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_role.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_role.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_role.php	(revision 2372)
@@ -0,0 +1,410 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+* Provê métodos para administrar os perfis do processo.
+* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+* @subpackage local
+*/
+class wf_role
+{
+	/**
+	* @var int $processID o ID do processo onde a classe está sendo utilizada
+	* @access private
+	*/
+	private $processID;
+
+	/**
+	* @var object $db link com o banco de dados do Expresso
+	* @access private
+	*/
+	private $db;
+
+	/**
+	* @var object $roleManager objeto da classe RoleManager
+	* @access private
+	*/
+	private $roleManager;
+
+	/**
+	* @var object $activityManager objeto da classe ActivityManager
+	* @access private
+	*/
+	private $activityManager;
+
+	/**
+	* Construtor da wf_role
+	* @return object
+	* @access public
+	*/
+	function wf_role()
+	{
+		if (!is_null($GLOBALS['workflow']['wf_runtime']->activity))
+			$this->processID = (int) $GLOBALS['workflow']['wf_runtime']->activity->getProcessId();
+		if (isset($GLOBALS['workflow']['job']))
+			$this->processID = (int) $GLOBALS['workflow']['job']['processID'];
+
+		$this->db = &$GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID;
+		$this->roleManager = Factory::getInstance('workflow_rolemanager');
+		$this->activityManager = Factory::getInstance('workflow_activitymanager');
+	}
+
+	/**
+	* Busca os perfis pertencentes ao processo que chama o método.
+	* @return array Lista dos perfis pertencentes ao processo.
+	* @access public
+	*/
+	function getRoles()
+	{
+		$output = array();
+		$roles = $this->roleManager->list_roles($this->processID, 0, -1, 'wf_name__ASC', '', '');
+		foreach ($roles['data'] as $role)
+			$output[] = array('id' => $role['wf_role_id'], 'name' => $role['wf_name'], 'description' => $role['wf_description']);
+		return $output;
+	}
+
+	/**
+	* Busca os perfis associados a uma atividade do processo.
+	* @param string $activityName O nome da atividade da qual se quer os perfis.
+	* @return array Lista dos perfis pertencentes à atividade.
+	* @access public
+	*/
+	function getActivityRoles($activityName)
+	{
+		/* check if the activity exists */
+		$output = array();
+		if (!$this->activityManager->activity_name_exists($this->processID, $activityName))
+			return $output;
+
+		/* get the roles */
+		$activityID = $this->activityManager->_get_activity_id_by_name($this->processID, $activityName);
+		$roles = $this->activityManager->get_activity_roles($activityID);
+		foreach ($roles as $role)
+			$output[] = array('id' => $role['wf_role_id'], 'name' => $role['wf_name'], 'read_only' => ($role['wf_readonly'] == 0) ? false : true);
+
+		usort($output, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+		return $output;
+	}
+
+	/**
+	* Busca o id de uma atividade pelo seu nome
+	* @param string $activityName O nome da atividade da qual se quer o id
+	* @return int O id da atividade ou null se não encontrado
+	* @access public
+	*/
+	function getActivityIdByName($activityName)
+	{
+		/* check if the activity exists */
+		if (!$this->activityManager->activity_name_exists($this->processID, $activityName))
+			return null;
+
+		/* get the id */
+		$activityID = $this->activityManager->_get_activity_id_by_name($this->processID, $activityName);
+		return $activityID;
+	}
+
+	/**
+	* Cria um perfil que poderá ser utilizado no processo atual.
+	* @param string $roleName O nome do perfil que será criado.
+	* @param string $description A descrição do perfil que será criado.
+	* @return mixed O ID do perfil criado. Em caso de erro, será retornado false.
+	* @access public
+	*/
+	function createRole($roleName, $description)
+	{
+		$values = array(
+			'wf_name' => $roleName,
+			'wf_description' => $description);
+		return $this->roleManager->replace_role($this->processID, 0, $values);
+	}
+
+	/**
+	* Remove um perfil.
+	* @param string $roleName O nome do perfil que será removido.
+	* @return bool Será retornado true em caso de sucesso e false caso contrário.
+	* @access public
+	*/
+	function removeRole($roleName)
+	{
+		/* check if the role exists */
+		if ($this->roleManager->role_name_exists($this->processID, $roleName) == 0)
+			return false;
+
+		/* remove the role */
+		$roleID = $this->roleManager->get_role_id($this->processID, $roleName);
+		return $this->roleManager->remove_role($this->processID, $roleID);
+	}
+
+	/**
+	* Atualiza um perfil.
+	* @param string $previousRoleName O nome do perfil que será atualizado.
+	* @param string $roleName O novo nome do perfil que será atualizado.
+	* @param string $description A nova descrição do perfil que será atualizado.
+	* @return mixed O ID do perfil atualizado. Em caso de erro, será retornado false.
+	* @access public
+	*/
+	function updateRole($previousRoleName, $newRoleName, $newDescription)
+	{
+		/* check if the role exists */
+		if ($this->roleManager->role_name_exists($this->processID, $previousRoleName) == 0)
+			return false;
+
+		/* update the role */
+		$roleID = $this->roleManager->get_role_id($this->processID, $previousRoleName);
+		$values = array(
+			'wf_name' => $newRoleName,
+			'wf_description' => $newDescription);
+		return $this->roleManager->replace_role($this->processID, $roleID, $values);
+	}
+
+	/**
+	* Adiciona usuários/grupos a um perfil.
+	* @param mixed $users Um inteiro ou um array de inteiros representando os IDs dos usuários/grupos que serão adicionados ao perfil.
+	* @param string $roleName O nome do perfil que receberá os usuários.
+	* @access public
+	*/
+	function addUsersToRole($users, $roleName)
+	{
+		/* check if the role exists */
+		if ($this->roleManager->role_name_exists($this->processID, $roleName) == 0)
+			return false;
+
+		/* add the user/group to the role */
+		if (!is_array($users))
+			$users = array((int) $users);
+		$roleID = $this->roleManager->get_role_id($this->processID, $roleName);
+		$ldap = Factory::getInstance('WorkflowLDAP');
+		foreach ($users as $user)
+		{
+			$user = str_replace('u', '', str_replace('g', '', $user));
+			$accountType = $ldap->getEntityType($user);
+			if (($accountType == 'u') || ($accountType == 'g'))
+				$this->roleManager->map_user_to_role($this->processID, $user, $roleID, $accountType);
+		}
+	}
+
+	/**
+	* Busca os usuários/grupos de um perfil.
+	* @param string  $roleName O nome do perfil do qual se quer os usuários/grupos.
+	* @param boolean $expandGroups Valor booleano que indica se os grupos devem ser expandidos.
+	* @return array Lista dos usuários/grupos (id, nome e tipo) pertencentes ao perfil especificado.
+	* @access public
+	*/
+	function getUsersFromRole($roleName, $expandGroups = false)
+	{
+		/* check if the role exists */
+		if ($this->roleManager->role_name_exists($this->processID, $roleName) == 0)
+			return false;
+
+		/* get the user/group from the role */
+		$users = $this->roleManager->list_mapped_users($this->processID, false, array('wf_role_name' => $roleName));
+
+		$ldap = Factory::getInstance('WorkflowLDAP');
+		$output = array();
+		foreach ($users as $id => $login)
+		{
+			$accountType = $ldap->getEntityType($id);
+			// if it must expand the group, get its users and put them into the tmp_output array using
+			// their uidnumber as key (it avoids duplicated values)
+			if($accountType == 'g' && $expandGroups)
+			{
+				$groupUsers = $ldap->getGroupUsers($id);
+				foreach ($groupUsers as $groupUser)
+					if ((!isset($output[$groupUser['account_id']])) && ($groupUser['account_name'] != ''))
+						$output[$groupUser['account_id']] = array('id' => $groupUser['account_id'],	'name' => $groupUser['account_name'],	'type' => 'u');
+			}
+			else
+			{
+				if (isset($output[$id]))
+					continue;
+
+				$name = $ldap->getName($id);
+				if ($name != '')
+					$output[$id] = array('id' => $id, 'name' => $name, 'type' => $accountType);
+			}
+		}
+
+		// format the output array
+		$output = array_values($output);
+
+		usort($output, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+		return $output;
+	}
+
+	/**
+	* Remove os usuários/grupos um perfil.
+	* @param mixed $users Um inteiro ou um array de inteiros representando os IDs dos usuários/grupos que serão removidos do perfil.
+	* @param string $roleName O nome do perfil que terá os usuários/grupos removidos.
+	* @access public
+	*/
+	function removeUsersFromRole($users, $roleName)
+	{
+		/* check if the role exists */
+		if ($this->roleManager->role_name_exists($this->processID, $roleName) == 0)
+			return false;
+
+		/* remove the users from the role */
+		if (!is_array($users))
+			$users = array((int) $users);
+		$roleID = $this->roleManager->get_role_id($this->processID, $roleName);
+
+		foreach ($users as $user)
+		{
+			$user = str_replace('u', '', str_replace('g', '', $user));
+			$this->roleManager->remove_mapping($user, $roleID);
+		}
+	}
+
+	/**
+	* Associa um perfil a uma atividade.
+	* @param string $roleName O nome do perfil que será associado à atividade.
+	* @param string $activityName O nome da atividade que será associada ao perfil.
+	* @return bool Será retornado true em caso de sucesso e false caso contrário.
+	* @access public
+	*/
+	function mapRoleToActivity($roleName, $activityName, $readOnly = false)
+	{
+		/* check if the role and the activity exist */
+		if (($this->roleManager->role_name_exists($this->processID, $roleName) == 0) || (!$this->activityManager->activity_name_exists($this->processID, $activityName)))
+			return false;
+
+		/* create the new mapping */
+		$activityID = $this->activityManager->_get_activity_id_by_name($this->processID, $activityName);
+		$roleID = $this->roleManager->get_role_id($this->processID, $roleName);
+		return $this->activityManager->add_activity_role($activityID, $roleID, $readOnly);
+	}
+
+	/**
+	* Desassocia um perfil de uma atividade.
+	* @param string $roleName O nome do perfil que será desassociado à atividade.
+	* @param string $activityName O nome da atividade que será desassociada ao perfil.
+	* @return bool Será retornado true em caso de sucesso e false caso contrário.
+	* @access public
+	*/
+	function unmapRoleFromActivity($roleName, $activityName)
+	{
+		/* check if the role and the activity exist */
+		if (($this->roleManager->role_name_exists($this->processID, $roleName) == 0) || (!$this->activityManager->activity_name_exists($this->processID, $activityName)))
+			return false;
+
+		/* remove the mapping */
+		$activityID = $this->activityManager->_get_activity_id_by_name($this->processID, $activityName);
+		$roleID = $this->roleManager->get_role_id($this->processID, $roleName);
+		return $this->activityManager->remove_activity_role($activityID, $roleID);
+	}
+
+	/**
+	* Recupera o ID de um perfil através do seu nome
+	* @param string $roleName O nome do perfil que será criado.
+	* @return int O ID do perfil solicitado
+	* @access public
+	*/
+	function getRoleIdByName($roleName)
+	{
+		/* check if the role exists */
+		if ($this->roleManager->role_name_exists($this->processID, $roleName) == 0)
+			return false;
+
+		/* get roleId by roleName */
+		return $this->roleManager->get_role_id($this->processID, $roleName);
+	}
+
+	/**
+	* Recupera informações sobre um perfil a partir de seu ID
+	* @param int $roleID O ID do perfil solicitado.
+	* @return mixed Uma array associativa contendo informações sobre o perfil. Em caso de erro, será retornado false.
+	* @access public
+	*/
+	function getRoleByID($roleID)
+	{
+		/* get role information */
+		$data = $this->roleManager->get_role($this->processID, $roleID);
+		if (!is_array($data))
+			return false;
+
+		/* user friendly keys */
+		$output = array(
+			'id' => $data['wf_role_id'],
+			'name' => $data['wf_name'],
+			'description' => $data['wf_description']
+		);
+
+		return $output;
+	}
+
+	/**
+	* Busca os perfis de um usuário
+	* @param int $userID O ID do usuário.
+	* @param string $activityName O nome de uma atividade do processo (parâmetro opcional que se utilizado, verifica somente os perfis do usuário na atividade indicada).
+	* @return array Uma array contendo os perfis do usuário.
+	* @access public
+	*/
+	function getUserRoles($userID, $activityName = null)
+	{
+		/* get valid roles and initilize some variables */
+		$roles = (is_null($activityName)) ? $this->getRoles() : $this->getActivityRoles($activityName);
+		$userID = (int) $userID;
+		$output = array();
+
+		/* if no role found, return an empty array */
+		if (count($roles) < 1)
+			return $output;
+
+		/* get only the IDs of the roles */
+		$roleIDs = array_map(create_function('$a', 'return $a[\'id\'];'), $roles);
+
+		/* get the roles */
+		$userGroups = Factory::getInstance('WorkflowLDAP')->getUserGroups($userID);
+		$query = 'SELECT DISTINCT role.wf_role_id, role.wf_name, role.wf_description FROM egw_wf_roles role, egw_wf_user_roles user_role WHERE (user_role.wf_role_id = role.wf_role_id) AND (role.wf_p_id = ?) AND (role.wf_role_id = ANY (?))';
+		$query .= ' AND (((user_role.wf_user = ?) AND (user_role.wf_account_type = ?))';
+		$values = array($this->processID, '{' . implode(', ', $roleIDs) . '}', $userID, 'u');
+		if (!empty($userGroups))
+		{
+			$query .= ' OR ((user_role.wf_user = ANY (?)) AND (user_role.wf_account_type = ?))';
+			$values[] = '{' . implode(', ', $userGroups) . '}';
+			$values[] = 'g';
+		}
+		$query .= ')';
+		$resultSet = $this->db->query($query, $values)->getArray(-1);
+
+		/* format the output */
+		foreach ($resultSet as $row)
+			$output[] = array(
+				'id' => $row['wf_role_id'],
+				'name' => $row['wf_name'],
+				'description' => $row['wf_description']
+			);
+
+		return $output;
+	}
+
+	/**
+	* Verifica se um usuário pertence a um determinado perfil
+	* @param int $userID O ID do usuário.
+	* @param string $roleName O nome do perfil.
+	* @return bool True se o usuário pertence ao perfil ou false caso contrário.
+	* @access public
+	*/
+	function checkUserInRole($userID, $roleName)
+	{
+		$roles = $this->getUserRoles($userID);
+		foreach ($roles as $role)
+			if ($role['name'] == $roleName)
+				return true;
+
+		return false;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_crypt.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_crypt.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_crypt.php	(revision 795)
@@ -0,0 +1,149 @@
+<?php
+/**
+* Criptografia simples e segura baseada em funções hash   
+* @author	Marc Wöhlken, woehlken@quadracom.de
+* @author	Carlos Eduardo Nogueira Gonçalves
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow 
+* @subpackage local
+**/	
+class wf_crypt {
+	/**
+	 * @var	string $hash_key Versão embaralhada da chave de criptografia fornecida pelo usuário
+	 * @access public
+	 **/
+	var $hash_key;
+	/**
+	 * @var	int $hash_length Comprimento da string dos valores criptografados usando o algoritmo atual
+	 * @access public
+	 **/	
+	var $hash_length;
+	/**
+	 * @var	boolean $base64 Usar codificação base64 
+	 * @access public
+	 **/	
+	var $base64;
+	/**
+	 * @var	string $salt Valor secreto que randomiza a saída e protege a chave fornecida pelo usuário	
+	 * @access public
+	 **/	
+	var $salt = 'd41d8cd98f00b204e9800998ecf8427e';
+	
+	/**
+	 * Construtor 
+	 * @return object
+	 * @access public
+	 */
+	function wf_crypt() {
+		$moduleConf = parse_ini_file(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'config' . SEP . 'module.ini', true);
+		$this->setKey($moduleConf['classes']['wf_crypt'], true);
+	}
+	
+	/**
+	 * Usado para definir a chave de criptografia e descriptografia
+	 * @param	string	$key	Chave secreta usada para criptografia e descriptografia
+	 * @param	boolean	$base64	Usar codificação base64
+	 * @return void 
+	 * @access public
+	 */
+	function setKey($key, $base64 = true) {
+		$this->base64 = $base64;		
+		$this->hash_key = $this->_hash($key);		
+		$this->hash_length = strlen($this->hash_key);
+	}
+		
+	/**
+	 * Criptografa dados
+	 * @param	string	$string	Informação a ser criptografada
+	 * @return string	Informação criptografada
+	 * @access public
+	 */
+	function encrypt($string) {
+		$iv = $this->_generate_iv();		
+		$out = '';		
+		for($c=0;$c < $this->hash_length;$c++) {
+			$out .= chr(ord($iv[$c]) ^ ord($this->hash_key[$c]));
+		}
+		$key = $iv;
+		$c = 0;
+		while($c < strlen($string)) {
+			if(($c != 0) and ($c % $this->hash_length == 0)) {
+				$key = $this->_hash($key . substr($string,$c - $this->hash_length,$this->hash_length));
+			}
+			$out .= chr(ord($key[$c % $this->hash_length]) ^ ord($string[$c]));
+			$c++;
+		}
+		if($this->base64) $out = base64_encode($out);
+		return $out;
+	}
+	
+	/**
+	 * Descriptografa
+	 * @param	string	$string Informação a ser descriptografada	
+	 * @return string	Informação descriptografada
+	 * @access public
+	 */
+	function decrypt($string) {
+		if($this->base64) $string = base64_decode($string);
+		$tmp_iv = substr($string,0,$this->hash_length);
+		$string = substr($string,$this->hash_length,strlen($string) - $this->hash_length);
+		$iv = $out = '';
+		for($c=0;$c < $this->hash_length;$c++) {
+			$iv .= chr(ord($tmp_iv[$c]) ^ ord($this->hash_key[$c]));
+		}
+		$key = $iv;
+		$c = 0;
+		while($c < strlen($string)) {
+			if(($c != 0) and ($c % $this->hash_length == 0)) {
+				$key = $this->_hash($key . substr($out,$c - $this->hash_length,$this->hash_length));
+			}
+			$out .= chr(ord($key[$c % $this->hash_length]) ^ ord($string[$c]));
+			$c++;
+		}
+		return $out;
+	}
+
+	/**
+	 * Função de hash usada para criptografar
+	 * @access private
+	 * @param	string	$string	Informação a ser criptografada
+	 * @return string	Valor criptografado dos dados de entrada
+	 */
+	function _hash($string) {
+		if(function_exists('sha1')) {
+			$hash = sha1($string);
+		} else {
+			$hash = md5($string);
+		}
+		$out ='';
+		for($c=0;$c<strlen($hash);$c+=2) {
+			$out .= $this->_hex2chr($hash[$c] . $hash[$c+1]);
+		}
+		return $out;
+	}
+	
+	/**
+	 * Gera uma string aleatória para inicializar criptografia
+	 * @access private
+	 * @return string	String pseudo-aleatória
+	 **/
+	function _generate_iv() {
+		srand ((double)microtime()*1000000);
+		$iv  = $this->salt;
+		$iv .= rand(0,getrandmax());
+		$iv .= serialize($GLOBALS);
+		return $this->_hash($iv);
+	}
+	
+	/**
+	 * Converte valor hexadecimal para string binária
+	 * @access private
+	 * @param	string	Número hexadecimal entre 00 e ff
+	 * @return	string	Caracter representando o valor de entrada
+	 **/
+	function _hex2chr($num) {
+		return chr(hexdec($num));
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_url.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_url.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_url.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * importa classe do módulo
+ */
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'class.utils.url.php');
+/**
+ * Classe que contém métodos utilitários para a construção
+ * e a manipulação de URLs
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local
+ */
+class wf_url extends UrlUtils {
+	/* desabilita método */
+	function anchor($url, $text, $statusBarText='', $cssClass='', $jsEvents=array(), $target='', $name='', $id='', $rel='', $accessKey='') {}		
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_instance.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_instance.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_instance.php	(revision 2372)
@@ -0,0 +1,534 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+* Provê métodos que acessam informações relacionadas às instâncias.
+* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+* @subpackage local
+*/
+class wf_instance
+{
+	/**
+	* @var object $db objeto do banco de dados
+	* @access private
+	*/
+	private $db;
+
+	/**
+	* @var int $processID o ID do processo onde a classe está sendo utilizada
+	* @access private
+	*/
+	private $processID;
+
+	/**
+	* Verifica se um dado processo equivale àquele que está sendo executado.
+	* @param int $processID O ID do processo.
+	* @return bool true caso sejam o mesmo processo ou, false caso contrário.
+	* @access public
+	*/
+	private function checkProcessAccess($processID)
+	{
+		$processID = (int) $processID;
+		return ($processID === $this->processID);
+	}
+
+	/**
+	* Verifica se uma instância pertence ao processo que está sendo executado.
+	* @param int instanceID O ID da instância.
+	* @return bool true caso a instância pertença ao processo que está sendo executado ou, false caso contrário.
+	* @access public
+	*/
+	private function checkInstanceAccess($instanceID, $activityID = null)
+	{
+		$instance = $this->getInstanceObject($instanceID);
+		if ($instance === false)
+			return false;
+		if (!is_null($activityID))
+		{
+			$activityFound = false;
+			foreach ($instance->activities as $activity)
+				if (($activityFound = ($activityID == $activity['wf_activity_id'])))
+					break;
+
+			if ($activityFound == false)
+				return false;
+		}
+		return $this->checkProcessAccess($instance->pId);
+	}
+
+	/**
+	* Pega o objeto de uma instância.
+	* @param int instanceID O ID da instância.
+	* @return mixed object caso a instância seja encontrada ou false caso contrário.
+	* @access public
+	*/
+	private function getInstanceObject($instanceID)
+	{
+		$instanceID = (int) $instanceID;
+		$instance = Factory::getInstance('workflow_instance');
+		if (!$instance->getInstance($instanceID))
+			return false;
+		else
+			return $instance;
+	}
+
+	/**
+	* Construtor do wf_instances.
+	* @return object
+	* @access public
+	*/
+	public function wf_instance()
+	{
+		/* load the DB */
+		$this->db = &$GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID;
+
+		/* load the process ID from the runtime */
+		if (!is_null($GLOBALS['workflow']['wf_runtime']->activity))
+			$this->processID = (int) $GLOBALS['workflow']['wf_runtime']->activity->getProcessId();
+		/* if a job is running the process, then load the processID specified by the job */
+		if (isset($GLOBALS['workflow']['job']))
+			$this->processID = (int) $GLOBALS['workflow']['job']['processID'];
+	}
+
+	/**
+	* Dá seqüência no fluxo de uma instância (simula ação do usuário).
+	* @param int $activityID O ID da atividade da instância.
+	* @param int $instanceID O ID da instância.
+	* @return bool true caso a instância tenha sido continuada e false caso contrário.
+	* @access public
+	*/
+	public function continueInstance($activityID, $instanceID)
+	{
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID, $activityID))
+			return false;
+
+		/* load the instance object */
+		$instance = $this->getInstanceObject($instanceID);
+
+		$runActivity = Factory::getInstance('run_activity');
+
+		ob_start();
+		$output = $runActivity->go($activityID, $instanceID, true);
+		ob_end_clean();
+
+		return ($output !== false);
+	}
+
+	/**
+	* Aborta uma instância
+	* @param int $instanceID O ID da instância.
+	* @return boolean true se foi possível abortar a instância e false caso contrário.
+	* @access public
+	*/
+	public function abort($instanceID)
+	{
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID))
+			return false;
+
+		/* load the instance object */
+		$instance = $this->getInstanceObject($instanceID);
+
+		/* abort the instance */
+		return $instance->abort();
+	}
+
+	/**
+	* Define o nome (identificador) de uma instância
+	* @param int $instanceID O ID da instância.
+	* @param string $name O novo nome da instância.
+	* @return boolean true se foi possível mudar o nome da instância e false caso contrário.
+	* @access public
+	*/
+	public function setName($instanceID, $name)
+	{
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID))
+			return false;
+
+		/* load the instance object */
+		$instance = $this->getInstanceObject($instanceID);
+
+		/* set the name */
+		$output = $instance->setName($name);
+		$output = $output && $instance->sync();
+
+		return $output;
+	}
+
+	/**
+	* Define a prioridade de uma instância
+	* @param int $instanceID O ID da instância.
+	* @param int $priority A nova prioridade da instância
+	* @return boolean true se foi possível mudar a prioridade da instância e false caso contrário.
+	* @access public
+	*/
+	public function setPriority($instanceID, $priority)
+	{
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID))
+			return false;
+
+		/* load the instance object */
+		$instance = $this->getInstanceObject($instanceID);
+
+		/* ensure the instance priority range */
+		$priority = max(min((int) $priority, 4), 0);
+
+		/* set the new priority */
+		$output = $instance->setPriority($priority);
+		$output = $output && $instance->sync();
+		return $output;
+	}
+
+	/**
+	* Busca instâncias ativas que estão "abandonadas".
+	* @param int $numberOfDays O tempo (em dias) em que a instância está abandonada.
+	* @param array $activities Uma lista de atividades das quais se quer as instâncias abandonadas (também pode ser um valor inteiro).
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	*/
+	public function getIdle($numberOfDays, $activities = null)
+	{
+		/* prepare some variables */
+		$output = array();
+		$restrictToActivities = !is_null($activities);
+		if (is_numeric($activities))
+			$activities = array((int) $activities);
+
+		if (is_numeric($numberOfDays))
+			$numberOfDays = (int) $numberOfDays;
+		else
+			return $output;
+
+		/* restrict the range and get the threshold date (in UNIX ERA format) */
+		$numberOfDays = max(0, $numberOfDays);
+		$threshold = time() - ($numberOfDays * 24 * 60 * 60);
+
+		/* build the SQL query */
+		$query = 'SELECT ia.wf_instance_id AS wf_instance_id, ia.wf_activity_id AS wf_activity_id, ia.wf_started AS wf_started, i.wf_name AS wf_name, i.wf_status AS wf_status, ia.wf_user AS wf_user, i.wf_priority AS wf_priority ';
+		$query .= 'FROM egw_wf_instance_activities ia, egw_wf_instances i ';
+		$query .= 'WHERE (ia.wf_instance_id = i.wf_instance_id) AND (i.wf_p_id = ?) AND (ia.wf_started < ?)';
+		$resultSet = $this->db->query($query, array($this->processID, $threshold));
+
+		/* fetch the results */
+		while ($row = $resultSet->fetchRow())
+		{
+			/* if required, restrict to specific activities */
+			if ($restrictToActivities)
+				if (!in_array($row['wf_activity_id'], $activities))
+					continue;
+
+			$output[] = $row;
+		}
+
+		return $output;
+	}
+
+	/**
+	* Busca todas as instâncias ativas.
+	* @param array $activities Uma lista de atividades das quais se quer as instâncias (também pode ser um valor inteiro).
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	*/
+	public function getAll($activities = null)
+	{
+		return $this->getIdle(0, $activities);
+	}
+
+	/**
+	* Busca as instâncias filhas de uma instância
+	* Se os parâmetros não forem informados, retorna instâncias filhas das instância atual.
+	* @param int $instanceID O ID da instância pai (não obrigatório).
+	* @param int $activityID O ID da atividade corrente da instância pai
+	* @return array As instâncias filhas do par instância/atividade atual
+	* @access public
+	*/
+	public function getChildren($instanceID = null, $activityID = null)
+	{
+		$output = array();
+		if (is_null($instanceID))
+			$instanceID = $GLOBALS['workflow']['wf_runtime']->instance_id;
+		if (is_null($activityID))
+			$activityID = $GLOBALS['workflow']['wf_runtime']->activity_id;
+
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID, $activityID))
+			return $output;
+
+		/* build the SQL query */
+		$query = 'SELECT i.wf_instance_id AS wf_instance_id, ia.wf_activity_id AS wf_activity_id, ia.wf_started AS wf_started, i.wf_name AS wf_name, i.wf_status AS wf_status, ia.wf_user AS wf_user, ir.wf_parent_lock AS wf_parent_lock ';
+		$query .= 'FROM egw_wf_interinstance_relations ir, egw_wf_instances i LEFT JOIN egw_wf_instance_activities ia ON (ia.wf_instance_id = i.wf_instance_id)';
+		$query .= 'WHERE (ir.wf_child_instance_id = i.wf_instance_id) AND (ir.wf_parent_instance_id = ?) AND (ir.wf_parent_activity_id = ?)';
+
+		$result = $this->db->query($query, array($instanceID, $activityID));
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	* Busca as propriedades de uma instância (do mesmo processo).
+	* @param int $instanceID O ID da instância.
+	* @return mixed Uma array contento as propriedades da instância (no formato "nome_da_propriedade" => "valor"). Ou false em caso de erro.
+	* @access public
+	*/
+	public function getProperties($instanceID)
+	{
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID))
+			return false;
+
+		/* load the properties of the instance object */
+		return $this->getInstanceObject($instanceID)->properties;
+	}
+
+	/**
+	* Define uma propriedade de uma instância.
+	* @param int $instanceID O ID da instância.
+	* @return bool true caso a propriedade tenha sido alterada com sucesso
+	* @access public
+	*/
+	public function setProperty($instanceID, $propertyName, $propertyValue)
+	{
+		/* check instanceID */
+		if (!$this->checkInstanceAccess($instanceID))
+			return false;
+
+		/* load the instance object */
+		$instance = $this->getInstanceObject($instanceID);
+
+		/* set the property */
+		$output = $instance->set($propertyName, $propertyValue);
+		$output = $output && $instance->sync();
+
+		return $output;
+	}
+
+	/**
+	* Busca as instância de usuários de acordo com alguns critérios
+	* @param mixed $users Um array com IDs de usuários ou perfis (no caso de perfis, deve-se prefixar seu ID com o caractere 'p'). Também pode possuir um único ID (seja de usuário ou de perfil)
+	* @param mixed $activities Um array com IDs de atividades das se quer as instâncias. Também pode ser um inteiro, representando um único ID. Caso possua valor null, o resultado não é filtrado de acordo com as atividades (parâmetro opcional)
+	* @param mixed $status Um array com os status requeridos (para filtrar as instâncias). Também pode ser uma string, representando um único status. Caso possua valor null, o resultado não é filtrado de acordo com o status. Os status podem ser: completed, active, aborted e exception (parâmetro opcional)
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	*/
+	public function getByUser($users, $activities = null, $status = null)
+	{
+		/* check for the supplied users/roles */
+		if (empty($users))
+			return array();
+		if (!is_array($users))
+			$users = array($users);
+		foreach ($users as &$user)
+		{
+			if (!eregi('^[p]{0,1}[0-9]+$', "$user"))
+				trigger_error('wf_engine::getUserInstances: O usuário/perfil "' . $user . '" é inválido', E_USER_ERROR);
+			$user = "'{$user}'";
+		}
+
+		/* check for activity restriction */
+		$restrictToActivities = !is_null($activities);
+		if (!is_array($activities))
+			$activities = array((int) $activities);
+		array_walk($activities, create_function('&$a', '$a = (int) $a;'));
+
+		/* check for status restriction */
+		$statusPossibleValues = array('completed', 'active', 'aborted', 'exception');
+		$restrictToStatus = !is_null($status);
+		if (is_string($status))
+			$status = array($status);
+		/* check if the supplied status are valid */
+		if ($restrictToStatus)
+		{
+			array_walk($status, create_function('&$a', '$a = strtolower($a);'));
+			foreach ($status as $currentStatus)
+				if (!in_array($currentStatus, $statusPossibleValues))
+					trigger_error('wf_engine::getUserInstances: O status "' . $currentStatus . '" é inválido', E_USER_ERROR);
+		}
+
+		/* build the SQL query */
+		$query = "SELECT ia.wf_instance_id AS wf_instance_id, ia.wf_activity_id AS wf_activity_id, ia.wf_started AS wf_started, i.wf_name AS wf_name, i.wf_status AS wf_status, ia.wf_user AS wf_user, i.wf_priority AS wf_priority ";
+		$query .= "FROM egw_wf_instance_activities ia, egw_wf_instances i ";
+		$query .= "WHERE (ia.wf_instance_id = i.wf_instance_id) AND (i.wf_p_id = ?) AND (ia.wf_user IN (" . implode(', ', $users) . "))";
+		$values = array($this->processID);
+
+		if ($restrictToActivities)
+		{
+			$query .= ' AND (ia.wf_activity_id = ANY (?))';
+			$values[] = '{' . implode(', ', $activities) . '}';
+		}
+
+		if ($restrictToStatus)
+		{
+			$aux = ' AND (i.wf_status IN (';
+			foreach($status as $id){
+				$values[] = $id;
+				$query .= $aux.' ?';
+				$aux = ', ';
+			}
+			$query .= ' ))';
+		}
+
+		$resultSet = $this->db->query($query, $values);
+
+		/* fetch and return the results */
+		return $resultSet->GetArray(-1);
+	}
+
+	/**
+	* Busca todas as instâncias que possuem esse nome (identificador).
+	* @param string $name O nome da instância que se quer encontrar.
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	*/
+	public function getByName($name)
+	{
+		/* build the SQL query */
+		$query = 'SELECT i.wf_instance_id AS wf_instance_id, ia.wf_activity_id AS wf_activity_id, ia.wf_started AS wf_started, i.wf_name AS wf_name, i.wf_status AS wf_status, ia.wf_user AS wf_user, i.wf_priority AS wf_priority ';
+		$query .= 'FROM egw_wf_instances i LEFT JOIN egw_wf_instance_activities ia ON (ia.wf_instance_id = i.wf_instance_id)';
+		$query .= 'WHERE (i.wf_p_id = ?) AND (UPPER(i.wf_name) = UPPER(?))';
+
+		$resultSet = $this->db->query($query, array($this->processID, $name));
+		return $resultSet->GetArray();
+	}
+
+	/**
+	* Verifica se um dado usuário tem acesso a uma instância
+	* @param int $userID O ID do usuário que se quer verificar
+	* @param int $instanceID O ID da instância
+	* @param int $activityID O ID da atividade onde a instância está
+	* @param bool $writeAccess Se true, indica que é necessário que o usuário tenha acesso para modificar a instância (dar seqüência ao fluxo). Se false, não será verificado se o usuário tem permissão de escrita na instância
+	* @return bool true se o usuário tiver acesso à instância (levando em consideração $writeAccess) ou false caso contrário
+	* @access public
+	*/
+	public function checkUserAccess($userID, $instanceID, $activityID, $writeAccess = true)
+	{
+		/* only integers are allowed */
+		$userID = (int) $userID;
+		$instanceID = (int) $instanceID;
+		$activityID = (int) $activityID;
+
+		/* load the required instance (for the required user) */
+		$GUI = &Factory::newInstance('GUI');
+		$userInstance = $GUI->gui_list_user_instances($userID, 0, -1, '', '', "(ga.wf_is_interactive = 'y') AND (gia.wf_activity_id = {$activityID}) AND (gia.wf_instance_id = {$instanceID})", false, $this->processID, true, false, true, false, false, false);
+		$userInstance = $userInstance['data'];
+
+		/* if no instance is found, the user does not have access to it */
+		if (empty($userInstance))
+			return false;
+
+		/* if no write access is required, then the user have access to the instance */
+		if (!$writeAccess)
+			return true;
+
+		/* write access is required, check for it */
+		return ($userInstance['wf_readonly'] == 0);
+	}
+
+	/**
+	* Define o usuário de uma instância (em uma atividade)
+	* @param int $instanceID O ID da instância.
+	* @param int $activityID O ID da atividade.
+	* @param int $userID O ID do usuário.
+	* @return boolean true se foi possível definir o usuário da instância ou false caso contrário.
+	* @access public
+	*/
+	public function setUser($instanceID, $activityID, $userID)
+	{
+		/* check instanceID and activityID */
+		if (!$this->checkInstanceAccess($instanceID, $activityID))
+			return false;
+
+		if ($userID !== '*')
+		{
+			$wfRole = Factory::getInstance('wf_role');
+			$engine = Factory::getInstance('wf_engine');
+			/* get information about the activity */
+			if (($activityInfo = $engine->getActivityInformationByID($activityID)) === false)
+				return false;
+
+			/* load the possible roles of the activity */
+			$possibleRoles = $wfRole->getActivityRoles($activityInfo['name']);
+			if (substr($userID, 0, 1) == 'p')
+			{
+				/* the instance is being set to a role */
+				/* check if the role is valid */
+				$roleID = (int) substr($userID, 1);
+				$userID = 'p' . $roleID;
+				$validRole = false;
+				foreach ($possibleRoles as $possibleRole)
+				{
+					if ($roleID == $possibleRole['id'])
+					{
+						$validRole = true;
+						break;
+					}
+				}
+				if (!$validRole)
+					return false;
+			}
+			else
+			{
+				/* the instance is being set to a user */
+				/* check if the $userID is a number */
+				if (!is_numeric($userID))
+					return false;
+
+				/* check if the user is valid */
+				$userID = (int) $userID;
+				$validUser = false;
+				foreach ($possibleRoles as $possibleRole)
+				{
+					if ($wfRole->checkUserInRole($userID, $possibleRole['name']))
+					{
+						$validUser = true;
+						break;
+					}
+				}
+				if (!$validUser)
+					return false;
+			}
+		}
+
+		$query = 'UPDATE egw_wf_instance_activities SET wf_user = ? WHERE (wf_instance_id = ?) AND (wf_activity_id = ?)';
+		$this->db->execute($query, array($userID, $instanceID, $activityID));
+
+		return true;
+	}
+
+	/**
+	* Define o perfil que poderá acessar uma instância (em uma atividade)
+	* @param int $instanceID O ID da instância.
+	* @param int $activityID O ID da atividade.
+	* @param string $roleName O nome do perfil.
+	* @return boolean true se foi possível definir o perfil da instância ou false caso contrário.
+	* @access public
+	*/
+	public function setRole($instanceID, $activityID, $roleName)
+	{
+		/* check instanceID and activityID */
+		if (!$this->checkInstanceAccess($instanceID, $activityID))
+			return false;
+
+		/* try to get the role id */
+		$wfRole = Factory::getInstance('wf_role');
+		if (($roleID = $wfRole->getRoleIdByName($roleName)) === false)
+			return false;
+
+		return $this->setUser($instanceID, $activityID, 'p' . $roleID);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_engine.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_engine.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_engine.php	(revision 2372)
@@ -0,0 +1,372 @@
+<?php
+/**
+* Provê métodos que acessam informações relacionadas à engine.
+* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+* @subpackage local
+*/
+class wf_engine
+{
+	/**
+	* @var object $processManager objeto da classe ProcessManager
+	* @access private
+	*/
+	var $processManager;
+	/**
+	* @var object $acl objeto da classe workflow_acl
+	* @access private
+	*/
+	var $acl;
+	/**
+	* @var object $run_activity objeto da classe run_activity
+	* @access private
+	*/
+	var $run_activity;
+
+	/**
+	* Construtor do wf_engine.
+	* @return object
+	* @access public
+	*/
+	function wf_engine()
+	{
+		$this->processManager = null;
+		$this->acl = null;
+		$this->run_activity = null;
+	}
+
+	private function getCurrentProcessID()
+	{
+		if (!is_null($GLOBALS['workflow']['wf_runtime']->activity))
+			return (int) $GLOBALS['workflow']['wf_runtime']->activity->getProcessId();
+
+		if (isset($GLOBALS['workflow']['job']))
+			return (int) $GLOBALS['workflow']['job']['processID'];
+
+		return false;
+	}
+
+	private function checkProcessAccess($processID)
+	{
+		$processID = (int) $processID;
+		return ($processID === $this->getCurrentProcessID());
+	}
+
+	/**
+	* Busca informações de um (ou mais) processo(s).
+	* @param mixed $pids Uma array de IDs de processo ou um inteiro representando o ID de um processo.
+	* @return array Informações sobre o(s) processo(s).
+	* @access public
+	*/
+	function getProcess($pids)
+	{
+		if (!is_array($pids))
+			$pids = array($pids);
+
+		$flagObject[0] = is_null($this->processManager);
+		if ($flagObject[0])
+			$this->processManager = Factory::getInstance('workflow_processmanager');
+
+		$output = array();
+		foreach ($pids as $pid)
+			$output[] = $this->processManager->get_process($pid, false);
+
+		if ($flagObject[0])
+			$this->processManager = null;
+
+		return $output;
+	}
+
+	/**
+	* Dá seqüência no fluxo de uma instância (simula ação do usuário).
+	* @param int $activityID O ID da atividade da instância.
+	* @param int $instanceID O ID da instância.
+	* @return bool true caso a instância tenha sido continuada e false caso contrário.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function continueInstance($activityID, $instanceID)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->continueInstance($activityID, $instanceID);
+	}
+
+	/**
+	* Aborta uma instância
+	* @param int $instanceID O ID da instância.
+	* @return boolean true se foi possível abortar a instância e false caso contrário.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function abortInstance($instanceID)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->abort($instanceID);
+	}
+
+	/**
+	* Define o nome (identificador) de uma instância
+	* @param int $instanceID O ID da instância.
+	* @param string $name O novo nome da instância.
+	* @return boolean true se foi possível mudar o nome da instância e false caso contrário.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function setInstanceName($instanceID, $name)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->setName($instanceID, $name);
+	}
+
+	/**
+	* Define a prioridade de uma instância
+	* @param int $instanceID O ID da instância.
+	* @param int $priority A nova prioridade da instância
+	* @return boolean true se foi possível mudar a prioridade da instância e false caso contrário.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function setInstancePriority($instanceID, $priority)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->setPriority($instanceID, $priority);
+	}
+
+	/**
+	* Busca instâncias abandonadas.
+	* @param int $numberOfDays O tempo (em dias) em que a instância está abandonada.
+	* @param array $activities Uma lista de atividades das quais se quer as instâncias abandonadas (também pode ser um valor inteiro).
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getIdleInstances($numberOfDays, $activities = null)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->getIdle($numberOfDays, $activities);
+	}
+
+	/**
+	* Busca todas as instâncias.
+	* @param array $activities Uma lista de atividades das quais se quer as instâncias (também pode ser um valor inteiro).
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getInstances($activities = null)
+	{
+		return $this->getIdleInstances(0, $activities);
+	}
+
+	/**
+	* Busca todas as instâncias que possuem esse nome (identificador).
+	* @param string $name O nome da instância que se quer encontrar.
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getInstancesByName($name)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		$preOutput = $WFInstance->getByName($name);
+		$output = array();
+		foreach ($preOutput as $childInstance)
+			if (!is_null($childInstance['wf_activity_id']))
+				$output[] = $childInstance;
+
+		return $output;
+	}
+
+	/**
+	* Busca as instâncias filhas de uma instância
+	* Se os parâmetros não forem informados, retorna instâncias filhas das instância atual.
+	* @param int $instanceID O ID da instância pai (não obrigatório).
+	* @param int $activityID O ID da atividade corrente da instância pai
+	* @return array As instâncias filhas do par instância/atividade atual
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getChildInstances($instanceID = null, $activityID = null)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		$preOutput = $WFInstance->getChildren($instanceID, $activityID);
+		$output = array();
+		foreach ($preOutput as $childInstance)
+			if (!is_null($childInstance['wf_activity_id']))
+				$output[] = $childInstance;
+
+		return $output;
+	}
+
+	/**
+	* Busca as propriedades de uma instância (do mesmo processo).
+	* @param int $instanceID O ID da instância.
+	* @return mixed Uma array contento as propriedades da instância (no formato "nome_da_propriedade" => "valor"). Ou false em caso de erro.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getInstanceProperties($instanceID)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->getProperties($instanceID);
+	}
+
+	/**
+	* Busca as propriedades de uma instância filha.
+	* @param int $instanceID O ID da instância filha.
+	* @return array Propriedades da instância filha. Array no formato "nome_da_propriedade" => "valor".
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getChildInstanceProperties($instanceID)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->getProperties($instanceID);
+	}
+
+	/**
+	* Busca os recursos que um usuário pode administrar.
+	* @param string $type Tipo do recurso ("PRO", "MON, etc.).
+	* @param int $uid O usuário do qual se quer obter informações de administração de recursos.
+	* @return array IDs dos recursos ao qual o usuário tem acesso.
+	* @access public
+	*/
+	function getUserPermissions($type, $uid)
+	{
+		$flagObject[0] = is_null($this->acl);
+		if ($flagObject[0])
+			$this->acl = Factory::getInstance('workflow_acl');
+
+		$output = $this->acl->getUserPermissions($type, $uid);
+
+		if ($flagObject[0])
+			$this->acl = null;
+
+		return $output;
+	}
+
+	/**
+	* Busca os recursos que um usuário pode administrar (inclusive faz verificação de acordo com permissões advindas de grupos).
+	* @param string $type Tipo do recurso ("PRO", "MON, etc.).
+	* @param int $uid O usuário do qual se quer obter informações de administração de recursos.
+	* @return array IDs dos recursos ao qual o usuário tem acesso.
+	* @access public
+	*/
+	function getUserGroupPermissions($type, $uid)
+	{
+		$flagObject[0] = is_null($this->acl);
+		if ($flagObject[0])
+			$this->acl = Factory::getInstance('workflow_acl');
+
+		$output = $this->acl->getUserGroupPermissions($type, $uid);
+
+		if ($flagObject[0])
+			$this->acl = null;
+
+		return $output;
+	}
+
+	/**
+	* Traz informações sobre uma atividade a partir de seu ID
+	* @param int $activityID O ID da atividade
+	* @return mixed Uma array associativa contendo as informações sobre a atividade ou false caso a atividade não seja encontrada
+	* @access public
+	*/
+	function getActivityInformationByID($activityID)
+	{
+		$activityID = (int) $activityID;
+		$processID = $this->getCurrentProcessID();
+
+		/* build the SQL query */
+		$query = "SELECT wf_activity_id, wf_name, wf_normalized_name, wf_type, wf_description FROM egw_wf_activities WHERE (wf_activity_id = ?) AND (wf_p_id = ?)";
+		$db = &$GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID;
+		$resultSet = $db->query($query, array($activityID, $processID));
+
+		/* return the data */
+		if (($row = $resultSet->fetchRow()))
+			return array(
+				'activity_id' => $row['wf_activity_id'],
+				'name' => $row['wf_name'],
+				'normalized_name' => $row['wf_normalized_name'],
+				'type' => $row['wf_type'],
+				'description' => $row['wf_description']
+			);
+		else
+			return false;
+	}
+
+	/**
+	* Traz informações sobre uma atividade a partir de seu nome
+	* @param int $activityName O nome da atividade
+	* @return mixed Uma array associativa contendo as informações sobre a atividade ou false caso a atividade não seja encontrada
+	* @access public
+	*/
+	function getActivityInformationByName($activityName)
+	{
+		$processID = $this->getCurrentProcessID();
+
+		/* build the SQL query */
+		$query = "SELECT wf_activity_id, wf_name, wf_normalized_name, wf_type, wf_description FROM egw_wf_activities WHERE (wf_name = ?) AND (wf_p_id = ?)";
+		$db = &$GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID;
+		$resultSet = $db->query($query, array($activityName, $processID));
+
+		/* return the data */
+		if (($row = $resultSet->fetchRow()))
+			return array(
+				'activity_id' => $row['wf_activity_id'],
+				'name' => $row['wf_name'],
+				'normalized_name' => $row['wf_normalized_name'],
+				'type' => $row['wf_type'],
+				'description' => $row['wf_description']
+			);
+		else
+			return false;
+	}
+
+	/**
+	* Busca as instância de usuários de acordo com alguns critérios
+	* @param mixed $users Um array com IDs de usuários ou perfis (no caso de perfis, deve-se prefixar seu ID com o caractere 'p'). Também pode possuir um único ID (seja de usuário ou de perfil)
+	* @param mixed $activities Um array com IDs de atividades das se quer as instâncias. Também pode ser um inteiro, representando um único ID. Caso possua valor null, o resultado não é filtrado de acordo com as atividades (parâmetro opcional)
+	* @param mixed $status Um array com os status requeridos (para filtrar as instâncias). Também pode ser uma string, representando um único status. Caso possua valor null, o resultado não é filtrado de acordo com o status. Os status podem ser: completed, active, aborted e exception (parâmetro opcional)
+	* @return array As instâncias que satisfazem o critério de seleção.
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function getUserInstances($users, $activities = null, $status = null)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->getByUser($users, $activities, $status);
+	}
+
+	/**
+	* Seta uma propriedade de uma instância.
+	* @param int $instanceID O ID da instância.
+	* @return bool true caso a propriedade tenha sido alterada com sucesso
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function setInstanceProperty($instanceID, $nameProperty, $value)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->setProperty($instanceID, $nameProperty, $value);
+	}
+
+	/**
+	* Verifica se um dado usuário tem acesso a uma instância
+	* @param int $userID O ID do usuário que se quer verificar
+	* @param int $instanceID O ID da instância
+	* @param int $activityID O ID da atividade onde a instância está
+	* @param bool $writeAccess Se true, indica que é necessário que o usuário tenha acesso para modificar a instância (dar seqüência ao fluxo). Se false, não será verificado se o usuário tem permissão de escrita na instância
+	* @return bool true se o usuário tiver acesso à instância (levando em consideração $writeAccess) ou false caso contrário
+	* @access public
+	* @deprecated 1.7.00.000
+	*/
+	function checkUserAccessToInstance($userID, $instanceID, $activityID, $writeAccess = true)
+	{
+		$WFInstance = &Factory::getInstance('wf_instance');
+		return $WFInstance->checkUserAccess($userID, $instanceID, $activityID, $writeAccess);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_paging.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_paging.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_paging.php	(revision 795)
@@ -0,0 +1,223 @@
+<?php
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'class.Paging.inc.php');
+/**
+* Class for generating paging links
+* @author Sidnei Augusto Drovetto Junior
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow 
+* @subpackage local  
+*/
+class wf_paging extends Paging
+{
+	
+	/**
+	 * @var boolean $flagUseDatabase Indica se a base de dados será utilizada
+	 * @access public
+	 */
+	var $flagUseDatabase;
+	/**
+	 * @var boolean $flagEnableSorting Habilita o sort
+	 * @access public
+	 */
+	var $flagEnableSorting;
+	/**
+	 * @var array $storage Armazena os dados da consulta
+	 * @access public
+	 */
+	var $storage;
+	/**
+	 * @var array $titles Armazena o titulo dos links
+	 * @access public
+	 */
+	var $titles;
+	/**
+	 * @var array $generatedTitles Armazena os titulos dos links gerados
+	 * @access public
+	 */
+	var $generatedTitles ;
+	/**
+	 * Inicializa os atributos da classe com valores padrões
+	 * @return void
+	 * @access private
+	 */
+	function initialize()
+	{
+		parent::initialize();
+
+		$this->storage = array();
+		$this->titles = null;
+		$this->generatedTitles = null;
+	}
+	/**
+	 * Utilizado para configurar a paginação
+	 * @param int $pItemsPerPage Numero de Itens por página
+	 * @param array $request requisição
+	 * @return void
+	 * @access public
+	 */
+	function configure($pItemsPerPage, $request = null)
+	{
+		$this->itemsPerPage = $pItemsPerPage;
+		$this->originalRequest = $request;
+
+		$this->initialize();
+	}
+	/**
+	 * Construtor da classe wf_paging
+	 * @return object
+	 * @access public
+	 */
+	function wf_paging()
+	{
+	}
+	/**
+	 * Utilizado para habilitar o flag que indica para fazer o sort
+	 * @param boolean $value (true ou false)
+	 * @access public
+	 */
+	function enableSorting($value)
+	{
+		$this->flagEnableSorting = $value;
+	}
+	/**
+	 * Utilizado para habilitar o flag que indica o uso de uma database
+	 * @param boolean $value (true ou false)
+	 * @access public
+	 */
+	function useDatabase($value)
+	{
+		$this->flagUseDatabase = $value;
+	}
+	/**
+	 * Realiza a paginação do resultado de uma consulta.
+	 * @param object $db  banco de dados da pesquisa
+	 * @param string $sql consulta em sql
+	 * @param array $values Valores que serão associados à query através de bind (opcional)
+	 * @return mixed (array ou boolean)
+	 * @access public
+	 */
+	function restrictDBItems($db, $sql, $values = false)
+	{
+		if (!$this->flagUseDatabase)
+			return false;
+
+		/* adiciona ordenação (se requisitado) */
+		if ($this->flagEnableSorting)
+			if (isset($this->storage['s_co']))
+				$sql .= " ORDER BY " . $this->storage['s_co'] . " " . (($this->storage['s_so'] == 0) ? "DESC" : "ASC");
+
+		/* utilliza diretamente o objeto ADOdb */
+		$adoDB = &$db->Link_ID;
+
+		/* executa a consulta (com possibilidade de passar variáveis por bind */
+		$resultSet = $adoDB->query($sql, $values);
+
+		/* faz a contagem de registros e extrai a quantidade desejada */
+		$this->itemsCount = $resultSet->RecordCount();
+		$this->items = $adoDB->_rs2rs($resultSet, $this->itemsPerPage, $this->nextItem, true)->GetArray();
+
+		return parent::restrictItems($this->items, $this->itemsCount);
+	}
+
+	/**
+	 * Utilizado para fazer o parse numa requisição
+	 * @param array $request requisição
+	 * @return void
+	 * @access public
+	 */
+	function parseRequest($request)
+	{
+		parent::parseRequest($request);
+		$this->newRequest = $this->_cleanRequest(array("p_page", "s_co", "s_so"), $request);
+	}
+
+	/**
+	 * Utilizado para determinar os parametros (links) para o sort  
+	 * @param array $ptitles
+	 * @return void
+	 * @access public
+	 */
+	function setSortingTitles($pTitles)
+	{
+		$this->titles = $pTitles;
+		$this->generateSortingTitles();
+	}
+    /**
+	 * Utilizado para buscar os links possíves para o sort  
+	 * @return void
+	 * @access public
+	 */
+	function getSortingTitles()
+	{
+		return $this->generatedTitles;
+	}
+	
+	/**
+	 * Utilizado para gerar os parametros (links) possíves para o sort  
+	 * @return boolean
+	 * @access public
+	 */ 
+	function generateSortingTitles()
+	{
+		if (is_null($this->titles))
+			return false;
+
+		if (!empty($this->newRequest))
+			$charSeparator = "&amp;";
+		else
+			$charSeparator = "";
+		
+		$requestSco = (isset($this->originalRequest['s_co'])) ? $this->originalRequest['s_co'] : 0;
+		$requestSco = (is_numeric($requestSco)) ? (int) $requestSco : 0;
+		$requestSso = (isset($this->originalRequest['s_so'])) ? $this->originalRequest['s_so'] : 0;
+		$requestSso = (is_numeric($requestSso)) ? (int) $requestSso : 0;
+		if ($requestSso != 1)
+			$requestSso = 0;
+
+		$allowedIds = array();
+		$this->generatedTitles = array();
+		foreach ($this->titles as $title)
+		{
+			$sco = $title['id'];
+			$allowedIds[] = $sco;
+			$sso = 0;
+			$arrow = "";
+			if ($sco == $requestSco)
+			{
+				if ($requestSso == 0)
+				{
+					$sso = 1;
+					$arrow = "&nbsp;&nbsp;&uarr;";
+				}
+				else
+				{
+					$sso = 0;
+					$arrow = "&nbsp;&nbsp;&darr;";
+				}
+			}
+			$title['link'] = $this->baseLink . "?" . $this->newRequest . $charSeparator . "s_co=$sco&amp;s_so=$sso";
+			$title['original_name'] = $title['name'];
+			$title['name'] .= $arrow;
+			$this->generatedTitles[] = $title;
+		}
+		
+		$allowedIds = array_values(array_unique($allowedIds));
+		$this->storage['s_co'] = (in_array($requestSco, $allowedIds)) ? $requestSco : $allowedIds[0];
+		$this->storage['s_so'] = $requestSso;
+	}
+
+/**
+ * Retorna o resultado da paginação
+ * @return array
+ * @access public 
+ *  */
+	function paginationResult()
+	{
+		$output = parent::paginationResult();
+		if (isset($this->originalRequest['s_co']) && isset($this->originalRequest['s_so']))
+			for ($i = 0; $i < count($output); $i++)
+				$output[$i]['link'] .= "&amp;s_co=" . $this->storage['s_co'] . "&amp;s_so=" . $this->storage['s_so'];
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_string.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_string.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_string.php	(revision 795)
@@ -0,0 +1,20 @@
+<?php
+/**
+ * importa classe do módulo
+ */
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'class.utils.string.php');
+
+/**
+ * Classe que contém funções utilitárias para manipulação
+ * de strings. As funções extendem a funcionalidade já oferecida
+ * pelo PHP (agrupando e tornando mais prática a utilização)
+ * e incluem novas ferramentas não implementadas
+ * de dados e conversão (cast) entre tipos primitivos de dados no PHP
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ */
+class wf_string extends StringUtils {}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_phplot.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_phplot.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_phplot.php	(revision 795)
@@ -0,0 +1,28 @@
+<?php
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'phplot'.SEP.'phplot.php');
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'phplot'.SEP.'phplot_data.php');
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'phplot'.SEP.'rgb.inc.php');
+
+/**
+ * Classe para geração de gráficos dinâmicos.
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Allan Bomfim
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com (revisão)
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_phplot extends PHPlot
+{
+	/**
+	 * Construtor da classe wf_phplot
+	 * @param int $width Largura da imagem.
+	 * @param int $height Altura da imagem.
+	 * @return object
+	 * @access public
+	 */
+	function wf_phplot($width = 800, $height = 600)
+	{
+		parent::PHPlot($width, $height);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_natural.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_natural.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_natural.php	(revision 795)
@@ -0,0 +1,130 @@
+<?php
+	require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'natural'.SEP.'class.natural.php');
+
+	/**
+	* Mainframe connection to workflow
+	* @author Everton Flávio Rufino Seára
+	* @package Workflow
+	* @subpackage local
+	* @license http://www.gnu.org/copyleft/gpl.html GPL
+	**/
+
+	class wf_natural extends Natural
+	{
+
+		function __construct()
+		{
+			parent::Natural();
+
+			$natconf = array(
+						'mainframe_ip'			=> '',
+						'mainframe_port'		=> '',
+						'mainframe_key'			=> '',
+						'mainframe_password'	=> '',
+						'mainframe_environment'	=> ''
+			);
+
+			$nat_conf_values = $GLOBALS['workflow']['wf_runtime']->getConfigValues($natconf);
+
+			$this->setIPAddress($nat_conf_values['mainframe_ip']);
+			$this->setServerPort($nat_conf_values['mainframe_port']);
+			$this->setKey($nat_conf_values['mainframe_key']);
+			$this->setPassword($nat_conf_values['mainframe_password']);
+			$this->setApplication($nat_conf_values['mainframe_environment']);
+		}
+
+		/**
+		 * Method to configure the access to mainframe
+		 * This method MUST be called before using execute method, else 'false' will be returned
+		 *
+		 * Only the first and second param are mandatory.
+		 *
+		 * @param String $subProgram - Name of sub-program
+		 * @param String $inputParameter - Input parameters to sub-program
+		 *
+		 * @param String $ip - IP Address of Mainfram
+		 * @param int $port - ServerPort to access the mainframe
+		 * @param String $key - Access key (user)
+		 * @param String $password - Key (user) password
+		 * @param char $environment - Application environment access 'D' (development) or 'P' (production)
+
+		 */
+
+		public function configure($obj)
+		{
+			$this->obj = $obj;
+
+			$this->initialize($obj->name);
+
+			if ($obj->server != NULL){
+				$this->setIPAddress($obj->server);
+			}
+			if ($obj->port != NULL){
+				$this->setServerPort($obj->port);
+			}
+			if ($obj->key != NULL){
+				$this->setKey($obj->key);
+			}
+			if ($obj->password != NULL){
+				$this->setPassword($obj->password);
+			}
+			if ($obj->environment != NULL){
+				$this->setApplication($obj->environment);
+			}
+			if ($obj->logon != NULL){
+				$this->setLogon($obj->logon);
+			}
+			if ($obj->system != NULL){
+				$this->setSystem($obj->system);
+			}
+			if ($obj->rc != NULL){
+				$this->setRC($obj->rc);
+			}
+		}
+
+		/*
+
+		public function configure($subProgram, $inputParameter, $ip = NULL, $port = NULL,
+										$key = NULL, $password = NULL, $environment = NULL, $logon = NULL, $system = NULL, $rc = NULL)
+		{
+			$this->initialize($subProgram, $inputParameter);
+
+			if ($ip != NULL){
+				$this->setIPAddress($ip);
+			}
+			if ($port != NULL){
+				$this->setServerPort($port);
+			}
+			if ($key != NULL){
+				$this->setKey($key);
+			}
+			if ($password != NULL){
+				$this->setPassword($password);
+			}
+			if ($environment != NULL){
+				$this->setApplication($environment);
+			}
+			if ($logon != NULL){
+				$this->setLogon($logon);
+			}
+			if ($system != NULL){
+				$this->setSystem($system);
+			}
+			if ($rc != NULL){
+				$this->setRC($rc);
+			}
+
+		}
+
+		 */
+
+		/**
+		 * Access and retrieve data from mainframe
+		 * @return bool
+		 */
+		public function execute($inputParams = "")
+		{
+			return parent::execute($inputParams);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_cached_ldap.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_cached_ldap.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_cached_ldap.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+require_once PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'class.CachedLDAP.inc.php';
+
+/**
+* Gera um cache do LDAP (em banco de dados) para não perder informações no caso de exclusão de um funcionário
+* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+* @subpackage local
+*/
+class wf_cached_ldap extends CachedLDAP
+{
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_location.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_location.php	(revision 2160)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_location.php	(revision 2160)
@@ -0,0 +1,243 @@
+<?php
+/**
+ * Class for getting city/state information
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ */
+
+class wf_location
+{  /**
+	* @var object $db banco de dados
+	* @access private
+	*/
+	var $db;
+   /**
+	* @var array $cityInfo Armazena informações sobre a cidade
+	* @access public
+	*/
+	var $cityInfo;
+   /**
+	* @var array $stateInfo Armazena as informações sobre o Estado
+	* @access public
+	*/
+	var $stateInfo;
+   /**
+	* @var array $citiesFromState Armazena as cidades de um estado
+	* @access public
+	*/
+	var $citiesFromState;
+
+	/**
+	 * Inicializa os arrays da classe
+	 * return void
+	 * @access private
+	 */
+	function initialize()
+	{
+		$this->db = &$GLOBALS['workflow']['workflowObjects']->getDBExpresso()->Link_ID;
+		$this->db->setFetchMode(ADODB_FETCH_ASSOC);
+		$this->cityInfo = array();
+		$this->stateInfo = array();
+		$this->citiesFromState = array();
+	}
+
+	/**
+	 * Construtor da classe
+	 * return object
+	 * @access public
+	 */
+	function wf_location()
+	{
+		$this->initialize();
+	}
+
+	/**
+	 * Busca as informações da cidade pelo numero id passado
+	 * @param int $city_id Numero ID da cidade
+	 * @return mixed (array ou boolean)
+	 * @access public
+	 */
+	function getCityById($city_id)
+	{
+		if (!is_numeric($city_id))
+			return false;
+
+		$city_id = (int) $city_id;
+		if (isset($this->cityInfo[$city_id]))
+			return $this->cityInfo[$city_id];
+
+		$sql =
+		"SELECT
+			c.id_city AS id_city,
+			c.city_name AS city_name,
+			c.is_district,
+			s.id_state AS id_state,
+			s.state_name AS state_name,
+			s.state_symbol AS state_symbol
+		FROM
+			phpgw_cc_state s,
+			phpgw_cc_city c
+		WHERE
+			c.id_state = s.id_state AND
+			s.id_country = 'BR' AND
+			c.id_city = ?";
+
+		$result = $this->db->query($sql, array($city_id));
+		$output = $result->fetchRow();
+
+		$this->cityInfo[$city_id] = $output;
+		return $output;
+	}
+
+   /**
+	* Busca as informações do estado pelo id passado
+	* @param int $state_id Numero ID do estado
+	* @return mixed (array ou boolean)
+	* @access public
+	*/
+	function getStateById($state_id)
+	{
+		if (!is_numeric($state_id))
+			return false;
+
+		$state_id = (int) $state_id;
+		if (isset($this->stateInfo[$state_id]))
+			return $this->stateInfo[$state_id];
+
+		$sql =
+		"SELECT
+			id_state,
+			state_name,
+			state_symbol
+		FROM
+			phpgw_cc_state
+		WHERE
+			id_country = 'BR' AND
+			id_state = ?";
+
+		$result = $this->db->query($sql, array($state_id));
+		$output = $result->fetchRow();
+
+		$this->stateInfo[$city_id] = $output;
+		return $output;
+	}
+    /**
+	 * Busca as cidades de um estado
+	 * @param int $state_id Numero ID do estado
+	 * @param bool $include_districts True, busca cidades e distritos. False, busca apenas cidades.
+	 * @return mixed (array ou boolean)
+	 * @access public
+	 */
+	function getCitiesFromState($state_id, $include_districts = true)
+	{
+		if (!is_numeric($state_id) || !is_bool($include_districts))
+			return false;
+
+		$state_id = (int) $state_id;
+		if (isset($this->citiesFromState[$state_id]))
+			return $this->citiesFromState[$state_id];
+
+		$where = "";
+		if(!$include_districts){
+			$where = " AND c.is_district = 'F' ";
+		}
+
+		$sql =
+		"SELECT
+			c.id_city AS id_city,
+			c.city_name AS city_name,
+			c.is_district
+		FROM
+			phpgw_cc_state s,
+			phpgw_cc_city c
+		WHERE
+			c.id_state = s.id_state AND
+			s.id_country = 'BR' AND
+			c.id_state = ? " . $where . "
+		ORDER BY
+			city_name";
+
+		$result = $this->db->query($sql, array($state_id));
+		$output = array();
+		while ($row = $result->fetchRow())
+			$output[] = $row;
+
+		$this->citiesFromState[$state_id] = $output;
+		return $output;
+	}
+    /**
+	 * Busca as cidades por parte do nome, sem considerar maiúsculas e/ou minúsculas e nem acentuação (retorna 10 resultados)
+	 * @param string Parte do nome da cidade
+	 * @param int $state_id Numero ID do estado
+	 * @param bool $include_districts True, busca cidades e distritos. False, busca apenas cidades.
+	 * @return mixed (array ou boolean)
+	 * @access public
+	 */
+	function getCitiesByKey($key, $state_id = 0, $include_districts = true)
+	{
+		if (!is_string($key) || !is_numeric($state_id) || !is_bool($include_districts))
+			return false;
+
+		$where = "";
+		if($state_id > 0){
+			$where = " AND c.id_state = " . $state_id;
+		}
+
+		if(!$include_districts){
+			$where = " AND c.is_district = 'F' ";
+		}
+
+		$sql =
+		"SELECT
+			c.id_city AS id_city,
+			c.city_name AS city_name,
+			s.id_state AS id_state,
+			s.state_name AS state_name,
+			s.state_symbol AS state_symbol
+		FROM
+			phpgw_cc_state s,
+			phpgw_cc_city c
+		WHERE
+			c.id_state = s.id_state AND
+			s.id_country = 'BR' AND
+			TO_ASCII(c.city_name) ILIKE TO_ASCII('" . $key . "%')
+			" . $where . "
+		ORDER BY
+			city_name
+		LIMIT 10";
+
+		$result = $this->db->query($sql);
+		$output = array();
+		while ($row = $result->fetchRow())
+			$output[] = $row;
+
+		return $output;
+	}
+	/**
+	 * Busca os estados brasileiros
+	 * @return mixed (array ou boolean)
+	 * @access public
+	 */
+	function getStates()
+	{
+		$sql =
+		"SELECT
+			id_state,
+			state_name
+		FROM
+			phpgw_cc_state
+		WHERE
+			id_country = 'BR'
+		ORDER BY
+			state_name";
+
+		$result = $this->db->query($sql);
+		$output = array();
+		while ($row = $result->fetchRow())
+			$output[] = $row;
+
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.JobBase.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.JobBase.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.JobBase.php	(revision 2372)
@@ -0,0 +1,252 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Classe base dos Jobs
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @abstract
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+abstract class JobBase
+{
+	/**
+	 * @var int $jobID O ID do Job
+	 * @access private
+	 */
+	private $jobID;
+
+	/**
+	 * @var int $processID O ID do Processo
+	 * @access private
+	 */
+	private $processID;
+
+	/**
+	 * @var string $currentDate Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @access private
+	 */
+	private $currentDate;
+
+	/**
+	 * @var object $jobManager Objeto da classe JobManager
+	 * @access private
+	 */
+	private $jobManager;
+
+	/**
+	 * @var bool $userLog Indica se o usuário gravou algum log (true) ou não (false)
+	 * @access private
+	 */
+	private $userLog;
+
+	/**
+	 * @var float $maximumExecutionTime O tempo máximo de execução do Job
+	 * @access private
+	 */
+	private $maximumExecutionTime;
+
+	/**
+	 * @var float $timeStart Início do Job (em microsegundos)
+	 * @access private
+	 */
+	private $timeStart;
+
+	/**
+	 * @var bool $testMode Indica se o job está sendo executado em modo de teste (true) ou não (false)
+	 * @access protected
+	 */
+	protected $testMode;
+
+	/**
+	 * @var array $environment Contém algumas variáveis/objetos relevantes para a execução de alguns Jobs
+	 * @access protected
+	 */
+	protected $environment;
+
+	/**
+	 * Construtor da classe JobBase
+	 * @param int $jobID O ID do Job que será atualizado
+	 * @param int $processID O ID do processo a qual o Job pertence
+	 * @param string $currentDate Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @param bool $testMode Indica se o job está sendo executado em modo de teste (true) ou não (false)
+	 * @param float $maximumExecutionTime O tempo máximo de execução do Job (em segundos)
+	 * @return object Objeto da classe JobBase
+	 * @final
+	 * @access public
+	 */
+	final public function JobBase($jobID, $processID, $currentDate, $testMode, $maximumExecutionTime)
+	{
+		require_once 'common.inc.php';
+		Factory::getInstance('WorkflowMacro')->prepareEnvironment();
+		$this->jobID = $jobID;
+		$this->processID = $processID;
+		$this->currentDate = $currentDate;
+		$this->jobManager = Factory::getInstance('WorkflowJobManager');
+		$this->testMode = $testMode;
+		$this->maximumExecutionTime = $maximumExecutionTime;
+		$this->timeStart = microtime(true);
+		$this->userLog = false;
+
+		$this->prepareEnvironment();
+	}
+
+	/**
+	 * Indica que a execução do Job falhou
+	 * @param string $message A mensagem que será armazenada
+	 * @return void
+	 * @final
+	 * @access public
+	 */
+	final public function fail($message)
+	{
+		$this->jobManager->writeLog($this->jobID, $this->currentDate, $message, JobManager::STATUS_JOB_FAIL);
+		$this->userLog = true;
+	}
+
+	/**
+	 * Indica que a execução do Job foi bem sucedida
+	 * @param string $message A mensagem que será armazenada
+	 * @return void
+	 * @final
+	 * @access public
+	 */
+	final public function success($message)
+	{
+		$this->jobManager->writeLog($this->jobID, $this->currentDate, $message, JobManager::STATUS_JOB_SUCCESS);
+		$this->userLog = true;
+	}
+
+	/**
+	 * Grava uma mensagem de log padrão (caso o desenvolvedor não chame os métodos "fail" ou "success")
+	 * @return void
+	 * @final
+	 * @access private
+	 */
+	final private function defaultLog()
+	{
+		$this->jobManager->writeLog($this->jobID, $this->currentDate, 'Job executado', JobManager::STATUS_UNKNOWN);
+		$this->userLog = true;
+	}
+
+	/**
+	 * Prepara o ambiente para a execução do Job
+	 * @return void
+	 * @final
+	 * @access private
+	 */
+	final private function prepareEnvironment()
+	{
+		Factory::getInstance('WorkflowMacro')->prepareProcessEnvironment($this->processID);
+
+		$this->environment = array();
+		$this->environment['factory']  = &Factory::newInstance('ProcessWrapperFactory');
+	}
+
+	/**
+	 * Procedimentos que são executados na finalização do Job
+	 * @return void
+	 * @final
+	 * @access private
+	 */
+	final public function finalize()
+	{
+		if (!$this->userLog)
+			$this->defaultLog();
+	}
+
+	/**
+	 * Pega o tempo de execução do Job (até o momento)
+	 * @return float O tempo de execução do Job
+	 * @final
+	 * @access public
+	 */
+	final public function getExecutionTime()
+	{
+		return microtime(true) - $this->timeStart;
+	}
+
+	/**
+	 * Pega o tempo máximo de execução do Job
+	 * @return float O tempo máximo de execução do Job
+	 * @final
+	 * @access public
+	 */
+	final public function getMaximumExectuionTime()
+	{
+		return $this->maximumExecutionTime;
+	}
+
+	/**
+	 * Cria uma nova instância do processo e encaminha para a próxima atividade
+	 * @param int $startActivityId ID da atividade Start que será usada para criar a instância
+	 * @param string $instanceName Identificador da instância
+	 * @param array $properties Array associativo contendo as popriedades da instância
+	 * @param int $user uidNumer do usuário do dono da instância (usuário que gerou a instância)
+	 * @return bool true se a instância foi criada, caso contrário, false.
+	 * @final
+	 * @access public
+	 */
+	final public function createNewInstance($startActivityId, $instanceName=false, $properties=false, $user=false)
+	{
+		$activityManager = Factory::getInstance('workflow_activitymanager');
+		$activity = $activityManager->get_activity($startActivityId);
+
+		// Verifica se a atividade existe e é uma atividade de start
+		if ($activity['wf_type'] != 'start')
+			return false;
+
+		// Verifica se existe uma transição da atividade de start para outra atividade
+		$transition = $activityManager->get_process_transitions($this->processID, $startActivityId);
+		$nextActivityId = $transition[0]['wf_act_to_id'];
+		if (empty($nextActivityId))
+			return false;
+
+		// Captura objeto runtime da globals
+		$runtime = &$GLOBALS['workflow']['wf_runtime'];
+
+		// TODO: Pegar usuário padrão da tabela phpgw_config
+		$defaultUser = 73231;
+
+		// Seta usuário para execução. Se $user for false, seta usuário padrão do job
+		$uidNumber = ($user)? $user : $defaultUser;
+		if (empty($uidNumber)) return false;
+
+		$GLOBALS['phpgw_info']['user']['account_id'] = $uidNumber;
+		$_SESSION['phpgw_info']['workflow']['account_id'] = $uidNumber;
+		$GLOBALS['user'] = $uidNumber;
+
+		if (!empty($instanceName) && is_string($instanceName))
+			$runtime->setName($instanceName);
+
+		if (!empty($properties) && is_array($properties))
+			$runtime->setProperties($properties);
+
+		// Cria a instância
+		if ($runtime->instance->complete($startActivityId)){
+			// Envia instância para próxima transição
+			$runtime->instance->sendTo($startActivityId, $nextActivityId);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * É o método que contém o código do Job que será executado
+	 * @return void
+	 * @abstract
+	 * @access public
+	 */
+	abstract public function run();
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_orgchart.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_orgchart.php	(revision 2371)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_orgchart.php	(revision 2371)
@@ -0,0 +1,1320 @@
+<?php
+/**
+ * Classe que permite aos processos workflow fazer consultas ao Organograma
+ *
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.2
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_orgchart
+{
+	/**
+	 * @var object $db Link para o Banco de Dados do Workflow.
+	 * @access private
+	 */
+	var $db;
+
+	/**
+	 * Construtor da classe wf_orgchart
+	 * @return object
+	 * @access public
+	 */
+	function wf_orgchart()
+	{
+		$this->db = &$GLOBALS['workflow']['workflowObjects']->getDBWorkflow()->Link_ID;
+		$this->db->setFetchMode(ADODB_FETCH_ASSOC);
+	}
+
+	/**
+	 * Busca uma organização pelo seu ID.
+	 *
+	 * Este método irá procurar uma organização na tabela de organizações, pelo seu ID, e retornará seu dados básicos.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array associativa contendo os atributos de uma organização:
+	 * - organizacao_id
+	 * - nome: o nome abreviado da organização
+	 * - descrição: o nome completo da organização
+	 * - url_imagem: a url onde se encontra o gráfico da organização
+	 * - ativa: se a organização está ativa ou não
+	 * - sitio: a url da página web da organização
+	 * @access public
+	 */
+	function getOrganization($organizationID)
+	{
+		$query = "SELECT organizacao_id, nome, descricao, url_imagem, ativa, sitio" .
+				 "  FROM organizacao" .
+				 " WHERE (organizacao_id = ?)";
+
+		$result = $this->db->query($query, array($organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca uma organização pelo seu nome.
+	 *
+	 * Este método irá buscar os dados básicos de uma organização, procurando pela sua sigla.
+	 * @param string $name A sigla da organização.
+	 * @return array Uma array associativa contendo os atributos de uma organização:
+	 * - organizacao_id
+	 * - nome: a sigla da organização
+	 * - descricao: o nome completo
+	 * - url_imagem: a url onde se encontra o gráfico da organização
+	 * - ativa: se a organização está ativa ou não
+	 * - sitio: a url da página web da organização
+	 * @access public
+	 */
+	function getOrganizationByName($name)
+	{
+		$query = "SELECT organizacao_id, nome, descricao, url_imagem, ativa, sitio" .
+				 "  FROM organizacao" .
+				 " WHERE (UPPER(nome) = UPPER(?))";
+
+		$result = $this->db->query($query, array($name));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Lista todos os telefones úteis de uma organização.
+	 *
+	 * Este método irá listar a tabela telefone.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array de arrays associativas contendo a lista dos telefones de uma organização:
+	 * - telefone_id
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getOrganizationTelephones($organizationID)
+	{
+		$query = "SELECT telefone_id, descricao, organizacao_id" .
+				 "  FROM telefone" .
+				 "	WHERE organizacao_id = ?";
+
+		$result = $this->db->query($query, array((int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca as áreas de uma organização
+	 *
+	 * Este método irá buscar na tabela de áreas, todas as áreas que pertencem à organização solicitada.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array seqüencial contendo as áreas de uma organização. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - area_id
+	 * - area_status_id: corresponde ao nível hierárquico da area
+	 * - superior_area_id: o id da área acima da atual
+	 * - centro_custo_id: o id do centro de custo da area
+	 * - titular_funcionario_id: o id do funcionario titular da área. Corresponde ao uidNumber do funcionário no catálogo Ldap.
+	 * - substituto_funcionario_id: o id do funcionario que está substituindo o titular temporariamente
+	 * - sigla: sigla da area
+	 * - descrição: nome completo da area
+	 * - ativa: indicativo de situação da area, sendo 's' ativa, e 'n' inativa
+	 * - auxiliar_funcionario_id: id da secretária da área
+	 * @access public
+	 */
+	function getOrganizationAreas($organizationID)
+	{
+		$query = "SELECT a.organizacao_id, a.area_id, a.area_status_id, " .
+				 "       a.superior_area_id, a.centro_custo_id, a.titular_funcionario_id, " .
+				 "       a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, " .
+				 "		 s.funcionario_id as substituto_funcionario_id " .
+				 " FROM area a " .
+				 "  LEFT OUTER JOIN substituicao s " .
+				 "  ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) " .
+				 " WHERE " .
+				 "	(a.organizacao_id = ?) " .
+				 " ORDER BY a.sigla, a.descricao";
+
+		$result = $this->db->query($query, array($organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca os status de área de uma organização.
+	 *
+	 * O status de área deve ser compreendido como um nível hirárquico das áreas da organização.
+	 * Por exemplo: presidência, assessoria, diretoria, gerência, divisão, etc.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array de arrays associativas contendo os atributos dos status de área. Cada linha do array conterá:
+	 * - area_status_id
+	 * - organização_id
+	 * - descrição
+	 * - nível: a posição hierárquica do nível no organograma. Por exemplo: 1 - presidencia, 2 - assessoria, etc
+	 * @access public
+	 */
+	function getOrganizationAreaStatus($organizationID)
+	{
+		$query = "SELECT area_status_id, organizacao_id, descricao, nivel" .
+				 "  FROM area_status" .
+				 " WHERE (organizacao_id = ?)";
+
+		$result = $this->db->query($query, array($organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca as localidades de uma organização.
+	 *
+	 * As localidades de uma organização representam o local físico de trabalho dos funcionários.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array de arrays associativas contendo os atributos das localidades. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - localidade_id
+	 * - centro_custo_id
+	 * - descricao: o nome simplificado localidade
+	 * - empresa: o nome completo da localidade
+	 * - endereço: o logradouro da empresa, com o número
+	 * - complemento: dado adicional do endereço
+	 * - cep: código de endereçamento postal, máscara nnnnnn-nnn
+	 * - bairro: nome do bairro
+	 * - cidade: nome da cidade
+	 * - uf: unidade da federação
+	 * @access public
+	 */
+	function getOrganizationLocals($organizationID)
+	{
+		$query = "SELECT organizacao_id, localidade_id, centro_custo_id, descricao, empresa,
+							endereco, complemento, cep, bairro, cidade, uf" .
+				 "  FROM localidade" .
+				 " WHERE (organizacao_id = ?)";
+
+		$result = $this->db->query($query, array($organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca os centros de custo de uma organização.
+	 *
+	 * Este método retornará todos os centros de custo de uma organização.
+	 * Centros de custo são como códigos contábeis para faturamento de serviços.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array de arrays associativas contendo os atributos dos centros de custo. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - centro_custo_id
+	 * - nm_centro_custo: número do centro de custo
+	 * - grupo: estrutura numerica a qual o centro de custo pertence
+	 * - descrição: nome do centro de custo
+	 * @access public
+	 */
+	function getOrganizationCostCenters($organizationID)
+	{
+		$query = "SELECT organizacao_id, centro_custo_id, nm_centro_custo, grupo, descricao" .
+				 "  FROM centro_custo" .
+				 " WHERE (organizacao_id = ?)" .
+				 " ORDER BY descricao";
+
+		$result = $this->db->query($query, array($organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Lista todas as categorias possíveis para um funcionário em uma organização.
+	 *
+	 * Este método listará a tabela de categorias.
+	 * Por exemplo: funcionário, estagiário, terceirizado, etc.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array de arrays associativas contendo os atributos das categorias. Cada linha do array conterá:
+	 * - funcionario_categoria_id: o id da categoria
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getOrganizationEmployeeCategories($organizationID)
+	{
+		$query = "SELECT funcionario_categoria_id, descricao, organizacao_id" .
+				 "  FROM funcionario_categoria" .
+				 "	WHERE organizacao_id = ?" .
+				 "  ORDER BY funcionario_categoria_id";
+
+		$result = $this->db->query($query, array((int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Lista todas as organizações do Organograma.
+	 *
+	 * Este método irá listar a tabela de organizações
+	 * O modelo de dados do organograma foi construído para abrigar mais de uma organização
+	 * @return um array de arrays associativas contendo a lista de organizações. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - nome: sigla da organizacao
+	 * - descricao
+	 * - url_imagem: a url onde se encontra o gráfico da organização
+	 * - ativa: se a organização está ativa ou não
+	 * - sitio: a url da página web da organização
+	 * @access public
+	 */
+	function getOrganizations()
+	{
+		$query = "SELECT organizacao_id, nome, descricao, url_imagem, ativa, sitio" .
+				 "  FROM organizacao";
+
+		$result = $this->db->query($query);
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+
+	/**
+	 * Busca uma área pelo seu ID.
+	 *
+	 * Este método irá retornar os dados de uma área buscando pelo seu ID.
+	 * @param int $areaID O ID da área.
+	 * @return array Uma array associativa contendo os atributos de uma área:
+	 * - organizacao_id
+	 * - area_id
+	 * - area_status: o nível hierárquico da área
+	 * - superior_area_id: o id da área acima da atual
+	 * - centro_custo_id: o centro de custo da área
+	 * - titular_funcionario_id: o id do chefe da área
+	 * - substituto_funcionario_id: o id do funcionario que esta substituindo o titular temporariamente
+	 * - sigla
+	 * - descicao
+	 * - ativa: indicativo de situação da área: 's' ativa, 'n' inativa
+	 * - auxiliar_funcionario_id: o id da secretária da área
+	 * @access public
+	 */
+	function getArea($areaID)
+	{
+		$query = "SELECT a.organizacao_id, a.area_id, a.area_status_id, " .
+				 "       a.superior_area_id, a.centro_custo_id, a.titular_funcionario_id, " .
+				 "       a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, " .
+				 "		 s.funcionario_id as substituto_funcionario_id " .
+				 " FROM area a " .
+				 "  LEFT OUTER JOIN substituicao s " .
+				 "  ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) " .
+				 " WHERE " .
+				 "	(a.area_id = ?) " .
+				 " ORDER BY a.sigla, a.descricao";
+
+
+		$result = $this->db->query($query, array($areaID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca uma área pela sua sigla.
+	 *
+	 * Este método retornará os atributos de uma área buscando pela sua sigla.
+	 * @param string $acronym A sigla da área.
+	 * @param int $organizationID O id da organização
+	 * @return array Uma array associativa contendo os atributos de uma área:
+	 * - organizacao_id
+	 * - area_id
+	 * - area_status: o nível hierárquico da área
+	 * - superior_area_id: o id da área acima da atual
+	 * - centro_custo_id: o centro de custo da área
+	 * - titular_funcionario_id: o id do chefe da área
+	 * - substituto_funcionario_id: o id do funcionario que esta substituindo o titular temporariamente
+	 * - sigla
+	 * - descicao
+	 * - ativa: indicativo de situação da área: 's' ativa, 'n' inativa
+	 * - auxiliar_funcionario_id: o id da secretária da área
+	 * @access public
+	 */
+	function getAreaByName($acronym, $organizationID = 1)
+	{
+		$query = "SELECT a.organizacao_id, a.area_id, a.area_status_id, " .
+				 "       a.superior_area_id, a.centro_custo_id, a.titular_funcionario_id, " .
+				 "       a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, " .
+				 "		 s.funcionario_id as substituto_funcionario_id " .
+				 " FROM area a " .
+				 "  LEFT OUTER JOIN substituicao s " .
+				 "  ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) " .
+				 " WHERE " .
+				 "	(UPPER(a.sigla) = UPPER(?)) " .
+				 " AND " .
+				 "	(a.organizacao_id = ?) " .
+				 " ORDER BY a.sigla, a.descricao";
+
+
+		$result = $this->db->query($query, array($acronym, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca as áreas que possuem um determinado status de área.
+	 *
+	 * Este método irá retornar todas as áreas cujo status (nível hierárquico) seja o solicitado.
+	 * @param int $areaStatusID O ID do status de área.
+	 * @return array Uma array de arrays associativas contendo os atributos de uma área. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - area_id
+	 * - area_status: o nível hierárquico da área
+	 * - superior_area_id: o id da área acima da atual
+	 * - centro_custo_id: o centro de custo da área
+	 * - titular_funcionario_id: o id do chefe da área
+	 * - substituto_funcionario_id: o id do funcionario que esta substituindo o titular temporariamente
+	 * - sigla
+	 * - descicao
+	 * - ativa: indicativo de situação da área: 's' ativa, 'n' inativa
+	 * - auxiliar_funcionario_id: o id da secretária da área
+	 * @access public
+	 */
+	function getAreaByStatus($areaStatusID)
+	{
+		$result = array();
+
+		$query = "SELECT a.organizacao_id, a.area_id, a.area_status_id, " .
+				 "       a.superior_area_id, a.centro_custo_id, a.titular_funcionario_id, " .
+				 "       a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, " .
+				 "		 s.funcionario_id as substituto_funcionario_id " .
+				 " FROM area a " .
+				 "  LEFT OUTER JOIN substituicao s " .
+				 "  ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) " .
+				 " WHERE " .
+				 "	(a.area_status_id = ?) " .
+				 " ORDER BY a.sigla, a.descricao";
+
+
+
+		$result = $this->db->query($query, array($areaStatusID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca várias áreas através de uma array de IDs
+	 *
+	 * Este método irá buscar de uma vez só os dados de mais de uma área.
+	 * @param array $areaIDs Array com os IDs das áreas
+	 * @return array Um array de arrays associativos contendo os atributos de várias áreas. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - area_id
+	 * - area_status: o nível hierárquico da área
+	 * - superior_area_id: o id da área acima da atual
+	 * - centro_custo_id: o centro de custo da área
+	 * - titular_funcionario_id: o id do chefe da área
+	 * - substituto_funcionario_id: o id do funcionario que esta substituindo o titular temporariamente
+	 * - sigla
+	 * - descicao
+	 * - ativa: indicativo de situação da área: 's' ativa, 'n' inativa
+	 * - auxiliar_funcionario_id: o id da secretária da área
+ 	 * @access public
+	 */
+	function getAreas($areaIDs)
+	{
+		if (!is_array($areaIDs))
+			return false;
+
+		$areas = implode(', ', $areaIDs);
+
+		$query = "SELECT a.organizacao_id, a.area_id, a.area_status_id, " .
+				 "       a.superior_area_id, a.centro_custo_id, a.titular_funcionario_id, " .
+				 "       a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, " .
+				 "		 s.funcionario_id as substituto_funcionario_id " .
+				 " FROM area a " .
+				 "  LEFT OUTER JOIN substituicao s " .
+				 "  ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) " .
+				 " WHERE " .
+				 "	(a.area_id IN ($areas)) " .
+				 " ORDER BY a.sigla, a.descricao";
+
+		// A execução é realizada sem o segundo parâmetro pois este não pode estar entre aspas
+		$result = $this->db->query($query);
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+		return $output;
+	}
+
+	/**
+	 * Busca o ID da área superior a uma dada área.
+	 *
+	 * Este método irá buscar a área imediatamente superior à solicitada, ou então subirá na hierarquia até chegar no nível solicitado.
+	 * @param int $areaID O ID da área da qual se quer saber a área superior.
+	 * @param int $areaStatusID O ID do status de área (nível) da área pai. Utilizar -1 caso se queira a área imediatamente superior.
+	 * - Por exemplo: área atual está no nível 5 (Divisão) e se quer buscar a área de nivel 3 (Diretoria).
+	 * @return int O ID da área que é superior à área informada.
+	 * @access public
+	 */
+	function getParentAreaID($areaID, $areaStatusID = -1)
+	{
+		$query  = "SELECT area_id, area_status_id" .
+				  "  FROM area" .
+				  " WHERE area_id = (SELECT superior_area_id" .
+				  "                    FROM area" .
+				  "                   WHERE (area_id = ?))";
+
+		$result = $this->db->query($query, array($areaID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+		if (!$output)
+			return false;
+
+		if (($areaStatusID == -1) || ($output['area_status_id'] == $areaStatusID))
+			return $output['area_id'];
+		else
+			return $this->getParentAreaID($output['area_id'], $areaStatusID);
+	}
+
+	/**
+	 * Busca as áreas abaixo de uma determinada área.
+	 *
+	 * Este método irá buscar as áreas imediatamente inferiores à solicitada, não descendo nos próximos níveis da hierarquia.
+	 * @param int $parentAreaID O ID da área da qual se quer saber as áreas imediatamente inferiores.
+	 * @param boolean $onlyActiveAreas Valor lógico que, caso verdadeiro, faz com que o método retorne somente as áreas ativas
+	 * @return array Um array de arrays associativos contendo os atributos de várias áreas. Cada linha do array conterá:
+	 * - organizacao_id
+	 * - area_id
+	 * - area_status: o nível hierárquico da área
+	 * - superior_area_id: o id da área acima da atual
+	 * - centro_custo_id: o centro de custo da área
+	 * - titular_funcionario_id: o id do chefe da área
+	 * - substituto_funcionario_id: o id do funcionario que esta substituindo o titular temporariamente
+	 * - sigla
+	 * - descicao
+	 * - ativa: indicativo de situação da área: 's' ativa, 'n' inativa
+	 * - auxiliar_funcionario_id: o id da secretária da área
+	 * @access public
+	 */
+	function getSubAreasByParentAreaID($parentAreaID, $onlyActiveAreas = false)
+	{
+		$query = "SELECT a.organizacao_id, a.area_id, a.area_status_id, " .
+				 "       a.superior_area_id, a.centro_custo_id, a.titular_funcionario_id, " .
+				 "       a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, " .
+				 "		 s.funcionario_id as substituto_funcionario_id " .
+				 " FROM area a " .
+				 "  LEFT OUTER JOIN substituicao s " .
+				 "  ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) " .
+				 " WHERE " .
+				 "	(a.superior_area_id = ?) ";
+
+
+		if ($onlyActiveAreas){
+			$query .= " AND ativa = 'S'";
+		}
+		$query .= " ORDER BY a.sigla, a.descricao";
+
+		$result = $this->db->query($query, array($parentAreaID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+		return $output;
+	}
+
+	/**
+	 * Busca um status de área pelo seu ID.
+	 *
+	 * Procura na tabela de status de área (nível hierárquico de áreas) o registro que corresponde ao ID solicitado.
+	 * @param int $areaStatusID O ID do status de área.
+	 * @return array Uma array associativa contendo os atributos de um status de área:
+	 * - area_status_id
+	 * - organizacao_id
+	 * - descricao: nome do nível hierárquivo. Por exemplo: presidência, assessoria, diretoria, gerência, etc.
+	 * - nivel: valor numérico que identifica o nível: 1, 2, 3, ...
+	 * @access public
+	 */
+	function getAreaStatus($areaStatusID)
+	{
+		$query = "SELECT area_status_id, organizacao_id, descricao, nivel" .
+				 "  FROM area_status" .
+				 " WHERE (area_status_id = ?)";
+
+		$result = $this->db->query($query, array($areaStatusID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um status de área pelo seu nome.
+	 *
+	 * Este método irá retornar os dados de um status, procurando o registro na tabela através do seu nome.
+	 * @param string $description O nome do status de área.
+	 * @param int $organizationID O id da organização.
+	 * @return array Uma array associativa contendo os atributos de um status de área:
+	 * - area_status_id
+	 * - organizacao_id
+	 * - descricao: nome do nível hierárquivo. Por exemplo: presidência, assessoria, diretoria, gerência, etc.
+	 * - nivel: valor numérico que identifica o nível: 1, 2, 3, ...
+	 * @access public
+	 */
+	function getAreaStatusByName($description, $organizationID = 1)
+	{
+		$query = "SELECT area_status_id, organizacao_id, descricao, nivel" .
+				 "  FROM area_status" .
+				 " WHERE (UPPER(descricao) = UPPER(?) and (organizacao_id = ?))";
+
+		$result = $this->db->query($query, array($description, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um status de área pelo seu nível.
+	 *
+	 * Este método irá retornar os dados de um status, procurando o registro na tabela através do seu nível.
+	 * @param int $level O nível do status de área.
+	 * @param int $organizationID O id da organização.
+	 * @return array Uma array associativa contendo os atributos de um status de área:
+	 * - area_status_id
+	 * - organizacao_id
+	 * - descricao: nome do nível hierárquivo. Por exemplo: presidência, assessoria, diretoria, gerência, etc.
+	 * - nivel: valor numérico que identifica o nível: 1, 2, 3, ...
+	 * @access public
+	 */
+	function getAreaStatusByLevel($level, $organizationID = 1)
+	{
+		$query = "SELECT area_status_id, organizacao_id, descricao, nivel" .
+				 " FROM area_status" .
+				 " WHERE (nivel = ?) AND (organizacao_id = ?)";
+
+		$result = $this->db->query($query, array((int) $level, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca o ID do titular de uma área.
+	 *
+	 * Este método busca uma área e retorna o atributo titular_funcionario_id
+	 * @param int $areaID O ID da área.
+	 * @return int O ID do titular da área.
+	 * @access public
+	 */
+	function getAreaSupervisorID($areaID)
+	{
+		$area = $this->getArea($areaID);
+		if (!$area)
+			return false;
+
+		return $area['titular_funcionario_id'];
+	}
+
+	/**
+	 * Busca o ID do substituto de uma área.
+	 *
+	 * Este método irá buscar uma área e retornar o atributo substituto_funcionario_id.
+	 * Note que o substituro é um campo opcional na área e poderá retornar vazio.
+	 * @param int $areaID O ID da área.
+	 * @return int O ID do substituto da área.
+	 * @access public
+	 */
+	function getAreaBackupSupervisorID($areaID)
+	{
+		$area = $this->getArea($areaID);
+		if (!$area)
+			return false;
+
+		return $area['substituto_funcionario_id'];
+	}
+
+	/**
+	 * Busca o ID do auxiliar administrativo de uma área.
+	 *
+	 * Este método busca uma área e retorna o atributo auxiliar_funcionario_id
+	 * Nem todas as áreas possuem funcionários auxiliares (secretárias)
+	 * @param int $areaID O ID da área.
+	 * @return int O ID do auxiliar administrativo da área.
+	 * @access public
+	 */
+	function getAreaAssistantID($areaID)
+	{
+		$area = $this->getArea($areaID);
+		if (!$area)
+			return false;
+
+		return $area['auxiliar_funcionario_id'];
+	}
+
+	/**
+	 * Busca o ID do titular atual de uma área.
+	 *
+	 * Este método irá buscar uma área e caso haja um substituto, este será o titular atual; caso contrário, o titular atual é o próprio titular da área.
+	 * @param int $areaID O ID da área.
+	 * @return int O ID do titular atual da área, podendo ser um dos campos abaixo:
+	 * - substituto_funcionario_id
+	 * - titular_funcionario_id
+	 * @access public
+	 */
+	function getAreaCurrentSupervisorID($areaID)
+	{
+		$area = $this->getArea($areaID);
+		if (!$area)
+			return false;
+
+		return is_null($area['substituto_funcionario_id']) ? $area['titular_funcionario_id'] : $area['substituto_funcionario_id'];
+	}
+
+	/**
+	 * Busca o ID do responsável administrativo atual de uma área.
+	 *
+	 * A precedência para definir quem é o responsável administrativo é: auxiliar administrativo, substituto e titular.
+	 * @param int $areaID O ID da área.
+	 * @return int O ID do responsável administrativo da área, podendo ser um dos atributos abaixo:
+	 * - auxiliar_funcionario_id
+	 * - substituto_funcionario_id
+	 * - titular_funcionario_id
+	 * @access public
+	 */
+	function getAreaCurrentAdministrativeResponsibleID($areaID)
+	{
+		$area = $this->getArea($areaID);
+		if (!$area)
+			return false;
+
+		return !is_null($area['auxiliar_funcionario_id']) ? $area['auxiliar_funcionario_id'] : (!is_null($area['substituto_funcionario_id']) ? $area['substituto_funcionario_id'] : $area['titular_funcionario_id']);
+	}
+
+	/**
+	 * Busca uma localidade pelo seu ID.
+	 *
+	 * Este método listará os atributos e uma localidade. Lembrando que localidade também pode ser entendida como o local físico de trabalho.
+	 * @param int $localID O ID da localidade.
+	 * @return array Uma array associativa contendo os atributos de uma localidade:
+	 * - organizacao_id
+	 * - localidade_id
+	 * - centro_custo_id
+	 * - descricao
+	 * - empresa: o nome completo da localidade
+	 * - endereço: o logradouro da empresa, com o número
+	 * - complemento: dado adicional do endereço
+	 * - cep: código de endereçamento postal, máscara nnnnnn-nnn
+	 * - bairro: nome do bairro
+	 * - cidade: nome da cidade
+	 * - uf: unidade da federação
+	 * @access public
+	 */
+	function getLocal($localID)
+	{
+		$query = "SELECT organizacao_id, localidade_id, centro_custo_id, descricao,
+							empresa, endereco, complemento, cep, bairro, cidade, uf" .
+				 "  FROM localidade" .
+				 " WHERE (localidade_id = ?)";
+
+		$result = $this->db->query($query, array($localID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca uma localidade pelo seu nome.
+	 *
+	 *
+	 * @param string $description O nome da localidade.
+	 * @param int $organizationID O id da organização.
+	 * @return array Uma array associativa contendo os atributos de uma localidade:
+	 * - organizacao_id
+	 * - localidade_id
+	 * - centro_custo_id
+	 * - descricao
+	 * - empresa: o nome completo da localidade
+	 * - endereço: o logradouro da empresa, com o número
+	 * - complemento: dado adicional do endereço
+	 * - cep: código de endereçamento postal, máscara nnnnnn-nnn
+	 * - bairro: nome do bairro
+	 * - cidade: nome da cidade
+	 * - uf: unidade da federação
+	 * @access public
+	 */
+	function getLocalByName($description, $organizationID = 1)
+	{
+		$query = "SELECT organizacao_id, localidade_id, centro_custo_id, descricao,
+							empresa, endereco, complemento, cep, bairro, cidade, uf" .
+				 "  FROM localidade" .
+				 " WHERE (UPPER(descricao) = UPPER(?) and (organizacao_id = ?))";
+
+		$result = $this->db->query($query, array($description, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um centro de custo pelo seu ID.
+	 *
+	 * Este método irá mostrar os atributos de um centro de custo, buscando na tabela pelo seu id.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @return array Uma array associativa contendo os atributos de um centro de custo:
+	 * - organizacao_id
+	 * - centro_custo_id
+	 * - nm_centro_custo: número do centro de custo
+	 * - grupo: estrutura numerica a qual o centro de custo pertence
+	 * - descrição: nome do centro de custo
+	 * @access public
+	 */
+	function getCostCenter($costCenterID)
+	{
+		$query = "SELECT organizacao_id, centro_custo_id, nm_centro_custo, grupo, descricao" .
+				 "  FROM centro_custo" .
+				 " WHERE (centro_custo_id  = ?)";
+
+		$result = $this->db->query($query, array($costCenterID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um centro de custo pelo seu número.
+	 *
+	 * Este método retornará os atributos de um centro de custo buscando pelo seu ID.
+	 * @param int $number O número do centro de custo.
+	 * @param ind $organizationID O id da organização
+	 * @return array Uma array associativa contendo os atributos de um centro de custo:
+	 * - organizacao_id
+	 * - centro_custo_id
+	 * - nm_centro_custo: número do centro de custo
+	 * - grupo: estrutura numerica a qual o centro de custo pertence
+	 * - descrição: nome do centro de custo
+	 * @access public
+	 */
+	function getCostCenterByNumber($number, $organizationID = 1)
+	{
+		$query = "SELECT organizacao_id, centro_custo_id, nm_centro_custo, grupo, descricao" .
+				 "  FROM centro_custo" .
+				 " WHERE ((nm_centro_custo = ?) and (organizacao_id = ?))";
+
+		$result = $this->db->query($query, array($number, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um centro de custo pelo seu nome.
+	 *
+	 * Este método irá retornar os atributos de um centro de custo buscando pelo seu nome.
+	 * @param string $description O nome do centro de custo.
+	 * @param int $organizationID O id da organização
+	 * @return array Uma array associativa contendo os atributos de um centro de custo.
+	 * - organizacao_id
+	 * - centro_custo_id
+	 * - nm_centro_custo: número do centro de custo
+	 * - grupo: estrutura numerica a qual o centro de custo pertence
+	 * - descrição: nome do centro de custo
+	 * 	 * @access public
+	 */
+	function getCostCenterByName($description, $organizationID = 1)
+	{
+		$query = "SELECT organizacao_id, centro_custo_id, nm_centro_custo, grupo, descricao" .
+				 "  FROM centro_custo" .
+				 " WHERE (UPPER(descricao) = UPPER(?) and (organizacao_id = ?))";
+
+		$result = $this->db->query($query, array($description, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca as informações de categoria a partir do ID.
+	 *
+	 * Este método irá retornar os atributos de uma linha da tabela de categorias de funcionários.
+	 * @param int $categoryID O ID da categoria.
+	 * @return array Uma array associativa contendo os atributos da categoria:
+	 * - funcionario_categoria_id
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getEmployeeCategory($categoryID)
+	{
+		$query  = "SELECT funcionario_categoria_id, descricao, organizacao_id" .
+				  "  FROM funcionario_categoria" .
+				  " WHERE (funcionario_categoria_id = ?)";
+
+		$result = $this->db->query($query, array($categoryID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca uma categoria a partir da sua descrição.
+	 *
+	 * Este método irá mostrar os atributos de uma categoria, buscando pela sua descrição.
+	 * @param string $description O nome da categoria.
+	 * @param int $organizationID O id da organização
+	 * @return array Uma array associativa contendo os atributos de uma categoria:
+	 * - funcionario_categoria_id
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getEmployeeCategoryByName($description, $organizationID = 1)
+	{
+		$query = "SELECT funcionario_categoria_id, descricao, organizacao_id" .
+				 "  FROM funcionario_categoria" .
+				 " WHERE (UPPER(descricao) = UPPER(?) and (organizacao_id = ?))";
+
+		$result = $this->db->query($query, array($description, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Lista todos os cargos de uma organização.
+	 *
+	 * Este método irá listar a tabela localidade.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Uma array de arrays associativas contendo a lista dos cargos de uma organização:
+	 * - cargo_id
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getJobTitles($organizationID)
+	{
+		$query = "SELECT cargo_id, descricao, organizacao_id" .
+				 "  FROM cargo" .
+				 "	WHERE organizacao_id = ?" .
+				 "  ORDER BY cargo_id";
+
+		$result = $this->db->query($query, array((int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca as informações de cargo a partir do ID.
+	 *
+	 * Este método irá listar os atributos de um cargo, buscando na tabela a partir do seu ID.
+	 * @param int $jobTitleID O ID do cargo.
+	 * @return array Uma array associativa contendo os atributos do cargo.
+	 * - cargo_id
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getJobTitle($jobTitleID)
+	{
+		$query  = "SELECT cargo_id, descricao, organizacao_id" .
+				  "  FROM cargo" .
+				  " WHERE (cargo_id = ?)";
+
+		$result = $this->db->query($query, array($jobTitleID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um cargo a partir da sua descrição.
+	 *
+	 * Este método irá mostrar os atributos de um cargo, buscando pela sua descrição.
+	 * @param string $description O nome do cargo.
+	 * @param int $organizationID O id da organização.
+	 * @return array Uma array associativa contendo os atributos de um cargo:
+	 * - cargo_id
+	 * - descricao
+	 * - organizacao_id
+	 * @access public
+	 */
+	function getJobTitleByName($description, $organizationID = 1)
+	{
+		$query = "SELECT cargo_id, descricao, organizacao_id" .
+				 "  FROM cargo" .
+				 " WHERE (UPPER(descricao) = UPPER(?) and (organizacao_id = ?))";
+
+		$result = $this->db->query($query, array($description, (int) $organizationID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca um funcionário pelo seu ID.
+	 *
+	 * Este método retorna os atributos de um funcionário buscando pelo se id.
+	 * O ID corresponde ao uidNumber do funcionário no catálogo LDAP.
+	 * Se necessitar de outros atributos como o nome, cpf, email, matrícula, é necessário fazer uma consulta ao Ldap.
+	 * @param int $employeeID O ID do funcionário.
+	 * @return array Uma array associativa contendo os atributos de um funcionário:
+	 * - funcionario_id
+	 * - area_id
+	 * - localidade_id
+	 * - centro_custo_id
+	 * - organizacao_id
+	 * - funcionario_status_id
+	 * - cargo_id
+	 * - nivel: o nível numérico dentro do cargo
+	 * - funcionario_categoria_id
+	 * - titulo: nome pelo qual o funcionário e reconhecido na organização, por exemplo: gerente comercial
+	 * @access public
+	 */
+	function getEmployee($employeeID)
+	{
+		if (!is_numeric($employeeID))
+			return false;
+
+		$query  = "SELECT funcionario_id, area_id, localidade_id, centro_custo_id, organizacao_id,
+							funcionario_status_id, cargo_id, nivel, funcionario_categoria_id, titulo" .
+				  "  FROM funcionario" .
+				  " WHERE (funcionario_id = ?)";
+
+		$result = $this->db->query($query, array($employeeID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca lista de funcionários de uma área pelo ID da área.
+	 *
+	 * Este método retornará todos os funcionários de uma área.
+	 * @param int $areaID O ID da área.
+	 * @param boolean $onlyActiveUsers true para retornar somente usuários ativos e false caso contrário
+	 * @return array Uma array sequencial de arrays associativos contendo contendo o ID dos funcionários de uma área:
+	 * - funcionario_id
+	 * @access public
+	 */
+	function getEmployeesAreaID($areaID, $onlyActiveUsers = false)
+	{
+		if($onlyActiveUsers){
+			$query = "SELECT funcionario_id " .
+					 "FROM funcionario " .
+					 "INNER JOIN funcionario_status " .
+					 "ON (funcionario.funcionario_status_id = funcionario_status.funcionario_status_id) " .
+					 "WHERE (area_id = ?) AND (funcionario_status.exibir = 'S')";
+		} else {
+			$query = "SELECT funcionario_id " .
+				     "FROM funcionario " .
+					 "WHERE (area_id = ?)";
+		}
+
+		$result = $this->db->query($query, array($areaID));
+		if (!$result)
+			return false;
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Busca um status de funcionário pelo seu ID.
+	 *
+	 * Este método irá retornar os dados de um status de funcionário, buscando pelo ID solicitado.
+	 * @param int $employeeStatusID O ID do status.
+	 * @return array Uma array associativa contendo os atributos de um status de funcionário:
+	 * - funcionario_status_id
+	 * - descricao
+	 * - exibir: indicativo booleado 'S' funcionário será listado no organograma, 'N' funcionário ficará oculto na aba organograma.
+	 * @access public
+	 */
+	function getEmployeeStatus($employeeStatusID)
+	{
+		$query = "SELECT funcionario_status_id, descricao, exibir " .
+				 "  FROM funcionario_status" .
+				 " WHERE (funcionario_status_id = ?)";
+
+		$result = $this->db->query($query, array($employeeStatusID));
+		if (!$result)
+			return false;
+
+		$output = $result->fetchRow();
+
+		return $output;
+	}
+
+	/**
+	 * Busca o ID da área (podendo ser de outros níveis) de um funcionário.
+	 *
+	 * Este método irá retornar o ID da área do funcionário. Fará uma busca para cima na hierarquia se for solicitado.
+	 * @param int $employeeID O ID do funcionário do qual se quer saber a área.
+	 * @param int $areaStatusID O ID do status de área (nível) da área do funcionário que se quer. Utilizar -1 caso se queira a área imediata do funcionário.
+	 * - Por exemplo: o funcionário está em uma área de status 5 (Divisão) e se quer a área superior de nível 3 (Diretoria).
+	 * @return int O ID da área do funcionário.
+	 * @access public
+	 */
+	function getEmployeeAreaID($employeeID, $areaStatusID = -1)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		/* requer a área do funcionário */
+		if ($areaStatusID == -1)
+			return $employee['area_id'];
+		else
+		{
+			/* verifica se a área do funcionário já está no nível solicitado */
+			$currentArea = $this->getArea($employee['area_id']);
+			if ($currentArea['area_status_id'] == $areaStatusID)
+				return $currentArea['area_id'];
+			else
+				return $this->getParentAreaID($currentArea['area_id'], $areaStatusID);
+		}
+	}
+
+	/**
+	 * Busca o ID da localidade de um funcionário.
+	 *
+	 * Este método buscará o funcionário pelo seu ID e retornará o ID da sua localidade.
+	 * @param int $employeeID O ID do funcionário.
+	 * @return int O ID da localidade do funcionário.
+	 * @access public
+	 */
+	function getEmployeeLocalID($employeeID)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		return $employee['localidade_id'];
+	}
+
+	/**
+	 * Busca o ID do status de um funcionário.
+	 *
+	 * Este método buscará um funcionário pelo seu ID e retornará o ID de status do funcionário.
+	 * Status de funcionário corresponde à sua situação: ativo, desligado, etc.
+	 * @param int $employeeID O ID do funcionário.
+	 * @return int O ID do status do funcionário.
+	 * @access public
+	 */
+	function getEmployeeStatusID($employeeID)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		return $employee['funcionario_status_id'];
+	}
+
+	/**
+	 * Busca o ID do centro de custo de um funcionário.
+	 *
+	 * Este método irá buscar um funcionário pelo seu ID e retornará o ID do centro de custo do funcionário.
+	 * O centro de custo não é obrigatório por funcionário. Neste caso, se necessário, busque o centro de custo da área ou da localidade.
+	 * @param int $employeeID O ID do funcionário.
+	 * @return int O ID do centro de custo do funcionário.
+	 * @access public
+	 */
+	function getEmployeeCostCenterID($employeeID)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		$costCenterID = $employee['centro_custo_id'];
+		if(!empty($costCenterID)){
+			return $costCenterID;
+		} else {
+			$employeeArea = $this->getArea($employee['area_id']);
+			return $employeeArea['centro_custo_id'];
+		}
+	}
+
+	/**
+	 * Busca o ID do cargo de um funcionário.
+	 *
+	 * Este método buscará um funcionário pelo seu ID e retornará o ID do cargo do funcionário.
+	 * @param int $employeeID O ID do funcionário.
+	 * @return int O ID do cargo do funcionário.
+	 * @access public
+	 */
+	function getEmployeeJobTitleID($employeeID)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		return $employee['cargo_id'];
+	}
+
+	/**
+	 * Busca o ID da categoria de um funcionário.
+	 *
+	 * Este método buscará um funcionário pelo seu ID e retornará o ID da categoria do funcionário.
+	 * A categoria corresponde ao tipo de vínculo do funcionário com a organizacao. Por exemplo:
+	 * - funcionário
+	 * - estagiário
+	 * - terceirizado, etc
+	 * @param int $employeeID O ID do funcionário.
+	 * @return int O ID do categoria do funcionário.
+	 * @access public
+	 */
+	function getEmployeeCategoryID($employeeID)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		return $employee['funcionario_categoria_id'];
+	}
+
+	/**
+	 * Busca o nível de um funcionário.
+	 *
+	 * Este método buscará o funcionário pelo seu ID e retornará o nível do funcionário dentro do cargo.
+	 * Geralmente um cargo (por exemplo: auxiliar tecnico) é composto por níveis de evolução na carreira: 1,2,3,...
+	 * @param int $employeeID O ID do funcionário.
+	 * @return int A quantidade de níveis do funcionário.
+	 * @access public
+	 */
+	function getEmployeeLevel($employeeID)
+	{
+		$employee = $this->getEmployee($employeeID);
+		if (!$employee)
+			return false;
+
+		if ($employee['nivel'] === null)
+			return false;
+
+		return $employee['nivel'];
+	}
+
+	/**
+	 * Busca o ID do titular da área de um funcionário.
+	 *
+	 * Este método buscará o titular da área do funcionário, e poderá subir na hierarquia, buscando o titular de áreas superiores à área do funcionário.
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $areaStatusID O ID do status de área (nível) da área do funcionário que se quer o titular. Utilizar -1 caso se queira o titular da área imediata do funcionário.
+	 * @return int O ID do titular da área do funcionário:
+	 * - titular_funcionario_id
+	 * @access public
+	 */
+	function getEmployeeSupervisorID($employeeID, $areaStatusID = -1)
+	{
+		return $this->getAreaSupervisorID($this->getEmployeeAreaID($employeeID, $areaStatusID));
+	}
+
+	/**
+	 * Busca o ID do titular atual da área do funcionário.
+	 *
+	 * Caso haja um substituto, este será o titular atual; caso contrário, o titular atual é o próprio titular da área.
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $areaStatusID O ID do status de área (nível) da área do funcionário que se quer o titular atual. Utilizar -1 caso se queira o titular atual da área imediata do funcionário.
+	 * @return int O ID do titular atual da área do funcionário:
+	 * - titular_funcionário_id ou
+	 * - substituto_funcionario_id
+	 * @access public
+	 */
+	function getEmployeeCurrentSupervisorID($employeeID, $areaStatusID = -1)
+	{
+		return $this->getAreaCurrentSupervisorID($this->getEmployeeAreaID($employeeID, $areaStatusID));
+	}
+
+	/**
+	 * Busca o ID do responsável administrativo atual de uma área.
+	 *
+	 * A precedência para definir quem é o responsável administrativo é: auxiliar administrativo, substituto e titular.
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $areaStatusID O ID do status de área (nível) da área do funcionário que se quer o responsável administrativo. Utilizar -1 caso se queira o responsável administrativo da área imediata do funcionário.
+	 * @return int O ID do responsável administrativo atual da área do funcionário:
+	 * - titular_funcionário_id ou
+	 * - substituto_funcionario_id ou
+	 * - auxiliar_funcionario_id
+	 * @access public
+	 */
+	function getEmployeeCurrentAdministrativeResponsibleID($employeeID, $areaStatusID = -1)
+	{
+		return $this->getAreaCurrentAdministrativeResponsibleID($this->getEmployeeAreaID($employeeID, $areaStatusID));
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_regex.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_regex.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_regex.php	(revision 795)
@@ -0,0 +1,556 @@
+<?php
+/**
+ * Classe repositorio de padroes de validacao de expressoes regulares
+ *
+ * @author Carlos Eduardo Nogueira Goncalves
+ * @version 1.2
+ * @todo Incluir mais validacoes pre-definidas.
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_regex
+{
+	/* INiCIO DECLARAcaO DE CONSTANTES */
+
+	/**
+	 * @var string $INDEX_BY_STRING Indexacao do array de resultados por string
+	 * @access private
+	 */
+	var $INDEX_BY_STRING = "string";
+
+	/**
+	 * @var string $INDEX_BY_INT Indexacao do array de resultados por inteiro
+	 * @access private
+	 */
+	var $INDEX_BY_INT = "int";
+
+	/* FORMATOS ESPECiFICOS */
+
+	/**
+	 * @var string $CEP Padrao de validacao de CEPs
+	 */
+	var $CEP = '^[[:digit:]]{5}-[[:digit:]]{3}$';
+
+	/**
+	 * @attention Formato xxx.xxx.xxx-xx
+	 * @var string $CPF Padrao de validacao de CPFs (Formato xxx.xxx.xxx-xx)
+	 */
+	var $CPF = '^([[:digit:]]{3}\.){2}[[:digit:]]{3}-[[:digit:]]{2}$';
+
+	/**
+	 * @var string $ADDR_MAC Padrao de validacao de enderecos MAC
+	 */
+	var $ADDR_MAC = '^(([0-9a-f]{2}):){5}([0-9a-f]{2})$';
+
+	/**
+	 * @var string $DATE Padrao de validacao de datas (Formato dd/mm/aaaa)
+	 */
+	var $DATE = '^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/[12][0-9]{3}$';
+
+	/**
+	 * @var string $TIME Padrao de validacao de horas (Formato hh:mm)
+	 */
+	var $TIME = '^([01][[:digit:]]|2[0-3]):[0-5][[:digit:]]$';
+
+	/**
+	 * @var string $TIME_GLOBAL Padrão de horas (Formato D:mm, onde D = N dígitos sendo N >=1)
+	 */
+	var $TIME_GLOBAL = '^([[:digit:]])+:[0-5][[:digit:]]$';
+
+	/**
+	 * @var string $TEL_DDI Padrao de validacao de numeros de telefones com DDI (Formato +00 (00) 0000-0000, podendo ter parênteses e/ou hífen, ou não)
+	 */
+	var $TEL_DDI = '^([+][[:digit:]]{2})?([ (]{1,2}[[:digit:]]{2}[ )]{1,2})?[[:digit:]]{4}[ -]?[[:digit:]]{4}$';
+
+	/**
+	 * @var string $TEL_DDD Padrao de validacao de numeros de telefones com DDD (Formato (00) 0000-0000)
+	 */
+	var $TEL_DDD = '^\([[:digit:]]{2}\)\s[[:digit:]]{4}-[[:digit:]]{4}$';
+
+	/**
+	 * @var string $TEL Padrao de validacao de numeros de telefones (Formato 0000-0000)
+	 */
+	var $TEL = '^([[:digit:]]{4})-([[:digit:]]{4})$';
+
+	/**
+	 * @var string $ADDR_IP Padrao de validacao de enderecos IP
+	 */
+	var $ADDR_IP = '^(([1]?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))\.){3}([1]?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))$';
+
+	/**
+	 * @var string $ADDR_EMAIL Padrao de validacao de enderecos de correio eletronico (Formato mail@mail.mail[.mail])
+	 */
+	var $ADDR_EMAIL = '^([0-9a-zA-Z]+)([._-]?[0-9a-zA-Z]+)*[@]([0-9a-zA-Z]+)([._-]?[0-9a-zA-Z]+)*[.][a-zA-Z][a-zA-Z]+$';
+//	var $ADDR_EMAIL = '^[A-Za-z0-9_.-]+@[[:lower:]]+\.[[:lower:]]+(\.[[:lower:]]+){0,2}$';
+//	var $ADDR_EMAIL = '^((\w)|([[:punct:]]))+@[[:lower:]]+\.[[:lower:]]+(\.[[:lower:]]+){0,2}$';
+
+	/**
+	 * @var string $RG Padrao de validacao de documentos de RG
+	 */
+	var $RG = '^[[:digit:]]{1,2}(\.[[:digit:]]{3}){2}-(([[:digit:]])|([xX]))$';
+
+	/**
+	 * @var string $CURRENCY Padrao de validacao de unidades monetarias
+	 */
+	var $CURRENCY = '^[R]?[$](([[:digit:]]){1,3}\.)*(([[:digit:]]){1,3}\,)(([[:digit:]]){2})$';
+
+	/* PADROES AUXILIARES DE POSICIONAMENTO */
+
+	/**
+	 * @var string $_BEGIN Caracter de inicio de textos alternativo
+	 */
+	var $_BEGIN = '\A';
+
+	/**
+	 * @var string $BEGIN Caracter de inicio de textos
+	 */
+	var $BEGIN = '^';
+
+	/**
+	 * @var string $_END Caracter de fim de textos alternativo
+	 */
+	var $_END = '\Z';
+
+	/**
+	 * @var string $END Caracter de fim de textos
+	 */
+	var $END = '$';
+
+	/**
+	 * @var string $WORD_BEGIN Inicio de palavras. Ex: dia\b = dia, bom-dia.
+	 */
+	var $WORD_BEGIN = '\h';
+
+	/**
+	 * @var string $WORD_END Nao aceita caracteres no inicio de palavras. Ex: dia\b = lombardia, covardia
+	 */
+	var $WORD_END = '\H';
+
+	/**
+	 * @var string $BORDER Extremidade (limite) de palavras. Ex: dia\b = dia, bom-dia. \bdia = dia, diagnostico
+	 */
+	var $BORDER = '\b';
+
+	/**
+	 * @var string $NON_BORDER Dentro das palavras. Ex: min\B = domingo, administrador
+	 */
+	var $NON_BORDER = '\B';
+
+	/* PADRoES AUXILIARES DE TIPO */
+
+	/**
+	 * @var string $DIGIT Digitos decimais
+	 */
+	var $DIGIT = '\d';
+
+	/**
+	 * @var string $NON_DIGIT Nao aceita digitos decimais
+	 */
+	var $NON_DIGIT = '\D';
+
+	/**
+	 * @var string $XDIGIT Digitos hexadecimais
+	 */
+	var $XDIGIT = '[[:xdigit:]]';
+
+	/**
+	 * @var string $ALPHA_NUM Letras e numeros
+	 */
+	var $ALPHA_NUM = '\w';
+
+	/**
+	 * @var string $NON_ALPHA_NUM Nao aceita letras e numeros
+	 */
+	var $NON_ALPHA_NUM = '\W';
+
+	/**
+	 * @var string $PUNCT Sinais de pontuacao
+	 */
+	var $PUNCT = '[[:punct:]]';
+
+	/* PADRoES AUXILIARES DE CONTROLE DE QUANTIDADE */
+
+	/**
+	 * @var string $ZERO_OR_ONE Nenhum ou um caracter
+	 */
+	var $ZERO_OR_ONE = '?';
+
+	/**
+	 * @var string $ZERO_OR_INFINITE Nenhum ou infinitos caracteres
+	 */
+	var $ZERO_OR_INFINITE = '*';
+
+	/**
+	 * @var string $ONE_OR_INFINITE Um ou infinitos caracteres
+	 */
+	var $ONE_OR_INFINITE = '+';
+
+	/* PADRoES AUXILIARES DE CAIXA DE TEXTO */
+
+	/**
+	 * @var string $UPPER Letras maiusculas
+	 */
+	var $UPPER = '[:upper:]';
+
+	/**
+	 * @var string $NON_UPPER Nao aceita letras maiusculas
+	 */
+	var $NON_UPPER = '\U';
+
+	/**
+	 * @var string $LOWER Letras minusculas
+	 */
+	var $LOWER = '[:lower:]';
+
+	/**
+	 * @var string $NON_LOWER Nao aceita letras minusculas
+	 */
+	var $NON_LOWER = '\L';
+
+	/* META-CARACTERES */
+
+	/**
+	 * @var string $BEGIN_ESCAPE Caracter de inicio de trecho com valor literal
+	 */
+	var $BEGIN_ESCAPE = '\Q';
+
+	/**
+	 * @var string $END_ESCAPE Caracter de encerramento de trecho com valor literal
+	 */
+	var $END_ESCAPE = '\E';
+
+	/**
+	 * @var string $BEGIN_GROUP Caracter de inicio de trecho agrupado
+	 */
+	var $BEGIN_GROUP = '(';
+
+	/**
+	 * @var string $END_GROUP Caracter de encerramento de trecho agrupado
+	 */
+	var $END_GROUP = ')';
+
+	/**
+	 * @var string $OR Caracter logico OU (mais util em grupos)
+	 */
+	var $OR = '|';
+
+	/**
+	 * @var string $V_TAB Caracter de tabulacao vertical
+	 */
+	var $V_TAB = '\v';
+
+	/**
+	 * @var string $TAB Caracter de tabulacao horizontal
+	 */
+	var $TAB = '\t';
+
+	/**
+	 * @var string $NEW_LINE Caracter de linha nova
+	 */
+	var $NEW_LINE = '\n';
+
+	/**
+	 * @var string $CARRIAGE_RETURN Caracter de retorno de carro
+	 */
+	var $CARRIAGE_RETURN = '\r';
+
+	/**
+	 * @var string $BLANK Caracteres de espaco e tabulacao
+	 */
+	var $BLANK = '[:blank:]';
+
+	/* FIM DECLARAcaO DE CONSTANTES */
+
+
+	/* INiCIO DECLARAcaO DE ATRIBUTOS */
+
+	/**
+     * @var array $validResults Array indexado pelos valores de entrada, com os respectivos resultados de validacao
+	 */
+	var $validResults;
+
+	/**
+	 * @var boolean $indexBy Modo de indexacao dos resultados da validacao de multiplos valores
+	 */
+	var $indexBy = INDEX_BY_STRING;
+
+	/**
+	 * @var string $custom Expressao regular personalizada
+	 */
+	var $custom;
+
+	/* FIM DECLARAcaO DE ATRIBUTOS */
+
+
+	/* INiCIO DECLARAcaO DE MeTODOS */
+
+	/**
+	 * Construtor.
+	 *
+	 * @param string $indexBy Modo de indexacao dos resultados da validacao de multiplos valores.
+	 * @return object
+	 */
+	function wf_regex( $indexBy = "string" )
+	{
+		$this->indexBy = $indexBy;
+	}
+
+	/**
+	 * Metodo para construir expressao regular personalizada.
+	 *
+	 * @param string $chars Caracteres a serem adicionados.
+	 * @return void
+	 */
+	function append ( $chars )
+	{
+		$this->custom .= $chars;
+	}
+
+	/**
+	 * Metodo para adicionar um caracter literal
+	 *
+	 * @param string $char Caracter.
+	 * @return void
+	 */
+	function appendEscaped ( $char )
+	{
+		$this->custom .= '\Q' . $char . '\E';
+	}
+
+	/**
+	 * Metodo para retorna um caracter literal
+	 *
+	 * @param string $char Caracter
+	 * @return string
+	 */
+	function getEscaped ( $char )
+	{
+		return('\Q' . $char . '\E');
+	}
+
+	/**
+	 * Metodo para adicionar um grupo de caracteres
+	 *
+	 * @param string $chars Caracteres
+	 * @return void
+	 */
+	function appendGroup ( $chars )
+	{
+		$this->custom .= '(' . $chars . ')';
+	}
+
+	/**
+	 * Metodo para retornar um grupo de caracteres
+	 *
+	 * @param string $chars Caracteres
+	 * @return string
+	 */
+	function getGroup ( $chars )
+	{
+		return('(' . $chars . ')');
+	}
+
+	/**
+	 * Metodo para adicionar uma lista a expressao regular personalizada
+	 *
+	 * @param string $chars Caracteres permitidos pela lista
+	 * @return void
+	 */
+	function appendList ( $chars )
+	{
+		$this->custom .= '[' . $chars . ']';
+	}
+
+	/**
+	 * Metodo para retornar uma lista
+	 *
+	 * @param string $chars Caracteres permitidos pela lista
+	 * @return string
+	 */
+	function getList ( $chars )
+	{
+		return('[' . $chars . ']');
+	}
+
+	/**
+	 * Metodo para adicionar uma lista negada a expressao regular personalizada
+	 *
+	 * @param string $chars Caracteres proibidos pela lista negada
+	 * @return void
+	 */
+	function appendDeniedList ( $chars )
+	{
+		$this->custom .= '[^' . $chars . ']';
+	}
+
+	/**
+	 * Metodo para retornar uma lista negada
+	 *
+	 * @param string $chars Caracteres proibidos pela lista negada
+	 * @return string
+	 */
+	function getDeniedList ( $chars )
+	{
+		return('[^' . $chars . ']');
+	}
+
+	/**
+	 * Metodo para adicionar uma intervalo de caracteres em uma lista
+	 *
+	 * @param string $ini Caracter inicial do intervalo
+	 * @param string $end Caracter final do intervalo
+	 * @return void
+	 */
+	function appendIntervalList ( $ini, $end )
+	{
+		$this->custom .= '[' . $ini . '-' . $end . ']';
+	}
+
+	/**
+	 * Metodo para retornar uma intervalo de caracteres em uma lista
+	 *
+	 * @param string $ini Caracter inicial do intervalo
+	 * @param string $end Caracter final do intervalo
+	 * @return string
+	 */
+	function getIntervalList ( $ini, $end )
+	{
+		return('[' . $ini . '-' . $end . ']');
+	}
+
+	/**
+	 * Metodo para adicionar uma intervalo de caracteres em uma lista negada
+	 *
+	 * @param string $ini Caracter inicial do intervalo
+	 * @param string $end Caracter final do intervalo
+	 * @return void
+	 */
+	function appendIntervalDeniedList ( $ini, $end )
+	{
+		$this->custom .= '[^' . $ini . '-' . $end . ']';
+	}
+
+	/**
+	 * Metodo para retornar uma intervalo de caracteres em uma lista negada
+	 *
+	 * @param string $ini Caracter inicial do intervalo
+	 * @param string $end Caracter final do intervalo
+	 * @return string
+	 */
+	function getIntervalDeniedList ( $ini, $end )
+	{
+		return('[^' . $ini . '-' . $end . ']');
+	}
+
+	/**
+	 * Metodo para adicionar um controle de quantidade de caracteres a expressao regular personalizada
+	 *
+	 * @param int $count Quantidade permitida
+	 * @return void
+	 */
+	function appendCount ( $count )
+	{
+		$this->custom .= '{' . $count . '}';
+	}
+
+	/**
+	 * Metodo para retornar um controle de quantidade de caracteres
+	 *
+	 * @param int $count Quantidade permitida
+	 * @return string
+	 */
+	function getCount ( $count )
+	{
+		return('{' . $count . '}');
+	}
+
+	/**
+	 * Metodo para adicionar um controle de quantidade de caracteres a expressao regular personalizada
+	 *
+	 * @param int $min Quantidade minima
+	 * @param int $max Quantidade maxima (vazio para infinito)
+	 * @return void
+	 */
+	function appendCountInterval ( $min, $max )
+	{
+		$this->custom .= '{' . $min . ',' . $max . '}';
+	}
+
+	/**
+	 * Metodo para retornar um controle de quantidade de caracteres
+	 *
+	 * @param int $min Quantidade minima
+	 * @param int $max Quantidade maxima (vazio para infinito)
+	 * @return string
+	 */
+	function getCountInterval ( $min, $max )
+	{
+		return('{' . $min . ',' . $max . '}');
+	}
+
+	/**
+	 * Metodo para limpar expressao regular personalizada
+	 *
+	 * @return void
+	 */
+	function clear ( )
+	{
+		$this->custom = "";
+	}
+
+	/**
+	 * Metodo para alterar a forma de indexacao dos resultados da validacao de multiplos valores
+	 *
+	 * @param string $mode Modo de indexacao. Deve ser wf_regex->INDEX_BY_STRING ou wf_regex->INDEX_BY_INT
+	 * @return void
+	 */
+	function setIndexMode ( $mode )
+	{
+		if ( ( $mode == $this->INDEX_BY_STRING ) || ( $mode == $this->INDEX_BY_INT ) )
+			$this->indexBy = $mode;
+	}
+
+	/**
+	 * Valida valor de entrada com base em padroes de expressoes regulares
+	 *
+	 * @param string $pattern Padrao de expressao regular
+	 * @param string $input Valor de entrada a ser validado
+	 * @param boolean $caseSensitive Considerar caixa do valor de entrada
+	 * @return boolean Resultado da validacao
+	 */
+	function validate( $pattern, $input, $caseSensitive = TRUE )
+	{
+		if ( $caseSensitive )
+			return( ereg( $pattern, (string) $input ) );
+		else
+			return( eregi( $pattern, (string) $input ) );
+	}
+
+	/**
+	 * Valida valores de entrada em forma de array com base em padroes de expressoes regulares
+	 *
+	 * @param string $pattern Padrao de expressao regular
+	 * @param array $input Valor de entrada a ser validado
+	 * @param boolean $caseSensitive Considerar caixa do valor de entrada
+	 * @return boolean Resultado da validacao
+	 */
+	function validateEntries( $pattern, $input, $caseSensitive = TRUE )
+	{
+		//caso o valor de entrada nao seja um array chama a funcao de validacao de valores individuais
+		if (! is_array( $input ) )
+			return( $this->validate( $pattern, $input, $caseSensitive ) );
+
+		//faz a validacao de cada elemento do array e armazena o resultado no atributo da classe
+		foreach ( $input as $item )
+		{
+			if ($this->indexBy == $this->INDEX_BY_STRING)
+				$this->validResults[ (string) $item ] = $this->validate( $pattern, $item, $caseSensitive );
+			else
+				$this->validResults[ ] = $this->validate( $pattern, $item, $caseSensitive );
+		}
+	}
+
+	/* FIM DECLARAcaO DE MeTODOS */
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_date.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_date.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_date.php	(revision 795)
@@ -0,0 +1,693 @@
+<?php
+/**
+ * Corresponde ao formato de data armazenado na configuração (d/m/Y ou Y/m/d)
+ * @name DATE_FORMAT_LOCAL
+ */
+define('DATE_FORMAT_LOCAL', 'd/m/Y');
+/**
+ * maior número inteiro
+ * @name DATE_FORMAT_LOCAL
+ */
+define('LONG_MAX', is_int(2147483648) ? 9223372036854775807 : 2147483647);
+/**
+ * Formato de data customizado
+ * @name DATE_FORMAT_LOCAL
+ */
+define('DATE_FORMAT_CUSTOM', 'CUSTOM');
+
+/**
+ * Classe para manipulação e realização de cálculos com datas
+ * @author Marcos Pont
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local 
+ */
+class wf_date
+{
+
+	/**
+	 * Construtora da classe wf_date
+	 * @return object Objeto da classe wf_date
+	 * @access public
+	 */
+	function wf_date()
+	{
+	}
+
+	/**
+	 * Verifica se uma determinada data é válida
+	 * @access public
+	 * @param string $date Data a ser validada
+	 * @return boolean
+	 */
+	function isValid($date) {
+		$regs = array();
+		if ($this->isEuroDate($date, $regs)) {
+			list(, $day, $month, $year) = $regs;
+		} else if ($this->isUsDate($date, $regs) || $this->isSqlDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+		} else {
+			return FALSE;
+		}
+		if ($year < 0 || $year > 9999) {
+			return FALSE;
+		} else {
+			return (checkdate($month, $day, $year));
+		}
+	}
+	/**
+	 *	Verifica se um valor de time zone é válido
+	 *	@access public
+	 *	@param	string $tz	Valor de time zone
+	 *	@return boolean	
+	 */	
+	function isValidTZ($tz) {
+		return preg_match("/^(((\+|\-)[0-9]{2}\:[0-9]{2})|(UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT)|([A-IK-Y]{1}))$/", $tz);
+	}
+	
+	/**
+	 * Verifica se uma data está no formato europeu dd[/-.]mm[/-.]YYYY[ HH:mm:ss]
+	 * @param array &$regs Vetor para onde retornam os valores destacados de dia, mês e ano
+	 * @access public
+	 * @return boolean
+	 */
+	function isEuroDate($date, &$regs) {
+		$date = trim($date);
+		if (ereg("^([0-9]{1,2})(/|\-|\.)([0-9]{1,2})(/|\-|\.)([0-9]{4})([[:space:]]([0-9]{1,2}):([0-9]{1,2}):?([0-9]{1,2})?)?$", $date, $matches)) {
+			$regs = array(
+				$matches[0], 
+				$matches[1], $matches[3], $matches[5], 
+				$matches[7], $matches[8], $matches[9]
+			);
+			return TRUE;
+		}
+		return FALSE;
+	}
+	
+	/**
+	 * Verifica se uma data está no formato americano YYYY[/-.]mm[/-.]dd[ HH:mm:ss]
+	 * @param string $date Data a ser verificada
+	 * @param array	&$regs Vetor para onde retornam os valores destacados de dia, mês e ano
+	 * @access public
+	 * @return boolean
+	 */	
+	function isUsDate($date, &$regs) {
+		$date = trim($date);
+		if (ereg("^([0-9]{4})(/|\-|\.)([0-9]{1,2})(/|\-|\.)([0-9]{1,2})([[:space:]]([0-9]{1,2}):([0-9]{1,2}):?([0-9]{1,2})?)?$", $date, $matches)) {
+			$regs = array(
+				$matches[0], 
+				$matches[1], $matches[3], $matches[5], 
+				$matches[7], $matches[8], $matches[9]
+			);
+			return TRUE;
+		}
+		return FALSE;
+	}
+	
+	/**
+	 * Verifica se uma data está no formato SQL YYYY-mm-dd
+	 * @param string $date Data a ser verificada
+	 * @param array &$regs Vetor para onde retornam os valores destacados de dia, mês e ano
+	 * @access public
+	 * @return boolean
+	 */
+	function isSqlDate($date, &$regs) {
+		$date = trim($date);
+		if (ereg("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})([[:space:]]([0-9]{1,2}):([0-9]{1,2}):?([0-9]{1,2})?)?$", $date, $matches)) {
+			$regs = array(
+				$matches[0], 
+				$matches[1], $matches[2], $matches[3], 
+				$matches[5], $matches[6], $matches[7]
+			);
+			return TRUE;			
+		}
+		return FALSE;
+	}
+	
+	/**
+	 * Verifica se uma data é posterior à data atual
+	 * @access public
+	 * @param string $date Data a ser verificada
+	 * @return boolean
+	 */
+	function isFuture($date) {
+		$daysFrom = $this->dateToDays($date);
+		$daysTo = $this->dateToDays();
+		return ($daysFrom > $daysTo);
+	}
+	
+	/**
+	 * Verifica se uma data é anterior à data atual
+	 * @access public
+	 * @param string date Data a ser verificada
+	 * @return boolean
+	 */
+	function isPast($date) {
+		$daysFrom = $this->dateToDays($date);
+		$daysTo = $this->dateToDays();
+		return ($daysTo > $daysFrom);
+	}
+	
+	/**
+	 * Calcula o dia seguinte em relação à data atual
+	 * @access public
+	 * @return string Data calculada
+	 */
+	function tomorrow() {
+		return $this->nextDay();
+	}
+	
+	/**
+	 * Verifica se um determinado valor é NULL
+	 * @param mixed $value Valor a testar
+	 * @param boolean $strict Considerar o tipo do dado
+	 * @access public
+	 * @return boolean
+	 */
+	function isNull($value, $strict = FALSE) {
+		return ($strict) ? (NULL === $value) : (NULL == $value);
+	}	
+	
+	/**
+	 * Calcula a data imediatamente posterior a uma determinada data
+	 * @access public
+	 * @param string $date Data base
+	 * @return string Dia seguinte calculado
+	 */
+	function nextDay($date=NULL) {
+		if ($this->isNull($date)) {
+			$date = $this->localDate();
+		}
+		return $this->futureDate($date, 1);
+	}
+	
+	/**
+	 * Calcula uma data no futuro, a partir de um número de dias, meses e anos
+	 * @access public
+	 * @param string $date Data original
+	 * @param iny $days Número de dias no futuro
+	 * @param int $months Número de meses no futuro
+	 * @param int $years Número de anos no futuro
+	 * @return string Data calculada no formato original
+	 */
+	function futureDate($date, $days = 0, $months = 0, $years = 0) {
+		// Captura o formato e os elementos da data base
+		$regs = array();		
+		if ($this->isEuroDate($date, $regs)) {
+			list(, $day, $month, $year) = $regs;
+			$dateFormat = "EURO";
+		} else if ($this->isSqlDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+			$dateFormat = "SQL";
+		} else if ($this->isUsDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+			$dateFormat = "US";
+		} else {			
+			return NULL;
+		}
+		// Calcula o número de dias da data original
+		$daysFrom = $this->dateToDays($date);
+		$daysInc = 0;
+		// Adiciona os anos
+		$years = intval($years);
+		for ($i = 1; $i <= $years; $i++) {
+			$year++;
+			$daysInc += ($this->isLeapYear($year)) ? 366 : 365;
+		}
+		// Adiciona os meses de acordo com o número de dias em cada um
+		$months = intval($months);
+		for ($i = 1; $i <= $months; $i++) {
+			$mTemp = $i % 12 - 1;
+			$yTemp = intval($i / 12);
+			if (($month + $mTemp) > 12) {
+				$yTemp++;
+				$mTemp = ($month + $mTemp) - 12;
+			} else {
+				$mTemp = $month + $mTemp;
+			}
+			$daysInc += $this->daysInMonth($mTemp, $year + $yTemp);
+		}
+		// Adiciona os dias
+		$daysInc += intval($days);
+		// Retorna a data calculada no formato original
+		return $this->daysToDate($daysFrom + $daysInc, $dateFormat);				
+	}
+	
+	/**
+	 * Calcula o dia anterior em relação à data atual
+	 * @access public
+	 * @return string Data calculada
+	 */
+	function yesterday() {
+		return $this->prevDay();
+	}
+	
+	/**
+	 * Calcula a data imediatamente anterior a uma determinada data
+	 * @access public 
+	 * @param string $date Data base
+	 * @return string Dia anterior calculado
+	 */
+	function prevDay($date=NULL) {
+		if ($this->isNull($date)) {
+			$date = $this->localDate();
+		}
+		return $this->pastDate($date, 1);
+	}
+	
+	/**
+	 * Calcula uma data no passado, a partir de um número de dias, meses e anos
+	 * @param string $date Data original
+	 * @param int $days Número de dias no passado
+	 * @param int $months Número de meses no passado
+	 * @param int $years Número de anos no passado
+	 * @return string Data calculada no formato original
+	 * @access public
+	 */
+	function pastDate($date, $days=0, $months=0, $years=0) {
+		// Captura o formato e os elementos da data base
+		$regs = array();
+		if ($this->isEuroDate($date, $regs)) {
+			list(, $day, $month, $year) = $regs;
+			$dateFormat = 'EURO';
+		} else if ($this->isSqlDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+			$dateFormat = 'SQL';
+		} else if ($this->isUsDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+			$dateFormat = 'US';
+		} else {
+			return NULL;
+		}
+		// Calcula o número de dias da data original
+		$daysFrom = $this->dateToDays($date);
+		$daysDec = 0;
+		// Adiciona os anos
+		for ($i = 1; $i <= $years; $i++) {
+			$s = ($this->isLeapYear($year)) ? 366 : 365;
+			$daysDec += ($this->isLeapYear($year)) ? 366 : 365;
+			$year--;			
+		}		
+		// Adiciona os meses de acordo com os dias de cada mês
+		for ($i = 1; $i <= $months; $i++) {
+			$mTemp = $i % 12;
+			$yTemp = intval($i / 12);
+			if (($month - $mTemp) <= 0) {
+				$yTemp++;
+				$mTemp = 12 + ($month - $mTemp);
+			} else {
+				$mTemp = $month - $mTemp;
+			}
+			$daysDec += $this->daysInMonth($mTemp, $year - $yTemp);
+		}
+		// Adiciona os dias
+		$daysDec += $days;
+		// Retorna a data calculada no formato original
+		return $this->daysToDate($daysFrom - $daysDec, $dateFormat);
+	}
+	
+	/**
+	 * Calcula a diferença em dias entre duas datas
+	 * @param string $dateM Data 1
+	 * @param string $dateS Data 2
+	 * @param boolean $unsigned Usar sinal no retorno
+	 * @access public
+	 */
+	function getDiff($dateM, $dateS, $unsigned=TRUE) {
+		// Calcula o número de dias da diferença
+		$daysS = $this->dateToDays($dateS);
+		$daysM = $this->dateToDays($dateM);
+		return ($unsigned? abs($daysS - $daysM) : ($daysS - $daysM));
+	}
+	
+	/**
+	 * Retorna o dia da semana para uma data
+	 * @param string $date Data a ser processada
+	 * @param boolean $text Retornar o nome do dia da semana
+	 * @param boolean $abbr Retornar o nome do dia da semana abreviadamente
+	 * @return mixed Nome ou número do dia da semana (baseado em zero)
+	 * @access public 
+	 */
+	function dayOfWeek($date, $text=TRUE, $abbr=FALSE) {
+		// Captura os elementos da data base de acordo com o formato
+		$regs = array();
+		if ($this->isEuroDate($date, $regs)) {
+			list(, $day, $month, $year) = $regs;
+		} else if ($this->isUsDate($date, $regs) || $this->isSqlDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+		} else {
+			return NULL;
+		}
+		// Cálculo do dia da semana
+		if ($month > 2) {
+			$month -= 2;
+		} else {
+			$month += 10;
+			$year--;
+		}
+		$dow = (floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4) + floor(($year / 100) / 4) - 2 * floor($year / 100) + 77);
+		$dow = (($dow - 7 * floor($dow / 7)));
+		// Exibição do resultado, de acordo com os parâmetros fornecidos
+		if ($text) {
+			$daysOfWeek = array('segunda', 'terça', 'quarta', 'quinta', 'sexta');
+			if ($abbr) {
+				return $daysOfWeek[$dow];	
+			} else {
+				return $daysOfWeek[$dow] . '-feira';
+			}					
+		} else {
+			return $dow;
+		}
+	}
+	
+	/**
+	 * Retorna o número de dias de um mês de acordo com o mês e o ano
+	 * @param int $month Mês
+	 * @param int $year Ano
+	 * @return int Número de dias do mês solicitado
+	 * @access public 
+	 */
+	function daysInMonth($month=NULL, $year=NULL) {
+		if ($this->isNull($year)) 
+			$year = date("Y");
+		if ($this->isNull($month)) 
+			$month = date("m");
+		if ($month == 2) {
+			return ($this->isLeapYear($year) ? 29 : 28);
+		} elseif (in_array($month, array(4, 6, 9, 11))) {
+			return 30;
+		} else {
+			return 31;
+		}
+	}
+	
+	/**
+	 * Verifica se um determinado ano é bissexto
+	 * @param int $year Ano para ser verificado
+	 * @access public
+	 * @return boolean
+	 */
+	function isLeapYear($year=NULL) {
+		if ($this->isNull($year))
+			$year = date("Y");
+		if (strlen($year) != 4 || preg_match("/\D/", $year))
+			return NULL;
+		return ((($year % 4) == 0 && ($year % 100) != 0) || ($year % 400) == 0);
+	}	
+	
+	/**
+	 * Converte uma data no padrão europeu (dd/mm/YYYY) para o padrão SQL (YYYY-mm-dd)
+	 * @param string $date Data a ser convertida
+	 * @param boolean @preserveTime Preservar porção de hora, se ela existir na data fornecida
+	 * @return string Data convertida ou a original se o padrão de entrada estiver incorreto
+	 * @access public
+	 */
+	function fromEuroToSqlDate($date, $preserveTime=FALSE) {
+		$regs = array();
+		if ($this->isEuroDate($date, $regs)) {
+			$res = "$regs[3]-$regs[2]-$regs[1]";
+			if ($preserveTime && $regs[4] !== FALSE && $regs[5] !== FALSE) {
+				$res .= " $regs[4]:$regs[5]";
+				if ($regs[6] !== FALSE)
+					$res .= ":$regs[6]";
+			}
+			return $res;
+		} else {
+			return $date;
+		}
+	}
+	
+	/**
+	 * Converte uma data no padrão europeu (dd/mm/YYYY)
+	 * @param string $date Data a ser convertida
+	 * @param boolean $preserveTime Preservar porção de hora, se ela existir na data fornecida
+	 * @return string Data convertida ou a original se o padrão de entrada estiver incorreto
+	 * @access public
+	 */
+	function fromEuroToUsDate($date, $preserveTime=FALSE) {
+		$regs = array();
+		if ($this->isEuroDate($date, $regs)) {			
+			$res = "$regs[3]/$regs[2]/$regs[1]";
+			if ($preserveTime && $regs[4] !== FALSE && $regs[5] !== FALSE) {
+				$res .= " $regs[4]:$regs[5]";
+				if ($regs[6] !== FALSE)
+					$res .= ":$regs[6]";
+			}
+			return $res;			
+		} else {
+			return $date;
+		}
+	}
+	
+	/**
+	 * Converte uma data no padrã americano (YYYY/mm/dd) para o padrão SQL (YYYY-mm-dd)
+	 * @param string $date Data a ser convertida
+	 * @return string Data convertida ou a original se o padrão de entrada estiver incorreto
+	 * @access public
+	 */
+	function fromUsToSqlDate($date) {
+		$regs = array();
+		if ($this->isUsDate($date, $regs)) {
+			return str_replace("/", "-", $date);
+		} else {
+			return $date;
+		}
+	}
+	
+	/**
+	 * Converte uma data no padrão americano (YYYY/mm/dd) para o padrão europeu (dd/mm/YYYY)
+	 * @param string $date Data a ser convertida
+	 * @param boolean $preserveTime Preservar porção de hora, se ela existir na data fornecida
+	 * @return string Data convertida ou a original se o padrão de entrada estiver incorreto
+	 * @access public
+	 */
+	function fromUsToEuroDate($date, $preserveTime=FALSE) {
+		$regs = array();
+		if ($this->isUsDate($date, $regs)) {
+			$res = "$regs[3]/$regs[2]/$regs[1]";
+			if ($preserveTime && $regs[4] !== FALSE && $regs[5] !== FALSE) {
+				$res .= " $regs[4]:$regs[5]";
+				if ($regs[6] !== FALSE)
+					$res .= ":$regs[6]";
+			}
+			return $res;			
+		} else {
+			return $date;
+		}
+	}
+	
+	/**
+	 * Converte uma data no padrão SQL (YYYY-mm-dd) para o padrão europeu (dd/mm/YYYY)
+	 * @param string $date	Data a ser convertida
+	 * @param boolean preserveTime Preservar porção de hora, se ela existir na data fornecida
+	 * @return string Data convertida ou a original se o padrão de entrada estiver incorreto
+	 * @access public
+	 */
+	function fromSqlToEuroDate($date, $preserveTime=FALSE) {
+		$regs = array();
+		if ($this->isSqlDate($date, $regs)) {
+			$res = "$regs[3]/$regs[2]/$regs[1]";
+			if ($preserveTime && $regs[4] !== FALSE && $regs[5] !== FALSE) {
+				$res .= " $regs[4]:$regs[5]";
+				if ($regs[6] !== FALSE)
+					$res .= ":$regs[6]";
+			}
+			return $res;			
+		} else {
+			return $date;
+		}
+	}
+	
+	/**
+	 * Converte uma data no padrão SQL (YYYY-mm-dd) para o padrão americano (YYYY/mm/dd)
+	 * @param string $date Data a ser convertida
+	 * @return string Data convertida ou a original se o padrão de entrada estiver incorreto
+	 * @access public
+	 */
+	function fromSqlToUsDate($date) {
+		$regs = array();
+		if ($this->isSqlDate($date, $regs)) {
+			return str_replace("-", "/", $date);
+		} else {
+			return $date;
+		}
+	}
+	
+	/**
+	 * Converte um timestamp Unix em uma data/hora no formato DOS com 4 bytes
+	 * @param int $unixTimestamp Timestamp UNIX para a conversão
+	 * @return string Data e hora no formato DOS
+	 * @access public
+	 */
+	function fromUnixToDosDate($unixTimestamp=0) {
+		$timeData = ($unixTimestamp) ? getdate($unixTimestamp) : getdate();
+		if ($timeData['year'] < 1980) {
+			$timeData['year'] = 1980;
+			$timeData['mon'] = 1;
+			$timeData['mday'] = 1;
+			$timeData['hours'] = 0;
+			$timeData['minutes'] = 0;
+			$timeData['seconds'] = 0;
+		}
+		return ((($timeData['year'] - 1980) << 25) |
+			($timeData['mon'] << 21) |
+			($timeData['mday'] << 16) |
+			($timeData['hours'] << 11) |
+			($timeData['minutes'] << 5) |
+			($timeData['seconds'] << 1));
+	}
+	
+	/**
+	 * Converte uma data nos formatos EURO, US ou SQL em um timestamp UNIX
+	 * @param string $date Data
+	 * @return int
+	 * @access public
+	 */
+	function dateToTime($date) {
+		$date = $this->fromEuroToUsDate($date, TRUE);
+		return strtotime($date);
+	}
+	
+	/**
+	 * Converte uma data para o correspondente em número de dias
+	 * @param string $date Data base para o cálculo
+	 * @return int Data convertida em número de dias
+	 * @access public
+	 */
+	function dateToDays($date=NULL) {		
+		if ($this->isNull($date))
+			$date = $this->localDate();
+		$regs = array();
+		if ($this->isEuroDate($date, $regs)) {
+			list(, $day, $month, $year) = $regs;
+		} else if ($this->isUsDate($date, $regs) || $this->isSqlDate($date, $regs)) {
+			list(, $year, $month, $day) = $regs;
+		} else {
+			return -1;
+		}		
+        $century = (int) substr($year,0,2);
+        $year = (int) substr($year,2,2);
+        if ($month > 2) {
+            $month -= 3;
+        } else {
+            $month += 9;
+            if ($year) {
+                $year--;
+            } else {
+                $year = 99;
+                $century --;
+            }
+        }
+        return (floor((146097 * $century) / 4 ) + floor(( 1461 * $year) / 4 ) + floor(( 153 * $month + 2) / 5 ) + $day + 1721119);
+	}
+	
+	/**
+	 * Converte um número de dias em uma data
+	 * @param int $days Número de dias
+	 * @param string $dateType Tipo da data a ser retornada (EURO, US ou SQL)
+	 * @return string Data correspondente
+	 * @access public
+	 */
+	function daysToDate($days, $dateType) {
+		if (!is_float($days) || !in_array(strtolower($dateType), array('euro', 'us', 'sql'))) {
+			return NULL;
+		}
+        $days -= 1721119;
+        $century = floor(( 4 * $days - 1) / 146097);
+        $days = floor(4 * $days - 1 - 146097 * $century);
+        $day = floor($days / 4);
+        $year = floor(( 4 * $day +  3) / 1461);
+        $day = floor(4 * $day +  3 - 1461 * $year);
+        $day = floor(($day +  4) / 4);
+        $month = floor(( 5 * $day - 3) / 153);
+        $day = floor(5 * $day - 3 - 153 * $month);
+        $day = floor(($day +  5) /  5);
+        if ($month < 10) {
+            $month +=3;
+        } else {
+            $month -=9;
+            if ($year++ == 99) {
+                $year = 0;
+                $century++;
+            }
+        }
+        $century = sprintf('%02d', $century);
+        $year = sprintf('%02d', $year);
+        $month = sprintf('%02d', $month);
+        $day = sprintf('%02d', $day);
+        if (strtolower($dateType) == 'euro') {
+        	return ("$day/$month/$century$year");
+        } else if (strtolower($dateType) == 'us') {
+        	return ("$century$year/$month/$day");
+        } else {
+        	return ("$century$year-$month-$day");
+        }		
+	}
+	
+	/**
+	 * Retorna a data local de acordo com o formato
+	 * @access public
+	 * @param int $ts Timestamp opcional para geração da data local
+	 * @return string Data local, a partir do timestamp atual ou um determinado
+	 */
+	function localDate($ts=0) {
+		$dateFormat = DATE_FORMAT_LOCAL;
+		if ($ts > 0) {
+			if ($dateFormat) {
+				return date($dateFormat . ' H:i:s', $ts);
+			} else {
+				return date("d/m/Y H:i:s", $ts);
+			}
+		} else {
+			if ($dateFormat) {
+				return date($dateFormat);
+			} else {
+				return date("d/m/Y");
+			}
+		}
+	}
+	
+	/**
+	 * Formata um valor de data a partir dos valores de dia, mês e ano
+	 * @param int $day Valor do dia na data
+	 * @param int $month Valor do mês na data
+	 * @param int $year Valor do ano na data, com 4 dígitos
+	 * @param int $fmtType Tipo de formato de data (vide constantes da classe)
+	 * @return string Data formatada
+	 * @access public
+	 */
+	function formatDate($day, $month, $year, $fmtType=DATE_FORMAT_LOCAL, $fmtStr='') {
+		$day = strval(str_repeat('0', (2 - strlen($day))) . $day);
+		$month = strval(str_repeat('0', (2 - strlen($month))) . $month);
+		$year = strval(str_repeat('0', (4 - strlen($year))) . $year);
+		$tsDate = mktime(0, 0, 0, $month, $day, $year);
+		return $this->formatTime($tsDate, $fmtType, $fmtStr);
+	}
+	
+	/**
+	 * Formata um valor de unix timestamp
+	 * @access public
+	 * @param int $time Unix timestamp
+	 * @param int $fmtType Tipo de formato de data (vide constantes da classse)
+	 * @param string $fmtString Descrição do formato (quando $fmtType==DATE_FORMAT_CUSTOM)
+	 * @return string Timestamp formatado
+	 */
+	function formatTime($time=NULL, $fmtType=DATE_FORMAT_LOCAL, $fmtStr='') {
+		if (empty($time)) {
+			$time = time();
+		}			
+		if (!is_int($time) || $time < 0 || $time > LONG_MAX) {
+			return $time;
+		}			
+		if ($fmtType == DATE_FORMAT_LOCAL) {			
+			return $this->localDate($time);			
+		} elseif ($fmtType == DATE_FORMAT_CUSTOM && !empty($fmtStr)) {
+			return date($fmtStr, $time);
+		} else {
+			return $time;
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_util.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_util.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_util.php	(revision 795)
@@ -0,0 +1,64 @@
+<?php
+/**
+ * importa classe do módulo
+ */
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'class.utils.php');
+/**
+ * Classe utilitária
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_util extends Utils {
+
+	function wf_util()
+	{
+		return true;
+	}
+
+	/* desabilita métodos */
+	function includeFile($filePath, $return=FALSE) {}
+	function scriptName() {}
+	function serverName() {}
+	function get($key) {}
+	function anchor($url, $text, $statusBarText='', $cssClass='', $jsEvents=array(), $target='', $name='', $id='', $rel='', $accessKey='') {}	
+
+	/**
+	* Formata um array em uma linha do formato CSV
+	*
+	* @return string Linha no formato CSV
+	* @access public
+	*/
+	function createCSVLine($item, $separator, $quotes = false)
+	{
+		if(is_array($item)){
+			if ($quotes){
+				foreach ($item as $key => $value){
+					$item[$key] = '"' . str_replace('"', '""', $value) . '"';
+				}
+			}
+			return implode($separator, $item) . "\n";
+		}
+		return false;
+	}
+
+	/**
+	* Cria um arquivo CSV baseado em um array
+	*
+	* @return string Linha no formato CSV
+	* @access public
+	*/
+	function createCSVFile($data, $separator, $quotes = false)
+	{
+		if(!is_array($data))
+			return false;
+
+		foreach($data as $item){
+			$output .= $this->createCSVLine($item, $separator, $quotes);
+		}
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_fpdf.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_fpdf.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_fpdf.php	(revision 795)
@@ -0,0 +1,88 @@
+<?php
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'fpdf'.SEP.'fpdf.php');
+
+/**
+ * Class for generating PDF reports
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local  
+ */
+class wf_fpdf extends FPDF
+{
+	/**
+	 * @var string $headerFunction Armazena a função que gera o Cabeçalho do documento
+	 * @access public 
+	 */
+	var $headerFunction;
+	/**
+	 * @var string $footerFunction Armazena a função que gera o Rodapé do documento
+	 * @access public
+	 */
+	var $footerFunction;
+
+	/**
+	 * Construtor da classe wf_fpdf inicializa a classe
+	 * @return object
+	 * @access public
+	 */
+	function wf_fpdf()
+	{
+		$this->headerFunction = "";
+		$this->footerFunction = "";
+
+		parent::FPDF();
+	}
+	/**
+	 * Utilizado para chamar o Metodo Output da classe base FPDF que retorna o documento PDF como uma string 
+	 * @return string
+	 * @access public
+	 */
+	function Output()
+	{
+		return parent::Output('', 'S');
+	}
+	 
+	/**
+	 * Utilizado para chamar (se existir) uma função para gerar o cabeçalho
+	 * @return mixed
+	 * @access public 
+	 */
+	function Header()
+	{
+		$funcao = $this->headerFunction;
+		if (!empty($funcao))
+			if ((function_exists($funcao)) && (is_callable($funcao)))
+				return call_user_func($funcao, &$this);
+	}
+    /**
+	 * Utilizado para chamar (se existir) uma função para gerar o rodapé
+	 * @return mixed
+	 * @access public 
+	 */
+	function Footer()
+	{
+		$funcao = $this->footerFunction;
+		if (!empty($funcao))
+			if ((function_exists($funcao)) && (is_callable($funcao)))
+				return call_user_func($funcao, &$this);
+	}
+    /**
+	 * Utilizado para atribuir uma função para gerar o Cabeçalho
+	 * @return void
+	 * @access public 
+	 */
+	function setHeaderFunction($funcao)
+	{
+		$this->headerFunction = $funcao;
+	}
+	/**
+	 * Utilizado para atribuir uma função para gerar o Rodapé
+	 * @return void
+	 * @access public 
+	 */
+	function setFooterFunction($funcao)
+	{
+		$this->footerFunction = $funcao;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_mem_image.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_mem_image.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_mem_image.php	(revision 795)
@@ -0,0 +1,37 @@
+<?php
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'fpdf'.SEP.'mem_image.php');
+
+/**
+ * Classe que permite a inclusão de imagens em relatórios gerados pelo FPDF sem a necessidade da utilização de arquivos temporários.
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Allan Bomfim
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com (revisão)
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_mem_image extends MEM_IMAGE
+{
+	/**
+	 * Construtor da classe wf_mem_image
+	 * @param string $orientation Orientação da página: 'P' (ou 'portrait') para retrato ou 'L' (ou 'landscape') para paisagem.
+	 * @param string $unit Unidade de medida: 'pt' para ponto, 'mm' para milímetro, 'cm' para centímetros ou 'in' para polegadas.
+	 * @param string $format Formato da página: 'a3', 'a4', 'a5', 'letter' ou 'legal'.
+	 * @return object
+	 * @access public
+	 */
+	function wf_mem_image($orientation = 'P', $unit = 'mm', $format = 'A4')
+	{
+		parent::MEM_IMAGE($orientation, $unit, $format);
+	}
+
+	/**
+	 * Utilizado para chamar o Metodo Output da classe base FPDF que retorna o documento PDF como uma string 
+	 * @return string
+	 * @access public
+	 */
+	function Output()
+	{
+		return parent::Output('', 'S');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_ldap.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_ldap.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_ldap.php	(revision 2372)
@@ -0,0 +1,163 @@
+<?php
+
+/**
+ * Class for basic operations with user accounts on LDAP to be used in activities only
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_ldap
+{
+	/**
+	 * @var $ds resource recurso
+	 * @access public
+	 */
+	var $ds;
+
+	/**
+	 * @var $user_context string contexto do usuário
+	 * @access public
+	 */
+	var $user_context  = '';
+
+	/**
+	 * @var $group_context string contexto do grupo
+	 * access public
+	 */
+	var $group_context = '';
+
+	/**
+	 * @var object $cachedLDAP Objeto da classe CachedLDAP
+	 * access private
+	 */
+	private $cachedLDAP;
+
+	/**
+	 *  Construtor da classe wf_ldap Inicializa a conexão com o LDAP
+	 *  @return object
+	 *  @access public
+	 */
+	function wf_ldap()
+	{
+		$tmpLDAP = Factory::getInstance('WorkflowLDAP');
+		$this->user_context  = $tmpLDAP->getUserContext();
+		$this->group_context = $tmpLDAP->getGroupContext();
+
+		$this->ds = &$GLOBALS['workflow']['workflowObjects']->getLDAP();
+
+		$this->cachedLDAP = &Factory::getInstance('wf_cached_ldap');
+		$this->cachedLDAP->setOperationMode($this->cachedLDAP->OPERATION_MODE_LDAP);
+	}
+
+	/**
+	 *  Busca registros do LDAP de acordo com o o id e tipo de conta passados como parametro
+	 *  @param int $account_id ID do usuário ou grupo.
+	 *  @param string $account_type Tipo de conta ("u" usuario,"g" grupo)
+	 *  @return array Informações do(s) registro(s) encontrado(s).
+	 *  @access public
+	 */
+	function get_entry($account_id, $account_type = "u")
+	{
+		if ($account_type == "u")
+		{
+			return $this->cachedLDAP->getEntryByID($account_id);
+		}
+		elseif ($account_type == "g")
+		{
+			$sri = ldap_search($this->ds, $this->group_context, '(&(gidnumber=' . (int)$account_id . ')(phpgwaccounttype=g))');
+			$allvalues = ldap_get_entries($this->ds, $sri);
+			return array( 'dn' => $allvalues[0]['dn'],
+				'memberuid' => $allvalues[0]['memberuid'],
+				'gidnumber' => $allvalues[0]['gidnumber'][0],
+				'cn' => $allvalues[0]['cn'][0]
+			);
+		}
+		else
+		{
+			return false;
+		}
+
+	}
+
+	/**
+	 *  Busca um registro do LDAP de acordo com o CPF.
+	 *  @param int $cpf CPF do usuário.
+	 *  @return array Informações do registro encontrado.
+	 *  @acess public
+	 */
+	function get_entry_by_cpf($cpf)
+	{
+		return $this->cachedLDAP->getEntryByCPF($cpf);
+	}
+
+	/**
+	 *  Busca um registro do LDAP de acordo com o e-mail.
+	 *  @param string $email E-mail do usuário.
+	 *  @return array Informações do registro encontrado.
+	 *  @acess public
+	 */
+	function get_entry_by_email($email)
+	{
+		return $this->cachedLDAP->getEntryByEmail($email);
+	}
+
+	/**
+	 *  Busca um registro do LDAP de acordo com a matricula.
+	 *  @param int $matricula Matrícula do usuário.
+	 *  @return array Informações do registro encontrado.
+	 *  @acess public
+	 */
+	function get_entry_by_matricula($matricula)
+	{
+		return $this->cachedLDAP->getEntryByEmployeeNumber($matricula);
+	}
+
+	/**
+	 *  Busca um registro do LDAP de acordo com o uid.
+	 *  @param string $uid Uid do usuário.
+	 *  @return array Informações do registro encontrado.
+	 *  @acess public
+	 */
+	function get_entry_by_uid($uid)
+	{
+		return $this->cachedLDAP->getEntryByUid($uid);
+	}
+
+
+	/**
+	 *  Busca nomes de uma array de IDs.
+	 *  @param array $IDs Os IDs dos quais se quer o nome.
+	 *  @return array Uma array contento os IDs e os nomes encontrados.
+	 *  @acess public
+	 */
+	function getNames($IDs)
+	{
+		if (!is_array($IDs))
+			return false;
+
+		/* faz a busca para encontrar os nomes */
+		$resourceIdentifier = ldap_search($this->ds, $this->user_context, "(|" . implode('', array_map(create_function('$a', 'return "(uidnumber={$a})";'), array_unique($IDs))) . ")", array('cn', 'uidnumber'));
+		$result = ldap_get_entries($this->ds, $resourceIdentifier);
+
+		/* prepara a saída */
+		$output = array();
+		for ($i = 0; $i < $result['count']; $i++)
+			$output[] = array(
+				'id' => $result[$i]['uidnumber'][0],
+				'name' => $result[$i]['cn'][0]);
+
+		/* retorna os IDs/nomes */
+		return $output;
+	}
+
+	/**
+	 * Termina a conexão com o LDAP
+	 * @return void
+	 * @acess public
+	 */
+	function close()
+	{
+		ldap_close($this->ds);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_log.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_log.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_log.php	(revision 795)
@@ -0,0 +1,34 @@
+<?php
+
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'class.Logger.inc.php');
+
+/**
+ * Geração de logs.
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Guilherme Striquer Bisotto - gbisotto@celepar.pr.gov.br
+ * @package Workflow
+ * @subpackage local
+ */
+class wf_log extends Logger
+{
+
+	/**
+	 * Construtor da classe wf_log
+	 * @param array/string $logTypes Array ou String com o(s) tipo(s) de log(s) que deverá(ão) ser criado(s)
+	 * @return object Objeto do tipo wf_log
+	 * @access public
+	 */
+	public function wf_log($logTypes = 'file')
+	{
+		$processName = $GLOBALS['workflow']['wf_normalized_name'];
+		if(empty($processName))
+			throw new Exception(lang('Cannot find out the process name'));
+
+		$processId = $GLOBALS['workflow']['wf_process_id'];
+		if(empty($processId))
+			throw new Exception('Cannot fint out the process id ');
+
+		parent::Logger($logTypes, $processId, $processName);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_type.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_type.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_type.php	(revision 795)
@@ -0,0 +1,16 @@
+<?php
+/**
+ * importa classe do módulo
+ */
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'class.utils.type.php');
+/**
+ * Classe que contém funções utilitárias para verificação de tipagem
+ * de dados e conversão (cast) entre tipos primitivos de dados no PHP
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow 
+ * @subpackage local  
+ */
+class wf_type extends TypeUtils {}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_mail.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_mail.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_mail.php	(revision 2372)
@@ -0,0 +1,174 @@
+<?php
+require_once(PHPGW_SERVER_ROOT . SEP . 'phpgwapi' . SEP . 'inc' . SEP . 'class.phpmailer.inc.php');
+
+/**
+* Permite ao desenvolvedor de processos Workflow enviar e-mails em tempo de execução.
+* @author Sidnei Augusto Drovetto Junior
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+* @subpackage local
+*/
+class wf_mail extends PHPMailer
+{
+	/**
+	* @var boolean $validConfig indica se as configurações de e-mail carregadas são válidas.
+	* @access private
+	*/
+	var $validConfig;
+
+	/**
+	* Construtor do wf_mail.
+	* @return object
+	* @access public
+	*/
+	function wf_mail()
+	{
+		//parent::PHPMailer();
+		$this->_init();
+	}
+
+	/**
+	* Inicializa a classe wf_mail (configura o PHPMailer com as configurações do processo).
+	* @return void
+	* @access private
+	*/
+	private function _init()
+	{
+		/* carrega as configurações de processo e do perfil de e-mail */
+		$requiredConfiguration = array('mail_smtp_profile' => false);
+		$configuration = $GLOBALS['workflow']['wf_runtime']->process->getConfigValues($requiredConfiguration);
+		$bo_emailadmin = Factory::getInstance('bo');
+		$profileData = $bo_emailadmin->getProfile($configuration['mail_smtp_profile']);
+
+		if (!is_array($profileData))
+		{
+			$this->validConfig = false;
+			return false;
+		}
+		else
+			$this->validConfig = true;
+
+		/* configura os parâmetros para envio de e-mail */
+		$userLang = $GLOBALS['phpgw_info']['user']['preferences']['common']['lang'];
+		/* FIXME: hardcoded 'br' because phpmailer don't use pt-br */
+		if ($userLang == 'pt-br')
+		{
+			$userLang = 'br';
+		}
+		$langFile = PHPGW_SERVER_ROOT."/phpgwapi/setup/phpmailer.lang-$userLang.php";
+		if(file_exists($langFile))
+			$this->SetLanguage($userLang, PHPGW_SERVER_ROOT."/phpgwapi/setup/");
+		else
+			$this->SetLanguage("en", PHPGW_SERVER_ROOT."/phpgwapi/setup/");
+
+		$this->PluginDir = PHPGW_SERVER_ROOT."/phpgwapi/inc/";
+		$this->IsSMTP();
+		$this->Host = $profileData['smtpServer'];
+		$this->Port = $profileData['smtpPort'];
+		if ($profile['smtpAuth'])
+		{
+			$this->SMTPAuth = true;
+			$this->Username = $GLOBALS['phpgw_info']['user']['userid'];
+			$this->Password = $GLOBALS['phpgw_info']['user']['passwd'];
+		}
+		$this->Encoding = '8bit';
+		$this->AddCustomHeader("X-Mailer: Egroupware Workflow");
+		$this->WordWrap = 76;
+		$this->IsHTML(true);
+	}
+
+	/**
+	* Limpa os erros encontrados até o momento.
+	* @return void
+	* @access private
+	*/
+	private function clearErrors()
+	{
+        $this->error_count = 0;;
+        $this->ErrorInfo = null;
+	}
+
+	/**
+	* Envia um e-mail de acordo com as propriedades da classe.
+	* @return bool TRUE em caso de sucesso e FALSE caso contrário.
+	* @access public
+	*/
+	function Send()
+	{
+		/* limpa possíveis erros (para que outras chamadas ao método não influenciem a chamada atual) */
+		$this->clearErrors();
+
+		/* checa se as configurações são válidas */
+		if (!$this->validConfig)
+			return false;
+
+		/* envia o e-mail */
+		return parent::Send();
+	}
+
+	/**
+	* Envia um e-mail de acordo com os parâmetros passados.
+	* @return bool TRUE em caso de sucesso e FALSE caso contrário.
+	* @param string $from O e-mail de origem (remetente).
+	* @param mixed $to Uma string contendo o e-mail do destino (destinatário) ou uma array contendo uma lista de destinatários.
+	* @param string $subject O assunto do e-mail.
+	* @param string $body O corpo da mensagem.
+	* @access public
+	*/
+	function quickSend($from, $to, $subject, $body)
+	{
+		/* limpa possíveis erros (para que outras chamadas ao método não influenciem a chamada atual) */
+		$this->clearErrors();
+
+		/* checa se as configurações são válidas */
+		if (!$this->validConfig)
+			return false;
+
+		/* preenche as informações para envio */
+		$this->FromName = $GLOBALS['workflow']['wf_runtime']->process->getName();
+		$this->From = $from;
+		$this->AddReplyTo($from);
+		$this->Subject = $subject;
+		$this->Body = str_replace("\n",'<br />',html_entity_decode($body));
+		// se for necessária compatibilidade com clientes de email antigos (e.g. mutt) descomente a linha abaixo
+		//$this->AltBody = $body;
+		$this->ClearAllRecipients();
+		if (!is_array($to))
+			$to = array($to);
+		foreach ($to as $recipient)
+			$this->AddAddress($recipient);
+
+		/* envia o e-mail */
+		return parent::Send();
+	}
+
+	/**
+	* Verifica se o recipiente (endereço de e-mail) está ok.
+	* @param string $recipient O endereço de e-mail do recipiente.
+	* @return mixed true se o recipiente estiver ok, caso o recipiente não esteja ok. Será retornado null se houver algum problema ao se iniciar uma transação com o servidor SMTP.
+	* @access public
+	*/
+	public function checkRecipient($recipient)
+	{
+        require_once $this->PluginDir . 'class.smtp.php';
+
+		/* tenta se conectar com o servidor SMTP */
+        if(!$this->SmtpConnect())
+			return false;
+
+		/* estabelece uma transação */
+		if (!$this->smtp->Mail(''))
+			return null;
+
+		/* verifica se o e-mail é válido */
+		$output = $this->smtp->Recipient($recipient);
+
+		/* finaliza a transação */
+		$this->smtp->Reset();
+
+		/* retorna a saída */
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/local/classes/class.wf_db.php
===================================================================
--- /sandbox/workflow/branches/993/inc/local/classes/class.wf_db.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/local/classes/class.wf_db.php	(revision 795)
@@ -0,0 +1,199 @@
+<?php
+
+	/**
+	* Connection to workflow database
+	* @license http://www.gnu.org/copyleft/gpl.html GPL
+	* @package Workflow
+	* @subpackage local
+	**/
+	class wf_db extends db
+	{
+	/**
+	 * Construtor da classe wf_db Inicializa os dados da classe
+	 * @access public
+	 * @return object
+ 	 */
+		function wf_db()
+		{
+			parent::db();
+
+			$dbconf = array(
+						'database_name'	=> '',
+						'database_host'	=> '',
+						'database_port'	=> '',
+						'database_user'	=> '',
+						'database_password'	=> '',
+						'execute_activities_in_debug_mode' => 0
+			);
+
+			$conf_db_values = $GLOBALS['workflow']['wf_runtime']->getConfigValues($dbconf);
+
+			$this->Database = $conf_db_values['database_name'];
+			$this->Host     = $conf_db_values['database_host'];
+			$this->Port		= $conf_db_values['database_port'];
+			$this->User		= $conf_db_values['database_user'];
+			$this->Password = $conf_db_values['database_password'];
+			$this->Type		= $conf_db_values['database_type'];
+
+			if ($conf_db_values['execute_activities_in_debug_mode'])
+			{
+				$this->Halt_On_Error = 'yes';
+			}
+			else
+			{
+				$this->Halt_On_Error = 'no';
+			}
+		}
+	/**
+	 * Conecta com o banco de dados
+	 * @param string $Database Nome do banco de dados
+	 * @param string $Host Nome do Servidor
+	 * @param int $Port Porta do Servidor
+	 * @param string $User Nome do usuário
+	 * @param string $Password Senha do usuário
+	 * @param string $Type Tipo do Banco de dados
+	 * @return object
+	 * @access public
+ 	 */
+		function connect($Database = NULL, $Host = NULL, $Port = NULL, $User = NULL, $Password = NULL,$Type = NULL)
+		{
+			/* Handle defaults */
+			if (!is_null($Database) && $Database)
+			{
+				$this->Database = $Database;
+			}
+			if (!is_null($Host) && $Host)
+			{
+				$this->Host     = $Host;
+			}
+			if (!is_null($Port) && $Port)
+			{
+				$this->Port     = $Port;
+			}
+			if (!is_null($User) && $User)
+			{
+				$this->User     = $User;
+			}
+			if (!is_null($Password) && $Password)
+			{
+				$this->Password = $Password;
+			}
+			if (!is_null($Type) && $Type)
+			{
+				$this->Type = $Type;
+			}
+			elseif (!$this->Type)
+			{
+				$this->Type = $GLOBALS['phpgw_info']['server']['db_type'];
+			}
+
+			if (strcasecmp($this->Database,$GLOBALS['phpgw_info']['server']['db_name']) == 0)
+			{
+				return null;
+			}
+
+			parent::connect();
+		}
+
+		/**
+		 * Desconecta do banco de dados
+		 * @return void
+		 * @access public
+		 */
+		function disconnect()
+		{
+			$this->Link_ID->Close();
+		}
+
+		/**
+		 * Utilizado para substituir "\\" e "'" nos campos passados como parametro.
+		 * @param mixed (string ou array)
+		 * @return mixed (string ou array)
+		 * @access public
+		 */
+		function quote($fields){
+		    if (is_array($fields)) {
+		        foreach($fields as $key => $value) {
+					$fields[$key] = str_replace("\\", "\\\\\\\\", str_replace("'", "''", $value));
+		        }
+		    } elseif (is_string($fields)){
+				$fields = str_replace("\\", "\\\\\\\\", str_replace("'", "''", $fields));
+		    }
+		    return $fields;
+		}
+
+		/**
+		 * Utilizado para escapar alguns caracteres de valores do tipo bytea (blob).
+		 * @param string $byteaValue Variável com conteúdo binário
+		 * @return string Valor com os caracteres já escapados
+		 * @access public
+		 */
+		function escapeBytea($byteaValue)
+		{
+			return str_replace(array(chr(92), chr(0), chr(39)), array('\134', '\000', '\047'), $byteaValue);
+		}
+
+		/**
+		 * Utilizado para executar queries com possibilidade de fazer bind dos valores.
+		 * @param string $sqlStatement Comando SQL
+		 * @param array $inputArray Array, seqüencial, com os valores que serão associados à query
+		 * @return mixed ResultSet em caso de sucesso ou false/null caso contrário
+		 * @access public
+		 */
+		function query($sqlStatement, $inputArray = false)
+		{
+			if (!is_array($inputArray))
+				return parent::query($sqlStatement);
+
+			if (!$this->Link_ID && !$this->connect())
+				return false;
+			return $this->Link_ID->query($sqlStatement, $inputArray);
+		}
+
+		/**
+		 * Utilizado para executar queries retornando apenas algumas tuplas
+		 * @param string $sqlStatement Comando SQL
+		 * @param int $offset Indica a primeira tupla que será retornada da consulta
+		 * @param int $line A linha do arquivo de código que está executando esta chamada. Normalmente, utiliza-se a variável mágica __LINE__
+		 * @param string $file O arquivo de código que está fazendo a chamada. Normalmente, utiliza-se a variável mágica __FILE__
+		 * @param int $numRows O número de tuplas que serão retornadas
+		 * @return mixed ResultSet em caso de sucesso ou false/null caso contrário
+		 * @access public
+		 */
+		function limit_query($sqlStatement, $offset, $line = '', $file = '', $numRows = '')
+		{
+			return parent::query($sqlStatement, $line, $file, $offset, $numRows);
+		}
+
+		/**
+		 * Inicia uma transação
+		 * @return void
+		 * @access public
+		 */
+		function startTrans()
+		{
+			$this->Link_ID->StartTrans();
+		}
+
+		/**
+		 * Finaliza uma transação. Quando $autoComplete é igual a true (valor padrão), é feito um commit se não forem encontrados erros SQL durante a transação e rollback caso ocorra erro.
+		 * @param bool $autoComplete Se true (padrão), executa commit quando nenhum erro é encontrado e rollback caso contrário. Se seu valor for false, mesmo que não ocorram erros, o rollback é executado.
+		 * @return bool True em caso de commit ou false em caso de rollback
+		 * @access public
+		 */
+		function completeTrans($autoComplete = true)
+		{
+			return $this->Link_ID->CompleteTrans($autoComplete);
+		}
+
+		/**
+		 * Indica a ocorrência de uma falha na transação (necessariamente, não executa o rollback)
+		 * @return void
+		 * @access public
+		 */
+		function failTrans()
+		{
+			$this->Link_ID->FailTrans();
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_acl.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_acl.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_acl.inc.php	(revision 2372)
@@ -0,0 +1,37 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+require_once 'class.so_adminaccess.inc.php';
+
+/**
+ * Implementa métodos para checar direitos de acesso ao workflow
+ *
+ * @package Workflow
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+*/
+class workflow_acl extends so_adminaccess
+{
+	/**
+	* Construtor da classe workflow_acl
+	* @return object
+	* @access public
+	*/
+	function workflow_acl()
+	{
+		parent::so_adminaccess(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+	}
+
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.utils.url.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.utils.url.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.utils.url.php	(revision 795)
@@ -0,0 +1,413 @@
+<?php
+require_once('class.utils.php');
+/**
+ * Contains useful methods for URL building and handling
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @author Marcos Pont
+ * @version 1.0
+ * @link http://workflow.celepar.parana/doc-workflow/classes/urlutils Complete reference
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class UrlUtils extends Utils
+{
+	/**
+	 * @var string $protocol
+	 * @access public
+	 */
+	var $protocol;
+	
+	/**
+	 * @var string $auth
+	 * @access public
+	 */
+	var $auth;
+			
+	/**
+	 * @var string $user
+	 * @access public
+	 */
+	var $user;
+	
+	/**
+	 * @var string $pass
+	 * @access public
+	 */		
+	var $pass;		
+	
+	/**
+	 * @var string $host
+	 * @access public
+	 */
+	var $host;		
+	
+	/**
+	 * @var string $port
+	 * @access public
+	 */
+	var $port;
+			
+	/**
+	 * @var string $path
+	 * @access public
+	 */
+	var $path;
+	
+	/**
+	 * @var string $file
+	 * @access public
+	 */		
+	var $file;
+	
+	/**
+	 * @var string $parameters
+	 * @access public
+	 */		
+	var $parameters;
+	
+	/**
+	 * @var string $fragment
+	 * @access public
+	 */
+	var $fragment;	
+
+
+	/**
+     * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function UrlUtils($url='') {		
+		if ($url != '') {
+			$this->set($url);			
+		}
+	}
+	/**
+	 * Set the current url
+	 * @param string $url
+	 * @access public
+	 */
+	function set($url) {
+		$this->_parse($url);
+	}
+	
+	/**
+	 * 
+	 * @access public
+	 */
+	function setFromCurrent() {
+		$this->set($this->uri());
+	}
+	
+	/**
+	 * Get the current protocol
+	 * @return string current protocol
+	 * @access public
+	 */
+	function getProtocol() {
+		return (isset($this->protocol) && !empty($this->protocol) ? $this->protocol : NULL);
+	}
+	
+	/**
+	 * Get the current protocol scheme
+	 * @return string
+	 * @access public
+	 */
+	function getScheme() {
+		$protocol = $this->getProtocol();
+		if (!$this->isNull($protocol))
+			return strtolower($protocol) . '://';
+		else
+			return NULL;
+	}
+	
+	/**
+	 * get current auth
+	 * @return string
+	 * @access public
+	 */
+	function getAuth() {
+		return (isset($this->auth) && !empty($this->auth) ? $this->auth : NULL);
+	}
+	/***
+	 * Return the user if is set
+	 * @access public
+	 * @return string
+	 */
+	function getUser() {
+		return (isset($this->user) && !empty($this->user) ? $this->user : NULL);
+	}
+	
+	/**
+	 * Get the password 
+	 * @access public
+	 * @return string 
+	 */
+	function getPass() {
+		return (isset($this->pass) && !empty($this->pass) ? $this->pass : NULL);
+	}
+	
+	/**
+	 * Get the host
+	 * @access public
+	 * @return string
+	 */
+	function getHost() {
+		if (!isset($this->host) || empty($this->host)) {			
+			return NULL;
+		} 			
+		if (ereg("[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", $this->host)) {
+			return gethostbyaddr($this->host);
+		} else {
+			return strtolower($this->host);
+		}
+	}
+	
+	/**
+	 * Get port
+	 * @access public
+	 * @return string
+	 */
+	function getPort() {
+		return (isset($this->port) && !empty($this->port) ? $this->port : NULL);
+	}
+	
+	/**
+	 * Get path 
+	 * @access public
+	 * @return string
+	 */
+	function getPath() {
+		return (isset($this->path) && !empty($this->path) ? $this->path : NULL);
+	}
+	/**
+	 * Get file
+	 * @access public
+	 * @return sting
+	 */
+	function getFile() {
+		return (isset($this->file) && !empty($this->file) ? $this->file : NULL);
+	}
+	/**
+	 * Get query string
+	 * @return string query string
+	 * @access public
+	 */
+	function getQueryString($prefix=FALSE) {
+		return (isset($this->parameters) && !empty($this->parameters) ? ($prefix ? '?' . $this->parameters : $this->parameters) : NULL);
+	}
+	
+	/**
+	 * Get query string array
+	 * @access public
+	 * @return array query string array
+	 */
+	function getQueryStringArray() {
+		$queryString = $this->getQueryString();
+		if (!$this->isNull($queryString)) {
+			parse_str($queryString, $result);
+			return $result;
+		}
+		return NULL;
+	}
+	
+	
+	/**
+	 * Add a parameter 
+	 * @param $name parameter name
+	 * @param $value parameter value
+	 * @access public
+	 * @return void
+	 */
+	function addParameter($name, $value) {
+		$queryString = $this->getQueryString();
+		if (!$this->isNull($queryString)) {
+			$result = '';
+			parse_str($queryString, $params);			
+			$params[$name] = $value;
+			foreach ($params as $name => $value)
+				$result .= ($result == '' ? "$name=$value" : "&$name=$value");
+			$this->parameters = $result;
+		} else {
+			$this->parameters = "$name=$value";
+		}
+	}
+	
+	/**
+	 * 
+	 * Remove parameter
+	 * @param string $name name of parameter
+	 * @return void
+	 */
+	function removeParameter($name) {
+		$query = $this->getQueryStringArray();
+		if (!$this->isNull($query)) {
+			unset($query[$name]);
+			$tmp = array();
+			foreach ($query as $k => $v)
+				$tmp[] = "$k=$v";
+			$this->parameters = implode("&", $tmp);
+		}
+	}
+	
+	
+	/**
+	 * Get fragment
+	 * @access public
+	 * @return string fragment
+	 */
+	function getFragment() {
+		return (isset($this->fragment) && !empty($this->fragment) ? $this->fragment : NULL);
+	}
+
+	/**
+	 * Get url 
+	 * @access public
+	 * @return string returns the full url  
+	 */
+	function getUrl() {
+		return sprintf("%s%s%s%s%s%s%s",
+			(isset($this->protocol) && !empty($this->protocol) ? "{$this->protocol}://" : ''),
+			(isset($this->auth) && !empty($this->auth) ? "{$this->user}:{$this->pass}@" : ''),
+			strtolower($this->host),
+			(isset($this->port) && !empty($this->port) ? ":{$this->port}" : ''),
+			$this->path,
+			(isset($this->parameters) && !empty($this->parameters) ? "?{$this->parameters}" : ''),
+			(isset($this->fragment) && !empty($this->fragment) ? "#{$this->fragment}" : '')
+		);
+	}
+	
+	/**
+	 * Get anchor
+	 * @access public  
+	 * @param $caption
+	 * 
+	 */
+	function getAnchor($caption, $statusBarText='', $cssClass='') {
+		return parent::anchor($this->getUrl(), $caption, $statusBarText, $cssClass);
+	}
+	
+	
+	/**
+	 * Reset the configuration
+	 * @access public
+	 * @return void 
+	 */
+	function reset() {
+		unset($this->protocol);
+		unset($this->auth);
+		unset($this->user);
+		unset($this->pass);
+		unset($this->host);
+		unset($this->port);
+		unset($this->path);
+		unset($this->file);
+		unset($this->parameters);
+		unset($this->fragment);
+	}
+	
+	/**
+	 * Encode the current url
+	 * 
+	 * @param string $url 
+	 * @param string $varName name of variable
+	 * @return string encoded url
+	 * @access public
+	 */
+	function encode($url=NULL, $varName='p2gvar') {
+		// utiliza como padrao a URL da classe
+		if ($this->isNull($url))
+			$url = $this->getUrl();
+		// busca a string de parametros
+		if (ereg("([^?#]+\??)?([^#]+)?(.*)", $url, $matches)) {			
+			if (!$this->isFalse($matches[2])) {
+				// codifica os parametros
+				$paramString = base64_encode(urlencode($matches[2]));
+				$returnUrl = $this->parseString($matches[1]) . $varName . '=' . $paramString . $this->parseString($matches[3]);
+			} else {
+				$returnUrl = $url;
+			}
+		}
+		return $returnUrl;
+	}
+	
+	
+	/**
+	 * Decode the current url
+	 * 
+	 * @param string $url url string
+	 * @param bool $resultAsArray result is array
+	 * @return array parameters array
+	 * @access public
+	 */
+	function decode($url=NULL, $returnAsArray=FALSE) {
+		// utiliza como padrï¿œo a URL da classe
+		if ($this->isNull($url))
+			$url = $this->getUrl();
+		// busca os parï¿œmetros codificados		
+		ereg("([^?#]+\??)?([^#]+)?(.*)", $url, $matches);
+		if (!$this->isFalse($matches[2])) {
+			parse_str($matches[2], $vars);
+			if (list(, $value) = each($vars)) {
+				// decodifica o conjunto de parï¿œmetros
+				$paramString = urldecode(base64_decode($value));
+				if ($returnAsArray) {
+					parse_str($paramString, $varsArray);
+					return $varsArray;
+				} else {
+					return $this->parseString($matches[1]) . $paramString . $this->parseString($matches[3]);
+				}
+			}			
+		}	
+		return FALSE;
+	}
+	
+	/**
+	 * Parse the currente url
+	 * @param string $url
+	 * @return void
+	 * @access public 
+	 */
+	function _parse($url) {
+        if (preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!', $url, $matches)) {
+			if (isset($matches[1]))
+				$this->protocol = $matches[2];
+			if (isset($matches[3]) && isset($matches[4])) {
+				$atPos = strpos($matches[4], '@');
+				if (!$this->isFalse($atPos)) {
+					$this->auth = $this->left($matches[4], $atPos);
+					$dotPos = strpos($this->auth, ':');
+					if (!$this->isFalse($dotPos)) {
+						$auth = explode(':', $this->auth);
+						$this->user = $auth[0];
+						$this->pass = $auth[1];
+					} else {
+						$this->user = $this->auth;
+					}
+					$matches[4] = substr($matches[4], $atPos+1);
+				}
+				$portPos = strrpos($matches[4], ':');
+				if (!$this->isFalse($portPos)) {
+					$this->port = $this->parseIntegerPositive(substr($matches[4], $portPos+1));
+					if (!$this->port) {
+						$this->port = NULL;
+					}
+				}
+				$this->host = $portPos ? $this->left($matches[4], $portPos) : $matches[4];
+			}
+			if (isset($matches[5])) {
+				$this->path = $matches[5];
+				$slashPos = strrpos(substr($this->path, 1), '/');
+				if (!$this->isFalse($slashPos)) {
+					$this->file = substr($this->path, $slashPos + 2);
+				}
+			}
+			$this->path = $matches[5] ? $matches[5] : '';
+            if (isset($matches[6]) && $matches[6] != '') 
+				$this->parameters = $matches[7];
+            if (isset($matches[8]) && $matches[8] != '') 
+				$this->fragment = $matches[9];
+        }
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_adminaccess.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_adminaccess.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_adminaccess.inc.php	(revision 2372)
@@ -0,0 +1,437 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+require_once(PHPGW_API_INC . SEP . 'common_functions.inc.php');
+
+/**
+ * Implementa métodos para administração do controle de acesso ao workflow.
+ * Controla administradores de processos e administradores de organograma
+ *
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class bo_adminaccess extends bo_ajaxinterface
+{
+	/**
+	* @var object $so Objeto para acesso à camada de dados
+	* @access public
+	*/
+	var $so;
+
+	/**
+	* Construtor
+	*
+	* @return object
+	* @access public
+	*/
+	function bo_adminaccess()
+	{
+		parent::bo_ajaxinterface();
+
+		if (!Factory::getInstance('workflow_acl')->checkWorkflowAdmin($_SESSION['phpgw_info']['workflow']['account_id']))
+			exit(serialize(array('error' => 'Você não tem permissão para executar esta operação.')));
+
+		$this->so = &Factory::getInstance('so_adminaccess', Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+	}
+
+	/**
+	* Obtém a lista de processos (consulta ao engine)
+	*
+	* @return array process data
+	* @access public
+	*/
+	function get_all_processes()
+	{
+		$proc_mng = &Factory::newInstance('ProcessManager');
+		$proc_list = $proc_mng->list_processes(0,-1,'wf_name__ASC');
+
+		$proc_data = array();
+
+		foreach($proc_list['data'] as $p)
+		{
+			$proc_data[] = array(
+				'proc_st_name' => $p['wf_name'] . ' ' . $p['wf_version'],
+				'proc_in_id'   => $p['wf_p_id']
+			);
+		}
+
+		@sort($proc_data);
+		@reset($proc_data);
+
+		return $proc_data;
+	}
+
+	/**
+	* Obtém a lista de administradores de um organograma
+	*
+	* @param array $p processo
+	* @return array ids dos admins do organograma
+	* @access public
+	*/
+	function get_organogram_admins($p)
+	{
+		$admins_id = $this->so->get_organogram_admins_id($p['org_id']);
+		return $this->so->getUserNames($admins_id);
+	}
+
+	/**
+	* Obtém a lista de administradores de um processo
+	*
+	* @param array $p processo
+	* @return array lista de administradores de um processo
+	* @access public
+	*/
+	function get_process_admins($p)
+	{
+		$admins_id = $this->so->get_process_admins_id($p['proc_id']);
+		return $this->so->getUserNames($admins_id);
+	}
+
+	/**
+	* Remove um administrador de organograma
+	*
+	* @param array $p processo
+	* @return array lista de administradores de um organograma
+	* @access public
+	*/
+	function del_organogram_admin($p)
+	{
+		$this->so->del_organogram_admin($p['org_id'],$p['admin_id']);
+        return $this->get_organogram_admins($p);
+	}
+
+	/**
+	* Remove um administrador de um processo
+	*
+	* @param array $p processo
+	* @return array lista de administradores de um processo
+	* @access public
+	*/
+	function del_process_admin($p)
+	{
+		$this->so->del_process_admin($p['proc_id'],$p['admin_id']);
+        return $this->get_process_admins($p);
+	}
+
+	/**
+	* Insere administradores de organograma
+	*
+	* @param array $p processo
+	* @return array administradores do organograma
+	* @access public
+	*/
+	function add_organogram_admins($p)
+	{
+		$ids = explode('.', str_replace('u','',$p['user_ids'] ) );
+		$this->so->add_organogram_admins($p['org_id'],$ids);
+		return $this->get_organogram_admins($p);
+	}
+
+	/**
+	* Insere administradores de processo
+	*
+	* @param array $p processo
+	* @return array administradores do processo
+	* @access public
+	*/
+	function add_process_admins($p)
+	{
+		$ids = explode('.', str_replace('g', '', str_replace('u','',$p['user_ids'])));
+		$this->so->add_process_admins($p['proc_id'],$ids);
+		return $this->get_process_admins($p);
+	}
+    /**
+	* Retorna os monitores do processo
+	*
+	* @param array $p processo
+	* @return array monitores do processo
+	* @access public
+	*/
+	function get_monitor_admins($p)
+	{
+		$admins_id = $this->so->getResourceAdmins('MON', $p['proc_id']);
+		return $this->so->getUserNames($admins_id);
+	}
+    /**
+	* Adiciona monitores do processo
+	*
+	* @param array $p processo
+	* @return array monitores do processo
+	* @access public
+	*/
+	function add_monitor_admins($p)
+	{
+		$ids = explode('.', str_replace('u','',$p['user_ids'] ) );
+		$this->so->addAdmin('MON', $ids, $p['proc_id']);
+		return $this->get_monitor_admins($p);
+	}
+	/**
+	* Remove monitores do processo
+	*
+	* @param array $p
+	* @return array monitores do processo
+	* @access public
+	*/
+	function del_monitor_admin($p)
+	{
+		$this->so->removeAdmin('MON', $p['admin_id'], $p['proc_id']);
+        return $this->get_monitor_admins($p);
+	}
+
+	/**
+	* Retorna o nivel administrativo do monitor do processo
+	*
+	* @param array $p processo
+	* @return array o nivel administrativo do monitor do processo
+	* @access public
+	*/
+	function get_monitor_admin_level($p)
+	{
+		return $this->so->getUserAdminLevel('MON', $p['uid'], $p['pid']);
+	}
+	/**
+	* Seta o nivel administrativo do monitor
+	*
+	* @param array $p processo
+	* @return arraym
+	* @access public
+	*/
+	function set_monitor_admin_level($p)
+	{
+		$np = explode('_', $p['np']);
+		$levels = array();
+		foreach ($np as $pair)
+		{
+			list($key, $value) = explode('=', $pair, 2);
+			$levels[$key] = ($value == '1') ? true : false;
+		}
+
+		$this->so->setAdminLevel('MON', $p['uid'], $p['pid'], $levels);
+		return null;
+	}
+
+	/**
+	* Busca os usuários/grupos que possuem acesso a uma determinada aplicação externa
+	*
+	* @param array $params Lista de parâmetros vindas do Ajax
+	* @return array lista dos usuarios com direito de accesso
+	* @access public
+	*/
+	function getExternalApplicationAdmins($params)
+	{
+		$admins_id = $this->so->getResourceAdmins('APX', $params['external_application_id']);
+		return $this->so->getUserNames($admins_id);
+	}
+
+	/**
+	* Remove o acesso de um usuário/grupo a uma aplicação externa
+	*
+	* @param array $params Lista de parâmetros vindas do Ajax
+	* @return array lista de administradores de uma aplicacao externa
+	* @access public
+	*/
+	function deleteExternalApplicationAdmin($params)
+	{
+		$this->so->removeAdmin('APX', $params['admin_id'], $params['external_application_id']);
+        return $this->getExternalApplicationAdmins($params);
+	}
+
+	/**
+	* Dá acesso para um usuário/grupo a uma aplicação externa
+	*
+	* @param array $params Lista de parâmetros vindas do Ajax
+	* @return array lista de administradores de uma aplicacao externa
+	* @access public
+	*/
+	function addExternalApplicationAdmins($params)
+	{
+		$ids = explode('.', str_replace('g', '', str_replace('u', '', $params['user_ids'])));
+		$this->so->addAdmin('APX', $ids, $params['external_application_id']);
+		return $this->getExternalApplicationAdmins($params);
+	}
+
+	/**
+	* Busca os usuários/grupos que podem administrar o módulo Workflow
+	*
+	* @param array $params Lista de parâmetros advindos do Ajax
+	* @return array Lista dos usuários com direito de administrar o módulo Workflow
+	* @access public
+	*/
+	function getWorkflowAdministrators()
+	{
+		$admins_id = $this->so->getResourceAdmins('ADM', 0);
+		return $this->so->getUserNames($admins_id);
+	}
+
+	/**
+	* Dá privilégio de administrar o módulo Workflow para um usuário/grupo
+	*
+	* @param array $params Lista de parâmetros advindos do Ajax
+	* @return array Lista dos usuários com direito de administrar o módulo Workflow
+	* @access public
+	*/
+	function addWorkflowAdministrators($params)
+	{
+		$ids = explode('.', str_replace('g', '', str_replace('u', '', $params['user_ids'])));
+		$this->so->addAdmin('ADM', $ids, 0);
+		return $this->getWorkflowAdministrators($params);
+	}
+
+	/**
+	* Remove o privilégio de administrar o módulo Workflow de um usuário/grupo
+	*
+	* @param array $params Lista de parâmetros advindos do Ajax
+	* @return array Lista dos usuários com direito de administrar o módulo Workflow
+	* @access public
+	*/
+	function deleteWorkflowAdministrators($params)
+	{
+		$this->so->removeAdmin('ADM', $params['admin_id'], 0);
+        return $this->getWorkflowAdministrators($params);
+	}
+
+	/**
+	* Busca os usuários/grupos que podem criar/administrar processos de Workflow
+	*
+	* @param array $params Lista de parâmetros vindas do Ajax
+	* @return array Lista dos usuarios com direito de criar/administrar processos
+	* @access public
+	*/
+	function getDevelopmentAdministrators()
+	{
+		$GLOBALS['phpgw']->db = $GLOBALS['ajax']->db;
+		$acl = &Factory::getInstance('acl');
+		$output = $this->so->getUserNames($acl->get_ids_for_location('admin_workflow', 1, 'workflow'));
+		unset($GLOBALS['phpgw']->db);
+		return $output;
+	}
+
+	/**
+	* Dá privilégio de criar/administrar processos de Workflow para um usuário/grupo
+	*
+	* @param array $params Lista de parâmetros vindas do Ajax
+	* @return array lista dos usuarios com direito de criar/administrar processos
+	* @access public
+	*/
+	function addDevelopmentAdministrators($params)
+	{
+		$ids = explode('.', str_replace('g', '', str_replace('u', '', $params['user_ids'])));
+		$GLOBALS['phpgw']->db = $GLOBALS['ajax']->db;
+		$acl = &Factory::getInstance('acl');
+		foreach ($ids as $id)
+			$acl->add_repository('workflow', 'admin_workflow', $id, 1);
+
+		unset($GLOBALS['phpgw']->db);
+		return $this->getDevelopmentAdministrators($params);
+	}
+
+	/**
+	* Remove o privilégio de criar/administrar processos de Workflow de um usuário/grupo
+	*
+	* @param array $params Lista de parâmetros vindas do Ajax
+	* @return array Lista dos usuarios com direito de criar/administrar processos
+	* @access public
+	*/
+	function deleteDevelopmentAdministrators($params)
+	{
+		$GLOBALS['phpgw']->db = $GLOBALS['ajax']->db;
+		$acl = &Factory::getInstance('acl');
+		$acl->delete_repository('workflow', 'admin_workflow', (int) $params['admin_id']);
+		unset($GLOBALS['phpgw']->db);
+
+		return $this->getDevelopmentAdministrators($params);
+	}
+
+	/**
+	* Retorna os recursos disponiveis ao Administrador
+	*
+	* @param string $type type of resource
+	* @param integer $rid resource id
+	* @return array array de recursos permitidos
+	* @access public
+	*/
+	function getResourceAdmins($type, $rid)
+	{
+		return $this->so->getResourceAdmins($type, $rid);
+	}
+
+	/**
+	* Verifica se o usuario tem acesso a um tipo de recurso
+	*
+	* @param string $type type of resource
+	* @param integer $uid user id
+	* @return bool accesso permitido false nao
+	* @access public
+	*/
+	function checkUserAccessToType($type, $uid)
+	{
+		return $this->so->checkUserAccessToType($type, $uid);
+	}
+
+	/**
+	* Verifica se o usuário tem direito de acesso a um recurso
+	*
+	* @param string $type tipo de recurso
+	* @param integer $uid id do usuário
+	* @param integer $rid id do recurso
+	* @return bool true accesso permitido false nao
+	* @access public
+	*/
+	function checkUserAccessToResource($type, $uid, $rid, $requiredLevel = null)
+	{
+		return $this->so->checkUserAccessToResource($type, $uid, $rid, $requiredLevel);
+	}
+
+	/**
+	* Retorna as permissoes do usúario
+	*
+	* @param string $type tipo do usuario
+	* @param integer $uid id do usuário
+	* @param integer $rid id do recurso
+	* @return array array com as permissoes do usuario
+	* @access public
+	*/
+	function getUserPermissions($type, $uid)
+	{
+		return $this->so->getUserPermissions($type, $uid);
+	}
+
+	/**
+	* Informa o nível de administração do usuário
+	* @param string $type O tipo do recurso
+	* @param int $uid O ID do usuário
+	* @param int $numvalue O ID do recurso
+	* @return array As permissões do usuário (em forma de número e de bits)
+	* @access public
+	*/
+	function getUserAdminLevel($type, $uid, $rid)
+	{
+		return $this->so->getUserAdminLevel($type, $uid, $rid);
+	}
+
+	/**
+	* Informa o nível de administração do usuário (incluindo herança por grupo)
+	* @param string $type O tipo do recurso
+	* @param int $uid O ID do usuário
+	* @param int $numvalue O ID do recurso
+	* @return array As permissões do usuário, inclusive herança por grupo. As permissões são retornadas em forma de número e de bits
+	* @access public
+	*/
+	function getUserGroupAdminLevel($type, $uid, $numvalue)
+	{
+		return $this->so->getUserGroupAdminLevel($type, $uid, $rid);
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.powergraphic.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.powergraphic.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.powergraphic.inc.php	(revision 2372)
@@ -0,0 +1,1363 @@
+<?php
+/**
+*
+*   PowerGraphic
+*   version 1.0
+*
+*
+*
+* Author: Carlos Reche
+* Author: Sidnei Augusto Drovetto Junior (revision) Apr 30, 2007
+* E-mail: carlosreche@yahoo.com
+* Sorocaba, SP - Brazil
+*
+* Created: Sep 20, 2004
+* Last Modification: Sep 20, 2004
+*
+*
+*
+*  Authors' comments:
+*
+*  PowerGraphic creates 6 different types of graphics with how many parameters you want. You can
+*  change the appearance of the graphics in 3 different skins, and you can still cross data from 2 
+*  graphics in only 1! It's a powerful script, and I recommend you read all the instructions 
+*  to learn how to use all of this features. Don't worry, it's very simple to use it.
+*
+*  This script is free. Please keep the credits.
+*
+*/
+
+/**
+
+   INSTRUNCTIONS OF HOW TO USE THIS SCRIPT  (Please, take a minute to read it. It's important!)
+
+
+   NOTE: make sure that your PHP is compiled to work with GD Lib.
+
+   NOTE: You may create test images using a form that comes with this script. Just add a "showform" 
+   as a query string. (Example: "graphic.php?showform")
+
+
+   PowerGraphic works with query strings (information sent after the "?" of an URL). Here is an 
+   example of how you will have to send the graphic information. Let's suppose that you want to 
+   show a graphic of your user's sex:
+
+       <img src="graphic.php?title=Sex&type=5&x1=male&y1=50&x2=female&y2=55" />
+
+   This will create a pie graphic (set by type=5) with title as "Sex" and default skin. 
+   Let's see the other parameters:
+
+       x1 = male
+       y1 = 50 (quantity of males)
+       x2 = female
+       y2 = 55 (quantity of females)
+
+   See how it's simple! :)
+   For those who don't know, to create a query string you have to put an "?" at the end of the URL and join
+   the parameters with "&". Example: "graphic.php?Parameter_1=Value_1&Parameter_2=Value_2" (and so on). You 
+   can set how many parameters you want.
+
+   The boring step would be to create this query string. Well, "would be", if I didn't create a function to do that. :)
+   Let's see an example of how you can use this function in a PHP document:
+
+
+///// START OF EXAMPLE /////
+
+<?php
+
+require "class.graphics.php";
+$PG = new PowerGraphic;
+
+$PG->title = "Sex";
+$PG->type  = "5";
+$PG->x[0]  = "male";
+$PG->y[0]  = "50";
+$PG->x[1]  = "female";
+$PG->y[1]  = "55";
+
+echo '<img src="graphic.php?' . $PG->create_query_string() . '" />';
+
+
+// If you're going to create more than 1 graphic, it'll be important to reset the values before 
+// create the next query string:
+$PG->reset_values();
+
+?>
+
+///// END OF EXAMPLE /////
+
+
+
+   Here is a list of all parameters you may set:
+
+   title      =>  Title of the graphic
+   axis_x     =>  Name of values from Axis X
+   axis_y     =>  Name of values from Axis Y
+   graphic_1  =>  Name of Graphic_1 (only shown if you are gonna cross data from 2 different graphics)
+   graphic_2  =>  Name of Graphic_2 (same comment of above)
+
+   type  =>  Type of graphic (values 1 to 6)
+                1 => Vertical bars (default)
+                2 => Horizontal bars
+                3 => Dots
+                4 => Lines
+                5 => Pie
+                6 => Donut
+
+   skin   => Skin of the graphic (values 1 to 3)
+                1 => Office (default)
+                2 => Matrix
+                3 => Spring
+
+   credits => Only if you want to show my credits in the image. :)
+                0 => doesn't show (default)
+                1 => shows
+
+   x[0]  =>  Name of the first parameter in Axis X
+   x[1]  =>  Name of the second parameter in Axis X
+   ... (etc)
+
+   y[0]  =>  Value from "graphic_1" relative for "x[0]"
+   y[1]  =>  Value from "graphic_1" relative for "x[1]"
+   ... (etc)
+
+   z[0]  =>  Value from "graphic_2" relative for "x[0]"
+   z[1]  =>  Value from "graphic_2" relative for "x[1]"
+   ... (etc)
+
+   NOTE: You can't cross data between graphics if you use "pie" or "donut" graphic. Values for "z"
+   won't be considerated.
+
+   That's all! Hope you make a good use of it!
+   It would be nice to receive feedback from others users. All comments are welcome!
+
+   Regards,
+
+   Carlos Reche
+
+*/
+
+
+require_once 'common.inc.php';
+
+$PowerGraphic = &Factory::newInstance('powergraphic');
+
+$PowerGraphic->start();
+
+
+class powergraphic 
+{
+	/**
+	 * @var float $x coordenate
+	 * @access public 
+ 	 */
+    var $x;
+    /**
+	 * @var float $y y coordenate
+	 * @access public 
+ 	 */
+    var $y; 
+    /**
+	 * @var float $z z coordenate
+	 * @access public 
+ 	 */
+    var $z;
+    /**
+	 * @var string $title 
+	 * @access public 
+ 	 */
+    var $title;
+    
+    /**
+     * @var float $axis_x
+     * @access public 
+     */
+    var $axis_x;
+    
+    /**
+     * @var float $axis_y
+     * @access public
+     */
+    var $axis_y;
+    
+    /**
+     * @var $graphic_1
+     * @access public
+     */
+    var $graphic_1;
+    
+    /**
+     * @var $graphic_2
+     * @access public 
+     */
+    var $graphic_2;
+    
+    /**
+     * @var string $type
+     * @access public
+     */
+    var $type;
+    
+    /**
+     * @var string $skin
+     * @access public
+     */
+    var $skin;
+    
+    /**
+     * @var $credits
+     * @access public
+     */
+    var $credits;
+    
+    /**
+     * @var $latin_notation
+     * @access public
+     */
+    var $latin_notation;
+
+	/**
+	 * @var int $width
+	 * @access public
+	 */
+    var $width;
+    
+    /**
+	 * @var float $height
+	 * @access public
+	 */
+    var $height;
+    
+    /**
+     * @var float $height_title
+     * @access public
+     */
+    var $height_title;
+    
+    /**
+     * @var float $alternate_x
+     * @access public
+     */
+    var $alternate_x;
+    
+	/**
+	 * @var float $total_parameters
+     * @access public
+     */
+    var $total_parameters;
+    
+    /**
+     * @var float $sum_total
+     * @access public
+     */
+    var $sum_total;
+    
+    /**
+     * @var float $biggest_value
+     * @access public
+     */
+    var $biggest_value;
+    
+    /**
+     * @var float $biggest_parameter
+     * @access public
+     */
+    var $biggest_parameter;
+    
+    /**
+     * @var array $available_types
+     * @access public
+     */
+    var $available_types;
+
+	/**
+	 * Constructor of class powergraphic
+	 * @access public
+	 * @return object
+	 */
+    function powergraphic()
+    {
+        $this->x = $this->y = $this->z = array();
+
+        $this->biggest_x        = NULL;
+        $this->biggest_y        = NULL;
+        
+        $this->alternate_x      = false;
+        $this->graphic_2_exists = false;
+        $this->total_parameters = 0;
+        $this->sum_total        = 1;
+
+        $this->title     = (isset($_GET['title']))     ? $_GET['title']     : "";
+        $this->axis_x    = (isset($_GET['axis_x']))    ? $_GET['axis_x']    : "";
+        $this->axis_y    = (isset($_GET['axis_y']))    ? $_GET['axis_y']    : "";
+        $this->graphic_1 = (isset($_GET['graphic_1'])) ? $_GET['graphic_1'] : "";
+        $this->graphic_2 = (isset($_GET['graphic_2'])) ? $_GET['graphic_2'] : "";
+        $this->type      = (isset($_GET['type']))      ? $_GET['type']      : 1;
+        $this->skin      = (isset($_GET['skin']))      ? $_GET['skin']      : 1;
+        $this->credits        = ((isset($_GET['credits'])) && ($_GET['credits'] == 1))               ? true : false;
+        $this->latin_notation = ((isset($_GET['latin_notation'])) && ($_GET['latin_notation'] == 1)) ? true : false;
+
+        $this->legend_exists        = (ereg("(5|6)", $this->type)) ? true : false;
+        $this->biggest_graphic_name = (strlen($this->graphic_1) > strlen($this->graphic_2)) ? $this->graphic_1 : $this->graphic_2;
+        $this->height_title         = (!empty($this->title)) ? ($this->string_height(5) + 15) : 0;
+        $this->space_between_bars   = ($this->type == 1) ? 40 : 30;
+        $this->space_between_dots   = 40;
+        $this->higher_value         = 0;
+        $this->higher_value_str     = 0;
+
+        $this->width               = 0;
+        $this->height              = 0;
+        $this->graphic_area_width  = 0;
+        $this->graphic_area_height = 0;
+        $this->graphic_area_x1     = 30;
+        $this->graphic_area_y1     = 20 + $this->height_title;
+        $this->graphic_area_x2     = $this->graphic_area_x1 + $this->graphic_area_width;
+        $this->graphic_area_y2     = $this->graphic_area_y1 + $this->graphic_area_height;
+
+        $this->available_types = array(
+            1 => 'Vertical Bars',
+            2 => 'Horizontal Bars',
+            3 => 'Dots',
+            4 => 'Lines',
+            5 => 'Pie',
+            6 => 'Donut',
+        );
+        $this->available_skins = array(
+            1 => 'Office',
+            2 => 'Matrix',
+            3 => 'Spring',
+        );
+    }
+
+
+	/**
+	 * Start the create of graphic 
+	 * @access public
+	 * @return bool
+	 */
+    function start()
+    {
+        if ( (!isset($_GET['x0'])) || (!isset($_GET['y0'])) )
+        {
+            if ($_SERVER['QUERY_STRING'] == 'showform')
+            {
+                $this->html();
+            }
+            return false;
+        }
+
+        // Defines array $temp
+        foreach ($_GET as $parameter => $value)
+        {
+            if (preg_match("/^x\d+$/i", $parameter))
+            {
+                if (strtolower($parameter{0}) == 'x')
+                {
+                    if (empty($value))
+                    {
+                        continue;
+                    }
+
+                    if (strlen($value) > strlen($this->biggest_x))
+                    {
+                        $this->biggest_x = $value;
+                    }
+
+                    $num        = substr($parameter, 1, (strlen($parameter)-1) );
+                    $temp[$num] = $value;
+
+                    if ((!empty($_GET['z'.$num])) && (ereg("(1|2|3|4)", $this->type)))
+                    {
+                        $this->graphic_2_exists = true;
+                    }
+                }
+            }
+        }
+
+        $i = 0;
+
+        // Defines arrays $this->x, $this->y and $this->z (if exists)
+        foreach ($temp as $index => $parameter)
+        {
+            $this->x[$i] = $parameter;
+            $this->y[$i] = 0;
+
+            if (!empty($_GET['y'.$index]))
+            {
+                $this->y[$i] = $_GET['y'.$index];
+
+                if ($_GET['y'.$index] > $this->biggest_y)
+                {
+                    $this->biggest_y = number_format(round($_GET['y'.$index], 1), 1, ".", "");
+                }
+            }
+
+            if ($this->graphic_2_exists)
+            {
+                $value       = (!empty($_GET['z'.$index])) ? $_GET['z'.$index] : 0;
+                $this->z[$i] = $value;
+
+                if ($value > $this->biggest_y)
+                {
+                    $this->biggest_y = number_format(round($value, 1), 1, ".", "");
+                }
+            }
+
+            unset($temp[$index]);
+            $i++;
+        }
+
+        if (($this->graphic_2_exists == true)  &&  ((!empty($this->graphic_1)) || (!empty($this->graphic_2))))
+        {
+            $this->legend_exists = true;
+        }
+
+
+        $this->total_parameters    = count($this->x);
+        $this->sum_total           = array_sum($this->y);
+        $this->space_between_bars += ($this->graphic_2_exists == true) ? 10 : 0;
+
+        $this->calculate_higher_value();
+        $this->calculate_width();
+        $this->calculate_height();
+
+        $this->create_graphic();
+    }
+
+
+	/**
+	 * Create and draw a graphic
+	 * @access public
+	 * @return void
+	 */
+    function create_graphic()
+    {
+        $this->img = imagecreatetruecolor($this->width, $this->height);
+
+        $this->load_color_palette();
+
+        // Fill background
+        imagefill($this->img, 0, 0, $this->color['background']);
+
+        // Draw title
+        if (!empty($this->title))
+        {
+            $center = ($this->width / 2) - ($this->string_width($this->title, 5) / 2);
+            imagestring($this->img, 5, $center, 10, $this->title, $this->color['title']);
+        }
+
+
+        // Draw axis and background lines for "vertical bars", "dots" and "lines"
+        if (ereg("^(1|3|4)$", $this->type))
+        {
+            if ($this->legend_exists == true)
+            {
+                $this->draw_legend();
+            }
+
+            $higher_value_y    = $this->graphic_area_y1 + (0.1 * $this->graphic_area_height);
+            $higher_value_size = 0.9 * $this->graphic_area_height;
+
+            $less  = 7 * strlen($this->higher_value_str);
+
+            imageline($this->img, $this->graphic_area_x1, $higher_value_y, $this->graphic_area_x2, $higher_value_y, $this->color['bg_lines']);
+            imagestring($this->img, 3, ($this->graphic_area_x1-$less-7), ($higher_value_y-7), $this->higher_value_str, $this->color['axis_values']);
+
+            for ($i = 1; $i < 10; $i++)
+            {
+                $dec_y = $i * ($higher_value_size / 10);
+                $x1 = $this->graphic_area_x1;
+                $y1 = $this->graphic_area_y2 - $dec_y;
+                $x2 = $this->graphic_area_x2;
+                $y2 = $this->graphic_area_y2 - $dec_y;
+
+                imageline($this->img, $x1, $y1, $x2, $y2, $this->color['bg_lines']);
+                if ($i % 2 == 0) {
+                    $value = $this->number_formated($this->higher_value * $i / 10);
+                    $less = 7 * strlen($value);
+                    imagestring($this->img, 3, ($x1-$less-7), ($y2-7), $value, $this->color['axis_values']);
+                }
+            }
+
+            // Axis X
+            imagestring($this->img, 3, $this->graphic_area_x2+10, $this->graphic_area_y2+3, $this->axis_x, $this->color['title']);
+            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
+            // Axis Y
+            imagestring($this->img, 3, 20, $this->graphic_area_y1-20, $this->axis_y, $this->color['title']);
+            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
+        }
+
+
+        // Draw axis and background lines for "horizontal bars"
+        else if ($this->type == 2)
+        {
+            if ($this->legend_exists == true)
+            {
+                $this->draw_legend();
+            }
+
+            $higher_value_x    = $this->graphic_area_x2 - (0.2 * $this->graphic_area_width);
+            $higher_value_size = 0.8 * $this->graphic_area_width;
+
+            imageline($this->img, ($this->graphic_area_x1+$higher_value_size), $this->graphic_area_y1, ($this->graphic_area_x1+$higher_value_size), $this->graphic_area_y2, $this->color['bg_lines']);
+            imagestring($this->img, 3, (($this->graphic_area_x1+$higher_value_size) - ($this->string_width($this->higher_value, 3)/2)), ($this->graphic_area_y2+2), $this->higher_value_str, $this->color['axis_values']);
+
+            for ($i = 1, $alt = 15; $i < 10; $i++)
+            {
+                $dec_x = number_format(round($i * ($higher_value_size  / 10), 1), 1, ".", "");
+
+                imageline($this->img, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y1, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y2, $this->color['bg_lines']);
+                if ($i % 2 == 0) {
+                    $alt   = (strlen($this->biggest_y) > 4 && $alt != 15) ? 15 : 2;
+                    $value = $this->number_formated($this->higher_value * $i / 10);
+                    imagestring($this->img, 3, (($this->graphic_area_x1+$dec_x) - ($this->string_width($this->higher_value, 3)/2)), ($this->graphic_area_y2+$alt), $value, $this->color['axis_values']);
+                }
+            }
+
+            // Axis X
+            imagestring($this->img, 3, ($this->graphic_area_x2+10), ($this->graphic_area_y2+3), $this->axis_y, $this->color['title']);
+            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
+            // Axis Y
+            imagestring($this->img, 3, 20, ($this->graphic_area_y1-20), $this->axis_x, $this->color['title']);
+            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
+        }
+
+
+        // Draw legend box for "pie" or "donut"
+        else if (ereg("^(5|6)$", $this->type))
+        {
+            $this->draw_legend();
+        }
+
+
+
+        /**
+        * Draw graphic: VERTICAL BARS
+        */
+        if ($this->type == 1)
+        {
+            $num = 1;
+            $x   = $this->graphic_area_x1 + 20;
+
+            foreach ($this->x as $i => $parameter)
+            {
+                if (isset($this->z[$i])) {
+                    $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
+                    $x1   = $x + 10;
+                    $y1   = ($this->graphic_area_y2 - $size) + 1;
+                    $x2   = $x1 + 20;
+                    $y2   = $this->graphic_area_y2 - 1;
+                    imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_2_shadow']);
+                    imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_2_shadow']);
+                    imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_2_shadow']);
+                    imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
+                }
+
+                $size = round($this->y[$i] * $higher_value_size / $this->higher_value);
+                $alt  = (($num % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
+                $x1   = $x;
+                $y1   = ($this->graphic_area_y2 - $size) + 1;
+                $x2   = $x1 + 20;
+                $y2   = $this->graphic_area_y2 - 1;
+                $x   += $this->space_between_bars;
+                $num++;
+
+                imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_shadow']);
+                imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_shadow']);
+                imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_shadow']);
+                imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
+                imagestring($this->img, 3, ((($x1+$x2)/2) - (strlen($parameter)*7/2)), ($y2+$alt+2), $parameter, $this->color['axis_values']);
+            }
+        }
+
+
+        /**
+        * Draw graphic: HORIZONTAL BARS
+        */
+        else if ($this->type == 2)
+        {
+            $y = 10;
+
+            foreach ($this->x as $i => $parameter)
+            {
+                if (isset($this->z[$i])) {
+                    $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
+                    $x1   = $this->graphic_area_x1 + 1;
+                    $y1   = $this->graphic_area_y1 + $y + 10;
+                    $x2   = $x1 + $size;
+                    $y2   = $y1 + 15;
+                    imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_2_shadow']);
+                    imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_2_shadow']);
+                    imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_2_shadow']);
+                    imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
+                    imagestring($this->img, 3, ($x2+7), ($y1+7), $this->number_formated($this->z[$i], 2), $this->color['bars_2_shadow']);
+                }
+
+                $size = round(($this->y[$i] / $this->higher_value) * $higher_value_size);
+                $x1   = $this->graphic_area_x1 + 1;
+                $y1   = $this->graphic_area_y1 + $y;
+                $x2   = $x1 + $size;
+                $y2   = $y1 + 15;
+                $y   += $this->space_between_bars;
+
+                imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_shadow']);
+                imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_shadow']);
+                imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_shadow']);
+                imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
+                imagestring($this->img, 3, ($x2+7), ($y1+2), $this->number_formated($this->y[$i], 2), $this->color['bars_shadow']);
+
+                imagestring($this->img, 3, ($x1 - ((strlen($parameter)*7)+7)), ($y1+2), $parameter, $this->color['axis_values']);
+            }
+        }
+
+
+        /**
+        * Draw graphic: DOTS or LINE
+        */
+        else if (ereg("^(3|4)$", $this->type))
+        {
+
+            $x[0] = $this->graphic_area_x1+1;
+
+            foreach ($this->x as $i => $parameter)
+            {
+                if ($this->graphic_2_exists == true) {
+                    $size  = round($this->z[$i] * $higher_value_size / $this->higher_value);
+                    $z[$i] = $this->graphic_area_y2 - $size;
+                }
+
+                $alt   = (($i % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
+                $size  = round($this->y[$i] * $higher_value_size / $this->higher_value);
+                $y[$i] = $this->graphic_area_y2 - $size;
+
+                if ($i != 0) {
+                    imageline($this->img, $x[$i], ($this->graphic_area_y1+10), $x[$i], ($this->graphic_area_y2-1), $this->color['bg_lines']);
+                }
+                imagestring($this->img, 3, ($x[$i] - (strlen($parameter)*7/2 )), ($this->graphic_area_y2+$alt+2), $parameter, $this->color['axis_values']);
+
+                $x[$i+1] = $x[$i] + 40;
+            }
+
+            foreach ($x as $i => $value_x)
+            {
+                if ($this->graphic_2_exists == true)
+                {
+                    if (isset($z[$i+1])) {
+                        // Draw lines
+                        if ($this->type == 4)
+                        {
+                            imageline($this->img, $x[$i], $z[$i], $x[$i+1], $z[$i+1], $this->color['line_2']);
+                            imageline($this->img, $x[$i], ($z[$i]+1), $x[$i+1], ($z[$i+1]+1), $this->color['line_2']);
+                        }
+                        imagefilledrectangle($this->img, $x[$i]-1, $z[$i]-1, $x[$i]+2, $z[$i]+2, $this->color['line_2']);
+                    }
+                    else { // Draw last dot
+                        imagefilledrectangle($this->img, $x[$i-1]-1, $z[$i-1]-1, $x[$i-1]+2, $z[$i-1]+2, $this->color['line_2']);
+                    }
+                }
+
+                if (count($y) > 1)
+                {
+                    if (isset($y[$i+1])) {
+                        // Draw lines
+                        if ($this->type == 4)
+                        {
+                            imageline($this->img, $x[$i], $y[$i], $x[$i+1], $y[$i+1], $this->color['line']);
+                            imageline($this->img, $x[$i], ($y[$i]+1), $x[$i+1], ($y[$i+1]+1), $this->color['line']);
+                        }
+                        imagefilledrectangle($this->img, $x[$i]-1, $y[$i]-1, $x[$i]+2, $y[$i]+2, $this->color['line']);
+                    }
+                    else { // Draw last dot
+                        imagefilledrectangle($this->img, $x[$i-1]-1, $y[$i-1]-1, $x[$i-1]+2, $y[$i-1]+2, $this->color['line']);
+                    }
+                }
+
+            }
+        }
+
+
+        /**
+        * Draw graphic: PIE or DONUT
+        */
+        else if (ereg("^(5|6)$", $this->type))
+        {
+            $center_x = ($this->graphic_area_x1 + $this->graphic_area_x2) / 2;
+            $center_y = ($this->graphic_area_y1 + $this->graphic_area_y2) / 2;
+            $width    = $this->graphic_area_width;
+            $height   = $this->graphic_area_height;
+            $start    = 0;
+            $sizes    = array();
+
+            foreach ($this->x as $i => $parameter)
+            {
+                $size    = $this->y[$i] * 360 / $this->sum_total;
+                $sizes[] = $size;
+                $start  += $size;
+            }
+            $start = 270;
+
+            // Draw PIE
+            if ($this->type == 5)
+            {
+                // Draw shadow
+                foreach ($sizes as $i => $size)
+                {
+                    $num_color = $i%7 + 1;
+                    $color = 'arc_' . $num_color . '_shadow';
+
+                    for ($i = 10; $i >= 0; $i -= 1)
+                    {
+                        imagearc($this->img, $center_x, ($center_y+$i), $width, $height, $start, ($start+$size), $this->color[$color]);
+                    }
+                    $start += $size;
+                }
+
+                $start = 270;
+
+                // Draw pieces
+                foreach ($sizes as $i => $size)
+                {
+                    $num_color = $i%7 + 1;
+                    $color = 'arc_' . $num_color;
+
+                    imagefilledarc($this->img, $center_x, $center_y, ($width+2), ($height+2), $start, ($start+$size), $this->color[$color], IMG_ARC_EDGED);
+                    $start += $size;
+                }
+            }
+
+            // Draw DONUT
+            else if ($this->type == 6)
+            {
+                foreach ($sizes as $i => $size)
+                {
+                    $num_color = $i%7 + 1;
+                    $color        = 'arc_' . $num_color;
+                    $color_shadow = 'arc_' . $num_color . '_shadow';
+                    imagefilledarc($this->img, $center_x, $center_y, $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_PIE);
+                    $start += $size;
+                }
+                imagefilledarc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['background'], IMG_ARC_PIE);
+                imagearc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['bg_legend']);
+                imagearc($this->img, $center_x, $center_y, ($width+1), ($height+1), 0, 360, $this->color['bg_legend']);
+            }
+        }
+
+
+        if ($this->credits == true) {
+            $this->draw_credits();
+        }
+
+
+        header('Content-type: image/png');
+        imagepng($this->img);
+        imagedestroy($this->img);
+        exit;
+    }
+
+
+
+	/**
+	 * Calculate width of graphic elements
+	 * @access public
+	 * @return void
+	 */
+    function calculate_width()
+    {
+        switch ($this->type)
+        {
+            // Vertical bars
+            case 1:
+                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, 3) + 25) : 0;
+                $this->graphic_area_width = ($this->space_between_bars * $this->total_parameters) + 30;
+                $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), 3);
+                $this->width += $this->graphic_area_x1 + 20;
+                $this->width += ($this->legend_exists == true) ? 50 : ((7 * strlen($this->axis_x)) + 10);
+                break;
+
+            // Horizontal bars
+            case 2:
+                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, 3) + 25) : 0;
+                $this->graphic_area_width = ($this->string_width($this->higher_value_str, 3) > 50) ? (5 * ($this->string_width($this->higher_value_str, 3)) * 0.85) : 200;
+                $this->graphic_area_x1 += 7 * strlen($this->biggest_x);
+                $this->width += ($this->legend_exists == true) ? 60 : ((7 * strlen($this->axis_y)) + 30);
+                $this->width += $this->graphic_area_x1;
+                break;
+
+            // Dots
+            case 3:
+                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, 3) + 25) : 0;
+                $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
+                $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), 3);
+                $this->width += $this->graphic_area_x1 + 20;
+                $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 10);
+                break;
+
+            // Lines
+            case 4:
+                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, 3) + 25) : 0;
+                $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
+                $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), 3);
+                $this->width += $this->graphic_area_x1 + 20;
+                $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 10);
+                break;
+
+            // Pie
+            case 5:
+                $this->legend_box_width   = $this->string_width($this->biggest_x, 3) + 85;
+                $this->graphic_area_width = 200;
+                $this->width += 90;
+                break;
+
+            // Donut
+            case 6:
+                $this->legend_box_width   = $this->string_width($this->biggest_x, 3) + 85;
+                $this->graphic_area_width = 180;
+                $this->width += 90;
+                break;
+        }
+
+        $this->width += $this->graphic_area_width;
+        $this->width += $this->legend_box_width;
+
+
+        $this->graphic_area_x2 = $this->graphic_area_x1 + $this->graphic_area_width;
+        $this->legend_box_x1   = $this->graphic_area_x2 + 40;
+        $this->legend_box_x2   = $this->legend_box_x1 + $this->legend_box_width;
+    }
+
+
+	/**
+	 * Calculate height
+	 * @access public
+	 * @return void
+	 */
+    function calculate_height()
+    {
+        switch ($this->type)
+        {
+            // Vertical bars
+            case 1:
+                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
+                $this->graphic_area_height = 150;
+                $this->height += 65;
+                break;
+
+            // Horizontal bars
+            case 2:
+                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
+                $this->graphic_area_height = ($this->space_between_bars * $this->total_parameters) + 10;
+                $this->height += 65;
+                break;
+
+            // Dots
+            case 3:
+                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
+                $this->graphic_area_height = 150;
+                $this->height += 65;
+                break;
+
+            // Lines
+            case 4:
+                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
+                $this->graphic_area_height = 150;
+                $this->height += 65;
+                break;
+
+            // Pie
+            case 5:
+                $this->legend_box_height   = (!empty($this->axis_x)) ? 30 : 5;
+                $this->legend_box_height  += (14 * $this->total_parameters);
+                $this->graphic_area_height = 150;
+                $this->height += 50;
+                break;
+
+            // Donut
+            case 6:
+                $this->legend_box_height   = (!empty($this->axis_x)) ? 30 : 5;
+                $this->legend_box_height  += (14 * $this->total_parameters);
+                $this->graphic_area_height = 180;
+                $this->height += 50;
+                break;
+        }
+
+        $this->height += $this->height_title;
+        $this->height += ($this->legend_box_height > $this->graphic_area_height) ? ($this->legend_box_height - $this->graphic_area_height) : 0;
+        $this->height += $this->graphic_area_height;
+
+        $this->graphic_area_y2 = $this->graphic_area_y1 + $this->graphic_area_height;
+        $this->legend_box_y1   = $this->graphic_area_y1 + 10;
+        $this->legend_box_y2   = $this->legend_box_y1 + $this->legend_box_height;
+    }
+
+	/**
+	 * Draw the graphic legend
+	 * @access public
+	 * @return void
+	 */
+    function draw_legend()
+    {
+        $x1 = $this->legend_box_x1;
+        $y1 = $this->legend_box_y1;
+        $x2 = $this->legend_box_x2;
+        $y2 = $this->legend_box_y2;
+
+        imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bg_legend']);
+
+        $x = $x1 + 5;
+        $y = $y1 + 5;
+
+
+        // Draw legend values for VERTICAL BARS, HORIZONTAL BARS, DOTS and LINES
+        if (ereg("^(1|2|3|4)$", $this->type))
+        {
+            $color_1 = (ereg("^(1|2)$", $this->type)) ? $this->color['bars']   : $this->color['line'];
+            $color_2 = (ereg("^(1|2)$", $this->type)) ? $this->color['bars_2'] : $this->color['line_2'];
+
+            imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_1);
+            imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
+            imagestring($this->img, 3, ($x+15), ($y-2), $this->graphic_1, $this->color['axis_values']);
+            $y += 20;
+            imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_2);
+            imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
+            imagestring($this->img, 3, ($x+15), ($y-2), $this->graphic_2, $this->color['axis_values']);
+        }
+
+        // Draw legend values for PIE or DONUT
+        else if (ereg("^(5|6)$", $this->type))
+        {
+            if (!empty($this->axis_x))
+            {
+                imagestring($this->img, 3, ((($x1+$x2)/2) - (strlen($this->axis_x)*7/2)), $y, $this->axis_x, $this->color['title']);
+                $y += 25;
+            }
+
+            $num = 0;
+
+            foreach ($this->x as $i => $parameter)
+            {
+                $num = $i%7 + 1;
+                $color = 'arc_' . $num;
+
+                $percent = number_format(round(($this->y[$i] * 100 / $this->sum_total), 2), 2, ".", "") . ' %';
+                $less    = (strlen($percent) * 7);
+
+                if ($num != 1) {
+                    imageline($this->img, ($x1+15), ($y-2), ($x2-5), ($y-2), $this->color['bg_lines']);
+                }
+                imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color[$color]);
+                imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
+                imagestring($this->img, 3, ($x+15), ($y-2), $parameter, $this->color['axis_values']);
+                imagestring($this->img, 2, ($x2-$less), ($y-2), $percent, $this->color['axis_values']);
+                $y += 14;
+                $num++;
+            }
+        }
+    }
+
+	/**
+	 * Calculate the string width
+	 * @access public
+	 * @return int string width
+	 */
+    function string_width($string, $size) {
+        $single_width = $size + 4;
+        return $single_width * strlen($string);
+    }
+    
+	/**
+	 * Calculate the string height
+	 * @access public
+	 * @return int string height
+	 */
+    function string_height($size) {
+        if ($size <= 1) {
+            $height = 8;
+        } else if ($size <= 3) {
+            $height = 12;
+        } else if ($size >= 4) {
+            $height = 14;
+        }
+        return $height;
+    }
+
+	/** 
+	 * Calculate the higher value
+	 * @access public
+	 * @return void
+	 */
+    function calculate_higher_value() {
+        $digits   = strlen(round($this->biggest_y));
+        $interval = pow(10, ($digits-1));
+        $this->higher_value     = round(($this->biggest_y - ($this->biggest_y % $interval) + $interval), 1);
+        $this->higher_value_str = $this->number_formated($this->higher_value);
+    }
+
+	/**
+	 * Number formated (Float to string representation) 
+	 * @param float $number
+	 * @param int $dec_size
+	 * @access public 
+	 * @return string
+	 */
+    function number_formated($number, $dec_size = 1)
+    {
+        if ($this->latin_notation == true) {
+            return number_format(round($number, $dec_size), $dec_size, ",", ".");
+        }
+        return number_format(round($number, $dec_size), $dec_size, ".", ",");
+    }
+	
+	/**
+	 * Number float
+	 * @param string $number
+	 * @return float
+	 */
+    function number_float($number)
+    {
+        if ($this->latin_notation == true) {
+            $number = str_replace(".", "", $number);
+            return (float)str_replace(",", ".", $number);
+        }
+        return (float)str_replace(",", "", $number);
+    }
+
+	/**
+	 * Draw the credits string
+	 * @param int $number 
+	 * @return void
+	 * @access public
+	 */
+    function draw_credits() {
+        imagestring($this->img, 1, ($this->width-120), ($this->height-10), "Powered by Carlos Reche", $this->color['title']);
+    }
+
+	/**
+	 * Load color palette
+	 * @return void
+	 * @access public
+	 */
+    function load_color_palette()
+    {
+        switch ($this->skin)
+        {
+            // Office
+            case 1:
+                $this->color['title']       = imagecolorallocate($this->img,   0,   0, 100);
+                $this->color['background']  = imagecolorallocate($this->img, 220, 220, 220);
+                $this->color['axis_values'] = imagecolorallocate($this->img,  50,  50,  50);
+                $this->color['axis_line']   = imagecolorallocate($this->img, 100, 100, 100);
+                $this->color['bg_lines']    = imagecolorallocate($this->img, 240, 240, 240);
+                $this->color['bg_legend']   = imagecolorallocate($this->img, 205, 205, 205);
+
+                if (ereg("^(1|2)$", $this->type))
+                {
+                    $this->color['bars']          = imagecolorallocate($this->img, 100, 150, 200);
+                    $this->color['bars_shadow']   = imagecolorallocate($this->img,  50, 100, 150);
+                    $this->color['bars_2']        = imagecolorallocate($this->img, 200, 250, 150);
+                    $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 120, 170,  70);
+                }
+                else if (ereg("^(3|4)$", $this->type))
+                {
+                    $this->color['line']   = imagecolorallocate($this->img, 100, 150, 200);
+                    $this->color['line_2'] = imagecolorallocate($this->img, 230, 100, 100);
+                }
+                else if (ereg("^(5|6)$", $this->type))
+                {
+                    $this->color['arc_1']        = imagecolorallocate($this->img, 100, 150, 200);
+                    $this->color['arc_2']        = imagecolorallocate($this->img, 200, 250, 150);
+                    $this->color['arc_3']        = imagecolorallocate($this->img, 250, 200, 150);
+                    $this->color['arc_4']        = imagecolorallocate($this->img, 250, 150, 150);
+                    $this->color['arc_5']        = imagecolorallocate($this->img, 250, 250, 150);
+                    $this->color['arc_6']        = imagecolorallocate($this->img, 230, 180, 250);
+                    $this->color['arc_7']        = imagecolorallocate($this->img, 200, 200, 150);
+                    $this->color['arc_1_shadow'] = imagecolorallocate($this->img,  60, 110, 170);
+                    $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 120, 170,  70);
+                    $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 180, 120,  70);
+                    $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 170, 100, 100);
+                    $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 180, 180, 110);
+                    $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 160, 110, 190);
+                    $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 140, 140, 100);
+                }
+                break;
+
+            // Matrix
+            case 2:
+                $this->color['title']       = imagecolorallocate($this->img, 255, 255, 255);
+                $this->color['background']  = imagecolorallocate($this->img,   0,   0,   0);
+                $this->color['axis_values'] = imagecolorallocate($this->img,   0, 230,   0);
+                $this->color['axis_line']   = imagecolorallocate($this->img,   0, 200,   0);
+                $this->color['bg_lines']    = imagecolorallocate($this->img, 100, 100, 100);
+                $this->color['bg_legend']   = imagecolorallocate($this->img,  70,  70,  70);
+
+                if (ereg("^(1|2)$", $this->type))
+                {
+                    $this->color['bars']          = imagecolorallocate($this->img,  50, 200,  50);
+                    $this->color['bars_shadow']   = imagecolorallocate($this->img,   0, 150,   0);
+                    $this->color['bars_2']        = imagecolorallocate($this->img, 255, 255, 255);
+                    $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 220, 220, 220);
+                }
+                else if (ereg("^(3|4)$", $this->type))
+                {
+                    $this->color['line']   = imagecolorallocate($this->img, 220, 220, 220);
+                    $this->color['line_2'] = imagecolorallocate($this->img,   0, 180,   0);
+                }
+                else if (ereg("^(5|6)$", $this->type))
+                {
+                    $this->color['arc_1']        = imagecolorallocate($this->img, 255, 255, 255);
+                    $this->color['arc_2']        = imagecolorallocate($this->img, 200, 220, 200);
+                    $this->color['arc_3']        = imagecolorallocate($this->img, 160, 200, 160);
+                    $this->color['arc_4']        = imagecolorallocate($this->img, 135, 180, 135);
+                    $this->color['arc_5']        = imagecolorallocate($this->img, 115, 160, 115);
+                    $this->color['arc_6']        = imagecolorallocate($this->img, 100, 140, 100);
+                    $this->color['arc_7']        = imagecolorallocate($this->img,  90, 120,  90);
+                    $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 200, 220, 200);
+                    $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 160, 200, 160);
+                    $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 135, 180, 135);
+                    $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 115, 160, 115);
+                    $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 100, 140, 100);
+                    $this->color['arc_6_shadow'] = imagecolorallocate($this->img,  90, 120,  90);
+                    $this->color['arc_7_shadow'] = imagecolorallocate($this->img,  85, 100,  85);
+                }
+                break;
+
+
+            // Spring
+            case 3:
+                $this->color['title']       = imagecolorallocate($this->img, 250,  50,  50);
+                $this->color['background']  = imagecolorallocate($this->img, 250, 250, 220);
+                $this->color['axis_values'] = imagecolorallocate($this->img,  50, 150,  50);
+                $this->color['axis_line']   = imagecolorallocate($this->img,  50, 100,  50);
+                $this->color['bg_lines']    = imagecolorallocate($this->img, 200, 224, 180);
+                $this->color['bg_legend']   = imagecolorallocate($this->img, 230, 230, 200);
+
+                if (ereg("^(1|2)$", $this->type))
+                {
+                    $this->color['bars']          = imagecolorallocate($this->img, 255, 170,  80);
+                    $this->color['bars_shadow']   = imagecolorallocate($this->img, 200, 120,  30);
+                    $this->color['bars_2']        = imagecolorallocate($this->img, 250, 230,  80);
+                    $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 180, 150,   0);
+                }
+                else if (ereg("^(3|4)$", $this->type))
+                {
+                    $this->color['line']   = imagecolorallocate($this->img, 230, 100,   0);
+                    $this->color['line_2'] = imagecolorallocate($this->img, 220, 200,  50);
+                }
+                else if (ereg("^(5|6)$", $this->type))
+                {
+                    $this->color['arc_1']        = imagecolorallocate($this->img, 100, 150, 200);
+                    $this->color['arc_2']        = imagecolorallocate($this->img, 200, 250, 150);
+                    $this->color['arc_3']        = imagecolorallocate($this->img, 250, 200, 150);
+                    $this->color['arc_4']        = imagecolorallocate($this->img, 250, 150, 150);
+                    $this->color['arc_5']        = imagecolorallocate($this->img, 250, 250, 150);
+                    $this->color['arc_6']        = imagecolorallocate($this->img, 230, 180, 250);
+                    $this->color['arc_7']        = imagecolorallocate($this->img, 200, 200, 150);
+                    $this->color['arc_1_shadow'] = imagecolorallocate($this->img,  60, 110, 170);
+                    $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 120, 170,  70);
+                    $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 180, 120,  70);
+                    $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 170, 100, 100);
+                    $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 180, 180, 110);
+                    $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 160, 110, 190);
+                    $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 140, 140, 100);
+                }
+                break;
+
+        }
+
+    }
+
+	/**
+	 * Echo html code for powergraphic funcionalitty
+	 * @access public
+	 * @return void
+	 */
+    function html()
+    {
+        echo 
+'<html>
+<head>
+<title>Power Graphic - by Carlos Reche</title>
+<style type="text/css">
+<!--
+
+body {
+    margin-top: 50px;
+    margin-bottom: 30px;
+    margin-left: 70px;
+    margin-right: 70px;
+    background-color: #ffffff;
+}
+body, table {
+    font-size: 13px;
+    font-family: verdana;
+    color: #666666;
+}
+input, select {
+    font-size: 11px;
+    font-family: verdana;
+    color: #333333;
+    border: 1px solid #aaaaaa;
+}
+
+a:link    { color: #666666; font-weight: bold; text-decoration: none; }
+a:visited { color: #666666; font-weight: bold; text-decoration: none; }
+a:hover   { color: #cc0000; text-decoration: none; }
+a:active  { color: #666666; text-decoration: none; }
+
+-->
+</style>
+<script type="text/javascript">
+<!--
+
+var i = 4;
+
+function add_parameter() {
+    i++;
+    space = ((i+1) < 10) ? "8px" : "0px";
+    display_status = (document.form_data.graphic_2_values.checked == true) ? "" : "none";
+    new_line  = "<div style=\"margin-left: " + space + "\"> " + (i+1) + ". <input type=\"text\" name=\"x" + i + "\" id=\"x" + i + "\" size=\"20\" /> ";
+    new_line += " <input type=\"text\" name=\"y" + i + "\" id=\"y" + i + "\" size=\"10\" onkeypress=\"return numbers();\" /> ";
+    new_line += " <input type=\"text\" name=\"z" + i + "\" id=\"z" + i + "\" size=\"10\" onkeypress=\"return numbers();\" style=\"display: " + display_status + ";\" /> </div>";
+    document.getElementById("add_parameter").innerHTML += new_line;
+}
+
+function show_graphic_2_values() {
+    var display_status = (document.form_data.graphic_2_values.checked == true) ? "" : "none";
+    document.getElementById("value_2").style.display = display_status;
+    for (var x = 0; x <= i; x++) {
+        document.getElementById("z" + x).style.display = display_status;
+    }
+}
+
+function numbers() {
+    key = event.keyCode;
+    if ((key >= 48 && key <= 57) || key == 46 || key == 13) { return true; } else { return false; }
+}
+
+//-->
+</script>
+</head>
+<body>
+
+<div style="position: absolute; right: 0px; top: -10px; right: 20px; z-index: -1; text-align: right;">
+  <div style="font-size: 60px;">
+    <span style="letter-spacing: -5px; font-family: arial black; color: #ffbbbb;">Power</span><span style="color: #bbbbff;">Graphics</span>
+  </div>
+  <div style="font-style: italic; font-size: 15px;">Powered by Carlos Reche</div>
+</div>
+
+
+<form action="' . $_SERVER['SCRIPT_NAME'] . '" method="get" name="form_data" id="form_data"> <br />
+  <div style="margin-bottom: 10px;">
+    Title: <input type="text" name="title" id="title" size="30" style="margin: 0px 0px 0px 11px;" />
+  </div>
+  Axis X: <input type="text" name="axis_x" id="axis_x" size="30" /> <br />
+  Axis Y: <input type="text" name="axis_y" id="axis_y" size="30" /> <br />
+
+  <div style="margin: 10px 0px 10px 0px;">
+    Graphic 1: <input type="text" name="graphic_1" id="graphic_1" style="width: 172px;" /> <br />
+    Graphic 2: <input type="text" name="graphic_2" id="graphic_2" style="width: 172px;" /> <br />
+  </div>
+
+  Type: <select name="type" id="type" style="margin: 5px 0px 0px 7px;">';
+        foreach ($this->available_types as $code => $type) {
+            echo '    <option value="' . $code . '"> ' . $type . ' </option>';
+        }
+        echo 
+'  </select> <br />
+Color: <select name="skin" id="skin" style="margin: 5px 0px 0px 7px;">';
+        foreach ($this->available_skins as $code => $color) {
+            echo '    <option value="' . $code . '"> ' . $color . ' </option>';
+        }
+        echo 
+'  </select>
+
+
+  <div style="margin-top: 20px;" id="parameters">
+    <div style="margin-bottom: 20px;">
+      <input type="checkbox" name="graphic_2_values" id="graphic_2_values" value="1" onclick="javascript: show_graphic_2_values();" style="border-width: 0px;" /> Show values for Graphic 2
+    </div>
+
+    <span style="margin-left: 5px; font-size: 15px; font-family: arial;"><a href="javascript: add_parameter();">+</a></span>
+    <span style="margin-left: 40px;">Parameter</span> 
+    <span style="margin-left: 50px;">Value 1</span>  <span id="value_2" style="display: none; margin-left: 25px;">Value 2</span>';
+        for ($i = 0; $i <= 4; $i++) {
+            echo '<div style="margin-left: 8px;"> '.($i+1).'. <input type="text" name="x'.$i.'" id="x'.$i.'" size="20" /> ';
+            echo ' <input type="text" name="y'.$i.'" id="y'.$i.'" size="10" onkeypress="return numbers();" /> ';
+            echo ' <input type="text" name="z'.$i.'" id="z'.$i.'" size="10" onkeypress="return numbers();" style="display: none;" /> </div>';
+        }
+echo 
+'    <div id="add_parameter"></div>
+    <span style="margin-left: 5px; font-size: 15px; font-family: arial;"><a href="javascript: add_parameter();">+</a></span>
+  </div>
+
+  <input type="checkbox" name="credits" id="credits" value="1" checked="checked" style="border-width: 0px;" /> Show credits
+
+  <input type="submit" value="Create" style="cursor: pointer; margin: 10px 0px 0px 60px;" />
+</form>
+
+
+</body>
+</html>';
+    }
+
+	/**
+	 * Reset all graphics  value
+	 * @access public
+	 * @return void
+	 */
+    function reset_values() {
+        $this->title     = NULL;
+        $this->axis_x    = NULL;
+        $this->axis_y    = NULL;
+        $this->type      = NULL;
+        $this->skin      = NULL;
+        $this->graphic_1 = NULL;
+        $this->graphic_2 = NULL;
+        $this->credits   = NULL;
+        $this->x = $this->y = $this->z = array();
+    }
+    
+	/**
+	 * Create query string array
+	 * @param array $array
+	 * @return string
+	 * @access public
+	 */
+    function create_query_string_array($array) {
+        if (!is_array($array)) {
+            return false;
+        }
+        $query_string = array();
+        foreach ($array as $parameter => $value) {
+            $query_string[] = urlencode($parameter) . '=' . urlencode($value);
+        }
+        return implode("&", $query_string);
+    }
+	
+	/**
+	 * Create query string
+	 * @return string query string 
+	 * @access public
+	 */
+    function create_query_string() {
+        $graphic['title']     = $this->title;
+        $graphic['axis_x']    = $this->axis_x;
+        $graphic['axis_y']    = $this->axis_y;
+        $graphic['type']      = $this->type;
+        $graphic['skin']      = $this->skin;
+        $graphic['graphic_1'] = $this->graphic_1;
+        $graphic['graphic_2'] = $this->graphic_2;
+        $graphic['credits']   = $this->credits;
+
+        foreach ($this->x as $i => $x)
+        {
+            $graphic['x'.$i] = $x;
+            if (isset($this->y[$i])) { $graphic['y'.$i] = $this->y[$i]; }
+            if (isset($this->z[$i])) { $graphic['z'.$i] = $this->z[$i]; }
+        }
+        return $this->create_query_string_array($graphic);
+    }
+}
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_userinterface.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_userinterface.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_userinterface.inc.php	(revision 2372)
@@ -0,0 +1,211 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php');
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class ui_userinterface extends ui_ajaxinterface
+{
+	/**
+	 * @var array public_functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'draw'	=> true,
+		'printArea' => true
+	);
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_userinterface() {
+
+	}
+
+	/**
+	 * Draw the user interface
+	 * @param int $tabIndex
+	 */
+	function draw($tabIndex = null)
+	{
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'];
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => false, 'nonavbar' => false, 'currentapp' => 'workflow');
+		$smarty = Factory::getInstance('workflow_smarty');
+
+		// Check if workflow config is ok
+		if (count($errors = $this->_checkWorkflowConfig()))
+		{
+			$smarty->assign('header', $smarty->expressoHeader);
+			$smarty->assign('footer', $smarty->expressoFooter);
+			$smarty->assign('errors', $errors);
+			$smarty->display('notworking.tpl');
+			return false;
+		}
+
+		$this->set_wf_session();
+
+		if (is_null($tabIndex))
+			$tabIndex = 1;
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'main');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'tigra_menu');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'common_functions');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'inbox');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'inbox_group');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'inbox_actions');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'processes');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'instances');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'instances_group');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'externals');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'orgchart');
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'scriptaculous', 'load=effects');
+		$javaScripts .= $this->get_js_link('workflow','experience', 'experience');
+		$javaScripts .= $this->get_js_link('workflow','experience', 'experience.panorama');
+
+		$css = $this->get_common_css();
+		$css .= $this->get_css_link('userinterface');
+		$css .= $this->get_css_link('orgchart');
+		$css .= $this->get_css_link('experience.panorama');
+
+		$tabs = array(
+			'Tarefas Pendentes',
+			'Processos',
+			'Acompanhamento',
+			'Aplicações Externas',
+			'Organograma'
+		);
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->assign('tabs', $tabs);
+		$smarty->assign('startTab', $tabIndex);
+
+		$smarty->display('userinterface.tpl');
+	}
+
+	/**
+	 * Check if workflow config is ok
+	 * @param void
+	 * @access private
+	 * @return array Errors that were found
+	 */
+	private function _checkWorkflowConfig()
+	{
+		$errors = array();
+
+		// Get a connection to db workflow and galaxia (module)
+		if (Factory::getInstance('WorkflowObjects')->getDBWorkflow()->Error)
+			$errors[] = 'Unable to connect to database Workflow';
+
+		if ($errormsg = Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Error)
+			$errors[] = 'Unable to connect to database Galaxia';
+
+		return $errors;
+	}
+
+	function printArea()
+	{
+		/* set some session variables */
+		$this->set_wf_session();
+
+		/* create some objects */
+		$so = &Factory::getInstance('so_userinterface');
+		$smarty = &Factory::getInstance('workflow_smarty');
+
+		/* get the user's organization */
+		$organizationInfo = $so->getUserOrganization($_SESSION['phpgw_info']['workflow']['account_id']);
+		if ($organizationInfo === false)
+			return false;
+
+		$organizationID = $organizationInfo['organizacao_id'];
+		$areaID = (int) $_REQUEST['areaID'];
+
+		/* load the entire orgchart */
+		$areaStack = $so->getHierarchicalArea($organizationID, null, 0);
+
+		/* if requested, load only one area */
+		if ($areaID !== 0)
+		{
+			$selectedArea = null;
+			while (($currentArea = array_pop($areaStack)) !== null)
+			{
+				if ($currentArea['area_id'] == $areaID)
+				{
+					$selectedArea = $currentArea;
+					break;
+				}
+
+				foreach ($currentArea['children'] as &$child)
+					$areaStack[] = $child;
+			}
+
+			if (is_null($selectedArea))
+				return false;
+
+			$areaStack = array(&$selectedArea);
+		}
+		else
+		{
+			$areaStack = array_reverse($areaStack);
+			$smarty->assign('organizationName', $organizationInfo['descricao']);
+		}
+
+		/* make the array flat (for a simpler handling) */
+		$flatAreas = array();
+		while (count($areaStack) > 0)
+		{
+			$currentArea = &$areaStack[count($areaStack) - 1];
+			unset($areaStack[count($areaStack) - 1]);
+
+			$currentArea['children'] = array_reverse($currentArea['children']);
+			foreach ($currentArea['children'] as &$item)
+			{
+				$item['orgchartPath'] = $currentArea['orgchartPath'] . $currentArea['sigla'] . ' &rarr; ';
+				$areaStack[count($areaStack)] = &$item;
+			}
+			unset($currentArea['children']);
+
+			$employees = $so->getAreaEmployees($currentArea['area_id'], $organizationID);
+			if (is_array($employees))
+				$currentArea['employees'] = $employees['employees'];
+			else
+				$currentArea['employees'] = array();
+			$flatAreas[] = $currentArea;
+		}
+
+		/* get the CSS and JS links */
+		$javaScripts = $this->get_js_link('workflow', 'jquery', 'jquery-1.2.6');
+		$javaScripts .= $this->get_js_link('workflow', 'userinterface', 'orgchartPrint');
+
+		$css = $this->get_css_link('orgchartPrint', 'print');
+		$css .= $this->get_css_link('orgchartPrintPreview');
+
+		/* pass variables to smarty */
+		$smarty->assign('areasJson', json_encode($flatAreas));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+
+		/* render the page */
+		$smarty->display('orgchartPrint.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.utils.string.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.utils.string.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.utils.string.php	(revision 795)
@@ -0,0 +1,736 @@
+<?php
+require_once('class.utils.php');
+/**
+ * Contains useful methods for string handling that extend standard PHP set and include new tools
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @author Marcos Pont
+ * @version 1.0
+ * @link http://workflow.celepar.parana/doc-workflow/classes/stringutils Complete reference
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class StringUtils extends Utils
+{
+	/**
+	 * Strips all blank  characters from the beginning and end of a string
+	 * @param string $str
+	 * @return result string
+	 * @access public 
+	 */
+	function allTrim($str) {
+		return $this->stripBlank(trim($str));
+	}
+
+	/**
+	 * Replace all blank characters 
+	 * @param string $str         
+	 * @param string $replace replace string
+	 * @return string result string   
+	 * @access public
+	 */
+	function stripBlank($str, $replace=' ') {
+		return ereg_replace("[[:blank:]]{1,}", $replace, $str);
+	}
+	
+	/**
+	 * Return the first n chars of the string 
+	 * @param string $str base string
+	 * @param int $chars number of chars to return  
+	 * @return string result substring
+	 * @access public
+	 */
+	function left($str, $chars = 0) {
+		if (!$this->isInteger($chars)) {
+			return $str;
+		} else if ($chars == 0) {
+			return '';
+		} else {
+			return substr($str, 0, $chars);
+		}
+	}
+	
+	/**
+	 * Return the last n chars of the string 
+	 * @param string $str base string  
+	 * @param int $chars  number of chars to return 
+	 * @return string result substring
+	 * @access public
+	 */
+	function right($str, $chars=0) {
+		if (!$this->isInteger($chars)) {
+			return $str;
+		} else if ($chars == 0) {
+			return '';
+		} else {
+			return substr($str, strlen($str) - $chars, strlen($str)-1);
+		}
+	}
+	
+	/**
+	 * Return parts of the current string 
+	 * @param string $str   base string  
+	 * @param int 	$startAt 
+	 * @param int 	$chars
+	 * @return string result substring
+	 * @access public
+	 */
+	function mid($str, $startAt=1, $chars=0) {
+		if (!$this->isInteger($chars)) {
+			return $str;
+		} else if ($str == '' || $chars == 0) {
+			return '';
+		} else if (($startAt + $chars) > strlen($str)) {
+			return $str;
+		} else {
+			if ($startAt == 0) $startAt = 1;
+			return substr($str, $startAt-1, $chars);
+		}
+	}
+	
+	/**
+	 * Returns the character at position  
+	 * @param string $str reference string
+	 * @param $index
+	 * @return string string value of a variable
+	 * @access public
+	 */
+	function charAt($str, $index) {
+		if (!$this->isInteger($index)) {
+			return '';
+		} else if ($str == '' || $index < 0 || $index >= strlen($str)) {
+			return '';
+		} else {
+			$strTranslated = strval($str);
+			return $strTranslated{$index};
+		}
+	}
+	/**
+	 * Search a string in another string 
+	 * @param string $str reference string  
+	 * @param $sValue search string
+	 * @param $caseSensitive caseSensitive true or false 
+	 * @return string position of  first occurrence of  sValue in str 
+	 * @access public
+	 */
+	function match($str, $sValue, $caseSensitive=TRUE) {
+		if (!$caseSensitive) $sValue = strtolower($sValue);
+		if (strlen($sValue) == 0) {
+			return FALSE;
+		} else {
+			$pos = strpos($str, $sValue);
+			return ($pos !== FALSE);
+		}
+	}
+	/**
+	 * Return all string starts with the substring
+	 * @param string $str referenfe string 
+	 * @param $slice
+	 * @param bool $caseSensitive caseSensitive true or false 
+	 * @param bool $ignSpaces ignore spaces
+	 * @return string
+	 * @access public  
+	 */
+	function startsWith($str, $slice, $caseSensitive=TRUE, $ignSpaces=TRUE) {
+		if (!$caseSensitive) {
+			$strUsed = ($ignSpaces) ? ltrim(strtolower($str)) : strtolower($str);
+			$sliceUsed = strtolower($slice);
+		} else {
+			$strUsed = ($ignSpaces) ? ltrim($str) : $str;
+			$sliceUsed = $slice;
+		}
+		return ($this->left($strUsed, strlen($sliceUsed)) == $sliceUsed);
+	}
+	
+	/**
+	 * Return all string ends with the substring
+	 * @param string $str
+	 * @param $slice
+	 * @param bool $caseSensitive caseSensitive true or false
+	 * @param bool $ignSpaces ignore spaces
+	 * @return string
+	 * @access public  
+	 */
+	function endsWith($str, $slice, $caseSensitive=TRUE, $ignSpaces=TRUE) {
+		if (!$caseSensitive) {
+			$strUsed = ($ignSpaces) ? rtrim(strtolower($str)) : strtolower($str);
+			$sliceUsed = strtolower($slice);
+		} else {
+			$strUsed = ($ignSpaces) ? rtrim($str) : $str;
+			$sliceUsed = $slice;
+		}
+		return ($this->right($strUsed, strlen($sliceUsed)) == $sliceUsed);
+	}
+	
+	/**
+	 * Checks with the all characters of string is upper case
+	 * @param string $str
+	 * @return bool
+	 * @access public   
+	 */
+	function isAllUpper($str) {
+		return (preg_match("/[a-z]/", $str) !== FALSE);
+	}
+	
+	/**
+	 * Checks with the all characters of string is lower case
+	 * @param string $str
+	 * @return bool
+	 * @access public  
+	 * 
+	 */
+	function isAllLower($str) {
+		return (preg_match("/[A-Z]/", $str) !== FALSE);
+	}
+	
+	/**
+	 * Checks with the values is empty
+	 * @param string $value 
+	 * @return bool
+	 * @access public  
+	 */
+	function isEmpty($value) {
+		$value = strval($value);
+		return (empty($value) && strlen($value) == 0);
+	}
+	
+	/**
+	 * If the $values replace with the $replacement parameter
+	 * @param mixed $value         
+	 * @param mixed $replacement 
+	 * @return bool
+	 * @access public  
+	 */
+	function ifEmpty($value, $replacement) {
+		return (empty($value) ? $replacement : $value);
+	}
+
+	/**
+	 * Concat two strings
+	 * @param string $str first string
+	 * @param string $concat second string
+	 * @return result string 
+	 */
+	function concat($str, $concat) {
+		return $str . $concat;
+	}
+
+	/**
+	 * Adds a prefix and suffix to a string 
+	 * @param string $str     reference string
+	 * @param string $prefix  prefix string
+	 * @param string $suffix  suffix string
+	 * @return string result string
+	 * @access public  
+	 */
+	function surround($str, $prefix, $suffix) {
+		return $prefix . $str . $suffix;
+	}
+	
+	/**
+	 * Insert a value in a determined  position in a string
+	 * @param $str reference string
+	 * @param $insValue value to insert
+	 * @param $insPos insert position 
+	 * @return string 
+	 * @access public
+	 */
+	function insert($str, $insValue = '', $insPos = 0) {
+		if (($insValue == '') || ($insPos < 0) || ($insPos > strlen($str))) {
+			return $str;
+		} else if ($insPos == 0) {
+			return $insValue . $str;
+		} else if ($insPos == strlen($str)) {
+			return $str . $insValue;
+		} else {
+			return $this->left($str, $insPos) . $insValue . $this->right($str, $insPos, strlen($str) - $insPos);
+		}
+	}
+
+	/**
+	 * Replace all occurrences of search in haystack with replace
+	 * 
+	 * @param string $str reference string
+	 * @param string $from string to search
+	 * @param string $to  string to replace
+	 * @return mixed 
+	 * @access public
+	 */
+	function replace($str, $from, $to) {
+		return str_replace($from, $to, $str);
+	}
+	
+	/**
+	 * Replace the pattern with a parameter string 
+	 * 
+	 * @param string $str reference string
+	 * @param string $pattern pattern to search
+	 * @param string $replacement string to replace
+	 * @return string  
+	 * @access public
+	 */
+	function regexReplace($str, $pattern, $replacement) {
+		if (empty($pattern))
+			return $str;
+		$matches = array();
+    	if (preg_match('!\W(\w+)$!s', $pattern, $matches) && (strpos($matches[1], 'e') !== FALSE))
+			$pattern = substr($pattern, 0, -strlen($matches[1])) . str_replace('e', '', $matches[1]);
+		return preg_replace($pattern, $replacement, $str);
+	}
+	
+	/**
+	 * Explode a string  in array of components 
+	 * 
+	 * @param string $str reference string
+	 * @param string $sep separator
+	 * @return array array of components
+	 * @access public
+	 */
+	function explode($str, $sep) {
+		$arr = explode($sep, $str);
+		return $arr;
+	}
+	
+	/**
+  	 * Join elements array in one string 
+	 * @param string $str reference string
+	 * @param string $glue glue string 
+	 * @return string result string 
+	 * @access public
+	 */
+	function implode($values, $glue) {
+		return implode($glue, (array)$values);
+	}
+
+	/**
+	 * Encode the string with encodetype 
+	 * 
+	 * @param string $str reference string 
+	 * @param string $encodeType encode type: 'base64', 'utf8' ,'7bit' , '8bit' or 'quoted-printable'
+	 * @param array  $params 
+	 * @return string encoded string 
+	 * @access public
+	 */
+	function encode($str, $encodeType, $params=NULL) {
+		switch(strtolower($encodeType)) {
+			case 'base64' :
+				$encoded = chunk_split(base64_encode($str));
+				break;
+			case 'utf8' :
+				$encoded = utf8_encode($str);
+				break;
+			case '7bit' :
+			case '8bit' :
+				$nl = $this->ifNull($params['nl'], "\n");
+				$str = str_replace(array("\r\n", "\r"), array("\n", "\n"), $str);
+				$encoded = str_replace("\n", $nl, $str);
+				if (!$this->endsWith($encoded, $nl))
+					$encoded .= $nl;
+				break;
+			case 'quoted-printable' :
+				static $qpChars;
+				if (!isset($qpChars))
+					$qpChars = array_merge(array(64, 61, 46), range(0, 31), range(127, 255));
+				$charset = $this->ifNull($params['charset'], 'iso-8859-1');
+				$replace = array(' ' => '_');
+				foreach ($qpChars as $char)
+					$replace[chr($char)] = '=' . strtoupper(dechex($char));
+				return sprintf("=?%s?Q?%s=", $charset, strtr($str, $replace));
+			default:
+				$encoded = $str;
+				break;
+		}
+		return $encoded;
+	}
+	/**
+	 * Decode the string parameter with encodetype  
+	 * 
+	 * @param string $str reference string
+	 * @param string $encodetype 'base64', 'base64', 'quoted-printable'
+	 * @return string decode string 
+	 * @access public
+	 */
+	function decode($str, $encodeType) {
+		switch(strtolower($encodeType)) {
+			case 'base64' :
+				$decoded = base64_decode($str);
+				break;
+			case 'base64' :
+				$decoded = utf8_decode($str);
+				break;
+			case 'quoted-printable' :
+				$decoded = quoted_printable_decode($str);
+				break;
+			default :
+				$decoded = $str;
+				break;
+		}
+		return $decoded;
+	}
+	
+	/**
+ 	 * Map 
+	 * 
+	 * @access public
+	 */
+	function map() {
+		$argc = func_num_args();
+		$argv = func_get_args();
+		if ($argc == 0)
+			return NULL;
+		$base = $argv[0];
+		for ($i=1,$s=sizeof($argv); $i<$s; $i+=2) {
+			if (array_key_exists($i+1, $argv)) {
+				if ($base == $argv[$i])
+					return $argv[$i+1];
+			} else {
+				return $argv[$i];
+			}
+		}
+		return $base;
+	}
+	
+	/**
+ 	 * Filter the selected strings  
+	 * 
+	 * @param string $str string reference 
+	 * @param string $filtertype regex expression
+	 * @param string $replaceStr string to replace
+	 * 
+	 * @return string 
+	 * @access public
+	 * 
+	 */
+	function filter($str, $filterType='alphanum', $replaceStr='') {
+		$replaceStr = strval($replaceStr);
+		switch ($filterType) {
+			case 'alpha' :
+				return (ereg_replace("[^a-zA-Z]", $replaceStr, $str));
+			case 'alphalower' :
+				return (ereg_replace("[^a-z]", $replaceStr, $str));
+			case 'alphaupper' :
+				return (ereg_replace("[^A-Z]", $replaceStr, $str));
+			case 'num' :
+				return (ereg_replace("[^0-9]", $replaceStr, $str));
+			case 'alphanum' :
+				return (ereg_replace("[^0-9a-zA-Z]", $replaceStr, $str));
+			case 'htmlentities' :
+				return (ereg_replace("&[[:alnum:]]{0,};", $replaceStr, $str));
+			case 'blank' :
+				return (ereg_replace("[[:blank:]]{1,}", $replaceStr, $str));
+			default :
+				return $str;
+		}
+	}
+
+	/**
+	 * Escape special characters
+	 * 
+	 * @param string $str reference string  
+	 * @param string $conversionType 'html', 'htmlall' ,'url' ,'quotes', 'javascript' 'mail'
+	 * @access public
+	 * @return string
+	 */
+	function escape($str, $conversionType='html') {
+		switch ($conversionType) {
+			case 'html':
+				return htmlspecialchars($str, ENT_QUOTES);
+			case 'htmlall' :
+				return htmlentities($str, ENT_QUOTES);
+			case 'url' :
+				return rawurlencode($str);
+			case 'quotes' :
+				return preg_replace("%(?<!\\\\)'%", "\\'", $str);
+			case 'javascript' :
+				$expressions = array(
+					"/(<scr)(ipt)/i" => "$1\"+\"$2", // quebrar tags "<script"
+					'/\\\\/' => '\\\\', // backslashes
+					'/\'/' => "\'", // single quotes
+					'/"/' => '\\"', // double quotes
+					"/\r/"=>'\\r', // caractere CR
+					"/\n/"=>'\\n', // caractere LF
+					"/\t/" => "\\t" // tabulaï¿œï¿œes
+				);
+				$str = str_replace("\\", "\\\\", $str);
+				$str = preg_replace(array_keys($expressions), array_values($expressions), $str);
+				return $str;
+			case 'mail' :
+				return str_replace(array('@', '.'), array(' at ', ' dot '), $str);
+			default :
+				return $str;
+		}
+	}
+
+    /**
+     * Camelize a string 
+     * 
+     * @param  string $str 
+     * @return string camelized string
+     * @access public
+     */
+	function camelize($str) {
+		return preg_replace("/[_|\s]([a-z0-9])/e", "strtoupper('\\1')", strtolower($str));
+	}
+
+	/**
+	 * Capitalize the parameter string 
+	 * @param string $str parameterstring 
+	 * @return string result string 
+	 * @access public
+	 */
+	function capitalize($str) {
+		if (!empty($str)) {
+			$w = preg_split("/\s+/", $str);
+			for ($i=0, $s=sizeof($w); $i<$s; $i++) {
+				if (empty($w[$i]))
+					continue;
+				$f = strtoupper($w[$i][0]);
+				$r = strtolower(substr($w[$i], 1));
+				$w[$i] = $f . $r;
+			}
+			return implode(' ', $w);
+		}
+		return $str;
+	}
+	
+	/**
+	 * Normalize the string 
+	 * @param string $str reference string 
+	 * @return string normalized string 
+	 * @access public
+	 */
+	function normalize($str) {
+		$ts = array("/[ï¿œ-ï¿œ]/", "/ï¿œ/", "/ï¿œ/", "/[ï¿œ-ï¿œ]/", "/[ï¿œ-ï¿œ]/", "/ï¿œ/", "/ï¿œ/", "/[ï¿œ-ï¿œï¿œ]/", "/ï¿œ/", "/[ï¿œ-ï¿œ]/", "/ï¿œ/", "/ï¿œ/", "/[ï¿œ-ï¿œ]/", "/ï¿œ/", "/ï¿œ/", "/[ï¿œ-ï¿œ]/", "/[ï¿œ-ï¿œ]/", "/ï¿œ/", "/ï¿œ/", "/[ï¿œ-ï¿œï¿œ]/", "/ï¿œ/", "/[ï¿œ-ï¿œ]/", "/[ï¿œ-ï¿œ]/");
+		$tn = array("A", "AE", "C", "E", "I", "D", "N", "O", "X", "U", "Y", "ss", "a", "ae", "c", "e", "i", "d", "n", "o", "x", "u", "y");
+		return preg_replace($ts, $tn, $str);
+	}
+	
+	/**
+	 * Cut before 
+	 * @param string $string 
+	 * @param string $token string to match
+	 * @param bool 
+	 * @return string 
+	 * @access public
+	 */
+	function cutBefore($string, $token, $caseSensitive=TRUE) {
+		if ($this->match($caseSensitive ? $string : strtolower($string), $token, $caseSensitive)) {
+			return stristr($string, $token);
+		}
+		return $string;
+	}
+	
+	/**
+	 * Cut last occurrence  
+	 * @param string $string 
+	 * @param string $cutOff
+	 * @param bool $caseSensitive 
+	 * @param bool 
+	 * @return string 
+	 * @access public
+	 */
+	function cutLastOcurrence($string, $cutOff, $caseSensitive=TRUE) {
+		if (!$this->match($caseSensitive ? $string : strtolower($string), $cutOff, $caseSensitive))
+			return $string;
+		else
+			return strrev(substr(stristr(strrev($string), strrev($cutOff)),strlen($cutOff)));
+	}
+
+	/**
+	 * Ident a string 
+	 * @param string $str string reference
+	 * @access public
+	 * @return string 
+	 */	
+	function indent($str, $nChars, $iChar=' ') {
+		if (!$this->isInteger($nChars) || $nChars < 1) {
+			$nChars = 1;
+		}
+		return preg_replace('!^!m', str_repeat($iChar, $nChars), $str);
+	}
+
+	/**
+	 * Truncate .....
+	 * @param string $str reference string 
+	 * @param int $lenght 
+	 * @param string $truncSufix truncate sufix 
+	 * @param bool $forcebreak
+	 * @return string  
+	 * @access public
+	 */
+	function truncate($str, $length, $truncSufix='...', $forceBreak=TRUE) {
+		if (!$this->isInteger($length) || $length < 1) {
+			return '';
+		} else {
+			if (strlen($str) > $length) {
+				$length -= strlen($truncSufix);
+        		if (!$forceBreak)
+            		$str = preg_replace('/\s+?(\S+)?$/', '', substr($str, 0, $length+1));
+				return substr($str, 0, $length) . $truncSufix;
+			} else {
+				return $str;
+			}
+		}
+	}
+	
+	/**
+	 * Insert Char in string 
+	 * @param $str reference string 
+	 * @param bool $stringEmpty 
+	 * @param string $char 
+	 * @return string 
+	 * @access public
+	 */
+	function insertChar($str, $char = ' ', $stripEmpty = TRUE) {
+		if ($stripEmpty) {
+			$strChars = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
+		} else {
+			$strChars = preg_split('//', $str, -1);
+		}
+		return implode($char, $strChars);
+	}
+	
+	/**
+	 * Wrap line 
+	 * @param string $str reference string   
+	 * @param int $num num of line to wrap
+	 * @param string $breakstring  
+	 * @return string 
+	 * @access public
+	 */
+	function wrapLine($str, $num, $breakString="\n") {
+		$line = '';
+		$processed = '';
+		$token = strtok($str, ' ');
+		while($token) {
+			if (strlen($line) + strlen($token) < ($num + 2)) {
+				$line .= " $token";
+			} else {
+				$processed .= "$line$breakString";
+				$line = $token;
+			}
+			$token = strtok(' ');
+		}
+		$processed .= $line;
+		$processed = trim($processed);
+		return $processed;
+	}
+
+	/**
+	 * Wrap  ....
+	 * 
+	 * @param $str reference string 
+	 * @param string $breakString separator
+	 * @return string  $processed  
+	 * @access public
+	 */
+	function wrap($str, $num, $breakString="\n") {
+		$str = ereg_replace("([^\r\n])\r\n([^\r\n])", "\\1 \\2", $str);
+		$str = ereg_replace("[\r\n]*\r\n[\r\n]*", "\r\n\r\n", $str);
+		$str = ereg_replace("[ ]* [ ]*", ' ', $str);
+		$str = stripslashes($str);
+		$processed = '';
+		$paragraphs = explode("\n", $str);
+		for ($i=0; $i<sizeof($paragraphs); $i++) {
+			$processed .= $this->wrapLine($paragraphs[$i], $num, $breakString) . $breakString;
+		}
+		$processed = trim($processed);
+		return $processed;
+	}
+	
+	/**
+	 * Add line numbers 
+	 * 
+	 * @param string $str reference string  
+	 * @param string $start character to start  
+	 * @param string $indent indent size  
+	 * @param string $afternumberChar char to place after number  
+	 * @return string $processed  result string 
+	 * @access public
+	 */
+	function addLineNumbers(&$str, $start = 1, $indent = 3, $afterNumberChar = ':', $glue='\n') {
+		// divide a string em linhas de um array
+		$line = explode("\n", $str);
+		$size = sizeof($line);
+		// calcula a largura maxima da numeraçao de acordo com o numero de linhas
+		$width = strlen((string)($start + $size -1));
+		$indent = max($width, $indent);
+		// gera a numeraï¿œï¿œo de linhas da string
+		for ($i = 0; $i < $size; $i++) {
+			$line[$i] = str_pad((string)($i + $start), $indent, ' ', STR_PAD_LEFT) . $afterNumberChar . ' ' . trim($line[$i]);
+		}
+		return implode($glue, $line);
+	}
+
+	/**
+	 * Count Chars 
+	 * @param string $str  reference string 
+	 * @param bool $includeSpaces spaces too
+	 * @return int number of chars
+	 * @access public 
+	 */
+	function countChars($str, $includeSpaces = FALSE) {
+		if ($includeSpaces) {
+			return strlen($str);
+		} else {
+			$match = array();
+			return preg_match_all('/[^\s]/', $str, $match);
+		}
+	}
+
+	/**
+	 * Count Words in a string 
+	 * @param string $str reference string 
+	 * @return mixed array or string 
+	 * @access public 
+	 */
+	function countWords($str) {
+		return str_word_count($str);
+	}
+
+	/**
+	 * Count Sentences in a string 
+	 * @param string $str reference string 
+	 * @return mixed number of sentences
+	 * @access public 
+	 */
+	function countSentences($str) {
+		$matches = array();
+		return preg_match_all('/[^\s]\.(?!\w)/', $str, $matches);
+	}
+
+	/**
+	 * Count Paragraphs in a string 
+	 * @param string $str reference string 
+	 * @return int number of paragraphs
+	 * @access public 
+	 */
+	function countParagraphs($str) {
+		return count(preg_split('/[\r\n]+/', $str));
+	}
+	
+	/**
+	 * Create a random string 
+	 * 
+	 * @param mixed $size size of the string  
+	 * @param bool $upper upper case permitted
+	 * @param bool $digit digits included 
+	 * @return string result string 
+	 * @access public 
+	 */
+	function randomString($size, $upper=TRUE, $digit=TRUE) {
+		$pSize = max(1, $size);
+		$start = $digit ? 48 : 65;
+		$end = 122;
+		$result = '';
+		while (strlen($result) < $size) {
+			$random = $this->randomize($start, $end);
+			if (($digit && $random >= 48 && $random <= 57) ||
+				($upper && $random >= 65 && $random <= 90) ||
+				($random >= 97 && $random <= 122)) {
+				$result .= chr($random);
+			}
+		}
+		return $result;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_move_instances.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_move_instances.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_move_instances.inc.php	(revision 2372)
@@ -0,0 +1,90 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+
+
+/**
+ * Camada Business para Mover Instâncias.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class bo_move_instances extends bo_ajaxinterface
+{
+	/**
+	 * @var object $so Acesso à camada model.
+	 * @access private
+	 */
+	private $so;
+
+
+	/**
+	 * Construtor da classe bo_move_instances
+	 * @return object
+	 * @access public
+	 */
+	function bo_move_instances()
+	{
+		parent::bo_ajaxinterface();
+		$this->so = &Factory::getInstance('so_move_instances');
+	}
+
+	/**
+	 * Carrega a lista de todos os processos que o usuário tem direito.
+	 * @return array Lista dos processos.
+	 * @access public
+	 */
+	function loadProcesses()
+	{
+		$output = $this->so->loadProcesses();
+		$this->disconnect_all();
+
+		return $output;
+	}
+
+	/**
+	 * Carrega a lista de todos as atividades dos processos que terão as instâncias movidas.
+	 * @param array $params Uma array contendo os parâmetros necessários para buscar as atividades dos processos.
+	 * @return array Lista das atividades de cada processo e um pré-relacionamento das atividades.
+	 * @access public
+	 */
+	function loadActivities($params)
+	{
+		$output['from'] = $this->so->loadProcessActivities($params['from']);
+		$output['to'] = $this->so->loadProcessActivities($params['to']);
+		$output['pre-match'] = $this->so->matchActivities($output['from'], $output['to'], 80);
+		$this->disconnect_all();
+
+		return $output;
+	}
+
+	/**
+	 * Move as instâncias de um processo para outro.
+	 * @param array $params Uma array contendo os parâmetros necessários para mover as instâncias.
+	 * @return bool TRUE em caso de sucesso e FALSE caso contrário.
+	 * @access public
+	 */
+	function moveInstances($params)
+	{
+		$JSON = &Factory::newInstance('Services_JSON');
+
+		/* convert the mappgin element to array */
+		$params['activityMappings'] = array_map("get_object_vars", get_object_vars($JSON->decode($params['activityMappings'])));
+
+		$active = ($params['active'] == 'on');
+		$completed = ($params['completed'] == 'on');
+
+		return $this->so->moveInstances($params['from'], $params['to'], $params['activityMappings'], $active, $completed);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.TemplateServer.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.TemplateServer.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.TemplateServer.inc.php	(revision 2372)
@@ -0,0 +1,285 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+
+/**
+ * Classe que redireciona requisições de arquivos de acordo com o template utilizado
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class TemplateServer
+{
+	/**
+	 * @var string $file O nome do arquivo requisitado
+	 * @access private
+	 */
+	private $file;
+
+	/**
+	 * @var string $currentTemplate O nome do template em uso
+	 * @access private
+	 */
+	private $currentTemplate;
+
+	/**
+	 * @var string $DEFAULT_TEMPLATE O nome do template padrão
+	 * @access private
+	 */
+	private $DEFAULT_TEMPLATE = 'default';
+
+	/**
+	 * @var string $FILE_SYSTEM_DIR O caminho (no sistema de arquivos) para o diretório de templates
+	 * @access private
+	 */
+	private $FILE_SYSTEM_DIR;
+
+	/**
+	 * @var string $WEB_WORKFLOW_BASE O caminho (na Web) para o diretório do Workflow
+	 * @access private
+	 */
+	private $WEB_WORKFLOW_BASE;
+
+	/**
+	 * @var string $WEB_PATH O caminho (na Web) para o diretório de templates
+	 * @access private
+	 */
+	private $WEB_PATH;
+
+	/**
+	 * @var array $cache O cache de templates (arquivo => template)
+	 * @access private
+	 */
+	private $cache;
+
+	/**
+	 * @var int $CACHE_SIZE O tamanho do cache
+	 * @access private
+	 */
+	private $CACHE_SIZE = 100;
+
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	public function TemplateServer()
+	{
+		if (!isset($_SESSION['workflow']['TemplateServer']['cache']))
+			$_SESSION['workflow']['TemplateServer']['cache'] = array();
+		$this->cache = &$_SESSION['workflow']['TemplateServer']['cache'];
+
+		/* encontra o template atualmente em uso */
+		if (isset($_SESSION['workflow']['TemplateServer']['templateSet']))
+		{
+			$this->currentTemplate = $_SESSION['workflow']['TemplateServer']['templateSet'];
+		}
+		else
+		{
+			if (isset($_SESSION['phpgw_info']['expresso']['server']['template_set']))
+			{
+				$this->currentTemplate = $_SESSION['phpgw_info']['expresso']['server']['template_set'];
+			}
+			else
+			{
+				if (isset($GLOBALS['phpgw_info']['login_template_set']))
+				{
+					$this->currentTemplate = $GLOBALS['phpgw_info']['login_template_set'];
+				}
+				else
+				{
+					Factory::getInstance('WorkflowMacro')->prepareEnvironment();
+					if (!isset($GLOBALS['phpgw_info']['login_template_set']))
+						return false;
+					$this->currentTemplate = $GLOBALS['phpgw_info']['login_template_set'];
+				}
+			}
+			$_SESSION['workflow']['TemplateServer']['templateSet'] = $this->currentTemplate;
+		}
+
+		$this->file = $_GET['file'];
+		$this->FILE_SYSTEM_DIR = dirname(__FILE__) . '/../templates';
+
+		/* tenta carregar o endereço Web do Workflow */
+		if (isset($_SESSION['workflow']['TemplateServer']['workflowBase']))
+		{
+			$this->WEB_WORKFLOW_BASE = $_SESSION['workflow']['TemplateServer']['workflowBase'];
+		}
+		else
+		{
+			if (isset($GLOBALS['phpgw_info']['server']) && is_array($GLOBALS['phpgw_info']['server']) && array_key_exists('webserver_url', $GLOBALS['phpgw_info']['server']))
+			{
+				$this->WEB_WORKFLOW_BASE = ((string) $GLOBALS['phpgw_info']['server']['webserver_url']) . '/workflow';
+			}
+			else
+			{
+				if (isset($_SESSION['phpgw_info']['workflow']['server']) && is_array($_SESSION['phpgw_info']['workflow']['server']) && array_key_exists('webserver_url', $_SESSION['phpgw_info']['workflow']['server']))
+				{
+					$this->WEB_WORKFLOW_BASE = ((string) $_SESSION['phpgw_info']['workflow']['server']['webserver_url']) . '/workflow';
+				}
+				else
+				{
+					/* se não for encontrado em nenhuma variável de ambiente, tenta carregar do banco de dados */
+					$webServerURL = (string) Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID->GetOne('SELECT config_value FROM phpgw_config WHERE config_app = ? AND config_name = ?', array('phpgwapi', 'webserver_url'));
+					$this->WEB_WORKFLOW_BASE = str_replace('//', '/', "{$webServerURL}/workflow");
+				}
+			}
+			$_SESSION['workflow']['TemplateServer']['workflowBase'] = $this->WEB_WORKFLOW_BASE;
+		}
+		$this->WEB_PATH = $this->WEB_WORKFLOW_BASE . '/templates';
+	}
+
+	/**
+	 * Redireciona a requisição para o arquivo do template adequado
+	 * @return void
+	 * @access public
+	 */
+	public function redirect()
+	{
+		if (strpos($this->file, '..') !== false)
+			return false;
+
+		if (($selectedTemplate = $this->getTemplateForFile($this->file)) === false)
+			return false;
+
+		$filename = $this->getSystemFile($this->file, $selectedTemplate);
+		$webFile = $this->getWebFile($this->file, $selectedTemplate);
+
+		if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == filemtime($filename)))
+		{
+			/* o cache do cliente está atualizado. Apenas envia um 304 (Não modificado) */
+			header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($filename)).' GMT', true, 304);
+		}
+		else
+		{
+			header("Location: {$webFile}");
+			exit;
+		}
+
+	}
+
+	/**
+	 * Encontra o template para o arquivo solicitado
+	 * @param string $file O nome do arquivo
+	 * @return string O nome do template que contém o arquivo (será 'default' ou o nome do template em uso)
+	 * @access public
+	 */
+	public function getTemplateForFile($file)
+	{
+		if (!is_null(($output = $this->getCache($file))))
+			return $output;
+
+		$output = false;
+		if (file_exists($filename = "{$this->FILE_SYSTEM_DIR}/{$this->currentTemplate}/{$file}"))
+			$output = $this->currentTemplate;
+		else
+			if (file_exists($filename = "{$this->FILE_SYSTEM_DIR}/{$this->DEFAULT_TEMPLATE}/{$file}"))
+				$output = $this->DEFAULT_TEMPLATE;
+
+		$this->setCache($file, $output);
+		return $output;
+	}
+
+	/**
+	 * Encontra o endereço (Web) do arquivo
+	 * @param string $file O nome do arquivo
+	 * @param string $template O template do arquivo (se não for passado, a classe tentará encontrar o template adeqüado)
+	 * @return string O endereço (Web) do arquivo
+	 * @access public
+	 */
+	public function getWebFile($file, $template = null)
+	{
+		if (is_null($template))
+			if (($template = $this->getTemplateForFile($file)) === false)
+				return false;
+
+		return str_replace('//', '/', "{$this->WEB_PATH}/{$template}/{$file}");
+	}
+
+	/**
+	 * Encontra o endereço (no sistema de arquivos) do arquivo
+	 * @param string $file O nome do arquivo
+	 * @param string $template O template do arquivo (se não for passado, a classe tentará encontrar o template adeqüado)
+	 * @return string O endereço (no sistema de arquivos) do arquivo
+	 * @access public
+	 */
+	public function getSystemFile($file, $template = null)
+	{
+		if (is_null($template))
+			if (($template = $this->getTemplateForFile($file)) === false)
+				return false;
+
+		return "{$this->FILE_SYSTEM_DIR}/{$template}/{$file}";
+	}
+
+	/**
+	 * Gera um link Web, através do servidor de templates (esta classe), para o arquivo informado
+	 * @param string $file O nome do arquivo
+	 * @return string O endereço do arquivo
+	 * @access public
+	 */
+	public function generateLink($file)
+	{
+		return "{$this->WEB_WORKFLOW_BASE}/templateFile.php?file={$file}";
+	}
+
+	/**
+	 * Gera um link Web, através do servidor de templates (esta classe), para a imagem informada
+	 * @param string $file O nome da imagem
+	 * @return string O endereço do arquivo
+	 * @access public
+	 */
+	public function generateImageLink($file)
+	{
+		return $this->generateLink("images/{$file}");
+	}
+
+	/**
+	 * Define um elemento no cache
+	 * @param string $key O nome da chave do cache
+	 * @param mixed $value O valor que será armazenado no cache
+	 * @return void
+	 * @access public
+	 */
+	private function setCache($key, $value)
+	{
+		if (isset($this->cache[$key]))
+			unset($this->cache[$key]);
+
+		$this->cache[$key] = $value;
+
+		if (count($this->cache) > $this->CACHE_SIZE)
+			array_shift($this->cache);
+	}
+
+	/**
+	 * Busca um elemento do cache
+	 * @param string $key O nome da chave do cache
+	 * @return mixed O valor que está armazenado no cache. Caso não seja encontrado, será retornado null
+	 * @return void
+	 * @access public
+	 */
+	private function getCache($key)
+	{
+		if (!isset($this->cache[$key]))
+			return null;
+
+		/* assegura que o elemento buscado fique em último lugar da array e, assim, garantindo que ficará mais tempo em cache (princípio da temporalidade) */
+		$output = $this->cache[$key];
+		unset($this->cache[$key]);
+		$this->cache[$key] = $output;
+
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_adminjobs.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_adminjobs.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_adminjobs.inc.php	(revision 2372)
@@ -0,0 +1,67 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php');
+
+/**
+ * Camada View para Mover Instâncias.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ui_adminjobs extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions Lista de métodos que podem ser executados.
+	 * @access private
+	 */
+	var $public_functions = array(
+			'form'	=> true
+		);
+
+	/**
+	 * Carrega os valores que serão utilizados para criação da interface para mover instâncias.
+	 * @return void
+	 * @access public
+	 */
+	function form()
+	{
+		$GLOBALS['phpgw_info']['flags'] = array(
+			'noheader' => false,
+			'nonavbar' => false,
+			'currentapp' => 'workflow',
+			'app_header' => $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('Jobs')
+		);
+		$smarty = &Factory::getInstance('workflow_smarty');
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','nano', 'JSON');
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'scriptaculous', 'load=effects');
+		$javaScripts .= $this->get_js_link('workflow','adminjobs', 'utils');
+		$javaScripts .= $this->get_js_link('workflow','adminjobs', 'actions');
+		$javaScripts .= $this->get_js_link('workflow','adminjobs', 'interface');
+
+		$css = $this->get_common_css();
+		$css .= $this->get_css_link('adminjobs');
+
+		$processInfo = Factory::getInstance('workflow_processmanager')->get_process((int) $_REQUEST['p_id']);
+		$smarty->assign('processNameVersion', "{$processInfo['wf_name']} v{$processInfo['wf_version']}");
+		$smarty->assign('processID', (int) $processInfo['wf_p_id']);
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $this->expressoFooter);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->display('adminjobs.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_processmanager.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_processmanager.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_processmanager.inc.php	(revision 2372)
@@ -0,0 +1,673 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'ProcessManager.php');
+
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_processmanager extends ProcessManager
+	{
+		/**
+		 * @var array $workflow_acl
+		 * @access public
+		 */
+		var $workflow_acl;
+		/**
+		 * @var array $not_export_attributes
+		 * @access public
+		 */
+		var $not_export_attributes = array(
+			'database_user',
+			'database_password'
+		);
+	   /**
+		 * Constructor
+		 * @access public
+		 * @return object
+		 */
+		function workflow_processmanager()
+		{
+			parent::ProcessManager();
+			$this->workflow_acl = Factory::getInstance('workflow_acl');
+
+			/* allow regular users to see the process graph */
+			if ($_GET['menuaction'] == "workflow.ui_adminactivities.show_graph")
+				return;
+
+			if (isset($_GET['p_id']))
+			{
+				if (!($this->workflow_acl->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']) || $this->workflow_acl->check_process_access($GLOBALS['phpgw_info']['user']['account_id'], (int) $_GET['p_id'])))
+                {
+                    $GLOBALS['phpgw']->common->phpgw_header();
+                    echo parse_navbar();
+                    echo lang('access not permitted');
+                    $GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+                    $GLOBALS['phpgw']->log->commit();
+                    $GLOBALS['phpgw']->common->phpgw_exit();
+                }
+            }
+		}
+		/**
+		 * Import process data
+		 * @param $data
+		 * @access public
+		 * @return bool
+		 */
+		function import_process(&$data)
+		{
+			if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+
+			if (parent::import_process($data))
+			{
+				$proc_name = $this->_normalize_name($data['name'],$data['version']);
+				foreach($data['templates'] as $tpl) 
+				{
+					$full_fname = GALAXIA_PROCESSES.SEP.$proc_name.SEP.'code'.SEP.'templates'.SEP.$tpl['name'];
+					if (file_exists($full_fname)) unlink($full_fname);
+					
+					$fp = fopen($full_fname,"w");
+			        fwrite($fp, $tpl['code']);
+					fclose($fp);
+				}
+
+				foreach($data['includes'] as $inc) 
+				{
+					$full_fname = GALAXIA_PROCESSES.SEP.$proc_name.SEP.'code'.SEP.$inc['name'];
+					if (file_exists($full_fname)) unlink($full_fname);
+					
+					$fp = fopen($full_fname,"w");
+			        fwrite($fp, $inc['code']);
+					fclose($fp);
+				}
+
+				//create resource dir if needed
+				$resource_dir = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'resources';
+				if (count($data['resources']))
+					if (!is_dir($resource_dir))
+						mkdir($resource_dir, 0770);
+
+				if (is_array($data['resources']))
+				{
+					foreach($data['resources'] as $res)
+					{
+						$full_fname = $resource_dir . SEP . $res['name'];
+						if (file_exists($full_fname)) unlink($full_fname);
+						$fp = fopen($full_fname,"w");
+						fwrite($fp, base64_decode($res['bindata']));
+						fclose($fp);
+					}
+				}
+
+				return true;
+			} else {
+				return false;
+			}
+		}
+
+		/** 
+    	* Creates an XML representation of a process.
+		* Original from ProcessManager Class
+		* Modified to support includes, resources and variable templates
+		* @param $pId process id
+		* @access public
+		* @return void
+  		*/
+		function serialize_process($pId)
+	  	{
+			if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+			if (!isset($this->jobManager))
+				$this->jobManager = &Factory::newInstance('JobManager');
+		
+			//if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db);
+			// <process>
+			$out = '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n";
+			$out.= '<process>'."\n";
+			//we retrieve config values with the others process data
+			$proc_info =& $this->get_process($pId, true);
+			$wf_procname = $proc_info['wf_normalized_name'];
+			$out.= '  <name>'.htmlspecialchars($proc_info['wf_name']).'</name>'."\n";
+			$out.= '  <isValid>'.htmlspecialchars($proc_info['wf_is_valid']).'</isValid>'."\n";
+			$out.= '  <version>'.htmlspecialchars($proc_info['wf_version']).'</version>'."\n";
+			$out.= '  <isActive>'.htmlspecialchars($proc_info['wf_is_active']).'</isActive>'."\n";
+			$out.='   <description>'.htmlspecialchars($proc_info['wf_description']).'</description>'."\n";
+			$out.= '  <lastModif>'.date("d/m/Y [h:i:s]",$proc_info['wf_last_modif']).'</lastModif>'."\n";
+
+			//Shared code
+			$out.= '  <sharedCode><![CDATA[';
+			$fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."shared.php","r");
+			while(!feof($fp)) {
+			  $line=fread($fp,8192);
+			  $out.=$line;
+			}
+			fclose($fp);
+			$out.= '  ]]></sharedCode>'."\n";
+
+			//Loop on config values
+			$out.='  <configs>'."\n";
+			foreach($proc_info['config'] as $res) {      
+			  $name = $res['wf_config_name'];
+			  $value_int = $res['wf_config_value_int'];
+			  $value = $res['wf_config_value'];
+			  if (array_search($name,$this->not_export_attributes) === false) 
+			  {
+			  	$out.='    <config>'."\n";
+			  	$out.='      <wf_config_name>'.htmlspecialchars($name).'</wf_config_name>'."\n";
+			  	$out.='      <wf_config_value>'.htmlspecialchars($value).'</wf_config_value>'."\n";
+			  	$out.='      <wf_config_value_int>'.htmlspecialchars($value_int).'</wf_config_value_int>'."\n";
+			  	$out.='    </config>'."\n";
+			  }
+			}
+			$out.='  </configs>'."\n";
+
+			// Now loop over activities
+			
+			$act_list = $this->activity_manager->list_activities($pId, 0, -1, 'wf_name__asc', '','',false);
+			$out.='  <activities>'."\n";
+			foreach($act_list['data'] as $res) {      
+			  $name = $res['wf_normalized_name'];
+			  $out.='    <activity>'."\n";
+			  $out.='      <name>'.htmlspecialchars($res['wf_name']).'</name>'."\n";
+			  $out.='      <type>'.htmlspecialchars($res['wf_type']).'</type>'."\n";
+			  $out.='      <description>'.htmlspecialchars($res['wf_description']).'</description>'."\n";
+			  $out.='      <menuPath>'.htmlspecialchars($res['wf_menu_path']).'</menuPath>'."\n";
+			  $out.='      <lastModif>'.date("d/m/Y [h:i:s]",$res['wf_last_modif']).'</lastModif>'."\n";
+			  $out.='      <isInteractive>'.$res['wf_is_interactive'].'</isInteractive>'."\n";
+			  $out.='      <isAutoRouted>'.$res['wf_is_autorouted'].'</isAutoRouted>'."\n";
+			  $out.='      <roles>'."\n";
+			  //loop on activity roles
+			  $actid = $res['wf_activity_id'];
+			  $roles =& $this->activity_manager->get_activity_roles($actid);
+			  foreach($roles as $role) {
+				if ($role['wf_readonly'])
+				{
+				  $out.='        <role readonly="true">'.htmlspecialchars($role['wf_name']).'</role>'."\n";
+				}
+				else
+				{
+				  $out.='        <role>'.htmlspecialchars($role['wf_name']).'</role>'."\n";
+				}
+			  }  
+			  $out.='      </roles>'."\n";
+			  $out.='      <agents>'."\n";
+			  //loop on activity agents
+			  $agents =& $this->activity_manager->get_activity_agents($actid);
+			  foreach($agents as $agent) {
+				$out.='        <agent>'."\n";
+				$out.='           <agent_type>'.htmlspecialchars($agent['wf_agent_type']).'</agent_type>'."\n";
+				//loop on agent datas
+				$agent_data =& $this->activity_manager->get_activity_agent_data($actid,$agent['wf_agent_type']);
+				$out.='           <agent_datas>'."\n";
+				foreach($agent_data as $key => $value)
+				{
+				  if (!($key=='wf_agent_id'))
+				  {
+					$out.='               <agent_data>'."\n";
+					$out.='                   <name>'.htmlspecialchars($key).'</name>'."\n";
+					$out.='                   <value>'.htmlspecialchars($value).'</value>'."\n";
+					$out.='               </agent_data>'."\n";
+				  }
+				}
+				$out.='           </agent_datas>'."\n";
+				$out.='        </agent>'."\n";
+			  }  
+			  $out.='      </agents>'."\n";
+
+			  //the code
+			  $out.='      <code><![CDATA[';
+			  $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."activities".SEP."$name.php","r");
+			  while(!feof($fp)) {
+				$line=fread($fp,8192);
+				$out.=$line;
+			  }
+			  fclose($fp);
+			  $out.='      ]]></code>';
+			  if($res['wf_is_interactive']=='y') {
+				$out.='      <template><![CDATA[';
+				$fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."templates".SEP."$name.tpl","r");
+				//while(!feof($fp)) {
+				//	$line=fread($fp,8192);
+					$out.=''; //all templatess will be exported in another section
+				//}
+				fclose($fp);
+				$out.='      ]]></template>';
+			  }
+			  $out.='    </activity>'."\n";    
+			}
+			$out.='  </activities>'."\n";
+			
+			//export all templates
+			$base_path = GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates';	
+			$handle = opendir($base_path); 
+			$out.='  <templates>'."\n";
+			while (false !== ($name = readdir($handle)))
+			{
+				if (is_dir($base_path.SEP.$name))
+					continue;
+				if (substr($name, -4) != ".tpl")
+					continue;
+				$out.='    <template>'."\n";
+				$out.='      <name>'.htmlspecialchars($name).'</name>'."\n";
+				//the code
+				$out.='      <code><![CDATA[';
+				$fp=fopen($base_path.SEP.$name,'r');
+				while(!feof($fp)) {
+					$line=fread($fp,8192);
+					$out.=$line;
+				}
+				fclose($fp);
+				$out.='      ]]></code>';
+				$out.='    </template>'."\n";    
+			}
+			$out.='  </templates>'."\n";
+
+			//export all includes 
+			$base_path = GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code';	
+			$handle = opendir($base_path); 
+			$out.='  <includes>'."\n";
+			while (false !== ($name = readdir($handle)))
+			{
+				if (is_dir($base_path.SEP.$name)) /* ignore directories */
+					continue;
+				if ($name == 'shared.php') /* shared.php was saved before */
+					continue;
+				if (substr($name, -4) != ".php")
+					continue;
+				$out.='    <include>'."\n";
+				$out.='      <name>'.htmlspecialchars($name).'</name>'."\n";
+				//the code
+				$out.='      <code><![CDATA[';
+				$fp=fopen($base_path.SEP.$name,'r');
+				while(!feof($fp))
+				{
+					$line=fread($fp,8192);
+					$out.=$line;
+				}
+				fclose($fp);
+				$out.='      ]]></code>';
+				$out.='    </include>'."\n";    
+			}
+			$out.='  </includes>'."\n";
+
+			$jobList = $this->jobManager->getJobsByProcessID($pId);
+			$out .= "  <jobs>\n";
+			foreach ($jobList as $job)
+			{
+				$out .= "    <job>\n";
+				$out .= "      <name>" . htmlspecialchars($job['name']) . "</name>\n";
+				$out .= "      <description>" . htmlspecialchars($job['description']) . "</description>\n";
+				$out .= "      <timeStart>" . htmlspecialchars($job['time_start']) . "</timeStart>\n";
+				$out .= "      <intervalValue>" . htmlspecialchars($job['interval_value']) . "</intervalValue>\n";
+				$out .= "      <intervalUnity>" . htmlspecialchars($job['interval_unity']) . "</intervalUnity>\n";
+				$out .= "      <dateType>" . htmlspecialchars($job['date_type']) . "</dateType>\n";
+				$out .= "      <weekDays>" . htmlspecialchars($job['week_days']) . "</weekDays>\n";
+				$out .= "      <monthOffset>" . htmlspecialchars($job['month_offset']) . "</monthOffset>\n";
+				$out .= "      <active>f</active>\n";
+				$out .= "      <fileContents><![CDATA[" . file_get_contents($this->jobManager->getJobFile($job['job_id'])) . "]]></fileContents>\n";
+				$out .= "    </job>\n";
+			}
+			$out .= "  </jobs>\n";
+
+			//export all resources 
+			$base_path = GALAXIA_PROCESSES . SEP . $wf_procname . SEP . 'resources';
+			$handle = opendir($base_path); 
+			$out.='  <resources>'."\n";
+			while (false !== ($name = readdir($handle)))
+			{ 
+				if (is_dir($base_path.SEP.$name))
+					continue;
+				if (substr($name, -4) == ".swp")
+					continue;
+				$out.='    <resource>'."\n";
+				$out.='      <name>'.htmlspecialchars($name).'</name>'."\n";
+				//the code
+				$out.='      <bindata><![CDATA[';
+				$fp=fopen($base_path.SEP.$name,'r');
+				//while(!feof($fp)) {
+				$line=fread($fp,filesize($base_path.SEP.$name));
+				$out.=chunk_split(base64_encode($line));
+				//}
+				fclose($fp);
+				$out.=' ]]></bindata>';
+				$out.='    </resource>'."\n";
+			}
+			$out.='  </resources>'."\n";
+
+
+			$out.='  <transitions>'."\n";
+			//loop on transitions
+			$transitions = $this->activity_manager->get_process_transitions($pId);
+			foreach($transitions as $tran) {
+			  $out.='     <transition>'."\n";
+			  $out.='       <from>'.htmlspecialchars($tran['wf_act_from_name']).'</from>'."\n";
+			  $out.='       <to>'.htmlspecialchars($tran['wf_act_to_name']).'</to>'."\n";
+			  $out.='     </transition>'."\n";
+			}     
+			$out.='  </transitions>'."\n";
+			$out.= '</process>'."\n";
+			
+			//$fp = fopen(GALAXIA_PROCESSES."/$wf_procname/$wf_procname.xml","w");
+			//fwrite($fp,$out);
+			//fclose($fp);
+			return $out;
+  		}
+
+		/**
+		 * Creates  a process PHP data structure from its XML representation
+		 * 
+		 * Unserialize process data  
+		 * @access public
+		 * @return void
+		 */
+		function unserialize_process(&$xml) 
+		{
+			// Create SAX parser assign this object as base for handlers
+			// handlers are private methods defined below.
+			// keep contexts and parse
+			$this->parser = xml_parser_create("ISO-8859-1"); 
+			xml_parser_set_option($this->parser,XML_OPTION_CASE_FOLDING,0);
+			//xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE, 1);
+			xml_set_object($this->parser, $this);
+			xml_set_element_handler($this->parser, '_start_element_handler', '_end_element_handler');
+			xml_set_character_data_handler($this->parser, '_data_handler');
+			 
+			$aux=Array(
+			  'name'=>'root',
+			  'children'=>Array(),
+			  'parent' => 0,
+			  'data'=>'', 
+			  'attribs'	=> Array(),
+			);
+			
+			$this->tree[0]=$aux;
+			$this->current=0;
+			
+			if (!xml_parse($this->parser, $xml, true)) {
+			   $error = sprintf("XML error: %s at line %d",
+							xml_error_string(xml_get_error_code($this->parser)),
+							xml_get_current_line_number($this->parser));
+			   trigger_error($error,E_USER_WARNING);
+			   $this->error[] = $error;
+			}
+			xml_parser_free($this->parser);   
+			// Now that we have the tree we can do interesting things
+			
+			$process=Array();
+			$activities=Array();
+			$transitions=Array();
+			$jobs = array();
+			for($i=0;$i<count($this->tree[1]['children']);$i++) {
+			  // Process attributes
+			  $z=$this->tree[1]['children'][$i];
+			  $name = trim($this->tree[$z]['name']);
+			  
+			  //config values
+			  if ($name=='configs') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+				  $z2 = $this->tree[$z]['children'][$j];
+				  // this is a config $name = $this->tree[$z2]['name'];
+				  $aux = Array();
+				  if($this->tree[$z2]['name']=='config') {
+					for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+					  $z3 = $this->tree[$z2]['children'][$k];
+					  $name = trim($this->tree[$z3]['name']);
+					  $value= trim($this->tree[$z3]['data']);
+					  $aux[$name]=$value;
+					}
+					$configs[]=$aux;
+				  }
+				}      
+			  }
+			  //activities
+			  elseif($name=='activities') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+				  $z2 = $this->tree[$z]['children'][$j];
+				  // this is an activity $name = $this->tree[$z2]['name'];
+				  $aux = Array();
+				  if($this->tree[$z2]['name']=='activity') {
+					for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+					  $z3 = $this->tree[$z2]['children'][$k];
+					  $name = trim($this->tree[$z3]['name']);
+					  $value= trim($this->tree[$z3]['data']);
+					  if($name=='roles') {
+						$roles=Array();
+						for($l=0;$l<count($this->tree[$z3]['children']);$l++) {
+						  $z4 = $this->tree[$z3]['children'][$l];
+						  $name = trim($this->tree[$z4]['name']);
+						  $data = trim($this->tree[$z4]['data']);
+						  $attribs = $this->tree[$z4]['attribs'];
+						  $readonly = false;
+						  if ( (isset($attribs['readonly'])) && ($attribs['readonly']))
+						  {
+							//role in read-only
+							$readonly = true;
+						  }
+						  $roles[]=array(
+							'name' 	=> $data,
+							'readonly'	=> $readonly,
+						  );
+						}
+					  } 
+					  elseif ($name=='agents') 
+					  {
+						$agents=Array();
+						for($l=0;$l<count($this->tree[$z3]['children']);$l++) 
+						{
+						  $z4 = $this->tree[$z3]['children'][$l];
+						  //$name is agent
+						  $name = trim($this->tree[$z4]['name']);
+						  if ($name = 'agent')
+						  {
+							$agent = array();
+							for($m=0;$m<count($this->tree[$z4]['children']);$m++)
+							{
+							  $z5 = $this->tree[$z4]['children'][$m];
+							  //$name is agent_type or agent_datas
+							  $name = trim($this->tree[$z5]['name']);
+							  // data will be the agent_type or an array for agent_datas
+							  $data = trim($this->tree[$z5]['data']);
+							  if ($name=='agent_type') 
+							  {
+								$agent['wf_agent_type']=$data;
+							  } 
+							  elseif ($name=='agent_datas') 
+							  {
+								for($n=0;$n<count($this->tree[$z5]['children']);$n++)
+								{
+								  $z6 = $this->tree[$z5]['children'][$n];
+								  //$name is agent_data $val is an array
+								  $name = trim($this->tree[$z6]['name']);
+								  $val = trim($this->tree[$z6]['data']);
+								  if ($name=='agent_data')
+								  {
+									for($o=0;$o<count($this->tree[$z6]['children']);$o++)
+									{
+									  $z7 = $this->tree[$z6]['children'][$o];
+									  //$name is agent_data $val is 'name' or 'value'
+									  $name = trim($this->tree[$z7]['name']);
+									  $content = trim($this->tree[$z7]['data']);
+									  //echo "<br>z7 name $name content: $content";
+									  if ($name=='name')
+									  {
+										$agent_data_name = $content;
+									  }
+									  elseif ($name=='value')
+									  {
+										$agent_data_value =& $content;
+									  }
+									}
+									//echo "<br>associate $agent_data_name to $agent_data_value <hr>";
+									$agent[$agent_data_name] = $agent_data_value;
+								  }
+								}
+							  }
+							}
+							$agents[]=$agent;
+						  }
+						}
+					  } else {
+						$aux[$name]=$value;
+						//print("$name:$value<br/>");
+					  }
+					}
+					$aux['agents']=$agents;
+					$aux['roles']=$roles;
+					$activities[]=$aux;
+				  }
+				}
+			  } elseif($name=='transitions') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+				  $z2 = $this->tree[$z]['children'][$j];
+				  // this is an activity $name = $this->tree[$z2]['name'];
+				  $aux=Array();
+				  if($this->tree[$z2]['name']=='transition') {
+					for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+					  $z3 = $this->tree[$z2]['children'][$k];
+					  $name = trim($this->tree[$z3]['name']);
+					  $value= trim($this->tree[$z3]['data']);
+					  if($name == 'from' || $name == 'to') {
+						$aux[$name]=$value;
+					  }
+					}
+				  }
+				  $transitions[] = $aux;
+				}
+			  } elseif($name=='includes') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+				  $z2 = $this->tree[$z]['children'][$j];
+				  // this is an activity $name = $this->tree[$z2]['name'];
+				  $aux=Array();
+				  if($this->tree[$z2]['name']=='include') {
+					for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+					  $z3 = $this->tree[$z2]['children'][$k];
+					  $name = trim($this->tree[$z3]['name']);
+					  $value= trim($this->tree[$z3]['data']);
+					  $aux[$name]=$value;
+					}
+				  }
+				  $includes[] = $aux;
+				}
+			  } elseif($name=='templates') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+				  $z2 = $this->tree[$z]['children'][$j];
+				  // this is an activity $name = $this->tree[$z2]['name'];
+				  $aux=Array();
+				  if($this->tree[$z2]['name']=='template') {
+					for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+					  $z3 = $this->tree[$z2]['children'][$k];
+					  $name = trim($this->tree[$z3]['name']);
+					  $value= trim($this->tree[$z3]['data']);
+					  $aux[$name]=$value;
+					}
+				  }
+				  $templates[] = $aux;
+				}
+			  } elseif($name=='resources') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+				  $z2 = $this->tree[$z]['children'][$j];
+				  // this is an activity $name = $this->tree[$z2]['name'];
+				  $aux=Array();
+				  if($this->tree[$z2]['name']=='resource') {
+					for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+					  $z3 = $this->tree[$z2]['children'][$k];
+					  $name = trim($this->tree[$z3]['name']);
+					  $value= trim($this->tree[$z3]['data']);
+					  $aux[$name]=$value;
+					}
+				  }
+				  $resources[] = $aux;
+				}
+			  }
+			  elseif ($name == 'jobs')
+			  {
+          for ($j = 0; $j < count($this->tree[$z]['children']); $j++)
+          {
+            $job = array();
+				    $jobIndex = $this->tree[$z]['children'][$j];
+            if($this->tree[$jobIndex]['name'] == 'job')
+            {
+              for ($k = 0; $k < count($this->tree[$jobIndex]['children']); $k++)
+              {
+                $propertyIndex = $this->tree[$jobIndex]['children'][$k];
+                $job[trim($this->tree[$propertyIndex]['name'])] = trim($this->tree[$propertyIndex]['data']);
+              }
+            }
+            $jobs[] = $job;
+          }
+			  }
+			  else {
+				$value = trim($this->tree[$z]['data']);
+				//print("$name is $value<br/>");
+				$process[$name]=$value;
+			  }
+			}
+
+			$process['configs']		= $configs;
+			$process['activities']	= $activities;
+			$process['transitions']	= $transitions;
+			$process['resources']	= $resources;
+			$process['includes']	= $includes;
+			$process['templates']	= $templates;
+			$process['jobs']	= $jobs;
+
+			return $process;
+		  }
+		  
+		/**
+		 * Creates a new process PHP data structure from its XML representation
+		 * unserial 
+		 * @access public
+		 * @return void
+		 */
+		  function new_process_version($pId, $minor=true)
+  		  {
+		  	 $new_id = parent::new_process_version($pId,$minor);
+
+			 //copy resource dir too
+			 $old_name = GALAXIA_PROCESSES . SEP . $this->_get_normalized_name($pId) . SEP . 'resources';
+			 $new_name = GALAXIA_PROCESSES . SEP . $this->_get_normalized_name($new_id) . SEP . 'resources';
+			 if (is_dir($old_name))
+ 			 	$this->_rec_copy($old_name,$new_name);
+
+			 $this->workflow_acl->add_process_admins($new_id, array( $GLOBALS['phpgw_info']['user']['account_id'] ));
+
+			 return $new_id;
+		  }
+		/**
+		 * Remove process
+		 * @param int $pId process id 
+		 * @access public
+		 * @return string 
+		 */
+		  function remove_process($pId)
+		  {
+			$result = parent::remove_process($pId);
+			$this->workflow_acl->del_process($pId);
+			return $result;
+		  }
+		/**
+		 * Replace_process
+		 * 
+		 * @param int      $pid     process id 
+		 * @param array    $vars 
+		 * @param boolean  $create
+		 *   
+		 * @access public
+		 * @return int new id
+		 */
+		  function replace_process($pId, &$vars, $create = true)
+          {
+            $id = parent::replace_process($pId, $vars, $create);
+
+            if (!$pId)
+            {
+				$this->workflow_acl->add_process_admins($id, array( $GLOBALS['phpgw_info']['user']['account_id'] ) );
+            }
+
+			return $id;
+          }	
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/hook_admin.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/hook_admin.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/hook_admin.inc.php	(revision 795)
@@ -0,0 +1,27 @@
+<?php
+  /**************************************************************************\
+  * phpGroupWare                                                             *
+  * http://www.phpgroupware.org                                              *
+  * Written by Joseph Engo <jengo@phpgroupware.org>                          *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+{
+	/* only modify the $file and $title variables..... */
+	$title = $appname;
+	$file = array
+	(
+		'Default Config Values' => $GLOBALS['phpgw']->link('/index.php','menuaction=admin.uiconfig.index&appname=' . $appname)
+	);
+
+	/* do not modify below this line */
+	display_section($appname, $title, $file);
+}
+?>
Index: /sandbox/workflow/branches/993/inc/natural/class.natural.php
===================================================================
--- /sandbox/workflow/branches/993/inc/natural/class.natural.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/natural/class.natural.php	(revision 795)
@@ -0,0 +1,414 @@
+<?php
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'natural'.SEP.'class.natural_resultset.php');
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'natural'.SEP.'pos_string.php');
+require_once(PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'inc'.SEP.'natural'.SEP.'nat_types.php');
+
+/**
+ * Código ascii do caracter espaço
+ * @name SPACE
+ */
+define (SPACE, ' ');
+
+/**
+ * Reader mainframe data class (PHP NatAPI)
+ *
+ * @author Everton Flávio Rufino Seára - rufino@celepar.pr.gov.br
+ * @version 1.0
+ * @package Workflow
+ * @subpackage natural
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class Natural
+{
+	/**
+	 * @var string $protocol Protocolo a ser utilizado
+	 * @access private
+	 */
+	private $protocol;
+	/**
+	 * @var string $endOfProtocol string delimitadora do protocolo
+	 * @access private
+	 */
+	private $endOfProtocol;
+	/**
+	 * @var string $strSubProgram  Sub-programa
+	 * @access private
+	 */
+	private $strSubProgram;
+	/**
+	 * @var string $strInputParameter Parametro de entrada
+	 * @access private
+	 */
+	private $strInputParameter;
+	/**
+	 * @var string $acronym  acronym of sub-program
+	 * @access private
+	 */
+	private $acronym;
+	/**
+	 * @var boolean $isDBGateway Flag utilizado para determinar se será utilizado o protocolo DBGateway ou DBCON
+	 * @access private
+	 */
+	private $isDBGateway;
+	/**
+	 * @var int $numRows Número de linhas
+	 * @access private
+	 */
+	private $numRows;
+	/**
+	 * @var string $IPAddress Endereço IP do Mainframe e.g:"10.15.60.20"
+	 * @access private
+	 */
+	private $IPAddress;
+	/**
+	 * @var int $serverPort Porta do servidor
+	 * @access private
+	 */
+	private $serverPort;
+	/**
+	 * @var string $key USU (8 bytes) - user => N000 + 3 positions for key + 1 space byte
+	 * @access private
+	 */
+	private $key;
+	/**
+	 * @var string $password Senha de acesso ao mainframe (8 bytes)
+	 * @access private
+	 */
+	private $password;
+	/**
+	 * @var string $application APLIC (4 bytes)  application => 3 bytes for system acronym AND 1 byte to environment 'P' or 'D'
+	 * @access private
+	 */
+	private $application;
+	/**
+	 * @var string $system Sistema (4 bytes)
+	 * @access private
+	 */
+	private $system;
+	/**
+	 * @var string $logon LOGON (8 bytes)
+	 * @access private
+	 */
+	private $logon;
+	/**
+	 * @var string $rc  PA_RC - Código de Retorno (4 bytes)
+	 * @access private
+	 */
+	private $rc;
+	/**
+	 * @var string $msg PA_MSG - Mensagem de retorno (60 bytes)
+	 * @access private
+	 */
+	private $msg;
+	/**
+	 * @var string $dataParameter Return of MAINFRAME environment
+	 * @access private
+	 */
+	private $dataParameter;
+ 	/**
+	 * @var object $resultSet Armazena o resultado das consulta
+	 * @access public
+	 */
+ 	public $resultSet;
+
+
+	/**
+	 * @var object $obj Objeto de Classe que contém a especificação e estrutura do programa natural acessado
+	 * @access protected
+	 */
+	protected $obj;
+
+	/**
+	 * Construtor da clase Natural
+	 * @access public
+	 */
+	public function Natural()
+	{
+		$this->protocol = "/cics/cwba/jaspin?";
+		$this->endOfProtocol = "!jaspin_fim_de_dados!";
+		$this->isDBGateway = false;
+	}
+
+	/**
+	 * Carrega atributos da classe com valores iniciais
+	 * @param String - Name of sub-program
+	 * @param String - Input parameters to sub-program
+	 * @access protected
+	 * @return void
+	 */
+	protected function initialize($strSubProgram/*, $strInputParameter*/)
+	{
+		$this->strSubProgram = strtoupper($strSubProgram);
+//		$this->strInputParameter = strtoupper($strInputParameter);
+
+		// get the acronym of the sub-program
+		$this->acronym = strtoupper(substr($strSubProgram, 0, 3));
+
+		// set the system
+		$this->system = str_repeat("X", 4);
+
+		// set the static logon
+		$this->logon = "N000" . $this->acronym . SPACE;
+
+		// initialize the return code
+		$this->rc = "9999";
+
+		// initialize the return message
+		$this->msg = str_repeat(SPACE, 60);
+
+		// initialize the data parameter
+		$this->dataParameter = "0000000000";
+	}
+
+	/**
+	 * Determina o protocolo a ser usado pelo Gateway
+	 *
+	 * In DBGateway protocol the size of returned data does not have any bound.
+	 * if you does not set DBGataway, PHP NatAPI will use DBCON. Using DBCon you can transfer only 32Kb of data.
+	 * @param String $dbGateway set BDGateway protocol
+	 * @access public
+	 * @return void
+	 */
+	public function setDBGatewayProtocol($dbGateway = true)
+	{
+		$this->isDBGateway = $dbGateway;
+		if ($dbGateway){
+			$this->protocol = "/cics/cwba/jasppion?";
+			$this->endOfProtocol = "!jasppion_fim_de_dados!";
+		} else {
+			$this->protocol = "/cics/cwba/jaspin?";
+			$this->endOfProtocol = "!jaspin_fim_de_dados!";
+		}
+	}
+
+	/**
+	 * Access and retrieve data from mainframe
+	 *
+	 * @return boolean
+	 * @access protected
+	 */
+	protected function execute($inputParams = "")
+	{
+
+		if (!empty($this->application) && !empty($this->strSubProgram) && !empty($this->key) && !empty($this->password) &&
+			!empty($this->IPAddress) && !empty($this->serverPort))
+		{
+			try
+			{
+				$str = new PosString(new NatType);
+				$this->strInputParameter = $str->mountString(array_merge($this->obj->input, $this->obj->output), $inputParams);
+
+				$url = $this->protocol . ($this->acronym . $this->application) . $this->system . $this->logon . $this->strSubProgram . $this->key . $this->password . $this->rc . $this->msg . $this->strInputParameter . $this->endOfProtocol;
+
+				$link = "http://" . $this->IPAddress . ":". $this->serverPort . $url;
+				// echo $link . "<br><br>";
+
+				$fp = @fsockopen($this->IPAddress, $this->serverPort, $errnum, $errstr);
+				$line = "";
+				$size = 0;
+
+				if ($fp) {
+					@fputs($fp, "GET " . $url . " HTTP/1.1\r\nHost: " . $this->IPAddress . "\r\nConnection: close\r\n\r\n");
+					$line = "";
+					while (!feof($fp)) {
+						$temp = fread($fp, 128);
+						$line = $line . $temp;
+					}
+					@fclose($fp);
+
+					$pos1 = @strpos($line, "<html><body>");
+					if ($pos1) {
+						$pos1 = $pos1 +12;
+						$pos2 = @strpos($line, "</body></html>");
+						if ($pos2) {
+							$size = $pos2 - $pos1;
+							$line = substr($line, $pos1, $size);
+							$this->rc = substr($line, 40, 4);
+							$this->msg = substr($line, 44, 60);
+
+							// Verify if user chose DBGateway or DBCon format.
+							// In DBGateway, the record count is also returned
+							if ($this->isDBGateway){
+								$this->numRows = (int)substr($line, 104, 5);
+								$this->dataParameter = substr($line, 109, ($size -109));
+							} else {
+								$this->dataParameter = substr($line, 104, ($size -104));
+							}
+						} else {
+							$this->msg = $line;
+						}
+					} else {
+						$this->msg = $line;
+					}
+				} else {
+					$this->rc = $this->rc . $errnum . "-" . $errstr;
+					$this->msg = $errnum . "-" . $errstr;
+					return false;
+				}
+				return $str->mountResult(array_merge($this->obj->input, $this->obj->output), $this->dataParameter);
+				// return true;
+			} catch (Exception $e) {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Returns the Return Code of the natural sub-program
+	 * @return int  Return Code
+	 * @access public
+	 */
+	public function getRC()
+	{
+		return $this->rc;
+	}
+
+	/**
+	 * Returns the return message of the natural sub-program
+	 * @return string $msg message from mainframe
+	 * @access public
+	 */
+	public function getMSG()
+	{
+		return $this->msg;
+	}
+
+	/**
+	 * Retorna os dados recuperados do mainframe
+	 * @return string $dataParameter  data recovered
+	 * @access public
+	 */
+	public function getDataParameter()
+	{
+		return $this->dataParameter;
+	}
+
+	/**
+	 * Sets the key (N000 + $key + space)
+	 * @param int $key  Key
+	 * @access protected
+	 */
+	protected function setKey($key)
+	{
+		if (strlen($key) < 7)
+			$this->key = "N000" . $key . SPACE;
+		else
+			$this->key = $key . SPACE;
+	}
+
+	/**
+	 * Sets the logon
+	 * @param int $logon  Logon
+	 * @access protected
+	 */
+	protected function setLogon($logon)
+	{
+		$this->logon = $logon;
+	}
+
+	/**
+	 * Sets the password
+	 * @param string $password Senha de acesso
+	 * @access protected
+	 * @return void
+	 */
+	protected function setPassword($password)
+	{
+		$this->password = $password . str_repeat(SPACE, (8 - strlen($password)));
+	}
+
+	/**
+	 * Sets the application environment
+	 * @param char $app Defines if the app. is in the production or development environment 'D' (development) or 'P' (production)
+	 * @access protected
+	 * @return void
+	 */
+	protected function setApplication($app)
+	{
+		$this->application = $app;
+	}
+
+	/**
+	 * Sets the IP address to access the mainframe
+	 * @param string $ip Endereço Ip do Mainframe e.g 10.15.60.20
+	 * @access protected
+	 * @return void
+	 */
+	protected function setIPAddress($ip)
+	{
+		$this->IPAddress = $ip;
+	}
+
+	/**
+	 * Seta a porta do servidor para acessar o Mainframe
+	 * @param int $portNumber Porta do Servidor  e.g 103
+	 * @access protected
+	 * @return void
+	 */
+	protected function setServerPort($portNumber)
+	{
+		$this->serverPort = $portNumber;
+	}
+
+	/**
+	 * Seta o sistema oara acesso
+	 * @param int $system 4 dígitos em caixa alta
+	 * @access protected
+	 * @return void
+	 */
+	protected function setSystem($system)
+	{
+		$this->system = $system;
+	}
+
+	/**
+	 * Seta o código de retorno
+	 * @param int $rc código de retorno com 4 dígitos
+	 * @access protected
+	 * @return void
+	 */
+	protected function setRC($rc)
+	{
+		$this->rc = $rc;
+	}
+
+
+	/**
+	 * Build a result set ($this->resultSet) to mainframe data. The result is returnd in array format
+	 *
+	 * <code>
+	 * $rowConf example - array (name_of_field => size_of_field)
+	 * $array = array("id" => 5, "name" => 10);
+	 * </code>
+	 * @param int $lineSize Size of each line return from mainframe
+	 * @param array $rowConf Configuration of the field's name and size of each fild
+	 * @return void
+	 * @access public
+	 */
+	 public function configureResultSet($lineSize, $rowConf)
+	 {
+	 	//$rows = explode("%NAT_SEP%", wordwrap($this->dataParameter, $lineSize, "%NAT_SEP%"));
+	 	for ($i=0; $i < strlen($this->dataParameter)/$lineSize; $i++){
+	 		$rows[] = substr($this->dataParameter, $lineSize*$i , $lineSize);
+	 	}
+
+	 	$result = array();
+	 	// for each row returned from mainframe
+	 	foreach ($rows as $id => $values){
+	 		$last_id = 0;
+	 		// get configuration array to build the result
+	 		foreach ($rowConf as $id_conf => $value_conf)
+	 		{
+	 			$result[$id][$id_conf] = substr($values, $last_id, $value_conf);
+	 			$last_id += (int)$value_conf;
+	 		}
+	 	}
+
+	 	if (!empty($this->resultSet))
+	 		unset($this->resultSet);
+	 	$this->resultSet = new NaturalResultSet($result);
+	 }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/natural/class.natural_resultset.php
===================================================================
--- /sandbox/workflow/branches/993/inc/natural/class.natural_resultset.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/natural/class.natural_resultset.php	(revision 795)
@@ -0,0 +1,86 @@
+<?php
+/*
+ * Created on 26/03/2007
+ */
+
+ /**
+  * Result set class for PHP NatAPI
+  * @author Everton Flávio Rufino Seára - rufino@celepar.pr.gov.br
+  * @version 1.0
+  * @package Workflow
+  * @subpackage natural
+  * @license http://www.gnu.org/copyleft/gpl.html GPL
+  */
+ class NaturalResultSet
+ {
+  /**
+   * @var int $currRows Linha atual
+   * @access private
+   */
+	private $currRows;
+
+  /**
+   * @var array $result Array com o resultado
+   * @access private
+   */
+ 	private $result;
+
+ 	/** Inicializa o result set
+ 	 * @return void
+ 	 * @param array $_result Array com o resultado
+ 	 * @access public
+ 	 */
+ 	function __construct($_result)
+ 	{
+ 		$this->result = $_result;
+ 		$this->currRows = -1;
+ 	}
+ 	/**
+ 	 * Returns the next row if it exists, else, returns false
+ 	 * @return array next row of data, if it exists
+ 	 * @access public
+ 	 */
+	public function getNextRow()
+	{
+		if (count($this->result) > ++$this->currRows){
+	 		return $this->result[$this->currRows];
+	 	} else {
+	 		return false;
+	 	}
+	}
+
+	/**
+	 * Returns the data from a specific field
+	 * @param string $name Field name
+	 * @return string data
+	 * @access public
+	 */
+	public function getFieldByName($name)
+	{
+		if (count($this->result) > $this->currRows)
+	 		return $this->result[$this->currRows][$name];
+	}
+
+	/**
+	 * Reset the result set
+	 * @return void
+	 * @access public
+	 */
+	public function resetRow()
+	{
+	 	$this->currRows = -1;
+	}
+
+	/**
+	 * Record count
+	 * @return int Numero de registros
+	 * @access public
+	 */
+	public function recordCount()
+	{
+	 	return count($this->result);
+	}
+
+
+ }
+?>
Index: /sandbox/workflow/branches/993/inc/natural/nat_types.php
===================================================================
--- /sandbox/workflow/branches/993/inc/natural/nat_types.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/natural/nat_types.php	(revision 795)
@@ -0,0 +1,119 @@
+<?php
+
+
+/*
+ * Criado em 22/10/2008
+ *
+ * Autor: André Alexandre Ávila/DIDES-C1/Celepar
+ * Projeto NatPHPDC1
+ *
+ */
+/**
+ * Tipos Padrão
+ * Classe de tipagem padrão para comunicação com mainframe
+ * Manter essa classe sem alterações
+ * Para mudar tipos, criar uma nova classe extendndo essa e passar ao construtor da natphp.
+ *
+ * Situacoes invalidas:
+ * padl e padr no mesmo tipo
+ * str sem arr e vice-versa
+ * type assoc num array input
+ *
+ * Quando utilizar o div:
+ * Quando o Mainframe retorna um valor 1234567890 mas seria 12345678.90 o valor, divide-se por 100
+ * Ao se enviar novamente ao mainframe ele multiplica por 100 e envia
+ *
+ * Prioridade de tratamento:
+ * 1 length
+ * 2 div
+ * 3 array e str
+ * 4 funcarr e funcstr
+ * 5 trim global
+ */
+class NatType {
+	private $types = array (
+		'A' => array (
+			'loop' => true,
+			'type' =>'num'
+		),
+		'AA' => array (
+			'loop' => true,
+			'type' =>'assoc'
+		),
+		'N' => array (
+			'padl' => '0'
+		),
+		'S' => array (
+			'padr' => ' '
+		),
+		'DATE' => array (
+			'str' => '%04d%02d%02d',
+			'arr' => '%04d-%02d-%02d'
+		),
+		'DATEBR' => array (
+			'str' => '%02d%02d%04d',
+			'arr' => '%02d/%02d/%04d'
+		),
+		'DATEDMY' => array (
+			'str' => '%04d%02d%02d',
+			'arr' => '%3$02d/%2$02d/%1$04d'
+		),
+		'DTIME' => array (
+			'str' => '%04d%02d%02d%02d%02d%02d',
+			'arr' => '%04d-%02d-%02d %02d:%02d:%02d'
+		),
+		'DT' => array (
+			'str' => '%04d%02d%02d%02d%02d%02d',
+			'arr' => '%04d-%02d-%02d %02d:%02d:%02d'
+		),
+		'TIME' => array (
+			'str' => '%02d%02d%02d',
+			'arr' => '%02d:%02d:%02d'
+		),
+		'DEC' => array (
+			'str' => '%0.2f',
+			'arr' => '%0.2f',
+			'div' => 100,
+			'padl' => '0'
+		),
+		'MONEY' => array (
+			'str' => '%f',
+			'arr' => '%0.2f',
+			'div' => 100,
+			'padl' => '0'
+		),
+		'SSA' => array (
+			'padr' => ' ',
+			'funcstr' => 'removeAcentos'
+		)//string sem acento
+	);
+
+	function setType($name, $val) {
+		$this->types[$name] = $val;
+	}
+
+	function getType($name) {
+		if (!isset ($this->types[$name]))
+			return $this->types['S'];
+		return $this->types[$name];
+	}
+
+	function removeAcentos($Msg) {
+		$a = array (
+			"/[ÂÀÁÄÃ]/"	=> "A",
+			"/[âãàáä]/"	=> "a",
+			"/[ÊÈÉË]/" 	=> "E",
+			"/[êèéë]/" 	=> "e",
+			"/[ÎÍÌÏ]/" 	=> "I",
+			"/[îíìï]/" 	=> "i",
+			"/[ÔÕÒÓÖ]/" => "O",
+			"/[ôõòóö]/" => "o",
+			"/[ÛÙÚÜ]/" 	=> "U",
+			"/[ûúùü]/" 	=> "u",
+			"/ç/" 		=> "c",
+			"/Ç/" 		=> "C"
+		);
+		return preg_replace(array_keys($a), array_values($a), $Msg);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/natural/pos_string.php
===================================================================
--- /sandbox/workflow/branches/993/inc/natural/pos_string.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/natural/pos_string.php	(revision 795)
@@ -0,0 +1,228 @@
+<?php
+
+/*
+ * Criado em 21/10/2008
+ *
+ * Autor: André Alexandre Ávila/DIDES-C1/Celepar
+ * Projeto NatPHPDC1
+ *
+ */
+/**
+====================== FORMATO ======================
+[FIELD] => array
+			[type]   = N(numeric), S(String), A(Array)
+			[length] = 6(six numbers), 9.2 or 9,2
+			if have array
+			[length] number of loops
+			[fields] = fields of array
+					=>
+						[FIELD] => array
+			 	 			[type]
+			 	 			[length]
+			 	 			[fields]
+
+================ FORMATO DO RETORNO =================
+ array ('name' => 'value')
+ array ('name' => array(
+			0 => array(
+				name1 => value1,
+				name2 => value2,
+				name3 => value3
+		)))
+=====================================================
+ * Prioridade de tratamento:
+ * 1 length
+ * 2 div
+ * 3 array e str
+ * 4 funcarr e funcstr
+ * 5 trim global
+*/
+
+class PosString {
+	public $trim = false;
+	private $types = null;
+	public $debug = false;
+	public $clearStep = true;
+	public $dbgln = array ();
+
+	function __construct($type) {
+		$this->types = & $type;
+	}
+	/**
+	Funcao sprintf com suporte a array
+	*/
+	private function sprintf_array($string, $array) {
+		$keys = array_keys($array);
+		$keysmap = array_flip($keys);
+		$values = array_values($array);
+		array_unshift($values, $string);
+		return call_user_func_array('sprintf', $values);
+	}
+	/**
+	 * Monta String de acordo com o formato
+	 * @param Array Formato
+	 * @param Array Dados Array
+	 * @return String String Posicional
+	 */
+	public function mountString($format, $dataArr) {
+		$dataS = '';
+		$iz = 0;
+		foreach ($format as $fieldName => $fieldDef) {
+			$type = $this->types->getType($fieldDef['type']);
+			if (!isset ($type['loop'])) {
+				$length = 0;
+				$value = '';
+				// procura o length
+				if (isset ($type['length']))
+					$length = $type['length'];
+				if (isset ($fieldDef['length']))
+					$length = $fieldDef['length'];
+				if (isset ($dataArr[$fieldName]))
+					$value = $dataArr[$fieldName];
+				if (isset ($type['div']) && is_numeric($value))
+					$value = (int) $value * $type['div'];
+				/* tipagem com mais opções e flexivel */
+				/* volta p/ valor original */
+				if (isset ($type['arr']) && isset ($type['str']))
+					$value = $this->returnFormat($value, $type['arr'], $type['str']);
+				if (isset ($type['funcstr']) && method_exists($this->types, $type['funcstr'])) {
+					$mtd = $type['funcstr'];
+					$value = $this->types-> $mtd ($value);
+				}
+				/* Usa o PAD para completar o campo caso não seja do tamanho necessário */
+				$padN = STR_PAD_RIGHT;
+				$padF = ' ';
+				if (isset ($type['padl']) || isset ($type['padr'])) {
+					if (isset ($type['padl'])) {
+						$padN = STR_PAD_LEFT;
+						$padF = $type['padl'];
+					} else {
+						$padN = STR_PAD_RIGHT;
+						$padF = $type['padr'];
+					}
+				}
+				$value = str_pad($value, $length, $padF, $padN);
+				if ($this->debug) {
+					$this->dbgln[] = "Campo:{$fieldName};Tipo:{$fieldDef['type']};Tamanho:{$length};Valor:{$value};";
+				}
+				$dataS .= $value;
+			} else {
+				$iz = 0;
+				// Loop para pegar os dados do nivel abaixo
+				/* No caso da geracao de string percorrer todos os campos eh necessario para
+				 * se manter a ordem correta
+				 */
+				while ($iz < $fieldDef['length']) {
+					$value = '';
+					if (isset ($dataArr[$fieldName])) {
+						if ($type['type'] == 'assoc')
+							$value = $dataArr[$fieldName][$iz];
+						else
+							$value = $dataArr[$fieldName][$iz];
+					}
+					$dataS .= $this->mountString($fieldDef['fields'], $value);
+					$iz++;
+				}
+			}
+		}
+		return $dataS;
+	}
+
+	/**
+	 * Monta Array de acordo com o formato
+	 * @param Array Formato
+	 * @param String String Posicional
+	 * @return Array Dados
+	 */
+	public function mountResult($format, $string, & $pt = 0) {
+		if ($pt == 0 && $this->clearStep)
+			$this->dbgln = array ();
+		$data = array ();
+		$iz = 0;
+		foreach ($format as $fieldName => $fieldDef) {
+			$type = $this->types->getType($fieldDef['type']);
+			if (!isset ($type['loop'])) {
+				$length = 0;
+				// procura o length
+				if (isset ($type['length']))
+					$length = $type['length'];
+				if (isset ($fieldDef['length']))
+					$length = $fieldDef['length'];
+				$value = substr($string, $pt, $length);
+				if (isset ($type['div']))
+					$value = (float) $value / $type['div'];
+				if (isset ($type['arr']) && isset ($type['str']))
+					$value = $this->returnFormat($value, $type['str'], $type['arr']);
+				if (isset ($type['funcarr']) && method_exists($this->types, $type['funcarr'])) {
+					$mtd = $type['funcarr'];
+					$value = $this->types-> $mtd ($value);
+				}
+				$pt += $length;
+				$data[$fieldName] = ($this->trim) ? (trim($value)) : ($value);
+				if ($this->debug) {
+					$this->dbgln[] = "Campo:{$fieldName};Tipo:{$fieldDef['type']};Tamanho:{$length};Valor:{$data[$fieldName]};";
+				}
+			} else {
+				$iz = 0;
+				$data[$fieldName] = array();
+				// caso haja um campo com o limitador de ocorrencias define ele como o length
+				if (isset ($fieldDef['index']) && $fieldDef['index'] != null)
+					$fieldDef['length'] = $data[$fieldDef['index']];
+				// Loop para pegar os dados do nivel abaixo
+				//echo 'ddsadsa'.$type['type'];
+				while ($iz < $fieldDef['length']) {
+					if ($type['type'] == 'assoc'){
+						$tmp = $this->mountResult($fieldDef['fields'], $string, $pt);
+						$data[$fieldName] = array_merge_recursive($data[$fieldName],$tmp);
+					} else {
+						$data[$fieldName][$iz] = $this->mountResult($fieldDef['fields'], $string, $pt);
+					}
+					$iz++;
+				}
+			}
+		}
+		return $data;
+	}
+	/**
+	 * Conta o Tamanho total dos campos
+	 * @param Array Formato
+	 * @return Integer Tamanho total dos campos
+	 */
+	public function countFormat($format) {
+		$pt = 0;
+		foreach ($format as $fieldName => $fieldDef) {
+			$type = $this->types->getType($fieldDef['type']);
+			if (!isset ($type['loop'])) {
+				$pt += $fieldDef['length'];
+			} else {
+				$pt += $fieldDef['length'] * $this->countFormat($fieldDef['fields']);
+			}
+		}
+		return $pt;
+	}
+	/**
+	 * Obtem o resultado da array de log.
+	 * @param bool Limpar array de log após obte-la
+	 */
+	function getDebugLog($clear = false) {
+		$log = $this->dbgln;
+		if ($clear)
+			$this->dbgln = array ();
+		return $log;
+	}
+	/**
+	 * Formata valor de acordo com o padrão sprintf
+	 * @param String Entrada
+	 * @param String Formato entrada
+	 * @param String Formato saída
+	 */
+	private function returnFormat($value, $typeIn, $typeOut) {
+		$tmp = sscanf($value, $typeIn);
+		if (!is_array($tmp)) {
+			return $value;
+		}
+		$ret = $this->sprintf_array($typeOut, $tmp);
+		return $ret;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_generic_select.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_generic_select.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_generic_select.inc.php	(revision 2372)
@@ -0,0 +1,99 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once dirname(__FILE__) . SEP . 'common.inc.php';
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Junior
+ */
+class ui_generic_select
+{
+	/**
+	 * @var array $public_functions public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+        'form'  => true
+    );
+
+    /**
+     * @var int $containerNumber
+     * @access public
+     */
+	var $containerNumber;
+	/**
+	 * @var $sessionSection
+	 * @access public
+	 */
+	var $sessionSection;
+	/**
+	 * @var $target_element
+	 * @access public
+	 */
+	var $targetElement;
+	/**
+	 * @var $selected
+	 * @access public
+	 */
+	var $selected;
+	/**
+	 * @var $digest
+	 * @access public
+	 */
+	var $digest;
+
+	function readPostedData()
+	{
+		$this->sessionSection = "generic_select";
+		$this->targetElement = isset($_GET['target_element']) ? $_GET['target_element'] : 'user_list';
+		$this->containerNumber = isset($_GET['container_number']) ? $_GET['container_number'] : 0;
+		$this->selected = isset($_GET['selected']) ? $_GET['selected'] : -1;
+		$this->digest = isset($_GET['digest']) ? $_GET['digest'] : "false";
+	}
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return void
+	 */
+	function ui_generic_select()
+	{
+		$this->readPostedData();
+	}
+
+	/**
+	 * Build the generic select form
+	 * @access public
+	 * @return void
+	 */
+	function form()
+	{
+		$smarty = Factory::getInstance('workflow_smarty', false);
+		$smarty->setHeader(workflow_smarty::SHOW_HEADER | workflow_smarty::SHOW_FOOTER);
+
+		$javaScripts = '<script src="' . $GLOBALS['phpgw_info']['server']['webserver_url'] . SEP . 'workflow' . SEP . 'js' . SEP . 'jscode' . SEP . 'generic_select.js' . '" type="text/javascript"></script>';
+
+		/* pass the variables to Smarty */
+		$smarty->assign('list', $_SESSION[$this->sessionSection][$this->digest][$this->containerNumber]);
+		$smarty->assign('selected', $this->selected);
+		$smarty->assign('targetElement', $this->targetElement);
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('lang_to_Search', lang('search'));
+		$smarty->assign('lang_Close', lang('Close'));
+		$smarty->assign('lang_Add', lang('Add'));
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->display('generic_select.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.CachedLDAP.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.CachedLDAP.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.CachedLDAP.inc.php	(revision 2372)
@@ -0,0 +1,355 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+* Gera um cache do LDAP (em banco de dados) para não perder informações no caso de exclusão de um funcionário
+* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+* @version 1.0
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+* @package Workflow
+*/
+class CachedLDAP
+{
+	/**
+	* @var int $OPERATION_MODE_NORMAL Modo de operação normal (acessa primeiro o BD e, se necessário, acessa o LDAP e atualiza o BD)
+	* @access public
+	*/
+	public $OPERATION_MODE_NORMAL = 0;
+
+	/**
+	* @var int $OPERATION_MODE_LDAP Modo de operação LDAP (acessa o LDAP e atualiza o BD)
+	* @access public
+	*/
+	public $OPERATION_MODE_LDAP = 1;
+
+	/**
+	* @var int $OPERATION_MODE_DATABASE Modo de operação banco de dados (acessa somente o BD)
+	* @access public
+	*/
+	public $OPERATION_MODE_DATABASE = 2;
+
+	/**
+	* @var int $OPERATION_MODE_LDAP_DATABASE Modo de operação LDAP e banco de dados. Acessa primeiro o LDAP e, somente se o usuário não existir no LDAP que o banco de dados será consultado.
+	* @access public
+	*/
+	public $OPERATION_MODE_LDAP_DATABASE = 3;
+
+	/**
+	* @var string $userContext Contexto do usuário (LDAP)
+	* @access protected
+	*/
+	protected $userContext;
+
+	/**
+	* @var string $groupContext Contexto do grupo (LDAP)
+	* @access protected
+	*/
+	protected $groupContext;
+
+	/**
+	* @var resource $dataSource Conexão com o LDAP
+	* @access protected
+	*/
+	protected $dataSource;
+
+	/**
+	* @var int $operationMode Modo de operação da classe
+	* @access private
+	*/
+	private $operationMode;
+
+	/**
+	* @var array $entryAttributes Os atributos que serão buscados (LDAP ou Banco de Dados)
+	* @access private
+	*/
+	private $entryAttributes = array('uid', 'cn', 'givenname', 'mail', 'sn', 'accountstatus', 'uidnumber', 'dn', 'employeenumber', 'cpf', 'telephonenumber');
+
+	/**
+	* @var resource $DBLink Link com o banco de dados
+	* @access protected
+	*/
+	protected $DBLink = null;
+
+	/**
+	* @var int $cacheDays O número de dias antes do cache ser renovado
+	* @access private
+	*/
+	private $cacheDays = 2;
+
+	/**
+	* Estabelece uma conexão com o LDAP
+	* @return void
+	* @access protected
+	*/
+	protected function loadLDAP()
+	{
+		/* check if the information was already loaded */
+		if (!empty($this->userContext))
+			return;
+
+		/* load the information and establish a connection */
+		$tmpLDAP =& Factory::getInstance('WorkflowLDAP');
+		$this->userContext  = $tmpLDAP->getUserContext();
+		$this->groupContext = $tmpLDAP->getGroupContext();
+		$this->dataSource =& Factory::getInstance('WorkflowObjects')->getLDAP();
+	}
+
+	/**
+	* Estabelece uma conexão com o Banco de Dados
+	* @return void
+	* @access protected
+	*/
+	protected function loadDB()
+	{
+		/* check if the information was already loaded */
+		if (!is_null($this->DBLink))
+			return;
+
+		/* establish a connection */
+		$this->DBLink =& Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
+	}
+
+	/**
+	* Executa uma query no LDAP e, retorna o seu resultado
+	* @param string $ldapQuery A query do LDAP que será executada
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access private
+	*/
+	private function runLDAP($ldapQuery)
+	{
+		/* load the information and establish the connection */
+		$this->loadLDAP();
+
+		/* perform the search */
+		$resourceIdentifier = ldap_search($this->dataSource, $this->userContext, $ldapQuery, $this->entryAttributes);
+		$entries = ldap_get_entries($this->dataSource, $resourceIdentifier);
+
+		/* check the returned data */
+		if ($entries['count'] != 1)
+			return false;
+
+		/* format the output */
+		$output = array();
+		foreach ($this->entryAttributes as $attribute)
+			if ($attribute == 'dn')
+				$output[$attribute] = $entries[0][$attribute];
+			else
+				$output[$attribute] = $entries[0][$attribute][0];
+
+		/* insert the timestamp of the last update */
+		$output['last_update'] = mktime();
+
+		return $output;
+	}
+
+	/**
+	* Executa uma query no Banco de Dados para encontrar um usuário
+	* @param string $bdQuery A cláusula WHERE da query
+	* @param array $bindVariables Valores que substituirão o pontos de interrogação na query
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access private
+	*/
+	private function runBD($bdQuery, $bindVariables)
+	{
+		/* establish the connection */
+		$this->loadDB();
+
+		/* perform the search */
+		$resultSet = $this->DBLink->query('SELECT ' . implode(', ', $this->entryAttributes) . ', EXTRACT(EPOCH FROM last_update) AS last_update FROM egw_wf_user_cache WHERE ' . $bdQuery, $bindVariables);
+
+		return $resultSet->fetchRow();
+	}
+
+	/**
+	* Atualiza, em Banco de Dados, os atributos de um usuário
+	* @param mixed $entry Uma array associativa contendo os atributos de um usuário (pode ser um boolean false)
+	* @param string $bdQuery A cláusula WHERE da query
+	* @param array $bindVariables Valores que substituirão o pontos de interrogação na query
+	* @return void
+	* @access private
+	*/
+	private function updateDB($entry, $bdQuery, $bindVariables)
+	{
+		/* establish the connection */
+		$this->loadDB();
+
+
+		if ($entry == false)
+		{
+			/* the user doesn't exist in LDAP anymore */
+			$this->DBLink->query('UPDATE egw_wf_user_cache SET last_update = NULL WHERE ' . $bdQuery, $bindVariables);
+		}
+		else
+		{
+			/* unset the timestamp */
+			unset($entry['last_update']);
+
+			/* insert/update the user info */
+			$this->DBLink->query('DELETE FROM egw_wf_user_cache WHERE (uidnumber = ?)', array($entry['uidnumber']));
+			$this->DBLink->query('INSERT INTO egw_wf_user_cache (' . implode(', ', array_keys($entry)) . ') VALUES (' . implode(', ', array_fill(0, count($entry), '?')) . ')', array_values($entry));
+		}
+	}
+
+	/**
+	* Faz a busca pelo usuário. Levando-se em conta o modo de operação selecionado
+	* @param string $ldapQuery A query do LDAP que será executada
+	* @param string $bdQuery A cláusula WHERE da query (se for utilizado o Banco de Dados)
+	* @param array $bindVariables Valores que substituirão o pontos de interrogação na query de Banco de Dados
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access private
+	*/
+	private function run($ldapQuery, $bdQuery, $bindVariables)
+	{
+		/* LDAP operation mode: load the user info in LDAP and then update the user info in the Database */
+		if (($this->operationMode == $this->OPERATION_MODE_LDAP) || ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE))
+		{
+			$entry = $this->runLDAP($ldapQuery);
+			$this->updateDB($entry, $bdQuery, $bindVariables);
+
+			/* return only the LDAP info when in LDAP operation mode, or if the user was found (when using the LDAP_DATABASE operation mode) */
+			if (($this->operationMode == $this->OPERATION_MODE_LDAP) || (($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE) && ($entry !== false)))
+				return $entry;
+		}
+
+		/* load the user information from the Database */
+		$entry = $this->runBD($bdQuery, $bindVariables);
+
+		/* return the database info when in LDAP_DATABASE operation mode (since the user wasn't found in the LDAP) */
+		if ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE)
+			return $entry;
+
+		/* normal operation mode: verify if the information in the Database is still valid; otherwise check it in LDAP */
+		if ($this->operationMode == $this->OPERATION_MODE_NORMAL)
+		{
+			/* if the user was found in the Database and if the user doesn't exist in LDAP anymore or the information is updated, then return the info. Otherwise update it with LDAP info */
+			if (($entry !== false) && ((is_null($entry['last_update'])) || (($entry['last_update'] + ($this->cacheDays * 24 * 60 * 60)) > mktime())))
+				return $entry;
+
+			/* we need to load info from the LDAP and update the Database record */
+			$newEntry = $this->runLDAP($ldapQuery);
+			$this->updateDB($newEntry, $bdQuery, $bindVariables);
+
+			/* return the information from LDAP if the user was found; otherwise return the entry from the database */
+			if ($newEntry !== false)
+				return $newEntry;
+			else
+				return $entry;
+		}
+
+		return $entry;
+	}
+
+	/**
+	* Construtor da classe CachedLDAP
+	* @return object Objeto da classe CachedLDAP
+	* @access public
+	*/
+	function CachedLDAP()
+	{
+		/* set the default operation mode */
+		$this->setOperationMode($this->OPERATION_MODE_NORMAL);
+	}
+
+	/**
+	* Define o modo como a classe vai operar (se busca somente no LDAP, no Banco de Dados, etc.)
+	* @param int $operationMode O modo de operação da classe
+	* @return void
+	* @access public
+	*/
+	function setOperationMode($operationMode)
+	{
+		/* make sure it's an integer */
+		$operationMode = (int) $operationMode;
+		$availableOptions = array(
+			$this->OPERATION_MODE_LDAP,
+			$this->OPERATION_MODE_DATABASE,
+			$this->OPERATION_MODE_NORMAL,
+			$this->OPERATION_MODE_LDAP_DATABASE);
+
+		/* check if the value is valid and set it */
+		if (in_array($operationMode, $availableOptions, true))
+			$this->operationMode = $operationMode;
+	}
+
+	/**
+	* Prepara os parâmetros para buscar o usuário
+	* @param string $field O nome do campo pelo qual a busca será feita
+	* @param string $value O valor que será utilizao na busca
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access private
+	*/
+	private function getEntry($field, $value)
+	{
+		/* build the queries */
+		$ldapQuery = "(&({$field}={$value})(phpgwaccounttype=u))";
+		$bdQuery = "({$field} = ?)";
+		$bindVariables = array($value);
+
+		return $this->run($ldapQuery, $bdQuery, $bindVariables);
+	}
+
+	/**
+	* Busca um usuário pelo seu ID
+	* @param int $userID O ID do usuário
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access public
+	*/
+	function getEntryByID($userID)
+	{
+		return $this->getEntry('uidnumber', (int) $userID);
+	}
+
+	/**
+	* Busca um usuário pelo seu CPF
+	* @param string $CPF O CPF do usuário
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access public
+	*/
+	function getEntryByCPF($CPF)
+	{
+		return $this->getEntry('cpf', $CPF);
+	}
+
+	/**
+	* Busca um usuário pelo seu e-mail
+	* @param string $email O e-mail do usuário
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access public
+	*/
+	function getEntryByEmail($email)
+	{
+		return $this->getEntry('mail', $email);
+	}
+
+	/**
+	* Busca um usuário pela sua matrícula
+	* @param int $employNumber A matrícula do usuário
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access public
+	*/
+	function getEntryByEmployeeNumber($employNumber)
+	{
+		return $this->getEntry('employeenumber', (int) $employNumber);
+	}
+
+	/**
+	* Busca um usuário pelo seu uid
+	* @param string $uid O uid do usuário
+	* @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
+	* @access public
+	*/
+	function getEntryByUid($uid)
+	{
+		return $this->getEntry('uid', $uid);
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.utils.type.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.utils.type.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.utils.type.php	(revision 795)
@@ -0,0 +1,215 @@
+<?php
+require_once('class.utils.php');
+/**
+ * Contains useful methods for PHP type checking and casting
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @author Marcos Pont
+ * @version 1.0
+ * @link http://workflow.celepar.parana/doc-workflow/classes/typeutils Complete reference
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class TypeUtils extends Utils
+{	
+	/**
+	 * Return the type of variable
+	 * @param $value 
+	 * @return type of element
+	 * @access public
+	 */
+	function getType($value) {
+		return gettype($value);
+	}
+	
+	/**
+	 * Check if value is a float number
+	 * @param int  $value 
+	 * @param bool $stritct
+	 * @access public
+	 * @return bool 
+	 */
+	function isFloat(&$value, $strict=FALSE) {
+		$locale = localeconv();
+		$dp = $locale['decimal_point'];
+		$exp = "/^\-?[0-9]+(\\" . $dp . "[0-9]+)?$/";
+		if (preg_match($exp, $value)) {
+			if (!$strict && !is_float($value)) {
+				$value = $this->parseFloat($value);
+			}
+			return TRUE;
+		} else {
+			return FALSE;
+		}
+	}
+	
+	/**
+	 * Parse Float number
+	 * @param string $value
+	 * @access public
+	 * @return float
+	 */
+	function parseFloat($value) {
+		if ($this->isString($value)) {
+			$locale = localeconv();
+			if ($locale['decimal_point'] != '.') {
+				$value = str_replace($locale['decimal_point'], '.', $value);
+			}
+		}
+		return floatval($value);
+	}
+	
+	
+	/**
+	 * Parse Float Positive
+	 * @param string $value
+	 * @access public
+	 * @return int
+	 */
+	function parseFloatPositive($value) {
+		return abs(floatval($value));
+	}
+	
+	/**
+	 * Checks if $value is a string
+	 * @param string $value
+	 * @access public
+	 * @return bool
+	 */
+	function isString($value) {
+		return is_string($value);
+	}
+
+	/**
+	 * Checks if $values is a array
+	 * @param string $value
+	 * @access public
+	 * @return bool
+	 */
+	function isArray($value) {
+		return is_array($value);
+	}
+	
+	/**
+	 * Checks if $value is a Hash array
+	 * @param string $value
+	 * @access public
+	 * @return bool
+	 */
+	function isHashArray($value) {
+		if (is_array($value) && sizeof($value)) {
+			$i = 0;
+			$keys = array_keys($value);
+			foreach ($keys as $k=>$v) {
+				if ($v !== $i) {
+					return TRUE;
+				}
+				$i++;
+			}
+		}
+		return FALSE;
+	}
+	
+	/**
+	 * the value to array
+	 * @param mixed $value 
+	 * @access public
+	 * @return array
+	 */
+	function toArray($value) {
+		return is_array($value) ? $value : array($value);
+	}
+	
+	/**
+	 * Check if the parameter is a object
+	 * @param mixed $value type to test
+	 * @access public
+	 * @return bool
+	 */
+	function isObject($value) {
+		return is_object($value);
+	}
+	
+	/**
+	 * Check if object is instance of class
+	 * @param object $object
+	 * @param string $className
+	 * @param bool   $recurse
+	 * @return bool
+	 * @access public
+	 */
+	function isInstanceOf($object, $className, $recurse=TRUE) {
+		if (!is_object($object))
+			return FALSE;
+		$objClass = get_class($object);
+		$otherClass = ($this->isPHP(5) ? $className : strtolower($className));
+		if ($recurse)
+			return ($objClass == $otherClass || is_subclass_of($object, $otherClass));
+		return ($objClass == $otherClass);
+	}
+	
+	/**
+	 * Check if the parameter is a Resource 
+	 * @param mixed $value
+	 * @return bool
+	 * @access public
+	 */
+	function isResource($value) {
+		if (is_resource($value))
+			return get_resource_type($value);
+		return FALSE;
+	}
+
+	/**
+	 * Checks if the value is a boolean
+	 * @param mixed $value
+	 * @return bool
+	 * @access public
+	 */
+	function isBoolean($value) {
+		return ($value === TRUE || $value === FALSE);
+	}
+	
+	/**
+	 * Check if the value is a boolean and true
+	 * @param bool $value
+	 * @return bool  
+	 * @access public
+	 */
+	function isTrue($value) {
+		return ($value === TRUE);
+	}
+
+	/**
+	 * Return a default value if first parameter is false
+	 * @param  mixed $value   test value
+	 * @param  mixed $default default value to return if first parameter is false
+	 * @access public
+	 */
+	function ifFalse($value, $default = FALSE) {
+		if ($value === FALSE)
+			return $default;
+		return $value;
+	}
+	
+	/**
+	 * Converts value to boolean 0 false otherwise true
+	 * @param mixed $value
+	 * @return bool true or false
+	 * @access public
+	 */
+	function toBoolean($value) {
+		return (bool)$value;
+	}
+	
+	/**
+	 * Checks if value parameter is empty
+	 * @param mixed $value
+	 * @return bool true empty otherwise false 
+	 * @access public
+	 */
+	function isEmpty($value) {
+		$result = empty($value);
+		return $result;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_adminprocesses.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_adminprocesses.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_adminprocesses.inc.php	(revision 2372)
@@ -0,0 +1,765 @@
+<?php
+require_once 'common.inc.php';
+require_once(dirname(__FILE__) . SEP . 'class.bo_workflow_forms.inc.php');
+require_once('engine' . SEP . 'config.egw.inc.php');
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ui_adminprocesses extends bo_workflow_forms
+{
+	/**
+	 * @var array $public_functions public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'form'	=> true,
+	);
+	/**
+	 * @var object $process_manager
+	 * @access public
+	 */
+	var $process_manager;
+
+	/**
+	 * @var object $activity_manager
+	 * @access public
+	 */
+	var $activity_manager;
+
+	/**
+	 * @var bool $filter_active
+	 * @access public
+	 */
+	var $filter_active;
+
+	/**
+	 * @var array $process_config
+	 * @access public
+	 */
+	var $process_config=array();
+
+	/**
+	 * @var array $workflow_acl
+	 * @access public
+	 */
+	var $workflow_acl;
+
+	/**
+	 * Contructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_adminprocesses()
+	{
+		parent::bo_workflow_forms('admin_processes');
+
+		$this->workflow_acl = Factory::getInstance('workflow_acl');
+		$denyAccess = true;
+		if ($this->workflow_acl->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']))
+		{
+			/* the user is an Expresso/Workflow admin */
+			$denyAccess = false;
+		}
+		else
+		{
+			if ($GLOBALS['phpgw']->acl->check('admin_workflow', 1, 'workflow'))
+			{
+				/* check if the user can admin the informed process */
+				if ($this->wf_p_id != 0)
+					$denyAccess = !$this->workflow_acl->check_process_access($GLOBALS['phpgw_info']['user']['account_id'], $this->wf_p_id);
+				else
+					$denyAccess = false;
+			}
+		}
+
+		if ($denyAccess)
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		$this->process_manager	= Factory::getInstance('workflow_processmanager');
+		$this->activity_manager	= Factory::getInstance('workflow_activitymanager');
+
+		$this->form_action = $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminprocesses.form');
+	}
+
+	/**
+	* Shows and processes process form
+	* Fields in the database are in the form 'wf_field', whereas in the form just 'field'
+	*
+	* @author	Alejandro Pedraza, Regis Leroy, Michael Bartz
+	* @access	public
+	*/
+	function form()
+	{
+		//$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('Admin Processes');
+		//$GLOBALS['phpgw']->common->phpgw_header();
+		//echo parse_navbar();
+		//$this->t->set_file('admin_processes', 'admin_processes.tpl');
+		$this->t->set_block('admin_processes', 'block_items', 'items');
+
+		$name			= get_var('name', 'POST', '');
+		$description		= get_var('description', 'POST', '');
+		$version		= get_var('version', 'POST', '');
+		$is_active		= get_var('isActive', 'POST', '');
+		$filter			= get_var('filter', 'any', '');
+		$this->filter_active	= get_var('filter_active', 'any', '');
+		$newminor		= get_var('newminor', 'GET', 0);
+		$newmajor		= get_var('newmajor', 'GET', 0);
+		//overwrite default sort order
+		$this->order		= get_var('order', 'any', 'wf_name');
+		$this->sort		= get_var('sort', 'any', 'asc');
+		$this->sort_mode	= $this->order . '__'. $this->sort;
+		//retrieve config_values POSTed by the form
+
+		// filtering options
+		$where_str = '';
+		$wheres = array();
+
+		if ($this->filter_active)
+		{
+			$wheres[] = " wf_is_active='". $this->filter_active ."'";
+		}
+
+		if (!Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']))
+		{
+			$proc_ids = $this->workflow_acl->get_granted_processes($GLOBALS['phpgw_info']['user']['account_id']);
+			if (count($proc_ids))
+			{
+				$wheres[] = ' wf_p_id in ('. implode(',',$proc_ids) .') ';
+			}
+			else
+			{
+				$wheres[] = ' wf_p_id = -1 ';
+			}
+		}
+
+		$where_str = implode('and', $wheres);
+
+		$this->link_data = array(
+			'filter_active'	=> $this->filter_active,
+			'search_str'	=> $this->search_str,
+			'offset'	=> $this->offset,
+			'start'		=> $this->start,
+		);
+
+
+		// we set an array with all config values and titles we know
+		// this will serve to show config values and to save them
+		$known_config_items= array(
+					'Running activities options'					=> 'title',
+					'auto-release_on_leaving_activity'				=> 'yesno',
+					'execute_activities_in_debug_mode'				=> 'yesno',
+					'execute_activities_using_secure_connection'	=> 'yesno',
+					'Graphic options'								=> 'title',
+					'draw_roles'									=> 'yesno',
+					'font_size'										=> 'text',
+					'Actions Right Options '						=> 'title',
+					'ownership_give_abort_right'    			    => 'yesno',
+					'ownership_give_exception_right'			    => 'yesno',
+					'ownership_give_release_right'  			    => 'yesno',
+					'role_give_abort_right'         			    => 'yesno',
+					'role_give_release_right'       			    => 'yesno',
+					'role_give_exception_right'     			    => 'yesno',
+					'disable_advanced_actions'      			    => 'yesno',
+					'Database Options'								=> 'title',
+					'database_name'									=> 'text',
+					'database_user'									=> 'text',
+					'database_password'								=> 'password',
+					'View Options'									=> 'title',
+					'iframe_view_height'							=> 'text'
+		);
+		//we add agents options
+		//mail_smtp
+
+		$log_levels = array(
+				0 => lang('emergency'),
+				1 => lang('alert'),
+				2 => lang('critical'),
+				3 => lang('error'),
+				4 => lang('warning'),
+				5 => lang('notice'),
+				6 => lang('information'),
+				7 => lang('debug')
+			);
+		$known_config_items = array_merge($known_config_items, array('Log Options' => 'title', 'log_level' => $log_levels));
+
+		$bo_agent = Factory::getInstance('bo_agent_mail_smtp');
+		$known_config_items = array_merge($known_config_items, $bo_agent->listProcessConfigurationFields());
+
+		//do we need to check validity, warning high load on database
+		$checkvalidity=false;
+
+		if( isset($_POST['upload']))
+		{
+			if ($_FILES['userfile1']['size'] == 0)
+			{
+				die("Bad upload!");
+			}
+
+			if ($_FILES['userfile1']['type'] != "text/xml") { die("Invalid file format!"); }
+			//if ($_FILES['userfile1']['type'] != "text/xml" && $_FILES['file']['type'] != "image/jpeg" && $_FILES['file']['type'] != "image/pjpeg") { die("Invalid file format!"); }
+			$fh = fopen ($_FILES['userfile1']['tmp_name'], "r") or die("Could not open file");
+
+			// read file
+			$date = '';
+			while (!feof($fh))
+			{
+				 $data .= fgets($fh);
+				 //echo $data;
+			}
+			// close file
+			fclose ($fh);
+
+			$process_data =& $this->process_manager->unserialize_process($data);
+			if ($_POST['customImport'] == 'on')
+			{
+				if (!empty($_POST['newName']))
+					$process_data['name'] = $_POST['newName'];
+				if (!empty($_POST['newVersion']))
+					$process_data['version'] = $_POST['newVersion'];
+			}
+
+			//_debug_array($process_data);
+			if ($this->process_manager->import_process($process_data))
+			{
+				$this->message[] = lang('Import successfull');
+			}
+			else
+			{
+				$this->message[] = lang('Import aborted');
+			}
+		}
+		// delete processes
+		if (isset($_POST['delete']))
+		{
+			$this->delete_processes(array_keys($_POST['process']));
+			$this->message[] = lang('Deletion successful');
+		}
+
+
+		// save new process
+		// or save modifs
+		if (isset($_POST['save']))
+		{
+			//retrieve config_values POSTed by the form
+			$config_yesno		=& get_var('config_yesno', 'POST', array());
+			$config_value 		=& get_var('config_value', 'POST', array());
+			$config_use_default 	=& get_var('config_use_default', 'POST', array());
+			$global_config_array = array(
+				'known_items' 	=> &$known_config_items,
+				'yesno'		=> &$config_yesno,
+				'value'		=> &$config_value,
+				'default' 	=> &$config_use_default,
+			);
+			$this->wf_p_id = $this->save_process($name, $version, $description, $is_active,$global_config_array);
+			//no need for $checkvalidity because this is done by the ProcessManager
+		}
+
+		// new minor
+		if ($newminor)
+		{
+			if (!($this->process_manager->new_process_version($newminor)))
+			{
+				$this->message[] = lang('something was wrong while creating the new minor version');
+			}
+			else
+			{
+				$this->message[] = lang('new minor version created');
+			}
+
+		}
+
+		// new major
+		if ($newmajor)
+		{
+			if (!($this->process_manager->new_process_version($newmajor, false)))
+			{
+				$this->message[] = lang('something was wrong while creating the new major version');
+			}
+			else
+			{
+				$this->message[] = lang('new major version created');
+			}
+
+		}
+
+		// retrieve current process
+		if ($this->wf_p_id)
+		{
+			$proc_info = $this->process_manager->get_process($this->wf_p_id);
+			$this->t->set_var('proc_bar', $this->fill_proc_bar($proc_info));
+			//retrieve config values
+			$this->process_config =& $this->process_manager->getConfigValues($this->wf_p_id);
+		}
+		else
+		{
+			$proc_info = array(
+				'wf_name'		=> '',
+				'wf_description'	=> '',
+				'wf_version'		=> '1.0',
+				'wf_is_active'		=> 'n',
+				'wf_p_id'		=> 0
+			);
+			$this->t->set_var('proc_bar', '');
+			$this->process_config = array();
+		}
+
+		// show list of processes
+		$items = &$this->process_manager->list_processes($this->start, $this->offset, $this->sort_mode, $search_str, $where_str);
+		//echo "list of processes: <pre>";print_r($items);echo "</pre>";
+		$this->show_list_processes($items['data'], $items['cant']);
+
+		if ($this->wf_p_id)
+		{
+			// check process validity and show errors if necessary
+			if ($checkvalidity) $proc_info['wf_is_valid'] = $this->show_errors($this->activity_manager, $error_str);
+		}
+
+		//collect some messages from used objects
+		$this->message[] = $this->activity_manager->get_error(false, _DEBUG);
+		$this->message[] = $this->process_manager->get_error(false, _DEBUG);
+
+		// show current process
+		$this->t->set_var(array(
+			'errors'		=> $error_str,
+			'txt_Process_Name'	=> lang('Process Name'),
+			'link_new'		=> $GLOBALS['phpgw']->link('/index.php', array_merge( array(
+							'menuaction'	=> $this->form_action,
+							'p_id'		=> 0,), $this->link_data)
+							),
+			'p_id'			=> $proc_info['wf_p_id'],
+			'name'			=> $proc_info['wf_name'],
+			'version'		=> $proc_info['wf_version'],
+			'description'		=> $proc_info['wf_description'],
+			'is_active'		=> ($proc_info['wf_is_active'] == 'y')? 'checked="checked"' : '',
+			'btn_update_create'	=> ($this->wf_p_id)? lang('update') : lang('create'),
+			'list_processes'	=> lang('List of processes'),
+		));
+		// show process config values
+		$this->show_process_config($known_config_items);
+
+		$this->fill_form_variables();
+		$this->finish();
+	}
+	/**
+	 * Delete processes
+	 * @param array $process_ids
+	 * @access public
+	 * @return void
+	 */
+	function delete_processes($process_ids)
+	{
+		foreach ($process_ids as $process_id)
+		{
+			$this->process_manager->remove_process($process_id);
+		}
+	}
+
+	/**
+	 * Show the list of process configuration options
+	 * Use the process_config array member which should be already setted. Show a table with a line for each config
+	 * value containing [Yes-No/value/select | default] choices.
+	 * @param array $known_config_itemns The parameter is an array containing all known config items and is used to show all config items, as only
+	 * the ones changed for this process are stored in process_config.You should give this function all config_names avaible at process level associated with type which
+	 * is 'yesno' or 'text' or an associative array with key 'select' containing an array of the select values
+	 * to show (array: key => value) ==> (select: name => value)
+	 * You can add titles by giving the title in the config_name and 'title' as type.
+	 *
+	 * @return void
+	 * @access public
+	 */
+	function show_process_config(&$known_config_items)
+	{
+
+		$siteconfiglink = '<a href="'.$GLOBALS['phpgw']->link('/index.php','menuaction=admin.uiconfig.index&appname=workflow')
+			.'">'.lang('Workflow Site Configuration').'</a>';
+		$this->t->set_var(array(
+			'txt_consult_site_config_with_link' => lang ('Consult %1 to get the default values:',$siteconfiglink),
+		));
+
+		$this->t->set_block('admin_processes', 'block_config_table_empty', 'config_table_empty');
+		$this->t->set_block('admin_processes', 'block_config_table_title', 'config_table_title');
+		$this->t->set_block('admin_processes', 'block_config_table_yesno', 'config_table_yesno');
+		$this->t->set_block('admin_processes', 'block_config_table_text', 'config_table_text');
+		$this->t->set_block('admin_processes', 'block_config_table_password', 'config_table_password');
+		$this->t->set_block('admin_processes', 'block_config_table_select_option', 'config_table_select_option');
+		$this->t->set_block('admin_processes', 'block_config_table_select', 'config_table_select');
+		$this->translate_template('block_config_table_title');
+		$this->translate_template('block_config_table_yesno');
+		$this->translate_template('block_config_table_text');
+		$this->translate_template('block_config_table_password');
+		$this->translate_template('block_config_table_empty');
+		$this->translate_template('block_config_table_select');
+
+		if (!(is_array($known_config_items)) || !count($known_config_items))
+		{
+			$this->t->set_var(array(
+				'config_empty' => lang('There are no config value defined'),
+				'config_table_title' => '',
+				'config_table_yesno' => '',
+				'config_table_text' => '',
+				'config_table_password' => '',
+				'config_table_select' => '',
+			));
+
+			$this->t->parse('config_table_empty', 'block_config_table_empty', true);
+		}
+		else
+		{
+			//we wont need the 'empty config' row
+			$this->t->set_var(array('config_table_empty'=> ''));
+			//we prepare the global table rows
+			$this->t->set_block('admin_processes', 'block_config_table', 'config_table');
+			$this->translate_template('block_config_table');
+			// we parse the config items we knows
+			while(list($config_name, $config_type) = each($known_config_items))
+			{
+				// now rows can be of different types
+				if (is_array($config_type))
+				{//we have a select
+					unset($row_value);
+					$row_value = $this->process_config[$config_name];
+
+					reset($config_type);
+					for($i = 0; ($current =& each($config_type) != null); $i++){
+						$this->t->set_var(array(
+							'config_option_name'		=> $current['value'],
+							'config_option_value'		=> $current['key'],
+							'config_option_selected'	=> ($current['key'] == $row_value)? 'selected' : '',
+						));//DEBUG TODO selected value?
+						$this->t->parse('config_table_select_option', 'block_config_table_select_option', (($i == 0) ? false : true ));
+					}
+
+					$this->t->set_var(array(
+						'config_name' 			=> $config_name,
+						'config_name_trad'		=> lang(str_replace('_',' ',$config_name)),
+						'color_line' 			=> $this->nextmatchs->alternate_row_color($tr_color),
+						'config_table_title' 		=> '',
+						'config_table_text' 		=> '',
+						'config_table_password' 	=> '',
+						'config_table_yesno'		=> '',
+					));
+
+					$this->t->parse('config_table_select', 'block_config_table_select', false);
+				}
+				elseif ($config_type=='title')
+				{
+					$this->t->set_var(array(
+						'config_name_trad'	=> lang(str_replace('_',' ',$config_name)),
+						'color_line'		=> '#D3DCE3',
+						'config_table_text' 	=> '',
+						'config_table_password'	=> '',
+						'config_table_yesno' 	=> '',
+						'config_table_select'	=> ''
+					));
+					$this->t->parse('config_table_title', 'block_config_table_title', false);
+				}
+
+				else
+				{
+					// if not title or select our row can be a text value or a Yes/No/Default value
+					$this->t->set_var(array(
+						'config_name' 			=> $config_name,
+						'config_name_trad'		=> lang(str_replace('_',' ',$config_name)),
+						'color_line' 			=> $this->nextmatchs->alternate_row_color($tr_color),
+						'config_table_title' 		=> '',
+						'config_table_select'		=> '',
+					));
+					unset($row_value);
+					$row_value = $this->process_config[$config_name];
+					if ($config_type=='text')
+					{
+						if (isset($row_value))
+						{
+							$this->t->set_var(array(
+								'config_value' 			=> $row_value,
+								'config_use_default_checked' 	=> '',
+								'txt_Use_Default'		=> lang('Use Default'),
+								'config_table_password' => '',
+								'config_table_yesno' 		=> '',
+							));
+						}
+						else
+						{
+							$this->t->set_var(array(
+								'config_value' 			=> '',
+								'config_use_default_checked' 	=> 'checked',
+								'txt_Use_Default'               => lang('Use Default'),
+								'config_table_password' => '',
+								'config_table_yesno' 		=> '',
+							));
+						}
+						$this->t->parse('config_table_text', 'block_config_table_text', false);
+					}
+					elseif ($config_type=='password')
+					{
+						$config = array(
+							'config_table_text' => '',
+							'config_value' => '',
+							'config_use_default_checked' => 'checked',
+							'txt_Use_Default' => lang('Use Default'),
+							'config_table_yesno' => ''
+						);
+						if (isset($row_value))
+						{
+							$config['config_value'] =$row_value;
+							$config['config_use_default_checked'] = '';
+						}
+						$this->t->set_var($config);
+						$this->t->parse('config_table_password', 'block_config_table_password', false);
+					}
+					elseif ($config_type=='yesno')
+					{
+						if (isset($row_value))
+						{
+							$this->t->set_var(array(
+								'config_table_text' 		=> '',
+								'config_table_password' => '',
+								'config_default_selected' 	=> '',
+								'config_yes_selected'		=> ($row_value==1)? 'selected':'',
+								'config_no_selected'		=> ($row_value==1)? '':'selected',
+							));
+						}
+						else
+						{
+							$this->t->set_var(array(
+								'config_table_text' 		=> '',
+								'config_table_password' => '',
+								'config_default_selected' 	=> 'selected',
+								'config_yes_selected'		=> '',
+								'config_no_selected'		=> '',
+							));
+						}
+						$this->t->parse('config_table_yesno', 'block_config_table_yesno', false);
+					}
+				}
+				$this->t->parse('config_table','block_config_table',true);
+			}
+		}
+	}
+	/**
+	 * Show list of processes
+	 * @param $items
+	 * @param int $total_number
+	 * @access public
+	 * @return void
+	 */
+	function show_list_processes(&$items, $total_number)
+	{
+		$header_array = array(
+			'wf_name'		=> lang('Process'),
+			'wf_version'	=> lang('Version'),
+			'wf_is_active'	=> lang('Active'),
+			'wf_is_valid'	=> lang('Valid'),
+		);
+		$this->fill_nextmatchs($header_array,$total_number);
+
+		// filter_active, "", y or n
+		$this->t->set_var(array(
+				'filter_active_selected_all'	=> ($this->filter_active=='')? 'selected':'',
+				'filter_active_selected_y'	=> ($this->filter_active=='y')? 'selected':'',
+				'filter_active_selected_n'	=> ($this->filter_active=='n')? 'selected':'',
+		));
+		$get_link = array(
+			'menuaction' 	=> 'workflow.ui_'. $this->class_name .'.form',
+			'search_str'	=> $this->search_str,
+			'start'		=> $this->start,
+			'sort'		=> $this->sort,
+			'order'		=> $this->order,
+		);
+		$get_link = array_merge($get_link, $this->link_data);
+		foreach ($items as $item)
+		{
+			if ($item['wf_is_valid'] == 'y')
+			{
+				$dot = 'green';
+				$alt = lang('Valid Process');
+			}
+			else
+			{
+				$dot = 'red';
+				$alt = lang('Invalid Process');
+			}
+
+			$myp_id = $item['wf_p_id'];
+			$templateServer = &Factory::getInstance('TemplateServer');
+			$this->t->set_var(array(
+				'item_wf_p_id'		=> $myp_id,
+				'href_item_name'	=> $GLOBALS['phpgw']->link('/index.php', array_merge($get_link,array('p_id' => $myp_id))),
+				'item_name'			=> $item['wf_name'],
+				'item_version'		=> $item['wf_version'],
+				'img_active'		=> ($item['wf_is_active'] == 'y')? '<img src="'. $templateServer->generateImageLink('refresh2.gif') .'" alt="'. lang('active') .'" title="'. lang('active') .'" />' : '',
+				'img_valid'			=> '<img src="'. $templateServer->generateImageLink($dot.'_dot.gif') .'" alt="'. $alt .'" title="'. $alt .'" />',
+				'href_item_minor'	=> $GLOBALS['phpgw']->link('/index.php', array_merge($get_link,array('newminor'	=> $myp_id))),
+				'img_new'			=> $GLOBALS['phpgw']->common->image('workflow', 'new'),
+				'href_item_major'	=> $GLOBALS['phpgw']->link('/index.php', array_merge($get_link,array('newmajor' => $myp_id))),
+				'href_item_activities'	=> $GLOBALS['phpgw']->link('/index.php', array(
+								'menuaction'	=> 'workflow.ui_adminactivities.form',
+								'p_id'		=> $myp_id)),
+				'img_activities'	=> $templateServer->generateImageLink('Activity.gif'),
+				'href_item_code'	=> $GLOBALS['phpgw']->link('/index.php', array(
+								'menuaction'	=> 'workflow.ui_adminsource.form',
+								'p_id'		=> $myp_id)),
+				'img_code'		=> $templateServer->generateImageLink('code.png'),
+				'href_item_export'	=> $GLOBALS['phpgw']->link('/index.php', array(
+								'menuaction'	=> 'workflow.WorkflowUtils.export',
+								'p_id'		=> $myp_id)),
+				'img_export'		=> $templateServer->generateImageLink('save.png'),
+				'href_item_roles'	=> $GLOBALS['phpgw']->link('/index.php', array(
+								'menuaction'	=> 'workflow.ui_adminroles.form',
+								'p_id'		=> $myp_id)),
+				'img_roles'		=> $templateServer->generateImageLink('roles.png'),
+				'href_item_jobs'	=> $GLOBALS['phpgw']->link('/index.php', array(
+								'menuaction'	=> 'workflow.ui_adminjobs.form',
+								'p_id'		=> $myp_id)),
+				'img_jobs'		=> $templateServer->generateImageLink('clock.png'),
+				'color_line'		=> $this->nextmatchs->alternate_row_color($tr_color),
+			));
+			$this->t->parse('items', 'block_items', True);
+		}
+		if (!count($items)) $this->t->set_var('items', '<tr><td colspan="5" align="center">'. lang('There are no processes defined')  .'</td></tr>');
+		$this->translate_template('block_items');
+	}
+
+	/**
+	 * Save or update the current process
+	 * @param string $name name of process
+	 * @param int $version version of process
+	 * @param bool $is_active
+	 * @param array $config_data
+	 * @return int process id
+	 * @access public
+	 */
+	function save_process($name, $version, $description, $is_active, &$config_data)
+	{
+		if (($this->wf_p_id == 0) && $this->process_manager->process_name_exists($name, $version))
+		{
+			$this->message[] = lang('Process name already exists');
+			return false;
+		}
+		else
+		{
+			/* prevent a process to overwrite an existing one */
+			if ($this->wf_p_id != 0)
+			{
+				$processInfo = $this->process_manager->get_process($this->wf_p_id);
+				if (($this->process_manager->_normalize_name($name, $version) != $processInfo['wf_normalized_name']) && $this->process_manager->process_name_exists($name, $version))
+				{
+					$this->message[] = lang('Process name already exists');
+					return false;
+				}
+			}
+
+			$proc_info = array(
+				'wf_name'		=> $name,
+				'wf_description'	=> $description,
+				'wf_version'		=> $version,
+				'wf_is_active'		=> ($is_active == 'on')? 'y' : 'n'
+			);
+			$this->wf_p_id = $this->process_manager->replace_process($this->wf_p_id, $proc_info);
+			$this->save_config($config_data);
+			$valid = $this->activity_manager->validate_process_activities($this->wf_p_id);
+			if (!$valid)
+			{
+				$this->process_manager->deactivate_process($this->wf_p_id);
+			}
+			$this->message[] = lang('Process saved');
+			return $this->wf_p_id;
+		}
+	}
+
+
+	/**
+	 * Save the configuration values for the current process
+	 * This function use the list of known configuration items to parse POSTed config values
+	 * Theses values are passed to the process->SetConfigValues which know well what to do with
+	 * them.
+	 * @param array $global_config_data Global config
+	 * @return void
+	 * @access public
+	 */
+	function save_config(&$global_config_data)
+	{
+		$known_config_items	=& $global_config_data['known_items'];
+		$config_yesno		=& $global_config_data['yesno'];
+		$config_value		=& $global_config_data['value'];
+		$config_use_default	=& $global_config_data['default'];
+		$array_config = array();
+		foreach ($known_config_items as $config_name => $config_type)
+		{
+			if (is_array($config_type))
+			{//case of a select
+				if (isset($config_use_default[$config_name]))
+				{
+					$user_post_value = $config_value[$config_name];
+					if ($user_post_value == 'default')
+					{
+						//user ask for default
+						$array_config[$config_name]=array('int' => -1);
+					}
+					elseif (is_numeric($user_post_value))
+					{
+						$array_config[$config_name]=array('int' => $user_post_value);
+					}
+					else
+					{
+						$array_config[$config_name]=array('text' => $user_post_value);
+					}
+				}
+			}
+			if (!($config_type=='title')) //we do not need titles
+			{
+				if ($config_type=='yesno')
+				{
+					if (isset($config_yesno[$config_name]))
+					{
+						$user_post_value = $config_yesno[$config_name];
+						if ($user_post_value == 'default')
+						{
+							//user ask for default
+							$array_config[$config_name]=array('int' => -1);
+						}
+						elseif ($user_post_value == 'yes')
+						{
+							$array_config[$config_name]=array('int' => 1);
+						}
+						else //no
+						{
+							$array_config[$config_name]=array('int' => 0);
+						}
+					}
+				}
+				else // text config type
+				{
+					if (isset($config_use_default[$config_name]))
+					{
+						//user ask for default
+						$array_config[$config_name]=array('int' => -1);
+					}
+					elseif (isset($config_value[$config_name]))
+					{
+						$user_post_value = $config_value[$config_name];
+						if (is_numeric($user_post_value))
+						{
+							$array_config[$config_name]=array('int' => $user_post_value);
+						}
+						else
+						{
+							$array_config[$config_name]=array('text' => $user_post_value);
+						}
+					}
+				}
+			}
+
+		} // end foreach
+		$this->process_manager->setConfigValues($this->wf_p_id,$array_config);
+	}// end function
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.process_smarty.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.process_smarty.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.process_smarty.inc.php	(revision 795)
@@ -0,0 +1,17 @@
+<?php
+	// include galaxia's configuration tailored to egroupware
+	define('SMART_DIR',PHPGW_SERVER_ROOT.'/workflow/inc/smarty/');
+	require_once('engine/config.egw.inc.php');
+	require_once('smarty/Smarty.class.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class process_smarty extends Smarty
+	{
+		function process_smarty()
+		{
+			$this->Smarty();
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_move_instances.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_move_instances.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_move_instances.inc.php	(revision 2372)
@@ -0,0 +1,344 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+/**
+ * Camada Model para Mover Instâncias.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class so_move_instances
+{
+	/**
+	 * @var bool True se o usuário for administrador do expresso.
+	 * @access private
+	 */
+	private $isAdmin;
+
+	/**
+	 * @var int ID do usuário logado no Expresso
+	 * @access private
+	 */
+	private $userID;
+
+	/**
+	 * @var object Link para a ACL do Workflow.
+	 * @access private
+	 */
+	private $acl;
+
+	/**
+	 * @var object Link para o Banco de Dados do Expresso.
+	 * @access private
+	 */
+	private $db;
+
+	/**
+	 * Checa se o usuário possui direitos administrativos em um processo.
+	 * @param int $processID O ID do processo que se quer checar se o usuário tem direito administrativo.
+	 * @return bool True em caso de sucesso. Em caso de falha, a execução é abortada.
+	 * @access private
+	 */
+	private function _checkAccess($processID = null)
+	{
+		/* the user is an administrator */
+		if ($this->isAdmin)
+			return true;
+
+		if (!is_null($processID))
+		{
+			if ($this->acl->checkUserGroupAccessToResource('PRO', $this->userID, $processID))
+				return true;
+			else
+				die(serialize("Você não tem permissão para executar este procedimento!"));
+		}
+		if ($this->acl->checkUserGroupAccessToType('PRO', $this->userID))
+			return true;
+
+		die(serialize("Você não tem permissão para executar este procedimento!"));
+	}
+
+	/**
+	 * Verifica se houve erro em alguma query do Banco de Dados.
+	 * @param object $result O resultado de alguma query
+	 * @return void
+	 * @access private
+	 */
+	private function _checkError($result)
+	{
+		if ($result === false)
+			die(serialize("Ocorreu um erro ao se tentar executar a operação solicitada."));
+	}
+
+	/**
+	 * Construtor da classe so_move_instances
+	 * @return object
+	 */
+	function so_move_instances()
+	{
+		$this->userID = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$this->isAdmin = $_SESSION['phpgw_info']['workflow']['user_is_admin'];
+		$this->acl =& $GLOBALS['ajax']->acl;
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
+	}
+
+	/**
+	 * Carrega a lista de processos que o usuário tem acesso.
+	 * @return array Lista de processos.
+	 * @access public
+	 */
+	function loadProcesses()
+	{
+		$this->_checkAccess();
+
+		$where = array();
+		if (!$this->isAdmin)
+		{
+			$processIDs = $this->acl->get_granted_processes($this->userID);
+			if (count($processIDs) > 0)
+				$where[] = 'wf_p_id IN (' . implode(',', $processIDs) . ')';
+			else
+				$where[] = 'wf_p_id IS NULL';
+		}
+		$processManager = &Factory::getInstance('ProcessManager', $this->db);
+
+		/* workaround to sort the result using two columns */
+		$items = $processManager->list_processes(0, -1, 'wf_name__ASC, wf_version ASC', '', implode(' AND ', $where));
+		$output = array();
+		foreach ($items['data'] as $item)
+			$output[] = array(
+				'wf_p_id' => $item['wf_p_id'],
+				'wf_name' => $item['wf_name'],
+				'wf_version' => $item['wf_version']);
+
+		return $output;
+	}
+
+	/**
+	 * Carrega a lista de atividades de um processo (com exceção de atividades do tipo Standalone e View).
+	 * @param int $processID O ID do processo do qual se quer a lista de atividades.
+	 * @return array Lista de atividades de um processo.
+	 * @access public
+	 */
+	function loadProcessActivities($processID)
+	{
+		$this->_checkAccess($processID);
+
+		$activityManager = &Factory::newInstance('ActivityManager');
+		$activities = $activityManager->list_activities($processID, 0, -1, 'wf_name__ASC', '', 'wf_type <> \'standalone\' AND wf_type <> \'view\'');
+		$output = array();
+		foreach ($activities['data'] as $activity)
+			$output[] = array(
+				'wf_activity_id' => $activity['wf_activity_id'],
+				'wf_name' => $activity['wf_name'],
+				'wf_type' => $activity['wf_type']);
+		return $output;
+	}
+
+	/**
+	 * Faz um pré-relacionamento das atividades dos dois processos.
+	 * @param array $fromActivities Lista de atividades do processo de origem.
+	 * @param array $toActivities Lista de atividades do processo de destino.
+	 * @param float $threshold Limiar que define a menor porcentagem de semelhança entre o nome de duas atividades para que estas sejam relacionadas.
+	 * @return array Lista de atividades relacionadas.
+	 * @access public
+	 */
+	function matchActivities($fromActivities, $toActivities, $threshold)
+	{
+		$preOutput = array();
+		foreach ($fromActivities as $fromActivity)
+		{
+			$fromActivityName = $fromActivity['wf_name'];
+			$fromActivityID = $fromActivity['wf_activity_id'];
+			foreach ($toActivities as $toActivity)
+			{
+				$toActivityName = $toActivity['wf_name'];
+				$toActivityID = $toActivity['wf_activity_id'];
+				$currentValue = isset($preOutput[$fromActivityID]) ? $preOutput[$fromActivityID]['value'] : 0;
+
+				similar_text($fromActivityName, $toActivityName, $matchValue);
+				if (($matchValue > $threshold) && ($matchValue > $currentValue))
+					$preOutput[$fromActivityID] = array(
+						'activityID' => $toActivityID,
+						'value' => $matchValue);
+			}
+		}
+		$output = array();
+		foreach ($preOutput as $fromActivityID => $toActivityInfo)
+			$output[] = array(
+				'from' => $fromActivityID,
+				'to' => $toActivityInfo['activityID']);
+
+		return $output;
+	}
+
+	/**
+	 * Move as instâncias de um processo para outro.
+	 * @param int $from O ID do processo de origem.
+	 * @param int $to O ID do processo de destino.
+	 * @param bool $active Indica se devem ser movidas as instâncias ativas.
+	 * @param bool $completed Indica se devem ser movidas as instâncias finalizadas.
+	 * @param array $activityMappings O relacionamento entre as atividades dos dois processos.
+	 * @return bool TRUE em caso de sucesso e FALSE caso contrário.
+	 * @access public
+	 */
+	function moveInstances($from, $to, $activityMappings, $active, $completed)
+	{
+		$this->_checkAccess($from);
+		$this->_checkAccess($to);
+
+		if (($active || $completed) == false)
+			return array('error' => 'Nenhuma instância foi movida. Selecione pelo menos uma das checkboxes do status das instâncias.');
+
+		$instanceStatus = array();
+		$instanceActivityStatus = array();
+		if ($active)
+		{
+			$instanceStatus[] = "'active'";
+			$instanceStatus[] = "'exception'";
+			$instanceActivityStatus[] = "'running'";
+		}
+
+		if ($completed)
+		{
+			$instanceStatus[] = "'completed'";
+			$instanceStatus[] = "'aborted'";
+			$instanceActivityStatus[] = "'completed'";
+
+		}
+
+		/* create an array for quick conversion between the old and the new activities ID */
+		$activitiesConvert = array();
+		foreach ($activityMappings as $toActivityID => $fromActivities)
+			foreach ($fromActivities as $fromActivityID)
+				$activitiesConvert[$fromActivityID] = $toActivityID;
+
+		$this->db->StartTrans();
+		$transactionResult = true;
+
+		/* update the instances table */
+		$resultSet = $this->db->query("SELECT wf_instance_id, wf_next_activity, wf_next_user FROM egw_wf_instances WHERE (wf_status IN (" . implode(', ', $instanceStatus) . ")) AND (wf_p_id = ?)", array($from));
+		$rows = $resultSet->GetArray(-1);
+		$instanceList = array();
+		if (is_array($rows))
+		{
+			foreach ($rows as $row)
+			{
+				/* save the ID of the instances for future use */
+				$instanceList[] = $row['wf_instance_id'];
+
+				/* get the data and unserialize them */
+				$oldInstance = array(
+					'wf_instance_id' => $row['wf_instance_id'],
+					'wf_next_activity' => unserialize(base64_decode($row['wf_next_activity'])),
+					'wf_next_user' => unserialize(base64_decode($row['wf_next_user'])));
+
+				/* change the next activity */
+				$newInstance['wf_next_activity'] = array();
+				if (is_array($oldInstance['wf_next_activity']))
+				{
+					foreach ($oldInstance['wf_next_activity'] as $k => $v)
+						$newInstance['wf_next_activity'][$activitiesConvert[$k]] = $activitiesConvert[$v];
+				}
+
+				/* change the next user */
+				$newInstance['wf_next_user'] = array();
+				if (is_array($oldInstance['wf_next_user']))
+				{
+					foreach ($oldInstance['wf_next_user'] as $k => $v)
+						if ($k[0] == '*')
+							$newInstance['wf_next_user']['*' . $activitiesConvert[substr($k, 1)]] = $v;
+						else
+							$newInstance['wf_next_user'][$activitiesConvert[$k]] = $v;
+				}
+
+				/* serialize and encode the data */
+				$newInstance['wf_next_activity'] = base64_encode(serialize($newInstance['wf_next_activity']));
+				$newInstance['wf_next_user'] = base64_encode(serialize($newInstance['wf_next_user']));
+
+				/* update the egw_wf_instances table */
+				if (!$this->db->query("UPDATE egw_wf_instances SET wf_next_activity = ?, wf_next_user = ?, wf_p_id = ? WHERE (wf_instance_id = ?)", array($newInstance['wf_next_activity'], $newInstance['wf_next_user'], $to, $oldInstance['wf_instance_id'])))
+				{
+					$this->db->FailTrans();
+					return array('error' => 'Erro atualizando a tabela de instâncias. Nenhuma modificação foi salva');
+				}
+			}
+		}
+		/* assure at least one element */
+		$instanceList[] = -1;
+
+		/* update the instance_activities table */
+		$instanceActivityList = array();
+		$resultSet = $this->db->query("SELECT wf_instance_id, wf_activity_id FROM egw_wf_instance_activities WHERE (wf_status IN (" . implode(', ', $instanceActivityStatus) . ")) AND (wf_activity_id IN (" . implode(', ', array_keys($activitiesConvert)) . "))");
+		$rows = $resultSet->GetArray(-1);
+		if (is_array($rows))
+		{
+			foreach ($rows as $row)
+			{
+				/* save the instance ID and activity ID pair for future use */
+				$instanceActivityList[] = array(
+					'iid' => $row['wf_instance_id'],
+					'aid' => $row['wf_activity_id']);
+
+				/* update the activity ID */
+				if (!$this->db->query("UPDATE egw_wf_instance_activities SET wf_activity_id = ? WHERE (wf_instance_id = ?) AND (wf_activity_id = ?)", array($activitiesConvert[$row['wf_activity_id']], $row['wf_instance_id'], $row['wf_activity_id'])))
+				{
+					$this->db->FailTrans();
+					return array('error' => 'Erro atualizando a tabela que relaciona instâncias e atividades. Nenhuma modificação foi salva');
+				}
+			}
+		}
+		/* assure at least one element */
+		$instanceActivityList[] = array('iid' => -1, 'aid' => -1);
+
+		/* update the workitems of the modified instances */
+		$resultSet = $this->db->query("SELECT wf_item_id, wf_activity_id FROM egw_wf_workitems WHERE (wf_instance_id IN (" . implode(', ', $instanceList) . "))");
+		$rows = $resultSet->GetArray(-1);
+		if (is_array($rows))
+		{
+			foreach ($rows as $row)
+			{
+				/* update the activity ID */
+				if (!$this->db->query("UPDATE egw_wf_workitems SET wf_activity_id = ? WHERE (wf_item_id = ?)", array($activitiesConvert[$row['wf_activity_id']], $row['wf_item_id'])))
+				{
+					$this->db->FailTrans();
+					return array('error' => 'Erro atualizando a tabela de workitems. Nenhuma modificação foi salva');
+				}
+			}
+		}
+
+		/* format the array elements for use in a SELECT SQL statement, e.g. [iid => 12, aid = 27] would produce (12, 27) */
+		$instanceActivityList = array_map(create_function('$e', 'return \'(\' . $e[\'iid\'] . \', \' . $e[\'aid\'] . \')\';'), $instanceActivityList);
+
+		/* update the interinstance relations of the modified rows of the instance_activities table */
+		$resultSet = $this->db->query("SELECT wf_parent_instance_id, wf_parent_activity_id FROM egw_wf_interinstance_relations WHERE ((wf_parent_instance_id, wf_parent_activity_id) IN (" . implode(', ', $instanceActivityList) . "))");
+		$rows = $resultSet->GetArray(-1);
+		if (is_array($rows))
+		{
+			foreach ($rows as $row)
+			{
+				/* update the activity ID */
+				if (!$this->db->query("UPDATE egw_wf_interinstance_relations SET wf_parent_activity_id = ? WHERE (wf_parent_instance_id = ?) AND (wf_parent_activity_id = ?)", array($activitiesConvert[$row['wf_parent_activity_id']], $row['wf_parent_instance_id'], $row['wf_parent_activity_id'])))
+				{
+					$this->db->FailTrans();
+					return array('error' => 'Erro atualizando a tabela de relacionamento inter-instância. Nenhuma modificação foi salva');
+				}
+			}
+		}
+
+		/* in case of success, commit the modifications */
+		$this->db->CompleteTrans();
+		return true;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/log/Log/error_log.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/error_log.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/error_log.php	(revision 795)
@@ -0,0 +1,160 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/error_log.php,v 1.9 2008/09/20 19:36:41 jon Exp $
+ *
+ * @version $Revision: 1.9 $
+ * @package Log
+ */
+
+/**
+ * The Log_error_log class is a concrete implementation of the Log abstract
+ * class that logs messages using PHP's error_log() function.
+ *
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.7.0
+ * @package Log
+ *
+ * @example error_log.php   Using the error_log handler.
+ */
+class Log_error_log extends Log
+{
+    /**
+     * The error_log() log type.
+     * @var integer
+     * @access private
+     */
+    var $_type = PEAR_LOG_TYPE_SYSTEM;
+
+    /**
+     * The type-specific destination value.
+     * @var string
+     * @access private
+     */
+    var $_destination = '';
+
+    /**
+     * Additional headers to pass to the mail() function when the
+     * PEAR_LOG_TYPE_MAIL type is used.
+     * @var string
+     * @access private
+     */
+    var $_extra_headers = '';
+
+    /**
+     * String containing the format of a log line.
+     * @var string
+     * @access private
+     */
+    var $_lineFormat = '%2$s: %4$s';
+
+    /**
+     * String containing the timestamp format.  It will be passed directly to
+     * strftime().  Note that the timestamp string will generated using the
+     * current locale.
+     * @var string
+     * @access private
+     */
+    var $_timeFormat = '%b %d %H:%M:%S';
+
+    /**
+     * Constructs a new Log_error_log object.
+     *
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_error_log($name, $ident = '', $conf = array(),
+                           $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_type = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (!empty($conf['destination'])) {
+            $this->_destination = $conf['destination'];
+        }
+
+        if (!empty($conf['extra_headers'])) {
+            $this->_extra_headers = $conf['extra_headers'];
+        }
+
+        if (!empty($conf['lineFormat'])) {
+            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
+                                             array_values($this->_formatMap),
+                                             $conf['lineFormat']);
+        }
+
+        if (!empty($conf['timeFormat'])) {
+            $this->_timeFormat = $conf['timeFormat'];
+        }
+    }
+
+    /**
+     * Opens the handler.
+     *
+     * @access  public
+     * @since   Log 1.9.6
+     */
+    function open()
+    {
+        $this->_opened = true;
+        return true;
+    }
+
+    /**
+     * Closes the handler.
+     *
+     * @access  public
+     * @since   Log 1.9.6
+     */
+    function close()
+    {
+        $this->_opened = false;
+        return true;
+    }
+
+    /**
+     * Logs $message using PHP's error_log() function.  The message is also
+     * passed along to any Log_observer instances that are observing this Log.
+     *
+     * @param mixed  $message   String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build the string containing the complete log line. */
+        $line = $this->_format($this->_lineFormat,
+                               strftime($this->_timeFormat),
+                               $priority, $message);
+
+        /* Pass the log line and parameters to the error_log() function. */
+        $success = error_log($line, $this->_type, $this->_destination,
+                             $this->_extra_headers);
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return $success;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/win.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/win.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/win.php	(revision 795)
@@ -0,0 +1,269 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/win.php,v 1.21 2008/11/12 05:07:31 jon Exp $
+ *
+ * @version $Revision: 1.21 $
+ * @package Log
+ */
+
+/**
+ * The Log_win class is a concrete implementation of the Log abstract
+ * class that logs messages to a separate browser window.
+ *
+ * The concept for this log handler is based on part by Craig Davis' article
+ * entitled "JavaScript Power PHP Debugging:
+ *
+ *  http://www.zend.com/zend/tut/tutorial-DebugLib.php
+ *
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.7.0
+ * @package Log
+ *
+ * @example win.php     Using the window handler.
+ */
+class Log_win extends Log
+{
+    /**
+     * The name of the output window.
+     * @var string
+     * @access private
+     */
+    var $_name = 'LogWindow';
+
+    /**
+     * The title of the output window.
+     * @var string
+     * @access private
+     */
+    var $_title = 'Log Output Window';
+
+    /**
+     * Mapping of log priorities to styles.
+     * @var array
+     * @access private
+     */
+    var $_styles = array(
+                        PEAR_LOG_EMERG   => 'color: red;',
+                        PEAR_LOG_ALERT   => 'color: orange;',
+                        PEAR_LOG_CRIT    => 'color: yellow;',
+                        PEAR_LOG_ERR     => 'color: green;',
+                        PEAR_LOG_WARNING => 'color: blue;',
+                        PEAR_LOG_NOTICE  => 'color: indigo;',
+                        PEAR_LOG_INFO    => 'color: violet;',
+                        PEAR_LOG_DEBUG   => 'color: black;'
+                    );
+
+    /**
+     * String buffer that holds line that are pending output.
+     * @var array
+     * @access private
+     */
+    var $_buffer = array();
+
+    /**
+     * Constructs a new Log_win object.
+     *
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_win($name, $ident = '', $conf = array(),
+                          $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_name = str_replace(' ', '_', $name);
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (isset($conf['title'])) {
+            $this->_title = $conf['title'];
+        }
+        if (isset($conf['styles']) && is_array($conf['styles'])) {
+            $this->_styles = $conf['styles'];
+        }
+        if (isset($conf['colors']) && is_array($conf['colors'])) {
+            foreach ($conf['colors'] as $level => $color) {
+                $this->_styles[$level] .= "color: $color;";
+            }
+        }
+
+        register_shutdown_function(array(&$this, '_Log_win'));
+    }
+
+    /**
+     * Destructor
+     */
+    function _Log_win()
+    {
+        if ($this->_opened || (count($this->_buffer) > 0)) {
+            $this->close();
+        }
+    }
+
+    /**
+     * The first time open() is called, it will open a new browser window and
+     * prepare it for output.
+     *
+     * This is implicitly called by log(), if necessary.
+     *
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            $win = $this->_name;
+            $styles = $this->_styles;
+
+            if (!empty($this->_ident)) {
+                $identHeader = "$win.document.writeln('<th>Ident</th>')";
+            } else {
+                $identHeader = '';
+            }
+
+            echo <<< EOT
+<script language="JavaScript">
+$win = window.open('', '{$this->_name}', 'toolbar=no,scrollbars,width=600,height=400');
+$win.document.writeln('<html>');
+$win.document.writeln('<head>');
+$win.document.writeln('<title>{$this->_title}</title>');
+$win.document.writeln('<style type="text/css">');
+$win.document.writeln('body { font-family: monospace; font-size: 8pt; }');
+$win.document.writeln('td,th { font-size: 8pt; }');
+$win.document.writeln('td,th { border-bottom: #999999 solid 1px; }');
+$win.document.writeln('td,th { border-right: #999999 solid 1px; }');
+$win.document.writeln('tr { text-align: left; vertical-align: top; }');
+$win.document.writeln('td.l0 { $styles[0] }');
+$win.document.writeln('td.l1 { $styles[1] }');
+$win.document.writeln('td.l2 { $styles[2] }');
+$win.document.writeln('td.l3 { $styles[3] }');
+$win.document.writeln('td.l4 { $styles[4] }');
+$win.document.writeln('td.l5 { $styles[5] }');
+$win.document.writeln('td.l6 { $styles[6] }');
+$win.document.writeln('td.l7 { $styles[7] }');
+$win.document.writeln('</style>');
+$win.document.writeln('</head>');
+$win.document.writeln('<body>');
+$win.document.writeln('<table border="0" cellpadding="2" cellspacing="0">');
+$win.document.writeln('<tr><th>Time</th>');
+$identHeader
+$win.document.writeln('<th>Priority</th><th width="100%">Message</th></tr>');
+</script>
+EOT;
+            $this->_opened = true;
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the output stream if it is open.  If there are still pending
+     * lines in the output buffer, the output window will be opened so that
+     * the buffer can be drained.
+     *
+     * @access public
+     */
+    function close()
+    {
+        /*
+         * If there are still lines waiting to be written, open the output
+         * window so that we can drain the buffer.
+         */
+        if (!$this->_opened && (count($this->_buffer) > 0)) {
+            $this->open();
+        }
+
+        if ($this->_opened) {
+            $this->_writeln('</table>');
+            $this->_writeln('</body></html>');
+            $this->_opened = false;
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Writes a single line of text to the output window.
+     *
+     * @param string    $line   The line of text to write.
+     *
+     * @access private
+     */
+    function _writeln($line)
+    {
+        /* Add this line to our output buffer. */
+        $this->_buffer[] = $line;
+
+        /* Buffer the output until this page's headers have been sent. */
+        if (!headers_sent()) {
+            return;
+        }
+
+        /* If we haven't already opened the output window, do so now. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* Drain the buffer to the output window. */
+        $win = $this->_name;
+        foreach ($this->_buffer as $line) {
+            echo "<script language='JavaScript'>\n";
+            echo "$win.document.writeln('" . addslashes($line) . "');\n";
+            echo "self.focus();\n";
+            echo "</script>\n";
+        }
+
+        /* Now that the buffer has been drained, clear it. */
+        $this->_buffer = array();
+    }
+
+    /**
+     * Logs $message to the output window.  The message is also passed along
+     * to any Log_observer instances that are observing this Log.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+        $message = preg_replace('/\r\n|\n|\r/', '<br />', $message);
+
+        list($usec, $sec) = explode(' ', microtime());
+
+        /* Build the output line that contains the log entry row. */
+        $line  = '<tr>';
+        $line .= sprintf('<td>%s.%s</td>',
+                         strftime('%H:%M:%S', $sec), substr($usec, 2, 2));
+        if (!empty($this->_ident)) {
+            $line .= '<td>' . $this->_ident . '</td>';
+        }
+        $line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>';
+        $line .= sprintf('<td class="l%d">%s</td>', $priority, $message);
+        $line .= '</tr>';
+
+        $this->_writeln($line);
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/sql.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/sql.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/sql.php	(revision 795)
@@ -0,0 +1,294 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/sql.php,v 1.42 2008/01/19 22:12:16 jon Exp $
+ * $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $
+ *
+ * @version $Revision: 1.42 $
+ * @package Log
+ */
+
+/**
+ * We require the PEAR DB class.  This is generally defined in the DB.php file,
+ * but it's possible that the caller may have provided the DB class, or a
+ * compatible wrapper (such as the one shipped with MDB2), so we first check
+ * for an existing 'DB' class before including 'DB.php'.
+ */
+if (!class_exists('DB')) {
+    require_once 'DB.php';
+}
+
+/**
+ * The Log_sql class is a concrete implementation of the Log::
+ * abstract class which sends messages to an SQL server.  Each entry
+ * occupies a separate row in the database.
+ *
+ * This implementation uses PHP's PEAR database abstraction layer.
+ *
+ * CREATE TABLE log_table (
+ *  id          INT NOT NULL,
+ *  logtime     TIMESTAMP NOT NULL,
+ *  ident       CHAR(16) NOT NULL,
+ *  priority    INT NOT NULL,
+ *  message     VARCHAR(200),
+ *  PRIMARY KEY (id)
+ * );
+ *
+ * @author  Jon Parise <jon@php.net>
+ * @since   Horde 1.3
+ * @since   Log 1.0
+ * @package Log
+ *
+ * @example sql.php     Using the SQL handler.
+ */
+class Log_sql extends Log
+{
+    /**
+     * Variable containing the DSN information.
+     * @var mixed
+     * @access private
+     */
+    var $_dsn = '';
+
+    /**
+     * String containing the SQL insertion statement.
+     *
+     * @var string
+     * @access private
+     */
+    var $_sql = '';
+
+    /**
+     * Array containing our set of DB configuration options.
+     * @var array
+     * @access private
+     */
+    var $_options = array('persistent' => true);
+
+    /**
+     * Object holding the database handle.
+     * @var object
+     * @access private
+     */
+    var $_db = null;
+
+    /**
+     * Resource holding the prepared statement handle.
+     * @var resource
+     * @access private
+     */
+    var $_statement = null;
+
+    /**
+     * Flag indicating that we're using an existing database connection.
+     * @var boolean
+     * @access private
+     */
+    var $_existingConnection = false;
+
+    /**
+     * String holding the database table to use.
+     * @var string
+     * @access private
+     */
+    var $_table = 'log_table';
+
+    /**
+     * String holding the name of the ID sequence.
+     * @var string
+     * @access private
+     */
+    var $_sequence = 'log_id';
+
+    /**
+     * Maximum length of the $ident string.  This corresponds to the size of
+     * the 'ident' column in the SQL table.
+     * @var integer
+     * @access private
+     */
+    var $_identLimit = 16;
+
+
+    /**
+     * Constructs a new sql logging object.
+     *
+     * @param string $name         The target SQL table.
+     * @param string $ident        The identification field.
+     * @param array $conf          The connection configuration array.
+     * @param int $level           Log messages up to and including this level.
+     * @access public
+     */
+    function Log_sql($name, $ident = '', $conf = array(),
+                     $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_table = $name;
+        $this->_mask = Log::UPTO($level);
+
+        /* Now that we have a table name, assign our SQL statement. */
+        if (!empty($conf['sql'])) {
+            $this->_sql = $conf['sql'];
+        } else {
+            $this->_sql = 'INSERT INTO ' . $this->_table .
+                          ' (id, logtime, ident, priority, message)' .
+                          ' VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)';
+        }
+
+        /* If an options array was provided, use it. */
+        if (isset($conf['options']) && is_array($conf['options'])) {
+            $this->_options = $conf['options'];
+        }
+
+        /* If a specific sequence name was provided, use it. */
+        if (!empty($conf['sequence'])) {
+            $this->_sequence = $conf['sequence'];
+        }
+
+        /* If a specific sequence name was provided, use it. */
+        if (isset($conf['identLimit'])) {
+            $this->_identLimit = $conf['identLimit'];
+        }
+
+        /* Now that the ident limit is confirmed, set the ident string. */
+        $this->setIdent($ident);
+
+        /* If an existing database connection was provided, use it. */
+        if (isset($conf['db'])) {
+            $this->_db = &$conf['db'];
+            $this->_existingConnection = true;
+            $this->_opened = true;
+        } else {
+            $this->_dsn = $conf['dsn'];
+        }
+    }
+
+    /**
+     * Opens a connection to the database, if it has not already
+     * been opened. This is implicitly called by log(), if necessary.
+     *
+     * @return boolean   True on success, false on failure.
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            /* Use the DSN and options to create a database connection. */
+            $this->_db = &DB::connect($this->_dsn, $this->_options);
+            if (DB::isError($this->_db)) {
+                return false;
+            }
+
+            /* Create a prepared statement for repeated use in log(). */
+            if (!$this->_prepareStatement()) {
+                return false;
+            }
+
+            /* We now consider out connection open. */
+            $this->_opened = true;
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the connection to the database if it is still open and we were
+     * the ones that opened it.  It is the caller's responsible to close an
+     * existing connection that was passed to us via $conf['db'].
+     *
+     * @return boolean   True on success, false on failure.
+     * @access public
+     */
+    function close()
+    {
+        if ($this->_opened && !$this->_existingConnection) {
+            $this->_opened = false;
+            $this->_db->freePrepared($this->_statement);
+            return $this->_db->disconnect();
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Sets this Log instance's identification string.  Note that this
+     * SQL-specific implementation will limit the length of the $ident string
+     * to sixteen (16) characters.
+     *
+     * @param string    $ident      The new identification string.
+     *
+     * @access  public
+     * @since   Log 1.8.5
+     */
+    function setIdent($ident)
+    {
+        $this->_ident = substr($ident, 0, $this->_identLimit);
+    }
+
+    /**
+     * Inserts $message to the currently open database.  Calls open(),
+     * if necessary.  Also passes the message along to any Log_observer
+     * instances that are observing this Log.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the connection isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* If we don't already have our statement object yet, create it. */
+        if (!is_object($this->_statement) && !$this->_prepareStatement()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build our set of values for this log entry. */
+        $id = $this->_db->nextId($this->_sequence);
+        $values = array($id, $this->_ident, $priority, $message);
+
+        /* Execute the SQL query for this log entry insertion. */
+        $result =& $this->_db->execute($this->_statement, $values);
+        if (DB::isError($result)) {
+            return false;
+        }
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+    /**
+     * Prepare the SQL insertion statement.
+     *
+     * @return boolean  True if the statement was successfully created.
+     *
+     * @access  private
+     * @since   Log 1.9.1
+     */
+    function _prepareStatement()
+    {
+        $this->_statement = $this->_db->prepare($this->_sql);
+
+        /* Return success if we didn't generate an error. */
+        return (DB::isError($this->_statement) === false);
+    }
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/sqlite.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/sqlite.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/sqlite.php	(revision 795)
@@ -0,0 +1,225 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/sqlite.php,v 1.5 2005/12/05 05:38:31 jon Exp $
+ *
+ * @version $Revision: 1.5 $
+ * @package Log
+ */
+
+/**
+ * The Log_sqlite class is a concrete implementation of the Log::
+ * abstract class which sends messages to an Sqlite database.
+ * Each entry occupies a separate row in the database.
+ *
+ * This implementation uses PHP native Sqlite functions.
+ *
+ * CREATE TABLE log_table (
+ *  id          INTEGER PRIMARY KEY NOT NULL,
+ *  logtime     NOT NULL,
+ *  ident       CHAR(16) NOT NULL,
+ *  priority    INT NOT NULL,
+ *  message
+ * );
+ *
+ * @author  Bertrand Mansion <bmansion@mamasam.com>
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.8.3
+ * @package Log
+ *
+ * @example sqlite.php      Using the Sqlite handler.
+ */
+class Log_sqlite extends Log
+{
+    /**
+     * Array containing the connection defaults
+     * @var array
+     * @access private
+     */
+    var $_options = array('mode'       => 0666,
+                          'persistent' => false);
+
+    /**
+     * Object holding the database handle.
+     * @var object
+     * @access private
+     */
+    var $_db = null;
+
+    /**
+     * Flag indicating that we're using an existing database connection.
+     * @var boolean
+     * @access private
+     */
+    var $_existingConnection = false;
+
+    /**
+     * String holding the database table to use.
+     * @var string
+     * @access private
+     */
+    var $_table = 'log_table';
+
+
+    /**
+     * Constructs a new sql logging object.
+     *
+     * @param string $name         The target SQL table.
+     * @param string $ident        The identification field.
+     * @param mixed  $conf         Can be an array of configuration options used
+     *                             to open a new database connection
+     *                             or an already opened sqlite connection.
+     * @param int    $level        Log messages up to and including this level.
+     * @access public
+     */
+    function Log_sqlite($name, $ident = '', &$conf, $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_table = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (is_array($conf)) {
+            foreach ($conf as $k => $opt) {
+                $this->_options[$k] = $opt;
+            }
+        } else {
+            // If an existing database connection was provided, use it.
+            $this->_db =& $conf;
+            $this->_existingConnection = true;
+        }
+    }
+
+    /**
+     * Opens a connection to the database, if it has not already
+     * been opened. This is implicitly called by log(), if necessary.
+     *
+     * @return boolean   True on success, false on failure.
+     * @access public
+     */
+    function open()
+    {
+        if (is_resource($this->_db)) {
+            $this->_opened = true;
+            return $this->_createTable();
+        } else {
+            /* Set the connection function based on the 'persistent' option. */
+            if (empty($this->_options['persistent'])) {
+                $connectFunction = 'sqlite_open';
+            } else {
+                $connectFunction = 'sqlite_popen';
+            }
+
+            /* Attempt to connect to the database. */
+            if ($this->_db = $connectFunction($this->_options['filename'],
+                                              (int)$this->_options['mode'],
+                                              $error)) {
+                $this->_opened = true;
+                return $this->_createTable();
+            }
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the connection to the database if it is still open and we were
+     * the ones that opened it.  It is the caller's responsible to close an
+     * existing connection that was passed to us via $conf['db'].
+     *
+     * @return boolean   True on success, false on failure.
+     * @access public
+     */
+    function close()
+    {
+        /* We never close existing connections. */
+        if ($this->_existingConnection) {
+            return false;
+        }
+
+        if ($this->_opened) {
+            $this->_opened = false;
+            sqlite_close($this->_db);
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Inserts $message to the currently open database.  Calls open(),
+     * if necessary.  Also passes the message along to any Log_observer
+     * instances that are observing this Log.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the connection isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        // Extract the string representation of the message.
+        $message = $this->_extractMessage($message);
+
+        // Build the SQL query for this log entry insertion.
+        $q = sprintf('INSERT INTO [%s] (logtime, ident, priority, message) ' .
+                     "VALUES ('%s', '%s', %d, '%s')",
+                     $this->_table,
+                     strftime('%Y-%m-%d %H:%M:%S', time()),
+                     sqlite_escape_string($this->_ident),
+                     $priority,
+                     sqlite_escape_string($message));
+        if (!($res = @sqlite_unbuffered_query($this->_db, $q))) {
+            return false;
+        }
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+    /**
+     * Checks whether the log table exists and creates it if necessary.
+     *
+     * @return boolean  True on success or false on failure.
+     * @access private
+     */
+    function _createTable()
+    {
+        $q = "SELECT name FROM sqlite_master WHERE name='" . $this->_table .
+             "' AND type='table'";
+
+        $res = sqlite_query($this->_db, $q);
+
+        if (sqlite_num_rows($res) == 0) {
+            $q = 'CREATE TABLE [' . $this->_table . '] (' .
+                 'id INTEGER PRIMARY KEY NOT NULL, ' .
+                 'logtime NOT NULL, ' .
+                 'ident CHAR(16) NOT NULL, ' .
+                 'priority INT NOT NULL, ' .
+                 'message)';
+
+            if (!($res = sqlite_unbuffered_query($this->_db, $q))) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/composite.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/composite.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/composite.php	(revision 795)
@@ -0,0 +1,231 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/composite.php,v 1.28 2006/06/29 07:12:34 jon Exp $
+ * $Horde: horde/lib/Log/composite.php,v 1.2 2000/06/28 21:36:13 jon Exp $
+ *
+ * @version $Revision: 1.28 $
+ * @package Log
+ */
+
+/**
+ * The Log_composite:: class implements a Composite pattern which
+ * allows multiple Log implementations to receive the same events.
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @author  Jon Parise <jon@php.net>
+ *
+ * @since Horde 1.3
+ * @since Log 1.0
+ * @package Log
+ *
+ * @example composite.php   Using the composite handler.
+ */
+class Log_composite extends Log
+{
+    /**
+     * Array holding all of the Log instances to which log events should be
+     * sent.
+     *
+     * @var array
+     * @access private
+     */
+    var $_children = array();
+
+
+    /**
+     * Constructs a new composite Log object.
+     *
+     * @param boolean   $name       This parameter is ignored.
+     * @param boolean   $ident      This parameter is ignored.
+     * @param boolean   $conf       This parameter is ignored.
+     * @param boolean   $level      This parameter is ignored.
+     *
+     * @access public
+     */
+    function Log_composite($name, $ident = '', $conf = array(),
+                           $level = PEAR_LOG_DEBUG)
+    {
+        $this->_ident = $ident;
+    }
+
+    /**
+     * Opens all of the child instances.
+     *
+     * @return  True if all of the child instances were successfully opened.
+     *
+     * @access public
+     */
+    function open()
+    {
+        /* Attempt to open each of our children. */
+        $this->_opened = true;
+        foreach ($this->_children as $id => $child) {
+            $this->_opened &= $this->_children[$id]->open();
+        }
+
+        /* If all children were opened, return success. */
+        return $this->_opened;
+    }
+
+    /**
+     * Closes all of the child instances.
+     *
+     * @return  True if all of the child instances were successfully closed.
+     *
+     * @access public
+     */
+    function close()
+    {
+        /* Attempt to close each of our children. */
+        $closed = true;
+        foreach ($this->_children as $id => $child) {
+            $closed &= $this->_children[$id]->close();
+        }
+
+        /* Track the _opened state for consistency. */
+        $this->_opened = false;
+
+        /* If all children were closed, return success. */
+        return $closed;
+    }
+
+    /**
+     * Flushes all child instances.  It is assumed that all of the children
+     * have been successfully opened.
+     *
+     * @return  True if all of the child instances were successfully flushed.
+     *
+     * @access public
+     * @since Log 1.8.2
+     */
+    function flush()
+    {
+        /* Attempt to flush each of our children. */
+        $flushed = true;
+        foreach ($this->_children as $id => $child) {
+            $flushed &= $this->_children[$id]->flush();
+        }
+
+        /* If all children were flushed, return success. */
+        return $flushed;
+    }
+
+    /**
+     * Sends $message and $priority to each child of this composite.  If the
+     * children aren't already open, they will be opened here.
+     *
+     * @param mixed     $message    String or object containing the message
+     *                              to log.
+     * @param string    $priority   (optional) The priority of the message.
+     *                              Valid values are: PEAR_LOG_EMERG,
+     *                              PEAR_LOG_ALERT, PEAR_LOG_CRIT,
+     *                              PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                              PEAR_LOG_NOTICE, PEAR_LOG_INFO, and
+     *                              PEAR_LOG_DEBUG.
+     *
+     * @return boolean  True if the entry is successfully logged.
+     *
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /*
+         * If the handlers haven't been opened, attempt to open them now.
+         * However, we don't treat failure to open all of the handlers as a
+         * fatal error.  We defer that consideration to the success of calling
+         * each handler's log() method below.
+         */
+        if (!$this->_opened) {
+            $this->open();
+        }
+
+        /* Attempt to log the event using each of the children. */
+        $success = true;
+        foreach ($this->_children as $id => $child) {
+            $success &= $this->_children[$id]->log($message, $priority);
+        }
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        /* Return success if all of the children logged the event. */
+        return $success;
+    }
+
+    /**
+     * Returns true if this is a composite.
+     *
+     * @return boolean  True if this is a composite class.
+     *
+     * @access public
+     */
+    function isComposite()
+    {
+        return true;
+    }
+
+    /**
+     * Sets this identification string for all of this composite's children.
+     *
+     * @param string    $ident      The new identification string.
+     *
+     * @access public
+     * @since  Log 1.6.7
+     */
+    function setIdent($ident)
+    {
+        /* Call our base class's setIdent() method. */
+        parent::setIdent($ident);
+
+        /* ... and then call setIdent() on all of our children. */
+        foreach ($this->_children as $id => $child) {
+            $this->_children[$id]->setIdent($ident);
+        }
+    }
+
+    /**
+     * Adds a Log instance to the list of children.
+     *
+     * @param object    $child      The Log instance to add.
+     *
+     * @return boolean  True if the Log instance was successfully added.
+     *
+     * @access public
+     */
+    function addChild(&$child)
+    {
+        /* Make sure this is a Log instance. */
+        if (!is_a($child, 'Log')) {
+            return false;
+        }
+
+        $this->_children[$child->_id] = &$child;
+
+        return true;
+    }
+
+    /**
+     * Removes a Log instance from the list of children.
+     *
+     * @param object    $child      The Log instance to remove.
+     *
+     * @return boolean  True if the Log instance was successfully removed.
+     *
+     * @access public
+     */
+    function removeChild($child)
+    {
+        if (!is_a($child, 'Log') || !isset($this->_children[$child->_id])) {
+            return false;
+        }
+
+        unset($this->_children[$child->_id]);
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/console.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/console.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/console.php	(revision 795)
@@ -0,0 +1,208 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/console.php,v 1.24 2006/12/07 04:15:02 jon Exp $
+ *
+ * @version $Revision: 1.24 $
+ * @package Log
+ */
+
+/**
+ * The Log_console class is a concrete implementation of the Log::
+ * abstract class which writes message to the text console.
+ * 
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.1
+ * @package Log
+ *
+ * @example console.php     Using the console handler.
+ */
+class Log_console extends Log
+{
+    /**
+     * Handle to the current output stream.
+     * @var resource
+     * @access private
+     */
+    var $_stream = STDOUT;
+
+    /**
+     * Should the output be buffered or displayed immediately?
+     * @var string
+     * @access private
+     */
+    var $_buffering = false;
+
+    /**
+     * String holding the buffered output.
+     * @var string
+     * @access private
+     */
+    var $_buffer = '';
+
+    /**
+     * String containing the format of a log line.
+     * @var string
+     * @access private
+     */
+    var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
+
+    /**
+     * String containing the timestamp format.  It will be passed directly to
+     * strftime().  Note that the timestamp string will generated using the
+     * current locale.
+     * @var string
+     * @access private
+     */
+    var $_timeFormat = '%b %d %H:%M:%S';
+
+    /**
+     * Constructs a new Log_console object.
+     * 
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_console($name, $ident = '', $conf = array(),
+                         $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (!empty($conf['stream'])) {
+            $this->_stream = $conf['stream'];
+        }
+
+        if (isset($conf['buffering'])) {
+            $this->_buffering = $conf['buffering'];
+        }
+
+        if (!empty($conf['lineFormat'])) {
+            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
+                                             array_values($this->_formatMap),
+                                             $conf['lineFormat']);
+        }
+
+        if (!empty($conf['timeFormat'])) {
+            $this->_timeFormat = $conf['timeFormat'];
+        }
+
+        /*
+         * If output buffering has been requested, we need to register a
+         * shutdown function that will dump the buffer upon termination.
+         */
+        if ($this->_buffering) {
+            register_shutdown_function(array(&$this, '_Log_console'));
+        }
+    }
+
+    /**
+     * Destructor
+     */
+    function _Log_console()
+    {
+        $this->close();
+    }
+
+    /**
+     * Open the output stream.
+     *
+     * @access public
+     * @since Log 1.9.7
+     */
+    function open()
+    {
+        $this->_opened = true;
+        return true;
+    }
+
+    /**
+     * Closes the output stream.
+     *
+     * This results in a call to flush().
+     *
+     * @access public
+     * @since Log 1.9.0
+     */
+    function close()
+    {
+        $this->flush();
+        $this->_opened = false;
+        return true;
+    }
+
+    /**
+     * Flushes all pending ("buffered") data to the output stream.
+     *
+     * @access public
+     * @since Log 1.8.2
+     */
+    function flush()
+    {
+        /*
+         * If output buffering is enabled, dump the contents of the buffer to
+         * the output stream.
+         */
+        if ($this->_buffering && (strlen($this->_buffer) > 0)) {
+            fwrite($this->_stream, $this->_buffer);
+            $this->_buffer = '';
+        }
+ 
+        if (is_resource($this->_stream)) {
+            return fflush($this->_stream);
+        }
+
+        return false;
+    }
+
+    /**
+     * Writes $message to the text console. Also, passes the message
+     * along to any Log_observer instances that are observing this Log.
+     * 
+     * @param mixed  $message    String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build the string containing the complete log line. */
+        $line = $this->_format($this->_lineFormat,
+                               strftime($this->_timeFormat),
+                               $priority, $message) . "\n";
+
+        /*
+         * If buffering is enabled, append this line to the output buffer.
+         * Otherwise, print the line to the output stream immediately.
+         */
+        if ($this->_buffering) {
+            $this->_buffer .= $line;
+        } else {
+            fwrite($this->_stream, $line);
+        }
+
+        /* Notify observers about this log message. */
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/daemon.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/daemon.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/daemon.php	(revision 795)
@@ -0,0 +1,235 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/daemon.php,v 1.3 2008/01/19 22:12:16 jon Exp $
+ *
+ * @version $Revision: 1.3 $
+ * @package Log
+ */
+
+/**
+ * The Log_daemon class is a concrete implementation of the Log::
+ * abstract class which sends messages to syslog daemon on UNIX-like machines.
+ * This class uses the syslog protocol: http://www.ietf.org/rfc/rfc3164.txt
+ *
+ * @author  Bart van der Schans <schans@dds.nl>
+ * @version $Revision: 1.3 $
+ * @package Log
+ */
+class Log_daemon extends Log
+{
+    /**
+     * Integer holding the log facility to use.
+     * @var string
+     */
+    var $_name = LOG_DAEMON;
+
+    /**
+     * Var holding the resource pointer to the socket
+     * @var resource
+     */
+    var $_socket;
+
+    /**
+     * The ip address or servername
+     * @see http://www.php.net/manual/en/transports.php
+     * @var string
+     */
+    var $_ip = '127.0.0.1';
+
+    /**
+     * Protocol to use (tcp, udp, etc.)
+     * @see http://www.php.net/manual/en/transports.php
+     * @var string
+     */
+    var $_proto = 'udp';
+
+    /**
+     * Port to connect to
+     * @var int
+     */
+    var $_port = 514;
+
+    /**
+     * Maximum message length in bytes
+     * @var int
+     */
+    var $_maxsize = 4096;
+
+    /**
+     * Socket timeout in seconds
+     * @var int
+     */
+    var $_timeout = 1;
+
+
+    /**
+     * Constructs a new syslog object.
+     *
+     * @param string $name     The syslog facility.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $maxLevel Maximum level at which to log.
+     * @access public
+     */
+    function Log_daemon($name, $ident = '', $conf = array(),
+                        $level = PEAR_LOG_DEBUG)
+    {
+        /* Ensure we have a valid integer value for $name. */
+        if (empty($name) || !is_int($name)) {
+            $name = LOG_SYSLOG;
+        }
+
+        $this->_id = md5(microtime());
+        $this->_name = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (isset($conf['ip'])) {
+            $this->_ip = $conf['ip'];
+        }
+        if (isset($conf['proto'])) {
+            $this->_proto = $conf['proto'];
+        }
+        if (isset($conf['port'])) {
+            $this->_port = $conf['port'];
+        }
+        if (isset($conf['maxsize'])) {
+            $this->_maxsize = $conf['maxsize'];
+        }
+        if (isset($conf['timeout'])) {
+            $this->_timeout = $conf['timeout'];
+        }
+        $this->_proto = $this->_proto . '://';
+
+        register_shutdown_function(array(&$this, '_Log_daemon'));
+    }
+
+    /**
+     * Destructor.
+     *
+     * @access private
+     */
+    function _Log_daemon()
+    {
+        $this->close();
+    }
+
+    /**
+     * Opens a connection to the system logger, if it has not already
+     * been opened.  This is implicitly called by log(), if necessary.
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            $this->_opened = (bool)($this->_socket = @fsockopen(
+                                                $this->_proto . $this->_ip,
+                                                $this->_port,
+                                                $errno,
+                                                $errstr,
+                                                $this->_timeout));
+        }
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the connection to the system logger, if it is open.
+     * @access public
+     */
+    function close()
+    {
+        if ($this->_opened) {
+            $this->_opened = false;
+            return fclose($this->_socket);
+        }
+        return true;
+    }
+
+    /**
+     * Sends $message to the currently open syslog connection.  Calls
+     * open() if necessary. Also passes the message along to any Log_observer
+     * instances that are observing this Log.
+     *
+     * @param string $message  The textual message to be logged.
+     * @param int $priority (optional) The priority of the message.  Valid
+     *                  values are: LOG_EMERG, LOG_ALERT, LOG_CRIT,
+     *                  LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO,
+     *                  and LOG_DEBUG.  The default is LOG_INFO.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the connection isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Set the facility level. */
+        $facility_level = intval($this->_name) +
+                          intval($this->_toSyslog($priority));
+
+        /* Prepend ident info. */
+        if (!empty($this->_ident)) {
+            $message = $this->_ident . ' ' . $message;
+        }
+
+        /* Check for message length. */
+        if (strlen($message) > $this->_maxsize) {
+            $message = substr($message, 0, ($this->_maxsize) - 10) . ' [...]';
+        }
+
+        /* Write to socket. */
+        fwrite($this->_socket, '<' . $facility_level . '>' . $message . "\n");
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+    }
+
+    /**
+     * Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
+     *
+     * This function exists because, under Windows, not all of the LOG_*
+     * constants have unique values.  Instead, the PEAR_LOG_* were introduced
+     * for global use, with the conversion to the LOG_* constants kept local to
+     * to the syslog driver.
+     *
+     * @param int $priority     PEAR_LOG_* value to convert to LOG_* value.
+     *
+     * @return  The LOG_* representation of $priority.
+     *
+     * @access private
+     */
+    function _toSyslog($priority)
+    {
+        static $priorities = array(
+            PEAR_LOG_EMERG   => LOG_EMERG,
+            PEAR_LOG_ALERT   => LOG_ALERT,
+            PEAR_LOG_CRIT    => LOG_CRIT,
+            PEAR_LOG_ERR     => LOG_ERR,
+            PEAR_LOG_WARNING => LOG_WARNING,
+            PEAR_LOG_NOTICE  => LOG_NOTICE,
+            PEAR_LOG_INFO    => LOG_INFO,
+            PEAR_LOG_DEBUG   => LOG_DEBUG
+        );
+
+        /* If we're passed an unknown priority, default to LOG_INFO. */
+        if (!is_int($priority) || !in_array($priority, $priorities)) {
+            return LOG_INFO;
+        }
+
+        return $priorities[$priority];
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/display.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/display.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/display.php	(revision 795)
@@ -0,0 +1,161 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/display.php,v 1.11 2008/03/20 16:03:57 jon Exp $
+ *
+ * @version $Revision: 1.11 $
+ * @package Log
+ */
+
+/**
+ * The Log_display class is a concrete implementation of the Log::
+ * abstract class which writes message into browser in usual PHP maner.
+ * This may be useful because when you use PEAR::setErrorHandling in
+ * PEAR_ERROR_CALLBACK mode error messages are not displayed by
+ * PHP error handler.
+ *
+ * @author  Paul Yanchenko <pusher@inaco.ru>
+ * @since   Log 1.8.0
+ * @package Log
+ *
+ * @example display.php     Using the display handler.
+ */
+class Log_display extends Log
+{
+    /**
+     * String containing the format of a log line.
+     * @var string
+     * @access private
+     */
+    var $_lineFormat = '<b>%3$s</b>: %4$s';
+
+    /**
+     * String containing the timestamp format.  It will be passed directly to
+     * strftime().  Note that the timestamp string will generated using the
+     * current locale.
+     * @var string
+     * @access private
+     */
+    var $_timeFormat = '%b %d %H:%M:%S';
+
+    /**
+     * Constructs a new Log_display object.
+     *
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_display($name = '', $ident = '', $conf = array(),
+                         $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        /* Start by configuring the line format. */
+        if (!empty($conf['lineFormat'])) {
+            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
+                                             array_values($this->_formatMap),
+                                             $conf['lineFormat']);
+        }
+
+        /* We may need to prepend a string to our line format. */
+        $prepend = null;
+        if (isset($conf['error_prepend'])) {
+            $prepend = $conf['error_prepend'];
+        } else {
+            $prepend = ini_get('error_prepend_string');
+        }
+        if (!empty($prepend)) {
+            $this->_lineFormat = $prepend . $this->_lineFormat;
+        }
+
+        /* We may also need to append a string to our line format. */
+        $append = null;
+        if (isset($conf['error_append'])) {
+            $append = $conf['error_append'];
+        } else {
+            $append = ini_get('error_append_string');
+        }
+        if (!empty($append)) {
+            $this->_lineFormat .= $append;
+        }
+
+        /* Lastly, the line ending sequence is also configurable. */
+        if (isset($conf['linebreak'])) {
+            $this->_lineFormat .= $conf['linebreak'];
+        } else {
+            $this->_lineFormat .= "<br />\n";
+        }
+
+        /* The user can also change the time format. */
+        if (!empty($conf['timeFormat'])) {
+            $this->_timeFormat = $conf['timeFormat'];
+        }
+    }
+
+    /**
+     * Opens the display handler.
+     *
+     * @access  public
+     * @since   Log 1.9.6
+     */
+    function open()
+    {
+        $this->_opened = true;
+        return true;
+    }
+
+    /**
+     * Closes the display handler.
+     *
+     * @access  public
+     * @since   Log 1.9.6
+     */
+    function close()
+    {
+        $this->_opened = false;
+        return true;
+    }
+
+    /**
+     * Writes $message to the text browser. Also, passes the message
+     * along to any Log_observer instances that are observing this Log.
+     *
+     * @param mixed  $message    String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build and output the complete log line. */
+        echo $this->_format($this->_lineFormat,
+                            strftime($this->_timeFormat),
+                            $priority,
+                            nl2br(htmlspecialchars($message)));
+
+        /* Notify observers about this log message. */
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/null.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/null.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/null.php	(revision 795)
@@ -0,0 +1,91 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/null.php,v 1.5 2006/06/29 07:09:21 jon Exp $
+ *
+ * @version $Revision: 1.5 $
+ * @package Log
+ */
+
+/**
+ * The Log_null class is a concrete implementation of the Log:: abstract
+ * class.  It simply consumes log events.
+ *
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.8.2
+ * @package Log
+ *
+ * @example null.php    Using the null handler.
+ */
+class Log_null extends Log
+{
+    /**
+     * Constructs a new Log_null object.
+     *
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_null($name, $ident = '', $conf = array(),
+					  $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+    }
+
+    /**
+     * Opens the handler.
+     *
+     * @access  public
+     * @since   Log 1.9.6
+     */
+    function open()
+    {
+        $this->_opened = true;
+        return true;
+    }
+
+    /**
+     * Closes the handler.
+     *
+     * @access  public
+     * @since   Log 1.9.6
+     */
+    function close()
+    {
+        $this->_opened = false;
+        return true;
+    }
+
+    /**
+     * Simply consumes the log event.  The message will still be passed
+     * along to any Log_observer instances that are observing this Log.
+     *
+     * @param mixed  $message    String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/mcal.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/mcal.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/mcal.php	(revision 795)
@@ -0,0 +1,170 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/mcal.php,v 1.18 2005/02/26 14:48:58 chagenbu Exp $
+ * $Horde: horde/lib/Log/mcal.php,v 1.2 2000/06/28 21:36:13 jon Exp $
+ *
+ * @version $Revision: 1.18 $
+ * @package Log
+ */
+
+/**
+ * The Log_mcal class is a concrete implementation of the Log::
+ * abstract class which sends messages to a local or remote calendar
+ * store accessed through MCAL.
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @since Horde 1.3
+ * @since Log 1.0
+ * @package Log
+ */
+class Log_mcal extends Log
+{
+    /**
+     * holding the calendar specification to connect to.
+     * @var string
+     * @access private
+     */
+    var $_calendar = '{localhost/mstore}';
+
+    /**
+     * holding the username to use.
+     * @var string
+     * @access private
+     */
+    var $_username = '';
+
+    /**
+     * holding the password to use.
+     * @var string
+     * @access private
+     */
+    var $_password = '';
+
+    /**
+     * holding the options to pass to the calendar stream.
+     * @var integer
+     * @access private
+     */
+    var $_options = 0;
+
+    /**
+     * ResourceID of the MCAL stream.
+     * @var string
+     * @access private
+     */
+    var $_stream = '';
+
+    /**
+     * Integer holding the log facility to use.
+     * @var string
+     * @access private
+     */
+    var $_name = LOG_SYSLOG;
+
+
+    /**
+     * Constructs a new Log_mcal object.
+     *
+     * @param string $name     The category to use for our events.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_mcal($name, $ident = '', $conf = array(),
+                      $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_name = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+        $this->_calendar = $conf['calendar'];
+        $this->_username = $conf['username'];
+        $this->_password = $conf['password'];
+        $this->_options = $conf['options'];
+    }
+
+    /**
+     * Opens a calendar stream, if it has not already been
+     * opened. This is implicitly called by log(), if necessary.
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            $this->_stream = mcal_open($this->_calendar, $this->_username,
+                $this->_password, $this->_options);
+            $this->_opened = true;
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the calendar stream, if it is open.
+     * @access public
+     */
+    function close()
+    {
+        if ($this->_opened) {
+            mcal_close($this->_stream);
+            $this->_opened = false;
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Logs $message and associated information to the currently open
+     * calendar stream. Calls open() if necessary. Also passes the
+     * message along to any Log_observer instances that are observing
+     * this Log.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message. Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the connection isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        $date_str = date('Y:n:j:G:i:s');
+        $dates = explode(':', $date_str);
+
+        mcal_event_init($this->_stream);
+        mcal_event_set_title($this->_stream, $this->_ident);
+        mcal_event_set_category($this->_stream, $this->_name);
+        mcal_event_set_description($this->_stream, $message);
+        mcal_event_add_attribute($this->_stream, 'priority', $priority);
+        mcal_event_set_start($this->_stream, $dates[0], $dates[1], $dates[2],
+            $dates[3], $dates[4], $dates[5]);
+        mcal_event_set_end($this->_stream, $dates[0], $dates[1], $dates[2],
+            $dates[3], $dates[4], $dates[5]);
+        mcal_append_event($this->_stream);
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/file.php	(revision 795)
@@ -0,0 +1,316 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/file.php,v 1.46 2006/12/07 04:15:02 jon Exp $
+ *
+ * @version $Revision: 1.46 $
+ * @package Log
+ */
+
+/**
+ * The Log_file class is a concrete implementation of the Log abstract
+ * class that logs messages to a text file.
+ * 
+ * @author  Jon Parise <jon@php.net>
+ * @author  Roman Neuhauser <neuhauser@bellavista.cz>
+ * @since   Log 1.0
+ * @package Log
+ *
+ * @example file.php    Using the file handler.
+ */
+class Log_file extends Log
+{
+    /**
+     * String containing the name of the log file.
+     * @var string
+     * @access private
+     */
+    var $_filename = 'php.log';
+
+    /**
+     * Handle to the log file.
+     * @var resource
+     * @access private
+     */
+    var $_fp = false;
+
+    /**
+     * Should new log entries be append to an existing log file, or should the
+     * a new log file overwrite an existing one?
+     * @var boolean
+     * @access private
+     */
+    var $_append = true;
+
+    /**
+     * Should advisory file locking (i.e., flock()) be used?
+     * @var boolean
+     * @access private
+     */
+    var $_locking = false;
+
+    /**
+     * Integer (in octal) containing the log file's permissions mode.
+     * @var integer
+     * @access private
+     */
+    var $_mode = 0644;
+
+    /**
+     * Integer (in octal) specifying the file permission mode that will be
+     * used when creating directories that do not already exist.
+     * @var integer
+     * @access private
+     */
+    var $_dirmode = 0755;
+
+    /**
+     * String containing the format of a log line.
+     * @var string
+     * @access private
+     */
+    var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
+
+    /**
+     * String containing the timestamp format.  It will be passed directly to
+     * strftime().  Note that the timestamp string will generated using the
+     * current locale.
+     * @var string
+     * @access private
+     */
+    var $_timeFormat = '%b %d %H:%M:%S';
+
+    /**
+     * String containing the end-on-line character sequence.
+     * @var string
+     * @access private
+     */
+    var $_eol = "\n";
+
+    /**
+     * Constructs a new Log_file object.
+     *
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_file($name, $ident = '', $conf = array(),
+                      $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_filename = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (isset($conf['append'])) {
+            $this->_append = $conf['append'];
+        }
+
+        if (isset($conf['locking'])) {
+            $this->_locking = $conf['locking'];
+        }
+
+        if (!empty($conf['mode'])) {
+            if (is_string($conf['mode'])) {
+                $this->_mode = octdec($conf['mode']);
+            } else {
+                $this->_mode = $conf['mode'];
+            }
+        }
+
+        if (!empty($conf['dirmode'])) {
+            if (is_string($conf['dirmode'])) {
+                $this->_dirmode = octdec($conf['dirmode']);
+            } else {
+                $this->_dirmode = $conf['dirmode'];
+            }
+        }
+
+        if (!empty($conf['lineFormat'])) {
+            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
+                                             array_values($this->_formatMap),
+                                             $conf['lineFormat']);
+        }
+
+        if (!empty($conf['timeFormat'])) {
+            $this->_timeFormat = $conf['timeFormat'];
+        }
+
+        if (!empty($conf['eol'])) {
+            $this->_eol = $conf['eol'];
+        } else {
+            $this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
+        }
+
+        register_shutdown_function(array(&$this, '_Log_file'));
+    }
+
+    /**
+     * Destructor
+     */
+    function _Log_file()
+    {
+        if ($this->_opened) {
+            $this->close();
+        }
+    }
+
+    /**
+     * Creates the given directory path.  If the parent directories don't
+     * already exist, they will be created, too.
+     *
+     * This implementation is inspired by Python's os.makedirs function.
+     *
+     * @param   string  $path       The full directory path to create.
+     * @param   integer $mode       The permissions mode with which the
+     *                              directories will be created.
+     *
+     * @return  True if the full path is successfully created or already
+     *          exists.
+     *
+     * @access  private
+     */
+    function _mkpath($path, $mode = 0700)
+    {
+        /* Separate the last pathname component from the rest of the path. */
+        $head = dirname($path);
+        $tail = basename($path);
+
+        /* Make sure we've split the path into two complete components. */
+        if (empty($tail)) {
+            $head = dirname($path);
+            $tail = basename($path);
+        }
+
+        /* Recurse up the path if our current segment does not exist. */
+        if (!empty($head) && !empty($tail) && !is_dir($head)) {
+            $this->_mkpath($head, $mode);
+        }
+
+        /* Create this segment of the path. */
+        return @mkdir($head, $mode);
+    }
+
+    /**
+     * Opens the log file for output.  If the specified log file does not
+     * already exist, it will be created.  By default, new log entries are
+     * appended to the end of the log file.
+     *
+     * This is implicitly called by log(), if necessary.
+     *
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            /* If the log file's directory doesn't exist, create it. */
+            if (!is_dir(dirname($this->_filename))) {
+                $this->_mkpath($this->_filename, $this->_dirmode);
+            }
+
+            /* Determine whether the log file needs to be created. */
+            $creating = !file_exists($this->_filename);
+
+            /* Obtain a handle to the log file. */
+            $this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w');
+
+            /* We consider the file "opened" if we have a valid file pointer. */
+            $this->_opened = ($this->_fp !== false);
+
+            /* Attempt to set the file's permissions if we just created it. */
+            if ($creating && $this->_opened) {
+                chmod($this->_filename, $this->_mode);
+            }
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the log file if it is open.
+     *
+     * @access public
+     */
+    function close()
+    {
+        /* If the log file is open, close it. */
+        if ($this->_opened && fclose($this->_fp)) {
+            $this->_opened = false;
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Flushes all pending data to the file handle.
+     *
+     * @access public
+     * @since Log 1.8.2
+     */
+    function flush()
+    {
+        if (is_resource($this->_fp)) {
+            return fflush($this->_fp);
+        }
+
+        return false;
+    }
+
+    /**
+     * Logs $message to the output window.  The message is also passed along
+     * to any Log_observer instances that are observing this Log.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the log file isn't already open, open it now. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build the string containing the complete log line. */
+        $line = $this->_format($this->_lineFormat,
+                               strftime($this->_timeFormat),
+                               $priority, $message) . $this->_eol;
+
+        /* If locking is enabled, acquire an exclusive lock on the file. */
+        if ($this->_locking) {
+            flock($this->_fp, LOCK_EX);
+        }
+
+        /* Write the log line to the log file. */
+        $success = (fwrite($this->_fp, $line) !== false);
+
+        /* Unlock the file now that we're finished writing to it. */ 
+        if ($this->_locking) {
+            flock($this->_fp, LOCK_UN);
+        }
+
+        /* Notify observers about this log message. */
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return $success;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/syslog.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/syslog.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/syslog.php	(revision 795)
@@ -0,0 +1,179 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/syslog.php,v 1.25 2007/01/29 05:09:07 jon Exp $
+ * $Horde: horde/lib/Log/syslog.php,v 1.6 2000/06/28 21:36:13 jon Exp $
+ *
+ * @version $Revision: 1.25 $
+ * @package Log
+ */
+
+/**
+ * The Log_syslog class is a concrete implementation of the Log::
+ * abstract class which sends messages to syslog on UNIX-like machines
+ * (PHP emulates this with the Event Log on Windows machines).
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @author  Jon Parise <jon@php.net>
+ * @since   Horde 1.3
+ * @since   Log 1.0
+ * @package Log
+ *
+ * @example syslog.php      Using the syslog handler.
+ */
+class Log_syslog extends Log
+{
+    /**
+     * Integer holding the log facility to use.
+     * @var integer
+     * @access private
+     */
+    var $_name = LOG_SYSLOG;
+
+    /**
+     * Should we inherit the current syslog connection for this process, or
+     * should we call openlog() to start a new syslog connection?
+     * @var boolean
+     * @access private
+     */
+    var $_inherit = false;
+
+    /**
+     * Constructs a new syslog object.
+     *
+     * @param string $name     The syslog facility.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_syslog($name, $ident = '', $conf = array(),
+                        $level = PEAR_LOG_DEBUG)
+    {
+        /* Ensure we have a valid integer value for $name. */
+        if (empty($name) || !is_int($name)) {
+            $name = LOG_SYSLOG;
+        }
+
+        if (isset($conf['inherit'])) {
+            $this->_inherit = $conf['inherit'];
+            $this->_opened = $this->_inherit;
+        }
+
+        $this->_id = md5(microtime());
+        $this->_name = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+    }
+
+    /**
+     * Opens a connection to the system logger, if it has not already
+     * been opened.  This is implicitly called by log(), if necessary.
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            $this->_opened = openlog($this->_ident, LOG_PID, $this->_name);
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the connection to the system logger, if it is open.
+     * @access public
+     */
+    function close()
+    {
+        if ($this->_opened && !$this->_inherit) {
+            closelog();
+            $this->_opened = false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Sends $message to the currently open syslog connection.  Calls
+     * open() if necessary. Also passes the message along to any Log_observer
+     * instances that are observing this Log.
+     *
+     * @param mixed $message String or object containing the message to log.
+     * @param int $priority (optional) The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the connection isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build a syslog priority value based on our current configuration. */
+        $priority = $this->_toSyslog($priority);
+        if ($this->_inherit) {
+            $priority |= $this->_name;
+        }
+
+        if (!syslog($priority, $message)) {
+            return false;
+        }
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+    /**
+     * Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
+     *
+     * This function exists because, under Windows, not all of the LOG_*
+     * constants have unique values.  Instead, the PEAR_LOG_* were introduced
+     * for global use, with the conversion to the LOG_* constants kept local to
+     * to the syslog driver.
+     *
+     * @param int $priority     PEAR_LOG_* value to convert to LOG_* value.
+     *
+     * @return  The LOG_* representation of $priority.
+     *
+     * @access private
+     */
+    function _toSyslog($priority)
+    {
+        static $priorities = array(
+            PEAR_LOG_EMERG   => LOG_EMERG,
+            PEAR_LOG_ALERT   => LOG_ALERT,
+            PEAR_LOG_CRIT    => LOG_CRIT,
+            PEAR_LOG_ERR     => LOG_ERR,
+            PEAR_LOG_WARNING => LOG_WARNING,
+            PEAR_LOG_NOTICE  => LOG_NOTICE,
+            PEAR_LOG_INFO    => LOG_INFO,
+            PEAR_LOG_DEBUG   => LOG_DEBUG
+        );
+
+        /* If we're passed an unknown priority, default to LOG_INFO. */
+        if (!is_int($priority) || !in_array($priority, $priorities)) {
+            return LOG_INFO;
+        }
+
+        return $priorities[$priority];
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/mail.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/mail.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/mail.php	(revision 795)
@@ -0,0 +1,294 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/mail.php,v 1.28 2008/09/22 04:39:29 jon Exp $
+ *
+ * @version $Revision: 1.28 $
+ * @package Log
+ */
+
+/**
+ * The Log_mail class is a concrete implementation of the Log:: abstract class
+ * which sends log messages to a mailbox.
+ * The mail is actually sent when you close() the logger, or when the destructor
+ * is called (when the script is terminated).
+ *
+ * PLEASE NOTE that you must create a Log_mail object using =&, like this :
+ *  $logger =& Log::factory("mail", "recipient@example.com", ...)
+ *
+ * This is a PEAR requirement for destructors to work properly.
+ * See http://pear.php.net/manual/en/class.pear.php
+ *
+ * @author  Ronnie Garcia <ronnie@mk2.net>
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.3
+ * @package Log
+ *
+ * @example mail.php    Using the mail handler.
+ */
+class Log_mail extends Log
+{
+    /**
+     * String holding the recipients' email addresses.  Multiple addresses
+     * should be separated with commas.
+     * @var string
+     * @access private
+     */
+    var $_recipients = '';
+
+    /**
+     * String holding the sender's email address.
+     * @var string
+     * @access private
+     */
+    var $_from = '';
+
+    /**
+     * String holding the email's subject.
+     * @var string
+     * @access private
+     */
+    var $_subject = '[Log_mail] Log message';
+
+    /**
+     * String holding an optional preamble for the log messages.
+     * @var string
+     * @access private
+     */
+    var $_preamble = '';
+
+    /**
+     * String containing the format of a log line.
+     * @var string
+     * @access private
+     */
+    var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
+
+    /**
+     * String containing the timestamp format.  It will be passed directly to
+     * strftime().  Note that the timestamp string will generated using the
+     * current locale.
+     * @var string
+     * @access private
+     */
+    var $_timeFormat = '%b %d %H:%M:%S';
+
+    /**
+     * String holding the mail message body.
+     * @var string
+     * @access private
+     */
+    var $_message = '';
+
+    /**
+     * Flag used to indicated that log lines have been written to the message
+     * body and the message should be sent on close().
+     * @var boolean
+     * @access private
+     */
+    var $_shouldSend = false;
+
+    /**
+     * String holding the backend name of PEAR::Mail
+     * @var string
+     * @access private
+     */
+    var $_mailBackend = '';
+
+    /**
+     * Array holding the params for PEAR::Mail
+     * @var array
+     * @access private
+     */
+    var $_mailParams = array();
+
+    /**
+     * Constructs a new Log_mail object.
+     *
+     * Here is how you can customize the mail driver with the conf[] hash :
+     *   $conf['from']:        the mail's "From" header line,
+     *   $conf['subject']:     the mail's "Subject" line.
+     *   $conf['mailBackend']: backend name of PEAR::Mail
+     *   $conf['mailParams']:  parameters for the PEAR::Mail backend
+     *
+     * @param string $name      The message's recipients.
+     * @param string $ident     The identity string.
+     * @param array  $conf      The configuration array.
+     * @param int    $level     Log messages up to and including this level.
+     * @access public
+     */
+    function Log_mail($name, $ident = '', $conf = array(),
+                      $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_recipients = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+        if (!empty($conf['from'])) {
+            $this->_from = $conf['from'];
+        } else {
+            $this->_from = ini_get('sendmail_from');
+        }
+
+        if (!empty($conf['subject'])) {
+            $this->_subject = $conf['subject'];
+        }
+
+        if (!empty($conf['preamble'])) {
+            $this->_preamble = $conf['preamble'];
+        }
+
+        if (!empty($conf['lineFormat'])) {
+            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
+                                             array_values($this->_formatMap),
+                                             $conf['lineFormat']);
+        }
+
+        if (!empty($conf['timeFormat'])) {
+            $this->_timeFormat = $conf['timeFormat'];
+        }
+
+        if (!empty($conf['mailBackend'])) {
+            $this->_mailBackend = $conf['mailBackend'];
+        }
+
+        if (!empty($conf['mailParams'])) {
+            $this->_mailParams = $conf['mailParams'];
+        }
+
+        /* register the destructor */
+        register_shutdown_function(array(&$this, '_Log_mail'));
+    }
+
+    /**
+     * Destructor. Calls close().
+     *
+     * @access private
+     */
+    function _Log_mail()
+    {
+        $this->close();
+    }
+
+    /**
+     * Starts a new mail message.
+     * This is implicitly called by log(), if necessary.
+     *
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            if (!empty($this->_preamble)) {
+                $this->_message = $this->_preamble . "\r\n\r\n";
+            }
+            $this->_opened = true;
+            $_shouldSend = false;
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the message, if it is open, and sends the mail.
+     * This is implicitly called by the destructor, if necessary.
+     *
+     * @access public
+     */
+    function close()
+    {
+        if ($this->_opened) {
+            if ($this->_shouldSend && !empty($this->_message)) {
+                if ($this->_mailBackend === '') {  // use mail()
+                    $headers = "From: $this->_from\r\n";
+                    $headers .= 'User-Agent: PEAR Log Package';
+                    if (mail($this->_recipients, $this->_subject,
+                             $this->_message, $headers) == false) {
+                        return false;
+                    }
+                } else {  // use PEAR::Mail
+                    include_once 'Mail.php';
+                    $headers = array('From' => $this->_from,
+                                     'To' => $this->_recipients,
+                                     'User-Agent' => 'PEAR Log Package',
+                                     'Subject' => $this->_subject);
+                    $mailer = &Mail::factory($this->_mailBackend,
+                                             $this->_mailParams);
+                    $res = $mailer->send($this->_recipients, $headers,
+                                         $this->_message);
+                    if (PEAR::isError($res)) {
+                        return false;
+                    }
+                }
+
+                /* Clear the message string now that the email has been sent. */
+                $this->_message = '';
+                $this->_shouldSend = false;
+            }
+            $this->_opened = false;
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Flushes the log output by forcing the email message to be sent now.
+     * Events that are logged after flush() is called will be appended to a
+     * new email message.
+     *
+     * @access public
+     * @since Log 1.8.2
+     */
+    function flush()
+    {
+        /*
+         * It's sufficient to simply call close() to flush the output.
+         * The next call to log() will cause the handler to be reopened.
+         */
+        return $this->close();
+    }
+
+    /**
+     * Writes $message to the currently open mail message.
+     * Calls open(), if necessary.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the message isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Append the string containing the complete log line. */
+        $this->_message .= $this->_format($this->_lineFormat,
+                                          strftime($this->_timeFormat),
+                                          $priority, $message) . "\r\n";
+        $this->_shouldSend = true;
+
+        /* Notify observers about this log message. */
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/firebug.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/firebug.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/firebug.php	(revision 795)
@@ -0,0 +1,214 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/firebug.php,v 1.6 2008/01/19 21:56:16 jon Exp $
+ *
+ * @version $Revision: 1.6 $
+ * @package Log
+ */
+
+/**
+ * The Log_firebug class is a concrete implementation of the Log::
+ * abstract class which writes message into Firebug console.
+ *
+ * http://www.getfirebug.com/
+ *
+ * @author  Mika Tuupola <tuupola@appelsiini.net>
+ * @since   Log 1.9.11
+ * @package Log
+ *
+ * @example firebug.php     Using the firebug handler.
+ */
+class Log_firebug extends Log
+{
+    /**
+     * Should the output be buffered or displayed immediately?
+     * @var string
+     * @access private
+     */
+    var $_buffering = false;
+
+    /**
+     * String holding the buffered output.
+     * @var string
+     * @access private
+     */
+    var $_buffer = array();
+
+    /**
+     * String containing the format of a log line.
+     * @var string
+     * @access private
+     */
+    var $_lineFormat = '%2$s [%3$s] %4$s';
+
+    /**
+     * String containing the timestamp format.  It will be passed directly to
+     * strftime().  Note that the timestamp string will generated using the
+     * current locale.
+     *
+     * Note! Default lineFormat of this driver does not display time.
+     *
+     * @var string
+     * @access private
+     */
+    var $_timeFormat = '%b %d %H:%M:%S';
+
+    /**
+     * Mapping of log priorities to Firebug methods.
+     * @var array
+     * @access private
+     */
+    var $_methods = array(
+                        PEAR_LOG_EMERG   => 'error',
+                        PEAR_LOG_ALERT   => 'error',
+                        PEAR_LOG_CRIT    => 'error',
+                        PEAR_LOG_ERR     => 'error',
+                        PEAR_LOG_WARNING => 'warn',
+                        PEAR_LOG_NOTICE  => 'info',
+                        PEAR_LOG_INFO    => 'info',
+                        PEAR_LOG_DEBUG   => 'debug'
+                    );
+
+    /**
+     * Constructs a new Log_firebug object.
+     *
+     * @param string $name     Ignored.
+     * @param string $ident    The identity string.
+     * @param array  $conf     The configuration array.
+     * @param int    $level    Log messages up to and including this level.
+     * @access public
+     */
+    function Log_firebug($name = '', $ident = 'PHP', $conf = array(),
+                         $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+        if (isset($conf['buffering'])) {
+            $this->_buffering = $conf['buffering'];
+        }
+
+        if ($this->_buffering) {
+            register_shutdown_function(array(&$this, '_Log_firebug'));
+        }
+
+        if (!empty($conf['lineFormat'])) {
+            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
+                                             array_values($this->_formatMap),
+                                             $conf['lineFormat']);
+        }
+
+        if (!empty($conf['timeFormat'])) {
+            $this->_timeFormat = $conf['timeFormat'];
+        }
+    }
+
+    /**
+     * Opens the firebug handler.
+     *
+     * @access  public
+     */
+    function open()
+    {
+        $this->_opened = true;
+        return true;
+    }
+
+    /**
+     * Destructor
+     */
+    function _Log_firebug()
+    {
+        $this->close();
+    }
+
+    /**
+     * Closes the firebug handler.
+     *
+     * @access  public
+     */
+    function close()
+    {
+        $this->flush();
+        $this->_opened = false;
+        return true;
+    }
+
+    /**
+     * Flushes all pending ("buffered") data.
+     *
+     * @access public
+     */
+    function flush() {
+        if (count($this->_buffer)) {
+            print '<script type="text/javascript">';
+            print "\nif (('console' in window) && ('firebug' in console)) {\n";
+            foreach ($this->_buffer as $line) {
+                print "  $line\n";
+            }
+            print "}\n";
+            print "</script>\n";
+        };
+        $this->_buffer = array();
+    }
+
+    /**
+     * Writes $message to Firebug console. Also, passes the message
+     * along to any Log_observer instances that are observing this Log.
+     *
+     * @param mixed  $message    String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+        $method  = $this->_methods[$priority];
+        
+        /* normalize line breaks */
+        $message = str_replace("\r\n", "\n", $message);
+        
+        /* escape line breaks */
+        $message = str_replace("\n", "\\n\\\n", $message);
+        
+        /* escape quotes */
+        $message = str_replace('"', '\\"', $message);
+        
+        /* Build the string containing the complete log line. */
+        $line = $this->_format($this->_lineFormat,
+                               strftime($this->_timeFormat),
+                               $priority, 
+                               $message);
+
+        if ($this->_buffering) {
+            $this->_buffer[] = sprintf('console.%s("%s");', $method, $line);
+        } else {
+            print '<script type="text/javascript">';
+            print "\nif (('console' in window) && ('firebug' in console)) {\n";
+            /* Build and output the complete log line. */
+            printf('  console.%s("%s");', $method, $line);
+            print "\n}\n";
+            print "</script>\n";
+        }
+        /* Notify observers about this log message. */
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/mdb2.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/mdb2.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/mdb2.php	(revision 795)
@@ -0,0 +1,358 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/mdb2.php,v 1.5 2006/01/08 03:35:44 jon Exp $
+ *
+ * @version $Revision: 1.5 $
+ * @package Log
+ */
+
+/** PEAR's MDB2 package */
+require_once 'MDB2.php';
+MDB2::loadFile('Date');
+
+/**
+ * The Log_mdb2 class is a concrete implementation of the Log:: abstract class
+ * which sends messages to an SQL server.  Each entry occupies a separate row
+ * in the database.
+ *
+ * This implementation uses PEAR's MDB2 database abstraction layer.
+ *
+ * CREATE TABLE log_table (
+ *  id          INT NOT NULL,
+ *  logtime     TIMESTAMP NOT NULL,
+ *  ident       CHAR(16) NOT NULL,
+ *  priority    INT NOT NULL,
+ *  message     VARCHAR(200),
+ *  PRIMARY KEY (id)
+ * );
+ *
+ * @author  Lukas Smith <smith@backendmedia.com>
+ * @author  Jon Parise <jon@php.net>
+ * @since   Log 1.9.0
+ * @package Log
+ */
+class Log_mdb2 extends Log
+{
+    /**
+     * Variable containing the DSN information.
+     * @var mixed
+     * @access private
+     */
+    var $_dsn = '';
+
+    /**
+     * Array containing our set of DB configuration options.
+     * @var array
+     * @access private
+     */
+    var $_options = array('persistent' => true);
+
+    /**
+     * Object holding the database handle.
+     * @var object
+     * @access private
+     */
+    var $_db = null;
+
+    /**
+     * Resource holding the prepared statement handle.
+     * @var resource
+     * @access private
+     */
+    var $_statement = null;
+
+    /**
+     * Flag indicating that we're using an existing database connection.
+     * @var boolean
+     * @access private
+     */
+    var $_existingConnection = false;
+
+    /**
+     * String holding the database table to use.
+     * @var string
+     * @access private
+     */
+    var $_table = 'log_table';
+
+    /**
+     * String holding the name of the ID sequence.
+     * @var string
+     * @access private
+     */
+    var $_sequence = 'log_id';
+
+    /**
+     * Maximum length of the $ident string.  This corresponds to the size of
+     * the 'ident' column in the SQL table.
+     * @var integer
+     * @access private
+     */
+    var $_identLimit = 16;
+
+    /**
+     * Set of field types used in the database table.
+     * @var array
+     * @access private
+     */
+    var $_types = array(
+        'id'        => 'integer',
+        'logtime'   => 'timestamp',
+        'ident'     => 'text',
+        'priority'  => 'text',
+        'message'   => 'clob'
+    );
+
+    /**
+     * Constructs a new sql logging object.
+     *
+     * @param string $name         The target SQL table.
+     * @param string $ident        The identification field.
+     * @param array $conf          The connection configuration array.
+     * @param int $level           Log messages up to and including this level.
+     * @access public
+     */
+    function Log_mdb2($name, $ident = '', $conf = array(),
+                     $level = PEAR_LOG_DEBUG)
+    {
+        $this->_id = md5(microtime());
+        $this->_table = $name;
+        $this->_mask = Log::UPTO($level);
+
+        /* If an options array was provided, use it. */
+        if (isset($conf['options']) && is_array($conf['options'])) {
+            $this->_options = $conf['options'];
+        }
+
+        /* If a specific sequence name was provided, use it. */
+        if (!empty($conf['sequence'])) {
+            $this->_sequence = $conf['sequence'];
+        }
+
+        /* If a specific sequence name was provided, use it. */
+        if (isset($conf['identLimit'])) {
+            $this->_identLimit = $conf['identLimit'];
+        }
+
+        /* Now that the ident limit is confirmed, set the ident string. */
+        $this->setIdent($ident);
+
+        /* If an existing database connection was provided, use it. */
+        if (isset($conf['db'])) {
+            $this->_db = &$conf['db'];
+            $this->_existingConnection = true;
+            $this->_opened = true;
+        } elseif (isset($conf['singleton'])) {
+            $this->_db = &MDB2::singleton($conf['singleton'], $this->_options);
+            $this->_existingConnection = true;
+            $this->_opened = true;
+        } else {
+            $this->_dsn = $conf['dsn'];
+        }
+    }
+
+    /**
+     * Opens a connection to the database, if it has not already
+     * been opened. This is implicitly called by log(), if necessary.
+     *
+     * @return boolean   True on success, false on failure.
+     * @access public
+     */
+    function open()
+    {
+        if (!$this->_opened) {
+            /* Use the DSN and options to create a database connection. */
+            $this->_db = &MDB2::connect($this->_dsn, $this->_options);
+            if (PEAR::isError($this->_db)) {
+                return false;
+            }
+
+            /* Create a prepared statement for repeated use in log(). */
+            if (!$this->_prepareStatement()) {
+                return false;
+            }
+
+            /* We now consider out connection open. */
+            $this->_opened = true;
+        }
+
+        return $this->_opened;
+    }
+
+    /**
+     * Closes the connection to the database if it is still open and we were
+     * the ones that opened it.  It is the caller's responsible to close an
+     * existing connection that was passed to us via $conf['db'].
+     *
+     * @return boolean   True on success, false on failure.
+     * @access public
+     */
+    function close()
+    {
+        /* If we have a statement object, free it. */
+        if (is_object($this->_statement)) {
+            $this->_statement->free();
+            $this->_statement = null;
+        }
+
+        /* If we opened the database connection, disconnect it. */
+        if ($this->_opened && !$this->_existingConnection) {
+            $this->_opened = false;
+            return $this->_db->disconnect();
+        }
+
+        return ($this->_opened === false);
+    }
+
+    /**
+     * Sets this Log instance's identification string.  Note that this
+     * SQL-specific implementation will limit the length of the $ident string
+     * to sixteen (16) characters.
+     *
+     * @param string    $ident      The new identification string.
+     *
+     * @access  public
+     * @since   Log 1.8.5
+     */
+    function setIdent($ident)
+    {
+        $this->_ident = substr($ident, 0, $this->_identLimit);
+    }
+
+    /**
+     * Inserts $message to the currently open database.  Calls open(),
+     * if necessary.  Also passes the message along to any Log_observer
+     * instances that are observing this Log.
+     *
+     * @param mixed  $message  String or object containing the message to log.
+     * @param string $priority The priority of the message.  Valid
+     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
+     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
+     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
+     * @return boolean  True on success or false on failure.
+     * @access public
+     */
+    function log($message, $priority = null)
+    {
+        /* If a priority hasn't been specified, use the default value. */
+        if ($priority === null) {
+            $priority = $this->_priority;
+        }
+
+        /* Abort early if the priority is above the maximum logging level. */
+        if (!$this->_isMasked($priority)) {
+            return false;
+        }
+
+        /* If the connection isn't open and can't be opened, return failure. */
+        if (!$this->_opened && !$this->open()) {
+            return false;
+        }
+
+        /* If we don't already have a statement object, create one. */
+        if (!is_object($this->_statement) && !$this->_prepareStatement()) {
+            return false;
+        }
+
+        /* Extract the string representation of the message. */
+        $message = $this->_extractMessage($message);
+
+        /* Build our set of values for this log entry. */
+        $values = array(
+            'id'       => $this->_db->nextId($this->_sequence),
+            'logtime'  => MDB2_Date::mdbNow(),
+            'ident'    => $this->_ident,
+            'priority' => $priority,
+            'message'  => $message
+        );
+
+        /* Execute the SQL query for this log entry insertion. */
+        $this->_db->expectError(MDB2_ERROR_NOSUCHTABLE);
+        $result = &$this->_statement->execute($values);
+        $this->_db->popExpect();
+
+        /* Attempt to handle any errors. */
+        if (PEAR::isError($result)) {
+            /* We can only handle MDB2_ERROR_NOSUCHTABLE errors. */
+            if ($result->getCode() != MDB2_ERROR_NOSUCHTABLE) {
+                return false;
+            }
+
+            /* Attempt to create the target table. */
+            if (!$this->_createTable()) {
+                return false;
+            }
+
+            /* Recreate our prepared statement resource. */
+            $this->_statement->free();
+            if (!$this->_prepareStatement()) {
+                return false;
+            }
+
+            /* Attempt to re-execute the insertion query. */
+            $result = $this->_statement->execute($values);
+            if (PEAR::isError($result)) {
+                return false;
+            }
+        }
+
+        $this->_announce(array('priority' => $priority, 'message' => $message));
+
+        return true;
+    }
+
+    /**
+     * Create the log table in the database.
+     *
+     * @return boolean  True on success or false on failure.
+     * @access private
+     */
+    function _createTable()
+    {
+        $this->_db->loadModule('Manager', null, true);
+        $result = $this->_db->manager->createTable(
+            $this->_table,
+            array(
+                'id'        => array('type' => $this->_types['id']),
+                'logtime'   => array('type' => $this->_types['logtime']),
+                'ident'     => array('type' => $this->_types['ident']),
+                'priority'  => array('type' => $this->_types['priority']),
+                'message'   => array('type' => $this->_types['message'])
+            )
+        );
+        if (PEAR::isError($result)) {
+            return false;
+        }
+
+        $result = $this->_db->manager->createIndex(
+            $this->_table,
+            'unique_id',
+            array('fields' => array('id' => true), 'unique' => true)
+        );
+        if (PEAR::isError($result)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Prepare the SQL insertion statement.
+     *
+     * @return boolean  True if the statement was successfully created.
+     *
+     * @access  private
+     * @since   Log 1.9.0
+     */
+    function _prepareStatement()
+    {
+        $this->_statement = &$this->_db->prepare(
+                'INSERT INTO ' . $this->_table .
+                ' (id, logtime, ident, priority, message)' .
+                ' VALUES(:id, :logtime, :ident, :priority, :message)',
+                $this->_types, MDB2_PREPARE_MANIP);
+
+        /* Return success if we didn't generate an error. */
+        return (PEAR::isError($this->_statement) === false);
+    }
+}
Index: /sandbox/workflow/branches/993/inc/log/Log/observer.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log/observer.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log/observer.php	(revision 795)
@@ -0,0 +1,129 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log/observer.php,v 1.18 2006/04/25 06:02:23 jon Exp $
+ * $Horde: horde/lib/Log/observer.php,v 1.5 2000/06/28 21:36:13 jon Exp $
+ *
+ * @version $Revision: 1.18 $
+ * @package Log
+ */
+
+/**
+ * The Log_observer:: class implements the Observer end of a Subject-Observer
+ * pattern for watching log activity and taking actions on exceptional events.
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @since   Horde 1.3
+ * @since   Log 1.0
+ * @package Log
+ *
+ * @example observer_mail.php   An example Log_observer implementation.
+ */
+class Log_observer
+{
+    /**
+     * Instance-specific unique identification number.
+     *
+     * @var integer
+     * @access private
+     */
+    var $_id = 0;
+
+    /**
+     * The minimum priority level of message that we want to hear about.
+     * PEAR_LOG_EMERG is the highest priority, so we will only hear messages
+     * with an integer priority value less than or equal to ours.  It defaults
+     * to PEAR_LOG_INFO, which listens to everything except PEAR_LOG_DEBUG.
+     *
+     * @var string
+     * @access private
+     */
+    var $_priority = PEAR_LOG_INFO;
+
+    /**
+     * Creates a new basic Log_observer instance.
+     *
+     * @param integer   $priority   The highest priority at which to receive
+     *                              log event notifications.
+     *
+     * @access public
+     */
+    function Log_observer($priority = PEAR_LOG_INFO)
+    {
+        $this->_id = md5(microtime());
+        $this->_priority = $priority;
+    }
+
+    /**
+     * Attempts to return a new concrete Log_observer instance of the requested
+     * type.
+     *
+     * @param string    $type       The type of concreate Log_observer subclass
+     *                              to return.
+     * @param integer   $priority   The highest priority at which to receive
+     *                              log event notifications.
+     * @param array     $conf       Optional associative array of additional
+     *                              configuration values.
+     *
+     * @return object               The newly created concrete Log_observer
+     *                              instance, or null on an error.
+     */
+    function &factory($type, $priority = PEAR_LOG_INFO, $conf = array())
+    {
+        $type = strtolower($type);
+        $class = 'Log_observer_' . $type;
+
+        /*
+         * If the desired class already exists (because the caller has supplied
+         * it from some custom location), simply instantiate and return a new
+         * instance.
+         */
+        if (class_exists($class)) {
+            $object = &new $class($priority, $conf);
+            return $object;
+        }
+
+        /* Support both the new-style and old-style file naming conventions. */
+        $newstyle = true;
+        $classfile = dirname(__FILE__) . '/observer_' . $type . '.php';
+
+        if (!file_exists($classfile)) {
+            $classfile = 'Log/' . $type . '.php';
+            $newstyle = false;
+        }
+
+        /*
+         * Attempt to include our version of the named class, but don't treat
+         * a failure as fatal.  The caller may have already included their own
+         * version of the named class.
+         */
+        @include_once $classfile;
+
+        /* If the class exists, return a new instance of it. */
+        if (class_exists($class)) {
+            /* Support both new-style and old-style construction. */
+            if ($newstyle) {
+                $object = &new $class($priority, $conf);
+            } else {
+                $object = &new $class($priority);
+            }
+            return $object;
+        }
+
+        $null = null;
+        return $null;
+    }
+
+    /**
+     * This is a stub method to make sure that Log_Observer classes do
+     * something when they are notified of a message.  The default behavior
+     * is to just print the message, which is obviously not desireable in
+     * practically any situation - which is why you need to override this
+     * method. :)
+     *
+     * @param array     $event      A hash describing the log event.
+     */
+    function notify($event)
+    {
+        print_r($event);
+    }
+}
Index: /sandbox/workflow/branches/993/inc/log/Log.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/Log.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/Log.php	(revision 795)
@@ -0,0 +1,858 @@
+<?php
+/**
+ * $Header: /repository/pear/Log/Log.php,v 1.74 2008/11/19 04:14:38 jon Exp $
+ * $Horde: horde/lib/Log.php,v 1.15 2000/06/29 23:39:45 jon Exp $
+ *
+ * @version $Revision: 1.74 $
+ * @package Log
+ */
+
+define('PEAR_LOG_EMERG',    0);     /* System is unusable */
+define('PEAR_LOG_ALERT',    1);     /* Immediate action required */
+define('PEAR_LOG_CRIT',     2);     /* Critical conditions */
+define('PEAR_LOG_ERR',      3);     /* Error conditions */
+define('PEAR_LOG_WARNING',  4);     /* Warning conditions */
+define('PEAR_LOG_NOTICE',   5);     /* Normal but significant */
+define('PEAR_LOG_INFO',     6);     /* Informational */
+define('PEAR_LOG_DEBUG',    7);     /* Debug-level messages */
+
+define('PEAR_LOG_ALL',      0xffffffff);    /* All messages */
+define('PEAR_LOG_NONE',     0x00000000);    /* No message */
+
+/* Log types for PHP's native error_log() function. */
+define('PEAR_LOG_TYPE_SYSTEM',  0); /* Use PHP's system logger */
+define('PEAR_LOG_TYPE_MAIL',    1); /* Use PHP's mail() function */
+define('PEAR_LOG_TYPE_DEBUG',   2); /* Use PHP's debugging connection */
+define('PEAR_LOG_TYPE_FILE',    3); /* Append to a file */
+
+/**
+ * The Log:: class implements both an abstraction for various logging
+ * mechanisms and the Subject end of a Subject-Observer pattern.
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @author  Jon Parise <jon@php.net>
+ * @since   Horde 1.3
+ * @package Log
+ */
+class Log
+{
+    /**
+     * Indicates whether or not the log can been opened / connected.
+     *
+     * @var boolean
+     * @access protected
+     */
+    var $_opened = false;
+
+    /**
+     * Instance-specific unique identification number.
+     *
+     * @var integer
+     * @access protected
+     */
+    var $_id = 0;
+
+    /**
+     * The label that uniquely identifies this set of log messages.
+     *
+     * @var string
+     * @access protected
+     */
+    var $_ident = '';
+
+    /**
+     * The default priority to use when logging an event.
+     *
+     * @var integer
+     * @access protected
+     */
+    var $_priority = PEAR_LOG_INFO;
+
+    /**
+     * The bitmask of allowed log levels.
+     *
+     * @var integer
+     * @access protected
+     */
+    var $_mask = PEAR_LOG_ALL;
+
+    /**
+     * Holds all Log_observer objects that wish to be notified of new messages.
+     *
+     * @var array
+     * @access protected
+     */
+    var $_listeners = array();
+
+    /**
+     * Maps canonical format keys to position arguments for use in building
+     * "line format" strings.
+     *
+     * @var array
+     * @access protected
+     */
+    var $_formatMap = array('%{timestamp}'  => '%1$s',
+                            '%{ident}'      => '%2$s',
+                            '%{priority}'   => '%3$s',
+                            '%{message}'    => '%4$s',
+                            '%{file}'       => '%5$s',
+                            '%{line}'       => '%6$s',
+                            '%{function}'   => '%7$s',
+                            '%{class}'      => '%8$s',
+                            '%\{'           => '%%{');
+
+    /**
+     * Utility function which wraps PHP's class_exists() function to ensure
+     * consistent behavior between PHP versions 4 and 5.  Autoloading behavior
+     * is always disabled.
+     *
+     * @param string $class     The name of the class whose existence should
+     *                          be tested.
+     *
+     * @return bool             True if the class exists.
+     *
+     * @access private
+     * @since Log 1.9.13
+     */
+    function _classExists($class)
+    {
+        if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {
+            return class_exists($class, false);
+        }
+
+        return class_exists($class);
+    }
+
+    /**
+     * Attempts to return a concrete Log instance of type $handler.
+     *
+     * @param string $handler   The type of concrete Log subclass to return.
+     *                          Attempt to dynamically include the code for
+     *                          this subclass. Currently, valid values are
+     *                          'console', 'syslog', 'sql', 'file', and 'mcal'.
+     *
+     * @param string $name      The name of the actually log file, table, or
+     *                          other specific store to use. Defaults to an
+     *                          empty string, with which the subclass will
+     *                          attempt to do something intelligent.
+     *
+     * @param string $ident     The identity reported to the log system.
+     *
+     * @param array  $conf      A hash containing any additional configuration
+     *                          information that a subclass might need.
+     *
+     * @param int $level        Log messages up to and including this level.
+     *
+     * @return object Log       The newly created concrete Log instance, or
+     *                          null on an error.
+     * @access public
+     * @since Log 1.0
+     */
+    function &factory($handler, $name = '', $ident = '', $conf = array(),
+                      $level = PEAR_LOG_DEBUG)
+    {
+        $handler = strtolower($handler);
+        $class = 'Log_' . $handler;
+        $classfile = 'Log/' . $handler . '.php';
+
+        /*
+         * Attempt to include our version of the named class, but don't treat
+         * a failure as fatal.  The caller may have already included their own
+         * version of the named class.
+         */
+        if (!Log::_classExists($class)) {
+            include_once $classfile;
+        }
+
+        /* If the class exists, return a new instance of it. */
+        if (Log::_classExists($class)) {
+            $obj = &new $class($name, $ident, $conf, $level);
+            return $obj;
+        }
+
+        $null = null;
+        return $null;
+    }
+
+    /**
+     * Attempts to return a reference to a concrete Log instance of type
+     * $handler, only creating a new instance if no log instance with the same
+     * parameters currently exists.
+     *
+     * You should use this if there are multiple places you might create a
+     * logger, you don't want to create multiple loggers, and you don't want to
+     * check for the existance of one each time. The singleton pattern does all
+     * the checking work for you.
+     *
+     * <b>You MUST call this method with the $var = &Log::singleton() syntax.
+     * Without the ampersand (&) in front of the method name, you will not get
+     * a reference, you will get a copy.</b>
+     *
+     * @param string $handler   The type of concrete Log subclass to return.
+     *                          Attempt to dynamically include the code for
+     *                          this subclass. Currently, valid values are
+     *                          'console', 'syslog', 'sql', 'file', and 'mcal'.
+     *
+     * @param string $name      The name of the actually log file, table, or
+     *                          other specific store to use.  Defaults to an
+     *                          empty string, with which the subclass will
+     *                          attempt to do something intelligent.
+     *
+     * @param string $ident     The identity reported to the log system.
+     *
+     * @param array $conf       A hash containing any additional configuration
+     *                          information that a subclass might need.
+     *
+     * @param int $level        Log messages up to and including this level.
+     *
+     * @return object Log       The newly created concrete Log instance, or
+     *                          null on an error.
+     * @access public
+     * @since Log 1.0
+     */
+    function &singleton($handler, $name = '', $ident = '', $conf = array(),
+                        $level = PEAR_LOG_DEBUG)
+    {
+        static $instances;
+        if (!isset($instances)) $instances = array();
+
+        $signature = serialize(array($handler, $name, $ident, $conf, $level));
+        if (!isset($instances[$signature])) {
+            $instances[$signature] = &Log::factory($handler, $name, $ident,
+                                                   $conf, $level);
+        }
+
+        return $instances[$signature];
+    }
+
+    /**
+     * Abstract implementation of the open() method.
+     * @since Log 1.0
+     */
+    function open()
+    {
+        return false;
+    }
+
+    /**
+     * Abstract implementation of the close() method.
+     * @since Log 1.0
+     */
+    function close()
+    {
+        return false;
+    }
+
+    /**
+     * Abstract implementation of the flush() method.
+     * @since Log 1.8.2
+     */
+    function flush()
+    {
+        return false;
+    }
+
+    /**
+     * Abstract implementation of the log() method.
+     * @since Log 1.0
+     */
+    function log($message, $priority = null)
+    {
+        return false;
+    }
+
+    /**
+     * A convenience function for logging a emergency event.  It will log a
+     * message at the PEAR_LOG_EMERG log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function emerg($message)
+    {
+        return $this->log($message, PEAR_LOG_EMERG);
+    }
+
+    /**
+     * A convenience function for logging an alert event.  It will log a
+     * message at the PEAR_LOG_ALERT log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function alert($message)
+    {
+        return $this->log($message, PEAR_LOG_ALERT);
+    }
+
+    /**
+     * A convenience function for logging a critical event.  It will log a
+     * message at the PEAR_LOG_CRIT log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function crit($message)
+    {
+        return $this->log($message, PEAR_LOG_CRIT);
+    }
+
+    /**
+     * A convenience function for logging a error event.  It will log a
+     * message at the PEAR_LOG_ERR log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function err($message)
+    {
+        return $this->log($message, PEAR_LOG_ERR);
+    }
+
+    /**
+     * A convenience function for logging a warning event.  It will log a
+     * message at the PEAR_LOG_WARNING log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function warning($message)
+    {
+        return $this->log($message, PEAR_LOG_WARNING);
+    }
+
+    /**
+     * A convenience function for logging a notice event.  It will log a
+     * message at the PEAR_LOG_NOTICE log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function notice($message)
+    {
+        return $this->log($message, PEAR_LOG_NOTICE);
+    }
+
+    /**
+     * A convenience function for logging a information event.  It will log a
+     * message at the PEAR_LOG_INFO log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function info($message)
+    {
+        return $this->log($message, PEAR_LOG_INFO);
+    }
+
+    /**
+     * A convenience function for logging a debug event.  It will log a
+     * message at the PEAR_LOG_DEBUG log level.
+     *
+     * @param   mixed   $message    String or object containing the message
+     *                              to log.
+     *
+     * @return  boolean True if the message was successfully logged.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function debug($message)
+    {
+        return $this->log($message, PEAR_LOG_DEBUG);
+    }
+
+    /**
+     * Returns the string representation of the message data.
+     *
+     * If $message is an object, _extractMessage() will attempt to extract
+     * the message text using a known method (such as a PEAR_Error object's
+     * getMessage() method).  If a known method, cannot be found, the
+     * serialized representation of the object will be returned.
+     *
+     * If the message data is already a string, it will be returned unchanged.
+     *
+     * @param  mixed $message   The original message data.  This may be a
+     *                          string or any object.
+     *
+     * @return string           The string representation of the message.
+     *
+     * @access protected
+     */
+    function _extractMessage($message)
+    {
+        /*
+         * If we've been given an object, attempt to extract the message using
+         * a known method.  If we can't find such a method, default to the
+         * "human-readable" version of the object.
+         *
+         * We also use the human-readable format for arrays.
+         */
+        if (is_object($message)) {
+            if (method_exists($message, 'getmessage')) {
+                $message = $message->getMessage();
+            } else if (method_exists($message, 'tostring')) {
+                $message = $message->toString();
+            } else if (method_exists($message, '__tostring')) {
+                if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {
+                    $message = (string)$message;
+                } else {
+                    $message = $message->__toString();
+                }
+            } else {
+                $message = var_export($message, true);
+            }
+        } else if (is_array($message)) {
+            if (isset($message['message'])) {
+                if (is_scalar($message['message'])) {
+                    $message = $message['message'];
+                } else {
+                    $message = var_export($message['message'], true);
+                }
+            } else {
+                $message = var_export($message, true);
+            }
+        } else if (is_bool($message) || $message === NULL) {
+            $message = var_export($message, true);
+        }
+
+        /* Otherwise, we assume the message is a string. */
+        return $message;
+    }
+
+    /**
+     * Using debug_backtrace(), returns the file, line, and enclosing function
+     * name of the source code context from which log() was invoked.
+     *
+     * @param   int     $depth  The initial number of frames we should step
+     *                          back into the trace.
+     *
+     * @return  array   Array containing four strings: the filename, the line,
+     *                  the function name, and the class name from which log()
+     *                  was called.
+     *
+     * @access  private
+     * @since   Log 1.9.4
+     */
+    function _getBacktraceVars($depth)
+    {
+        /* Start by generating a backtrace from the current call (here). */
+        $bt = debug_backtrace();
+
+        /*
+         * If we were ultimately invoked by the composite handler, we need to
+         * increase our depth one additional level to compensate.
+         */
+        $class = isset($bt[$depth+1]['class']) ? $bt[$depth+1]['class'] : null;
+        if ($class !== null && strcasecmp($class, 'Log_composite') == 0) {
+            $depth++;
+            $class = isset($bt[$depth + 1]) ? $bt[$depth + 1]['class'] : null;
+        }
+
+        /*
+         * We're interested in the frame which invoked the log() function, so
+         * we need to walk back some number of frames into the backtrace.  The
+         * $depth parameter tells us where to start looking.   We go one step
+         * further back to find the name of the encapsulating function from
+         * which log() was called.
+         */
+        $file = isset($bt[$depth])     ? $bt[$depth]['file'] : null;
+        $line = isset($bt[$depth])     ? $bt[$depth]['line'] : 0;
+        $func = isset($bt[$depth + 1]) ? $bt[$depth + 1]['function'] : null;
+
+        /*
+         * However, if log() was called from one of our "shortcut" functions,
+         * we're going to need to go back an additional step.
+         */
+        if (in_array($func, array('emerg', 'alert', 'crit', 'err', 'warning',
+                                  'notice', 'info', 'debug'))) {
+            $file = isset($bt[$depth + 1]) ? $bt[$depth + 1]['file'] : null;
+            $line = isset($bt[$depth + 1]) ? $bt[$depth + 1]['line'] : 0;
+            $func = isset($bt[$depth + 2]) ? $bt[$depth + 2]['function'] : null;
+        }
+
+        /*
+         * If we couldn't extract a function name (perhaps because we were
+         * executed from the "main" context), provide a default value.
+         */
+        if (is_null($func)) {
+            $func = '(none)';
+        }
+
+        /* Return a 4-tuple containing (file, line, function, class). */
+        return array($file, $line, $func, $class);
+    }
+
+    /**
+     * Produces a formatted log line based on a format string and a set of
+     * variables representing the current log record and state.
+     *
+     * @return  string  Formatted log string.
+     *
+     * @access  protected
+     * @since   Log 1.9.4
+     */
+    function _format($format, $timestamp, $priority, $message)
+    {
+        /*
+         * If the format string references any of the backtrace-driven
+         * variables (%5 %6,%7,%8), generate the backtrace and fetch them.
+         */
+        if (preg_match('/%[5678]/', $format)) {
+            list($file, $line, $func, $class) = $this->_getBacktraceVars(2);
+        }
+
+        /*
+         * Build the formatted string.  We use the sprintf() function's
+         * "argument swapping" capability to dynamically select and position
+         * the variables which will ultimately appear in the log string.
+         */
+        return sprintf($format,
+                       $timestamp,
+                       $this->_ident,
+                       $this->priorityToString($priority),
+                       $message,
+                       isset($file) ? $file : '',
+                       isset($line) ? $line : '',
+                       isset($func) ? $func : '',
+                       isset($class) ? $class : '');
+    }
+
+    /**
+     * Returns the string representation of a PEAR_LOG_* integer constant.
+     *
+     * @param int $priority     A PEAR_LOG_* integer constant.
+     *
+     * @return string           The string representation of $level.
+     *
+     * @access  public
+     * @since   Log 1.0
+     */
+    function priorityToString($priority)
+    {
+        $levels = array(
+            PEAR_LOG_EMERG   => 'emergency',
+            PEAR_LOG_ALERT   => 'alert',
+            PEAR_LOG_CRIT    => 'critical',
+            PEAR_LOG_ERR     => 'error',
+            PEAR_LOG_WARNING => 'warning',
+            PEAR_LOG_NOTICE  => 'notice',
+            PEAR_LOG_INFO    => 'info',
+            PEAR_LOG_DEBUG   => 'debug'
+        );
+
+        return $levels[$priority];
+    }
+
+    /**
+     * Returns the the PEAR_LOG_* integer constant for the given string
+     * representation of a priority name.  This function performs a
+     * case-insensitive search.
+     *
+     * @param string $name      String containing a priority name.
+     *
+     * @return string           The PEAR_LOG_* integer contstant corresponding
+     *                          the the specified priority name.
+     *
+     * @access  public
+     * @since   Log 1.9.0
+     */
+    function stringToPriority($name)
+    {
+        $levels = array(
+            'emergency' => PEAR_LOG_EMERG,
+            'alert'     => PEAR_LOG_ALERT,
+            'critical'  => PEAR_LOG_CRIT,
+            'error'     => PEAR_LOG_ERR,
+            'warning'   => PEAR_LOG_WARNING,
+            'notice'    => PEAR_LOG_NOTICE,
+            'info'      => PEAR_LOG_INFO,
+            'debug'     => PEAR_LOG_DEBUG
+        );
+
+        return $levels[strtolower($name)];
+    }
+
+    /**
+     * Calculate the log mask for the given priority.
+     *
+     * This method may be called statically.
+     *
+     * @param integer   $priority   The priority whose mask will be calculated.
+     *
+     * @return integer  The calculated log mask.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function MASK($priority)
+    {
+        return (1 << $priority);
+    }
+
+    /**
+     * Calculate the log mask for all priorities up to the given priority.
+     *
+     * This method may be called statically.
+     *
+     * @param integer   $priority   The maximum priority covered by this mask.
+     *
+     * @return integer  The resulting log mask.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     *
+     * @deprecated deprecated since Log 1.9.4; use Log::MAX() instead
+     */
+    function UPTO($priority)
+    {
+        return Log::MAX($priority);
+    }
+
+    /**
+     * Calculate the log mask for all priorities greater than or equal to the
+     * given priority.  In other words, $priority will be the lowest priority
+     * matched by the resulting mask.
+     *
+     * This method may be called statically.
+     *
+     * @param integer   $priority   The minimum priority covered by this mask.
+     *
+     * @return integer  The resulting log mask.
+     *
+     * @access  public
+     * @since   Log 1.9.4
+     */
+    function MIN($priority)
+    {
+        return PEAR_LOG_ALL ^ ((1 << $priority) - 1);
+    }
+
+    /**
+     * Calculate the log mask for all priorities less than or equal to the
+     * given priority.  In other words, $priority will be the highests priority
+     * matched by the resulting mask.
+     *
+     * This method may be called statically.
+     *
+     * @param integer   $priority   The maximum priority covered by this mask.
+     *
+     * @return integer  The resulting log mask.
+     *
+     * @access  public
+     * @since   Log 1.9.4
+     */
+    function MAX($priority)
+    {
+        return ((1 << ($priority + 1)) - 1);
+    }
+
+    /**
+     * Set and return the level mask for the current Log instance.
+     *
+     * @param integer $mask     A bitwise mask of log levels.
+     *
+     * @return integer          The current level mask.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function setMask($mask)
+    {
+        $this->_mask = $mask;
+
+        return $this->_mask;
+    }
+
+    /**
+     * Returns the current level mask.
+     *
+     * @return interger         The current level mask.
+     *
+     * @access  public
+     * @since   Log 1.7.0
+     */
+    function getMask()
+    {
+        return $this->_mask;
+    }
+
+    /**
+     * Check if the given priority is included in the current level mask.
+     *
+     * @param integer   $priority   The priority to check.
+     *
+     * @return boolean  True if the given priority is included in the current
+     *                  log mask.
+     *
+     * @access  protected
+     * @since   Log 1.7.0
+     */
+    function _isMasked($priority)
+    {
+        return (Log::MASK($priority) & $this->_mask);
+    }
+
+    /**
+     * Returns the current default priority.
+     *
+     * @return integer  The current default priority.
+     *
+     * @access  public
+     * @since   Log 1.8.4
+     */
+    function getPriority()
+    {
+        return $this->_priority;
+    }
+
+    /**
+     * Sets the default priority to the specified value.
+     *
+     * @param   integer $priority   The new default priority.
+     *
+     * @access  public
+     * @since   Log 1.8.4
+     */
+    function setPriority($priority)
+    {
+        $this->_priority = $priority;
+    }
+
+    /**
+     * Adds a Log_observer instance to the list of observers that are listening
+     * for messages emitted by this Log instance.
+     *
+     * @param object    $observer   The Log_observer instance to attach as a
+     *                              listener.
+     *
+     * @param boolean   True if the observer is successfully attached.
+     *
+     * @access  public
+     * @since   Log 1.0
+     */
+    function attach(&$observer)
+    {
+        if (!is_a($observer, 'Log_observer')) {
+            return false;
+        }
+
+        $this->_listeners[$observer->_id] = &$observer;
+
+        return true;
+    }
+
+    /**
+     * Removes a Log_observer instance from the list of observers.
+     *
+     * @param object    $observer   The Log_observer instance to detach from
+     *                              the list of listeners.
+     *
+     * @param boolean   True if the observer is successfully detached.
+     *
+     * @access  public
+     * @since   Log 1.0
+     */
+    function detach($observer)
+    {
+        if (!is_a($observer, 'Log_observer') ||
+            !isset($this->_listeners[$observer->_id])) {
+            return false;
+        }
+
+        unset($this->_listeners[$observer->_id]);
+
+        return true;
+    }
+
+    /**
+     * Informs each registered observer instance that a new message has been
+     * logged.
+     *
+     * @param array     $event      A hash describing the log event.
+     *
+     * @access protected
+     */
+    function _announce($event)
+    {
+        foreach ($this->_listeners as $id => $listener) {
+            if ($event['priority'] <= $this->_listeners[$id]->_priority) {
+                $this->_listeners[$id]->notify($event);
+            }
+        }
+    }
+
+    /**
+     * Indicates whether this is a composite class.
+     *
+     * @return boolean          True if this is a composite class.
+     *
+     * @access  public
+     * @since   Log 1.0
+     */
+    function isComposite()
+    {
+        return false;
+    }
+
+    /**
+     * Sets this Log instance's identification string.
+     *
+     * @param string    $ident      The new identification string.
+     *
+     * @access  public
+     * @since   Log 1.6.3
+     */
+    function setIdent($ident)
+    {
+        $this->_ident = $ident;
+    }
+
+    /**
+     * Returns the current identification string.
+     *
+     * @return string   The current Log instance's identification string.
+     *
+     * @access  public
+     * @since   Log 1.6.3
+     */
+    function getIdent()
+    {
+        return $this->_ident;
+    }
+}
Index: /sandbox/workflow/branches/993/inc/log/docs/guide.txt
===================================================================
--- /sandbox/workflow/branches/993/inc/log/docs/guide.txt	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/docs/guide.txt	(revision 795)
@@ -0,0 +1,1282 @@
+=================
+ The Log Package
+=================
+
+--------------------
+ User Documentation
+--------------------
+
+:Author:        Jon Parise
+:Contact:       jon@php.net
+:Date:          $Date: 2008/11/19 05:12:26 $
+:Revision:      $Revision: 1.41 $
+
+.. contents:: Contents
+.. section-numbering::
+
+Using Log Handlers
+==================
+
+The Log package is implemented as a framework that supports the notion of
+backend-specific log handlers.  The base logging object (defined by the `Log
+class`_) is primarily an abstract interface to the currently configured
+handler.
+
+A wide variety of handlers are distributed with the Log package, and, should
+none of them fit your application's needs, it's easy to `write your own`__.
+
+.. _Log class: http://cvs.php.net/viewvc.cgi/pear/Log/Log.php
+__ `Custom Handlers`_
+
+Creating a Log Object
+---------------------
+There are three ways to create Log objects:
+
+    - Using the ``Log::factory()`` method
+    - Using the ``Log::singleton()`` method
+    - Direct instantiation
+
+The Factory Method
+~~~~~~~~~~~~~~~~~~
+The ``Log::factory()`` method implements the `Factory Pattern`_.  It allows
+for the parameterized construction of concrete Log instances at runtime.  The
+first parameter to the ``Log::factory()`` method indicates the name of the
+concrete handler to create.  The rest of the parameters will be passed on to
+the handler's constructor (see `Configuring a Handler`_ below).
+
+The new ``Log`` instance is returned by reference.
+
+::
+
+    require_once 'Log.php';
+
+    $console = &Log::factory('console', '', 'TEST');
+    $console->log('Logging to the console.');
+
+    $file = &Log::factory('file', 'out.log', 'TEST');
+    $file->log('Logging to out.log.');
+
+.. _Factory Pattern: http://wikipedia.org/wiki/Factory_method_pattern
+
+The Singleton Method
+~~~~~~~~~~~~~~~~~~~~
+The ``Log::singleton()`` method implements the `Singleton Pattern`_.  The
+singleton pattern ensures that only a single instance of a given log type and
+configuration is ever created.  This has two benefits: first, it prevents
+duplicate ``Log`` instances from being constructed, and, second, it gives all
+of your code access to the same ``Log`` instance.  The latter is especially
+important when logging to files because only a single file handler will need
+to be managed.
+
+The ``Log::singleton()`` method's parameters match the ``Log::factory()``
+method.  The new ``Log`` instance is returned by reference.
+
+::
+
+    require_once 'Log.php';
+
+    /* Same construction parameters */
+    $a = &Log::singleton('console', '', 'TEST');
+    $b = &Log::singleton('console', '', 'TEST');
+
+    if ($a === $b) {
+        echo '$a and $b point to the same Log instance.' . "\n";
+    }
+
+    /* Different construction parameters */
+    $c = &Log::singleton('console', '', 'TEST1');
+    $d = &Log::singleton('console', '', 'TEST2');
+
+    if ($c !== $d) {
+        echo '$c and $d point to different Log instances.' . "\n";
+    }
+
+.. _Singleton Pattern: http://wikipedia.org/wiki/Singleton_pattern
+
+Direct Instantiation
+~~~~~~~~~~~~~~~~~~~~
+It is also possible to directly instantiate concrete ``Log`` handler
+instances.  However, this method is **not recommended** because it creates a
+tighter coupling between your application code and the Log package than is
+necessary.  Use of `the factory method`_ or `the singleton method`_ is
+preferred.
+
+
+Configuring a Handler
+---------------------
+A log handler's configuration is determined by the arguments used in its
+construction.  Here's an overview of those parameters::
+
+    /* Using the factory method ... */
+    &Log::factory($handler, $name, $ident, $conf, $maxLevel);
+
+    /* Using the singleton method ... */
+    &Log::singleton($handler, $name, $ident, $conf, $maxLevel);
+
+    /* Using direct instantiation ... */
+    new Log_handler($name, $ident, $conf, $maxLevel);
+
++---------------+-----------+-----------------------------------------------+
+| Parameter     | Type      | Description                                   |
++===============+===========+===============================================+
+| ``$handler``  | String    | The type of Log handler to construct.  This   |
+|               |           | parameter is only available when `the factory |
+|               |           | method`_ or `the singleton method`_ are used. |
++---------------+-----------+-----------------------------------------------+
+| ``$name``     | String    | The name of the log resource to which the     |
+|               |           | events will be logged.  The use of this value |
+|               |           | is determined by the handler's implementation.|
+|               |           | It defaults to an empty string.               |
++---------------+-----------+-----------------------------------------------+
+| ``$ident``    | String    | An identification string that will be included|
+|               |           | in all log events logged by this handler.     |
+|               |           | This value defaults to an empty string and can|
+|               |           | be changed at runtime using the ``setIdent()``|
+|               |           | method.                                       |
++---------------+-----------+-----------------------------------------------+
+| ``$conf``     | Array     | Associative array of key-value pairs that are |
+|               |           | used to specify any handler-specific settings.|
++---------------+-----------+-----------------------------------------------+
+| ``$level``    | Integer   | Log messages up to and including this level.  |
+|               |           | This value defaults to ``PEAR_LOG_DEBUG``.    |
+|               |           | See `Log Levels`_ and `Log Level Masks`_.     |
++---------------+-----------+-----------------------------------------------+
+
+
+Logging an Event
+----------------
+Events are logged using the ``log()`` method::
+
+    $logger->log('Message', PEAR_LOG_NOTICE);
+
+The first argument contains the log event's message.  Even though the event is
+always logged as a string, it is possible to pass an object to the ``log()``
+method.  If the object implements a ``getString()`` method, a ``toString()``
+method or Zend Engine 2's special ``__toString()`` casting method, it will be
+used to determine the object's string representation.  Otherwise, the
+`serialized`_ form of the object will be logged.
+
+The second, optional argument specifies the log event's priority.  See the
+`Log Levels`_ table for the complete list of priorities.  The default priority
+is PEAR_LOG_INFO.
+
+The ``log()`` method will return ``true`` if the event was successfully
+logged.
+
+"Shortcut" methods are also available for logging an event at a specific log
+level.  See the `Log Levels`_ table for the complete list.
+
+.. _serialized: http://www.php.net/serialize
+
+
+Log Levels
+----------
+This table is ordered by highest priority (``PEAR_LOG_EMERG``) to lowest
+priority (``PEAR_LOG_DEBUG``).
+
++-----------------------+---------------+-----------------------------------+
+| Level                 | Shortcut      | Description                       |
++=======================+===============+===================================+
+| ``PEAR_LOG_EMERG``    | ``emerg()``   | System is unusable                |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_ALERT``    | ``alert()``   | Immediate action required         |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_CRIT``     | ``crit()``    | Critical conditions               |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_ERR``      | ``err()``     | Error conditions                  |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_WARNING``  | ``warning()`` | Warning conditions                |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_NOTICE``   | ``notice()``  | Normal but significant            |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_INFO``     | ``info()``    | Informational                     |
++-----------------------+---------------+-----------------------------------+
+| ``PEAR_LOG_DEBUG``    | ``debug()``   | Debug-level messages              |
++-----------------------+---------------+-----------------------------------+
+
+
+Log Level Masks
+---------------
+Defining a log level mask allows you to include and/or exclude specific levels
+of events from being logged.  The ``$level`` construction parameter (see
+`Configuring a Handler`_) uses this mechanism to exclude log events below a
+certain priority, and it's possible to define more complex masks once the Log
+object has been constructed.
+
+Each priority has a specific mask associated with it.  To compute a priority's
+mask, use the static ``Log::MASK()`` method::
+
+    $mask = Log::MASK(PEAR_LOG_INFO);
+
+To compute the mask for all priorities up to, and including, a certain level,
+use the ``Log::MAX()`` static method::
+
+    $mask = Log::MAX(PEAR_LOG_INFO);
+
+To compute the mask for all priorities greater than or equal to a certain
+level, use the ``Log::MIN()`` static method::
+
+    $mask = Log::MIN(PEAR_LOG_INFO);
+
+The apply the mask, use the ``setMask()`` method::
+
+    $logger->setMask($mask);
+
+Masks can be be combined using bitwise operations.  To restrict logging to
+only those events marked as ``PEAR_LOG_NOTICE`` or ``PEAR_LOG_DEBUG``::
+
+    $mask = Log::MASK(PEAR_LOG_NOTICE) | Log::MASK(PEAR_LOG_DEBUG);
+    $logger->setMask($mask);
+
+For convenience, two special masks are predefined: ``PEAR_LOG_NONE`` and
+``PEAR_LOG_ALL``.  ``PEAR_LOG_ALL`` is especially useful for excluding only
+specific priorities::
+
+    $mask = PEAR_LOG_ALL ^ Log::MASK(PEAR_LOG_NOTICE);
+    $logger->setMask($mask);
+
+It is also possible to retrieve and modify a Log object's existing mask::
+
+    $mask = $logger->getMask() | Log::MASK(PEAR_LOG_INFO);
+    $logger->setMask($mask);
+
+
+Log Line Format
+---------------
+Most log handlers support configurable line formats.  The following is a list 
+of special tokens that will be expanded at runtime with contextual information
+related to the log event.  Each token has an alternate shorthand notation, as
+well.
+
++------------------+-----------+--------------------------------------------+
+| Token            | Alternate | Description                                |
++==================+===========+============================================+
+| ``%{timestamp}`` | ``%1$s``  | Timestamp.  This is often configurable.    |
++------------------+-----------+--------------------------------------------+
+| ``%{ident}``     | ``%2$s``  | The log handler's identification string.   |
++------------------+-----------+--------------------------------------------+
+| ``%{priority}``  | ``%3$s``  | The log event's priority.                  |
++------------------+-----------+--------------------------------------------+
+| ``%{message}``   | ``%4$s``  | The log event's message text.              |
++------------------+-----------+--------------------------------------------+
+| ``%{file}``      | ``%5$s``  | The full filename of the logging file.     |
++------------------+-----------+--------------------------------------------+
+| ``%{line}``      | ``%6$s``  | The line number on which the event occured.|
++------------------+-----------+--------------------------------------------+
+| ``%{function}``  | ``%7$s``  | The function from which the event occurred.|
++------------------+-----------+--------------------------------------------+
+| ``%{class}``     | ``%8$s``  | The class in which the event occurred.     |
++------------------+-----------+--------------------------------------------+
+
+
+Flushing Log Events
+-------------------
+Some log handlers (such as `the console handler`_) support explicit
+"buffering".  When buffering is enabled, log events won't actually be written
+to the output stream until the handler is closed.  Other handlers (such as
+`the file handler`_) support implicit buffering because they use the operating
+system's IO routines, which may buffer the output.
+
+It's possible to force these handlers to flush their output, however, by
+calling their ``flush()`` method::
+
+    $conf = array('buffering' => true);
+    $logger = &Log::singleton('console', '', 'test', $conf);
+
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log('This event will be buffered.');
+    }
+
+    /* Flush all of the buffered log events. */
+    $logger->flush();
+
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log('This event will be buffered.');
+    }
+
+    /* Implicitly flush the buffered events on close. */
+    $logger->close();
+
+At this time, the ``flush()`` method is only implemented by `the console
+handler`_, `the file handler`_, `the Firebug handler`_, and `the mail
+handler`_.
+
+
+Standard Log Handlers
+=====================
+
+The Console Handler
+-------------------
+The Console handler outputs log events directly to the console.  It supports
+output buffering and configurable string formats.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``stream``        | File      | STDOUT_       | The output stream to use. |
++-------------------+-----------+---------------+---------------------------+
+| ``buffering``     | Boolean   | False         | Should the output be      |
+|                   |           |               | buffered until shutdown?  |
++-------------------+-----------+---------------+---------------------------+
+| ``lineFormat``    | String    | ``%1$s %2$s   | `Log line format`_        |
+|                   |           | [%3$s] %4$s`` | specification.            |
++-------------------+-----------+---------------+---------------------------+
+| ``timeFormat``    | String    | ``%b %d       | Time stamp format         |
+|                   |           | %H:%M:%S``    | (for strftime_).          |
++-------------------+-----------+---------------+---------------------------+
+
+.. _STDOUT: http://www.php.net/wrappers.php
+.. _strftime: http://www.php.net/strftime
+
+Example
+~~~~~~~
+::
+
+    $logger = &Log::singleton('console', '', 'ident');
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The Display Handler
+-------------------
+The Display handler simply prints the log events back to the browser.  It
+respects the ``error_prepend_string`` and ``error_append_string`` `error
+handling values`_ and is useful when `logging from standard error handlers`_.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``lineFormat``    | String    | ``<b>%3$s</b>:| `Log line format`_        |
+|                   |           | %4$s``        | specification.            |
++-------------------+-----------+---------------+---------------------------+
+| ``timeFormat``    | String    | ``%b %d       | Time stamp format         |
+|                   |           | %H:%M:%S``    | (for strftime_).          |
++-------------------+-----------+---------------+---------------------------+
+| ``error_prepend`` | String    | PHP INI value | This string will be       |
+|                   |           |               | prepended to the line     |
+|                   |           |               | format.                   |
++-------------------+-----------+---------------+---------------------------+
+| ``error_append``  | String    | PHP INI value | This string will be       |
+|                   |           |               | appended to the line      |
+|                   |           |               | format.                   |
++-------------------+-----------+---------------+---------------------------+
+| ``linebreak``     | String    | ``<br />\n``  | This string is used to    |
+|                   |           |               | represent a line break.   |
++-------------------+-----------+---------------+---------------------------+
+
+.. _error handling values: http://www.php.net/errorfunc
+
+Example
+~~~~~~~
+::
+
+    $conf = array('error_prepend' => '<font color="#ff0000"><tt>',
+                  'error_append'  => '</tt></font>');
+    $logger = &Log::singleton('display', '', '', $conf, PEAR_LOG_DEBUG);
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The Error_Log Handler
+---------------------
+The Error_Log handler sends log events to PHP's `error_log()`_ function.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``destination``   | String    | '' `(empty)`  | Optional destination value|
+|                   |           |               | for `error_log()`_.  See  |
+|                   |           |               | `Error_Log Types`_ for    |
+|                   |           |               | more details.             |
++-------------------+-----------+---------------+---------------------------+
+| ``extra_headers`` | String    | '' `(empty)`  | Additional headers to pass|
+|                   |           |               | to the `mail()`_ function |
+|                   |           |               | when the                  |
+|                   |           |               | ``PEAR_LOG_TYPE_MAIL``    |
+|                   |           |               | type is specified.        |
++-------------------+-----------+---------------+---------------------------+
+| ``lineFormat``    | String    | ``%2$s: %4$s``| `Log line format`_        |
+|                   |           |               | specification.            |
++-------------------+-----------+---------------+---------------------------+
+| ``timeFormat``    | String    | ``%b %d       | Time stamp format         |
+|                   |           | %H:%M:%S``    | (for strftime_).          |
++-------------------+-----------+---------------+---------------------------+
+
+Error_Log Types
+~~~~~~~~~~~~~~~
+All of the available log types are detailed in the `error_log()`_ section of
+the PHP manual.  For your convenience, the Log package also defines the
+following constants that can be used for the ``$name`` handler construction
+parameter.
+
++---------------------------+-----------------------------------------------+
+| Constant                  | Description                                   |
++===========================+===============================================+
+| ``PEAR_LOG_TYPE_SYSTEM``  | Log events are sent to PHP's system logger,   |
+|                           | which uses the operating system's logging     |
+|                           | mechanism or a file (depending on the value   |
+|                           | of the `error_log configuration directive`_). |
++---------------------------+-----------------------------------------------+
+| ``PEAR_LOG_TYPE_MAIL``    | Log events are sent via email to the address  |
+|                           | specified in the ``destination`` value.       |
++---------------------------+-----------------------------------------------+
+| ``PEAR_LOG_TYPE_DEBUG``   | Log events are sent through PHP's debugging   |
+|                           | connection.  This will only work if           |
+|                           | `remote debugging`_ has been enabled.  The    |
+|                           | ``destination`` value is used to specify the  |
+|                           | host name or IP address of the target socket. |
++---------------------------+-----------------------------------------------+
+| ``PEAR_LOG_TYPE_FILE``    | Log events will be appended to the file named |
+|                           | by the ``destination`` value.                 |
++---------------------------+-----------------------------------------------+
+
+.. _error_log(): http://www.php.net/error_log
+.. _mail(): http://www.php.net/mail
+.. _error_log configuration directive: http://www.php.net/errorfunc#ini.error-log
+.. _remote debugging: http://www.php.net/install.configure#install.configure.enable-debugger
+
+Example
+~~~~~~~
+::
+
+    $logger = &Log::singleton('error_log', PEAR_LOG_TYPE_SYSTEM, 'ident');
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The File Handler
+----------------
+The File handler writes log events to a text file using configurable string
+formats.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``append``        | Boolean   | True          | Should new log entries be |
+|                   |           |               | append to an existing log |
+|                   |           |               | file, or should the a new |
+|                   |           |               | log file overwrite an     |
+|                   |           |               | existing one?             |
++-------------------+-----------+---------------+---------------------------+
+| ``locking``       | Boolean   | False         | Should advisory file      |
+|                   |           |               | locking (using flock_) be |
+|                   |           |               | used?                     |
++-------------------+-----------+---------------+---------------------------+
+| ``mode``          | Integer   | 0644          | Octal representation of   |
+|                   |           |               | the log file's permissions|
+|                   |           |               | mode.                     |
++-------------------+-----------+---------------+---------------------------+
+| ``dirmode``       | Integer   | 0755          | Octal representation of   |
+|                   |           |               | the file permission mode  |
+|                   |           |               | that will be used when    |
+|                   |           |               | creating directories that |
+|                   |           |               | do not already exist.     |
++-------------------+-----------+---------------+---------------------------+
+| ``eol``           | String    | OS default    | The end-on-line character |
+|                   |           |               | sequence.                 |
++-------------------+-----------+---------------+---------------------------+
+| ``lineFormat``    | String    | ``%1$s %2$s   | `Log line format`_        |
+|                   |           | [%3$s] %4$s`` | specification.            |
++-------------------+-----------+---------------+---------------------------+
+| ``timeFormat``    | String    | ``%b %d       | Time stamp format         |
+|                   |           | %H:%M:%S``    | (for strftime_).          |
++-------------------+-----------+---------------+---------------------------+
+
+.. _flock: http://www.php.net/flock
+.. _strftime: http://www.php.net/strftime
+
+The file handler will only attempt to set the ``mode`` value if it was
+responsible for creating the file.
+
+Example
+~~~~~~~
+::
+
+    $conf = array('mode' => 0600, 'timeFormat' => '%X %x');
+    $logger = &Log::singleton('file', 'out.log', 'ident', $conf);
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The Firebug Handler
+-------------------
+The Firebug handler outputs log events to the Firebug_ console. It supports
+output buffering and configurable string formats.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``buffering``     | Boolean   | False         | Should the output be      |
+|                   |           |               | buffered until shutdown?  |
++-------------------+-----------+---------------+---------------------------+
+| ``lineFormat``    | String    | ``%2$s [%3$s] | `Log line format`_        |
+|                   |           | %4$s``        | specification.            |
++-------------------+-----------+---------------+---------------------------+
+| ``timeFormat``    | String    | ``%b %d       | Time stamp format         |
+|                   |           | %H:%M:%S``    | (for strftime_).          |
++-------------------+-----------+---------------+---------------------------+
+
+.. _Firebug: http://www.getfirebug.com/
+.. _strftime: http://www.php.net/strftime
+
+Example
+~~~~~~~
+::
+
+    $logger = &Log::singleton('firebug', '', 'ident');
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The Mail Handler
+----------------
+
+The Mail handler aggregates a session's log events and sends them in the body
+of an email message using either the `PEAR Mail`_ package or PHP's native
+`mail()`_ function.
+
+If an empty ``mailBackend`` value is specified, the `mail()`_ function will be
+used instead of the `PEAR Mail`_ package.
+
+Multiple recipients can be specified by separating their email addresses with
+commas in the ``$name`` construction parameter.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``from``          | String    | sendmail_from | Value for the message's   |
+|                   |           | INI value     | ``From:`` header.         |
++-------------------+-----------+---------------+---------------------------+
+| ``subject``       | String    | ``[Log_mail]  | Value for the message's   |
+|                   |           | Log message`` | ``Subject:`` header.      |
++-------------------+-----------+---------------+---------------------------+
+| ``preamble``      | String    | `` `(empty)`  | Preamble for the message. |
++-------------------+-----------+---------------+---------------------------+
+| ``lineFormat``    | String    | ``%1$s %2$s   | `Log line format`_        |
+|                   |           | [%3$s] %4$s`` | specification.            |
++-------------------+-----------+---------------+---------------------------+
+| ``timeFormat``    | String    | ``%b %d       | Time stamp format         |
+|                   |           | %H:%M:%S``    | (for strftime_).          |
++-------------------+-----------+---------------+---------------------------+
+| ``mailBackend``   | String    | `` `(empty)`  | Name of the Mail package  |
+|                   |           |               | backend to use.           |
++-------------------+-----------+---------------+---------------------------+
+| ``mailParams``    | Array     | `(empty)`     | Array of parameters that  |
+|                   |           |               | will be passed to the     |
+|                   |           |               | Mail package backend.     |
++-------------------+-----------+---------------+---------------------------+
+
+.. _PEAR Mail: http://pear.php.net/package/Mail
+.. _mail(): http://www.php.net/mail
+
+Example
+~~~~~~~
+::
+
+    $conf = array('subject' => 'Important Log Events');
+    $logger = &Log::singleton('mail', 'webmaster@example.com', 'ident', $conf);
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The MDB2 Handler
+----------------
+The MDB2 handler is similar to `the SQL (DB) handler`_, but instead of using
+the PEAR DB package, it uses the `MDB2 database abstraction package`_.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``dsn``           | Mixed     | '' `(empty)`  | A `Data Source Name`_.    |
+|                   |           |               | |required|                |
++-------------------+-----------+---------------+---------------------------+
+| ``options``       | Array     | ``persistent``| An array of `MDB2`_       |
+|                   |           |               | options.                  |
++-------------------+-----------+---------------+---------------------------+
+| ``db``            | Object    | NULL          | An existing `MDB2`_       |
+|                   |           |               | object.  If specified,    |
+|                   |           |               | this object will be used, |
+|                   |           |               | and ``dsn`` will be       |
+|                   |           |               | ignored.                  |
++-------------------+-----------+---------------+---------------------------+
+| ``sequence``      | String    | ``log_id``    | The name of the sequence  |
+|                   |           |               | to use when generating    |
+|                   |           |               | unique event IDs.   Under |
+|                   |           |               | many databases, this will |
+|                   |           |               | be used as the name of    |
+|                   |           |               | the sequence table.       |
++-------------------+-----------+---------------+---------------------------+
+| ``identLimit``    | Integer   | 16            | The maximum length of the |
+|                   |           |               | ``ident`` string.         |
+|                   |           |               | **Changing this value may |
+|                   |           |               | require updates to the SQL|
+|                   |           |               | schema, as well.**        |
++-------------------+-----------+---------------+---------------------------+
+| ``singleton``     | Boolean   | false         | Is true, use a singleton  |
+|                   |           |               | database object using     |
+|                   |           |               | `MDB2::singleton()`_.     |
++-------------------+-----------+---------------+---------------------------+
+
+.. _MDB2: http://pear.php.net/package/MDB2
+.. _MDB2 database abstraction package: MDB2_
+.. _MDB2::singleton(): http://pear.php.net/package/MDB2/docs/latest/MDB2/MDB2.html#methodsingleton
+
+The Null Handler
+----------------
+The Null handler simply consumes log events (akin to sending them to
+``/dev/null``).  `Log level masks`_ are respected, and the event will still be
+sent to any registered `log observers`_.
+
+Example
+~~~~~~~
+::
+
+    $logger = &Log::singleton('null');
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The SQL (DB) Handler
+--------------------
+
+The SQL handler sends log events to a database using `PEAR's DB abstraction
+layer`_.
+
+**Note:** Due to the constraints of the default database schema, the SQL
+handler limits the length of the ``$ident`` string to sixteen (16) characters.
+This limit can be adjusted using the ``identLimit`` configuration parameter.
+
+The Log Table
+~~~~~~~~~~~~~
+The default SQL table used by this handler looks like this::
+
+    CREATE TABLE log_table (
+        id          INT NOT NULL,
+        logtime     TIMESTAMP NOT NULL,
+        ident       CHAR(16) NOT NULL,
+        priority    INT NOT NULL,
+        message     VARCHAR(200),
+        PRIMARY KEY (id)
+    );
+
+This is the "lowest common denominator" that should work across all SQL
+compliant database.  You may want to make database- or site-specific changes
+to this schema to support your specific needs, however.  For example,
+`PostgreSQL`_ users may prefer to use a ``TEXT`` type for the ``message``
+field.
+
+.. _PostgreSQL: http://www.postgresql.org/
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``dsn``           | Mixed     | '' `(empty)`  | A `Data Source Name`_.    |
+|                   |           |               | |required|                |
++-------------------+-----------+---------------+---------------------------+
+| ``sql``           | String    | |sql-default| | SQL insertion statement.  |
++-------------------+-----------+---------------+---------------------------+
+| ``options``       | Array     | ``persistent``| An array of `DB`_ options.|
++-------------------+-----------+---------------+---------------------------+
+| ``db``            | Object    | NULL          | An existing `DB`_ object. |
+|                   |           |               | If specified, this object |
+|                   |           |               | will be used, and ``dsn`` |
+|                   |           |               | will be ignored.          |
++-------------------+-----------+---------------+---------------------------+
+| ``sequence``      | String    | ``log_id``    | The name of the sequence  |
+|                   |           |               | to use when generating    |
+|                   |           |               | unique event IDs.   Under |
+|                   |           |               | many databases, this will |
+|                   |           |               | be used as the name of    |
+|                   |           |               | the sequence table.       |
++-------------------+-----------+---------------+---------------------------+
+| ``identLimit``    | Integer   | 16            | The maximum length of the |
+|                   |           |               | ``ident`` string.         |
+|                   |           |               | **Changing this value may |
+|                   |           |               | require updates to the SQL|
+|                   |           |               | schema, as well.**        |
++-------------------+-----------+---------------+---------------------------+
+
+The name of the database table to which the log entries will be written is
+specified using the ``$name`` construction parameter (see `Configuring a
+Handler`_).
+
+.. |sql-default| replace:: ``INSERT INTO $table (id, logtime, ident, priority, message) VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)``
+
+.. _DB: http://pear.php.net/package/DB
+.. _PEAR's DB abstraction layer: DB_
+.. _Data Source Name: http://pear.php.net/manual/en/package.database.db.intro-dsn.php
+
+Examples
+~~~~~~~~
+Using a `Data Source Name`_ to create a new database connection::
+
+    $conf = array('dsn' => 'pgsql://jon@localhost+unix/logs');
+    $logger = &Log::singleton('sql', 'log_table', 'ident', $conf);
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+Using an existing `DB`_ object::
+
+    require_once 'DB.php';
+    $db = &DB::connect('pgsql://jon@localhost+unix/logs');
+
+    $conf['db'] = $db;
+    $logger = &Log::singleton('sql', 'log_table', 'ident', $conf);
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The Sqlite Handler
+------------------
+:Author:        Bertrand Mansion
+
+The Sqlite handler sends log events to an Sqlite database using the `native
+PHP sqlite functions`_.
+
+It is faster than `the SQL (DB) handler`_ because requests are made directly
+to the database without using an abstraction layer.  It is also interesting to
+note that Sqlite database files can be moved, copied, and deleted on your
+system just like any other files, which makes log management easier.  Last but
+not least, using a database to log your events allows you to use SQL queries
+to create reports and statistics.
+
+When using a database and logging a lot of events, it is recommended to split
+the database into smaller databases.  This is allowed by Sqlite, and you can
+later use the Sqlite `ATTACH`_ statement to query your log database files
+globally.
+
+If the database does not exist when the log is opened, sqlite will try to
+create it automatically. If the log table does not exist, it will also be
+automatically created.  The table creation uses the following SQL request::
+
+    CREATE TABLE log_table (
+        id          INTEGER PRIMARY KEY NOT NULL,
+        logtime     NOT NULL,
+        ident       CHAR(16) NOT NULL,
+        priority    INT NOT NULL,
+        message
+    );
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``filename``      | String    | '' `(empty)`  | Path to an Sqlite         |
+|                   |           |               | database. |required|      |
++-------------------+-----------+---------------+---------------------------+
+| ``mode``          | Integer   | 0666          | Octal mode used to open   |
+|                   |           |               | the database.             |
++-------------------+-----------+---------------+---------------------------+
+| ``persistent``    | Boolean   | false         | Use a persistent          |
+|                   |           |               | connection.               |
++-------------------+-----------+---------------+---------------------------+
+
+An already opened database connection can also be passed as parameter instead
+of the above configuration.  In this case, closing the database connection is
+up to the user.
+
+.. _native PHP sqlite functions: http://www.php.net/sqlite
+.. _ATTACH: http://www.sqlite.org/lang.html#attach
+
+Examples
+~~~~~~~~
+Using a configuration to create a new database connection::
+
+    $conf = array('filename' => 'log.db', 'mode' => 0666, 'persistent' => true);
+    $logger =& Log::factory('sqlite', 'log_table', 'ident', $conf);
+    $logger->log('logging an event', PEAR_LOG_WARNING);
+
+Using an existing connection::
+
+    $db = sqlite_open('log.db', 0666, $error);
+    $logger =& Log::factory('sqlite', 'log_table', 'ident', $db);
+    $logger->log('logging an event', PEAR_LOG_WARNING);
+    sqlite_close($db);
+
+
+The Syslog Handler
+------------------
+The Syslog handler sends log events to the system logging service (syslog on
+Unix-like environments or the Event Log on Windows systems).  The events are
+sent using PHP's `syslog()`_ function.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``inherit``       | Boolean   | false         | Inherit the current syslog|
+|                   |           |               | connection for this       |
+|                   |           |               | process, or start a new   |
+|                   |           |               | one via `openlog()`_?     |
++-------------------+-----------+---------------+---------------------------+
+
+Facilities
+~~~~~~~~~~
++-------------------+-------------------------------------------------------+
+| Constant          | Category Description                                  |
++===================+=======================================================+
+| ``LOG_AUTH``      | Security / authorization messages; ``LOG_AUTHPRIV`` is|
+|                   | preferred on systems where it is defined.             |
++-------------------+-------------------------------------------------------+
+| ``LOG_AUTHPRIV``  | Private security / authorization messages             |
++-------------------+-------------------------------------------------------+
+| ``LOG_CRON``      | Clock daemon (``cron`` and ``at``)                    |
++-------------------+-------------------------------------------------------+
+| ``LOG_DAEMON``    | System daemon processes                               |
++-------------------+-------------------------------------------------------+
+| ``LOG_KERN``      | Kernel messages                                       |
++-------------------+-------------------------------------------------------+
+| ``LOG_LOCAL0`` .. | Reserved for local use; **not** available under       |
+| ``LOG_LOCAL7``    | Windows.                                              |
++-------------------+-------------------------------------------------------+
+| ``LOG_LPR``       | Printer subsystem                                     |
++-------------------+-------------------------------------------------------+
+| ``LOG_MAIL``      | Mail subsystem                                        |
++-------------------+-------------------------------------------------------+
+| ``LOG_NEWS``      | USENET news subsystem                                 |
++-------------------+-------------------------------------------------------+
+| ``LOG_SYSLOG``    | Internal syslog messages                              |
++-------------------+-------------------------------------------------------+
+| ``LOG_USER``      | Generic user-level messages                           |
++-------------------+-------------------------------------------------------+
+| ``LOG_UUCP``      | UUCP subsystem                                        |
++-------------------+-------------------------------------------------------+
+
+.. _syslog(): http://www.php.net/syslog
+.. _openlog(): http://www.php.net/openlog
+
+Example
+~~~~~~~
+::
+
+    $logger = &Log::singleton('syslog', LOG_LOCAL0, 'ident');
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+The Window Handler
+------------------
+The Window handler sends log events to a separate browser window.  The
+original idea for this handler was inspired by Craig Davis' Zend.com article
+entitled `"JavaScript Power PHP Debugging"`_.
+
+Configuration
+~~~~~~~~~~~~~
++-------------------+-----------+---------------+---------------------------+
+| Parameter         | Type      | Default       | Description               |
++===================+===========+===============+===========================+
+| ``title``         | String    | ``Log Output  | The title of the output   |
+|                   |           | Window``      | window.                   |
++-------------------+-----------+---------------+---------------------------+
+| ``styles``        | Array     | `ROY G BIV`_  | Mapping of log priorities |
+|                   |           | (high to low) | to CSS styles.            |
++-------------------+-----------+---------------+---------------------------+
+
+**Note:** The Window handler may not work reliably when PHP's `output
+buffering`_ system is enabled.
+
+.. _"JavaScript Power PHP Debugging": http://www.zend.com/zend/tut/tutorial-DebugLib.php
+.. _ROY G BIV: http://www.cis.rit.edu/
+.. _output buffering: http://www.php.net/outcontrol
+
+Example
+~~~~~~~
+::
+
+    $conf = array('title' => 'Sample Log Output');
+    $logger = &Log::singleton('win', 'LogWindow', 'ident', $conf);
+    for ($i = 0; $i < 10; $i++) {
+        $logger->log("Log entry $i");
+    }
+
+
+Composite Handlers
+==================
+It is often useful to log events to multiple handlers.  The Log package
+provides a compositing system that marks this task trivial.
+
+Start by creating the individual log handlers::
+
+    $console = &Log::singleton('console', '', 'TEST');
+    $file = &Log::singleton('file', 'out.log', 'TEST');
+
+Then, construct a composite handler and add the individual handlers as
+children of the composite::
+
+    $composite = &Log::singleton('composite');
+    $composite->addChild($console);
+    $composite->addChild($file);
+
+The composite handler implements the standard ``Log`` interface so you can use
+it just like any of the other handlers::
+
+    $composite->log('This event will be logged to both handlers.');
+
+Children can be removed from the composite when they're not longer needed::
+
+    $composite->removeChild($file);
+
+
+Log Observers
+=============
+Log observers provide an implementation of the `observer pattern`_.  In the
+content of the Log package, they provide a mechanism by which you can examine
+(i.e. observe) each event as it is logged.  This allows the implementation of
+special behavior based on the contents of a log event.  For example, the
+observer code could send an alert email if a log event contained the string
+``PANIC``.
+
+Creating a log observer involves implementing a subclass of the
+``Log_observer`` class.  The subclass must override the base class's
+``notify()`` method.  This method is passed a hash containing the event's
+priority and event.  The subclass's implementation is free to act upon this
+information in any way it likes.
+
+Log observers are attached to ``Log`` instances via the ``attach()`` method::
+
+    $observer = &Log_observer::factory('yourType');
+    $logger->attach($observer);
+
+Observers can be detached using the ``detach()`` method::
+
+    $logger->detach($observer);
+
+At this time, no concrete ``Log_observer`` implementations are distributed
+with the Log package.
+
+.. _observer pattern: http://wikipedia.org/wiki/Observer_pattern
+
+
+Logging From Standard Error Handlers
+====================================
+
+Logging PHP Errors
+------------------
+PHP's default error handler can be overridden using the `set_error_handler()`_
+function.  The custom error handling function can use a global Log instance to
+log the PHP errors.
+
+**Note:** Fatal PHP errors cannot be handled by a custom error handler at this
+time.
+
+::
+
+    function errorHandler($code, $message, $file, $line)
+    {
+        global $logger;
+
+        /* Map the PHP error to a Log priority. */
+        switch ($code) {
+        case E_WARNING:
+        case E_USER_WARNING:
+            $priority = PEAR_LOG_WARNING;
+            break;
+        case E_NOTICE:
+        case E_USER_NOTICE:
+            $priority = PEAR_LOG_NOTICE;
+            break;
+        case E_ERROR:
+        case E_USER_ERROR:
+            $priority = PEAR_LOG_ERR;
+            break;
+        default:
+            $priority = PEAR_LOG_INFO;
+        }
+
+        $logger->log($message . ' in ' . $file . ' at line ' . $line,
+                     $priority);
+    }
+
+    set_error_handler('errorHandler');
+    trigger_error('This is an information log message.', E_USER_NOTICE);
+
+.. _set_error_handler(): http://www.php.net/set_error_handler
+
+Logging PHP Assertions
+----------------------
+PHP allows user-defined `assert()`_ callback handlers.  The assertion callback
+is configured using the `assert_options()`_ function.
+
+::
+
+    function assertCallback($file, $line, $message)
+    {
+        global $logger;
+
+        $logger->log($message . ' in ' . $file . ' at line ' . $line,
+                     PEAR_LOG_ALERT);
+    }
+
+    assert_options(ASSERT_CALLBACK, 'assertCallback');
+    assert(false);
+
+.. _assert(): http://www.php.net/assert
+.. _assert_options(): http://www.php.net/assert_options
+
+Logging PHP Exceptions
+----------------------
+PHP 5 and later support the concept of `exceptions`_.  A custom exception
+handler can be assigned using the `set_exception_handler()`_ function.
+
+::
+
+    function exceptionHandler($exception)
+    {
+        global $logger;
+
+        $logger->log($exception->getMessage(), PEAR_LOG_ALERT);
+    }
+
+    set_exception_handler('exceptionHandler');
+    throw new Exception('Uncaught Exception');
+
+.. _exceptions: http://www.php.net/exceptions
+.. _set_exception_handler(): http://www.php.net/set_exception_handler
+
+Logging PEAR Errors
+-------------------
+The Log package can be used with `PEAR::setErrorHandling()`_'s
+``PEAR_ERROR_CALLBACK`` mechanism by writing an error handling function that
+uses a global Log instance.  Here's an example::
+
+    function errorHandler($error)
+    {
+        global $logger;
+
+        $message = $error->getMessage();
+
+        if (!empty($error->backtrace[1]['file'])) {
+            $message .= ' (' . $error->backtrace[1]['file'];
+            if (!empty($error->backtrace[1]['line'])) {
+                $message .= ' at line ' . $error->backtrace[1]['line'];
+            }
+            $message .= ')';
+        }
+
+        $logger->log($message, $error->code);
+    }
+
+    PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'errorHandler');
+    PEAR::raiseError('This is an information log message.', PEAR_LOG_INFO);
+
+.. _PEAR::setErrorHandling(): http://pear.php.net/manual/en/core.pear.pear.seterrorhandling.php
+
+
+Custom Handlers
+===============
+There are times when the standard handlers aren't a perfect match for your
+needs.  In those situations, the solution might be to write a custom handler.
+
+Using a Custom Handler
+----------------------
+Using a custom Log handler is very simple.  Once written (see `Writing New
+Handlers`_ and `Extending Existing Handlers`_ below), you have the choice of
+placing the file in your PEAR installation's main ``Log/`` directory (usually
+something like ``/usr/local/lib/php/Log`` or ``C:\php\pear\Log``), where it
+can be found and use by any PHP application on the system, or placing the file
+somewhere in your application's local hierarchy and including it before the
+the custom Log object is constructed.
+
+Method 1: Handler in the Standard Location
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+After copying the handler file to your PEAR installation's ``Log/`` directory,
+simply treat the handler as if it were part of the standard distributed.  If
+your handler is named ``custom`` (and therefore implemented by a class named
+``Log_custom``)::
+
+    require_once 'Log.php';
+
+    $logger = &Log::factory('custom', '', 'CUSTOM');
+
+
+Method 2: Handler in a Custom Location
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you prefer storing your handler in your application's local hierarchy,
+you'll need to include that file before you can create a Log instance based on
+it.
+
+::
+
+    require_once 'Log.php';
+    require_once 'LocalHandlers/custom.php';
+
+    $logger = &Log::factory('custom', '', 'CUSTOM');
+
+
+Writing New Handlers
+--------------------
+Writing a new Log handler is as simple as authoring a new class that extends
+the ``Log`` class and that implements a relatively small set of standard
+methods.
+
+Every handler's class name must start with ``Log_`` in order for it to be
+recognized by the Log package.
+
+::
+
+    class Log_custom extends Log
+
+The handler's constructor will be called with four parameters.  These values
+are discussed in detail in the `Configuring a Handler`_ section.
+
+::
+
+    Log_custom($name, $ident = '', $conf = array(), $level = PEAR_LOG_DEBUG)
+
+The constructor is responsible for configuring the handler based on these
+values.  Handler-specific parameters are passed as part of the ``$conf``
+array.  At a minimum, the handler's constructor must set the following values
+defined by the ``Log`` base class::
+
+        $this->_id = md5(microtime());
+        $this->_name = $name;
+        $this->_ident = $ident;
+        $this->_mask = Log::UPTO($level);
+
+The `Handler Methods`_ section below details the various standard methods that
+can be implemented by a log handler.  The `Utility Methods`_ section describes
+some useful utility methods provided by the ``Log`` base class which may be
+useful when implementing a log handler.
+
+
+Extending Existing Handlers
+---------------------------
+Extending existing handlers is very similar to `writing new handlers`_ with
+the exception that, instead of inheriting from the ``Log`` base class
+directly, the handler extends an existing handler's class.  This is a useful
+way of adding some custom behavior to an existing handler without writing an
+entirely new class (in the spirit of object-oriented programming).
+
+For example, `the mail handler`_ could be extended to support sending messages
+with MIME-encoded attachments simply by authoring a new ``Log_mail_mime``
+class with a compliant constructor and a custom ``log()`` method.  The rest of
+the standard methods would fall back on the ``Log_mail`` base class's
+implementations.
+
+Obviously, the specific details involved in extending an existing handler
+require a good working understanding of that handler's implementation.
+
+
+Handler Methods
+---------------
+
+bool open()
+~~~~~~~~~~~
+The ``open()`` method is called to open the log resource for output.  Handlers
+can call ``open()`` immediately upon construction or lazily at runtime
+(perhaps when the first log event is received).
+
+The ``Log`` base class provides a protected ``$_opened`` member variable which
+should be set to ``true`` when the log handler is opened and ``false`` when it
+is closed.  Handler methods can inspect this value to determine whether or not
+the handler is currently open and ready for output.
+
+If the ``open()`` method fails to ready the handler for output, it should
+return ``false`` and set ``$this->_opened`` to ``false``.
+
+bool close()
+~~~~~~~~~~~~
+The ``close()`` method is called to close the log resource.  This method is
+the analog of the ``open()`` method.  It should be safe to call ``close()``
+even when the handler is not open for output.
+
+If the ``close()`` method fails to close the handler, it should return
+``false``.  Otherwise, it should return ``true``.  The ``$this->_opened``
+flag should also be updated appropriately.
+
+bool flush()
+~~~~~~~~~~~~
+The ``flush()`` method flushes any buffered log events, as described in
+`Flushing Log Events`_.  The implementation of this method will be largely
+handler-specific.  If the handler does not support buffered output,
+implementing this method is not necessary; the ``Log`` class's ``flush()``
+method will be called instead.
+
+bool log($message, $priority = null)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The ``log()`` method is the core of every log handler.  It is called whenever
+the user wishes to log an event.  The implementation of this method is very
+handler-specific.  It should return ``true`` or ``false``, depending on
+whether or not the message was successfully logged by the handler.
+
+The ``log()`` implementation should be sure to call `_announce()`__ whenever
+an event is successfully logged.
+
+.. __: `void _announce($event)`_
+
+Utility Methods
+---------------
+These utility methods are provided by the ``Log`` base class and provide
+common, useful functionality to handler implementations.
+
+string _extractMessage($message)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This method returns the string representation of the provided message data.
+
+If ``$message`` is an object, ``_extractMessage()`` will attempt to extract
+the message text using a known method (such as a `PEAR_Error`_ object's
+`getMessage()`_ method).  If a known method, cannot be found, the serialized
+representation of the object will be returned.
+
+If the message data is already a string, it will be returned unchanged.
+
+.. _PEAR_Error: http://pear.php.net/manual/en/core.pear.pear-error.php
+.. _getMessage(): http://pear.php.net/manual/en/core.pear.pear-error.getmessage.php
+
+string _format($format, $timestamp, $priority, $message)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This method produces a formatted log line based on a format string and a set
+of `tokens`_ representing the current log record and state.  
+
+.. _tokens: `Log Line Format`_
+
+bool _isMasked($priority)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+This method checks if the given priority is included in the handler's current
+level mask.  This is useful for determining whether or not a log event should
+be written to the handler's log.
+
+void _announce($event)
+~~~~~~~~~~~~~~~~~~~~~~
+This method informs any registered `log observers`_ that a new event has been
+logged.  ``$event`` is an array containing two named elements::
+
+    array('priority' => $priority, 'message' => $message)
+
+``_announce()`` should be called from a handler's `log()`_ method whenever an
+event is successfully logged.  Otherwise, registered observers will never
+become aware of the event.
+
+.. _log(): `bool log($message, $priority = null)`_
+
+.. |required| replace:: **[required]**
+
+.. vim: tabstop=4 shiftwidth=4 softtabstop=4 expandtab textwidth=78 ft=rst:
Index: /sandbox/workflow/branches/993/inc/log/misc/log.sql
===================================================================
--- /sandbox/workflow/branches/993/inc/log/misc/log.sql	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/misc/log.sql	(revision 795)
@@ -0,0 +1,10 @@
+-- $Id: log.sql,v 1.1 2006/06/26 15:25:35 jon Exp $
+
+CREATE TABLE log_table (
+    id          INT NOT NULL,
+    logtime     TIMESTAMP NOT NULL,
+    ident       CHAR(16) NOT NULL,
+    priority    INT NOT NULL,
+    message     VARCHAR(200),
+    PRIMARY KEY (id)
+);
Index: /sandbox/workflow/branches/993/inc/log/examples/observer_mail.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/observer_mail.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/observer_mail.php	(revision 795)
@@ -0,0 +1,30 @@
+<?php
+
+require_once 'Log/observer.php';
+
+class Log_observer_mail extends Log_observer
+{
+    var $_to = '';
+    var $_subject = '';
+    var $_pattern = '';
+
+    function Log_observer_mail($priority, $conf)
+    {
+        /* Call the base class constructor. */
+        $this->Log_observer($priority);
+
+        /* Configure the observer. */
+        $this->_to = $conf['to'];
+        $this->_subject = $conf['subject'];
+        $this->_pattern = $conf['pattern'];
+    }
+
+    function notify($event)
+    {
+        if (preg_match($this->_pattern, $event['message']) != 0) {
+            mail($this->_to, $this->_subject, $event['message']);
+        }
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/log/examples/error_log.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/error_log.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/error_log.php	(revision 795)
@@ -0,0 +1,8 @@
+<?php
+
+require_once 'Log.php';
+
+$logger = &Log::singleton('error_log', PEAR_LOG_TYPE_SYSTEM, 'ident');
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/null.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/null.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/null.php	(revision 795)
@@ -0,0 +1,8 @@
+<?php
+
+require_once 'Log.php';
+
+$logger = &Log::singleton('null');
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/pear_error_handler.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/pear_error_handler.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/pear_error_handler.php	(revision 795)
@@ -0,0 +1,25 @@
+<?php
+
+require_once 'Log.php';
+
+function errorHandler($error)
+{
+    global $logger;
+
+    $message = $error->getMessage();
+
+    if (!empty($error->backtrace[1]['file'])) {
+        $message .= ' (' . $error->backtrace[1]['file'];
+        if (!empty($error->backtrace[1]['line'])) {
+            $message .= ' at line ' . $error->backtrace[1]['line'];
+        }
+        $message .= ')';
+    }
+
+    $logger->log($message, $error->code);
+}
+
+$logger = &Log::singleton('console', '', 'ident');
+
+PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'errorHandler');
+PEAR::raiseError('This is an information log message.', PEAR_LOG_INFO);
Index: /sandbox/workflow/branches/993/inc/log/examples/php_error_handler.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/php_error_handler.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/php_error_handler.php	(revision 795)
@@ -0,0 +1,34 @@
+<?php
+
+require_once 'Log.php';
+
+function errorHandler($code, $message, $file, $line)
+{
+    global $logger;
+
+    /* Map the PHP error to a Log priority. */
+    switch ($code) {
+    case E_WARNING:
+    case E_USER_WARNING:
+        $priority = PEAR_LOG_WARNING;
+        break;
+    case E_NOTICE:
+    case E_USER_NOTICE:
+        $priority = PEAR_LOG_NOTICE;
+        break;
+    case E_ERROR:
+    case E_USER_ERROR:
+        $priority = PEAR_LOG_ERR;
+        break;
+    default:
+        $priotity = PEAR_LOG_INFO;
+    }
+
+    $logger->log($message . ' in ' . $file . ' at line ' . $line,
+                 $priority);
+}
+
+$logger = &Log::singleton('console', '', 'ident');
+
+set_error_handler('errorHandler');
+trigger_error('This is an information log message.', E_USER_NOTICE);
Index: /sandbox/workflow/branches/993/inc/log/examples/win.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/win.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/win.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+
+require_once 'Log.php';
+
+$conf = array('title' => 'Sample Log Output');
+$logger = &Log::singleton('win', 'LogWindow', 'ident', $conf);
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/file.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+
+require_once '../Log.php';
+
+$conf = array('mode' => 0600, 'timeFormat' => '%X %x');
+$logger = &Log::singleton('file', '/tmp/out.log', 'ident', $conf);
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/sql.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/sql.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/sql.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+
+require_once 'Log.php';
+
+$conf = array('dsn' => 'pgsql://jon@localhost+unix/logs');
+$logger = &Log::singleton('sql', 'log_table', 'ident', $conf);
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/syslog.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/syslog.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/syslog.php	(revision 795)
@@ -0,0 +1,8 @@
+<?php
+
+require_once 'Log.php';
+
+$logger = &Log::singleton('syslog', LOG_LOCAL0, 'ident');
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/sqlite.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/sqlite.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/sqlite.php	(revision 795)
@@ -0,0 +1,14 @@
+<?php
+
+require_once 'Log.php';
+
+/* Creating a new database connection. */
+$conf = array('filename' => 'log.db', 'mode' => 0666, 'persistent' => true);
+$logger =& Log::factory('sqlite', 'log_table', 'ident', $conf);
+$logger->log('logging an event', PEAR_LOG_WARNING);
+
+/* Using an existing database connection. */
+$db = sqlite_open('log.db', 0666, $error);
+$logger =& Log::factory('sqlite', 'log_table', 'ident', $db);
+$logger->log('logging an event', PEAR_LOG_WARNING);
+sqlite_close($db);
Index: /sandbox/workflow/branches/993/inc/log/examples/composite.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/composite.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/composite.php	(revision 795)
@@ -0,0 +1,12 @@
+<?php
+
+require_once 'Log.php';
+
+$console = &Log::singleton('console', '', 'TEST');
+$file = &Log::singleton('file', 'out.log', 'TEST');
+
+$composite = &Log::singleton('composite');
+$composite->addChild($console);
+$composite->addChild($file);
+
+$composite->log('This event will be logged to both handlers.');
Index: /sandbox/workflow/branches/993/inc/log/examples/console.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/console.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/console.php	(revision 795)
@@ -0,0 +1,8 @@
+<?php
+
+require_once 'Log.php';
+
+$logger = &Log::singleton('console', '', 'ident');
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/mail.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/mail.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/mail.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+
+require_once 'Log.php';
+
+$conf = array('subject' => 'Important Log Events');
+$logger = &Log::singleton('mail', 'webmaster@example.com', 'ident', $conf);
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/firebug.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/firebug.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/firebug.php	(revision 795)
@@ -0,0 +1,12 @@
+<?php
+
+require_once '../Log.php';
+
+$logger = &Log::singleton('firebug', '',
+                          'PHP',
+                          array('buffering' => true),
+                          PEAR_LOG_DEBUG);
+
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/log/examples/display.php
===================================================================
--- /sandbox/workflow/branches/993/inc/log/examples/display.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/log/examples/display.php	(revision 795)
@@ -0,0 +1,10 @@
+<?php
+
+require_once '../Log.php';
+
+$conf = array('error_prepend' => '<font color="#ff0000"><tt>',
+              'error_append'  => '</tt></font>');
+$logger = &Log::singleton('display', '', '', $conf, PEAR_LOG_DEBUG);
+for ($i = 0; $i < 10; $i++) {
+    $logger->log("Log entry $i");
+}
Index: /sandbox/workflow/branches/993/inc/class.workflow_activitymanager.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_activitymanager.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_activitymanager.inc.php	(revision 2372)
@@ -0,0 +1,22 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'ActivityManager.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_activitymanager extends ActivityManager
+	{  /**
+		 * Construtor da classe workflow_activitymanager
+		 * @access public
+		 * @return object
+		 */
+		function workflow_activitymanager()
+		{
+			parent::ActivityManager(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ajax.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ajax.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.ajax.inc.php	(revision 795)
@@ -0,0 +1,41 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ */
+class ajax 
+{
+	/**
+     * Constructor
+     * 
+     * @return object
+     * @access public
+     */
+	function ajax() {
+	}
+	
+    /**
+     * Get Last Ajax response
+     * @return array session last ajax response
+     * @access public
+     */
+	function getLastAjaxResponse()
+    {
+		$result = $_SESSION['response'];
+		$_SESSION['response'] = null;
+		
+		return $result;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowObjects.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowObjects.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowObjects.inc.php	(revision 2372)
@@ -0,0 +1,234 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Provê objetos de multipropósito do Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class WorkflowObjects
+{
+	/**
+	 * @var array $cache Cache de objetos
+	 * @access private
+	 */
+	private $cache;
+
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	function WorkflowObjects()
+	{
+		$this->cache = array();
+	}
+
+	/**
+	 * Monta o ambiente requerido pelos métodos (somente se for necessário)
+	 * @param bool $requireGalaxia Indica que os métodos da engine Galaxia são necessários
+	 * @return void
+	 * @access public
+	 */
+	private function assureEnvironment($requireGalaxia = true)
+	{
+		if (!defined('PHPGW_API_INC'))
+			define('PHPGW_API_INC', dirname(__FILE__) . '/../../phpgwapi/inc');
+
+		if ($requireGalaxia)
+		{
+			if (!function_exists('galaxia_get_config_values'))
+			{
+				require_once 'engine/config.ajax.inc.php' ;
+				require_once 'engine/class.ajax_config.inc.php' ;
+			}
+		}
+	}
+
+	/**
+	 * Retorna uma conexão com o banco de dados do Galaxia (normalmente associado ao banco de dados do Expresso (eGroupWare))
+	 * @return object O objeto de acesso a banco de dados, já conectado
+	 * @access public
+	 */
+	function &getDBGalaxia()
+	{
+		if (!isset($this->cache['DBGalaxia']))
+		{
+			/* make sure the environment is set */
+			$this->assureEnvironment();
+
+			/* load the configuration required to establish a connection to the Galaxia database */
+			$dbConfigValues = galaxia_get_config_values(array(
+				'workflow_database_name' => '',
+				'workflow_database_host' => '',
+				'workflow_database_port' => '',
+				'workflow_database_user' => '',
+				'workflow_database_password' => '',
+				'workflow_database_type' => ''
+			));
+
+			/* check if all configuration is OK */
+			$dedicatedDB = true;
+			foreach ($dbConfigValues as $configName => $configValue)
+				if (empty($configValue) && ($configName != 'workflow_database_password'))
+					$dedicatedDB = false;
+
+			if ($dedicatedDB)
+			{
+				/* connect to the database */
+				$this->cache['DBGalaxia'] = Factory::newInstance('WorkflowWatcher', Factory::newInstance('db'));
+				$this->cache['DBGalaxia']->disconnect(); /* for some reason it won't connect to the desired database unless we disconnect it first */
+				$this->cache['DBGalaxia']->Halt_On_Error = 'no';
+				$this->cache['DBGalaxia']->connect(
+					$dbConfigValues['workflow_database_name'],
+					$dbConfigValues['workflow_database_host'],
+					$dbConfigValues['workflow_database_port'],
+					$dbConfigValues['workflow_database_user'],
+					$dbConfigValues['workflow_database_password'],
+					$dbConfigValues['workflow_database_type']
+				);
+				Factory::getInstance('WorkflowSecurity')->removeSensitiveInformationFromDatabaseObject($this->cache['DBGalaxia']);
+				$this->cache['DBGalaxia']->Link_ID = Factory::newInstance('WorkflowWatcher', $this->cache['DBGalaxia']->Link_ID);
+			}
+			else
+				$this->cache['DBGalaxia'] = &$this->getDBExpresso();
+		}
+
+		return $this->cache['DBGalaxia'];
+	}
+
+	/**
+	 * Retorna uma conexão com o banco de dados do Expresso (eGroupWare)
+	 * @return object O objeto de acesso a banco de dados, já conectado
+	 * @access public
+	 */
+	function &getDBExpresso()
+	{
+		if (!isset($this->cache['DBExpresso']))
+		{
+			/* make sure the environment is set */
+			$this->assureEnvironment(false);
+
+			/* check where the connection parameters are */
+			$connectionInfo = (isset($GLOBALS['phpgw_info']['server']['db_name'])) ?
+				$GLOBALS['phpgw_info']['server'] :
+				$_SESSION['phpgw_info']['workflow']['server'];
+
+			/* the information was not found. Try to load the environment */
+			if (!isset($connectionInfo['db_name']))
+			{
+				Factory::getInstance('WorkflowMacro')->prepareEnvironment();
+				if (isset($GLOBALS['phpgw_info']['server']))
+					$connectionInfo = $GLOBALS['phpgw_info']['server'];
+				else
+					return false;
+			}
+
+			/* connect to the database */
+			$this->cache['DBExpresso'] = Factory::newInstance('WorkflowWatcher', Factory::newInstance('db'));
+			$this->cache['DBExpresso']->disconnect(); /* for some reason it won't connect to the desired database unless we disconnect it first */
+			$this->cache['DBExpresso']->Halt_On_Error = 'no';
+			$this->cache['DBExpresso']->connect(
+				$connectionInfo['db_name'],
+				$connectionInfo['db_host'],
+				$connectionInfo['db_port'],
+				$connectionInfo['db_user'],
+				$connectionInfo['db_pass'],
+				$connectionInfo['db_type']
+			);
+			Factory::getInstance('WorkflowSecurity')->removeSensitiveInformationFromDatabaseObject($this->cache['DBExpresso']);
+			$this->cache['DBExpresso']->Link_ID = Factory::newInstance('WorkflowWatcher', $this->cache['DBExpresso']->Link_ID);
+		}
+
+		return $this->cache['DBExpresso'];
+	}
+
+	/**
+	 * Retorna uma conexão com o banco de dados do Workflow
+	 * @return object O objeto de acesso a banco de dados, já conectado
+	 * @access public
+	 */
+	function &getDBWorkflow()
+	{
+		if (!isset($this->cache['DBWorkflow']))
+		{
+			/* make sure the environment is set */
+			$this->assureEnvironment();
+
+			/* load the configuration required to establish a connection to the Galaxia database */
+			$dbConfigValues = galaxia_get_config_values(array(
+				'database_name' => '',
+				'database_host' => '',
+				'database_port' => '',
+				'database_admin_user' => '',
+				'database_admin_password' => '',
+				'database_type' => ''
+			));
+
+			/* connect to the database */
+			$this->cache['DBWorkflow'] = Factory::newInstance('WorkflowWatcher', Factory::newInstance('db'));
+			$this->cache['DBWorkflow']->disconnect(); /* for some reason it won't connect to the desired database unless we disconnect it first */
+			$this->cache['DBWorkflow']->Halt_On_Error = 'no';
+			$this->cache['DBWorkflow']->connect(
+				$dbConfigValues['database_name'],
+				$dbConfigValues['database_host'],
+				$dbConfigValues['database_port'],
+				$dbConfigValues['database_admin_user'],
+				$dbConfigValues['database_admin_password'],
+				$dbConfigValues['database_type']
+			);
+			Factory::getInstance('WorkflowSecurity')->removeSensitiveInformationFromDatabaseObject($this->cache['DBWorkflow']);
+			$this->cache['DBWorkflow']->Link_ID = Factory::newInstance('WorkflowWatcher', $this->cache['DBWorkflow']->Link_ID);
+		}
+
+		return $this->cache['DBWorkflow'];
+	}
+
+	/**
+	 * Retorna um recurso de LDAP
+	 * @return resource O recurso LDAP
+	 * @access public
+	 */
+	function &getLDAP()
+	{
+		if (!isset($this->cache['ldap']))
+		{
+			/* make sure the environment is set */
+			$this->assureEnvironment();
+
+			/* check where the connection parameters are */
+			$connectionInfo = (isset($GLOBALS['phpgw_info']['server']['ldap_host'])) ?
+				$GLOBALS['phpgw_info']['server'] :
+				$_SESSION['phpgw_info']['workflow']['server'];
+
+			/* load required information */
+			$ldapConfigValues = galaxia_get_config_values(array('ldap_host' => '', 'ldap_user' => '', 'ldap_password'=> '', 'ldap_follow_referrals' => ''));
+			if (empty($ldapConfigValues['ldap_host']))
+				$ldapConfigValues['ldap_host'] = $connectionInfo['ldap_host'];
+
+			/* connect to the LDAP server */
+			$this->cache['ldap'] = ldap_connect($ldapConfigValues['ldap_host']);
+
+			/* configure the connection */
+			ldap_set_option($this->cache['ldap'], LDAP_OPT_PROTOCOL_VERSION, 3);
+			ldap_set_option($this->cache['ldap'], LDAP_OPT_REFERRALS, ($ldapConfigValues['ldap_follow_referrals'] == 1) ? 1 : 0);
+
+			/* if  username and password are available, bind the connection */
+			if ((!empty($ldapConfigValues['ldap_user'])) && (!empty($ldapConfigValues['ldap_password'])))
+				ldap_bind($this->cache['ldap'], $ldapConfigValues['ldap_user'], $ldapConfigValues['ldap_password']);
+		}
+
+		return $this->cache['ldap'];
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_ajaxinterface.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_ajaxinterface.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_ajaxinterface.inc.php	(revision 2372)
@@ -0,0 +1,94 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Caracter separador
+ * @name SEP
+ */
+if (!defined('PHPGW_SERVER_ROOT'))
+{
+	define('SEP', '/');
+	/**
+	 * Raiz do servidor
+	 * @name PHPGW_SERVER_ROOT
+	 */
+	define('PHPGW_SERVER_ROOT' , $_SESSION['phpgw_info']['workflow']['server_root']);
+	/**
+	 * Caminho para o diretorio INCLUDE
+	 * @name PHPGW_INCLUDE_ROOT
+	 */
+
+	define('PHPGW_INCLUDE_ROOT', $_SESSION['phpgw_info']['workflow']['phpgw_include_root']);
+	/**
+	 * Caminho para a PHPGW_API
+	 * @name PHPGW_API_INC
+	 */
+	define('PHPGW_API_INC'     , $_SESSION['phpgw_info']['workflow']['phpgw_api_inc']);
+}
+
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'common.inc.php');
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'engine' . SEP . 'class.ajax_config.inc.php');
+require_once(PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'inc' . SEP . 'engine' . SEP . 'config.ajax.inc.php');
+
+/**
+ * Implementa o suporte básico para execução de métodos requisitados via AJAX
+ * Cria objetos globais para bancos de dados, ldap, config do eGroupware e
+ * acl do workflow
+ *
+ * @package Workflow
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ * @author Sidnei Augusto C Drovetto - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @access public
+*/
+class bo_ajaxinterface
+{
+	/**
+	* Cria objetos globais para o ldap, banco do expresso, banco do workflow,
+	* e acl do workflow
+	*
+	* @return void
+	* @access public
+	*/
+	function bo_ajaxinterface()
+	{
+		if (isset($_SESSION['phpgw_info']['workflow']['account_id']))
+		{
+			$GLOBALS['ajax']->ldap = &Factory::getInstance('ajax_ldap');
+			$GLOBALS['ajax']->db =& Factory::getInstance('WorkflowObjects')->getDBExpresso();
+			$GLOBALS['ajax']->db->Halt_On_Error = 'no';
+
+			$GLOBALS['ajax']->db_workflow =& Factory::getInstance('WorkflowObjects')->getDBWorkflow();
+			$GLOBALS['ajax']->db_workflow->Halt_On_Error = 'no';
+
+			$GLOBALS['phpgw']->ADOdb = &$GLOBALS['ajax']->db->Link_ID;
+			$GLOBALS['ajax']->acl = &Factory::getInstance('so_adminaccess', Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+		else
+		{
+			die("Impossível executar a operação solicitada.");
+		}
+	}
+
+	/**
+	* Fecha a conexão com os objetos globais
+	*
+	* @return void
+	* @access public
+	*/
+	function disconnect_all()
+	{
+		$GLOBALS['ajax']->db->Link_ID->Close();
+		$GLOBALS['ajax']->db_workflow->Link_ID->Close();
+		$GLOBALS['ajax']->ldap->close();
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_external_applications.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_external_applications.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_external_applications.inc.php	(revision 2372)
@@ -0,0 +1,105 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php';
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class ui_external_applications extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'draw' => true,
+		'upload_image' => true
+	);
+
+	/**
+	 * @var array $workflow_acl
+	 * @access public
+	 */
+	var $workflow_acl;
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_external_applications()
+	{
+	}
+
+	/**
+	 * Draw external applications interface
+	 * @return void
+	 * @access public
+	 */
+	function draw()
+	{
+		if (!Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']))
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_orgchart');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'];
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => false, 'nonavbar' => false, 'currentapp' => 'workflow');
+		$smarty = Factory::getInstance('workflow_smarty');
+
+		$this->set_wf_session();
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'scriptaculous', 'load=effects');
+		$javaScripts .= $this->get_js_link('workflow','external_applications', 'main');
+
+		$css = $this->get_common_css();
+		$css .= $this->get_css_link('external_applications');
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->display('external_applications.tpl');
+	}
+
+	/**
+	 * Upload image
+	 * @access public
+	 * @return void
+	 */
+	function upload_image()
+	{
+		if (isset($_FILES['image_tmp']))
+		{
+			$data = array(
+				'name' => $_FILES['image_tmp']['name'],
+				'contents' => file_get_contents($_FILES['image_tmp']['tmp_name']));
+			$data = base64_encode(serialize($data));
+			$output = '<html><head><title>-</title ></head><body>';
+			$output .= '<script language="JavaScript" type="text/javascript">' . "\n";
+			$output .= 'window.parent.document.getElementById(\'image\').value = \'' . $data . '\';' . "\n";
+			$output .= 'window.parent.document.getElementById(\'buttonSave\').onclick();' . "\n";
+			$output .= '</script></body></html >';
+			echo $output;
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.UserPictureProvider.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.UserPictureProvider.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.UserPictureProvider.inc.php	(revision 2372)
@@ -0,0 +1,170 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+
+/**
+ * Classe que provê as fotos dos usuários do LDAP
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class UserPictureProvider
+{
+	/**
+	 * @var int $userID O ID do usuário cuja foto será exibida
+	 * @access private
+	 */
+	private $userID = false;
+
+	/**
+	* @var int $cacheDays O número de dias antes da imagem ser renovada
+	* @access private
+	*/
+	private $cacheDays = 5;
+
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	public function UserPictureProvider()
+	{
+		if (isset($_GET['userID']))
+			if (is_numeric($_GET['userID']))
+				$this->userID = (int) $_GET['userID'];
+	}
+
+	/**
+	 * Redimensiona uma imagem de acordo com o tamanho padrão (hardcoded 60x80)
+	 * @param resource $image Um resource do tipo image (da imagem de entrada)
+	 * @return resource Um resource do tipo image (da imagem redimensionada)
+	 * @access private
+	 */
+	private function resizeImage($image)
+	{
+		/* thumbnail dimensions */
+		$thumbWidth = 60;
+		$thumbHeight = 80;
+		$thumbRatio = $thumbWidth/$thumbHeight;
+
+		/* get the image dimensions */
+		$width = imagesx($image);
+		$height = imagesy($image);
+		$ratio = $width/$height;
+
+		/* resize the image according to the ratio */
+		if ($ratio > $thumbRatio)
+		{
+			$newWidth = $thumbWidth;
+			$newHeight = $height * ($newWidth/$width);
+		}
+		else
+		{
+			$newHeight = $thumbHeight;
+			$newWidth = $width * ($newHeight/$height);
+		}
+
+		/* create the new image */
+		$output = imagecreatetruecolor($newWidth, $newHeight);
+		imagecopyresampled($output, $image, 0, 0, 0, 0,$newWidth, $newHeight, $width, $height);
+
+		return $output;
+	}
+
+	/**
+	 * Serve a imagem do usuário
+	 * @return void
+	 * @access public
+	 */
+	public function serve()
+	{
+		if ($this->userID === false)
+			return;
+
+		/* encontra o diretório onde os arquivos estão armazenados */
+		$baseDirectory = '';
+		if (isset($_SESSION['workflow']['ResourcesRedirector']['baseDirectory']))
+		{
+			$baseDirectory = $_SESSION['workflow']['ResourcesRedirector']['baseDirectory'];
+		}
+		else
+		{
+			if (isset($_SESSION['phpgw_info']['workflow']['vfs_basedir']))
+			{
+				$baseDirectory = $_SESSION['phpgw_info']['workflow']['vfs_basedir'];
+			}
+			else
+			{
+				if (isset($_SESSION['phpgw_info']['expressomail']['server']['files_dir']))
+				{
+					$baseDirectory = $_SESSION['phpgw_info']['expressomail']['server']['files_dir'];
+				}
+				else
+				{
+					/* em último caso, tenta buscar a informação em banco de dados */
+					/* prepara o ambiente para a carga de informações sobre o banco de dados */
+					$result = Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID->query('SELECT config_value FROM phpgw_config WHERE config_app = ? AND config_name = ?', array('phpgwapi', 'files_dir'));
+					if (empty($result))
+						return;
+					$fields = $result->fetchRow();
+					$baseDirectory = $fields['config_value'];
+				}
+			}
+			$_SESSION['workflow']['ResourcesRedirector']['baseDirectory'] = $baseDirectory;
+		}
+
+		$baseDirectory = str_replace('//', '/', $baseDirectory . '/workflow/workflow/ldapPictures');
+		$filename =  $baseDirectory . '/' . $this->userID;
+
+		$createPictureFile = true;
+		if (file_exists($filename))
+		{
+			if ((filemtime($filename) + ($this->cacheDays * 24 * 60 * 60)) > mktime())
+				$createPictureFile = false;
+			else
+				unlink($filename);
+		}
+
+		if ($createPictureFile)
+		{
+			if (!is_dir($baseDirectory))
+				mkdir($baseDirectory, 0770, true);
+
+			$contents = Factory::getInstance('WorkflowLDAP')->getUserPicture($this->userID);
+			$success = true;
+			if ($contents !== false)
+			{
+				$image = imagecreatefromstring($contents);
+				$image = $this->resizeImage($image);
+				$success = @imagepng($image, $filename);
+			}
+
+			if (($contents === false) || ($success === false))
+			{
+				$filename = $baseDirectory . '/default.png';
+				if (!file_exists($filename))
+				{
+					$image = imagecreatefrompng(dirname(__FILE__) . '/../../expressoMail1_2/templates/default/images/photo.png');
+					$image = $this->resizeImage($image);
+					$success = @imagepng($image, $filename);
+				}
+
+				if ($success === false)
+					return false;
+			}
+		}
+
+		Factory::getInstance('ResourcesRedirector')->show($filename);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_rolemanager.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_rolemanager.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_rolemanager.inc.php	(revision 2372)
@@ -0,0 +1,22 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'RoleManager.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_rolemanager extends RoleManager
+	{   /**
+		 * Construtor da classe workflow_rolemanager
+		 * @access public
+		 * @return object
+		 */
+		function workflow_rolemanager()
+		{
+			parent::RoleManager(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.utils.xml.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.utils.xml.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.utils.xml.php	(revision 795)
@@ -0,0 +1,371 @@
+<?php
+require_once('class.utils.php');
+
+/**
+ * Generates XML from vectors and vice-versa
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @author Enderlin Ivan <enderlin.ivan@firegates.com> Classe Clean XML To Array
+ * @link http://www.phpclasses.org/browse/package/3598.html Classe Clean XML To Array
+ * @author Johnny Brochard <johnny.brochard@libertysurf.fr> Classe Array 2 XML
+ * @link http://www.phpclasses.org/browse/package/1826.html Classe Array 2 XML
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ */
+class XmlUtils extends Utils
+{
+	/**
+	 * Xml parser container
+	 * @var resource parser
+	 * @access private
+	 * @see XmlUtils::fromXML
+	 */
+	var $parser;
+	/**
+	 * Parse result
+	 * @var array pOut
+	 * @access private
+	 * @see XmlUtils::fromXML
+	 */
+	var $pOut = array();
+	/**
+	 * Contains the overlap tag temporarily
+	 * @var array track
+	 * @access private
+	 * @see XmlUtils::fromXML
+	 */
+	var $track = array();
+	/**
+	 * Current tag level
+	 * @var string tmpLevel
+	 * @access private
+	 * @see XmlUtils::fromXML
+	 */
+	var $tmpLevel;
+	/**
+	 * Attribut of current tag
+	 * @var array tmpAttrLevel
+	 * @access private
+	 * @see XmlUtils::fromXML
+	 */
+	var $tmpAttrLevel = array();
+	/**
+	 * Write result
+	 * @var string wOut
+	 * @access private
+	 * @see XmlUtils::fromXML
+	 */
+	var $wOut = '';
+
+	/**
+	 * XML Array
+	 * @var array
+	 * @access private
+	 * @see XmlUtils::toXML
+	 */
+	var $XMLArray;
+
+	/**
+	 * DOM document instance
+	 * @var DomDocument
+	 * @access private
+	 * @see XmlUtils::toXML
+	 */
+	var $doc;
+
+	/**
+	 * Gets vector from XML
+	 *
+	 * @access  public
+	 * @param   string $src Source
+	 * @param   string $typeof Source type : NULL, FILE, CURL
+	 * @param   string $encoding Encoding type
+	 * @return  array
+	 */
+	function fromXML ( $src, $typeof = 'FILE', $encoding = 'UTF-8' )
+	{
+		// ini;
+		// (re)set array;
+		$this->pOut = array();
+		$this->parser = xml_parser_create();
+		xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+		xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $encoding);
+		xml_set_object($this->parser, $this);
+		xml_set_element_handler($this->parser, '_startHandler', '_endHandler');
+		xml_set_character_data_handler($this->parser, '_contentHandler');
+		// format source;
+		if($typeof == NULL) {
+			$data = $src;
+		}
+		elseif($typeof == 'FILE') {
+			$fop = fopen($src, 'r');
+			$data = fread($fop, filesize($src));
+			fclose($fop);
+		}
+		elseif($typeof == 'CURL') {
+			$curl = curl_init();
+			curl_setopt($curl, CURLOPT_URL, $src);
+			curl_setopt($curl, CURLOPT_HEADER, 0);
+			$data = curl_exec($curl);
+			curl_close($curl);
+		}
+		else {
+			$this->raiseError('O analisador XML precisa de informações', __FILE__, __LINE__);
+		}
+		// parse $data;
+		$parse = xml_parse($this->parser, $data);
+		if(!$parse) {
+			$this->raiseError
+			(
+				'XML Error : '                                      .
+				xml_error_string(xml_get_error_code($this->parser)) .
+				' at line '                                         .
+				xml_get_current_line_number($this->parser)          ,
+				__FILE__                                            ,
+				__LINE__
+			);
+		}
+		// destroy parser;
+		xml_parser_free($this->parser);
+		// unset extra vars;
+		unset($data,
+			  $this->track,
+			  $this->tmpLevel,
+			  $this->tmpAttrLevel);
+		// remove global tag and return the result;
+		return $this->pOut[0][key($this->pOut[0])];
+	}
+
+	/**
+	 * Converts vectors to XML
+	 *
+	 * @param array $input Vector, associative or not, to be parsed into XML
+	 * @param string $rootName Root tag's label
+	 * @access public
+	 * @return string
+	 */
+	function toXML($input, $rootName="")
+	{
+		if (is_array($input) && count($input) != 0){
+			$this->XMLArray = $input;
+		} else {
+			$this->raiseError('O argumento a ser convertido deve ser um array com pelo menos 1 elemento', __FILE__, __LINE__);
+		}
+		global $debug;
+		$this->doc = domxml_new_doc("1.0");
+		$arr = array();
+		if (count($this->XMLArray) > 1) {
+			if ($rootName != "") {
+				$root = $this->doc->create_element($rootName);
+			} else {
+				$root = $this->doc->create_element("root");
+				$rootName = "root";
+			}
+			$arr = $this->XMLArray;
+		} else {
+			$key = key($this->XMLArray);
+			$val = $this->XMLArray[$key];
+			if (!is_int($key)) {
+				$root = $this->doc->create_element($key);
+				$rootName = $key;
+			} else {
+				if ($rootName != "") {
+					$root = $this->doc->create_element($rootName);
+				} else {
+					$root = $this->doc->create_element("root");
+					$rootName = "root";
+				}
+			}
+			$arr = $this->XMLArray[$key];
+		}
+		$root = $this->doc->append_child($root);
+		$this->_addArray($arr, $root, $rootName);
+		return($this->doc->dump_mem(true));
+	}
+
+	/**
+	 * Manages the open tag, and these attributs by callback
+	 * The purpose is to create a pointer : {{int ptr}}
+	 * If the pointer exists, we have a multi-tag situation
+	 * Tag name  is stocked like : '<tag>'
+	 * Attributs is stocked like : '<tag>-ATTR'
+	 * Returns TRUE but built $this->pOut
+	 *
+	 * @access  private
+	 * @param   resource $parser Parser resource
+	 * @param   string $tag Tag name
+	 * @param   array $attr Attribut
+	 * @return  bool
+	 * @see XmlUtils::fromXML
+	 */
+	function _startHandler ( $parser, $tag, $attr )
+	{
+		static $attrLevel = -1;
+		static $fnstAttr = TRUE;
+		$attrLevel++;
+		// built $this->track;
+		$this->track[] = $tag;
+		// place pointer to the end;
+		end($this->track);
+		// temp level;
+		$this->tmpLevel = key($this->track);
+		// built $this->pOut;
+		if(!isset($this->pOut[key($this->track)][$tag])) {
+			$this->pOut[key($this->track)][$tag] = '{{'.key($this->track).'}}';
+			$attrLevel = 0;
+			$this->tmpAttrLevel = array();
+		}
+		// built attributs;
+		if(!empty($attr)) {
+			$this->tmpAttrLevel[] = $attrLevel;
+			end($this->tmpAttrLevel);
+			// it's the first attribut;
+			if(!isset($this->pOut[key($this->track)][$tag.'-ATTR'])) {
+				$this->pOut[key($this->track)][$tag.'-ATTR'] = $attr;
+			} else { // or it's not the first;
+				// so it's the second;
+				if($fnstAttr === TRUE) {
+					$this->pOut[key($this->track)][$tag.'-ATTR'] = array(
+						prev($this->tmpAttrLevel) => $this->pOut[key($this->track)][$tag.'-ATTR'],
+						next($this->tmpAttrLevel) => $attr
+					);
+					$fnstAttr = FALSE;
+				} else { // or one other;
+					$this->pOut[key($this->track)][$tag.'-ATTR'][current($this->tmpAttrLevel)] = $attr;
+				}
+			}
+		}
+		return TRUE;
+	}
+
+	/**
+	 * Detects the pointer, or the multi-tag by callback
+	 * If we have a pointer, the method replaces this pointer by the content
+	 * Else we have a multi-tag, the method add a element to this array
+	 * This method returns TRUE but built $this->pOut
+	 *
+	 * @access  private
+	 * @param   resource $parser Parser resource
+	 * @param   string $contentHandler Tag content
+	 * @return  bool
+	 * @see XmlUtils::fromXML
+	 */
+	function _contentHandler ( $parser, $contentHandler )
+	{
+		// remove all spaces;
+		if(!preg_match('#^[[:space:]]*$#', $contentHandler)) {
+			// $contentHandler is a string;
+			if(is_string($this->pOut[key($this->track)][current($this->track)])) {
+				// then $contentHandler is a pointer : {{int ptr}}     case 1;
+				if(preg_match('#{{([0-9]+)}}#', $this->pOut[key($this->track)][current($this->track)])) {
+					$this->pOut[key($this->track)][current($this->track)] = $contentHandler;
+				} else { // or then $contentHandler is a multi-tag content      case 2;
+					$this->pOut[key($this->track)][current($this->track)] = array(
+						0 => $this->pOut[key($this->track)][current($this->track)],
+						1 => $contentHandler
+					);
+				}
+			} else { // or $contentHandler is an array;
+				// then $contentHandler is the multi-tag array         case 1;
+				if(isset($this->pOut[key($this->track)][current($this->track)][0])) {
+					$this->pOut[key($this->track)][current($this->track)][] = $contentHandler;
+				} else { // or then $contentHandler is a node-tag               case 2;
+					$this->pOut[key($this->track)][current($this->track)] = array(
+						0 => $this->pOut[key($this->track)][current($this->track)],
+						1 => $contentHandler
+					);
+				}
+			}
+		}
+		return TRUE;
+	}
+
+	/**
+	 * Detects the last pointer by callback
+	 * Move the last tags block up
+	 * And reset some temp variables
+	 * This method returns TRUE but built $this->pOut
+	 * @param   resource $parser Parser resource
+	 * @param   string $tag Tag name
+	 * @return  bool
+	 * @see XmlUtils::fromXML
+	 * @access  public
+	 */
+	function _endHandler ( $parser, $tag )
+	{
+		// if level--;
+		if(key($this->track) == $this->tmpLevel-1) {
+			// search up tag;
+			// use array_keys if an empty tag exists (taking the last tag);
+			// if it's a normal framaset;
+			$keyBack = array_keys($this->pOut[key($this->track)], '{{'.key($this->track).'}}');
+			$count = count($keyBack);
+			if($count != 0) {
+				$keyBack = $keyBack{$count-1};
+				// move this level up;
+				$this->pOut[key($this->track)][$keyBack] = $this->pOut[key($this->track)+1];
+			} else { // if we have a multi-tag framaset ($count == 0);
+				// if place is set;
+				if(isset($this->pOut[key($this->track)][current($this->track)][0])) {
+					// if it's a string, we built an array;
+					if(is_string($this->pOut[key($this->track)][current($this->track)])) {
+						$this->pOut[key($this->track)][current($this->track)] = array(
+							0 => $this->pOut[key($this->track)][current($this->track)],
+							1 => $this->pOut[key($this->track)+1]
+						);
+					} else { // else add an index into the array;
+						$this->pOut[key($this->track)][current($this->track)][] = $this->pOut[key($this->track)+1];
+					}
+				} else { // else set the place;
+					$this->pOut[key($this->track)][current($this->track)] = array(
+						0 => $this->pOut[key($this->track)][current($this->track)],
+						1 => $this->pOut[key($this->track)+1]
+					);
+				}
+			}
+			// kick $this->pOut level out;
+			array_pop($this->pOut);
+			end($this->pOut);
+		}
+		// re-temp level;
+		$this->tmpLevel = key($this->track);
+		// kick $this->track level out;
+		array_pop($this->track);
+		end($this->track);
+		return TRUE;
+	}
+
+	/**
+	 * Recursively converts nested arrays to nested XML tags
+	 *
+	 * @param array $arr
+	 * @param object &$n DomNode instance
+	 * @param string $name
+	 * @see XmlUtils::toXML
+	 * @access public
+	 * @return void
+	 */
+	function _addArray($arr, &$n, $name="")
+	{
+		foreach ($arr as $key => $val) {
+			if (is_int($key)) {
+				if (strlen($name)>1) {
+					$newKey = substr($name, 0, strlen($name)-1);
+				} else {
+					$newKey="item";
+				}
+			} else {
+				$newKey = $key;
+			}
+			$node = $this->doc->create_element($newKey);
+			if (is_array($val)) {
+				$this->_addArray($arr[$key], $node, $key);
+			} else {
+				$nodeText = $this->doc->create_text_node($val);
+				$node->append_child($nodeText);
+			}
+			$n->append_child($node);
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowWatcher.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowWatcher.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowWatcher.inc.php	(revision 795)
@@ -0,0 +1,136 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+
+/**
+ * Classe utilizada para protejer objetos do código dos processos. Essa classe atua como um intermediário entre o objeto protegido e o trecho de código que tenta acessar um de seus métodos/atributos.
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class WorkflowWatcher
+{
+	/**
+	 * @var object $protectedObject O objeto que está sendo protegido
+	 * @access private
+	 */
+	private $protectedObject;
+
+	/**
+	 * @var string $currentDir O diretório a partir do qual, os arquivos de código podem utilizar o objeto protegido
+	 * @access private
+	 */
+	private $currentDir;
+
+	/**
+	 * @var int $currentDirLength O número de caracteres de $currentDir
+	 * @access private
+	 */
+	private $currentDirLength;
+
+	/**
+	 * @var bool $enabledSecurity Indica se a segurança está ativa ou não
+	 * @access private
+	 */
+	private static $enabledSecurity = false;
+
+	/**
+	 * Verifica se o arquivo que está acessando um método/atributo do objeto possui permissão para tal
+	 * @param int $index O índice da pilha de chamadas de métodos e funções que deve ser verificado para se encontrar a origem da chamada ao objeto protegido
+	 * @return bool true caso o objeto possa ser acessado ou false caso contrário
+	 * @access private
+	 */
+	private final function workflowWatcherCheckSecurity($index = 2)
+	{
+		if (self::$enabledSecurity == false)
+			return true;
+
+		/* busca a pilha das chamadas de métodos/funções */
+		$debugBacktrace = debug_backtrace();
+
+		/* checa se o acesso ao objeto será permitido ou não */
+		if ((!isset($debugBacktrace[$index]['file'])) || (substr($debugBacktrace[$index]['file'], 0, $this->currentDirLength) === $this->currentDir))
+			return true;
+		else
+			return false;
+	}
+
+	/**
+	 * Aplica as diretivas de segurança do módulo
+	 * @return void
+	 * @access public
+	 */
+	public final function WorkflowWatcher($object)
+	{
+		$this->protectedObject = $object;
+		$this->currentDir = dirname(__FILE__);
+		$this->currentDir = substr($this->currentDir, 0, -13);
+		$this->currentDirLength = strlen($this->currentDir);
+	}
+
+	/**
+	 * Ativa a verificação de acesso ao objeto protegido. Por padrão a segurança fica desabilitada pois ela só é interessante antes da execução do código dos processos e, sendo assim, só é habilitada nestes casos.
+	 * @return void
+	 * @access public
+	 */
+	public final static function workflowWatcherEnableSecurity()
+	{
+		self::$enabledSecurity = true;
+	}
+
+	/**
+	 * Implementação do método mágico "__call" que intercepta as chamadas ao objeto protegido
+	 * @param string $methodName O nome do método que está sendo requisitado
+	 * @param array $arguments Os parâmetros passados para o método
+	 * @return mixed O resultado da chamada do método ou false se o código que o método não tiver permissão para tal
+	 * @access public
+	 */
+	public final function __call($methodName, $arguments)
+	{
+		if (!$this->workflowWatcherCheckSecurity())
+			return false;
+
+		$method = new ReflectionMethod($this->protectedObject, $methodName);
+		return $method->invokeArgs($this->protectedObject, $arguments);
+	}
+
+	/**
+	 * Implementação do método mágico "__set" que intercepta definições de atributos do objeto protegido
+	 * @param string $name O nome do atributo ao qual está sendo atribuído um valor
+	 * @param mixed $value O valor que será atribuído ao atributo do objeto
+	 * @return void
+	 * @access public
+	 */
+	public final function __set($name, $value)
+	{
+		if (!$this->workflowWatcherCheckSecurity(1))
+			return false;
+
+		$this->protectedObject->{$name} = $value;
+	}
+
+	/**
+	 * Implementação do método mágico "__get" que intercepta leitura de atributos do objeto potegido
+	 * @param string $name O nome do atributo que se está tentando acessar
+	 * @return mixed O valor do atributo que se está acessando. Ou false, caso o acesso ao atributo seja negado
+	 * @access public
+	 */
+	public final function __get($name)
+	{
+		if (!$this->workflowWatcherCheckSecurity(1))
+			return false;
+
+		return $this->protectedObject->{$name};
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.fsutils.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.fsutils.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.fsutils.inc.php	(revision 795)
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Supporting class for file system handling.
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class FsUtils {
+	
+	/**
+	 * @var string $configDir Path to configs files directory
+	 * @access public
+	 */
+	var $configDir = null;
+	/**
+	 * @var string $processDir Path to workflow processes directory
+	 * @access public
+	 */
+	var $processDir = null;
+	/**
+	 * @var array $errors Errors summary
+	 * @access public
+	 */
+	var $errors = null;		
+	/**
+	 * Sets constants and initializes attributes
+	 * @access public
+	 * @return FileSystem
+	 */
+	function FsUtils()
+	{
+		$this->configDir = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP .'inc' . SEP . 'config' . SEP;
+		$this->processDir = GALAXIA_PROCESSES . SEP;				
+		$this->errors = array();		
+	}
+	/**
+	 * Simple wrapper for appending errors to the summary
+	 * @param string $errorMsg Error details
+	 * @return void
+	 * @access public
+	 */
+	function _appendError ($errorMsg) {
+		array_push($this->errors, $errorMsg);
+	}
+	/**
+	 * Clears error summary
+	 * @return void
+	 * @access public
+	 */	
+	function clearErrors () {
+		$this->errors = array();
+	}
+	/** 
+	 * Reads directories contents 
+	 * @param string $path Directory path
+	 * @return mixed  Directory's content where the array's keys are the file names and the values its contents or false in case of errors
+	 * @access public  
+	 */
+	function readFolder ($path)	{
+
+		$contents = array(); /* dir content */
+		$dir = null; /* dir reading handle */	
+		$file = null; /* each dir's file name */
+		$absolute = $this->processDir . $path; /* absolute path to the processes dir - prevents access to other dirs */
+
+		if (! is_dir($absolute) ) {			
+			$this->_appendError("O caminho $absolute não é um diretório.");
+			return false; 
+		}
+		
+		if (! $dir = @opendir($absolute) ) {			
+			$this->_appendError("O diretório $absolute não pode ser lido.");
+			return false; 					
+		} else {			
+			while ( false !== ( $fileName = readdir($dir) ) ) {				
+				$file = $absolute . $fileName; /* gets full path reference */
+				if ( is_file($file) ) { /* ignores subdirs */										
+					if (! is_readable($file) ) {
+						$this->_appendError("O arquivo " . $path . $file . " não pode ser lido.");
+					} else {
+						@$contents[$fileName] = file_get_contents($file); /* reads each file contents */						
+					}								
+				}				
+			}
+		}
+		
+		if ( count($this->errors) ) { 
+			return false;
+		} else {
+			return $contents;
+		}
+	}
+	
+	/**
+	 * Loads configuration settings from *.ini files
+	 * @param string $configFile File name
+	 * @return array Configuration settings or an error message
+	 * @access public
+	 */
+	function getConfig ($configFile) {		
+		
+		$absolute = $this->configDir . $configFile; /* absolute path to the config file - prevents access to other dirs */
+		
+		if (! file_exists($absolute) ) {			
+			return "O arquivo $configFile não existe.";
+		} elseif (! is_file($absolute) ) {
+			return $configFile . " não é um arquivo comum.";
+		} elseif (! is_readable($absolute) ) {
+			return "O arquivo $configFile não pode ser lido.";
+		}
+
+		return parse_ini_file($absolute);
+	}		
+}
+?>
Index: /sandbox/workflow/branches/993/inc/hook_deleteaccount.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/hook_deleteaccount.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/hook_deleteaccount.inc.php	(revision 795)
@@ -0,0 +1,47 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	// Delete all records for a user
+	if((int)$_POST['new_owner'] == 0)
+	{
+		//remove user from role mappings
+		ExecMethod('workflow.workflow_rolemanager.remove_user',(int)$_POST['account_id']);
+		//remove user from user/owner/next_user of instances
+		ExecMethod('workflow.workflow_instancemanager.remove_user',(int)$_POST['account_id']);
+		//remove user from default_next_user of activities
+		ExecMethod('workflow.workflow_activitymanager.remove_user',(int)$_POST['account_id']);
+	}
+	else
+	{
+		ExecMethod('workflow.workflow_rolemanager.transfer_user', 
+			Array(
+				'old_user'	=> (int)$_POST['account_id'],
+				'new_user'	=> (int)$_POST['new_owner']
+			)
+		);
+		ExecMethod('workflow.workflow_instancemanager.transfer_user', 
+			Array(
+				'old_user'	=> (int)$_POST['account_id'],
+				'new_user'	=> (int)$_POST['new_owner']
+			)
+		);
+		ExecMethod('workflow.workflow_activitymanager.transfer_user', 
+			Array(
+				'old_user'	=> (int)$_POST['account_id'],
+				'new_user'	=> (int)$_POST['new_owner']
+			)
+		);
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.basemodel.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.basemodel.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.basemodel.inc.php	(revision 795)
@@ -0,0 +1,430 @@
+<?php
+/**
+ * Implements workflow module processes providing support for MVC architecture
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.3
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class BaseModel
+{
+	/* begin constants declaration */
+	/**
+	 * @var string $CANCELAR Stopping activities shortcut
+	 * @access public
+	 */
+	var $CANCELAR = '__leave_activity';
+
+	/* end constants declaration */
+
+	/* begin attributes declaration */
+	/**
+	 * @var array $workflow Workflow module information
+     * @access public
+     */
+	var $workflow;
+
+	/**
+     * @var object $activity Activity class instance
+     * @access public
+     */
+    var $activity;
+
+	/**
+     * @var object $factory Factory class reference
+     * @access public
+     */
+    var $factory;
+
+	/**
+     * @var object $instance Instance class reference
+     * @access public
+     */
+    var $instance;
+
+	/**
+	 * @var object $DAO DAO (Data Access Object) instance
+     * @access public
+     */
+    var $DAO;
+
+	/**
+	 * @var object $natural Natural instance
+     * @access public
+     */
+    var $natural;
+
+	/**
+     * @var array $viewData Data sent to view layer by Controller.
+     * Template vars must have the same names of this array's keys
+     * @access public
+     */
+    var $viewData = array();
+
+	/**
+	 * @var array $request Data received from the user
+     * @access public
+     */
+    var $request;
+
+	/**
+     * @var string $commandText Holds SQL commands
+     * @access public
+     */
+    var $commandText;
+
+	/**
+     * @var object Holds query resultsets
+     * @access public
+     */
+    var $resultSet;
+
+	/**
+     * @var array $resultRow Holds resultset records
+     * @access public
+     */
+    var $resultRow;
+	/* end attributes declaration */
+	
+	/**
+     * Constructor
+     *
+     * @param array $env MVC settings
+     * @param boolean $autoAssign Automatically fills layers attributes with request data
+     * @return object
+     * @access public
+     */
+	function BaseModel(&$env, $autoAssign = false)
+    {
+        $this->DAO      =& $env['dao']     ;
+        $this->workflow =& $env['workflow'];
+        $this->instance =& $env['instance'];
+        $this->activity =& $env['activity'];
+        $this->request  =& $env['request'] ;
+        $this->factory  =& $env['factory'] ;
+        $this->natural  =& $env['natural'] ;
+
+        if ( $autoAssign ) {
+        	$this->getRequest();
+        }
+	 }
+	/* begin methods declaration */
+
+   /**
+    * Returns layer's attributes along with their values
+    *
+    * @return array result vector
+    * @access public
+    */
+	function getAttributes()
+    {
+		/* gets associative vector with name and declaration values of attributes */
+		$attributes = get_class_vars(get_class($this));
+		/* result vector */
+		$result = array();
+		/* iterates over attributes list */
+		foreach ($attributes as $attribute => $value) {
+			/* parses only process-level attributes, whose names start with a _ signal */
+			if (ereg('^_{1}', $attribute)) {
+				$result[$attribute] = $this->{$attribute};
+			}
+		}
+		/* return result vector */
+		return $result;
+	}
+
+   /**
+    * Returns the user supplied attributes that are also an attribute of the model class
+	* @param mixed $fields Use an array of attributes names to use only those in the array. Use null (default value) to select all the attributes. Also, it's possible to use a string to specify only one attribute.
+    * @return mixed The filtered array or false in case of errors.
+    * @access public
+    */
+	function filterUserSuppliedAttributes($fields)
+	{
+		$attributes = $this->getAttributes();
+		if (is_null($fields))
+		{
+			$fields = $attributes;
+		}
+		else
+		{
+			if (is_string($fields))
+				$fields = array($fields);
+
+			if (!is_array($fields))
+				return false;
+
+			$fields = array_flip(array_intersect(array_keys($attributes), $fields));
+		}
+
+		return $fields;
+	}
+
+   /**
+    * Creates module API class instance
+    *
+    * @param string $obj Class name
+    * @return mixed
+    * @deprecated
+    * @access public
+    */
+	function &getInstance($obj)
+    {
+		return(wf_create_object(strtolower($obj)));
+	}
+
+   /**
+    * Maps request vars to layer attributes
+	* @param mixed $fields Use an array of attributes names to use only those in the array. Use null (default value) to select all the attributes. Also, it's possible to use a string to specify only one attribute.
+	* @return bool true in case of success of false otherwise.
+    * @access public
+    */
+	function getRequest($fields = null, $from = null)
+	{
+		if (($fields = $this->filterUserSuppliedAttributes($fields)) === false)
+			return false;
+
+		/* define the origin of the variables */
+		$request = is_null($from) ? $this->request : $from;
+		foreach ($request as $key => $value)
+			if (array_key_exists($key, $fields))
+				@$this->{$key} = $value;
+
+		return true;
+	}
+
+   /**
+    * Stores value to be shown on view layer
+    *
+    * @param string $var Template var name
+    * @param string $value Template var value
+    * @return void
+    * @access public
+    */
+	function addViewVar($var, $value)
+    {
+		@$this->viewData[$var] = $value;
+	}
+
+   /**
+    * Retrieves view layer vars
+    *
+    * @param string $var Template var name
+    * @return mixed
+    * @access public
+    */
+	function getViewVar($var)
+    {
+		if ( array_key_exists($var , $this->viewData) ) {
+			return ( $this->viewData[$var] );
+		}
+	}
+
+   /**
+    * Catches module properties
+    *
+    * @param string $property Property name
+    * @return mixed property value
+    * @access public
+    */
+	function getWfProperty($property)
+    {
+		return( $this->workflow[$property] );
+	}
+
+   /**
+    * Sets module properties
+    *
+    * @param string $property property name
+    * @param string $value value
+    * @return void
+    * @access public
+    */
+	function setWfProperty($property , $value)
+    {
+		if ( array_key_exists($property , $this->workflow) ) {
+			$this->workflow[$property] = $value;
+		}
+	}
+
+	/**
+	 * Assign an identifier to the instance
+	 * 
+	 * @param string $param Indentifier to instance
+	 * @return void
+	 * @access public
+	 */
+	function setNameInstance($param)
+	{
+		$this->instance->setName($param);
+	}
+
+    /**
+     * Serializes an array
+     *
+     * @param array $input Array var to be serialized
+     * @access public
+     * @return object ArrayObject
+     * @since PHP 5
+     * @throws Exception
+     */
+    function toObject($input = array())
+    {
+        if (is_array($input)) {
+            return new ArrayObject($input);
+    	}
+        return false;
+    }
+
+    /**
+     * Unserializes an array
+     *
+     * @param object $input ArrayObject to be unserialized
+     * @since PHP 5
+     * @return array
+     * @access public
+     */
+    function fromObject(ArrayObject $input)
+    {
+        return iterator_to_array($input->getIterator());
+    }
+
+    /**
+     * Give useful runtime information about classes and objects
+     *
+     * @param mixed $target Target class name or class instance
+     * @return object Object with runtime information as properties
+     * @access public
+     * @since PHP 5
+     */
+    function inspect($target = null)
+    {
+        if (!is_null($target)) {
+            switch(gettype($target)) {
+                case 'string':
+                    return new ReflectionClass($target);
+                    break;
+                case 'object':
+                    return new ReflectionObject($target);
+                    break;
+                default:
+                    return false;
+                    break;
+            }
+        }
+        return false;
+    }
+
+   /**
+     * Builds SQL commands
+     *
+     * @param string $commandText SQL command
+     * @return void
+     * @access public
+     */
+	function commandBuilder($commandText)
+    {
+		$this->commandText .= $commandText;
+	}
+
+   /**
+     * Finalizes an activity life cycle
+     *
+     * @return void
+     * @access public
+     */
+	function commitInstance()
+    {
+		$this->instance->complete();
+	}
+
+   /**
+     * Updates module data with layer attributes
+	 * @param mixed $fields Use an array of attributes names to use only those in the array. Use null (default value) to select all the attributes. Also, it's possible to use a string to specify only one attribute.
+     * @return bool true in case of success of false otherwise.
+     * @access public
+     */
+    function updateInstance($fields = null)
+    {
+    	$attributes = $this->getAttributes();
+		if (($fields = $this->filterUserSuppliedAttributes($fields)) === false)
+			return false;
+
+		$fields = array_keys($fields);
+    	foreach ($fields as $fieldName)
+			$this->instance->set($fieldName, $attributes[$fieldName]);
+		return true;
+    }
+
+   /**
+     * Updates layer attributes with module data
+	 * @param mixed $fields Use an array of attributes names to use only those in the array. Use null (default value) to select all the attributes. Also, it's possible to use a string to specify only one attribute.
+     * @return bool true in case of success of false otherwise.
+     * @access public
+     */
+    function updateAttributes($fields = null)
+    {
+		if (($fields = $this->filterUserSuppliedAttributes($fields)) === false)
+			return false;
+
+		$fields = array_keys($fields);
+		foreach ($fields as $fieldName)
+			if ($this->instance->exists($fieldName))
+				$this->{$fieldName} = $this->instance->get($fieldName); /* now fills the current object with the values retrieved from the instance */
+
+		return true;
+    }
+
+   /**
+     * Sends a file for download. This method halts the execution of php by using the 'exit' "function".
+     *
+	 * @param string $filename The filename
+	 * @param string $data The file's data
+	 * @param string $mime The mime type of the file. If not used, a mime type that forces the download will be used.
+     * @return bool false in case of error. In case of success, the script is interrupted to avoid incorrect behavior of php
+     * @access public
+     */
+	function sendFile($filename, $data, $mime = null)
+	{
+		/* check if everything is ok */
+		if (empty($filename))
+			return false;
+
+		/* check if the user supplied a mime type */
+		if (is_null($mime))
+			$mime = 'application/force-download';
+
+		/* use the download mode */
+		$this->setWfProperty('downloadMode', true);
+
+		/* send the file */
+		header('Pragma: public');
+		header('Cache-Control: cache, must-revalidate');
+		header('Content-Type: ' . $mime);
+		header('Content-Disposition: attachment; filename="' . $filename . '"');
+		header('Pragma: no-cache');
+		header('Expires: 0');
+		header('Content-length: ' . strlen($data));
+		echo $data;
+
+		/* ends PHP execution to avoid incorret behavior */
+		exit();
+	}
+
+   /**
+     * Provides constructor access to its subclasses for processes startup settings
+     *
+     * @param array   $env MVC settings
+     * @param boolean $autoAssign Automatically fills layers attributes with request data
+     * @return object
+     * @access public
+     */
+	function super(&$env, $autoAssign = false)
+    {
+		BaseModel::BaseModel(&$env, $autoAssign);
+	}
+
+	/* end methods declaration */
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_agent.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_agent.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_agent.inc.php	(revision 2372)
@@ -0,0 +1,88 @@
+<?php
+/**************************************************************************\
+* eGroupWare - Workflow Agent's SO-layer (storage-object)                  *
+* http://www.egroupware.org                                                *
+* (c) 2005 by Regis leroy <regis.leroy@glconseil.com>                      *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+/**
+ * Abstract Class to store/read all agents data
+ *
+ * Creation and deletion of agents records are done by the workflow engine, not
+ * by this class and her childs.
+ *
+ * @package Workflow
+ * @author regis.leroy@glconseil.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+
+class so_agent
+{
+	//public functions
+
+	/**
+	 * @var array $public_functions Array of public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'read'	=> true,
+		'save'	=> true,
+	);
+	/**
+	 * @var array $wf_table
+	 * @access public
+	 */
+	var $wf_table = 'egw_wf_agent_';
+	/**
+	 * @var string $agent_table
+	 * @access public
+	 */
+	var $agent_table = '';
+
+	// link to the global db-object
+
+	/**
+	 * @var object $db objeto para conexao do banco de dados
+	 * @access public
+	 */
+	var $db;
+
+	/**
+	 * Constructor of the so_agent class
+	 * do not forget to call it (parent::so_agent();) in child classes
+	 * @access public
+	 * @return object
+	 */
+
+	function so_agent()
+	{
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBGalaxia();
+	}
+
+	/**
+	 * @abstract read all agent datas from the database
+	 * @param int $agent_id int id of the entry to read
+	 * @return array array/boolean array with column => value pairs or false if entry not found
+	 */
+	function read($agent_id)
+	{
+		return false;
+	}
+
+	/**
+	 * @abstract save all agent datas to the database
+	 * @param int $agent_id int id of the entry to save
+	 * @param array $datas is an array containing columns => value pairs which will be saved for this agent
+	 * @return true if everything was ok, false else
+	 */
+	function save($agent_id, &$datas)
+	{
+		return false;
+	}
+}
Index: /sandbox/workflow/branches/993/inc/class.bo_workflow_forms.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_workflow_forms.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_workflow_forms.inc.php	(revision 2372)
@@ -0,0 +1,209 @@
+<?php
+	require_once(dirname(__FILE__) . SEP . 'class.WorkflowUtils.inc.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */	
+	class bo_workflow_forms extends WorkflowUtils
+	{
+		/**
+		 * @var int $nextrows nextmatchs (max number of rows per page) and associated vars
+		 * @access public
+		 */
+		var $nextmatchs;
+		/**
+		 * @var int $start actual starting row number
+		 * @access public
+		 */
+		var $start; 
+		/**
+		 * @var int $total_records total number of rows
+		 * @access public
+		 */
+		var $total_records; 
+		/**
+		 * @var string $order column used for order 
+		 * @access public
+		 */
+		var $order;
+		/**
+		 * @var string $sort ASC or DESC 
+		 * @access public
+		 */
+		var $sort;
+		/**
+		 * @var int $sort_mode combination of order and sort 
+		 * @access public
+		 */
+		var $sort_mode; 
+		/**
+		 * @var int $offset the number of authorized lines 
+		 * @access public
+		 */
+		var $offset; 
+		/**
+		 * @var string $search_str searched string
+		 * @access public
+		 */
+		var $search_str;
+		/**
+		 * @var array $link_data associative array of input and values used for get links and/or hidden fields
+		 * @access public
+		 */
+		var $link_data = array();
+		/**
+		 * @var string $template_name name of the template associated with this form, used to set the form_action as well
+		 * for example a template named monitor_processes must be linked with a class.ui_monitor_processes.inc.php
+		 * @access public
+		 */
+		var $template_name;
+		/**
+		 * @var string $form_action form destination
+		 * @access public
+		 */
+		var $form_action;
+		/**
+		 * @var string $class_name related to template_name, name of the child class
+		 * @access public
+		 */
+		var $class_name;
+		/**
+		 * @var array $message message shown in red in top of forms
+		 * @access public
+		 */
+		var $message=Array();
+		
+		/**
+		 * Construtor 
+		 * 
+		 * @access public
+		 * @return object
+		 */
+		function bo_workflow_forms($template_name)
+		{
+			parent::WorkflowUtils();
+			
+			//retrieve common form POST or GET values
+			$this->start		= (int)get_var('start', 'any', 0);
+			$this->order		= get_var('order','any','wf_procname');
+			$this->sort		= get_var('sort','any','ASC');
+			$this->sort_mode	= $this->order . '__' . $this->sort;
+			$this->search_str	= get_var('find', 'any', '');
+			$this->nextmatchs	= Factory::getInstance('nextmatchs');
+			
+			// number of rows allowed
+			if ($GLOBALS['phpgw_info']['user']['preferences']['workflow']['ui_items_per_page'] > 0)
+			{
+				$this->offset = $GLOBALS['phpgw_info']['user']['preferences']['workflow']['ui_items_per_page'];
+			}
+			else
+			{
+				$this->offset = 15;
+			}
+			$this->nextmatchs->maxmatches = $this->offset;
+			
+			$this->template_name = $template_name;
+			$this->class_name = explode('_', $this->template_name);
+			$this->class_name = implode('', $this->class_name);
+			$this->form_action = $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_'. $this->class_name .'.form');
+
+			$title = explode('_', $this->template_name);
+			$title[0] = ucfirst($title[0]);
+			$title[1] = ucfirst($title[1]);
+			$title = implode(' ', $title);
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang($title);
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+
+			$this->t->set_file($this->template_name, $this->template_name . '.tpl');
+			
+			//common css
+ 	  	    $this->t->set_var('processes_css', '<LINK href="'.$this->get_css_link('processes').'" type="text/css" rel="StyleSheet">');
+ 	  	 
+ 	  	 
+		}
+		/**
+		 *  Fill the nextmatchs fields, arrows, and counter
+		 * 
+		 * @param array $header_array is an array with header_names => header_text_shown
+		 * @param int $total_number total records
+		 *  warning header names are header_[name or alias of the column in the query without a dot]
+		 *  this is necessary for sorting
+		 *  You need some fields on the template:
+		 *          <table style="border: 0px;width:100%; margin:0 auto">
+		 *          	<tr class="th" style="font-weight:bold">
+		 *                 	{left}
+		 * 		 * 	* 		 * 	<td><div align="center">{lang_showing}</div></td>
+		 * 		 * 	* 		 * 	{right}
+		 *          	</tr>
+		 * 	</table>
+		 * @return void
+		 * @access public
+		 */
+		function fill_nextmatchs(&$header_array, $total_number)
+		{
+			$this->total_records = $total_number;
+			// left and right nextmatchs arrows
+			$this->t->set_var('left',$this->nextmatchs->left(
+				$this->form_action,$this->start,$this->total_records,$this->link_data));
+			$this->t->set_var('right',$this->nextmatchs->right(
+				$this->form_action,$this->start,$this->total_records,$this->link_data));
+			//show table headers with sort
+			foreach($header_array as $col => $translation) 
+			{
+				$this->t->set_var('header_'.$col,$this->nextmatchs->show_sort_order(
+					$this->sort,$col,$this->order,'/index.php',$translation,$this->link_data));
+			}
+			
+			// info about number of rows
+			if (($this->total_records) > $this->offset)	
+			{
+				$this->t->set_var('lang_showing',lang('showing %1 - %2 of %3',
+					1+$this->start,
+					(($this->start+$this->offset) > ($this->total_records))? $this->total_records : $this->start+$this->offset,
+					$this->total_records));
+			}
+			else 
+			{
+				$this->t->set_var('lang_showing', lang('showing %1',$this->total_records));
+			}
+		}
+		/**
+		 * Fill general datas of workflow forms 
+		 * 
+		 * theses datas are:
+		 * 	$message	   : one or more ui message
+		 * 	$search_str	   : search string for research
+		 * 	$start		   : nextmatch: number of the first row
+		 * 	$sort		   : nextmatch: current sort header
+		 * 	$order		   : nextmatch: asc or desc
+		 * 	$form_action   : link to the monitor subclass
+		 * 
+		 * @return void
+		 * @access public
+		 */
+		function fill_form_variables()
+		{
+			$this->t->set_var(array(
+				'message'			=> implode('<br />', array_filter($this->message)),
+				'start'				=> $this->start,
+				'search_str'			=> $this->search_str,
+				'sort'				=> $this->sort,
+				'order'				=> $this->order,
+				'form_action'			=> $this->form_action,
+			));
+		}
+		/**
+		 * Finish the form process by translating the template, outputing it and showing the footer
+		 * @return void
+		 * @access public
+		 */
+		function finish()
+		{
+			$this->translate_template($this->template_name);
+			$this->t->pparse('output', $this->template_name);
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowSecurity.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowSecurity.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowSecurity.inc.php	(revision 2372)
@@ -0,0 +1,131 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+
+/**
+ * Classe utilizada para melhorar a segurança do módulo ao se executar código dos processos
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class WorkflowSecurity
+{
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	public function WorkflowSecurity()
+	{
+	}
+
+	/**
+	 * Aplica as diretivas de segurança do módulo
+	 * @return void
+	 * @access public
+	 */
+	public function enableSecurityPolicy()
+	{
+		$this->ensureEnvironmentProperWorking();
+		WorkflowWatcher::workflowWatcherEnableSecurity();
+		$this->protectDatabaseObjects();
+		$this->removeSensitiveInformation();
+	}
+
+	/**
+	 * Garante que o ambiente funcionará corretamente após a ativação da segurança
+	 * @return void
+	 * @access private
+	 */
+	private function ensureEnvironmentProperWorking()
+	{
+		/* garante que o objeto de DataBase do Expresso estará disponível */
+		Factory::getInstance('WorkflowObjects')->getDBExpresso();
+	}
+
+	/**
+	 * Protege os objetos de banco de dados (classe DB) conhecidos e que estão na $GLOBALS
+	 * @return void
+	 * @access public
+	 */
+	public function protectDatabaseObjects()
+	{
+		$variables = array();
+		$variables[] = &$GLOBALS['phpgw']->accounts->db;
+		$variables[] = &$GLOBALS['phpgw']->applications->db;
+		$variables[] = &$GLOBALS['phpgw']->acl->db;
+		$variables[] = &$GLOBALS['phpgw']->hooks->db;
+		$variables[] = &$GLOBALS['phpgw']->preferences->db;
+		$variables[] = &$GLOBALS['phpgw']->session->db;
+		$variables[] = &$GLOBALS['phpgw']->translation->db;
+		$variables[] = &$GLOBALS['run_activity']->categories->db;
+		$variables[] = &$GLOBALS['run_activity']->categories->db2;
+		$variables[] = &$GLOBALS['phpgw']->db;
+		foreach ($variables as &$variable)
+		{
+			if (is_null($variable) || (get_class($variable) !== 'db'))
+				continue;
+			$this->removeSensitiveInformationFromDatabaseObject($variable);
+			$variable = Factory::newInstance('WorkflowWatcher', $variable);
+		}
+	}
+
+	/**
+	 * Remove informações sensíveis de variáveis que o código dos processos pode acessar ($GLOBALS e $_SESSION)
+	 * @return void
+	 * @access public
+	 */
+	public function removeSensitiveInformation()
+	{
+		unset(
+			$GLOBALS['phpgw_info']['server']['db_host'],
+			$GLOBALS['phpgw_info']['server']['db_port'],
+			$GLOBALS['phpgw_info']['server']['db_name'],
+			$GLOBALS['phpgw_info']['server']['db_user'],
+			$GLOBALS['phpgw_info']['server']['db_pass'],
+			$GLOBALS['phpgw_info']['server']['db_type'],
+
+			$_SESSION['phpgw_info']['workflow']['server']['db_host'],
+			$_SESSION['phpgw_info']['workflow']['server']['db_port'],
+			$_SESSION['phpgw_info']['workflow']['server']['db_name'],
+			$_SESSION['phpgw_info']['workflow']['server']['db_user'],
+			$_SESSION['phpgw_info']['workflow']['server']['db_pass'],
+			$_SESSION['phpgw_info']['workflow']['server']['db_type'],
+
+			$_SESSION['phpgw_info']['expressomail']['server']['db_host'],
+			$_SESSION['phpgw_info']['expressomail']['server']['db_port'],
+			$_SESSION['phpgw_info']['expressomail']['server']['db_name'],
+			$_SESSION['phpgw_info']['expressomail']['server']['db_user'],
+			$_SESSION['phpgw_info']['expressomail']['server']['db_pass'],
+			$_SESSION['phpgw_info']['expressomail']['server']['db_type'],
+
+			$GLOBALS['phpgw_domain']['default']
+		);
+	}
+
+	/**
+	 * Remove informações de objetos de banco de dados
+	 * @return void
+	 * @access public
+	 */
+	public function removeSensitiveInformationFromDatabaseObject(&$object)
+	{
+		$object->User = '';
+		$object->Password = '';
+		$object->Database = '';
+		$object->Port = '';
+		$object->Host = '';
+		$object->Link_ID->host = '';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/config.egw.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/config.egw.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/config.egw.inc.php	(revision 2372)
@@ -0,0 +1,375 @@
+<?php
+
+/**
+ * Configuration of the Galaxia Workflow Engine for E-Groupware
+ * @package Galaxia
+ */
+
+// Common prefix used for all database table names, e.g. galaxia_
+if (!defined('GALAXIA_TABLE_PREFIX')) {
+		define('GALAXIA_TABLE_PREFIX', 'egw_wf_');
+}
+
+// Directory containing the Galaxia library, e.g. this directory
+if (!defined('GALAXIA_LIBRARY')) {
+		define('GALAXIA_LIBRARY', dirname(__FILE__));
+}
+
+// Specify how error messages should be shown
+if (!function_exists('galaxia_show_error')) {
+	/**
+	* Show error messages from the engine
+	* @param $msg is the message to show
+	* @param $dying is true by default and will launch a terminal die command
+	* @param $log is trru by default and will emit a PHP WARNING if set to true
+	* if not set to false.
+	*/
+	function galaxia_show_error($msg, $dying = true, $log=true)
+	{
+		$final_message = str_replace(htmlspecialchars('<br />'), '<br />', htmlspecialchars("Galaxia Workflow Error: $msg"));
+		if ($log)
+		{
+			trigger_error($final_message, E_USER_WARNING);
+		}
+		if ($dying)
+		{
+			die($final_message);
+		}
+		else
+		{
+			echo("<br>$final_message");
+		}
+	}
+}
+
+
+// filesystem Operations
+$GLOBALS['phpgw']->vfs = createobject('phpgwapi.vfs');
+
+// check if basedir exists
+$test=$GLOBALS['phpgw']->vfs->get_real_info(array('string' => '/', 'relatives' => array(RELATIVE_NONE), 'relative' => False));
+if($test[mime_type]!='Directory')
+{
+	galaxia_show_error(lang('Base directory does not exist, please ask adminstrator to check the global configuration'),false, true);
+}
+
+// check if /workflow  exists
+$test = @$GLOBALS['phpgw']->vfs->get_real_info(array('string' => '/workflow', 'relatives' => array(RELATIVE_NONE), 'relative' => False));
+if($test[mime_type]!='Directory')
+{
+	// if not, create it
+	$GLOBALS['phpgw']->vfs->override_acl = 1;
+	$GLOBALS['phpgw']->vfs->mkdir(array(
+		'string' => '/workflow',
+		'relatives' => array(RELATIVE_NONE)
+	));
+	$GLOBALS['phpgw']->vfs->override_acl = 0;
+
+	// test one more time
+	$test = $GLOBALS['phpgw']->vfs->get_real_info(array('string' => '/workflow', 'relatives' => array(RELATIVE_NONE), 'relative' => False));
+	if($test[mime_type]!='Directory')
+	{
+		galaxia_show_error(lang('/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration'), false, true);
+	}
+}
+			
+// Directory where the Galaxia processes will be stored, e.g. /workflow on the vfs
+if (!defined('GALAXIA_PROCESSES'))
+{
+		// Note: this directory must be writeable by the webserver !
+		define('GALAXIA_PROCESSES', $GLOBALS['phpgw']->vfs->basedir.SEP.'workflow');
+}
+
+// Directory where a *copy* of the Galaxia activity templates will be stored, e.g. templates
+// Define as '' if you don't want to copy templates elsewhere
+if (!defined('GALAXIA_TEMPLATES')) {
+		// Note: this directory must be writeable by the webserver !
+		define('GALAXIA_TEMPLATES', '');
+}
+
+// Default header to be added to new activity templates
+if (!defined('GALAXIA_TEMPLATE_HEADER')) {
+		define('GALAXIA_TEMPLATE_HEADER', '');
+}
+
+// File where the ProcessManager logs for Galaxia will be saved, e.g. lib/Galaxia/log/pm.log
+// Define as '' if you don't want to use logging
+if (!defined('GALAXIA_LOGFILE')) {
+		// Note: this file must be writeable by the webserver !
+		//define('GALAXIA_LOGFILE', GALAXIA_LIBRARY . '/log/pm.log');
+		define('GALAXIA_LOGFILE',  $GLOBALS['phpgw']->vfs->basedir.SEP.'workflow'.SEP.'galaxia.log');
+}
+
+// Directory containing the GraphViz 'dot' and 'neato' programs, in case
+// your webserver can't find them via its PATH environment variable
+if (!defined('GRAPHVIZ_BIN_DIR')) {
+		define('GRAPHVIZ_BIN_DIR', '');
+		//define('GRAPHVIZ_BIN_DIR', 'd:/wintools/ATT/GraphViz/bin');
+}
+
+if (!function_exists('tra'))
+{
+	// language function
+	function tra($msg, $m1='', $m2='', $m3='', $m4='')
+	{
+		return lang($msg, $m1, $m2, $m3, $m4);
+	}
+}
+
+
+//define the list of agents avaible with your Galaxia installation
+if (!function_exists('galaxia_get_agents_list'))
+{
+	/**
+	 * * This function list the agents avaible with your galaxia installation. The name of an agent
+	 * * is his unique identifier, the priority is an execution order priority
+	*  * @return an associative array of agents description, each row is an agent description
+	*  * containing a 'wf_agent_type' key and a 'wf_agent_priority' key
+	 */
+	function galaxia_get_agents_list()
+	{
+		$res = array(
+			array(
+				'wf_agent_type' => 'mail_smtp', 
+				'wf_agent_priority' => 1,
+			)
+		);
+		return  $res;
+	}
+}
+
+
+
+if (!function_exists('galaxia_user_can_admin_process'))
+{
+	//! Specify if the user has special admin rights on processes
+	/**
+	*  * @return true if the actual user has access to the processes administration. 
+	*  * ie. he can edit/activate/deactivate/create/destroy processes and activities
+	*  * warning: dangerous rights, this user can do whatever PHP can do...
+	 */
+	function galaxia_user_can_admin_process()
+	{
+		return (Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']) || $GLOBALS['phpgw']->acl->check('admin_workflow', 1, 'workflow'));
+	}
+}
+
+if (!function_exists('galaxia_user_can_admin_instance'))
+{
+	//! Specify if the user has special admin rights on instances
+	/**
+	*  * @return true if the actual user has access to the instance administration
+	*  * ie. he can edit and modify all properties, members, assigned users of an instance whatever the state of the instance is
+	*  * warning: this is clearly an administrator right
+	 */
+	function galaxia_user_can_admin_instance()
+	{
+		return (Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']) || $GLOBALS['phpgw']->acl->check('admin_instance_workflow', 1, 'workflow'));
+	}
+}
+
+
+if (!function_exists('galaxia_user_can_clean_instances'))
+{
+	//! Specify if the user has special cleanup rights on ALL instances
+	/**
+	*  * @return true if the actual user is granted access to the 'clean instances' and 'clean all instances for a process' functions
+	*  * warning: theses are dangerous functions!
+	 */
+	function galaxia_user_can_clean_instances()
+	{
+		return (Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']) || $GLOBALS['phpgw']->acl->check('cleanup_workflow', 1, 'workflow'));
+	}
+}
+
+if (!function_exists('galaxia_user_can_clean_aborted_instances'))
+{
+	//! Specify if the actual user has special cleanup rights on aborted instances
+	/**
+	*  * @return true if the user is granted access to the 'clean aborted instances' functions
+	 */
+	function galaxia_user_can_clean_aborted_instances()
+	{
+		return (Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']) || $GLOBALS['phpgw']->acl->check('cleanup_aborted_workflow', 1, 'workflow'));
+	}
+}
+
+if (!function_exists('galaxia_user_can_monitor'))
+{
+	//! Specify if the user has special monitors rights
+	/**
+	*  * @return true if the actual user has access to the monitor screens (this is not sufficient for cleanup access)
+	 */
+	function galaxia_user_can_monitor()
+	{
+		return (Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']) || $GLOBALS['phpgw']->acl->check('monitor_workflow', 1, 'workflow'));
+	}
+}
+
+	if (!function_exists('galaxia_retrieve_user_groups')) 
+	{
+		/*!
+		* Specify how to retrieve an array containing all groups id for a given user
+		* if the user is in no group this function should return false
+		* @param $user is the current user id
+		* @return an arry of integers, the groups ids the user is member of, or false if the user is not
+		* the member of any group
+		*/
+		function galaxia_retrieve_user_groups($user = 0)
+		{
+			if ($user == '')
+				$user = $GLOBALS['phpgw_info']['user']['account_id'];
+
+			$memberships = Factory::getInstance('WorkflowLDAP')->getUserGroups($user);
+
+			if ($memberships === false)
+				return false;
+
+			if (count($memberships) == 0)
+				return false;
+
+			return $memberships;
+		}
+	}
+
+
+	if (!function_exists('galaxia_retrieve_group_users')) 
+	{
+		//! Specify how to retrieve an array containing all users id for a given group id
+		/**
+		*  * @param $group the group id
+		*  * @param $add_names false by default, if true we add user names in the result
+		*  * return an array with all users id or an associative array with names associated with ids if $add_names is true
+		 */
+		function galaxia_retrieve_group_users($group, $add_names = false)
+		{
+			/* get information regarding the members of the group */
+			$members = &Factory::getInstance('WorkflowLDAP')->getGroupUsers($group);
+
+			/* checl for error in the LDAP query */
+			if ($members === false)
+				return false;
+
+			/* format the output as requested */
+			$group_users = array();
+			foreach($members as $member)
+				if ($add_names)
+					$group_users[$member['account_id']] = $member['account_name'];
+				else
+					$group_users[] = $member['account_id'];
+
+			return $group_users;
+		}
+	}
+	
+	if (!function_exists('galaxia_retrieve_running_user'))
+{
+	//! returns the actual user running this PHP code
+	/**
+	*  * @return the user id of the actual running user. 
+	 */
+	function galaxia_retrieve_running_user()
+	{
+			return ($GLOBALS['phpgw_info']['user']['account_id']);
+	}
+}
+
+
+	if (!function_exists('galaxia_retrieve_name')) 
+	{
+		//! Specify how to retrieve the name of an user with is Id
+		/**
+		*  * @param $user the user or group id
+		*  * return the name of the user
+		 */
+		function galaxia_retrieve_name($user) 
+		{
+			$username = $GLOBALS['phpgw']->accounts->id2name($user);
+			return $username;
+		}
+	}
+	 
+// Specify how to execute a non-interactive activity (for use in src/API/Instance.php)
+if (!function_exists('galaxia_execute_activity')) {
+		/**
+		 * * This function will execute automatic (non-interactive) activities for the engine
+		*  * @param $activityId (default 0) is the activity_id it should run
+		*  * @param $iid (default 0) is the instance id it should run for
+		*  * @param $auto is true by default
+		*  * @return AN ARRAY, or at least true or false. This array can contain :
+		*	* a key 'failure' with an error string the engine will retrieve in instance error messages in case of
+		*	failure (this will mark your execution as Bad), 
+		*	* a key 'debug' with a debug string the engine will retrieve in instance error messages,
+		 */
+		function galaxia_execute_activity($activityId = 0, $iid = 0, $auto = 1)
+		{
+			// This way we create a new run_activity instance for the next activity
+			$run_activity = Factory::getInstance('run_activity');
+			$data = $run_activity->go($activityId, $iid, $auto);
+			return $data;
+		}
+}
+
+/*
+	Specify how to obtain stored config values
+	Parameter: an array containing pairs of (variables_names => default values)
+	For an unknown variable name it will return default_value and this
+	default value will be the NEW STORED value. If no default value is
+	given we assume it's a false.
+	WARNING: you should cast your result if you bet its' an integer
+	as it is maybe stored as a string. But 1 and 0 special values are
+	handled correctly as ints (bools).
+*/
+if (!function_exists('galaxia_get_config_values')) 
+{
+	function galaxia_get_config_values($parameters=array())
+	{
+			$config = Factory::getInstance('config');
+			$config->read_repository();
+
+			$result_array = array();
+			foreach ($parameters as $config_var => $default_value)
+			{
+				$config_value = $config->config_data[$config_var];
+				if(isset($config_value))
+				{ //we add something in the config store, we take it
+					if ($config_value=='False')
+					{
+						$result_array[$config_var]=0;
+					}
+					elseif ($config_value=='True')
+					{
+						$result_array[$config_var]=1;
+					}
+					else
+					{
+						$result_array[$config_var] = $config_value;
+					}
+				}
+				else
+				{
+					//we had no value stored yet, so we store it now
+		//boolean warning: egw'config class is not storing false values if it is 0
+					//we have to map theses int...
+					$stored_value= (string)$default_value;
+					if ($stored_value=='1')
+					{
+						$stored_value='True';
+					}
+					elseif ($stored_value=='0')
+					{
+						$stored_value='False';
+					}
+
+					$config->value($config_var,$stored_value);
+					$config->save_repository();
+					// take the not casted variable
+					$result_array[$config_var] = $default_value;
+				}
+			}
+			unset($config);
+			return $result_array;
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/class.ajax_ldap.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/class.ajax_ldap.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/class.ajax_ldap.inc.php	(revision 2372)
@@ -0,0 +1,195 @@
+<?php
+	/**
+	* @package Galaxia
+	* @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+	*/
+
+class ajax_ldap
+{
+	/**
+ 	* @var object $ds data source
+	* @access public
+	*/
+	var $ds;
+	/**
+ 	* @var $user_context
+	* @access public
+	*/
+	var $user_context  = '';
+	/**
+ 	* @var $group_context
+	* @access public
+	*/
+	var $group_context = '';
+	/**
+   	*
+   	* @return void
+   	* @access public
+   	*/
+	function ajax_ldap()
+	{
+		$tmpLDAP = &Factory::getInstance('WorkflowLDAP');
+		$this->user_context  = $tmpLDAP->getUserContext();
+		$this->group_context = $tmpLDAP->getGroupContext();
+
+		$this->ds =& Factory::getInstance('WorkflowObjects')->getLDAP();
+	}
+
+	/**
+   	* @param integer $account_id
+   	* @param $wich
+   	* @return
+   	* @access public
+   	*/
+	function id2name($account_id,$which='account_lid')
+	{
+		if ($which == 'account_lid' || $which == 'account_type')	// groups only support account_lid and account_type
+		{
+			$allValues = array();
+			$sri = ldap_search($this->ds, $this->group_context, '(&(gidnumber=' . (int)$account_id . ')(phpgwaccounttype=g))');
+			$allValues = ldap_get_entries($this->ds, $sri);
+
+			$attr = $which == 'account_lid' ? 'cn' : 'phpgwaccounttype';
+			if (@$allValues[0]['cn'][0])
+			{
+				return $allValues[0]['cn'][0];
+			}
+		}
+		$to_ldap = array(
+				'account_lid'   => 'uid',
+				'account_email' => 'mail',
+				'account_firstname' => 'surname',
+				'account_lastname'  => 'cn',
+				'account_type'      => 'phpgwaccounttype',
+		);
+		if (!isset($to_ldap[$which])) return False;
+
+		$allValues = array();
+		$sri = ldap_search($this->ds, $this->user_context, '(&(uidnumber=' . (int)$account_id . ')(phpgwaccounttype=u))');
+		$allValues = ldap_get_entries($this->ds, $sri);
+
+		if (@$allValues[0][$to_ldap[$which]][0])
+		{
+			return $allValues[0][$to_ldap[$which]][0];
+		}
+		return False;
+	}
+
+	/**
+   	* Get full account data from account id
+   	* @return array the whole config-array for that app
+   	* @access public
+   	*/
+	function id2fullname($account_id)
+    {
+		return Factory::getInstance('WorkflowLDAP')->getName($account_id);
+    }
+
+    /**
+   	* Close the ldap connection
+   	* @return void
+   	* @access public
+   	*/
+    function close()
+    {
+        ldap_close($this->ds);
+    }
+
+    /**
+    * Return groups IDs and names of a given user
+    * @param $accountID ID of the user that we want to know the groups
+   	* @return mixed Array containing the groups informations or false in case no group was found
+   	* @access public
+   	*/
+    function membership($accountID = '')
+	{
+		if ($accountID == '')
+			$accountID = $_SESSION['phpgw_info']['workflow']['account_id'];
+
+		$ldap =& Factory::getInstance('WorkflowLDAP');
+		if (count($output = $ldap->getUserGroups($accountID)) == 0)
+			return false;
+		else
+			return $output;
+	}
+	/**
+	* @param string $app
+	* @param string $required
+	* @param string $accountid
+   	* @return mixed
+   	* @access public
+   	*/
+	function get_location_list_for_id($app, $required, $accountid = '')
+	{
+		$GLOBALS['ajax']->db->select('phpgw_acl','acl_location,acl_rights',array(
+				'acl_appname' => $app,
+				'acl_account' => $accountid,
+			),__LINE__,__FILE__);
+
+		$locations = false;
+		while ($GLOBALS['ajax']->db->next_record())
+		{
+			if ($GLOBALS['ajax']->db->f('acl_rights') & $required)
+			{
+				$locations[] = $GLOBALS['ajax']->db->f('acl_location');
+			}
+		}
+		return $locations;
+	}
+	/**
+	* Return members from accountid
+	*
+	* @param integer $accountid
+   	* @return mixed (boolean or array)
+   	* @access public
+   	*/
+	function member($accountid = '')
+	{
+			$security_equals = Array();
+			$security_equals = $this->get_ids_for_location($accountid, 1, 'phpgw_group');
+
+			if ($security_equals == False)
+			{
+				return False;
+			}
+
+			$members = array();
+
+			for ($idx=0; $idx<count($security_equals); $idx++)
+			{
+				$name = $this->id2name((int)$security_equals[$idx]);
+				$members[] = Array('account_id' => (int)$security_equals[$idx], 'account_name' => $name);
+			}
+
+			return $members;
+		}
+	/**
+	 * Return accounts from location
+	 *
+	 * @param $location
+	 * @param $required
+	 * @param $app
+   	 * @return void
+   	 * @access public
+   	 */
+	function get_ids_for_location($location, $required, $app = False)
+	{
+
+			$GLOBALS['ajax']->db->select('phpgw_acl',array('acl_account','acl_rights'),array(
+				'acl_appname'  => $app,
+				'acl_location' => $location,
+				),__LINE__,__FILE__);
+
+			$accounts = false;
+			while ($GLOBALS['ajax']->db->next_record())
+			{
+				if (!!($GLOBALS['ajax']->db->f('acl_rights') & $required))
+				{
+					$accounts[] = (int) $GLOBALS['ajax']->db->f('acl_account');
+				}
+			}
+			return $accounts;
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/config.ajax.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/config.ajax.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/config.ajax.inc.php	(revision 2372)
@@ -0,0 +1,306 @@
+<?php
+/**
+ * @package Galaxia
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ * @licence 
+ */
+
+// Common prefix used for all database table names, e.g. galaxia_
+if (!defined('GALAXIA_TABLE_PREFIX')) {
+		define('GALAXIA_TABLE_PREFIX', 'egw_wf_');
+}
+
+// Directory containing the Galaxia library, e.g. this directory
+if (!defined('GALAXIA_LIBRARY')) {
+		define('GALAXIA_LIBRARY', dirname(__FILE__));
+}
+
+// Directory where the Galaxia processes will be stored, e.g. /workflow on the vfs
+if (!defined('GALAXIA_PROCESSES'))
+{
+		// Note: this directory must be writeable by the webserver !
+		define('GALAXIA_PROCESSES', $_SESSION['phpgw_info']['workflow']['vfs_basedir'].SEP.'workflow');
+}
+
+// Directory where a *copy* of the Galaxia activity templates will be stored, e.g. templates
+// Define as '' if you don't want to copy templates elsewhere
+if (!defined('GALAXIA_TEMPLATES')) {
+		// Note: this directory must be writeable by the webserver !
+		define('GALAXIA_TEMPLATES', '');
+}
+
+// Default header to be added to new activity templates
+if (!defined('GALAXIA_TEMPLATE_HEADER')) {
+		define('GALAXIA_TEMPLATE_HEADER', '');
+}
+
+// File where the ProcessManager logs for Galaxia will be saved, e.g. lib/Galaxia/log/pm.log
+// Define as '' if you don't want to use logging
+if (!defined('GALAXIA_LOGFILE')) {
+		// Note: this file must be writeable by the webserver !
+		//define('GALAXIA_LOGFILE', GALAXIA_LIBRARY . '/log/pm.log');
+		define('GALAXIA_LOGFILE',  $_SESSION['phpgw_info']['workflow']['vfs_basedir'].SEP.'workflow'.SEP.'galaxia.log');
+}
+
+// Directory containing the GraphViz 'dot' and 'neato' programs, in case
+// your webserver can't find them via its PATH environment variable
+if (!defined('GRAPHVIZ_BIN_DIR')) {
+		define('GRAPHVIZ_BIN_DIR', '');
+		//define('GRAPHVIZ_BIN_DIR', 'd:/wintools/ATT/GraphViz/bin');
+}
+
+// language function
+function tra($msg, $m1='', $m2='', $m3='', $m4='')
+{
+	$frase = $msg."*";	
+
+	if (isset($_SESSION['phpgw_info']['workflow']['lang'][$msg]))
+	{
+		$frase = $_SESSION['phpgw_info']['workflow']['lang'][$msg];
+	}
+	
+	$sub_array = array('%1', '%2', '%3', '%4');
+	$new_array = array($m1, $m2, $m3, $m4);
+	
+	return str_replace($sub_array, $new_array, $frase);
+}
+
+//define the list of agents avaible with your Galaxia installation
+if (!function_exists('galaxia_get_agents_list'))
+{
+	/**
+	 * * This function list the agents avaible with your galaxia installation. The name of an agent
+	 * * is his unique identifier, the priority is an execution order priority
+	*  * @return an associative array of agents description, each row is an agent description
+	*  * containing a 'wf_agent_type' key and a 'wf_agent_priority' key
+	 */
+	function galaxia_get_agents_list()
+	{
+		$res = array(
+			array(
+				'wf_agent_type' => 'mail_smtp', 
+				'wf_agent_priority' => 1,
+			)
+		);
+		return  $res;
+	}
+}
+
+
+if (!function_exists('galaxia_user_can_admin_process'))
+{
+	//! Specify if the user has special admin rights on processes
+	/**
+	*  * @return true if the actual user has access to the processes administration. 
+	*  * ie. he can edit/activate/deactivate/create/destroy processes and activities
+	*  * warning: dangerous rights, this user can do whatever PHP can do...
+	 */
+	function galaxia_user_can_admin_process()
+	{
+			return  $_SESSION['phpgw_info']['workflow']['user_can_admin_process'];
+	}
+}
+
+if (!function_exists('galaxia_user_can_admin_instance'))
+{
+	//! Specify if the user has special admin rights on instances
+	/**
+	*  * @return true if the actual user has access to the instance administration
+	*  * ie. he can edit and modify all properties, members, assigned users of an instance whatever the state of the instance is
+	*  * warning: this is clearly an administrator right
+	 */
+	function galaxia_user_can_admin_instance()
+	{
+		return  $_SESSION['phpgw_info']['workflow']['user_can_admin_instance'];
+	}
+}
+
+
+if (!function_exists('galaxia_user_can_clean_instances'))
+{
+	//! Specify if the user has special cleanup rights on ALL instances
+	/**
+	*  * @return true if the actual user is granted access to the 'clean instances' and 'clean all instances for a process' functions
+	*  * warning: theses are dangerous functions!
+	 */
+	function galaxia_user_can_clean_instances()
+	{
+		return  $_SESSION['phpgw_info']['workflow']['user_can_clean_instances'];
+	}
+}
+
+if (!function_exists('galaxia_user_can_clean_aborted_instances'))
+{
+	//! Specify if the actual user has special cleanup rights on aborted instances
+	/**
+	*  * @return true if the user is granted access to the 'clean aborted instances' functions
+	 */
+	function galaxia_user_can_clean_aborted_instances()
+	{
+		return  $_SESSION['phpgw_info']['workflow']['user_can_clean_aborted_instances'];
+	}
+}
+
+if (!function_exists('galaxia_user_can_monitor'))
+{
+	//! Specify if the user has special monitors rights
+	/**
+	*  * @return true if the actual user has access to the monitor screens (this is not sufficient for cleanup access)
+	 */
+	function galaxia_user_can_monitor()
+	{
+		return  $_SESSION['phpgw_info']['workflow']['user_can_monitor'];
+	}
+}
+
+if (!function_exists('galaxia_retrieve_user_groups')) 
+{
+	/*!
+	* Specify how to retrieve an array containing all groups id for a given user
+	* if the user is in no group this function should return false
+	* @param $user is the current user id
+	* @return an arry of integers, the groups ids the user is member of, or false if the user is not
+	* the member of any group
+	*/
+	function galaxia_retrieve_user_groups($user = 0)
+	{
+		$memberships = array();
+
+		$loadGroups = ($user != $_SESSION['phpgw_info']['workflow']['account_id']) || (is_null($_SESSION['phpgw_info']['workflow']['user_groups']));
+		if ($loadGroups)
+		{
+			$memberships = Factory::getInstance('WorkflowLDAP')->getUserGroups($user);
+			if ($user == $_SESSION['phpgw_info']['workflow']['account_id'])
+				$_SESSION['phpgw_info']['workflow']['user_groups'] = $memberships;
+		}
+		else
+			$memberships = $_SESSION['phpgw_info']['workflow']['user_groups']; // we are asking groups membership for the actual user in egroupware we retrieve the already loaded in memory group list.
+
+		if (empty($memberships))
+			return false;
+
+		return $memberships;
+	}
+}
+
+
+if (!function_exists('galaxia_retrieve_group_users')) 
+{
+	//! Specify how to retrieve an array containing all users id for a given group id
+	/**
+	*  * @param $group the group id
+	*  * @param $add_names false by default, if true we add user names in the result
+	*  * return an array with all users id or an associative array with names associated with ids if $add_names is true
+	*/
+	function galaxia_retrieve_group_users($group, $add_names = false) 
+		{
+			/* get information regarding the members of the group */
+			$ldap = &Factory::getInstance('WorkflowLDAP');
+			$members = $ldap->getGroupUsers($group);
+
+			/* checl for error in the LDAP query */
+			if ($members === false)
+				return false;
+
+			/* format the output as requested */
+			$group_users = array();
+			foreach($members as $member)
+				if ($add_names)
+					$group_users[$member['account_id']] = $member['account_name'];
+				else
+					$group_users[] = $member['account_id'];
+
+			return $group_users;
+		}
+}
+	
+if (!function_exists('galaxia_retrieve_running_user'))
+{
+	//! returns the actual user running this PHP code
+	/**
+	*  * @return the user id of the actual running user. 
+	 */
+	function galaxia_retrieve_running_user()
+	{
+		return $_SESSION['phpgw_info']['workflow']['account_id'];
+	}
+}
+
+
+if (!function_exists('galaxia_retrieve_name')) 
+{
+	//! Specify how to retrieve the name of an user with is Id
+	/**
+	*  * @param $user the user or group id
+	*  * return the name of the user
+	 */
+	function galaxia_retrieve_name($user) 
+	{
+		$username = $GLOBALS['ajax']->ldap->id2name($user);
+		return $username;
+	}
+}
+	 
+/*
+	Specify how to obtain stored config values
+	Parameter: an array containing pairs of (variables_names => default values)
+	For an unknown variable name it will return default_value and this
+	default value will be the NEW STORED value. If no default value is
+	given we assume it's a false.
+	WARNING: you should cast your result if you bet its' an integer
+	as it is maybe stored as a string. But 1 and 0 special values are
+	handled correctly as ints (bools).
+*/
+if (!function_exists('galaxia_get_config_values')) 
+{
+	function galaxia_get_config_values($parameters=array())
+	{
+			$config = &Factory::getInstance('ajax_config');
+			$config->read_repository();
+
+			$result_array = array();
+			foreach ($parameters as $config_var => $default_value)
+			{
+				$config_value = $config->config_data[$config_var];
+				if(isset($config_value))
+				{ //we add something in the config store, we take it
+					if ($config_value=='False')
+					{
+						$result_array[$config_var]=0;
+					}
+					elseif ($config_value=='True')
+					{
+						$result_array[$config_var]=1;
+					}
+					else
+					{
+						$result_array[$config_var] = $config_value;
+					}
+				}
+				else
+				{
+					//we had no value stored yet, so we store it now
+					//boolean warning: egw'config class is not storing false values if it is 0
+					//we have to map theses int...
+					$stored_value= (string)$default_value;
+					if ($stored_value=='1')
+					{
+						$stored_value='True';
+					}
+					elseif ($stored_value=='0')
+					{
+						$stored_value='False';
+					}
+
+					$config->value($config_var,$stored_value);
+					$config->save_repository();
+					// take the not casted variable
+					$result_array[$config_var] = $default_value;
+				}
+			}
+			unset($config);
+			return $result_array;
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/GUI/GUI.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/GUI/GUI.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/GUI/GUI.php	(revision 2372)
@@ -0,0 +1,1201 @@
+<?php require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+/**
+ * Provides methods for use in typical user interface scripts
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @todo More options in list_user_instances, they should not be added by the external modules  
+ */
+class GUI extends Base {
+
+  /**
+   * @var object $wf_cecurity Used to obtain access for the user on certain actions from the engine
+   * @access public
+   */
+  var $wf_security;
+  /**
+   * @var object  $pm Process manager object used to retrieve infos from processes
+   * @access public
+   */
+  var $pm;
+  /**
+   * @var array $process_cache Cache to avoid queries
+   * @access public
+   */
+  var $process_cache=Array();
+
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object GUI instance
+   * @access public
+   */
+  function GUI()
+  {
+    $this->child_name = 'GUI';
+    parent::Base();
+    $this->wf_security = &Factory::getInstance('WfSecurity');
+  }
+
+  /**
+   * Collects errors from all linked objects which could have been used by this object.
+   * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
+   * 
+   * @param bool $debug False by default, if true debug messages can be added to 'normal' messages
+   * @param string $prefix Appended to the debug message
+   * @access public
+   * @return void 
+   */
+  function collect_errors($debug=false, $prefix='')
+  {
+    parent::collect_errors($debug, $prefix);
+    $this->error[] = $this->wf_security->get_error(false, $debug, $prefix);
+  }
+
+   /**
+    * List user processes, user processes should follow one of these conditions:
+    * 1) The process has an instance assigned to the user
+    * 2) The process has a begin activity with a role compatible to the user roles
+    * 3) The process has an instance assigned to '*' and the roles for the activity match the roles assigned to the user
+    * 
+    * @param int $user Current user id
+    * @param int $offset Current starting point for the query results
+    * @param int $maxRecords Max number of results to return
+    * @param string $sort_mode For sorting
+    * @param string $find Search in activity name or description
+    * @param string $where Deprecated it's a string to add to the query, use with care for SQL injection 
+    * @access public
+    * @return array List of processes that match this and it also returns the number of instances that are in the process matching the conditions
+    */
+  function gui_list_user_processes($user,$offset,$maxRecords,$sort_mode,$find,$where='')
+  {
+    // FIXME: this doesn't support multiple sort criteria
+    //$sort_mode = $this->convert_sortmode($sort_mode);
+    $sort_mode = str_replace("__"," ",$sort_mode);
+
+    $mid = "where gp.wf_is_active=?";
+    // add group mapping, warning groups and user can have the same id
+    $groups = galaxia_retrieve_user_groups($user);
+    $mid .= " and ((gur.wf_user=? and gur.wf_account_type='u')";
+    if (is_array($groups))
+    {
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+      $mid .= '	or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+    }
+    $mid .= ')';
+    $bindvars = array('y',$user);
+    if($find) {
+      $findesc = '%'.$find.'%';
+      $mid .= " and ((gp.wf_name like ?) or (gp.wf_description like ?))";
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+    }
+    if($where) {
+      $mid.= " and ($where) ";
+    }
+    
+    $query = "select distinct(gp.wf_p_id), 
+                     gp.wf_is_active,                    
+                     gp.wf_name as wf_procname, 
+                     gp.wf_normalized_name as normalized_name, 
+                     gp.wf_version as wf_version,
+                     gp.wf_version as version
+              from ".GALAXIA_TABLE_PREFIX."processes gp
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+              $mid";
+    $query_cant = "select count(distinct(gp.wf_p_id))
+              from ".GALAXIA_TABLE_PREFIX."processes gp
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+              $mid";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode);
+    $cant = $this->getOne($query_cant,$bindvars);
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow()) {
+        // Get instances and activities per process,
+        $pId=$res['wf_p_id'];
+        $query_act = 'select count(distinct(ga.wf_activity_id))
+              from '.GALAXIA_TABLE_PREFIX.'processes gp
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities ga ON gp.wf_p_id=ga.wf_p_id
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'roles gr ON gr.wf_role_id=gar.wf_role_id
+                INNER JOIN '.GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+              where gp.wf_p_id=? 
+              and (  ((gur.wf_user=? and gur.wf_account_type='u') ";
+        if (is_array($groups))
+        {
+          $query_act .= ' or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+        }
+        $query_act .= '))';
+         
+        $res['wf_activities']=$this->getOne($query_act,array($pId,$user));
+        //we are counting here instances which are completed/exception or actives
+        // TODO: maybe we should add a second counter with only running instances
+        $query_inst = 'select count(distinct(gi.wf_instance_id))
+              from '.GALAXIA_TABLE_PREFIX.'instances gi
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'instance_activities gia ON gi.wf_instance_id=gia.wf_instance_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'activity_roles gar ON gia.wf_activity_id=gar.wf_activity_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX."user_roles gur ON gar.wf_role_id=gur.wf_role_id
+              where gi.wf_p_id=? 
+              and (";
+        if (is_array($groups))
+        {
+          $query_inst .= "(gur.wf_user in (".implode(",",$groups).") and gur.wf_account_type='g') or ";
+        }
+        $query_inst .= "(gi.wf_owner=?) 
+                         or ((gur.wf_user=?) and gur.wf_account_type='u'))";
+        $res['wf_instances']=$this->getOne($query_inst,array($pId,$user,$user));
+        $ret[] = $res;
+      }
+    }
+    $retval = Array();
+    $retval["data"] = $ret;
+    $retval["cant"] = $cant;
+    return $retval;
+  }
+
+  /**
+   * Gets user activities
+   * 
+   * @param int $user Current user id
+   * @param int $offset Current starting point for the query results
+   * @param int $maxRecords Max number of results to return
+   * @param string $sort_mode For sorting
+   * @param string $find Search in activity name or description
+   * @param string $where Deprecated it's a string to add to the query, use with care for SQL injection 
+   * @param bool $remove_activities_without_instances False by default will remove all activities having no instances related at this time
+   * @param bool $remove_instances_activities False by default, if true then all activities related to instances will be avoided (i.e. activities which are not standalone, start or view). If $remove_activities_without_instances is true you'll obtain nothing :-)
+   * @param bool $add_start False by default, if true start activities are added to the listing, no effect if $remove_activities_without_instances is true
+   * @param bool $add_standalone False by default, if true standalone activities are added to the listing, no effect if $remove_activities_without_instances is true
+   * @param bool $add_view False by default, if true view activities are added to the listing, no effect if $remove_activities_without_instances is true
+   * @return array Associative, key cant gives the number of results, key data is an associative array conteining the results
+   * @access public
+   */
+  function gui_list_user_activities($user,$offset,$maxRecords,$sort_mode,$find,$where='', $remove_activities_without_instances=false, $remove_instances_activities =false, $add_start = false, $add_standalone = false, $add_view = false)
+  {
+    // FIXME: this doesn't support multiple sort criteria
+    //$sort_mode = $this->convert_sortmode($sort_mode);
+    $sort_mode = str_replace("__"," ",$sort_mode);
+    $mid = "where gp.wf_is_active=?";
+    $bindvars = array('y');
+    
+    if ($remove_instances_activities)
+    {
+      $mid .= " and ga.wf_type <> ? and ga.wf_type <> ? and ga.wf_type <> ?  and  ga.wf_type <> ?  and  ga.wf_type <> ? ";
+      $bindvars[] = 'end';
+      $bindvars[] = 'switch';
+      $bindvars[] = 'join';
+      $bindvars[] = 'activity';
+      $bindvars[] = 'split';
+    }
+    if (!($add_start))
+    {
+      $mid .= " and ga.wf_type <> ?";
+      $bindvars[] = 'start';
+    }
+    if (!($add_standalone))
+    {
+      $mid .= " and ga.wf_type <> ?";
+      $bindvars[] = 'standalone';
+    }
+    if (!($add_view))
+    {
+      $mid .= " and ga.wf_type <> ?";
+      $bindvars[] = 'view';
+    }
+
+    // add group mapping, warning groups and user can have the same id
+    $groups = galaxia_retrieve_user_groups($user);
+    if (is_array($groups))
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+    $mid .= " and ((gur.wf_user=? and gur.wf_account_type='u')";
+    if (is_array($groups))
+    {
+      $mid .= '	or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+    }
+    $mid .= ')';
+    $bindvars[] = $user;
+    if($find) {
+      $findesc = '%'.$find.'%';
+      $mid .= " and ((ga.wf_name like ?) or (ga.wf_description like ?))";
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+    }
+    if($where) {
+      $mid.= " and ($where) ";
+    }
+    if ($remove_activities_without_instances)
+    {
+      $more_tables = "INNER JOIN ".GALAXIA_TABLE_PREFIX."instance_activities gia ON gia.wf_activity_id=gar.wf_activity_id
+                      INNER JOIN ".GALAXIA_TABLE_PREFIX."instances gi ON gia.wf_instance_id=gi.wf_instance_id";
+    }
+    else
+    {
+	$more_tables = "";
+    }
+    $query = "select distinct(ga.wf_activity_id),
+                     ga.wf_name,
+                     NULLIF(ga.wf_menu_path, '') AS wf_menu_path,
+                     ga.wf_type,
+                     gp.wf_name as wf_procname,
+                     ga.wf_is_interactive,
+                     ga.wf_is_autorouted,
+                     ga.wf_activity_id,
+                     gp.wf_version as wf_version,
+                     gp.wf_p_id,
+                     gp.wf_is_active,
+		     gp.wf_normalized_name
+                from ".GALAXIA_TABLE_PREFIX."processes gp
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+                $more_tables
+                $mid";
+              
+    $query_cant = "select count(distinct(ga.wf_activity_id))
+              from ".GALAXIA_TABLE_PREFIX."processes gp
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+                $more_tables
+                $mid ";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode);
+    $cant = (int) $this->getOne($query_cant,$bindvars);
+    $ret = Array();
+
+    if (!empty($result) && ($cant > 0))
+      $ret = $result->getArray(-1);
+
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = $cant;
+    return $retval;
+  }
+
+  /**
+   * Gets user activities but each activity name (and not id) appears only one time
+   * 
+   * @param int $user Current user id
+   * @param int $offset Current starting point for the query results
+   * @param int $maxRecords Max number of results to return
+   * @param string $sort_mode For sorting
+   * @param string $find Search in activity name or description
+   * @param string $where Deprecated it's a string to add to the query, use with care for SQL injection 
+   * @param bool $remove_instances_activities False by default, if true then all activities related to instances will be avoided (i.e. activities which are not standalone, start or view).
+   * @param bool $add_start False by default, if true start activities are added to the listing
+   * @param bool $add_standalone False by default, if true standalone activities are added to the listing
+   * @param bool $add_view False by default, if true view activities are added to the listing
+   * @return array Associative, key cant gives the number of results, key data is an associative array conteining the results
+   * @access public
+   */	
+	function gui_list_user_activities_by_unique_name($user,$offset,$maxRecords,$sort_mode,$find,$where='', $remove_instances_activities =false, $add_start = false, $add_standalone = false, $add_view = false)
+	{
+		// FIXME: this doesn't support multiple sort criteria
+		//$sort_mode = $this->convert_sortmode($sort_mode);
+		$sort_mode = str_replace("__"," ",$sort_mode);
+		$mid = "where gp.wf_is_active=?";
+		$bindvars = array('y');
+		
+                if ($remove_instances_activities)
+                {
+                   $mid .= " and ga.wf_type <> ? and ga.wf_type <> ? and ga.wf_type <> ?  and  ga.wf_type <> ?  and  ga.wf_type <> ? ";
+                   $bindvars[] = 'end';
+                   $bindvars[] = 'switch';
+                   $bindvars[] = 'join';
+                   $bindvars[] = 'activity';
+                   $bindvars[] = 'split';
+                }
+		if (!($add_start))
+		{
+		  $mid .= " and ga.wf_type <> ?";
+		  $bindvars[] = 'start';
+                }
+                if (!($add_standalone))
+		{
+		  $mid .= " and ga.wf_type <> ?";
+		  $bindvars[] = 'standalone';
+                }
+                if (!($add_view))
+		{
+		  $mid .= " and ga.wf_type <> ?";
+		  $bindvars[] = 'view';
+                }
+                
+		// add group mapping, warning groups and user can have the same id
+		$groups = galaxia_retrieve_user_groups($user);
+		$mid .= " and ((gur.wf_user=? and gur.wf_account_type='u')";
+		if (is_array($groups))
+		{
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+		  $mid .= ' or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+                }
+                $mid .= ')';
+
+		$bindvars[] = $user;
+		if($find) 
+		{
+			$findesc = '%'.$find.'%';
+			$mid .= " and ((ga.wf_name like ?) or (ga.wf_description like ?))";
+			$bindvars[] = $findesc;
+			$bindvars[] = $findesc;
+		}
+		if($where) 
+		{
+			$mid.= " and ($where) ";
+		}
+
+		$query = "select distinct(ga.wf_name)
+			from ".GALAXIA_TABLE_PREFIX."processes gp
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+			$mid";
+
+		$query_cant = "select count(distinct(ga.wf_name))
+			from ".GALAXIA_TABLE_PREFIX."processes gp
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+			INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+			$mid";
+		$result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode);
+		$cant = $this->getOne($query_cant,$bindvars);
+		$ret = Array();
+		if (!(empty($result)))
+		{
+		  while($res = $result->fetchRow()) 
+		  {
+			$ret[] = $res;
+                  }
+                }
+
+		$retval = Array();
+		$retval["data"] = $ret;
+		$retval["cant"] = $cant;
+		return $retval;
+	}
+
+  /**
+   * Gets start activities avaible for a given user
+   * 
+   * @param int $user Current user id
+   * @param int $offset Current starting point for the query results
+   * @param int $maxRecords Max number of results to return
+   * @param string $sort_mode For sorting
+   * @param string $find Search in activity name or description
+   * @param string $where Deprecated it's a string to add to the query, use with care for SQL injection
+   * @return array Associative, key cant gives the number of results, key data is an associative array conteining the results
+   * @access public
+   */	  
+  function gui_list_user_start_activities($user,$offset,$maxRecords,$sort_mode,$find,$where='')
+  {
+    // FIXME: this doesn't support multiple sort criteria
+    $sort_mode = str_replace("__"," ",$sort_mode);
+
+    $mid = "where gp.wf_is_active=? and ga.wf_type=?";
+    // add group mapping, warning groups and user can have the same id
+    $groups = galaxia_retrieve_user_groups($user);
+    $mid .= " and ((gur.wf_user=? and gur.wf_account_type='u')";
+    if (is_array($groups))
+    {
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+      $mid .= '	or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+    }
+    $mid .= ')';
+    $bindvars = array('y','start',$user);
+    if($find)
+    {
+      //search on activities and processes
+      $findesc = '%'.$find.'%';
+      $mid .= " and ((ga.wf_name like ?) or (ga.wf_description like ?) or (gp.wf_name like ?) or (gp.wf_description like ?))";
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+    }
+    if($where) 
+    {
+      $mid.= " and ($where) ";
+    }
+
+    $query = "select distinct(ga.wf_activity_id), 
+                              ga.wf_name,
+                              ga.wf_is_interactive,
+                              ga.wf_is_autorouted,
+                              gp.wf_p_id,
+                              gp.wf_name as wf_procname,
+                              gp.wf_version,
+			      gp.wf_normalized_name
+        from ".GALAXIA_TABLE_PREFIX."processes gp
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+	$mid";
+    $query_cant = "select count(distinct(ga.wf_activity_id))
+	from ".GALAXIA_TABLE_PREFIX."processes gp
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_activity_id=ga.wf_activity_id
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.wf_role_id=gar.wf_role_id
+	INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.wf_role_id=gr.wf_role_id
+	$mid";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode);
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow()) 
+      {
+        $ret[] = $res;
+      }
+    }
+    $retval = Array();
+    $retval["data"]= $ret;
+    $retval["cant"]= $this->getOne($query_cant,$bindvars);
+    
+    return $retval;
+  }
+
+  /**
+   * Gets instances avaible for a given user, theses instances are all the instances where the user is able to launch a gui action (could be a run --even a run view activity-- or an advanced action like grab, release, admin, etc)
+   * type of action really avaible are not given by this function
+   *
+   * @see GUI::getUserAction
+   * @access public
+   * @param int $user User id
+   * @param int $offset Starting number for the returned records
+   * @param int $maxRecords Limit of records to return in data (but the 'cant' key count the total number without limits)
+   * @param string $sort_mode Sort mode for the query
+   * @param string $find Look at in activity name, activity description or instance name
+   * @param string $where is an empty string by default, the string let you add a string to the SQL statement -please be carefull with it
+   * @param bool $add_properties False by default, will add properties in the returned instances
+   * @param int $pId Process id, 0 by default, in such case it is ignored
+   * @param bool $add_completed_instances False by default, if true we add completed instances in the result
+   * @param bool $add_exception_instances False by default, if true we add instances in exception in the result
+   * @param bool $add_aborted_instances False by default, if true we add aborted instances in the result
+   * @param bool $restrict_to_owner False by default, if true we restrict to instance for which the user is the owner even if it gives no special rights (that can give more or less results -- you'll have ownership but no rights but you wont get rights without ownership)
+   * @param bool $add_non_interactive_instances_of_the_owner False by default, if true we include the non interactive instances the user owns
+   * @return array Number of records in the 'cant key and instances in the 'data' key.
+   * Each instance is an array containing theses keys: wf_instance_id, wf_started (instance), wf_ended (instance), wf_owner, wf_user, wf_status (instance status),
+   * wf_category, wf_act_status, wf_act_started, wf_name (activity name), wf_type, wf_procname, wf_is_interactive, wf_is_autorouted, wf_activity_id, 
+   * wf_version (process version), wf_p_id, insname (instance name), wf_priority and wf_readonly (which is true if the user only have read-only roles associated with this activity)
+   */
+  function gui_list_user_instances($user, $offset, $maxRecords, $sort_mode, $find, $where='', $add_properties=false, $pId=0, $add_active_instances=true, $add_completed_instances=false, $add_exception_instances=false, $add_aborted_instances=false, $restrict_to_owner=false, $add_non_interactive_instances_of_the_owner = false)
+  {
+    // FIXME: this doesn't support multiple sort criteria
+    //$sort_mode = $this->convert_sortmode($sort_mode);
+    $sort_mode = str_replace("__"," ",$sort_mode);
+
+    $mid = 'WHERE (gp.wf_is_active = ?)';
+    $bindvars = array('y');
+
+    /* restrict to process */
+    if ($pId !== 0)
+    {
+        $mid .= ' AND (gp.wf_p_id = ?)';
+        $bindvars[] = $pId;
+    }
+
+    /* look for a owner restriction */
+    if ($restrict_to_owner)
+    {
+        $mid .= ' AND (gi.wf_owner = ?)';
+        $bindvars[] = $user;
+    }
+    else /* no restriction on ownership, look for user and/or owner */
+    {
+      $groups = galaxia_retrieve_user_groups($user);
+      if (is_array($groups))
+        $groups = '{' . implode(', ', $groups) . '}';
+
+      /* selects the instances that belong to a role, which the user mapped to */
+      $mid .= ' AND (';
+      $mid .= 'gia.wf_user IN (SELECT \'p\' || gur.wf_role_id FROM egw_wf_user_roles gur WHERE (gur.wf_user = ? and gur.wf_account_type=\'u\')';
+      $bindvars[] = $user;
+      if ($groups)
+      {
+        $mid .= ' OR (gur.wf_user = ANY (?) AND gur.wf_account_type=\'g\')';
+        $bindvars[] = $groups;
+      }
+      $mid .= ')';
+
+      /* selects the instances that belong to the user or everyone (the user must be mapped to a role that has access to the activity the instance is in) */
+      $mid .= 'OR (((gia.wf_user = \'*\') OR (gia.wf_user = ?)) AND gia.wf_activity_id IN (SELECT gar.wf_activity_id FROM egw_wf_activity_roles gar, egw_wf_user_roles gur WHERE (gur.wf_role_id = gar.wf_role_id) AND ((gur.wf_user = ? AND gur.wf_account_type=\'u\')';
+      $bindvars[] = $user;
+      $bindvars[] = $user;
+      if ($groups)
+      {
+        $mid .= 'OR (gur.wf_user = ANY (?) AND gur.wf_account_type = \'g\')';
+        $bindvars[] = $groups;
+      }
+      $mid .= ')))';
+
+      /* this collect non interactive instances we are owner of */
+      if ($add_non_interactive_instances_of_the_owner)
+      {
+        $mid .= ' OR ((gi.wf_owner = ?) AND ga.wf_is_interactive = \'n\')';
+        $bindvars[] = $user;
+      }
+
+      /* and this collect completed/aborted instances when asked which haven't got any user anymore */
+      if ($add_completed_instances || $add_aborted_instances)
+          $mid .= ' OR (gur.wf_user IS NULL)';
+
+      $mid .= ')';
+    }
+
+    if($find)
+    {
+      $findesc = '%'. $find .'%';
+      $mid .= " AND ((UPPER(ga.wf_name) LIKE UPPER(?))";
+      $mid .= " OR (UPPER(gi.wf_name) LIKE UPPER(?)))";
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+    }
+
+    if($where)
+      $mid.= " AND ({$where}) ";
+
+    /* instance selection :: instances can be active|exception|aborted|completed */
+    $or_status = Array();
+    if ($add_active_instances)
+      $or_status[] = "(gi.wf_status = 'active')";
+    if ($add_exception_instances)
+      $or_status[] = "(gi.wf_status = 'exception')";
+    if ($add_aborted_instances)
+      $or_status[] = "(gi.wf_status = 'aborted')";
+    if ($add_completed_instances)
+      $or_status[] = "(gi.wf_status = 'completed')";
+    if (!(empty($or_status)))
+        $mid .= ' AND (' . implode(' OR ', $or_status) . ')';
+    else
+      /*special case, we want no active instance, and we do not want exception/aborted and completed, so what?
+       * maybe a special new status or some bad record in database... */
+      $mid .= " AND (gi.wf_status NOT IN ('active','exception','aborted','completed'))";
+
+
+    $selectedColumns = array(
+      'DISTINCT(gi.wf_instance_id)',
+      'gi.wf_started',
+      'gi.wf_ended',
+      'gi.wf_owner',
+      'gia.wf_user',
+      'gi.wf_status',
+      'gi.wf_category',
+      'gia.wf_status AS wf_act_status',
+      'gia.wf_started AS wf_act_started',
+      'ga.wf_name',
+      'ga.wf_type',
+      'gp.wf_name AS wf_procname',
+      'ga.wf_is_interactive',
+      'ga.wf_is_autorouted',
+      'ga.wf_activity_id',
+      'gp.wf_version AS wf_version',
+      'gp.wf_p_id',
+      'gp.wf_normalized_name',
+      'gi.wf_name AS insname',
+      'gi.wf_priority'
+    );
+
+    /* add the read only column */
+    $readOnlyColumn = '(SELECT MIN(gar.wf_readonly) FROM egw_wf_activity_roles gar, egw_wf_user_roles gur WHERE (gar.wf_activity_id = gia.wf_activity_id) AND (gur.wf_role_id=gar.wf_role_id) AND ((gur.wf_user = ? and gur.wf_account_type=\'u\')';
+    if ($groups)
+    {
+      $readOnlyColumn .= ' OR (gur.wf_user = ANY (?) AND gur.wf_account_type = \'g\')';
+      /* add the groups to be the second element of the array (there's another 'array_unshift' in the next lines) */
+      array_unshift($bindvars, $groups);
+    }
+    /* add as the first element of the array */
+    array_unshift($bindvars, $user);
+    $readOnlyColumn .= ')) AS wf_readonly';
+    $selectedColumns[] = $readOnlyColumn;
+
+    /* if requested, retrieve the properties */
+    if ($add_properties)
+      $selectedColumns[] = 'gi.wf_properties';
+
+    /* (regis) we need LEFT JOIN because aborted and completed instances are not showned
+     * in instance_activities, they're only in instances */
+    $query = 'SELECT ' . implode(', ', $selectedColumns) . ' ';
+    $query .= 'FROM egw_wf_instances gi LEFT JOIN egw_wf_instance_activities gia ON gi.wf_instance_id=gia.wf_instance_id ';
+    $query .= 'LEFT JOIN egw_wf_activities ga ON gia.wf_activity_id = ga.wf_activity_id ';
+    $query .= 'INNER JOIN egw_wf_processes gp ON gp.wf_p_id=gi.wf_p_id ';
+    $query .= $mid;
+
+    /* fetch the data (paging, if necessary) and count the records */
+    $result = $this->query($query, $bindvars, -1, 0, true, $sort_mode);
+    $cant = $result->NumRows();
+    $realMaxRecords = ($maxRecords == -1) ? ($cant - $offset) : min($maxRecords, $cant - $offset);
+    $ret = Array();
+    if ($cant > $offset)
+    {
+      $result->Move($offset);
+      for ($i = 0; $i < $realMaxRecords; $i++)
+      {
+        $res = $result->fetchRow();
+        if (substr($res['wf_user'], 0, 1) == 'p')
+          $res['wf_user'] = '*';
+        $ret[] = $res;
+      }
+    }
+
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = $cant;
+    return $retval;
+  }
+
+ /**
+  * Gets all instances where the user is the owner (active, completed, aborted, exception)
+  * 
+  * @access public
+  * @param int $user User id
+  * @param int $offset Starting number for the returned records
+  * @param int $maxRecords Limit of records to return in data (but the 'cant' key count the total number without limits)
+  * @param string $sort_mode Sort mode for the query
+  * @param string $find Look at in activity name, activity description or instance name
+  * @param string $where Empty by default, the string let you add a string to the SQL statement -please be carefull with it
+  * @param bool $add_properties False by default, will add properties in the returned instances
+  * @param int $pId Process id, 0 by default, in such case it is ignored
+  * @param bool $add_completed_instances False by default, if true we add completed instances in the result
+  * @param bool $add_exception_instances False by default, if true we add instances in exception in the result
+  * @param bool $add_aborted_instances False by default, if true we add aborted instances in the result
+  * @param bool $add_non_interactive_instances_of_the_owner True by default, if true we include the non interactive instances the user owns
+  * @return array Associative, key cant gives the number of results, key data is an array of instances and each instance
+  * an array containing theses keys: wf_instance_id, wf_started (instance), wf_ended (instance), wf_owner, wf_user,
+  * wf_status (instance status), wf_category, wf_act_status (activity), wf_act_started (activity), wf_name (activity name),
+  * wf_type, wf_procname, wf_is_interactive, wf_is_autorouted, wf_activity_id, wf_version (process version), wf_p_id,
+  * insname (instance name), wf_priority and wf_readonly (which is true if the user only have read-only roles associated
+  * with this activity)
+  */
+  function gui_list_instances_by_owner($user, $offset, $maxRecords, $sort_mode, $find, $where='', $add_properties=false, $pId=0, $add_active_instances=true, $add_completed_instances=false, $add_exception_instances=false, $add_aborted_instances=false, $add_non_interactive_instances_of_the_owner = true)
+  {
+	  return $this->gui_list_user_instances($user,$offset,$maxRecords,$sort_mode,$find,$where,$add_properties, $pId,$add_active_instances,$add_completed_instances,$add_exception_instances, $add_aborted_instances, true, $add_non_interactive_instances_of_the_owner);
+  }
+
+  /**
+   * Gets the view activity id avaible for a given process.
+   * No test is done on real access to this activity for users, this access will be check at runtime (when clicking)
+   * 
+   * @param int $pId Process Id
+   * @return mixed View activity id or false if no view activity is present dor this process
+   * @access public
+   */
+  function gui_get_process_view_activity($pId)
+  {
+    if (!(isset($this->process_cache[$pId]['view'])))
+    {
+      if (!(isset($this->pm)))
+      {
+        $this->pm = &Factory::newInstance('ProcessManager');
+      }
+      $this->process_cache[$pId]['view'] = $this->pm->get_process_view_activity($pId);
+    }
+    return $this->process_cache[$pId]['view'];
+  }
+
+  /**
+   * Gets all informations about a given instance and a given user, list activities and status.
+   * We list activities for which the user is the owner or the actual user or in a role giving him access to the activity
+   * notice that completed and aborted instances aren't associated with activities and that start and standalone activities
+   * aren't associated with an instance ==> if instanceId is 0 you'll get all standalone and start activities in the result.
+   * This is the reason why you can give --if you have it-- the process id, to restrict results to start and standalone
+   * activities to this process
+   * 
+   * @access public
+   * @param int $user User id
+   * @param int $instance_id Instance id
+   * @param int $pId Process id, 0 by default, in such case it is ignored
+   * @param bool $add_completed_instances False by default, if true we add completed instances in the result
+   * @param bool $add_exception_instances False by default, if true we add instances in exception in the result
+   * @param bool $add_aborted_instances False by default, if true we add aborted instances in the result
+   * @return array Associative, contains:
+   * ['instance'] =>
+   *    ['instance_id'], ['instance_status'], ['owner'], ['started'], 
+   *    ['ended'], ['priority'], ['instance_name'], 
+   *    ['process_name'], ['process_version'], ['process_id']
+   * ['activities'] =>
+   *     ['activity'] =>
+   *         ['user']		    : current user
+   *         ['id']		        : activity Id
+   *         ['name']
+   *         ['type']
+   *         ['is_interactive']	: 'y' or 'n'
+   *         ['is_autorouted']	: 'y' or 'n'
+   *         ['status']
+   */
+  function gui_get_user_instance_status($user,$instance_id, $pId=0, $add_completed_instances=false,$add_exception_instances=false, $add_aborted_instances=false)
+  {
+    $bindvars =Array();
+    $mid = "\n where gp.wf_is_active=?";
+    $bindvars[] = 'y';
+    if (!($pId==0))
+    {
+      // process restriction
+      $mid.= " and gp.wf_p_id=?";
+      $bindvars[] = $pId;
+    }
+    if (!($instance_id==0))
+    {
+      // instance selection
+      $mid .= " and (gi.wf_instance_id=?)";
+      $bindvars[] = $instance_id;
+      $statuslist[]='active';
+      if ($add_exception_instances) $statuslist[]='exception';
+      if ($add_aborted_instances) $statuslist[]='aborted';
+      if ($add_completed_instances) $statuslist[]='completed';
+      $status_list = implode ($statuslist,',');
+      $mid .= " and (gi.wf_status in ('".implode ("','",$statuslist)."'))\n";
+    }
+    else
+    {
+      // collect NULL instances for start and standalone activities
+      $mid .= " and (gi.wf_instance_id is NULL)";
+    }
+    // add group mapping, warning groups and user can have the same id
+    $groups = galaxia_retrieve_user_groups($user);
+    $mid .= "\n and ( ((gur.wf_user=? and gur.wf_account_type='u')";
+    if (is_array($groups))
+    {
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+      $mid .= '	or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+    }
+    $mid .= ')';
+    $bindvars[] = $user;
+    // this collect non interactive instances we are owner of
+    $mid .= "\n or (gi.wf_owner=?)"; 
+    $bindvars[] = $user;
+    // and this collect completed/aborted instances when asked which haven't got any user anymore
+    if (($add_completed_instances) || ($add_aborted_instances))
+    {
+      $mid .= "\n or (gur.wf_user is NULL)";
+    }
+    $mid .= ")";
+    
+    // we need LEFT JOIN because aborted and completed instances are not showned 
+    // in instance_activities, they're only in instances
+    $query = 'select distinct(gi.wf_instance_id) as instance_id,
+                     gi.wf_status as instance_status,
+                     gi.wf_owner as owner,
+                     gi.wf_started as started,
+                     gi.wf_ended as ended,
+                     gi.wf_priority as priority,
+                     gi.wf_name as instance_name,
+                     gp.wf_name as process_name,
+                     gp.wf_version as process_version,
+                     gp.wf_p_id as process_id,
+                     gia.wf_user as user,
+                     ga.wf_activity_id as id,
+                     ga.wf_name as name,
+                     ga.wf_type as type,
+                     ga.wf_is_interactive as is_interactive,
+                     ga.wf_is_autorouted as is_autorouted,
+                     gia.wf_status as status';
+    if ($instance_id==0)
+    {//TODO: this gives all activities, rstrict to standalone and start
+      $query.=' from '.GALAXIA_TABLE_PREFIX.'activities ga
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'instance_activities gia ON ga.wf_activity_id=gia.wf_activity_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'instances gi ON gia.wf_activity_id = gi.wf_instance_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'activity_roles gar ON gia.wf_activity_id=gar.wf_activity_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'user_roles gur ON gur.wf_role_id=gar.wf_role_id
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'processes gp ON gp.wf_p_id=ga.wf_p_id '.$mid;
+    }
+    else
+    {
+      $query.=' from '.GALAXIA_TABLE_PREFIX.'instances gi
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'instance_activities gia ON gi.wf_instance_id=gia.wf_instance_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'activities ga ON gia.wf_activity_id = ga.wf_activity_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'activity_roles gar ON gia.wf_activity_id=gar.wf_activity_id
+                LEFT JOIN '.GALAXIA_TABLE_PREFIX.'user_roles gur ON gur.wf_role_id=gar.wf_role_id
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'processes gp ON gp.wf_p_id=gi.wf_p_id '.$mid;
+    }
+    $result = $this->query($query,$bindvars);
+    $retinst = Array();
+    $retacts = Array();
+    if (!!$result)
+    {
+      while($res = $result->fetchRow()) 
+      {
+        // Get instances per activity
+        if (count($retinst)==0)
+        {//the first time we retain instance data
+          $retinst[] = array_slice($res,0,-7);
+        }
+        $retacts[] = array_slice($res,10);
+      }
+    }
+    $retval = Array();
+    $retval["instance"] = $retinst{0};
+    $retval["activities"] = $retacts;
+    return $retval;
+  }
+  
+  /**
+   * Aborts an instance by terminating the instance with status 'aborted', and removes all running activities
+   * 
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */
+  function gui_abort_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    // start a transaction
+    $this->db->StartTrans();
+
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'abort')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $instance = &Factory::newInstance('Instance');
+      $instance->getInstance($instanceId);
+      if (!empty($instance->instanceId)) 
+      {
+          if (!($instance->abort()))
+          {
+            $this->error[] = ($instance->get_error());
+            $this->db->FailTrans();
+          }
+      }
+      unset($instance);
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+  
+  /**
+   * Exception handling for an instance, setting instance status to 'exception', but keeps all running activities.
+   * Instance can be resumed afterwards via gui_resume_instance()
+   * 
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */
+  function gui_exception_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    // start a transaction
+    $this->db->StartTrans();
+
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'exception')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $query = "update ".GALAXIA_TABLE_PREFIX."instances
+              set wf_status=?
+              where wf_instance_id=?";
+      $this->query($query, array('exception',$instanceId));
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+   * Resumes an instance by setting instance status from 'exception' back to 'active'
+   * 
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */  
+  function gui_resume_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    // start a transaction
+    $this->db->StartTrans();
+
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'resume')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $query = "update ".GALAXIA_TABLE_PREFIX."instances
+              set wf_status=?
+              where wf_instance_id=?";
+      $this->query($query, array('active',$instanceId));
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+   * Restarts an automated activity (non-interactive) which is still in running mode (maybe it failed)
+   * 
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */  
+  function gui_restart_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    //start a transaction
+    $this->db->StartTrans();
+    
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'restart')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $instance = &Factory::newInstance('Instance');
+      $instance->getInstance($instanceId);
+      // we force the execution of the activity
+      $result = $instance->executeAutomaticActivity($activityId, $instanceId);      
+      //TODO handle information returned in the sendAutorouted like in the completed activity template
+      //_debug_array($result);
+      $this->error[] = $instance->get_error();
+      unset($instance);
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+   * This function send a non autorouted activity i.e. take the transition which was not
+   * taken automatically. It can be as well used to walk a transition which failed the first time by the admin
+   * 
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */   
+  function gui_send_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    //start a transaction
+    $this->db->StartTrans();
+    
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'send')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $instance = &Factory::newInstance('Instance');
+      $instance->getInstance($instanceId);
+      // we force the continuation of the flow
+      $result = $instance->sendAutorouted($activityId,true);
+      //TODO handle information returned in the sendAutorouted like in the completed activity template
+      //_debug_array($result);
+      $this->error[] = $instance->get_error();
+      unset($instance);
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+
+  
+  /**
+   * Releases instances
+   *  
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */ 
+  function gui_release_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    // start a transaction
+    $this->db->StartTrans();
+
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'release')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $query = "update ".GALAXIA_TABLE_PREFIX."instance_activities
+                set wf_user = ? 
+                where wf_instance_id=? and wf_activity_id=?";
+      $this->query($query, array('*',$instanceId,$activityId));
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+  
+  /**
+   * Grabs instance for this activity and user if the security object agreed
+   *  
+   * @access public
+   * @param int $activityId  
+   * @param int $instanceId
+   * @return bool  
+   */  
+  function gui_grab_instance($activityId,$instanceId)
+  {
+    $user = galaxia_retrieve_running_user();
+    
+    // start a transaction
+    $this->db->StartTrans();
+    //this check will as well lock the table rows
+    if (!($this->wf_security->checkUserAction($activityId, $instanceId,'grab')))
+    {
+      $this->error[] = ($this->wf_security->get_error());
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //the security object said everything was fine
+      $query = "update ".GALAXIA_TABLE_PREFIX."instance_activities
+                set wf_user = ? 
+                where wf_instance_id=? and wf_activity_id=?";
+      $this->query($query, array($user,$instanceId,$activityId));
+    }
+    // perform commit (return true) or Rollback (return false) if Failtrans it will automatically rollback
+    return $this->db->CompleteTrans();
+  }
+
+  
+ 
+  /**
+  * Gets avaible actions for a given user on a given activity and a given instance assuming he already have access to it.
+  * To be able to decide this function needs the user id, instance_id and activity_id. 
+  * Optional arguments can be retrieved by internal queries BUT if you want this function to be fast and if you already 
+  * have theses datas you should give as well these fields (all or none)
+  * 
+  * @access public  
+  * @param int $user User id (required)
+  * @param int $instanceId Instance id (can be 0 if you have no instance - for start or standalone activities, required) 
+  * @param int $activityId Activity id (can be 0 if you have no activity - for aborted or completed instances, required)
+  * @param bool $readonly Role mode, if true this is a readonly access, if false it is a not-only-read access (required)
+  * @param int $pId Process id
+  * @param string $actType Activity type string ('split', 'activity', 'switch', etc.)
+  * @param string $actInteractive Activity interactivity ('y' or 'n')
+  * @param string $actAutorouted Activity routage ('y' or 'n')
+  * @param string $actStatus Activity status ('completed' or 'running')
+  * @param int $instanceOwner Instance owner user id
+  * @param string $instanceStatus Instance status ('completed', 'active', 'exception', 'aborted')
+  * @param mixed $currentUser Current user of the instance (user id or '*')
+  * @return array In this form:
+  * array('action name' => 'action description')
+  * 'actions names' are: 'grab', 'release', 'run', 'send', 'view', 'exception', 'resume' and 'monitor'
+  * Some config values can change theses rules but basically here they are:
+  * 	* 'grab'	: be the user of this activity. User has access to it and instance status is ok.
+  * 	* 'release'	: let * be the user of this activity. Must be the actual user or the owner of the instance.
+  * 	* 'run'		: run an associated form. This activity is interactive, user has access, instance status is ok.
+  * 	* 'send'	: send this instance, activity was non-autorouted and he has access and status is ok.
+  * 	* 'view'	: view the instance, activity ok, always avaible except for start or standalone act or processes with view activities.
+  *	* 'viewrun'	: view the instance in a view activity, need to have a role on this view activity
+  * 	* 'abort'	: abort an instance, ok when we are the user
+  * 	* 'exception' 	: set the instance status to exception, need to be the user 
+  * 	* 'resume'	: back to running when instance status was exception, need to be the user
+  * 	* 'monitor' 	: special user rights to administer the instance
+  * 'actions description' are translated explanations like 'release access to this activity'
+  * WARNING: this is a snapshot, the engine give you a snaphsots of the rights a user have on an instance-activity
+  * at a given time, this is not meaning theses rights will still be there when the user launch the action.
+  * You should absolutely use the GUI Object to execute theses actions (except monitor) and they could be rejected.
+  * WARNING: we do not check the user access rights. If you launch this function for a list of instances obtained via this
+  * GUI object theses access rights are allready checked.
+  */
+  function getUserActions($user, $instanceId, $activityId, $readonly, $pId=0, $actType='not_set', $actInteractive='not_set', $actAutorouted='not_set', $actStatus='not_set', $instanceOwner='not_set', $instanceStatus='not_set', $currentUser='not_set') 
+  {
+    $result= array();//returned array
+
+    //check if we have all the args and retrieve the ones whe did not have:
+    if ((!($pId)) ||
+      ($actType=='not_set') || 
+      ($actInteractive=='not_set') || 
+      ($actAutorouted=='not_set') || 
+      ($actStatus=='not_set') ||
+      ($instanceOwner=='not_set') ||
+      ($currentUser=='not_set') ||
+      ($instanceStatus=='not_set'))
+    {
+      // get process_id, type, interactivity, autorouting and act status and others for this instance
+      // we retrieve info even if ended or in exception or aborted instances
+      // and if $instanceId is 0 we get all standalone and start activities
+      //echo '<br> call gui_get_user_instance_status:'.$pId.':'.$actType.':'.$actInteractive.':'.$actAutorouted.':'.$actStatus.':'.$instanceOwner.':'.$currentUser.':'.$instanceStatus;
+      $array_info = $this->gui_get_user_instance_status($user,$instanceId,0,true,true,true);
+      
+      //now set our needed values
+      $instance = $array_info['instance'];
+      $pId = $instance['instance_id'];
+      $instanceStatus = $instance['instance_status'];
+      $instanceOwner = $instance['owner'];
+      
+      if (!((int)$activityId))
+      {
+        //we have no activity Id, like for aborted or completed instances, we set default values
+        $actType = '';
+        $actInteractive = 'n';
+        $actAutorouted = 'n';
+        $actstatus = '';
+        $currentUser = 0;
+      }
+      else
+      {
+        $find=false;
+        foreach ($array_info['activities'] as $activity)
+        {
+          //_debug_array($activity);
+          //echo "<br> ==>".$activity['id']." : ".$activityId;
+          if ((int)$activity['id']==(int)$activityId)
+          {
+            $actType = $activity['type'];
+            $actInteractive = $activity['is_interactive'];
+            $actAutorouted = $activity['is_autorouted'];
+            $actstatus = $activity['status'];
+            $currentUser = $activity['user'];
+            $find = true;
+            break;
+          }
+        }
+        //if the activity_id can't be find we return empty actions
+        if (!($find))
+        {
+          return array();
+        }
+      }
+    }
+    
+    //now use the security object to get actions avaible, this object know the rules
+    $view_activity = $this->gui_get_process_view_activity($pId);
+    $result =& $this->wf_security->getUserActions($user, $instanceId, $activityId, $readonly, $pId, $actType, $actInteractive, $actAutorouted, $actStatus, $instanceOwner, $instanceStatus, $currentUser, $view_activity);
+    return $result;
+  }
+
+  
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessMonitor/ProcessMonitor.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessMonitor/ProcessMonitor.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessMonitor/ProcessMonitor.php	(revision 2372)
@@ -0,0 +1,745 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+
+/**
+ * Provides methods for use in typical monitoring scripts, where the first part are methods for cleaning up instances and workitems associated with a process
+ * and the second, methods to obtains information about the actual state or histroy of the process
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class ProcessMonitor extends Base 
+{
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object ProcessMonitor
+   * @access public
+   */
+  function ProcessMonitor()
+  {
+    $this->child_name = 'ProcessMonitor';
+    parent::Base();
+    // check the the actual user can really do this
+    if ( !(galaxia_user_can_monitor()))
+    {
+      unset($this);
+      galaxia_show_error('forbidden access to ProcessMonitor object');
+    }
+  }
+
+  /**
+   * Gets statistics about all processes handled by the engine
+   * 
+   * @return array Resulting array has the following pairs of keys and values: 
+   * [active_processes] => number, [processes] => number (total number of processes), [running_processes] => number, 
+   * [active_instances] => number, [completed_instances] => number, [exception_instances] => number, [aborted_instances] => number
+   * @access public
+   */
+  function monitor_stats() {
+    $res = Array();
+    $res['active_processes'] = $this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."processes` where `wf_is_active`=?",array('y'));
+    $res['processes'] = $this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."processes`");
+    $result = $this->query("select distinct(`wf_p_id`) from `".GALAXIA_TABLE_PREFIX."instances` where `wf_status`=?",array('active'));
+    $res['running_processes'] = $result->numRows();
+    // get the number of instances per status
+    $query = "select wf_status, count(*) as num_instances from ".GALAXIA_TABLE_PREFIX."instances group by wf_status";
+    $result = $this->query($query);
+    $status = array();
+    while($info = $result->fetchRow()) {
+      $status[$info['wf_status']] = $info['num_instances'];
+    }
+    $res['active_instances'] = isset($status['active']) ? $status['active'] : 0;
+    $res['completed_instances'] = isset($status['completed']) ? $status['completed'] : 0;
+    $res['exception_instances'] = isset($status['exception']) ? $status['exception'] : 0;
+    $res['aborted_instances'] = isset($status['aborted']) ? $status['aborted'] : 0;
+    return $res;
+  }
+
+  /**
+   * @deprecated
+   */
+  function update_instance_status($iid,$status) {
+    return;
+    $query = "update `".GALAXIA_TABLE_PREFIX."instances` set `wf_status`=? where `wf_instance_id`=?";
+    $this->query($query,array($status,$iid));    
+  }
+  
+  
+  /**
+   * @deprecated
+   */
+  function update_instance_activity_status($iid,$activityId,$status) {
+    return;
+    $query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `wf_status`=? where `wf_instance_id`=? and `wf_activity_id`=?";
+    $this->query($query,array($status,$iid,$activityId));
+  }
+
+  /**
+  * Removes instance along with its workitems (history), current activities and properties altogether
+  * 
+  * @param int $iid Instance id
+  * @return bool
+  * @access public
+  */
+  function remove_instance($iid) 
+  {
+    // start a transaction
+    $this->db->StartTrans();
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."workitems` where `wf_instance_id`=?";
+    $this->query($query,array($iid));
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `wf_instance_id`=?";
+    $this->query($query,array($iid));
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."instances` where `wf_instance_id`=?";
+    $this->query($query,array($iid));
+    // perform commit (return true) or Rollback (return false)
+    return $this->db->CompleteTrans();
+
+  }
+  
+  /**
+  * Removes aborted instances along with workitems (history), 
+  * you can limit this behaviour to a single process by specifying its process id
+  * 
+  * @param int $process_id Providable process id to limit this function range to only one process
+  * @return bool
+  * @access public
+  */
+  function remove_aborted($pId=0) 
+  {
+    // check the the actual user can really do this
+    if ( !((galaxia_user_can_clean_instances()) || (galaxia_user_can_clean_aborted_instances())) )
+    {
+      $this->error[] = tra('user is not authorized to delete aborted instances');
+      return false;
+    }
+    if (!($pId))
+    {
+      $whereand = '';
+      $bindvars = array('aborted');
+    }
+    else
+    {
+      $whereand = 'and wf_p_id = ?';
+      $bindvars = array('aborted', $pId);
+    }
+    $query="select `wf_instance_id` from `".GALAXIA_TABLE_PREFIX."instances` where `wf_status`=?".$whereand;
+    // start a transaction
+    $this->db->StartTrans();
+    $result = $this->query($query,$bindvars);
+    while($res = $result->fetchRow()) 
+    {  
+      $iid = $res['wf_instance_id'];
+      $query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `wf_instance_id`=?";
+      $this->query($query,array($iid));
+      $query = "delete from `".GALAXIA_TABLE_PREFIX."workitems` where `wf_instance_id`=?";
+      $this->query($query,array($iid));  
+    }
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."instances` where `wf_status`=?".$whereand;
+    $this->query($query,$bindvars);
+    // perform commit (return true) or Rollback (return false)
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+  * Provided a process, it removes instances, workitems (history) and activities current running associated with these instances
+  *  
+  * @param int $pId Process id whose contents will be erased
+  * @return bool
+  * @access public 
+  */
+  function remove_all($pId) {
+    // check the the actual user can really do this
+    if ( !(galaxia_user_can_clean_instances()) )
+    {
+      $this->error[] = tra('user is not authorized to delete instances');
+      return false;
+    }
+    $query="select `wf_instance_id` from `".GALAXIA_TABLE_PREFIX."instances` where `wf_p_id`=?";
+    // start a transaction
+    $this->db->StartTrans();
+    $result = $this->query($query,array($pId));
+    while($res = $result->fetchRow()) {
+      $iid = $res['wf_instance_id'];
+      $query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `wf_instance_id`=?";
+      $this->query($query,array($iid));
+      $query = "delete from `".GALAXIA_TABLE_PREFIX."workitems` where `wf_instance_id`=?";
+      $this->query($query,array($iid));  
+    }
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."instances` where `wf_p_id`=?";
+    $this->query($query,array($pId));
+    // perform commit (return true) or Rollback (return false)
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+  * Lists all processes and return stats
+  * 
+  * @param int $offset Starting row number to return
+  * @param int $maxRecords Max number of records to return
+  * @param string $sort_mode Sort order
+  * @param string $find Search for in process name or process description
+  * @param string $where Condition query, be carefull with this string, read the query before
+  * @param bool $add_stats True by default, by setting it to false you wont get the statistics associated with
+  * the processes, this could be helpfull for gui listing on selects, to avoid (a big number of) unnecessary queries
+  * @return array Associative, with the number of records for the 'cant' key and an array of process stats for the 
+  * 'data' key. each row follows this form: key : process_id, value : an array of infos: 
+  * keys are : wf_p_id, wf_name, wf_is_valid, wf_is_active, wf_version, wf_description, wf_last_modif, 
+  * and wf_normalized_name for the 'classical part' and for the 'stats part' whe have: active_instances, 
+  * exception_instances, completed_instances, aborted_instances, all_instances, activities
+  * @access public
+  */
+  function monitor_list_processes($offset,$maxRecords,$sort_mode,$find,$where='', $add_stats=true) 
+  {
+  
+    $sort_mode = $this->convert_sortmode($sort_mode);
+    if($find) {
+      $findesc = '%'.$find.'%';
+      $mid=" where ((wf_name like ?) or (wf_description like ?))";
+      $bindvars = array($findesc,$findesc);
+    } else {
+      $mid="";
+      $bindvars = array();
+    }
+    if($where) {
+      if($mid) {
+        $mid.= " and ($where) ";
+      } else {
+        $mid.= " where ($where) ";
+      }
+    }
+    // get the requested processes
+    $query = "select * from ".GALAXIA_TABLE_PREFIX."processes $mid order by $sort_mode";
+    $query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."processes $mid";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset);
+    $cant = $this->getOne($query_cant,$bindvars);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $pId = $res['wf_p_id'];
+      // Number of active instances
+      $res['active_instances'] = 0;
+      // Number of exception instances
+      $res['exception_instances'] = 0;
+      // Number of completed instances
+      $res['completed_instances'] = 0;
+      // Number of aborted instances
+      $res['aborted_instances'] = 0;
+      $res['all_instances'] = 0;
+      // Number of activities
+      $res['activities'] = 0;
+      $ret[$pId] = $res;
+    }
+    if (count($ret) < 1) {
+      $retval = Array();
+      $retval["data"] = $ret;
+      $retval["cant"] = $cant;
+      return $retval;
+    }
+    if ($add_stats)
+    {
+      // get number of instances and timing statistics per process and status
+      $query = "select wf_p_id, wf_status, count(*) as num_instances,
+                min(wf_ended - wf_started) as min_time, avg(wf_ended - wf_started) as avg_time, max(wf_ended - wf_started) as max_time
+                from ".GALAXIA_TABLE_PREFIX."instances where wf_p_id in (" . join(', ', array_keys($ret)) . ") group by wf_p_id, wf_status";
+      $result = $this->query($query);
+      while($res = $result->fetchRow()) {
+        $pId = $res['wf_p_id'];
+        if (!isset($ret[$pId])) continue;
+        switch ($res['wf_status']) {
+          case 'active':
+            $ret[$pId]['active_instances'] = $res['num_instances'];
+            $ret[$pId]['all_instances'] += $res['num_instances'];
+            break;
+          case 'completed':
+            $ret[$pId]['completed_instances'] = $res['num_instances'];
+            $ret[$pId]['all_instances'] += $res['num_instances'];
+            $ret[$pId]['duration'] = array('min' => $res['min_time'], 'avg' => $res['avg_time'], 'max' => $res['max_time']);
+            break;
+          case 'exception':
+            $ret[$pId]['exception_instances'] = $res['num_instances'];
+            $ret[$pId]['all_instances'] += $res['num_instances'];
+            break;
+          case 'aborted':
+            $ret[$pId]['aborted_instances'] = $res['num_instances'];
+            $ret[$pId]['all_instances'] += $res['num_instances'];
+            break;
+        }
+      }
+      // get number of activities per process
+      $query = "select wf_p_id, count(*) as num_activities
+                from ".GALAXIA_TABLE_PREFIX."activities
+                where wf_p_id in (" . join(', ', array_keys($ret)) . ")
+                group by wf_p_id";
+      $result = $this->query($query);
+      while($res = $result->fetchRow()) {
+        $pId = $res['wf_p_id'];
+        if (!isset($ret[$pId])) continue;
+        $ret[$pId]['activities'] = $res['num_activities'];
+      }
+    }
+    $retval = Array();
+    $retval["data"] = $ret;
+    $retval["cant"] = $cant;
+    return $retval;
+  }
+
+  /**
+  * Lists all activities and return stats
+  * 
+  * @param int $offset First row number to return
+  * @param int $maxRecords Maximum number of records to return
+  * @param string $sort_mode Sort order
+  * @param string $find Search for in activity name or activity description
+  * @param string $where Ads to the query, be carefull with this string, read the query before
+  * @param bool $add_stats True by default, by setting it to false you wont get the statistics associated with
+  * the activities, this could be helpfull for gui listing on selects, to avoid (a big number of) unnecessary queries
+  * @return array Associative, with the number of records for the 'cant' key and an array of process stats for the 
+  * 'data' key. each row is of this form: key : activity_id, value : an array of infos: keys are : wf_procname, wf_version, 
+  * wf_proc_normalized_name, wf_activity_id, wf_name, wf_normalized_name, wf_p_id, wf_type, wf_is_autorouted, wf_flow_num, 
+  * wf_is_interactive, wf_last_modif, wf_description, wf_default_user and for the stats part: active_instances, completed_instances, 
+  * aborted_instances, exception_instances, act_running_instances, act_completed_instances
+  * @access public
+  */
+  function monitor_list_activities($offset,$maxRecords,$sort_mode,$find,$where='', $add_stats=true) 
+  {
+  
+    $sort_mode = $this->convert_sortmode($sort_mode);
+    if($find) {
+      $findesc = '%'.$find.'%';
+      $mid=" where ((ga.wf_name like ?) or (ga.wf_description like ?))";
+      $bindvars = array($findesc,$findesc);
+    } else {
+      $mid="";
+      $bindvars = array();
+    }
+    if($where) {
+      $where = preg_replace('/pId/', 'ga.wf_p_id', $where);
+      if($mid) {
+        $mid.= " and ($where) ";
+      } else {
+        $mid.= " where ($where) ";
+      }
+    }
+    $query = "select gp.`wf_name` as `wf_procname`, gp.`wf_version`, gp.wf_normalized_name as wf_proc_normalized_name, ga.*
+              from ".GALAXIA_TABLE_PREFIX."activities ga
+                left join ".GALAXIA_TABLE_PREFIX."processes gp on gp.wf_p_id=ga.wf_p_id
+              $mid order by $sort_mode";
+    $query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."activities ga $mid";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset);
+    $cant = $this->getOne($query_cant,$bindvars);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      // Number of active instances
+      $aid = $res['wf_activity_id'];
+      if ($add_stats)
+      {
+        $res['active_instances']=$this->getOne("select count(gi.wf_instance_id) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.wf_instance_id=gia.wf_instance_id and gia.wf_activity_id=$aid and gi.wf_status='active' and wf_p_id=".$res['wf_p_id']);
+      // activities of completed instances are all removed from the instance_activities table for some reason, so we need to look at workitems
+        $res['completed_instances']=$this->getOne("select count(distinct gi.wf_instance_id) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."workitems gw where gi.wf_instance_id=gw.wf_instance_id and gw.wf_activity_id=$aid and gi.wf_status='completed' and wf_p_id=".$res['wf_p_id']);
+      // activities of aborted instances are all removed from the instance_activities table for some reason, so we need to look at workitems
+        $res['aborted_instances']=$this->getOne("select count(distinct gi.wf_instance_id) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."workitems gw where gi.wf_instance_id=gw.wf_instance_id and gw.wf_activity_id=$aid and gi.wf_status='aborted' and wf_p_id=".$res['wf_p_id']);
+        $res['exception_instances']=$this->getOne("select count(gi.wf_instance_id) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.wf_instance_id=gia.wf_instance_id and gia.wf_activity_id=$aid and gi.wf_status='exception' and wf_p_id=".$res['wf_p_id']);
+        $res['act_running_instances']=$this->getOne("select count(gi.wf_instance_id) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.wf_instance_id=gia.wf_instance_id and gia.wf_activity_id=$aid and gia.wf_status='running' and wf_p_id=".$res['wf_p_id']);      
+      // completed activities are removed from the instance_activities table unless they're part of a split for some reason, so this won't work
+      //  $res['act_completed_instances']=$this->getOne("select count(gi.wf_instance_id) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.wf_instance_id=gia.wf_instance_id and gia.activityId=$aid and gia.status='completed' and pId=".$res['pId']);      
+        $res['act_completed_instances'] = 0;
+      }
+      $ret[$aid] = $res;
+    }
+    if (count($ret) < 1) {
+      $retval = Array();
+      $retval["data"] = $ret;
+      $retval["cant"] = $cant;
+      return $retval;
+    }
+    if ($add_stats)
+    {
+      $query = "select wf_activity_id, count(distinct wf_instance_id) as num_instances, min(wf_ended - wf_started) as min_time, avg(wf_ended - wf_started) as avg_time, max(wf_ended - wf_started) as max_time
+                from ".GALAXIA_TABLE_PREFIX."workitems
+                where wf_activity_id in (" . join(', ', array_keys($ret)) . ")
+                group by wf_activity_id";
+      $result = $this->query($query);
+      while($res = $result->fetchRow()) {
+        // Number of active instances
+        $aid = $res['wf_activity_id'];
+        if (!isset($ret[$aid])) continue;
+        $ret[$aid]['act_completed_instances'] = $res['num_instances'] - $ret[$aid]['aborted_instances'];
+        $ret[$aid]['duration'] = array('min' => $res['min_time'], 'avg' => $res['avg_time'], 'max' => $res['max_time']);
+      }
+    }
+    $retval = Array();
+    $retval["data"] = $ret;
+    $retval["cant"] = $cant;
+    return $retval;
+  }
+
+ /**
+  * Lists all instances and return stats
+  * 
+  * @param int $offset First row number to return
+  * @param int $maxRecords Maximum number of records to return
+  * @param string $sort_mode Sort order
+  * @param string $find Search for in instance name or instance description
+  * @param string $where Ads to the query, be carefull with this string, read the query before
+  * @return array Associative
+  * @access public
+  */
+  function monitor_list_instances($offset,$maxRecords,$sort_mode,$find,$where='') 
+  {
+    $wherevars = array();
+    if($find) {
+      $findesc = $this->qstr('%'.$find.'%');
+      $mid=' where ((`wf_properties` like ?) or (gi.`wf_name` like ?)
+        or (ga.`wf_name` like ?) or (gp.`wf_name` like ?))';
+        $wherevars[] = $findesc;
+        $wherevars[] = $findesc;
+        $wherevars[] = $findesc;
+        $wherevars[] = $findesc;
+    } else {
+      $mid='';
+    }
+    if($where) {
+      if($mid) {
+        $mid.= " and ($where) ";
+      } else {
+        $mid.= " where ($where) ";
+      }
+    }
+
+    $query = 'select gp.wf_p_id, ga.wf_is_interactive,gp.wf_normalized_name as wf_proc_normalized_name, gi.wf_owner, gp.wf_name as wf_procname, gp.wf_version, ga.wf_type,';
+    $query.= ' ga.wf_activity_id, ga.wf_name as wf_activity_name, gi.wf_instance_id, gi.wf_name as wf_instance_name, gi.wf_priority, gi.wf_status, gia.wf_activity_id, gia.wf_user, gia.wf_started as wf_act_started, gi.wf_started, gi.wf_ended, gia.wf_status as wf_act_status ';
+    $query.= ' from `'.GALAXIA_TABLE_PREFIX.'instances` gi LEFT JOIN `'.GALAXIA_TABLE_PREFIX.'instance_activities` gia ON gi.`wf_instance_id`=gia.`wf_instance_id` ';
+    $query.= 'LEFT JOIN `'.GALAXIA_TABLE_PREFIX.'activities` ga ON gia.`wf_activity_id` = ga.`wf_activity_id` ';
+    $query.= 'LEFT JOIN `'.GALAXIA_TABLE_PREFIX."processes` gp ON gp.`wf_p_id`=gi.`wf_p_id` $mid";
+
+    $query_cant = 'select count(*) from `'.GALAXIA_TABLE_PREFIX.'instances` gi LEFT JOIN `'.GALAXIA_TABLE_PREFIX.'instance_activities` gia ON gi.`wf_instance_id`=gia.`wf_instance_id` ';
+    $query_cant.= 'LEFT JOIN `'.GALAXIA_TABLE_PREFIX.'activities` ga ON gia.`wf_activity_id` = ga.`wf_activity_id` LEFT JOIN `'.GALAXIA_TABLE_PREFIX."processes` gp ON gp.`wf_p_id`=gi.`wf_p_id` $mid";
+    $result = $this->query($query,$wherevars,$maxRecords,$offset,true,$this->convert_sortmode($sort_mode));
+	$cant = $this->getOne($query_cant,$wherevars);
+
+    $ret = Array();
+	while($res = $result->fetchRow())
+      $ret[] = $res;
+
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = $cant;
+    return $retval;
+  }
+
+ /**
+  * Lists completed instances and return stats
+  *
+  * @param int $offset First row number to return
+  * @param int $maxRecords Maximum number of records to return
+  * @param string $sort_mode Sort order
+  * @param string $find Search for in instance name or instance description
+  * @param string $where Ads to the query, be carefull with this string, read the query before
+  * @return array Associative
+  * @access public
+  */
+  function monitor_list_completed_instances($offset,$maxRecords,$sort_mode,$find,$where='') 
+  {
+    $wherevars = array();
+    $mid = " where (gi.wf_status IN ('completed', 'aborted'))";
+    if($find)
+    {
+      $findesc = $this->qstr('%'.$find.'%');
+      $mid=' AND ((gi.`wf_name` LIKE ?)
+        OR (gp.`wf_name` LIKE ?))';
+      $wherevars[] = $findesc;
+      $wherevars[] = $findesc;
+      $wherevars[] = $findesc;
+    }
+
+    if($where)
+    {
+      if($mid)
+        $mid.= " and ($where) ";
+      else
+        $mid.= " where ($where) ";
+    }
+
+    $query = 'select gp.wf_p_id, gp.wf_normalized_name as wf_proc_normalized_name, gi.wf_owner, gp.wf_name as wf_procname, gp.wf_version,';
+    $query.= ' gi.wf_instance_id, gi.wf_name as wf_instance_name, gi.wf_priority, gi.wf_status, gi.wf_started, gi.wf_ended ';
+    $query.= ' from `'.GALAXIA_TABLE_PREFIX.'instances` gi LEFT JOIN `'.GALAXIA_TABLE_PREFIX."processes` gp ON gp.`wf_p_id`=gi.`wf_p_id` $mid";
+
+    $query_cant = 'select count(*) from `'.GALAXIA_TABLE_PREFIX.'instances` gi LEFT JOIN `'.GALAXIA_TABLE_PREFIX."processes` gp ON gp.`wf_p_id`=gi.`wf_p_id` $mid";
+    $result = $this->query($query,$wherevars,$maxRecords,$offset,true,$this->convert_sortmode($sort_mode));
+    $cant = $this->getOne($query_cant,$wherevars);
+
+    $ret = Array();
+    while($res = $result->fetchRow())
+      $ret[] = $res;
+
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = $cant;
+    return $retval;
+  }
+  
+ /**
+  * Lists all processes
+  * 
+  * @param string $sort_mode Sort order
+  * @param string $where Ads to the query, be carefull with this string, read the query before
+  * @return array Associative
+  * @access public
+  */
+  function monitor_list_all_processes($sort_mode = 'wf_name_asc', $where = '') {
+    if (!empty($where)) {
+      $where = " where ($where) ";
+    }
+    $query = "select `wf_name`,`wf_version`,`wf_p_id` from `".GALAXIA_TABLE_PREFIX."processes` $where order by ".$this->convert_sortmode($sort_mode);
+    $result = $this->query($query);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $pId = $res['wf_p_id'];
+      $ret[$pId] = $res;
+    }
+    return $ret;
+  }
+  
+ /**
+  * Lists all activities
+  * 
+  * @param string $sort_mode Sort order
+  * @param string $where Ads to the query, be carefull with this string, read the query before
+  * @return array Associative
+  * @access public
+  */
+  function monitor_list_all_activities($sort_mode = 'wf_name_asc', $where = '') {
+    if (!empty($where)) {
+      $where = " where ($where) ";
+    }
+    $query = "select `wf_name`,`wf_activity_id` from `".GALAXIA_TABLE_PREFIX."activities` $where order by ".$this->convert_sortmode($sort_mode);
+    $result = $this->query($query);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $aid = $res['wf_activity_id'];
+      $ret[$aid] = $res;
+    }
+    return $ret;
+  }
+  
+  /**
+   * Lists instances status types in the database
+   * 
+   * @return array Associative
+   * @access public
+   */ 
+  function monitor_list_statuses() {
+    $query = "select distinct(`wf_status`) from `".GALAXIA_TABLE_PREFIX."instances`";
+    $result = $this->query($query);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res['wf_status'];
+    }
+    return $ret;
+  }
+  
+  /**
+   * List users associated with instances available in the current database
+   * 
+   * @return array Associative
+   * @access public
+   */  
+  function monitor_list_users($where = null, $bindVars = null)
+  {
+    $query = "select distinct(`wf_user`) from `".GALAXIA_TABLE_PREFIX."instance_activities`";
+    if (!is_null($where))
+      $query .= ' WHERE ' . $where;
+    if (!is_null($bindVars) && is_array($bindVars))
+      $result = $this->query($query);
+    else
+      $result = $this->query($query, $bindVars);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res['wf_user'];
+    }
+    return $ret;
+  }
+
+  /**
+   * List users associated with workitems available in the current database
+   * 
+   * @return array Associative
+   * @access public
+   */  
+  function monitor_list_wi_users() {
+    $query = "select distinct(`wf_user`) from `".GALAXIA_TABLE_PREFIX."workitems`";
+    $result = $this->query($query);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res['wf_user'];
+    }
+    return $ret;
+  }
+
+  /**
+   * List instance owners available in the current database
+   * 
+   * @return array Associative
+   * @access public
+   */    
+  function monitor_list_owners() {
+    $query = "select distinct(`wf_owner`) from `".GALAXIA_TABLE_PREFIX."instances`";
+    $result = $this->query($query);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res['wf_owner'];
+    }
+    return $ret;
+  }
+  
+  /**
+   * List activity types available in the current database
+   * 
+   * @return array Associative
+   * @access public
+   */
+  function monitor_list_activity_types() {
+    $query = "select distinct(`wf_type`) from `".GALAXIA_TABLE_PREFIX."activities`";
+    $result = $this->query($query);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res['wf_type'];
+    }
+    return $ret;  
+  }
+  
+  /**
+   * Gets workitem information
+   * 
+   * @param int $itemId Workitem id
+   * @return array Associative
+   * @access public
+   */  
+  function monitor_get_workitem($itemId) {
+    $query = "select gw.`wf_order_id`,ga.`wf_name`,ga.`wf_type`,ga.`wf_is_interactive`,gp.`wf_name` as `wf_wf_procname`,gp.`wf_version`,";
+    $query.= "gw.`wf_item_id`,gw.`wf_properties`,gw.`wf_user`,`wf_started`,`wf_ended`-`wf_started` as wf_duration ";
+    $query.= "from `".GALAXIA_TABLE_PREFIX."workitems` gw,`".GALAXIA_TABLE_PREFIX."activities` ga,`".GALAXIA_TABLE_PREFIX."processes` gp where ga.`wf_activity_id`=gw.`wf_activity_id` and ga.`wf_p_id`=gp.`wf_p_id` and `wf_item_id`=?";
+    $result = $this->query($query, array($itemId));
+    $res = $result->fetchRow();
+    $res['wf_properties'] = unserialize($res['wf_properties']);
+    return $res;
+  }
+
+  /**
+  * Gets workitems per instance
+  * 
+  * @param int $offset First row number to return
+  * @param int $maxRecords Maximum number of records to return
+  * @param string $sort_mode Sort order
+  * @param string $find Search for in instance name or instance description
+  * @param string $where Ads to the query, be carefull with this string, read the query before 
+  * @param array $wherevars Set of vars used in where clause
+  * @access public
+  * @return array 
+  */
+  function monitor_list_workitems($offset,$maxRecords,$sort_mode,$find,$where='',$wherevars=array()) {
+    $mid = '';
+    if ($where) {
+      $mid.= " and ($where) ";
+    }
+    if($find) {
+      $findesc = $this->qstr('%'.$find.'%');
+      $mid.=" and ((`wf_properties` like $findesc) or (gp.wf_name like $findesc) or (ga.wf_name like $findesc))";
+    }
+// TODO: retrieve instance status as well
+    $query = 'select wf_item_id,wf_ended-wf_started as wf_duration,ga.wf_is_interactive, ga.wf_type,gp.wf_name as wf_procname,gp.wf_version,gp.wf_normalized_name as wf_proc_normalized_name,ga.wf_name as wf_act_name,';
+    $query.= 'ga.wf_activity_id,wf_instance_id,wf_order_id,wf_properties,wf_started,wf_ended,wf_user';
+    $query.= ' from '.GALAXIA_TABLE_PREFIX.'workitems gw,'.GALAXIA_TABLE_PREFIX.'activities ga,'.GALAXIA_TABLE_PREFIX.'processes gp';
+    $query.= ' where gw.wf_activity_id=ga.wf_activity_id and ga.wf_p_id=gp.wf_p_id '.$mid.' order by '.$this->convert_sortmode($sort_mode);
+    $query_cant = "select count(*) from `".GALAXIA_TABLE_PREFIX."workitems` gw,`".GALAXIA_TABLE_PREFIX."activities` ga,`".GALAXIA_TABLE_PREFIX."processes` gp where gw.`wf_activity_id`=ga.`wf_activity_id` and ga.`wf_p_id`=gp.`wf_p_id` $mid";
+    $result = $this->query($query,$wherevars,$maxRecords,$offset);
+    $cant = $this->getOne($query_cant,$wherevars);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $itemId = $res['wf_item_id'];
+      $ret[$itemId] = $res;
+    }
+    $retval = Array();
+    $retval["data"] = $ret;
+    $retval["cant"] = $cant;
+    return $retval;
+  }
+
+/**
+  * Stats Instances per month 
+  * 
+  * @param integer $pid pid 
+  * @param integer $months number of months
+  * @access public
+  * @return array 
+  */
+  function stats_instances_per_month($pid, $months = 12)
+  {
+    list($year, $month) = explode('-', date('Y-m'));
+    $output = array();
+    for ($i = $months - 1; $i >= 0; $i--)
+      $output[date('Y-m', mktime(0, 0, 0, $month - $i, 1, $year))] = 0;
+    $query = "SELECT wf_started FROM " . GALAXIA_TABLE_PREFIX . "instances WHERE (wf_started > ?) AND (wf_p_id = ?)";
+    $result = $this->query($query, array(mktime(0, 0, 0, $month - ($months - 1), 1, $year), $pid));
+    while($res = $result->fetchRow())
+      $output[date('Y-m', $res['wf_started'])]++;
+
+    return $output;
+  }
+
+/**
+  * Stats activities instances
+  * 
+  * @param integer $pid pid 
+  * @access public
+  * @return array 
+  */
+  function stats_instances_activities($pid)
+  {
+    $output = array();
+    $query = "SELECT ga.wf_name, COUNT(*) AS count FROM " . GALAXIA_TABLE_PREFIX . "instance_activities gia, " . GALAXIA_TABLE_PREFIX . "activities ga WHERE (gia.wf_activity_id = ga.wf_activity_id) AND (ga.wf_p_id = ?) GROUP BY ga.wf_name ORDER BY ga.wf_name";
+    $result = $this->query($query, array($pid));
+    while($res = $result->fetchRow())
+      $output[] = $res;
+
+    return $output;
+  }
+
+/**
+  * Stats instances per user 
+  * 
+  * @param integer $pid pid 
+  * @param integer $users
+  * @access public
+  * @return array 
+  */
+  function stats_instances_per_user($pid, $users = 10)
+  {
+    $output = array();
+    $query = "SELECT gia.wf_user, COUNT(*) AS count FROM egw_wf_instance_activities gia, egw_wf_activities ga WHERE (ga.wf_activity_id = gia.wf_activity_id) AND (gia.wf_user <> '*') AND (ga.wf_p_id = ?) GROUP BY gia.wf_user ORDER BY count DESC";
+    $result = $this->query($query, array($pid), $users);
+    while($res = $result->fetchRow())
+      $output[$res['wf_user']] = $res['count'];
+
+    return $output;
+  }
+/**
+  * Stats instances per status
+  * 
+  * @param integer $pid pid 
+  * @access public
+  * @return array 
+  */
+  function stats_instances_per_status($pid)
+  {
+    $output = array();
+    $query = "SELECT wf_status, COUNT(*) AS count FROM egw_wf_instances WHERE (wf_p_id = ?) AND (wf_status <> 'completed') GROUP BY wf_status";
+    $result = $this->query($query, array($pid));
+    while($res = $result->fetchRow())
+      $output[$res['wf_status']] = $res['count'];
+
+    return $output;
+  }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/common/Base.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/common/Base.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/common/Base.php	(revision 2372)
@@ -0,0 +1,378 @@
+<?php
+/**
+ * This class is derived by all the API classes so they get the
+ * database connection and the database methods.
+ *
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class Base {
+	/**
+	 * @var object $db Database abstraction object used to access the database
+	 * @access public
+	 */
+	var $db;
+	/**
+	 * @var int	$num_queries Debugging var
+	 * @access private
+	 */
+  	var $num_queries = 0;
+	/**
+	 * @var int	$num_queries_total Debugging var
+	 * @access private
+	 */
+  	var $num_queries_total = 0;
+	/**
+	 * @var array  $error Error messages
+	 * @access public
+	 */
+  	var $error= Array();
+  	/**
+  	 * @var array $warning Warning messages
+  	 * @access public
+  	 */
+  	var $warning = array();
+  	/**
+  	 * @var string $child_name Name of the current object
+  	 * @access public
+  	 */
+  	var $child_name = 'Base';
+
+	/**
+	 * @var object $db_shared_obj The database abstraction object shared between
+	 *						      all instances of this class.
+	 * @acess private
+	 * @static
+	 */
+	private static $db_shared_obj = null;
+
+  /**
+   * Constructor receiving a database abstraction object
+   * @package Galaxia
+   * @param object &$db ADOdb
+   * @return object Base instance
+   * @access public
+   */
+  function Base()
+  {
+  	/**
+	 * New Stuff!
+	 * We decided to get here the database object. In a recent past,
+	 * all the classes that specialize this one passed a db object.
+	 * Now, to simplify and save memory, we store the database object
+	 * into a single and static atribute shared among each instance
+	 * of this class.
+	 *
+	 * To prevent to modify all sub-classes to use "self::$db" instead
+	 * of "this->db", we made a very tiny workaround here. In the first
+	 * instantiation of this class, we instantiate the database object
+	 * and store it into 'self::$db_shared_obj'. Any subsequent
+	 * instantiations will just point to the static one.
+	 */
+	if (!self::$db_shared_obj)
+		self::$db_shared_obj = &Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
+
+	$this->db = &self::$db_shared_obj;
+
+
+    if(!$this->db) {
+      die('Invalid db object passed to '.$this->child_name.' constructor');
+    }
+    //Force transactionnal mysql (Innodb) -> mysqlt
+    if ($this->db->databaseType=='mysql')
+    {
+    	$GLOBALS['phpgw']->db->disconnect();
+    	$this->db = $GLOBALS['phpgw']->db->connect(
+			$GLOBALS['phpgw_info']['server']['db_name'],
+			$GLOBALS['phpgw_info']['server']['db_host'],
+			$GLOBALS['phpgw_info']['server']['db_port'],
+			$GLOBALS['phpgw_info']['server']['db_user'],
+			$GLOBALS['phpgw_info']['server']['db_pass'],
+			'mysqlt'
+		);
+    }
+  }
+
+  /**
+   * Gets errors recorded by this object
+   * Always call this function after failed operations on a workflow object to obtain messages
+   *
+   * @param bool $as_array if true the result will be send as an array of errors or an empty array. Else, if you do not give any parameter
+   * or give a false parameter you will obtain a single string which can be empty or will contain error messages with <br /> html tags
+   * @param bool $debug is false by default, if true you wil obtain more messages
+   * @param string $prefix string appended to the debug message
+   * @return mixed Error and debug messages or an array of theses messages and empty the error messages
+   * @access public
+   */
+  function get_error($as_array=false, $debug=false, $prefix='')
+  {
+    //collect errors from used objects
+    $this->collect_errors($debug, $prefix.$this->child_name.'::');
+    if ($as_array)
+    {
+      $result = $this->error;
+      $this->error= Array();
+      return $result;
+    }
+    $result_str = implode('<br />',array_filter($this->error));
+    $this->error= Array();
+    return $result_str;
+  }
+
+  /**
+   * Gets warnings recorded by this object
+   *
+   * @param bool $as_array if true the result will be send as an array of warnings or an empty array. Else, if you do not give any parameter
+   * or give a false parameter you will obtain a single string which can be empty or will contain warning messages with <br /> html tags
+   * @return mixed Warning messages or an array of theses messages and empty the warning messages
+   * @access public
+   */
+  function get_warning($as_array=false)
+  {
+    if ($as_array)
+    {
+      $result = $this->warning;
+      $this->warning= Array();
+      return $result;
+    }
+    $result_str = implode('<br />',array_filter($this->warning));
+    $this->warning= Array();
+    return $result_str;
+  }
+
+  /**
+   * Collect errors from all linked objects which could have been used by this object
+   * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
+   *
+   * @param bool $debug is false by default, if true debug messages can be added to 'normal' messages
+   * @param string $prefix is a string appended to the debug message
+   * @abstract
+   * @access public
+   * @return void
+   */
+  function collect_errors($debug=false, $prefix = '')
+  {
+  	if ($debug)
+  	{
+  		$this->num_queries_total += $this->num_queries;
+  		$this->error[] = $prefix.': number of queries: new='.$this->num_queries.'/ total='.$this->num_queries_total;
+  		$this->num_queries = 0;
+	}
+  }
+
+	/**
+	 * Performs a query on the AdoDB database object
+	 *
+	 * @param string $query sql query, parameters should be replaced with ?
+	 * @param array $values array containing the parameters (going in the ?), use it to avoid security problems. If
+	 * one of theses values is an array it will be serialized and encoded in Base64
+	 * @param int $numrows maximum number of rows to return
+	 * @param int $offset starting row number
+	 * @param bool $reporterrors is true by default, if false no warning will be generated in the php log
+	 * @param string $sort is the sort sql string for the query (without the "order by ")
+	 * @param bool $bulk is false by default, if true the $values array parameters could contain arrays vars for bulk statement
+	 * (see ADOdb help) theses arrays wont be serialized and encoded in Base64 like current arrays parameters,
+	 * it will be checked for security reasons before being appended to the sql
+	 * @return mixed false if something went wrong or the resulting recordset array if it was ok
+	 * @access public
+	 */
+	function query($query, $values = null, $numrows = -1, $offset = -1, $reporterrors = true, $sort='', $bulk=false)
+	{
+		//clean the parameters
+		$clean_values = Array();
+		if (!($values===null))
+		{
+			if (!(is_array($values)))
+			{
+				$values= array($values);
+			}
+			foreach($values as $value)
+			{
+				$clean_values[] = $this->security_cleanup($value, !($bulk));
+			}
+		}
+		//clean sort order as well and add it to the query
+		if (!(empty($sort)))
+		{
+			$sort = $this->security_cleanup($sort, true, true);
+			$query .= " order by $sort";
+		}
+
+
+		//conversion must be done after oder by is set
+		$this->convert_query($query);
+		// Galaxia needs to be call ADOdb in associative mode
+		$this->db->SetFetchMode(ADODB_FETCH_ASSOC);
+		if ($numrows == -1 && $offset == -1)
+			$result = $this->db->Execute($query, $clean_values);
+		else
+			$result = $this->db->SelectLimit($query, $numrows, $offset, $clean_values);
+		if (empty($result))
+		{
+			$result = false;
+		}
+		$this->num_queries++;
+		if (!$result)
+		{
+			$this->error[] = "there were some SQL errors in the database, please warn your sysadmin.";
+			if ($reporterrors) $this->sql_error($query, $clean_values, $result);
+		}
+		return $result;
+	}
+
+	/**
+	 * @see Base::query
+	 * @param string $query sql query, parameters should be replaced with ?
+     * @param array $values array containing the parameters (going in the ?), use it to avoid security problems
+	 * @param bool $reporterrors is true by default, if false no warning will be generated in the php log
+	 * @return mixed NULL if something went wrong or the first value of the first row if it was ok
+	 * @access public
+	 */
+	function getOne($query, $values = null, $reporterrors = true) {
+		$this->convert_query($query);
+		$clean_values = Array();
+		if (!($values===null))
+		{
+			if (!(is_array($values)))
+			{
+				$values= array($values);
+			}
+			foreach($values as $value)
+			{
+				$clean_values[] = $this->security_cleanup($value);
+			}
+		}
+		$result = $this->db->SelectLimit($query, 1, 0, $clean_values);
+		if (empty($result))
+		{
+			$result = false;
+		}
+		if (!$result && $reporterrors )
+			$this->sql_error($query, $clean_values, $result);
+		if (!!$result)
+		{
+			$res = $result->fetchRow();
+		}
+		else
+		{
+			$res = false;
+		}
+		$this->num_queries++;
+		if ($res === false)
+			return (NULL); //simulate pears behaviour
+		list($key, $value) = each($res);
+		return $value;
+	}
+
+	/**
+	 * Throws error warnings
+	 *
+	 * @param string $query
+	 * @param array $values
+	 * @param mixed $result
+	 * @access public
+	 * @return void
+	 */
+	function sql_error($query, $values, $result) {
+		trigger_error($this->db->databaseType . " error:  " . $this->db->ErrorMsg(). " in query:<br/>" . $query . "<br/>", E_USER_WARNING);
+		// DO NOT DIE, if transactions are there, they will do things in a better way
+	}
+
+	/**
+	 * Clean the data before it is recorded on the database
+	 *
+	 * @param $value is a data we want to be stored in the database.
+	 * If it is an array we'll make a serialize and then an base64_encode
+	 * (you'll have to make an unserialize(base64_decode())
+	 * If it is not an array we make an htmlspecialchars() on it
+	 * @param bool $flat_arrays is true by default, if false arrays won't be serialized and encoded
+	 * @param bool $check_for_injection is false by default, if true we'll perform some modifications
+	 * on the string to avoid SQL injection
+	 * @return mixed @access public
+	 */
+	function security_cleanup($value, $flat_arrays = true, $check_for_injection = false)
+	{
+		if (is_array($value))
+		{
+			if ($flat_arrays) {
+				//serialize and \' are a big #!%*
+				$res = base64_encode(serialize($value));
+			}
+			else
+			{
+				//recursive cleanup on the array
+				$res = Array();
+				foreach ($value as $key => $item)
+				{
+					$res[$this->security_cleanup($key,$flat_arrays)] = $this->security_cleanup($item, $flat_arrays);
+				}
+			}
+		}
+		else
+		{
+			$res = ($check_for_injection)? addslashes(str_replace(';','',$value)) : $value;
+		}
+		return $res;
+	}
+
+	/**
+	 * Supports DB abstraction
+	 *
+	 * @param string &$query
+	 * @return void
+	 * @access public
+	 */
+	function convert_query(&$query) {
+
+		switch ($this->db->databaseType) {
+		case "oci8":
+			$query = preg_replace("/`/", "\"", $query);
+			// convert bind variables - adodb does not do that
+			$qe = explode("?", $query);
+			$query = '';
+			for ($i = 0; $i < sizeof($qe) - 1; $i++) {
+				$query .= $qe[$i] . ":" . $i;
+			}
+			$query .= $qe[$i];
+			break;
+		case "postgres7":
+		case "sybase":
+			$query = preg_replace("/`/", "\"", $query);
+			break;
+		}
+	}
+	/**
+	 * Supports DB abstraction
+	 *
+	 * @param string $sort_mode
+	 * @return string
+	 * @access public
+	 */
+	function convert_sortmode($sort_mode) {
+		$sort_mode = str_replace("__", "` ", $sort_mode);
+		$sort_mode = "`" . $sort_mode;
+		return $sort_mode;
+	}
+	/**
+	 * Supports DB abstraction
+	 *
+	 * @return mixed
+	 * @access public
+	 */
+	function convert_binary() {
+
+		switch ($this->db->databaseType) {
+		case "pgsql72":
+		case "oci8":
+		case "postgres7":
+			return;
+			break;
+		case "mysql3":
+		case "mysql":
+			return "binary";
+			break;
+		}
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/common/WfRuntime.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/common/WfRuntime.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/common/WfRuntime.php	(revision 2372)
@@ -0,0 +1,1150 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+
+/**
+ * Can be viewed by the user like an Instance, it is in fact more than an instance
+ * as it handle concurrency and part of the core execution of the instance while avoiding
+ * bad manipulation of the instance
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class WfRuntime extends Base 
+{  
+  /**
+   * @var array processes config values cached for this object life duration, init is done at first use for the only process associated with this runtime object
+   * @access public
+   */
+  var $conf= Array();  
+  /**
+   * @var object $activity
+   * @access public 
+   */
+  var $activity = null;
+  /**
+   * @var object $instance
+   * @access public 
+   */
+  var $instance = null;
+  /**
+   * @var int $instance_id
+   * @access public 
+   */
+  var $instance_id = 0;  
+  /**
+   * @var int $activity_id
+   * @access public 
+   */
+  var $activity_id = 0;
+  /**
+   * @var object $process Retrieve process information
+   * @access public 
+   */
+  var $process = null;
+  /**
+   * @var object $workitems  Reference to $instance->workitems
+   * @access public 
+   */
+  var $workitems = null;
+  /**
+   * @var object $activities Reference to $instance->activities
+   * @access public 
+   */  
+  var $activities = null;
+  /**
+   * @var object $security Security object
+   * @access public 
+   */  
+  var $security = null;
+  /**
+   * @var bool $transaction_in_progress Transaction state
+   * @access public 
+   */  
+  var $transaction_in_progress = false; 
+  /**
+   * @var bool $debug Debug state
+   * @access public 
+   */   
+  var $debug=false;
+  /**
+   * @var bool $auto_mode Automatic mode state, non-interactive for instance, big impact on error handling
+   * @access public 
+   */  
+  var $auto_mode=false;
+
+  /**
+   * @var string $activityCompleteMessage Holds a message which is displayed in the activity completion page
+   * @access public
+   */
+  var $activityCompleteMessage = '';
+
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object WfRuntime instance
+   * @access public
+   */
+  function WfRuntime() 
+  {
+    $this->child_name = 'WfRuntime';
+    parent::Base();
+
+    //first the activity is not set
+    $this->activity = null;
+    $this->instance = &Factory::newInstance('Instance');
+    $this->process = &Factory::newInstance('Process');
+    $this->security = &Factory::getInstance('WfSecurity');
+  }
+
+  /**
+   * Collect errors from all linked objects which could have been used by this object
+   * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
+   * 
+   * @param bool $debug false by default, if true debug messages can be added to 'normal' messages
+   * @param string $prefix appended to the debug message
+   * @return void 
+   * @access private
+   */
+  function collect_errors($debug=false, $prefix = '')
+  {
+    parent::collect_errors($debug, $prefix);
+    if (isset($this->instance) && !!($this->instance)) $this->error[] = $this->instance->get_error(false, $debug, $prefix);
+    if (isset($this->process) && !!($this->process)) $this->error[] = $this->process->get_error(false, $debug, $prefix);
+    if (isset($this->security) && !!($this->security)) $this->error[] = $this->security->get_error(false, $debug, $prefix);
+    if (isset($this->activity) && !!($this->activity)) $this->error[] = $this->activity->get_error(false, $debug, $prefix);
+  }
+
+  /**
+   * Ends-up dying and giving a last message
+   * 
+   * @param string $last_message last sentence
+   * @param bool $include_errors false by default, if true we'll include error messages
+   * @param bool $debug false by default, if true you will obtain more messages, if false you could obtain those
+   * @param bool $dying true by default, tells the engine to die or not
+   * messages as well if this object has been placed in debug mode with setDebug(true)
+   * recorded by this runtme object.
+   * @access public
+   * @return void
+   */
+  function fail($last_message, $include_errors = false, $debug=false, $dying=true)
+  {
+    $the_end = '';
+    //see if local objects have been set to enforce it
+    if ($this->debug) $debug = true;
+    if ($this->auto_mode) $dying = false;
+    
+    if ($include_errors)
+    {
+      $the_end = $this->get_error(false, $debug).'<br />';
+    }
+    $the_end .= $last_message;
+    if ($this->transaction_in_progress)
+    {
+      //we had a transaction actually, we mark a fail, this will force Rollback
+      $this->db->FailTrans();
+      $this->db->CompleteTrans();
+    }
+    if ($dying)
+    {
+      //this will make the session die
+      galaxia_show_error($the_end, $dying);
+    }
+    else
+    {
+      //this will NOT BREAK the session!
+      return $the_end;
+    }
+  }
+
+  /**
+   * Loads the config values for the process associated with the runtime
+   * config values are cached while this WfRuntime object stays alive
+   * 
+   * @param array $arrayconf Config array with default value, where key is config option name and value is default value
+   * @access private 
+   * @return array Values associated with the current process for the asked config options and as well for som WfRuntime internal config options
+   */
+  function &getConfigValues(&$arrayconf)
+  {
+    if (!(isset($this->process)))
+    {
+      $this->loadProcess();
+    }
+    $arrayconf['auto-release_on_leaving_activity'] = 1;  
+    $this->conf =  $this->process->getConfigValues($arrayconf);
+    return $this->conf;
+  }
+
+  /**
+   * Loads instance, the activity and the process, needed by the runtime engine to 'execute' the activity
+   * 
+   * @param int $activityId activity id, the activity we will run
+   * @param int $instanceId instance Id, can be empty for a start or standalone activity
+   * @return bool 
+   * @access public
+   */
+  function &LoadRuntime($activityId,$instanceId=0)
+  {
+    // load activity
+    if (!($this->loadActivity($activityId, true, true)))
+    {
+      return false;
+    }
+    //interactive or non_interactive?
+    $this->setAuto(!($this->activity->isInteractive()));
+    //load instance
+    if (!($this->loadInstance($instanceId)))
+    {
+      return false;
+    }
+    // load process
+    if (!($this->loadProcess()))
+    {
+      return false;
+    }
+    
+    //ensure the activity is not completed
+    $this->instance->setActivityCompleted(false);
+	$this->instance->activityID = $activityId;
+    
+    //set the workitems and activities links
+    $this->workitems =& $this->instance->workitems;
+    $this->activities =& $this->instance->activities;
+    return true;
+  }
+  
+  /**
+   * Retrieves the process object associated with the activity
+   * 
+   * @param int $pId Process id of the process you want, if you do not give it we will try to take it from the activity
+   * @return mixed Process object of the right type or false
+   * @access private
+   */
+  function loadProcess($pId=0)
+  {
+    if ( (!(isset($this->process))) || ($this->process->getProcessId()==0))
+    {
+      if ( (empty($pId)) || (!($pId)) )
+      {
+        $pId = $this->activity->getProcessId();
+        if ( (empty($pId)) || (!($pId)) )
+        {
+          //fail can return in auto mode or die
+          $errors = $this->fail(tra('No Process indicated'),true, $this->debug, !($this->auto_mode));
+          $this->error[] = $errors;
+          return false;
+        }
+      }
+      if ($this->debug) $this->error[] = 'loading process '.$pId;
+      $this->process->getProcess($pId);
+    }
+    return true;
+  }
+  
+  /**
+   * Gets current process instance
+   * 
+   * @return object Process instance
+   * @access public
+   */
+  function &getProcess()
+  {
+    return $this->process;
+  }
+
+  /**
+   * Retrieves the activity of the right type from a baseActivity Object
+   * 
+   * @param int $activity_id activity_id you want
+   * @param bool $with_roles will load the roles links on the object
+   * @param bool $with_agents will load the agents links on the object
+   * @return mixed Activity object of the right type or false
+   * @access private
+   */
+  function loadActivity($activity_id, $with_roles= true,$with_agents=false)
+  {
+    if ( (empty($activity_id)) || (!($activity_id)) )
+    {
+      //fail can return in auto mode or die
+      $errors = $this->fail(tra('No activity indicated'),true, $this->debug, !($this->auto_mode));
+      $this->error[] = $errors;
+      return false;
+    }
+    $base_activity = &Factory::newInstance('BaseActivity');
+    $this->activity =& $base_activity->getActivity($activity_id, $with_roles, $with_agents);
+    if (!$this->activity)
+    {
+      $errors = $this->fail(tra('failed to load the activity'),true, $this->debug, !($this->auto_mode));
+      $this->error[] = $errors;
+      return false;
+    }
+    $this->activity_id = $activity_id;
+    $this->error[] =  $base_activity->get_error();
+    if ($this->debug) $this->error[] = 'loading activity '.$activity_id;
+    return true;
+  }
+  
+  /**
+   * Gets current activity instance
+   * 
+   * @return object Activity instance
+   * @access public
+   */  
+  function &getActivity()
+  {
+    return $this->activity;
+  }
+  
+  /**
+   * Gets the instance which could be an empty object
+   * 
+   * @param int $instanceId is the instance id
+   * @return mixed Instance object which can be empty or string if something was turning bad
+   * @access public
+   */
+  function loadInstance($instanceId)
+  {
+    $this->instance_id = $instanceId;
+    $this->instance->getInstance($instanceId);
+    if ( ($this->instance->getInstanceId()==0) 
+      && (! (($this->activity->getType()=='standalone') || ($this->activity->getType()=='start') )) )
+    {
+      //fail can return in auto mode or die
+      $errors = $this->fail(tra('no instance avaible'), true, $this->debug, !($this->auto_mode));
+      $this->error[] = $errors;
+      return false;
+    }
+    if ($this->debug) $this->error[] = 'loading instance '.$instanceId;
+    return true;
+  }
+  
+  /**
+   * Perform necessary security checks at runtime before running an activity
+   * This will as well lock the tables via the security object
+   * It should be launched in a transaction
+   * 
+   * @return bool true if ok, false if the user has no runtime access
+   * @access public
+   */
+  function checkUserRun()
+  {
+    if ($this->activity->getType()=='view')
+    {
+      //on view activities  the run action is a special action
+      $action = 'viewrun';
+    }
+    else
+    {
+      $action = 'run';
+    }
+    //this will test the action rights and lock the necessary rows in tables in case of 'run'
+    $result = $this->security->checkUserAction($this->activity_id,$this->instance_id,$action);
+    $this->error[] =  $this->security->get_error(false, $this->debug);
+    if ($result)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  /**
+   * Perform necessary security checks at runtime
+   * This will as well lock the tables via the security object
+   * It should be launched in a transaction
+   * 
+   * @return bool true if ok, false if the user has no runtime access instance and activity are unsetted in case of false check
+   * @access public
+   */
+  function checkUserRelease()
+  {
+    //the first thing to scan if wether or not this process is configured for auto-release
+    if ( (isset($this->conf['auto-release_on_leaving_activity'])) && ($this->conf['auto-release_on_leaving_activity']))
+    {
+      //this will test the release rights and lock the necessary rows in tables in case of 'release'
+      $result = $this->security->checkUserAction($this->activity_id,$this->instance_id,'release');
+      $this->error[] =  $this->security->get_error(false, $this->debug);
+      if ($result)
+      {
+        //we are granted an access to release but there is a special bad case where
+        //we are a user authorized at releasing instances owned by others and where
+        //this instance is owned by another (for some quite complex reasons). 
+        //we should not release this new user!!
+        //Then this is auto-release, not a conscious act and so we will release only 
+        //if we can still grab this instance (avoiding the bad case)
+        
+        //test grab before release
+        if ($this->checkUserRun())
+        {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  
+  /**
+   * Sets/unsets the WfRuntime in debug mode
+   * 
+   * @param bool $debug_mode true by default, set it to false to disable debug mode
+   * @access public
+   * @return void 
+   */
+  function setDebug($debug_mode=true)
+  {
+    $this->debug = $debug_mode;
+  }
+  
+  /**
+   * Sets/unsets the WfRuntime in automatic mode. i.e : executing
+   * non-interactive or interactive activities. Automatic mode have big impacts
+   * on error handling and on the way activities are executed
+   * 
+   * @param bool $auto_mode true by default, set it to false to disable automatic mode
+   * @access public
+   * @return void 
+   */
+  function setAuto($auto_mode=true)
+  {
+    $this->auto_mode = $auto_mode;
+  }
+  
+  /**
+   * This function will start a transaction, call it before setActivityUser()
+   * 
+   * @access public
+   * @return void 
+   */
+  function StartRun()
+  {
+    $this->transaction_in_progress =true;
+    $this->db->StartTrans();
+  }
+  
+  /**
+   * This function ends the transactions started in StartRun()
+   * 
+   * @access public
+   * @return void
+   */
+  function EndStartRun()
+  {
+    if ($this->transaction_in_progress) 
+    {
+      $this->db->CompleteTrans();
+      $this->transaction_in_progress =false;
+    }
+  }
+  
+  /**
+   * For interactive activities this function will set the current user on the instance-activities table. 
+   * This will prevent having several user using the same activity on the same intsance at the same time
+   * But if you want this function to behave well you should call it after a checkUserRun or a checkUserRelease
+   * and inside a transaction. Theses others function will ensure the table will be locked and the user
+   * is really granted the action
+   * 
+   * @param bool $grab true by default, if false the user will be set to '*', releasing the instance-activity record
+   * @access public
+   * @return bool 
+   */
+  function setActivityUser($grab=true)
+  {
+    if(isset($GLOBALS['user']) && !empty($this->instance->instanceId) && !empty($this->activity_id)) 
+    {
+      if ($this->activity->isInteractive())
+      {// activity is interactive and we want the form, we'll try to grab the ticket on this instance-activity (or release)
+        if ($grab)
+        {
+          $new_user = $GLOBALS['user'];
+        }
+        else
+        {
+          $new_user= '*';
+        }
+        if (!$this->instance->setActivityUser($this->activity_id,$new_user))
+        {
+           //fail can return in auto mode or die
+           $errors = $this->fail(lang("You do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.", true, $this->debug, !($this->auto_mode)));
+           $this->error[] = $errors;
+           return false;
+        }
+      }// if activity is not interactive there's no need to grab the token
+    }
+    else
+    {
+      //fail can return in auto mode or die
+      $errors= $this->fail(lang("We cannot run this activity, maybe this instance or this activity do not exists anymore.", true, $this->debug, !($this->auto_mode)));
+      $this->error[] = $errors;
+      return false;
+    }    
+  }
+  
+  /**
+   * Tries to give some usefull info about the current runtime
+   * 
+   * @return array associative arrays with keys/values which could be usefull
+   * @access public
+   */
+  function &getRuntimeInfo()
+  {
+    $result = Array();
+//    _debug_array($this->instance);
+    if (isset($this->instance))
+    {
+      $result['instance_name'] = $this->instance->getName();
+      $result['instance_owner'] = $this->instance->getOwner();
+    }
+    if (isset($this->activity))
+    {
+      $result['activity_name'] = $this->activity->getName();
+      $result['activity_id'] = $this->activity_id;
+      $result['activity_type'] = $this->activity->getType();
+    }
+    return $result;
+  }
+
+  /**
+   * This part of the runtime will be runned just after the activity code inclusion.
+   * We are in fact after all the "user code" part. We should decide what to do next
+   * 
+   * @param bool $debug false by default
+   * @return array an array which must be analysed by the application run class. It contains 2 keys
+   ** 'action' : value is a string is the action the run class should do
+   *	* 'return' should return the result we just returned (in auto mode, to propagate infos)
+   *	* 'loop' should just loop on the form, i.e.: do nothing
+   *	* 'leaving' should show a page for the user leaving the activity (Cancel or Close without completing)
+   *	* 'completed' should show a page for the user having completed the activity
+   ** 'engine_info' : value is an array is an array containing a lot of infos about what was done by the engine
+   *	especially when completing the instance or when executing an automatic activity
+   * @access public
+   */
+  function handle_postUserCode($debug=false)
+  {
+    $result = Array();
+    
+     // re-retrieve instance id which could have been modified by a complete
+     $this->instance_id	= $this->instance->getInstanceId();
+     
+     //synchronised instance object with the database
+     $this->instance->sync();
+
+    // for interactive activities in non-auto mode:
+    if (!($this->auto_mode) && $this->activity->isInteractive())
+    {
+      if ($this->instance->getActivityCompleted())
+      {
+        // activity is interactive and completed, 
+        // we have to continue the workflow
+        // and send any autorouted activity which could be after this one
+        // this is not done in the $instance->complete() to let
+        // xxx_pos.php code be executed before sending the instance
+
+        $result['engine_info'] =& $this->instance->sendAutorouted($this->activity_id);
+
+        // application should display completed page
+        $result['action']='completed';
+        return $result;
+      }
+      // it hasn't been completed
+      else
+      {
+        if ($GLOBALS['workflow']['__leave_activity'])
+        {
+          // activity is interactive and the activity source set the 
+          // $GLOBALS[workflow][__leave_activity] it's a 'cancel' mode.
+          // we redirect the user to the leave activity page
+          $result['action']='leaving';
+          return $result;
+        }
+        else
+        { 
+          //the activity is not completed and the user doesn't want to leave
+          // we loop on the form
+          $result['action']='loop';
+          return $result;
+        }
+      }
+    }
+    else
+    { 
+      // in auto mode or with non interactive activities we return engine info
+      // and we collect our errors, we do not let them for other objects
+      $this->collect_errors($debug);
+      $result['engine_info']['debug'] = implode('<br />',array_filter($this->error));
+      $result['engine_info']['info'] =& $this->getRuntimeInfo();
+      $result['action'] = 'return';
+      return $result;
+    }
+  }
+
+  /**
+   * Gets the the 'Activity Completed' status
+   * 
+   * @access public
+   * @return string 
+   */
+  function getActivityCompleted()
+  {
+    return $this->instance->getActivityCompleted();
+  }
+
+  
+  //----------- Instance public function mapping -------------------------------------------
+  
+  /**
+   * Sets the next activity to be executed, if the current activity is
+   * a switch activity the complete() method will use the activity setted
+   * in this method as the next activity for the instance. 
+   * Note that this method receives an activity name as argument (Not an Id)
+   * and that it does not need the activityId like the instance method
+   * 
+   * @param string $actname name of the next activity
+   * @return bool
+   * @access public
+   */
+  function setNextActivity($actname) 
+  {
+    return $this->instance->setNextActivity($this->activity_id,$actname);
+  }
+
+  /**
+   * Sets the user that must perform the next 
+   * activity of the process. this effectively "assigns" the instance to
+   * some user
+   * 
+   * @param int $user the next user id
+   * @param string $activityName The name of the activity that the user will be able to executed. '*' means the next activity.
+   * @return bool 
+   * @access public
+   */
+  function setNextUser($user, $activityName = '*')
+  {
+    if ($activityName != '*')
+		$activityID = $this->getOne('SELECT wf_activity_id FROM ' . GALAXIA_TABLE_PREFIX . 'activities WHERE (wf_name = ?) AND (wf_p_id = ?)', array($activityName, $this->activity->getProcessId()));
+    else
+		$activityID = '*';
+    return $this->instance->setNextUser($user, $activityID);
+  }
+
+  /**
+   * Sets the user role that must perform the next 
+   * activity of the process. this effectively "assigns" the instance to
+   * some user
+   * 
+   * @param string $roleName the next activity role
+   * @param string $activityName The name of the activity that the role will be able to executed. '*' means the next activity.
+   * @return bool true in case of success or false otherwise
+   * @access public
+   */
+  function setNextRole($roleName, $activityName = '*')
+  {
+    $roleID = $this->getOne('SELECT wf_role_id FROM ' . GALAXIA_TABLE_PREFIX . 'roles WHERE (wf_name = ?) AND (wf_p_id = ?)', array($roleName, $this->activity->getProcessId()));
+    if (is_null($roleID))
+      return false;
+
+    if ($activityName != '*')
+		$activityID = $this->getOne('SELECT wf_activity_id FROM ' . GALAXIA_TABLE_PREFIX . 'activities WHERE (wf_name = ?) AND (wf_p_id = ?)', array($activityName, $this->activity->getProcessId()));
+    else
+		$activityID = '*';
+
+    return $this->instance->setNextRole($roleID, $activityID);
+  }
+
+  /**
+   * Gets the user that must perform the next activity of the process. 
+   * This can be empty if no setNextUser() was done before.
+   * It wont return the default user but only the user which was assigned by a setNextUser
+   * 
+   * @return int 
+   * @access public
+   */
+  function getNextUser() 
+  {
+    return $this->instance->getNextUser();
+  }
+ 
+  /**
+   * Sets the name of this instance.
+   * 
+   * @param string $value new name of the instance
+   * @return bool 
+   * @access public
+   */
+  function setName($value) 
+  {
+    return $this->instance->setName($value);
+  }
+
+  /**
+   * Gets the name of this instance
+   * 
+   * @return string 
+   * @access public
+   */
+  function getName() {
+    return $this->instance->getName();
+  }
+
+  /**
+   * Sets the category of this instance
+   * 
+   * @param string $value
+   * @return bool
+   * @access public
+   */
+  function setCategory($value) 
+  {
+    return $this->instance->setcategory($value);
+  }
+
+  /**
+   * Gets category of this instance
+   * 
+   * @return string 
+   * @access public
+   */
+  function getCategory() 
+  {
+    return $this->instance->getCategory();
+  }
+  
+  /**
+   * Sets a property in this instance. This method is used in activities to
+   * set instance properties.
+   * all property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces). If you have several set to call look
+   * at the setProperties function. Each call to this function has an impact on database
+   * 
+   * @param string $name property name (it will be normalized)
+   * @param mixed $value value for this property
+   * @return bool 
+   * @access public
+   */
+  function set($name,$value) 
+  {
+    return $this->instance->set($name,$value);
+  }
+  
+  /**
+   * Unsets a property in this instance. This method is used in activities to
+   * unset instance properties.
+   * All property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces). Each call to this function has an impact on database
+   * 
+   * @param string $name property name (it will be normalized)
+   * @return bool true if it was ok
+   * @access public
+   */
+  function clear($name) 
+  {
+    return $this->instance->clear($name);
+  }
+
+  /**
+   * Checks if a property in this instance exists. This method is used in activities to
+   * check the existance of instance properties.
+   * All property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces)
+   * 
+   * @param string $name property name (it will be normalized)
+   * @return bool true if it exists and false otherwise
+   * @access public
+   */
+  function exists($name)
+  {
+  	return $this->instance->exists($name);
+  }
+
+  /**
+   * Sets several properties in this instance. This method is used in activities to
+   * set instance properties. Use this method if you have several properties to set
+   * as it will avoid
+   * all property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces). If you have several set to call look
+   * at the setProperties function. Each call to this function has an impact on database
+   * 
+   * @param array $properties_array associative array containing for each record the
+   * property name as the key and the property value as the value. You do not need the complete
+   * porperty array, you can give only the knew or updated properties.
+   * @return bool true if it was ok
+   * @access public
+   */
+  function setProperties($properties_array)
+  {
+     return $this->instance->setProperties($properties_array);
+  }
+
+  /**
+   * Gets the value of an instance property
+   * 
+   * @param string $name name of the instance
+   * @param string $defaultValue
+   * @return bool false if the property was not found, but an error message is stored in the instance object
+   * @access public
+   */
+  function get($name, $defaultValue = "__UNDEF__")
+  {
+    return $this->instance->get($name, $defaultValue);
+  }
+
+  /**
+   * Describes the activities where the instance is present, can be more than one activity if the instance was "splitted"
+   * 
+   * @access public
+   * @return array Vector of assocs
+   */
+  function getActivities() 
+  {
+    return $this->instance->getActivities();
+  }
+  
+  /**
+   * Gets the instance status can be 'completed', 'active', 'aborted' or 'exception'
+   * 
+   * @access public
+   * @return string Instance status
+   */
+  function getStatus() 
+  {
+    return $this->instance->getStatus();
+  }
+  
+  /**
+   * Sets the instance status
+   * 
+   * @param $status Desired status, it can be: 'completed', 'active', 'aborted' or 'exception'
+   * @return bool
+   * @access public
+   */
+  function setStatus($status) 
+  {
+    return $this->instance->setStatus($status);
+  }
+  
+  /**
+   * Gets the instance priority
+   * 
+   * @access public
+   * @return int 
+   */
+  function getPriority()
+  {
+    return $this->instance->getPriority();
+  } 
+
+  /**
+   * Sets the instance priority
+   * 
+   * @param int $priority
+   * @access public
+   * @return bool 
+   */
+  function setPriority($priority)
+  {
+    return $this->instance->setPriority($priority);
+  }
+   
+  /**
+   * Returns the instance id
+   * 
+   * @return int 
+   * @access public
+   */
+  function getInstanceId() 
+  {
+    return $this->instance->getInstanceId();
+  }
+  
+  /**
+   * Returns the process id for this instance
+   * 
+   * @return int 
+   * @access public 
+   */
+  function getProcessId() {
+    return $this->instance->getProcessId();
+  }
+  
+  /**
+   * Returns the owner of the instance
+   * 
+   * @return string 
+   * @access public
+   */
+  function getOwner() 
+  {
+    return $this->instance->getOwner();
+  }
+  
+  /**
+   * Sets the instance owner
+   * 
+   * @param string $user 
+   * @access public
+   * @return bool  
+   */
+  function setOwner($user) 
+  {
+    return $this->instance->setOwner($user);
+  }
+  
+  /**
+   * Returns the user that must execute or is already executing an activity where the instance is present
+   * 
+   * @param int $activityId
+   * @return bool False if the activity was not found for the instance, else return the user id or '*' if no user is defined yet
+   * @access public
+   */  
+  function getActivityUser($activityId) 
+  {
+    return $this->instance->getActivityUser($activityId);
+  }
+  
+  /**
+   * Sets the status of the instance in some activity
+   * 
+   * @param int $activityId Activity id
+   * @param string $status New status, it can be 'running' or 'completed'
+   * @return bool False if no activity was found for the instance
+   * @access public
+   */  
+  function setActivityStatus($activityId,$status) 
+  {
+    return $this->instance->setActivityStatus($activityId,$status);
+  }
+  
+  
+  /**
+   * Gets the status of the instance in some activity 
+   * 
+   * @param int $activityId 
+   * @return string 'running' or 'completed'
+   * @access public
+   */
+  function getActivityStatus($activityId) 
+  {
+    return $this->instance->getActivityStatus($activityId);
+  }
+  
+  /**
+   * Resets the start time of the activity indicated to the current time
+   * 
+   * @param int $activityId
+   * @return bool 
+   * @access public
+   */
+  function setActivityStarted($activityId) 
+  {
+    return $this->instance->setActivityStarted($activityId);
+  }
+  
+  /**
+   * Gets the Unix timstamp of the starting time for the given activity
+   * 
+   * @param int $activityId
+   * @return int 
+   * @access public
+   */
+  function getActivityStarted($activityId) 
+  {
+    return $this->instance->getActivityStarted($activityId);
+  }
+  
+  /**
+   * Gets the time where the instance was started
+   * 
+   * @return int 
+   * @access public
+   */
+  function getStarted() 
+  {
+    return $this->instance->getStarted();
+  }
+  
+  /**
+   * Gets the end time of the instance (when the process was completed)
+   * 
+   * @return int 
+   * @access public 
+   */
+  function getEnded() 
+  {
+    return $this->instance->getEnded();
+  }
+  
+  
+  /**
+   * Completes an activity.
+   * YOU MUST NOT CALL complete() for non-interactive activities since
+   * the engine does automatically complete automatic activities after
+   * executing them
+   * 
+   * @return bool True or false, if false it means the complete was not done for some internal reason
+   * consult get_error() for more informations
+   * @access public
+   */
+  function complete() 
+  {
+    if (!($this->activity->isInteractive()))
+    {
+      $this->error[] = tra('interactive activities should not call the complete() method');
+      return false;
+    }
+    
+    return $this->instance->complete($this->activity_id);
+  }
+
+  /**
+   * Aborts an activity and terminates the whole instance. We still create a workitem to keep track
+   * of where in the process the instance was aborted
+   * 
+   * @return bool 
+   * @access public
+   */
+  function abort() 
+  {
+    return $this->instance->abort();
+  }
+  
+  /**
+   * Gets a comment for this instance
+   * 
+   * @param int $cId Comment id
+   * @return string 
+   * @access public
+   */
+  function get_instance_comment($cId) 
+  {
+    return $this->instance->get_instance_comment($cId);
+  }
+  
+  /**
+   * Inserts or updates an instance comment
+   * 
+   * @param int $cId Commend id
+   * @param int $activityId 
+   * @param object $activity 
+   * @param int	$user User id
+   * @param string $title Comment's title
+   * @param string $comment Comment's contents
+   * @return bool 
+   * @access public
+   */
+  function replace_instance_comment($cId, $activityId, $activity, $user, $title, $comment) 
+  {
+    return $this->instance->replace_instance_comment($cId, $activityId, $activity, $user, $title, $comment);
+  }
+  
+  /**
+   * Removes an instance comment
+   * 
+   * @param int $cId Comment id
+   * @return bool 
+   * @access public
+   */
+  function remove_instance_comment($cId) 
+  {
+    return $this->instance->remove_instance_comment($cId);
+  }
+ 
+  /**
+   * Lists instance comments
+   * 
+   * @return array 
+   * @access public
+   */
+  function get_instance_comments() 
+  {
+    return $this->instance->get_instance_comments();
+  }
+
+  /**
+   * Creates a child instance from the current one
+   *
+   * @param string $activityName The name of the activity of the new instance
+   * @param mixed $properties Determines the new instance properties. If "true" the properties of the current instance will be inherited by the new instance. If "false" no properties will be set. If an "array" (format: property_name => property_value) every property defined in that array will be available to the new instance. False by default
+   * @param mixed $user The ID of the user who will own the new instance or '*' (i.e., everyone). '*' by default
+   * @param bool $parentLock Flag that determines if the parent instance MUST wait for it's children completion before it's own completion ("true") or not ("false"). "true" by default.
+   * @return int The instance ID of the just created instance
+   * @access public
+   */
+  function createChildInstance($activityName, $properties = false, $user = '*', $parentLock = true)
+  {
+    if ((!$this->activity->isInteractive()) && $parentLock)
+      $this->error[] = "createChildInstance: atividades não interativas não podem executar este método com travamento da instância pai";
+
+    $activityID = $this->getOne('SELECT wf_activity_id FROM ' . GALAXIA_TABLE_PREFIX . 'activities WHERE (wf_name = ?) AND (wf_p_id = ?)', array($activityName, $this->activity->getProcessId()));
+
+    if ($properties === true)
+      $properties = $this->instance->properties;
+    if (!is_array($properties))
+      $properties = array();
+
+    $iid = $_REQUEST['iid'];
+    $workflow = $GLOBALS['workflow'];
+    unset($_REQUEST['iid']);
+    $run_activity = Factory::getInstance('run_activity');
+    $run_activity->runtime->instance->parentInstanceId = $this->instance_id;
+    $run_activity->runtime->instance->parentActivityId = $this->activity_id;
+    $output = $run_activity->goChildInstance($activityID, $properties, $user, $parentLock);
+    $_REQUEST['iid'] = $iid;
+    $GLOBALS['workflow'] = $workflow;
+
+    return $output;
+  }
+
+  /**
+   * Set a message which is displayed in the activity completion page.
+   *
+   * @param string $message The message itself.
+   * @return void
+   * @access public
+   */
+  function setActivityCompleteMessage($message)
+  {
+    $this->activityCompleteMessage = $message;
+  }
+
+  /**
+   * Get the message which is displayed in the activity completion page.
+   *
+   * @return string The message which will be shown.
+   * @access public
+   */
+  function getActivityCompleteMessage()
+  {
+    return $this->activityCompleteMessage;
+  }
+
+  /**
+   * Get information about the parent of an instance (if it has one)
+   *
+   * @return mixed An array containing the information of the parent or false if the instances does not have a parent
+   * @access public
+   */
+  function getParent()
+  {
+    $resultSet = $this->query("SELECT wf_parent_instance_id, wf_parent_activity_id, wf_parent_lock FROM egw_wf_interinstance_relations WHERE (wf_child_instance_id = ?)", array($this->getInstanceId()));
+    if (($row = $resultSet->fetchRow()))
+      return array('instance_id' => $row['wf_parent_instance_id'], 'activity_id' => $row['wf_parent_activity_id'], 'lock' => ($row['wf_parent_lock'] == 1));
+    else
+      return false;
+  }
+
+  /**
+   * Unlock the parent of the instance
+   *
+   * @return void
+   * @access public
+   */
+  function unlockParent()
+  {
+    $this->query("UPDATE egw_wf_interinstance_relations SET wf_parent_lock = 0 WHERE (wf_child_instance_id = ?)", array($this->getInstanceId()));
+  }
+}
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/common/WfSecurity.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/common/WfSecurity.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/common/WfSecurity.php	(revision 2372)
@@ -0,0 +1,914 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+
+/**
+ * Handles most security issues in the engine
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class WfSecurity extends Base {
+  
+  /**
+   * @var array processes config values cached for this object life duration, init is done at first use for each process
+   * @access public
+   */
+  var $processesConfig= Array();
+      
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object WfSecurity
+   * @access public
+   */
+  function WfSecurity() 
+  {
+    $this->child_name = 'WfSecurity';
+    parent::Base();
+  }
+
+  /**
+   * Loads config values for a given process. 
+   * Config values for a given process are cached while this WfSecurity object stay alive
+   * 
+   * @param int $pId Process id
+   * @access private
+   * @return void 
+   */
+  function loadConfigValues($pId)
+  {
+    //check if we already have the config values for this processId
+    if (!(isset($this->processesConfig[$pId])))
+    {
+      //define conf values we need
+      $arrayConf=array(
+        'ownership_give_abort_right'		=>1,
+        'ownership_give_exception_right'	=>1,
+        'ownership_give_release_right'		=>1,
+        'role_give_abort_right'           	=>0,
+        'role_give_release_right'		=>0,
+        'role_give_exception_right'		=>0,
+        'disable_advanced_actions'		=>0,
+		'iframe_view_height'			=>-1,
+		'execute_activities_using_secure_connection' =>0
+      );
+      //check theses values for this process and store the result for this object life duration
+      $myProcess = &Factory::newInstance('Process');
+      $myProcess->getProcess($pId);
+      $this->processesConfig[$pId] = $myProcess->getConfigValues($arrayConf);
+      unset($myProcess);
+    }    
+  }
+
+  /**
+   * Checks if a user has a access to an activity, use it at runtime.
+   * To do so it checks if the user is in the users having the roles associated with the activity
+   * or if he is in the groups having roles associated with the activity
+   * 
+   * @access public
+   * @param int $user User id
+   * @param int $activityId Activity id
+   * @param bool $readonly False by default. If true we only check read-only access level for the user on this activity
+   * @return bool True if access is granted false in other case. Errors are stored in the object
+   */
+  function checkUserAccess($user, $activity_id, $readonly=false) 
+  {
+	/* if activity is non-interactive is not necessary checking user access */
+	$activity = &Factory::getInstance('BaseActivity')->getActivity($activity_id);
+	if (!$activity->isInteractive())
+		return true;
+
+    //group mapping, warning groups and user can have the same id
+    if ($user[0] != 'p')
+        $groups = galaxia_retrieve_user_groups($user);
+    else
+        $groups = false;
+        
+    $query = 'select count(*) from '.GALAXIA_TABLE_PREFIX.'activity_roles gar 
+        INNER JOIN '.GALAXIA_TABLE_PREFIX.'roles gr ON gar.wf_role_id=gr.wf_role_id
+        INNER JOIN '.GALAXIA_TABLE_PREFIX.'user_roles gur ON gur.wf_role_id=gr.wf_role_id 
+        where gar.wf_activity_id=? 
+        and ( (gur.wf_user=? and gur.wf_account_type=?)';
+    if (is_array($groups))
+    {
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+      $query .= ' or (gur.wf_user in ('.implode(',',$groups).") and gur.wf_account_type='g')";
+    }
+
+    $query .= " or ('p'||gur.wf_role_id = '$user')";
+
+    $query .= ')';
+
+    if (!($readonly))
+    {
+      $query.= 'and NOT(gar.wf_readonly=1)';
+    }
+    $result= $this->getOne($query ,array($activity_id, $user, 'u'));
+    if ($result)
+    {
+      //echo "<br>Access granted for ".$user;
+      return true;
+    }
+    else
+    {
+      $this->error[]= tra('Access denied for user %1 on activity %2, no role', $user, $activity_id);
+      return false;
+    }
+  }
+
+  /**
+   * Checks at RUNTIME whether running user is authorized for a given action on some activity/instance.
+   * This function will check the given action for the current running user, lock the table rows if necessary to ensure
+   * nothing will move from another process between the check and the later action. 
+   * loacked tables can be instances and instance-activities.
+   * NOTA BENE: there is no lock on activity/processes table, we assume the admin is not changing the activity data
+   * on a running/production process, this is why there is versioning and activation on processes
+   * Encapsulate this function call in a transaction, locks will be removed at the end of the transaction, whent COMMIT 
+   * or ROLLBACK will be launched
+   * 
+   * @param int $activityId Activity id, it may be 0
+   * @param int $instanceId InstanceId, it may be 0
+   * @param string $action ONE action asked, it must be one of: 'grab', 'release', 'exception', 'resume', 'abort', 'run', 'send', 'view', 'viewrun', 'complete' (internal action before completing), 'restart' admin function, restarting a failed automatic activity 
+   * be carefull, View can be done in 2 ways: viewrun : by the view activity if the process has a view activity, and only by this way in such case, view: by a general view form with access to everybody if the process has no view activity
+   * @return bool True if action access is granted false in other case. Errors are stored in the object
+   * @access public
+   */
+  function checkUserAction($activityId, $instanceId,$action)
+  {
+    //Warning: 
+    //start and standalone activities have no instances associated
+    //aborted and completed instances have no activities associated
+
+    //$this->error[] = 'DEBUG: action:'.$action;
+    if ($action!='run' && $action!='send' && $action!='view' && $action!='viewrun' && $action!='complete' && $action!='grab' && $action!='release' && $action!='exception' && $action!='resume' && $action!='abort' && $action!='restart')
+    {
+      $this->error[] = tra('Security check: Cannot understand asked action');
+      return false;
+    }
+    
+    $user = galaxia_retrieve_running_user();
+    //$this->error[] = 'DEBUG: running user:'.$user;
+    if ( (!(isset($user))) || (empty($user)) )
+    {
+      $this->error[] = tra('Cannot retrieve the user running the security check');
+      return false;
+    }
+
+    //0 - prepare RowLocks ----------------------------------------------------------
+    $lock_instance_activities = false;
+    $lock_instances = false;
+    switch($action)
+    {
+      case 'view':
+      case 'viewrun':
+        //no impact on write mode, no lock
+        break;
+      case 'grab':
+        //impacted tables is instance_activities
+        $lock_instance_activities = true;
+        break;
+      case 'release' :
+        //impacted tables is instance_activities
+        $lock_instance_activities = true;
+        break;
+      case 'exception':
+        //impacted tables is instances
+        $lock_instances = true;
+        break;
+      case 'resume':
+        //impacted tables is instances
+        $lock_instances = true;
+        break;
+      case 'abort':
+        //impacted tables are instances and instance_activities (deleting rows)
+        $lock_instance_activities = true;
+        $lock_instances = true;
+        break;
+      case 'run':
+        //impacted tables is instance_activities (new running user)
+        $lock_instance_activities = true;
+        break;
+      case 'send':
+        //impacted tables is instance_activities (deleting/adding row)
+        $lock_instance_activities = true;
+        break;
+      case 'complete':
+        //impacted tables are instances and instance_activities
+        $lock_instance_activities = true;
+        $lock_instances = true;
+        break;
+      case 'restart':
+        //nothing to do, it will be done by the run part.
+        break;
+    }
+    // no lock on instance_activities without a lock on instances
+    // to avoid changing status of an instance or deletion of an instance while impacting instance_activities
+    if ($lock_instance_activities) $lock_instances = true;
+    
+    //1 - load data -----------------------------------------------------------------
+    $_no_activity=false;
+    $_no_instance=false;
+    
+    //retrieve some activity datas and process data
+    if ($activityId==0)
+    {
+      $_no_activity = true;
+    }
+    else
+    {
+      $query = 'select ga.wf_activity_id, ga.wf_type, ga.wf_is_interactive, ga.wf_is_autorouted, 
+              gp.wf_name as wf_procname, gp.wf_is_active, gp.wf_version, gp.wf_p_id
+              from '.GALAXIA_TABLE_PREFIX.'activities ga 
+                INNER JOIN '.GALAXIA_TABLE_PREFIX.'processes gp ON gp.wf_p_id=ga.wf_p_id
+                where ga.wf_activity_id = ?';
+      $result = $this->query($query, array($activityId));
+      $resactivity = Array();
+      if (!!$result)
+      {
+        $resactivity = $result->fetchRow();
+        $pId = $resactivity['wf_p_id'];
+        //DEBUG
+        //$debugactivity = implode(",",$resactivity);
+        //$this->error[] = 'DEBUG: '. date("[d/m/Y h:i:s]").'activity:'.$debugactivity;
+      }
+      if (count($resactivity)==0)
+      {
+        $_no_activity = true;
+      }
+    }
+
+    //retrieve some instance and process data (need process data here as well if there is no activity)
+    if ($instanceId==0)
+    {
+      $_no_instance = true;
+    }
+    else
+    {
+      if ($lock_instances)
+      {
+        //we need to make a row lock now, before any read action
+        $where = 'wf_instance_id='.(int)$instanceId;
+        //$this->error[]= '<br> Debug:locking instances '.$where;
+        if (!($this->db->RowLock(GALAXIA_TABLE_PREFIX.'instances', $where)))
+        {
+          $this->error[] = tra('failed to obtain lock on %1 table', 'instances');
+          return false;
+        }
+      }
+      $query = 'select gi.wf_instance_id, gi.wf_owner, gi.wf_status, 
+              gp.wf_name as wf_procname, gp.wf_is_active, gp.wf_version, gp.wf_p_id
+              from '.GALAXIA_TABLE_PREFIX.'instances gi
+              INNER JOIN '.GALAXIA_TABLE_PREFIX.'processes gp ON gp.wf_p_id=gi.wf_p_id
+              where gi.wf_instance_id=?';
+      $result = $this->query($query,array($instanceId));
+      if (!!$result)
+      {
+
+        $resinstance = $result->fetchRow();
+        $pId = $resinstance['wf_p_id'];
+        //DEBUG
+        //$debuginstance = implode(",",$resinstance);
+        //$this->error[] = 'DEBUG: '. date("[d/m/Y h:i:s]").'instance:'.$debuginstance;
+      }
+      if (count($resinstance)==0)
+      {
+        $_no_instance = true;
+      }
+    }
+
+    if ($_no_activity && $_no_instance)
+    {
+      $this->error[] = tra('Action %1 is impossible if we have no activity and no instance designated for it!',$action);
+      return false;
+    }
+    
+    //retrieve some instance/activity data
+    //if no_activity or no_instance we are with out-flow/without instances activities or with instances terminated 
+    //we would not obtain anything there
+    if (!($_no_activity || $_no_instance))
+    {
+      if ($lock_instance_activities)
+      {
+        //we need to lock this row now, before any read action
+        $where = 'wf_instance_id='.(int)$instanceId.' and wf_activity_id='.(int)$activityId;
+        //$this->error[] = '<br> Debug:locking instance_activities '.$where;
+        if (!($this->db->RowLock(GALAXIA_TABLE_PREFIX.'instance_activities', $where)))
+        {
+          if ($this->db->getOne('SELECT 1 FROM ' . GALAXIA_TABLE_PREFIX . 'instance_activities WHERE ' . $where))
+          {
+            $this->error[] = tra('failed to obtain lock on %1 table','instances_activities');
+            return false;
+          }
+          else
+          {
+            $this->error[] = tra("This instance doesn't exist in this activity. Probably, this instance has already been executed");
+            return false;
+          }
+        }
+      }
+      $query = 'select gia.wf_instance_id, gia.wf_user, gia.wf_status
+              from '.GALAXIA_TABLE_PREFIX.'instance_activities gia
+                where gia.wf_activity_id = ? and gia.wf_instance_id = ?';
+      $result = $this->query($query, array($activityId, $instanceId));
+      $res_inst_act = Array();
+      if (!!$result)
+      {
+        $res_inst_act = $result->fetchRow();
+        //DEBUG
+        //$debuginstact = implode(",",$res_inst_act);
+        //$this->error[] = 'DEBUG: '. date("[d/m/Y h:i:s]").'instance/activity:'.$debuginstact;
+
+      }
+    }
+
+    //Now that we have the process we can load config values
+    //$this->error[] = 'DEBUG: load config values for process:'.$pId;
+    $this->loadConfigValues($pId);
+    //$debuconfig = '';foreach ($this->processesConfig[$pId] as $label => $value){$debugconfig .= ':'.$label.'=>'.$value;} $this->error[] = 'DEBUG: config:'.$debugconfig;
+
+
+    
+    //2 - decide which tests must be done ------------------------------------------------
+    //init tests
+    $_check_active_process = false; // is the process is valid?
+    $_check_instance = false; //have we got an instance?
+    $_check_instance_status = array(); //use to test some status between 'active','exception','aborted','completed'
+    $_fail_on_exception = false; //no comment
+    $_check_activity = false; //have we got an activity?
+    //is there a relationship between instance and activity? this one can be decided already
+    $_check_instance_activity =  !(($_no_instance) || ($_no_activity));
+    $_bypass_user_role_if_owner = false; //if our user is the owner we ignore user tests
+    $_bypass_user_on_non_interactive = false; //if activty is not interactive we do not perform user tests
+    $_bypass_user_if_admin = false; //is our user a special rights user?
+    $_bypass_instance_on_pseudo = false; //should we jump the instance check when in 'start' activity?
+    $_check_is_user = false; //is the actual_user our user?
+    $_check_is_not_star = false; //is the actual <>*?
+    $_check_is_star = false; // is the actual user *?
+    $_check_is_in_role = false; //is our user in associated roles with readonly=false?
+    $_check_is_in_role_in_readonly = false; //is our user in associated roles?
+    $_check_no_view_activity = false; //is the process having no view activities?
+    $_check_is_admin_only = false; //is the action vaible only for admins?
+    
+    //first have a look at the action asked
+    switch($action)
+    {
+      case 'restart':
+        // we need an activity 'in_flow' ie: not start or standalone that means we need an instance
+        // we need an instance not completed or aborted that means we need an activity
+        // but if we have an instance it musn't be in 'exception' as well
+        // authorization is given to admin only
+        $_check_active_process          = true;
+        $_check_activity                = true;
+        $_check_instance		= true;
+        $_fail_on_exception             = true;
+        $_check_is_admin_only		= true;
+        break;
+      case 'view':
+        //process can be inactive
+        //we need an existing instance
+        //no activity needed
+        $_check_instance = true;
+        $_bypass_user_if_admin	= true;
+        //but be carefull the view function is forbidden on process having the viewrun action with activities
+        $_check_no_view_activity = true;
+        break;
+      case 'viewrun':
+        //process can be inactive
+        //we need an existing instance
+        //we need an activity
+        //need a read-only role at least on this activity
+        $_check_instance = true;
+        $_bypass_user_if_admin	= true;
+        $_check_activity = true; 
+        $_check_is_in_role_in_readonly = true;
+        //The view type is a special activity related to all instances
+        $_check_instance_activity = false;
+        break;
+      case 'complete':
+        // we need an activity 'in_flow' ie: not start or standalone that means we need an instance
+        // (the 'view' activity is not 'in_flow' and has instance, but no relashionship, no need to 
+        // test it here or later for grab or others actions). 
+        // warning we can complete a start activity, in this case it is the contrary, we musn't have an instance
+        // we need an instance not completed or aborted that means we need an activity
+        // but if we have an instance it musn't be in 'exception' as well
+        // authorization is given to currentuser only,
+        // for interactive activities (except start), instance user need to be the actual user
+        // 'view' cannot be completed
+        $_check_active_process		= true;
+        $_check_instance        	= true;
+        $_bypass_instance_on_pseudo	= true;
+        $_fail_on_exception		= true;
+        $_check_activity	        = true;
+        $_bypass_user_on_non_interactive = true;
+        $_check_is_user			= true;
+        $_check_is_not_star		= true;
+        break;
+      case 'grab': 
+        // we need an activity 'in_flow' ie: not start or standalone that means we need an instance
+        // we need an instance not completed or aborted that means we need an activity
+        // authorization are given to currentuser, role, never owner actually
+        // TODO: add conf setting to give grab access to owner (that mean run access as well maybe)
+        // current user MUST be '*' or user (no matter to grab something we already have)
+        // check is star is done after check_is_user which can be false
+        $_check_active_process	= true;
+        $_check_activity	= true;
+        $_check_instance	= true;
+        $_check_is_user		= true;
+        $_check_is_star		= true;
+        $_bypass_user_if_admin	= true;
+        $_check_is_in_role	= true;
+        break;
+      case 'release' :
+        // we need an activity 'in_flow' ie: not start or standalone that means we need an instance
+        // we need an instance not completed or aborted that means we need an activity
+        // authorization are given to currentuser, maybe role, maybe owner,
+        // current must not be '*'
+        $_check_active_process	= true;
+        $_check_activity        = true;
+        $_check_instance        = true;
+        $_check_is_user		= true;
+        $_check_is_not_star 	= true;
+        $_bypass_user_if_admin	= true;
+        if ($this->processesConfig[$pId]['role_give_release_right']) $_check_is_in_role 		= true;
+        if ($this->processesConfig[$pId]['ownership_give_release_right']) $_bypass_user_role_if_owner 	= true;
+        break;
+      case 'exception':
+        // we need an activity 'in_flow' ie: not start or standalone that means we need an instance
+        // we need an instance not completed or aborted that means we need an activity
+        // authorization are given to currentuser, maybe role, maybe owner,
+        $_check_active_process	= true;
+        $_check_activity        = true;
+        $_check_instance        = true;
+        $_check_instance_status = array('active');
+        $_bypass_user_if_admin	= true;
+        $_check_is_user		= true;
+        if ($this->processesConfig[$pId]['role_give_exception_right']) $_check_is_in_role                 = true;
+        if ($this->processesConfig[$pId]['ownership_give_exception_right']) $_bypass_user_role_if_owner   = true;
+        break;
+      case 'resume':
+        // like exception but inversed activity status
+        $_check_active_process	= true;
+        $_check_activity        = true;
+        $_check_instance        = true;
+        $_check_instance_status = array('exception');
+        $_bypass_user_if_admin	= true;
+        $_check_is_user		= true;
+        if ($this->processesConfig[$pId]['role_give_exception_right']) $_check_is_in_role                 = true;
+        if ($this->processesConfig[$pId]['ownership_give_exception_right']) $_bypass_user_role_if_owner   = true;
+        break;
+      case 'abort':
+        // process can be inactive
+        // we do not need an activity
+        // we need an instance
+        // authorization are given to currentuser, maybe role, maybe owner,
+        // TODO: add conf setting to refuse abort by user
+        $_check_instance        = true;
+        $_check_instance_status = array('active','exception','completed');
+        $_bypass_user_if_admin	= true;
+        $_check_is_user		= true;
+        if ($this->processesConfig[$pId]['role_give_abort_right']) $_check_is_in_role                 = true;
+        if ($this->processesConfig[$pId]['ownership_give_abort_right']) $_bypass_user_role_if_owner   = true;
+        break;
+      case 'run':
+        // the hell door:
+        // all activities can be runned, even without instance, even if non interactive
+        // if we have one we need an instance not completed or aborted that means we need an activity
+        // but if we have an instance it musn't be in 'exception' as well
+        // for interactive activities (except start and standalone), instance user need to be the actual user
+        // run is ok if user is in role and actual user is '*', no rights for owner actually
+        // no user bypassing on admin user, admin must grab (release if needed) the instance before
+        $_check_active_process		= true;
+        $_check_activity	        = true;
+        $_fail_on_exception		= true;
+        $_bypass_user_on_non_interactive = true;
+        $_check_is_user			= true;
+        $_check_is_star			= true;
+        $_check_is_in_role		= true;
+        break;
+      case 'send':
+        // we need an instance not completed or aborted that means we need an activity
+        // but if we have an instance it musn't be in 'exception' as well
+        // authorization are given to currentuser, maybe role, no rights for owner actually
+        // run is ok if user is in role and actual user is '*'
+        // no user bypassing on admin user, admin must grab (release if needed) the instance before
+        $_check_active_process          = true;
+        $_check_activity                = true;
+        $_fail_on_exception             = true;
+        $_bypass_user_if_admin		= true;
+        $_check_is_user                 = true;
+        $_check_is_star			= true;
+        $_check_is_in_role		= true;
+        break;
+    }
+    
+    //3- now perform asked tests ---------------------------------------------------------------------
+    if ($_check_active_process) // require an active process?
+    {
+      //$this->error[] = 'DEBUG: check active process';
+      if ($_no_instance) //we need an instance or an activity to perfom the check
+      {
+        //we cannot be there without instance and without activity, we now we have one activity at least
+        if (!($resactivity['wf_is_active']=='y'))
+        {
+          $this->error[] = tra('Process %1 %2 is not active, action %3 is impossible', $resactivity['wf_procname'], $resactivity['wf_version'], $action);
+          return false;
+        }
+      }
+      else
+      {
+        if (!($resinstance['wf_is_active']=='y'))
+        {
+          $this->error[] = tra('Process %1 %2 is not active, action %3 is impossible', $resinstance['wf_procname'], $resactivity['wf_version'], $action);
+          return false;
+        }
+      }
+    }
+    
+    if ($_check_instance)
+    {
+      //$this->error[] = 'DEBUG: check instance';
+      if ( (!($_bypass_instance_on_pseudo)) && ($_no_instance))
+      {
+        $this->error[] = tra('Action %1 needs an instance and instance %2 does not exists', $action, $instanceId);
+        return false;
+      }
+    }
+    
+    if ($_check_activity)
+    {
+      //$this->error[] = 'DEBUG: check activity';
+      if ($_no_activity)
+      {
+        $this->error[] = tra('Action %1 needs an activity and activity %2 does not exists', $action, $activityId);
+        return false;
+      }
+    }
+    
+    if ($_check_instance_activity) //is there a realtionship between instance and activity
+    {
+      //$this->error[] = 'DEBUG: check activity-instance relationship'.count($res_inst_act);
+      if ( (!isset($res_inst_act)) || empty($res_inst_act) || (count($res_inst_act)==0) )
+      {
+        $this->error[] = tra('Instance %1 is not associated with activity %2, action %3 is impossible.', $instanceId, $activityId, $action);
+        return false;
+      }
+    }
+    
+    if (!(count($_check_instance_status) == 0)) //use to test some status between 'active','exception','aborted','completed'
+    {
+      //DEBUG
+      //$debug_status = implode(",",$_check_instance_status);
+      //$this->error[] = 'DEBUG: check instance status, actually :'.$resinstance['wf_status'].' need:'.$debug_status;
+      if (!(in_array($resinstance['wf_status'],$_check_instance_status)))
+      {
+        $this->error[] = tra('Instance %1 is in %2 state, action %3 is impossible.', $instanceId, $resinstance['wf_status'], $action);
+        return false;
+      }
+    }
+    if (($_fail_on_exception) && ($resinstance['wf_status']=='exception'))
+    {
+        $this->error[] = tra('Instance %1 is in exception, action %2 is not possible.', $instanceId, $action);
+        return false;
+    }
+    
+    // Test on the process to see if he has a view activity
+    if ($_check_no_view_activity)
+    {
+      if (!(isset($this->pm)))
+      {
+        $this->pm = &Factory::newInstance('ProcessManager');
+      }
+      //$this->error[] = 'DEBUG: checking to see if there is no view activities on process :'.$pId.':'.$this->pm->get_process_view_activity($pId);
+      /** whithout this check we can see the instance data if any view activity exists */
+	/*if ($this->pm->get_process_view_activity($pId))
+      {
+        $this->error[] = tra('This process has a view activity. Access in view mode is granted only for this view activty.');
+        return false;
+      }*/
+    }
+    
+    // user tests ---------------
+    $checks = true;
+    //is our actual workflow user a special rights user?
+    // TODO test actual workflow user diff of $user
+    //$this->error[] = 'DEBUG: user can admin instance :'.galaxia_user_can_admin_instance().' bypass?:'.$_bypass_user_if_admin;
+    $is_admin = galaxia_user_can_admin_instance();
+    if (! ( (($_bypass_user_if_admin) && ($is_admin)) || (($_check_is_admin_only) && ($is_admin))) )
+    {
+      //if our user is the owner we ignore user tests
+      //$this->error[] = 'DEBUG: user is owner :'.$resinstance['wf_owner'].' bypass?:'.$_bypass_user_role_if_owner;
+      if (!( ($_bypass_user_role_if_owner) && ((int)$resinstance['wf_owner']==(int)$user) ))
+      {
+        //$this->error[] = 'DEBUG: no_activity:'.$_no_activity.' interactive? :'.$resactivity['wf_is_interactive'].' bypass?:'.$_bypass_user_on_non_interactive;
+        //if activity is not interactive we do not perform user tests
+        if (!( (!($_no_activity)) && ($_bypass_user_on_non_interactive) && ($resactivity['wf_is_interactive']=='n') ))
+        {
+          //$this->error[] = 'DEBUG: no bypassing done:';
+          //is the actual_user our user?
+          if ( (!($_no_instance)) && $_check_is_user) 
+          {
+            //$this->error[] = 'DEBUG: check user is actual instance user:'.$user.':'.$res_inst_act['wf_user'];
+            if (!((int)$res_inst_act['wf_user']==(int)$user))
+            {
+              //user test was false, but maybe we'll have better chance later
+              $checks = false;
+            }
+          }
+          // special '*' user
+          if ($res_inst_act['wf_user']=='*')
+          {
+            //$this->error[] = 'DEBUG: we have the special * user:';
+            //is the actual *?
+            if ($_check_is_star)
+            {
+              // redemption here
+              //$this->error[] = 'DEBUG Ok, we have a star';
+              $checks = true;
+            }
+            
+            //is the actual <>*?
+            if ($_check_is_not_star)
+            {
+              //no redemption here
+              $this->error[] = tra('Action %1 is impossible, there are no user assigned to this activity for this instance', $action);
+              return false;
+            }
+            //perform the role test if actual user is '*'
+            //$this->error[] = 'DEBUG: role checking?:'.$_check_is_in_role;
+            if ($_check_is_in_role)
+            {
+              //$this->error[] = 'DEBUG: we have *, checking role of user:'.$user;
+              $checks=$this->checkUserAccess($user, $activityId);
+            }
+            //$this->error[] = 'DEBUG: role checking in read-only at least?:'.$_check_is_in_role_in_readonly;
+            if ($_check_is_in_role_in_readonly)
+            {
+              //$this->error[] = 'DEBUG: we have *, checking readonly role of user:'.$user;
+              $checks=$this->checkUserAccess($user, $activityId, true);
+            }        
+          }
+          else
+          {
+            if (substr($res_inst_act['wf_user'], 0, 1) == 'p')
+            {
+              $role_id = substr($res_inst_act['wf_user'], 1);
+              $groups = galaxia_retrieve_user_groups($user);
+              $sql = "SELECT 1 ";
+              $sql .= "FROM " . GALAXIA_TABLE_PREFIX . "user_roles WHERE (";
+              if (is_array($groups))
+              {
+                foreach ($groups as &$group)
+                  $group = "'{$group}'";
+                $sql .= "(wf_user IN (" . implode(',',$groups) . ") AND wf_account_type = 'g') OR ";
+              }
+              $sql .= "(wf_user = '$user' AND wf_account_type = 'u')) AND ";
+              $sql .= "(wf_role_id = $role_id)";
+              $result = $this->getOne($sql);
+
+              if (is_null($result))
+                $checks = false;
+              else
+                $checks = true;
+
+            }
+            else
+            {
+              //we have not *, do we need * as the actual? (done only if check_is_user is false)
+              //notice that if check_user was false and we have not the '*' user and if you do not want
+              //the check_is_star it means the user can bypass the actual user if you have a check_is_in_role ok!
+              if ( (!($checks)) && ($_check_is_star))
+              {
+                // that was necessary
+                $this->error[] = tra('Action %1 is impossible, another user is already in place', $action);
+                return false;
+              }
+              //is our user in associated roles (done even if check_is_user was true)
+              //$this->error[] = 'DEBUG: role checking?:'.$_check_is_in_role;
+              if ($_check_is_in_role)
+              {
+                //$this->error[] = 'DEBUG: we have not *, checking role for user:'.$user;
+                $checks=$this->checkUserAccess($user, $activityId);
+              }
+              //$this->error[] = 'DEBUG: role checking in read-only at least?:'.$_check_is_in_role_in_readonly;
+              if ($_check_is_in_role_in_readonly)
+              {
+                //$this->error[] = 'DEBUG: we have not *, checking role in read-only for user:'.$user;
+                $checks=$this->checkUserAccess($user, $activityId, true);
+              }
+            }
+          }
+        }
+      }
+    }
+    //$this->error[] = 'DEBUG: final check:'.$checks;
+    return $checks;
+  }
+
+  /**
+   * Gets avaible actions for a given user on some activity and instance assuming he already have access to it.
+   * To be able to decide this function needs all the parameters, use the GUI object equivalent function if you want less parameters.
+   * 
+   * @access public
+   * @param int $user User id
+   * @param int $instanceId Instance id
+   * @param int $activityId Activity id
+   * @param bool $readonly It has to be true if the user has only read-only level access with his role mappings
+   * @param int $pId Process id
+   * @param string $actType Activity type
+   * @param string $actInteractive 'y' or 'n' and is the activity interactivity
+   * @param string $actAutorouted 'y' or 'n' and is the activity routage 
+   * @param string $actStatus Activity status ('running' or 'completed')
+   * @param int $instanceOwner Instance owner id
+   * @param string $instanceStatus Instance status ('running', 'completed', 'aborted' or 'exception')
+   * @param mixed $currentUser Current instance/activity user id or '*'.
+   * @param bool $viewactivity False if the process has no view activity, else it's the id of the view activity
+   * @return array An array of this form:
+   * array('action name' => 'action description')
+   * 'actions names' are: 'grab', 'release', 'run', 'send', 'view', 'viewrun', 'exception', 'resume', 'monitor'
+   * note that for the 'viewrun' key value is an array with a 'lang' key for the translation and a 'link' key for the view activity id
+   * Some config values can change theses rules but basically here they are:
+   *	* 'grab'	: be the user of this activity. User has access to it and instance status is ok.
+   *	* 'release'	: let * be the user of this activity. Must be the actual user or the owner of the instance.
+   *	* 'run'	: run an associated form. This activity is interactive, user has access, instance status is ok.
+   *	* 'send'	: send this instance, activity was non-autorouted and he has access and status is ok.
+   *	* 'view'	: view the instance, activity ok, always avaible if no view activity on the process except for start or standalone act.
+   *	* 'viewrun'	: view the instance in a view activity, need role on view activity, always avaible except for start or standalone act.
+   *	* 'abort'	: abort an instance, ok when we are the user
+   *	* 'exception' : set the instance status to exception, need to be the user 
+   *	* 'resume'	: back to running when instance status was exception, need to be the user
+   *	* 'monitor' : admin the instance, for special rights users
+   * 'actions description' are translated explanations like 'release access to this activity'
+   * This function will as well load process configuration which could have some impact on the rights. 
+   * Theses config data will be cached during the existence of this WfSecurity object.
+   * WARNING: this is a snapshot, the engine give you a snaphsot of the rights a user have on an instance-activity
+   * at a given time, this is not meaning theses rights will still be there when the user launch the action.
+   * You should absolutely use the GUI Object or runtime to execute theses actions (except monitor) and they could be rejected.
+   * WARNING: we do not check the user access rights. If you launch this function for a list of instances obtained via a 
+   * GUI object theses access rights are allready checked (for example we do not check your readonly parameter is true).
+   * In fact this function is GUI oriented, it is not granting rights
+   */
+  function getUserActions($user, $instanceId, $activityId, $readonly, $pId, $actType, $actInteractive, $actAutorouted, $actStatus, $instanceOwner, $instanceStatus, $currentUser, $view_activity)
+  {
+    $result= array();//returned array
+    $stopflow=false;//true when the instance is in a state where the flow musn't advance
+                    //ie: we can't send or run it
+    $deathflow=false;//true when the instance is in a state where the flow will never advance anymore
+                    //ie: we can't send, run, grab, release, exception or resume it
+    $associated_instance=true;//false when no instance is associated with the activity
+                    // ie: we cannot send, grab, release, exception, resume or view the instance but we can run
+                    // it covers standalone activities and start activities not completed
+    $_run  = false;
+    $_send = false;
+    $_grab = false;
+    $_release = false;
+    $_abort = false;
+    $_view = false;
+    $_viewrun = false;
+    $_resume = false;
+    $_exception = false;
+    // this can be decided right now, it depends only on user rights
+    $_monitor = galaxia_user_can_admin_instance($user);
+
+    $this->loadConfigValues($pId);
+
+    // check the instance status
+    // 'completed' => no action except 'view'/'viewrun' or 'abort' or 'monitor'
+    // 'aborted' =>  no action except 'view'/'viewrun' or 'monitor'
+    // 'active' => ok first add 'exception'
+    // 'exception' => first add 'resume', no 'run' or 'send' after    
+    $_view = true;
+    if ($view_activity)
+    {
+      //we should have a 'viewrun' instead of a 'view' action, but maybe we do not have access on this view activity
+      //this access right will be checked by gui_get_process_view_activity
+      $_viewrun = true;      
+      $_iframe_height =  $this->processesConfig[$pId]['iframe_view_height'];
+    }
+       
+    
+    //on readonly mode things are simplier, no more rights
+    if (!($readonly))
+    {
+      if ($instanceStatus == 'aborted')
+      {
+        $deathflow=true;
+      }
+      else
+      {
+        // first check ABORT
+        if ( ($user==$currentUser) ||
+             (($user==$instanceOwner)&&($this->processesConfig[$pId]['ownership_give_abort_right'])) ||
+             ($this->processesConfig[$pId]['role_give_abort_right']))
+        {// we are the assigned user 
+         //OR we are the owner and it gives rights
+         //OR we have the role and it gives rights
+         $_abort =true;
+        }
+        // now handle resume and exception but before detect completed instances
+        if ($instanceStatus == 'completed')
+        {
+          $deathflow=true;
+        }
+        else
+        {
+          if ($instanceStatus == 'exception')
+          {
+            $stopflow = true;
+            if ( ($user==$currentUser) ||
+                 (($user==$instanceOwner)&&($this->processesConfig[$pId]['ownership_give_exception_right'])) ||
+                 ($this->processesConfig[$pId]['role_give_exception_right']))
+            {// we are the assigned user OR we are the owner and it gives rights
+              $_resume = true;
+            }
+          }
+          elseif ($instanceStatus == 'active')
+          {
+            //handle rules about ownership
+            if ( ($user==$currentUser) ||
+                (($user==$instanceOwner)&&($this->processesConfig[$pId]['ownership_give_exception_right'])) ||
+                ($this->processesConfig[$pId]['role_give_exception_right']))
+            {// we are the assigned user OR we are the owner and it gives rights
+              $_exception = true;
+            }
+          }
+        }
+      }
+  
+      //now we check the activity
+      // start (only uncompleted) and standalone activities have no instance associated.
+      // If we are not in a 'stop' or 'death' flow we can check interactivity
+      // interactive -> run
+      // not interactive -> send (except for 'standalone')
+      // if we are not in a 'death flow' we can add grab and release actions
+      if ( ($actType=='standalone') || (($actType=='start') && (!($actStatus=='completed'))) )
+      {
+        $associated_instance=false;
+        // there's no instance to view in fact
+        $_view = false;
+        $_viewrun = false;
+      }
+      if (($actInteractive=='y') && (!($deathflow)))
+      {
+        if ($associated_instance)
+        {
+            if ($currentUser=='*')
+            {
+              $_grab = true;
+            }
+            else
+            {
+              if ( ($user==$currentUser) ||
+                 (($user==$instanceOwner)&&($this->processesConfig[$pId]['ownership_give_release_right'])) ||
+                 ($this->processesConfig[$pId]['role_give_release_right']))
+              {// we are the assigned user 
+               //OR we are the owner and it gives rights
+               //OR we have the role and it gives rights
+                $_release = true;
+              }
+            }
+        }
+        if (($actStatus=='running') && !($stopflow) && !($deathflow))
+        {
+          if (($currentUser=='*') || ($currentUser==$user))
+          {
+            $_run = true;
+          }
+        }
+      }
+      //for non autorouted activities we'll have to send, useless on standalone but usefull for start
+      //activities which can be sended if completed and of course for all other activities
+      if ($actAutorouted=='n')
+      {
+        if ($associated_instance)
+        {
+          if (($actStatus=='completed') && !($stopflow) && !($deathflow))
+          {
+            $_send = true;
+          }
+        }
+      }
+    }//end if !$readonly
+	
+    //build final array
+    if ($_run) $result['run']=tra('Execute this activity');
+    if ($_send) $result['send']=tra('Send this instance to the next activity');
+    if ($_grab) $result['grab']=tra('Assign me this activity');
+    if ($_release) $result['release']=tra('Release access to this activity');
+    if ($_abort) $result['abort']=tra('Abort this instance');
+    if ($_view) $result['view']=tra('View this instance');
+    if ($_viewrun) $result['viewrun']= array('lang' => tra('View this instance'), 'link' => $view_activity);
+    if ($_iframe_height) $result['viewrun']['iframe_height'] = $_iframe_height;
+    if ($_resume) $result['resume']=tra('Resume this exception instance');
+    if ($_exception) $result['exception']=tra('Exception this instance');
+    if ($_monitor) $result['monitor']=tra('Monitor this instance');   
+ 
+    return $result;
+  }
+
+  
+}
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/Process.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/Process.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/Process.php	(revision 2372)
@@ -0,0 +1,274 @@
+<?php
+require_once (GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+/**
+ * Represents the process that is being executed when an activity
+ * is executed. You can access this class methods using $process from any activity.
+ * No need to instantiate a new object
+ *
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Process extends Base {
+	/**
+	* @var string $name
+	* @access protected 
+	*/
+	var $name;
+	/**
+	* @var string $description
+	* @access protected 
+	*/
+	var $description;
+	/**
+	* @var int $version
+	* @access protected 
+	*/
+	var $version;
+	/**
+	* @var string $normalizedName
+	* @access protected 
+	*/
+	var $normalizedName;
+	/**
+	* @var string $pId Process id
+	* @access protected 
+	*/
+	var $pId = 0;
+	/**
+	* @var array $config
+	* @access protected 
+	*/
+	var $config = array();
+
+	/**
+	 * Constructor
+	 *
+	 * @param object $db
+	 * @return object
+	 * @access public
+	 */
+	function Process() 
+	{
+		$this->child_name = 'Process';
+		parent::Base();
+	}
+
+  	/**
+  	 * Loads a process from the database
+  	 *
+  	 * @param int $pId
+  	 * @return bool
+  	 * @access public
+  	 */
+	function getProcess($pId) 
+	{
+		$query = "select * from `".GALAXIA_TABLE_PREFIX."processes` where `wf_p_id`=?";
+		$result = $this->query($query,array($pId));
+		if(!$result->numRows()) return false;
+		$res = $result->fetchRow();
+		$this->name = $res['wf_name'];
+		$this->description = $res['wf_description'];
+		$this->normalizedName = $res['wf_normalized_name'];
+		$this->version = $res['wf_version'];
+		$this->pId = $res['wf_p_id'];
+		//config is load only on the first getConfigValues call
+	}
+  
+  /**
+   * Gets the process Id
+   *
+   * @return int
+   * @access public
+   */
+	function getProcessId() 
+	{
+		return $this->pId;
+	}
+  
+  /**
+   * Gets the normalized name of the process
+   *
+   * @return string
+   * @access public
+   */
+	function getNormalizedName() 
+	{
+		return $this->normalizedName;
+	}
+  
+	/**
+	 * Gets the process name
+	 *
+	 * @return string
+	 * @access public
+	 */
+	function getName() 
+	{
+		return $this->name;
+	}
+  
+	/**
+	 * Gets the process version
+	 *
+	 * @return int
+	 * @access public
+	 */
+	function getVersion() 
+	{
+		return $this->version;
+	}
+
+  /**
+   * Gets information about an activity in this process by name
+   *
+   * @param string $actname
+   * @return array
+   * @access public
+   */
+	function getActivityByName($actname) 
+	{
+		// Get the activity data
+		$query = "select * from `".GALAXIA_TABLE_PREFIX."activities` where `wf_p_id`=? and `wf_name`=?";
+		$pId = $this->pId;
+		$result = $this->query($query,array($pId,$actname));
+		if(!$result->numRows()) return false;
+		$res = $result->fetchRow();
+		return $res;
+	}
+
+	/**
+	 * Store config values for this process
+	 *
+	 * @param array $parameters pairs of (config_variables_names => (type => value))
+     * type can be int or text, anything else is considered text
+     * int value of -1 is considered as 'default global configuration option'. So nothing
+     * will be stored for this process (and existing values are erased)
+	 * @return bool
+	 * @access public
+	 */
+	function setConfigValues(&$parameters) 
+	{
+		if (!is_array($parameters))
+		{
+		  return false;
+		}
+		$array_delete=array();
+		$array_set=array();
+		$pId = (string)$this->pId;
+		foreach ($parameters as $config_var => $config_value)
+		{
+		  //all config values will be deleted
+		  $array_delete[] = array($pId, $config_var);
+		  
+		  //foreach but normally there's only one loop
+		  foreach($config_value as $value_type => $value_zone)
+		  {
+		    $ok = true;
+		    if ($value_type=='int')
+		    {
+		      //special value, refer to global config values for this process conf variable
+		      //we don't want any value stored for this process conf variable
+		      //so we break the foreach before setting the $array_set
+		      if ($value_zone == -1)
+		      {
+		        $ok=false;
+		        break;
+		      }
+		      //else it's classic
+		      $value_int = $value_zone;
+		      $value= '';
+		    }
+		    else
+		    {
+		      $value = $value_zone;
+		      $value_int = null;
+		    }
+		  }
+		  //we are going to set this config value if $ok says so
+		  if ($ok) $array_set[] = array($config_var, $value, $value_int, $pId);
+		}
+		//delete previous config values if they are in a bulk statement
+		if (count($array_delete)>0) 
+		{
+		  $result= $this->query("DELETE from ".GALAXIA_TABLE_PREFIX."process_config where wf_p_id=? and wf_config_name=?",$array_delete, -1,-1,true,'',true);
+		}
+		//insert in a bulk statement
+		if (count($array_set)>0) 
+		{
+		    $result= $this->query("INSERT into ".GALAXIA_TABLE_PREFIX."process_config 
+		      (wf_config_name,wf_config_value,wf_config_value_int,wf_p_id) values (?,?,?,?)"
+		      ,$array_set, -1,-1,true,'', true);
+		}
+	}
+  
+	/**
+	 * Gets all the process configuration values. The configuration data is then cached for this process object life
+	 *
+	 * @param array $parameters pairs of (config_variables_names => default_values)
+     * For a variable name which has no previous value and no global value (default process value)
+     * it will return default_value and this default value will be the NEW STORED value 
+     * If no default value is given we assume it's a false
+	 * @return array
+	 * @access public
+	 */
+	function getConfigValues(&$parameters) 
+	{
+		if (!is_array($parameters))
+		{
+		  return false;
+		}
+		if (count($this->config) == 0) 
+		{ // first time we come
+		  // Get all the config data for this process
+		  $query = "select * from ".GALAXIA_TABLE_PREFIX."process_config where wf_p_id=?";
+		  $pId = $this->pId;
+		  $result = $this->query($query,array($pId));
+		
+		  if($result->numRows()>0) 
+		  {
+		    //we add process datas for some config_name, we store it in $this->config
+		    while ($res=$result->fetchRow())
+		    {
+		      //int values are not stored in the same field
+		      $int_value= $res['wf_config_value_int'];
+		      if (isset($int_value))
+		      {
+		        $this->config[$res['wf_config_name']] = $int_value;
+		      }
+		      else
+		      {
+		        $this->config[$res['wf_config_name']] = $res['wf_config_value'];
+		      }
+		    }
+		  }
+		}// the second time we jump here
+		
+		//parse config_name asked
+		$local_array = array();
+		$global_default_array = array();
+		foreach ($parameters as $config_var => $default_value)
+		{
+		  if (isset($this->config[$config_var]))
+		  {// we already know this config value
+		    //echo "<br>ok we had one for ".$config_var;
+		    $local_array[$config_var] = $this->config[$config_var];
+		  }
+		  else
+		  {
+		    // we have no value for it here, we'll ask it in the global conf
+		    //echo "<br>we had nothing for ".$config_var;
+		    $global_default_array[$config_var] = $default_value;
+		  }
+		}
+		
+		// if we have some not set value that we need to check in global conf
+		if (count($global_default_array) > 0)
+		{
+		  $global_array =& galaxia_get_config_values($global_default_array);
+		}
+		$result = (array)$local_array + (array)$global_array;
+		return $result;
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/View.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/View.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/View.php	(revision 2372)
@@ -0,0 +1,25 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'view'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class View extends BaseActivity 
+{
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */	
+	function View()
+	{
+	 	parent::Base();
+		$this->child_name = 'View';
+	}
+	
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/Split.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/Split.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/Split.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'split'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Split extends BaseActivity {
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */
+	function Split()
+	{
+	 	parent::Base();
+		$this->child_name = 'Split';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/Activity.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/Activity.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/Activity.php	(revision 2372)
@@ -0,0 +1,25 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'activity'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Activity extends BaseActivity 
+{
+	/**
+	 * Constructor
+	 * 
+	 * @param object &$db ADOdb
+	 * @return object Activity instance
+	 * @access public
+	 */
+	function Activity()
+	{
+		parent::Base();
+		$this->child_name = 'Activity';
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/Start.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/Start.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/Start.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'start'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Start extends BaseActivity {
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */
+	function Start()
+	{
+	 	parent::Base();
+		$this->child_name = 'Start';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/SwitchActivity.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/SwitchActivity.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/SwitchActivity.php	(revision 2372)
@@ -0,0 +1,24 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'switch'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class SwitchActivity extends BaseActivity 
+{
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */
+	function SwitchActivity()
+	{
+	   parent::Base();
+	   $this->child_name = 'Switch';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/Join.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/Join.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/Join.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'join'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Join extends BaseActivity {
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */
+	function Join()
+	{
+	 	parent::Base();
+		$this->child_name = 'Join';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/End.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/End.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/End.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'end'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class End extends BaseActivity {
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */
+	function End()
+	{
+	 	parent::Base();
+		$this->child_name = 'End';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/activities/Standalone.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/activities/Standalone.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/activities/Standalone.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
+/**
+ * Handles activities of type 'standalone'
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Standalone extends BaseActivity {
+	/**
+	 * Constructor
+	 * 
+	 * @param object $db ADOdb
+	 * @return object Class instance
+	 * @access public
+	 */
+	function Standalone()
+	{
+	 	parent::Base();
+		$this->child_name = 'Standalone';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/Role.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/Role.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/Role.php	(revision 795)
@@ -0,0 +1,13 @@
+<?php
+require_once (GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+/**
+ * Represents a role
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @todo Implement this class 
+ */
+class Role extends Base {
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/Workitem.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/Workitem.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/Workitem.php	(revision 795)
@@ -0,0 +1,38 @@
+<?php
+require_once (GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+/**
+ * Represents workitems
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @todo Implement this class 
+ */
+class Workitem extends Base 
+{
+	/**
+	 * @var object $instance
+	 * @access public
+	 */
+	var $instance;
+	/**
+	 * @var array $properties
+	 * @access public
+	 */	
+	var $properties=Array();
+	/**
+	 * @var int $started
+	 * @access public
+	 */
+	var $started;
+	/**
+	 * @var int $ended
+	 * @access public
+	 */
+	var $ended;
+	/**
+	 * @var object $activity
+	 * @access public
+	 */
+	var $activity;  
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/Instance.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/Instance.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/Instance.php	(revision 2372)
@@ -0,0 +1,1800 @@
+<?php
+require_once (GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'ActivityManager.php');
+
+/**
+ * This class represents a process instance, it is used when any activity is
+ * executed. The $instance object is created representing the instance of a
+ * process being executed in the activity or even a to-be-created instance
+ * if the activity is a start activity
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class Instance extends Base {
+  /**
+   * @var array $changed Changed instance object's members
+   * @access protected 
+   */
+  var $changed = Array('properties' => Array(), 'nextActivity' => Array(), 'nextUser' => Array());
+  /**
+   * @var array $properties Instance properties
+   * @access protected
+   */
+  var $properties = Array();
+  /**
+   * @var array $cleared Used to detect conflicts on sync with the database
+   * @access protected
+   */  
+  var $cleared = Array();
+  /**
+   * @var string  $owner Instance owner
+   * @access protected
+   */  
+  var $owner = '';
+  /**
+   * @var string $status Instance status
+   * @access protected
+   */  
+  var $status = '';
+  /**
+   * @var bool $started
+   * @access protected
+   */  
+  var $started;
+  /**
+   * @var array $nextActivity
+   * @access protected
+   */  
+  var $nextActivity=Array();
+  /**
+   * @var string $nextUser
+   * @access protected
+   */  
+  var $nextUser;
+  /**
+   * @var bool $ended
+   * @access protected
+   */  
+  var $ended;
+  /**
+   * @var string $name Instance name
+   * @access protected
+   */
+  var $name='';
+  /**
+   * @var string $category Instance category
+   * @access protected
+   */
+  var $category;
+  /**
+   * @var int $prioryty Instance priority
+   * @access protected
+   */
+  var $priority = 1;
+
+  /**
+   * @var bool $isChildInstance Indicates wether the current instance is a child instance or not
+   * @access public
+   */
+  var $isChildInstance = false;
+  /**
+   * @var bool $parentLock Indicates wether the parent instance depends on the child instance or not
+   * @access public
+   */
+  var $parentLock = false;
+  /**
+   * @var int $parentActivityId The activity ID of the parent instance
+   * @access public
+   */
+  var $parentActivityId;
+  /**
+   * @var int $parentInstanceId The instance ID of the parent instance
+   * @access public
+   */
+  var $parentInstanceId;
+
+  /**
+   * @var array $activities Array of assocs(activityId, status, started, ended, user, name, interactivity, autorouting)
+   * @access protected
+   */
+  var $activities = Array();
+  /**
+   * @var int $pIdProcess id
+   * @access protected
+   */
+  var $pId;
+  /**
+   * @var int $instanceId Instance id
+   * @access protected
+   */
+  var $instanceId = 0;
+  /**
+   * @var array $workitems An array of workitem ids, date, duration, activity name, user, activity type and interactivity
+   * @access protected
+   */
+  var $workitems = Array(); 
+  /**
+   * @var object $security Performs some tests and locks
+   * @access protected
+   */
+  var $security;
+  /**
+   * @var bool $__activity_completed Internal reminder
+   * @access protected
+   */
+  var $__activity_completed=false;
+  /**
+   * @var bool $unsynch indicator, if true we are not synchronised in the memory object with the database 
+   * @see sync()
+   * @access protected
+   */
+  var $unsynch=false;
+  
+  /**
+   * Constructor
+   * 
+   * @param object $db ADOdb object
+   * @access public
+   */
+
+  var $activityID = null;
+  function Instance() 
+  {
+    $this->child_name = 'Instance';
+    parent::Base();
+  }
+
+  /**
+   * Method used to load an instance data from the database.
+   * This function will load/initialize members of the instance object from the database
+   * it will populatae all members and will by default populate the related activities array
+   * and the workitems (history) array.
+   * 
+   * @param int $instanceId
+   * @param bool $load_activities true by default, do we need to reload activities from the database?
+   * @param bool $load_workitems true by default, do we need to reload workitems from the database?  
+   * @return bool 
+   * @access protected
+   */
+  function getInstance($instanceId, $load_activities=true, $load_workitems=true) 
+  {
+    if (!($instanceId)) return true; //start activities for example - pseudo instances
+    // Get the instance data
+    $query = "select * from `".GALAXIA_TABLE_PREFIX."instances` where `wf_instance_id`=?";
+    $result = $this->query($query,array((int)$instanceId));
+    if( empty($result) || (!$result->numRows())) return false;
+    $res = $result->fetchRow();
+
+    //Populate 
+    $this->properties = unserialize(base64_decode($res['wf_properties']));
+    $this->status = $res['wf_status'];
+    $this->pId = $res['wf_p_id'];
+    $this->instanceId = $res['wf_instance_id'];
+    $this->priority = $res['wf_priority'];
+    $this->owner = $res['wf_owner'];
+    $this->started = $res['wf_started'];
+    $this->ended = $res['wf_ended'];
+    $this->nextActivity = unserialize(base64_decode($res['wf_next_activity']));
+    $this->nextUser = unserialize(base64_decode($res['wf_next_user']));
+    $this->name = $res['wf_name'];
+    $this->category = $res['wf_category'];
+
+    // Get the activities where the instance is (nothing for start activities)
+    if ($load_activities)
+    {
+      $this->_populate_activities($instanceId);
+
+    }
+    
+    // Get the workitems where the instance is
+    if ($load_workitems)
+    {
+      $query = "select wf_item_id, wf_order_id, gw.wf_instance_id, gw.wf_activity_id, wf_started, wf_ended, gw.wf_user,
+              ga.wf_name, ga.wf_type, ga.wf_is_interactive
+              from ".GALAXIA_TABLE_PREFIX."workitems gw
+              INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON ga.wf_activity_id = gw.wf_activity_id
+              where wf_instance_id=? order by wf_order_id ASC";
+      $result = $this->query($query,array((int)$instanceId));
+      if (!(empty($result)))
+      {
+        while($res = $result->fetchRow()) 
+        {
+          $this->workitems[]=$res;
+        }
+      }
+      return true;
+    }
+    
+  }
+  
+  /**
+   * Loads all activities related to the insance given in parameter in the activities array
+   * 
+   * @access private
+   * @param int $instanceId
+   */
+  function _populate_activities($instanceId)
+  {
+    $this->activities=Array();
+    $query = "select gia.wf_activity_id, gia.wf_instance_id, wf_started, wf_ended, wf_started, wf_user, wf_status,
+            ga.wf_is_autorouted, ga.wf_is_interactive, ga.wf_name, ga.wf_type
+            from ".GALAXIA_TABLE_PREFIX."instance_activities gia
+            INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON ga.wf_activity_id = gia.wf_activity_id
+            where wf_instance_id=?";
+    $result = $this->query($query,array((int)$instanceId));
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow())
+      {
+        $this->activities[] = $res;
+      }
+    }
+  }
+
+  /**
+   * Performs synchronization on an instance member
+   * 
+   * @param bool $changed
+   * @param array $init 
+   * @param array $actual 
+   * @param string $name 
+   * @param string $fieldname 
+   * @param array $namearray
+   * @param array $vararray 
+   * @return void 
+   * @access private
+   */
+  function _synchronize_member(&$changed,&$init,&$actual,$name,$fieldname,&$namearray,&$vararray)
+  {
+    //if we work with arrays then it's more complex
+    //echo "<br>$name is_array?".(is_array($changed)); _debug_array($changed);
+    if (!(is_array($changed)))
+    {
+      if (isset($changed))
+      {
+        //detect unsynchro
+        if (!($actual==$init))
+        {
+          $this->error[] = tra('Instance: unable to modify %1, someone has changed it before us', $name);
+        }
+        else
+        {
+          $namearray[] = $fieldname;
+          $vararray[] = $changed;
+          $actual = $changed;
+        }
+        unset ($changed);
+      }
+    }
+    else //we are working with arrays (properties for example)
+    {
+      $modif_done = false;
+      foreach ($changed as $key => $value)
+      {
+        //detect unsynchro
+        if (!($actual[$key]==$init[$key]))
+        {
+          $this->error[] = tra('Instance: unable to modify %1 [%2], someone has changed it before us', $name, $key);
+        }
+        else
+        {
+          $actual[$key] = $value;
+          $modif_done = true;
+        }
+      }
+      if ($modif_done) //at least one modif
+      {
+        $namearray[] = $fieldname;
+        //no more serialize, done by the core security_cleanup
+        $vararray[] = $actual; //serialize($actual);
+      }   
+      $changed=Array();
+    }
+  }
+  
+  /**
+   * Synchronize thes instance object with the database. All change smade will be recorded except
+   * conflicting ones (changes made on members or properties that has been changed by another source
+   * --could be another 'instance' of this instance or an admin form-- since the last call of sync() )
+   * the unsynch private member is used to test if more heavy tests should be done or not
+   * pseudo instances (start, standalone) are not synchronised since there is no record on database
+   * 
+   * @access public
+   * @return bool  
+   */
+  function sync()
+  {
+    if ( (!($this->instanceId)) || (!($this->unsynch)) )
+    {
+      //echo "<br>nothing to do ".$this->unsynch;
+      return true;
+    }
+    //echo "<br> synch!";_debug_array($this->changed);
+    //do it in a transaction, can have several activities running
+    $this->db->StartTrans();
+    //we need to make a row lock now,
+    $where = 'wf_instance_id='.(int)$this->instanceId;
+    if (!($this->db->RowLock(GALAXIA_TABLE_PREFIX.'instances', $where)))
+    {
+      $this->error[] = 'sync: '.tra('failed to obtain lock on %1 table', 'instances');
+      $this->db->FailTrans();
+    }
+    else
+    {
+      //wf_p_id and wf_instance_id are set in creation only.
+      //we remember initial values
+      $init_properties = $this->properties;
+      $init_status = $this->status;
+      $init_priority = $this->priority;
+      $init_owner = $this->owner;
+      $init_started = $this->started;
+      $init_ended = $this->ended;
+      $init_nextUser = $this->nextUser;
+      $init_nextActivity = $this->nextActivity;
+      $init_name = $this->name;
+      $init_category = $this->category;
+      // we re-read instance members to detect conflicts, changes made while we were unsynchronised
+      $this->getInstance($this->instance_id, false, false);
+      // Now for each modified field we'll change the database vale if nobody has changed
+      // the database value before us
+      // (Drovetto) Inclusion of the nextUser field in the synchronization
+      $bindvars = Array();
+      $querysets = Array();
+      $queryset = '';
+      $this->_synchronize_member($this->changed['status'],$init_status,$this->status,tra('status'),'wf_status',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['priority'],$init_priority,$this->priority,tra('priority'),'wf_priority',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['owner'],$init_owner,$this->owner,tra('owner'),'wf_owner',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['started'],$init_started,$this->started,tra('started'),'wf_started',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['ended'],$init_ended,$this->ended,tra('ended'),'wf_ended',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['name'],$init_name,$this->name,tra('name'),'wf_name',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['category'],$init_category,$this->category,tra('category'),'wf_category',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['properties'],$init_properties,$this->properties,tra('property'),'wf_properties',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['nextUser'],$init_nextUser,$this->nextUser,tra('next user'),'wf_next_user',$querysets,$bindvars);
+      $this->_synchronize_member($this->changed['nextActivity'],$init_nextActivity,$this->nextActivity,tra('next activity'),'wf_next_activity',$querysets,$bindvars);
+      /* remove unsetted properties */
+      if (($propertiesIndex = array_search("wf_properties", $querysets)) !== false)
+        foreach ($this->cleared as $clearedName)
+          unset($bindvars[$propertiesIndex][$clearedName]);
+      /* remove unsetted nextUser */
+      if (($nextUserIndex = array_search("wf_next_user", $querysets)) !== false)
+        foreach ($bindvars[$nextUserIndex] as $nextUserKey => $nextUserValue)
+          if ($bindvars[$nextUserIndex][$nextUserKey] == '__UNDEF__')
+          {
+            unset($bindvars[$nextUserIndex][$nextUserKey]);
+            unset($this->nextUser[$nextUserKey]);
+          }
+      if (!(empty($querysets)))
+      {
+        $queryset = implode(' = ?,', $querysets). ' = ?';
+        $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set '.$queryset
+              .' where wf_instance_id=?';
+        $bindvars[] = $this->instanceId;
+        //echo "<br> query $query"; _debug_array($bindvars);
+        $this->query($query,$bindvars);
+      }
+    }
+    if (!($this->db->CompleteTrans()))
+    {
+      $this->error[] = tra('failed to synchronize instance data with the database');
+      return false;
+    }
+
+    //we are not unsynchronized anymore.
+    $this->unsynch = false;
+    return true;
+  }
+  
+  /**
+   * Sets the next activity to be executed, if the current activity is
+   * a switch activity the complete() method will use the activity setted
+   * in this method as the next activity for the instance. 
+   * The object records an array of transitions, as the instance can be splitted in several 
+   * running activities, transition from the current activity to the given activity will
+   * be recorded and all previous recorded transitions starting from the current activity
+   * will be deleted
+   * 
+   * @param int $activityId Running activity Id 
+   * @param string $actname Activity name as argument (not an id)
+   * @return bool
+   * @access public  
+   */
+  function setNextActivity($activityId, $actname) 
+  {
+    $pId = $this->pId;
+    $actname=trim($actname);
+    $aid = $this->getOne('select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_name=?',array($pId,$actname));
+    if (!($aid))
+    {
+      $this->error[] = tra('setting next activity to an unexisting activity');
+      return false;
+    }
+    $this->changed['nextActivity'][$activityId]=$aid;
+    $this->unsynch = true;
+    return true;
+  }
+
+  /**
+   * This method can be used to set the user that must perform the next 
+   * activity of the process. this effectively "assigns" the instance to
+   * some user
+   * 
+   * @param mixed $user The user which will execute the next activity
+   * @param mixed $activityID The ID of the activity that the user will be able to execute. '*' means any next activity
+   * @return bool true in case of success or false otherwise
+   * @access public
+   */
+  function setNextUser($user, $activityID = '*')
+  {
+    if ($activityID == '*')
+    {
+      $candidates = $this->getActivityCandidates($this->activityID);
+      foreach ($candidates as $candidate)
+        $this->changed['nextUser'][$candidate] = $user;
+    }
+    else
+      $this->changed['nextUser'][$activityID] = $user;
+    $this->unsynch = true;
+    return true;
+  }
+
+  /**
+   * Sets next instance user role
+   *
+   * @param string $roleName The name of the role
+   * @param mixed $activityID The ID of the activity that the role will be able to execute. '*' means any next activity
+   * @return bool true in case of success or false otherwise
+   * @access public
+   */
+  function setNextRole($roleID, $activityID = '*')
+  {
+    return $this->setNextUser('p' . $roleID, $activityID);
+  }
+
+  /**
+   * Removes the user/role of the provided activity ID
+   *
+   * @param mixed $activityID The ID of the activity from which the users/roles will be removed.
+   * @return void
+   * @access public
+   */
+  function unsetNextUser($activityID = '*')
+  {
+    $this->setNextUser('__UNDEF__', $activityID);
+  }
+
+  /**
+   * This method can be used to get the user that must perform the next 
+   * activity of the process. This can be empty if no setNextUser was done before.
+   * It wont return the default user but inly the user which was assigned by a setNextUser
+   * 
+   * @param mixed $activityID The ID of the activity from which we want the user/role that will execute it.
+   * @return string
+   * @access public
+   */
+  function getNextUser($activityID = '*')
+  {
+    if ($activityID == '*')
+      $order = array('*' . $this->activityID);
+    else
+      $order = array($activityID, '*' . $this->activityID);
+    foreach ($order as $currentOrder)
+    {
+      if (isset($this->changed['nextUser'][$currentOrder]) && ($this->changed['nextUser'][$currentOrder] == '__UNDEF__'))
+        continue;
+      if (isset($this->changed['nextUser'][$currentOrder]))
+        return $this->changed['nextUser'][$currentOrder];
+      if (isset($this->nextUser[$currentOrder]))
+        return $this->nextUser[$currentOrder];
+    }
+    return '';
+  }
+ 
+  /**
+   * Creates a new instance.
+   * This method is called in start activities when the activity is completed
+   * to create a new instance representing the started process.
+   *
+   * @param int $activityId start activity id
+   * @param int $user current user id
+   * @return bool
+   * @access private
+   */
+  function _createNewInstance($activityId,$user) {
+    // Creates a new instance setting up started, ended, user, status and owner
+    $pid = $this->getOne('select wf_p_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_activity_id=?',array((int)$activityId));
+    $this->pId = $pid;
+    $this->setStatus('active');
+    //$this->setNextUser('');
+    $now = date("U");
+    $this->setStarted($now);
+    $this->setOwner($user);
+    
+    $query = 'insert into '.GALAXIA_TABLE_PREFIX.'instances
+      (wf_started,wf_ended,wf_status,wf_p_id,wf_owner,wf_properties) 
+      values(?,?,?,?,?,?)';
+    $this->query($query,array($now,0,'active',$pid,$user,$this->security_cleanup(Array(),false)));
+    $this->instanceId = $this->getOne('select max(wf_instance_id) from '.GALAXIA_TABLE_PREFIX.'instances 
+                      where wf_started=? and wf_owner=?',array((int)$now,$user));
+    $iid=$this->instanceId;
+    
+    // Then add in ".GALAXIA_TABLE_PREFIX."instance_activities an entry for the
+    // activity the user and status running and started now
+    $query = 'insert into '.GALAXIA_TABLE_PREFIX.'instance_activities (wf_instance_id,wf_activity_id,wf_user,
+            wf_started,wf_status) values(?,?,?,?,?)';
+    $this->query($query,array((int)$iid,(int)$activityId,$user,(int)$now,'running'));
+
+    if (($this->isChildInstance) && (!is_null($this->parentInstanceId)))
+    {
+      $query = 'INSERT INTO '.GALAXIA_TABLE_PREFIX.'interinstance_relations(wf_parent_instance_id, wf_parent_activity_id, wf_child_instance_id, wf_parent_lock) VALUES(?,?,?,?)';
+      $this->query($query,array((int) $this->parentInstanceId, (int) $this->parentActivityId, (int) $iid, (int) (($this->parentLock) ? 1 : 0)));
+    }
+    
+    //update database with other datas stored in the object
+    return $this->sync();
+  }
+  
+  /**
+   * Sets the name of this instance
+   *
+   * @param string $value
+   * @return bool
+   * @access public
+   */
+  function setName($value) 
+  {
+    $this->changed['name'] = substr($value,0,120);
+    $this->unsynch = true;
+    return true;
+  }
+
+  /**
+   * Get the name of this instance
+   *
+   * @return string
+   * @access public
+   */
+  function getName() 
+  {
+    if (!(isset($this->changed['name'])))
+    {
+      return $this->name;
+    }
+    else
+    {
+      return $this->changed['name'];
+    }
+  }
+
+  /**
+   * Sets the category of this instance
+   *
+   * @param string $value
+   * @return bool
+   * @access public
+   */
+  function setCategory($value) 
+  {
+    $this->changed['category'] = $value;
+    $this->unsynch = true;
+    return true;
+  }
+
+  /**
+   * Get the category of this instance
+   *
+   * @return string
+   * @access public
+   */
+  function getCategory() 
+  {
+    if (!(isset($this->changed['category'])))
+    {
+      return $this->category;
+    }
+    else
+    {
+      return $this->changed['category'];
+    }
+  }
+
+  /**
+   * Normalizes a property name
+   *
+   * @param string $name name you want to normalize
+   * @return string property name
+   * @access private
+   */
+  function _normalize_name($name)
+  {
+    $name = trim($name);
+    $name = str_replace(" ","_",$name);
+    $name = preg_replace("/[^0-9A-Za-z\_]/",'',$name);
+    return $name;
+  }
+
+  /**
+   * Sets a property in this instance. This method is used in activities to
+   * set instance properties.
+   * all property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces). If you have several set to call look
+   * at the setProperties function. Each call to this function has an impact on database
+   *
+   * @param string $name property name (it will be normalized)
+   * @param mixed $value value you want for this property
+   * @return bool
+   * @access public
+   */
+  function set($name,$value) 
+  {
+    $name = $this->_normalize_name($name);
+    unset($this->cleared[$name]);
+    $this->changed['properties'][$name] = $this->security_cleanup($value);
+    if (is_array($value))
+      $this->changed['properties'][$name] = "__ARRAY__" . $this->changed['properties'][$name];
+    $this->unsynch = true;
+    return true;
+  }
+  
+  /**
+   * Unsets a property in this instance. This method is used in activities to
+   * unset instance properties.
+   * All property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces). Each call to this function has an impact on database
+   *
+   * @param string $name the property name (it will be normalized)
+   * @return bool
+   * @access public
+   */
+  function clear($name)
+  {
+    $this->set($name, '');
+    $this->cleared[$name] = $name;
+    $this->unsynch = true;
+    return true;
+  }
+
+  /**
+   * Checks if a property in this instance exists. This method is used in activities to
+   * check the existance of instance properties.
+   * All property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces).
+   *
+   * @param string $name property name (it will be normalized)
+   * @return bool
+   * @access public
+   */
+  function exists($name)
+  {
+    $name = $this->_normalize_name($name);
+
+    return ((isset($this->changed['properties'][$name]) || isset($this->properties[$name])) && !isset($this->cleared[$name]));
+  }
+
+  /**
+   * Sets several properties in this instance. This method is used in activities to
+   * set instance properties. Use this method if you have several properties to set
+   * as it will avoid to re-call the SQL engine for each property.
+   * all property names are normalized for security reasons and to avoid localisation
+   * problems (A->z, digits and _ for spaces). 
+   *
+   * @param array $properties_array associative array containing for each record the
+   * property name as the key and the property value as the value
+   * @return bool
+   * @access public
+   */
+  function setProperties($properties_array) 
+  {
+    $backup_values = $this->properties;
+    foreach ($properties_array as $key => $value)
+    {
+      $name = $this->_normalize_name($key);
+      $this->changed['properties'][$name] = $this->security_cleanup($value);
+    }
+    $this->unsynch = true;
+    return true;
+  }
+  
+  /**
+   * Gets the value of an instance property
+   *
+   * @param string $name name of the property
+   * @param mixed $defaultValue
+   * @return bool
+   * @access public
+   */
+  function get($name, $defaultValue = "__UNDEF__")
+  {
+    $name = $this->_normalize_name($name);
+    $output = "";
+
+    /* select the value of the current property */
+    if (isset($this->changed['properties'][$name]))
+    {
+      $output = $this->changed['properties'][$name];
+    }
+    else
+    {
+      if (isset($this->properties[$name]))
+      {
+        $output = $this->properties[$name];
+      }
+    }
+
+    /* if the property doesn't exist return the default value or throw an error */
+    if (isset($this->cleared[$name]) || ((!isset($this->properties[$name])) && (!isset($this->changed['properties'][$name]))))
+    {
+      if ($defaultValue != "__UNDEF__")
+      {
+        $output = $defaultValue;
+      }
+      else
+      {
+        $this->error[] = tra('property %1 not found', $name);
+        $output = false;
+      }
+    }
+
+    /* if the requested value is an enconded/serialized array, change it back to its original type */
+    if (@strcmp(@substr($output, 0, 9), "__ARRAY__") == 0)
+      if ( ($tmp = base64_decode(substr($output, 9))) !== false )
+        if ( ($tmp = unserialize($tmp)) !== false )
+          $output = $tmp;
+    return $output;
+  }
+  
+  /**
+   * Returns an array of assocs describing the activities where the instance
+   * is present, can be more than one activity if the instance was "splitted"
+   *
+   * @return array
+   * @access public
+   */
+  function getActivities() {
+    return $this->activities;
+  }
+  
+  /**
+   * Gets the instance status can be
+   * 'completed', 'active', 'aborted' or 'exception'
+   *
+   * @return string
+   * @access public
+   */
+  function getStatus() {
+    if (!(isset($this->changed['status'])))
+    {
+      return $this->status;
+    }
+    else
+    {
+      return $this->changed['status'];
+    }
+  }
+  
+  /**
+   * Sets the instance status
+   *
+   * @param string_type $status it can be: 'completed', 'active', 'aborted' or 'exception'
+   * @return bool
+   * @access public
+   */
+  function setStatus($status) 
+  {
+    if (!(($status=='completed') || ($status=='active') || ($status=='aborted') || ($status=='exception')))
+    {
+      $this->error[] = tra('unknown status');
+      return false;
+    }
+    $this->changed['status'] = $status; 
+    $this->unsynch = true;
+    return true;
+  }
+  
+  /**
+   * Gets the instance priority
+   *
+   * @return int
+   * @access public
+   */
+  function getPriority()
+  {
+    if (!(isset($this->changed['priority'])))
+    {
+      return $this->priority;
+    }
+    else
+    {
+      return $this->changed['priority'];
+    }
+  } 
+
+  /**
+   * Sets the instance priority
+   *
+   * @param int $priority
+   * @return bool
+   * @access public
+   */
+  function setPriority($priority)
+  {
+    $mypriority = (int)$priority;
+    $this->changed['priority'] = $mypriority;
+    $this->unsynch = true;
+    return true;
+  }
+   
+  /**
+   * Returns the instanceId
+   *
+   * @return int
+   * @access public
+   */
+  function getInstanceId() 
+  {
+    return $this->instanceId;
+  }
+  
+  /**
+   * Returns the processId for this instance
+   *
+   * @return int
+   * @access public
+   */
+  function getProcessId() 
+  {
+    return $this->pId;
+  }
+  
+  /**
+   * Returns the user that created the instance
+   *
+   * @return int
+   * @access public
+   */
+  function getOwner() 
+  {
+    if (!(isset($this->changed['owner'])))
+    {
+      return $this->owner;
+    }
+    else
+    {
+      return $this->changed['owner'];
+    }
+  }
+  
+  /**
+   * Sets the instance creator user
+   *
+   * @param int $user new owner id, musn't be false, 0 or empty
+   * @return bool
+   * @access public
+   */
+  function setOwner($user) 
+  {
+    if (empty($user))
+    { 
+      return false;
+    }
+    $this->changed['owner'] = $user;
+    $this->unsynch = true;
+    return true;
+  }
+  
+  /**
+   * Sets the user that must execute the activity indicated by the activityId.
+   * Note that the instance MUST be present in the activity to set the user,
+   * you can't program who will execute an activity.
+   * If the user is empty then the activity user is setted to *, allowing any
+   * authorised user to take the token later concurrent access to this function 
+   * is normally handled by WfRuntime and WfSecurity theses objects are the only ones 
+   * which should call this function. WfRuntime is handling the current transaction and
+   * WfSecurity is Locking the instance and instance_activities table on a 'run' action 
+   * which is the action leading to this setActivityUser call (could be a release 
+   * as well on auto-release)
+   *
+   * @param int $activityId
+   * @param int $theuser user id or '*' (or 0, '' or null which will be set to '*')
+   * @return bool
+   * @access public
+   */
+  function setActivityUser($activityId,$theuser) {
+    if(empty($theuser)) $theuser='*';
+    $found = false;
+    for($i=0;$i<count($this->activities);$i++) {
+      if($this->activities[$i]['wf_activity_id']==$activityId) {
+        // here we are in the good activity
+        $found = true;
+
+        // prepare queries
+        $where = ' where wf_activity_id=? and wf_instance_id=?';
+        $bindvars = array((int)$activityId,(int)$this->instanceId);
+        if(!($theuser=='*')) 
+        {
+          $where .= ' and (wf_user=? or wf_user=? or wf_user LIKE ?)';
+          $bindvars[]= $theuser;
+          $bindvars[]= '*';
+          $bindvars[]= 'p%';
+        }
+        
+        // update the user
+        $query = 'update '.GALAXIA_TABLE_PREFIX.'instance_activities set wf_user=?';
+        $query .= $where;
+        $bindvars_update = array_merge(array($theuser),$bindvars);
+        $this->query($query,$bindvars_update);
+        $this->activities[$i]['wf_user']=$theuser;
+        return true;
+      }
+    }
+    // if we didn't find the activity it will be false
+    return $found;
+  }
+
+  /**
+   * Returns the user that must execute or is already executing an activity
+   * wherethis instance is present
+   *
+   * @param int $activityId
+   * @return bool
+   * @access public
+   */
+  function getActivityUser($activityId) {
+    for($i=0;$i<count($this->activities);$i++) {
+      if($this->activities[$i]['wf_activity_id']==$activityId) {
+        return $this->activities[$i]['wf_user'];
+      }
+    }  
+    return false;
+  }
+
+  /**
+   * Sets the status of the instance in some activity
+   *
+   * @param int $activityId
+   * @param string $status new status, it can be 'running' or 'completed'
+   * @return bool
+   * @access public
+   */
+  function setActivityStatus($activityId,$status) 
+  {
+    if (!(($status=='running') || ($status=='completed')))
+    {
+      $this->error[] = tra('unknown status');
+      return false;
+    }
+    for($i=0;$i<count($this->activities);$i++) 
+    {
+      if($this->activities[$i]['wf_activity_id']==$activityId) 
+      {
+        $query = 'update '.GALAXIA_TABLE_PREFIX.'instance_activities set wf_status=? where wf_activity_id=? and wf_instance_id=?';
+        $this->query($query,array($status,(int)$activityId,(int)$this->instanceId));
+        return true;
+      }
+    }
+    $this->error[] = tra('new status not set, no corresponding activity was found.'); 
+    return false;
+  }
+  
+  
+  /**
+   * Gets the status of the instance in some activity, can be
+   * 'running' or 'completed'
+   *
+   * @param int $activityId
+   * @return mixed
+   * @access public
+   */
+  function getActivityStatus($activityId) {
+    for($i=0;$i<count($this->activities);$i++) {
+      if($this->activities[$i]['wf_activity_id']==$activityId) {
+        return $this->activities[$i]['wf_status'];
+      }
+    }
+    $this->error[] = tra('activity status not avaible, no corresponding activity was found.');
+    return false;
+  }
+  
+  /**
+   * Resets the start time of the activity indicated to the current time
+   *
+   * @param int $activityId
+   * @return bool
+   * @access public
+   */
+  function setActivityStarted($activityId) {
+    $now = date("U");
+    for($i=0;$i<count($this->activities);$i++) {
+      if($this->activities[$i]['wf_activity_id']==$activityId) {
+        $this->activities[$i]['wf_started']=$now;
+        $query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `wf_started`=? where `wf_activity_id`=? and `wf_instance_id`=?";
+        $this->query($query,array($now,(int)$activityId,(int)$this->instanceId));
+        return true;
+      }
+    }
+    $this->error[] = tra('activity start not set, no corresponding activity was found.');
+    return false;
+  }
+  
+  /**
+   * Gets the Unix timstamp of the starting time for the given activity
+   *
+   * @param int $activityId
+   * @return mixed
+   * @access public
+   */
+  function getActivityStarted($activityId) {
+    for($i=0;$i<count($this->activities);$i++) {
+      if($this->activities[$i]['wf_activity_id']==$activityId) {
+        return $this->activities[$i]['wf_started'];
+      }
+    }
+    $this->error[] = tra('activity start not avaible, no corresponding activity was found.');
+    return false;
+  }
+  
+  /**
+   * Gets an activity from the list of activities of the instance
+   * the result is an array describing the instance
+   *
+   * @param int $activityId
+   * @return mixed
+   * @access private
+   */
+  function _get_instance_activity($activityId) 
+  {
+    for($i=0;$i<count($this->activities);$i++) {
+      if($this->activities[$i]['wf_activity_id']==$activityId) {
+        return $this->activities[$i];
+      }
+    }
+    $this->error[] = tra('no corresponding activity was found.');
+    return false;
+  }
+
+  /**
+   * Sets the time where the instance was started
+   *
+   * @param int $time
+   * @return bool
+   * @access public
+   */
+  function setStarted($time) 
+  {
+    $this->changed['started'] = $time;
+    $this->unsynch = true;
+    return true;
+  }
+  
+  /**
+   * Gets the time where the instance was started (Unix timestamp)
+   *
+   * @return int
+   * @access public
+   */
+  function getStarted() 
+  {
+    if (!(isset($this->changed['started'])))
+    {
+      return $this->started;
+    }
+    else
+    {
+      return $this->changed['started'];
+    }
+  }
+  
+  /**
+   * Sets the end time of the instance (when the process was completed)
+   *
+   * @param int $time
+   * @return bool
+   * @access public
+   */
+  function setEnded($time) 
+  {
+    $this->changed['ended']=$time;
+    $this->unsynch = true;
+    return true;
+  }
+  
+  /**
+   * Gets the end time of the instance (when the process was completed)
+   *
+   * @return int
+   * @access public
+   */
+  function getEnded() 
+  {
+    if (!(isset($this->changed['ended'])))
+    {
+      return $this->ended;
+    }
+    else
+    {
+      return $this->changed['ended'];
+    }
+  }
+  
+  /**
+   * This set to true or false the 'Activity Completed' status which will
+   * be important to know if the user code has completed the current activity
+   *
+   * @param bool $bool true by default, it will be the next status of the 'Activity Completed' indicator
+   * @access private
+   * @return void
+   */
+  function setActivityCompleted($bool)
+  {
+    $this->__activity_completed = $bool;
+  }
+  
+  /**
+   * Gets the 'Activity Completed' status
+   *
+   * @return mixed
+   * @access public
+   */
+  function getActivityCompleted()
+  {
+    return $this->__activity_completed;
+  }
+ 
+  /**
+   * This function can be called by the instance object himself (for automatic activities)
+   * or by the WfRuntime object. In interactive activities code users use complete() --without args-- 
+   * which refer to the WfRuntime->complete() function which call this one. 
+   * In non-interactive activities a call to a complete() will generate errors because the engine
+   * does it his own way as I said first.
+   * Particularity of this Complete is that it is Transactional, i.e. it it done completely
+   * or not and row locks are ensured
+   *
+   * @param int $activityId activity that is being completed
+   * @param bool $addworkitem indicates if a workitem should be added for the completed
+   * activity (true by default)
+   * @return bool false it means the complete was not done for some internal reason
+   * consult $instance->get_error() for more informations
+   * @access public
+   */
+  function complete($activityId,$addworkitem=true)
+  {
+    //$this->db->
+    $result = $this->query("SELECT 1 FROM " . GALAXIA_TABLE_PREFIX . "instances i, " . GALAXIA_TABLE_PREFIX . "interinstance_relations ir WHERE (ir.wf_child_instance_id = i.wf_instance_id) AND (i.wf_status IN ('active', 'exception')) AND (ir.wf_parent_lock = 1) AND (ir.wf_parent_instance_id = ?) AND (ir.wf_parent_activity_id = ?)", array($this->instanceId, $activityId));
+    if ($result->numRows() > 0)
+      die("Esta instância está aguardando que outras instâncias, das quais depende, sejam finalizadas.");
+    //ensure it's false at first
+    $this->setActivityCompleted(false);
+
+    //The complete() is in a transaction, it will be completly done or not at all
+    $this->db->StartTrans();
+    
+    //lock rows and ensure access is granted
+    if (!(isset($this->security))) $this->security = &Factory::getInstance('WfSecurity', $this->db);
+    if (!($this->security->checkUserAction($activityId,$this->instanceId,'complete')))
+    {
+      $this->error[] = tra('you were not allowed to complete the activity');
+      $this->db->FailTrans();
+    }
+    else
+    {
+      if (!($this->_internalComplete($activityId,$addworkitem)))
+      {
+        $this->error[] = tra('The activity was not completed');
+        $this->db->FailTrans();
+      }
+    }
+    //we mark completion with result of the transaction wich will be false if any error occurs
+    //this is the end of the transaction
+    $this->setActivityCompleted($this->db->CompleteTrans());
+
+    //we return the completion state.
+    return $this->getActivityCompleted();
+  }
+
+  /**
+   * YOU MUST NOT CALL _internalComplete() directly, use Complete() instead
+   *
+   * @param int $activityId activity that is being completed
+   * @param bool $addworkitem indicates if a workitem should be added for the completed
+   * activity (true by default)
+   * @return bool false it means the complete was not done for some internal reason
+   * consult $instance->get_error() for more informations
+   * @access private
+   */
+  function _internalComplete($activityId,$addworkitem=true) {
+    global $user;
+
+    if(empty($user)) 
+    {
+      $theuser='*';
+    } 
+    else 
+    {
+      $theuser=$user;
+    }
+
+    if(!($activityId)) 
+    {
+      $this->error[] = tra('it was impossible to complete, no activity was given.');
+      return false;
+    }  
+    
+    $now = date("U");
+    
+    // If we are completing a start activity then the instance must 
+    // be created first!
+    $type = $this->getOne('select wf_type from '.GALAXIA_TABLE_PREFIX.'activities where wf_activity_id=?',array((int)$activityId));
+    if($type=='start') 
+    {
+      if (!($this->_createNewInstance((int)$activityId,$theuser)))
+      {
+        return false;
+      }
+    }
+    else
+    {  
+      // Now set ended
+      $query = 'update '.GALAXIA_TABLE_PREFIX.'instance_activities set wf_ended=? where wf_activity_id=? and wf_instance_id=?';
+      $this->query($query,array((int)$now,(int)$activityId,(int)$this->instanceId));
+    }
+    
+    //Set the status for the instance-activity to completed
+    //except for start activities
+    if (!($type=='start'))
+    {
+      if (!($this->setActivityStatus($activityId,'completed')))
+      {
+        return false;
+      }
+    }
+    
+    //If this and end actt then terminate the instance
+    if($type=='end') 
+    {
+      if (!($this->terminate($now)))
+      {
+        return false;
+      }
+    }
+
+    //now we synchronise instance with the database
+    if (!($this->sync())) return false;
+    
+    //Add a workitem to the instance 
+    if ($addworkitem)
+    {
+      return $this->addworkitem($type,$now, $activityId);
+    }
+    else
+    {
+      return true;
+    }
+  }
+  
+  /**
+   * This function will add a workitem in the workitems table, the instance MUST be synchronised before
+   * calling this function.
+   *
+   * @param string $activity_type activity type, needed because internals are different for start activities
+   * @param int $ended ending time
+   * @param int $activityId finishing activity id
+   * @return mixed
+   * @access private
+   */
+  function addworkitem($activity_type, $ended, $activityId)
+  {
+    $iid = $this->instanceId;
+    $max = $this->getOne('select max(wf_order_id) from '.GALAXIA_TABLE_PREFIX.'workitems where wf_instance_id=?',array((int)$iid));
+    if(!$max) 
+    {
+        $max=1;
+    }
+    else 
+    {
+        $max++;
+    }
+    if($activity_type=='start')
+    {
+      //Then this is a start activity ending
+      $started = $this->getStarted();
+      //at this time owner is the creator
+      $putuser = $this->getOwner();
+    }
+    else
+    {
+      $act = $this->_get_instance_activity($activityId);
+      if(!$act) 
+      {
+        //this will abort the function
+        $this->error[] = tra('failed to create workitem');
+        return false;
+      }
+      else 
+      {
+        $started = $act['wf_started'];
+        $putuser = $act['wf_user'];
+      }
+    }
+    //no more serialize, done by the core security_cleanup
+    $properties = $this->security_cleanup($this->properties, false); //serialize($this->properties);
+    $query='insert into '.GALAXIA_TABLE_PREFIX.'workitems
+        (wf_instance_id,wf_order_id,wf_activity_id,wf_started,wf_ended,wf_properties,wf_user) values(?,?,?,?,?,?,?)';    
+    $this->query($query,array((int)$iid,(int)$max,(int)$activityId,(int)$started,(int)$ended,$properties,$putuser));
+    return true;
+  }
+  
+  /**
+   * Send autorouted activities to the next one(s)
+   * YOU MUST NOT CALL sendAutorouted() for non-interactive activities since
+   * the engine does automatically complete and send automatic activities after
+   * executing them
+   * This function is in fact a Private function runned by the engine
+   * You should never use it without knowing very well what you're doing
+   *
+   * @param int $activityId activity that is being completed, when this is not
+   * passed the engine takes it from the $_REQUEST array,all activities
+   * are executed passing the activityId in the URI
+   * @param bool $force indicates that the instance must be routed no matter if the
+   * activity is auto-routing or not. This is used when "sending" an
+   * instance from a non-auto-routed activity to the next activity
+   * @return mixed
+   * @access private
+   */
+  function sendAutorouted($activityId,$force=false)
+  {
+    $returned_value = Array();
+    $type = $this->getOne("select `wf_type` from `".GALAXIA_TABLE_PREFIX."activities` where `wf_activity_id`=?",array((int)$activityId));    
+    //on a end activity we have nothing to do
+    if ($type == 'end')
+    {
+      return true;
+    }
+    //If the activity ending is not autorouted then we have nothing to do
+    if (!(($force) || ($this->getOne("select `wf_is_autorouted` from `".GALAXIA_TABLE_PREFIX."activities` where `wf_activity_id`=?",array($activityId)) == 'y')))
+    {
+      $returned_value['transition']['status'] = 'not autorouted';
+      return $returned_value;
+    }
+    //If the activity ending is autorouted then send to the activity
+    // Now determine where to send the instance
+    $candidates = $this->getActivityCandidates($activityId);
+    if($type == 'split') 
+    {
+      $erase_from = false;
+      $num_candidates = count($candidates);
+      $returned_data = Array();
+      $i = 1;
+      foreach ($candidates as $cand) 
+      {
+        // only erase split activity in instance when all the activities comming from the split have been set up
+        if ($i == $num_candidates)
+        { 
+          $erase_from = true;
+        }
+        $returned_data[$i] = $this->sendTo($activityId,$cand,$erase_from);
+        $this->unsetNextUser($cand);
+        $this->sync();
+        $i++;
+      }
+      $this->unsetNextUser('*' . $activityId);
+      $this->sync();
+      return $returned_data;
+    } 
+    elseif($type == 'switch') 
+    {
+      if (in_array($this->nextActivity[$activityId],$candidates))
+      {
+        $selectedActivity = $this->nextActivity[$activityId];
+        foreach ($candidates as $candidate)
+          if ($candidate != $selectedActivity)
+            $this->unsetNextUser($candidate);
+        $output = $this->sendTo((int)$activityId,(int)$selectedActivity);
+        $this->unsetNextUser($selectedActivity);
+        $this->unsetNextUser('*' . $activityId);
+        $this->sync();
+        return $output;
+      } 
+      else 
+      {
+        $returned_value['transition']['failure'] = tra('Error: nextActivity does not match any candidate in autorouting switch activity');
+        return $returned_value;
+      }
+    } 
+    else 
+    {
+      if (count($candidates)>1) 
+      {
+        $returned_value['transition']['failure'] = tra('Error: non-deterministic decision for autorouting activity');
+        return $returned_value;
+      }
+      else 
+      {
+        $output = $this->sendTo((int)$activityId,(int)$candidates[0]);
+        $this->unsetNextUser($candidates[0]);
+        $this->unsetNextUser('*' . $activityId);
+        $this->sync();
+        return $output;
+      }
+    }
+  }
+  
+  /**
+   * This is a semi-private function, use GUI's abort function
+   * Aborts an activity and terminates the whole instance. We still create a workitem to keep track
+   * of where in the process the instance was aborted
+   *
+   * @param bool $addworkitem
+   * @return bool
+   * @access public
+   * @todo review, reuse of completed code
+   */
+  function abort($addworkitem=true) 
+  {
+    // If we are aborting a start activity then the instance must 
+    // be created first!
+    // ==> No, there's no reason to have an uncompleted start activity to abort
+
+    // load all the activities of the current instance
+    if ($addworkitem)
+    {
+      $activities = array();
+      $query = 'SELECT a.wf_type AS wf_type, ia.wf_activity_id AS wf_activity_id FROM '.GALAXIA_TABLE_PREFIX.'activities a, '.GALAXIA_TABLE_PREFIX.'instance_activities ia WHERE (ia.wf_activity_id = a.wf_activity_id) AND (ia.wf_instance_id = ?)';
+      $result = $this->query($query,array((int)$this->instanceId));
+      while ($row = $result->fetchRow())
+        $activities[] = $row;
+    }
+
+    // Now set ended on instance_activities
+    $now = date("U");
+
+    // terminate the instance with status 'aborted'
+    if (!($this->terminate($now,'aborted')))
+      return false;
+
+    //now we synchronise instance with the database
+    if (!($this->sync()))
+      return false;
+    
+    //Add a workitem to the instance 
+    if ($addworkitem)
+    {
+      foreach ($activities as $activity)
+        if (!($this->addworkitem($activity['wf_type'], $now, $activity['wf_activity_id'])))
+          return false;
+      return true;
+    }
+    else
+    {
+      return true;
+    }
+  }
+  
+  /**
+   * Terminates the instance marking the instance and the process
+   * as completed. This is the end of a process
+   * Normally you should not call this method since it is automatically
+   * called when an end activity is completed
+   * object is synched at the end of this function
+   *
+   * @param int $time terminating time
+   * @param string $status
+   * @return bool
+   * @access private
+   */
+  function terminate($time, $status = 'completed') {
+    //Set the status of the instance to completed
+    if (!($this->setEnded((int)$time))) return false;
+    if (!($this->setStatus($status))) return false;
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `wf_instance_id`=?";
+    $this->query($query,array((int)$this->instanceId));
+    return $this->sync();
+  }
+  
+  
+  /**
+   * Sends the instance from some activity to another activity. (walk on a transition)
+   * You should not call this method unless you know very very well what
+   * you are doing
+   *
+   * @param int $from activity id at the start of the transition
+   * @param int $activityId activity id at the end of the transition
+   * @param bool $erase_from true by default, if true the coming activity row will be erased from
+   * instance_activities table. You should set it to false for example with split activities while
+   * you still want to re-call this function
+   * @return mixed false if anything goes wrong, true if we are at the end of the execution tree and an array
+   * if a part of the process was automatically runned at the end of the transition. this array contains
+   * 2 keys 'transition' is the transition we walked on, 'activity' is the result of the run part if it was an automatic activity.
+   * 'activity' value is an associated array containing several usefull keys:
+   * 'completed' is a boolean indicating that the activity was completed or not
+   * 'debug contains debug messages
+   * 'info' contains some usefull infos about the activity-instance running (like names)
+   * 'next' is the result of a SendAutorouted part which could in fact be the result of a call to this function, etc
+   * @access public
+   */
+  function sendTo($from,$activityId,$erase_from=true) 
+  {
+    //we will use an array for return value
+    $returned_data = Array();
+    //1: if we are in a join check
+    //if this instance is also in
+    //other activity if so do
+    //nothing
+    $query = 'select wf_type, wf_name from '.GALAXIA_TABLE_PREFIX.'activities where wf_activity_id=?';
+    $result = $this->query($query,array($activityId));
+    if (empty($result))
+    {
+      $returned_data['transition']['failure'] = tra('Error: trying to send an instance to an activity but it was impossible to get this activity');
+      return $returned_data;
+    }
+    while ($res = $result->fetchRow())
+    {
+      $type = $res['wf_type'];
+      $targetname = $res['wf_name'];
+    }
+    $returned_data['transition']['target_id'] = $activityId;
+    $returned_data['transition']['target_name'] = $targetname;
+    
+    // Verify the existence of a transition
+    if(!$this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."transitions` where `wf_act_from_id`=? and `wf_act_to_id`=?",array($from,(int)$activityId))) {
+      $returned_data['transition']['failure'] = tra('Error: trying to send an instance to an activity but no transition found');
+      return $returned_data;
+    }
+
+    //init
+    $putuser=0;
+    
+    //try to determine the user or *
+    //Use the nextUser
+    $the_next_user = $this->getNextUser($activityId);
+    if($the_next_user) 
+    {
+      //we check rights for this user on the next activity
+      if (!(isset($this->security))) $this->security = &Factory::getInstance('WfSecurity');
+      if ($this->security->checkUserAccess($the_next_user,$activityId))
+      {
+        $putuser = $the_next_user;
+      }
+    }
+    if ($putuser===0)
+    {
+      // then check to see if there is a default user
+      $activity_manager = &Factory::newInstance('ActivityManager');
+      //get_default_user will give us '*' if there is no default_user or if the default user has no role
+      //mapped anymore
+      $default_user = $activity_manager->get_default_user($activityId,true);
+      unset($activity_manager);
+      // if they were no nextUser, no unique user avaible, no default_user then we'll have '*'
+      // which will let user having the good role mapping grab this activity later
+      $putuser = $default_user;
+    }
+    if ($the_next_user)
+      $this->setNextUser($the_next_user, '*' . $activityId);
+    
+    //update the instance_activities table
+    //if not splitting delete first
+    //please update started,status,user
+    if (($erase_from) && (!empty($this->instanceId)))
+    {
+      $query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `wf_instance_id`=? and `wf_activity_id`=?";
+      $this->query($query,array((int)$this->instanceId,$from));
+    }
+  
+    if ($type == 'join') {
+      if (count($this->activities)>1) {
+        // This instance will have to wait!
+        $returned_data['transition']['status'] = 'waiting';
+        return $returned_data;
+      }
+    }    
+
+    //create the new instance-activity
+    $returned_data['transition']['target_id'] = $activityId;
+    $returned_data['transition']['target_name'] = $targetname;
+    $now = date("U");
+    $iid = $this->instanceId;
+    $query="delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `wf_instance_id`=? and `wf_activity_id`=?";
+    $this->query($query,array((int)$iid,(int)$activityId));
+    $query="insert into `".GALAXIA_TABLE_PREFIX."instance_activities`(`wf_instance_id`,`wf_activity_id`,`wf_user`,`wf_status`,`wf_started`) values(?,?,?,?,?)";
+    $this->query($query,array((int)$iid,(int)$activityId,$putuser,'running',(int)$now));
+    
+    //record the transition walk
+    $returned_data['transition']['status'] = 'done';
+
+    
+    //we are now in a new activity
+    $this->_populate_activities($iid);
+    //if the activity is not interactive then
+    //execute the code for the activity and
+    //complete the activity
+    $isInteractive = $this->getOne("select `wf_is_interactive` from `".GALAXIA_TABLE_PREFIX."activities` where `wf_activity_id`=?",array((int)$activityId));
+    if ($isInteractive=='n') 
+    {
+      //first we sync actual instance because the next activity could need it
+      if (!($this->sync()))
+      {
+        $returned_data['activity']['failure'] = true;
+        return $returned_data;
+      }
+      // Now execute the code for the activity
+      $this->activityID = $activityId;
+      $returned_data['activity'] = $this->executeAutomaticActivity($activityId, $iid);
+      $this->activityID = $from;
+    }
+    else
+    {
+      // we sync actual instance
+      if (!($this->sync()))
+      {
+        $returned_data['failure'] = true;
+        return $returned_data;
+      }
+    }
+    return $returned_data;
+  }
+  
+  /**
+   * This is a public method only because the GUI can ask this action for the admin
+   * on restart failed automated activities, but in fact it's quite an internal function,
+   * This function handle the execution of automatic activities (and the launch of transitions
+   * which can be related to this activity)
+   *
+   * @param int $activityId activity id at the end of the transition
+   * @param int $iid instance id
+   * @return array
+   * @access public
+   */
+  function executeAutomaticActivity($activityId, $iid)
+  {
+    $returned_data = Array();
+    // Now execute the code for the activity (function defined in galaxia's config.php)
+    $returned_data =& galaxia_execute_activity($activityId, $iid , 1);
+
+    //we should have some info in $returned_data now. if it is false there's a problem
+    if ((!(is_array($returned_data))) && (!($returned_data)) )
+    {
+      $this->error[] = tra('failed to execute automatic activity');
+      //record the failure
+      $returned_data['failure'] = true;
+      return $returned_data;
+    }
+    else
+    {
+      //ok, we have an array, but it can still be a bad result
+      //this one is just for debug info
+      if (isset($returned_data['debug']))
+      {
+        //we retrieve this info here, in this object
+        $this->error[] = $returned_data['debug'];
+      }
+      //and this really test if it worked, if not we have a nice failure message (better than just failure=true)
+      if (isset($returned_data['failure']))
+      {
+        $this->error[] = tra('failed to execute automatic activity');
+        $this->error[] = $returned_data['failure'];
+        //record the failure
+        return $returned_data;
+      }
+      
+    }
+    // Reload in case the activity did some change, last sync was done just before calling this function
+    //TODO: check if this sync is really needed
+    $this->getInstance($this->instanceId, false, false);
+
+    //complete the automatic activity----------------------------
+    if ($this->Complete($activityId))
+    {
+      $returned_data['completed'] = true;
+      
+      //and send the next autorouted activity if any
+      $returned_data['next'] = $this->sendAutorouted($activityId);
+    }
+    else
+    {
+      $returned_data['failure'] = $this->get_error();
+    }
+    return $returned_data;
+  }
+  
+  /**
+   * Gets a comment for this instance 
+   *
+   * @param int $cId
+   * @return mixed
+   * @access public
+   */
+  function get_instance_comment($cId) {
+    $iid = $this->instanceId;
+    $query = "select * from `".GALAXIA_TABLE_PREFIX."instance_comments` where `wf_instance_id`=? and `wf_c_id`=?";
+    $result = $this->query($query,array((int)$iid,(int)$cId));
+    $res = $result->fetchRow();
+    return $res;
+  }
+  
+  /**
+   * Inserts or updates an instance comment 
+   *
+   * @param int $cId
+   * @param int $activityId
+   * @param object $activity
+   * @param int $user
+   * @param string $title
+   * @param mixed $comment
+   * @return bool
+   * @access public
+   */
+  function replace_instance_comment($cId, $activityId, $activity, $user, $title, $comment) {
+    if (!$user) {
+      $user = 'Anonymous';
+    }
+    $iid = $this->instanceId;
+    //no need on pseudo-instance
+    if (!!($this->instanceId))
+    {
+      if ($cId) 
+      {
+        $query = "update `".GALAXIA_TABLE_PREFIX."instance_comments` set `wf_title`=?,`wf_comment`=? where `wf_instance_id`=? and `wf_c_id`=?";
+        $this->query($query,array($title,$comment,(int)$iid,(int)$cId));
+      } 
+      else 
+      {
+        $hash = md5($title.$comment);
+        if ($this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."instance_comments` where `wf_instance_id`=? and `wf_hash`=?",array($iid,$hash))) 
+        {
+          return false;
+        }
+        $now = date("U");
+        $query ="insert into `".GALAXIA_TABLE_PREFIX."instance_comments`(`wf_instance_id`,`wf_user`,`wf_activity_id`,`wf_activity`,`wf_title`,`wf_comment`,`wf_timestamp`,`wf_hash`) values(?,?,?,?,?,?,?,?)";
+        $this->query($query,array((int)$iid,$user,(int)$activityId,$activity,$title,$comment,(int)$now,$hash));
+      }
+    }
+    return true;
+  }
+  
+  /**
+   * Removes an instance comment
+   *
+   * @param int $cId
+   * @access public
+   * @return void
+   */
+  function remove_instance_comment($cId) {
+    $iid = $this->instanceId;
+    $query = "delete from `".GALAXIA_TABLE_PREFIX."instance_comments` where `wf_c_id`=? and `wf_instance_id`=?";
+    $this->query($query,array((int)$cId,(int)$iid));
+  }
+ 
+  /**
+   * Lists instance comments
+   *
+   * @return array
+   * @access public
+   */
+  function get_instance_comments() {
+    $iid = $this->instanceId;
+    $query = "select * from `".GALAXIA_TABLE_PREFIX."instance_comments` where `wf_instance_id`=? order by ".$this->convert_sortmode("timestamp_desc");
+    $result = $this->query($query,array((int)$iid));    
+    $ret = Array();
+    while($res = $result->fetchRow()) {    
+      $ret[] = $res;
+    }
+    return $ret;
+  }
+
+  /**
+   * Get the activity candidates (more than one in split and switch)
+   *
+   * @param int $activityID The activity from which we want to obtain the candidate activities
+   * @return array List of activities that can be reached from one given activity
+   * @access public
+   */
+  function getActivityCandidates($activityID)
+  {
+    $query = 'SELECT wf_act_to_id FROM ' . GALAXIA_TABLE_PREFIX . 'transitions WHERE (wf_act_from_id = ?)';
+    $result = $this->query($query, array((int) $activityID));
+    $candidates = Array();
+    while ($res = $result->fetchRow())
+      $candidates[] = $res['wf_act_to_id'];
+    return $candidates;
+  }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/API/BaseActivity.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/API/BaseActivity.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/API/BaseActivity.php	(revision 2372)
@@ -0,0 +1,561 @@
+<?php
+require_once (GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+/**
+ * Represents activities, and must be derived for each activity type supported in the system. 
+ * Derived activities extending this class can be found in the activities subfolder.
+ * This class is observable.
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL 
+ */
+class BaseActivity extends Base {
+  /**
+   * @var string $name Activity's name
+   * @access public
+   */
+  var $name;
+  /**
+   * @var string $normalizedName Activity's normalized (follows a pattern) name
+   * @access public
+   */  
+  var $normalizedName;
+  /**
+   * @var string $description Activity's description
+   * @access public
+   */  
+  var $description;
+  /**
+   * @var string $menuPath Activity's menu path
+   * @access public
+   */  
+  var $menuPath;
+  /**
+   * @var bool $isInteractive
+   * @access public
+   */  
+  var $isInteractive;
+  /**
+   * @var bool $isAutoRouted
+   * @access public
+   */  
+  var $isAutoRouted;
+  /**
+   * @var array $roles
+   * @access public
+   */
+  var $roles=Array();
+  /**
+   * @var array $outbound
+   * @access public
+   */
+  var $outbound=Array();
+  /**
+   * @var array $inbound
+   * @access public
+   */
+  var $inbound=Array();
+  /**
+   * @var int $pId Process's identification number 
+   * @access public
+   */
+  var $pId;
+  /**
+   * @var int $activityId Activity's identification number 
+   * @access public
+   */  
+  var $activityId;
+  /**
+   * @var string $type Activity's type 
+   * @access public
+   */
+  var $type;
+  /**
+   * @var string  $defaultUser
+   * @access public
+   */
+  var $defaultUser='*';
+  /**
+   * @var array $agents
+   * @access public
+   */  
+  var $agents=Array();
+  
+  /**
+   * Seems to be the rest of a bad object architecture
+   * 
+   * @deprecated
+   */
+  function setDb(&$db)
+  {
+    $this->db =& $db;
+  }
+  
+  /**
+   * Constructor of the BaseActivity Object
+   * 
+   * @param object $db ADODB object
+   * @access public
+   */
+  function BaseActivity()
+  {
+    $this->type='base';
+    $this->child_name = 'BaseActivity';
+    parent::Base();
+  }
+
+  /**
+   * Factory method returning an activity of the desired type, loading the information from the database 
+   * and populating the activity object with datas related to his activity type (being more than a BaseActivity then
+   * 
+   * @param int $activityId it is the id of the wanted activity
+   * @param bool $with_roles true by default, gives you the basic roles information in the result
+   * @param bool $with_agents false by default, gives you the basic agents information in the result
+   * @param bool $as_array false by default, if true the function will return an array instead of an object
+   * @return object Activity of the right class (Child class) or an associative array containing the activity 
+   * information if $as_array is set to true
+   * @access public  
+   */
+  function &getActivity($activityId, $with_roles= true,$with_agents=false,$as_array=false) 
+  {
+    $query = "select * from `".GALAXIA_TABLE_PREFIX."activities` where `wf_activity_id`=?";
+    $result = $this->query($query,array($activityId));
+    if(!$result || !$result->numRows() ) return false;
+    $res = $result->fetchRow();
+
+    switch($res['wf_type']) {
+      case 'start':
+        $act = &Factory::newInstance('Start');
+        break;
+
+      case 'end':
+        $act = &Factory::newInstance('End');
+        break;
+
+      case 'join':
+        $act = &Factory::newInstance('Join');
+        break;
+
+      case 'split':
+        $act = &Factory::newInstance('Split');
+        break;
+
+      case 'standalone':
+        $act = &Factory::newInstance('Standalone');
+        break;
+
+      case 'view':
+        $act = &Factory::newInstance('View');
+        break;
+
+      case 'switch':
+        $act = &Factory::newInstance('SwitchActivity');
+        break;
+
+      case 'activity':
+        $act = &Factory::newInstance('Activity');
+        break;
+
+      default:
+        trigger_error('Unknown activity type:'.$res['wf_type'],E_USER_WARNING);
+    }
+
+    $act->setName($res['wf_name']);
+    $act->setProcessId($res['wf_p_id']);
+    $act->setNormalizedName($res['wf_normalized_name']);
+    $act->setDescription($res['wf_description']);
+    $act->setMenuPath($res['wf_menu_path']);
+    $act->setIsInteractive($res['wf_is_interactive']);
+    $act->setIsAutoRouted($res['wf_is_autorouted']);
+    $act->setActivityId($res['wf_activity_id']);
+    $act->setType($res['wf_type']);
+    $act->setDefaultUser($res['wf_default_user']);
+    
+    //Now get forward transitions 
+    
+    //Now get backward transitions
+    
+    //Now get roles
+    if ($with_roles)
+    {
+      $query = "select `wf_role_id` from `".GALAXIA_TABLE_PREFIX."activity_roles` where `wf_activity_id`=?";
+      $result=$this->query($query,array($activityId));
+      if (!(empty($result)))
+      {
+        while($res = $result->fetchRow()) 
+        {
+          $this->roles[] = $res['wf_role_id'];
+        }
+      }
+      $act->setRoles($this->roles);
+    }
+    
+    //Now get agents if asked so
+    if ($with_agents)
+    {
+      $query = "select wf_agent_id, wf_agent_type from ".GALAXIA_TABLE_PREFIX."activity_agents where wf_activity_id=?";
+      $result=$this->query($query,array($activityId));
+      if (!(empty($result)))
+      {
+        while($res = $result->fetchRow()) 
+        {
+          $this->agents[] = array(
+              'wf_agent_id'	=> $res['wf_agent_id'],
+              'wf_agent_type'	=> $res['wf_agent_type'],
+            );
+        }
+      }
+      $act->setAgents($this->agents);
+    }
+
+    if ($as_array)
+    {//we wont return the object but an associative array instead
+       $res['wf_name']=$act->getName();
+       $res['wf_normalized_name']=$act->getNormalizedName();
+       $res['wf_description']=$act->getDescription();
+       $res['wf_menu_path']=$act->getMenuPath();
+       $res['wf_is_interactive']=$act->isInteractive();
+       $res['wf_is_autorouted']=$act->isAutoRouted();
+       $res['wf_roles']=$act->getRoles();
+       //$res['outbound']=$act->get();
+       //$res['inbound']=$act->get();
+       $res['wf_p_id']=$act->getProcessId();
+       $res['wf_activity_id']=$act->getActivityId();
+       $res['wf_type']=$act->getType();
+       $res['wf_default_user']=$act->getDefaultUser();
+       $res['wf_agents']= $act->getAgents();
+       return $res;
+    }
+    else
+    {
+      return $act;
+    }
+  }
+  
+  /**
+   * Gets performed roles for a given user
+   * 
+   * @param array $user
+   * @return array RoleIds for the given user
+   * @access public
+   */
+  function getUserRoles($user) {
+    
+    // retrieve user_groups information in an array containing all groups for this user
+    $user_groups = galaxia_retrieve_user_groups($GLOBALS['phpgw_info']['user']['account_id'] );
+    // and append it to query                      
+    $query = 'select `wf_role_id` from `'.GALAXIA_TABLE_PREFIX."user_roles` 
+          where (
+            (wf_user=? and wf_account_type='u')";
+    if (is_array($groups))
+    {
+      foreach ($groups as &$group)
+        $group = "'{$group}'";
+      $mid .= '	or (wf_user in ('.implode(',',$groups).") and wf_account_type='g')";
+    }
+    $mid .= ')';
+
+    $result=$this->query($query,array($user));
+    $ret = Array();
+    while($res = $result->fetchRow()) 
+    {
+      $ret[] = $res['wf_role_id'];
+    }
+    return $ret;
+  }
+
+  /**
+   * Gets activity's roleId and name
+   * 
+   * @return array $ret Array of associative arrays with roleId and name
+   * @access public
+   */
+  function getActivityRoleNames() {
+    $aid = $this->activityId;
+    $query = "select gr.`wf_role_id`, `wf_name` from `".GALAXIA_TABLE_PREFIX."activity_roles` gar, `".GALAXIA_TABLE_PREFIX."roles` gr where gar.`wf_role_id`=gr.`wf_role_id` and gar.`wf_activity_id`=?";
+    $result=$this->query($query,array($aid));
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res;
+    }
+    return $ret;
+  }
+  
+  /**
+   * Returns the normalized name for the activity
+   * 
+   * @return string
+   * @access public 
+   */
+  function getNormalizedName() {
+    return $this->normalizedName;
+  }
+
+  /**
+   * Sets normalized name for the activity
+   * 
+   * @return void
+   * @access public
+   */  
+  function setNormalizedName($name) {
+    $this->normalizedName=$name;
+  }
+  
+  /**
+   * Sets the name for the activity
+   * 
+   * @param string New desired activity's name
+   * @return void
+   * @access public
+   */
+  function setName($name) {
+    $this->name=$name;
+  }
+  
+  /**
+   * Gets the activity name
+   * 
+   * @return void
+   * @access public
+   */
+  function getName() {
+    return $this->name;
+  }
+
+  /**
+   * Sets the agents for the activity object (no save)
+   * 
+   * @param array $agents Has 'wf_agent_id' and 'wf_agent_type' as keys
+   * @return bool False if any problem is detected
+   * @access public
+   */
+  function setAgents($agents) 
+  {
+    if (!(is_array($agents)))
+    {
+      $this->error[] = tra('bad parameter for setAgents, the parameter should be an array');
+      return false;
+    }
+    $this->agents = $agents;
+  }
+  
+  /**
+   * Gets the activity agents
+   * 
+   * @return array Basic agents informations (id an type) or false if no agent is defined for this activity
+   * @access public
+   */
+  function getAgents() 
+  {
+    if (empty($this->agents)) return false;
+    return $this->agents;
+  }
+  
+  /**
+   * Sets the activity description
+   * 
+   * @param string $desc Activity description
+   * @return void
+   * @access public
+   */
+  function setDescription($desc) {
+    $this->description=$desc;
+  }
+
+  /**
+   * Gets the activity description
+   * 
+   * @return string
+   * @access public
+   */  
+  function getDescription() {
+    return $this->description;
+  }
+
+  /**
+   * Sets the activity menu path
+   * 
+   * @param string $mp Menu path
+   * @return void
+   * @access public
+   */
+  function setMenuPath($mp) {
+    $this->menuPath=$mp;
+  }
+
+  /**
+   * Gets the activity menu path
+   * 
+   * @return string
+   * @access public
+   */  
+  function getMenuPath() {
+    return $this->menuPath;
+  }
+  
+  /**
+   * Sets the type for the activity although it does NOT allow you to change the current type
+   * 
+   * @param string $type 
+   * @return void
+   * @access public
+   */
+  function setType($type) {
+    $this->type=$type;
+  }
+  
+  /**
+   * Gets the activity type
+   * 
+   * @return string
+   * @access public
+   */
+  function getType() {
+    return $this->type;
+  }
+
+  /**
+   * Sets if the activity is interactive
+   * 
+   * @param bool $is
+   * @return void
+   * @access public
+   */
+  function setIsInteractive($is) {
+    $this->isInteractive=$is;
+  }
+  
+  /**
+   * Returns if the activity is interactive
+   * 
+   * @return string
+   * @access public
+   */
+  function isInteractive() {
+    return $this->isInteractive == 'y';
+  }
+  
+  /**
+   * Sets if the activity is auto-routed
+   * 
+   * @param boolean $is 
+   * @return void
+   * @access public 
+   */
+  function setIsAutoRouted($is) {
+    $this->isAutoRouted = $is;
+  }
+  
+  /**
+   * Gets if the activity is auto routed
+   * 
+   * @return string
+   * @access public
+   */
+  function isAutoRouted() {
+    return $this->isAutoRouted == 'y';
+  }
+
+  /**
+   * Sets the processId for this activity
+   * 
+   * @param int $pid
+   * @return void 
+   * @access public
+   */
+  function setProcessId($pid) {
+    $this->pId=$pid;
+  }
+  
+  /**
+   * Gets the processId for this activity
+   * 
+   * @return int 
+   * @access public
+   */
+  function getProcessId() {
+    return $this->pId;
+  }
+
+  /**
+   * Gets the activityId
+   * 
+   * @return int 
+   * @access public
+   */
+  function getActivityId() {
+    return $this->activityId;
+  }  
+  
+  /**
+   * Sets the activityId
+   * 
+   * @param int $id
+   * @return void 
+   * @access public
+   */
+  function setActivityId($id) {
+    $this->activityId=$id;
+  }
+  
+  /**
+   * Gets array with roleIds asociated to this activity
+   * 
+   * @return array 
+   * @access public
+   */
+  function getRoles() {
+    return $this->roles;
+  }
+  
+  /**
+   * Sets roles for this activities, should receive an array of roleIds
+   * 
+   * @param array $roles
+   * @return void 
+   * @access public
+   */
+  function setRoles($roles) {
+    $this->roles = $roles;
+  }
+
+  /**
+   * Gets default user id associated with this activity as he's recorded 
+   * there's no check about validity of this user
+   * 
+   * @return string 
+   * @access protected
+   */
+  function getDefaultUser() {
+    return $this->defaultUser;
+  }
+
+  /**
+   * Sets the default user for an activity
+   * 
+   * @param string $default_user
+   * @return void 
+   * @access public
+   */
+  function setDefaultUser($default_user)
+  {
+    if ((!isset($default_user)) || ($default_user=='') || ($default_user==false))
+    {
+      $default_user='*';
+    }
+    $this->defaultUser = $default_user;
+  }
+
+   /**
+   * Checks if a user has a certain role (by name) for this activity,
+   * e.g. $isadmin = $activity->checkUserRole($user,'admin')
+   * 
+   * @deprecated Unused function. Old API, do not use it. Return always false
+   */
+  function checkUserRole($user,$rolename) 
+  {
+    $this->error[] = 'use of an old deprecated function checkUserRole, return always false';
+    return false;
+  }
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/ProcessManager.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/ProcessManager.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/ProcessManager.php	(revision 2372)
@@ -0,0 +1,1364 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'BaseManager.php');
+/**
+ * Adds, removes, modifies and lists processes.
+ * Most of the methods acts directly in database level, bypassing Project object methods
+ *
+ * @todo Fix multiple non checked fopen ==> infinite loops in case of problems with filesystem
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ProcessManager extends BaseManager {
+
+	/**
+	 * @var resource $parser xml parser
+	 * @access public
+	 */
+	var $parser;
+
+	/**
+	 * @var array $tree data struture
+	 * @access public
+	 */
+	var $tree;
+
+	/**
+	 * @var $current current element
+	 * @access public
+	 */
+	var $current;
+
+	/**
+	 * @var $buffer buffer for data
+	 * @access public
+	 */
+	var $buffer;
+
+	/**
+	 * @var object $Process Process
+	 * @access public
+	 */
+	var $Process;
+
+	/**
+	 * @var object $activity_manager Activity Manager
+	 * @access public
+	 */
+	var $activity_manager;
+
+	/**
+	 * @var object $jobManager Job Manager object
+	 * @access public
+	 */
+	var $jobManager;
+
+	/**
+	 * @var object $role_manager Role Manager
+	 * @access public
+	 */
+	var $role_manager;
+
+	/**
+	 * Constructor
+	 *
+	 * @param object &$db ADOdb
+	 * @return object ProcessManager
+	 * @access public
+	 */
+	function ProcessManager()
+	{
+		parent::BaseManager();
+		$this->child_name = 'ProcessManager';
+		// $this->activity_manager is not set here to avoid objects loading object A loading object B loading object A, etc
+		//$this->role_manager will only be loaded when needed as well
+	}
+
+	/**
+	 * Collect errors from all linked objects which could have been used by this object.
+	 * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
+	 *
+	 * @param bool $debug False by default, if true debug messages can be added to 'normal' messages
+	 * @param string $prefix Appended to the debug message
+	 * @return void
+	 * @access public
+	 */
+	function collect_errors($debug=false, $prefix = '')
+	{
+		parent::collect_errors($debug, $prefix);
+		if (isset($this->activity_manager)) $this->error[] = $this->activity_manager->get_error(false, $debug, $prefix);
+		if (isset($this->role_manager)) $this->error[] = $this->role_manager->get_error(false, $debug, $prefix);
+	}
+
+	/**
+	 * Activates a process
+	 *
+	 * @param int $pId Process id
+	 * @return void
+	 * @access public
+	 */
+	function activate_process($pId)
+	{
+		$query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?';
+		$this->query($query, array('y',$pId));
+		$msg = sprintf(tra('Process %d has been activated'),$pId);
+		$this->error[] = $msg;
+	}
+
+	/**
+	 * Deactivates a process
+	 *
+	 * @param int $pId Process id
+	 * @return void
+	 * @access public
+	 */
+	function deactivate_process($pId)
+	{
+		$query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?';
+		$this->query($query, array('n',$pId));
+		$msg = sprintf(tra('Process %d has been deactivated'),$pId);
+		$this->error[] = $msg;
+	}
+
+	/**
+	 * Creates an XML representation of a process
+	 *
+	 * @param int $pId Process id
+	 * @return string
+	 * @access public
+	 */
+	function serialize_process($pId)
+	{
+		if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+		// <process>
+		$out = '<process>'."\n";
+		//we retrieve config values with the others process data
+		$proc_info =& $this->get_process($pId, true);
+		$wf_procname = $proc_info['wf_normalized_name'];
+		$out.= '  <name>'.htmlspecialchars($proc_info['wf_name']).'</name>'."\n";
+		$out.= '  <isValid>'.htmlspecialchars($proc_info['wf_is_valid']).'</isValid>'."\n";
+		$out.= '  <version>'.htmlspecialchars($proc_info['wf_version']).'</version>'."\n";
+		$out.= '  <isActive>'.htmlspecialchars($proc_info['wf_is_active']).'</isActive>'."\n";
+		$out.='   <description>'.htmlspecialchars($proc_info['wf_description']).'</description>'."\n";
+		$out.= '  <lastModif>'.date("d/m/Y [h:i:s]",$proc_info['wf_last_modif']).'</lastModif>'."\n";
+
+		//Shared code
+		$out.= '  <sharedCode><![CDATA[';
+		$fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."shared.php","r");
+		while(!feof($fp)) {
+			$line=fread($fp,8192);
+			$out.=$line;
+		}
+		fclose($fp);
+		$out.= '  ]]></sharedCode>'."\n";
+
+		//Loop on config values
+		$out.='  <configs>'."\n";
+		foreach($proc_info['config'] as $res) {
+			$name = $res['wf_config_name'];
+			$value_int = $res['wf_config_value_int'];
+			$value = $res['wf_config_value'];
+			$out.='    <config>'."\n";
+			$out.='      <wf_config_name>'.htmlspecialchars($name).'</wf_config_name>'."\n";
+			$out.='      <wf_config_value>'.htmlspecialchars($value).'</wf_config_value>'."\n";
+			$out.='      <wf_config_value_int>'.htmlspecialchars($value_int).'</wf_config_value_int>'."\n";
+			$out.='    </config>'."\n";
+		}
+		$out.='  </configs>'."\n";
+
+		// Now loop over activities
+		$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where wf_p_id=$pId";
+		$result = $this->query($query);
+		$out.='  <activities>'."\n";
+		while($res = $result->fetchRow()) {
+			$name = $res['wf_normalized_name'];
+			$out.='    <activity>'."\n";
+			$out.='      <name>'.htmlspecialchars($res['wf_name']).'</name>'."\n";
+			$out.='      <type>'.htmlspecialchars($res['wf_type']).'</type>'."\n";
+			$out.='      <description>'.htmlspecialchars($res['wf_description']).'</description>'."\n";
+			$out.='      <lastModif>'.date("d/m/Y [h:i:s]",$res['wf_last_modif']).'</lastModif>'."\n";
+			$out.='      <isInteractive>'.$res['wf_is_interactive'].'</isInteractive>'."\n";
+			$out.='      <isAutoRouted>'.$res['wf_is_autorouted'].'</isAutoRouted>'."\n";
+			$out.='      <roles>'."\n";
+			//loop on activity roles
+			$actid = $res['wf_activity_id'];
+			$roles =& $this->activity_manager->get_activity_roles($actid);
+			foreach($roles as $role) {
+				if ($role['wf_readonly'])
+				{
+					$out.='        <role readonly="true">'.htmlspecialchars($role['wf_name']).'</role>'."\n";
+				}
+				else
+				{
+					$out.='        <role>'.htmlspecialchars($role['wf_name']).'</role>'."\n";
+				}
+			}
+			$out.='      </roles>'."\n";
+			$out.='      <agents>'."\n";
+			//loop on activity agents
+			$agents =& $this->activity_manager->get_activity_agents($actid);
+			foreach($agents as $agent) {
+				$out.='        <agent>'."\n";
+				$out.='           <agent_type>'.htmlspecialchars($agent['wf_agent_type']).'</agent_type>'."\n";
+				//loop on agent datas
+				$agent_data =& $this->activity_manager->get_activity_agent_data($actid,$agent['wf_agent_type']);
+				$out.='           <agent_datas>'."\n";
+				foreach($agent_data as $key => $value)
+				{
+					if (!($key=='wf_agent_id'))
+					{
+						$out.='               <agent_data>'."\n";
+						$out.='                   <name>'.htmlspecialchars($key).'</name>'."\n";
+						$out.='                   <value>'.htmlspecialchars($value).'</value>'."\n";
+						$out.='               </agent_data>'."\n";
+					}
+				}
+				$out.='           </agent_datas>'."\n";
+				$out.='        </agent>'."\n";
+			}
+			$out.='      </agents>'."\n";
+
+			//the code
+			$out.='      <code><![CDATA[';
+			$fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."activities".SEP."$name.php","r");
+			while(!feof($fp)) {
+				$line=fread($fp,8192);
+				$out.=$line;
+			}
+			fclose($fp);
+			$out.='      ]]></code>';
+			if($res['wf_is_interactive']=='y') {
+				$out.='      <template><![CDATA[';
+				$fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."templates".SEP."$name.tpl","r");
+				while(!feof($fp)) {
+					$line=fread($fp,8192);
+					$out.=$line;
+				}
+				fclose($fp);
+				$out.='      ]]></template>';
+			}
+			$out.='    </activity>'."\n";
+		}
+		$out.='  </activities>'."\n";
+		$out.='  <transitions>'."\n";
+		//loop on transitions
+		$transitions = $this->activity_manager->get_process_transitions($pId);
+		foreach($transitions as $tran) {
+			$out.='     <transition>'."\n";
+			$out.='       <from>'.htmlspecialchars($tran['wf_act_from_name']).'</from>'."\n";
+			$out.='       <to>'.htmlspecialchars($tran['wf_act_to_name']).'</to>'."\n";
+			$out.='     </transition>'."\n";
+		}
+		$out.='  </transitions>'."\n";
+		$out.= '</process>'."\n";
+		//$fp = fopen(GALAXIA_PROCESSES."/$wf_procname/$wf_procname.xml","w");
+		//fwrite($fp,$out);
+		//fclose($fp);
+		return $out;
+	}
+
+	/**
+	 * Creates  a process PHP data structure from its XML representation
+	 *
+	 * @param string &$xml XML document
+	 * @return array Process data structure
+	 * @access public
+	 */
+	function unserialize_process(&$xml)
+	{
+		// Create SAX parser assign this object as base for handlers
+		// handlers are private methods defined below.
+		// keep contexts and parse
+		$this->parser = xml_parser_create();
+		xml_parser_set_option($this->parser,XML_OPTION_CASE_FOLDING,0);
+		//xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE, 1);
+		xml_set_object($this->parser, $this);
+		xml_set_element_handler($this->parser, '_start_element_handler', '_end_element_handler');
+		xml_set_character_data_handler($this->parser, '_data_handler');
+		$aux=Array(
+			'name'=>'root',
+			'children'=>Array(),
+			'parent' => 0,
+			'data'=>'',
+			'attribs'	=> Array(),
+		);
+		$this->tree[0]=$aux;
+		$this->current=0;
+
+
+		if (!xml_parse($this->parser, $xml, true)) {
+			$error = sprintf("XML error: %s at line %d",
+				xml_error_string(xml_get_error_code($this->parser)),
+				xml_get_current_line_number($this->parser));
+			trigger_error($error,E_USER_WARNING);
+			$this->error[] = $error;
+		}
+		xml_parser_free($this->parser);
+		// Now that we have the tree we can do interesting things
+
+		$process=Array();
+		$activities=Array();
+		$transitions=Array();
+		for($i=0;$i<count($this->tree[1]['children']);$i++) {
+			// Process attributes
+			$z=$this->tree[1]['children'][$i];
+			$name = trim($this->tree[$z]['name']);
+
+			//config values
+			if ($name=='configs') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+					$z2 = $this->tree[$z]['children'][$j];
+					// this is a config $name = $this->tree[$z2]['name'];
+					$aux = Array();
+					if($this->tree[$z2]['name']=='config') {
+						for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+							$z3 = $this->tree[$z2]['children'][$k];
+							$name = trim($this->tree[$z3]['name']);
+							$value= trim($this->tree[$z3]['data']);
+							$aux[$name]=$value;
+						}
+						$configs[]=$aux;
+					}
+				}
+			}
+			//activities
+			elseif($name=='activities') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+					$z2 = $this->tree[$z]['children'][$j];
+					// this is an activity $name = $this->tree[$z2]['name'];
+					$aux = Array();
+					if($this->tree[$z2]['name']=='activity') {
+						for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+							$z3 = $this->curre[$z2]['children'][$k];
+							$name = trim($this->tree[$z3]['name']);
+							$value= trim($this->tree[$z3]['data']);
+							if($name=='roles') {
+								$roles=Array();
+								for($l=0;$l<count($this->tree[$z3]['children']);$l++) {
+									$z4 = $this->tree[$z3]['children'][$l];
+									$name = trim($this->tree[$z4]['name']);
+									$data = trim($this->tree[$z4]['data']);
+									$attribs = $this->tree[$z4]['attribs'];
+									$readonly = false;
+									if ( (isset($attribs['readonly'])) && ($attribs['readonly']))
+									{
+										//role in read-only
+										$readonly = true;
+									}
+									$roles[]=array(
+										'name' 	=> $data,
+										'readonly'	=> $readonly,
+									);
+								}
+							}
+							elseif ($name=='agents')
+							{
+								$agents=Array();
+								for($l=0;$l<count($this->tree[$z3]['children']);$l++)
+								{
+									$z4 = $this->tree[$z3]['children'][$l];
+									//$name is agent
+									$name = trim($this->tree[$z4]['name']);
+									if ($name = 'agent')
+									{
+										$agent = array();
+										for($m=0;$m<count($this->tree[$z4]['children']);$m++)
+										{
+											$z5 = $this->tree[$z4]['children'][$m];
+											//$name is agent_type or agent_datas
+											$name = trim($this->tree[$z5]['name']);
+											// data will be the agent_type or an array for agent_datas
+											$data = trim($this->tree[$z5]['data']);
+											if ($name=='agent_type')
+											{
+												$agent['wf_agent_type']=$data;
+											}
+											elseif ($name=='agent_datas')
+											{
+												for($n=0;$n<count($this->tree[$z5]['children']);$n++)
+												{
+													$z6 = $this->tree[$z5]['children'][$n];
+													//$name is agent_data $val is an array
+													$name = trim($this->tree[$z6]['name']);
+													$val = trim($this->tree[$z6]['data']);
+													if ($name=='agent_data')
+													{
+														for($o=0;$o<count($this->tree[$z6]['children']);$o++)
+														{
+															$z7 = $this->tree[$z6]['children'][$o];
+															//$name is agent_data $val is 'name' or 'value'
+															$name = trim($this->tree[$z7]['name']);
+															$content = trim($this->tree[$z7]['data']);
+															//echo "<br>z7 name $name content: $content";
+															if ($name=='name')
+															{
+																$agent_data_name = $content;
+															}
+															elseif ($name=='value')
+															{
+																$agent_data_value =& $content;
+															}
+														}
+														//echo "<br>associate $agent_data_name to $agent_data_value <hr>";
+														$agent[$agent_data_name] = $agent_data_value;
+													}
+												}
+											}
+										}
+										$agents[]=$agent;
+									}
+								}
+							} else {
+								$aux[$name]=$value;
+								//print("$name:$value<br/>");
+							}
+						}
+						$aux['agents']=$agents;
+						$aux['roles']=$roles;
+						$activities[]=$aux;
+					}
+				}
+			} elseif($name=='transitions') {
+				for($j=0;$j<count($this->tree[$z]['children']);$j++) {
+					$z2 = $this->tree[$z]['children'][$j];
+					// this is an activity $name = $this->tree[$z2]['name'];
+					$aux=Array();
+					if($this->tree[$z2]['name']=='transition') {
+						for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
+							$z3 = $this->tree[$z2]['children'][$k];
+							$name = trim($this->tree[$z3]['name']);
+							$value= trim($this->tree[$z3]['data']);
+							if($name == 'from' || $name == 'to') {
+								$aux[$name]=$value;
+							}
+						}
+					}
+					$transitions[] = $aux;
+				}
+			} else {
+				$value = trim($this->tree[$z]['data']);
+				//print("$name is $value<br/>");
+				$process[$name]=$value;
+			}
+		}
+		$process['configs']=$configs;
+		$process['activities']=$activities;
+		$process['transitions']=$transitions;
+		return $process;
+	}
+
+	/**
+	 * Creates a process from the process data structure, if you want to convert an XML to a process then use first unserialize_process and then this method.
+	 *
+	 * @access public
+	 * @param string &$data
+	 * @return bool
+	 */
+	function import_process(&$data)
+	{
+		//Now the show begins
+		if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+		if (!(isset($this->role_manager))) $this->role_manager = &Factory::newInstance('RoleManager');
+		if (!isset($this->jobManager))
+			$this->jobManager = &Factory::newInstance('JobManager');
+
+		// First create the process. Always inactive and inactive first.
+		$vars = Array(
+			'wf_name' => trim($data['name']),
+			'wf_version' => $data['version'],
+			'wf_description' => $data['description'],
+			'wf_last_modif' => $data['lastModif'],
+			'wf_is_active' => false,
+			'wf_is_valid' => false,
+			'config' => $data['configs'],
+		);
+
+		if (empty($vars['wf_name']))
+		{
+			$msg = tra('invalid name specified');
+			$this->error[] = $msg;
+			return false;
+		}
+
+		if (ereg('^[0-9]{1,2}\.[0-9]{1,2}$', $vars['wf_version']) === false)
+		{
+			$msg = tra('invalid version specified');
+			$this->error[] = $msg;
+			return false;
+		}
+
+		if ($this->process_name_exists($vars['wf_name'], $vars['wf_version']))
+		{
+			$msg = sprintf(tra('Process %s %s already exists, the import process was aborted'),$vars['wf_name'],$vars['wf_version']);
+			$this->error[] = $msg;
+			return false;
+		}
+		$pid = $this->replace_process(0,$vars,false);
+		//Put the shared code
+		$proc_info = $this->get_process($pid);
+		$wf_procname = $proc_info['wf_normalized_name'];
+		$fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'shared.php',"w");
+		fwrite($fp, $data['sharedCode']);
+		fclose($fp);
+		$actids = Array();
+
+		// Foreach activity create activities
+		foreach($data['activities'] as $activity) {
+
+			$vars = Array(
+				'wf_name' => $activity['name'],
+				'wf_description' => $activity['description'],
+				'wf_type' => $activity['type'],
+				'wf_menu_path' => $activity['menuPath'],
+				'wf_last_modif' => $activity['lastModif'],
+				'wf_is_interactive' => $activity['isInteractive'],
+				'wf_is_autorouted' => $activity['isAutoRouted']
+			);
+			$actname=$this->activity_manager->_normalize_name($activity['name']);
+			$actid = $this->activity_manager->replace_activity($pid,0,$vars);
+
+			$fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php',"w");
+			fwrite($fp, $activity['code']);
+			fclose($fp);
+			if($activity['isInteractive']=='y') {
+				$fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$actname.'.tpl',"w");
+				fwrite($fp,$activity['template']);
+				fclose($fp);
+			}
+			$actids[$activity['name']] = $this->activity_manager->_get_activity_id_by_name($pid, $activity['name']);
+			$actname = $this->activity_manager->_normalize_name($activity['name']);
+			$now = date("U");
+			//roles
+			if( is_array($activity['roles']) && count($activity['roles']) > 0 )
+			{
+				foreach($activity['roles'] as $role)
+				{
+					$rolename = $role['name'];
+					$vars = Array(
+						'wf_name' => $rolename,
+						'wf_description' => $rolename,
+						'wf_last_modif' => $now,
+					);
+					if(!$this->role_manager->role_name_exists($pid,$rolename)) {
+						$rid=$this->role_manager->replace_role($pid,0,$vars);
+					} else {
+						$rid = $this->role_manager->get_role_id($pid,$rolename);
+					}
+					if($actid && $rid) {
+						$this->activity_manager->add_activity_role($actid,$rid,$role['readonly']);
+					}
+				}
+			}
+			//agents
+			if( is_array($activity['agents']) && count($activity['agents']) > 0 )
+			{
+				foreach($activity['agents'] as $agent)
+				{
+					if (empty($agent['wf_agent_type']))
+					{
+						$this->error[] = lang('empty agent type');
+					}
+					else
+					{
+						//create a new agent of the same type for the new activity
+						$agentid = $this->activity_manager->add_activity_agent($actid,$agent['wf_agent_type']);
+						//save values of this new agent
+						$bindvars = Array();
+						$query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$agent['wf_agent_type'].'
+							set ';
+						//we wont need the old type anymore
+						unset($agent['wf_agent_type']);
+						$countfields = 0;
+						foreach ($agent as $key => $value)
+						{
+							if ($key)
+							{
+								$countfields++;
+								$query .= "$key = ? ,";
+								$bindvars[] = $value;
+							}
+						}
+						$query = substr($query,'0',-1);
+						$query .= ' where wf_agent_id = ?';
+						$bindvars[] = $agentid;
+						if ($countfields) $this->query($query, $bindvars);
+					}
+				}
+			}
+		}
+		//transitions
+		foreach($data['transitions'] as $tran)
+		{
+			$this->activity_manager->add_transition($pid,$actids[$tran['from']],$actids[$tran['to']]);
+		}
+
+		foreach ($data['jobs'] as $job)
+		{
+			$this->jobManager->replaceJob($pid, 0, $job);
+		}
+
+		// create a graph for the new process
+		$this->activity_manager->build_process_graph($pid);
+		//Test the final process
+		$this->activity_manager->validate_process_activities($pid);
+
+		$msg = sprintf(tra('Process %s %s imported'),$proc_info['wf_name'],$proc_info['wf_version']);
+		$this->error[] = $msg;
+		return true;
+	}
+
+	/**
+	 * Creates a new process based on an existing process changing the process version.
+	 * By default the process is created as an unactive process and the version is by default a minor version of the process
+	 *
+	 * @param int $pId Process id
+	 * @param bool $minor Process previous version
+	 * @return int Process id
+	 * @access public
+	 */
+	function new_process_version($pId, $minor=true)
+	{
+		if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+		$oldpid = $pId;
+		//retrieve process info with config rows
+		$proc_info = $this->get_process($pId, true);
+		if(!($proc_info) || (count($proc_info)==0)) return false;
+		$name = $proc_info['wf_name'];
+
+		// Now update the version
+		$version = $this->_new_version($proc_info['wf_version'],$minor);
+		while($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_name=? and wf_version=?',array($name,$version)))
+		{
+			$version = $this->_new_version($version,$minor);
+		}
+		$oldname = $proc_info['wf_normalized_name'];
+
+		// Make new versions unactive
+		$proc_info['wf_version'] = $version;
+		$proc_info['wf_is_active'] = 'n';
+		// create a new process, but don't create start/end activities
+		$pid = $this->replace_process(0, $proc_info, false);
+		if (!pid) return false;
+
+		//Since we are copying a process we should copy
+		//the old directory structure to the new directory
+		//oldname was saved a few lines before
+		$newname = $this->_get_normalized_name($pid);
+		$this->_rec_copy(GALAXIA_PROCESSES.SEP.$oldname.SEP.'code',GALAXIA_PROCESSES.SEP.$newname.SEP.'code');
+		// And here copy all the activities & so
+		$query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?';
+		$result = $this->query($query, array($oldpid));
+		$newaid = array();
+		while($res = $result->fetchRow()) {
+			$oldaid = $res['wf_activity_id'];
+			// the false tell the am not to create activities source files
+			$newaid[$oldaid] = $this->activity_manager->replace_activity($pid,0,$res, false);
+		}
+		// create transitions
+		$query = 'select * from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=?';
+		$result = $this->query($query, array($oldpid));
+
+		/* create the jobs */
+		$query = "INSERT INTO " . GALAXIA_TABLE_PREFIX . "jobs (wf_process_id, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, active) (SELECT {$pid}, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, FALSE FROM " . GALAXIA_TABLE_PREFIX . "jobs WHERE wf_process_id = ?)";
+		$this->query($query, array($oldpid));
+
+		while($res = $result->fetchRow()) {
+			if (empty($newaid[$res['wf_act_from_id']]) || empty($newaid[$res['wf_act_to_id']])) {
+				continue;
+			}
+			$this->activity_manager->add_transition($pid,$newaid[$res['wf_act_from_id']],$newaid[$res['wf_act_to_id']]);
+		}
+		// create roles
+		if (!(isset($this->role_manager))) $this->role_manager = &Factory::newInstance('RoleManager');
+		$query = 'select * from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?';
+		$result = $this->query($query, array($oldpid));
+		$newrid = array();
+		while($res = $result->fetchRow()) {
+			if(!$this->role_manager->role_name_exists($pid,$res['wf_name'])) {
+				$rid=$this->role_manager->replace_role($pid,0,$res);
+			} else {
+				$rid = $this->role_manager->get_role_id($pid,$res['wf_name']);
+			}
+			$newrid[$res['wf_role_id']] = $rid;
+		}
+		// map users to roles
+		if (count($newrid) > 0) {
+			$query = 'select * from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?';
+			$result = $this->query($query, array($oldpid));
+			while($res = $result->fetchRow()) {
+				if (empty($newrid[$res['wf_role_id']])) {
+					continue;
+				}
+				$this->role_manager->map_user_to_role($pid,$res['wf_user'],$newrid[$res['wf_role_id']], $res['wf_account_type']);
+			}
+		}
+		// add roles to activities
+		if (count($newaid) > 0 && count($newrid ) > 0) {
+			$query = 'select * from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id in (' . join(', ',array_keys($newaid)) . ')';
+			$result = $this->query($query);
+			while($res = $result->fetchRow()) {
+				if (empty($newaid[$res['wf_activity_id']]) || empty($newrid[$res['wf_role_id']])) {
+					continue;
+				}
+				$this->activity_manager->add_activity_role($newaid[$res['wf_activity_id']],$newrid[$res['wf_role_id']], $res['wf_readonly']);
+			}
+		}
+
+		//create agents
+		//get the list of agents used by the old process
+		$query = 'select gaa.* from '.GALAXIA_TABLE_PREFIX.'activity_agents gaa
+			INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities gac ON gaa.wf_activity_id = gac.wf_activity_id
+			where gac.wf_p_id=?';
+		$result = $this->query($query, array($oldpid));
+		if (!(empty($result)))
+		{
+			while ($res = $result->fetchRow())
+			{
+				//create a new agent of the same type for the new activity
+				$agentid = $this->activity_manager->add_activity_agent($newaid[$res['wf_activity_id']],$res['wf_agent_type']);
+				//save values of this new agents, taking the old ones, we make a simple copy
+				$old_activity_agent_data =& $this->activity_manager->get_activity_agent_data($res['wf_activity_id'],$res['wf_agent_type']);
+				//we wont need the old id and type
+				unset($old_activity_agent_data['wf_agent_id']);
+				unset($old_activity_agent_data['wf_agent_type']);
+				$bindvars = Array();
+				$query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$res['wf_agent_type'].'
+					set ';
+				$countfields = 0;
+				foreach ($old_activity_agent_data as $key => $value)
+				{
+					if ($key)
+					{
+						$countfields++;
+						$query .= "$key = ? ,";
+						$bindvars[] = $value;
+					}
+				}
+				$query = substr($query,'0',-1);
+				$query .= ' where wf_agent_id = ?';
+				$bindvars[] = $agentid;
+				if ($countfields) $this->query($query, $bindvars);
+			}
+		}
+
+		// create a graph for the new process
+		$this->activity_manager->build_process_graph($pid);
+
+		return $pid;
+	}
+
+	/**
+	 * This function can be used to check if a process name exists, note that this is NOT used by replace_process since that function can be used to
+	 * create new versions of an existing process. The application must use this method to ensure that processes have unique names.
+	 *
+	 * @param string $name Process name
+	 * @param string $version Process version
+	 * @return bool
+	 * @access public
+	 */
+	function process_name_exists($name,$version)
+	{
+		$name = addslashes($this->_normalize_name($name,$version));
+		return $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_normalized_name=?',array($name));
+	}
+
+
+	/**
+	 * Gets a process by pId. Fields are returned as an associative array.
+	 * If withConfig is set (false by default), the configuration options are returned as well the ['config'] key is then an array containing the config data with type distinction
+	 *
+	 * @param int $pId Process id
+	 * @param bool $withConfig Configuration options
+	 * @return bool
+	 * @access public
+	 */
+	function get_process($pId, $withConfig=false)
+	{
+		$query = 'select * from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?';
+		$result = $this->query($query, array($pId));
+		if((empty($result)) || (!$result->numRows())) return false;
+		$res = $result->fetchRow();
+		if ($withConfig)
+		{
+			// by setting true we force this function to keep type distinction on config values
+			$res['config'] = $this->getConfigValues($res['wf_p_id'], true);
+		}
+		return $res;
+	}
+
+	/**
+	 * Lists all processes
+	 *
+	 * @param int $offset Resultset starting row
+	 * @param int	$maxRecords Max number of resulting rows
+	 * @param string $sort_mode Sorting mode
+	 * @param string $find Search query string
+	 * @param string $where Condition query string
+	 * @return bool
+	 * @access public
+	 */
+	function list_processes($offset,$maxRecords,$sort_mode,$find='',$where='')
+	{
+		$sort_mode = $this->convert_sortmode($sort_mode);
+		if($find) {
+			$findesc = '%'.$find.'%';
+			$mid=' where ((wf_name like ?) or (wf_description like ?))';
+			$bindvars = array($findesc,$findesc);
+		} else {
+			$mid='';
+			$bindvars = array();
+		}
+		if($where) {
+			if($mid) {
+				$mid.= " and ($where) ";
+			} else {
+				$mid.= " where ($where) ";
+			}
+		}
+		$query = 'select * from '.GALAXIA_TABLE_PREFIX."processes $mid";
+		$query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."processes $mid";
+		$result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode);
+		$cant = $this->getOne($query_cant,$bindvars);
+		$ret = Array();
+		if (isset($result))
+		{
+			while($res = $result->fetchRow())
+			{
+				$ret[] = $res;
+			}
+		}
+		$retval = Array();
+		$retval['data'] = $ret;
+		$retval['cant'] = $cant;
+		return $retval;
+	}
+
+  /*!
+   Marks a process as an invalid process
+   */
+	function invalidate_process($pid)
+	{
+		$query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_valid=? where wf_p_id=?';
+		$this->query($query, array('n',$pid));
+	}
+
+	/**
+	 * Removes a process by pId
+	 *
+	 * @param int $pId Process id
+	 * @return bool
+	 * @access public
+	 */
+	function remove_process($pId)
+	{
+		if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+		if (!isset($this->jobManager))
+			$this->jobManager = &Factory::newInstance('JobManager');
+		$this->deactivate_process($pId);
+		$name = $this->_get_normalized_name($pId);
+
+		// start a transaction
+		$this->db->StartTrans();
+		$this->jobManager->removeJobsByProcessID($pId);
+
+		// Remove process activities
+		$query = 'select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?';
+		$result = $this->query($query, array($pId));
+		while($res = $result->fetchRow()) {
+			//we add a false parameter to prevent the ActivityManager from opening a new transaction
+			$this->activity_manager->remove_activity($pId,$res['wf_activity_id'], false);
+		}
+
+		// Remove process roles
+		$query = 'delete from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?';
+		$this->query($query, array($pId));
+		$query = 'delete from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?';
+		$this->query($query, array($pId));
+
+		// Remove process instances
+		$query = 'delete from '.GALAXIA_TABLE_PREFIX.'instances where wf_p_id=?';
+		$this->query($query, array($pId));
+
+		// Remove the directory structure
+		if (!empty($name) && is_dir(GALAXIA_PROCESSES.SEP.$name)) {
+			$this->_remove_directory(GALAXIA_PROCESSES.SEP.$name,true);
+		}
+		if (GALAXIA_TEMPLATES && !empty($name) && is_dir(GALAXIA_TEMPLATES.SEP.$name)) {
+			$this->_remove_directory(GALAXIA_TEMPLATES.SEP.$name,true);
+		}
+
+		// Remove configuration data
+		$query = 'delete from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?';
+		$this->query($query, array($pId));
+
+		// And finally remove the proc
+		$query = 'delete from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?';
+		$this->query($query, array($pId));
+		$msg = sprintf(tra('Process %s removed'),$name);
+		$this->error[] = $msg;
+
+		// perform commit (return true) or Rollback (return false)
+		return $this->db->CompleteTrans();
+
+	}
+
+	/**
+	 * Updates or inserts a new process in the database, $vars is an associative array containing the fields to update or to insert as needed.
+	 * Configuration options should be in an array associated with the 'config' key
+	 * this config array should contain 'wf_config_name', 'wf_config_value' and 'wf_config_value_int' keys.
+	 * $pId is the processI. If $pId is 0 then we create a new process, else we are in edit mode.
+	 * if $create is true start and end activities will be created (when importing use $create=false)
+	 *
+	 * @param int $pId Process id, if 0 then we create a new process, else we are in edit mode
+	 * @param array &$vars Associative containing the fields to update or to insert as needed
+	 * @param bool $create If true, start and end activities will be created (when importing use $create=false).
+	 * @return int Process id
+	 * @access public
+	 */
+	function replace_process($pId, &$vars, $create = true)
+	{
+		if (!(isset($this->activity_manager)))  $this->activity_manager = &Factory::newInstance('ActivityManager');
+		$TABLE_NAME = GALAXIA_TABLE_PREFIX.'processes';
+		$now = date("U");
+		$vars['wf_last_modif']=$now;
+		$vars['wf_normalized_name'] = $this->_normalize_name($vars['wf_name'],$vars['wf_version']);
+		$config_array = array();
+
+		foreach($vars as $key=>$value)
+		{
+			if ($key=='config')
+			{
+				$config_array_init =& $value;
+				// rebuild a nice config_array with type of config and value
+				if( is_array($config_array_init) && count($config_array_init) > 0 )
+				{
+					foreach($config_array_init as $config)
+					{
+						if (isset($config['wf_config_value_int']) && (!($config['wf_config_value_int']=='')))
+						{
+							$config_array[$config['wf_config_name']] = array('int' => $config['wf_config_value_int']);
+						}
+						else
+						{
+							if (isset($config['wf_config_value']))
+							{
+								$config_array[$config['wf_config_name']] = array('text' => $config['wf_config_value']);
+							}
+						}
+					}
+				}
+				//no need to keep it in the vars array, this array is used in queries
+				unset($vars['config']);
+			}
+			else // not config, it's just process's fields values
+			{
+				$vars[$key]=addslashes($value);
+			}
+		}
+
+		if($pId) {
+			// update mode
+			$old_proc = $this->get_process($pId);
+			$first = true;
+			$query ="update $TABLE_NAME set";
+			foreach($vars as $key=>$value) {
+				if(!$first) $query.= ',';
+				if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'";
+				$query.= " $key=$value ";
+				$first = false;
+			}
+			$query .= " where wf_p_id=$pId ";
+			$this->query($query);
+
+			//set config values
+			$this->setConfigValues($pId,$config_array);
+
+			// Note that if the name is being changed then
+			// the directory has to be renamed!
+			$oldname = $old_proc['wf_normalized_name'];
+			$newname = $vars['wf_normalized_name'];
+			if ($newname != $oldname) {
+				rename(GALAXIA_PROCESSES.SEP."$oldname",GALAXIA_PROCESSES.SEP."$newname");
+			}
+			$msg = sprintf(tra('Process %s has been updated'),$vars['wf_name']);
+			$this->error[] = $msg;
+		} else {
+			unset($vars['wf_p_id']);
+			// insert mode
+			$name = $this->_normalize_name($vars['wf_name'],$vars['wf_version']);
+			$this->_create_directory_structure($name);
+			$first = true;
+			$query = "insert into $TABLE_NAME(";
+			foreach(array_keys($vars) as $key) {
+				if(!$first) $query.= ',';
+				$query.= "$key";
+				$first = false;
+			}
+			$query .=") values(";
+			$first = true;
+			foreach(array_values($vars) as $value) {
+				if(!$first) $query.= ',';
+				if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'";
+				$query.= "$value";
+				$first = false;
+			}
+			$query .=")";
+			$this->query($query);
+			//FIXME: this query seems to be quite sure to get a result, I would prefer something
+			// more sure to get the right result everytime
+			$pId = $this->getOne("select max(wf_p_id) from $TABLE_NAME where wf_last_modif=$now");
+
+			//set config values
+			$this->setConfigValues($pId,$config_array);
+
+			// Now automatically add a start and end activity
+			// unless importing ($create = false)
+			if($create) {
+				$vars1 = Array(
+					'wf_name' => 'start',
+					'wf_description' => 'default start activity',
+					'wf_type' => 'start',
+					'wf_is_interactive' => 'y',
+					'wf_is_autorouted' => 'y'
+				);
+				$vars2 = Array(
+					'wf_name' => 'end',
+					'wf_description' => 'default end activity',
+					'wf_type' => 'end',
+					'wf_is_interactive' => 'n',
+					'wf_is_autorouted' => 'y'
+				);
+
+				$this->activity_manager->replace_activity($pId,0,$vars1);
+				$this->activity_manager->replace_activity($pId,0,$vars2);
+			}
+			$msg = sprintf(tra('Process %s has been created'),$vars['wf_name']);
+			$this->error[] = $msg;
+		}
+		// Get the id
+		return $pId;
+	}
+
+	/**
+	 * Gets the normalized name of a process by pid
+	 *
+	 * @param int $pId Process id
+	 * @access private
+	 * @return string
+	 */
+	function _get_normalized_name($pId)
+	{
+		$info = $this->get_process($pId);
+		return $info['wf_normalized_name'];
+	}
+
+	/**
+	 * Normalizes a process name
+	 *
+	 * @param string $name Process name to be normalized
+	 * @param string $version Process version
+	 * @access private
+	 * @return string Process normalized name
+	 */
+	function _normalize_name($name, $version)
+	{
+		$name = $name.'_'.$version;
+		$name = str_replace(" ","_",$name);
+		$name = preg_replace("/[^0-9A-Za-z\_]/",'',$name);
+		return $name;
+	}
+
+	/**
+	 * Generates a new minor version number
+	 *
+	 * @param string $version Current process version
+	 * @param bool $minor Generate minor version
+	 * @access private
+	 * @return string
+	 */
+	function _new_version($version,$minor=true)
+	{
+		$parts = explode('.',$version);
+		if($minor) {
+			$parts[count($parts)-1]++;
+		} else {
+			$parts[0]++;
+			for ($i = 1; $i < count($parts); $i++) {
+				$parts[$i] = 0;
+			}
+		}
+		return implode('.',$parts);
+	}
+
+	/**
+	 * Creates directory structure for process
+	 *
+	 * @param string $name Dir name in process repository
+	 * @access private
+	 * @return bool
+	 */
+	function _create_directory_structure($name)
+	{
+		$path = GALAXIA_PROCESSES.SEP.$name;
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."resources";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."graph";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."code";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."activities";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."templates";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."jobs";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."cache";
+		if (!file_exists($path)) mkdir($path,0770);
+		$path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."compiled";
+		if (!file_exists($path)) mkdir($path,0770);
+		if (GALAXIA_TEMPLATES) {
+			$path = GALAXIA_TEMPLATES.SEP.$name;
+			if (!file_exists($path)) mkdir($path,0770);
+		}
+		// Create shared file
+		$file = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php";
+		if (!file_exists($file))
+		{
+			$fp = fopen(GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php","w");
+			if (!fp) return false;
+			fwrite($fp,'<'.'?'.'php'."\n".'?'.'>');
+			fclose($fp);
+		}
+	}
+
+	/**
+	 * Removes a directory recursively
+	 *
+	 * @param string $dir Dir name to be erased
+	 * @param bool $rec Recursive mode
+	 * @access private
+	 * @return void
+	 */
+	function _remove_directory($dir,$rec=false)
+	{
+		// Prevent a disaster
+		if(trim($dir) == SEP || trim($dir)=='.' || trim($dir)=='templates' || trim($dir)=='templates'.SEP) return false;
+		$h = opendir($dir);
+		while(($file = readdir($h)) != false) {
+			if(is_file($dir.SEP.$file)) {
+				@unlink($dir.SEP.$file);
+			} else {
+				if($rec && $file != '.' && $file != '..') {
+					$this->_remove_directory($dir.SEP.$file, true);
+				}
+			}
+		}
+		closedir($h);
+		@rmdir($dir);
+		@unlink($dir);
+	}
+
+	/**
+	 * Copies a directory recursively
+	 *
+	 * @param string $dir1 Dir name to be copied
+	 * @param string $dir2 Generated destination dir
+	 * @access private
+	 * @return void
+	 */
+	function _rec_copy($dir1,$dir2)
+	{
+		@mkdir($dir2,0777);
+		$h = opendir($dir1);
+		while(($file = readdir($h)) !== false) {
+			if(is_file($dir1.SEP.$file)) {
+				copy($dir1.SEP.$file,$dir2.SEP.$file);
+			} else {
+				if($file != '.' && $file != '..') {
+					$this->_rec_copy($dir1.SEP.$file, $dir2.SEP.$file);
+				}
+			}
+		}
+		closedir($h);
+	}
+
+	/**
+	 * XML parser start element handler
+	 *
+	 * @param resource $parser Parser handle
+	 * @param string $element XML tag
+	 * @param array $attribs XML tag attributes
+	 * @access private
+	 * @return void
+	 */
+	function _start_element_handler($parser, $element, $attribs)
+	{
+		$aux=Array('name'=>$element,
+			'data'=>'',
+			'parent' => $this->current,
+			'children'=>Array(),
+			'attribs' => $attribs);
+
+		$i = count($this->tree);
+		$this->tree[$i] = $aux;
+
+		$this->tree[$this->current]['children'][]=$i;
+		$this->current=$i;
+	}
+
+	/**
+	 * XML parser end element handler
+	 *
+	 * @param resource $parser Parser handle
+	 * @param string $element XML tag
+	 * @param array $attribs XML tag attributes
+	 * @access private
+	 * @return void
+	 */
+	function _end_element_handler($parser, $element)
+	{
+		//when a tag ends put text
+		$this->tree[$this->current]['data']=$this->buffer;
+		$this->buffer='';
+		$this->current=$this->tree[$this->current]['parent'];
+	}
+
+	/**
+	 * XML parser element data handler
+	 *
+	 * @param resource $parser Parser handle
+	 * @param string $element XML tag
+	 * @param string $data XML tag content
+	 * @access private
+	 * @return void
+	 */
+	function _data_handler($parser, $data)
+	{
+		$this->buffer .= $data;
+	}
+
+	/**
+	 * This getConfigValues differs from the Process::getConfigValues because requires only process id.
+	 * This method gets the items defined in process_config table for this process, in fact this admin function bypass
+	 * the process behaviour and is just showing you the basic content of the table.
+	 * All config items are returned as a function result.
+	 *
+	 * @param int $pId Process id
+	 * @param bool $distinct_types If the distinct_type is set the returned array will follow the format:
+	 * * 0	=>('wf_config_name'=> 'foo')
+	 *  		=>('wf_config_value'=>'bar')
+	 *  		=>('wf_config_vale_int'=>null)
+	 * * 1 	=>('wf_config_name' => 'toto')
+	 *  		=>('wf_config_value'=>'')
+	 *  		=>('wf_config_vale_int'=>15)
+	 * if set to false (default) the result array will be (note that this is the default result if having just the $pId):
+	 * * 'foo'=>'bar'
+	 * * 'toto'=>15
+	 * @param bool $askProcessObject If the askProcessObject is set to true (false by default) then the ProcessManager will load a process
+	 * object to run directly Process->getConfigValues($config_ask_array) this let you use this ProcessManager
+	 * getConfigValues the same way you would use $process->getConfigValues, with initialisation of default values.
+	 * you should then call this function this way: $conf_result=$pm->getConfigValues($pId,true,true,$my_conf_array)
+	 * @param array $config_array
+	 * @access public
+	 * @return array
+	 */
+	function getConfigValues($pId, $distinct_types=false, $askProcessObject=false, $config_array=array())
+	{
+		if (!$askProcessObject)
+		{
+			$query = 'select * from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?';
+			$result = $this->query($query, array($pId));
+			$result_array=array();
+			while($res = $result->fetchRow())
+			{
+				if ( (!$distinct_types) )
+				{// we want a simple array
+					if ($res['wf_config_value_int']==null)
+					{
+						$result_array[$res['wf_config_name']] = $res['wf_config_value'];
+					}
+					else
+					{
+						$result_array[$res['wf_config_name']] = $res['wf_config_value_int'];
+					}
+				}
+				else
+				{// build a more complex result array, which is just the table rows
+					$result_array[] = $res;
+				}
+			}
+		}
+		else //we'll load a Process object and let him work for us
+		{
+			//Warning: this means you have to include the Process.php from the API
+			$this->Process = &Factory::newInstance('Process');
+			$this->Process->getProcess($pId);
+			$result_array = $this->Process->getConfigValues($config_array);
+			unset ($this->Process);
+		}
+		return $result_array;
+	}
+
+	/**
+	 * Calls a process object to save his new config values by taking a process Id as first argument and simply call
+	 * this process's setConfigValues method. We let the process define the better way to store the data given as second arg.
+	 *
+	 * @param int $pId Process id
+	 * @param array &$config_array
+	 * @return void
+	 * @access public
+	 */
+	function setConfigValues($pId, &$config_array)
+	{
+		//Warning: this means you have to include the Process.php from the API
+		$this->Process = &Factory::newInstance('Process');
+		$this->Process->getProcess($pId);
+		$this->Process->setConfigValues($config_array);
+		unset ($this->Process);
+	}
+
+	/**
+	 * Gets available agents list
+	 *
+	 * @return array
+	 * @access public
+	 */
+	function get_agents()
+	{
+		return galaxia_get_agents_list();
+	}
+
+	/**
+	 * Gets the view activity id avaible for a given process
+	 *
+	 * @param int $pId Process Id
+	 * @return bool False if no view activity is avaible for the process, return the activity id if there is one
+	 * @access public
+	 */
+	function get_process_view_activity($pId)
+	{
+		$mid = 'where gp.wf_p_id=? and ga.wf_type=?';
+		$bindvars = array($pId,'view');
+		$query = 'select ga.wf_activity_id
+			from '.GALAXIA_TABLE_PREFIX.'processes gp
+			INNER JOIN '.GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
+			$mid";
+		$result = $this->query($query,$bindvars);
+		$ret = Array();
+		$retval = false;
+		if (!(empty($result)))
+		{
+			while($res = $result->fetchRow())
+			{
+				$retval = $res['wf_activity_id'];
+			}
+		}
+		return $retval;
+	}
+
+}
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/GraphViz.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/GraphViz.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/GraphViz.php	(revision 795)
@@ -0,0 +1,496 @@
+<?php
+//
+// +----------------------------------------------------------------------+
+// | PEAR :: Image :: GraphViz                                            |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 2002 Sebastian Bergmann <sb@sebastian-bergmann.de> and |
+// |                    Dr. Volker GÃ¶bbels <vmg@arachnion.de>.            |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 3.00 of the PHP License,      |
+// | that is available at http://www.php.net/license/3_0.txt.             |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+//
+//
+
+/**
+* PEAR::Image_GraphViz
+*
+* Purpose
+*
+*     Allows for the creation of and the work with directed
+*     and undirected graphs and their visualization with
+*     AT&T's GraphViz tools. These can be found at
+*     http://www.research.att.com/sw/tools/graphviz/
+*
+* Example
+*
+*     require_once 'Image/GraphViz.php';
+*     $graph = new Image_GraphViz();
+*
+*     $graph->addNode('Node1', array('URL'      => 'http://link1',
+*                                    'label'    => 'This is a label',
+*                                    'shape'    => 'box'
+*                                    )
+*                     );
+*     $graph->addNode('Node2', array('URL'      => 'http://link2',
+*                                    'fontsize' => '14'
+*                                    )
+*                     );
+*     $graph->addNode('Node3', array('URL'      => 'http://link3',
+*                                    'fontsize' => '20'
+*                                    )
+*                     );
+*
+*     $graph->addEdge(array('Node1' => 'Node2'), array('label' => 'Edge Label'));
+*     $graph->addEdge(array('Node1' => 'Node2'), array('color' => 'red'));
+*
+*     $graph->image();
+*
+* @author  Sebastian Bergmann <sb@sebastian-bergmann.de>
+*          Dr. Volker GÃ¶bbels <vmg@arachnion.de>
+* @package Galaxia
+*/
+class Process_GraphViz {
+    /**
+    * @var string $dotCommand Path to GraphViz/dot command
+    * @access public
+    */
+    var $dotCommand = 'dot';
+    
+    /**
+    * @var string $pid
+    * @access public
+    */
+    var $pid;
+
+    /**
+    * @var string $neatoCommand Path to GraphViz/dot command
+    * @access public
+    */
+    var $neatoCommand = 'neato';
+
+    /**
+    * @var  array $graph Path to GraphViz/dot command
+    * @access public
+    */
+    var $graph;
+
+    /**
+    * Constructor
+    *
+    * @param  boolean $directed Directed (true) or undirected (false) graph.
+    * @param  array  $attributes Attributes of the graph
+    * @access public
+    */
+    function Process_GraphViz($directed = true, $attributes = array()) {
+        $this->setDirected($directed);
+        $this->setAttributes($attributes);
+        if (defined('GRAPHVIZ_BIN_DIR') && GRAPHVIZ_BIN_DIR) {
+            $this->dotCommand = GRAPHVIZ_BIN_DIR.'/'.$this->dotCommand;
+            $this->neatoCommand = GRAPHVIZ_BIN_DIR.'/'.$this->neatoCommand;
+        }
+    }
+    
+    /**
+    * Set pid
+    *
+    * @param  string $pid pid
+    * @access public
+    * @return void
+    */
+    function set_pid($pid) 
+    {
+      $this->pid = $pid;
+    }
+
+    /**
+    * Output image of the graph in a given format.
+    *
+    * @param  string $format Format of the output image. This may be one of the formats supported by GraphViz.
+    * @param  string $file Name of the output file.
+    * @access public
+    * @return string
+    */
+    function image($format = 'png', $file = '') {
+        if ($file = $this->saveParsedGraph($file)) {
+            $outputfile = $file . '.' . $format;
+            $outputfile2 = $file . '.' . 'map';
+            $command  = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
+            $command .= " -T$format -Gcharset=latin1 -o$outputfile $file";
+
+            @`$command`;
+            $command = $this->dotCommand;
+            $command.= " -Tcmap -Gcharset=latin1 -o$outputfile2 $file";
+            @`$command`;
+            $fr = fopen($outputfile2,"r");
+            $map = fread($fr,filesize($outputfile2));
+            fclose($fr);
+            @unlink($file);
+
+            switch ($format) {
+                case 'gif':
+                case 'jpg':
+                case 'png':
+                case 'svg':
+                case 'wbmp': {
+                    header('Content-Type: image/' . $format);
+                }
+                break;
+
+                case 'pdf': {
+                    header('Content-Type: application/pdf');
+                }
+                break;
+            }
+
+            header('Content-Length: ' . filesize($outputfile));
+
+            $fp = fopen($outputfile, 'rb');
+
+            if ($fp) {
+                echo fread($fp, filesize($outputfile));
+                fclose($fp);
+                @unlink($outputfile);
+            }
+            @unlink($outputfile2);
+            return $map;
+        }
+    }
+    
+    /**
+    * Output image of the graph in a given format.
+    *
+    * @param  string $format Format of the output image. This may be one of the formats supported by GraphViz.
+    * @access public
+    * return boolean
+    */
+    function image_and_map($format = 'png') {
+        if ($file = $this->saveParsedGraph()) {
+            $outputfile = $file . '.' . $format;
+            $outputfile2 = $file . '.' . 'map';
+            if(!isset($this->graph['directed'])) $this->graph['directed']=true;
+            $command  = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
+            $command .= " -T$format -Gcharset=latin1 -o $outputfile $file";
+            @`$command`;
+
+            $command = $this->dotCommand;
+            $command.= " -Tcmap -Gcharset=latin1 -o $outputfile2 $file";
+            @`$command`;
+            @unlink($file);
+            return true;
+        }
+    }
+
+    /**
+    * Map the current image
+    *
+    * @access public
+    * return boolean
+    */
+    function map() {
+        if ($file = $this->saveParsedGraph()) {
+            
+            $outputfile2 = $file . '.' . 'map';
+            
+            $command = $this->dotCommand;
+            $command.= " -Tcmap -Gcharset=latin1 -o$outputfile2 $file";
+            @`$command`;
+            $fr = fopen($outputfile2,"r");
+            $map = fread($fr,filesize($outputfile2));
+            fclose($fr);
+            
+            @unlink($outputfile2);
+            @unlink($file);
+            return $map;
+        }
+    }
+
+    /**
+    * Add a cluster to the graph.
+    *
+    * @param  string $id ID.
+    * @param  array  $title Title.
+    * @access public
+    * @return void
+    */
+    function addCluster($id, $title) {
+        $this->graph['clusters'][$id] = $title;
+    }
+
+    /**
+    * Add a node to the graph.
+    *
+    * @param  string $name Name of the node.
+    * @param  array $attributes  Attributes of the node.
+    * @param  string $group Group of the node.
+    * @access public
+    * @return void
+    */
+    function addNode($name, $attributes = array(), $group = 'default') {
+        $this->graph['nodes'][$group][$name] = $attributes;
+    }
+
+    /**
+    * Remove a node from the graph.
+    *
+    * @param  string $name Name of the node to be removed.
+    * @param  string $group Name of the node group to be removed.
+    * @access public
+    * @return void
+    */
+    function removeNode($name, $group = 'default') {
+        if (isset($this->graph['nodes'][$group][$name])) {
+            unset($this->graph['nodes'][$group][$name]);
+        }
+    }
+
+    /**
+    * Add an edge to the graph.
+    *
+    * @param  array $edge Start and End node of the edge.
+    * @param  array $attributes Attributes of the edge.
+    * @access public
+    * @return void
+    */
+    function addEdge($edge, $attributes = array()) {
+        if (is_array($edge)) {
+            $from = key($edge);
+            $to   = $edge[$from];
+            $id   = $from . '_' . $to;
+
+            if (!isset($this->graph['edges'][$id])) {
+                $this->graph['edges'][$id] = $edge;
+            } else {
+                $this->graph['edges'][$id] = array_merge(
+                  $this->graph['edges'][$id],
+                  $edge
+                );
+            }
+
+            if (is_array($attributes)) {
+                if (!isset($this->graph['edgeAttributes'][$id])) {
+                    $this->graph['edgeAttributes'][$id] = $attributes;
+                } else {
+                    $this->graph['edgeAttributes'][$id] = array_merge(
+                      $this->graph['edgeAttributes'][$id],
+                      $attributes
+                    );
+                }
+            }
+        }
+    }
+
+    /**
+    * Remove an edge from the graph.
+    *
+    * @param  array $edge Start and End node of the edge to be removed.
+    * @access public
+    * return void
+    */
+    function removeEdge($edge) {
+        if (is_array($edge)) {
+              $from = key($edge);
+              $to   = $edge[$from];
+              $id   = $from . '_' . $to;
+
+            if (isset($this->graph['edges'][$id])) {
+                unset($this->graph['edges'][$id]);
+            }
+
+            if (isset($this->graph['edgeAttributes'][$id])) {
+                unset($this->graph['edgeAttributes'][$id]);
+            }
+        }
+    }
+
+    /**
+    * Add attributes to the graph.
+    *
+    * @param  array Attributes to be added to the graph.
+    * @access public
+    * @return void
+    * 
+    */
+    function addAttributes($attributes) {
+        if (is_array($attributes)) {
+            $this->graph['attributes'] = array_merge(
+              $this->graph['attributes'],
+              $attributes
+            );
+        }
+    }
+
+    /**
+    * Set attributes of the graph.
+    *
+    * @param  array Attributes to be set for the graph.
+    * @access public
+    * @return void
+    */
+    function setAttributes($attributes) {
+        if (is_array($attributes)) {
+            $this->graph['attributes'] = $attributes;
+        }
+    }
+
+    /**
+    * Set directed/undirected flag for the graph.
+    *
+    * @param  boolean Directed (true) or undirected (false) graph.
+    * @access public
+    * @return void
+    */
+    function setDirected($directed) {
+        if (is_bool($directed)) {
+            $this->graph['directed'] = $directed;
+        }
+    }
+
+    /**
+    * Load graph from file.
+    *
+    * @param  string $file File to load graph from.
+    * @access public
+    * @return void
+    */
+    function load($file) {
+        if ($serialized_graph = implode('', @file($file))) {
+            $this->graph = unserialize($serialized_graph);
+        }
+    }
+
+    /**
+    * Save graph to file.
+    *
+    * @param  string  $file File to save the graph to.
+    * @return mixed  File the graph was saved to, false on failure.
+    * @access public
+    */
+    function save($file = '') {
+        $serialized_graph = serialize($this->graph);
+
+        if (empty($file)) {
+            $file = tempnam('temp', 'graph_');
+        }
+
+        if ($fp = @fopen($file, 'w')) {
+            @fputs($fp, $serialized_graph);
+            @fclose($fp);
+
+            return $file;
+        }
+
+        return false;
+    }
+
+    /**
+    * Parse the graph into GraphViz markup.
+    *
+    * @return string  GraphViz markup
+    * @access public
+    */
+    function parse() {
+        $parsedGraph = "digraph G {\n";
+
+        if (isset($this->graph['attributes'])) {
+            foreach ($this->graph['attributes'] as $key => $value) {
+                $attributeList[] = $key . '="' . $value . '"';
+            }
+
+            if (!empty($attributeList)) {
+              $parsedGraph .= implode(',', $attributeList) . ";\n";
+            }
+        }
+
+        if (isset($this->graph['nodes'])) {
+            foreach($this->graph['nodes'] as $group => $nodes) {
+                if ($group != 'default') {
+                  $parsedGraph .= sprintf(
+                    "subgraph \"cluster_%s\" {\nlabel=\"%s\";\n",
+
+                    $group,
+                    isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group] : ''
+                  );
+                }
+
+                foreach($nodes as $node => $attributes) {
+                    unset($attributeList);
+
+                    foreach($attributes as $key => $value) {
+                        $attributeList[] = $key . '="' . $value . '"';
+                    }
+
+                    if (!empty($attributeList)) {
+                        $parsedGraph .= sprintf(
+                          "\"%s\" [ %s ];\n",
+                          addslashes(stripslashes($node)),
+                          implode(',', $attributeList)
+                        );
+                    }
+                }
+
+                if ($group != 'default') {
+                  $parsedGraph .= "}\n";
+                }
+            }
+        }
+
+        if (isset($this->graph['edges'])) {
+            foreach($this->graph['edges'] as $label => $node) {
+                unset($attributeList);
+
+                $from = key($node);
+                $to   = $node[$from];
+
+                foreach($this->graph['edgeAttributes'][$label] as $key => $value) {
+                    $attributeList[] = $key . '="' . $value . '"';
+                }
+
+                $parsedGraph .= sprintf(
+                  '"%s" -> "%s"',
+                  addslashes(stripslashes($from)),
+                  addslashes(stripslashes($to))
+                );
+                
+                if (!empty($attributeList)) {
+                    $parsedGraph .= sprintf(
+                      ' [ %s ]',
+                      implode(',', $attributeList)
+                    );
+                }
+
+                $parsedGraph .= ";\n";
+            }
+        }
+
+        return $parsedGraph . "}\n";
+    }
+
+    /**
+    * Save GraphViz markup to file.
+    *
+    * @param  string $file File to write the GraphViz markup to.
+    * @return mixed   File to which the GraphViz markup was
+    *                 written, false on failure.
+    * @access public
+    */
+    function saveParsedGraph($file = '') {
+        $parsedGraph = $this->parse();
+        if (!empty($parsedGraph)) {
+			if (empty($file))
+                $file = GALAXIA_PROCESSES.'/'.$this->pid.'/graph/'.$this->pid;
+            if ($fp = @fopen($file, 'w')) {
+                @fputs($fp, $parsedGraph);
+                @fclose($fp);
+
+                return $file;
+            }
+        }
+
+        return false;
+    }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/RoleManager.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/RoleManager.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/RoleManager.php	(revision 2372)
@@ -0,0 +1,483 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'BaseManager.php');
+
+/**
+ * Adds, removes, modifies and lists roles used in the Workflow engine.
+ * Roles are managed in a per-process level, each role belongs to some process
+ * 
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @todo Add a method to check if a role name exists in a process to prevent duplicate names 
+ */
+class RoleManager extends BaseManager {
+    
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object RoleManager
+   * @access public
+   */
+  function RoleManager() 
+  {
+    parent::Base();
+    $this->child_name = 'RoleManager';
+  }
+
+  /**
+   * Gets role id
+   * 
+   * @param int $pid Process id
+   * @param string $name Role name
+   * @access public
+   * @return string 
+   */
+  function get_role_id($pid,$name)
+  {
+    $name = addslashes($name);
+    return ($this->getOne('select wf_role_id from '.GALAXIA_TABLE_PREFIX.'roles where wf_name=? and wf_p_id=?', array($name, $pid)));
+  }
+  
+  /**
+  * Gets a role
+  * 
+  * @param int $pId Process Id
+  * @param int $roleId Role Id
+  * @return array
+  * @access public
+  */
+  function get_role($pId, $roleId)
+  {
+    $query = 'select * from `'.GALAXIA_TABLE_PREFIX.'roles` where `wf_p_id`=? and `wf_role_id`=?';
+    $result = $this->query($query,array($pId, $roleId));
+    $res = $result->fetchRow();
+    return $res;
+  }
+  
+  /**
+  * Indicates if a role exists
+  * 
+  * @param int $pid Process Id
+  * @param string $name Role name
+  * @return int Number of roles with this name on this process
+  * @access public
+  */
+  function role_name_exists($pid,$name)
+  {
+    $name = addslashes($name);
+    return ($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=? and wf_name=?', array($pid, $name)));
+  }
+  
+  /**
+   * Maps a user to a role
+   * 
+   * @param int $pId Process id
+   * @param int $user User id
+   * @param int $roleId Role id
+   * @param string $account_type User account type
+   * @return void 
+   * @access public
+   */
+  function map_user_to_role($pId,$user,$roleId,$account_type='u')
+  {
+  $query = 'delete from `'.GALAXIA_TABLE_PREFIX.'user_roles` where wf_p_id=? AND wf_account_type=? and `wf_role_id`=? and `wf_user`=?';
+  $this->query($query,array($pId, $account_type,$roleId, $user));
+  $query = 'insert into '.GALAXIA_TABLE_PREFIX.'user_roles (wf_p_id, wf_user, wf_role_id ,wf_account_type)
+  values(?,?,?,?)';
+  $this->query($query,array($pId,$user,$roleId,$account_type));
+  }
+  
+  /**
+   * Removes a mapping
+   * 
+   * @param int $user User id
+   * @param int $roleId Role id
+   * @return void 
+   * @access public
+   */
+  function remove_mapping($user,$roleId)
+  { 
+    $query = 'delete from `'.GALAXIA_TABLE_PREFIX.'user_roles` where `wf_user`=? and `wf_role_id`=?';
+    $this->query($query,array($user, $roleId));
+  }
+
+  /**
+   * Deletes all existing mappings concerning one user
+   * 
+   * @param int $user User id
+   * @return void 
+   * @access public
+   */
+  function remove_user($user)  
+  {
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_user=?';
+    $this->query($query,array($user));
+  }
+  
+  /**
+  * Transfers all existing mappings concerning one user to another user
+  * 
+  * @param array $user_array Associative, keys are: 'old_user': current user id and 'new_user', the new user id
+  * @return void 
+  * @access public
+  */
+  function transfer_user($user_array)  
+  {
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'user_roles set wf_user=? where wf_user=?';
+    $this->query($query,array($user_array['new_user'], $user_array['old_user']));
+  }
+  
+  /**
+  * Gets list of roles/users mappings for a given process
+  * 
+  * @param int $pId Process id, mappings are returned for a complete process
+  * @param int $offset Starting record of the returned array
+  * @param int $maxRecords Maximum number of records for the returned array
+  * @param string $sort_mode Sort order for the query, like 'wf_name__ASC'
+  * @param string $find Searched in role name, role description or user/group name
+  * @return array Having for each row [wf_name] (role name),[wf_role_id],[wf_user] and [wf_account_type] ('u' user  or 'g' group),
+  * Be aware 'cause you may have the same user or group several times if mapped to several roles
+  * @access public
+  */
+  function list_mappings($pId,$offset,$maxRecords,$sort_mode,$find)  {
+    $sort_mode = $this->convert_sortmode($sort_mode);
+    $whereand = ' and gur.wf_p_id=? ';
+    $bindvars = Array($pId);
+    if($find) 
+    {
+      // no more quoting here - this is done in bind vars already
+      $findesc = '%'.$find.'%';
+      $whereand .=  ' and ((wf_name like ?) or (wf_user like ?) or (wf_description like ?)) ';
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+      $bindvars[] = $findesc;
+    }
+    
+    $query = "select wf_name,gr.wf_role_id,wf_user,wf_account_type from
+                    ".GALAXIA_TABLE_PREFIX."roles gr,
+                    ".GALAXIA_TABLE_PREFIX."user_roles gur 
+                where gr.wf_role_id=gur.wf_role_id 
+                $whereand";
+    $result = $this->query($query,$bindvars, $maxRecords, $offset, true, $sort_mode);
+    $query_cant = "select count(*) from 
+                      ".GALAXIA_TABLE_PREFIX."roles gr, 
+                      ".GALAXIA_TABLE_PREFIX."user_roles gur 
+                  where gr.wf_role_id=gur.wf_role_id 
+                  $whereand";
+    $cant = $this->getOne($query_cant,$bindvars);
+
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res;
+    }
+    $retval = Array();
+    $retval["data"] = $ret;
+    $retval["cant"] = $cant;
+    return $retval;
+  }
+
+  /**
+   * Gets a list of users/groups mapped for a given process. Can expand groups to real users in the result and can restrict mappings to a given subset of roles and or activities
+   * 
+   * @param int $pId Process id, mappings are returned for a complete process by default (see param roles_subset or activities_subset)
+   * @param bool $expand_groups If true (false by default) we are not giving the group mappings but instead expand these groups to real users while avoiding repeating users twice
+   * @param array $subset Associative containing a list of roles and/or activities for which we want to restrict the list empty by default.
+   * This array needs to contains the [wf_role_name] key with role names values to restrict roles.
+   * This array needs to contains the [wf_activity_name] key with activity names values to restrict activities
+   * @return array Associative, having for each row the user or group id and an associated name
+   * @access public
+   */
+
+  function &list_mapped_users($pId,$expand_groups=false, $subset=Array())  
+  {
+    $whereand = ' where gur.wf_p_id=? ';
+    $bindvars = Array($pId);
+    
+    if (!(count($subset)==0))
+    {
+       $roles_subset = Array();
+       $activities_subset =Array();
+       $activities_id_subset = Array();
+       foreach($subset as $key => $value )
+       {
+         if ($key=='wf_role_name')
+         {
+           $roles_subset = $value;
+         }
+         if ($key=='wf_activity_name')
+         {
+           $activities_subset = $value;
+         }
+         if ($key == 'wf_activity_id')
+         {
+           $activities_id_subset = $value;
+         }
+       }
+       if (count($roles_subset)>0)
+       {
+         if (!(is_array($roles_subset)))
+         {
+           $roles_subset = explode(',',$roles_subset);
+         }
+         $whereand .= " and ((gr.wf_name) in ('".implode("','",$roles_subset)."'))";
+       }
+       if (count($activities_subset)>0)
+       {
+         if (!(is_array($activities_subset)))
+         {
+           $activities_subset = explode(',',$activities_subset);
+         }
+         $whereand .= " and ((ga.wf_name) in ('".implode("','",$activities_subset)."'))";
+       }
+       if (count($activities_id_subset) > 0)
+       {
+         if (!(is_array($activities_id_subset)))
+         {
+           $activities_id_subset = explode(',',$activities_id_subset);
+         }
+         $whereand .= " and ((ga.wf_activity_id) in ('".implode("','",$activities_id_subset)."'))";
+       }
+    }
+    $query = "select distinct(wf_user),wf_account_type from
+                    ".GALAXIA_TABLE_PREFIX."roles gr
+                INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gr.wf_role_id=gur.wf_role_id 
+                LEFT JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.wf_role_id=gr.wf_role_id 
+                LEFT JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON ga.wf_activity_id=gar.wf_activity_id 
+                $whereand ";
+    $result = $this->query($query,$bindvars);
+    $ret = Array();
+    $ldap = &Factory::getInstance('WorkflowLDAP');
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow()) 
+      {
+        if (($expand_groups) && ($res['wf_account_type']=='g'))
+        {
+          //we have a group instead of a simple user and we want real users
+          $real_users = galaxia_retrieve_group_users($res['wf_user'], true);
+		  if (!empty($real_users)) {
+            foreach ($real_users as $key => $value)
+            {
+              $ret[$key]=$value;
+            }
+		  }
+        }
+        else
+        {
+          $ret[$res['wf_user']] = $ldap->getName($res['wf_user']);
+        }
+      }
+    }
+    return $ret;
+  }
+  
+  /**
+   * Lists roles at process level
+   * 
+   * @param int $pId Process id
+   * @param int $offset Starting resultset row
+   * @param int $maxRecords Maximum number of records
+   * @param string $sort_mode Query sorting mode
+   * @param string $find Search query string
+   * @param string $where Condition query string
+   * @return array Roles list
+   * @access public
+   */
+  function list_roles($pId,$offset,$maxRecords,$sort_mode,$find,$where='')
+  {
+    $sort_mode = $this->convert_sortmode($sort_mode);
+    if($find) {
+      // no more quoting here - this is done in bind vars already
+      $findesc = '%'.$find.'%';
+      $mid=' where wf_p_id=? and ((wf_name like ?) or (wf_description like ?))';
+      $bindvars = array($pId,$findesc,$findesc);
+    } else {
+      $mid=' where wf_p_id=? ';
+      $bindvars = array($pId);
+    }
+    if($where) {
+      $mid.= " and ($where) ";
+    }
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX."roles $mid";
+    $query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."roles $mid";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset, 1, $sort_mode);
+    $cant = $this->getOne($query_cant,$bindvars);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      $ret[] = $res;
+    }
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = $cant;
+    return $retval;
+  }
+   
+  /** 
+  * Removes a role
+  * 
+  * @param int $pId Process Id
+  * @param int $roleId Role Id
+  * @return bool
+  * @access public
+  */
+  function remove_role($pId, $roleId)
+  {
+    // start a transaction
+    $this->db->StartTrans();
+    $query = 'delete from `'.GALAXIA_TABLE_PREFIX.'roles` where `wf_p_id`=? and `wf_role_id`=?';
+    $this->query($query,array($pId, $roleId));
+    $query = 'delete from `'.GALAXIA_TABLE_PREFIX.'activity_roles` where `wf_role_id`=?';
+    $this->query($query,array($roleId));
+    $query = 'delete from `'.GALAXIA_TABLE_PREFIX.'user_roles` where `wf_role_id`=?';
+    $this->query($query,array($roleId));
+    // perform commit (return true) or Rollback (return false)
+    return $this->db->CompleteTrans();
+    }
+  
+  /**
+  * Updates or inserts a new role in the database
+  *  
+  * @param array $vars Associative, having the fields to update or to insert as needed
+  * @param int $pId Process id
+  * @param int $roleId Role id, 0 in insert mode
+  * @return mixed Role id (the new one if in insert mode) if everything was ok, false in the other case
+  */
+  function replace_role($pId, $roleId, $vars) 
+  {
+    // start a transaction 
+    $this->db->StartTrans(); 
+    $TABLE_NAME = GALAXIA_TABLE_PREFIX.'roles'; 
+    $now = date("U");
+    if (!(isset($vars['wf_last_modif']))) $vars['wf_last_modif']=$now; 
+    $vars['wf_p_id']=$pId;
+    
+    foreach($vars as $key=>$value) 
+    {
+      $vars[$key]=addslashes($value);
+    }
+  
+    if($roleId) {
+      // update mode 
+      $first = true; 
+      $query ="update $TABLE_NAME set"; 
+      $bindvars = Array();
+      foreach($vars as $key=>$value) 
+      {
+        if(!$first) $query.= ','; 
+        //if(!is_numeric($value)) $value="'".$value."'"; 
+        $query.= " $key=? ";
+        $bindvars[] = $value; 
+        $first = false;
+      }
+      $query .= ' where wf_p_id=? and wf_role_id=? '; 
+      $bindvars[] = $pId;
+      $bindvars[] = $roleId; 
+      $this->query($query, $bindvars);
+    } 
+    else 
+    {
+      //check unicity 
+      $name = $vars['wf_name']; 
+      if ($this->getOne('select count(*) from '.$TABLE_NAME.' where wf_p_id=? and wf_name=?', array($pId,$name))) 
+      { 
+        return false;
+      }
+      unset($vars['wf_role_id']); 
+      // insert mode
+      $bindvars = Array();
+      $first = true;
+      $query = "insert into $TABLE_NAME(";
+      foreach(array_keys($vars) as $key)
+      {
+        if(!$first) $query.= ','; 
+        $query.= "$key";
+        $first = false;
+      } 
+      $query .=') values(';
+      $first = true;
+      foreach(array_values($vars) as $value) 
+      {
+        if(!$first) $query.= ','; 
+        //if(!is_numeric($value)) $value="'".$value."'";
+        $query.= '?';
+        $bindvars[] = $value;
+        $first = false;
+      } 
+      $query .=')';
+      $this->query($query, $bindvars);
+      //get the last inserted row
+      $roleId = $this->getOne('select max(wf_role_id) from '.$TABLE_NAME.' where wf_p_id=?', array($pId)); 
+    }
+    // perform commit (return true) or Rollback (return false)
+    if ($this->db->CompleteTrans())
+    {
+      // Get the id
+      return $roleId;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  
+  /**
+  * Lists all users and groups recorded in the mappings with their status (user or group)
+  * 
+  * @return array Associative, containing a row for each user, where each row is an array containing 'wf_user' and 'wf_account_type' keys
+  * @access public
+  */
+  function get_all_users()
+  {
+    $final = Array();
+    //query for user mappings affected to groups & vice-versa
+    $query ='select distinct(gur.wf_user), gur.wf_account_type
+            from '.GALAXIA_TABLE_PREFIX.'user_roles gur';
+    $result = $this->query($query);
+    if (!(empty($result)))
+    {
+    while ($res = $result->fetchRow())
+    {
+        $final[] = $res;
+    }
+    }
+    return $final;
+  }
+
+  /**
+   * Get roles for a given user
+   *
+   * @param int $user The given user
+   * @return array Roles for the given user
+   * @access public
+   */
+  function getUserRoles($user, $pid = null)
+  {
+    /* retrieve user_groups information in an array containing all groups for this user */
+    $userGroups = galaxia_retrieve_user_groups($user);
+    $values = array($user);
+    $query = 'SELECT wf_role_id FROM ' . GALAXIA_TABLE_PREFIX . 'user_roles
+          WHERE (
+            (wf_user = ? AND wf_account_type = \'u\')';
+    if (is_array($userGroups))
+    {
+      foreach ($userGroups as &$group)
+        $group = "'{$group}'";
+      $query .= ' OR (wf_user IN (' . implode(',', $userGroups) . ') AND wf_account_type = \'g\')';
+    }
+    $query .= ')';
+    if (!is_null($pid))
+    {
+      $query .= ' AND (wf_p_id = ?)';
+      $values[] = $pid;
+    }
+
+    $result = $this->query($query, $values);
+    $output = Array();
+    while($res = $result->fetchRow())
+      $output[] = $res['wf_role_id'];
+
+    return $output;
+  }
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/InstanceManager.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/InstanceManager.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/InstanceManager.php	(revision 2372)
@@ -0,0 +1,327 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'BaseManager.php');
+/**
+ * Add, removes, modifies and lists instances.
+ *
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class InstanceManager extends BaseManager {
+  
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object InstanceManager
+   * @access public
+   */
+  function InstanceManager() 
+  {
+    parent::BaseManager();
+    $this->child_name = 'InstanceManager';
+  }
+
+  /**
+   * Gets an activities related to some instance
+   * 
+   * @param int $iid Instance Id
+   * @return array Associative, describing activities and their relation with the instance
+   * @access public
+   */
+  function get_instance_activities($iid)
+  {
+    $query = 'select ga.wf_type,ga.wf_is_interactive,ga.wf_is_autorouted,ga.wf_activity_id,ga.wf_name,
+            gi.wf_p_id,gi.wf_instance_id,gi.wf_status,gi.wf_started,
+            gia.wf_activity_id,gia.wf_user,gia.wf_status as wf_act_status 
+            from '.GALAXIA_TABLE_PREFIX.'activities ga,
+            INNER JOIN '.GALAXIA_TABLE_PREFIX.'instance_activities gia ON ga.wf_activity_id=gia.wf_activity_id
+            INNER JOIN '.GALAXIA_TABLE_PREFIX.'instances gi ON gia.wf_instance_id=gi.wf_instance_id,
+            where gi.wf_instance_id=?';
+    $result = $this->query($query, array($iid));
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow()) 
+      {
+        // Number of active instances
+        $ret[] = $res;
+      }
+    }
+    return $ret;
+  }
+
+  /**
+  * Describes given instance
+  * 
+  * @access public
+  * @param int $iid Instance Id
+  * @return array Associative, describing the instance
+  */
+  function get_instance($iid)
+  {
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'instances gi where wf_instance_id=?';
+    $result = $this->query($query, array($iid));
+    $res = Array();
+    if (!(empty($result)))
+    {
+      $res = $result->fetchRow();
+      $res['wf_next_activity']=unserialize(base64_decode($res['wf_next_activity']));
+      $res['wf_workitems']=$this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'workitems where wf_instance_id=?', array($iid));
+    }
+    return $res;
+  }
+
+  /**
+   * Describes instance properties 
+   * 
+   * @access public
+   * @param int $iid Instance id
+   * @return array Associative, describing the instance properties
+   */
+  function get_instance_properties($iid)
+  {
+    $prop = unserialize(base64_decode($this->getOne('select wf_properties from '.GALAXIA_TABLE_PREFIX.'instances gi where wf_instance_id=?',array($iid))));
+    return $prop;
+  }
+
+  /**
+  * Start a transaction and lock the instance table on the given instance row.
+  * It can lock as weel the instance-activities table.
+  * 
+  * @access private 
+  * @param int $instanceId Instance id
+  * @param int $activityId Activity id, 0 b default, the instance-activities table is not locked, instead the instance-activities table will be locked on the corresponding instance-activity row
+  * @return bool 
+  */
+  function lockAndStartTrans($instanceId, $activityId=0)
+  {
+    //do it in a transaction, for activities running
+    $this->db->StartTrans();
+    //we need to make a row lock now, first on the instance table (always first!)
+    $where = 'wf_instance_id='.(int)$instanceId;
+    if (!($this->db->RowLock(GALAXIA_TABLE_PREFIX.'instances', $where)))
+    {
+      $this->error[] = 'Process Manager: '.tra('failed to obtain lock on %1 table', 'instances');
+      $this->db->FailTrans();
+    }
+    if ($activityId)
+    {
+      //we need to make a row lock now, on the instance_activities table (always second!)
+      $where = 'wf_instance_id='.(int)$instanceId.' and wf_activity_id='.(int)$activityId;
+      if (!($this->db->RowLock(GALAXIA_TABLE_PREFIX.'instance_activities', $where)))
+      {
+        $this->error[] = 'Process Manager: '.tra('failed to obtain lock on %1 table','instances_activities');
+        return false;
+      }
+    }
+   } 
+
+  
+  /**
+  * Saves given instance properties
+  * 
+  * @access public 
+  * @param int $iid Instance Id
+  * @param array $prop Associative, describing the instance properties
+  * @return bool
+  */
+  function set_instance_properties($iid,&$prop)
+  {
+    $this->lockAndStartTrans($iid);
+    //no more serialize, done by the core security_cleanup, empty array and bad properties names handled
+    $prop = $this->security_cleanup($prop, false);
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_properties=? where wf_instance_id=?';
+    $this->query($query, array($prop,$iid));
+    return $this->db->CompleteTrans();
+  }
+  
+  /**
+  * Saves given instance name
+  * 
+  * @access public 
+  * @param int $iid Instance Id
+  * @param string $name Instance name
+  * @return bool
+  */
+  function set_instance_name($iid,$name)
+  {
+    $this->lockAndStartTrans($iid);
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_name=? where wf_instance_id=?';
+    $this->query($query, array($name,$iid));
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+  * Saves given instance priority
+  * 
+  * @access public 
+  * @param int $iid Instance id
+  * @param int $priority Instance priority
+  * @return bool
+  */
+  function set_instance_priority($iid,$priority)
+  {
+    $this->lockAndStartTrans($iid);
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_priority=? where wf_instance_id=?';
+    $this->query($query, array((int)$priority, (int)$iid));
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+  * Saves given instance category
+  * 
+  * @access public 
+  * @param int $iid Instance Id
+  * @param string $category Instance category
+  * @return bool
+  */
+  function set_instance_category($iid,$category)
+  {
+    $this->lockAndStartTrans($iid);
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_category=? where wf_instance_id=?';
+    $this->query($query, array((int)$category, (int)$iid));
+    return $this->db->CompleteTrans();
+  }
+
+  /**
+  * Saves given instance owner
+  * 
+  * @access public 
+  * @param int $iid Instance Id
+  * @param int $owner Instance owner id
+  * @return bool
+  */
+  function set_instance_owner($iid,$owner)
+  {
+    $this->lockAndStartTrans($iid);
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_owner=? where wf_instance_id=?';
+    $this->query($query, array($owner, $iid));
+    return $this->db->CompleteTrans();
+  }
+  
+  /**
+  * Saves given instance status
+  * 
+  * @access public 
+  * @param int $iid Instance Id
+  * @param string $status Instance status, should be one of 'active', 'completed', 'exception' or 'aborted
+  * @return bool
+  */
+  function set_instance_status($iid,$status)
+  {
+    if (!(($status=='completed') || ($status=='active') || ($status=='aborted') || ($status=='exception')))
+    {
+      $this->error[] = tra('unknown status');
+      return false;
+    }
+    $this->lockAndStartTrans($iid);
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_status=? where wf_instance_id=?';
+    $this->query($query, array($status,$iid));
+    return $this->db->CompleteTrans();
+  }
+  
+  /**
+  * Removes all previous activities on this instance and create a new activity on the activity given
+  * 
+  * @access public 
+  * @param int $iid Instance id
+  * @param int $activityId Activity id
+  * @param mixed $user '*' by default and could be an user id
+  * @param string $status 'running' by default but you could send 'completed' as well
+  * @return bool False if any problems was encoutered (the database is then intact), true if everything was ok;
+  * WARNING: if they were multiple activities ALL previous activities avaible on this instance are deleted
+  */
+  function set_instance_destination($iid,$activityId, $user='*', $status='running')
+  {
+    $this->lockAndStartTrans($iid, $activityId);
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'instance_activities where wf_instance_id=?';
+    $this->query($query, array($iid));
+    $query = 'insert into '.GALAXIA_TABLE_PREFIX.'instance_activities(wf_instance_id,wf_activity_id,wf_user,wf_status, wf_started, wf_ended)
+    values(?,?,?,?,?,?)';
+    $this->query($query, array($iid,$activityId,$user,$status,date('U'),0));
+    // perform commit (return true) or Rollback (return false)
+    return $this->db->CompleteTrans();
+  }
+ 
+  /**
+  * Sets new user for activity $activityId if this activity is really related to the instance
+  *  
+  * @access public 
+  * @param int $iid Instance Id
+  * @param int $activityId Activity Id
+  * @param int $user New user id
+  * @return bool
+  */
+  function set_instance_user($iid,$activityId,$user)
+  {
+    $this->lockAndStartTrans($iid, $activityId);
+    $query = "update ".GALAXIA_TABLE_PREFIX."instance_activities set wf_user=? where wf_instance_id=? and wf_activity_id=?";
+    $this->query($query, array($user, $iid, $activityId));
+    return $this->db->CompleteTrans();
+  }
+  
+  /**
+  * Deletes all references to given user on all instances, concerning wf_user, wf_owner and wf_next_user fields
+  * 
+  * @param int $user User id to remove
+  * @return bool
+  * @access public
+  */
+  function remove_user($user)  
+  {
+    //TODO: add a global lock on the whole tables
+    // user=id => user='*'
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instance_activities set wf_user=? where wf_user=?';
+    $this->query($query,array('*',$user));
+    // owner=id => owner=0
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_owner=? where wf_owner=?';
+    $this->query($query,array(0,$user));
+    // next_user=id => next_user=NULL
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_next_user=? where wf_next_user=?';
+    $this->query($query,array(NULL,$user));
+    return true;
+  }
+  
+  /**
+  * Transfers all references concerning one user to another user, concerning wf_user, wf_owner and wf_next_user fields
+  * This function will not check access on the instance for the new user, it is the task of the admin to ensure the new user will have the necessary access rights
+  * 
+  * @param array $user_array Associative, keys are 'old_user' : current user id and 'new_user' : the new user id
+  * @return bool
+  * @access public
+  */
+  function transfer_user($user_array)  
+  {
+    $new_user = $user_array['new_user'];
+    $old_user = $user_array['old_user'];
+    //TODO: add a global lock on the whole tables
+    // user
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instance_activities set wf_user=? where wf_user=?';
+    $this->query($query,array($new_user,$old_user));
+    // owner
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_owner=? where wf_owner=?';
+    $this->query($query,array($new_user,$old_user));
+    // next_user
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'instances set wf_next_user=? where wf_next_user=?';
+    $this->query($query,array($new_user,$old_user));
+    return true;
+  }
+  
+  /**
+  * Normalizes a property name
+  * 
+  * @access public 
+  * @param string $name Name to normalize
+  * @return string Property name
+  */
+  function normalize_name($name)
+  {
+    $name = trim($name);
+    $name = str_replace(" ","_",$name);
+    $name = preg_replace("/[^0-9A-Za-z\_]/",'',$name);
+    return $name;
+  }
+
+}    
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/BaseManager.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/BaseManager.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/BaseManager.php	(revision 2372)
@@ -0,0 +1,27 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
+
+/**
+ * This class is derived by all the API classes so they get the
+ * database connection and the database methods.
+ *
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class BaseManager extends Base {
+
+  /**
+   * Constructor
+   * 
+   * @param object &$db ADOdb
+   * @return object BaseManager
+   * @access public
+   */
+  function BaseManager()
+  {
+    $this->child_name = 'BaseManager';
+    parent::Base();
+  }
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/JobManager.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/JobManager.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/JobManager.php	(revision 2372)
@@ -0,0 +1,477 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once GALAXIA_LIBRARY . '/src/ProcessManager/BaseManager.php';
+require_once GALAXIA_LIBRARY . '/src/ProcessManager/ProcessManager.php';
+require_once GALAXIA_LIBRARY . '/../jobs/class.JobEnum.inc.php';
+
+/**
+ * Classe para gerenciamento de Jobs
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @subpackage Job
+ */
+class JobManager extends BaseManager
+{
+	/**
+	 * @var string $jobTable O nome da tabela de Jobs (normalmente: egw_wf_jobs)
+	 * @access private
+	 */
+	private $jobTable;
+
+	/**
+	 * @var string $logTable O nome da tabela de Log dos Jobs (normalmente: egw_wf_job_logs)
+	 * @access private
+	 */
+	private $logTable;
+
+	/**
+	 * @var object $processManager Objeto da classe ProcessManager
+	 * @access private
+	 */
+	private $processManager;
+
+	/**
+	 * Status de Job executado com sucesso (o usuário chama o método informando o sucesso)
+	 * @name STATUS_JOB_SUCCESS
+	 */
+	const STATUS_JOB_SUCCESS = 0;
+
+	/**
+	 * Status de Job executado com falha (quando o usuário chama o método de falha)
+	 * @name STATUS_JOB_FAIL
+	 */
+	const STATUS_JOB_FAIL = 1;
+
+	/**
+	 * Status de Job que apresentou falha. A classe JobRunner faz algumas verificações e, pode detectar alguns problemas e impedir a execução do Job (atribuindo este Status ao log do Job)
+	 * @name STATUS_FAIL
+	 */
+	const STATUS_FAIL = 2;
+
+	/**
+	 * Status de Job quando ocorre algum erro Fatal do PHP na execução do Job. A descrição do Job é a o erro gerado pelo PHP
+	 * @name STATUS_ERROR
+	 */
+	const STATUS_ERROR = 3;
+
+	/**
+	 * Status de Job que é aplicado quando não há erros e o código do usuário não informa se a execução foi bem sucedida ou não
+	 * @name STATUS_UNKNOWN
+	 */
+	const STATUS_UNKNOWN = 4;
+
+	/**
+	 * Construtor da classe JobManager
+	 * @return object
+	 * @access public
+	 */
+	public function JobManager()
+	{
+		parent::BaseManager();
+		$this->child_name = 'JobManager';
+
+		$this->jobTable = GALAXIA_TABLE_PREFIX . 'jobs';
+		$this->logTable = GALAXIA_TABLE_PREFIX . 'job_logs';
+		$this->processManager = &Factory::newInstance('ProcessManager');
+	}
+
+	/**
+	 * Gera um nome normalizado a partir de um nome de Job
+	 * @param string $name O nome do Job
+	 * @return string O valor de $name normalizado
+	 * @access private
+	 */
+	private function normalize($name)
+	{
+		$search = array('/[À-Å]/', '/Æ/', '/Ç/', '/[È-Ë]/', '/[Ì-Ï]/', '/Ð/', '/Ñ/', '/[Ò-ÖØ]/', '/×/', '/[Ù-Ü]/', '/Ý/', '/ß/', '/[à-å]/', '/æ/', '/ç/', '/[è-ë]/', '/[ì-ï]/', '/ð/', '/ñ/', '/[ò-öø]/', '/÷/', '/[ù-ü]/', '/[ý-ÿ]/');
+		$replace = array('A', 'AE', 'C', 'E', 'I', 'D', 'N', 'O', 'X', 'U', 'Y', 'ss', 'a', 'ae', 'c', 'e', 'i', 'd', 'n', 'o', 'x', 'u', 'y');
+		$output = str_replace(' ', '', ucwords(preg_replace($search, $replace, $name)));
+		$output = preg_replace("/[^0-9A-Za-z\_\-]/", '', $output);
+
+		return $output;
+	}
+
+	/**
+	 * Valida os parâmetros para atualização e criação de jobs
+	 * @param string $name O nome do Job
+	 * @param string $timeStart Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @param int $intervalValue O intervalo de repetição
+	 * @param int $intervalUnity A unidade de repetição (dia, mês, etc.)
+	 * @param int $dateType O tipo que define quando o Job é executado
+	 * @param int $weekDays Inteiro que representa os dias da semana em que o Job será executado
+	 * @param int $monthOffset Intervalo de execução relativa a mês
+	 * @param bool $active Indica se o job está ativo (true) ou não (false)
+	 * @param int $processID O ID do processo a qual o Job pertence
+	 * @param int $jobID O ID do Job (no caso de atualização)
+	 * @return bool Indica se os parâmetros foram aceitos (true) ou não (false)
+	 * @access private
+	 */
+	private function validateJobParameters($name, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active, $processID, $jobID = null)
+	{
+		$normalizedName = $this->normalize($name);
+		if (strlen($normalizedName) < 1)
+			$this->error[] = 'Este processo produz um nome normalizado que é vazio. Troque o nome do job.';
+
+		list($date, $time) = explode(' ', $timeStart, 2);
+		if (strlen($date) != 10)
+			$this->error[] = 'A data está num formato inválido. Utilize: dd/mm/aaaa.';
+
+		list($year, $month, $day) = explode('-', $date, 3);
+		if (!checkdate($month, $day, $year))
+			$this->error[] = 'A data fornecida não é válida.';
+
+		list($hour, $minute, $second) = explode(':', $time, 3);
+		if (($hour < 0) || ($hour > 23) || ($minute < 0) || ($minute > 59))
+			$this->error[] = 'A horário informado não é válido.';
+
+		if ((!is_numeric($intervalValue)) || (strpos($intervalValue, '.') !== false) || (strpos($intervalValue, ',') !== false) || (($intervalValue < 1) && ($intervalUnity != DateUnity::NONE)))
+			$this->error[] = 'O intervalo de tempo para repetição precisa ser um número inteiro positivo.';
+
+		switch ($dateType)
+		{
+			case DateType::ABSOLUTE_DATE:
+				if (!in_array($intervalUnity, array(DateUnity::YEAR, DateUnity::MONTH, DateUnity::WEEK, DateUnity::DAY, DateUnity::HOUR, DateUnity::MINUTE, DateUnity::NONE)))
+					$this->error[] = 'A unidade de intervalo utilizada é inválida.';
+				break;
+
+			case DateType::WEEK_DATE:
+				if (($weekDays < 0) || ($weekDays > 127))
+					$this->error[] = 'Os dias da semana selecionados geraram não formam uma possibilidade válida.';
+				break;
+
+			case DateType::RELATIVE_DATE:
+				if ($monthOffset < 1)
+					$this->error[] = 'O deslocamento relativo ao mês seguinte não possui um valor válido.';
+				break;
+		}
+
+		/* a new job will be created */
+		$allJobs = $this->getJobsByProcessID($processID);
+
+		foreach ($allJobs as $currentJob)
+		{
+			if ($currentJob['job_id'] == $jobID)
+				continue;
+			if (strcasecmp($this->normalize($currentJob['name']), $normalizedName) == 0)
+			{
+				$this->error[] = 'O nome escolhido entra em conflito com outro job do mesmo processo.';
+				break;
+			}
+		}
+
+		return (count($this->error) === 0);
+	}
+
+	/**
+	 * Busca informações de todos os Jobs de um processo
+	 * @param int $processID O ID do processo
+	 * @return array A lista de Jobs de um processo
+	 * @access public
+	 */
+	public function getJobsByProcessID($processID)
+	{
+		return $this->query("SELECT * FROM {$this->jobTable} WHERE wf_process_id = ?", array($processID))->getArray();
+	}
+
+	/**
+	 * Obtém o arquivo de código do Job
+	 * @param int $jobID O ID do Job
+	 * @return string O arquivo do Job
+	 * @access public
+	 */
+	public function getJobFile($jobID)
+	{
+		$jobInfo = $this->getJob($jobID);
+		$processInfo = $this->processManager->get_process($jobInfo['wf_process_id']);
+		return GALAXIA_PROCESSES . '/' . $processInfo['wf_normalized_name'] . '/code/jobs/' . 'class.job.' . $this->normalize($jobInfo['name']) . '.php';
+	}
+
+	/**
+	 * Obtém o nome da classe de um Job
+	 * @param int $jobID O ID do Job
+	 * @return string O nome da classe do Job
+	 * @access public
+	 */
+	public function getClassName($jobID)
+	{
+		$jobInfo = $this->getJob($jobID);
+		return $this->normalize($jobInfo['name']);
+	}
+
+	/**
+	 * Obtém informações sobre um Job
+	 * @param int $jobID O ID do Job
+	 * @return array Informações sobre o Job
+	 * @access public
+	 */
+	public function getJob($jobID)
+	{
+		return $this->query("SELECT * FROM {$this->jobTable} WHERE job_id = ?", array($jobID))->fetchRow();
+	}
+
+	/**
+	 * Define se um Job está ativo ou não
+	 * @param int $jobID O ID do Job
+	 * @param bool $active Informa se o Job será ativado (true) ou não (false)
+	 * @return bool True em caso de sucesso ou false caso contrário
+	 * @access public
+	 */
+	public function setActive($jobID, $active)
+	{
+		$jobID = (int) $jobID;
+		$active = $active ? 'TRUE' : 'FALSE';
+		return $this->query("UPDATE {$this->jobTable} SET active = ? WHERE job_id = ?", array($active, $jobID));
+	}
+
+	/**
+	 * Busca os logs de um Job
+	 * @param int $jobID O ID do Job
+	 * @return array Os logs do Job
+	 * @access public
+	 */
+	public function getLogsByJobID($jobID)
+	{
+		return $this->query("SELECT * FROM {$this->logTable} WHERE job_id = ? ORDER BY date_time DESC", array($jobID))->getArray();
+	}
+
+	/**
+	 * Grava uma entrada de log para um Job
+	 * @param int $jobID O ID do Job
+	 * @param object $currentDate Um objeto da classe DateTime contendo a data em que o Job foi executado
+	 * @param string $message A mensagem que será salva no Log
+	 * @param int $status O status do log
+	 * @return void
+	 * @access public
+	 */
+	public function writeLog($jobID, $currentDate, $message, $status)
+	{
+		$message = str_replace(array(chr(92), chr(0), chr(39)), array('\134', '\000', '\047'), $message);
+		$this->db->StartTrans();
+
+		/* remove any previous log for the same time */
+		$query = "DELETE FROM {$this->logTable} WHERE (job_id = ?) AND (date_time = TO_TIMESTAMP(?, 'YYYY-MM-DD HH24:MI:SS'))";
+		$values = array($jobID, $currentDate->format('Y-m-d H:i:00'));
+		$this->query($query, $values);
+
+		/* insert the new log */
+		$query = "INSERT INTO {$this->logTable}(job_id, date_time, result, status) VALUES(?, TO_TIMESTAMP(?, 'YYYY-MM-DD HH24:MI:SS'), ?, ?)";
+		$values = array($jobID, $currentDate->format('Y-m-d H:i:00'), $message, $status);
+		$this->query($query, $values);
+
+		$this->db->CompleteTrans();
+	}
+
+	/**
+	 * Cria e grava um arquivo modelo do Job
+	 * @param int $jobID O ID do Job
+	 * @return void
+	 * @access public
+	 */
+	private function createModelFile($jobID)
+	{
+		$className = $this->getClassName($jobID);
+		$contents = "<?php\nclass {$className} extends JobBase\n{\n\tpublic function run()\n\t{\n\t\t/* código que será executado */\n\t}\n}\n?>";
+		$this->setJobFileContent($jobID, $contents);
+	}
+
+	/**
+	 * Define o conteúdo de um arquivo de Job
+	 * @param int $jobID O ID do Job
+	 * @param string $contents O conteúdo do arquivo
+	 * @return bool True se o arquivo foi criado corretamente ou false caso contrário
+	 * @access public
+	 */
+	public function setJobFileContent($jobID, $contents)
+	{
+		$jobFile = $this->getJobFile($jobID);
+		if (!is_dir(($jobDirectory = dirname($jobFile))))
+			mkdir($jobDirectory, 0770);
+
+		$success = @file_put_contents($jobFile, $contents);
+		if ($success === false)
+			$this->error[] = "Não foi possível definir o conteúdo do arquivo de Job. Crie manualmente o arquivo:\n{$jobFile}";
+
+		return $success;
+	}
+
+	/**
+	 * Cria um novo Job
+	 * @param int $processID O ID do processo a qual o Job pertence
+	 * @param string $name O nome do Job
+	 * @param string $description A descrição do Job
+	 * @param string $timeStart Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @param int $intervalValue O intervalo de repetição
+	 * @param int $intervalUnity A unidade de repetição (dia, mês, etc.)
+	 * @param int $dateType O tipo que define quando o Job é executado
+	 * @param int $weekDays Inteiro que representa os dias da semana em que o Job será executado
+	 * @param int $monthOffset Intervalo de execução relativa a mês
+	 * @param bool $active Indica se o job está ativo (true) ou não (false)
+	 * @return bool True em caso de sucesso ou false caso os parâmetros não sejam válidos
+	 * @access public
+	 */
+	public function createJob($processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active)
+	{
+		if ($this->validateJobParameters($name, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active, $processID) === false)
+			return false;
+
+		switch ($dateType)
+		{
+			case DateType::ABSOLUTE_DATE:
+				$weekDays = $monthOffset = null;
+				break;
+
+			case DateType::WEEK_DATE:
+				$monthOffset = null;
+				break;
+
+			case DateType::RELATIVE_DATE:
+				$weekDays = null;
+				break;
+		}
+
+		$query = "INSERT INTO {$this->jobTable}(wf_process_id, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, active) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+		$values = array($processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active);
+		$this->query($query, $values);
+		$row = $this->query("SELECT job_id FROM {$this->jobTable} WHERE wf_process_id = ? AND name = ?", array($processID, $name))->fetchRow();
+		$this->createModelFile($row['job_id']);
+
+		return true;
+	}
+
+	/**
+	 * Atualiza um Job
+	 * @param int $jobID O ID do Job que será atualizado
+	 * @param int $processID O ID do processo a qual o Job pertence
+	 * @param string $name O nome do Job
+	 * @param string $description A descrição do Job
+	 * @param string $timeStart Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @param int $intervalValue O intervalo de repetição
+	 * @param int $intervalUnity A unidade de repetição (dia, mês, etc.)
+	 * @param int $dateType O tipo que define quando o Job é executado
+	 * @param int $weekDays Inteiro que representa os dias da semana em que o Job será executado
+	 * @param int $monthOffset Intervalo de execução relativa a mês
+	 * @param bool $active Indica se o job está ativo (true) ou não (false)
+	 * @return bool True em caso de sucesso ou false caso os parâmetros não sejam válidos
+	 * @access public
+	 */
+	public function updateJob($jobID, $processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active)
+	{
+		if ($this->validateJobParameters($name, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active, $processID, $jobID) === false)
+			return false;
+
+		$oldJob = $this->getJob($jobID);
+		$oldJobFile = $this->getJobFile($jobID);
+		$oldJobClassName = $this->getClassName($jobID);
+
+		switch ($dateType)
+		{
+			case DateType::ABSOLUTE_DATE:
+				$weekDays = $monthOffset = null;
+				break;
+
+			case DateType::WEEK_DATE:
+				$monthOffset = null;
+				break;
+
+			case DateType::RELATIVE_DATE:
+				$weekDays = null;
+				break;
+		}
+		$query = "UPDATE {$this->jobTable} SET name = ?, description = ?, time_start = ?, interval_value = ?, interval_unity = ?, date_type = ?, week_days = ?, month_offset = ?, active = ? WHERE job_id = ?";
+		$values = array($name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active, $jobID);
+
+		$this->query($query, $values);
+
+		if (!file_exists($oldJobFile))
+		{
+			$this->createModelFile($jobID);
+		}
+		else
+		{
+			if ($oldJob['name'] != $name)
+			{
+				$oldFileContents = file_get_contents($oldJobFile);
+				$newFileContents = str_replace("class {$oldJobClassName}", 'class ' . $this->getClassName($jobID), $oldFileContents, $count);
+				if ($count == 0)
+					$this->error[] = 'É necessário trocar manualmente o nome da classe. O nome que deve ser utilizado é: ' . $this->getClassName($jobID) . '.';
+				file_put_contents($this->getJobFile($jobID), $newFileContents);
+				unlink($oldJobFile);
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Cria ou atualiza um Job. Este método é utilizado na criação de Jobs ocorrida na importação de um processo
+	 * @param int $processID O ID do processo
+	 * @param int $jobID O ID do Job. Se for 0 (zero) indica que deve ser criado um novo processo
+	 * @param array $params Os parâmetros para criação/atualização de um processo
+	 * @return int O ID do Job criado/atualizado
+	 * @access public
+	 */
+	public function replaceJob($processID, $jobID, $params)
+	{
+		$name = $params['name'];
+		$description = $params['description'];
+		$timeStart = $params['timeStart'];
+		$intervalValue = $params['intervalValue'];
+		$intervalUnity = $params['intervalUnity'];
+		$dateType = $params['dateType'];
+		$weekDays = $params['weekDays'];
+		$monthOffset = $params['monthOffset'];
+		$active = 'f';
+		$fileContents = $params['fileContents'];
+
+		if ($jobID === 0)
+		{
+			$this->createJob($processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active);
+			$jobID = $this->getOne("SELECT MAX(job_id) FROM {$this->jobTable} WHERE (wf_process_id = ?)", array($processID));
+		}
+		else
+		{
+			$this->updateJob($jobID, $processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active);
+		}
+		$this->setJobFileContent($jobID, $fileContents);
+
+		return $jobID;
+	}
+
+	/**
+	 * Remove um Job e seus logs
+	 * @param int $jobID O ID do Job
+	 * @return void
+	 * @access public
+	 */
+	public function removeJob($jobID)
+	{
+		$jobID = (int) $jobID;
+		@unlink($this->getJobFile($jobID));
+		$this->query("DELETE FROM {$this->jobTable} WHERE job_id = ?", array($jobID));
+		$this->query("DELETE FROM {$this->logTable} WHERE job_id = ?", array($jobID));
+	}
+
+	/**
+	 * Remove os Jobs e logs de um processo
+	 * @param int $processID O ID do processo
+	 * @return void
+	 * @access public
+	 */
+	public function removeJobsByProcessID($processID)
+	{
+		$jobs = $this->getJobsByProcessID($processID);
+		foreach ($jobs as $job)
+			$this->removeJob($job['job_id']);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/ActivityManager.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/ActivityManager.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/src/ProcessManager/ActivityManager.php	(revision 2372)
@@ -0,0 +1,1376 @@
+<?php
+require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'BaseManager.php');
+/**
+ * Handles process activities and transitions.
+ * This class is used to add, remove, modify and list
+ * activities used in the Workflow engine.
+ * Activities are managed in a per-process level, each
+ * activity belongs to some process.
+ *
+ * @package Galaxia
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @todo Build real process graph
+ */
+class ActivityManager extends BaseManager {
+  /**
+   * @var object $process_manager ProcessManager instance used sometimes by this object
+   * @access public
+   */
+  var $process_manager;    
+
+  /**
+   * Constructor
+   *
+   * @param object &$db ADOdb Used to manipulate activities in the database
+   * @return object ActivityManager instance
+   * @access public
+   */
+  function ActivityManager()
+  {
+    parent::BaseManager();
+    $this->child_name = 'ActivityManager';
+    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager' .SEP . 'ProcessManager.php');
+    //$this->process_manager is not set here to avoid object A loading objetc B loading object A, etc...
+    
+  }
+
+  /**
+   * Collect errors from all linked objects which could have been used by this object.
+   * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
+   *
+   * @param bool $debug False by default, if true debug messages can be added to 'normal' messages
+   * @param string $prefix Appended to the debug message
+   * @return void
+   * @access public
+   */
+  function collect_errors($debug=false, $prefix='')
+  {
+    parent::collect_errors($debug, $prefix);
+    if (isset($this->process_manager)) $this->error[] = $this->process_manager->get_error(false, $debug, $prefix);
+  }
+
+  /**
+   * Binds an activity to a role
+   *
+   * @param int $activityId
+   * @param int $roleId
+   * @param bool $readonly False by default, if true the role will be in read-only mode
+   * @access public
+   * @return void
+   */
+  function add_activity_role($activityId, $roleId, $readonly = false)
+  {
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id=? and wf_role_id=?';
+    $this->query($query,array($activityId, $roleId));
+    $query = 'insert into '.GALAXIA_TABLE_PREFIX.'activity_roles (wf_activity_id,wf_role_id,wf_readonly) values(?,?,?)';
+    $this->query($query,array($activityId, $roleId, (int)$readonly));
+  }
+ 
+  /**
+   * Gets the roles bound to an activity
+   *
+   * @param int $activityId
+   * @return array
+   * @access public
+   */
+  function get_activity_roles($activityId) {
+    $query = 'select wf_activity_id,roles.wf_role_id,roles.wf_name, wf_readonly
+              from '.GALAXIA_TABLE_PREFIX.'activity_roles gar
+              INNER JOIN '.GALAXIA_TABLE_PREFIX.'roles roles on gar.wf_role_id = roles.wf_role_id
+              where wf_activity_id=?';
+    $result = $this->query($query,array($activityId));
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow())
+      {
+        $ret[] = $res;
+      }
+    }
+    return $ret;
+  }
+ 
+  /**
+   * Unbinds a role from an activity
+   *
+   * @param int $activityId  
+   * @param int $roleId
+   * @return void
+   * @access public
+   */
+  function remove_activity_role($activityId, $roleId)
+  {
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'activity_roles
+              where wf_activity_id=? and wf_role_id=?';
+    $this->query($query, array($activityId,$roleId));
+  }
+
+  /**
+   * Removes an user from all fields where he could be on every activities.
+   *
+   * @param int $user User id
+   * @return void
+   * @access public
+   */
+  function remove_user($user)  
+  {
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_default_user=? where wf_default_user=?';
+    $this->query($query,array('',$user));
+  }
+ 
+  /**
+   * Transfers all references to one user to another one in the activities
+   *
+   * @param array $user_array Associative, keys are: 'old_user' is current user id and 'new_user' the new user id
+   * @return void
+   * @access public
+   */
+  function transfer_user($user_array)
+  {
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_default_user=? where wf_default_user=?';
+    $this->query($query,array($user_array['new_user'],$user_array['old_user']));
+  }  
+
+  /**
+   * Checks if a transition exists
+   *
+   * @param int $pid Process id
+   * @param int    $actFromId Id for starting activity
+   * @param int    $actToId Id for end activity
+   * @return bool
+   * @access public
+   */
+  function transition_exists($pid,$actFromId,$actToId)
+  {
+    return($this->getOne('select count(*) from
+      '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=? and wf_act_from_id=? and wf_act_to_id=?',
+      array($pid,$actFromId,$actToId)
+    ));
+  }
+ 
+  /**
+   * Adds a transition
+   *
+   * @param int $pId Process id
+   * @param int    $actFromId Id for starting activity
+   * @param int    $actToId Id for end activity
+   * @return bool
+   * @access public
+   */  
+  function add_transition($pId, $actFromId, $actToId)
+  {
+    // No circular transitions allowed
+    if($actFromId == $actToId) {
+        $this->error[] = tra('No circular transitions allowed.');
+        return false;
+    }
+    
+    // Rule: if act is not spl-x or spl-a it can't have more than
+    // 1 outbound transition.
+    $a1 = $this->get_activity($actFromId);
+    $a2 = $this->get_activity($actToId);
+    if(!$a1 || !$a2) {
+        $this->error[] = tra('No activites');
+        return false;
+    }
+    if($a1['wf_type'] != 'switch' && $a1['wf_type'] != 'split') {
+      if($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'transitions where wf_act_from_id=?', array($actFromId)) > 1) {
+        $this->error[] = tra('Cannot add transition only split or switch activities can have more than one outbound transition');
+        return false;
+      }
+    }
+    
+    // Rule: if act is standalone or view no transitions allowed
+    if(($a1['wf_type'] == 'standalone' || $a2['wf_type']=='standalone') || ($a1['wf_type'] == 'view' || $a2['wf_type']=='view') )
+    {
+        $this->error[] = tra('No transitions allowed for standalone or view activities');
+        return false;
+    }
+    // No inbound to start
+    if($a2['wf_type'] == 'start') {
+        $this->error[] = tra('No inbound for start activity');
+        return false;
+    }
+    // No outbound from end
+    if($a1['wf_type'] == 'end') {
+        $this->error[] = tra('No outbound for end activity');
+        return false;
+    }
+     
+    
+    $query = 'delete from `'.GALAXIA_TABLE_PREFIX.'transitions` where `wf_act_from_id`=? and `wf_act_to_id`=?';
+    $this->query($query,array($actFromId, $actToId));
+    $query = 'insert into `'.GALAXIA_TABLE_PREFIX.'transitions`(`wf_p_id`,`wf_act_from_id`,`wf_act_to_id`) values(?,?,?)';
+    $this->query($query,array($pId, $actFromId, $actToId));
+
+    return true;
+  }
+ 
+  /**
+   * Removes a transition
+   *
+   * @param int    $actFromId Id for starting activity
+   * @param int    $actToId Id for end activity
+   * @return bool
+   * @access public
+   */  
+  function remove_transition($actFromId, $actToId)
+  {
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'transitions where wf_act_from_id=? and wf_act_to_id=?';
+    $this->query($query, array($actFromId,$actToId));
+    return true;
+  }
+ 
+  /**
+   * Removes all activity transitions
+   *
+   * @param int    $pId Process id
+   * @param int    $aid Activity id
+   * @return void
+   * @access public
+   */   
+  function remove_activity_transitions($pId, $aid)
+  {
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=? and (wf_act_from_id=? or wf_act_to_id=?)';
+    $this->query($query,array($pId,$aid,$aid));
+  }
+ 
+  /**
+   * Returns all process's transitions
+   *
+   * @param int    $pId Process id
+   * @param int    $actid Activity id
+   * @return array
+   * @access public
+   */  
+  function get_process_transitions($pId,$actid=0)
+  {
+    $bindvars = Array();
+    $bindvars[] = $pId;
+    if(!$actid) {
+        $query = 'select a1.wf_name as wf_act_from_name, a2.wf_name as wf_act_to_name, wf_act_from_id, wf_act_to_id
+          from '.GALAXIA_TABLE_PREFIX.'transitions gt
+          INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities a1 ON gt.wf_act_from_id = a1.wf_activity_id
+          INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities a2 ON gt.wf_act_to_id = a2.wf_activity_id
+          where gt.wf_p_id = ?';
+    } else {
+        $query = 'select a1.wf_name as wf_act_from_name, a2.wf_name as wf_act_to_name, wf_act_from_id, wf_act_to_id
+        from '.GALAXIA_TABLE_PREFIX.'transitions gt
+        INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities a1 ON gt.wf_act_from_id = a1.wf_activity_id
+        INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities a2 ON gt.wf_act_to_id = a2.wf_activity_id
+        where gt.wf_p_id = ?
+        and (wf_act_from_id = ?)';
+        $bindvars[] = $actid;
+    }
+    $result = $this->query($query, $bindvars, -1, -1, true, 'a1.wf_flow_num');
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow())
+      {
+        $ret[] = $res;
+      }
+    }
+    return $ret;
+  }
+ 
+  /**
+   * Indicates whether an activity is autoRouted
+   *
+   * @param int $actid Activity id
+   * @return bool
+   * @access public
+   */
+  function activity_is_auto_routed($actid)
+  {
+    return($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'activities where wf_activity_id=? and wf_is_autorouted=?', array($actid,'y')));
+  }
+ 
+  /**
+   * Returns process's activities
+   *
+   * @param int pId    Process id
+   * @return array   
+   * @access public
+   */
+  function get_process_activities($pId)
+  {
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?';
+    $result = $this->query($query, array($pId));
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow())
+      {
+        $ret[] = $res;
+      }
+    }
+    return $ret;
+  }
+    /**
+    * Returns a set of activities that may have transitions, i.e., non-standalone/view activities
+    *
+    * @param int $pId Process id
+    * @param bool $type_exclusion Type to exclude from the result
+    * @return array Activities set in ['data'] and count in ['cant']
+    * @access public
+    */
+  function &get_transition_activities($pId, $type_exclusion = false)
+  {
+    $where = '';
+    $wheres = array();
+    $wheres[] = "wf_type <> 'standalone'";
+    $wheres[] = "wf_type <> 'view'";
+
+    if( $type_exclusion )
+    {
+      $wheres[] = "wf_type <> '".$type_exclusion."'";
+    }
+    $where = implode(' and ', $wheres);
+      
+    return $this->list_activities($pId, 0, -1, 'wf_flow_num__asc', '', $where);
+  }
+ 
+  /**
+  * Returns a set of activities having transitions
+  *
+  * @param int $pId Process id
+  * @return array Activities set, with activities set in ['data'] and count in ['cant']
+  * @access public
+  */
+  function get_process_activities_with_transitions($pId)
+  {
+    $query = 'select distinct a1.wf_name as wf_name, a1.wf_activity_id as wf_activity_id, a1.wf_flow_num
+      from '.GALAXIA_TABLE_PREFIX.'transitions gt
+      INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities a1 ON gt.wf_act_from_id = a1.wf_activity_id
+      INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities a2 ON gt.wf_act_to_id = a2.wf_activity_id
+      where gt.wf_p_id = ? ';
+    $result = $this->query($query, array($pId),  -1, -1, true, ' a1.wf_flow_num');
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow())
+      {
+        $ret[] = $res;
+      }
+    }
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = count($ret);
+    return $retval;
+  }
+
+  /**
+   * Builds process graph
+   *
+   * @param int $pId Process id
+   * @return bool
+   * @access public
+   */
+  function build_process_graph($pId)
+  {
+    if (!(isset($this->process_manager))) $this->process_manager = &Factory::newInstance('ProcessManager');
+    $attributes = Array(
+    
+    );
+    $graph = &Factory::newInstance('Process_GraphViz', true, $attributes);
+    $name = $this->process_manager->_get_normalized_name($pId);
+    $graph->set_pid($name);
+    
+    //Get the config of the workflow where we'll have some tips for the graph
+    $myconfneeds = array(
+      'draw_roles' => true,
+      'font_size' => 12,
+      );
+    $configs = $this->process_manager->getConfigValues($pId,true,true,$myconfneeds);
+
+    // Nodes are process activities so get
+    // the activities and add nodes as needed
+    $nodes = $this->get_process_activities($pId);
+    
+    $standaloneActivities = array();
+    foreach($nodes as $node)
+    {
+      if ($node['wf_type'] == 'standalone')
+        $standaloneActivities[] = $node['wf_name'];
+      if($node['wf_is_interactive']=='y')
+      {
+        $color='black';
+        $fillcolor='0.6,0.6,0.9'; //blue TLS values
+      }
+      else
+      {
+        $color='black';
+        $fillcolor='0.25,1,0.8';//green in TLS values
+      }
+      // get the fontsize, defined in the process
+      $fontsize = $configs['font_size'];
+      // define a fontname
+      $fontname = 'serif';
+      // if asked add roles on the graph
+      if ($configs['draw_roles'])
+      {
+        $activity_roles = $this->get_activity_roles($node['wf_activity_id']);
+      }
+      // fill activity roles
+      $act_role= '';
+      if (isset($activity_roles))
+      {
+        foreach ($activity_roles as $role)
+        {
+          // the / is escaped and space seems to be necessary,
+          //issues with some special characters if no spaces between this char and the /
+          $act_role = $act_role." \\n[".$role['wf_name']."]";
+        }
+      }
+      $auto[$node['wf_name']] = $node['wf_is_autorouted'];
+      $graph->addNode($node['wf_name'],array('URL'=>"foourl?wf_activity_id=".$node['wf_activity_id'],
+                                      'label'=>$node['wf_name'].$act_role,
+                                      'shape' => $this->_get_activity_shape($node['wf_type']),
+                                      'color' => $color,
+                                      'fillcolor'=> $fillcolor,
+                                      'style' => 'filled',
+                                      'fontsize' => $fontsize,
+                                      'fontname' => $fontname
+                                      )
+                     );
+    }
+    
+    // Now add edges, edges are transitions,
+    // get the transitions and add the edges
+    $edges = $this->get_process_transitions($pId);
+    foreach($edges as $edge)
+    {
+      if($auto[$edge['wf_act_from_name']] == 'y') {
+        $color = '0.25,1,0.28'; #dark green in TLS values
+        $arrowsize = 1;
+      } else {
+        $color = 'red2'; #blue in TLS values
+        $arrowsize= 1;
+      }
+        $graph->addEdge(array($edge['wf_act_from_name'] => $edge['wf_act_to_name']), array('color'=>$color,arrowsize=>$arrowsize));    
+    }
+
+    /* group the standalone activities vertically (workaround) */
+    $from = $to = null;
+    foreach ($standaloneActivities as $sa)
+    {
+      list($from, $to) = array($to, $sa);
+      if (!is_null($from))
+        $graph->addEdge(array($from => $to), array('color'=>'white'));
+    }
+    
+    
+    // Save the map image and the image graph
+    $graph->image_and_map();
+    unset($graph);
+    return true;   
+  }
+ 
+ 
+  /**
+   * Validates if a process can be activated checking the
+   * process activities and transitions the rules are:
+   * 0) No circular activities
+   * 1) Must have only one a start and end activity
+   * 2) End must be reachable from start
+   * 3) Interactive activities must have a role assigned
+   * 4) Roles should be mapped
+   * 5) Standalone and view activities cannot have transitions
+   * 6) Non intractive activities non-auto routed must have some role so the user can "send" the activity
+   * 7) start activities must be autorouted and interactive
+   *
+   * @param int $pId Process id
+   * @return bool
+   * @access public
+   */
+  function validate_process_activities($pId)
+  {
+    $errors = Array();
+    $warnings = Array();
+    // Pre rule no cricular activities
+    $cant = $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=? and wf_act_from_id=wf_act_to_id'
+      , array($pId));
+    if($cant) {
+      $errors[] = tra('Circular reference found some activity has a transition leading to itself');
+    }
+
+    // Rule 1 must have exactly one start and end activity
+    $cant = $this->getOne('select count(*) from '
+      .GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_type=?', array($pId,'start'));
+    if($cant < 1) {
+      $errors[] = tra('Process does not have a start activity');
+    }
+    $cant = $this->getOne('select count(*) from '
+      .GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_type=?', array($pId,'end'));
+    if($cant != 1) {
+      $errors[] = tra('Process does not have exactly one end activity');
+    }
+    
+    // Rule 2 end must be reachable from start
+    // and Rule 7 start activities must be autorouted and interactive
+    $nodes = Array();
+    $endId = $this->getOne('select wf_activity_id from '
+      .GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_type=?', array($pId,'end'));
+    if ((!isset($endId)) || ($endId=='') || ($endId == 0))
+    {
+      //no end
+      $errors[] = tra('this process has no end activity');
+      $endId = 0;
+    }
+    
+    $aux['id']=$endId;
+    $aux['visited']=false;
+    $nodes[] = $aux;
+    
+    $query = 'select wf_is_autorouted,wf_is_interactive,wf_activity_id from '
+      .GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_type=?';
+    $result = $this->query($query, array($pId,'start'));
+    while($res = $result->fetchRow()) {
+      $start_node['id'] = $res['wf_activity_id'];
+      if(!($res['wf_is_interactive'] == 'y')) {
+            $errors[] = tra('start activities must be interactive');
+      }
+      if(!($res['wf_is_autorouted'] == 'y')) {
+            $errors[] = tra('start activities must be autorouted');
+      }
+    }
+    $start_node['visited']=true;    
+    
+    while($this->_list_has_unvisited_nodes($nodes) && !$this->_node_in_list($start_node,$nodes)) {
+      for($i=0;$i<count($nodes);$i++) {
+        $node=&$nodes[$i];
+        if(!$node['visited']) {
+          $node['visited']=true;          
+          $query = 'select wf_act_from_id from '.GALAXIA_TABLE_PREFIX.'transitions where wf_act_to_id=?';
+          $result = $this->query($query, array($node['id']));
+          $ret = Array();
+          while($res = $result->fetchRow()) {  
+            $aux['id'] = $res['wf_act_from_id'];
+            $aux['visited']=false;
+            if(!$this->_node_in_list($aux,$nodes)) {
+              $nodes[] = $aux;
+            }
+          }
+        }
+      }
+    }
+    
+    if(!$this->_node_in_list($start_node,$nodes)) {
+      // Start node is NOT reachable from the end node
+      $errors[] = tra('End activity is not reachable from start activity');
+    }
+    
+    //Rule 3: interactive activities must have a role
+    //assigned.
+    //Rule 5: standalone and view activities can't have transitions
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id = ?';
+    $result = $this->query($query, array($pId));
+    while($res = $result->fetchRow()) {  
+      $aid = $res['wf_activity_id'];
+      if($res['wf_is_interactive'] == 'y') {
+          $cant = $this->getOne('select count(*) from '
+            .GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id=?', array($res['wf_activity_id']));
+          if(!$cant) {
+            $errors[] = tra('Activity %1 is interactive but has no role assigned', $res['wf_name']);
+          }
+      } else {
+        if( $res['wf_type'] != 'end' && $res['wf_is_autorouted'] == 'n') {
+          $cant = $this->getOne('select count(*) from '
+            .GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id=?', array($res['wf_activity_id']));
+          if(!$cant)
+          {
+              $errors[] = tra('Activity %1 is non-interactive and non-autorouted but has no role assigned', $res['wf_name']);
+          }
+        }
+      }
+      if(($res['wf_type']=='standalone')||($res['wf_type']=='view')) {
+        if($this->getOne('select count(*) from '
+          .GALAXIA_TABLE_PREFIX.'transitions where wf_act_from_id=? or wf_act_to_id=?', array($aid,$aid)))
+        {
+           $errors[] = tra('Activity %1 is standalone or view but has transitions', $res['wf_name']);
+        }
+      }
+
+    }
+    
+    
+    //Rule4: roles should be mapped
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id = ?';
+    $result = $this->query($query, array($pId));
+    while($res = $result->fetchRow()) {      
+        $cant = $this->getOne('select count(*) from '
+          .GALAXIA_TABLE_PREFIX.'user_roles where wf_role_id=?', array($res['wf_role_id']));
+        if(!$cant) {
+          $warnings[] = tra('Role %1 is not mapped', $res['wf_name']);
+        }        
+    }
+    
+    
+    // End of rules
+
+    // Validate process sources
+    $serrors=$this->validate_process_sources($pId);
+    $errors = array_merge($errors,$serrors['errors']);
+    $warnings = array_merge($warnings,$serrors['warnings']);
+    
+    $this->error = array_merge ($this->error, $errors);
+    $this->warning = array_merge ($this->warning, $warnings);
+    
+    
+    
+    $isValid = (count($errors)==0) ? 'y' : 'n';
+
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_valid=? where wf_p_id=?';
+    $this->query($query, array($isValid,$pId));
+    
+    $this->_label_nodes($pId);    
+    
+    return ($isValid=='y');
+    
+  }
+ 
+  /**
+   * Validates process sources
+   * Rules:
+   * 1) Interactive activities (non-standalone or view) must use complete()
+   * 2) Standalone activities must not use $instance
+   * 3) Switch activities must use setNextActivity
+   * 4) Non-interactive activities cannot use complete()
+   * 5) View activities cannot use $instance->set
+   *
+   * @param int $pid Process id
+   * @return bool
+   * @access public
+   */
+  function validate_process_sources($pid)
+  {
+    $errors=Array();
+    $errors['errors'] = Array();
+    $errors['warnings'] = Array();
+    $wf_procname= $this->getOne('select wf_normalized_name from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?', array($pid));
+    
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?';
+    $result = $this->query($query, array($pid));
+    while($res = $result->fetchRow()) {          
+      $actname = $res['wf_normalized_name'];
+      $source = GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php';
+      if (!file_exists($source)) {
+          $errors['errors'][] = tra('source code file for activity %1 is not avaible', $actname);
+          continue;
+      }
+      $fp = fopen($source,'r');
+      if (!$fp)
+      {
+        $errors['errors'][] = tra('source code for activity %1 is not avaible', $actname);
+      }
+      else
+      {
+        $data='';
+        while(!feof($fp))
+        {
+          $data.=fread($fp,8192);
+        }
+        fclose($fp);
+      }
+      if($res['wf_type']=='standalone') {
+          if(strstr($data,'$instance')) {
+            $errors['warnings'][] = tra('Activity %1 is standalone and is using the $instance object', $res['wf_name']);
+          }    
+      }
+      else
+      {
+        if($res['wf_type']=='view')
+        {
+          if(strstr($data,'$instance->set'))
+          {
+            $errors['errors'][] = tra('Activity %1 is view and is using the $instance object in write mode', $res['wf_name']);
+          }
+        }
+        else
+        { // for all others than standalone or view ...
+          if($res['wf_is_interactive']=='y')
+          {
+            if(!strstr($data,'$instance->complete()'))
+            {
+              $errors['warnings'][] = tra('Activity %1 is interactive so it must use the $instance->complete() method', $res['wf_name']);
+            }
+          }
+          else
+          { // not interactive ...
+            if(strstr($data,'$instance->complete()'))
+            {
+              $errors['errors'][] = tra('Activity %1 is non-interactive so it must not use the $instance->complete() method', $res['wf_name']);
+            }
+          }
+          if($res['wf_type']=='switch')
+          {
+            if(!strstr($data,'$instance->setNextActivity('))
+            {
+              $errors['warnings'][] = tra('Activity %1 is switch so it must use $instance->setNextActivity($actname) method', $res['wf_name']);
+            }
+          }
+        }
+      }    
+    }
+    return $errors;
+  }
+ 
+  /**
+   * Indicates if an activity with the same name exists.
+   * If you gives an activityId this activity won't be checked (if the activity already exists give this activity id)
+   *
+   * @param int $pId Process id
+   * @param string $name Activity name to be checked
+   * @param int $activityId
+   * @return bool
+   * @access public
+   */
+  function activity_name_exists($pId,$name, $activityId=0)
+  {
+    $name = addslashes($this->_normalize_name($name));
+    $array_args = array($pId, $name, $activityId);
+    $number = $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'activities
+            where wf_p_id=? and wf_normalized_name=? and not(wf_activity_id=?)', $array_args);
+    return !($number==0);
+  }
+ 
+  /**
+   * Gets activity information fields
+   * Warning: get_activity requires no more processId, an activity id is far enough to return informations about an activity
+   *
+   * @param int $activityId
+   * @return array description
+   * @access public
+   */
+  function get_activity($activityId)
+  {
+    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP . 'BaseActivity.php');
+    $act = &Factory::newInstance('BaseActivity');
+    //Warning, we now use the BaseActivity object for it, interactivity and autorouting is now true/fales, not y/n
+    return ($act->getActivity($activityId,false,true, true));
+  /*
+    $query = "select * from ".GALAXIA_TABLE_PREFIX."activities where wf_activity_id=?";
+    $result = $this->query($query, array($activityId));
+    $res = False;
+    if (!(empty($result)))
+    {
+      $res = $result->fetchRow();
+    }
+    $res['toto']=$toto;
+    return $res;
+  */
+  }
+ 
+  /**
+   * Lists activities at a per-process level
+   *
+   * @param int $pId Process id
+   * @param int $offset First row number (see $maxRecords)
+   * @param int $maxRecords Maximum number of records returned
+   * @param string $sort_mode Sort order
+   * @param string $find Searched name or description of the activity
+   * @param string $where SQL string appended
+   * @param bool $count_roles True by default and is adding stat queries results about number of roles concerned by the activity
+   * @return array Associative having two keys, 'cant' for the number of total activities and 'data' containing an associative array with the activities content
+   * @access public
+   */
+  function &list_activities($pId,$offset,$maxRecords,$sort_mode,$find,$where='', $count_roles=true)
+  {
+    $sort_mode = str_replace("__"," ",$sort_mode);
+    if($find) {
+      $findesc = '%'.$find.'%';
+      $mid=' where wf_p_id=? and ((wf_name like ?) or (wf_description like ?))';
+      $bindvars = array($pId,$findesc,$findesc);
+    } else {
+      $mid=' where wf_p_id=? ';
+      $bindvars = array($pId);
+    }
+    if($where) {
+      $mid.= " and ($where) ";
+    }
+    $query = 'select * from '.GALAXIA_TABLE_PREFIX."activities $mid";
+    $query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."activities $mid";
+    $result = $this->query($query,$bindvars,$maxRecords,$offset,true,$sort_mode);
+    $cant = $this->getOne($query_cant,$bindvars);
+    $ret = Array();
+    while($res = $result->fetchRow()) {
+      if ($count_roles) {
+        $res['wf_roles'] = $this->getOne('select count(*) from '
+        .GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id=?',array($res['wf_activity_id']));
+      }
+      $ret[] = $res;
+    }
+    $retval = Array();
+    $retval['data'] = $ret;
+    $retval['cant'] = $cant;
+    return $retval;
+  }
+ 
+ 
+ 
+  /**
+  * Removes an activity.
+  * 
+  * This will also remove transitions concerning the activity, roles associations, agents associations
+  * anassociated agents data
+  * @param int $pId is the process id
+  * @param int $activityId is the activity id
+  * @param bool $transaction is optional and true by default, it will permit to encapsulate the different deletes
+  * in a transaction, if you already started a transaction encapsulating this one use this paramater to prevent
+  * us to open a new one.
+  * @return bool true if it was ok, false if nothing was done
+  * @access public
+  */
+  function remove_activity($pId, $activityId, $transaction = true)
+  {
+    if (!(isset($this->process_manager))) $this->process_manager = &Factory::newInstance('ProcessManager');
+    $proc_info = $this->process_manager->get_process($pId);
+    $actname = $this->_get_normalized_name($activityId);
+    
+    // start a transaction
+    $this->db->StartTrans();
+     
+    //the activity
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_activity_id=?';
+    $this->query($query,array($pId,$activityId));
+    
+    //transitions
+    $query = 'select wf_act_from_id,wf_act_to_id from '
+      .GALAXIA_TABLE_PREFIX.'transitions where wf_act_from_id=? or wf_act_to_id=?';
+    $result = $this->query($query, array($activityId,$activityId));
+    while($res = $result->fetchRow()) {
+      $this->remove_transition($res['wf_act_from_id'], $res['wf_act_to_id']);
+    }
+    
+    //roles
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id=?';
+    $this->query($query, array($activityId));
+    
+    //agents
+    $query = 'select wf_agent_id, wf_agent_type from '.GALAXIA_TABLE_PREFIX.'activity_agents where wf_activity_id=?';
+    $result = $this->query($query, array($activityId));
+    if (!(empty($result)))
+    {
+      while ($res = $result->fetchRow())
+      {
+        //delete the associated agent
+        $query = 'delete from '.GALAXIA_TABLE_PREFIX.'agent_'.$res['wf_agent_type'].' where wf_agent_id=?';
+        $this->query($query, array($res['wf_agent_id']));
+      }
+      //now we can delete the association table
+      $query = 'delete from '.GALAXIA_TABLE_PREFIX.'activity_agents where wf_activity_id=?';
+      $this->query($query, array($activityId));
+    }
+    
+    // And we have to remove the user files
+    // for this activity
+    $wf_procname = $proc_info['wf_normalized_name'];
+    unlink(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php');
+    if (file_exists(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$actname.'.tpl')) {
+      @unlink(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.$actname.'.tpl');
+    }
+    
+    // perform commit (return true) or Rollback (return false)
+    return $this->db->CompleteTrans();
+  }
+ 
+  /**
+   * Updates or inserts a new activity in the database, $vars is an associative
+   * array containing the fields to update or to insert as needed.
+   * @param int $pId is the processId
+   * @param int $activityId is the activityId
+   * @param array $vars
+   * @param bool $create_files
+   * @return int The new activity id 
+   * @access public
+  */
+  function replace_activity($pId, $activityId, $vars, $create_files=true)
+  {
+    if (!(isset($this->process_manager))) $this->process_manager = &Factory::newInstance('ProcessManager');
+    $TABLE_NAME = GALAXIA_TABLE_PREFIX.'activities';
+    $now = date("U");
+    $vars['wf_last_modif']=$now;
+    $vars['wf_p_id']=$pId;
+    $vars['wf_normalized_name'] = $this->_normalize_name($vars['wf_name']);    
+
+    $proc_info = $this->process_manager->get_process($pId);
+    
+    
+    foreach($vars as $key=>$value)
+    {
+      $vars[$key]=addslashes($value);
+    }
+ 
+    if($activityId) {
+      $oldname = $this->_get_normalized_name($activityId);
+      // update mode
+      $first = true;
+      $bindvars = Array();
+      $query ="update $TABLE_NAME set";
+      foreach($vars as $key=>$value) {
+        if(!$first) $query.= ',';
+        if(!is_numeric($value)) $value="'".$value."'";
+        $query.= " $key=$value ";
+        $first = false;
+      }
+      $query .= ' where wf_p_id=? and wf_activity_id=? ';
+      $bindvars[] = $pId;
+      $bindvars[] = $activityId;
+      $this->query($query, $bindvars);
+      
+      $newname = $vars['wf_normalized_name'];
+      // if the activity is changing name then we
+      // should rename the user_file for the activity
+      
+      $user_file_old = GALAXIA_PROCESSES.SEP.$proc_info['wf_normalized_name'].SEP.'code'.SEP.'activities'.SEP.$oldname.'.php';
+      $user_file_new = GALAXIA_PROCESSES.SEP.$proc_info['wf_normalized_name'].SEP.'code'.SEP.'activities'.SEP.$newname.'.php';
+      rename($user_file_old, $user_file_new);
+
+      $user_file_old = GALAXIA_PROCESSES.SEP.$proc_info['wf_normalized_name'].SEP.'code'.SEP.'templates'.SEP.$oldname.'.tpl';
+      $user_file_new = GALAXIA_PROCESSES.SEP.$proc_info['wf_normalized_name'].SEP.'code'.SEP.'templates'.SEP.$newname.'.tpl';
+      if ($user_file_old != $user_file_new) {
+        @rename($user_file_old, $user_file_new);
+      }
+    } else {
+      
+      // When inserting activity names can't be duplicated
+      if($this->activity_name_exists($pId, $vars['wf_name'])) {
+          return false;
+      }
+      unset($vars['wf_activity_id']);
+      // insert mode
+      $first = true;
+      $query = "insert into $TABLE_NAME(";
+      foreach(array_keys($vars) as $key) {
+        if(!$first) $query.= ',';
+        $query.= "$key";
+        $first = false;
+      }
+      $query .=") values(";
+      $first = true;
+      foreach(array_values($vars) as $value) {
+        if(!$first) $query.= ',';
+        if(!is_numeric($value)) $value="'".$value."'";
+        $query.= "$value";
+        $first = false;
+      }
+      $query .=")";
+      $this->query($query);
+      //commented, last_modif time can be far away on high load! And if your database is not incrementing Ids it is not a database
+      //$activityId = $this->getOne('select max(wf_activity_id) from '.$TABLE_NAME.' where wf_p_id=? and wf_last_modif=?', array($pId,$now));
+      $activityId = $this->getOne('select max(wf_activity_id) from '.$TABLE_NAME.' where wf_p_id=? ', array($pId));
+      $ret = $activityId;
+      /* seems to be a debug code
+      if(!$activityId) {
+         print("select max(wf_activity_id) from $TABLE_NAME where wf_p_id=$pId and wf_last_modif=$now");
+         die;      
+      }
+      */
+      // Should create the code file
+      if ($create_files) {
+          $wf_procname = $proc_info["wf_normalized_name"];
+          $fw = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$vars['wf_normalized_name'].'.php','w');
+            fwrite($fw,'<'.'?'.'php'."\n".'?'.'>');
+            fclose($fw);
+            
+             if($vars['wf_is_interactive']=='y') {
+                $fw = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$vars['wf_normalized_name'].'.tpl','w');
+                if (defined('GALAXIA_TEMPLATE_HEADER') && GALAXIA_TEMPLATE_HEADER) {
+                  fwrite($fw,GALAXIA_TEMPLATE_HEADER . "\n");
+                }
+                fclose($fw);
+            }
+      }
+    }
+    // Get the id
+    return $activityId;
+  }
+
+  /**
+  * Associates an activity with an agent type and create or retrieve the associated agent
+  * if the agent of this type for this activity already exists we return his id.
+  * @param int activityId: the activity id
+  * @param string $agentType: The type of the agent
+  * @return agent_id created or retrieved after this association was done or false in case of problems
+  * @access public
+  */
+  function add_activity_agent($activityId, $agentType)
+  {
+    $agent_id = 0;
+    //this will retrieve info directly from the agent table, not on the recorded activity-agent association table
+    $agents = $this->get_activity_agents($activityId);
+    foreach ($agents as $agent)
+    {
+      if ($agent['wf_type']==$agentType)
+      {
+        //we found an agent which were previously associated with the activity
+        $agent_id = $agent['wf_agent_id'];
+        //but we still need to ensure it is still associated with the activity
+        $actualAssoc = $this->getOne('select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activity_agents where wf_activity_id=?', array($activityId));
+        if (!($actualAssoc == $activityId))
+        {
+          $query = 'insert into '.GALAXIA_TABLE_PREFIX.'activity_agents (wf_activity_id,wf_agent_id,wf_agent_type) values(?,?,?)';
+          $this->query($query,array($activityId, $agentId, $agentType));
+        }
+        return $agent_id;
+      }
+    }
+    //if we are here we did not find this type of agent for this activity
+      //TODO: check agent type is in autorized list
+    //add a new agent record
+    $query = 'insert into '.GALAXIA_TABLE_PREFIX.'agent_'.$agentType.' (wf_agent_id) values(DEFAULT)';
+    $this->query($query);
+    $query = 'select max(wf_agent_id) from '.GALAXIA_TABLE_PREFIX.'agent_'.$agentType;
+    $agentId = $this->getOne($query);
+    //record the association
+    $query = 'insert into '.GALAXIA_TABLE_PREFIX.'activity_agents (wf_activity_id,wf_agent_id,wf_agent_type) values(?,?,?)';
+    $this->query($query,array($activityId, $agentId, $agentType));
+    return $agentId;
+  }
+ 
+  /**
+  * Gets the agents (id and type) associated to an activity
+  * @param int $activityId is the activity id
+  * @return array an associative array which can be empty
+  * @access public
+  */
+  function get_activity_agents($activityId)
+  {
+    $query = 'select wf_agent_id, wf_agent_type
+              from '.GALAXIA_TABLE_PREFIX.'activity_agents
+              where wf_activity_id=?';
+    $result = $this->query($query,array($activityId));
+    $ret = Array();
+    if (!(empty($result)))
+    {
+      while($res = $result->fetchRow())
+      {
+        $ret[] = $res;
+      }
+    }
+    
+    return $ret;
+  }
+
+  /**
+  * Gets the agent datas (with id and type as well) associated to an activity
+  * from the agent table
+  * @param int $activityId is the activity id
+  * @param string $agentType is the agent type, giving the table name for the engine
+  * @return array an associative array which can be empty if we did not find the agentType
+  * for this activity
+  * @access public
+  */
+  function get_activity_agent_data($activityId, $agentType)
+  {
+    $query = 'select wf_agent_id
+              from '.GALAXIA_TABLE_PREFIX.'activity_agents
+              where wf_activity_id=? and wf_agent_type=?';
+    $agent_id = $this->getOne($query,array($activityId,$agentType));
+    $ret = Array();
+    if ($agent_id==0)
+    {
+      return $ret;
+    }
+    else
+    {
+      $query = 'select * from '.GALAXIA_TABLE_PREFIX.'agent_'.$agentType.' where wf_agent_id=?';
+      $result = $this->query($query,array($agent_id));
+      if (!(empty($result)))
+      {
+        while($res = $result->fetchRow())
+        {
+          $ret[] = $res;
+        }
+        //fake agent_type column, we know what it should be and that we should have only one record
+        $ret[0]['wf_agent_type'] = $agentType;
+      }
+    }
+    return $ret[0];
+  }
+ 
+  /**
+  * Removes an agent from an activity
+  * @param int activityId the activity id
+  * @param int $agentId The id of the agent
+  * @param bool $removeagent is false by default, if true the agent himself is destroyed, that means if you
+  * re-associate the activity with the same agent type all previous configuration will be lost
+  * @return void
+  * @access public
+  */
+  function remove_activity_agent($activityId, $agentId, $removeagent=false)
+  {
+    
+    if ($removeagent)
+    {
+      $query = 'select wf_agent_type from '.GALAXIA_TABLE_PREFIX.'activity_agents
+          where wf_activity_id=? and wf_agent_id=?';
+      $agent_type = $this->getOne($query, array($activityId, $agentId));
+      $this->remove_agent($agentId, $agent_type);
+    }
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'activity_agents
+            where wf_activity_id=? and wf_agent_id=?';
+    $this->query($query, array($activityId, $agentId));
+  }
+
+  /**
+  * Remove an agent.
+  * @param int $agentId is the agent id
+  * @param string $agent_type is the agent_type
+  * @return void
+  * @access public
+  */
+  function remove_agent($agentId, $agent_type)
+  {
+    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'agent_'.$agent_type.'
+      where wf_agent_id=?';
+    $this->query($query, array($agentId));
+  }
+
+  /**
+  * Sets if an activity is interactive or not
+  * @param int $pId The process id
+  * @param int $actid The activity id
+  * @param string $value y or n 
+  * @access public
+  */
+  function set_interactivity($pId, $actid, $value)
+  {
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_is_interactive=? where wf_p_id=? and wf_activity_id=?';
+    $this->query($query, array($value, $pId, $actid));
+  }
+
+  /**
+  * Sets if an activity is auto routed or not
+  * @param int $pId The processo id
+  * @param int $actid The activity id
+  * @param string $value y or n
+  * @return void
+  * @access public
+  */
+  function set_autorouting($pId, $actid, $value)
+  {
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_is_autorouted=? where wf_p_id=? and wf_activity_id=?';
+    $this->query($query, array($value, $pId, $actid));
+  }
+
+  /**
+   * Sets the default user for an activity
+   * @param int $activityId The activity id
+   * @param mixed $default_user This param can be the id of a user or '' for all
+   * @return void
+   * @access public
+  */
+  function set_default_user($activityId, $default_user)
+  {
+    if ($default_user=='')
+    {
+      $default_user='*';
+    }
+    $query  = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_default_user=? where wf_activity_id=?';
+    $this->query($query, array($default_user, $activityId));
+  }
+
+  /**
+   * Gets the default user for an activity
+   * if performAccessCheck is true then this function will check if this user as really access granted
+   * to the given activity.
+   * If wrong or no default user or the user has no access grant and performAccessCheck was asked, '*' is returned
+   *
+   * @param int $activityId Activity Id
+   * @param boll $performAccessCheck
+   * @return mixed User Id or '*' if no default user is set
+   * @access public
+  */
+  function get_default_user($activityId, $performAccessCheck=true)
+  {
+    $query  = 'Select wf_default_user from '.GALAXIA_TABLE_PREFIX.'activities where wf_activity_id=?';
+    $result = $this->getOne($query,array($activityId));
+    if (!(isset($result)) || ($result=='') || ($result==false))
+    {
+      $result='*';
+    }
+    //if we had a user and if asked we'll try to see if he has really access granted
+    elseif ( (!($result=='*')) && $performAccessCheck)
+    {
+      $wf_security = &Factory::getInstance('WfSecurity', $this->db);
+      // perform the check
+      if (!($wf_security->checkUserAccess($result,$activityId)))
+      {
+        // bad check, we ignore this default_user
+        $result='*';
+      }
+    }
+    return $result;
+  }
+ 
+  /**
+   * Returns activity id by pid,name (activity names are unique)
+   * @param int $pid The process id
+   * @param string $name The name of the activity
+   * @return int The id of the activity
+   * @access private
+  */
+  function _get_activity_id_by_name($pid,$name)
+  {
+    $name = addslashes($name);
+    $bindarray = array($pid,$name);
+    if($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_name=?', $bindarray))
+    {
+      return($this->getOne('select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_name=?', $bindarray));    
+    }
+    else
+    {
+      return '';
+    }
+  }
+ 
+  /**
+   * Returns the activity shape
+   * @param string $type The type of the activity: start, end, activity, split,
+   * switch, join, standalone, view
+   * @return string The shape of the image representing a activity: circle,
+   * doublecircle, box, triangle, diamond, invtriangle, hexagon
+   * @access private
+  */
+  function _get_activity_shape($type)
+  {
+    switch($type) {
+      case 'start':
+          return 'circle';
+      case 'end':
+          return 'doublecircle';
+      case 'activity':
+          return 'box';
+      case 'split':
+          return 'triangle';
+      case 'switch':
+        return 'diamond';
+      case 'join':
+          return 'invtriangle';
+      case 'standalone':
+          return 'hexagon';
+      case 'view':
+          return 'hexagon';
+      default:
+          return 'egg';            
+      
+    }
+
+  }
+
+ 
+  /**
+   * Returns true if a list contains unvisited nodes.
+   * @param array $list List members are assoc arrays containing id and visited
+   * @return bool
+   * @access private   
+  */
+  function _list_has_unvisited_nodes($list)
+  {
+    foreach($list as $node) {
+      if(!$node['visited']) return true;
+    }
+    return false;
+  }
+ 
+  /**
+   * Returns true if a node is in a list
+   * @param array $node
+   * @param array $list List members are assoc arrays containing id and visited
+   * @return bool 
+   * @access private
+  */
+  function _node_in_list($node,$list)
+  {
+    foreach($list as $a_node) {
+      if($node['id'] == $a_node['id']) return true;
+    }
+    return false;
+  }
+ 
+  /**
+   * Normalizes an activity name
+   * @param string $name
+   * @return string 
+   * @access private
+  */
+  function _normalize_name($name)
+  {
+    $name = str_replace(" ","_",$name);
+    $name = preg_replace("/[^A-Za-z_0-9]/",'',$name);
+    return $name;
+  }
+ 
+  /**
+   * Returns normalized name of an activity
+   * @param int $activityId The activity id
+   * @return string The activity name normalized. Spaces are turned to underscore, and special chars are suppressed.
+   * @access private
+  */
+  function _get_normalized_name($activityId)
+  {
+    return $this->getOne('select wf_normalized_name from '
+      .GALAXIA_TABLE_PREFIX.'activities where wf_activity_id=?', array($activityId));
+  }
+ 
+  /**
+   * Labels nodes. Return false if something was wrong
+   * @access private
+   * @param int $pId The process id
+   * @return array  
+  */  
+  function _label_nodes($pId)
+  {
+    ///an empty list of nodes starts the process
+    $nodes = Array();
+    // the end activity id
+    $endId = $this->getOne('select wf_activity_id from '
+      .GALAXIA_TABLE_PREFIX.'activities where wf_p_id=? and wf_type=?',array($pId,'end'));
+    if ((!isset($endId)) || ($endId=='') || ($endId == 0))
+    {
+      //no end
+      return false;
+    }
+    
+    // and the number of total nodes (=activities)
+    $cant = $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?', array($pId));
+    $nodes[] = $endId;
+    $label = $cant;
+    $num = $cant;
+    
+    $query = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_flow_num=? where wf_p_id=?';
+    $this->query($query,array($cant+1,$pId));
+    $seen = array();
+    while(count($nodes)) {
+      $newnodes = Array();
+      foreach($nodes as $node) {
+        // avoid endless loops
+        if (isset($seen[$node])) continue;
+        $seen[$node] = 1;
+        $query = 'update '.GALAXIA_TABLE_PREFIX.'activities set wf_flow_num=? where wf_activity_id=?';
+        $this->query($query, array($num,$node));
+        $query = 'select wf_act_from_id from '.GALAXIA_TABLE_PREFIX.'transitions where wf_act_to_id=?';
+        $result = $this->query($query, array($node));
+        $ret = Array();
+        while($res = $result->fetchRow()) {  
+          $newnodes[] = $res['wf_act_from_id'];
+        }
+      }
+      $num--;
+      $nodes=Array();
+      $nodes=$newnodes;
+      
+    }
+    
+    $min = $this->getOne('select min(wf_flow_num) from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?', array($pId));
+    $query = 'update '.GALAXIA_TABLE_PREFIX."activities set wf_flow_num=wf_flow_num-$min where wf_p_id=?";
+    $this->query($query, array($pId));
+    
+    //$query = "update ".GALAXIA_TABLE_PREFIX."activities set flowNum=0 where flowNum=$cant+1";
+    //$this->query($query);
+    return true;
+  }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/class.ajax_config.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/class.ajax_config.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/engine/class.ajax_config.inc.php	(revision 2372)
@@ -0,0 +1,194 @@
+<?php
+  /**
+   * Realiza operações com os dados de configuração do workflow 
+   * 
+   * @author  viani
+   * @version 1.0
+   * @license http://www.gnu.org/copyleft/gpl.html GPL
+   * @package Galaxia
+   */ 
+class ajax_config
+{	
+	/**		
+ 	* @var object $db database
+	* @access public
+	*/
+	var $db;
+  	/**		
+   	* @var string $appname Application (module) to config
+   	* @access public
+   	*/
+	var $appname;
+  	/**		
+   	* @var array $config_data Actual config-data
+   	* @access public
+   	*/
+	var $config_data;	
+  	/**		
+   	* @var array $read_data Config-data as read from db
+   	* @access public
+   	*/
+	var $read_data;		
+
+  	/**
+   	* Set appname and db for ajax config
+   	* 
+   	* @param string $appname Which application to config. Default workflow.
+   	* @return void
+   	* @access public
+   	*/
+	function ajax_config($appname = '')
+	{
+		if (! $appname)
+		{
+			$appname = 'workflow';
+		}
+
+		$this->db      =& Factory::getInstance('WorkflowObjects')->getDBExpresso();
+		$this->appname = $appname;
+  	}
+
+ 	/**
+   	* Reads the whole repository for $this->appname, appname has to be set via the constructor
+   	*
+   	* @return array the whole config-array for that app
+   	* @access public
+   	*/
+  	function read_repository()
+  	{
+		$this->config_data = array();
+
+		$this->db->query("select * from phpgw_config where config_app='" . $this->appname . "'",__LINE__,__FILE__);
+		while ($this->db->next_record())			
+		{
+			$test = @unserialize($this->db->f('config_value'));
+			if($test)
+			{
+				$this->config_data[$this->db->f('config_name')] = $test;
+			}
+			else
+			{
+				$this->config_data[$this->db->f('config_name')] = $this->db->f('config_value');
+			}
+		}
+		return $this->read_data = $this->config_data;
+	}
+
+  	/** 
+   	* Updates the whole repository for $this->appname, you have to call read_repository() before (!)
+   	* @access public	
+   	* @return void
+   	*/
+	function save_repository()
+	{
+		if (is_array($this->config_data))
+		{
+			$this->db->lock(array('phpgw_config','phpgw_app_sessions'));
+			if($this->appname == 'phpgwapi')
+			{
+				$this->db->query("delete from phpgw_app_sessions where sessionid = '0' and loginid = '0' and app = '".$this->appname."' and location = 'config'",__LINE__,__FILE__);
+			}
+			foreach($this->config_data as $name => $value)
+			{
+				$this->save_value($name,$value);
+			}
+			foreach($this->read_data as $name => $value)
+			{
+				if (!isset($this->config_data[$name]))	// has been deleted
+				{
+					$this->db->query("DELETE FROM phpgw_config WHERE config_app='$this->appname' AND config_name='$name'",__LINE__,__FILE__);
+				}
+			}
+			$this->db->unlock();
+		}
+		$this->read_data = $this->config_data;
+	}
+
+	/**
+	* Updates or insert a single config-value
+	* 
+	* @param string $name name of the config-value
+	* @param mixed $value content
+ 	* @param string $app app-name, defaults to $this->appname set via the constructor
+ 	* @return array
+	* @access public
+	*/
+	function save_value($name,$value,$app=False)
+	{
+		//echo "<p>config::save_value('$name','".print_r($value,True)."','$app')</p>\n";
+		if (!$app || $app == $this->appname)
+		{
+			$app = $this->appname;
+			$this->config_data[$name] = $value;
+		}
+		$name = $this->db->db_addslashes($name);
+
+		if ($app == $this->appname && $this->read_data[$name] == $value)
+		{
+			return True;	// no change ==> exit
+		}
+		$this->db->query($sql="select * from phpgw_config where config_app='$app' AND config_name='$name'",__LINE__,__FILE__);
+		if ($this->db->next_record())
+		{
+			$value_read = @unserialize($this->db->f('config_value'));
+			if (!$value_read)
+			{
+				$value_read = $this->db->f('config_value');
+			}
+			if ($value_read == $value)
+			{
+				return True;	// no change ==> exit
+			}
+			$update = True;
+		}
+		//echo "<p>config::save_value('$name','".print_r($value,True)."','$app')</p>\n";
+
+		if(is_array($value))
+		{
+			$value = serialize($value);
+		}
+		$value = $this->db->db_addslashes($value);
+
+		$query = $update ? "UPDATE phpgw_config SET config_value='$value' WHERE config_app='$app' AND config_name='$name'" :
+				"INSERT INTO phpgw_config (config_app,config_name,config_value) VALUES ('$app','$name','$value')";
+
+		return $this->db->query($query,__LINE__,__FILE__);
+	}
+
+	/**
+	* Deletes the whole repository for $this->appname, appname has to be set via the constructor
+	* 
+	* @access public
+	* @return void 		
+	*/	
+	function delete_repository()
+	{
+		$this->db->query("delete from phpgw_config where config_app='" . $this->appname . "'",__LINE__,__FILE__);
+	}
+
+	/**
+	* Deletes a single value from the repository, you need to call save_repository after
+	* 
+	* @param string $variable_name name of the config
+	* @return void
+	* @access public
+	*/
+	function delete_value($variable_name)
+	{
+		unset($this->config_data[$variable_name]);
+	}
+	/**
+	* Sets a single value in the repository, you need to call save_repository after
+	* 
+	* @param string $variable_name name of the config
+	* @param mixed $variable_data the content
+	* @return void
+	* @access public
+	*/
+	function value($variable_name,$variable_data)
+	{
+		$this->config_data[$variable_name] = $variable_data;
+	}
+	
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/view_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/view_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/view_pos.php	(revision 795)
@@ -0,0 +1,3 @@
+<?php
+//Code to be executed after a view activity
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/standalone_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/standalone_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/standalone_pre.php	(revision 795)
@@ -0,0 +1,13 @@
+<?php
+//Code to be executed before a standalone activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/split_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/split_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/split_pre.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+//Code to be executed before a split activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+if (!($GLOBALS['workflow']['__leave_activity']))
+{
+  // Set the current user for this activity
+    $this->runtime->setActivityUser();
+}
+
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/activity_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/activity_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/activity_pre.php	(revision 795)
@@ -0,0 +1,18 @@
+<?php
+//Code to be executed before an activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+if (!($GLOBALS['workflow']['__leave_activity']))
+{
+  // Set the current user for this activity
+  $this->runtime->setActivityUser();
+}
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/agents_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/agents_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/agents_pos.php	(revision 795)
@@ -0,0 +1,24 @@
+<?php
+//Code to be executed after an activity by agents
+if (!($instance->getActivityCompleted()))
+{
+  foreach ($this->agents as $agent_type => $ui_agent)
+  {
+    if(!($ui_agent->run_activity_pos()))
+    {
+      galaxia_show_error($ui_agent->get_error(), false);
+    }
+
+  }
+}
+else
+{
+  foreach ($this->agents as $agent_type => $ui_agent)
+  {
+    if (!($ui_agent->run_activity_completed_pos()))
+    {
+      galaxia_show_error($ui_agent->get_error(), false);
+    }
+  }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/start_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/start_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/start_pre.php	(revision 795)
@@ -0,0 +1,13 @@
+<?php
+//Code to be executed before a start activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/join_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/join_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/join_pre.php	(revision 795)
@@ -0,0 +1,20 @@
+<?php
+//Code to be executed before a join activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+
+if (!($GLOBALS['workflow']['__leave_activity']))
+{
+  // Set the current user for this activity
+    $this->runtime->setActivityUser();
+}
+
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/switch_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/switch_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/switch_pre.php	(revision 795)
@@ -0,0 +1,18 @@
+<?php
+//Code to be executed before a switch activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+if (!($GLOBALS['workflow']['__leave_activity']))
+{
+  // Set the current user for this activity
+    $this->runtime->setActivityUser();
+}
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/standalone_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/standalone_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/standalone_pos.php	(revision 795)
@@ -0,0 +1,3 @@
+<?php
+//Code to be executed after a standalone activity
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/_shared_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/_shared_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/_shared_pre.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+//Code shared by all the activities (pre)
+if (isset($_REQUEST['__Cancel']))
+{
+  // user want to leave this activity,
+  $GLOBALS['workflow']['__leave_activity']=true;
+}
+          
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/end_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/end_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/end_pre.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+//Code to be executed before the end activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+if (!($GLOBALS['workflow']['__leave_activity']))
+{
+  // Set the current user for this activity
+    $this->runtime->setActivityUser();
+}
+
+$this->runtime->EndStartRun();
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/split_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/split_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/split_pos.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+//Code to be executed after a split activity
+// we save name and others only when the instance
+// has been completed
+if ($instance->getActivityCompleted())
+{
+  if(isset($_REQUEST['wf_name']))
+  {
+    $instance->setName($_REQUEST['wf_name']);
+  }
+  if(isset($_REQUEST['wf_priority']))
+  {
+    $instance->setPriority((int)$_REQUEST['wf_priority']);
+  }
+  if(isset($_REQUEST['wf_set_next_user']))
+  {
+    $instance->setNextUser((int)$_REQUEST['wf_set_next_user']);
+  }
+  if(isset($_REQUEST['wf_set_owner']))
+  {
+    $instance->setOwner((int)$_REQUEST['wf_set_owner']);
+  }
+  if(isset($_REQUEST['wf_category']))
+  {
+    $instance->setCategory((int)$_REQUEST['wf_category']);
+  }
+}
+elseif($GLOBALS['workflow']['__leave_activity'])
+{
+  $this->runtime->StartRun();
+  //tests for auto-release (more complex than release) and lock some rows if needed--------------------
+  if ($this->runtime->checkUserRelease())
+  {
+    //release
+    $this->runtime->setActivityUser(false);
+  }
+  $this->runtime->EndStartRun();  
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/activity_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/activity_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/activity_pos.php	(revision 795)
@@ -0,0 +1,39 @@
+<?php
+//Code to be executed after an activity
+// we save name and others only when the instance
+// has been completed
+if ($instance->getActivityCompleted())
+{
+  if(isset($_REQUEST['wf_name']))
+  {
+    $instance->setName($_REQUEST['wf_name']);
+  }
+  if(isset($_REQUEST['wf_priority']))
+  {
+    $instance->setPriority((int)$_REQUEST['wf_priority']);
+  }
+  if(isset($_REQUEST['wf_set_next_user']))
+  {
+    $instance->setNextUser((int)$_REQUEST['wf_set_next_user']);
+  }
+  if(isset($_REQUEST['wf_set_owner']))
+  {
+    $instance->setOwner((int)$_REQUEST['wf_set_owner']);
+  }
+  if(isset($_REQUEST['wf_category']))
+  {
+    $instance->setCategory((int)$_REQUEST['wf_category']);
+  }
+}
+elseif($GLOBALS['workflow']['__leave_activity'])
+{
+  $this->runtime->StartRun();
+  //tests for auto-release (more complex than release) and lock some rows if needed--------------------
+  if ($this->runtime->checkUserRelease())
+  {
+    //release
+    $this->runtime->setActivityUser(false);
+  }
+  $this->runtime->EndStartRun();  
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/start_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/start_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/start_pos.php	(revision 795)
@@ -0,0 +1,29 @@
+<?php
+//Code to be executed after a start activity
+// we save name and others only when the instance
+// has been completed
+if ($instance->getActivityCompleted())
+{
+  if(isset($_REQUEST['wf_name']))
+  {
+    $instance->setName($_REQUEST['wf_name']);
+  }
+  if(isset($_REQUEST['wf_priority']))
+  {
+    $instance->setPriority((int)$_REQUEST['wf_priority']);
+  }
+  if(isset($_REQUEST['wf_set_next_user']))
+  {
+    $instance->setNextUser((int)$_REQUEST['wf_set_next_user']);
+  }
+  if(isset($_REQUEST['wf_set_owner']))
+  {
+    $instance->setOwner((int)$_REQUEST['wf_set_owner']);
+  }
+  if(isset($_REQUEST['wf_category']))
+  {
+    $instance->setCategory((int)$_REQUEST['wf_category']);
+  }
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/view_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/view_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/view_pre.php	(revision 795)
@@ -0,0 +1,13 @@
+<?php
+//Code to be executed before a view activity
+
+$this->runtime->StartRun();
+
+//tests for access rights and lock some rows--------------------------
+if (!($this->runtime->checkUserRun($GLOBALS['user'])))
+{
+  return $this->runtime->fail(lang('You have not permission to execute this activity'), true);
+}
+
+$this->runtime->EndStartRun();
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/join_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/join_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/join_pos.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+//Code to be executed after a join activity
+// we save name and others only when the instance
+// has been completed
+if ($instance->getActivityCompleted())
+{
+  if(isset($_REQUEST['wf_name']))
+  {
+    $instance->setName($_REQUEST['wf_name']);
+  }
+  if(isset($_REQUEST['wf_priority']))
+  {
+    $instance->setPriority((int)$_REQUEST['wf_priority']);
+  }
+  if(isset($_REQUEST['wf_set_next_user']))
+  {
+    $instance->setNextUser((int)$_REQUEST['wf_set_next_user']);
+  }
+  if(isset($_REQUEST['wf_set_owner']))
+  {
+    $instance->setOwner((int)$_REQUEST['wf_set_owner']);
+  }
+  if(isset($_REQUEST['wf_category']))
+  {
+    $instance->setCategory((int)$_REQUEST['wf_category']);
+  }
+}
+elseif($GLOBALS['workflow']['__leave_activity'])
+{
+  $this->runtime->StartRun();
+  //tests for auto-release (more complex than release) and lock some rows if needed--------------------
+  if ($this->runtime->checkUserRelease())
+  {
+    //release
+    $this->runtime->setActivityUser(false);
+  }
+  $this->runtime->EndStartRun();  
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/switch_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/switch_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/switch_pos.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+//Code to be executed after a switch activity
+// we save name and others only when the instance
+// has been completed
+if ($instance->getActivityCompleted())
+{
+  if(isset($_REQUEST['wf_name']))
+  {
+    $instance->setName($_REQUEST['wf_name']);
+  }
+  if(isset($_REQUEST['wf_priority']))
+  {
+    $instance->setPriority((int)$_REQUEST['wf_priority']);
+  }
+  if(isset($_REQUEST['wf_set_next_user']))
+  {
+    $instance->setNextUser((int)$_REQUEST['wf_set_next_user']);
+  }
+  if(isset($_REQUEST['wf_set_owner']))
+  {
+    $instance->setOwner((int)$_REQUEST['wf_set_owner']);
+  }
+  if(isset($_REQUEST['wf_category']))
+  {
+    $instance->setCategory((int)$_REQUEST['wf_category']);
+  }
+}
+elseif($GLOBALS['workflow']['__leave_activity'])
+{
+  $this->runtime->StartRun();
+  //tests for auto-release (more complex than release) and lock some rows if needed--------------------
+  if ($this->runtime->checkUserRelease())
+  {
+    //release
+    $this->runtime->setActivityUser(false);
+  }
+  $this->runtime->EndStartRun();  
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/_shared_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/_shared_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/_shared_pos.php	(revision 795)
@@ -0,0 +1,3 @@
+<?php
+//Code shared by all activities (pos)
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/end_pos.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/end_pos.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/end_pos.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+//Code to be executed after the end activity
+// we save name and others only when the instance
+// has been completed
+if ($instance->getActivityCompleted())
+{
+  if(isset($_REQUEST['wf_name']))
+  {
+    $instance->setName($_REQUEST['wf_name']);
+  }
+  if(isset($_REQUEST['wf_priority']))
+  {
+    $instance->setPriority((int)$_REQUEST['wf_priority']);
+  }
+  if(isset($_REQUEST['wf_set_next_user']))
+  {
+    $instance->setNextUser((int)$_REQUEST['wf_set_next_user']);
+  }
+  if(isset($_REQUEST['wf_set_owner']))
+  {
+    $instance->setOwner((int)$_REQUEST['wf_set_owner']);
+  }
+  if(isset($_REQUEST['wf_category']))
+  {
+    $instance->setCategory((int)$_REQUEST['wf_category']);
+  }
+}
+elseif($GLOBALS['workflow']['__leave_activity'])
+{
+  $this->runtime->StartRun();
+  //tests for auto-release (more complex than release) and lock some rows if needed--------------------
+  if ($this->runtime->checkUserRelease())
+  {
+    //release
+    $this->runtime->setActivityUser(false);
+  }
+  $this->runtime->EndStartRun();  
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/engine/compiler/agents_pre.php
===================================================================
--- /sandbox/workflow/branches/993/inc/engine/compiler/agents_pre.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/engine/compiler/agents_pre.php	(revision 795)
@@ -0,0 +1,42 @@
+<?php
+//Code to be executed before an activity by agents
+
+//retrieve agents list
+$activity_agents =& $this->activity->getAgents();
+//for all agents we create ui_agent object to handle agents executing tasks
+foreach ($activity_agents as $agent)
+{
+	//create an empty temp ui_agent object
+	$ui_agent =& createObject('workflow.ui_agent_'.$agent['wf_agent_type']);
+	//build this object
+	$ui_agent->load($agent['wf_agent_id']);
+	//At runtime agents need to handle relations with the instance and the activity
+	$ui_agent->runtime($instance, $activity);
+	//store it in an array
+	$this->agents[$agent['wf_agent_type']] = $ui_agent;
+	//delete the temp object
+	unset($ui_agent);
+}
+
+if (!($GLOBALS['workflow']['__leave_activity']))
+{
+  foreach ($this->agents as $agent_type => $ui_agent)
+  {
+    if (!($ui_agent->run_activity_pre()))
+    {
+      galaxia_show_error($ui_agent->get_error(),false);
+    }
+
+  }
+}
+else
+{
+  foreach ($this->agents as $agent_type => $ui_agent)
+  {
+    if (!($ui_agent->run_leaving_activity_pre()))
+    {
+      galaxia_show_error($ui_agent->get_error(), false);
+    }
+  }
+}
+?>
Index: /sandbox/workflow/branches/993/inc/config/module.ini
===================================================================
--- /sandbox/workflow/branches/993/inc/config/module.ini	(revision 795)
+++ /sandbox/workflow/branches/993/inc/config/module.ini	(revision 795)
@@ -0,0 +1,3 @@
+;arquivo de configurações do ambiente de workflow
+[classes]
+wf_crypt = wolfkrow ;chave de criptografia
Index: /sandbox/workflow/branches/993/inc/hook_home.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/hook_home.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/hook_home.inc.php	(revision 2372)
@@ -0,0 +1,59 @@
+<?php
+require_once 'common.inc.php';
+
+$GLOBALS['phpgw_info']['flags']['currentapp'] = "workflow";
+if (!isset($_SESSION['phpgw_info']['workflow']['server']))
+{
+	$_SESSION['phpgw_info']['workflow'] = array();
+
+	$membership = $GLOBALS['phpgw']->accounts->membership();
+	$_SESSION['phpgw_info']['workflow']['user_groups'] = array();
+	foreach($membership as $idx => $group)
+		$_SESSION['phpgw_info']['workflow']['user_groups'][] = $group['account_id'];
+
+	$_SESSION['phpgw_info']['workflow']['account_id'] = $GLOBALS['phpgw_info']['user']['account_id'];
+	$_SESSION['phpgw_info']['workflow']['phpgw_api_inc'] = dirname(__FILE__) . '/../../phpgwapi/inc';
+	$_SESSION['phpgw_info']['workflow']['server']['db_name'] = $GLOBALS['phpgw_info']['server']['db_name'];
+	$_SESSION['phpgw_info']['workflow']['server']['db_host'] = $GLOBALS['phpgw_info']['server']['db_host'];
+	$_SESSION['phpgw_info']['workflow']['server']['db_port'] = $GLOBALS['phpgw_info']['server']['db_port'];
+	$_SESSION['phpgw_info']['workflow']['server']['db_user'] = $GLOBALS['phpgw_info']['server']['db_user'];
+	$_SESSION['phpgw_info']['workflow']['server']['db_pass'] = $GLOBALS['phpgw_info']['server']['db_pass'];
+	$_SESSION['phpgw_info']['workflow']['server']['db_type'] = $GLOBALS['phpgw_info']['server']['db_type'];
+	$_SESSION['phpgw_info']['workflow']['server']['webserver_url'] = $GLOBALS['phpgw_info']['server']['webserver_url'];
+}
+
+$title = lang("External Applications");
+$bo	= Factory::getInstance('bo_userinterface');
+$externals 	= $bo -> externals();
+$extra_data = '';
+$next_br = "0";
+$extra_data = "<div style='width:100%'><table width='100%' cellpadding='0' cellspacing='0'>";
+foreach($externals as $idx => $external){
+	if($next_br == 0){
+		$extra_data .= "<tr>";
+	}
+	$extra_data .=  "<td align=center style='valign:top;width:10em;padding:2px'><a target='_blank' href='".$external["wf_ext_link"]."' nowrap><img width='32px' height='32px' align='center' src='".$external["image"]."'/><br>".$external["name"]."</a></td>";
+	$next_br++;
+	if($next_br == 3){
+		$extra_data .= "</tr>";
+		$next_br = 0;
+	}
+}
+if($next_br == 3){
+	$extra_data .= "</tr>";
+}
+$extra_data .= "</table></div>";
+$portalbox = Factory::getInstance('listbox',
+	Array(
+		'title'     => $title,
+		'primary'   => $GLOBALS['phpgw_info']['theme']['navbar_bg'],
+		'secondary' => $GLOBALS['phpgw_info']['theme']['navbar_bg'],
+		'tertiary'  => $GLOBALS['phpgw_info']['theme']['navbar_bg'],
+		'width'     => '100%',
+		'outerborderwidth' => '0',
+		'header_background_image' => $GLOBALS['phpgw']->common->image('phpgwapi/templates/phpgw_website','bg_filler')
+	)
+);
+
+echo "\n".'<!-- BEGIN Workflow info -->'."\n".$portalbox->draw($extra_data).'<!-- END Workflow info -->'."\n";
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_agent_mail_smtp.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_agent_mail_smtp.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.so_agent_mail_smtp.inc.php	(revision 795)
@@ -0,0 +1,68 @@
+<?php
+/**************************************************************************\
+* eGroupWare - Workflow Agent's SO-layer (storage-object)                  *
+* http://www.egroupware.org                                                *
+* (c) 2005 by Regis leroy <regis.leroy@glconseil.com>                      *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.so_agent.inc.php');
+
+/**
+ * Class to store/read all agents data
+ *
+ * Creation and deletion of agents records are done by the workflow engine, not
+ * by this class and her childs.
+ *
+ * @package Workflow
+ * @author regis.leroy@glconseil.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class so_agent_mail_smtp extends so_agent
+{
+	 /**
+	  * Constructor of the so_agent class
+	  * 
+	  * @return object
+	  * @access public
+	  */
+	function so_agent_mail_smtp()
+	{
+		parent::so_agent();
+		$this->agent_table = $this->wf_table.'mail_smtp';
+	}
+	
+	/**
+	 * Read all agent datas from the database
+	 * @param $agent_id int id of the entry to read
+	 * @return mixed array/boolean array with column => value pairs or false if entry not found
+	 */
+	function read($agent_id)
+	{
+		//perform the query
+		$this->db->select($this->agent_table,'*',array('wf_agent_id'=>$agent_id),__LINE__,__FILE__, 'workflow');
+		
+		while (($row = $this->db->row(true)))
+		{
+			return $row;
+		}
+
+		return false;
+	}
+
+	/**
+	 * @abstract save all agent datas to the database
+	 * @param $agent_id int id of the entry to save
+	 * @param $datas is an array containing columns => value pairs which will be saved for this agent
+	 * @return bool true if everything was ok, false else
+	 */
+	function save($agent_id, &$datas)
+	{
+		$this->db->update($this->agent_table,$datas,array('wf_agent_id'=>$agent_id),__LINE__,__FILE__, 'workflow');
+		return false;
+	}
+}
Index: /sandbox/workflow/branches/993/inc/class.workflow_process.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_process.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_process.inc.php	(revision 2372)
@@ -0,0 +1,21 @@
+<?php
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'API' . SEP . 'Process.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_process extends Process
+	{   /**
+		 * Construtor da classe workflow_process
+		 * @access public
+		 * @return object
+		 */
+		function workflow_process()
+		{
+			parent::Process(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.JobScheduler.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.JobScheduler.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.JobScheduler.inc.php	(revision 2372)
@@ -0,0 +1,196 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'jobs/class.JobEnum.inc.php';
+
+/**
+ * Classe que verifica se um Job deve ser executado neste momento. E, em caso positivo, dispara sua execução
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+class JobScheduler
+{
+	/**
+	 * @var object $currentDate A data corrente (truncada nos minutos)
+	 * @access private
+	 */
+	private $currentDate;
+
+	/**
+	 * @var object $db Objeto de conexão com o Banco de Dados
+	 * @access private
+	 */
+	private $db;
+
+	/**
+	 * @var object $jobManager Objeto da classe JobManager
+	 * @access private
+	 */
+	private $jobManager;
+
+	/**
+	 * Tempo máximo de execução de um Job (em microsegundos)
+	 * @name MAXIMUM_EXECUTION_TIME
+	 */
+	const MAXIMUM_EXECUTION_TIME = 900000000;
+
+	/**
+	 * Construtor da classe JobScheduler
+	 * @return object Objeto da classe JobScheduler
+	 * @access public
+	 */
+	function JobScheduler()
+	{
+		$this->currentDate = new DateTime(date('Y-n-j G:i:00'));
+		$this->db = &Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
+		$this->jobManager = &Factory::getInstance('WorkflowJobManager');
+	}
+
+	/**
+	 * Gera um objeto de data (dos Jobs) a partir de um registro de banco de dados
+	 * @param array $record Um registro da tabela de jobs
+	 * @return object Um objeto de data
+	 * @access private
+	 */
+	private function convertRecordToDateObject($record)
+	{
+		$interval = array('value' => $record['interval_value'], 'unity' => $record['interval_unity']);
+		$startDate = new DateTime($record['time_start']);
+
+		$object = null;
+		switch ($record['date_type'])
+		{
+			case DateType::ABSOLUTE_DATE:
+				$object = &Factory::getInstance('AbsoluteDate', $startDate, $interval);
+				break;
+
+			case DateType::WEEK_DATE:
+				$object = &Factory::getInstance('WeekDate', $startDate, $interval);
+				$object->setWeekDays($record['week_days']);
+				break;
+
+			case DateType::RELATIVE_DATE:
+				$object = &Factory::getInstance('RelativeDate', $startDate, $interval);
+				$object->setOffset($record['month_offset']);
+				break;
+		}
+
+		return $object;
+	}
+
+	/**
+	 * Verifica os jobs que devem ser executados e solicita sua execução
+	 * @return void
+	 * @access public
+	 */
+	public function run()
+	{
+		$records = $this->db->query('SELECT job.job_id, job.wf_process_id, job.name, job.time_start, job.interval_value, job.interval_unity, job.date_type, job.week_days, job.month_offset FROM egw_wf_jobs job, egw_wf_processes process WHERE job.active AND (job.wf_process_id = process.wf_p_id) AND (wf_is_active = \'y\')')->getArray();
+		$jobs = array();
+		foreach ($records as $record)
+			if ($this->convertRecordToDateObject($record)->checkMatchesInterval($this->currentDate))
+				$jobs[] = $record;
+
+		$runningJobs = array_map(array($this, 'execute'), $jobs);
+
+		$numerOfJobs = count($runningJobs);
+		$timeLeft = JobScheduler::MAXIMUM_EXECUTION_TIME;
+		$timeStep = 50000;
+		do
+		{
+			$active = false;
+			for ($i = 0; ($i < $numerOfJobs) && !$active; $i++)
+				$active = $active || $runningJobs[$i]->isActive();
+			usleep($timeStep);
+			$timeLeft -= $timeStep;
+			if ($timeLeft <= 0)
+				$active = false;
+		}
+		while ($active);
+
+		for ($i = 0; $i < $numerOfJobs; $i++)
+		{
+			if (!$runningJobs[$i]->isActive())
+			{
+				if (strpos(($errors = $runningJobs[$i]->getError()), 'PHP Fatal error') !== false)
+					$this->jobManager->writeLog($jobs[$i]['job_id'], $this->currentDate, $errors, JobManager::STATUS_ERROR);
+				$runningJobs[$i]->close();
+			}
+			else
+			{
+				$runningJobs[$i]->kill();
+				$this->jobManager->writeLog($jobs[$i]['job_id'], $this->currentDate, 'O Job foi abortado por ultrapassar o limite do tempo de execução (atualmente em: ' . (JobScheduler::MAXIMUM_EXECUTION_TIME / 1000000) . 's)', JobManager::STATUS_FAIL);
+			}
+		}
+	}
+
+	/**
+	 * Dispara a execução de um Job
+	 * @param array $job Um registro da tabela de jobs
+	 * @param bool $testMode Indica se o Job será executado em modo de teste (true) ou não (false)
+	 * @return object Um objeto da classe Thread que gerencia a execução do Job
+	 * @access public
+	 */
+	public function execute($job, $testMode = false)
+	{
+		if (($job['interval_unity'] == DateUnity::NONE) && (!$testMode))
+		{
+			$disable = true;
+			if ($job['date_type'] == DateType::WEEK_DATE)
+				if (WeekDate::getWeekDay($this->currentDate) <= ($job['week_days'] - WeekDate::getWeekDay($this->currentDate)))
+					$disable = false;
+
+			if ($disable)
+				$records = $this->db->query('UPDATE egw_wf_jobs SET active = FALSE WHERE job_id = ?', array($job['job_id']));
+		}
+
+		$parameters = array();
+		$parameters['file'] = $this->jobManager->getJobFile($job['job_id']);
+		$parameters['jobID'] = $job['job_id'];
+		$parameters['processID'] = $job['wf_process_id'];
+		$parameters['currentDate'] = $this->currentDate->format('Y-m-d H:i:00');
+		$parameters['className'] = $this->jobManager->getClassName($job['job_id']);
+		$parameters['maximumExecutionTime'] = JobScheduler::MAXIMUM_EXECUTION_TIME / 1000000;
+		$parameters['testMode'] = $testMode;
+		$parameters = base64_encode(serialize($parameters));
+
+		$previousDir = getcwd();
+		chdir(GALAXIA_LIBRARY . '/../');
+		$output = Factory::newInstance('Thread', 'class.JobRunner.inc.php "' . $parameters . '"');
+		chdir($previousDir);
+		return $output;
+	}
+
+	/**
+	 * Pega a data atual
+	 * @return object A data atual
+	 * @access public
+	 */
+	public function getCurrentDate()
+	{
+		return $this->currentDate;
+	}
+}
+
+/* se este arquivo é executado a partir da linha de comando, executa os
+ * jobs que estão programados para execução no momento da chamada */
+if (php_sapi_name() == 'cli')
+{
+	require_once 'common.inc.php';
+	Factory::getInstance('WorkflowMacro')->prepareEnvironment();
+
+	$job = Factory::newInstance('JobScheduler');
+	$job->run();
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_orgchart.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_orgchart.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_orgchart.inc.php	(revision 2372)
@@ -0,0 +1,1556 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Camada Model do Organograma.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class so_orgchart
+{
+	/**
+	 * @var bool True se o usuário for administrador do expresso.
+	 * @access private
+	 */
+	private $isAdmin;
+
+	/**
+	 * @var int ID do usuário logado no Expresso
+	 * @access private
+	 */
+	private $userID;
+
+	/**
+	 * @var object Link para a ACL do Workflow.
+	 * @access private
+	 */
+	private $acl;
+
+	/**
+	 * @var object Link para o Banco de Dados do Workflow.
+	 * @access private
+	 */
+	private $db;
+
+	/**
+	 * @var bool Indica se alguns métodos desta classe poderão ser chamados por métodos externos
+	 * @access private
+	 */
+	private $externalCalls = false;
+
+	/**
+	 * Checa se o usuário possui acesso ao Organograma ou permissão para modificar determinada organização.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @param bool $checkType Indica se a checagem não depende do ID da organização.
+	 * @param bool $safeMethod Indica que a checagem pode ser ignorada quando chamada por outras partes do módulo Workflow
+	 * @return void
+	 * @access private
+	 */
+	private function _checkAccess($organizationID = null, $checkType = false, $safeMethod = false)
+	{
+		/* the user is an administrator */
+		if ($this->isAdmin)
+			return true;
+
+		if ($safeMethod)
+			if ($this->externalCalls)
+				return true;
+
+		$authorized = false;
+		if ($checkType)
+			$authorized = $this->acl->checkUserAccessToType('ORG', $this->userID);
+		else
+		{
+			if (!is_numeric($organizationID))
+				$authorized = false;
+			else
+				$authorized = $this->acl->checkUserAccessToResource('ORG', $this->userID, (int) $organizationID);
+		}
+
+		if (!$authorized)
+			$this->endExecution("Você não tem permissão para executar este procedimento!");
+	}
+
+	/**
+	 * Finaliza a execução e envia uma mensagem serializada (para ser exibida no retorno do Ajax).
+	 * @param mixed A mensagem que será exibida. Pode ser uma array de mensagens ou uma string.
+	 * @return void
+	 * @access private
+	 */
+	private function endExecution($message)
+	{
+		if (!is_array($message))
+			$message = array($message);
+
+		die(serialize(implode("\n", $message)));
+	}
+
+	/**
+	 * Define que alguns métodos desta classe poderão ser chamados.
+	 * @param bool $satus O status. true para permitir e false para restringir.
+	 * @return void
+	 * @access public
+	 */
+	public function setExternalCalls($status)
+	{
+		$this->externalCalls = ($status === true);
+	}
+
+	/**
+	 * Verifica se houve erro em alguma query do Banco de Dados.
+	 * @param object $result O resultado de alguma query
+	 * @return void
+	 * @access private
+	 */
+	private function _checkError($result)
+	{
+		if ($result === false)
+			die(serialize("Ocorreu um erro ao se tentar executar a operação solicitada."));
+	}
+
+	/**
+	 * Construtor da classe so_orgchart
+	 * @return object
+	 */
+	function so_orgchart()
+	{
+		$this->userID = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$this->isAdmin = $_SESSION['phpgw_info']['workflow']['user_is_admin'];
+		$this->acl = &$GLOBALS['ajax']->acl;
+		$this->db = &Factory::getInstance('WorkflowObjects')->getDBWorkflow()->Link_ID;
+		$this->db = &Factory::getInstance('WorkflowObjects')->getDBWorkflow()->Link_ID;
+		$this->db->SetFetchMode(ADODB_FETCH_ASSOC);
+	}
+
+	/**
+	 * Lista todas as organizações do Organograma.
+	 * @return array Lista de organizações.
+	 * @access public
+	 */
+	function getOrganizations()
+	{
+		$this->_checkAccess(null, true);
+
+		if ($this->isAdmin)
+			$query = "SELECT organizacao_id, nome, descricao, ativa, url_imagem, sitio FROM organizacao ORDER BY nome";
+		else
+		{
+			$organizations = $this->acl->getUserPermissions("ORG", $this->userID);
+			$organizations[] = -1;
+			$query = "SELECT organizacao_id, nome, descricao, ativa, url_imagem, sitio FROM organizacao WHERE (organizacao_id IN (" . implode(',', $organizations)  . ")) ORDER BY nome";
+		}
+		$result = $this->db->query($query);
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona uma organização.
+	 * @param string $name O nome da organização.
+	 * @param string $description A descrição da organização.
+	 * @param string $imageURL O caminho da imagem que representa o organograma da organização.
+	 * @param char $active 'S' se a organização estiver ativa e 'N' caso contrário.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addOrganization($name, $description, $imageURL, $active, $siteURL)
+	{
+		$this->_checkAccess(null, true);
+
+		$query = "INSERT INTO organizacao(nome, descricao, url_imagem, ativa, sitio) VALUES(?, ?, ?, ?, ?)";
+		$result = $this->db->query($query, array($name, $description, $imageURL, $active, $siteURL));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza as informações sobre uma organização.
+	 * @param string $name O nome da organização.
+	 * @param string $description A descrição da organização.
+	 * @param string $imageURL O caminho da imagem que representa o organograma da organização.
+	 * @param char $active 'S' se a organização estiver ativa e 'N' caso contrário.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateOrganization($name, $description, $imageURL, $active, $organizationID, $siteURL)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE organizacao SET nome = ?, descricao = ?, url_imagem = ?, ativa = ?, sitio = ? WHERE (organizacao_id = ?)";
+		$result = $this->db->query($query, array($name, $description, $imageURL, $active, $siteURL, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove uma organização.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeOrganization($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM organizacao WHERE (organizacao_id = ?)";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista os possíveis status dos funcionários.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @return array Lista dos possíveis status dos empregados.
+	 * @access public
+	 */
+	function getEmployeeStatus($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "SELECT funcionario_status_id, descricao, exibir, organizacao_id FROM funcionario_status WHERE (organizacao_id = ?) ORDER BY descricao";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um Status de funcionário.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @param string $description A descrição do status.
+	 * @param char $show 'S' se o funcionário será exibido na interface de organograma do usuário ou 'N' caso contrário.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addEmployeeStatus($organizationID, $description, $show)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "INSERT INTO funcionario_status(organizacao_id, descricao, exibir) VALUES(?, ?, ?)";
+		$result = $this->db->query($query, array($organizationID, $description, $show));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza um Status de funcionário.
+	 * @param int $employeeStatusID O ID do status de funcionário.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @param string $description A descrição do status.
+	 * @param char $show 'S' se o funcionário será exibido na interface de organograma do usuário ou 'N' caso contrário.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateEmployeeStatus($employeeStatusID, $organizationID, $description, $show)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE funcionario_status SET descricao = ?, exibir = ? WHERE (funcionario_status_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($description, $show, $employeeStatusID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove um Status de funcionário.
+	 * @param int $employeeStatusID O ID do status de funcionário.
+	 * @param int $organizationID O ID da organização do Orgranograma.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeEmployeeStatus($employeeStatusID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM funcionario_status WHERE (funcionario_status_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($employeeStatusID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista as possíveis categorias de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista das possíveis categorias de uma organização.
+	 * @access public
+	 */
+	function getEmployeeCategory($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "SELECT funcionario_categoria_id, organizacao_id, descricao FROM funcionario_categoria WHERE (organizacao_id = ?) ORDER BY descricao";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona uma categoria.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição da categoria.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addEmployeeCategory($organizationID, $description)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "INSERT INTO funcionario_categoria(organizacao_id, descricao) VALUES(?, ?)";
+		$result = $this->db->query($query, array($organizationID, $description));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza uma categoria.
+	 * @param int $employeeCategoryID O ID da categoria.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição da categoria.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateEmployeeCategory($employeeCategoryID, $organizationID, $description)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE funcionario_categoria SET descricao = ? WHERE (funcionario_categoria_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($description, $employeeCategoryID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove uma categoria.
+	 * @param int $employeeCategoryID O ID da categoria.
+	 * @param int $organizationID O ID da organização.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeEmployeeCategory($employeeCategoryID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM funcionario_categoria WHERE (funcionario_categoria_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($employeeCategoryID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista os possíveis cargos de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista dos possíveis cargos de uma organização.
+	 * @access public
+	 */
+	function getJobTitle($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "SELECT cargo_id, organizacao_id, descricao FROM cargo WHERE (organizacao_id = ?) ORDER BY descricao";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um cargo.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição do cargo.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addJobTitle($organizationID, $description)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "INSERT INTO cargo(organizacao_id, descricao) VALUES(?, ?)";
+		$result = $this->db->query($query, array($organizationID, $description));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza um cargo.
+	 * @param int $jobTitleID O ID do cargo.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição do cargo.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateJobTitle($jobTitleID, $organizationID, $description)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE cargo SET descricao = ? WHERE (cargo_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($description, $jobTitleID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove um cargo.
+	 * @param int $jobTitleID O ID do cargo.
+	 * @param int $organizationID O ID da organização.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeJobTitle($jobTitleID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM cargo WHERE (cargo_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($jobTitleID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista os possíveis status das áreas de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista dos possíveis status das áreas de uma organização.
+	 * @access public
+	 */
+	function getAreaStatus($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "SELECT area_status_id, organizacao_id, descricao, nivel FROM area_status WHERE organizacao_id = ? ORDER BY descricao";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um status de área.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição do status.
+	 * @param int $level O nível do status.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addAreaStatus($organizationID, $description, $level)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "INSERT INTO area_status(organizacao_id, descricao, nivel) VALUES(?, ?, ?)";
+		$result = $this->db->query($query, array($organizationID, $description, $level));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza um status de área.
+	 * @param int $areaStatusID O ID do status da área.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição do status.
+	 * @param int $level O nível do status.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateAreaStatus($areaStatusID, $organizationID, $description, $level)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE area_status SET descricao = ?, nivel = ? WHERE (area_status_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($description, $level, $areaStatusID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove um status de área.
+	 * @param int $areaStatusID O ID do status da área.
+	 * @param int $organizationID O ID da organização.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeAreaStatus($areaStatusID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM area_status WHERE (area_status_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($areaStatusID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista os centros de custo de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista dos centros de custo de uma organização.
+	 * @access public
+	 */
+	function getCostCenter($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "SELECT organizacao_id, centro_custo_id, nm_centro_custo, descricao, grupo FROM centro_custo WHERE organizacao_id = ? ORDER BY descricao";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um centro de custo.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $number O número do centro de custo.
+	 * @param string $description A descrição do centro de custo.
+	 * @param string $group O grupo do centro de custo.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addCostCenter($organizationID, $number, $description, $group)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "INSERT INTO centro_custo(organizacao_id, nm_centro_custo, descricao, grupo) VALUES(?, ?, ?, ?)";
+		$result = $this->db->query($query, array($organizationID, $number, $description, $group));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza um centro de custo.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $number O número do centro de custo.
+	 * @param string $description A descrição do centro de custo.
+	 * @param string $group O grupo do centro de custo.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateCostCenter($organizationID, $number, $description, $group, $costCenterID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE centro_custo SET organizacao_id = ?, nm_centro_custo = ?, descricao = ?, grupo = ? WHERE (centro_custo_id = ?)";
+		$result = $this->db->query($query, array($organizationID, $number, $description, $group, $costCenterID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove um centro de custo.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param int $organizationID O ID da organização.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeCostCenter($costCenterID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM centro_custo WHERE (centro_custo_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($costCenterID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista as localidade de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista das localidades de uma organização.
+	 * @access public
+	 */
+	function getLocal($organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query_fields = 'organizacao_id, localidade_id, centro_custo_id, descricao, empresa, endereco, complemento, cep, bairro, cidade, uf';
+		$query = "SELECT {$query_fields} FROM localidade WHERE organizacao_id = ? ORDER BY descricao";
+		$result = $this->db->query($query, array($organizationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona uma localidade.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param string $description A descrição da localidade.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addLocal($organizationID, $costCenter, $description, $company, $address, $complement, $zipCode, $neighborhood, $city, $state )
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "INSERT INTO localidade(organizacao_id, centro_custo_id, descricao, empresa, endereco, complemento, cep, bairro, cidade, uf) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+		$result = $this->db->query($query, array($organizationID, $costCenter, $description, $company, $address, $complement, $zipCode, $neighborhood, $city, $state ));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza uma localidade.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param string $description A descrição da localidade.
+	 * @param int $localID O ID da localidade.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateLocal($organizationID, $costCenter, $description, $localID, $company, $address, $complement, $zipCode, $neighborhood, $city, $state )
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE localidade SET organizacao_id = ?, centro_custo_id = ?, descricao = ?, empresa = ?, endereco = ?, complemento = ?, cep = ?, bairro = ?, cidade = ?, uf = ? WHERE (localidade_id = ?)";
+		$result = $this->db->query($query, array($organizationID, $costCenter, $description, $company, $address, $complement, $zipCode, $neighborhood, $city, $state, $localID) );
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove uma localidade.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $localID O ID da localidade.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeLocal($localID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM localidade WHERE (localidade_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($localID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista os funcionários de uma determinada área da organização.
+	 * @param int $areaID O ID da área.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista dos funcionários de uma determinada área da organização.
+	 * @access public
+	 */
+	function getAreaEmployee($areaID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		/* gather some info from the area */
+		$areaInfo = $this->db->query('SELECT COALESCE(a.titular_funcionario_id, -1) AS titular_funcionario_id, COALESCE(s.funcionario_id, -1) AS substituto_funcionario_id FROM area a LEFT OUTER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE (a.organizacao_id = ?) AND (a.area_id = ?)', array($organizationID, $areaID))->GetArray(-1);
+		if (empty($areaInfo))
+			return false;
+		$areaInfo = $areaInfo[0];
+		$supervisors = '{' . implode(', ', $areaInfo) . '}';
+
+		$query = "SELECT funcionario_id, funcionario_status_id, centro_custo_id, localidade_id, organizacao_id, area_id, cargo_id, nivel, funcionario_categoria_id, titulo FROM funcionario WHERE ((area_id = ?) AND (organizacao_id = ?)) OR (funcionario_id = ANY (?))";
+		$result = $this->db->query($query, array($areaID, $organizationID, $supervisors));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP_DATABASE);
+		for ($i = 0; $i < count($output); $i++)
+		{
+			$output[$i]['funcionario_id_desc'] = '';
+			$output[$i]['uid'] = '';
+
+			if (in_array($output[$i]['funcionario_id'], $areaInfo))
+				$output[$i]['chief'] = ($output[$i]['funcionario_id'] == $areaInfo['titular_funcionario_id']) ? 1 : 2;
+
+			if (($entry = $cachedLDAP->getEntryByID($output[$i]['funcionario_id'])))
+			{
+				$output[$i]['funcionario_id_desc'] = $entry['cn'];
+				$output[$i]['uid'] = $entry['uid'];
+				$output[$i]['removed'] = is_null($entry['last_update']);
+			}
+		}
+
+		usort($output, create_function('$a,$b', 'return strcasecmp($a[\'funcionario_id_desc\'],$b[\'funcionario_id_desc\']);'));
+		return $output;
+	}
+
+	/**
+	 * Procura por funcionários de acordo com um termo de busca.
+	 * @param string $searchTerm O termo de busca. Pode ser referente ao ID do funcionário ou ao nome do mesmo.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista dos funcionários que satisfazem o critério de busca.
+	 * @access public
+	 */
+	function searchEmployee($searchTerm, $organizationID)
+	{
+		$organizationID = (int) $organizationID;
+		$this->_checkAccess($organizationID);
+
+		/* initialize some variables */
+		$output = array();
+		$unifiedResult = array();
+
+		/* FIXME - this piece of code should use the new CacheLdap class */
+		if (is_numeric($searchTerm))
+		{
+			$searchTerm = (int) $searchTerm;
+			$ldapSearch = "(&(|(employeenumber={$searchTerm})(uidnumber={$searchTerm}))(phpgwaccounttype=u))";
+			$DBSearch = "SELECT uidnumber, cn, uid, last_update FROM egw_wf_user_cache WHERE (employeenumber = ?) OR (uidnumber = ?)";
+			$DBValues = array($searchTerm, $searchTerm);
+		}
+		else
+		{
+			$ldapSearch = "(&(cn=*{$searchTerm}*)(phpgwaccounttype=u))";
+			$DBSearch = "SELECT uidnumber, cn, uid, last_update FROM egw_wf_user_cache WHERE (cn ILIKE ?)";
+			$DBValues = array("%{$searchTerm}%");
+		}
+
+		/* search for the $searchTerm in the LDAP */
+		$ldap = &Factory::getInstance('WorkflowObjects')->getLDAP();
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), $ldapSearch, array('uidnumber', 'cn', 'uid'));
+		if ($list === false)
+			die(serialize("O sistema de busca não pode ser utilizado nesta organização."));
+		$entries = ldap_get_entries($ldap, $list);
+		for ($i=0; $i < $entries['count']; $i++)
+			$unifiedResult[$entries[$i]['uidnumber'][0]] = array('name' => $entries[$i]['cn'][0], 'uid' => $entries[$i]['uid'][0], 'removed' => false);
+
+		/* search for the $searchTerm in the DB */
+		$resultSet = Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID->query($DBSearch, $DBValues)->GetArray(-1);
+		foreach ($resultSet as $row)
+			if (!isset($unifiedResult[$row['uidnumber']]))
+				$unifiedResult[$row['uidnumber']] = array('name' => $row['cn'], 'uid' => $row['uid'], 'removed' => is_null($row['last_update']));
+
+		/* check if any result was found */
+		if (count($unifiedResult) < 1)
+			return $output;
+
+		/* load employee information */
+		$query = "SELECT f.funcionario_id, f.funcionario_status_id, f.centro_custo_id, f.localidade_id, f.organizacao_id, f.area_id, f.cargo_id, f.nivel, f.funcionario_categoria_id, f.titulo, a.sigla AS area_sigla FROM funcionario f, area a WHERE (f.area_id = a.area_id) AND (f.organizacao_id = $organizationID) AND (f.funcionario_id IN (" . implode(',', array_keys($unifiedResult))  ."))";
+		$result = $this->db->query($query);
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+		{
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+			$output[$i]['funcionario_id_desc'] = $unifiedResult[$output[$i]['funcionario_id']]['name'];
+			$output[$i]['uid'] = $unifiedResult[$output[$i]['funcionario_id']]['uid'];
+			$output[$i]['removed'] = $unifiedResult[$output[$i]['funcionario_id']]['removed'];
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um funcionário.
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $areaID O ID da área.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param int $localID O ID da localidade.
+	 * @param int $employeeStatusID O ID do status do funcionário.
+	 * @param int $jobTitleID O ID do cargo do funcionário.
+	 * @param int $level O nível do cargo do funcionário.
+	 * @param int $employeeCategoryID O ID da categoria do funcionário.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addEmployee($employeeID, $organizationID, $areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = 'SELECT area.sigla FROM funcionario, area WHERE (funcionario.area_id = area.area_id) AND (funcionario.funcionario_id = ?)';
+		if (($row = $this->db->query($query, $employeeID)->fetchRow()))
+		{
+			$errors = array(
+				"O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($employeeID) . "\" já pertença à área \"{$row['sigla']}\".",
+				'-----------------',
+				'Caso você queira colocá-lo na área selecionada, siga o procedimento: faça uma busca por seu nome, clique para editá-lo e, troque pela área desejada.'
+			);
+			$this->endExecution($errors);
+		}
+
+		$query = "INSERT INTO funcionario(funcionario_id, organizacao_id, area_id, centro_custo_id, localidade_id, funcionario_status_id, cargo_id, nivel, funcionario_categoria_id, titulo) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+		$result = $this->db->query($query, array($employeeID, $organizationID, $areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza o funcionário.
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $areaID O ID da área.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param int $localID O ID da localidade.
+	 * @param int $employeeStatusID O ID do status do funcionário.
+	 * @param int $jobTitleID O ID do cargo do funcionário.
+	 * @param int $level O nível do cargo do funcionário.
+	 * @param int $employeeCategoryID O ID da categoria do funcionário.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateEmployee($employeeID, $organizationID, $areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "UPDATE funcionario SET area_id = ?, centro_custo_id = ?, localidade_id = ?, funcionario_status_id = ?, cargo_id = ?, nivel = ?, funcionario_categoria_id = ?, titulo = ? WHERE (funcionario_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title, $employeeID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove um funcionário.
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $organizationID O ID da organização.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeEmployee($employeeID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = 'SELECT DISTINCT(a.sigla) FROM area a LEFT OUTER JOIN substituicao s USING (area_id) WHERE (? IN (a.titular_funcionario_id, s.funcionario_id, a.auxiliar_funcionario_id))';
+		$areas = array();
+		$resultSet = $this->db->query($query, $employeeID);
+		while (($row = $resultSet->fetchRow()))
+			$areas[] = $row['sigla'];
+		if (count($areas) > 0)
+		{
+			$errors = array(
+				"O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($employeeID) . "\" é titular, substituto, já participou de substituição ou é auxiliar administrativo das seguintes áreas: " . implode(", ", $areas),
+				'-----------------',
+				'Se você quiser excluir este funcionário, precisa removê-lo dos "cargos" que ele possui nas áreas citadas.'
+			);
+			$this->endExecution($errors);
+		}
+
+		$query = "DELETE FROM funcionario WHERE (funcionario_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($employeeID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Lista as áreas de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Lista das áreas de uma organização.
+	 * @access public
+	 */
+	function getArea($organizationID, $areaID = -1)
+	{
+		$this->_checkAccess($organizationID);
+
+		$output = array();
+		$values = array($organizationID);
+
+		// if we are looking for a specific area
+		$area_condition = "";
+		if (($areaID != -1) && !empty($areaID)) {
+			$area_condition = " AND a.area_id = ? ";
+			$values[]= $areaID;
+		}
+
+		$query = "SELECT a.area_id, a.centro_custo_id, a.organizacao_id, a.area_status_id, a.titular_funcionario_id, a.superior_area_id, a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, s.funcionario_id as substituto_funcionario_id FROM area a LEFT OUTER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE organizacao_id = ? " . $area_condition . " ORDER BY sigla";
+		$result = $this->db->query($query, $values);
+		$this->_checkError($result);
+
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
+		{
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($row[$j]);
+			$row['substituto_funcionario_id_desc'] = ($row['substituto_funcionario_id'] != '') ? $ldap->getName($row['substituto_funcionario_id']) : '';
+			$row['titular_funcionario_id_desc'] = ($row['titular_funcionario_id'] != '') ? $ldap->getName($row['titular_funcionario_id']) : '';
+			$row['auxiliar_funcionario_id_desc'] = ($row['auxiliar_funcionario_id'] != '') ? $ldap->getName($row['auxiliar_funcionario_id']) : '';
+			$output[] = $row;
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Lista, hierarquicamente, as áreas de uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $parent O ID da área superior (ou NULL para buscar todas as áreas).
+	 * @param int $depth O nível hierárquico da área (profundidade do nó na árvore do Organograma).
+	 * @return array Lista hierárquica das áreas de uma organização.
+	 * @access public
+	 */
+	function getHierarchicalArea($organizationID, $parent, $depth)
+	{
+		$this->_checkAccess($organizationID);
+
+		if (is_null($parent)){
+			$query = "SELECT a.area_id, a.sigla, a.titular_funcionario_id FROM area a";
+			$query .=" INNER JOIN area_status a_s ON (a_s.area_status_id = a.area_status_id)";
+			$query .=" WHERE (a.superior_area_id IS NULL) AND (a.organizacao_id = ?) AND (a.ativa = 'S') ORDER BY a_s.nivel, a.sigla";
+			$result = $this->db->query($query, array($organizationID));
+		} else {
+			$query = "SELECT a.area_id, a.sigla, a.titular_funcionario_id FROM area a";
+			$query .=" INNER JOIN area_status a_s ON (a_s.area_status_id = a.area_status_id)";
+			$query .=" WHERE (a.superior_area_id = ?) AND (a.ativa = 'S') ORDER BY a_s.nivel, a.sigla";
+			$result = $this->db->query($query, array($parent));
+		}
+
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+		{
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+			$output[$i]['children'] = $this->getHierarchicalArea($organizationID, $output[$i]['area_id'], $depth + 1);
+			$output[$i]['depth'] = $depth;
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona uma área em uma organização.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $areaStatusID O ID do status da área.
+	 * @param int $supervisorID O ID do funcionário que é superior da área.
+	 * @param int $superiorAreaID O ID da área que é superior a que está sendo adicionada (NULL caso não possua área superior).
+	 * @param string $acronym A sigla da área.
+	 * @param string $description A descrição da área.
+	 * @param char $active 'S' se a área estiver ativa e 'N' caso contrário.
+	 * @param int $assistantID O ID do funcionário que está auxiliando o superior da área.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addArea($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$checkEmployees = array($supervisorID, $assistantID);
+		$errors = array();
+		foreach ($checkEmployees as $checkEmployee)
+		{
+			if (is_null($checkEmployee))
+				continue;
+
+			$query = 'SELECT 1 FROM funcionario WHERE (funcionario_id = ?)';
+			if (!$this->db->query($query, $checkEmployee)->fetchRow())
+				$errors[] = "O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($checkEmployee) . "\" não está vinculado a uma área.";
+		}
+
+		if (count($errors) > 0)
+		{
+			$errors[] = '-----------------';
+			$errors[] = 'Se você está iniciando a construção de um organograma, crie as áreas sem titulares/substitutos/auxiliares administrativos e, adicione os funcionários a elas. Só então, adicione os titulares, substitutos, etc. A razão disto, é que estes "cargos" só podem ser ocupados por pessoas que estão vinculadas a alguma área.';
+			$this->endExecution($errors);
+		}
+
+		$query = "INSERT INTO area(centro_custo_id, organizacao_id, area_status_id, titular_funcionario_id, superior_area_id, sigla, descricao, ativa, auxiliar_funcionario_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
+		$result = $this->db->query($query, array($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza a área de uma organização.
+	 * @param int $costCenterID O ID do centro de custo.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $areaStatusID O ID do status da área.
+	 * @param int $supervisorID O ID do funcionário que é superior da área.
+	 * @param int $superiorAreaID O ID da área que é superior a que está sendo atualizada (NULL caso não possua área superior).
+	 * @param string $acronym A sigla da área.
+	 * @param string $description A descrição da área.
+	 * @param char $active 'S' se a área estiver ativa e 'N' caso contrário.
+	 * @param int $areaID O ID da área.
+	 * @param int $assistantID O ID do funcionário que está auxiliando o superior da área.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateArea($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID, $areaID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$checkEmployees = array($supervisorID, $assistantID);
+		$errors = array();
+		foreach ($checkEmployees as $checkEmployee)
+		{
+			if (is_null($checkEmployee))
+				continue;
+
+			$query = 'SELECT 1 FROM funcionario WHERE (funcionario_id = ?)';
+			if (!$this->db->query($query, $checkEmployee)->fetchRow())
+				$errors[] = "O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($checkEmployee) . "\" não está vinculado a uma área.";
+		}
+
+		if (count($errors) > 0)
+		{
+			$errors[] = '-----------------';
+			$errors[] = 'Somente funcionários que estão vinculados a alguma área podem ser colocados na posição de titular ou auxiliar administrativo.';
+			$this->endExecution($errors);
+		}
+
+		$query = "UPDATE area SET centro_custo_id = ?, organizacao_id = ?, area_status_id = ?, titular_funcionario_id = ?, superior_area_id = ?, sigla = ?, descricao = ?, ativa = ?, auxiliar_funcionario_id = ? WHERE (area_id = ?)";
+		$result = $this->db->query($query, array($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID, $areaID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove a área de uma organização.
+	 * @param int $areaID O ID da área.
+	 * @param int $organizationID O ID da organização.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeArea($areaID, $organizationID)
+	{
+		$this->_checkAccess($organizationID);
+
+		$query = "DELETE FROM area WHERE (area_id = ?) AND (organizacao_id = ?)";
+		$result = $this->db->query($query, array($areaID, $organizationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Busca informações sobre um funcionário.
+	 * @param array $params Uma array contendo o ID do funcionário cujas informações serão extraídas e de sua organização (Ajax).
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Informações sobre o funcionário.
+	 * @access public
+	 */
+	function getEmployeeInfo($employeeID, $organizationID)
+	{
+		$this->_checkAccess($organizationID, false, true);
+
+		/**
+		 * This is so wrong.. We should always use the factory to
+		 * instantiate stuff. Besides, module class should not
+		 * use process classes; the correct is to do the inverse.
+		 */
+		require_once dirname(__FILE__) . '/local/classes/class.wf_orgchart.php';
+		$orgchart = new wf_orgchart();
+
+		$outputInfo = array();
+
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
+
+		/* here we need fresh information. Let's access ldap first */
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP_DATABASE);
+		$employeeEntry = $cachedLDAP->getEntryByID($employeeID);
+
+		if ($entry === false)
+			return array('error' => 'Funcionário não encontrado.');
+
+		$outputInfo[] = array(
+			'name' => 'Nome',
+			'value' => $employeeEntry['cn']);
+
+		$outputInfo[] = array(
+			'name' => 'Telefone',
+			'value' => ( ! empty( $employeeEntry['telephonenumber'] ) ? $employeeEntry['telephonenumber'] : '' ) );
+
+		if (!empty($employeeEntry['employeenumber']))
+		{
+			$outputInfo[] = array(
+				'name' => 'Matrícula',
+				'value' => $employeeEntry['employeenumber']);
+		}
+
+		$outputInfo[] = array(
+			'name' => 'UIDNumber',
+			'value' => $employeeID);
+
+		$employeeInfo = $orgchart->getEmployee($employeeID);
+		$employeeStatusInfo = $orgchart->getEmployeeStatus($employeeInfo['funcionario_status_id']);
+
+		$outputInfo[] = array(
+			'name' => 'Status',
+			'value' => $employeeStatusInfo['descricao']);
+
+		if (!empty($employeeInfo['funcionario_categoria_id']))
+		{
+			$categoryInfo = $orgchart->getEmployeeCategory($employeeInfo['funcionario_categoria_id']);
+			$outputInfo[] = array(
+				'name' => 'Vínculo',
+				'value' => $categoryInfo['descricao']);
+		}
+
+		$titulo = NULL;
+		if ( !empty( $employeeInfo['titulo'] ) )
+		{
+			$titulo = $employeeInfo['titulo'];
+		}
+
+		$outputInfo[] = array(
+			'name' => 'Título',
+			'value' => ( $titulo ? $titulo : '' )
+		);
+
+		$cargo = NULL;
+		if ( !empty($employeeInfo['cargo_id']) )
+		{
+			$jobTitleInfo = $orgchart->getJobTitle($employeeInfo['cargo_id']);
+			$cargo = $jobTitleInfo['descricao'];
+		}
+
+		$outputInfo[] = array(
+			'name' => 'Cargo',
+			'value' => ( $cargo ? $cargo : '' )
+		);
+
+		$nivel = NULL;
+		if ( !empty($employeeInfo['nivel']) )
+		{
+			$nivel = $employeeInfo['nivel'];
+		}
+
+		$outputInfo[] = array(
+			'name' => 'Nível',
+			'value' => ( $nivel ? $nivel : '' )
+		);
+
+		$areaInfo = $orgchart->getArea($employeeInfo['area_id']);
+		$outputInfo[] = array(
+			'name' => 'Área',
+			'value' => $areaInfo['sigla']);
+
+		$outputInfo[] = array(
+			'name' => 'ÁreaID',
+			'value' => $employeeInfo['area_id']);
+
+		$localInfo = $orgchart->getLocal($employeeInfo['localidade_id']);
+		$outputInfo[] = array(
+			'name' => 'Localidade',
+			'value' => $localInfo['descricao']);
+
+		$outputInfo[] = array(
+			'name' => 'Empresa',
+			'value' => ( ! empty( $localInfo['empresa'] ) ? $localInfo['empresa'] : '') );;
+
+		$outputInfo[] = array(
+			'name' => 'Endereço',
+			'value' => ( ! empty( $localInfo['endereco'] ) ? $localInfo['endereco'] : '') );
+
+		$outputInfo[] = array(
+			'name' => 'Complemento',
+			'value' => ( ! empty( $localInfo['complemento'] ) ? $localInfo['complemento'] : '') );;
+
+		$outputInfo[] = array(
+			'name' => 'Cep',
+			'value' => ( ! empty( $localInfo['cep'] ) ? $localInfo['cep'] : '') );
+
+		$outputInfo[] = array(
+			'name' => 'Bairro',
+			'value' => ( ! empty( $localInfo['bairro'] ) ? $localInfo['bairro'] : '') );
+
+		$outputInfo[] = array(
+			'name' => 'Cidade',
+			'value' => ( ! empty( $localInfo['cidade'] ) ? $localInfo['cidade'] : '') );
+
+		$outputInfo[] = array(
+			'name' => 'UF',
+			'value' => ( ! empty( $localInfo['uf'] ) ? $localInfo['uf'] : '') );
+
+		if (!empty($employeeInfo['centro_custo_id']))
+			$costCenterInfo = $orgchart->getCostCenter($employeeInfo['centro_custo_id']);
+		else
+			$costCenterInfo = $orgchart->getCostCenter($areaInfo['centro_custo_id']);
+		$outputInfo[] = array(
+			'name' => 'Centro de Custo',
+			'value' => $costCenterInfo['descricao']);
+
+		$outputInfo[] = array(
+			'name' => 'e-mail',
+			'value' => $employeeEntry['mail']);
+
+		$organizationInfo = $orgchart->getOrganization( $employeeInfo['organizacao_id'] );
+
+		$outputInfo[] = array(
+			'name' => 'sitio',
+			'value' => $organizationInfo['sitio']);
+
+		return array('info' => $outputInfo);
+	}
+
+	/**
+	 * Busca informações sobre uma área.
+	 * @param array $params Uma array contendo o ID da área cujas informações serão extraídas e de sua organização (Ajax).
+	 * @param int $areaID O ID da área.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Informações sobre o funcionário.
+	 * @access public
+	 */
+	function getAreaInfo($areaID, $organizationID)
+	{
+		$this->_checkAccess($organizationID, false, true);
+
+		$areaID = (int) $areaID;
+		$organizationID = (int) $organizationID;
+
+		require_once dirname(__FILE__) . '/local/classes/class.wf_orgchart.php';
+		$orgchart = new wf_orgchart();
+
+		$outputInfo = array();
+		$areaInfo = $orgchart->getArea($areaID);
+
+		$outputInfo[] = array(
+			'name' => 'Nome',
+			'value' => $areaInfo['descricao']
+		);
+
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP_DATABASE);
+		if (!empty($areaInfo['titular_funcionario_id']))
+		{
+			$employeeInfo = $cachedLDAP->getEntryByID($areaInfo['titular_funcionario_id']);
+			$outputInfo[] = array(
+				'name' => 'Titular',
+				'value' => $employeeInfo['cn']
+			);
+		}
+
+		if (!empty($areaInfo['substituto_funcionario_id']))
+		{
+			$employeeInfo = $cachedLDAP->getEntryByID($areaInfo['substituto_funcionario_id']);
+			$outputInfo[] = array(
+				'name' => 'Substituto',
+				'value' => $employeeInfo['cn']
+			);
+		}
+
+		if (!empty($areaInfo['auxiliar_funcionario_id']))
+		{
+			$employeeInfo = $cachedLDAP->getEntryByID($areaInfo['auxiliar_funcionario_id']);
+			$outputInfo[] = array(
+				'name' => 'Auxiliar Administrativo',
+				'value' => $employeeInfo['cn']
+			);
+		}
+
+		$outputInfo[] = array(
+			'name' => 'No. de Funcionários',
+			'value' => $this->db->GetOne("SELECT COUNT(*) FROM funcionario f, funcionario_status s WHERE (s.funcionario_status_id = f.funcionario_status_id) AND (s.exibir = 'S') AND (f.area_id = ?) AND (f.organizacao_id = ?)", array($areaID, $organizationID))
+		);
+
+		return array('info' => $outputInfo);
+	}
+
+	/**
+	 * Lista todos os telefones da organização.
+	 * @return array Lista de telefones da organização.
+	 * @access public
+	 */
+	function getTelephones( $organizationID )
+	{
+		$this -> _checkAccess( $organizationID );
+
+		$query = "SELECT organizacao_id, telefone_id, descricao, numero FROM telefone WHERE organizacao_id = ? ORDER BY descricao";
+		$result = $this -> db -> query( $query, array( $organizationID ) );
+		$this -> _checkError( $result );
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um telefone a uma organização.
+	 * @param int $organizationID O ID da organização.
+	 * @param string $description A descrição da localidade.
+	 * @param string $number String com os números de telefones.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addTelephone( $organizationID, $description, $number )
+	{
+		$this->_checkAccess( $organizationID );
+
+		$query = "INSERT INTO telefone( organizacao_id, descricao, numero ) VALUES( ?, ?, ? )";
+		$result = $this -> db -> query( $query, array( $organizationID, $description, $number ) );
+		$this -> _checkError( $result );
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove um telefone.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $telephoneID O ID do telefone.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeTelephone( $organizationID, $telephoneID )
+	{
+		$this->_checkAccess( $organizationID );
+
+		$query = "DELETE FROM telefone WHERE (telefone_id = ?) AND (organizacao_id = ?)";
+		$result = $this -> db -> query( $query, array( $telephoneID, $organizationID ) );
+		$this -> _checkError( $result );
+
+		return ( ( $result === false ) ? false : true );
+	}
+
+	/**
+	 * Atualiza um telefone.
+	 * @param int $organizationID O ID da organização.
+	 * @param int $telephoneID O ID do telefone.
+	 * @param string $description A descrição do telefone.
+	 * @param string $number String com os números de telefones.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateTelephone( $organizationID, $telephoneID, $description, $number )
+	{
+		$this->_checkAccess( $organizationID );
+
+		$query = "UPDATE telefone SET descricao = ?, numero = ? WHERE (telefone_id = ?)";
+		$result = $this -> db -> query( $query, array( $description, $number, $telephoneID ) );
+		$this->_checkError( $result );
+
+		return ( ( $result === false ) ? false : true );
+	}
+
+	/**
+	 * Validate start and end dates for a substitution
+	 * @param int $areaID Area's ID.
+	 * @param string $date_start Substitution's start date.
+	 * @param string $date_start Substitution's end date.
+	 * @return bool
+	 * @access private
+	 */
+	function validateSubstitutionDates($areaID, $date_start, $date_end, $substitutionID = -1)
+	{
+		/* TODO
+		* I'm not supose to be here.. (date validations speaking)
+		* move me to some validation class!
+		*/ 
+
+		/* validating dates */
+		$date_pattern = '/^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/[12][0-9]{3}$/';
+
+		if (!preg_match($date_pattern, $date_start))
+			$this->endExecution("Formato inválido para data de início.");
+		if (!preg_match($date_pattern, $date_end))
+			$this->endExecution("Formato inválido para data de término. ");
+
+		$date_start_arr = explode('/', $date_start);
+		$date_end_arr = explode('/', $date_end);
+
+		/* is it a gregorian date? */
+		if (!checkdate($date_start_arr[1], $date_start_arr[0], $date_start_arr[2]))
+			$this->endExecution("Data de início inválida.");
+		if (!checkdate($date_end_arr[1], $date_end_arr[0], $date_end_arr[2]))
+			$this->endExecution("Data de término inválida. ");
+
+		/* is date_end greater then date_start? */
+		if (mktime(0,0,0, $date_start_arr[1], $date_start_arr[0], $date_start_arr[2]) >= mktime(0,0,0, $date_end_arr[1], $date_end_arr[0], $date_end_arr[2]))
+			$this->endExecution("A data de término deve ser maior que a data de início.");
+
+		/* preparing dates to database */
+		$date_start = implode('-', array_reverse($date_start_arr));
+		$date_end = implode('-', array_reverse($date_end_arr));
+
+		/* checking if there is a substitution in conflict with these dates */
+		$query  = "SELECT * FROM substituicao WHERE ";
+		$query .= "	area_id = ? ";
+		$query .= " AND ";
+		$query .= " 	substituicao_id != ? ";
+		$query .= " AND ";
+		$query .= " 	(";
+		$query .= "		(? BETWEEN data_inicio AND data_fim) ";
+		$query .= "	OR ";
+		$query .= " 		(? BETWEEN data_inicio AND data_fim)";
+		$query .= "	OR ";
+		$query .= " 		(data_inicio BETWEEN ? AND ?)";
+		$query .= "	) ";
+
+		// raise an error if there is any record
+		if ($row = $this->db->query($query, array( $areaID, $substitutionID, $date_start, $date_end, $date_start, $date_end ))->fetchRow())
+		{
+			$row['data_inicio'] = implode('/', array_reverse(explode('-', $row['data_inicio'])));
+			$row['data_fim'] = implode('/', array_reverse(explode('-', $row['data_fim'])));
+			$this->endExecution('Já existe uma substituição no período de '. $row['data_inicio'] . ' a ' . $row['data_fim']);
+		}
+		return true;
+	}
+
+	/**
+	 * Add a substitution.
+	 * @param int $organizationID Organization's ID.
+	 * @param int $areaID Area's ID.
+	 * @param int $substituteID Substitute's employee ID.
+	 * @param string $date_start Substitution's start date.
+	 * @param string $date_start Substitution's end date.
+	 * @return bool
+	 * @access public
+	 */
+	function addSubstitution( $organizationID, $areaID, $substituteID, $date_start, $date_end )
+	{
+		$this->_checkAccess( $organizationID );
+
+		if (!$this->validateSubstitutionDates($areaID, $date_start, $date_end))
+			return false;
+
+		/* formating dates */
+		$date_start = implode('-', array_reverse(explode('/', $date_start)));
+		$date_end = implode('-', array_reverse(explode('/', $date_end)));
+
+		$query = "INSERT INTO substituicao (area_id, funcionario_id, data_inicio, data_fim) VALUES (?, ?, ?, ?)";
+		$result = $this -> db -> query( $query, array( $areaID, $substituteID, $date_start, $date_end ) );
+		$this->_checkError( $result );
+		
+		return ( ( $result === false ) ? false : true );
+	}
+
+	/**
+	 * Update a substitution.
+	 * @param int $organizationID Organization's ID.
+	 * @param int $areaID Area's ID.
+	 * @param int $substituteID Substitute's employee ID.
+	 * @param string $date_start Substitution's start date.
+	 * @param string $date_start Substitution's end date.
+	 * @return bool
+	 * @access public
+	 */
+	function updateSubstitution( $organizationID, $areaID, $substituteID, $date_start, $date_end, $substitutionID )
+	{
+		$this->_checkAccess( $organizationID );
+
+		if (!$this->validateSubstitutionDates($areaID, $date_start, $date_end, $substitutionID))
+			return false;
+
+		/* formating dates */
+		$date_start = implode('-', array_reverse(explode('/', $date_start)));
+		$date_end = implode('-', array_reverse(explode('/', $date_end)));
+
+		$query = "UPDATE substituicao SET funcionario_id = ?, data_inicio = ?, data_fim = ? WHERE substituicao_id = ?";
+		$result = $this -> db -> query( $query, array( $substituteID, $date_start, $date_end, $substitutionID ) );
+		$this->_checkError( $result );
+		
+		return ( ( $result === false ) ? false : true );
+	}
+
+	/**
+	 * List all the substituions for a given area
+	 * @return array List of the substitutions
+	 * @access public
+	 */
+	function getSubstitutions( $organizationID, $areaID )
+	{
+		$this -> _checkAccess( $organizationID );
+
+		/* we must join area table to get organizacao_id */
+		$query = "SELECT s.*, a.organizacao_id FROM substituicao s INNER JOIN area a USING(area_id) WHERE area_id = ? ORDER BY data_inicio DESC";
+		$result = $this -> db -> query( $query, array( $areaID ) );
+		$this -> _checkError( $result );
+
+		/* we must query ldap to get full user names. In workflow db we just store uids */
+		$cachedLDAP = Factory::getInstance('CachedLDAP');
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++) {
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+			/* including substitute full name */
+			$ldap_result = $cachedLDAP->getEntryByID($output[$i]['funcionario_id']);
+			$output[$i]['substituto_funcionario_id'] = $output[$i]['funcionario_id'];
+			$output[$i]['substituto_funcionario_id_desc'] = $ldap_result['cn'];
+
+			/* formating dates */
+			$output[$i]['data_inicio'] = implode('/', array_reverse(explode('-', $output[$i]['data_inicio'])));
+			$output[$i]['data_fim'] = implode('/', array_reverse(explode('-', $output[$i]['data_fim'])));
+		}
+		return $output;
+	}
+
+	/**
+	 * Remove a substitution
+	 * @param int $organizationID Organization's ID
+	 * @param int $telephoneID Substitution's ID
+	 * @return bool 
+	 * @access public
+	 */
+	function removeSubstitution( $organizationID, $substitutionID )
+	{
+		$this->_checkAccess( $organizationID );
+
+		$query = "DELETE FROM substituicao WHERE substituicao_id = ?";
+		$result = $this -> db -> query( $query, array( $substitutionID ) );
+		$this -> _checkError( $result );
+
+		return ( ( $result === false ) ? false : true );
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_adminaccess.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_adminaccess.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_adminaccess.inc.php	(revision 2372)
@@ -0,0 +1,645 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Realiza operações de acl e organograma no banco de dados e ldap
+ *
+ * @package Workflow
+ * @class so_adminaccess
+ * @private
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class so_adminaccess
+{
+	/**
+	* Objeto do banco de dados (conectado)
+	*
+	* @var object $db
+	* @access public
+	*/
+	var $db;
+
+	private $numberOfPermissions = 32;
+
+	/**
+	* Recebe objeto do banco de dados e armazena como atributo da classe.
+	*
+	* @return void
+	* @access public
+	*/
+	function so_adminaccess($db)
+	{
+		$this->db = $db;
+	}
+
+	/**
+	* Obtém a lista de administradores de um processo
+	*
+	* @param integer $proc_id
+	* @return array
+	* @access public
+	*/
+	function get_process_admins_id($proc_id)
+	{
+		return $this->getResourceAdmins('PRO', $proc_id);
+	}
+
+	/**
+	* Obtém a lista de administradores do organograma de uma organização
+	*
+	* @param integer $org
+	* @return array
+	* @access public
+	*/
+	function get_organogram_admins_id($org)
+	{
+		return $this->getResourceAdmins('ORG', $org);
+	}
+
+	/**
+	* Obtém os atributos cn e uidNumber, no ldap, para uma lista de usuários
+	*
+	* @param array $userIDs Os IDs dos usuários/grupos
+	* @return array Uma array contendo os IDs e nomes que foram encontrados
+	* @access public
+	*/
+	function getUserNames($userIDs)
+	{
+		$output = array();
+		$names = Factory::getInstance('WorkflowLDAP')->getNames($userIDs);
+		foreach ($names as $name)
+			$output[] = array(
+				'cn' => $name['name'],
+				'uidnumber' => $name['id']);
+		return $output;
+    }
+
+	/**
+	* Remove o administrador de um organograma
+	*
+	* @param integer $org_id
+	* @param integer $admin_id
+	* @return void
+	* @access public
+	*/
+	function del_organogram_admin($org_id,$admin_id)
+	{
+		$this->removeAdmin('ORG', $admin_id, $org_id);
+	}
+
+	/**
+	* Remove o administrador de um processo
+	*
+	* @param integer $proc_id
+	* @param integer $admin_id
+	* @return void
+	* @access public
+	*/
+	function del_process_admin($proc_id,$admin_id)
+	{
+		$this->removeAdmin('PRO', $admin_id, $proc_id);
+	}
+
+	/**
+	* Remove todos os administradores de um processo
+	*
+	* @param integer $proc_id
+	* @return void
+	* @access public
+	*/
+	function del_process($proc_id)
+	{
+		$this->removeAdminsFromResource('PRO', $proc_id);
+	}
+
+
+	/**
+	* Insere administradores de organograma
+	*
+	* @param integer $org_id
+	* @param array $ids
+	* @return void
+	* @access public
+	*/
+	function add_organogram_admins($org_id,$ids)
+	{
+		$this->addAdmin('ORG', $ids, $org_id);
+	}
+
+	/**
+	* Insere administradores de um processo
+	*
+	* @param integer $proc_id
+	* @param integer $ids
+	* @return void
+	* @access public
+	*/
+	function add_process_admins($proc_id,$ids)
+	{
+		$this->addAdmin('PRO', $ids, $proc_id);
+	}
+
+	/**
+	* Verifica se um usuário pode administrar um processo
+	*
+	* @param integer $user_id
+	* @param integer $proc_id
+	* @return array
+	* @access public
+	*/
+	function check_process_access($user_id,$proc_id)
+	{
+		return $this->checkUserGroupAccessToResource('PRO', $user_id, $proc_id);
+	}
+
+		/**
+	* Obtém os processos permitidos para um usuário
+	*
+	* @param integer $user_id
+	* @return array
+	* @access public
+	*/
+	function get_granted_processes($user_id)
+	{
+		return $this->getUserGroupPermissions('PRO', $user_id);
+	}
+
+	/**
+	* Obtém os organogramas permitidos para um usuário
+	*
+	* @param integer $user_id
+	* @return array
+	* @access public
+	*/
+	function get_granted_organograms($user_id)
+	{
+		return $this->getUserPermissions('ORG', $user_id);
+	}
+
+	/**
+	* Indica se um usuário é administrador do Workflow ou não.
+	*
+	* @param int $userID O ID do usuário
+	* @return bool true se o usuário é um administrador do Workflow (ou do Expresso) ou false caso contrário
+	* @access public
+	*/
+	function checkWorkflowAdmin($userID)
+	{
+		if ($this->checkUserGroupAccessToType('ADM', $userID) === true)
+			return true;
+
+		if (!is_object($GLOBALS['phpgw']->acl))
+		{
+			$GLOBALS['phpgw']->db =& Factory::getInstance('WorkflowObjects')->getDBExpresso();
+			$GLOBALS['phpgw']->acl =& Factory::getInstance('acl', $userID);
+		}
+
+		if (is_object($GLOBALS['phpgw']->acl))
+			if ($GLOBALS['phpgw']->acl->check('run', 1, 'admin') === true)
+				return true;
+
+		return false;
+	}
+
+	/**
+	* Obtém a lista de permissoes equivalente ao numero decimal passado como parametro
+	*
+	* @param integer $number
+	* @return array
+	* @access public
+	*/
+	function _numberToPermissionList($number)
+	{
+		/* prepare the permission list*/
+		$levelList = array_fill(0, $this->numberOfPermissions, false);
+
+		$tmpBin = decbin($number);
+		$tmpSize = strlen($tmpBin);
+		for ($i = 0; $i < $tmpSize; $i++)
+			$levelList[$tmpSize - $i - 1] = ($tmpBin[$i] == '0') ? false : true;
+
+		return $levelList;
+	}
+	/**
+	* Converte uma lista de permissoes para um numero inteiro que a representa
+	*
+	* @param string $list
+	* @return integer
+	* @access public
+	*/
+	function _permissionListToNumber($list)
+	{
+		if (is_numeric($list))
+			return (int) $list;
+
+		$text = "";
+		for ($i = 0; $i < $this->numberOfPermissions; $i++)
+			if (isset($list[$i]))
+				$text = (($list[$i] == true) ? '1' : '0') . $text;
+			else
+				$text = "0" . $text;
+
+		return bindec($text);
+	}
+
+	/**
+	* Verifica se o numero passado representa todas as permissoes requeridas
+	*
+	* @param integer $number Número que representa uma lista de permissões
+	* @param array $required Permissões requeridas
+	* @return boolean
+	* @access public
+	*/
+	function _checkLevelNumber($number, $required)
+	{
+		if (is_null($required))
+			return true;
+		if (!is_array($required))
+			$required = array($required);
+
+		$levelList = $this->_numberToPermissionList($number);
+
+		/* check for the required permissions */
+		foreach ($required as $req)
+			if (!$levelList[$req])
+				return false;
+
+		return true;
+	}
+
+	/**
+	* Retorna os recursos disponiveis ao Administrador
+	*
+	* @param string $type type of resource
+	* @param integer $numvalue resource id
+	* @return array
+	* @access public
+	*/
+	function getResourceAdmins($type, $numvalue)
+	{
+		$query = "
+			SELECT
+				admin_access_id
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(numvalue = ?)";
+
+		$result = $this->db->query($query, array($type, $numvalue));
+
+		$output = array();
+		while ($row = $result->fetchRow())
+			$output[] = $row['admin_access_id'];
+
+		return $output;
+	}
+
+	/**
+	* Verifica se o usuario tem acesso a um tipo de recurso
+	*
+	* @param string $type type of resource
+	* @param integer $uid user id
+	* @return bool
+	* @access public
+	*/
+	function getUserPermissions($type, $uid)
+	{
+		$query = "
+			SELECT
+				numvalue
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(admin_access_id = ?)";
+
+		$result = $this->db->query($query, array($type, $uid));
+
+		$output = array();
+		if ($result)
+			while ($row = $result->fetchRow())
+				$output[] = $row['numvalue'];
+
+		return $output;
+	}
+	/**
+	 * Retorna as permissoes do grupo do usuário
+	 *
+	 * @param string $type
+	 * @param integer $uid id do usuário
+	 * @access public
+	 * @return array
+ 	 */
+	function getUserGroupPermissions($type, $uid)
+	{
+		$groups = galaxia_retrieve_user_groups($uid);
+		if ($groups === false)
+			$groups = array();
+
+		$query = "
+			SELECT
+				DISTINCT(numvalue) AS numvalue
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(admin_access_id IN (" . implode(', ', array_merge(array($uid), $groups)) . "))";
+
+		$result = $this->db->query($query, array($type));
+
+		$output = array();
+		if ($result)
+			while ($row = $result->fetchRow())
+				$output[] = $row['numvalue'];
+
+		return $output;
+	}
+	/**
+	* Verifica se o usuario tem acesso a um tipo de recurso
+	*
+	* @param string $type type of resource
+	* @param integer $uid user id
+	* @return bool
+	* @access public
+	*/
+	function checkUserAccessToType($type, $uid)
+	{
+		return (count($this->getUserPermissions($type, $uid)) > 0);
+	}
+	/**
+	* Verifica se o grupo do usuario tem acesso a um tipo de recurso
+	*
+	* @param string $type type of resource
+	* @param integer $uid user id
+	* @return bool
+	* @access public
+	*/
+	function checkUserGroupAccessToType($type, $uid)
+	{
+		return (count($this->getUserGroupPermissions($type, $uid)) > 0);
+	}
+
+	/**
+	* Verifica se o usuário tem direito de acesso a um recurso
+	*
+	* @param string $type tipo de recurso
+	* @param integer $uid id do usuário
+	* @param integer $numvalue id do recurso
+	* @param array  $requiredLevel permissoes requeridas
+	* @return bool
+	* @access public
+	*/
+	function checkUserAccessToResource($type, $uid, $numvalue, $requiredLevel = null)
+	{
+		$query = "
+			SELECT
+				nivel
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(admin_access_id = ?) AND
+				(numvalue = ?)";
+
+		$result = $this->db->query($query, array($type, $uid, $numvalue));
+		$row = $result->fetchRow();
+
+		if (isset($row['nivel']))
+			return $this->_checkLevelNumber($row['nivel'], $requiredLevel);
+		else
+			return false;
+	}
+	/**
+	* Verifica se o grupo do usuário tem direito de acesso a um recurso
+	*
+	* @param string $type tipo de recurso
+	* @param integer $uid id do usuário
+	* @param integer $numvalue id do recurso
+	* @param array  $requiredLevel permissoes requeridas
+	* @return bool
+	* @access public
+	*/
+	function checkUserGroupAccessToResource($type, $uid, $numvalue, $requiredLevel = null)
+	{
+		$groups = galaxia_retrieve_user_groups($uid);
+		if ($groups === false)
+			$groups = array();
+
+		$query = "
+			SELECT
+				nivel
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(admin_access_id IN (" . implode(', ', array_merge(array($uid), $groups)) . ")) AND
+				(numvalue = ?)";
+
+		$levels = array();
+		$permissions = 0;
+		$result = $this->db->query($query, array($type, $numvalue));
+		while ($row = $result->fetchRow())
+		{
+			$levels[] = $row['nivel'];
+			$permissions |= $row['nivel'];
+		}
+
+		if (empty($levels))
+			return false;
+		else
+			return $this->_checkLevelNumber($permissions, $requiredLevel);
+	}
+
+	/**
+	* Adiciona um administrador
+	*
+	* @param string  $type tipo de recurso
+	* @param array   $uids
+	* @param integer $numvalue id do recurso
+	* @param array   $level nivel de permissao do usuario
+	* @return void
+	* @access public
+	*/
+	function addAdmin($type, $uids, $numvalue, $level = 0)
+	{
+		if (!is_array($uids))
+			$uids = array($uids);
+		if (is_array($level))
+			$level = $this->_permissionListToNumber($level);
+		foreach($uids as $uid)
+		{
+			$query = "
+				INSERT INTO egw_wf_admin_access
+					(admin_access_id,
+					tipo,
+					numvalue,
+					nivel)
+				VALUES (?, ?, ?, ?)";
+			$this->db->query($query, array($uid, $type, $numvalue, $level));
+		}
+	}
+	/**
+	* Setaa o nivel de administracao
+	*
+	* @param string  $type tipo de recurso
+	* @param integer $uid id do usuário
+	* @param integer $numvalue id do recurso
+	* @param array   $level permissoes requeridas
+	* @return void
+	* @access public
+	*/
+	function setAdminLevel($type, $uid, $numvalue, $level)
+	{
+		if (is_array($level))
+			$level = $this->_permissionListToNumber($level);
+
+		$query = "
+			UPDATE egw_wf_admin_access
+			SET
+				nivel = ?
+			WHERE
+				(admin_access_id = ?) AND
+				(tipo = ?) AND
+				(numvalue = ?)";
+		$this->db->query($query, array($level, $uid, $type, $numvalue));
+	}
+
+	/**
+	* Informa o nível de administração do usuário
+	* @param string $type O tipo do recurso
+	* @param int $uid O ID do usuário
+	* @param int $numvalue O ID do recurso
+	* @return array As permissões do usuário (em forma de número e de bits)
+	* @access public
+	*/
+	function getUserAdminLevel($type, $uid, $numvalue)
+	{
+		$query = "
+			SELECT
+				nivel
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(admin_access_id = ?) AND
+				(numvalue = ?)";
+
+		$result = $this->db->query($query, array($type, $uid, $numvalue));
+
+		$row = $result->fetchRow();
+		if (isset($row['nivel']))
+		{
+			$output['number'] = $row['nivel'];
+			$output['bits'] = $this->_numberToPermissionList($row['nivel']);
+			return $output;
+		}
+		else
+			return false;
+	}
+
+	/**
+	* Informa o nível de administração do usuário (incluindo herança por grupo)
+	* @param string $type O tipo do recurso
+	* @param int $uid O ID do usuário
+	* @param int $numvalue O ID do recurso
+	* @return array As permissões do usuário, inclusive herança por grupo. As permissões são retornadas em forma de número e de bits
+	* @access public
+	*/
+	function getUserGroupAdminLevel($type, $uid, $numvalue)
+	{
+		/* prepare the group information */
+		$groups = galaxia_retrieve_user_groups($uid);
+		if ($groups === false)
+			$groups = array();
+		$groups[] = $uid;
+        $groups = '{' . implode(', ', $groups) . '}';
+
+		$query = "
+			SELECT
+				nivel
+			FROM
+				egw_wf_admin_access
+			 WHERE
+				(tipo = ?) AND
+				(admin_access_id = ANY (?)) AND
+				(numvalue = ?)";
+
+		$result = $this->db->query($query, array($type, $groups, $numvalue));
+
+		$levels = array();
+		$permissions = 0;
+		while ($row = $result->fetchRow())
+		{
+			$permissions |= $row['nivel'];
+			$levels[] = $row['nivel'];
+		}
+
+		if (count($levels) > 0)
+		{
+			return array(
+				'number' => $permissions,
+				'bits' => $this->_numberToPermissionList($permissions));
+		}
+		else
+			return false;
+	}
+
+	/**
+	* Remove administrador(es)
+	*
+	* @param string  $type tipo de recurso
+	* @param integer $uids id(s) do(s) usuário(s)
+	* @param integer $numvalue id do recurso
+	* @return void
+	* @access public
+	*/
+	function removeAdmin($type, $uids, $numvalue)
+	{
+		if (!is_array($uids))
+			$uids = array($uids);
+		foreach($uids as $uid)
+		{
+			$query = "
+				DELETE FROM
+					egw_wf_admin_access
+				WHERE
+					(tipo = ?) AND
+					(numvalue = ?) AND
+					(admin_access_id = ?)";
+
+			$result = $this->db->query($query, array($type, $numvalue, $uid));
+		}
+	}
+	/**
+	* Remove todos os administradores de um recurso
+	*
+	* @param string  $type tipo de recurso
+	* @param integer $numvalue id do recurso
+	* @return void
+	* @access public
+	*/
+	function removeAdminsFromResource($type, $numvalue)
+	{
+		$query = "
+			DELETE FROM
+				egw_wf_admin_access
+			WHERE
+				(tipo = ?) AND
+				(numvalue = ?)";
+
+		$result = $this->db->query($query, array($type, $numvalue));
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/hook_settings.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/hook_settings.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/hook_settings.inc.php	(revision 795)
@@ -0,0 +1,57 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - Preferences                                                 *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	
+	// ui_userinterface preferences
+	create_select_box('Starting page','startpage',array(
+               'Tarefas Pendentes',
+               'Processos',
+               'Acompanhamento',
+               'Aplicações Externas',
+			   'Organograma'),
+               'This is the first screen shown when you click on the workflow application icon');
+	create_select_box('Inbox Sorting', 'inbox_sort', array(
+	           'wf_act_started__ASC' => 'Data - Crescente',
+	           'wf_act_started__DESC' => 'Data - Decrescente',
+	           'wf_procname__ASC' => 'Processo - Crescente',
+			   'wf_procname__DESC' => 'Processo - Decrescente',
+			   'wf_priority__ASC' => 'Prioridade - Crescente',
+			   'wf_priority__DESC' => 'Prioridade - Decrescente',
+	           'wf_name__ASC' => 'Atividade - Crescente',
+	           'wf_name__DESC' => 'Atividade - Decrescente',
+	           'insname__ASC' => 'Identificador - Crescente',
+	           'insname__DESC' => 'Identificador - Decrescente'),
+			   'Sets the default sorting criteria for the inbox instances.');
+	create_select_box('Number of items per page', 'ui_items_per_page', array(
+				'5' => '5',
+				'10' => '10',
+				'15' => '15',
+				'20' => '20',
+				'25' => '25',
+				'30' => '30',
+				'40' => '40',
+				'50' => '50',
+				'100' => '100',
+				'150' => '150',
+				'200' => '200'),
+				'Determines the number of items per page in the user interface.');
+	create_select_box('Show activity complete page', 'show_activity_complete_page', array(
+				'1' => 'Sim',
+				'0' => 'Não'),
+				'Determines if the activity complete page should be displayed after the completion of the activity');
+	create_select_box('Use light interface', 'use_light_interface', array(
+				'1' => 'Sim',
+				'0' => 'Não'),
+				'Determines if a lighter version of the interface should be used');
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_agent.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_agent.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_agent.inc.php	(revision 2372)
@@ -0,0 +1,298 @@
+<?php
+/**************************************************************************\
+* eGroupWare Workflow - Agents Connector - business objects layer          *
+* ------------------------------------------------------------------------ *
+* This program is free software; you can redistribute it and/or modify it  *
+* under the terms of the GNU General Public License as published           *
+* by the Free Software Foundation; either version 2 of the License, or     *
+* any later version.                                                       *
+\**************************************************************************/
+
+/**
+ * This allows the Workflow Engine to connect to various agents
+ * Agents are external elements for the workflow. It could be
+ * email systems, filesystems, calendars, what you want.
+ * Use this class to make childrens like, for example in the
+ * class.bo_agent_mail_smtp.inc.php for the mail_smtp susbsytem
+ * 
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author regis.leroy@glconseil.com
+ */
+class bo_agent
+{		
+	/**
+	 * @var array $error the local error storage
+	 * @access public
+	 */
+	var $error = Array();
+	/**
+	 * @var object $activity the activity object we are working with at runtime (reference)
+	 * @access public
+	 */	
+	var $activity = null;
+	/**
+	 * @var object $instance the instance object we are working with at runtime (reference)
+	 * @access public
+	 */	
+	var $instance = null;
+	/**
+	 * @var object $process the process object is used for process level configuration
+	 * @access public
+	 */	
+	var $process = null;
+	/**
+	 * @var array $conf
+	 * @access public
+	 */	
+	var $conf;
+	// define theses values in your child class ----------------------------------------------
+	
+	/**
+	 * @var string $title Agent title
+	 * @access public
+	 */	
+	var $title='';
+	/**
+	 * @var string $description Agent description
+	 * @access public
+	 */	
+	var $description='';
+	/**
+	 * @var string $help Agent help
+	 * @access public
+	 */	
+	var $help='';
+	/**
+	 * @var object $so_agent derived so object. i.e.: for foo agent it is an so_agent_foo
+	 * @access public
+	 */	
+	var $so_agent;
+	/**
+	 * @var integer $agent_id Agent id
+	 * @access public
+	 */	
+	var $agent_id;
+	/**
+	 *  @var array $fields the fields which are saved at admin time and just changed at runtime (without saving)
+	 *  @access public
+	 */
+	var $fields = Array();	
+	/**
+	 *  @var array $ProcessConfigurationFieldsdefault the config fields which are at process level , key is the config option and value is the
+	 *  default value
+	 *  @access public
+	 */
+	var $ProcessConfigurationFieldsdefault = Array();
+	/**
+	 * @var array $showProcessConfigurationFieldsdefault the config fields which are at process level , key is the config option and value is an
+	 * associative array with keys:
+	 * - 'title' for an helper/title line, not a conf value in fact
+	 * - 'text' for a text input
+	 * - 'yesno' to select between true or false
+	 * - an array for a list of select key => value pairs
+	 * @access public
+	 */
+	var $showProcessConfigurationFieldsdefault = Array();
+	
+	/**
+	 *  Constructor
+	 *  
+	 *  @access public
+	 *  @return object
+	 */
+	function bo_agent()
+	{
+		
+	}
+	
+	/**
+	 * You should always call this function after failed operations on a workflow object to obtain messages
+	 * @param array $as_array if true the result will be send as an array of errors or an empty array. Else, if you do not give any parameter 
+	 * or give a false parameter you will obtain a single string which can be empty or will contain error messages with <br /> html tags.
+	 * @return mixed single string,array of errors or an empty array
+	 * @access public
+	 */
+	 function get_error($as_array=false) 
+	 {
+	 	if ($as_array)
+		 {
+		 	return $this->error;
+		 }
+		 $result_str = implode('<br />',$this->error);
+		 $this->error= Array();
+		 return $result_str;
+		}
+	
+	/**
+	 *  Get the title
+	 * 
+	 *  @return string title
+	 *  @access public
+	 */
+	function getTitle()
+	{
+		return $this->title;
+	}
+	
+	/**
+	 *  Get the description
+	 * 
+	 *  @return string description
+	 *  @access public
+	 */
+	
+	function getDescription()
+	{
+		return $this->description;
+	}
+	
+	/**
+	 *  Get the help
+	 * 
+	 *  @return string help
+	 *  @access public
+	 */
+	function getHelp()
+	{
+		return $this->help;
+	}
+
+	/**
+	  * Factory: Load the agent values stored somewhere in the agent object and retain the agent id
+	  *
+	  * @param int $agent_id is the agent id
+	  * @param bool $really_load boolean, true by default, if false the data wont be loaded from database and
+	  * the only thing done by this function is storing the agent_id (usefull if you know you wont need actual data)
+	  * @return bool false if the agent cannot be loaded, true else
+	  * @access public
+	 */
+	function load($agent_id, $really_load=true)
+	{
+		$this->agent_id = $agent_id;
+		return true;
+	}
+
+	/**
+	  * Save the agent datas
+	  *
+	  * @return bool false if the agent cannot be saved, true else
+	  * @access public
+	 */
+	function save()
+	{
+		return true;
+	}
+	
+	/**
+	 * Function called at runtime to permit association with the instance and the activity
+	 * we store references to theses objects
+	 * @return void
+	 * @access public
+	 */
+	function runtime(&$instance, &$activity)
+	{
+		$this->instance =& $instance;
+		$this->activity =& $activity;
+	}
+
+	/**
+	* Return the agent fields in different forms
+	* @param int $result_type :
+	* - 1 the result is an array containing the field names
+	* - 2 the result is an array containing fields names => value pairs
+    * - 3 the result is an array containing fields names => field array pairs, the field array is an associative array
+	*   containing all infos about the field with $key => $value pairs.
+	* @return array an array, the form depends on the parameter $result_type
+	* @access public
+	*/
+	function get($result_type)
+	{
+		switch ($result_type)
+		{
+			case 1:
+				return array_keys($this->fields);
+				break;
+			case 2:
+				$res = Array();
+				foreach ($this->fields as $key => $value)
+				{
+					$res[$key] = html_entity_decode($value['value']);
+				}
+				return $res;
+				break;
+			default :
+				return $this->fields;
+		}
+	}
+
+	/**
+	 * Affect some values to some of the agent's fields
+	 * @param array $datas is an array containing fields => value pairs
+	 * @return bool false if one or more value cannot be affected, true else
+	 * @access public
+	 */
+	function set(&$datas)
+	{
+		foreach ($datas as $key => $value)
+		{
+			if ( (isset($this->fields[$key])) && (is_array($this->fields[$key])) )
+			{
+				$this->fields[$key]['value'] = htmlentities($value);
+			}
+			else
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+
+
+	/**
+	 * this function tell the engine which process level options have to be set
+	 *
+	 * for the agent. Theses options will be initialized for all processes by the engine
+	 * and can be different for each process.
+	 * @return array an array which can be empty
+	 * @access public
+	 */
+	function listProcessConfigurationFields()
+	{
+		return $this->showProcessConfigurationFields;
+	}
+	
+	/**
+	 * This function retrieve process level configuration otpions set by the engine
+	 * for the agent. Theses conf values are cached locally for the object life duration
+	 * @param int $wf_p_id is the process id
+	 * @param bool $force is false by default, if true we retrieve theses config values even if the $conf
+	 * 	local cache is already set
+	 * @return array an associative array which can be empty
+	 * @access public
+	 */
+	function getProcessConfigurationFields($wf_p_id, $force=false)
+	{
+		if ($force || (!(isset($this->conf))) )
+		{
+			if (!(isset($this->process)))
+			{
+				$this->process = Factory::getInstance('workflow_process');
+				$this->process->getProcess($wf_p_id);
+			}
+			$this->conf = $this->process->getConfigValues($this->ProcessConfigurationFieldsdefault);
+		}
+		return $this->conf;
+	}
+	/**
+	 * this function lists activity level options avaible for the agent
+	 *
+	 * @return array an associative array which can be empty
+	 * @access public
+	 */
+	function getAdminActivityOptions ()
+	{
+		return (Array(Array()));
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_templateeditor.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_templateeditor.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.ui_templateeditor.inc.php	(revision 795)
@@ -0,0 +1,27 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once dirname(__FILE__) . SEP . 'class.ui_phpeditor.inc.php';
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ */
+class ui_templateeditor extends ui_phpeditor
+{
+	protected function loadVariables()
+	{
+		$this->HTMLFile = 'tpleditor.html';
+		$this->type = 'tpl';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_participants.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_participants.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_participants.inc.php	(revision 2372)
@@ -0,0 +1,207 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+require_once 'class.bo_ajaxinterface.inc.php';
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+ */
+class bo_participants extends bo_ajaxinterface
+{
+	/**
+	 * @var resource $ldap Conexão com o LDAP
+	 * @access public
+	 */
+	var $ldap;
+
+	/**
+	 * Construtor da classe bo_participants
+	 * @return object
+	 * @access public
+	 */
+	function bo_participants()
+	{
+		$this->ldap = &Factory::getInstance('WorkflowLDAP');
+	}
+
+	/**
+	 * Busca as organizações do LDAP
+	 * @return array A lista de organizações
+	 * @access public
+	 */
+	function getOrganizations()
+	{
+		return $this->ldap->getOrganizations();
+	}
+
+	/**
+	 * Busca as entidades (usuários, grupos ou listas públicas) de uma organização
+	 * @param array $params Array que contém parâmetros necessários para fazer a busca (podem ser advindos de Ajax)
+	 * @param bool $raw Se false, indica que os dados devem ser retornados em código HTML (via Ajax), se true indica que os dados devem ser retornados em forma de array
+	 * @return mixed A lista de entidades em formato de array ou em formato de string HTML para construção de combo box
+	 * @access public
+	 */
+	function getEntities($params, $raw = false)
+	{
+		if (preg_match('/^[a-z0-9_\- =,]+$/i', $params['context']) < 1)
+		{
+			if ($raw)
+				return array();
+			else
+				return '';
+		}
+
+		$id = ($params['id'] === 'mail') ? 'mail' : 'id';
+		$usePreffix = ($params['usePreffix'] == true) ? true : false;
+
+		$output = array();
+		$entities = $params['entities'];
+
+		/* se requisitado, carrega os usuários */
+		if (strpos($entities, 'u') !== false)
+		{
+			$preffix = ($usePreffix) ? 'u' : '';
+			$ents = $this->ldap->getUsers($params['context']);
+			foreach ($ents as $ent)
+				$output[$preffix . $ent[$id]] = $ent['name'];
+		}
+
+		/* se requisitado, carrega os grupos */
+		if (strpos($entities, 'g') !== false)
+		{
+			$preffix = ($usePreffix) ? 'g' : '';
+			$ents = $this->ldap->getGroups($params['context']);
+			foreach ($ents as $ent)
+				$output[$preffix . $ent[$id]] = $ent['name'];
+		}
+
+		/* se requisitado, carrega as listas públicas */
+		if (strpos($entities, 'l') !== false)
+		{
+			$preffix = ($usePreffix) ? 'l' : '';
+			$ents = $this->ldap->getPublicLists($params['context']);
+			foreach ($ents as $ent)
+				$output[$preffix . $ent[$id]] = $ent['name'];
+		}
+
+		if (!$raw)
+			$output = implode("\n", array_map(create_function('$a,$b', 'return \'<option value="\' . $a . \'">\' . $b . \'</option>\';'), array_keys($output), array_values($output)));
+
+		return $output;
+	}
+
+	/**
+	 * Busca os setores de um dado contexto
+	 * @param array $params Array que contém parâmetros necessários para fazer a busca (podem ser advindos de Ajax)
+	 * @param bool $raw Se false, indica que os dados devem ser retornados em código HTML (via Ajax), se true indica que os dados devem ser retornados em forma de array
+	 * @return mixed A lista de setores em formato de array ou em formato de string HTML para construção de combo box
+	 * @access public
+	 */
+	function getSectors($params, $raw = false)
+	{
+		if (preg_match('/^[a-z0-9_\- ]+$/i', $params['organization']) < 1)
+		{
+			if ($raw)
+				return array();
+			else
+				return array('sectors' => '', 'participants' => '');
+		}
+
+		$output = array('ou=' . $params['organization'] . ',' . $this->ldap->getLDAPContext() => $params['organization']);
+		$sectorList = $this->ldap->getSectors($params['organization'], true);
+		foreach ($sectorList as $sector)
+			$output[$sector['dn']] = str_repeat('&nbsp;', 3 * $sector['level']) . $sector['ou'];
+
+		if (!$raw)
+		{
+			$newOutput['sectors'] = implode("\n", array_map(create_function('$a,$b', 'return \'<option value="\' . $a . \'">\' . $b . \'</option>\';'), array_keys($output), array_values($output)));
+			reset($output);
+			$params['context'] = key($output);
+			$newOutput['participants'] = $this->getEntities($params, false);
+			$output = $newOutput;
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Efetua uma busca no catálogo LDAP (completo)
+	 * @param array $params Array que contém parâmetros necessários para fazer a busca (podem ser advindos de Ajax)
+	 * @param bool $raw Se false, indica que os dados devem ser retornados em código HTML (via Ajax), se true indica que os dados devem ser retornados em forma de array
+	 * @return mixed Os registros encontrados, em formato de array ou em formato de string HTML para construção de combo box
+	 * @access public
+	 */
+	function globalSearch($params, $raw = false)
+	{
+		$entities = $params['entities'];
+
+		$searchTerm = $params['searchTerm'];
+
+		if (strlen(str_replace(' ', '', $searchTerm)) < 3)
+			return array('warnings' => array('Utilize ao menos três caracteres em sua busca.'));
+
+		if (preg_match('/^[a-z0-9_\- =,]+$/i', $searchTerm) < 1)
+			return array('warnings' => array('O parâmetro de busca é inválido.'));
+
+		$searchTerm = '*' . str_replace(' ', '*', trim($searchTerm)) . '*';
+
+		$searchUsers = (strpos($entities, 'u') !== false);
+		$searchGroups = (strpos($entities, 'g') !== false);
+		$searchLists = (strpos($entities, 'l') !== false);
+
+		/* faz a busca */
+		$output = array();
+		$output['participants'] = $this->ldap->search($searchTerm, $searchUsers, $searchGroups, $searchLists);
+
+		/* limita os resultados e define uma mensagem que será exibida */
+		$participantsCount = count($output['participants']);
+		if ($participantsCount > 200)
+		{
+			$participantsCount = 200;
+			$output['participants'] = array_slice($output['participants'], 0, 200);
+			$output['warnings'][] = 'Sua busca foi limitada a 200 registros.';
+		}
+		else
+		{
+			if ($participantsCount === 0)
+				$output['warnings'][] = 'Nenhum registro encontrado.';
+			else
+				if ($participantsCount > 1)
+					$output['warnings'][] = $participantsCount . ' registros encontrados';
+
+		}
+
+		/* se necessário, gera a saída em formato HTML */
+		if (!$raw)
+		{
+			$id = ($params['id'] === 'mail') ? 'mail' : 'id';
+			$usePreffix = ($params['usePreffix'] == true) ? true : false;
+
+			$newOutput = array();
+			foreach ($output['participants'] as $row)
+			{
+				$organization = str_replace('ou=', '', implode('/', array_reverse(array_filter(explode(',', $row['dn']), create_function('$a', 'return (substr($a, 0, 2) == "ou");')))));
+				$key = ($usePreffix ? $row['type'] : '') . $row[$id];
+				$value = "{$row['name']} ({$organization})";
+				$newOutput[$key] = $value;
+			}
+
+			$newOutput = implode("\n", array_map(create_function('$a,$b', 'return \'<option value="\' . $a . \'">\' . $b . \'</option>\';'), array_keys($newOutput), array_values($newOutput)));
+			$output['participants'] = $newOutput;
+		}
+
+		return $output;
+	}
+}
Index: /sandbox/workflow/branches/993/inc/common.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/common.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/common.inc.php	(revision 2372)
@@ -0,0 +1,74 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Server base path. This constant is somewhat simililar to
+ * 'PHPGW_SERVER_ROOT'. Nevertheless, there are cases that we
+ * access Workflow directly and it must be defined somewhere.
+ * Recently discovered, when we are runnnig jobs HTTP_SERVER_VARS
+ * exported by apache are not available.
+ * Therefore, we are using this workaround here, setting
+ * EGW_SERVER_ROOT based on the location of this file. This constant
+ * should be updated properly every time we move this file.
+ * @name EGW_SERVER_ROOT
+ */
+define('EGW_SERVER_ROOT', dirname(dirname(dirname(__FILE__))));
+//define('EGW_SERVER_ROOT', $GLOBALS['HTTP_SERVER_VARS']['DOCUMENT_ROOT']);
+
+/**
+ * Server include base path. We must define our own constants
+ * because there are several cases in which workflow is called
+ * directly, thus PHPGW constants are not defined.
+ * @name EGW_INC_ROOT
+ */
+define('EGW_INC_ROOT', EGW_SERVER_ROOT . '/phpgwapi/inc/');
+
+/**
+ * Workflow base path.
+ * @name WF_SERVER_ROOT
+ */
+define('WF_SERVER_ROOT', EGW_SERVER_ROOT.'/workflow/');
+
+/**
+ * Workflow include path.
+ * @name WF_INC_ROOT
+ */
+define('WF_INC_ROOT', WF_SERVER_ROOT.'/inc/');
+
+/**
+ * Workflow lib base dir.
+ * @name WF_LIB_ROOT
+ */
+define('WF_LIB_ROOT', WF_SERVER_ROOT.'/lib/');
+
+
+if (file_exists(EGW_SERVER_ROOT . '/header.session.inc.php')) {
+	require_once EGW_SERVER_ROOT . '/header.session.inc.php';
+}
+
+
+/* assure that the correct encondig will be used (e.g string functions) */
+setlocale(LC_CTYPE, 'pt_BR', 'pt_BR.iso-8859-1', 'pt_BR.utf-8');
+
+
+/* define o umask para a criação de arquivos por parte do Workflow */
+umask(007);
+
+
+/* including common classes */
+require_once WF_LIB_ROOT . 'security/Security.php';
+require_once WF_LIB_ROOT . 'factory/Factory.php';
+require_once WF_LIB_ROOT . 'factory/BaseFactory.php';
+require_once WF_LIB_ROOT . 'factory/WorkflowFactory.php';
+require_once WF_LIB_ROOT . 'factory/ProcessFactory.php';
+
+$GLOBALS['workflow']['workflowObjects'] = Factory::getInstance('WorkflowObjects');
+?>
Index: /sandbox/workflow/branches/993/inc/class.utils.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.utils.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.utils.php	(revision 795)
@@ -0,0 +1,420 @@
+<?php
+/**
+ * Base utility class
+ * @author Carlos Eduardo Nogueira Goncalves
+ * @author Marcos Pont
+ * @version 1.0
+ * @link http://workflow.celepar.parana/doc-workflow/classes/utils Complete reference
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class Utils 
+{
+	/**
+	 * Include File
+	 * @param string $filePath
+	 * @param bool $return
+	 * @access public
+	 * @return bool
+	 */
+	function includeFile($filePath, $return=FALSE) 
+	{
+		if ($return === TRUE) {
+			return (include($filePath));
+		} 
+		else 
+		{
+			if (!@include($filePath)) 
+			{
+				return FALSE;
+			} 
+			else 
+			{
+				return TRUE;
+			}
+		}
+	}
+	
+	/**
+	 * Println 
+	 * @param $str
+	 * @param $nl
+	 * @access public
+	 * @return void
+	 */
+	function println($str, $nl='<br>') {
+		echo $str . $nl;
+	}	
+	
+	/**
+	 * Dump the $var Variable on screen
+	 * @param mixed $var
+	 */
+	function dumpVariable($var) {
+		print '<pre>';
+		var_dump($var);
+		print '</pre>';
+	}
+	/**
+	 * DumpArray
+	 * @param $arr
+	 * @param $stringLimit
+	 * @param deep
+	 */
+	function dumpArray($arr, $return=TRUE, $stringLimit=200, $deep=FALSE) {
+		$r = array();
+		foreach ($arr as $k => $v) {
+			if (is_string($v)) {
+				$r[] = $k . "=>'" . (strlen($v) > $stringLimit ? substr($v, 0, $stringLimit) . "...(" . strlen($v) . ")" : $v) . "'";
+			} elseif ($deep && (is_array($v) || is_object($v))) {
+				(is_object($v)) && ($v = get_object_vars($v));
+				$r[] = $k . '=>' . dumpArray($v, TRUE, $stringLimit, TRUE);
+			} else {
+				$r[] = $k . '=>' . $v;
+			}
+		}
+		if ($return)
+			return "[" . implode(", ", $r) . "]";
+		print "[" . implode(", ", $r) . "]";
+		return TRUE;
+	}
+	
+	/**
+	 * Export Variable
+	 * @param $var 
+	 * @param bool $formatted 
+	 * @access public
+	 * @return string
+	 */
+	function exportVariable($var, $formatted=FALSE) {
+		if (is_object($var) && !$this->isPHP(5) && method_exists($var, '__tostring'))
+			$export = $var->__toString();
+		else
+			$export = var_export($var, TRUE);
+		if ($formatted)
+			return '<pre>' . $export . '</pre>';
+		else
+			return $export;
+	}	
+	
+	
+	/**
+	 *
+	 * @param $var 
+	 * @param bool $formatted 
+	 * @access public
+	 * @return string
+	 */
+	function consumeArray(&$array, $key) {
+		if (is_array($array)) {
+			if (array_key_exists($key, $array)) {
+				$return = $array[$key];
+				unset($array[$key]);
+				return $return;
+			}
+		}
+		return NULL;
+	}	
+	
+	/**
+	 * Find Array path
+	 * @param  array  $arr 
+	 * @param  string $formatted
+	 * @param  string $separator
+	 * @param  string $fallback  
+	 * @access public
+	 * @return string
+	 */
+	function findArrayPath($arr, $path, $separator='.', $fallback=NULL) {
+		if (!is_array($arr))
+			return $fallback;
+		$parts = explode($separator, $path);
+		if (sizeof($parts) == 1) {
+			return (isset($arr[$path]) ? $arr[$path] : $fallback);
+		} else {
+			$i = 0;
+			$base = $arr;
+			$size = sizeof($parts);
+			while ($i < $size) {
+				if (!isset($base[$parts[$i]]))
+					return $fallback;
+				else
+					$base = $base[$parts[$i]];
+				if ($i < ($size-1) && !is_array($base))
+					return $fallback;
+				$i++;
+			}
+			return $base;
+		}
+	}	
+	
+	/**
+	 * isPHP
+	 * @param  int $num   
+	 * @access public
+	 * @return float
+	 */
+	function isPHP($num=5) {
+		return (floatval(PHP_VERSION) >= $num);
+	}	
+	
+	/**
+	 * uri
+	 * @param uri
+	 * @bool
+	 * 
+	 * @access public
+	 * @return string
+	 */
+	function uri($full=TRUE) {
+		if ($full) {
+			$protocol = $this->protocol();
+			$port = $this->get('SERVER_PORT');
+			if (($protocol == 'http' && $port != '80') || ($protocol == 'https' && $port != '443'))
+				$base = "{$protocol}://" . $this->serverName() . ":{$port}";
+			else
+				$base = "{$protocol}://" . $this->serverName();
+		} else {
+			$base = '';
+		}
+		if (!$requestUri = $this->get('REQUEST_URI')) {
+			if ($queryString = $this->get('QUERY_STRING'))
+				return $base . $this->scriptName() . '?' . $queryString;
+			else
+				return NULL;
+		}
+		$requestUri = preg_replace('#[?|&]' . session_name() . '=[^&|?]*#', '', $requestUri);
+		return $base . $requestUri;
+	}
+	
+	
+	/**
+	 * Return the protocol
+	 * @return string if isSecure returns true https else return http
+	 * @access public
+	 */
+	function protocol() {
+		if ($this->isSecure())
+			return 'https';
+		else
+			return 'http';
+	}	
+	
+	/**
+	 * Return if secure connection is required
+	 * @return bool https required or not 
+	 * @access public
+	 */
+	function isSecure() {
+		return (strtolower($this->get('HTTPS')) == 'on' || $this->has('SSL_PROTOCOL_VERSION'));
+	}
+	
+	/**
+	 * Return the script name
+	 * @return string script name
+	 * @access public
+	 */
+	function scriptName() {
+		return $this->get('SCRIPT_NAME');
+	}	
+	
+	/**
+	 * Return the server name
+	 * @return string server Name
+	 * @access public
+	 */	
+	function serverName() {
+		return $this->get('SERVER_NAME');
+	}
+	
+	/**
+	 * Return Environment variable
+	 * @return enviroment variable
+	 * @access public
+	 */	
+	function get($key) {
+		if (isset($_SERVER[$key])) {
+			return $_SERVER[$key];
+		}
+		if (@getenv($key))
+			return getenv($key);
+		else
+			return NULL;
+	}	
+	
+	/**
+	 * Check if the value of variable is NULL
+	 * @param mixed $value value 
+	 * @param bool  $strict  strict true compares the type and value 
+	 * @access public
+	 */
+	function isNull($value, $strict = FALSE) {
+		return ($strict) ? (NULL === $value) : (NULL == $value);
+	}
+	
+	/**
+	 * Get the string value of variable
+	 * @param mixed $value
+	 * @access public
+	 * @return string 
+	 */
+	function parseString($value) {
+		return strval($value);
+	}	
+	
+	/**
+	 * Checks if $value is false
+	 * @param mixed $value
+	 * @return bool true if is a boolean and false 
+	 */
+	function isFalse($value) {
+		return ($value === FALSE);
+	}
+	
+	/**
+	 * Checks if $value is false
+	 * @param string $str
+	 * @param $chars 
+	 * @return string
+	 * @access public
+	 *  
+	 */
+	function left($str, $chars = 0) {
+		if (!$this->isInteger($chars)) {
+			return $str;
+		} else if ($chars == 0) {
+			return '';
+		} else {
+			return substr($str, 0, $chars);
+		}
+	}	
+	
+	/**
+	 * Checks if $value is a integer
+	 * @param string $value
+	 * @param $chars 
+	 * @return string
+	 * @access public 
+	 */
+	function isInteger(&$value, $strict=FALSE) {
+		$exp = "/^\-?[0-9]+$/";
+		if (preg_match($exp, $value)) {
+			if (!$strict && !is_int($value)) {
+				$value = $this->parseInteger($value);
+			}
+			return TRUE;
+		} else {
+			return FALSE;
+		}
+	}	
+	
+	/**
+	 * Get the integer value of variable
+	 * @param $value integer value
+	 * @access public
+	 */
+	function parseInteger($value) {
+		return intval($value);
+	}	
+	
+	/**
+	 * Return the positive integer value of variable 
+	 * @param mixed $value
+	 * @return int 
+	 * @access public
+	 */
+	function parseIntegerPositive($value) {
+		return abs(intval($value));
+	}
+	
+	/**
+	 * Returns a random number 
+	 * @param int $rangeMin
+	 * @param int $rangeMax
+	 * @return string
+	 * @access public
+	 */
+	function randomize($rangeMin, $rangeMax) {
+		if ($rangeMax > $rangeMin && is_numeric($rangeMin) && is_numeric($rangeMax)) {
+			return rand($rangeMin, $rangeMax);
+		} else {
+			return NULL;
+		}
+	}	
+	
+	/** 
+	 * Return a $default value if the first parameter is NULL else returns the first parameter 
+	 * 
+	 * @param mixed $value   first parameter
+	 * @param mixed $default default value to return if $value == NULL
+	 * @access public
+	 * @return mixed  
+	 */
+	
+	function ifNull($value, $default = NULL) {
+		if ($value === NULL)
+			return $default;
+		return $value;
+	}	
+	
+	/**
+	 * Return the javascript code for a anchor
+	 * 
+	 * @param string $url     base url
+	 * @param string $text    
+	 * @param string $statusBarText
+	 * @param string $cssClass
+	 * @param array $jsEvents
+	 * @param string $target
+	 * @param string $name
+	 * @param string $id
+	 * @param string $rel
+	 * @param string $accessKey
+	 * 
+	 * @param array $jsEvents
+	 * 
+	 * @return string javascript code
+	 * @access public
+	 */
+	 function anchor($url, $text, $statusBarText='', $cssClass='', $jsEvents=array(), $target='', $name='', $id='', $rel='', $accessKey='') 
+	 {
+		if (empty($url))
+			$url = "javascript:void(0);";
+		$scriptStr = '';
+		if (!empty($jsEvents) && $statusBarText != "") {
+			$jsEvents['onMouseOver'] = (isset($jsEvents['onMouseOver']) ? $jsEvents['onMouseOver'] . "window.status='$statusBarText';return true;" : "window.status='$statusBarText';return true;");
+			$jsEvents['onMouseOut'] = (isset($jsEvents['onMouseOut']) ? $jsEvents['onMouseOut'] . "window.status='';return true;" : "window.status='';return true;");
+		} else if ($statusBarText) {
+			$scriptStr .= "onMouseOver=\"window.status='$statusBarText';return true;\" onMouseOut=\"window.status='';return true;\"";
+		}
+		foreach ($jsEvents as $event => $action)
+			$scriptStr .= " $event=\"" . ereg_replace("\"", "'", $action) . "\"";
+		return sprintf("<a href=\"%s\"%s%s%s%s%s%s%s%s>%s</a>", htmlentities($url),
+			(!empty($name) ? " name=\"{$name}\"" : ""),
+			(!empty($id) ? " id=\"{$id}\"" : ""),
+			(!empty($rel) ? " rel=\"{$rel}\"" : ""),
+			(!empty($accessKey) ? " accesskey=\"{$accessKey}\"" : ""),
+			(!empty($target) ? " target=\"{$target}\"" : ""),
+			(!empty($cssClass) ? " class=\"{$cssClass}\"" : ""),
+			(!empty($statusBarText) ? " title=\"{$statusBarText}\"" : ""),
+			(!empty($scriptStr) ? " {$scriptStr}" : ""),
+			$text);
+	}	
+	
+	/**
+	 * Return a error message 
+	 * @param string $msg
+	 * @param string $file
+	 * @param string $line
+	 * 
+	 * @return void 
+	 * @access public 
+	 */
+	function raiseError($msg = 'Erro', $file = __FILE__, $line = __LINE__)
+	{
+		ini_set('display_errors', true);
+		error_reporting(E_ALL);
+		trigger_error("$file ($line): $msg", E_USER_ERROR);
+	}	
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.crontab.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.crontab.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.crontab.inc.php	(revision 795)
@@ -0,0 +1,236 @@
+<?
+/**
+ * Creates cron jobs
+ * @author Carlos Eduardo Nogueira Gonçalves
+ * @author	Richard Sumilang <richard@richard-sumilang.com>
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class Crontab {
+	
+	/**
+	 * @var int $minute Minute(s)... 0 to 59
+	 * @access public
+	 */
+	var $minute      = null;
+	/**
+	 * @var int $hour $hour Hour(s)... 0 to 23 
+	 * @access public
+	 */	
+	var $hour        = null;
+	/**
+	 * @var int $day day Day(s)... 1 to 31
+	 * @access public
+	 */
+	var $day         = null;
+	/**
+	 * @var int $month month Month(s)... 1 to 12 or short name
+	 * @access public
+	 */	
+	var $month       = null;
+	/**
+	 * @var int $dayofweek dayofweek Day(s) of week... 0 to 7 or short name. 0 and 7 = sunday
+	 * @access public
+	 */	
+	var $dayofweek   = null;
+	/**
+	 * @var string $command Comand to set
+	 * @access public
+	 */		
+	var $command     = null;
+	/**
+	 * @var string $directory Directory to hold cron job files
+	 * @access public
+	 */	
+	var $directory   = null;
+	/**
+	 * @var string $filename Filename to write to
+	 * @access public
+	 */	
+	var $filename    = 'crons';
+	/**
+	 * @var string $crontabPath Path to cron program
+	 * @access public
+	 */	
+	var $crontabPath = null; 
+	/**
+	 * @var mixed $handle Resource handle to the file
+	 * @access public
+	 */	
+	var $handle      = null;
+
+	/**
+	 *	Attempts to create directory for holding cron jobs
+	 *	@param	string	$dir		 Directory to hold cron job files
+	 *	@param	string	$filename	 Filename to write to
+	 *	@param	string	$crontabPath Path to cron program
+	 *	@access public
+	 */
+	function Crontab($dir = null, $filename = null, $crontabPath = null) {
+		$result = (!$dir) ? $this->setDirectory("~/my_crontabs") : $this->setDirectory($dir);
+		if (!$result) {
+			exit('Directory error');
+		}			
+		$result = (!$filename) ? $this->createCronFile("crons") : $this->createCronFile($filename);
+		if (!$result) {
+			exit('File error');
+		}			
+		$this->pathToCrontab = ($crontabPath) ? null : $crontabPath;
+	}
+
+	/**
+	 * Sets date parameters.
+	 * If any parameters are left null then they default to *.
+	 * A hyphen (-) between integers specifies a range of integers. For example, 1-4 means the integers 1, 2, 3, and 4. 
+	 * A list of values separated by commas (,) specifies a list. For example, 3, 4, 6, 8 indicates those four specific integers.
+	 * The forward slash (/) can be used to specify step values. The value of an integer can be skipped within a range by following the range
+	 * with /<integer>. For example, 0-59/2 can be used to define every other minute in the minute field. Step values can also be used with an asterisk.
+	 * For instance, the value * /3 (no space) can be used in the month field to run the task every third month.
+	 *	@param	mixed	$min		Minute(s)... 0 to 59
+	 *	@param	mixed	$hour		Hour(s)... 0 to 23
+	 *	@param	mixed	$day		Day(s)... 1 to 31
+	 *	@param	mixed	$month		Month(s)... 1 to 12 or short name
+	 *	@param	mixed	$dayofweek	Day(s) of week... 0 to 7 or short name. 0 and 7 = sunday
+	 *	$acccess public
+	 */
+	function setDateParams($min = null, $hour = null, $day = null, $month = null, $dayofweek = null) {		
+		if ($min == "0")
+			$this->minute = 0;
+		elseif ($min)
+			$this->minute = $min;
+		else
+			$this->minute = "*";
+		
+		if ($hour == "0")
+			$this->hour = 0;
+		elseif ($hour)
+			$this->hour = $hour;
+		else
+			$this->hour = "*";
+		$this->month = ($month) ? $month : "*";
+		$this->day = ($day) ? $day : "*";
+		$this->dayofweek = ($dayofweek) ? $dayofweek : "*";		
+	}
+
+	/**
+	 * Sets the directory path
+	 * Will check it if it exists then try to open it. Also if it doesn't exist then it will try to create it, makes it with mode 0700
+	 * @param string $directory	Directory, relative or full path
+	 * @access public
+	 * @return boolean
+	 */
+	function setDirectory($directory) {
+		if (!$directory) {
+			return false;	
+		}		
+		if(is_dir($directory)) {
+			if ($dh = opendir($directory)) {
+				$this->directory = $directory;
+				return true;
+			} else {
+				return false;
+			}				
+		} else {
+			if (mkdir($directory, 0700)){
+				$this->directory = $directory;
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+	/**
+	 * Creates cron file
+	 * This will create a cron job file for you and set the filename 
+	 * of this class to use it. Make sure you have already set the directory
+	 * path variable with the consructor. If the file exists and we can write
+	 * it then return true esle false. Also sets $handle with the resource handle
+	 * to the file
+	 * @param string $filename	Name of file you want to create
+	 * @access public
+	 * @return boolean
+	 */
+	function createCronFile($filename = null) {
+		if (!$filename) {
+			return false;
+		}		
+		if (file_exists($this->directory . $filename)) {
+			if ($handle = fopen($this->directory . $filename, 'a')) {
+				$this->handle =& $handle;
+				$this->filename = $filename;
+				return true;
+			} else {
+				return false;
+			}				
+		}		
+		if (!$handle = fopen($this->directory . $filename, 'a')) {
+			return false;
+		} else {
+			$this->handle =& $handle;
+			$this->filename = $filename;
+			return true;
+		}
+	}
+
+	/**
+	 * Sets command to execute
+	 * @param string $command Comand to set
+	 * @access public
+	 * @return bool 
+	 */
+	function setCommand($command) {
+		if ($command) {
+			$this->command = $command;
+			return false;
+		} else {
+			return false;
+		}			
+	}
+
+	/**
+	 *	Write cron command to file. Make sure you used createCronFile
+	 *	before using this function of it will return false
+	 *
+	 *	@access	public
+	 *	@return	bool
+	 */
+	function saveCronFile() {
+		$command = 
+		$this->minute . " " . 
+		$this->hour . " " . 
+		$this->day . " "  . 
+		$this->month . " " . 
+		$this->dayofweek . " " . 
+		$this->command . "\n";
+		if (!fwrite($this->handle, $command)) {
+			return true;
+		} else {
+			return false;
+		}			
+	}
+
+	/**
+	 *	Saves cron in system
+	 *	@access public
+	 *	@return void
+	 */
+	function addToCrontab() {		
+		if (!$this->filename) {
+			exit('No name specified for cron file');
+		}	
+		exec($this->crontabPath . "crontab " . $this->directory . $this->filename);
+	}
+
+	/**
+	 *	Destroys file pointer
+	 *	@access public
+	 *	@return boolean
+	 */
+	function destroyFilePoint() {
+		fclose($this->handle);
+		return true;
+	}
+}		
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_adminroles.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_adminroles.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_adminroles.inc.php	(revision 2372)
@@ -0,0 +1,363 @@
+<?php
+require_once(dirname(__FILE__) . SEP . 'class.WorkflowUtils.inc.php');
+require_once('engine' . SEP . 'config.egw.inc.php');
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ui_adminroles extends WorkflowUtils
+{
+	/**
+	 * @var array $public_functions public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'form'	=> true
+	);
+
+	/**
+	 * @var object $process_manager Process manager object
+	 * @access public
+	 */
+	var $process_manager;
+	/**
+	 * @var object $activity_manager Activity manager object
+	 * @access public
+	 */
+	var $activity_manager;
+
+	/**
+	 * @var array $workflow_acl
+	 * @access public
+	 */
+	var $workflow_acl;
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_adminroles()
+	{
+		parent::WorkflowUtils();
+
+		$this->workflow_acl = Factory::getInstance('workflow_acl');
+		$denyAccess = true;
+		if ($this->workflow_acl->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']))
+		{
+			/* the user is an Expresso/Workflow admin */
+			$denyAccess = false;
+		}
+		else
+		{
+			if ($GLOBALS['phpgw']->acl->check('admin_workflow', 1, 'workflow'))
+			{
+				/* check if the user can admin the informed process */
+				if ($this->wf_p_id != 0)
+					$denyAccess = !$this->workflow_acl->check_process_access($GLOBALS['phpgw_info']['user']['account_id'], $this->wf_p_id);
+				else
+					$denyAccess = false;
+			}
+		}
+
+		if ($denyAccess)
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		$this->process_manager	= Factory::getInstance('workflow_processmanager');
+		$this->activity_manager	= Factory::getInstance('workflow_activitymanager');
+		$this->role_manager	= Factory::getInstance('workflow_rolemanager');
+		$this->form_action = $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminroles.form');
+		
+	}
+	/**
+	 * Show the adminroles form
+	 * @access public
+	 * @return void
+	 */
+	function form()
+	{
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('Admin Process Roles');
+		$GLOBALS['phpgw']->common->phpgw_header();
+		echo parse_navbar();
+
+		$this->t->set_file('admin_roles', 'admin_roles.tpl');
+
+		$this->order		= get_var('order', 'GET', 'wf_name');
+		$this->sort			= get_var('sort', 'GET', 'asc');
+		$this->sort_mode	= $this->order . '__'. $this->sort;
+		$sort_mode2			= get_var('sort_mode2', 'any', 'wf_name__asc');
+		$role_id				= (int)get_var('role_id', 'any', 0);
+
+		if (!$this->wf_p_id) die(lang('No process indicated'));
+		
+		//do we need to check validity, warning high load on database
+		$checkvalidity=false;
+
+		// save new role
+		if (isset($_POST['save']))
+		{
+			$this->save_role($role_id, $_POST['name'], $_POST['description']);
+			$checkvalidity = true;
+		}
+
+		// save new mapping
+		if (isset($_POST['save_map']))
+		{
+			$this->save_mapping($_POST['user'], $_POST['role']);
+			$this->message[] = lang('New mapping added');
+			$checkvalidity = true;
+		}
+
+		// delete roles
+		if (isset($_POST['delete_roles']))
+		{
+			$this->delete_roles(array_keys($_POST['role']));
+			$checkvalidity = true;
+		}
+		
+		// delete mappings
+		if (isset($_POST['delete_map'])) 
+		{
+			$this->delete_maps(array_keys($_POST['map']));
+		}
+
+		// retrieve process info
+		$proc_info = $this->process_manager->get_process($this->wf_p_id);
+
+		// check process validity and show errors if necessary
+		if ($checkvalidity) $proc_info['isValid'] = $this->show_errors($this->activity_manager, $error_str);
+
+		// fill proc_bar
+		$this->t->set_var('proc_bar', $this->fill_proc_bar($proc_info));
+		
+		// retrieve role info
+		if ($role_id || isset($_POST['new_role']))
+		{
+			$role_info = $this->role_manager->get_role($this->wf_p_id, $_GET['role_id']);
+		}
+		else
+		{
+			$role_info = array(
+				'name'			=> '',
+				'description'	=> '',
+				'role_id'		=> 0
+			);
+		}
+
+		// retrieve all roles info
+		$all_roles = $this->role_manager->list_roles($this->wf_p_id, 0, -1, 'wf_name__asc', '');
+		//echo "all_roles: <pre>";print_r($all_roles);echo "</pre>";
+		
+		//collect some messages from used objects
+		$this->message[] = $this->activity_manager->get_error(false, _DEBUG);
+		$this->message[] = $this->process_manager->get_error(false, _DEBUG);
+		$this->message[] = $this->role_manager->get_error(false, _DEBUG);
+
+
+		// fill the general varibles of the template
+		$this->t->set_var(array(
+			'message'				=> implode('<br>', array_filter($this->message)),
+			'errors'				=> $error_str,
+			'form_action_adminroles'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminroles.form'),
+			'role_info_role_id'		=> $role_info['wf_role_id'],
+			'role_info_name'		=> $role_info['wf_name'],
+			'role_info_description'	=> $role_info['wf_description'],
+			'p_id'					=> $this->wf_p_id,
+			'start'					=> $this->start,
+		));
+
+		$this->show_process_roles_list($all_roles['data']);
+
+		// build users and roles multiple select boxes
+		$this->show_users_roles_selects($all_roles['data']);
+
+		// retrieve and show mappings
+		$this->show_mappings();
+
+		$this->translate_template('admin_roles');
+		$this->t->pparse('output', 'admin_roles');
+		$GLOBALS['phpgw']->common->phpgw_footer();
+	}
+	/**
+	 * Save role
+	 * @param int $role_id role identifier
+	 * @param string $name role name
+	 * @param string $description role description
+	 * @access public
+	 * @return void
+	 */
+	function save_role($role_id, $name, $description)
+	{
+		$vars = array(
+			'wf_name'			=> $name,
+			'wf_description'	=> $description,
+		);
+		if ($this->role_manager->replace_role($this->wf_p_id, $role_id, $vars))
+		{
+			$this->message[] = lang('Role saved');
+		}
+		else
+		{
+			$this->message[] = lang('Role not saved (maybe a name collision)');
+		}
+		
+	}
+ 	/**
+ 	 * Delet selected roles
+ 	 * @param array $roles_ids 
+ 	 * @access public
+ 	 * @return void
+ 	 */
+	function delete_roles($roles_ids)
+	{
+		foreach ($roles_ids as $role_id)
+		{
+			$this->role_manager->remove_role($this->wf_p_id, $role_id);
+		}
+		$this->message[] = lang('Roles deleted');
+	}
+	/**
+	 * Delete mappings
+	 * @param array $mappings
+	 * @return void
+	 * @access public
+	 */
+	function delete_maps($mappings)
+	{
+					foreach($mappings as $map)
+					{
+								 $pos = strpos($map,":::");
+								 $user=substr($map,0,$pos);
+								 $role_id=substr($map,$pos+3);
+								 $this->role_manager->remove_mapping($user,$role_id);
+					}
+		$this->message[] = lang('Mappings deleted');
+	}
+	/**
+	 * Show mappings
+	 * @return void
+	 * @access public
+	 */
+	function show_mappings()
+	{
+		$this->t->set_block('admin_roles', 'block_list_mappings', 'list_mappings');
+		$mappings = $this->role_manager->list_mappings($this->wf_p_id, $this->start, -1, $this->sort_mode, '');
+		//echo "mappings: <pre>";print_r($mappings);echo "</pre>";
+		if (!count($mappings['data'])) {
+			$this->t->set_var('list_mappings', '<tr><td colspan="3" align="center">'. lang('There are no mappings defined for this process')  .'</td></tr>');
+		}
+		else {
+			/* load the LDAP information */
+			$cachedLDAP = Factory::getInstance('CachedLDAP');
+			$tmpLDAP = &Factory::getInstance('WorkflowLDAP');
+			$userContext  = $tmpLDAP->getUserContext();
+			$groupContext = $tmpLDAP->getGroupContext();
+
+			foreach ($mappings['data'] as $mapping)
+			{
+				if ($mapping['wf_account_type'] == 'g') {
+					$sri = ldap_search(Factory::getInstance('WorkflowObjects')->getLDAP(),
+									$groupContext,
+									'(&(gidnumber=' . (int)$mapping['wf_user'] . ')(phpgwAccountType=g))');
+
+					$allValues = ldap_get_entries(Factory::getInstance('WorkflowObjects')->getLDAP(), $sri);
+
+					$cname = $GLOBALS['phpgw']->translation->convert($allValues[0]['cn'][0],'utf-8');
+					$glabel = '[' . lang('Group') . ']';
+				}
+				else {
+					$entry = $cachedLDAP->getEntryByID($mapping['wf_user']);
+					$cname = $GLOBALS['phpgw']->translation->convert($entry['cn'],'utf-8');
+					$glabel = "";
+					if (is_null($entry['last_update']))
+						$glabel = '<font color="red">(excluído)</font>';
+				}
+
+				$this->t->set_var(array(
+					'map_user_id'	=> $mapping['wf_user'],
+					'map_role_id'	=> $mapping['wf_role_id'],
+					'map_role_name'	=> $mapping['wf_name'],
+					'map_user_name'	=> $cname . ' ' . $glabel,
+				));
+				$this->t->parse('list_mappings', 'block_list_mappings', true);
+			}
+		}
+	}
+	/**
+	 * Save mapping
+	 * @param array users list of users
+	 * @param array $roles list of roles
+	 * @access public
+	 * @return void
+	 */
+	function save_mapping($users, $roles)
+	{
+		foreach ($users as $user)
+		{
+			$account_type   = $user{0};
+			$user           = substr($user, 1);
+			foreach ($roles as $role)
+			{
+				$this->role_manager->map_user_to_role($this->wf_p_id, $user, $role, $account_type);
+			}
+		}
+	}
+	/**
+	 * Show users roles selects
+	 * @param string $all_roles_data
+	 * @return
+	 */
+	function show_users_roles_selects($all_roles_data)
+	{
+		$templateServer = &Factory::getInstance('TemplateServer');
+		$imgaddusers = $templateServer->generateImageLink('add_group.png');
+		$imgdelusers = $templateServer->generateImageLink('delete_group.png');
+
+		$this->t->set_var(array(
+			'src_img_add_users' => $imgaddusers,
+			'src_img_del_users' => $imgdelusers
+		));
+
+		$this->t->set_block('admin_roles', 'block_select_roles', 'select_roles');
+		foreach ($all_roles_data as $role)
+		{
+			$this->t->set_var(array(
+				'select_role_id'	=> $role['wf_role_id'],
+				'select_role_name'	=> $role['wf_name']
+			));
+			$this->t->parse('select_roles', 'block_select_roles', true);
+		}
+	}
+	/**
+	 * Show process roles list
+	 * @param array $all_roles_data
+	 * @return void
+	 */
+	function show_process_roles_list($all_roles_data)
+	{
+		$this->t->set_block('admin_roles', 'block_process_roles_list', 'process_roles_list');
+		$this->translate_template('block_process_roles_list');
+
+		foreach ($all_roles_data as $role)
+		{
+			$this->t->set_var(array(
+				'all_roles_role_id'		=> $role['wf_role_id'],
+				'all_roles_href'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminroles.form&sort_mode='. $this->sort_mode .'&start='. $this->start .'&find='. $find .'&p_id='. $this->wf_p_id .'&sort_mode2='. $sort_mode2 .'&role_id='. $role['wf_role_id']),
+				'all_roles_name'		=> $role['wf_name'],
+				'all_roles_description'	=> $role['wf_description'],
+				'color_line'			=> $this->nextmatchs->alternate_row_color($tr_color),
+			));
+			$this->t->parse('process_roles_list', 'block_process_roles_list', true);
+		}
+		if (!count($all_roles_data)) $this->t->set_var('process_roles_list', '<tr><td colspan="3">'. lang('There are no roles defined for this process') .'</td></tr>');
+
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_resourceeditor.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_resourceeditor.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.ui_resourceeditor.inc.php	(revision 795)
@@ -0,0 +1,27 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once dirname(__FILE__) . SEP . 'class.ui_phpeditor.inc.php';
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ */
+class ui_resourceeditor extends ui_phpeditor
+{
+	protected function loadVariables()
+	{
+		$this->HTMLFile = 'reseditor.html';
+		$this->type = 'res';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowUtils.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowUtils.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowUtils.inc.php	(revision 2372)
@@ -0,0 +1,413 @@
+<?php
+	require_once 'common.inc.php';
+
+	//set here the global DEBUG level which is actually 0 (nothing) or 1 (all)
+	if (!defined('_DEBUG')) define('_DEBUG', 0);
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class WorkflowUtils
+	{
+		/**
+		 * @var array $public_functions Array of public functions
+		 * @access public
+		 */
+		var $public_functions = array(
+			'export'	=> true,
+		);
+		/**
+		 * @var object $t the template 
+		 * @access public
+		 */
+		var $t;		
+		/**
+		 * @var int wf_p_id  
+		 * @access public
+		 */
+		var $wf_p_id;
+		/**
+		 * @var array $message message array 
+		 * @access public
+		 */
+		var $message = array();
+
+		//TODO: when migration to bo_workflow_forms will be closed erase theses vars--------------
+		//nextmatchs (max number of rows per page) and associated vars
+		
+		/**
+		 * @var int $nextmatchs 
+		 * @access public
+		 */
+		var $nextmatchs;
+		
+		/**
+		 * @var int $start actual starting row number
+		 * @access public
+		 */
+		var $start; 
+		/**
+		 * @var int $total_records total number of rows 
+		 * @access public
+		 */
+		var $total_records; 
+		/**
+		 * @var array $message message array column used for order 
+		 * @access public
+		 */
+		var $order; 
+		/**
+		 * @var string $sort ASC or DESC 
+		 * @access public
+		 */
+		var $sort; 
+		/**
+		 * @var array $sort_mode combination of order and sort   
+		 * @access public
+		 */
+		var $sort_mode; 
+		/**
+		 * @var array $search_str  
+		 * @access public
+		 */
+		var $search_str;
+		//------------------------------------------------------------------------------------------
+		/**
+		 * @var array $stats
+		 * @access public
+		 */
+		var $stats;
+		/**
+		 * @var array $wheres 
+		 * @access public
+		 */
+		var $wheres = array();
+
+		/**
+		 * Constructor of workflow class
+		 *  
+		 * @access public
+		 * @return void
+		 */
+		function WorkflowUtils()
+		{
+			// check version
+			if (alessthanb($GLOBALS['phpgw_info']['apps']['workflow']['version'], '1.2.01.006'))
+			{
+				$GLOBALS['phpgw']->common->phpgw_header();
+				echo parse_navbar();
+				die("Please upgrade this application to be able to use it");
+			}
+
+			$this->t		=& $GLOBALS['phpgw']->template;
+			$this->wf_p_id		= (int)get_var('p_id', 'any', 0);
+			$this->start		= (int)get_var('start', 'any', 0);
+			$this->search_str	= get_var('find', 'any', '');
+			$this->nextmatchs	= Factory::getInstance('nextmatchs');
+		}
+
+		/**
+		 * Fill the process bar
+		 *
+		 * @param array $proc_info
+		 * @access public
+		 * @return string
+		 */
+		function fill_proc_bar($proc_info)
+		{
+			//echo "proc_info: <pre>";print_r($proc_info);echo "</pre>";
+			$this->t->set_file('proc_bar_tpl', 'proc_bar.tpl');
+			$templateServer = &Factory::getInstance('TemplateServer');
+
+			if ($proc_info['wf_is_valid'] == 'y')
+			{
+				$dot_color = 'green';
+				$alt_validity = lang('valid');
+			}
+			else
+			{
+				$dot_color = 'red';
+				$alt_validity = lang('invalid');
+			}
+
+			// if process is active show stop button. Else show start button, but only if it is valid. If it's not valid, don't show any activation or stop button.
+			if ($proc_info['wf_is_active'] == 'y')
+			{
+				$start_stop = '<td><a href="'. $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form&p_id='. $proc_info['wf_p_id'] .'&deactivate_proc='. $proc_info['wf_p_id']) .'"><img border ="0" src="'. $templateServer->generateImageLink('stop.gif') .'" alt="'. lang('stop') .'" title="'. lang('stop') .'" />'.lang('stop').'</a></td>';
+			}
+			elseif ($proc_info['wf_is_valid'] == 'y')
+			{
+				$start_stop = '<td><a href="'. $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form&p_id='. $proc_info['wf_p_id'] .'&activate_proc='. $proc_info['wf_p_id']) .'"><img border ="0" src="'. $templateServer->generateImageLink('refresh2.gif') .'" alt="'. lang('activate') .'" title="'. lang('activate') .'" />'.lang('activate').'</a></td>';
+			}
+			else
+			{
+				$start_stop = '';
+			}
+			$this->t->set_var(array(
+				'proc_name'				=> $proc_info['wf_name'],
+				'version'				=> $proc_info['wf_version'],
+				'img_validity'			=> $templateServer->generateImageLink($dot_color.'_dot.gif'),
+				'alt_validity'			=> $alt_validity,
+				'start_stop'			=> $start_stop,
+				'link_admin_activities'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form&p_id='. $proc_info['wf_p_id']),
+				'img_activity'			=> $templateServer->generateImageLink('Activity.gif'),
+				'link_admin_jobs'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminjobs.form&p_id='. $proc_info['wf_p_id']),
+				'img_job'			=> $templateServer->generateImageLink('clock.png'),
+				'link_admin_processes'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminprocesses.form&p_id='. $proc_info['wf_p_id']),
+				'img_change'			=> $templateServer->generateImageLink('change.gif'),
+				'link_admin_shared_source'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminsource.form&p_id='. $proc_info['wf_p_id']),
+				'img_code'			=> $templateServer->generateImageLink('code.png'),
+				'link_admin_export'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.WorkflowUtils.export&p_id='. $proc_info['wf_p_id']),
+				'link_admin_roles'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminroles.form&p_id='. $proc_info['wf_p_id']),
+				'img_roles'			=> $templateServer->generateImageLink('roles.png'),
+				'link_graph'			=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.show_graph&p_id=' . $proc_info['wf_p_id']),
+				'img_process'			=> $templateServer->generateImageLink('Process.gif'),
+				'link_save_process'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminprocesses.save_process&id='. $proc_info['wf_p_id']),
+				'img_save'			=> $templateServer->generateImageLink('save.png')
+			));
+
+			$this->translate_template('proc_bar_tpl');
+			return $this->t->parse('proc_bar', 'proc_bar_tpl');
+		}
+		/**
+		 * Select activity representation icon
+		 *
+		 * @var string $type type of activity
+		 * @var bool   $interactive interactive?
+		 * @access public
+		 * @return void
+		 */
+		function act_icon($type, $interactive)
+		{
+			switch($type)
+			{
+				case 'activity':
+					$ic = "mini_".(($interactive == 'y')? 'blue_':'')."rectangle.gif";
+					break;
+				case 'switch':
+					$ic = "mini_".(($interactive == 'y')? 'blue_':'')."diamond.gif";
+					break;
+				case 'start':
+					$ic="mini_".(($interactive == 'y')? 'blue_':'')."circle.gif";
+					break;
+				case 'end':
+					$ic="mini_".(($interactive == 'y')? 'blue_':'')."dbl_circle.gif";
+					break;
+				case 'split':
+					$ic="mini_".(($interactive == 'y')? 'blue_':'')."triangle.gif";
+					break;
+				case 'join':
+					$ic="mini_".(($interactive == 'y')? 'blue_':'')."inv_triangle.gif";
+					break;
+				case 'standalone':
+					$ic="mini_".(($interactive == 'y')? 'blue_':'')."hexagon.gif";
+					break;
+				case 'view':
+					$ic="mini_blue_eyes.gif";
+					break;
+				default:
+					$ic="no-activity.gif";
+			}
+			return '<img src="'. Factory::getInstance('TemplateServer')->generateImageLink($ic) .'" alt="'. lang($type) .'" title="'. lang($type) .'" />';
+		}
+
+		/**
+		 * Translate template file
+		 * @param string $template_name template name
+		 * @return void
+		 * @access public
+		 */
+		function translate_template($template_name)
+		{
+			$undef = $this->t->get_undefined($template_name);
+			if ($undef != False)
+			{
+				foreach ($undef as $value)
+				{
+					$valarray = explode('_', $value);
+					$type = array_shift($valarray);
+					$newval = implode(' ', $valarray);
+					if ($type == 'lang')
+					{
+						$this->t->set_var($value, lang($newval));
+					}
+				}
+			}
+		}
+		/**
+		 * Show errors
+		 * @param object $activity_manager
+		 * @param string $error_str destination string to place errors
+		 * @return bool
+		 * @access public 
+		 */
+		function show_errors(&$activity_manager, &$error_str)
+		{
+			$valid = $activity_manager->validate_process_activities($this->wf_p_id);
+			$errors = $activity_manager->get_error(true);
+			$warnings = $activity_manager->get_warning(true);
+			$tmp = array();
+
+			/* remove empty errors from the error list */
+			foreach ($errors as $index => $error)
+				if (trim($error) == '')
+					unset($errors[$index]);
+
+			if ((count($warnings) > 0) || (count($errors) > 0))
+			{
+				$error_str = '';
+				$output = 'y';
+				if (count($errors) > 0)
+				{
+					$error_str = '<b>' . lang('The following items must be corrected to be able to activate this process').':</b><br/><small><ul>';
+					foreach ($errors as $error)
+					{
+						$error_str .= '<li>'. $error . '<br/>';
+					}
+					$error_str .= '</ul></small>';
+					$output = 'n';
+				}
+
+				if (count($warnings) > 0)
+				{
+					if ($error_str != '')
+						$error_str .= "<br />";
+
+					$error_str .= '<b>' . lang('warnings in this process').':</b><br/><small><ul>';
+					foreach ($warnings as $warning)
+						if (trim($warning) != '')
+							$error_str .= '<li>'. $warning . '<br/>';
+
+					$error_str .= '</ul></small>';
+				}
+				return $output;
+			}
+			else
+			{
+				$error_str = '';
+				return 'y';
+			}
+		}
+		
+		/**
+		 * Get source code
+		 * @param string $proc_name process name 
+		 * @param string $act_name activity name
+		 * @param string $type actyvity type
+		 * @access public
+		 * @return string source code dat
+		 */
+		function get_source($proc_name, $act_name, $type)
+		{
+			switch($type)
+			{
+				case 'code':
+					$path =  'activities' . SEP . $act_name . '.php';
+					break;
+				case 'template':
+					$path = 'templates' . SEP . $act_name . '.tpl';
+					break;
+				default:
+					$path = 'shared.php';
+					break;
+			}
+			$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+												if (!$file_size = filesize($complete_path)) return '';
+			$fp = fopen($complete_path, 'r');
+			$data = fread($fp, $file_size);
+			fclose($fp);
+			return $data;
+		}
+		/**
+		 * Save the source of process
+		 * 
+		 * @param string $proc_name process name
+		 * @param string $act_name activity name
+		 * @param string $type type of activity
+		 * @param string $source source code of activity
+		 * @return void
+		 * @access public
+		 */
+		function save_source($proc_name, $act_name, $type, $source)
+		{
+			// in case code was filtered
+			if (!$source) $source = @$GLOBALS['egw_unset_vars']['_POST[source]'];
+
+			switch($type)
+			{
+				case 'code':
+					$path =  'activities' . SEP . $act_name . '.php';
+					break;
+				case 'template':
+					$path = 'templates' . SEP . $act_name . '.tpl';
+					break;
+				default:
+					$path = 'shared.php';
+					break;
+			}
+			$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+			// In case you want to be warned when source code is changed:
+			// mail('yourmail@domain.com', 'source changed', "PATH: $complete_path \n\n SOURCE: $source");
+			$fp = fopen($complete_path, 'w');
+			fwrite($fp, $source);
+			fclose($fp);
+		}
+
+		/**
+		 * Export process to a xml file to be downloaded 
+		 * @access public
+		 * @return void
+		 */
+		function export()
+		{
+			$this->process_manager	= Factory::getInstance('workflow_processmanager');
+
+			// retrieve process info
+			$proc_info = $this->process_manager->get_process($this->wf_p_id);
+			$filename = $proc_info['wf_normalized_name'].'.xml';
+			$out = $this->process_manager->serialize_process($this->wf_p_id);
+			$mimetype = 'application/xml';
+			// MSIE5 and Opera show allways the document if they recognise. But we want to oblige them do download it, so we use the mimetype x-download:
+			if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5') || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 7'))
+				$mimetype = 'application/x-download';
+			// Show appropiate header for a file to be downloaded:
+			header("content-disposition: attachment; filename=$filename");
+			header("content-type: $mimetype");
+			header('content-length: ' . strlen($out));
+			echo $out;
+		}
+		
+		/**
+		* Get the href link for the css file, searching for themes specifics stylesheet if any
+		* @param string $css_name is the name of the css file, without the .css extension
+		* @param bool $print_mode is false by default, if true '_print.css' is appended to the name if this css print file exists
+		* @return string a string containing the link to a css file that you can use in a href, you'll have at least a link
+		* to a non-existent css in template/default/css/
+		* @access public
+		*/
+		function get_css_link($css_name, $print_mode = false)
+		{
+			$file = "css/$css_name" . (($print_mode !== false) ? '_print' : '') . '.css';
+			return Factory::getInstance('TemplateServer')->getWebFile($file);
+		}
+
+		/**
+		 * Return a given duration in human readable form, usefull for workitems duration
+		 * @param int $to given duration
+		 * @return string given duration in human readable form
+		 * @access public
+		 */
+		function time_diff($to) {
+			$days = (int)($to/(24*3600));
+			$to = $to - ($days*(24*3600));
+			$hours = (int)($to/3600);
+			$to = $to - ($hours*3600);
+			$min = date("i", $to);
+			$to = $to - ($min*60);			
+			$sec = date("s", $to);
+
+			return lang('%1 days, %2:%3:%4',$days,$hours,$min,$sec);
+		}
+
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowMacro.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowMacro.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowMacro.inc.php	(revision 2372)
@@ -0,0 +1,75 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Classe que implementa algumas ações que se repetem em várias partes do módulo
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class WorkflowMacro
+{
+	/**
+	 * Construtor da classe WorkflowMacro
+	 * @return object Objeto da classe WorkflowMacro
+	 * @access public
+	 */
+	public function WorkflowMacro()
+	{
+	}
+
+	/**
+	 * Prepara o ambiente disponibilizado pelo ExpressoLivre/Workflow
+	 * @return void
+	 * @access public
+	 */
+	public function prepareEnvironment()
+	{
+		define('SEP', '/');
+		$currentApplication = (php_sapi_name() == 'cli') ? 'login' : 'home';
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => true, 'nonavbar' => true, 'currentapp' => $currentApplication, 'enable_network_class' => true, 'enable_contacts_class' => true, 'enable_nextmatchs_class' => true);
+		require_once dirname(__FILE__) . '/../../header.inc.php';
+		require dirname(__FILE__) . '/../setup/setup.inc.php'; /* DO NOT USE require_once */
+		$GLOBALS['phpgw_info']['apps']['workflow'] = $setup_info['workflow'];
+		$row = Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID->query('SELECT config_value FROM phpgw_config WHERE config_app = ? AND config_name = ?', array('phpgwapi', 'files_dir'))->fetchRow();
+		$_SESSION['phpgw_info']['workflow']['vfs_basedir'] = ($row !== false) ? $row['config_value'] : '/home/expressolivre';
+		$_SESSION['phpgw_info']['workflow']['phpgw_api_inc'] = PHPGW_API_INC;
+		$_SESSION['phpgw_info']['workflow']['account_id'] = $GLOBALS['phpgw_info']['user']['account_id'];
+		$_SESSION['phpgw_info']['workflow']['server']['webserver_url'] = $GLOBALS['phpgw_info']['server']['webserver_url'];
+
+		require_once PHPGW_API_INC . '/functions.inc.php';
+		require_once 'engine/class.ajax_config.inc.php';
+		require_once 'engine/config.ajax.inc.php';
+		$GLOBALS['ajax']->ldap = &Factory::getInstance('ajax_ldap');
+
+		/* definição de algumas constantes */
+		define('PHPGW_TEMPLATE_DIR', ExecMethod('phpgwapi.phpgw.common.get_tpl_dir', 'phpgwapi'));
+		$_SERVER['DOCUMENT_ROOT'] = PHPGW_SERVER_ROOT;
+	}
+
+	/**
+	 * Prepara o ambiente disponibilizado pelo Workflow para um dado processo
+	 * @return void
+	 * @access public
+	 */
+	public function prepareProcessEnvironment($processID)
+	{
+		require_once PHPGW_SERVER_ROOT . '/workflow/inc/local/functions/local.functions.php';
+
+		$runtime = &Factory::getInstance('WfRuntime', Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		$runtime->loadProcess($processID);
+
+		/* GLOBALS */
+		$GLOBALS['workflow']['wf_runtime'] = &$runtime;
+		$GLOBALS['workflow']['wf_normalized_name'] = $runtime->process->getNormalizedName();
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_instance.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_instance.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_instance.inc.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	if (!defined('GALAXIA_LIBRARY'))
+		require_once 'engine/config.egw.inc.php';
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'API' . SEP . 'Instance.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_instance extends Instance
+	{   /**
+		 * Construtor da classe workflow_Instance
+		 * @access public
+		 * @return object
+		 */
+		function workflow_Instance()
+		{
+			parent::Instance(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.utils.security.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.utils.security.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.utils.security.php	(revision 795)
@@ -0,0 +1,271 @@
+<?php
+require_once('class.utils.php');
+ /**
+  * Filters input of stray or malicious PHP, Javascript or HTML tags.
+  * It can be used to prevent cross-site scripting (XSS) attacks.
+  * It should be used to filter input supplied by the user, such as an HTML code
+  * entered in form fields. You would create the filter object, configure it with your
+  * own settings, then call its process method to clean the form input values.
+  *
+  * @author: Daniel Morris
+  * @version: 1.2.2_php4/php5
+  * @package Workflow
+  * @license http://www.gnu.org/copyleft/gpl.html GPL
+  */
+class SecurityUtils extends Utils {
+
+	/**
+	 * @var array $tagsArray default = empty array
+	 * @access public
+	 */
+	var $tagsArray;
+
+	/**
+	 * @var array $attrArray  default = empty array
+	 * @access public
+	 */
+	var $attrArray;
+
+	/**
+	 * @var $tagsMethod  default = 0
+	 * @access public
+	 */
+	var $tagsMethod;
+
+	/**
+	 * @var $attrMethod  default = 0
+	 * @access public
+	 */
+	var $attrMethod;
+
+	/**
+	 * @var $xssAuto  default = 1
+	 * @access public
+	 */
+	var $xssAuto;
+
+	/**
+	 * @var array $tagBlacklist
+	 * @access public
+	 */
+	var $tagBlacklist = array('applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml');
+
+	/**
+	 * @var array $attrBlackList
+	 * @access public
+	 */
+	var $attrBlacklist = array('action', 'background', 'codebase', 'dynsrc', 'lowsrc');  // also will strip ALL event handlers
+
+	/**
+	  * Constructor for inputFilter class. Only first parameter is required.
+	  * @access constructor
+	  * @param Array $tagsArray - list of user-defined tags
+	  * @param Array $attrArray - list of user-defined attributes
+	  * @param int $tagsMethod - 0= allow just user-defined, 1= allow all but user-defined
+	  * @param int $attrMethod - 0= allow just user-defined, 1= allow all but user-defined
+	  * @param int $xssAuto - 0= only auto clean essentials, 1= allow clean blacklisted tags/attr
+	  */
+	function SecurityUtils($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1) {
+		// make sure user defined arrays are in lowercase
+		for ($i = 0; $i < count($tagsArray); $i++) $tagsArray[$i] = strtolower($tagsArray[$i]);
+		for ($i = 0; $i < count($attrArray); $i++) $attrArray[$i] = strtolower($attrArray[$i]);
+		// assign to member vars
+		$this->tagsArray = (array) $tagsArray;
+		$this->attrArray = (array) $attrArray;
+		$this->tagsMethod = $tagsMethod;
+		$this->attrMethod = $attrMethod;
+		$this->xssAuto = $xssAuto;
+	}
+
+	/**
+	  * Method to be called by another php script. Processes for XSS and specified bad code.
+	  * @access public
+	  * @param Mixed $source - input string/array-of-string to be 'cleaned'
+	  * @return String $source - 'cleaned' version of input parameter
+	  */
+	function process($source) {
+		// clean all elements in this array
+		if (is_array($source)) {
+			foreach($source as $key => $value)
+				// filter element for XSS and other 'bad' code etc.
+				if (is_string($value)) $source[$key] = $this->remove($this->decode($value));
+			return $source;
+		// clean this string
+		} else if (is_string($source)) {
+			// filter source for XSS and other 'bad' code etc.
+			return $this->remove($this->decode($source));
+		// return parameter as given
+		} else return $source;
+	}
+
+	/**
+	  * Internal method to iteratively remove all unwanted tags and attributes
+	  * @access protected
+	  * @param String $source - input string to be 'cleaned'
+	  * @return String $source - 'cleaned' version of input parameter
+	  */
+	function remove($source) {
+		$loopCounter=0;
+		// provides nested-tag protection
+		while($source != $this->filterTags($source)) {
+			$source = $this->filterTags($source);
+			$loopCounter++;
+		}
+		return $source;
+	}
+
+	/**
+	  * Internal method to strip a string of certain tags
+	  * @access protected
+	  * @param String $source - input string to be 'cleaned'
+	  * @return String $source - 'cleaned' version of input parameter
+	  */
+	function filterTags($source)
+	{
+		return strip_tags($source);
+	}
+
+	/**
+	  * Internal method to strip a tag of certain attributes
+	  * @access protected
+	  * @param Array $attrSet
+	  * @return Array $newSet
+	  */
+	function filterAttr($attrSet) {
+		$newSet = array();
+		// process attributes
+		for ($i = 0; $i <count($attrSet); $i++) {
+			// skip blank spaces in tag
+			if (!$attrSet[$i]) continue;
+			// split into attr name and value
+			$attrSubSet = explode('=', trim($attrSet[$i]));
+			list($attrSubSet[0]) = explode(' ', $attrSubSet[0]);
+			// removes all "non-regular" attr names AND also attr blacklisted
+			if ((!eregi("^[a-z]*$",$attrSubSet[0])) || (($this->xssAuto) && ((in_array(strtolower($attrSubSet[0]), $this->attrBlacklist)) || (substr($attrSubSet[0], 0, 2) == 'on'))))
+				continue;
+			// xss attr value filtering
+			if ($attrSubSet[1]) {
+				// strips unicode, hex, etc
+				$attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]);
+				// strip normal newline within attr value
+				$attrSubSet[1] = preg_replace('/\s+/', '', $attrSubSet[1]);
+				// strip double quotes
+				$attrSubSet[1] = str_replace('"', '', $attrSubSet[1]);
+				// [requested feature] convert single quotes from either side to doubles (Single quotes shouldn't be used to pad attr value)
+				if ((substr($attrSubSet[1], 0, 1) == "'") && (substr($attrSubSet[1], (strlen($attrSubSet[1]) - 1), 1) == "'"))
+					$attrSubSet[1] = substr($attrSubSet[1], 1, (strlen($attrSubSet[1]) - 2));
+				// strip slashes
+				$attrSubSet[1] = stripslashes($attrSubSet[1]);
+			}
+			// auto strip attr's with "javascript:
+			if (	((strpos(strtolower($attrSubSet[1]), 'expression') !== false) &&	(strtolower($attrSubSet[0]) == 'style')) ||
+					(strpos(strtolower($attrSubSet[1]), 'javascript:') !== false) ||
+					(strpos(strtolower($attrSubSet[1]), 'behaviour:') !== false) ||
+					(strpos(strtolower($attrSubSet[1]), 'vbscript:') !== false) ||
+					(strpos(strtolower($attrSubSet[1]), 'mocha:') !== false) ||
+					(strpos(strtolower($attrSubSet[1]), 'livescript:') !== false)
+			) continue;
+
+			// if matches user defined array
+			$attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray);
+			// keep this attr on condition
+			if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod)) {
+				// attr has value
+				if ($attrSubSet[1]) $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"';
+				// attr has decimal zero as value
+				else if ($attrSubSet[1] == "0") $newSet[] = $attrSubSet[0] . '="0"';
+				// reformat single attributes to XHTML
+				else $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"';
+			}
+		}
+		return $newSet;
+	}
+
+	/**
+	  * Try to convert to plaintext
+	  * @access protected
+	  * @param String $source
+	  * @return String $source
+	  */
+	function decode($source) {
+		// url decode
+		$source = html_entity_decode($source, ENT_QUOTES, "ISO-8859-1");
+		// convert decimal
+		$source = preg_replace('/&#(\d+);/me',"chr(\\1)", $source);				// decimal notation
+		// convert hex
+		$source = preg_replace('/&#x([a-f0-9]+);/mei',"chr(0x\\1)", $source);	// hex notation
+		return $source;
+	}
+
+	/**
+	  * Method to be called by another php script. Processes for SQL injection
+	  * @access public
+	  * @param Mixed $source - input string/array-of-string to be 'cleaned'
+	  * @return String $source - 'cleaned' version of input parameter
+	  */
+	function safeSQL($source) {
+		// clean all elements in this array
+		if (is_array($source)) {
+			foreach($source as $key => $value)
+				// filter element for SQL injection
+				if (is_string($value)) $source[$key] = $this->quoteSmart($this->decode($value));
+			return $source;
+		// clean this string
+		} else if (is_string($source)) {
+			// filter source for SQL injection
+			if (is_string($source)) return $this->quoteSmart($this->decode($source));
+		// return parameter as given
+		} else return $source;
+	}
+
+	/**
+	  * @author Chris Tobin
+	  * @author Daniel Morris
+	  * @access protected
+	  * @param String $source
+	  * @return String $source
+	  */
+	function quoteSmart($source) {
+		// strip slashes
+		if (get_magic_quotes_gpc()) $source = stripslashes($source);
+		// quote both numeric and text
+		$source = $this->escapeString($source);
+		return $source;
+	}
+
+	/**
+	  * @author Chris Tobin
+	  * @author Daniel Morris
+	  * @access protected
+	  * @param String $source
+	  * @return String $source
+	  */
+	function escapeString($string) {
+		// depreciated function
+		if (version_compare(phpversion(),"4.3.0", "<")) mysql_escape_string($string);
+		// current function
+		else mysql_real_escape_string($string);
+		return $string;
+	}
+
+	/**
+	 * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+	 * @param mixed $source A string or array of strings to be escaped
+	 * @return mixed $source An object of the same type of the input, only escaped
+	 * @access public
+	 */
+	function escapeHTML($source)
+	{
+		$output = $source;
+		if (is_string($output))
+			$output = htmlentities($output, ENT_QUOTES, 'ISO-8859-1');
+		else
+			if (is_array($output))
+				foreach ($output as &$element)
+					$element = $this->escapeHTML($element);
+
+		return $output;
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.external_bridge.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.external_bridge.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.external_bridge.inc.php	(revision 2372)
@@ -0,0 +1,163 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+require_once 'engine/config.egw.inc.php';
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class external_bridge
+{
+	/**
+	 * @var string $siteAddress the address of the site
+	 * @access public
+	 */
+	var $siteAddress;
+
+	/**
+	 * @var object  $acl access rights object
+	 * @access public
+	 */
+	var $acl;
+	/**
+	 * @var object $db
+	 * @access public
+	 */
+	var $db;
+	/**
+	 * @var array $public_functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'render' => True
+	);
+	/**
+	 * External bridge
+	 * @access public
+	 * @return void
+ 	 */
+	function external_bridge()
+	{
+		$this->db = Factory::getInstance('WorkflowObjects')->getDBGalaxia();
+		$this->acl = &Factory::getInstance('so_adminaccess', Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+	}
+	/**
+	 * load Data
+	 * @access public
+	 * @return void
+ 	 */
+	function loadData($site)
+	{
+		/* define the dynamic values that can be used in the login process */
+		$tmpUser = "";
+		$tmpOrg = "";
+
+		$tmpUser = $GLOBALS['phpgw_info']['user']['account_lid'];
+		$tmpOrg = explode(",ou=", $GLOBALS['phpgw_info']['user']['account_dn']);
+		$tmpOrg = explode(",", $tmpOrg[1]);
+		$tmpOrg = $tmpOrg[0];
+
+		$replace = array(
+					'%user%' => $tmpUser,
+					'%organization%' => $tmpOrg,
+					'%password%' => $GLOBALS['phpgw_info']['user']['passwd']);
+
+		/* select the required form values for submission */
+		$result = $this->db->query("SELECT address, post FROM egw_wf_external_application WHERE (external_application_id = {$site})");
+		$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+		if (!$row)
+			die("");
+
+		$dataTmp = str_replace("\r", "", $row['post']);
+		$dataTmp = explode("\n", $dataTmp);
+
+		$this->siteAddress = $row['address'];
+
+		$data = array();
+		foreach ($dataTmp as $aux)
+		{
+			list($varName,$value) = explode("=", $aux, 2);
+			$data["$varName"] = $value;
+		}
+
+		/* replace the tags with the actual values */
+		foreach ($data as $key => $value)
+			foreach ($replace as $before => $after)
+				$data[$key] = str_replace($before, $after, $data[$key]);
+
+		/* load the data */
+	    $output = array();
+	    foreach ($data as $key => $value)
+	        $output[] = array(
+			            "name" => $key,
+			            "value" => $value);
+
+		return $output;
+	}
+	/**
+	 * External bridge
+	 * @access public
+	 * @return void
+ 	 */
+	function render()
+	{
+		if (($GLOBALS['phpgw_info']['server']['use_https'] > 0) && ($_SERVER['HTTPS'] != 'on'))
+		{
+			header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
+			exit;
+		}
+
+		/* validate the var and avoid SQL injection */
+		$site = $_REQUEST['site'];
+
+		$redirect = false;
+		if (!is_numeric($site))
+			$redirect = true;
+		else
+		{
+			/* check if the user has the permission to access the requested site */
+			$site = (int) $site;
+			if (!$this->acl->checkUserGroupAccessToResource('APX', $GLOBALS['phpgw_info']['user']['account_id'], $site))
+				$redirect = true;
+		}
+
+		/* in case of any error, send the user to the frontpage */
+		if ($redirect)
+		{
+			header("Location: index.php");
+			exit;
+		}
+
+		/* generates the form */
+		$generatedForm = '';
+		$loginData = $this->loadData($site);
+		foreach ($loginData as $formData)
+			$generatedForm .= "<input type=\"hidden\" name=\"" . $formData['name']  . "\" id=\"" . $formData['name']  . "\" value=\"" . $formData['value']  . "\">";
+		$generatedForm = 'document.write(\'' . $generatedForm . '\');';
+
+		/* encode the form before submission */
+		$encodedForm = '';
+		for ($i = 0; $i < strlen($generatedForm); $i++)
+			$encodedForm .= '%' . bin2hex($generatedForm[$i]);
+		$encodedForm = '<script type="text/javascript">eval(unescape(\'' . $encodedForm . '\'))</script>';
+
+		/* assign variables to the template */
+		$smarty = Factory::getInstance('workflow_smarty', false);
+		$smarty->assign('encodedForm', $encodedForm);
+		$smarty->assign('siteAddress', $this->siteAddress);
+		$smarty->display('external_bridge.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_participants.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_participants.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_participants.inc.php	(revision 2372)
@@ -0,0 +1,135 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once dirname(__FILE__) . SEP . 'common.inc.php';
+require_once dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php';
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @author Rodrigo Daniel C Lira - rodrigo.lira@gmail.com
+ */
+class ui_participants extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions Array contento as funções públicas
+	 * @access public
+	 */
+	var $public_functions = array(
+        'form'  => true
+    );
+	/**
+	 * @var object $bo Objeto que representa a camada Business
+	 * @access public
+	 */
+	var $bo;
+
+	/**
+	 * Contrutor da classe
+	 * @access public
+	 * @return object
+	 */
+	function ui_participants()
+	{
+		$this->bo = Factory::getInstance('bo_participants');
+	}
+
+	/**
+	 * Constrói a interface de participantes
+	 * @access public
+	 * @return void
+	 */
+	function form()
+	{
+		$smarty = Factory::getInstance('workflow_smarty', false);
+		$smarty->setHeader(workflow_smarty::SHOW_HEADER | workflow_smarty::SHOW_FOOTER);
+		$ldap = Factory::getInstance('WorkflowLDAP');
+		$userDN = $GLOBALS['phpgw_info']['user']['account_dn'];
+		$account = Factory::getInstance('accounts', $userDN);
+		$organizationList = $this->bo->getOrganizations();
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'participants');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'connector');
+
+		/* define the entities that should be listed */
+		if (!isset($_REQUEST['entities']))
+		{
+			/* for backward compatibility */
+			$entities = 'u';
+			if (isset($_REQUEST['mail']))
+				$entities .= 'l';
+			else
+				if (!isset($_REQUEST['hidegroups']))
+					$entities .= 'g';
+		}
+		else
+			$entities = $_REQUEST['entities'];
+
+		/* define the type of information that should be returned */
+		if (isset($_REQUEST['mail']))
+			$id = 'mail'; //return the e-mail
+		else
+			$id = 'id'; //return the uidnumber
+
+		/* indicates wether the uidnumbers should be preffixed with a char that represents the type of the entity (e.g. 'u' for users) */
+		if (isset($_REQUEST['usePreffix']))
+			$usePreffix = ($_REQUEST['usePreffix'] == '1') ? true : false;
+		else
+			$usePreffix = false;
+
+		$hideOrganizations = ($_REQUEST['hideOrganizations'] == '1') ? true : false;
+		$hideSectors = ($_REQUEST['hideSectors'] == '1') ? true : false;
+
+		/* define the initial organization */
+		$selectedOrganization = $ldap->getOrganizationFromDN($userDN);
+		/* check for request supplied organization */
+		if (isset($_REQUEST['organization']))
+			if (preg_match('/^[a-z0-9_\- ]+$/i', $_REQUEST['organization']) > 0)
+				$selectedOrganization = $_REQUEST['organization'];
+		/* if the organization is invalid, use the first in the list */
+		if (($selectedOrganization === false) || !in_array(strtolower($selectedOrganization), array_map('strtolower', $organizationList)))
+			$selectedOrganization = $organizationList[0];
+
+		$organizationRoot = 'ou=' . $selectedOrganization . ',' . $ldap->getLDAPContext();
+		$selectedSector = $organizationRoot;
+		if (isset($_REQUEST['sector']))
+		{
+			if (preg_match('/^[a-z0-9_\- =,]+$/i', $_REQUEST['sector']) > 0)
+			{
+				$requestedSector = $ldap->getSectors(null, false, $_REQUEST['sector']);
+				if ($requestedSector !== false)
+					$selectedSector = $_REQUEST['sector'];
+			}
+		}
+
+		/* send the variables to Smarty */
+		$smarty->assign('organizations', $organizationList);
+		$smarty->assign('selectedOrganization', $selectedOrganization);
+		$smarty->assign('sectors', $this->bo->getSectors(array('organization' => $selectedOrganization), true));
+		$smarty->assign('selectedSector', $selectedSector);
+		$smarty->assign('participants', $this->bo->getEntities(array('entities' => $entities, 'id' => $id, 'context' => $selectedSector, 'usePreffix' => $usePreffix), true));
+		$smarty->assign('entities', $entities);
+		$smarty->assign('id', $id);
+		$smarty->assign('target', $_REQUEST['target_element']);
+		$smarty->assign('usePreffix', $usePreffix);
+		$smarty->assign('hideOrganizations', $hideOrganizations);
+		$smarty->assign('hideSectors', $hideSectors);
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->display('participants.tpl');
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.BrowserInfo.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.BrowserInfo.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.BrowserInfo.inc.php	(revision 795)
@@ -0,0 +1,412 @@
+<?php
+/**************************************************************************\
+* Copyright (C) 2003  Gary White                                           *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+*                                                                          *
+*  This program is distributed in the hope that it will be useful,         *
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+*  GNU General Public License for more details at:                         *
+*  http://www.gnu.org/copyleft/gpl.html                                    *
+\**************************************************************************/
+
+/**
+ * Interpreta informações enviadas pelo navegador do usuário
+ * @author Gary White
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com (revision)
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class BrowserInfo
+{
+	/**
+	 * @var string $name O nome do navegador
+	 * @access private
+	 */
+	private $name = "Unknown";
+
+	/**
+	 * @var string $version A versão do navegador
+	 * @access private
+	 */
+	private $version = "Unknown";
+
+	/**
+	 * @var string $platform O sistema operacional do usuário
+	 * @access private
+	 */
+	private $platform = "Unknown";
+
+	/**
+	 * @var string $userAgent O agente do navegador do usuário
+	 * @access private
+	 */
+	private $userAgent = "Not reported";
+
+	/**
+	 * @var bool Indica se o MSIE é uma versão modificada pela AOL
+	 * @access private
+	 */
+	private $AOL = false;
+
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	function BrowserInfo()
+	{
+		$agent = $_SERVER['HTTP_USER_AGENT'];
+
+		// initialize properties
+		$bd['platform'] = "Unknown";
+		$bd['browser'] = "Unknown";
+		$bd['version'] = "Unknown";
+		$this->userAgent = $agent;
+
+		// find operating system
+		if (eregi("win", $agent))
+			$bd['platform'] = "Windows";
+		elseif (eregi("mac", $agent))
+			$bd['platform'] = "MacIntosh";
+		elseif (eregi("linux", $agent))
+			$bd['platform'] = "Linux";
+		elseif (eregi("OS/2", $agent))
+			$bd['platform'] = "OS/2";
+		elseif (eregi("BeOS", $agent))
+			$bd['platform'] = "BeOS";
+
+		// test for Opera
+		if (eregi("opera",$agent))
+		{
+			$val = stristr($agent, "opera");
+			if (eregi("/", $val))
+			{
+				$val = explode("/",$val);
+				$bd['browser'] = $val[0];
+				$val = explode(" ",$val[1]);
+				$bd['version'] = $val[0];
+			}
+			else
+			{
+				$val = explode(" ",stristr($val,"opera"));
+				$bd['browser'] = $val[0];
+				$bd['version'] = $val[1];
+			}
+
+		// test for WebTV
+		}
+		elseif (eregi("webtv",$agent))
+		{
+			$val = explode("/",stristr($agent,"webtv"));
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for MS Internet Explorer version 1
+		}
+		elseif (eregi("microsoft internet explorer", $agent))
+		{
+			$bd['browser'] = "MSIE";
+			$bd['version'] = "1.0";
+			$var = stristr($agent, "/");
+			if (ereg("308|425|426|474|0b1", $var))
+				$bd['version'] = "1.5";
+
+		// test for NetPositive
+		}
+		elseif (eregi("NetPositive", $agent))
+		{
+			$val = explode("/",stristr($agent,"NetPositive"));
+			$bd['platform'] = "BeOS";
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for MS Internet Explorer
+		}
+		elseif (eregi("msie",$agent) && !eregi("opera",$agent))
+		{
+			$val = explode(" ",stristr($agent,"msie"));
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for MS Pocket Internet Explorer
+		}
+		elseif (eregi("mspie",$agent) || eregi('pocket', $agent))
+		{
+			$val = explode(" ",stristr($agent,"mspie"));
+			$bd['browser'] = "MSPIE";
+			$bd['platform'] = "WindowsCE";
+			if (eregi("mspie", $agent))
+				$bd['version'] = $val[1];
+			else
+			{
+				$val = explode("/",$agent);
+				$bd['version'] = $val[1];
+			}
+
+		// test for Galeon
+		}
+		elseif (eregi("galeon",$agent))
+		{
+			$val = explode(" ",stristr($agent,"galeon"));
+			$val = explode("/",$val[0]);
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for Konqueror
+		}
+		elseif (eregi("Konqueror",$agent))
+		{
+			$val = explode(" ",stristr($agent,"Konqueror"));
+			$val = explode("/",$val[0]);
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for iCab
+		}
+		elseif (eregi("icab",$agent))
+		{
+			$val = explode(" ",stristr($agent,"icab"));
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for OmniWeb
+		}
+		elseif (eregi("omniweb",$agent))
+		{
+			$val = explode("/",stristr($agent,"omniweb"));
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+
+		// test for Phoenix
+		}
+		elseif (eregi("Phoenix", $agent))
+		{
+			$bd['browser'] = "Phoenix";
+			$val = explode("/", stristr($agent,"Phoenix/"));
+			$bd['version'] = $val[1];
+
+		// test for Firebird
+		}
+		elseif (eregi("firebird", $agent))
+		{
+			$bd['browser']="Firebird";
+			$val = stristr($agent, "Firebird");
+			$val = explode("/",$val);
+			$bd['version'] = $val[1];
+
+		// test for Firefox
+		}
+		elseif (eregi("Firefox", $agent))
+		{
+			$bd['browser']="Firefox";
+			$val = stristr($agent, "Firefox");
+			$val = explode("/",$val);
+			$bd['version'] = $val[1];
+
+	  // test for Mozilla Alpha/Beta Versions
+		}
+		elseif (eregi("mozilla",$agent) && eregi("rv:[0-9].[0-9][a-b]",$agent) && !eregi("netscape",$agent))
+		{
+			$bd['browser'] = "Mozilla";
+			$val = explode(" ",stristr($agent,"rv:"));
+			eregi("rv:[0-9].[0-9][a-b]",$agent,$val);
+			$bd['version'] = str_replace("rv:","",$val[0]);
+
+		// test for Mozilla Stable Versions
+		}
+		elseif (eregi("mozilla",$agent) && eregi("rv:[0-9]\.[0-9]",$agent) && !eregi("netscape",$agent))
+		{
+			$bd['browser'] = "Mozilla";
+			$val = explode(" ",stristr($agent,"rv:"));
+			eregi("rv:[0-9]\.[0-9]\.[0-9]",$agent,$val);
+			$bd['version'] = str_replace("rv:","",$val[0]);
+
+		// test for Lynx & Amaya
+		}
+		elseif (eregi("libwww", $agent))
+		{
+			if (eregi("amaya", $agent))
+			{
+				$val = explode("/",stristr($agent,"amaya"));
+				$bd['browser'] = "Amaya";
+				$val = explode(" ", $val[1]);
+				$bd['version'] = $val[0];
+			}
+			else
+			{
+				$val = explode("/",$agent);
+				$bd['browser'] = "Lynx";
+				$bd['version'] = $val[1];
+			}
+
+		// test for Safari
+		}
+		elseif (eregi("safari", $agent))
+		{
+			$bd['browser'] = "Safari";
+			$bd['version'] = "";
+
+		// remaining two tests are for Netscape
+		}
+		elseif (eregi("netscape",$agent))
+		{
+			$val = explode(" ",stristr($agent,"netscape"));
+			$val = explode("/",$val[0]);
+			$bd['browser'] = $val[0];
+			$bd['version'] = $val[1];
+		}
+		elseif (eregi("mozilla",$agent) && !eregi("rv:[0-9]\.[0-9]\.[0-9]",$agent))
+		{
+			$val = explode(" ",stristr($agent,"mozilla"));
+			$val = explode("/",$val[0]);
+			$bd['browser'] = "Netscape";
+			$bd['version'] = $val[1];
+		}
+
+		// clean up extraneous garbage that may be in the name
+		$bd['browser'] = ereg_replace("[^a-z,A-Z]", "", $bd['browser']);
+		// clean up extraneous garbage that may be in the version
+		$bd['version'] = ereg_replace("[^0-9,.,a-z,A-Z]", "", $bd['version']);
+
+		// check for AOL
+		if (eregi("AOL", $agent))
+		{
+			$var = stristr($agent, "AOL");
+			$var = explode(" ", $var);
+			$bd['aol'] = ereg_replace("[^0-9,.,a-z,A-Z]", "", $var[1]);
+		}
+
+		// finally assign our properties
+		$this->name = $bd['browser'];
+		$this->version = $bd['version'];
+		$this->platform = $bd['platform'];
+		$this->AOL = $bd['aol'];
+	}
+
+	/**
+	 * Checa se a versão do navegador é igual o superior que a requisitada
+	 * @param string $version A versão requisitada
+	 * @return bool true se a versão atual é igual ou superior que a requisitada ou false caso contrário
+	 * @access private
+	 */
+	private function checkVersion($version)
+	{
+		/* in case the version is unknown, return false */
+		if ($this->getBrowserVersion() == 'Unknown')
+			return false;
+
+		$required = explode('.', $version);
+		$current = explode('.', $this->getBrowserVersion());
+		for ($i = 0; $i < count($required); $i++)
+		{
+			$subRequired = (int) $required[$i];
+			$subCurrent = (int) (isset($current[$i]) ? $current[$i] : 0);
+			if ($subCurrent < $subRequired)
+				return false;
+			if ($subCurrent > $subRequired)
+				return true;
+		}
+		return true;
+	}
+
+	/**
+	 * Retorna o nome do navegador
+	 * @return string O nome do navegador
+	 * @access public
+	 */
+	public function getBrowserName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Retorna a versão do navegador
+	 * @return string A versão do navegador
+	 * @access public
+	 */
+	public function getBrowserVersion()
+	{
+		return $this->version;
+	}
+
+	/**
+	 * Retorna o sistema operacional do usuário
+	 * @return string O sistema operacional do usuário
+	 * @access public
+	 */
+	public function getOperatingSystem()
+	{
+		return $this->platform;
+	}
+
+	/**
+	 * Retorna o agente do navegador do usuário
+	 * @return string O agente do navegador do usuário
+	 * @access public
+	 */
+	public function getUserAgent()
+	{
+		return $this->userAgent;
+	}
+
+	/**
+	 * Checa o tipo e a versão do navegador de acordo com as informações requisitadas
+	 * @param string $browser O tipo requisitado
+	 * @param string $version A versão requisitada (opcional)
+	 * @return bool true se o navegador atual bate com os requisitos ou false caso contrário
+	 * @access private
+	 */
+	private function isBrowser($browser, $version = null)
+	{
+		if (strpos(strtolower($browser), strtolower($this->getBrowserName())) === 0)
+		{
+			if ($version == null)
+				return true;
+			else
+				if ($this->checkVersion($version))
+					return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Checa se o navegador é o Firefox
+	 * @param string $version A versão requisitada (opcional)
+	 * @return bool true se o navegador atual bate com os requisitos ou false caso contrário
+	 * @access private
+	 */
+	function isFirefox($version = null)
+	{
+		return $this->isBrowser('firefox', $version);
+	}
+
+	/**
+	 * Checa se o navegador é o Opera
+	 * @param string $version A versão requisitada (opcional)
+	 * @param string $version The required version (optional)
+	 * @return bool true se o navegador atual bate com os requisitos ou false caso contrário
+	 * @access private
+	 */
+	function isOpera($version = null)
+	{
+		return $this->isBrowser('opera', $version);
+	}
+
+	/**
+	 * Checa se o navegador é o Internet Explorer
+	 * @param string $version A versão requisitada (opcional)
+	 * @return bool true se o navegador atual bate com os requisitos ou false caso contrário
+	 * @access private
+	 */
+	function isIE($version = null)
+	{
+		return $this->isBrowser('msie', $version);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_userinterface.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_userinterface.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_userinterface.inc.php	(revision 2372)
@@ -0,0 +1,847 @@
+<?php
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class so_userinterface
+{
+	/**
+	 * @var object database object
+	 * @access public
+	 */
+	var $db;
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function so_userinterface()
+	{
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBWorkflow()->Link_ID;
+		$this->db->SetFetchMode(ADODB_FETCH_ASSOC);
+	}
+
+	/**
+	 * Obtain the subnet of an IP Address based on the numer of bits of the subnet
+	 * @param string $ip The IP Address
+	 * @param int $bits Number of bits of the subnet
+	 * @return string The subnet of the IP
+	 * @access private
+	 */
+	private function getSubnet($ip, $bits)
+	{
+		$octets = explode('.', $ip);
+		$output = array();
+		for ($i = 0; $i < 4; $i++)
+		{
+			if ($bits >= 8)
+			{
+				$output[] = $octets[$i];
+				$bits -= 8;
+				continue;
+			}
+			$output[] = $octets[$i] & bindec(str_repeat('1', $bits) . str_repeat('0',8 - $bits));
+			$bits = 0;
+		}
+		return implode('.', $output);
+	}
+
+	/**
+	 * Get External Applications
+	 * @access public
+	 * @return array list of external applications
+	 */
+	function getExternalApplications()
+	{
+		/* load the intranet subnetworks */
+		$oldDB = $GLOBALS['phpgw']->db;
+		$GLOBALS['phpgw']->db = $GLOBALS['ajax']->db;
+		$config = &Factory::getInstance('config', 'workflow');
+		$configValues = $config->read_repository();
+		$submasksString = $configValues['intranet_subnetworks'];
+		$GLOBALS['phpgw']->db = $oldDB;
+
+		$userIP = getenv('REMOTE_ADDR');
+		if (getenv('HTTP_X_FORWARDED_FOR'))
+		{
+			$tmpIP = explode(',', getenv('HTTP_X_FORWARDED_FOR'));
+			$userIP = $tmpIP[0];
+		}
+
+		/* check if the user has access to intranet applications, i.e., is in the intranet */
+		$showIntranetApplications = false;
+		$submasks = explode(';', $submasksString);
+		foreach ($submasks as $submask)
+		{
+			list($ip,$bits) = explode('/', trim($submask) . '/32', 2);
+			if ($this->getSubnet($ip, $bits) == $this->getSubnet($userIP, $bits))
+			{
+				$showIntranetApplications = true;
+				break;
+			}
+		}
+
+		$preOutput = array();
+		$output = array();
+
+		/* select the sites that the user can access */
+		$externalApplicationsID = $GLOBALS['ajax']->acl->getUserGroupPermissions('APX', $_SESSION['phpgw_info']['workflow']['account_id']);
+		if (!empty($externalApplicationsID))
+		{
+			$result = Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID->query("SELECT DISTINCT external_application_id, name, address, image, authentication, intranet_only FROM egw_wf_external_application WHERE (external_application_id IN (" . implode(', ', $externalApplicationsID)  . ")) ORDER BY name");
+			$preOutput = $result->GetArray(-1);
+
+			/* keep only associative elments and check if the user can access an intranet application */
+			for ($i = 0; $i < count($preOutput); $i++)
+			{
+				if (($preOutput[$i]['intranet_only'] == '1') && (!$showIntranetApplications))
+					continue;
+
+				for ($j = 0; $j < $result->_numOfFields; $j++)
+					unset($preOutput[$i][$j]);
+				$output[] = $preOutput[$i];
+			}
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Get User Organization ID
+	 * @param int $userID User identifier
+	 * @return mixed Informações sobre a organização ou false em caso de erro.
+	 * @access public
+	 */
+	function getUserOrganization($userID)
+	{
+		$query = "SELECT o.organizacao_id, o.nome, o.descricao, o.url_imagem, o.ativa FROM funcionario f, organizacao o WHERE (o.organizacao_id = f.organizacao_id) AND (f.funcionario_id = ?)";
+		$result = $this->db->query($query, array((int) $userID));
+
+		$output = $result->fetchRow(DB_FETCHMODE_ASSOC);
+		if (!$output)
+			return false;
+
+		for ($i = 0; $i < $result->_numOfFields; $i++)
+			unset($output[$i]);
+
+		return $output;
+	}
+
+	/**
+	 * Get cost center list
+	 * @param int $organizationID The organization ID
+	 * @return array Lista de centros de custo
+	 * @access public
+	 */
+	function getCostCenters($organizationID)
+	{
+		$result = $this->db->query("SELECT nm_centro_custo, grupo, descricao FROM centro_custo WHERE (organizacao_id = ?) ORDER BY descricao", array($organizationID));
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Get hierarchical Area
+	 * @return array
+	 * @access public
+	 */
+	function getHierarchicalArea($organizationID, $parent = null, $depth = 0)
+	{
+		if (is_null($parent)){
+			$query = "SELECT a.area_id, a.sigla, a.titular_funcionario_id FROM area a";
+			$query .=" INNER JOIN area_status a_s ON (a_s.area_status_id = a.area_status_id)";
+			$query .=" WHERE (a.superior_area_id IS NULL) AND (a.organizacao_id = ?) AND (a.ativa = 'S') ORDER BY a_s.nivel, a.sigla";
+			$result = $this->db->query($query, array($organizationID));
+		} else {
+			$query = "SELECT a.area_id, a.sigla, a.titular_funcionario_id FROM area a";
+			$query .=" INNER JOIN area_status a_s ON (a_s.area_status_id = a.area_status_id)";
+			$query .=" WHERE (a.superior_area_id = ?) AND (a.ativa = 'S') ORDER BY a_s.nivel, a.sigla";
+			$result = $this->db->query($query, array($parent));
+		}
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+		{
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+			$output[$i]['children'] = $this->getHierarchicalArea($organizationID, $output[$i]['area_id'], $depth + 1);
+			$output[$i]['depth'] = $depth;
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Get organization area list
+	 * @return array
+	 * @access public
+	 */
+	function getAreaList($organizationID)
+	{
+		$result = $this->db->query("SELECT area_id, sigla FROM area WHERE (organizacao_id = ?) AND (ativa = 'S') ORDER BY sigla", array($organizationID));
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Get organization categories list
+	 * @param int $organizationID The organization ID
+	 * @return array The categories list
+	 * @access public
+	 */
+	function getCategoriesList($organizationID)
+	{
+		$output = $this->db->query('SELECT funcionario_categoria_id, descricao FROM funcionario_categoria WHERE (organizacao_id = ?)', array($organizationID))->GetArray();
+		$numerOfEmployees = $this->db->GetAssoc('SELECT COALESCE(f.funcionario_categoria_id, 0) AS funcionario_categoria_id, COUNT(*) FROM funcionario f, funcionario_status fs WHERE (f.organizacao_id = ?) AND (f.funcionario_status_id = fs.funcionario_status_id) AND (fs.exibir = \'S\') GROUP BY funcionario_categoria_id', array($organizationID));
+
+		$output[] = array(
+			'funcionario_categoria_id' => 0,
+			'descricao' => 'Sem Vínculo'
+		);
+
+		foreach ($output as &$row)
+			$row['contagem'] .= (isset($numerOfEmployees[$row['funcionario_categoria_id']]) ? $numerOfEmployees[$row['funcionario_categoria_id']] : 0);
+
+		return $output;
+	}
+
+	/**
+	 * Get Area Employees
+	 * @param int $areaID
+	 * @param int $organizationID
+	 * @return array
+	 * @access public
+	 */
+	function getAreaEmployees($areaID, $organizationID)
+	{
+		$organizationID = (int) $organizationID;
+		$areaID = (int) $areaID;
+
+		/* gather some info from the area */
+		$areaInfo = $this->db->query('SELECT COALESCE(a.titular_funcionario_id, -1) AS titular_funcionario_id, COALESCE(s.funcionario_id, -1) AS substituto_funcionario_id FROM area a LEFT OUTER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE (a.organizacao_id = ?) AND (a.area_id = ?)', array($organizationID, $areaID))->GetArray(-1);
+		if (empty($areaInfo))
+			return false;
+		$areaInfo = $areaInfo[0];
+		$supervisors = '{' . implode(', ', $areaInfo) . '}';
+
+		/* load the employees from the area */
+		$query = "SELECT f.funcionario_id, f.organizacao_id, f.area_id, COALESCE(f.funcionario_categoria_id, 0) AS funcionario_categoria_id FROM funcionario f, funcionario_status s WHERE ((f.area_id = ?) OR (f.funcionario_id = ANY (?))) AND (f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = ?)";
+		$result = $this->db->query($query, array($areaID, $supervisors, 'S'));
+
+		$employees = $result->GetArray(-1);
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_NORMAL);
+		$categoriesCount = array();
+		for ($i = 0; $i < count($employees); $i++)
+		{
+			/* remove numeric fields */
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($employees[$i][$j]);
+
+			$employees[$i]['cn'] = '';
+			$employees[$i]['telephoneNumber'] = '';
+			if (in_array($employees[$i]['funcionario_id'], $areaInfo))
+				$employees[$i]['chief'] = ($employees[$i]['funcionario_id'] == $areaInfo['titular_funcionario_id']) ? 1 : 2;
+
+			/* try to find the telephone number */
+			$entry = $cachedLDAP->getEntryByID($employees[$i]['funcionario_id']);
+			if ($entry)
+			{
+				$employees[$i]['telephoneNumber'] = is_null($entry['telephonenumber']) ? '' : $entry['telephonenumber'];
+				$employees[$i]['cn'] = is_null($entry['cn']) ? '' : $entry['cn'];
+				$employees[$i]['removed'] = is_null($entry['last_update']);
+			}
+
+			/* count the number of employees in each category */
+			$categoryID = $employees[$i]['funcionario_categoria_id'];
+			if (isset($categoriesCount[$categoryID]))
+				$categoriesCount[$categoryID]++;
+			else
+				$categoriesCount[$categoryID] = 1;
+		}
+		$usedCategories = array_keys($categoriesCount);
+		$availableCategories = $this->getCategoriesList($organizationID);
+		$output = array();
+		$output['employees'] = $employees;
+		$output['categories'] = array();
+		foreach ($availableCategories as $category)
+		{
+			if (!in_array($category['funcionario_categoria_id'], $usedCategories))
+				continue;
+
+			$category['contagem'] = $categoriesCount[$category['funcionario_categoria_id']];
+			$output['categories'][] = $category;
+		}
+
+		usort($output['employees'], create_function('$a,$b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);'));
+
+		return $output;
+	}
+
+	/**
+	 * Get employees from a specific category
+	 * @param int $categoryID The category ID
+	 * @param int $organizationID The organization ID
+	 * @return array The list o employees of that category
+	 * @access public
+	 */
+	function getCategoryEmployees($categoryID, $organizationID)
+	{
+		$organizationID = (int) $organizationID;
+
+		/* load the employees from the area */
+		if ($categoryID == 0)
+		{
+			$query = "SELECT f.funcionario_id, f.organizacao_id, a.area_id, a.sigla AS area FROM funcionario f, funcionario_status s, area a WHERE (f.funcionario_status_id = s.funcionario_status_id) AND (f.area_id = a.area_id) AND (f.funcionario_categoria_id IS NULL) AND (s.exibir = ?) AND (f.organizacao_id = ?)";
+			$result = $this->db->query($query, array('S', $organizationID));
+		}
+		else
+		{
+			$query = "SELECT f.funcionario_id, f.organizacao_id, a.area_id, a.sigla AS area FROM funcionario f, funcionario_status s, area a WHERE (f.funcionario_status_id = s.funcionario_status_id) AND (f.area_id = a.area_id) AND (f.funcionario_categoria_id = ?) AND (s.exibir = ?) AND (f.organizacao_id = ?)";
+			$result = $this->db->query($query, array((int)$categoryID, 'S', $organizationID));
+		}
+
+		$employees = $result->GetArray(-1);
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_NORMAL);
+		for ($i = 0; $i < count($employees); $i++)
+		{
+			/* remove numeric fields */
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($employees[$i][$j]);
+
+			$employees[$i]['cn'] = '';
+			$employees[$i]['telephoneNumber'] = '';
+
+			/* try to find the telephone number */
+			$entry = $cachedLDAP->getEntryByID($employees[$i]['funcionario_id']);
+			if ($entry)
+			{
+				$employees[$i]['telephoneNumber'] = is_null($entry['telephonenumber']) ? '' : $entry['telephonenumber'];
+				$employees[$i]['cn'] = is_null($entry['cn']) ? '' : $entry['cn'] . (is_null($entry['last_update']) ? ' <font color="red">(excluído)</font>' : '');
+			}
+		}
+
+		$output = array('employees' => $employees);
+		return $output;
+	}
+
+	/**
+	 * Search Employee by Name
+	 * @param int $searchTerm term to search
+	 * @param int $organizationID  Id of organization
+	 * @return array employee data information
+	 * @access public
+	 */
+	function searchEmployeeByName($searchTerm, $organizationID)
+	{
+		/* get ldap connection */
+		$ldap = &$GLOBALS['workflow']['workflowObjects']->getLDAP();
+
+		$searchTermExploded = explode(" ", $searchTerm);
+		$fullSearch = false;
+
+		if (count($searchTermExploded) > 0){
+			for ($i=1; $i<count($searchTermExploded); $i++) {
+				if (strlen($searchTermExploded[$i]) > 2) {
+					$fullSearch = true;
+				}
+			}
+
+			if ($fullSearch){
+				$searchTerm = implode("*", $searchTermExploded);
+			}
+		}
+
+		/* searching employees by name in the ldap server */
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), ('(&(cn=*' . $searchTerm . '*)(phpgwaccounttype=u))'), array('uidNumber', 'cn', 'telephoneNumber'));
+		if ($list === false)
+			return false;
+
+		/* parsing ldap result */
+		$entries = ldap_get_entries($ldap, $list);
+		$ldapResult = array();
+
+		for ($i = 0; $i < $entries['count']; $i++)
+			$ldapResult[$entries[$i]['uidnumber'][0]] = array('cn' => $entries[$i]['cn'][0], 'telephoneNumber' => $entries[$i]['telephonenumber'][0]);
+
+		/* no records found. bye. */
+		if (count($ldapResult) == 0)
+			return array();
+
+		$uids = implode( ',', array_keys( $ldapResult ) );
+
+		/* searching for aditional employee information */
+		$query  = "SELECT ";
+		$query .= "		f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area ";
+		$query .= " FROM ";
+		$query .= "			funcionario f ";
+		$query .= "		INNER JOIN ";
+		$query .= "			area a USING (area_id) ";
+		$query .= "		INNER JOIN ";
+		$query .= "			funcionario_status s ON ((f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')) ";
+		$query .= " WHERE ";
+		$query .= "		(f.organizacao_id = ?) ";
+		$query .= " 	AND ";
+		$query .= "		(f.funcionario_id IN ({$uids})) ";
+
+		$result = $this->db->query($query, array($organizationID))->GetArray(-1);
+		$employees = array();
+
+		/* filling return array with employee's information */
+		for ($i = 0; $i < count($result); $i++) {
+			$employees []= array(
+					'area'	 			=> $result[$i]['area'],
+					'area_id' 			=> $result[$i]['area_id'],
+					'funcionario_id'	=> $result[$i]['funcionario_id'],
+					'cn'			 	=> $ldapResult[$result[$i]['funcionario_id']]['cn'],
+					'telephoneNumber'	=> empty($ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']) ? '': $ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']
+			);
+		}
+
+		/* sorting by name (cn) */
+        $sort_function = create_function('$a, $b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);');
+        usort($employees, $sort_function );
+
+		return $employees;
+	}
+
+	/**
+	 * Search Employee by Area
+	 * @param int $searchTerm term to search
+	 * @param int $organizationID  Id of organization
+	 * @return array employee data information
+	 * @access public
+	 */
+	function searchEmployeeByArea($searchTerm, $organizationID)
+	{
+		/* get ldap connection */
+		$ldap = &$GLOBALS['workflow']['workflowObjects']->getLDAP();
+
+		/* makes no sense search for an area if the string has more than one word */
+		if (count(explode(" ", $searchTerm)) > 1)
+			return array();
+
+		/* searching for employees in areas that match 'searchTerm' */
+		$query  = "SELECT ";
+		$query .= "		f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area ";
+		$query .= " FROM ";
+		$query .= "			funcionario f ";
+		$query .= "		INNER JOIN ";
+		$query .= "			area a USING (area_id) ";
+		$query .= "		INNER JOIN ";
+		$query .= "			funcionario_status s ON ((f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')) ";
+		$query .= " WHERE ";
+		$query .= "		(f.organizacao_id = ?) ";
+		$query .= " 	AND ";
+		$query .= "		(UPPER(a.sigla) LIKE UPPER(?)) ";
+
+		$result = $this->db->query($query, array($organizationID, '%'.$searchTerm.'%'))->GetArray(-1);
+	
+		/* no records found. bye */
+		if (count($result) == 0)
+			return array();
+
+		/* creating the ldap query */
+		$ldap_query = '(&(|';
+		for ($i = 0; $i < count($result); $i++) {
+			$ldap_query .= '(uidNumber=' . $result[$i]['funcionario_id'] . ')';
+		}
+		$ldap_query .= ')(phpgwAccountType=u))';
+
+		/* executing it */
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), $ldap_query, array('uidNumber', 'cn', 'telephoneNumber'));
+		$entries = ldap_get_entries($ldap, $list);
+
+		/* parsing result */
+		$ldapResult = array();
+		for ($i = 0; $i < $entries['count']; $i++)
+			$ldapResult[$entries[$i]['uidnumber'][0]] = array('cn' => $entries[$i]['cn'][0], 'telephoneNumber' => $entries[$i]['telephonenumber'][0]);
+
+		/* we will need to search into database 'cache' for users deleted in ldap */
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
+		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_DATABASE );
+
+		/* filling return array with employee's information */
+		$employees = array();
+		for ($i = 0; $i < count($result); $i++) {
+
+			$employee = array();
+
+			/* user deleted in ldap. Let's try to find him into database 'cache' */
+			if (empty($ldapResult[$result[$i]['funcionario_id']]['cn'])) {
+				$entry = $cachedLDAP->getEntryByID($result[$i]['funcionario_id']);
+
+				$employee['removed'] = is_null($entry['last_update']);
+
+				if ($entry && !empty($entry['cn']))
+					$employee['cn']	= $entry['cn'];
+				/* we cant find it anywhere */
+				else
+					$employee['cn']	= $result[$i]['funcionario_id'];
+			}
+			else
+				$employee['cn']	= $ldapResult[$result[$i]['funcionario_id']]['cn'];
+
+			$employee['area']	 			= $result[$i]['area'];
+			$employee['area_id'] 			= $result[$i]['area_id'];
+			$employee['funcionario_id'] 	= $result[$i]['funcionario_id'];
+			$employee['telephoneNumber']	= empty($ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']) ? '': $ldapResult[$result[$i]['funcionario_id']]['telephoneNumber'];
+
+			$employees []= $employee;
+		}
+
+		/* sorting by name (cn) */
+        $sort_function = create_function('$a, $b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);');
+        usort($employees, $sort_function );
+
+		return $employees;
+	}
+
+	/**
+	 * Search Employee by Telephone
+	 * @param int $searchTerm term to search
+	 * @param int $organizationID  Id of organization
+	 * @return array employee data information
+	 * @access public
+	 */
+	function searchEmployeeByTelephone($searchTerm, $organizationID)
+	{
+		/* we will just excute it if we just get numbers and '-' */
+		if (!preg_match('/^[0-9-]+$/', $searchTerm))
+			return array();
+
+		/* get ldap connection */
+		$ldap = &$GLOBALS['workflow']['workflowObjects']->getLDAP();
+
+		/* searching employees by telephoneNumber in the ldap server */
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), ('(&(telephoneNumber=*' . $searchTerm . '*)(phpgwaccounttype=u))'), array('uidNumber', 'cn', 'telephoneNumber'));
+
+		if (!$list) return false;
+
+		/* parsing ldap result */
+		$entries = ldap_get_entries($ldap, $list);
+		$ldapResult = array();
+
+		for ($i = 0; $i < $entries['count']; $i++)
+			$ldapResult[$entries[$i]['uidnumber'][0]] = array('cn' => $entries[$i]['cn'][0], 'telephoneNumber' => $entries[$i]['telephonenumber'][0]);
+
+		/* no records found. bye. */
+		if (count($ldapResult) == 0)
+			return array();
+
+		$uids = implode( ',', array_keys( $ldapResult ) );
+
+		/* searching for aditional employee information */
+		$query  = "SELECT ";
+		$query .= "		f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area ";
+		$query .= " FROM ";
+		$query .= "			funcionario f ";
+		$query .= "		INNER JOIN ";
+		$query .= "			area a USING (area_id) ";
+		$query .= "		INNER JOIN ";
+		$query .= "			funcionario_status s ON ((f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')) ";
+		$query .= " WHERE ";
+		$query .= "		(f.organizacao_id = ?) ";
+		$query .= " 	AND ";
+		$query .= "		(f.funcionario_id IN ({$uids})) ";
+
+		$result = $this->db->query($query, array($organizationID))->GetArray(-1);
+		$employees = array();
+
+		/* filling return array with employee's information */
+		for ($i = 0; $i < count($result); $i++) {
+			$employees []= array(
+					'area'	 			=> $result[$i]['area'],
+					'area_id'	 		=> $result[$i]['area_id'],
+					'funcionario_id'	=> $result[$i]['funcionario_id'],
+					'cn'			 	=> $ldapResult[$result[$i]['funcionario_id']]['cn'],
+					'telephoneNumber'	=> empty($ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']) ? '': $ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']
+			);
+		}
+
+		/* sorting by name (cn) */
+        $sort_function = create_function('$a, $b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);');
+        usort($employees, $sort_function );
+
+		return $employees;
+	}
+
+
+	/**
+	 * Busca informações sobre um funcionário.
+	 * @param array $params Uma array contendo o ID do funcionário cujas informações serão extraídas e de sua organização (Ajax).
+	 * @param int $employeeID O ID do funcionário.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Informações sobre o funcionário.
+	 * @access public
+	 */
+	function getEmployeeInfo($employeeID, $organizationID)
+	{
+		$SOOrgchart = &Factory::getInstance('so_orgchart');
+		$SOOrgchart->setExternalCalls(true);
+		$output = $SOOrgchart->getEmployeeInfo($employeeID, $organizationID);
+		$SOOrgchart->setExternalCalls(false);
+
+		return $output;
+	}
+
+	/**
+	 * Busca informações sobre uma área.
+	 * @param array $params Uma array contendo o ID da área cujas informações serão extraídas e de sua organização (Ajax).
+	 * @param int $areaID O ID da área.
+	 * @param int $organizationID O ID da organização.
+	 * @return array Informações sobre a área.
+	 * @access public
+	 */
+	function getAreaInfo($areaID, $organizationID)
+	{
+		$SOOrgchart = &Factory::getInstance('so_orgchart');
+		$SOOrgchart->setExternalCalls(true);
+		$output = $SOOrgchart->getAreaInfo($areaID, $organizationID);
+		$SOOrgchart->setExternalCalls(false);
+
+		return $output;
+	}
+
+	/**
+	 * Get useful phones list
+	 * @param int $organizationID The organization ID
+	 * @return array Useful phones list
+	 * @access public
+	 */
+	function getUsefulPhones( $organizationID )
+	{
+		$result = $this -> db -> query( "SELECT descricao, numero FROM telefone WHERE (organizacao_id = ?) ORDER BY descricao", array( $organizationID ) );
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Get areas with substitute boss
+	 * @param int $organizationID The organization ID
+	 * @return array areas with substitute boss
+	 * @access public
+	 */
+	function getAreaWithSubtituteBoss( $organizationID )
+	{
+		$result = $this -> db -> query( "SELECT a.sigla as area, a.titular_funcionario_id as titular, s.funcionario_id as substituto, s.data_inicio, s.data_fim FROM area a INNER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE (organizacao_id = ?) ORDER BY area", array( $organizationID ) );
+
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
+		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_LDAP_DATABASE );
+
+		$output = $result->GetArray(-1);
+		for ( $i = 0; $i < count($output); $i++ )
+		{
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+			$entry = $cachedLDAP -> getEntryByID( $output[ $i ][ 'titular' ] );
+			if ( $entry && ( ! is_null( $entry[ 'cn' ] ) ) )
+				$output[ $i ][ 'titular' ] = $entry[ 'cn' ];
+
+			$entry = $cachedLDAP -> getEntryByID( $output[ $i ][ 'substituto' ] );
+			if ( $entry && ( ! is_null( $entry[ 'cn' ] ) ) )
+				$output[ $i ][ 'substituto' ] = $entry[ 'cn' ];
+
+			$output[$i]['data_inicio'] = implode('/', array_reverse(explode('-', $output[$i]['data_inicio'])));
+			$output[$i]['data_fim'] = implode('/', array_reverse(explode('-', $output[$i]['data_fim'])));
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Get manning list
+	 * @param int $organizationID The organization ID
+	 * @return array The manning list
+	 * @access public
+	 */
+	function getManning( $organizationID )
+	{
+		$result = $this -> db -> query( 'SELECT localidade_id, descricao FROM localidade WHERE (organizacao_id = ?) ORDER BY descricao', array( $organizationID ) );
+
+		$output = $result->GetArray( -1 );
+		for ( $i = 0; $i < count($output); $i++ )
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Get employees from a specific location
+	 * @param int $categoryID The category ID
+	 * @param int $organizationID The organization ID
+	 * @return array The list o employees of that location
+	 * @access public
+	 */
+	function getManningEmployees( $locationID, $organizationID )
+	{
+		$organizationID = ( int ) $organizationID;
+		$locationID = ( int ) $locationID;
+
+		// load the employees from the location
+		$query = "SELECT f.funcionario_id, f.organizacao_id, f.area_id, a.sigla AS area,"
+			. " COALESCE(f.funcionario_categoria_id, 0) AS funcionario_categoria_id"
+			. " FROM funcionario f, funcionario_status s, area a"
+			. " WHERE (f.area_id = a.area_id)"
+			. " AND (f.funcionario_status_id = s.funcionario_status_id)"
+			. " AND (f.organizacao_id = ?)"
+			. " AND (f.localidade_id = ?)"
+			. " AND (s.exibir = ?)";
+
+		$result = $this -> db -> query( $query, array( $organizationID, $locationID, 'S' ) );
+
+		$employees = $result -> GetArray( -1 );
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
+		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_NORMAL );
+
+		$categoriesCount = array( );
+		for ( $i = 0; $i < count( $employees ); $i++ )
+		{
+			// remove numeric fields
+			for ( $j = 0; $j < $result -> _numOfFields; $j++ )
+				unset( $employees[ $i ][ $j ] );
+
+			$employees[ $i ][ 'cn' ] = '';
+			$employees[ $i ][ 'telephoneNumber' ] = '';
+
+			// try to find the telephone number
+			$entry = $cachedLDAP -> getEntryByID( $employees[ $i ][ 'funcionario_id' ] );
+			if ( $entry )
+			{
+				$employees[ $i ][ 'telephoneNumber' ] = is_null( $entry[ 'telephonenumber' ] ) ? '' : $entry[ 'telephonenumber' ];
+				$employees[ $i ][ 'cn' ] = is_null( $entry[ 'cn' ] ) ? '' : $entry[ 'cn' ];
+				$employees[ $i ][ 'removed' ] = is_null( $entry[ 'last_update' ] );
+			}
+
+			// count the number of employees in each category
+			$categoryID = $employees[ $i ][ 'funcionario_categoria_id' ];
+			if ( isset( $categoriesCount[ $categoryID ] ) )
+				$categoriesCount[ $categoryID ]++;
+			else
+				$categoriesCount[ $categoryID ] = 1;
+		}
+
+		$usedCategories = array_keys( $categoriesCount );
+		$availableCategories = $this -> getCategoriesList( $organizationID );
+		$output = array( );
+		$output[ 'employees' ] = $employees;
+		$output[ 'categories' ] = array( );
+		foreach ( $availableCategories as $category )
+		{
+			if ( ! in_array( $category[ 'funcionario_categoria_id' ], $usedCategories ) )
+				continue;
+
+			$category[ 'contagem' ] = $categoriesCount[ $category[ 'funcionario_categoria_id' ] ];
+			$output[ 'categories' ][ ] = $category;
+		}
+
+		usort( $output[ 'employees' ], create_function( '$a,$b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);' ) );
+
+		return $output;
+	}
+
+	/**
+	 * Return the list of employees in alphabetical order
+	 * @param int $organizationID The organization ID
+	 * @return array The list o employees
+	 * @access public
+	 */
+	function getAlphabeticalEmployees( $organizationID )
+	{
+		$organizationID = ( int ) $organizationID;
+
+		// load the employees from the location
+		$query = "SELECT f.funcionario_id, f.organizacao_id, f.area_id, a.sigla AS area,"
+			. " COALESCE(f.funcionario_categoria_id, 0) AS funcionario_categoria_id"
+			. " FROM funcionario f, funcionario_status s, area a"
+			. " WHERE (f.area_id = a.area_id)"
+			. " AND (f.funcionario_status_id = s.funcionario_status_id)"
+			. " AND (f.organizacao_id = ?)"
+			. " AND (s.exibir = ?)";
+
+		$result = $this -> db -> query( $query, array( $organizationID, 'S' ) );
+
+		$employees = $result -> GetArray( -1 );
+
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
+		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_NORMAL );
+
+		$categoriesCount = array( );
+		for ( $i = 0; $i < count( $employees ); $i++ )
+		{
+			// remove numeric fields
+			for ( $j = 0; $j < $result -> _numOfFields; $j++ )
+				unset( $employees[ $i ][ $j ] );
+
+			$employees[ $i ][ 'cn' ] = '';
+			$employees[ $i ][ 'telephoneNumber' ] = '';
+
+			// try to find the telephone number
+			$entry = $cachedLDAP -> getEntryByID( $employees[ $i ][ 'funcionario_id' ] );
+			if ( $entry )
+			{
+				$employees[ $i ][ 'telephoneNumber' ] = is_null( $entry[ 'telephonenumber' ] ) ? '' : $entry[ 'telephonenumber' ];
+				$employees[ $i ][ 'cn' ] = is_null( $entry[ 'cn' ] ) ? '' : $entry[ 'cn' ];
+				$employees[ $i ][ 'removed' ] = is_null( $entry[ 'last_update' ] );
+			}
+
+		}
+
+		usort( $employees, create_function( '$a,$b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);' ) );
+
+		$paging = Factory::newInstance('Paging', 50, $_POST);
+		$employees = $paging->restrictItems( $employees );
+
+		// count the number of employees in each category
+		for ( $i = 0; $i < count( $employees ); $i++ )
+		{
+			$categoryID = $employees[ $i ][ 'funcionario_categoria_id' ];
+			if ( isset( $categoriesCount[ $categoryID ] ) )
+				$categoriesCount[ $categoryID ]++;
+			else
+				$categoriesCount[ $categoryID ] = 1;
+		}
+
+		$usedCategories = array_keys( $categoriesCount );
+		$availableCategories = $this -> getCategoriesList( $organizationID );
+		$output = array( );
+
+		$output['employees'] = $employees;
+		$output['categories'] = array( );
+		$output['paging_links'] = $paging -> commonLinks();
+
+		foreach ( $availableCategories as $category )
+		{
+			if ( ! in_array( $category[ 'funcionario_categoria_id' ], $usedCategories ) )
+				continue;
+
+			$category[ 'contagem' ] = $categoriesCount[ $category[ 'funcionario_categoria_id' ] ];
+			$output[ 'categories' ][ ] = $category;
+		}
+
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowJobManager.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowJobManager.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowJobManager.inc.php	(revision 2372)
@@ -0,0 +1,21 @@
+<?php
+require_once 'common.inc.php';
+
+require_once GALAXIA_LIBRARY . '/src/ProcessManager/JobManager.php';
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class WorkflowJobManager extends JobManager
+{
+	/**
+	 * Construtor da classe WorkflowJobManager
+	 * @access public
+	 * @return object
+	 */
+	public function WorkflowJobManager()
+	{
+		parent::JobManager(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_ajaxinterface.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_ajaxinterface.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_ajaxinterface.inc.php	(revision 2372)
@@ -0,0 +1,166 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+require_once 'engine/class.ajax_config.inc.php';
+require_once 'engine/config.ajax.inc.php';
+/**
+ * Cria o ambiente de sessão para rodar Ajax e implementa alguns métodos
+ * básicos para inclusão de JavaScript e CSS
+ *  
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ */
+class ui_ajaxinterface
+{
+	/**
+	* @var int $num_version Identifica a verão dos arquivos JavaScript e CSS. Incremente o valor deste atribuito
+	* sempre que existirem alterações nos arquivos, para forçar o download pelo browser
+	* @access public 
+	*/		
+	var $num_version = 213;
+
+	/**
+	 * Construtor
+	 * @access public
+	 * @return object
+	 */			
+	function ui_ajaxinterface()
+	{
+	}
+
+	/**
+	* Coloca na variável de sessão todas as informações que serão necessárias para 
+	* rodar os métodos acionados pelas requisições Ajax.
+	* 
+	* @return void
+	* @access public 
+	*/
+	function set_wf_session()
+	{
+		$acl = Factory::getInstance('workflow_acl');
+		$_SESSION['phpgw_info']['workflow']['server_root'] = PHPGW_SERVER_ROOT;
+		$_SESSION['phpgw_info']['workflow']['phpgw_api_inc'] = PHPGW_API_INC;
+		$_SESSION['phpgw_info']['workflow']['phpgw_include_root'] = PHPGW_INCLUDE_ROOT;
+		$vfs = createobject('phpgwapi.vfs');
+		$_SESSION['phpgw_info']['workflow']['vfs_basedir'] = $vfs->basedir;
+		$_SESSION['phpgw_info']['workflow']['server'] = $GLOBALS['phpgw_info']['server'];
+		$_SESSION['phpgw_info']['workflow']['lang'] = $GLOBALS['lang'];
+		$_SESSION['phpgw_info']['workflow']['account_id'] = $GLOBALS['phpgw_info']['user']['account_id'];
+		$_SESSION['phpgw_info']['workflow']['user_groups'] = Factory::getInstance('WorkflowLDAP')->getUserGroups($GLOBALS['phpgw_info']['user']['account_id']);
+		$user_is_admin = $acl->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']);
+		$_SESSION['phpgw_info']['workflow']['user_is_admin'] = $user_is_admin;
+		$_SESSION['phpgw_info']['workflow']['user_can_admin_process'] = ($user_is_admin || ($GLOBALS['phpgw']->acl->check('admin_workflow',1,'workflow')));
+		$_SESSION['phpgw_info']['workflow']['user_can_admin_instance'] = ($user_is_admin || ($GLOBALS['phpgw']->acl->check('admin_instance_workflow',1,'workflow')));
+
+		$can_monitor = $acl->checkUserGroupAccessToType('MON', $GLOBALS['phpgw_info']['user']['account_id']);
+		$_SESSION['phpgw_info']['workflow']['user_can_monitor'] = ($user_is_admin || $can_monitor);
+		$_SESSION['phpgw_info']['workflow']['user_can_clean_instances'] = $_SESSION['phpgw_info']['workflow']['user_can_monitor'];
+		$_SESSION['phpgw_info']['workflow']['user_can_clean_aborted_instances'] = $_SESSION['phpgw_info']['workflow']['user_can_monitor'];
+		$_SESSION['phpgw_info']['workflow']['user']['preferences'] = $GLOBALS['phpgw_info']['user']['preferences']['workflow'];
+		$_SESSION['phpgw_info']['workflow']['voip_groups'] = $GLOBALS['phpgw_info']['server']['voip_groups'];
+	}
+
+	/**
+	* Insere código html para incorporar arquivos JavaScript de uso comum
+	* 
+	* @return string codigo html para insercao do javascript
+	* @access public 
+	*/
+	function get_common_js()
+	{
+		$result = "<script language='javascript'>var _web_server_url = '" . $GLOBALS['phpgw_info']['server']['webserver_url'] . "';</script>";
+		$result = $result . $this->get_js_link('workflow','jscode', 'globals');			
+		$result = $result . $this->get_js_link('workflow','jscode', 'common_functions');
+		$result = $result . $this->get_js_link('workflow','jscode', 'abas');
+		$result = $result . $this->get_js_link('workflow','jscode', 'connector');
+		$result = $result . $this->get_js_link('workflow','jscode', 'sniff_browser');
+		$result = $result . $this->get_js_link('workflow','jscode', 'wz_dragdrop');
+		$result = $result . $this->get_js_link('workflow','jscode', 'dJSWin');
+		$result = $result . $this->get_js_link('workflow','jscode', 'doiMenuDOM');
+		
+		return $result;
+	}
+
+	/**
+	* Insere o código html para inclusão do arquivo de estilo common.css
+	* 
+	* @return string tag html completa para inserção do arquivo common.css
+	* @access public 
+	*/
+	function get_common_css()
+	{
+		return $this->get_css_link('common');
+	}
+
+	/**
+	* Insere o código html para inclusão de um arquivo de folha de estilo. Primeiramente
+	* procura o arquivo no template do usuário. Se não encontrado monta o link para o
+	* template default.
+	*
+	* @param string $CSSName nome do arquivo de folha de estilo.
+	* @param string $mediaType o tipo de mídia (padrão: all)
+	* @return string tag html completa para inserção do arquivo solicitado
+	* @access public
+	*/
+	function get_css_link($CSSName, $mediaType = 'all')
+	{
+		$CSSName = "css/{$CSSName}.css";
+		$templateServer = &Factory::getInstance('TemplateServer');
+		$CSSLink = $templateServer->getWebFile($CSSName);
+		$CSSFile = $templateServer->getSystemFile($CSSName);
+
+		return '<link href="' . $CSSLink . '?' . (file_exists($CSSFile) ? filesize($CSSFile) : $this->num_version) . '" type="text/css" rel="StyleSheet" media="' . $mediaType . '">';
+	}
+
+	/**
+	* Insere o código html para inclusão de um arquivo JavaScript.
+	* 
+	* @param string $module nome do módulo do eGroupware (preferencialmente workflow)
+	* @param string $js_package nome do grupamento de arquivos javascript
+	* @param string $js_name nome do arquivo javascript
+	* @param array  $params parametros 
+	* @return string tag html completa para inserção do arquivo solicitado 
+	* @access public 
+	*/
+	function get_js_link($module, $js_package, $js_name, $params = null)
+	{
+		if (is_null($params))
+			$params = array();
+		else
+			if (!is_array($params))
+				$params = array($params);
+
+		$localFile = $_SESSION['phpgw_info']['workflow']['server_root'] . SEP . $module . SEP . 'js' . SEP . $js_package . SEP . $js_name.'.js';
+		if (@file_exists($localFile))
+			$params[] = filesize($localFile);
+		else
+			$params[] = $this->num_version;
+		$js_file = $GLOBALS['phpgw_info']['server']['webserver_url'].SEP.$module.SEP.'js'.SEP.$js_package.SEP.$js_name.'.js';
+		return '<script src="'.$js_file.'?'.implode('&', $params).'" type="text/javascript"></script>';
+	}
+	
+	/**
+	* Executa a função inicial JavaScript que irá montar os dados da interface.
+	* 
+	* @param string $param nome da função JavaScript
+	* @return string tag html completa com a chamada da função 
+	* @access public 
+	*/
+	function run_init_script($param)
+	{
+		return '<script language="javascript">' . $param . '</script>';
+		}
+	
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.JobRunner.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.JobRunner.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.JobRunner.inc.php	(revision 2372)
@@ -0,0 +1,106 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Classe responsável pela execução dos Jobs
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @subpackage Job
+ */
+class JobRunner
+{
+	/**
+	 * @var array $parameters Parâmetros passados pela linha de comando
+	 * @access private
+	 */
+	private $parameters;
+
+	/**
+	 * @var object $jobManager Objeto da classe JobManager
+	 * @access private
+	 */
+	private $jobManager;
+
+	/**
+	 * Construtor da classe JobRunner
+	 * @param array $parameters Parâmetros passados pela linha de comando
+	 * @return object Objeto da classe JobRunner
+	 * @access public
+	 */
+	public function JobRunner($parameters)
+	{
+		ini_set('display_errors', false);
+		ini_set('log_errors', true);
+		$this->parameters = unserialize(base64_decode($parameters));
+		$this->parameters['currentDate'] = new DateTime($this->parameters['currentDate']);
+		$this->jobManager =& Factory::getInstance('WorkflowJobManager');
+	}
+
+	/**
+	 * Indica que a execução do Job falhou (este Status de falha implica que o Job não foi executado). Após a execução deste método, a execução do PHP é encerrada
+	 * @param string $message A mensagem que será armazenada
+	 * @return void
+	 * @access private
+	 */
+	private function fail($message)
+	{
+		$this->jobManager->writeLog($this->parameters['jobID'], $this->parameters['currentDate'], $message, JobManager::STATUS_FAIL);
+		exit;
+	}
+
+	/**
+	 * Executa o Job
+	 * @return void
+	 * @access public
+	 */
+	public function run()
+	{
+		/* activate the security policy */
+		Factory::getInstance('WorkflowSecurity')->enableSecurityPolicy();
+
+		/**
+		 * Since all jobs must run in process mode, e. g. it's user code,
+		 * we must enable the security.
+		 */
+		Security::enable();
+
+		if (!file_exists($this->parameters['file']))
+			$this->fail('Arquivo contendo o código do Job não foi encontrado');
+
+		require_once dirname(__FILE__) . '/local/classes/class.JobBase.php';
+		require_once $this->parameters['file'];
+
+		if (!class_exists($this->parameters['className']))
+			$this->fail('A classe "' . $this->parameters['className'] . '" não foi encontrada');
+
+		$job = new $this->parameters['className']($this->parameters['jobID'], $this->parameters['processID'], $this->parameters['currentDate'], $this->parameters['testMode'], $this->parameters['maximumExecutionTime']);
+
+		if (!is_subclass_of($job, 'JobBase'))
+			$this->fail('A classe "' . $this->parameters['className'] . '" não está estendendo a classe JobBase');
+
+		$GLOBALS['workflow']['job']['processID'] = $this->parameters['processID'];
+		$job->run();
+		$job->finalize();
+	}
+}
+
+/* esta classe só pode ser executada a partir da linha de comando.
+ * Além disso, ela exige um parâmetro (que é uma string serializada e codificada em base64) */
+if ((php_sapi_name() !== 'cli') || (!isset($argv[1])))
+	exit;
+
+require_once 'common.inc.php';
+Factory::getInstance('WorkflowMacro')->prepareEnvironment();
+
+$jobRunner = &Factory::newInstance('JobRunner', $argv[1]);
+$jobRunner->run();
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_adminsource.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_adminsource.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_adminsource.inc.php	(revision 2372)
@@ -0,0 +1,111 @@
+<?php
+	/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+require_once dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php';
+require_once 'engine' . SEP . 'config.ajax.inc.php';
+
+class ui_adminsource extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'form'	=> true,
+	);
+
+	/**
+	 * @var array $workflow_acl
+	 * @access public
+	 */
+	var $workflow_acl;
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_adminsource()
+	{
+		$this->workflow_acl = Factory::getInstance('workflow_acl');
+		$denyAccess = true;
+		if ($this->workflow_acl->checkWorkflowAdmin($_SESSION['phpgw_info']['workflow']['account_id']))
+		{
+			/* the user is an Expresso/Workflow admin */
+			$denyAccess = false;
+		}
+		else
+		{
+			if ($GLOBALS['phpgw']->acl->check('admin_workflow', 1, 'workflow'))
+			{
+				$pid = (int) $_GET['p_id'];
+				/* check if the user can admin the informed process */
+				$denyAccess = !$this->workflow_acl->check_process_access($_SESSION['phpgw_info']['workflow']['account_id'], $pid);
+			}
+		}
+
+		if ($denyAccess)
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+	}
+
+	/**
+	 * Show user interface admin source form
+	 * @access public
+	 * @return object
+	 */
+	function form()
+	{
+		$smarty = Factory::getInstance('workflow_smarty', false);
+		$smarty->setHeader(workflow_smarty::SHOW_HEADER | workflow_smarty::SHOW_NAVIGATION_BAR | workflow_smarty::SHOW_FOOTER, $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('Admin Processes Sources'));
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','adminsource', 'php_folder');
+		$javaScripts .= $this->get_js_link('workflow','adminsource', 'templates_folder');
+		$javaScripts .= $this->get_js_link('workflow','adminsource', 'resources_folder');
+		$javaScripts .= $this->get_js_link('workflow','adminsource', 'includes_folder');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'lightbox');
+		$javaScripts .= $this->get_js_link('workflow','adminsource', 'main');
+
+		$css = $this->get_common_css();
+		$css .=  $this->get_css_link('lb');
+
+		$tabs = array(
+			'Atividades',
+			'Includes',
+			'Templates',
+			'Resources'
+		);
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang('loading'));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->assign('tabs', $tabs);
+		$smarty->assign('processID', $_GET['p_id']);
+		$smarty->display('adminsource.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_adminjobs.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_adminjobs.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_adminjobs.inc.php	(revision 2372)
@@ -0,0 +1,251 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+/**
+ * Camada Model para Administração de Jobs.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class so_adminjobs
+{
+	/**
+	 * @var bool True se o usuário for administrador do expresso.
+	 * @access private
+	 */
+	private $isAdmin;
+
+	/**
+	 * @var int ID do usuário logado no Expresso
+	 * @access private
+	 */
+	private $userID;
+
+	/**
+	 * @var object Link para a ACL do Workflow.
+	 * @access private
+	 */
+	private $acl;
+
+	/**
+	 * @var object Link para o Banco de Dados do Expresso.
+	 * @access private
+	 */
+	private $db;
+
+	/**
+	 * @var object Link para o objeto de Administração de Jobs
+	 * @access private
+	 */
+	private $jobManager;
+
+	/**
+	 * Checa se o usuário possui direitos administrativos em um processo.
+	 * @param int $processID O ID do processo que se quer checar se o usuário tem direito administrativo.
+	 * @param int $jobID O ID do job que se quer checar acesso.
+	 * @return bool True em caso de sucesso. Em caso de falha, a execução é abortada.
+	 * @access private
+	 */
+	private function checkAccess($processID, $jobID = null)
+	{
+		$error = array('error' => array('Você não tem permissão para executar este procedimento!'));
+
+		/* the user is an administrator */
+		if ($this->isAdmin)
+			return true;
+
+		if (is_null($processID) && is_null($jobID))
+			return $error;
+
+		if (!is_null($jobID))
+		{
+			$jobInfo = $this->jobManager->getJob((int) $jobID);
+
+			if (is_null($processID))
+				$processID = $jobInfo['wf_process_id'];
+			else
+				if ($jobInfo['wf_process_id'] != $processID)
+					return $error;
+		}
+
+		if ($this->acl->checkUserGroupAccessToResource('PRO', $this->userID, $processID))
+			return true;
+
+		return $error;
+	}
+
+	/**
+	 * Construtor da classe so_adminjobs
+	 * @return object
+	 */
+	function so_adminjobs()
+	{
+		$this->userID = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$this->isAdmin = $_SESSION['phpgw_info']['workflow']['user_is_admin'];
+		$this->acl = &$GLOBALS['ajax']->acl;
+		$this->db = &Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
+		$this->jobManager = &Factory::newInstance('JobManager');
+	}
+
+	/**
+	 * Carrega a lista de todos os jobs de um determinado processo.
+	 * @param int $processID O ID do processo
+	 * @return array Lista dos jobs
+	 * @access public
+	 */
+	function loadJobs($processID)
+	{
+		$processID = (int) $processID;
+		if (($errors = $this->checkAccess($processID)) !== true)
+			return $errors;
+
+		return $this->jobManager->getJobsByProcessID($processID);
+	}
+
+	/**
+	 * Atualiza um job
+	 * @param int $jobID O ID do Job que será atualizado
+	 * @param int $processID O ID do processo a qual o Job pertence
+	 * @param string $name O nome do Job
+	 * @param string $description A descrição do Job
+	 * @param string $timeStart Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @param int $intervalValue O intervalo de repetição
+	 * @param int $intervalUnity A unidade de repetição (dia, mês, etc.)
+	 * @param int $dateType O tipo que define quando o Job é executado
+	 * @param int $weekDays Inteiro que representa os dias da semana em que o Job será executado
+	 * @param int $monthOffset Intervalo de execução relativa a mês
+	 * @param bool $active Indica se o job está ativo (true) ou não (false)
+	 * @return array Lista de possíveis erros
+	 * @access public
+	 */
+	function updateJob($jobID, $processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active)
+	{
+		$processID = (int) $processID;
+		$jobID = (int) $jobID;
+		if (($errors = $this->checkAccess($processID, $jobID)) !== true)
+			return $errors;
+
+		$this->jobManager->updateJob($jobID, $processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active);
+		return array('error' => $this->jobManager->get_error(true));
+	}
+
+	/**
+	 * Cria um novo Job
+	 * @param int $processID O ID do processo a qual o Job pertence
+	 * @param string $name O nome do Job
+	 * @param string $description A descrição do Job
+	 * @param string $timeStart Uma string cujo conteúdo é um data e horário devidamente formatados
+	 * @param int $intervalValue O intervalo de repetição
+	 * @param int $intervalUnity A unidade de repetição (dia, mês, etc.)
+	 * @param int $dateType O tipo que define quando o Job é executado
+	 * @param int $weekDays Inteiro que representa os dias da semana em que o Job será executado
+	 * @param int $monthOffset Intervalo de execução relativa a mês
+	 * @param bool $active Indica se o job está ativo (true) ou não (false)
+	 * @return array Lista de possíveis erros
+	 * @access public
+	 */
+	function createJob($processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active)
+	{
+		$processID = (int) $processID;
+		if (($errors = $this->checkAccess($processID)) !== true)
+			return $errors;
+
+		$this->jobManager->createJob($processID, $name, $description, $timeStart, $intervalValue, $intervalUnity, $dateType, $weekDays, $monthOffset, $active);
+		return array('error' => $this->jobManager->get_error(true));
+	}
+
+	/**
+	 * Remove um Job
+	 * @param int $jobID O ID do job
+	 * @return void
+	 * @access public
+	 */
+	function removeJob($jobID)
+	{
+		$jobID = (int) $jobID;
+		if (($errors = $this->checkAccess(null, $jobID)) !== true)
+			return $errors;
+
+		return $this->jobManager->removeJob($jobID);
+	}
+
+	/**
+	 * Carrega a lista dos logs de um Job
+	 * @param int $jobID O ID do job
+	 * @return array Lista dos logs
+	 * @access public
+	 */
+	function loadLogs($jobID)
+	{
+		$jobID = (int) $jobID;
+		if (($errors = $this->checkAccess(null, $jobID)) !== true)
+			return $errors;
+
+		return $this->jobManager->getLogsByJobID($jobID);
+	}
+
+	/**
+	 * Alterna o status do Job entre ativado e desativado
+	 * @param int $jobID O ID do job
+	 * @return array Lista de possíveis erros
+	 * @access public
+	 */
+	function toggleActive($jobID)
+	{
+		$jobID = (int) $jobID;
+		if (($errors = $this->checkAccess(null, $jobID)) !== true)
+			return $errors;
+
+		$jobInfo = $this->jobManager->getJob($jobID);
+		$newStatus = ($jobInfo['active'] != 't');
+		$this->jobManager->setActive($jobID, $newStatus);
+		return array('error' => $this->jobManager->get_error(true));
+	}
+
+	/**
+	 * Executa um determinado Job
+	 * @param int $jobID O ID do job
+	 * @return array Uma array contendo a saída da execução do Job (saída padrão e saída de erro) e outras mensagens
+	 * @access public
+	 */
+	function runJob($jobID)
+	{
+		$jobID = (int) $jobID;
+		if (($errors = $this->checkAccess(null, $jobID)) !== true)
+			return $errors;
+
+		$output = array();
+		$job = $this->jobManager->getJob($jobID);
+		$jobScheduler =& Factory::getInstance('JobScheduler');
+		$totalTime = microtime(true);
+		$thread = $jobScheduler->execute($job, true);
+		while ($thread->isActive())
+			usleep(50000);
+		$totalTime = microtime(true) - $totalTime;
+
+		$output['output']['messages'] = array();
+		$output['output']['messages'][] = 'Tempo de execução: ' . number_format($totalTime, 4) . 's (o tempo máximo permitido é de ' . JobScheduler::MAXIMUM_EXECUTION_TIME/1000000.0 . 's)';
+		$output['output']['default'] = htmlentities($thread->listen());
+		$output['output']['error'] = htmlentities($thread->getError());
+
+		if ($thread->isActive())
+			$thread->kill();
+		else
+			$thread->close();
+
+		if (strpos($output['output']['error'], 'PHP Fatal error') !== false)
+			$this->jobManager->writeLog($jobID, $jobScheduler->getCurrentDate(), $output['output']['error'], JobManager::STATUS_ERROR);
+
+		return $output;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_smarty.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_smarty.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_smarty.inc.php	(revision 2372)
@@ -0,0 +1,175 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'smarty/Smarty.class.php';
+
+/**
+ * Classe para utilizar o Smarty na criação de interfaces do módulo.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class workflow_smarty extends Smarty
+{
+	/**
+	 * Valor usado para indicar a exibição do cabeçalho
+	 * @name SHOW_HEADER
+	 */
+	const SHOW_HEADER = 1;
+
+	/**
+	 * Valor usado para indicar a exibição da barra de navegação
+	 * @name SHOW_NAVIGATION_BAR
+	 */
+	const SHOW_NAVIGATION_BAR = 2;
+
+	/**
+	 * Valor usado para indicar a exibição do rodapé
+	 * @name SHOW_FOOTER
+	 */
+	const SHOW_FOOTER = 4;
+
+	/**
+	 * @var string $expressoHeader Cabeçalho do Expresso.
+	 * @access public
+	 */
+	public $expressoHeader = '';
+
+	/**
+	 * @var string $expressoFooter Rodapé do Expresso.
+	 * @access public
+	 */
+	public $expressoFooter = '';
+
+	/**
+	 * @var bool $showHeader Indicador de exibição do rodapé
+	 * @access private
+	 */
+	private $showHeader = true;
+
+	/**
+	 * @var bool $showNavigationBar Indicador de exibição da barra de navegação (se utilizado, o cabeçalho também será exibido)
+	 * @access private
+	 */
+	private $showNavigationBar = true;
+
+	/**
+	 * @var bool $showFooter Indicador de exibição do rodapé
+	 * @access private
+	 */
+	private $showFooter = true;
+
+   /**
+	 * Construtor da classe workflow_smarty
+	 * @param bool $createHeader Indica que o cabeçalho/rodapé devem ser "criados" na criação do objeto (se true, irá criar: cabeçalho, barra de navegação e rodapé)
+	 * @return object
+	 * @access public
+	 */
+	function workflow_smarty($createHeader = true)
+	{
+		$this->Smarty();
+
+		/* define some directories */
+		$workflowHomeDirectory = isset($_SESSION['phpgw_info']['workflow']['vfs_basedir']) ?
+			$_SESSION['phpgw_info']['workflow']['vfs_basedir'] . '/workflow':
+			$GLOBALS['phpgw_info']['server']['files_dir'] . '/workflow';
+		$smartyDirectory = $workflowHomeDirectory . '/smarty';
+		$templateSet = isset($_SESSION['phpgw_info']['workflow']['server']['template_set']) ?
+			$_SESSION['phpgw_info']['workflow']['server']['template_set'] :
+			$GLOBALS['phpgw_info']['server']['template_set'];
+		$documentRoot = isset($_SESSION['phpgw_info']['workflow']['server_root']) ?
+			$_SESSION['phpgw_info']['workflow']['server_root'] :
+			$_SERVER['DOCUMENT_ROOT'] . $GLOBALS['phpgw_info']['server']['webserver_url'];
+
+		/* list of directories used by the Smarty Template Engine */
+		$directories = array(
+			'home' => $workflowHomeDirectory,
+			'main' => $smartyDirectory,
+			'template' => array(
+				"{$documentRoot}/workflow/templates/{$templateSet}",
+				"{$documentRoot}/workflow/templates/default"
+			),
+			'compile' => $smartyDirectory . '/compile',
+			'config' => $smartyDirectory . '/config',
+			'cache' => $smartyDirectory . '/cache'
+		);
+
+		/* if necessary, create the directories */
+		if (!is_dir($directories['main']))
+			foreach ($directories as $key => $dir)
+				if ($key != 'template')
+					if (!is_dir($dir))
+						@mkdir($dir,0770);
+
+		/* setup the Smarty configuration */
+		$this->template_dir = $directories['template'];
+		$this->compile_dir = $directories['compile'];
+		$this->config_dir = $directories['config'];
+		$this->cache_dir = $directories['cache'];
+		$this->plugins_dir[] = $documentRoot . '/workflow/inc/smarty/module_plugins';
+
+		if ($createHeader)
+			$this->setHeader(workflow_smarty::SHOW_HEADER | workflow_smarty::SHOW_NAVIGATION_BAR | workflow_smarty::SHOW_FOOTER);
+	}
+
+   /**
+	 * Define os elementos do template padrão, do ExpressoLivre, que serão exibidos
+	 * @param int $config Um inteiro que representa quais os elementos que serão exibidos
+	 * @param string $applicationTitle O título da aplicação, opcional (valor padrão: Workflow)
+	 * @return void
+	 * @access public
+	 */
+	public function setHeader($config, $applicationTitle = 'Workflow')
+	{
+		$this->showHeader = (bool) ($config & workflow_smarty::SHOW_HEADER);
+		$this->showNavigationBar = (bool) ($config & workflow_smarty::SHOW_NAVIGATION_BAR);
+		$this->showFooter = (bool) ($config & workflow_smarty::SHOW_FOOTER);
+		$this->showHeader = $this->showHeader || $this->showNavigationBar;
+
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $applicationTitle;
+		$GLOBALS['phpgw_info']['flags'] = array(
+			'noheader' => true,
+			'nonavbar' => true,
+			'currentapp' => 'workflow'
+		);
+
+		$this->createHeader();
+	}
+
+   /**
+	 * Cria o cabeçalho de acordo com os elementos selecionados
+	 * @return void
+	 * @access private
+	 */
+	private function createHeader()
+	{
+		/* get the header code */
+		if ($this->showHeader)
+		{
+			ob_start();
+			$GLOBALS['phpgw']->common->phpgw_header();
+			if ($this->showNavigationBar)
+				parse_navbar();
+			$this->expressoHeader = ob_get_contents();
+			ob_end_clean();
+		}
+
+		/* get the footer code */
+		if ($this->showFooter)
+		{
+			ob_start();
+			$GLOBALS['phpgw']->common->phpgw_footer();
+			$this->expressoFooter = ob_get_contents();
+			ob_end_clean();
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_move_instances.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_move_instances.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_move_instances.inc.php	(revision 2372)
@@ -0,0 +1,59 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php');
+
+/**
+ * Camada View para Mover Instâncias.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ui_move_instances extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions Lista de métodos que podem ser executados.
+	 * @access private
+	 */
+	var $public_functions = array(
+		'form'	=> true
+	);
+
+	/**
+	 * Carrega os valores que serão utilizados para criação da interface para mover instâncias.
+	 * @return void
+	 * @access public
+	 */
+	function form()
+	{
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => false, 'nonavbar' => false, 'currentapp' => 'workflow');
+		$smarty = Factory::getInstance('workflow_smarty');
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','nano', 'JSON');
+		$javaScripts .= $this->get_js_link('workflow','move_instances', 'main');
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'scriptaculous', 'load=effects,dragdrop');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'niftycube');
+
+		$css = $this->get_common_css();
+		$css .= $this->get_css_link('move_instances');
+		$css .= $this->get_css_link('niftyCorners');
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->display('move_instances.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_adminactivities.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_adminactivities.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_adminactivities.inc.php	(revision 2372)
@@ -0,0 +1,1095 @@
+<?php
+
+require_once dirname(__FILE__) . SEP . 'class.WorkflowUtils.inc.php';
+require_once 'engine' . SEP . 'config.egw.inc.php';
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ui_adminactivities extends WorkflowUtils
+{
+	/**
+	 * @var array $public_functions Array of public functions 
+	 * @access public
+	 */
+	var $public_functions = array(
+		'form'			=> true,
+		'show_graph'	=> true
+	);
+/**
+ * @var object $process_manager Process manager
+ * @access public 
+ */
+	var $process_manager;		
+/**
+ * @var object $activity_manager
+ * @access public 
+ */
+	var $activity_manager;
+/**
+ * @var object $role_manager
+ * @access public 
+ */
+	var $role_manager;
+/**
+ * @var $where2 
+ * @access public 
+ */	
+	var $where2;
+	/**
+	 * @var object $sort_mode2
+	 * @access public 
+	 */	
+	var $sort_mode2;
+	/**
+	 * @var array $agents agents handling
+	 * @access public
+	 */
+	var $agents=Array();
+	/**
+	 * @var object $workflow_acl
+	 * @access public 
+	 */
+	var $workflow_acl;
+	/**
+	 * @var object $fs object for reading process folder  
+	 * @access public
+	 */
+	var $fs; 
+	/**
+	 * @var array  $invalidFiles invalid files list 
+	 * @access public
+	 */
+	var $invalidFiles = array();	 
+	/**
+	 * Constructor da classe ui_adminactivities
+	 * 
+	 * @access public
+	 * @return void
+	 */	
+	function ui_adminactivities()
+	{
+		parent::WorkflowUtils();
+
+		$this->workflow_acl = Factory::getInstance('workflow_acl');
+		$denyAccess = true;
+		if ($this->workflow_acl->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']))
+		{
+			/* the user is an Expresso/Workflow admin */
+			$denyAccess = false;
+		}
+		else
+		{
+			if ($GLOBALS['phpgw']->acl->check('admin_workflow', 1, 'workflow'))
+			{
+				/* check if the user can admin the informed process */
+				if ($this->wf_p_id != 0)
+					$denyAccess = !$this->workflow_acl->check_process_access($GLOBALS['phpgw_info']['user']['account_id'], $this->wf_p_id);
+				else
+					$denyAccess = false;
+			}
+		}
+
+		/* allow regular users to see the process graph */
+		if ($_GET['menuaction'] == "workflow.ui_adminactivities.show_graph")
+			$denyAccess = false;
+
+		if ($denyAccess)
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		$this->process_manager	= Factory::getInstance('workflow_processmanager');
+		$this->activity_manager	= Factory::getInstance('workflow_activitymanager');
+		$this->role_manager	= Factory::getInstance('workflow_rolemanager');
+		$this->fs = &Factory::newInstance('FsUtils'); /* gets instance */
+
+	}
+		
+	/**
+	 * Build the form for Activities Administration
+	 * @return void
+	 * @access public
+	 */
+	function form()
+	{
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('Admin Process Activities');
+		$GLOBALS['phpgw']->common->phpgw_header();
+		echo parse_navbar();
+
+		$this->t->set_file('admin_activities', 'admin_activities.tpl');
+		$this->t->set_block('admin_activities', 'block_select_type', 'select_type');
+		$this->t->set_block('admin_activities', 'block_activity_roles', 'activity_roles');
+		$this->t->set_block('admin_activities', 'block_process_roles', 'process_roles');
+		$this->t->set_block('admin_activities', 'block_activity_agents', 'activity_agents');
+		$this->t->set_block('admin_activities', 'block_default_roles', 'default_roles');
+		$this->t->set_block('admin_activities', 'block_select_agents', 'select_agents');
+	
+		$proc_info =& $this->process_manager->get_process($this->wf_p_id);
+	
+		$activity_id		= (int)get_var('activity_id', 'any', 0);
+		$name				= get_var('name', 'any', '');
+					
+		// TODO: not all variables below are still required.  clean up
+		
+		$description			= get_var('description', 'any', '');
+		$type					= get_var('type', 'any', '');
+		$is_interactive			= get_var('is_interactive', 'any', '');
+		$is_autorouted			= get_var('is_autorouted', 'any', '');
+		$default_user      		= get_var('default_user', 'any', '');
+		$useagent				= get_var('useagent', 'POST', '');
+		$where					= get_var('where', array('GET', 'POST'), '');
+		$this->where2			= get_var('where2', 'any', '');
+		$find					= get_var('find', 'any', '');
+		$find2					= get_var('find2', 'any', '');
+		$this->sort_mode2		= get_var('sort_mode2', 'any', '');
+		$filter_trans_from		= get_var('filter_trans_from', 'any', '');
+		$this->order			= get_var('order', 'GET', 'wf_flow_num');
+		$this->sort				= get_var('sort', 'GET', 'asc');
+		$this->sort_mode		= $this->order . '__'. $this->sort;
+		$menu_path				= get_var('menu_path', 'any', '');
+		//roles
+		$activity_role_ro		= get_var('activity_role_ro','POST', Array());
+		$activity_role_delete	= get_var('activity_role_delete','POST', Array());
+		$remove_roles			= get_var('remove_roles', 'POST', false);
+		$rolename				= get_var('rolename', 'POST', '');
+		$roledescription		= get_var('roledescription', 'POST', '');
+		$userole				= get_var('userole', 'POST', '');
+		$userole_ro				= get_var('userole_ro', 'POST', 'off');
+		$newrole_ro				= get_var('newrole_ro', 'POST', 'off');
+
+
+		if (!$this->wf_p_id) die(lang('No process indicated'));
+
+		// *************************************   START OF OPERATIONS COMMANDED BY THIS SAME FORM ******************
+		// do we need to check validity? do it only if necessary, high load on database
+		$checkvalidity = false;
+
+		// add role to process roles
+		if( !(empty($rolename)) )
+		{
+			$rolename = trim($rolename);
+			if( strlen($rolename) > 0 ) 
+			{
+				//second parameter for read-only mode
+				$newrole_id = $this->add_process_role($rolename, $roledescription);
+				if ($newrole_id)
+				{
+					$this->message[] = lang('Role added to process');
+					if ($activity_id)
+					{
+						$this->activity_manager->add_activity_role($activity_id, $newrole_id, ($newrole_ro=='on'));
+						$this->message[] = lang('Role added to activity');
+					}
+					$checkvalidity = true;
+				}
+			}
+			else 
+			{
+				$this->message[] = lang('Invalid role name');
+			}
+		}
+
+		// remove activity role
+		if (!!($remove_roles) && $activity_id)
+		{
+			foreach ($activity_role_delete as $role_id => $checked_on)
+			{
+				$this->activity_manager->remove_activity_role($activity_id, $role_id);
+				$this->message[] = lang('Activity role #%1 removed', $role_id);
+			}
+			$this->message[] = $this->activity_manager->get_error(false, _DEBUG);
+			$checkvalidity = true;
+		}
+
+		// remove activity agent
+		if (isset($_GET['remove_agent']) && $activity_id)
+		{
+			$this->activity_manager->remove_activity_agent($activity_id, $_GET['remove_agent'],true);
+			$this->message[] = lang('Activity agent removed');
+			$this->message[] = $this->activity_manager->get_error(false, _DEBUG);
+		}
+
+		// TODO: activityname need to be valid.  Add a validity checking function?
+		// save activity
+		if (isset($_POST['save_act']))
+		{
+			$activity_id = $this->save_activity($activity_id, $name, $description, $type, $default_user, $is_interactive, $is_autorouted, $userole, $userole_ro, $useagent, $rolename, $menu_path);
+			if( $activity_id ) 
+			{
+				if ($newrole_id)
+				{
+					$this->activity_manager->add_activity_role($activity_id, $newrole_id, ($newrole_ro=='on'));
+					$this->message[] = lang('Role added to activity');
+				}
+				$this->message[] = lang('Activity saved');
+			}
+			//no checkvalidity, this is done already in ActivityManager
+		}
+
+		// delete activity
+		if (isset($_POST['delete_act']))
+		{
+			if( isset($_POST['activities']) ) 
+			{
+				if ($this->delete_activities(array_keys($_POST['activities']))) $this->message[] = lang('Deletion successful');
+				$checkvalidity = true;
+			}
+		}
+
+		// add transitions
+		if (isset($_POST['add_trans']))
+		{ 
+			$this->message[] = $this->add_transition($_POST['wf_act_from_id'], $_POST['wf_act_to_id']);
+			$checkvalidity = true;
+		}
+
+		// delete transitions
+		if (isset($_POST['delete_tran']))
+		{
+			$this->delete_transitions($_POST['transition']);
+			$checkvalidity = true;
+		}
+
+		// *************************************   END OF OPERATIONS COMMANDED BY THIS SAME FORM ******************
+
+		$expandTable = isset($_POST['new_activity']);
+		// retrieve activity info and its roles and agents
+		if (!$activity_id || isset($_POST['new_activity']))
+		{
+			$activity_info = array(
+				'wf_name'		=> '',
+				'wf_description'	=> '',
+				'wf_activity_id'	=> 0,
+				'wf_is_interactive'	=> true,
+				'wf_is_autorouted'	=> false,
+				'wf_default_user'       => '*',
+				'wf_type'		=> 'activity',
+				'wf_menu_path'	=> ''
+			);
+			$activity_roles = array();
+			$activity_agents = array();
+		}
+		else
+		{
+			$expandTable = true;
+			$activity_info =& $this->activity_manager->get_activity($activity_id);
+			$activity_roles =& $this->activity_manager->get_activity_roles($activity_id);
+			$activity_agents =& $this->activity_manager->get_activity_agents($activity_id);
+			//for all agents we create ui_agent object to handle admin agents displays
+			//this array can be already done by the save_activity function, in this case
+			// we will just actualize most of the records
+			foreach ($activity_agents as $agent)
+			{
+				if (empty($this->agents[$agent['wf_agent_type']]))
+				{
+					$ui_agent =& createObject('workflow.ui_agent_'.$agent['wf_agent_type']);
+					$ui_agent->load($agent['wf_agent_id']);
+					$this->agents[$agent['wf_agent_type']] = $ui_agent;
+					unset($ui_agent);
+				}
+				else
+				{
+					$this->agents[$agent['wf_agent_type']]->load($agent['wf_agent_id']);
+				}
+			}
+		}
+
+		// fill type filter select box
+		$activity_types = array('start', 'end', 'activity', 'switch', 'split', 'join', 'standalone', 'view');
+		$filter_type = get_var('filter_type', 'any', '');
+		$this->show_select_filter_type($activity_types, $filter_type);
+		
+		$filter_interactive		= get_var('filter_interactive', 'any', '');
+		$activity_interactive = array('y' => lang('Interactive'), 'n'=>lang('Automatic'));
+		$this->show_select_filter_interactive($activity_interactive, $filter_interactive);
+		
+		$filter_autoroute		= get_var('filter_autoroute', 'any', '');
+		$activity_autoroute = array('y' => lang('Auto Routed'), 'n'=>lang('Manual'));
+		$this->show_select_filter_autoroute($activity_autoroute, $filter_autoroute);
+		
+		$where = '';
+		$wheres = array();
+		if( !($filter_type == '') ) 
+		{
+					$wheres[] = "wf_type = '" .$filter_type. "'";
+		}
+		if( !($filter_interactive == '') ) 
+		{
+					$wheres[] = "wf_is_interactive = '" .$filter_interactive. "'";
+		}
+		if( !($filter_autoroute == '') ) 
+		{
+			$wheres[] = "wf_is_autorouted = '" .$filter_autoroute. "'";
+		}
+		if( count($wheres) > 0 ) 
+		{
+			$where = implode(' and ', $wheres);
+		}
+		
+		if (empty($process_activities)) $process_activities =& $this->activity_manager->list_activities($this->wf_p_id, 0, -1, $this->sort_mode, $find, $where);
+		$all_transition_activities_from =& $this->activity_manager->get_transition_activities($this->wf_p_id, 'end');
+		$all_transition_activities_to =& $this->activity_manager->get_transition_activities($this->wf_p_id, 'start');
+		if ($activity_id) $this->search_transitions_act($process_activities, $activity_id);
+		$process_roles =& $this->role_manager->list_roles($this->wf_p_id, 0, -1, 'wf_name__asc', '');
+		$agents_list =& $this->process_manager->get_agents();
+		$all_process_transitions =& $this->activity_manager->get_process_transitions($this->wf_p_id);
+		$process_transitions =& $this->activity_manager->get_process_transitions($this->wf_p_id, $filter_trans_from);
+		$process_activities_with_transitions =& $this->activity_manager->get_process_activities_with_transitions($this->wf_p_id);
+
+		// update activities
+		if (isset($_POST['update_act']))
+		{
+			if( is_array($process_activities['data']) && count($process_activities['data']) > 0 )
+			{
+				$this->update_activities($process_activities, array_keys($_POST['activity_inter']), array_keys($_POST['activity_route']));
+				$this->message[] = lang('Activities updated');
+			}
+		}
+
+		// activate process
+		if (isset($_GET['activate_proc']))
+		{
+			$this->process_manager->activate_process($_GET['activate_proc']);
+			$proc_info['wf_is_active'] = 'y';
+		}
+
+		// deactivate process
+		if (isset($_GET['deactivate_proc']))
+		{
+			$this->process_manager->deactivate_process($_GET['deactivate_proc']);
+			$proc_info['wf_is_active'] = 'n';
+		}
+
+		/* warning, heavy database load! */
+		/* check process validity and show errors if necessary */
+		if ($checkvalidity) $proc_info['wf_is_valid'] = $this->show_errors($this->activity_manager, $error_str);
+
+		// fill proc_bar
+		$this->t->set_var('proc_bar', $this->fill_proc_bar($proc_info));
+
+		//collect some messages from used objects
+		$this->message[] = $this->activity_manager->get_error(false, _DEBUG);
+		$this->message[] = $this->process_manager->get_error(false, _DEBUG);
+		$this->message[] = $this->role_manager->get_error(false, _DEBUG);
+
+		$templateServer = &Factory::getInstance('TemplateServer');
+
+		// fill the general variables of the template
+		$this->t->set_var(array(
+			'message'				=> implode('<br>', array_filter($this->message)),
+			'errors'				=> $error_str,
+			'form_details_action'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form'),
+			'form_list_transitions_action'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form'),
+			'p_id'					=> $this->wf_p_id,
+			'where'					=> $where,
+			'where2'				=> $this->where2,
+			'sort_mode'				=> $this->sort_mode,
+			'sort_mode2'			=> $this->sort_mode2,
+			'find'				=> $find,
+			'find2'				=> $find2,
+			'expandTable'			=> ($expandTable ? 'true' : 'false'),
+			'activity_id'			=> $activity_info['wf_activity_id'],
+			'new_act_href'			=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form'),
+			'name'					=> $activity_info['wf_name'],
+			'description'			=> $activity_info['wf_description'],
+			'checked_interactive'	=> ($activity_info['wf_is_interactive'])? 'checked="checked"' : '',
+			'checked_autorouted'	=> ($activity_info['wf_is_autorouted'])? 'checked="checked"' : '',
+			'menu_path'				=> $activity_info['wf_menu_path'],
+			'img_transition_auto'           => '<img src="'.$templateServer->generateImageLink('transition_interactive.gif') .'" alt="'. lang('transition mode') .'" />',
+			'img_interactive'               => '<img src="'.$templateServer->generateImageLink('mini_interactive.gif') .'" alt="'. lang('interactivity') .'" />',
+			'img_transition'                => '<img src="'.$templateServer->generateImageLink('transition.gif') .'" alt="'. lang('transitions') .'" />',
+			'img_transition_add'            => '<img src="'.$templateServer->generateImageLink('transition_add.gif') .'" alt="'. lang('add transition') .'" />',
+			'img_transition_delete'         => '<img src="'.$templateServer->generateImageLink('transition_remove.gif') .'" alt="'. lang('delete transition') .'" />',
+			'add_trans_from'		=> $this->build_select_transition('add_tran_from[]', $all_transition_activities_from['data'], true, false, 'from'),
+			'add_trans_to'			=> $this->build_select_transition('add_tran_to[]', $all_transition_activities_to['data'], true, false, 'to'),
+			'add_a_trans_from'		=> $this->build_select_transition('wf_act_from_id', $all_transition_activities_from['data'], false, false),
+			'add_a_trans_to'		=> $this->build_select_transition('wf_act_to_id', $all_transition_activities_to['data'], false, false)
+		));
+
+		if( $filter_trans_from ) {
+			$this->t->set_var('filter_trans_from', $this->build_select_transition_filtered('filter_trans_from', $process_activities_with_transitions['data'], false, true, $filter_trans_from));
+			$this->t->set_var('filter_trans_from_value', $filter_trans_from);
+		}
+		else {
+			$this->t->set_var('filter_trans_from', $this->build_select_transition_filtered('filter_trans_from', $process_activities_with_transitions['data'], false, true, false));				
+			$this->t->set_var('filter_trans_from_value', '');
+		}
+
+		// show process activities table
+		$this->show_process_activities($process_activities['data']);
+
+		
+		foreach ($activity_types as $type)
+		{
+			$this->t->set_var(array(
+				'type_value'	=> $type,
+				'type_selected'	=> ($activity_info['wf_type'] == $type)? 'selected="selected"' : '',
+				'type_name'		=> $type
+			));
+			$this->t->parse('select_type', 'block_select_type', true);
+		}
+
+		// fill activity roles
+		if (!$activity_roles)
+		{
+			$this->t->set_var('activity_roles', '<tr><td colspan="3">'.lang('No roles asociated with this activity').'</td></tr>');
+		}
+		else
+		{
+			foreach ($activity_roles as $role)
+			{
+				$this->t->set_var(array(
+					'act_role_name'		=> $role['wf_name'],
+					'act_role_id'		=> $role['wf_role_id'],
+					'act_role_ro_checked'	=> ($role['wf_readonly'])? 'checked="checked"' : '',
+					'act_role_href'		=> $GLOBALS['phpgw']->link('/index.php', array(
+							'menuaction'	=> 'workflow.ui_adminactivities.form',
+							'where2'	=> $where2,
+							'sort_mode2'	=> $sort_mode2,
+							'find'		=> $find,
+							'where'		=> $where,
+							'activity_id'	=> $activity_info['wf_activity_id'],
+							'p_id'		=> $this->wf_p_id,
+							'remove_role'	=> $role['wf_role_id'],
+					)),
+					 'lang_delete'		=> lang('delete'),
+				));
+				$this->t->parse('activity_roles', 'block_activity_roles', True);
+			}
+			
+		}
+		
+		//general texts about roles
+		$this->t->set_var(array(
+			'txt_read_only'				=> lang('read-only'),
+			'txt_role_name'				=> lang('Role Name'),
+			'txt_Remove_selected_roles'		=> lang('remove selected roles'),
+			'txt_Use_existing_roles'		=> lang('Use existing roles'),
+			)
+		);
+		
+		// fill activity agents
+		if (!$activity_agents)
+		{
+			$this->t->set_var(array(
+				'activity_agents'	=> lang('No agents associated with this activity'),
+				'agents_config_rows' 	=> '',
+			));
+		}
+		else
+		{
+			foreach ($activity_agents as $agent)
+			{
+				$this->t->set_var(array(
+					'act_agent_type'	=> $agent['wf_agent_type'],
+					'act_agent_href'	=> $GLOBALS['phpgw']->link('/index.php', array(
+						'menuaction'	=> 'workflow.ui_adminactivities.form',
+						'where2'	=> $where2,
+						'sort_mode2'	=> $sort_mode2,
+						'find'		=> $find,
+						'where'		=> $where,
+						'activity_id'	=> $activity_info['wf_activity_id'],
+						'p_id'		=> $this->wf_p_id,
+						'remove_agent'	=> $agent['wf_agent_id'],
+					)),
+					'lang_delete'		=> lang('delete'),
+				));
+				$this->t->parse('activity_agents', 'block_activity_agents', True);
+			}
+		}
+		
+		//display agents options
+		$this->display_agents_rows();
+
+		// if we have no default user
+		if ($activity_info['wf_default_user'] == '*')
+			$wf_default_user_desc = '';
+		else
+			$wf_default_user_desc = $GLOBALS['phpgw']->accounts->id2name($activity_info['wf_default_user'], 'account_lastname');
+
+		$this->t->set_var(array(
+			'wf_default_user' => $activity_info['wf_default_user'],
+			'wf_default_user_desc' => $wf_default_user_desc
+		));
+
+		$this->t->set_var(array(
+			'default_user_option_checked_0' => ($activity_info['wf_default_user'][0] != 'p')? "checked='checked'": '',
+			'default_user_option_checked_1' => ($activity_info['wf_default_user'][0] == 'p')? "checked='checked'": '',
+		));
+
+		// fill process roles
+		foreach ($process_roles['data'] as $role)
+		{
+			$this->t->set_var(array(
+				'proc_roleId'	=> $role['wf_role_id'],
+				'proc_roleName'	=> $role['wf_name']
+			));
+			$this->t->parse('process_roles', 'block_process_roles', True);
+		}
+
+		// fill process roles for activity default role
+		foreach ($process_roles['data'] as $role)
+		{
+			$role_id = 'p' . $role['wf_role_id'];
+			$this->t->set_var(array(
+				'proc_roleId'			=> $role_id,
+				'proc_role_selected'	=> ($role_id == $activity_info['wf_default_user'])? 'selected="selected"' : '',
+				'proc_roleName'			=> $role['wf_name']
+			));
+			$this->t->parse('default_roles', 'block_default_roles', true);
+		}
+
+		// fill agents select
+		foreach ($agents_list as $agent)
+		{
+			$this->t->set_var(array(
+				'select_agentType'	=> $agent['wf_agent_type']
+			));
+			$this->t->parse('select_agents', 'block_select_agents', True);
+		}
+
+		// fill list of transitions table
+		$this->show_transitions_table($process_transitions);
+		$this->t->set_var('filter_type_value', $filter_type);
+		$this->t->set_var('filter_interactive_value', $filter_interactive);
+		$this->t->set_var('filter_autoroute_value', $filter_autoroute);
+		$this->t->set_var('find_value', $find);
+
+		// create graph
+		$this->activity_manager->build_process_graph($this->wf_p_id);
+
+		$this->translate_template('admin_activities');
+		$this->t->pparse('output', 'admin_activities');
+		$GLOBALS['phpgw']->common->phpgw_footer();
+	}
+	/**
+	* Show select filter type
+	* @param array $all_activity_types
+	* @param $filter_type 
+	* @access public
+	* @return void
+	*/
+	function show_select_filter_type($all_activity_types, $filter_type)
+	{
+		$this->t->set_block('admin_activities', 'block_select_filter_type', 'select_filter_type');
+		$this->t->set_var('selected_filter_type_all', (!($filter_type))? 'selected="selected"' : '');
+
+		foreach ($all_activity_types as $type)
+		{
+			$this->t->set_var(array(
+				'selected_filter_type'	=> ($filter_type == $type)? 'selected="selected"' : '',
+				'filter_type_name'	=> lang($type),
+				'filter_type_en_name'	=> $type
+			));
+			$this->t->parse('select_filter_type', 'block_select_filter_type', true);
+		}
+	}
+	
+	/**
+	* Show select filter type
+	* @param array $all_activity_types
+	* @param $filter_type 
+	* @access public
+	* @return void
+	*/
+	function show_select_filter_interactive($all_activity_interactive, $filter_interactive)
+	{
+		$this->t->set_block('admin_activities', 'block_select_filter_interactive', 'select_filter_interactive');
+		$this->t->set_var('selected_filter_interactive_all', (!($filter_interactive))? 'selected="selected"' : '');
+
+		foreach ($all_activity_interactive as $value=>$name)
+		{
+			$this->t->set_var(array(
+				'selected_filter_interactive'	=> ($filter_interactive == $value)? 'selected="selected"' : '',
+				'filter_interactive_name'		=> $name,
+				'filter_interactive_value'		=> $value
+			));
+			$this->t->parse('select_filter_interactive', 'block_select_filter_interactive', true);
+		}
+	}
+	/**
+	* Show select filter type
+	* @param array $all_activity_types
+	* @param $filter_type 
+	* @access public
+	* @return void
+	*/
+	function show_select_filter_autoroute($all_activity_autoroute, $filter_autoroute)
+	{
+		$this->t->set_block('admin_activities', 'block_select_filter_autoroute', 'select_filter_autoroute');
+		$this->t->set_var('selected_filter_autoroute_all', (!($filter_autoroute))? 'selected="selected"' : '');
+
+		foreach ($all_activity_autoroute as $value=>$name)
+		{
+			$this->t->set_var(array(
+				'selected_filter_autoroute'	=> ($filter_autoroute == $value)? 'selected="selected"' : '',
+				'filter_autoroute_name'		=> $name,
+				'filter_autoroute_value'		=> $value
+			));
+			$this->t->parse('select_filter_autoroute', 'block_select_filter_autoroute', true);
+		}
+	}
+	
+	/**
+	* Show select filter type
+	* @param array $all_activity_types
+	* @param $filter_type 
+	* @access public
+	* @return void
+	*/
+	function update_activities(&$process_activities, $activities_inter, $activities_route)
+	{
+		$num_activities = count($process_activities['data']);
+		for ($i=0; $i < $num_activities; $i++)
+		{
+			$act_id = $process_activities['data'][$i]['wf_activity_id'];
+			if ($process_activities['data'][$i]['wf_is_interactive'] == 'y' && !in_array($act_id, $activities_inter))
+			{
+				$process_activities['data'][$i]['wf_is_interactive'] = 'n';
+				$this->activity_manager->set_interactivity($this->wf_p_id, $act_id, 'n');
+			}
+			if ($process_activities['data'][$i]['wf_is_interactive'] == 'n' && in_array($act_id, $activities_inter))
+			{
+				$process_activities['data'][$i]['wf_is_interactive'] = 'y';
+				$this->activity_manager->set_interactivity($this->wf_p_id, $act_id, 'y');
+			}
+			if ($process_activities['data'][$i]['wf_is_autorouted'] == 'y' && !in_array($act_id, $activities_route))
+			{
+				$process_activities['data'][$i]['wf_is_autorouted'] = 'n';
+				$this->activity_manager->set_autorouting($this->wf_p_id, $act_id, 'n');
+			}
+			if ($process_activities['data'][$i]['wf_is_autorouted'] == 'n' && in_array($act_id, $activities_route))
+			{
+				$process_activities['data'][$i]['wf_is_autorouted'] = 'y';
+				$this->activity_manager->set_autorouting($this->wf_p_id, $act_id, 'y');
+			}
+		}
+	}
+
+	/**
+	 *  Add a role to the process
+	 *  @param $rolename is the role name
+	 *  @param $roledescription is the role description
+	 *  @return int new role id
+	 */
+	function add_process_role($rolename, $roledescription)
+	{
+		$vars = array(
+			'wf_name'		=> $rolename,
+			'wf_description'	=> $roledescription,
+		);
+		return $this->role_manager->replace_role($this->wf_p_id, 0, $vars);
+	}
+	/**
+	 *  Search transitions activities
+	 *  @param array $process_activities
+	 *  @param int $act_id 
+	 *  @return int new role id
+	 */
+	function search_transitions_act(&$process_activities, $act_id)
+	{
+		for ($i=0; $i < $process_activities['cant']; $i++)
+		{
+			$id = $process_activities['data'][$i]['wf_activity_id'];
+			$process_activities['data'][$i]['to'] = $this->activity_manager->transition_exists($this->wf_p_id, $act_id, $id)? 'y' : 'n';
+			$process_activities['data'][$i]['from'] = $this->activity_manager->transition_exists($this->wf_p_id, $id, $act_id)? 'y' : 'n';
+		}
+	}
+	/**
+	 *  Show process activities data
+	 *  @param $rolename is the role name
+	 *  @param $roledescription is the role description
+	 *  @return int new role id
+	 */
+	function show_process_activities($process_activities_data)
+	{
+		$this->t->set_block('admin_activities', 'block_process_activities', 'process_activities');
+		$this->t->set_var(array(
+			'form_process_activities_action'=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form'),
+			'left_arrow'		=> $this->nextmatchs->left('index.php', $this->start, $this->total),
+			'right_arrow'		=> $this->nextmatchs->right('index.php', $this->start, $this->total),
+		));
+		$this->translate_template('block_process_activities');
+
+		$this->t->set_block('admin_activities', 'block_process_activities_header', 'process_activities_header');
+		$this->t->set_block('admin_activities', 'block_process_activities_footer', 'process_activities_footer');
+		if( is_array($process_activities_data) && count($process_activities_data) > 0 )
+		{
+			$this->t->set_var(array(
+				'header_name'		=> $this->nextmatchs->show_sort_order($this->sort, 'wf_name', $this->order, 'index.php', lang('Name'), array('p_id'=>$this->wf_p_id)),
+				'header_type'		=> $this->nextmatchs->show_sort_order($this->sort, 'wf_type', $this->order, 'index.php', lang('Type'), array('p_id'=>$this->wf_p_id)),
+				'header_interactive'	=> $this->nextmatchs->show_sort_order($this->sort, 'wf_is_interactive', $this->order, 'index.php', lang('Interactive'),  array('p_id'=>$this->wf_p_id)),
+				'header_route'		=> $this->nextmatchs->show_sort_order($this->sort, 'wf_is_autorouted', $this->order, 'index.php', lang('Auto routed'),  array('p_id'=>$this->wf_p_id)),
+				'header_default_user'	=> lang('Default User')
+			));
+			$this->translate_template('block_process_activities_header');
+			$this->t->parse('process_activities_header', 'block_process_activities_header', True);
+			$templateServer = &Factory::getInstance('TemplateServer');
+			foreach ($process_activities_data as $activity)
+			{
+				if($activity['wf_default_user'] == '*' )
+				{
+					$act_default_user = lang('None');
+				}
+				else if($activity['wf_default_user'] != '*')
+				{
+					$act_default_user = $GLOBALS['phpgw']->accounts->id2name($activity['wf_default_user']);
+				}
+				
+				$this->t->set_var(array(
+					'act_activity_id'	=> $activity['wf_activity_id'],
+					'act_flowNum'		=> $activity['wf_flow_num'],
+					'act_href'			=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form&where2='. $where2 .'&sort_mode2='. $sort_mode2 .'&p_id='. $this->wf_p_id .'&find='. $find .'&where='. $where .'&sort_mode='. $this->sort_mode .'&activity_id='. $activity['wf_activity_id']),
+					'act_name'			=> $activity['wf_name'],
+					'no_roles'			=> ($activity['wf_roles'] < 1)? '<small>('.lang('no roles').')</small>' : '',
+					'act_icon'			=> $this->act_icon($activity['wf_type'],$activity['wf_is_interactive']),
+					'act_inter_checked'	=> ($activity['wf_is_interactive'] == 'y')? 'checked="checked"' : '',
+					'act_route_checked'	=> ($activity['wf_is_autorouted'] == 'y')? 'checked="checked"' : '',
+					'act_default_user'      => $act_default_user,
+					'act_href_edit'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminsource.form&p_id='. $this->wf_p_id .'&activity_id='. $activity['wf_activity_id']),
+					'act_template'		=> ($activity['wf_is_interactive'] == 'y')? '<a href="'. $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminsource.form&p_id='. $this->wf_p_id .'&activity_id='. $activity['wf_activity_id'] .'&template=1') .'"><img src="'. $templateServer->generateImageLink('template.png') .'" alt="' .lang('template') .'" title="' . lang('template') .'" /></a>' : '',
+					'img_code'		=> $templateServer->generateImageLink('code.png'),
+					'color_line'		=> $this->nextmatchs->alternate_row_color($tr_color),
+
+				));
+				$this->t->parse('process_activities', 'block_process_activities', True);
+			}
+			$this->translate_template('block_process_activities_footer');
+			$this->t->parse('process_activities_footer', 'block_process_activities_footer', True);
+		}
+		else 
+		{
+			$this->t->set_var('process_activities_header', '');
+			$this->t->set_var('process_activities', '<tr><td colspan="7" align="center">'. lang('There are no processes with the current filter')  .'</td></tr>');
+			$this->t->set_var('process_activities_footer', '');
+		}
+	}
+/** 
+ * Show transitions table
+ * @var array $process_transition 
+ * @access public
+ * @return void
+ */
+	function show_transitions_table($process_transitions)
+	{
+		$this->t->set_block('admin_activities', 'block_transitions_table', 'transitions_table');
+		$this->t->set_block('admin_activities', 'block_transitions_table_footer', 'transitions_table_footer');
+		$this->translate_template('block_transitions_table');
+		$this->translate_template('block_transitions_table_footer');
+
+		foreach ($process_transitions as $transition)
+		{
+			$this->t->set_var(array(
+				'trans_actFromId'	=> $transition['wf_act_from_id'],
+				'trans_actToId'		=> $transition['wf_act_to_id'],
+				'trans_href_from'	=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form&where2='. $where2 .'&sort_mode2='. $sort_mode2 .'&p_id='. $this->wf_p_id .'&find='. $find .'&where='. $where .'&sort_mode='. $this->sort_mode .'&activity_id='. $transition['wf_act_from_id']),
+				'trans_actFromName'	=> $transition['wf_act_from_name'],
+				'trans_arrow'		=> Factory::getInstance('TemplateServer')->generateImageLink('next.gif'),
+				'trans_href_to'		=> $GLOBALS['phpgw']->link('/index.php', 'menuaction=workflow.ui_adminactivities.form&where2='. $where2 .'&sort_mode2='. $sort_mode2 .'&p_id='. $this->wf_p_id .'&find='. $find .'&where='. $where .'&sort_mode='. $this->sort_mode .'&activity_id='. $transition['wf_act_to_id']),
+				'trans_actToName'	=> $transition['wf_act_to_name'],
+				'color_line'		=> $this->nextmatchs->alternate_row_color($tr_color),
+			));
+			$this->t->parse('transitions_table', 'block_transitions_table', true);
+		}
+		if (!count($process_transitions))
+		{
+			$this->t->set_var('transitions_table', '<tr><td colspan="2" align="center">'. lang('There are no transitions defined')  .'</td></tr>');
+			$this->t->set_var('transitions_table_footer', '');
+		} 
+		else 
+		{
+			$this->t->parse('transitions_table_footer', 'block_transitions_table_footer', true);
+		}
+	}
+
+	/**
+	 * Build select box with all transitions activities
+	 * @param string  $var_name		
+	 * @param array   $process_activities_data array of process data
+	 * @param boolean $multiple 
+	 * @param boolean $show_all show all list 
+	 * @param boolean $from_or_to 
+	 * @access public
+	 * @return string html code with select box
+	 */
+	function build_select_transition($var_name, $process_activities_data, $multiple=false, 
+	$show_all=true, $from_or_to=false)
+	{
+		//echo "process_activities_data: <pre>";print_r($process_activities_data);echo "</pre>";
+		$select_str = "<select name='$var_name'" . (($multiple)? " multiple='multiple' size='5'" : "" ) . ">";
+		if ($show_all) $select_str .= '<option value="">'. lang('All') .'</option>';
+		
+		foreach ($process_activities_data as $activity)
+		{
+			if ($from_or_to && isset($activity[$from_or_to]) && $activity[$from_or_to] == 'y')
+			{
+				$selected = 'selected="selected"';
+			}
+			else
+			{
+				$selected = '';
+			}
+			$select_str .= '<option value="'. $activity['wf_activity_id'] .'" '. $selected .'>'. $activity['wf_name'] .'</option>';
+		}
+		$select_str .= "</select>\n";
+		return $select_str;
+	}
+	
+	/**
+	 * Build select box with all transitions activities filtered
+	 * @param string  $var_name		
+	 * @param array   $process_activities_data array of process data
+	 * @param boolean $multiple 
+	 * @param boolean $show_all show all list 
+	 * @param boolean $from_or_to 
+	 * @access public
+	 * @return string html code with select box
+	 */	
+	function build_select_transition_filtered($var_name, $process_activities_data, $multiple=false, $show_all=true, $from=false)
+	{
+		$select_str = "<select name='$var_name'" . (($multiple)? " multiple='multiple' size='5'" : "" ) . ">";
+		if ($show_all) $select_str .= '<option value="">'. lang('All') .'</option>';
+		
+		if( is_array($process_activities_data) && count($process_activities_data) > 0 ) 
+		{
+			foreach ($process_activities_data as $activity)
+			{
+				if ($from && $activity['wf_activity_id'] == $from )
+				{
+					$selected = 'selected="selected"';
+				}
+				else
+				{
+					$selected = '';
+				}
+				$select_str .= '<option value="'. $activity['wf_activity_id'] .'" '. $selected .'>'. $activity['wf_name'] .'</option>';
+			}
+		}
+		$select_str .= "</select>\n";
+		return $select_str;
+	}
+
+	/**
+	 * Save the edited activity. 
+	 * 
+	 * @param int $activity_id
+	 * @param string $name
+	 * @param string $description
+	 * @param string $type
+	 * @param string $default_user
+	 * @param bool $is_interative
+	 * @param bool $is_autorouted 
+	 * @return mixed Return the activity_id or false in case of error, $this->message is set in case of error
+	 * @access public
+	 */
+	function save_activity($activity_id, $name, $description, $type, $default_user, $is_interactive, $is_autorouted, $userole, $userole_ro, $useagent, $rolename, $menu_path)
+	{
+		$is_interactive = ($is_interactive == 'on') ? 'y' : 'n';
+		$is_autorouted = ($is_autorouted == 'on') ? 'y' : 'n';
+		$vars = array(
+			'wf_name' => $name,
+			'wf_description' => $description,
+			'wf_activity_id' => $activity_id,
+			'wf_is_interactive' => $is_interactive,
+			'wf_is_autorouted' => $is_autorouted,
+			'wf_default_user' => $default_user,
+			'wf_type' => $type,
+			'wf_menu_path' => $menu_path
+		);
+
+		if( strlen($name) > 0 )
+		{
+			if ($this->activity_manager->activity_name_exists($this->wf_p_id, $name, $activity_id))
+			{
+				$this->message[] = ($name . ': '. lang('activity name already exists'));
+				return false;
+			}
+		}
+		else
+		{
+			$this->message[] = lang('Enter an activity name');
+			return false;
+		}
+
+		$activity_id = $this->activity_manager->replace_activity($this->wf_p_id, $activity_id, $vars);
+		
+		// assign role to activity
+		if ($userole) 
+		{
+			$this->activity_manager->add_activity_role($activity_id, $userole, ($userole_ro=='on'));
+		}
+		
+		// assign agent to activity
+		if ($useagent) 
+		{
+			$this->activity_manager->add_activity_agent($activity_id, $useagent);
+		}
+
+		//save agent configuration datas if any
+		if (isset($_POST['wf_agent']))
+		{
+			$agents_conf =& $_POST['wf_agent'];
+			
+			//retrieve agents list
+			$activity_agents =& $this->activity_manager->get_activity_agents($activity_id);
+			//for all agents we create ui_agent object to handle admin agents displays and savings
+			foreach ($activity_agents as $agent)
+			{
+				//create an empty temp ui_agent object
+				$ui_agent =& createObject('workflow.ui_agent_'.$agent['wf_agent_type']);
+				//build this object BUT without loading actual data
+				//because we will save next values soon
+				$ui_agent->load($agent['wf_agent_id'],false);
+				//store it in an array
+				$this->agents[$agent['wf_agent_type']] = $ui_agent;
+				//delete the temp object
+				unset($ui_agent);
+			}
+			// now we save the data obtained from the form in theses agents
+			foreach ($agents_conf as $typeagent => $confarray)
+			{
+				$this->agents[$typeagent]->save($confarray);
+			}
+		}
+
+		// add activity transitions
+		if (isset($_POST['add_tran_from']))
+		{
+			foreach ($_POST['add_tran_from'] as $act_from)
+			{
+				$this->activity_manager->add_transition($this->wf_p_id, $act_from, $activity_id);
+			}
+		}
+		if (isset($_POST['add_tran_to']))
+		{
+			foreach ($_POST['add_tran_to'] as $act_to)
+			{
+				$this->activity_manager->add_transition($this->wf_p_id, $activity_id, $act_to);
+			}
+		}
+		$this->activity_manager->validate_process_activities($this->wf_p_id);
+		
+		
+		return $activity_id;
+	}
+	/**
+	 * Delete selected activities
+	 * @param array $activities_ids
+	 * @return bool true always
+	 * @access public
+	 */
+	function delete_activities($activities_ids)
+	{
+		foreach ($activities_ids as $act_id)
+		{
+			$this->activity_manager->remove_activity($this->wf_p_id, $act_id);
+		}
+		return true;
+	}
+
+	function delete_transitions($transitions)
+	{
+		if( is_array($transitions) && count($transitions) > 0 ) {
+			foreach (array_keys($transitions) as $transition)
+			{
+				$parts = explode('_', $transition);
+				$this->activity_manager->remove_transition($parts[0], $parts[1]);
+			}
+			$this->message[] = lang('Transitions removed successfully');
+		}
+		else 
+		{
+			$this->message[] = lang('Select a transition to remove');
+		}
+	}
+	/**
+	 * Add a transition activity
+	 * @param int $from from activity 
+	 * @param int $to   next activity
+	 * @return string Error or success message
+	 * @access public
+	 */
+	function add_transition($from, $to)
+	{
+		if ($this->activity_manager->add_transition($this->wf_p_id, $from, $to))
+		{
+			$this->activity_manager->validate_process_activities($this->wf_p_id);
+			return lang('New transition added');
+		}
+		$error_msg =  $this->activity_manager->get_error(false, _DEBUG);
+		return lang("Couldn't add transition"). '; '. $error_msg[0];
+	}
+	/**
+	 * Show actual process graph
+	 * @access public
+	 */
+	function show_graph()
+	{
+		$proc_info = $this->process_manager->get_process($this->wf_p_id);
+		$image_name = $proc_info['wf_normalized_name'] . SEP . 'graph' . SEP . $proc_info['wf_normalized_name'] . '.png';
+		$image = GALAXIA_PROCESSES . SEP . $image_name;
+		if (Factory::getInstance('BrowserInfo')->isOpera())
+			$maximumDimension = 1000000;
+		else
+			$maximumDimension = 2500;
+
+		$dims = getimagesize($image);
+		list($originalWidth, $originalHeight) = $dims;
+
+		/* the image must be resized */
+		if (max($originalWidth, $originalHeight) > $maximumDimension)
+		{
+			/* define the new width and height */
+			$newWidth = $newHeight = $maximumDimension;
+			if ($originalWidth > $originalHeight)
+				$newHeight = $maximumDimension * ($originalHeight / $originalWidth);
+			else
+				$newWidth = $maximumDimension * ($originalWidth / $originalHeight);
+
+			/* create the new image and send to the browser */
+			$smallerImage = imagecreatetruecolor($newWidth, $newHeight);
+			imagecopyresampled($smallerImage, imagecreatefrompng($image), 0, 0, 0, 0, $newWidth, $newHeight, $originalWidth, $originalHeight);
+			header('content-disposition: inline; filename=' . $image_name);
+			header('content-type: ' . $dims['mime']);
+			imagepng($smallerImage);
+		}
+		else
+		{
+			header('content-disposition: inline; filename=' . $image_name);
+			header('content-type: ' . $dims['mime']);
+			header('content-length: ' . filesize($image));
+			readfile($image);
+		}
+	}
+
+	/**
+	 * Dislays the activity agents config rows
+	 * @return void
+	 * @access public
+	 */
+	function display_agents_rows()
+	{
+		if (empty($this->agents))
+		{
+			$this->t->set_var(array('agents_config_rows' => ''));
+		}
+		else
+		{
+			$this->t->set_file('admin_agents', 'admin_agents.tpl');
+			foreach ($this->agents as $ui_agent)
+			{
+				//this is parsing the agent's admin template in the given template var
+				$ui_agent->showAdminActivityOptions('each_agent_rows');
+			}
+			$this->translate_template('admin_agents');
+			$this->t->parse('agents_config_rows', 'admin_agents');
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_wfruntime.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_wfruntime.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_wfruntime.inc.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'common' . SEP . 'WfRuntime.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_wfruntime extends WfRuntime
+	{
+		/**
+		 * Construtor da classe workflow_wfruntime
+		 * @access public
+		 * @return object
+		 */
+		function workflow_wfruntime()
+		{
+			parent::WfRuntime(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.WorkflowLDAP.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.WorkflowLDAP.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.WorkflowLDAP.inc.php	(revision 2372)
@@ -0,0 +1,658 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Implements common LDAP methods
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class WorkflowLDAP
+{
+	/**
+	 * @var resource $dataSource Recurso de conexão com o LDAP
+	 * @access private
+	 */
+	private $dataSource;
+
+	/**
+	 * @var string $userContext Contexto do usuário
+	 * @access private
+	 */
+	private $userContext;
+
+	/**
+	 * @var string $groupContext Contexto do grupo
+	 * @access private
+	 */
+	private $groupContext;
+
+	/**
+	 * @var string $ldapContext Contexto do LDAP
+	 * @access private
+	 */
+	private $ldapContext;
+
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	function WorkflowLDAP()
+	{
+		$this->dataSource =& Factory::getInstance('WorkflowObjects')->getLDAP();
+
+		/* get the required parameters */
+		$info = (isset($GLOBALS['phpgw_info']['server']['ldap_context'])) ?
+			$GLOBALS['phpgw_info']['server'] :
+			$_SESSION['phpgw_info']['workflow']['server'];
+		$ldapConfigValues = galaxia_get_config_values(array('ldap_user_context' => '', 'ldap_group_context' => ''));
+		if (empty($ldapConfigValues['ldap_user_context']))
+			$ldapConfigValues['ldap_user_context'] = $info['ldap_context'];
+		if (empty($ldapConfigValues['ldap_group_context']))
+			$ldapConfigValues['ldap_group_context'] = $info['ldap_group_context'];
+		$this->userContext = $ldapConfigValues['ldap_user_context'];
+		$this->groupContext = $ldapConfigValues['ldap_group_context'];
+		$this->ldapContext = $ldapConfigValues['ldap_user_context'];
+
+		$this->cache = array(
+			'getEntities' => array(),
+			'getUserGroups' => array(),
+			'getGroupUsers' => array(),
+			'getOrganizations' => array(),
+			'getNames' => array()
+		);
+	}
+
+	/**
+	 * Checa se um método, e seus parâmetros, já estãoe em cache
+	 * @param string $methodName O nome do método que se quer verificar
+	 * @param string $parameters Parâmetros passados para o método (serializados)
+	 * @return bool true se foi encontrada uma versão em cache dos dados solicitados e false caso contrário
+	 * @access private
+	 */
+	private function checkCache($methodName, $parameters)
+	{
+		return isset($this->cache[$methodName][$parameters]);
+	}
+
+	/**
+	 * Pega a informação, em cache, de um método e seus parâmetros
+	 * @param string $methodName O nome do método que está em cache
+	 * @param string $parameters Parâmetros passados para o método (serializados)
+	 * @return mixed O retorno do método usando os parâmetros passados
+	 * @access private
+	 */
+	private function getCache($methodName, $parameters)
+	{
+		return $this->cache[$methodName][$parameters];
+	}
+
+	/**
+	 * Coloca em cache um método e seus parâmetros
+	 * @param string $methodName O nome do método
+	 * @param string $parameters Parâmetros passados para o método (serializados)
+	 * @param mixed $output Saída do método usando os parâmetros passados
+	 * @return mixed A saída igual ao parâmetro $output
+	 * @access private
+	 */
+	private function setCache($methodName, $parameters, $output)
+	{
+		$this->cache[$methodName][$parameters] = $output;
+		return $output;
+	}
+
+	/**
+	 * Faz consultas ao LDAP
+	 * @param string $context Contexto das entidades
+	 * @param string $filter Filtro utilizado para selecionar as entidades desejadas
+	 * @param array $elements Array dos campos que se deseja obter
+	 * @param bool $depthSearch Indica se a busca deve incluir sub-árvores ou não
+	 * @param string $elementSort O elemento pelo qual se quer ordenar o resultado
+	 * @return mixed Array do resultado. Ou false em caso de erro
+	 * @access private
+	 */
+	private function runLDAP($context, $filter, $elements, $depthSearch = false, $elementSort = null)
+	{
+		if ($depthSearch)
+			$resourceIdentifier = ldap_search($this->dataSource, $context, $filter, $elements);
+		else
+			$resourceIdentifier = ldap_list($this->dataSource, $context, $filter, $elements);
+
+		if (!$resourceIdentifier)
+			return false;
+
+		if (!is_null($elementSort))
+			ldap_sort($this->dataSource, $resourceIdentifier, $elementSort);
+
+		$output = ldap_get_entries($this->dataSource, $resourceIdentifier);
+		return $output;
+	}
+
+	/**
+	 * Faz consultas ao LDAP (inclusive com campos binários)
+	 * @param string $context Contexto das entidades
+	 * @param string $filter Filtro utilizado para selecionar as entidades desejadas
+	 * @param array $elements Array dos campos que se deseja obter
+	 * @param bool $depthSearch Indica se a busca deve incluir sub-árvores ou não
+	 * @param string $elementSort O elemento pelo qual se quer ordenar o resultado
+	 * @return mixed Array do resultado. Ou false em caso de erro
+	 * @access private
+	 */
+	private function runBinaryLDAP($context, $filter, $elements, $depthSearch = false, $elementSort = null)
+	{
+		if ($depthSearch)
+			$resourceIdentifier = ldap_search($this->dataSource, $context, $filter, $elements);
+		else
+			$resourceIdentifier = ldap_list($this->dataSource, $context, $filter, $elements);
+
+		if (!$resourceIdentifier)
+			return false;
+
+		if (!is_null($elementSort))
+			ldap_sort($this->dataSource, $resourceIdentifier, $elementSort);
+
+		$entry = ldap_first_entry($this->dataSource, $resourceIdentifier);
+		if (!$entry)
+			return array();
+
+		$output = array();
+		$counter = 0;
+		do
+		{
+			$attributes = ldap_get_attributes($this->dataSource, $entry);
+			for ($i = 0; $i < $attributes['count']; $i++)
+				$output[$counter][$attributes[$i]] = ldap_get_values_len($this->dataSource, $entry, $attributes[$i]);
+
+			$counter++;
+		} while ($entry = ldap_next_entry($this->dataSource, $entry));
+
+		return $output;
+	}
+
+	/**
+	 * Busca entidades (usuários, grupos ou listas públicas) do LDAP
+	 * @param string $context Contexto das entidades
+	 * @param string $filter Filtro utilizado para selecionar as entidades desejadas
+	 * @param array $elements Array dos campos que representa, nesta ordem: o ID, o nome e o e-mail da entidade
+	 * @param char $type O tipo da entidade: 'u' para usuários; 'g' para grupos; e 'l' para listas públicas
+	 * @param bool $depthSearch Indica se a busca deve incluir sub-árvores ou não
+	 * @return array Array das entidades
+	 * @access private
+	 */
+	private function getEntities($context, $filter, $elements, $type, $depthSearch = false)
+	{
+		/* check if the required information is in cache */
+		$methodName = 'getEntities';
+		$parameters = serialize(func_get_args());
+		if ($this->checkCache($methodName, $parameters))
+			return $this->getCache($methodName, $parameters);
+
+		$result = $this->runLDAP($context, $filter, $elements, $depthSearch, $elements[1]);
+
+		$output = array();
+		for ($i = 0; $i < $result['count']; $i++)
+		{
+			$output[] = array(
+				'id' => $result[$i][$elements[0]][0],
+				'name' => $result[$i][$elements[1]][0],
+				'type' => $type,
+				'mail' => $result[$i][$elements[2]][0]);
+		}
+
+		/* store the information in cache and return the output */
+		return $this->setCache($methodName, $parameters, $output);
+	}
+
+	/**
+	 * Retorna os grupos de um usuário
+	 * @param int $userID O ID do usuário
+	 * @return array Array dos grupos
+	 * @access public
+	 */
+	function getUserGroups($userID)
+	{
+		/* do not perform any search if the user is '*' */
+		if ($userID == '*')
+			return array();
+
+		/* check if the required information is in cache */
+		$methodName = 'getUserGroups';
+		$parameters = serialize(func_get_args());
+		if ($this->checkCache($methodName, $parameters))
+			return $this->getCache($methodName, $parameters);
+
+		/* check for error in connection */
+		if (!$this->dataSource)
+			return false;
+
+		/* first, get the UID */
+		$resourceIdentifier = ldap_search($this->dataSource, $this->userContext, "(&(phpgwaccounttype=u)(uidnumber={$userID}))", array('uid'));
+		$result = ldap_get_entries($this->dataSource, $resourceIdentifier);
+		if (!isset($result[0]['uid'][0]))
+			return false;
+		$userLogin = $result[0]['uid'][0];
+
+		/* initialize some variables */
+		$output = array();
+
+		/* search the LDAP tree */
+		$resourceIdentifier = ldap_search($this->dataSource, $this->groupContext, "(&(phpgwaccounttype=g)(memberuid={$userLogin}))", array('gidnumber'));
+		$result = ldap_get_entries($this->dataSource, $resourceIdentifier);
+		for ($i = 0; $i < $result['count']; $i++)
+			$output[] = $result[$i]['gidnumber'][0];
+
+		/* store the information in cache and return the output */
+		return $this->setCache($methodName, $parameters, $output);
+	}
+
+	/**
+	 * Retorna os usuários de um grupo
+	 * @param int $groupID O ID do grupo
+	 * @return array Array dos usuários
+	 * @access public
+	 */
+	function getGroupUsers($groupID)
+	{
+		/* check if the required information is in cache */
+		$methodName = 'getGroupUsers';
+		$parameters = serialize(func_get_args());
+		if ($this->checkCache($methodName, $parameters))
+			return $this->getCache($methodName, $parameters);
+
+		/* check for error in connection */
+		if (!$this->dataSource)
+			return false;
+
+		/* first, we get the UIDs that are members of the group */
+		$resourceIdentifier = ldap_search($this->dataSource, $this->ldapContext, "(&(phpgwaccounttype=g)(gidnumber={$groupID}))", array('memberuid'));
+		$result = ldap_get_entries($this->dataSource, $resourceIdentifier);
+		if (!isset($result[0]['memberuid'][0]))
+			return false;
+
+		$userLogins = $result[0]['memberuid'];
+		unset($userLogins['count']);
+
+		/* load the user information ten users at a time. This approach was proven to be faster on some systems */
+		$result = array();
+		while (count($userLogins) > 0)
+		{
+			$selectedUserLogins = array_splice($userLogins, 0, 10);
+			$resourceIdentifier = ldap_search($this->dataSource, $this->ldapContext, "(&(phpgwaccounttype=u)(|" . implode('', array_map(create_function('$a', 'return "(uid={$a})";'), $selectedUserLogins)) . "))", array('cn', 'uidnumber'));
+			$result = array_merge($result, ldap_get_entries($this->dataSource, $resourceIdentifier));
+			unset($result['count']);
+		}
+
+		$output = array();
+		$userCount = count($result);
+		for ($i = 0; $i < $userCount; $i++)
+			$output[] = array(
+				'account_id' => $result[$i]['uidnumber'][0],
+				'account_name' => $result[$i]['cn'][0]);
+
+		/* sort the result */
+		usort($output, create_function('$a,$b', 'return strcasecmp($a[\'account_name\'],$b[\'account_name\']);'));
+
+		/* store the information in cache and return the output */
+		return $this->setCache($methodName, $parameters, $output);
+	}
+
+	/**
+	 * Retorna as organizações do nível raiz
+	 * @return array Array de organizações
+	 * @access public
+	 */
+	function getOrganizations()
+	{
+		/* check if the required information is in cache */
+		$methodName = 'getOrganizations';
+		$parameters = serialize(func_get_args());
+		if ($this->checkCache($methodName, $parameters))
+			return $this->getCache($methodName, $parameters);
+
+		/* check for error in connection */
+		if (!$this->dataSource)
+			return false;
+
+		/* load the sectors of level 0 as organizations, then format the data */
+		$output = array_map(create_function('$a', 'return $a[\'ou\'];'), $this->getSectors());
+
+		/* store the information in cache and return the output */
+		return $this->setCache($methodName, $parameters, $output);
+	}
+
+	/**
+	 * Retorna os setores de um determinado contexto
+	 * @param string $organization A organização a partir da qual a busca deve inciar. Utilize null para o nível raiz
+	 * @param bool $recursive Indica se a busca deve ser recursiva ou não. true indica que deve ser recursiva e false que não deve ser recursiva
+	 * @param string $contextBase A base do contexto. Utilize null para o contexto padrão
+	 * @param int $level Indica o nível atual de recursão
+	 * @return array Array de setores
+	 * @access public
+	 */
+	function getSectors($organization = null, $recursive = false, $contextBase = null, $level = 0)
+	{
+		/* determines the context in which the search will be performed */
+		$context = (!is_null($contextBase) ? $contextBase : $this->ldapContext);
+		$context = (!is_null($organization) ? 'ou=' . $organization . ',' : '') . $context;
+
+		/* search for the sectors */
+		$resourceIdentifier = @ldap_list($this->dataSource, $context, '(objectClass=organizationalUnit)', array('ou'));
+		if ($resourceIdentifier === false)
+			return false;
+
+		ldap_sort($this->dataSource, $resourceIdentifier, 'ou');
+		$result = ldap_get_entries($this->dataSource, $resourceIdentifier);
+
+		/* collect the data */
+		$output = array();
+		for ($i = 0; $i < $result['count']; $i++)
+		{
+			$output[] = array(
+				'dn' => $result[$i]['dn'],
+				'ou' => $result[$i]['ou'][0],
+				'level' => $level);
+
+			/* if requested, perform a recursive search */
+			if ($recursive)
+				$output = array_merge($output, $this->getSectors($result[$i]['ou'][0], $recursive, $context, $level + 1));
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Retorna os usuários de um determinado contexto
+	 * @param string $context O contexto a partir do qual a busca deve começar
+	 * @return array Array dos usuários encontrados
+	 * @access public
+	 */
+	function getUsers($context)
+	{
+		$filter = '(&(phpgwaccounttype=u)(!(phpgwAccountVisible=-1)))';
+		$elements = array('uidnumber', 'cn', 'mail');
+		return $this->getEntities($context, $filter, $elements, 'u', false);
+	}
+
+	/**
+	 * Retorna os grupos de um determinado contexto
+	 * @param string $context O contexto a partir do qual a busca deve começar
+	 * @return array Array dos grupos encontrados
+	 * @access public
+	 */
+	function getGroups($context)
+	{
+		$filter = '(phpgwaccounttype=g)';
+		$elements = array('gidnumber', 'cn', 'mail');
+		return $this->getEntities($context, $filter, $elements, 'g', false);
+	}
+
+	/**
+	 * Retorna listas públicas de um determinado contexto
+	 * @param string $context O contexto a partir do qual a busca deve começar
+	 * @return array Array das listas públicas encontradas
+	 * @access public
+	 */
+	function getPublicLists($context)
+	{
+		$filter = '(phpgwaccounttype=l)';
+		$elements = array('uidnumber', 'cn', 'mail');
+		return $this->getEntities($context, $filter, $elements, 'l', false);
+	}
+
+	/**
+	 * Retornar informação sobre um usuário
+	 * @param int $userID O ID do usuário
+	 * @return mixed Array contento informação sobre um usuário ou false se o usuário não for encontrado
+	 * @access public
+	 */
+	function getUserInfo($userID)
+	{
+		$filter = '(&(phpgwaccounttype=u)(uidnumber=' . $userID . '))';
+		$elements = array('uidnumber', 'cn', 'mail');
+		$output = $this->getEntities($this->ldapContext, $filter, $elements, 'u', true);
+		if (count($output) == 1)
+			return $output[0];
+		else
+			return false;
+	}
+
+	function getUserPicture($userID)
+	{
+		$userID = (int) $userID;
+		$filter = '(&(phpgwaccounttype=u)(uidnumber=' . $userID . '))';
+		$elements = array('jpegPhoto');
+		$result = $this->runBinaryLDAP($this->ldapContext, $filter, $elements, true);
+
+		if (isset($result[0]['jpegPhoto'][0]))
+			return $result[0]['jpegPhoto'][0];
+
+		return false;
+	}
+
+	/**
+	 * Retrieves information about a group
+	 * @param int $userID The ID of the group
+	 * @return mixed Array containing information about a group or false if the group is not found
+	 * @access public
+	 */
+	function getGroupInfo($groupID)
+	{
+		$filter = '(&(phpgwaccounttype=g)(gidnumber=' . $groupID . '))';
+		$elements = array('gidnumber', 'cn', 'mail');
+		$output = $this->getEntities($this->ldapContext, $filter, $elements, 'g', true);
+		if (count($output) == 1)
+			return $output[0];
+		else
+			return false;
+	}
+
+	/**
+	 * Retorna o tipo de uma entidade
+	 * @param int $entityID O ID da entidade
+	 * @return string O tipo da entidade ('g' para grupo e 'u' para usuário)
+	 * @access public
+	 */
+	function getEntityType($entityID)
+	{
+		if ($entityID == '*')
+			return false;
+
+		$output = $this->getUserInfo($entityID);
+		if (is_array($output))
+			return 'u';
+		else
+		{
+			$output = $this->getGroupInfo($entityID);
+			if (is_array($output))
+				return 'g';
+		}
+
+		return false;
+	}
+
+	/**
+	 * Retorna o nome de uma entidade
+	 * @param int $entityID O ID da entidade
+	 * @return string O nome da entidade
+	 * @access public
+	 */
+	function getName($entityID)
+	{
+		if ($entityID == '*')
+			return '*';
+		$output = $this->getUserInfo($entityID);
+		if (is_array($output))
+			return $output['name'];
+		else
+		{
+			$output = $this->getGroupInfo($entityID);
+			if (is_array($output))
+				return $output['name'];
+		}
+	}
+
+	/**
+	 * Retorna os nomes de uma entidade
+	 * @param array $entitiesID Os IDs das entidades
+	 * @return string Os nomes das entidades
+	 * @access public
+	 */
+	function getNames($entitiesID)
+	{
+		/* check if the required information is in cache */
+		$methodName = 'getNames';
+		$parameters = serialize(func_get_args());
+		if ($this->checkCache($methodName, $parameters))
+			return $this->getCache($methodName, $parameters);
+
+		/* check for error in connection */
+		if (!$this->dataSource)
+			return false;
+
+		/* check for '*' */
+		$asteriskIndex = array_search('*', $entitiesID);
+		if ($asteriskIndex !== false)
+			unset($entitiesID[$asteriskIndex]);
+
+		/* load the entity information ten entities at a time. This approach was proven to be faster on some systems */
+		$result = array();
+		while (count($entitiesID) > 0)
+		{
+			$selectedEntitiesID = array_splice($entitiesID, 0, 10);
+			$resourceIdentifier = ldap_search($this->dataSource, $this->ldapContext, "(|" . implode('', array_map(create_function('$a', 'return "(|(&(uidnumber={$a})(|(phpgwaccounttype=u)(phpgwaccounttype=l)))(&(gidnumber={$a})(phpgwaccounttype=g)))";'), array_unique($selectedEntitiesID))) . ')', array('cn', 'uidnumber', 'gidnumber', 'phpgwaccounttype'));
+			$result = array_merge($result, ldap_get_entries($this->dataSource, $resourceIdentifier));
+			unset($result['count']);
+		}
+
+		$output = array();
+		$entityCount = count($result);
+		for ($i = 0; $i < $entityCount; $i++)
+			$output[] = array(
+				'id' => ($result[$i]['phpgwaccounttype'][0] == 'g') ? $result[$i]['gidnumber'][0] : $result[$i]['uidnumber'][0],
+				'name' => $result[$i]['cn'][0]);
+
+		if ($asteriskIndex !== false)
+			$output[] = array('id' => '*', 'name' => '*');
+
+		/* sort the result */
+		usort($output, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+
+		/* store the information in cache and return the output */
+		return $this->setCache($methodName, $parameters, $output);
+	}
+
+	/**
+	 * Faz uma busca (em todo o catálogo) por um nome
+	 * @param string $searchTerm O termo que está sendo procurado (pode conter '*')
+	 * @param bool $includeUsers Indica se na busca devem ser incluídos os registros referentes a usuários (true por padrão)
+	 * @param bool $includeGroups Indica se na busca devem ser incluídos os registros referentes a grupos (false por padrão)
+	 * @param bool $includeLists Indica se na busca devem ser incluídos os registros referentes a listas (false por padrão)
+	 * @return array Uma array contendo os registros encontrados
+	 * @access public
+	 */
+	function search($searchTerm, $includeUsers = true, $includeGroups = false, $includeLists = false, $context = null)
+	{
+		if (!($includeUsers || $includeGroups || $includeLists))
+			return false;
+
+		if (is_null($context))
+			$context = $this->ldapContext;
+
+		/* check for error in connection */
+		if (!$this->dataSource)
+			return false;
+
+		$entityFilter = array();
+		if ($includeUsers)
+			$entityFilter[] = '(phpgwaccounttype=u)';
+		if ($includeGroups)
+			$entityFilter[] = '(phpgwaccounttype=g)';
+		if ($includeLists)
+			$entityFilter[] = '(phpgwaccounttype=l)';
+
+		if (count($entityFilter) > 1)
+			$entityFilter = '(|' . implode('', $entityFilter) . ')';
+		else
+			$entityFilter = $entityFilter[0];
+
+		$filter = "(&{$entityFilter}(cn={$searchTerm})(!(phpgwAccountVisible=-1)))";
+		$resourceIdentifier = ldap_search($this->dataSource, $context, $filter, array('cn', 'uidnumber', 'gidnumber', 'phpgwaccounttype', 'mail'));
+		ldap_sort($this->dataSource, $resourceIdentifier, 'cn');
+		$result = ldap_get_entries($this->dataSource, $resourceIdentifier);
+
+		$output = array();
+		for ($i = 0; $i < $result['count']; $i++)
+			$output[] = array(
+				'id' => ($result[$i]['phpgwaccounttype'][0] == 'g') ? $result[$i]['gidnumber'][0] : $result[$i]['uidnumber'][0],
+				'name' => $result[$i]['cn'][0],
+				'mail' => $result[$i]['mail'][0],
+				'type' => $result[$i]['phpgwaccounttype'][0],
+				'dn' => $result[$i]['dn']
+			);
+
+		/* store the information in cache and return the output */
+		return $output;
+	}
+
+	/**
+	 * Retorna o contexto de usuários do LDAP
+	 * @return string O contexto de usuários do LDAP
+	 * @access public
+	 */
+	function getUserContext()
+	{
+		return $this->userContext;
+	}
+
+	/**
+	 * Retorna o contexto de grupos do LDAP
+	 * @return string O contexto de grupos do LDAP
+	 * @access public
+	 */
+	function getGroupContext()
+	{
+		return $this->groupContext;
+	}
+
+	/**
+	 * Retorna o contexto do LDAP
+	 * @return string O contexto do LDAP
+	 * @access public
+	 */
+	function getLDAPContext()
+	{
+		return $this->ldapContext;
+	}
+
+	/**
+	 * Retorna a organização de um DN
+	 * @param mixed $DN O DN do usuário
+	 * @return mixed Uma string contendo a organização ou false caso não seja achada a organização
+	 * @access public
+	 */
+	public function getOrganizationFromDN($DN)
+	{
+		$userContext = str_replace(' ', '', $this->userContext);
+		$DN = str_replace(' ', '', $DN);
+		$userInfo = array_reverse(explode(',', substr($DN, 0, - (strlen($userContext) + 1))));
+		foreach ($userInfo as $attributePair)
+		{
+			list($name, $value) = explode('=', $attributePair, 2);
+			if ($name === 'ou')
+				return $value;
+		}
+
+		return false;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/fpdf.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/fpdf.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/fpdf.php	(revision 795)
@@ -0,0 +1,1649 @@
+<?php
+/*******************************************************************************
+* Software: FPDF                                                               *
+* Version:  1.53                                                               *
+* Date:     2004-12-31                                                         *
+* Author:   Olivier PLATHEY                                                    *
+* License:  Freeware
+* @package	Workflow
+* @subpackage	fpdf                                                           *
+*                                                                              *
+* You may use, modify and redistribute this software as you wish.              *
+*******************************************************************************/
+
+if(!class_exists('FPDF'))
+{
+define('FPDF_VERSION','1.53');
+
+class FPDF
+{
+//Private properties
+var $page;               //current page number
+var $n;                  //current object number
+var $offsets;            //array of object offsets
+var $buffer;             //buffer holding in-memory PDF
+var $pages;              //array containing pages
+var $state;              //current document state
+var $compress;           //compression flag
+var $DefOrientation;     //default orientation
+var $CurOrientation;     //current orientation
+var $OrientationChanges; //array indicating orientation changes
+var $k;                  //scale factor (number of points in user unit)
+var $fwPt,$fhPt;         //dimensions of page format in points
+var $fw,$fh;             //dimensions of page format in user unit
+var $wPt,$hPt;           //current dimensions of page in points
+var $w,$h;               //current dimensions of page in user unit
+var $lMargin;            //left margin
+var $tMargin;            //top margin
+var $rMargin;            //right margin
+var $bMargin;            //page break margin
+var $cMargin;            //cell margin
+var $x,$y;               //current position in user unit for cell positioning
+var $lasth;              //height of last cell printed
+var $LineWidth;          //line width in user unit
+var $CoreFonts;          //array of standard font names
+var $fonts;              //array of used fonts
+var $FontFiles;          //array of font files
+var $diffs;              //array of encoding differences
+var $images;             //array of used images
+var $PageLinks;          //array of links in pages
+var $links;              //array of internal links
+var $FontFamily;         //current font family
+var $FontStyle;          //current font style
+var $underline;          //underlining flag
+var $CurrentFont;        //current font info
+var $FontSizePt;         //current font size in points
+var $FontSize;           //current font size in user unit
+var $DrawColor;          //commands for drawing color
+var $FillColor;          //commands for filling color
+var $TextColor;          //commands for text color
+var $ColorFlag;          //indicates whether fill and text colors are different
+var $ws;                 //word spacing
+var $AutoPageBreak;      //automatic page breaking
+var $PageBreakTrigger;   //threshold used to trigger page breaks
+var $InFooter;           //flag set when processing footer
+var $ZoomMode;           //zoom display mode
+var $LayoutMode;         //layout display mode
+var $title;              //title
+var $subject;            //subject
+var $author;             //author
+var $keywords;           //keywords
+var $creator;            //creator
+var $AliasNbPages;       //alias for total number of pages
+var $PDFVersion;         //PDF version number
+
+/*******************************************************************************
+*                                                                              *
+*                               Public methods                                 *
+*                                                                              *
+*******************************************************************************/
+function FPDF($orientation='P',$unit='mm',$format='A4')
+{
+	//Some checks
+	$this->_dochecks();
+	//Initialization of properties
+	$this->page=0;
+	$this->n=2;
+	$this->buffer='';
+	$this->pages=array();
+	$this->OrientationChanges=array();
+	$this->state=0;
+	$this->fonts=array();
+	$this->FontFiles=array();
+	$this->diffs=array();
+	$this->images=array();
+	$this->links=array();
+	$this->InFooter=false;
+	$this->lasth=0;
+	$this->FontFamily='';
+	$this->FontStyle='';
+	$this->FontSizePt=12;
+	$this->underline=false;
+	$this->DrawColor='0 G';
+	$this->FillColor='0 g';
+	$this->TextColor='0 g';
+	$this->ColorFlag=false;
+	$this->ws=0;
+	//Standard fonts
+	$this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
+		'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
+		'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
+		'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
+	//Scale factor
+	if($unit=='pt')
+		$this->k=1;
+	elseif($unit=='mm')
+		$this->k=72/25.4;
+	elseif($unit=='cm')
+		$this->k=72/2.54;
+	elseif($unit=='in')
+		$this->k=72;
+	else
+		$this->Error('Incorrect unit: '.$unit);
+	//Page format
+	if(is_string($format))
+	{
+		$format=strtolower($format);
+		if($format=='a3')
+			$format=array(841.89,1190.55);
+		elseif($format=='a4')
+			$format=array(595.28,841.89);
+		elseif($format=='a5')
+			$format=array(420.94,595.28);
+		elseif($format=='letter')
+			$format=array(612,792);
+		elseif($format=='legal')
+			$format=array(612,1008);
+		else
+			$this->Error('Unknown page format: '.$format);
+		$this->fwPt=$format[0];
+		$this->fhPt=$format[1];
+	}
+	else
+	{
+		$this->fwPt=$format[0]*$this->k;
+		$this->fhPt=$format[1]*$this->k;
+	}
+	$this->fw=$this->fwPt/$this->k;
+	$this->fh=$this->fhPt/$this->k;
+	//Page orientation
+	$orientation=strtolower($orientation);
+	if($orientation=='p' || $orientation=='portrait')
+	{
+		$this->DefOrientation='P';
+		$this->wPt=$this->fwPt;
+		$this->hPt=$this->fhPt;
+	}
+	elseif($orientation=='l' || $orientation=='landscape')
+	{
+		$this->DefOrientation='L';
+		$this->wPt=$this->fhPt;
+		$this->hPt=$this->fwPt;
+	}
+	else
+		$this->Error('Incorrect orientation: '.$orientation);
+	$this->CurOrientation=$this->DefOrientation;
+	$this->w=$this->wPt/$this->k;
+	$this->h=$this->hPt/$this->k;
+	//Page margins (1 cm)
+	$margin=28.35/$this->k;
+	$this->SetMargins($margin,$margin);
+	//Interior cell margin (1 mm)
+	$this->cMargin=$margin/10;
+	//Line width (0.2 mm)
+	$this->LineWidth=.567/$this->k;
+	//Automatic page break
+	$this->SetAutoPageBreak(true,2*$margin);
+	//Full width display mode
+	$this->SetDisplayMode('fullwidth');
+	//Enable compression
+	$this->SetCompression(true);
+	//Set default PDF version number
+	$this->PDFVersion='1.3';
+}
+
+function SetMargins($left,$top,$right=-1)
+{
+	//Set left, top and right margins
+	$this->lMargin=$left;
+	$this->tMargin=$top;
+	if($right==-1)
+		$right=$left;
+	$this->rMargin=$right;
+}
+
+function SetLeftMargin($margin)
+{
+	//Set left margin
+	$this->lMargin=$margin;
+	if($this->page>0 && $this->x<$margin)
+		$this->x=$margin;
+}
+
+function SetTopMargin($margin)
+{
+	//Set top margin
+	$this->tMargin=$margin;
+}
+
+function SetRightMargin($margin)
+{
+	//Set right margin
+	$this->rMargin=$margin;
+}
+
+function SetAutoPageBreak($auto,$margin=0)
+{
+	//Set auto page break mode and triggering margin
+	$this->AutoPageBreak=$auto;
+	$this->bMargin=$margin;
+	$this->PageBreakTrigger=$this->h-$margin;
+}
+
+function SetDisplayMode($zoom,$layout='continuous')
+{
+	//Set display mode in viewer
+	if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom))
+		$this->ZoomMode=$zoom;
+	else
+		$this->Error('Incorrect zoom display mode: '.$zoom);
+	if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default')
+		$this->LayoutMode=$layout;
+	else
+		$this->Error('Incorrect layout display mode: '.$layout);
+}
+
+function SetCompression($compress)
+{
+	//Set page compression
+	if(function_exists('gzcompress'))
+		$this->compress=$compress;
+	else
+		$this->compress=false;
+}
+
+function SetTitle($title)
+{
+	//Title of document
+	$this->title=$title;
+}
+
+function SetSubject($subject)
+{
+	//Subject of document
+	$this->subject=$subject;
+}
+
+function SetAuthor($author)
+{
+	//Author of document
+	$this->author=$author;
+}
+
+function SetKeywords($keywords)
+{
+	//Keywords of document
+	$this->keywords=$keywords;
+}
+
+function SetCreator($creator)
+{
+	//Creator of document
+	$this->creator=$creator;
+}
+
+function AliasNbPages($alias='{nb}')
+{
+	//Define an alias for total number of pages
+	$this->AliasNbPages=$alias;
+}
+
+function Error($msg)
+{
+	//Fatal error
+	die('<B>FPDF error: </B>'.$msg);
+}
+
+function Open()
+{
+	//Begin document
+	$this->state=1;
+}
+
+function Close()
+{
+	//Terminate document
+	if($this->state==3)
+		return;
+	if($this->page==0)
+		$this->AddPage();
+	//Page footer
+	$this->InFooter=true;
+	$this->Footer();
+	$this->InFooter=false;
+	//Close page
+	$this->_endpage();
+	//Close document
+	$this->_enddoc();
+}
+
+function AddPage($orientation='')
+{
+	//Start a new page
+	if($this->state==0)
+		$this->Open();
+	$family=$this->FontFamily;
+	$style=$this->FontStyle.($this->underline ? 'U' : '');
+	$size=$this->FontSizePt;
+	$lw=$this->LineWidth;
+	$dc=$this->DrawColor;
+	$fc=$this->FillColor;
+	$tc=$this->TextColor;
+	$cf=$this->ColorFlag;
+	if($this->page>0)
+	{
+		//Page footer
+		$this->InFooter=true;
+		$this->Footer();
+		$this->InFooter=false;
+		//Close page
+		$this->_endpage();
+	}
+	//Start new page
+	$this->_beginpage($orientation);
+	//Set line cap style to square
+	$this->_out('2 J');
+	//Set line width
+	$this->LineWidth=$lw;
+	$this->_out(sprintf('%.2f w',$lw*$this->k));
+	//Set font
+	if($family)
+		$this->SetFont($family,$style,$size);
+	//Set colors
+	$this->DrawColor=$dc;
+	if($dc!='0 G')
+		$this->_out($dc);
+	$this->FillColor=$fc;
+	if($fc!='0 g')
+		$this->_out($fc);
+	$this->TextColor=$tc;
+	$this->ColorFlag=$cf;
+	//Page header
+	$this->Header();
+	//Restore line width
+	if($this->LineWidth!=$lw)
+	{
+		$this->LineWidth=$lw;
+		$this->_out(sprintf('%.2f w',$lw*$this->k));
+	}
+	//Restore font
+	if($family)
+		$this->SetFont($family,$style,$size);
+	//Restore colors
+	if($this->DrawColor!=$dc)
+	{
+		$this->DrawColor=$dc;
+		$this->_out($dc);
+	}
+	if($this->FillColor!=$fc)
+	{
+		$this->FillColor=$fc;
+		$this->_out($fc);
+	}
+	$this->TextColor=$tc;
+	$this->ColorFlag=$cf;
+}
+
+function Header()
+{
+	//To be implemented in your own inherited class
+}
+
+function Footer()
+{
+	//To be implemented in your own inherited class
+}
+
+function PageNo()
+{
+	//Get current page number
+	return $this->page;
+}
+
+function SetDrawColor($r,$g=-1,$b=-1)
+{
+	//Set color for all stroking operations
+	if(($r==0 && $g==0 && $b==0) || $g==-1)
+		$this->DrawColor=sprintf('%.3f G',$r/255);
+	else
+		$this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
+	if($this->page>0)
+		$this->_out($this->DrawColor);
+}
+
+function SetFillColor($r,$g=-1,$b=-1)
+{
+	//Set color for all filling operations
+	if(($r==0 && $g==0 && $b==0) || $g==-1)
+		$this->FillColor=sprintf('%.3f g',$r/255);
+	else
+		$this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
+	$this->ColorFlag=($this->FillColor!=$this->TextColor);
+	if($this->page>0)
+		$this->_out($this->FillColor);
+}
+
+function SetTextColor($r,$g=-1,$b=-1)
+{
+	//Set color for text
+	if(($r==0 && $g==0 && $b==0) || $g==-1)
+		$this->TextColor=sprintf('%.3f g',$r/255);
+	else
+		$this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
+	$this->ColorFlag=($this->FillColor!=$this->TextColor);
+}
+
+function GetStringWidth($s)
+{
+	//Get width of a string in the current font
+	$s=(string)$s;
+	$cw=&$this->CurrentFont['cw'];
+	$w=0;
+	$l=strlen($s);
+	for($i=0;$i<$l;$i++)
+		$w+=$cw[$s{$i}];
+	return $w*$this->FontSize/1000;
+}
+
+function SetLineWidth($width)
+{
+	//Set line width
+	$this->LineWidth=$width;
+	if($this->page>0)
+		$this->_out(sprintf('%.2f w',$width*$this->k));
+}
+
+function Line($x1,$y1,$x2,$y2)
+{
+	//Draw a line
+	$this->_out(sprintf('%.2f %.2f m %.2f %.2f l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k));
+}
+
+function Rect($x,$y,$w,$h,$style='')
+{
+	//Draw a rectangle
+	if($style=='F')
+		$op='f';
+	elseif($style=='FD' || $style=='DF')
+		$op='B';
+	else
+		$op='S';
+	$this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
+}
+
+function AddFont($family,$style='',$file='')
+{
+	//Add a TrueType or Type1 font
+	$family=strtolower($family);
+	if($file=='')
+		$file=str_replace(' ','',$family).strtolower($style).'.php';
+	if($family=='arial')
+		$family='helvetica';
+	$style=strtoupper($style);
+	if($style=='IB')
+		$style='BI';
+	$fontkey=$family.$style;
+	if(isset($this->fonts[$fontkey]))
+		$this->Error('Font already added: '.$family.' '.$style);
+	include($this->_getfontpath().$file);
+	if(!isset($name))
+		$this->Error('Could not include font definition file');
+	$i=count($this->fonts)+1;
+	$this->fonts[$fontkey]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file);
+	if($diff)
+	{
+		//Search existing encodings
+		$d=0;
+		$nb=count($this->diffs);
+		for($i=1;$i<=$nb;$i++)
+		{
+			if($this->diffs[$i]==$diff)
+			{
+				$d=$i;
+				break;
+			}
+		}
+		if($d==0)
+		{
+			$d=$nb+1;
+			$this->diffs[$d]=$diff;
+		}
+		$this->fonts[$fontkey]['diff']=$d;
+	}
+	if($file)
+	{
+		if($type=='TrueType')
+			$this->FontFiles[$file]=array('length1'=>$originalsize);
+		else
+			$this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
+	}
+}
+
+function SetFont($family,$style='',$size=0)
+{
+	//Select a font; size given in points
+	global $fpdf_charwidths;
+
+	$family=strtolower($family);
+	if($family=='')
+		$family=$this->FontFamily;
+	if($family=='arial')
+		$family='helvetica';
+	elseif($family=='symbol' || $family=='zapfdingbats')
+		$style='';
+	$style=strtoupper($style);
+	if(strpos($style,'U')!==false)
+	{
+		$this->underline=true;
+		$style=str_replace('U','',$style);
+	}
+	else
+		$this->underline=false;
+	if($style=='IB')
+		$style='BI';
+	if($size==0)
+		$size=$this->FontSizePt;
+	//Test if font is already selected
+	if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size)
+		return;
+	//Test if used for the first time
+	$fontkey=$family.$style;
+	if(!isset($this->fonts[$fontkey]))
+	{
+		//Check if one of the standard fonts
+		if(isset($this->CoreFonts[$fontkey]))
+		{
+			if(!isset($fpdf_charwidths[$fontkey]))
+			{
+				//Load metric file
+				$file=$family;
+				if($family=='times' || $family=='helvetica')
+					$file.=strtolower($style);
+				include($this->_getfontpath().$file.'.php');
+				if(!isset($fpdf_charwidths[$fontkey]))
+					$this->Error('Could not include font metric file');
+			}
+			$i=count($this->fonts)+1;
+			$this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]);
+		}
+		else
+			$this->Error('Undefined font: '.$family.' '.$style);
+	}
+	//Select it
+	$this->FontFamily=$family;
+	$this->FontStyle=$style;
+	$this->FontSizePt=$size;
+	$this->FontSize=$size/$this->k;
+	$this->CurrentFont=&$this->fonts[$fontkey];
+	if($this->page>0)
+		$this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
+}
+
+function SetFontSize($size)
+{
+	//Set font size in points
+	if($this->FontSizePt==$size)
+		return;
+	$this->FontSizePt=$size;
+	$this->FontSize=$size/$this->k;
+	if($this->page>0)
+		$this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
+}
+
+function AddLink()
+{
+	//Create a new internal link
+	$n=count($this->links)+1;
+	$this->links[$n]=array(0,0);
+	return $n;
+}
+
+function SetLink($link,$y=0,$page=-1)
+{
+	//Set destination of internal link
+	if($y==-1)
+		$y=$this->y;
+	if($page==-1)
+		$page=$this->page;
+	$this->links[$link]=array($page,$y);
+}
+
+function Link($x,$y,$w,$h,$link)
+{
+	//Put a link on the page
+	$this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
+}
+
+function Text($x,$y,$txt)
+{
+	//Output a string
+	$s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt));
+	if($this->underline && $txt!='')
+		$s.=' '.$this->_dounderline($x,$y,$txt);
+	if($this->ColorFlag)
+		$s='q '.$this->TextColor.' '.$s.' Q';
+	$this->_out($s);
+}
+
+function AcceptPageBreak()
+{
+	//Accept automatic page break or not
+	return $this->AutoPageBreak;
+}
+
+function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
+{
+	//Output a cell
+	$k=$this->k;
+	if($this->y+$h>$this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak())
+	{
+		//Automatic page break
+		$x=$this->x;
+		$ws=$this->ws;
+		if($ws>0)
+		{
+			$this->ws=0;
+			$this->_out('0 Tw');
+		}
+		$this->AddPage($this->CurOrientation);
+		$this->x=$x;
+		if($ws>0)
+		{
+			$this->ws=$ws;
+			$this->_out(sprintf('%.3f Tw',$ws*$k));
+		}
+	}
+	if($w==0)
+		$w=$this->w-$this->rMargin-$this->x;
+	$s='';
+	if($fill==1 || $border==1)
+	{
+		if($fill==1)
+			$op=($border==1) ? 'B' : 'f';
+		else
+			$op='S';
+		$s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
+	}
+	if(is_string($border))
+	{
+		$x=$this->x;
+		$y=$this->y;
+		if(strpos($border,'L')!==false)
+			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
+		if(strpos($border,'T')!==false)
+			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
+		if(strpos($border,'R')!==false)
+			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
+		if(strpos($border,'B')!==false)
+			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
+	}
+	if($txt!=='')
+	{
+		if($align=='R')
+			$dx=$w-$this->cMargin-$this->GetStringWidth($txt);
+		elseif($align=='C')
+			$dx=($w-$this->GetStringWidth($txt))/2;
+		else
+			$dx=$this->cMargin;
+		if($this->ColorFlag)
+			$s.='q '.$this->TextColor.' ';
+		$txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
+		$s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
+		if($this->underline)
+			$s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
+		if($this->ColorFlag)
+			$s.=' Q';
+		if($link)
+			$this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
+	}
+	if($s)
+		$this->_out($s);
+	$this->lasth=$h;
+	if($ln>0)
+	{
+		//Go to next line
+		$this->y+=$h;
+		if($ln==1)
+			$this->x=$this->lMargin;
+	}
+	else
+		$this->x+=$w;
+}
+
+function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0)
+{
+	//Output text with automatic or explicit line breaks
+	$cw=&$this->CurrentFont['cw'];
+	if($w==0)
+		$w=$this->w-$this->rMargin-$this->x;
+	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
+	$s=str_replace("\r",'',$txt);
+	$nb=strlen($s);
+	if($nb>0 && $s[$nb-1]=="\n")
+		$nb--;
+	$b=0;
+	if($border)
+	{
+		if($border==1)
+		{
+			$border='LTRB';
+			$b='LRT';
+			$b2='LR';
+		}
+		else
+		{
+			$b2='';
+			if(strpos($border,'L')!==false)
+				$b2.='L';
+			if(strpos($border,'R')!==false)
+				$b2.='R';
+			$b=(strpos($border,'T')!==false) ? $b2.'T' : $b2;
+		}
+	}
+	$sep=-1;
+	$i=0;
+	$j=0;
+	$l=0;
+	$ns=0;
+	$nl=1;
+	while($i<$nb)
+	{
+		//Get next character
+		$c=$s{$i};
+		if($c=="\n")
+		{
+			//Explicit line break
+			if($this->ws>0)
+			{
+				$this->ws=0;
+				$this->_out('0 Tw');
+			}
+			$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
+			$i++;
+			$sep=-1;
+			$j=$i;
+			$l=0;
+			$ns=0;
+			$nl++;
+			if($border && $nl==2)
+				$b=$b2;
+			continue;
+		}
+		if($c==' ')
+		{
+			$sep=$i;
+			$ls=$l;
+			$ns++;
+		}
+		$l+=$cw[$c];
+		if($l>$wmax)
+		{
+			//Automatic line break
+			if($sep==-1)
+			{
+				if($i==$j)
+					$i++;
+				if($this->ws>0)
+				{
+					$this->ws=0;
+					$this->_out('0 Tw');
+				}
+				$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
+			}
+			else
+			{
+				if($align=='J')
+				{
+					$this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
+					$this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
+				}
+				$this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
+				$i=$sep+1;
+			}
+			$sep=-1;
+			$j=$i;
+			$l=0;
+			$ns=0;
+			$nl++;
+			if($border && $nl==2)
+				$b=$b2;
+		}
+		else
+			$i++;
+	}
+	//Last chunk
+	if($this->ws>0)
+	{
+		$this->ws=0;
+		$this->_out('0 Tw');
+	}
+	if($border && strpos($border,'B')!==false)
+		$b.='B';
+	$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
+	$this->x=$this->lMargin;
+}
+
+function Write($h,$txt,$link='')
+{
+	//Output text in flowing mode
+	$cw=&$this->CurrentFont['cw'];
+	$w=$this->w-$this->rMargin-$this->x;
+	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
+	$s=str_replace("\r",'',$txt);
+	$nb=strlen($s);
+	$sep=-1;
+	$i=0;
+	$j=0;
+	$l=0;
+	$nl=1;
+	while($i<$nb)
+	{
+		//Get next character
+		$c=$s{$i};
+		if($c=="\n")
+		{
+			//Explicit line break
+			$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
+			$i++;
+			$sep=-1;
+			$j=$i;
+			$l=0;
+			if($nl==1)
+			{
+				$this->x=$this->lMargin;
+				$w=$this->w-$this->rMargin-$this->x;
+				$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
+			}
+			$nl++;
+			continue;
+		}
+		if($c==' ')
+			$sep=$i;
+		$l+=$cw[$c];
+		if($l>$wmax)
+		{
+			//Automatic line break
+			if($sep==-1)
+			{
+				if($this->x>$this->lMargin)
+				{
+					//Move to next line
+					$this->x=$this->lMargin;
+					$this->y+=$h;
+					$w=$this->w-$this->rMargin-$this->x;
+					$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
+					$i++;
+					$nl++;
+					continue;
+				}
+				if($i==$j)
+					$i++;
+				$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
+			}
+			else
+			{
+				$this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
+				$i=$sep+1;
+			}
+			$sep=-1;
+			$j=$i;
+			$l=0;
+			if($nl==1)
+			{
+				$this->x=$this->lMargin;
+				$w=$this->w-$this->rMargin-$this->x;
+				$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
+			}
+			$nl++;
+		}
+		else
+			$i++;
+	}
+	//Last chunk
+	if($i!=$j)
+		$this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
+}
+
+function Image($file,$x,$y,$w=0,$h=0,$type='',$link='')
+{
+	//Put an image on the page
+	if(!isset($this->images[$file]))
+	{
+		//First use of image, get info
+		if($type=='')
+		{
+			$pos=strrpos($file,'.');
+			if(!$pos)
+				$this->Error('Image file has no extension and no type was specified: '.$file);
+			$type=substr($file,$pos+1);
+		}
+		$type=strtolower($type);
+		$mqr=get_magic_quotes_runtime();
+		set_magic_quotes_runtime(0);
+		if($type=='jpg' || $type=='jpeg')
+			$info=$this->_parsejpg($file);
+		elseif($type=='png')
+			$info=$this->_parsepng($file);
+		else
+		{
+			//Allow for additional formats
+			$mtd='_parse'.$type;
+			if(!method_exists($this,$mtd))
+				$this->Error('Unsupported image type: '.$type);
+			$info=$this->$mtd($file);
+		}
+		set_magic_quotes_runtime($mqr);
+		$info['i']=count($this->images)+1;
+		$this->images[$file]=$info;
+	}
+	else
+		$info=$this->images[$file];
+	//Automatic width and height calculation if needed
+	if($w==0 && $h==0)
+	{
+		//Put image at 72 dpi
+		$w=$info['w']/$this->k;
+		$h=$info['h']/$this->k;
+	}
+	if($w==0)
+		$w=$h*$info['w']/$info['h'];
+	if($h==0)
+		$h=$w*$info['h']/$info['w'];
+	$this->_out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i']));
+	if($link)
+		$this->Link($x,$y,$w,$h,$link);
+}
+
+function Ln($h='')
+{
+	//Line feed; default value is last cell height
+	$this->x=$this->lMargin;
+	if(is_string($h))
+		$this->y+=$this->lasth;
+	else
+		$this->y+=$h;
+}
+
+function GetX()
+{
+	//Get x position
+	return $this->x;
+}
+
+function SetX($x)
+{
+	//Set x position
+	if($x>=0)
+		$this->x=$x;
+	else
+		$this->x=$this->w+$x;
+}
+
+function GetY()
+{
+	//Get y position
+	return $this->y;
+}
+
+function SetY($y)
+{
+	//Set y position and reset x
+	$this->x=$this->lMargin;
+	if($y>=0)
+		$this->y=$y;
+	else
+		$this->y=$this->h+$y;
+}
+
+function SetXY($x,$y)
+{
+	//Set x and y positions
+	$this->SetY($y);
+	$this->SetX($x);
+}
+
+function Output($name='',$dest='')
+{
+	//Output PDF to some destination
+	//Finish document if necessary
+	if($this->state<3)
+		$this->Close();
+	//Normalize parameters
+	if(is_bool($dest))
+		$dest=$dest ? 'D' : 'F';
+	$dest=strtoupper($dest);
+	if($dest=='')
+	{
+		if($name=='')
+		{
+			$name='doc.pdf';
+			$dest='I';
+		}
+		else
+			$dest='F';
+	}
+	switch($dest)
+	{
+		case 'I':
+			//Send to standard output
+			if(ob_get_contents())
+				$this->Error('Some data has already been output, can\'t send PDF file');
+			if(php_sapi_name()!='cli')
+			{
+				//We send to a browser
+				header('Content-Type: application/pdf');
+				if(headers_sent())
+					$this->Error('Some data has already been output to browser, can\'t send PDF file');
+				header('Content-Length: '.strlen($this->buffer));
+				header('Content-disposition: inline; filename="'.$name.'"');
+			}
+			echo $this->buffer;
+			break;
+		case 'D':
+			//Download file
+			if(ob_get_contents())
+				$this->Error('Some data has already been output, can\'t send PDF file');
+			if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
+				header('Content-Type: application/force-download');
+			else
+				header('Content-Type: application/octet-stream');
+			if(headers_sent())
+				$this->Error('Some data has already been output to browser, can\'t send PDF file');
+			header('Content-Length: '.strlen($this->buffer));
+			header('Content-disposition: attachment; filename="'.$name.'"');
+			echo $this->buffer;
+			break;
+		case 'F':
+			//Save to local file
+			$f=fopen($name,'wb');
+			if(!$f)
+				$this->Error('Unable to create output file: '.$name);
+			fwrite($f,$this->buffer,strlen($this->buffer));
+			fclose($f);
+			break;
+		case 'S':
+			//Return as a string
+			return $this->buffer;
+		default:
+			$this->Error('Incorrect output destination: '.$dest);
+	}
+	return '';
+}
+
+/*******************************************************************************
+*                                                                              *
+*                              Protected methods                               *
+*                                                                              *
+*******************************************************************************/
+function _dochecks()
+{
+	//Check for locale-related bug
+	if(1.1==1)
+		$this->Error('Don\'t alter the locale before including class file');
+	//Check for decimal separator
+	if(sprintf('%.1f',1.0)!='1.0')
+		setlocale(LC_NUMERIC,'C');
+}
+
+function _getfontpath()
+{
+	if(!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font'))
+		define('FPDF_FONTPATH',dirname(__FILE__).'/font/');
+	return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : '';
+}
+
+function _putpages()
+{
+	$nb=$this->page;
+	if(!empty($this->AliasNbPages))
+	{
+		//Replace number of pages
+		for($n=1;$n<=$nb;$n++)
+			$this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
+	}
+	if($this->DefOrientation=='P')
+	{
+		$wPt=$this->fwPt;
+		$hPt=$this->fhPt;
+	}
+	else
+	{
+		$wPt=$this->fhPt;
+		$hPt=$this->fwPt;
+	}
+	$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+	for($n=1;$n<=$nb;$n++)
+	{
+		//Page
+		$this->_newobj();
+		$this->_out('<</Type /Page');
+		$this->_out('/Parent 1 0 R');
+		if(isset($this->OrientationChanges[$n]))
+			$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
+		$this->_out('/Resources 2 0 R');
+		if(isset($this->PageLinks[$n]))
+		{
+			//Links
+			$annots='/Annots [';
+			foreach($this->PageLinks[$n] as $pl)
+			{
+				$rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
+				$annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
+				if(is_string($pl[4]))
+					$annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
+				else
+				{
+					$l=$this->links[$pl[4]];
+					$h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt;
+					$annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
+				}
+			}
+			$this->_out($annots.']');
+		}
+		$this->_out('/Contents '.($this->n+1).' 0 R>>');
+		$this->_out('endobj');
+		//Page content
+		$p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
+		$this->_newobj();
+		$this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
+		$this->_putstream($p);
+		$this->_out('endobj');
+	}
+	//Pages root
+	$this->offsets[1]=strlen($this->buffer);
+	$this->_out('1 0 obj');
+	$this->_out('<</Type /Pages');
+	$kids='/Kids [';
+	for($i=0;$i<$nb;$i++)
+		$kids.=(3+2*$i).' 0 R ';
+	$this->_out($kids.']');
+	$this->_out('/Count '.$nb);
+	$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
+	$this->_out('>>');
+	$this->_out('endobj');
+}
+
+function _putfonts()
+{
+	$nf=$this->n;
+	foreach($this->diffs as $diff)
+	{
+		//Encodings
+		$this->_newobj();
+		$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
+		$this->_out('endobj');
+	}
+	$mqr=get_magic_quotes_runtime();
+	set_magic_quotes_runtime(0);
+	foreach($this->FontFiles as $file=>$info)
+	{
+		//Font file embedding
+		$this->_newobj();
+		$this->FontFiles[$file]['n']=$this->n;
+		$font='';
+		$f=fopen($this->_getfontpath().$file,'rb',1);
+		if(!$f)
+			$this->Error('Font file not found');
+		while(!feof($f))
+			$font.=fread($f,8192);
+		fclose($f);
+		$compressed=(substr($file,-2)=='.z');
+		if(!$compressed && isset($info['length2']))
+		{
+			$header=(ord($font{0})==128);
+			if($header)
+			{
+				//Strip first binary header
+				$font=substr($font,6);
+			}
+			if($header && ord($font{$info['length1']})==128)
+			{
+				//Strip second binary header
+				$font=substr($font,0,$info['length1']).substr($font,$info['length1']+6);
+			}
+		}
+		$this->_out('<</Length '.strlen($font));
+		if($compressed)
+			$this->_out('/Filter /FlateDecode');
+		$this->_out('/Length1 '.$info['length1']);
+		if(isset($info['length2']))
+			$this->_out('/Length2 '.$info['length2'].' /Length3 0');
+		$this->_out('>>');
+		$this->_putstream($font);
+		$this->_out('endobj');
+	}
+	set_magic_quotes_runtime($mqr);
+	foreach($this->fonts as $k=>$font)
+	{
+		//Font objects
+		$this->fonts[$k]['n']=$this->n+1;
+		$type=$font['type'];
+		$name=$font['name'];
+		if($type=='core')
+		{
+			//Standard font
+			$this->_newobj();
+			$this->_out('<</Type /Font');
+			$this->_out('/BaseFont /'.$name);
+			$this->_out('/Subtype /Type1');
+			if($name!='Symbol' && $name!='ZapfDingbats')
+				$this->_out('/Encoding /WinAnsiEncoding');
+			$this->_out('>>');
+			$this->_out('endobj');
+		}
+		elseif($type=='Type1' || $type=='TrueType')
+		{
+			//Additional Type1 or TrueType font
+			$this->_newobj();
+			$this->_out('<</Type /Font');
+			$this->_out('/BaseFont /'.$name);
+			$this->_out('/Subtype /'.$type);
+			$this->_out('/FirstChar 32 /LastChar 255');
+			$this->_out('/Widths '.($this->n+1).' 0 R');
+			$this->_out('/FontDescriptor '.($this->n+2).' 0 R');
+			if($font['enc'])
+			{
+				if(isset($font['diff']))
+					$this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
+				else
+					$this->_out('/Encoding /WinAnsiEncoding');
+			}
+			$this->_out('>>');
+			$this->_out('endobj');
+			//Widths
+			$this->_newobj();
+			$cw=&$font['cw'];
+			$s='[';
+			for($i=32;$i<=255;$i++)
+				$s.=$cw[chr($i)].' ';
+			$this->_out($s.']');
+			$this->_out('endobj');
+			//Descriptor
+			$this->_newobj();
+			$s='<</Type /FontDescriptor /FontName /'.$name;
+			foreach($font['desc'] as $k=>$v)
+				$s.=' /'.$k.' '.$v;
+			$file=$font['file'];
+			if($file)
+				$s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
+			$this->_out($s.'>>');
+			$this->_out('endobj');
+		}
+		else
+		{
+			//Allow for additional types
+			$mtd='_put'.strtolower($type);
+			if(!method_exists($this,$mtd))
+				$this->Error('Unsupported font type: '.$type);
+			$this->$mtd($font);
+		}
+	}
+}
+
+function _putimages()
+{
+	$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+	reset($this->images);
+	while(list($file,$info)=each($this->images))
+	{
+		$this->_newobj();
+		$this->images[$file]['n']=$this->n;
+		$this->_out('<</Type /XObject');
+		$this->_out('/Subtype /Image');
+		$this->_out('/Width '.$info['w']);
+		$this->_out('/Height '.$info['h']);
+		if($info['cs']=='Indexed')
+			$this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
+		else
+		{
+			$this->_out('/ColorSpace /'.$info['cs']);
+			if($info['cs']=='DeviceCMYK')
+				$this->_out('/Decode [1 0 1 0 1 0 1 0]');
+		}
+		$this->_out('/BitsPerComponent '.$info['bpc']);
+		if(isset($info['f']))
+			$this->_out('/Filter /'.$info['f']);
+		if(isset($info['parms']))
+			$this->_out($info['parms']);
+		if(isset($info['trns']) && is_array($info['trns']))
+		{
+			$trns='';
+			for($i=0;$i<count($info['trns']);$i++)
+				$trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
+			$this->_out('/Mask ['.$trns.']');
+		}
+		$this->_out('/Length '.strlen($info['data']).'>>');
+		$this->_putstream($info['data']);
+		unset($this->images[$file]['data']);
+		$this->_out('endobj');
+		//Palette
+		if($info['cs']=='Indexed')
+		{
+			$this->_newobj();
+			$pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
+			$this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
+			$this->_putstream($pal);
+			$this->_out('endobj');
+		}
+	}
+}
+
+function _putxobjectdict()
+{
+	foreach($this->images as $image)
+		$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
+}
+
+function _putresourcedict()
+{
+	$this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
+	$this->_out('/Font <<');
+	foreach($this->fonts as $font)
+		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
+	$this->_out('>>');
+	$this->_out('/XObject <<');
+	$this->_putxobjectdict();
+	$this->_out('>>');
+}
+
+function _putresources()
+{
+	$this->_putfonts();
+	$this->_putimages();
+	//Resource dictionary
+	$this->offsets[2]=strlen($this->buffer);
+	$this->_out('2 0 obj');
+	$this->_out('<<');
+	$this->_putresourcedict();
+	$this->_out('>>');
+	$this->_out('endobj');
+}
+
+function _putinfo()
+{
+	$this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
+	if(!empty($this->title))
+		$this->_out('/Title '.$this->_textstring($this->title));
+	if(!empty($this->subject))
+		$this->_out('/Subject '.$this->_textstring($this->subject));
+	if(!empty($this->author))
+		$this->_out('/Author '.$this->_textstring($this->author));
+	if(!empty($this->keywords))
+		$this->_out('/Keywords '.$this->_textstring($this->keywords));
+	if(!empty($this->creator))
+		$this->_out('/Creator '.$this->_textstring($this->creator));
+	$this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
+}
+
+function _putcatalog()
+{
+	$this->_out('/Type /Catalog');
+	$this->_out('/Pages 1 0 R');
+	if($this->ZoomMode=='fullpage')
+		$this->_out('/OpenAction [3 0 R /Fit]');
+	elseif($this->ZoomMode=='fullwidth')
+		$this->_out('/OpenAction [3 0 R /FitH null]');
+	elseif($this->ZoomMode=='real')
+		$this->_out('/OpenAction [3 0 R /XYZ null null 1]');
+	elseif(!is_string($this->ZoomMode))
+		$this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
+	if($this->LayoutMode=='single')
+		$this->_out('/PageLayout /SinglePage');
+	elseif($this->LayoutMode=='continuous')
+		$this->_out('/PageLayout /OneColumn');
+	elseif($this->LayoutMode=='two')
+		$this->_out('/PageLayout /TwoColumnLeft');
+}
+
+function _putheader()
+{
+	$this->_out('%PDF-'.$this->PDFVersion);
+}
+
+function _puttrailer()
+{
+	$this->_out('/Size '.($this->n+1));
+	$this->_out('/Root '.$this->n.' 0 R');
+	$this->_out('/Info '.($this->n-1).' 0 R');
+}
+
+function _enddoc()
+{
+	$this->_putheader();
+	$this->_putpages();
+	$this->_putresources();
+	//Info
+	$this->_newobj();
+	$this->_out('<<');
+	$this->_putinfo();
+	$this->_out('>>');
+	$this->_out('endobj');
+	//Catalog
+	$this->_newobj();
+	$this->_out('<<');
+	$this->_putcatalog();
+	$this->_out('>>');
+	$this->_out('endobj');
+	//Cross-ref
+	$o=strlen($this->buffer);
+	$this->_out('xref');
+	$this->_out('0 '.($this->n+1));
+	$this->_out('0000000000 65535 f ');
+	for($i=1;$i<=$this->n;$i++)
+		$this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
+	//Trailer
+	$this->_out('trailer');
+	$this->_out('<<');
+	$this->_puttrailer();
+	$this->_out('>>');
+	$this->_out('startxref');
+	$this->_out($o);
+	$this->_out('%%EOF');
+	$this->state=3;
+}
+
+function _beginpage($orientation)
+{
+	$this->page++;
+	$this->pages[$this->page]='';
+	$this->state=2;
+	$this->x=$this->lMargin;
+	$this->y=$this->tMargin;
+	$this->FontFamily='';
+	//Page orientation
+	if(!$orientation)
+		$orientation=$this->DefOrientation;
+	else
+	{
+		$orientation=strtoupper($orientation{0});
+		if($orientation!=$this->DefOrientation)
+			$this->OrientationChanges[$this->page]=true;
+	}
+	if($orientation!=$this->CurOrientation)
+	{
+		//Change orientation
+		if($orientation=='P')
+		{
+			$this->wPt=$this->fwPt;
+			$this->hPt=$this->fhPt;
+			$this->w=$this->fw;
+			$this->h=$this->fh;
+		}
+		else
+		{
+			$this->wPt=$this->fhPt;
+			$this->hPt=$this->fwPt;
+			$this->w=$this->fh;
+			$this->h=$this->fw;
+		}
+		$this->PageBreakTrigger=$this->h-$this->bMargin;
+		$this->CurOrientation=$orientation;
+	}
+}
+
+function _endpage()
+{
+	//End of page contents
+	$this->state=1;
+}
+
+function _newobj()
+{
+	//Begin a new object
+	$this->n++;
+	$this->offsets[$this->n]=strlen($this->buffer);
+	$this->_out($this->n.' 0 obj');
+}
+
+function _dounderline($x,$y,$txt)
+{
+	//Underline text
+	$up=$this->CurrentFont['up'];
+	$ut=$this->CurrentFont['ut'];
+	$w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
+	return sprintf('%.2f %.2f %.2f %.2f re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt);
+}
+
+function _parsejpg($file)
+{
+	//Extract info from a JPEG file
+	$a=GetImageSize($file);
+	if(!$a)
+		$this->Error('Missing or incorrect image file: '.$file);
+	if($a[2]!=2)
+		$this->Error('Not a JPEG file: '.$file);
+	if(!isset($a['channels']) || $a['channels']==3)
+		$colspace='DeviceRGB';
+	elseif($a['channels']==4)
+		$colspace='DeviceCMYK';
+	else
+		$colspace='DeviceGray';
+	$bpc=isset($a['bits']) ? $a['bits'] : 8;
+	//Read whole file
+	$f=fopen($file,'rb');
+	$data='';
+	while(!feof($f))
+		$data.=fread($f,4096);
+	fclose($f);
+	return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
+}
+
+function _parsepng($file)
+{
+	//Extract info from a PNG file
+	$f=fopen($file,'rb');
+	if(!$f)
+		$this->Error('Can\'t open image file: '.$file);
+	//Check signature
+	if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
+		$this->Error('Not a PNG file: '.$file);
+	//Read header chunk
+	fread($f,4);
+	if(fread($f,4)!='IHDR')
+		$this->Error('Incorrect PNG file: '.$file);
+	$w=$this->_freadint($f);
+	$h=$this->_freadint($f);
+	$bpc=ord(fread($f,1));
+	if($bpc>8)
+		$this->Error('16-bit depth not supported: '.$file);
+	$ct=ord(fread($f,1));
+	if($ct==0)
+		$colspace='DeviceGray';
+	elseif($ct==2)
+		$colspace='DeviceRGB';
+	elseif($ct==3)
+		$colspace='Indexed';
+	else
+		$this->Error('Alpha channel not supported: '.$file);
+	if(ord(fread($f,1))!=0)
+		$this->Error('Unknown compression method: '.$file);
+	if(ord(fread($f,1))!=0)
+		$this->Error('Unknown filter method: '.$file);
+	if(ord(fread($f,1))!=0)
+		$this->Error('Interlacing not supported: '.$file);
+	fread($f,4);
+	$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
+	//Scan chunks looking for palette, transparency and image data
+	$pal='';
+	$trns='';
+	$data='';
+	do
+	{
+		$n=$this->_freadint($f);
+		$type=fread($f,4);
+		if($type=='PLTE')
+		{
+			//Read palette
+			$pal=fread($f,$n);
+			fread($f,4);
+		}
+		elseif($type=='tRNS')
+		{
+			//Read transparency info
+			$t=fread($f,$n);
+			if($ct==0)
+				$trns=array(ord(substr($t,1,1)));
+			elseif($ct==2)
+				$trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
+			else
+			{
+				$pos=strpos($t,chr(0));
+				if($pos!==false)
+					$trns=array($pos);
+			}
+			fread($f,4);
+		}
+		elseif($type=='IDAT')
+		{
+			//Read image data block
+			$data.=fread($f,$n);
+			fread($f,4);
+		}
+		elseif($type=='IEND')
+			break;
+		else
+			fread($f,$n+4);
+	}
+	while($n);
+	if($colspace=='Indexed' && empty($pal))
+		$this->Error('Missing palette in '.$file);
+	fclose($f);
+	return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
+}
+
+function _freadint($f)
+{
+	//Read a 4-byte integer from file
+	$a=unpack('Ni',fread($f,4));
+	return $a['i'];
+}
+
+function _textstring($s)
+{
+	//Format a text string
+	return '('.$this->_escape($s).')';
+}
+
+function _escape($s)
+{
+	//Add \ before \, ( and )
+	return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
+}
+
+function _putstream($s)
+{
+	$this->_out('stream');
+	$this->_out($s);
+	$this->_out('endstream');
+}
+
+function _out($s)
+{
+	//Add a line to the document
+	if($this->state==2)
+		$this->pages[$this->page].=$s."\n";
+	else
+		$this->buffer.=$s."\n";
+}
+//End of class
+}
+
+//Handle special IE contype request
+if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype')
+{
+	header('Content-Type: application/pdf');
+	exit;
+}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/timesi.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/timesi.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/timesi.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['timesI']=array(
+	chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+	chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>420,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>214,'('=>333,')'=>333,'*'=>500,'+'=>675,
+	','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>675,'='=>675,'>'=>675,'?'=>500,'@'=>920,'A'=>611,
+	'B'=>611,'C'=>667,'D'=>722,'E'=>611,'F'=>611,'G'=>722,'H'=>722,'I'=>333,'J'=>444,'K'=>667,'L'=>556,'M'=>833,'N'=>667,'O'=>722,'P'=>611,'Q'=>722,'R'=>611,'S'=>500,'T'=>556,'U'=>722,'V'=>611,'W'=>833,
+	'X'=>611,'Y'=>556,'Z'=>556,'['=>389,'\\'=>278,']'=>389,'^'=>422,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>278,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>444,'l'=>278,'m'=>722,
+	'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>500,'v'=>444,'w'=>667,'x'=>444,'y'=>444,'z'=>389,'{'=>400,'|'=>275,'}'=>400,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+	chr(132)=>556,chr(133)=>889,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>500,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>556,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>556,chr(148)=>556,chr(149)=>350,chr(150)=>500,chr(151)=>889,chr(152)=>333,chr(153)=>980,
+	chr(154)=>389,chr(155)=>333,chr(156)=>667,chr(157)=>350,chr(158)=>389,chr(159)=>556,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>275,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>675,chr(173)=>333,chr(174)=>760,chr(175)=>333,
+	chr(176)=>400,chr(177)=>675,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>523,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>611,chr(193)=>611,chr(194)=>611,chr(195)=>611,chr(196)=>611,chr(197)=>611,
+	chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>667,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>675,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>556,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
+	chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>675,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>444,chr(254)=>500,chr(255)=>444);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/timesbi.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/timesbi.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/timesbi.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['timesBI']=array(
+	chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+	chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>389,'"'=>555,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570,
+	','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>832,'A'=>667,
+	'B'=>667,'C'=>667,'D'=>722,'E'=>667,'F'=>667,'G'=>722,'H'=>778,'I'=>389,'J'=>500,'K'=>667,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>611,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>667,'W'=>889,
+	'X'=>667,'Y'=>611,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>570,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
+	'n'=>556,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>556,'v'=>444,'w'=>667,'x'=>500,'y'=>444,'z'=>389,'{'=>348,'|'=>220,'}'=>348,'~'=>570,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+	chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>389,chr(159)=>611,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>266,chr(171)=>500,chr(172)=>606,chr(173)=>333,chr(174)=>747,chr(175)=>333,
+	chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>576,chr(182)=>500,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>300,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+	chr(198)=>944,chr(199)=>667,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>570,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>611,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556,
+	chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>444,chr(254)=>500,chr(255)=>444);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/zapfdingbats.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/zapfdingbats.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/zapfdingbats.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['zapfdingbats']=array(
+	chr(0)=>0,chr(1)=>0,chr(2)=>0,chr(3)=>0,chr(4)=>0,chr(5)=>0,chr(6)=>0,chr(7)=>0,chr(8)=>0,chr(9)=>0,chr(10)=>0,chr(11)=>0,chr(12)=>0,chr(13)=>0,chr(14)=>0,chr(15)=>0,chr(16)=>0,chr(17)=>0,chr(18)=>0,chr(19)=>0,chr(20)=>0,chr(21)=>0,
+	chr(22)=>0,chr(23)=>0,chr(24)=>0,chr(25)=>0,chr(26)=>0,chr(27)=>0,chr(28)=>0,chr(29)=>0,chr(30)=>0,chr(31)=>0,' '=>278,'!'=>974,'"'=>961,'#'=>974,'$'=>980,'%'=>719,'&'=>789,'\''=>790,'('=>791,')'=>690,'*'=>960,'+'=>939,
+	','=>549,'-'=>855,'.'=>911,'/'=>933,'0'=>911,'1'=>945,'2'=>974,'3'=>755,'4'=>846,'5'=>762,'6'=>761,'7'=>571,'8'=>677,'9'=>763,':'=>760,';'=>759,'<'=>754,'='=>494,'>'=>552,'?'=>537,'@'=>577,'A'=>692,
+	'B'=>786,'C'=>788,'D'=>788,'E'=>790,'F'=>793,'G'=>794,'H'=>816,'I'=>823,'J'=>789,'K'=>841,'L'=>823,'M'=>833,'N'=>816,'O'=>831,'P'=>923,'Q'=>744,'R'=>723,'S'=>749,'T'=>790,'U'=>792,'V'=>695,'W'=>776,
+	'X'=>768,'Y'=>792,'Z'=>759,'['=>707,'\\'=>708,']'=>682,'^'=>701,'_'=>826,'`'=>815,'a'=>789,'b'=>789,'c'=>707,'d'=>687,'e'=>696,'f'=>689,'g'=>786,'h'=>787,'i'=>713,'j'=>791,'k'=>785,'l'=>791,'m'=>873,
+	'n'=>761,'o'=>762,'p'=>762,'q'=>759,'r'=>759,'s'=>892,'t'=>892,'u'=>788,'v'=>784,'w'=>438,'x'=>138,'y'=>277,'z'=>415,'{'=>392,'|'=>392,'}'=>668,'~'=>668,chr(127)=>0,chr(128)=>390,chr(129)=>390,chr(130)=>317,chr(131)=>317,
+	chr(132)=>276,chr(133)=>276,chr(134)=>509,chr(135)=>509,chr(136)=>410,chr(137)=>410,chr(138)=>234,chr(139)=>234,chr(140)=>334,chr(141)=>334,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
+	chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>0,chr(161)=>732,chr(162)=>544,chr(163)=>544,chr(164)=>910,chr(165)=>667,chr(166)=>760,chr(167)=>760,chr(168)=>776,chr(169)=>595,chr(170)=>694,chr(171)=>626,chr(172)=>788,chr(173)=>788,chr(174)=>788,chr(175)=>788,
+	chr(176)=>788,chr(177)=>788,chr(178)=>788,chr(179)=>788,chr(180)=>788,chr(181)=>788,chr(182)=>788,chr(183)=>788,chr(184)=>788,chr(185)=>788,chr(186)=>788,chr(187)=>788,chr(188)=>788,chr(189)=>788,chr(190)=>788,chr(191)=>788,chr(192)=>788,chr(193)=>788,chr(194)=>788,chr(195)=>788,chr(196)=>788,chr(197)=>788,
+	chr(198)=>788,chr(199)=>788,chr(200)=>788,chr(201)=>788,chr(202)=>788,chr(203)=>788,chr(204)=>788,chr(205)=>788,chr(206)=>788,chr(207)=>788,chr(208)=>788,chr(209)=>788,chr(210)=>788,chr(211)=>788,chr(212)=>894,chr(213)=>838,chr(214)=>1016,chr(215)=>458,chr(216)=>748,chr(217)=>924,chr(218)=>748,chr(219)=>918,
+	chr(220)=>927,chr(221)=>928,chr(222)=>928,chr(223)=>834,chr(224)=>873,chr(225)=>828,chr(226)=>924,chr(227)=>924,chr(228)=>917,chr(229)=>930,chr(230)=>931,chr(231)=>463,chr(232)=>883,chr(233)=>836,chr(234)=>836,chr(235)=>867,chr(236)=>867,chr(237)=>696,chr(238)=>696,chr(239)=>874,chr(240)=>0,chr(241)=>874,
+	chr(242)=>760,chr(243)=>946,chr(244)=>771,chr(245)=>865,chr(246)=>771,chr(247)=>888,chr(248)=>967,chr(249)=>888,chr(250)=>831,chr(251)=>873,chr(252)=>927,chr(253)=>970,chr(254)=>918,chr(255)=>0);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/helveticai.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/helveticai.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/helveticai.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['helveticaI']=array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
+	'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
+	'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
+	chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
+	chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-1.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-1.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-1.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+00D0 Eth
+!D1 U+00D1 Ntilde
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+00DE Thorn
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+00F0 eth
+!F1 U+00F1 ntilde
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+00FE thorn
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-2.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-2.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-2.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0104 Aogonek
+!A2 U+02D8 breve
+!A3 U+0141 Lslash
+!A4 U+00A4 currency
+!A5 U+013D Lcaron
+!A6 U+015A Sacute
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+0160 Scaron
+!AA U+015E Scedilla
+!AB U+0164 Tcaron
+!AC U+0179 Zacute
+!AD U+00AD hyphen
+!AE U+017D Zcaron
+!AF U+017B Zdotaccent
+!B0 U+00B0 degree
+!B1 U+0105 aogonek
+!B2 U+02DB ogonek
+!B3 U+0142 lslash
+!B4 U+00B4 acute
+!B5 U+013E lcaron
+!B6 U+015B sacute
+!B7 U+02C7 caron
+!B8 U+00B8 cedilla
+!B9 U+0161 scaron
+!BA U+015F scedilla
+!BB U+0165 tcaron
+!BC U+017A zacute
+!BD U+02DD hungarumlaut
+!BE U+017E zcaron
+!BF U+017C zdotaccent
+!C0 U+0154 Racute
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+0102 Abreve
+!C4 U+00C4 Adieresis
+!C5 U+0139 Lacute
+!C6 U+0106 Cacute
+!C7 U+00C7 Ccedilla
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0118 Eogonek
+!CB U+00CB Edieresis
+!CC U+011A Ecaron
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+010E Dcaron
+!D0 U+0110 Dcroat
+!D1 U+0143 Nacute
+!D2 U+0147 Ncaron
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+0150 Ohungarumlaut
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+0158 Rcaron
+!D9 U+016E Uring
+!DA U+00DA Uacute
+!DB U+0170 Uhungarumlaut
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+0162 Tcommaaccent
+!DF U+00DF germandbls
+!E0 U+0155 racute
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!E4 U+00E4 adieresis
+!E5 U+013A lacute
+!E6 U+0107 cacute
+!E7 U+00E7 ccedilla
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+0119 eogonek
+!EB U+00EB edieresis
+!EC U+011B ecaron
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+010F dcaron
+!F0 U+0111 dcroat
+!F1 U+0144 nacute
+!F2 U+0148 ncaron
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+0151 ohungarumlaut
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+0159 rcaron
+!F9 U+016F uring
+!FA U+00FA uacute
+!FB U+0171 uhungarumlaut
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+0163 tcommaaccent
+!FF U+02D9 dotaccent
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp874.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp874.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp874.map	(revision 795)
@@ -0,0 +1,225 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!85 U+2026 ellipsis
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!A0 U+00A0 space
+!A1 U+0E01 kokaithai
+!A2 U+0E02 khokhaithai
+!A3 U+0E03 khokhuatthai
+!A4 U+0E04 khokhwaithai
+!A5 U+0E05 khokhonthai
+!A6 U+0E06 khorakhangthai
+!A7 U+0E07 ngonguthai
+!A8 U+0E08 chochanthai
+!A9 U+0E09 chochingthai
+!AA U+0E0A chochangthai
+!AB U+0E0B sosothai
+!AC U+0E0C chochoethai
+!AD U+0E0D yoyingthai
+!AE U+0E0E dochadathai
+!AF U+0E0F topatakthai
+!B0 U+0E10 thothanthai
+!B1 U+0E11 thonangmonthothai
+!B2 U+0E12 thophuthaothai
+!B3 U+0E13 nonenthai
+!B4 U+0E14 dodekthai
+!B5 U+0E15 totaothai
+!B6 U+0E16 thothungthai
+!B7 U+0E17 thothahanthai
+!B8 U+0E18 thothongthai
+!B9 U+0E19 nonuthai
+!BA U+0E1A bobaimaithai
+!BB U+0E1B poplathai
+!BC U+0E1C phophungthai
+!BD U+0E1D fofathai
+!BE U+0E1E phophanthai
+!BF U+0E1F fofanthai
+!C0 U+0E20 phosamphaothai
+!C1 U+0E21 momathai
+!C2 U+0E22 yoyakthai
+!C3 U+0E23 roruathai
+!C4 U+0E24 ruthai
+!C5 U+0E25 lolingthai
+!C6 U+0E26 luthai
+!C7 U+0E27 wowaenthai
+!C8 U+0E28 sosalathai
+!C9 U+0E29 sorusithai
+!CA U+0E2A sosuathai
+!CB U+0E2B hohipthai
+!CC U+0E2C lochulathai
+!CD U+0E2D oangthai
+!CE U+0E2E honokhukthai
+!CF U+0E2F paiyannoithai
+!D0 U+0E30 saraathai
+!D1 U+0E31 maihanakatthai
+!D2 U+0E32 saraaathai
+!D3 U+0E33 saraamthai
+!D4 U+0E34 saraithai
+!D5 U+0E35 saraiithai
+!D6 U+0E36 sarauethai
+!D7 U+0E37 saraueethai
+!D8 U+0E38 sarauthai
+!D9 U+0E39 sarauuthai
+!DA U+0E3A phinthuthai
+!DF U+0E3F bahtthai
+!E0 U+0E40 saraethai
+!E1 U+0E41 saraaethai
+!E2 U+0E42 saraothai
+!E3 U+0E43 saraaimaimuanthai
+!E4 U+0E44 saraaimaimalaithai
+!E5 U+0E45 lakkhangyaothai
+!E6 U+0E46 maiyamokthai
+!E7 U+0E47 maitaikhuthai
+!E8 U+0E48 maiekthai
+!E9 U+0E49 maithothai
+!EA U+0E4A maitrithai
+!EB U+0E4B maichattawathai
+!EC U+0E4C thanthakhatthai
+!ED U+0E4D nikhahitthai
+!EE U+0E4E yamakkanthai
+!EF U+0E4F fongmanthai
+!F0 U+0E50 zerothai
+!F1 U+0E51 onethai
+!F2 U+0E52 twothai
+!F3 U+0E53 threethai
+!F4 U+0E54 fourthai
+!F5 U+0E55 fivethai
+!F6 U+0E56 sixthai
+!F7 U+0E57 seventhai
+!F8 U+0E58 eightthai
+!F9 U+0E59 ninethai
+!FA U+0E5A angkhankhuthai
+!FB U+0E5B khomutthai
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-4.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-4.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-4.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0104 Aogonek
+!A2 U+0138 kgreenlandic
+!A3 U+0156 Rcommaaccent
+!A4 U+00A4 currency
+!A5 U+0128 Itilde
+!A6 U+013B Lcommaaccent
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+0160 Scaron
+!AA U+0112 Emacron
+!AB U+0122 Gcommaaccent
+!AC U+0166 Tbar
+!AD U+00AD hyphen
+!AE U+017D Zcaron
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+0105 aogonek
+!B2 U+02DB ogonek
+!B3 U+0157 rcommaaccent
+!B4 U+00B4 acute
+!B5 U+0129 itilde
+!B6 U+013C lcommaaccent
+!B7 U+02C7 caron
+!B8 U+00B8 cedilla
+!B9 U+0161 scaron
+!BA U+0113 emacron
+!BB U+0123 gcommaaccent
+!BC U+0167 tbar
+!BD U+014A Eng
+!BE U+017E zcaron
+!BF U+014B eng
+!C0 U+0100 Amacron
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+012E Iogonek
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0118 Eogonek
+!CB U+00CB Edieresis
+!CC U+0116 Edotaccent
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+012A Imacron
+!D0 U+0110 Dcroat
+!D1 U+0145 Ncommaaccent
+!D2 U+014C Omacron
+!D3 U+0136 Kcommaaccent
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+0172 Uogonek
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+0168 Utilde
+!DE U+016A Umacron
+!DF U+00DF germandbls
+!E0 U+0101 amacron
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+012F iogonek
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+0119 eogonek
+!EB U+00EB edieresis
+!EC U+0117 edotaccent
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+012B imacron
+!F0 U+0111 dcroat
+!F1 U+0146 ncommaaccent
+!F2 U+014D omacron
+!F3 U+0137 kcommaaccent
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+0173 uogonek
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+0169 utilde
+!FE U+016B umacron
+!FF U+02D9 dotaccent
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-5.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-5.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-5.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0401 afii10023
+!A2 U+0402 afii10051
+!A3 U+0403 afii10052
+!A4 U+0404 afii10053
+!A5 U+0405 afii10054
+!A6 U+0406 afii10055
+!A7 U+0407 afii10056
+!A8 U+0408 afii10057
+!A9 U+0409 afii10058
+!AA U+040A afii10059
+!AB U+040B afii10060
+!AC U+040C afii10061
+!AD U+00AD hyphen
+!AE U+040E afii10062
+!AF U+040F afii10145
+!B0 U+0410 afii10017
+!B1 U+0411 afii10018
+!B2 U+0412 afii10019
+!B3 U+0413 afii10020
+!B4 U+0414 afii10021
+!B5 U+0415 afii10022
+!B6 U+0416 afii10024
+!B7 U+0417 afii10025
+!B8 U+0418 afii10026
+!B9 U+0419 afii10027
+!BA U+041A afii10028
+!BB U+041B afii10029
+!BC U+041C afii10030
+!BD U+041D afii10031
+!BE U+041E afii10032
+!BF U+041F afii10033
+!C0 U+0420 afii10034
+!C1 U+0421 afii10035
+!C2 U+0422 afii10036
+!C3 U+0423 afii10037
+!C4 U+0424 afii10038
+!C5 U+0425 afii10039
+!C6 U+0426 afii10040
+!C7 U+0427 afii10041
+!C8 U+0428 afii10042
+!C9 U+0429 afii10043
+!CA U+042A afii10044
+!CB U+042B afii10045
+!CC U+042C afii10046
+!CD U+042D afii10047
+!CE U+042E afii10048
+!CF U+042F afii10049
+!D0 U+0430 afii10065
+!D1 U+0431 afii10066
+!D2 U+0432 afii10067
+!D3 U+0433 afii10068
+!D4 U+0434 afii10069
+!D5 U+0435 afii10070
+!D6 U+0436 afii10072
+!D7 U+0437 afii10073
+!D8 U+0438 afii10074
+!D9 U+0439 afii10075
+!DA U+043A afii10076
+!DB U+043B afii10077
+!DC U+043C afii10078
+!DD U+043D afii10079
+!DE U+043E afii10080
+!DF U+043F afii10081
+!E0 U+0440 afii10082
+!E1 U+0441 afii10083
+!E2 U+0442 afii10084
+!E3 U+0443 afii10085
+!E4 U+0444 afii10086
+!E5 U+0445 afii10087
+!E6 U+0446 afii10088
+!E7 U+0447 afii10089
+!E8 U+0448 afii10090
+!E9 U+0449 afii10091
+!EA U+044A afii10092
+!EB U+044B afii10093
+!EC U+044C afii10094
+!ED U+044D afii10095
+!EE U+044E afii10096
+!EF U+044F afii10097
+!F0 U+2116 afii61352
+!F1 U+0451 afii10071
+!F2 U+0452 afii10099
+!F3 U+0453 afii10100
+!F4 U+0454 afii10101
+!F5 U+0455 afii10102
+!F6 U+0456 afii10103
+!F7 U+0457 afii10104
+!F8 U+0458 afii10105
+!F9 U+0459 afii10106
+!FA U+045A afii10107
+!FB U+045B afii10108
+!FC U+045C afii10109
+!FD U+00A7 section
+!FE U+045E afii10110
+!FF U+045F afii10193
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/koi8-r.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/koi8-r.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/koi8-r.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+2500 SF100000
+!81 U+2502 SF110000
+!82 U+250C SF010000
+!83 U+2510 SF030000
+!84 U+2514 SF020000
+!85 U+2518 SF040000
+!86 U+251C SF080000
+!87 U+2524 SF090000
+!88 U+252C SF060000
+!89 U+2534 SF070000
+!8A U+253C SF050000
+!8B U+2580 upblock
+!8C U+2584 dnblock
+!8D U+2588 block
+!8E U+258C lfblock
+!8F U+2590 rtblock
+!90 U+2591 ltshade
+!91 U+2592 shade
+!92 U+2593 dkshade
+!93 U+2320 integraltp
+!94 U+25A0 filledbox
+!95 U+2219 periodcentered
+!96 U+221A radical
+!97 U+2248 approxequal
+!98 U+2264 lessequal
+!99 U+2265 greaterequal
+!9A U+00A0 space
+!9B U+2321 integralbt
+!9C U+00B0 degree
+!9D U+00B2 twosuperior
+!9E U+00B7 periodcentered
+!9F U+00F7 divide
+!A0 U+2550 SF430000
+!A1 U+2551 SF240000
+!A2 U+2552 SF510000
+!A3 U+0451 afii10071
+!A4 U+2553 SF520000
+!A5 U+2554 SF390000
+!A6 U+2555 SF220000
+!A7 U+2556 SF210000
+!A8 U+2557 SF250000
+!A9 U+2558 SF500000
+!AA U+2559 SF490000
+!AB U+255A SF380000
+!AC U+255B SF280000
+!AD U+255C SF270000
+!AE U+255D SF260000
+!AF U+255E SF360000
+!B0 U+255F SF370000
+!B1 U+2560 SF420000
+!B2 U+2561 SF190000
+!B3 U+0401 afii10023
+!B4 U+2562 SF200000
+!B5 U+2563 SF230000
+!B6 U+2564 SF470000
+!B7 U+2565 SF480000
+!B8 U+2566 SF410000
+!B9 U+2567 SF450000
+!BA U+2568 SF460000
+!BB U+2569 SF400000
+!BC U+256A SF540000
+!BD U+256B SF530000
+!BE U+256C SF440000
+!BF U+00A9 copyright
+!C0 U+044E afii10096
+!C1 U+0430 afii10065
+!C2 U+0431 afii10066
+!C3 U+0446 afii10088
+!C4 U+0434 afii10069
+!C5 U+0435 afii10070
+!C6 U+0444 afii10086
+!C7 U+0433 afii10068
+!C8 U+0445 afii10087
+!C9 U+0438 afii10074
+!CA U+0439 afii10075
+!CB U+043A afii10076
+!CC U+043B afii10077
+!CD U+043C afii10078
+!CE U+043D afii10079
+!CF U+043E afii10080
+!D0 U+043F afii10081
+!D1 U+044F afii10097
+!D2 U+0440 afii10082
+!D3 U+0441 afii10083
+!D4 U+0442 afii10084
+!D5 U+0443 afii10085
+!D6 U+0436 afii10072
+!D7 U+0432 afii10067
+!D8 U+044C afii10094
+!D9 U+044B afii10093
+!DA U+0437 afii10073
+!DB U+0448 afii10090
+!DC U+044D afii10095
+!DD U+0449 afii10091
+!DE U+0447 afii10089
+!DF U+044A afii10092
+!E0 U+042E afii10048
+!E1 U+0410 afii10017
+!E2 U+0411 afii10018
+!E3 U+0426 afii10040
+!E4 U+0414 afii10021
+!E5 U+0415 afii10022
+!E6 U+0424 afii10038
+!E7 U+0413 afii10020
+!E8 U+0425 afii10039
+!E9 U+0418 afii10026
+!EA U+0419 afii10027
+!EB U+041A afii10028
+!EC U+041B afii10029
+!ED U+041C afii10030
+!EE U+041D afii10031
+!EF U+041E afii10032
+!F0 U+041F afii10033
+!F1 U+042F afii10049
+!F2 U+0420 afii10034
+!F3 U+0421 afii10035
+!F4 U+0422 afii10036
+!F5 U+0423 afii10037
+!F6 U+0416 afii10024
+!F7 U+0412 afii10019
+!F8 U+042C afii10046
+!F9 U+042B afii10045
+!FA U+0417 afii10025
+!FB U+0428 afii10042
+!FC U+042D afii10047
+!FD U+0429 afii10043
+!FE U+0427 afii10041
+!FF U+042A afii10044
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-7.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-7.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-7.map	(revision 795)
@@ -0,0 +1,250 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+2018 quoteleft
+!A2 U+2019 quoteright
+!A3 U+00A3 sterling
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AF U+2015 afii00208
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+0384 tonos
+!B5 U+0385 dieresistonos
+!B6 U+0386 Alphatonos
+!B7 U+00B7 periodcentered
+!B8 U+0388 Epsilontonos
+!B9 U+0389 Etatonos
+!BA U+038A Iotatonos
+!BB U+00BB guillemotright
+!BC U+038C Omicrontonos
+!BD U+00BD onehalf
+!BE U+038E Upsilontonos
+!BF U+038F Omegatonos
+!C0 U+0390 iotadieresistonos
+!C1 U+0391 Alpha
+!C2 U+0392 Beta
+!C3 U+0393 Gamma
+!C4 U+0394 Delta
+!C5 U+0395 Epsilon
+!C6 U+0396 Zeta
+!C7 U+0397 Eta
+!C8 U+0398 Theta
+!C9 U+0399 Iota
+!CA U+039A Kappa
+!CB U+039B Lambda
+!CC U+039C Mu
+!CD U+039D Nu
+!CE U+039E Xi
+!CF U+039F Omicron
+!D0 U+03A0 Pi
+!D1 U+03A1 Rho
+!D3 U+03A3 Sigma
+!D4 U+03A4 Tau
+!D5 U+03A5 Upsilon
+!D6 U+03A6 Phi
+!D7 U+03A7 Chi
+!D8 U+03A8 Psi
+!D9 U+03A9 Omega
+!DA U+03AA Iotadieresis
+!DB U+03AB Upsilondieresis
+!DC U+03AC alphatonos
+!DD U+03AD epsilontonos
+!DE U+03AE etatonos
+!DF U+03AF iotatonos
+!E0 U+03B0 upsilondieresistonos
+!E1 U+03B1 alpha
+!E2 U+03B2 beta
+!E3 U+03B3 gamma
+!E4 U+03B4 delta
+!E5 U+03B5 epsilon
+!E6 U+03B6 zeta
+!E7 U+03B7 eta
+!E8 U+03B8 theta
+!E9 U+03B9 iota
+!EA U+03BA kappa
+!EB U+03BB lambda
+!EC U+03BC mu
+!ED U+03BD nu
+!EE U+03BE xi
+!EF U+03BF omicron
+!F0 U+03C0 pi
+!F1 U+03C1 rho
+!F2 U+03C2 sigma1
+!F3 U+03C3 sigma
+!F4 U+03C4 tau
+!F5 U+03C5 upsilon
+!F6 U+03C6 phi
+!F7 U+03C7 chi
+!F8 U+03C8 psi
+!F9 U+03C9 omega
+!FA U+03CA iotadieresis
+!FB U+03CB upsilondieresis
+!FC U+03CC omicrontonos
+!FD U+03CD upsilontonos
+!FE U+03CE omegatonos
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1250.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1250.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1250.map	(revision 795)
@@ -0,0 +1,251 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!89 U+2030 perthousand
+!8A U+0160 Scaron
+!8B U+2039 guilsinglleft
+!8C U+015A Sacute
+!8D U+0164 Tcaron
+!8E U+017D Zcaron
+!8F U+0179 Zacute
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!99 U+2122 trademark
+!9A U+0161 scaron
+!9B U+203A guilsinglright
+!9C U+015B sacute
+!9D U+0165 tcaron
+!9E U+017E zcaron
+!9F U+017A zacute
+!A0 U+00A0 space
+!A1 U+02C7 caron
+!A2 U+02D8 breve
+!A3 U+0141 Lslash
+!A4 U+00A4 currency
+!A5 U+0104 Aogonek
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+015E Scedilla
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+017B Zdotaccent
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+02DB ogonek
+!B3 U+0142 lslash
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+0105 aogonek
+!BA U+015F scedilla
+!BB U+00BB guillemotright
+!BC U+013D Lcaron
+!BD U+02DD hungarumlaut
+!BE U+013E lcaron
+!BF U+017C zdotaccent
+!C0 U+0154 Racute
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+0102 Abreve
+!C4 U+00C4 Adieresis
+!C5 U+0139 Lacute
+!C6 U+0106 Cacute
+!C7 U+00C7 Ccedilla
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0118 Eogonek
+!CB U+00CB Edieresis
+!CC U+011A Ecaron
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+010E Dcaron
+!D0 U+0110 Dcroat
+!D1 U+0143 Nacute
+!D2 U+0147 Ncaron
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+0150 Ohungarumlaut
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+0158 Rcaron
+!D9 U+016E Uring
+!DA U+00DA Uacute
+!DB U+0170 Uhungarumlaut
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+0162 Tcommaaccent
+!DF U+00DF germandbls
+!E0 U+0155 racute
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!E4 U+00E4 adieresis
+!E5 U+013A lacute
+!E6 U+0107 cacute
+!E7 U+00E7 ccedilla
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+0119 eogonek
+!EB U+00EB edieresis
+!EC U+011B ecaron
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+010F dcaron
+!F0 U+0111 dcroat
+!F1 U+0144 nacute
+!F2 U+0148 ncaron
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+0151 ohungarumlaut
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+0159 rcaron
+!F9 U+016F uring
+!FA U+00FA uacute
+!FB U+0171 uhungarumlaut
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+0163 tcommaaccent
+!FF U+02D9 dotaccent
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-9.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-9.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-9.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+011E Gbreve
+!D1 U+00D1 Ntilde
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+0130 Idotaccent
+!DE U+015E Scedilla
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+011F gbreve
+!F1 U+00F1 ntilde
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+0131 dotlessi
+!FE U+015F scedilla
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1251.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1251.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1251.map	(revision 795)
@@ -0,0 +1,255 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0402 afii10051
+!81 U+0403 afii10052
+!82 U+201A quotesinglbase
+!83 U+0453 afii10100
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+20AC Euro
+!89 U+2030 perthousand
+!8A U+0409 afii10058
+!8B U+2039 guilsinglleft
+!8C U+040A afii10059
+!8D U+040C afii10061
+!8E U+040B afii10060
+!8F U+040F afii10145
+!90 U+0452 afii10099
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!99 U+2122 trademark
+!9A U+0459 afii10106
+!9B U+203A guilsinglright
+!9C U+045A afii10107
+!9D U+045C afii10109
+!9E U+045B afii10108
+!9F U+045F afii10193
+!A0 U+00A0 space
+!A1 U+040E afii10062
+!A2 U+045E afii10110
+!A3 U+0408 afii10057
+!A4 U+00A4 currency
+!A5 U+0490 afii10050
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+0401 afii10023
+!A9 U+00A9 copyright
+!AA U+0404 afii10053
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+0407 afii10056
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+0406 afii10055
+!B3 U+0456 afii10103
+!B4 U+0491 afii10098
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+0451 afii10071
+!B9 U+2116 afii61352
+!BA U+0454 afii10101
+!BB U+00BB guillemotright
+!BC U+0458 afii10105
+!BD U+0405 afii10054
+!BE U+0455 afii10102
+!BF U+0457 afii10104
+!C0 U+0410 afii10017
+!C1 U+0411 afii10018
+!C2 U+0412 afii10019
+!C3 U+0413 afii10020
+!C4 U+0414 afii10021
+!C5 U+0415 afii10022
+!C6 U+0416 afii10024
+!C7 U+0417 afii10025
+!C8 U+0418 afii10026
+!C9 U+0419 afii10027
+!CA U+041A afii10028
+!CB U+041B afii10029
+!CC U+041C afii10030
+!CD U+041D afii10031
+!CE U+041E afii10032
+!CF U+041F afii10033
+!D0 U+0420 afii10034
+!D1 U+0421 afii10035
+!D2 U+0422 afii10036
+!D3 U+0423 afii10037
+!D4 U+0424 afii10038
+!D5 U+0425 afii10039
+!D6 U+0426 afii10040
+!D7 U+0427 afii10041
+!D8 U+0428 afii10042
+!D9 U+0429 afii10043
+!DA U+042A afii10044
+!DB U+042B afii10045
+!DC U+042C afii10046
+!DD U+042D afii10047
+!DE U+042E afii10048
+!DF U+042F afii10049
+!E0 U+0430 afii10065
+!E1 U+0431 afii10066
+!E2 U+0432 afii10067
+!E3 U+0433 afii10068
+!E4 U+0434 afii10069
+!E5 U+0435 afii10070
+!E6 U+0436 afii10072
+!E7 U+0437 afii10073
+!E8 U+0438 afii10074
+!E9 U+0439 afii10075
+!EA U+043A afii10076
+!EB U+043B afii10077
+!EC U+043C afii10078
+!ED U+043D afii10079
+!EE U+043E afii10080
+!EF U+043F afii10081
+!F0 U+0440 afii10082
+!F1 U+0441 afii10083
+!F2 U+0442 afii10084
+!F3 U+0443 afii10085
+!F4 U+0444 afii10086
+!F5 U+0445 afii10087
+!F6 U+0446 afii10088
+!F7 U+0447 afii10089
+!F8 U+0448 afii10090
+!F9 U+0449 afii10091
+!FA U+044A afii10092
+!FB U+044B afii10093
+!FC U+044C afii10094
+!FD U+044D afii10095
+!FE U+044E afii10096
+!FF U+044F afii10097
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/koi8-u.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/koi8-u.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/koi8-u.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+2500 SF100000
+!81 U+2502 SF110000
+!82 U+250C SF010000
+!83 U+2510 SF030000
+!84 U+2514 SF020000
+!85 U+2518 SF040000
+!86 U+251C SF080000
+!87 U+2524 SF090000
+!88 U+252C SF060000
+!89 U+2534 SF070000
+!8A U+253C SF050000
+!8B U+2580 upblock
+!8C U+2584 dnblock
+!8D U+2588 block
+!8E U+258C lfblock
+!8F U+2590 rtblock
+!90 U+2591 ltshade
+!91 U+2592 shade
+!92 U+2593 dkshade
+!93 U+2320 integraltp
+!94 U+25A0 filledbox
+!95 U+2022 bullet
+!96 U+221A radical
+!97 U+2248 approxequal
+!98 U+2264 lessequal
+!99 U+2265 greaterequal
+!9A U+00A0 space
+!9B U+2321 integralbt
+!9C U+00B0 degree
+!9D U+00B2 twosuperior
+!9E U+00B7 periodcentered
+!9F U+00F7 divide
+!A0 U+2550 SF430000
+!A1 U+2551 SF240000
+!A2 U+2552 SF510000
+!A3 U+0451 afii10071
+!A4 U+0454 afii10101
+!A5 U+2554 SF390000
+!A6 U+0456 afii10103
+!A7 U+0457 afii10104
+!A8 U+2557 SF250000
+!A9 U+2558 SF500000
+!AA U+2559 SF490000
+!AB U+255A SF380000
+!AC U+255B SF280000
+!AD U+0491 afii10098
+!AE U+255D SF260000
+!AF U+255E SF360000
+!B0 U+255F SF370000
+!B1 U+2560 SF420000
+!B2 U+2561 SF190000
+!B3 U+0401 afii10023
+!B4 U+0404 afii10053
+!B5 U+2563 SF230000
+!B6 U+0406 afii10055
+!B7 U+0407 afii10056
+!B8 U+2566 SF410000
+!B9 U+2567 SF450000
+!BA U+2568 SF460000
+!BB U+2569 SF400000
+!BC U+256A SF540000
+!BD U+0490 afii10050
+!BE U+256C SF440000
+!BF U+00A9 copyright
+!C0 U+044E afii10096
+!C1 U+0430 afii10065
+!C2 U+0431 afii10066
+!C3 U+0446 afii10088
+!C4 U+0434 afii10069
+!C5 U+0435 afii10070
+!C6 U+0444 afii10086
+!C7 U+0433 afii10068
+!C8 U+0445 afii10087
+!C9 U+0438 afii10074
+!CA U+0439 afii10075
+!CB U+043A afii10076
+!CC U+043B afii10077
+!CD U+043C afii10078
+!CE U+043D afii10079
+!CF U+043E afii10080
+!D0 U+043F afii10081
+!D1 U+044F afii10097
+!D2 U+0440 afii10082
+!D3 U+0441 afii10083
+!D4 U+0442 afii10084
+!D5 U+0443 afii10085
+!D6 U+0436 afii10072
+!D7 U+0432 afii10067
+!D8 U+044C afii10094
+!D9 U+044B afii10093
+!DA U+0437 afii10073
+!DB U+0448 afii10090
+!DC U+044D afii10095
+!DD U+0449 afii10091
+!DE U+0447 afii10089
+!DF U+044A afii10092
+!E0 U+042E afii10048
+!E1 U+0410 afii10017
+!E2 U+0411 afii10018
+!E3 U+0426 afii10040
+!E4 U+0414 afii10021
+!E5 U+0415 afii10022
+!E6 U+0424 afii10038
+!E7 U+0413 afii10020
+!E8 U+0425 afii10039
+!E9 U+0418 afii10026
+!EA U+0419 afii10027
+!EB U+041A afii10028
+!EC U+041B afii10029
+!ED U+041C afii10030
+!EE U+041D afii10031
+!EF U+041E afii10032
+!F0 U+041F afii10033
+!F1 U+042F afii10049
+!F2 U+0420 afii10034
+!F3 U+0421 afii10035
+!F4 U+0422 afii10036
+!F5 U+0423 afii10037
+!F6 U+0416 afii10024
+!F7 U+0412 afii10019
+!F8 U+042C afii10046
+!F9 U+042B afii10045
+!FA U+0417 afii10025
+!FB U+0428 afii10042
+!FC U+042D afii10047
+!FD U+0429 afii10043
+!FE U+0427 afii10041
+!FF U+042A afii10044
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1252.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1252.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1252.map	(revision 795)
@@ -0,0 +1,251 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!83 U+0192 florin
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+02C6 circumflex
+!89 U+2030 perthousand
+!8A U+0160 Scaron
+!8B U+2039 guilsinglleft
+!8C U+0152 OE
+!8E U+017D Zcaron
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!98 U+02DC tilde
+!99 U+2122 trademark
+!9A U+0161 scaron
+!9B U+203A guilsinglright
+!9C U+0153 oe
+!9E U+017E zcaron
+!9F U+0178 Ydieresis
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+00D0 Eth
+!D1 U+00D1 Ntilde
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+00DE Thorn
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+00F0 eth
+!F1 U+00F1 ntilde
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+00FE thorn
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1253.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1253.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1253.map	(revision 795)
@@ -0,0 +1,239 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!83 U+0192 florin
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!89 U+2030 perthousand
+!8B U+2039 guilsinglleft
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!99 U+2122 trademark
+!9B U+203A guilsinglright
+!A0 U+00A0 space
+!A1 U+0385 dieresistonos
+!A2 U+0386 Alphatonos
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+2015 afii00208
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+0384 tonos
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+0388 Epsilontonos
+!B9 U+0389 Etatonos
+!BA U+038A Iotatonos
+!BB U+00BB guillemotright
+!BC U+038C Omicrontonos
+!BD U+00BD onehalf
+!BE U+038E Upsilontonos
+!BF U+038F Omegatonos
+!C0 U+0390 iotadieresistonos
+!C1 U+0391 Alpha
+!C2 U+0392 Beta
+!C3 U+0393 Gamma
+!C4 U+0394 Delta
+!C5 U+0395 Epsilon
+!C6 U+0396 Zeta
+!C7 U+0397 Eta
+!C8 U+0398 Theta
+!C9 U+0399 Iota
+!CA U+039A Kappa
+!CB U+039B Lambda
+!CC U+039C Mu
+!CD U+039D Nu
+!CE U+039E Xi
+!CF U+039F Omicron
+!D0 U+03A0 Pi
+!D1 U+03A1 Rho
+!D3 U+03A3 Sigma
+!D4 U+03A4 Tau
+!D5 U+03A5 Upsilon
+!D6 U+03A6 Phi
+!D7 U+03A7 Chi
+!D8 U+03A8 Psi
+!D9 U+03A9 Omega
+!DA U+03AA Iotadieresis
+!DB U+03AB Upsilondieresis
+!DC U+03AC alphatonos
+!DD U+03AD epsilontonos
+!DE U+03AE etatonos
+!DF U+03AF iotatonos
+!E0 U+03B0 upsilondieresistonos
+!E1 U+03B1 alpha
+!E2 U+03B2 beta
+!E3 U+03B3 gamma
+!E4 U+03B4 delta
+!E5 U+03B5 epsilon
+!E6 U+03B6 zeta
+!E7 U+03B7 eta
+!E8 U+03B8 theta
+!E9 U+03B9 iota
+!EA U+03BA kappa
+!EB U+03BB lambda
+!EC U+03BC mu
+!ED U+03BD nu
+!EE U+03BE xi
+!EF U+03BF omicron
+!F0 U+03C0 pi
+!F1 U+03C1 rho
+!F2 U+03C2 sigma1
+!F3 U+03C3 sigma
+!F4 U+03C4 tau
+!F5 U+03C5 upsilon
+!F6 U+03C6 phi
+!F7 U+03C7 chi
+!F8 U+03C8 psi
+!F9 U+03C9 omega
+!FA U+03CA iotadieresis
+!FB U+03CB upsilondieresis
+!FC U+03CC omicrontonos
+!FD U+03CD upsilontonos
+!FE U+03CE omegatonos
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/makefont.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/makefont.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/makefont.php	(revision 795)
@@ -0,0 +1,416 @@
+<?php
+/*******************************************************************************
+* Utility to generate font definition files                                    *
+* Version: 1.13                                                                *
+* Date:    2004-12-31                                                          *
+*******************************************************************************/
+
+function ReadMap($enc)
+{
+	//Read a map file
+	$file=dirname(__FILE__).'/'.strtolower($enc).'.map';
+	$a=file($file);
+	if(empty($a))
+		die('<B>Error:</B> encoding not found: '.$enc);
+	$cc2gn=array();
+	foreach($a as $l)
+	{
+		if($l{0}=='!')
+		{
+			$e=preg_split('/[ \\t]+/',rtrim($l));
+			$cc=hexdec(substr($e[0],1));
+			$gn=$e[2];
+			$cc2gn[$cc]=$gn;
+		}
+	}
+	for($i=0;$i<=255;$i++)
+	{
+		if(!isset($cc2gn[$i]))
+			$cc2gn[$i]='.notdef';
+	}
+	return $cc2gn;
+}
+
+function ReadAFM($file,&$map)
+{
+	//Read a font metric file
+	$a=file($file);
+	if(empty($a))
+		die('File not found');
+	$widths=array();
+	$fm=array();
+	$fix=array('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent',
+		'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut',
+		'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent',
+		'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent',
+		'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent',
+		'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat',
+		'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb',
+		'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong');
+	foreach($a as $l)
+	{
+		$e=explode(' ',rtrim($l));
+		if(count($e)<2)
+			continue;
+		$code=$e[0];
+		$param=$e[1];
+		if($code=='C')
+		{
+			//Character metrics
+			$cc=(int)$e[1];
+			$w=$e[4];
+			$gn=$e[7];
+			if(substr($gn,-4)=='20AC')
+				$gn='Euro';
+			if(isset($fix[$gn]))
+			{
+				//Fix incorrect glyph name
+				foreach($map as $c=>$n)
+				{
+					if($n==$fix[$gn])
+						$map[$c]=$gn;
+				}
+			}
+			if(empty($map))
+			{
+				//Symbolic font: use built-in encoding
+				$widths[$cc]=$w;
+			}
+			else
+			{
+				$widths[$gn]=$w;
+				if($gn=='X')
+					$fm['CapXHeight']=$e[13];
+			}
+			if($gn=='.notdef')
+				$fm['MissingWidth']=$w;
+		}
+		elseif($code=='FontName')
+			$fm['FontName']=$param;
+		elseif($code=='Weight')
+			$fm['Weight']=$param;
+		elseif($code=='ItalicAngle')
+			$fm['ItalicAngle']=(double)$param;
+		elseif($code=='Ascender')
+			$fm['Ascender']=(int)$param;
+		elseif($code=='Descender')
+			$fm['Descender']=(int)$param;
+		elseif($code=='UnderlineThickness')
+			$fm['UnderlineThickness']=(int)$param;
+		elseif($code=='UnderlinePosition')
+			$fm['UnderlinePosition']=(int)$param;
+		elseif($code=='IsFixedPitch')
+			$fm['IsFixedPitch']=($param=='true');
+		elseif($code=='FontBBox')
+			$fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]);
+		elseif($code=='CapHeight')
+			$fm['CapHeight']=(int)$param;
+		elseif($code=='StdVW')
+			$fm['StdVW']=(int)$param;
+	}
+	if(!isset($fm['FontName']))
+		die('FontName not found');
+	if(!empty($map))
+	{
+		if(!isset($widths['.notdef']))
+			$widths['.notdef']=600;
+		if(!isset($widths['Delta']) and isset($widths['increment']))
+			$widths['Delta']=$widths['increment'];
+		//Order widths according to map
+		for($i=0;$i<=255;$i++)
+		{
+			if(!isset($widths[$map[$i]]))
+			{
+				echo '<B>Warning:</B> character '.$map[$i].' is missing<BR>';
+				$widths[$i]=$widths['.notdef'];
+			}
+			else
+				$widths[$i]=$widths[$map[$i]];
+		}
+	}
+	$fm['Widths']=$widths;
+	return $fm;
+}
+
+function MakeFontDescriptor($fm,$symbolic)
+{
+	//Ascent
+	$asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000);
+	$fd="array('Ascent'=>".$asc;
+	//Descent
+	$desc=(isset($fm['Descender']) ? $fm['Descender'] : -200);
+	$fd.=",'Descent'=>".$desc;
+	//CapHeight
+	if(isset($fm['CapHeight']))
+		$ch=$fm['CapHeight'];
+	elseif(isset($fm['CapXHeight']))
+		$ch=$fm['CapXHeight'];
+	else
+		$ch=$asc;
+	$fd.=",'CapHeight'=>".$ch;
+	//Flags
+	$flags=0;
+	if(isset($fm['IsFixedPitch']) and $fm['IsFixedPitch'])
+		$flags+=1<<0;
+	if($symbolic)
+		$flags+=1<<2;
+	if(!$symbolic)
+		$flags+=1<<5;
+	if(isset($fm['ItalicAngle']) and $fm['ItalicAngle']!=0)
+		$flags+=1<<6;
+	$fd.=",'Flags'=>".$flags;
+	//FontBBox
+	if(isset($fm['FontBBox']))
+		$fbb=$fm['FontBBox'];
+	else
+		$fbb=array(0,$des-100,1000,$asc+100);
+	$fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";
+	//ItalicAngle
+	$ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0);
+	$fd.=",'ItalicAngle'=>".$ia;
+	//StemV
+	if(isset($fm['StdVW']))
+		$stemv=$fm['StdVW'];
+	elseif(isset($fm['Weight']) and eregi('(bold|black)',$fm['Weight']))
+		$stemv=120;
+	else
+		$stemv=70;
+	$fd.=",'StemV'=>".$stemv;
+	//MissingWidth
+	if(isset($fm['MissingWidth']))
+		$fd.=",'MissingWidth'=>".$fm['MissingWidth'];
+	$fd.=')';
+	return $fd;
+}
+
+function MakeWidthArray($fm)
+{
+	//Make character width array
+	$s="array(\n\t";
+	$cw=$fm['Widths'];
+	for($i=0;$i<=255;$i++)
+	{
+		if(chr($i)=="'")
+			$s.="'\\''";
+		elseif(chr($i)=="\\")
+			$s.="'\\\\'";
+		elseif($i>=32 and $i<=126)
+			$s.="'".chr($i)."'";
+		else
+			$s.="chr($i)";
+		$s.='=>'.$fm['Widths'][$i];
+		if($i<255)
+			$s.=',';
+		if(($i+1)%22==0)
+			$s.="\n\t";
+	}
+	$s.=')';
+	return $s;
+}
+
+function MakeFontEncoding($map)
+{
+	//Build differences from reference encoding
+	$ref=ReadMap('cp1252');
+	$s='';
+	$last=0;
+	for($i=32;$i<=255;$i++)
+	{
+		if($map[$i]!=$ref[$i])
+		{
+			if($i!=$last+1)
+				$s.=$i.' ';
+			$last=$i;
+			$s.='/'.$map[$i].' ';
+		}
+	}
+	return rtrim($s);
+}
+
+function SaveToFile($file,$s,$mode='t')
+{
+	$f=fopen($file,'w'.$mode);
+	if(!$f)
+		die('Can\'t write to file '.$file);
+	fwrite($f,$s,strlen($s));
+	fclose($f);
+}
+
+function ReadShort($f)
+{
+	$a=unpack('n1n',fread($f,2));
+	return $a['n'];
+}
+
+function ReadLong($f)
+{
+	$a=unpack('N1N',fread($f,4));
+	return $a['N'];
+}
+
+function CheckTTF($file)
+{
+	//Check if font license allows embedding
+	$f=fopen($file,'rb');
+	if(!$f)
+		die('<B>Error:</B> Can\'t open '.$file);
+	//Extract number of tables
+	fseek($f,4,SEEK_CUR);
+	$nb=ReadShort($f);
+	fseek($f,6,SEEK_CUR);
+	//Seek OS/2 table
+	$found=false;
+	for($i=0;$i<$nb;$i++)
+	{
+		if(fread($f,4)=='OS/2')
+		{
+			$found=true;
+			break;
+		}
+		fseek($f,12,SEEK_CUR);
+	}
+	if(!$found)
+	{
+		fclose($f);
+		return;
+	}
+	fseek($f,4,SEEK_CUR);
+	$offset=ReadLong($f);
+	fseek($f,$offset,SEEK_SET);
+	//Extract fsType flags
+	fseek($f,8,SEEK_CUR);
+	$fsType=ReadShort($f);
+	$rl=($fsType & 0x02)!=0;
+	$pp=($fsType & 0x04)!=0;
+	$e=($fsType & 0x08)!=0;
+	fclose($f);
+	if($rl and !$pp and !$e)
+		echo '<B>Warning:</B> font license does not allow embedding';
+}
+
+/*******************************************************************************
+* $fontfile : chemin du fichier TTF (ou chaîne vide si pas d'incorporation)    *
+* $afmfile :  chemin du fichier AFM                                            *
+* $enc :      encodage (ou chaîne vide si la police est symbolique)            *
+* $patch :    patch optionnel pour l'encodage                                  *
+* $type :     type de la police si $fontfile est vide                          *
+*******************************************************************************/
+function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueType')
+{
+	//Generate a font definition file
+	set_magic_quotes_runtime(0);
+	ini_set('auto_detect_line_endings','1');
+	if($enc)
+	{
+		$map=ReadMap($enc);
+		foreach($patch as $cc=>$gn)
+			$map[$cc]=$gn;
+	}
+	else
+		$map=array();
+	if(!file_exists($afmfile))
+		die('<B>Error:</B> AFM file not found: '.$afmfile);
+	$fm=ReadAFM($afmfile,$map);
+	if($enc)
+		$diff=MakeFontEncoding($map);
+	else
+		$diff='';
+	$fd=MakeFontDescriptor($fm,empty($map));
+	//Find font type
+	if($fontfile)
+	{
+		$ext=strtolower(substr($fontfile,-3));
+		if($ext=='ttf')
+			$type='TrueType';
+		elseif($ext=='pfb')
+			$type='Type1';
+		else
+			die('<B>Error:</B> unrecognized font file extension: '.$ext);
+	}
+	else
+	{
+		if($type!='TrueType' and $type!='Type1')
+			die('<B>Error:</B> incorrect font type: '.$type);
+	}
+	//Start generation
+	$s='<?php'."\n";
+	$s.='$type=\''.$type."';\n";
+	$s.='$name=\''.$fm['FontName']."';\n";
+	$s.='$desc='.$fd.";\n";
+	if(!isset($fm['UnderlinePosition']))
+		$fm['UnderlinePosition']=-100;
+	if(!isset($fm['UnderlineThickness']))
+		$fm['UnderlineThickness']=50;
+	$s.='$up='.$fm['UnderlinePosition'].";\n";
+	$s.='$ut='.$fm['UnderlineThickness'].";\n";
+	$w=MakeWidthArray($fm);
+	$s.='$cw='.$w.";\n";
+	$s.='$enc=\''.$enc."';\n";
+	$s.='$diff=\''.$diff."';\n";
+	$basename=substr(basename($afmfile),0,-4);
+	if($fontfile)
+	{
+		//Embedded font
+		if(!file_exists($fontfile))
+			die('<B>Error:</B> font file not found: '.$fontfile);
+		if($type=='TrueType')
+			CheckTTF($fontfile);
+		$f=fopen($fontfile,'rb');
+		if(!$f)
+			die('<B>Error:</B> Can\'t open '.$fontfile);
+		$file=fread($f,filesize($fontfile));
+		fclose($f);
+		if($type=='Type1')
+		{
+			//Find first two sections and discard third one
+			$header=(ord($file{0})==128);
+			if($header)
+			{
+				//Strip first binary header
+				$file=substr($file,6);
+			}
+			$pos=strpos($file,'eexec');
+			if(!$pos)
+				die('<B>Error:</B> font file does not seem to be valid Type1');
+			$size1=$pos+6;
+			if($header and ord($file{$size1})==128)
+			{
+				//Strip second binary header
+				$file=substr($file,0,$size1).substr($file,$size1+6);
+			}
+			$pos=strpos($file,'00000000');
+			if(!$pos)
+				die('<B>Error:</B> font file does not seem to be valid Type1');
+			$size2=$pos-$size1;
+			$file=substr($file,0,$size1+$size2);
+		}
+		if(function_exists('gzcompress'))
+		{
+			$cmp=$basename.'.z';
+			SaveToFile($cmp,gzcompress($file),'b');
+			$s.='$file=\''.$cmp."';\n";
+			echo 'Font file compressed ('.$cmp.')<BR>';
+		}
+		else
+		{
+			$s.='$file=\''.basename($fontfile)."';\n";
+			echo '<B>Notice:</B> font file could not be compressed (zlib extension not available)<BR>';
+		}
+		if($type=='Type1')
+		{
+			$s.='$size1='.$size1.";\n";
+			$s.='$size2='.$size2.";\n";
+		}
+		else
+			$s.='$originalsize='.filesize($fontfile).";\n";
+	}
+	else
+	{
+		//Not embedded font
+		$s.='$file='."'';\n";
+	}
+	$s.="?>\n";
+	SaveToFile($basename.'.php',$s);
+	echo 'Font definition file generated ('.$basename.'.php'.')<BR>';
+}
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1254.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1254.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1254.map	(revision 795)
@@ -0,0 +1,249 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!83 U+0192 florin
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+02C6 circumflex
+!89 U+2030 perthousand
+!8A U+0160 Scaron
+!8B U+2039 guilsinglleft
+!8C U+0152 OE
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!98 U+02DC tilde
+!99 U+2122 trademark
+!9A U+0161 scaron
+!9B U+203A guilsinglright
+!9C U+0153 oe
+!9F U+0178 Ydieresis
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+011E Gbreve
+!D1 U+00D1 Ntilde
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+0130 Idotaccent
+!DE U+015E Scedilla
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+011F gbreve
+!F1 U+00F1 ntilde
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+0131 dotlessi
+!FE U+015F scedilla
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1255.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1255.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1255.map	(revision 795)
@@ -0,0 +1,233 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!83 U+0192 florin
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+02C6 circumflex
+!89 U+2030 perthousand
+!8B U+2039 guilsinglleft
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!98 U+02DC tilde
+!99 U+2122 trademark
+!9B U+203A guilsinglright
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+20AA afii57636
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00D7 multiply
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD sfthyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 middot
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00F7 divide
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+05B0 afii57799
+!C1 U+05B1 afii57801
+!C2 U+05B2 afii57800
+!C3 U+05B3 afii57802
+!C4 U+05B4 afii57793
+!C5 U+05B5 afii57794
+!C6 U+05B6 afii57795
+!C7 U+05B7 afii57798
+!C8 U+05B8 afii57797
+!C9 U+05B9 afii57806
+!CB U+05BB afii57796
+!CC U+05BC afii57807
+!CD U+05BD afii57839
+!CE U+05BE afii57645
+!CF U+05BF afii57841
+!D0 U+05C0 afii57842
+!D1 U+05C1 afii57804
+!D2 U+05C2 afii57803
+!D3 U+05C3 afii57658
+!D4 U+05F0 afii57716
+!D5 U+05F1 afii57717
+!D6 U+05F2 afii57718
+!D7 U+05F3 gereshhebrew
+!D8 U+05F4 gershayimhebrew
+!E0 U+05D0 afii57664
+!E1 U+05D1 afii57665
+!E2 U+05D2 afii57666
+!E3 U+05D3 afii57667
+!E4 U+05D4 afii57668
+!E5 U+05D5 afii57669
+!E6 U+05D6 afii57670
+!E7 U+05D7 afii57671
+!E8 U+05D8 afii57672
+!E9 U+05D9 afii57673
+!EA U+05DA afii57674
+!EB U+05DB afii57675
+!EC U+05DC afii57676
+!ED U+05DD afii57677
+!EE U+05DE afii57678
+!EF U+05DF afii57679
+!F0 U+05E0 afii57680
+!F1 U+05E1 afii57681
+!F2 U+05E2 afii57682
+!F3 U+05E3 afii57683
+!F4 U+05E4 afii57684
+!F5 U+05E5 afii57685
+!F6 U+05E6 afii57686
+!F7 U+05E7 afii57687
+!F8 U+05E8 afii57688
+!F9 U+05E9 afii57689
+!FA U+05EA afii57690
+!FD U+200E afii299
+!FE U+200F afii300
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1257.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1257.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1257.map	(revision 795)
@@ -0,0 +1,244 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!89 U+2030 perthousand
+!8B U+2039 guilsinglleft
+!8D U+00A8 dieresis
+!8E U+02C7 caron
+!8F U+00B8 cedilla
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!99 U+2122 trademark
+!9B U+203A guilsinglright
+!9D U+00AF macron
+!9E U+02DB ogonek
+!A0 U+00A0 space
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00D8 Oslash
+!A9 U+00A9 copyright
+!AA U+0156 Rcommaaccent
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00C6 AE
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00F8 oslash
+!B9 U+00B9 onesuperior
+!BA U+0157 rcommaaccent
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00E6 ae
+!C0 U+0104 Aogonek
+!C1 U+012E Iogonek
+!C2 U+0100 Amacron
+!C3 U+0106 Cacute
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+0118 Eogonek
+!C7 U+0112 Emacron
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0179 Zacute
+!CB U+0116 Edotaccent
+!CC U+0122 Gcommaaccent
+!CD U+0136 Kcommaaccent
+!CE U+012A Imacron
+!CF U+013B Lcommaaccent
+!D0 U+0160 Scaron
+!D1 U+0143 Nacute
+!D2 U+0145 Ncommaaccent
+!D3 U+00D3 Oacute
+!D4 U+014C Omacron
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+0172 Uogonek
+!D9 U+0141 Lslash
+!DA U+015A Sacute
+!DB U+016A Umacron
+!DC U+00DC Udieresis
+!DD U+017B Zdotaccent
+!DE U+017D Zcaron
+!DF U+00DF germandbls
+!E0 U+0105 aogonek
+!E1 U+012F iogonek
+!E2 U+0101 amacron
+!E3 U+0107 cacute
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+0119 eogonek
+!E7 U+0113 emacron
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+017A zacute
+!EB U+0117 edotaccent
+!EC U+0123 gcommaaccent
+!ED U+0137 kcommaaccent
+!EE U+012B imacron
+!EF U+013C lcommaaccent
+!F0 U+0161 scaron
+!F1 U+0144 nacute
+!F2 U+0146 ncommaaccent
+!F3 U+00F3 oacute
+!F4 U+014D omacron
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+0173 uogonek
+!F9 U+0142 lslash
+!FA U+015B sacute
+!FB U+016B umacron
+!FC U+00FC udieresis
+!FD U+017C zdotaccent
+!FE U+017E zcaron
+!FF U+02D9 dotaccent
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1258.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1258.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/cp1258.map	(revision 795)
@@ -0,0 +1,247 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!83 U+0192 florin
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+02C6 circumflex
+!89 U+2030 perthousand
+!8B U+2039 guilsinglleft
+!8C U+0152 OE
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!98 U+02DC tilde
+!99 U+2122 trademark
+!9B U+203A guilsinglright
+!9C U+0153 oe
+!9F U+0178 Ydieresis
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+0102 Abreve
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+0300 gravecomb
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+0110 Dcroat
+!D1 U+00D1 Ntilde
+!D2 U+0309 hookabovecomb
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+01A0 Ohorn
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+01AF Uhorn
+!DE U+0303 tildecomb
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+0301 acutecomb
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+0111 dcroat
+!F1 U+00F1 ntilde
+!F2 U+0323 dotbelowcomb
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+01A1 ohorn
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+01B0 uhorn
+!FE U+20AB dong
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-11.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-11.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-11.map	(revision 795)
@@ -0,0 +1,248 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0E01 kokaithai
+!A2 U+0E02 khokhaithai
+!A3 U+0E03 khokhuatthai
+!A4 U+0E04 khokhwaithai
+!A5 U+0E05 khokhonthai
+!A6 U+0E06 khorakhangthai
+!A7 U+0E07 ngonguthai
+!A8 U+0E08 chochanthai
+!A9 U+0E09 chochingthai
+!AA U+0E0A chochangthai
+!AB U+0E0B sosothai
+!AC U+0E0C chochoethai
+!AD U+0E0D yoyingthai
+!AE U+0E0E dochadathai
+!AF U+0E0F topatakthai
+!B0 U+0E10 thothanthai
+!B1 U+0E11 thonangmonthothai
+!B2 U+0E12 thophuthaothai
+!B3 U+0E13 nonenthai
+!B4 U+0E14 dodekthai
+!B5 U+0E15 totaothai
+!B6 U+0E16 thothungthai
+!B7 U+0E17 thothahanthai
+!B8 U+0E18 thothongthai
+!B9 U+0E19 nonuthai
+!BA U+0E1A bobaimaithai
+!BB U+0E1B poplathai
+!BC U+0E1C phophungthai
+!BD U+0E1D fofathai
+!BE U+0E1E phophanthai
+!BF U+0E1F fofanthai
+!C0 U+0E20 phosamphaothai
+!C1 U+0E21 momathai
+!C2 U+0E22 yoyakthai
+!C3 U+0E23 roruathai
+!C4 U+0E24 ruthai
+!C5 U+0E25 lolingthai
+!C6 U+0E26 luthai
+!C7 U+0E27 wowaenthai
+!C8 U+0E28 sosalathai
+!C9 U+0E29 sorusithai
+!CA U+0E2A sosuathai
+!CB U+0E2B hohipthai
+!CC U+0E2C lochulathai
+!CD U+0E2D oangthai
+!CE U+0E2E honokhukthai
+!CF U+0E2F paiyannoithai
+!D0 U+0E30 saraathai
+!D1 U+0E31 maihanakatthai
+!D2 U+0E32 saraaathai
+!D3 U+0E33 saraamthai
+!D4 U+0E34 saraithai
+!D5 U+0E35 saraiithai
+!D6 U+0E36 sarauethai
+!D7 U+0E37 saraueethai
+!D8 U+0E38 sarauthai
+!D9 U+0E39 sarauuthai
+!DA U+0E3A phinthuthai
+!DF U+0E3F bahtthai
+!E0 U+0E40 saraethai
+!E1 U+0E41 saraaethai
+!E2 U+0E42 saraothai
+!E3 U+0E43 saraaimaimuanthai
+!E4 U+0E44 saraaimaimalaithai
+!E5 U+0E45 lakkhangyaothai
+!E6 U+0E46 maiyamokthai
+!E7 U+0E47 maitaikhuthai
+!E8 U+0E48 maiekthai
+!E9 U+0E49 maithothai
+!EA U+0E4A maitrithai
+!EB U+0E4B maichattawathai
+!EC U+0E4C thanthakhatthai
+!ED U+0E4D nikhahitthai
+!EE U+0E4E yamakkanthai
+!EF U+0E4F fongmanthai
+!F0 U+0E50 zerothai
+!F1 U+0E51 onethai
+!F2 U+0E52 twothai
+!F3 U+0E53 threethai
+!F4 U+0E54 fourthai
+!F5 U+0E55 fivethai
+!F6 U+0E56 sixthai
+!F7 U+0E57 seventhai
+!F8 U+0E58 eightthai
+!F9 U+0E59 ninethai
+!FA U+0E5A angkhankhuthai
+!FB U+0E5B khomutthai
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-15.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-15.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-15.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+20AC Euro
+!A5 U+00A5 yen
+!A6 U+0160 Scaron
+!A7 U+00A7 section
+!A8 U+0161 scaron
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+017D Zcaron
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+017E zcaron
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+0152 OE
+!BD U+0153 oe
+!BE U+0178 Ydieresis
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+00D0 Eth
+!D1 U+00D1 Ntilde
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+00DE Thorn
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+00F0 eth
+!F1 U+00F1 ntilde
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+00FE thorn
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-16.map
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-16.map	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/makefont/iso-8859-16.map	(revision 795)
@@ -0,0 +1,256 @@
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0104 Aogonek
+!A2 U+0105 aogonek
+!A3 U+0141 Lslash
+!A4 U+20AC Euro
+!A5 U+201E quotedblbase
+!A6 U+0160 Scaron
+!A7 U+00A7 section
+!A8 U+0161 scaron
+!A9 U+00A9 copyright
+!AA U+0218 Scommaaccent
+!AB U+00AB guillemotleft
+!AC U+0179 Zacute
+!AD U+00AD hyphen
+!AE U+017A zacute
+!AF U+017B Zdotaccent
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+010C Ccaron
+!B3 U+0142 lslash
+!B4 U+017D Zcaron
+!B5 U+201D quotedblright
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+017E zcaron
+!B9 U+010D ccaron
+!BA U+0219 scommaaccent
+!BB U+00BB guillemotright
+!BC U+0152 OE
+!BD U+0153 oe
+!BE U+0178 Ydieresis
+!BF U+017C zdotaccent
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+0102 Abreve
+!C4 U+00C4 Adieresis
+!C5 U+0106 Cacute
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+0110 Dcroat
+!D1 U+0143 Nacute
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+0150 Ohungarumlaut
+!D6 U+00D6 Odieresis
+!D7 U+015A Sacute
+!D8 U+0170 Uhungarumlaut
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+0118 Eogonek
+!DE U+021A Tcommaaccent
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!E4 U+00E4 adieresis
+!E5 U+0107 cacute
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+0111 dcroat
+!F1 U+0144 nacute
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+0151 ohungarumlaut
+!F6 U+00F6 odieresis
+!F7 U+015B sacute
+!F8 U+0171 uhungarumlaut
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+0119 eogonek
+!FE U+021B tcommaaccent
+!FF U+00FF ydieresis
Index: /sandbox/workflow/branches/993/inc/fpdf/font/helveticabi.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/helveticabi.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/helveticabi.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['helveticaBI']=array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
+	'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
+	'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
+	chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
+	chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/times.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/times.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/times.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['times']=array(
+	chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+	chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>408,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>180,'('=>333,')'=>333,'*'=>500,'+'=>564,
+	','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>564,'='=>564,'>'=>564,'?'=>444,'@'=>921,'A'=>722,
+	'B'=>667,'C'=>667,'D'=>722,'E'=>611,'F'=>556,'G'=>722,'H'=>722,'I'=>333,'J'=>389,'K'=>722,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>556,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>722,'W'=>944,
+	'X'=>722,'Y'=>722,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>469,'_'=>500,'`'=>333,'a'=>444,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
+	'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>333,'s'=>389,'t'=>278,'u'=>500,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>480,'|'=>200,'}'=>480,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+	chr(132)=>444,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>889,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>444,chr(148)=>444,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>980,
+	chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>200,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>564,chr(173)=>333,chr(174)=>760,chr(175)=>333,
+	chr(176)=>400,chr(177)=>564,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>453,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>444,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+	chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>564,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>722,chr(222)=>556,chr(223)=>500,chr(224)=>444,chr(225)=>444,chr(226)=>444,chr(227)=>444,chr(228)=>444,chr(229)=>444,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
+	chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>564,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>500,chr(254)=>500,chr(255)=>500);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/timesb.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/timesb.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/timesb.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['timesB']=array(
+	chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+	chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>555,'#'=>500,'$'=>500,'%'=>1000,'&'=>833,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570,
+	','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>930,'A'=>722,
+	'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>778,'I'=>389,'J'=>500,'K'=>778,'L'=>667,'M'=>944,'N'=>722,'O'=>778,'P'=>611,'Q'=>778,'R'=>722,'S'=>556,'T'=>667,'U'=>722,'V'=>722,'W'=>1000,
+	'X'=>722,'Y'=>722,'Z'=>667,'['=>333,'\\'=>278,']'=>333,'^'=>581,'_'=>500,'`'=>333,'a'=>500,'b'=>556,'c'=>444,'d'=>556,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>333,'k'=>556,'l'=>278,'m'=>833,
+	'n'=>556,'o'=>500,'p'=>556,'q'=>556,'r'=>444,'s'=>389,'t'=>333,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>394,'|'=>220,'}'=>394,'~'=>520,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+	chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>667,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>300,chr(171)=>500,chr(172)=>570,chr(173)=>333,chr(174)=>747,chr(175)=>333,
+	chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>556,chr(182)=>540,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>330,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>570,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>722,chr(222)=>611,chr(223)=>556,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556,
+	chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/helvetica.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/helvetica.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/helvetica.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['helvetica']=array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
+	'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
+	'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
+	chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
+	chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/symbol.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/symbol.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/symbol.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['symbol']=array(
+	chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+	chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549,
+	','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722,
+	'B'=>667,'C'=>722,'D'=>612,'E'=>611,'F'=>763,'G'=>603,'H'=>722,'I'=>333,'J'=>631,'K'=>722,'L'=>686,'M'=>889,'N'=>722,'O'=>722,'P'=>768,'Q'=>741,'R'=>556,'S'=>592,'T'=>611,'U'=>690,'V'=>439,'W'=>768,
+	'X'=>645,'Y'=>795,'Z'=>611,'['=>333,'\\'=>863,']'=>333,'^'=>658,'_'=>500,'`'=>500,'a'=>631,'b'=>549,'c'=>549,'d'=>494,'e'=>439,'f'=>521,'g'=>411,'h'=>603,'i'=>329,'j'=>603,'k'=>549,'l'=>549,'m'=>576,
+	'n'=>521,'o'=>549,'p'=>549,'q'=>521,'r'=>549,'s'=>603,'t'=>439,'u'=>576,'v'=>713,'w'=>686,'x'=>493,'y'=>686,'z'=>494,'{'=>480,'|'=>200,'}'=>480,'~'=>549,chr(127)=>0,chr(128)=>0,chr(129)=>0,chr(130)=>0,chr(131)=>0,
+	chr(132)=>0,chr(133)=>0,chr(134)=>0,chr(135)=>0,chr(136)=>0,chr(137)=>0,chr(138)=>0,chr(139)=>0,chr(140)=>0,chr(141)=>0,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
+	chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>750,chr(161)=>620,chr(162)=>247,chr(163)=>549,chr(164)=>167,chr(165)=>713,chr(166)=>500,chr(167)=>753,chr(168)=>753,chr(169)=>753,chr(170)=>753,chr(171)=>1042,chr(172)=>987,chr(173)=>603,chr(174)=>987,chr(175)=>603,
+	chr(176)=>400,chr(177)=>549,chr(178)=>411,chr(179)=>549,chr(180)=>549,chr(181)=>713,chr(182)=>494,chr(183)=>460,chr(184)=>549,chr(185)=>549,chr(186)=>549,chr(187)=>549,chr(188)=>1000,chr(189)=>603,chr(190)=>1000,chr(191)=>658,chr(192)=>823,chr(193)=>686,chr(194)=>795,chr(195)=>987,chr(196)=>768,chr(197)=>768,
+	chr(198)=>823,chr(199)=>768,chr(200)=>768,chr(201)=>713,chr(202)=>713,chr(203)=>713,chr(204)=>713,chr(205)=>713,chr(206)=>713,chr(207)=>713,chr(208)=>768,chr(209)=>713,chr(210)=>790,chr(211)=>790,chr(212)=>890,chr(213)=>823,chr(214)=>549,chr(215)=>250,chr(216)=>713,chr(217)=>603,chr(218)=>603,chr(219)=>1042,
+	chr(220)=>987,chr(221)=>603,chr(222)=>987,chr(223)=>603,chr(224)=>494,chr(225)=>329,chr(226)=>790,chr(227)=>790,chr(228)=>786,chr(229)=>713,chr(230)=>384,chr(231)=>384,chr(232)=>384,chr(233)=>384,chr(234)=>384,chr(235)=>384,chr(236)=>494,chr(237)=>494,chr(238)=>494,chr(239)=>494,chr(240)=>0,chr(241)=>329,
+	chr(242)=>274,chr(243)=>686,chr(244)=>686,chr(245)=>686,chr(246)=>384,chr(247)=>384,chr(248)=>384,chr(249)=>384,chr(250)=>384,chr(251)=>384,chr(252)=>494,chr(253)=>494,chr(254)=>494,chr(255)=>0);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/helveticab.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/helveticab.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/helveticab.php	(revision 795)
@@ -0,0 +1,15 @@
+<?php
+$fpdf_charwidths['helveticaB']=array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
+	'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
+	'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
+	chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
+	chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/font/courier.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/font/courier.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/font/courier.php	(revision 795)
@@ -0,0 +1,7 @@
+<?php
+for($i=0;$i<=255;$i++)
+	$fpdf_charwidths['courier'][chr($i)]=600;
+$fpdf_charwidths['courierB']=$fpdf_charwidths['courier'];
+$fpdf_charwidths['courierI']=$fpdf_charwidths['courier'];
+$fpdf_charwidths['courierBI']=$fpdf_charwidths['courier'];
+?>
Index: /sandbox/workflow/branches/993/inc/fpdf/mem_image.php
===================================================================
--- /sandbox/workflow/branches/993/inc/fpdf/mem_image.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/fpdf/mem_image.php	(revision 795)
@@ -0,0 +1,220 @@
+<?php
+require_once('fpdf.php');
+
+class VariableStream
+{
+	// Stream handler to read from global variables
+	var $varname;
+	var $position;
+
+	function stream_open($path, $mode, $options, &$opened_path)
+	{
+		$url = parse_url($path);
+		$this->varname = $url['host'];
+		if(!isset($GLOBALS[$this->varname]))
+		{
+			trigger_error('Global variable '.$this->varname.' does not exist', E_USER_WARNING);
+			return false;
+		}
+		$this->position = 0;
+		return true;
+	}
+
+	function stream_read($count)
+	{
+		$ret = substr($GLOBALS[$this->varname], $this->position, $count);
+		$this->position += strlen($ret);
+		return $ret;
+	}
+
+	function stream_eof()
+	{
+		return $this->position >= strlen($GLOBALS[$this->varname]);
+	}
+
+	function stream_tell()
+	{
+		return $this->position;
+	}
+
+	function stream_seek($offset, $whence)
+	{
+		if($whence==SEEK_SET)
+		{
+			$this->position = $offset;
+			return true;
+		}
+		return false;
+	}
+}
+
+class MEM_IMAGE extends FPDF
+{
+	// (c) Xavier Nicolay
+	// V1.01 : 2006-11-19
+
+	//
+	// CONSTRUCTOR
+	//
+	function MEM_IMAGE($orientation='P',$unit='mm',$format='A4')
+	{
+		$this->FPDF($orientation, $unit, $format);
+		//Register var stream protocol (requires PHP>=4.3.2)
+		if(function_exists('stream_wrapper_register'))
+			stream_wrapper_register('var','VariableStream');
+	}
+
+	//
+	// PRIVATE FUNCTIONS
+	//
+	function _readstr($var, &$pos, $n)
+	{
+		//Read some bytes from string
+		$string = substr($var, $pos, $n);
+		$pos += $n;
+		return $string;
+	}
+
+	function _readstr_int($var, &$pos)
+	{
+		//Read a 4-byte integer from string
+		$i =ord($this->_readstr($var, $pos, 1))<<24;
+		$i+=ord($this->_readstr($var, $pos, 1))<<16;
+		$i+=ord($this->_readstr($var, $pos, 1))<<8;
+		$i+=ord($this->_readstr($var, $pos, 1));
+		return $i;
+	}
+
+	function _parsemempng($var)
+	{
+		$pos=0;
+		//Check signature
+		$sig = $this->_readstr($var,$pos, 8);
+		if($sig != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
+			$this->Error('Not a PNG image');
+		//Read header chunk
+		$this->_readstr($var,$pos,4);
+		$ihdr = $this->_readstr($var,$pos,4);
+		if( $ihdr != 'IHDR')
+			$this->Error('Incorrect PNG Image');
+		$w=$this->_readstr_int($var,$pos);
+		$h=$this->_readstr_int($var,$pos);
+		$bpc=ord($this->_readstr($var,$pos,1));
+		if($bpc>8)
+			$this->Error('16-bit depth not supported: '.$file);
+		$ct=ord($this->_readstr($var,$pos,1));
+		if($ct==0)
+			$colspace='DeviceGray';
+		elseif($ct==2)
+			$colspace='DeviceRGB';
+		elseif($ct==3)
+			$colspace='Indexed';
+		else
+			$this->Error('Alpha channel not supported: '.$file);
+		if(ord($this->_readstr($var,$pos,1))!=0)
+			$this->Error('Unknown compression method: '.$file);
+		if(ord($this->_readstr($var,$pos,1))!=0)
+			$this->Error('Unknown filter method: '.$file);
+		if(ord($this->_readstr($var,$pos,1))!=0)
+			$this->Error('Interlacing not supported: '.$file);
+		$this->_readstr($var,$pos,4);
+		$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
+		//Scan chunks looking for palette, transparency and image data
+		$pal='';
+		$trns='';
+		$data='';
+		do
+		{
+			$n=$this->_readstr_int($var,$pos);
+			$type=$this->_readstr($var,$pos,4);
+			if($type=='PLTE')
+			{
+				//Read palette
+				$pal=$this->_readstr($var,$pos,$n);
+				$this->_readstr($var,$pos,4);
+			}
+			elseif($type=='tRNS')
+			{
+				//Read transparency info
+				$t=$this->_readstr($var,$pos,$n);
+				if($ct==0)
+					$trns=array(ord(substr($t,1,1)));
+				elseif($ct==2)
+					$trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
+				else
+				{
+					$p=strpos($t,chr(0));
+					if(is_int($p))
+						$trns=array($p);
+				}
+				$this->_readstr($var,$pos,4);
+			}
+			elseif($type=='IDAT')
+			{
+				//Read image data block
+				$data.=$this->_readstr($var,$pos,$n);
+				$this->_readstr($var,$pos,4);
+			}
+			elseif($type=='IEND')
+				break;
+			else
+				$this->_readstr($var,$pos,$n+4);
+		}
+		while($n);
+		if($colspace=='Indexed' and empty($pal))
+			$this->Error('Missing palette in '.$file);
+		return array('w'=>$w,
+					 'h'=>$h,
+					 'cs'=>$colspace,
+					 'bpc'=>$bpc,
+					 'f'=>'FlateDecode',
+					 'parms'=>$parms,
+					 'pal'=>$pal,
+					 'trns'=>$trns,
+					 'data'=>$data);
+	}
+
+	/********************/
+	/* PUBLIC FUNCTIONS */
+	/********************/
+	function MemImage($data, $x, $y, $w=0, $h=0, $link='')
+	{
+		//Put the PNG image stored in $data
+		$id = md5($data);
+		if(!isset($this->images[$id]))
+		{
+			$info = $this->_parsemempng( $data );
+			$info['i'] = count($this->images)+1;
+			$this->images[$id]=$info;
+		}
+		else
+			$info=$this->images[$id];
+
+		//Automatic width and height calculation if needed
+		if($w==0 and $h==0)
+		{
+			//Put image at 72 dpi
+			$w=$info['w']/$this->k;
+			$h=$info['h']/$this->k;
+		}
+		if($w==0)
+			$w=$h*$info['w']/$info['h'];
+		if($h==0)
+			$h=$w*$info['h']/$info['w'];
+		$this->_out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i']));
+		if($link)
+			$this->Link($x,$y,$w,$h,$link);
+	}
+
+	function GDImage($im, $x, $y, $w=0, $h=0, $link='')
+	{
+		//Put the GD image $im
+		ob_start();
+		imagepng($im);
+		$data = ob_get_contents();
+		ob_end_clean();
+		$this->MemImage($data, $x, $y, $w, $h, $link);
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/hook_preferences.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/hook_preferences.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/hook_preferences.inc.php	(revision 795)
@@ -0,0 +1,28 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * Written first by Joseph Engo <jengo@phpgroupware.org>                    *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+
+{
+// Only Modify the $file and $title variables.....
+	$title = $appname;
+	$file = array(
+		'Preferences' => $GLOBALS['phpgw']->link('/preferences/preferences.php','appname=workflow')
+	);
+
+//	$workflowPreferences = ExecMethod('workflow.bopreferences.getPreferences');
+//Do not modify below this line
+	display_section($appname,$title,$file);
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.assign_smarty_interface.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.assign_smarty_interface.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.assign_smarty_interface.php	(revision 795)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty assign_smarty_interface core plugin
+ *
+ * Type:     core<br>
+ * Name:     assign_smarty_interface<br>
+ * Purpose:  assign the $smarty interface variable
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_assign_smarty_interface($params, &$smarty)
+{
+        if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
+            return;
+        }
+
+        $_globals_map = array('g'  => 'HTTP_GET_VARS',
+                             'p'  => 'HTTP_POST_VARS',
+                             'c'  => 'HTTP_COOKIE_VARS',
+                             's'  => 'HTTP_SERVER_VARS',
+                             'e'  => 'HTTP_ENV_VARS');
+
+        $_smarty_vars_request  = array();
+
+        foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
+            if (isset($_globals_map[$_c])) {
+                $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
+            }
+        }
+        $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
+
+        $smarty->_smarty_vars['request'] = $_smarty_vars_request;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.load_resource_plugin.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.load_resource_plugin.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.load_resource_plugin.php	(revision 795)
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * load a resource plugin
+ *
+ * @param string $type
+ */
+
+// $type
+
+function smarty_core_load_resource_plugin($params, &$smarty)
+{
+    /*
+     * Resource plugins are not quite like the other ones, so they are
+     * handled differently. The first element of plugin info is the array of
+     * functions provided by the plugin, the second one indicates whether
+     * all of them exist or not.
+     */
+
+    $_plugin = &$smarty->_plugins['resource'][$params['type']];
+    if (isset($_plugin)) {
+        if (!$_plugin[1] && count($_plugin[0])) {
+            $_plugin[1] = true;
+            foreach ($_plugin[0] as $_plugin_func) {
+                if (!is_callable($_plugin_func)) {
+                    $_plugin[1] = false;
+                    break;
+                }
+            }
+        }
+
+        if (!$_plugin[1]) {
+            $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
+        }
+
+        return;
+    }
+
+    $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
+    $_found = ($_plugin_file != false);
+
+    if ($_found) {            /*
+         * If the plugin file is found, it -must- provide the properly named
+         * plugin functions.
+         */
+        include_once($_plugin_file);
+
+        /*
+         * Locate functions that we require the plugin to provide.
+         */
+        $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
+        $_resource_funcs = array();
+        foreach ($_resource_ops as $_op) {
+            $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
+                return;
+            } else {
+                $_resource_funcs[] = $_plugin_func;
+            }
+        }
+
+        $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.rm_auto.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.rm_auto.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.rm_auto.php	(revision 795)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete an automagically created file by name and id
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
+
+function smarty_core_rm_auto($params, &$smarty)
+{
+    if (!@is_dir($params['auto_base']))
+      return false;
+
+    if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
+        $_params = array(
+            'dirname' => $params['auto_base'],
+            'level' => 0,
+            'exp_time' => $params['exp_time']
+        );
+        require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+        $_res = smarty_core_rmdir($_params, $smarty);
+    } else {
+        $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
+
+        if(isset($params['auto_source'])) {
+            if (isset($params['extensions'])) {
+                $_res = false;
+                foreach ((array)$params['extensions'] as $_extension)
+                    $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
+            } else {
+                $_res = $smarty->_unlink($_tname, $params['exp_time']);
+            }
+        } elseif ($smarty->use_sub_dirs) {
+            $_params = array(
+                'dirname' => $_tname,
+                'level' => 1,
+                'exp_time' => $params['exp_time']
+            );
+            require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+            $_res = smarty_core_rmdir($_params, $smarty);
+        } else {
+            // remove matching file names
+            $_handle = opendir($params['auto_base']);
+            $_res = true;
+            while (false !== ($_filename = readdir($_handle))) {
+                if($_filename == '.' || $_filename == '..') {
+                    continue;
+                } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
+                    $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
+                }
+            }
+        }
+    }
+
+    return $_res;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.write_compiled_include.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.write_compiled_include.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.write_compiled_include.php	(revision 795)
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Extract non-cacheable parts out of compiled template and write it
+ *
+ * @param string $compile_path
+ * @param string $template_compiled
+ * @return boolean
+ */
+
+function smarty_core_write_compiled_include($params, &$smarty)
+{
+    $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
+    $_tag_end   = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
+
+    preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
+                   $params['compiled_content'], $_match_source, PREG_SET_ORDER);
+    
+    // no nocache-parts found: done
+    if (count($_match_source)==0) return;
+
+    // convert the matched php-code to functions
+    $_include_compiled =  "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+    $_include_compiled .= "         compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
+
+    $_compile_path = $params['include_file_path'];
+
+    $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
+    $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
+
+    $_include_compiled .= $params['plugins_code'];
+    $_include_compiled .= "<?php";
+
+    $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
+    for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
+        $_match =& $_match_source[$_i];
+        $source = $_match[4];
+        if ($this_varname == '_smarty') {
+            /* rename $this to $_smarty in the sourcecode */
+            $tokens = token_get_all('<?php ' . $_match[4]);
+
+            /* remove trailing <?php */
+            $open_tag = '';
+            while ($tokens) {
+                $token = array_shift($tokens);
+                if (is_array($token)) {
+                    $open_tag .= $token[1];
+                } else {
+                    $open_tag .= $token;
+                }
+                if ($open_tag == '<?php ') break;
+            }
+
+            for ($i=0, $count = count($tokens); $i < $count; $i++) {
+                if (is_array($tokens[$i])) {
+                    if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
+                        $tokens[$i] = '$' . $this_varname;
+                    } else {
+                        $tokens[$i] = $tokens[$i][1];
+                    }                   
+                }
+            }
+            $source = implode('', $tokens);
+        }
+
+        /* add function to compiled include */
+        $_include_compiled .= "
+function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
+{
+$source
+}
+
+";
+    }
+    $_include_compiled .= "\n\n?>\n";
+
+    $_params = array('filename' => $_compile_path,
+                     'contents' => $_include_compiled, 'create_dirs' => true);
+
+    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+    smarty_core_write_file($_params, $smarty);
+    return true;
+}
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.write_cache_file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.write_cache_file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.write_cache_file.php	(revision 795)
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Prepend the cache information to the cache file
+ * and write it
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return true|null
+ */
+
+ // $tpl_file, $cache_id, $compile_id, $results
+
+function smarty_core_write_cache_file($params, &$smarty)
+{
+
+    // put timestamp in cache header
+    $smarty->_cache_info['timestamp'] = time();
+    if ($smarty->cache_lifetime > -1){
+        // expiration set
+        $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
+    } else {
+        // cache will never expire
+        $smarty->_cache_info['expires'] = -1;
+    }
+
+    // collapse nocache.../nocache-tags
+    if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
+        // remove everything between every pair of outermost noache.../nocache-tags
+        // and replace it by a single nocache-tag
+        // this new nocache-tag will be replaced by dynamic contents in
+        // smarty_core_process_compiled_includes() on a cache-read
+        
+        $match_count = count($match[0]);
+        $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
+        
+        $level = 0;
+        $j = 0;
+        for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
+            if ($results[$i] == $match[0][$j]) {
+                // nocache tag
+                if ($match[1][$j]) { // closing tag
+                    $level--;
+                    unset($results[$i]);
+                } else { // opening tag
+                    if ($level++ > 0) unset($results[$i]);
+                }
+                $j++;
+            } elseif ($level > 0) {
+                unset($results[$i]);
+            }
+        }
+        $params['results'] = implode('', $results);
+    }
+    $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
+
+    // prepend the cache header info into cache file
+    $_cache_info = serialize($smarty->_cache_info);
+    $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
+
+    if (!empty($smarty->cache_handler_func)) {
+        // use cache_handler function
+        call_user_func_array($smarty->cache_handler_func,
+                             array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+    } else {
+        // use local cache file
+
+        if(!@is_writable($smarty->cache_dir)) {
+            // cache_dir not writable, see if it exists
+            if(!@is_dir($smarty->cache_dir)) {
+                $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+                return false;
+            }
+            $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
+            return false;
+        }
+
+        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+        $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
+        require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+        smarty_core_write_file($_params, $smarty);
+        return true;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.process_cached_inserts.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.process_cached_inserts.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.process_cached_inserts.php	(revision 795)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace cached inserts with the actual results
+ *
+ * @param string $results
+ * @return string
+ */
+function smarty_core_process_cached_inserts($params, &$smarty)
+{
+    preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
+                   $params['results'], $match);
+    list($cached_inserts, $insert_args) = $match;
+
+    for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $smarty);
+        }
+
+        $args = unserialize($insert_args[$i]);
+        $name = $args['name'];
+
+        if (isset($args['script'])) {
+            $_params = array('resource_name' => $smarty->_dequote($args['script']));
+            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+            if(!smarty_core_get_php_resource($_params, $smarty)) {
+                return false;
+            }
+            $resource_type = $_params['resource_type'];
+            $php_resource = $_params['php_resource'];
+
+
+            if ($resource_type == 'file') {
+                $smarty->_include($php_resource, true);
+            } else {
+                $smarty->_eval($php_resource);
+            }
+        }
+
+        $function_name = $smarty->_plugins['insert'][$name][0];
+        if (empty($args['assign'])) {
+            $replace = $function_name($args, $smarty);
+        } else {
+            $smarty->assign($args['assign'], $function_name($args, $smarty));
+            $replace = '';
+        }
+
+        $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
+                                                'filename'  => 'insert_'.$name,
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
+        }
+    }
+
+    return $params['results'];
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.write_compiled_resource.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.write_compiled_resource.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.write_compiled_resource.php	(revision 795)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write the compiled resource
+ *
+ * @param string $compile_path
+ * @param string $compiled_content
+ * @return true
+ */
+function smarty_core_write_compiled_resource($params, &$smarty)
+{
+    if(!@is_writable($smarty->compile_dir)) {
+        // compile_dir not writable, see if it exists
+        if(!@is_dir($smarty->compile_dir)) {
+            $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+            return false;
+        }
+        $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
+        return false;
+    }
+
+    $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
+    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+    smarty_core_write_file($_params, $smarty);
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.rmdir.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.rmdir.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.rmdir.php	(revision 795)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete a dir recursively (level=0 -> keep root)
+ * WARNING: no tests, it will try to remove what you tell it!
+ *
+ * @param string $dirname
+ * @param integer $level
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+//  $dirname, $level = 1, $exp_time = null
+
+function smarty_core_rmdir($params, &$smarty)
+{
+   if(!isset($params['level'])) { $params['level'] = 1; }
+   if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
+
+   if($_handle = @opendir($params['dirname'])) {
+
+        while (false !== ($_entry = readdir($_handle))) {
+            if ($_entry != '.' && $_entry != '..') {
+                if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
+                    $_params = array(
+                        'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
+                        'level' => $params['level'] + 1,
+                        'exp_time' => $params['exp_time']
+                    );
+                    smarty_core_rmdir($_params, $smarty);
+                }
+                else {
+                    $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
+                }
+            }
+        }
+        closedir($_handle);
+   }
+
+   if ($params['level']) {
+       return @rmdir($params['dirname']);
+   }
+   return (bool)$_handle;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.load_plugins.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.load_plugins.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.load_plugins.php	(revision 795)
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Load requested plugins
+ *
+ * @param array $plugins
+ */
+
+// $plugins
+
+function smarty_core_load_plugins($params, &$smarty)
+{
+
+    foreach ($params['plugins'] as $_plugin_info) {
+        list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
+        $_plugin = &$smarty->_plugins[$_type][$_name];
+
+        /*
+         * We do not load plugin more than once for each instance of Smarty.
+         * The following code checks for that. The plugin can also be
+         * registered dynamically at runtime, in which case template file
+         * and line number will be unknown, so we fill them in.
+         *
+         * The final element of the info array is a flag that indicates
+         * whether the dynamically registered plugin function has been
+         * checked for existence yet or not.
+         */
+        if (isset($_plugin)) {
+            if (empty($_plugin[3])) {
+                if (!is_callable($_plugin[0])) {
+                    $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                } else {
+                    $_plugin[1] = $_tpl_file;
+                    $_plugin[2] = $_tpl_line;
+                    $_plugin[3] = true;
+                    if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
+                }
+            }
+            continue;
+        } else if ($_type == 'insert') {
+            /*
+             * For backwards compatibility, we check for insert functions in
+             * the symbol table before trying to load them as a plugin.
+             */
+            $_plugin_func = 'insert_' . $_name;
+            if (function_exists($_plugin_func)) {
+                $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
+                continue;
+            }
+        }
+
+        $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
+
+        if (! $_found = ($_plugin_file != false)) {
+            $_message = "could not load plugin file '$_type.$_name.php'\n";
+        }
+
+        /*
+         * If plugin file is found, it -must- provide the properly named
+         * plugin function. In case it doesn't, simply output the error and
+         * do not fall back on any other method.
+         */
+        if ($_found) {
+            include_once $_plugin_file;
+
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                continue;
+            }
+        }
+        /*
+         * In case of insert plugins, their code may be loaded later via
+         * 'script' attribute.
+         */
+        else if ($_type == 'insert' && $_delayed_loading) {
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            $_found = true;
+        }
+
+        /*
+         * Plugin specific processing and error checking.
+         */
+        if (!$_found) {
+            if ($_type == 'modifier') {
+                /*
+                 * In case modifier falls back on using PHP functions
+                 * directly, we only allow those specified in the security
+                 * context.
+                 */
+                if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
+                    $_message = "(secure mode) modifier '$_name' is not allowed";
+                } else {
+                    if (!function_exists($_name)) {
+                        $_message = "modifier '$_name' is not implemented";
+                    } else {
+                        $_plugin_func = $_name;
+                        $_found = true;
+                    }
+                }
+            } else if ($_type == 'function') {
+                /*
+                 * This is a catch-all situation.
+                 */
+                $_message = "unknown tag - '$_name'";
+            }
+        }
+
+        if ($_found) {
+            $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
+        } else {
+            // output error
+            $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.create_dir_structure.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.create_dir_structure.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.create_dir_structure.php	(revision 795)
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * create full directory structure
+ *
+ * @param string $dir
+ */
+
+// $dir
+
+function smarty_core_create_dir_structure($params, &$smarty)
+{
+    if (!file_exists($params['dir'])) {
+        $_open_basedir_ini = ini_get('open_basedir');
+
+        if (DIRECTORY_SEPARATOR=='/') {
+            /* unix-style paths */
+            $_dir = $params['dir'];
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(':', $_open_basedir_ini);
+            }
+
+        } else {
+            /* other-style paths */
+            $_dir = str_replace('\\','/', $params['dir']);
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
+                /* leading "//" for network volume, or "[letter]:/" for full path */
+                $_new_dir = $_root_dir[1];
+                /* remove drive-letter from _dir_parts */
+                if (isset($_root_dir[3])) array_shift($_dir_parts);
+
+            } else {
+                $_new_dir = str_replace('\\', '/', getcwd()).'/';
+
+            }
+
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
+            }
+
+        }
+
+        /* all paths use "/" only from here */
+        foreach ($_dir_parts as $_dir_part) {
+            $_new_dir .= $_dir_part;
+
+            if ($_use_open_basedir) {
+                // do not attempt to test or make directories outside of open_basedir
+                $_make_new_dir = false;
+                foreach ($_open_basedirs as $_open_basedir) {
+                    if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
+                        $_make_new_dir = true;
+                        break;
+                    }
+                }
+            } else {
+                $_make_new_dir = true;
+            }
+
+            if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
+                $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
+                return false;
+            }
+            $_new_dir .= '/';
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.is_secure.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.is_secure.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.is_secure.php	(revision 795)
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is secure or not.
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+//  $resource_type, $resource_name
+
+function smarty_core_is_secure($params, &$smarty)
+{
+    if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
+        return true;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $_rp = realpath($params['resource_name']);
+        if (isset($params['resource_base_path'])) {
+            foreach ((array)$params['resource_base_path'] as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false &&
+                     strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                     substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                    return true;
+                }
+            }
+        }
+        if (!empty($smarty->secure_dir)) {
+            foreach ((array)$smarty->secure_dir as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false) {
+                    if($_cd == $_rp) {
+                        return true;
+                    } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                        substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
+                        return true;
+                    }
+                }
+            }
+        }
+    } else {
+        // resource is not on local file system
+        return call_user_func_array(
+            $smarty->_plugins['resource'][$params['resource_type']][0][2],
+            array($params['resource_name'], &$smarty));
+    }
+
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.run_insert_handler.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.run_insert_handler.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.run_insert_handler.php	(revision 795)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Handle insert tags
+ *
+ * @param array $args
+ * @return string
+ */
+function smarty_core_run_insert_handler($params, &$smarty)
+{
+
+    require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+    if ($smarty->debugging) {
+        $_params = array();
+        $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+    }
+
+    if ($smarty->caching) {
+        $_arg_string = serialize($params['args']);
+        $_name = $params['args']['name'];
+        if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
+            $smarty->_cache_info['insert_tags'][$_name] = array('insert',
+                                                             $_name,
+                                                             $smarty->_plugins['insert'][$_name][1],
+                                                             $smarty->_plugins['insert'][$_name][2],
+                                                             !empty($params['args']['script']) ? true : false);
+        }
+        return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
+    } else {
+        if (isset($params['args']['script'])) {
+            $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
+            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+            if(!smarty_core_get_php_resource($_params, $smarty)) {
+                return false;
+            }
+
+            if ($_params['resource_type'] == 'file') {
+                $smarty->_include($_params['php_resource'], true);
+            } else {
+                $smarty->_eval($_params['php_resource']);
+            }
+            unset($params['args']['script']);
+        }
+
+        $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
+        $_content = $_funcname($params['args'], $smarty);
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
+                                                'filename'  => 'insert_'.$params['args']['name'],
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+        }
+
+        if (!empty($params['args']["assign"])) {
+            $smarty->assign($params['args']["assign"], $_content);
+        } else {
+            return $_content;
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.assemble_plugin_filepath.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.assemble_plugin_filepath.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.assemble_plugin_filepath.php	(revision 795)
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * assemble filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+function smarty_core_assemble_plugin_filepath($params, &$smarty)
+{
+    static $_filepaths_cache = array();
+
+    $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
+    if (isset($_filepaths_cache[$_plugin_filename])) {
+        return $_filepaths_cache[$_plugin_filename];
+    }
+    $_return = false;
+
+    foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
+
+        $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+        // see if path is relative
+        if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
+            $_relative_paths[] = $_plugin_dir;
+            // relative path, see if it is in the SMARTY_DIR
+            if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
+                $_return = SMARTY_DIR . $_plugin_filepath;
+                break;
+            }
+        }
+        // try relative to cwd (or absolute)
+        if (@is_readable($_plugin_filepath)) {
+            $_return = $_plugin_filepath;
+            break;
+        }
+    }
+
+    if($_return === false) {
+        // still not found, try PHP include_path
+        if(isset($_relative_paths)) {
+            foreach ((array)$_relative_paths as $_plugin_dir) {
+
+                $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+                $_params = array('file_path' => $_plugin_filepath);
+                require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                if(smarty_core_get_include_path($_params, $smarty)) {
+                    $_return = $_params['new_file_path'];
+                    break;
+                }
+            }
+        }
+    }
+    $_filepaths_cache[$_plugin_filename] = $_return;
+    return $_return;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.is_trusted.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.is_trusted.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.is_trusted.php	(revision 795)
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is trusted or not
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ // $resource_type, $resource_name
+
+function smarty_core_is_trusted($params, &$smarty)
+{
+    $_smarty_trusted = false;
+    if ($params['resource_type'] == 'file') {
+        if (!empty($smarty->trusted_dir)) {
+            $_rp = realpath($params['resource_name']);
+            foreach ((array)$smarty->trusted_dir as $curr_dir) {
+                if (!empty($curr_dir) && is_readable ($curr_dir)) {
+                    $_cd = realpath($curr_dir);
+                    if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+                        && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                        $_smarty_trusted = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+    } else {
+        // resource is not on local file system
+        $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
+                                                array($params['resource_name'], $smarty));
+    }
+
+    return $_smarty_trusted;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.get_microtime.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.get_microtime.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.get_microtime.php	(revision 795)
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get seconds and microseconds
+ * @return double
+ */
+function smarty_core_get_microtime($params, &$smarty)
+{
+    $mtime = microtime();
+    $mtime = explode(" ", $mtime);
+    $mtime = (double)($mtime[1]) + (double)($mtime[0]);
+    return ($mtime);
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.smarty_include_php.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.smarty_include_php.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.smarty_include_php.php	(revision 795)
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * called for included php files within templates
+ *
+ * @param string $smarty_file
+ * @param string $smarty_assign variable to assign the included template's
+ *               output into
+ * @param boolean $smarty_once uses include_once if this is true
+ * @param array $smarty_include_vars associative array of vars from
+ *              {include file="blah" var=$var}
+ */
+
+//  $file, $assign, $once, $_smarty_include_vars
+
+function smarty_core_smarty_include_php($params, &$smarty)
+{
+    $_params = array('resource_name' => $params['smarty_file']);
+    require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+    smarty_core_get_php_resource($_params, $smarty);
+    $_smarty_resource_type = $_params['resource_type'];
+    $_smarty_php_resource = $_params['php_resource'];
+
+    if (!empty($params['smarty_assign'])) {
+        ob_start();
+        if ($_smarty_resource_type == 'file') {
+            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+        } else {
+            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+        }
+        $smarty->assign($params['smarty_assign'], ob_get_contents());
+        ob_end_clean();
+    } else {
+        if ($_smarty_resource_type == 'file') {
+            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+        } else {
+            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+        }
+    }
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.write_file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.write_file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.write_file.php	(revision 795)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write out a file to disk
+ *
+ * @param string $filename
+ * @param string $contents
+ * @param boolean $create_dirs
+ * @return boolean
+ */
+function smarty_core_write_file($params, &$smarty)
+{
+    $_dirname = dirname($params['filename']);
+
+    if ($params['create_dirs']) {
+        $_params = array('dir' => $_dirname);
+        require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
+        smarty_core_create_dir_structure($_params, $smarty);
+    }
+
+    // write to tmp file, then rename it to avoid file locking race condition
+    $_tmp_file = tempnam($_dirname, 'wrt');
+
+    if (!($fd = @fopen($_tmp_file, 'wb'))) {
+        $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
+        if (!($fd = @fopen($_tmp_file, 'wb'))) {
+            $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
+            return false;
+        }
+    }
+
+    fwrite($fd, $params['contents']);
+    fclose($fd);
+
+    if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
+        // On platforms and filesystems that cannot overwrite with rename() 
+        // delete the file before renaming it -- because windows always suffers
+        // this, it is short-circuited to avoid the initial rename() attempt
+        @unlink($params['filename']);
+        @rename($_tmp_file, $params['filename']);
+    }
+    @chmod($params['filename'], $smarty->_file_perms);
+
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.read_cache_file.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.read_cache_file.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.read_cache_file.php	(revision 795)
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * read a cache file, determine if it needs to be
+ * regenerated or not
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return boolean
+ */
+
+//  $tpl_file, $cache_id, $compile_id, &$results
+
+function smarty_core_read_cache_file(&$params, &$smarty)
+{
+    static  $content_cache = array();
+
+    if ($smarty->force_compile) {
+        // force compile enabled, always regenerate
+        return false;
+    }
+
+    if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
+        list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
+        return true;
+    }
+
+    if (!empty($smarty->cache_handler_func)) {
+        // use cache_handler function
+        call_user_func_array($smarty->cache_handler_func,
+                             array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+    } else {
+        // use local cache file
+        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+        $params['results'] = $smarty->_read_file($_cache_file);
+    }
+
+    if (empty($params['results'])) {
+        // nothing to parse (error?), regenerate cache
+        return false;
+    }
+
+    $_contents = $params['results'];
+    $_info_start = strpos($_contents, "\n") + 1;
+    $_info_len = (int)substr($_contents, 0, $_info_start - 1);
+    $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
+    $params['results'] = substr($_contents, $_info_start + $_info_len);
+
+    if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
+        // caching by expiration time
+        if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
+            // cache expired, regenerate
+            return false;
+        }
+    } else {
+        // caching by lifetime
+        if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
+            // cache expired, regenerate
+            return false;
+        }
+    }
+
+    if ($smarty->compile_check) {
+        $_params = array('get_source' => false, 'quiet'=>true);
+        foreach (array_keys($_cache_info['template']) as $_template_dep) {
+            $_params['resource_name'] = $_template_dep;
+            if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+                // template file has changed, regenerate cache
+                return false;
+            }
+        }
+
+        if (isset($_cache_info['config'])) {
+            $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
+            foreach (array_keys($_cache_info['config']) as $_config_dep) {
+                $_params['resource_name'] = $_config_dep;
+                if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+                    // config file has changed, regenerate cache
+                    return false;
+                }
+            }
+        }
+    }
+
+    $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
+
+    $smarty->_cache_info = $_cache_info;
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.process_compiled_include.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.process_compiled_include.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.process_compiled_include.php	(revision 795)
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace nocache-tags by results of the corresponding non-cacheable
+ * functions and return it
+ *
+ * @param string $compiled_tpl
+ * @param string $cached_source
+ * @return string
+ */
+
+function smarty_core_process_compiled_include($params, &$smarty)
+{
+    $_cache_including = $smarty->_cache_including;
+    $smarty->_cache_including = true;
+
+    $_return = $params['results'];
+
+    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+        $smarty->_include($_include_file_path, true);
+    }
+
+    foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) {
+        $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
+                                         array(&$smarty, '_process_compiled_include_callback'),
+                                         $_return);
+    }
+    $smarty->_cache_including = $_cache_including;
+    return $_return;
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.get_php_resource.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.get_php_resource.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.get_php_resource.php	(revision 795)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Retrieves PHP script resource
+ *
+ * sets $php_resource to the returned resource
+ * @param string $resource
+ * @param string $resource_type
+ * @param  $php_resource
+ * @return boolean
+ */
+
+function smarty_core_get_php_resource(&$params, &$smarty)
+{
+
+    $params['resource_base_path'] = $smarty->trusted_dir;
+    $smarty->_parse_resource_name($params, $smarty);
+
+    /*
+     * Find out if the resource exists.
+     */
+
+    if ($params['resource_type'] == 'file') {
+        $_readable = false;
+        if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
+            $_readable = true;
+        } else {
+            // test for file in include_path
+            $_params = array('file_path' => $params['resource_name']);
+            require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+            if(smarty_core_get_include_path($_params, $smarty)) {
+                $_include_path = $_params['new_file_path'];
+                $_readable = true;
+            }
+        }
+    } else if ($params['resource_type'] != 'file') {
+        $_template_source = null;
+        $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
+            && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
+                                    array($params['resource_name'], &$_template_source, &$smarty));
+    }
+
+    /*
+     * Set the error function, depending on which class calls us.
+     */
+    if (method_exists($smarty, '_syntax_error')) {
+        $_error_funcc = '_syntax_error';
+    } else {
+        $_error_funcc = 'trigger_error';
+    }
+
+    if ($_readable) {
+        if ($smarty->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
+            if (!smarty_core_is_trusted($params, $smarty)) {
+                $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
+                return false;
+            }
+        }
+    } else {
+        $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
+        return false;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $params['php_resource'] = $params['resource_name'];
+    } else {
+        $params['php_resource'] = $_template_source;
+    }
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.display_debug_console.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.display_debug_console.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.display_debug_console.php	(revision 795)
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty debug_console function plugin
+ *
+ * Type:     core<br>
+ * Name:     display_debug_console<br>
+ * Purpose:  display the javascript debug console window
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_display_debug_console($params, &$smarty)
+{
+    // we must force compile the debug template in case the environment
+    // changed between separate applications.
+
+    if(empty($smarty->debug_tpl)) {
+        // set path to debug template from SMARTY_DIR
+        $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
+        if($smarty->security && is_file($smarty->debug_tpl)) {
+            $smarty->secure_dir[] = realpath($smarty->debug_tpl);
+        }
+        $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
+    }
+
+    $_ldelim_orig = $smarty->left_delimiter;
+    $_rdelim_orig = $smarty->right_delimiter;
+
+    $smarty->left_delimiter = '{';
+    $smarty->right_delimiter = '}';
+
+    $_compile_id_orig = $smarty->_compile_id;
+    $smarty->_compile_id = null;
+
+    $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
+    if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
+    {
+        ob_start();
+        $smarty->_include($_compile_path);
+        $_results = ob_get_contents();
+        ob_end_clean();
+    } else {
+        $_results = '';
+    }
+
+    $smarty->_compile_id = $_compile_id_orig;
+
+    $smarty->left_delimiter = $_ldelim_orig;
+    $smarty->right_delimiter = $_rdelim_orig;
+
+    return $_results;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/internals/core.get_include_path.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/internals/core.get_include_path.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/internals/core.get_include_path.php	(revision 795)
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get path to file from include_path
+ *
+ * @param string $file_path
+ * @param string $new_file_path
+ * @return boolean
+ * @staticvar array|null
+ */
+
+//  $file_path, &$new_file_path
+
+function smarty_core_get_include_path(&$params, &$smarty)
+{
+    static $_path_array = null;
+
+    if(!isset($_path_array)) {
+        $_ini_include_path = ini_get('include_path');
+
+        if(strstr($_ini_include_path,';')) {
+            // windows pathnames
+            $_path_array = explode(';',$_ini_include_path);
+        } else {
+            $_path_array = explode(':',$_ini_include_path);
+        }
+    }
+    foreach ($_path_array as $_include_path) {
+        if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
+               $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
+            return true;
+        }
+    }
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_image.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_image.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_image.php	(revision 795)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_image} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_image<br>
+ * Date:     Feb 24, 2003<br>
+ * Purpose:  format HTML tags for the image<br>
+ * Input:<br>
+ *         - file = file (and path) of image (required)
+ *         - height = image height (optional, default actual height)
+ *         - width = image width (optional, default actual width)
+ *         - basedir = base directory for absolute paths, default
+ *                     is environment variable DOCUMENT_ROOT
+ *         - path_prefix = prefix for path output (optional, default empty)
+ *
+ * Examples: {html_image file="/images/masthead.gif"}
+ * Output:   <img src="/images/masthead.gif" width=400 height=23>
+ * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
+ *      (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Duda <duda@big.hu> - wrote first image function
+ *           in repository, helped with lots of functionality
+ * @version  1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    
+    $alt = '';
+    $file = '';
+    $height = '';
+    $width = '';
+    $extra = '';
+    $prefix = '';
+    $suffix = '';
+    $path_prefix = '';
+    $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+    $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'file':
+            case 'height':
+            case 'width':
+            case 'dpi':
+            case 'path_prefix':
+            case 'basedir':
+                $$_key = $_val;
+                break;
+
+            case 'alt':
+                if(!is_array($_val)) {
+                    $$_key = smarty_function_escape_special_chars($_val);
+                } else {
+                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+
+            case 'link':
+            case 'href':
+                $prefix = '<a href="' . $_val . '">';
+                $suffix = '</a>';
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (empty($file)) {
+        $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+        return;
+    }
+
+    if (substr($file,0,1) == '/') {
+        $_image_path = $basedir . $file;
+    } else {
+        $_image_path = $file;
+    }
+    
+    if(!isset($params['width']) || !isset($params['height'])) {
+        if(!$_image_data = @getimagesize($_image_path)) {
+            if(!file_exists($_image_path)) {
+                $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+                return;
+            } else if(!is_readable($_image_path)) {
+                $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+                return;
+            } else {
+                $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+                return;
+            }
+        }
+        if ($smarty->security &&
+            ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
+            (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
+            (!smarty_core_is_secure($_params, $smarty)) ) {
+            $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
+        }        
+        
+        if(!isset($params['width'])) {
+            $width = $_image_data[0];
+        }
+        if(!isset($params['height'])) {
+            $height = $_image_data[1];
+        }
+
+    }
+
+    if(isset($params['dpi'])) {
+        if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
+            $dpi_default = 72;
+        } else {
+            $dpi_default = 96;
+        }
+        $_resize = $dpi_default/$params['dpi'];
+        $width = round($width * $_resize);
+        $height = round($height * $_resize);
+    }
+
+    return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.spacify.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.spacify.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.spacify.php	(revision 795)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty spacify modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     spacify<br>
+ * Purpose:  add spaces between characters in a string
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
+ *          spacify (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ')
+{
+    return implode($spacify_char,
+                   preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_sentences.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_sentences.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_sentences.php	(revision 795)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_sentences
+ * Purpose:  count the number of sentences in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_sentences (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_sentences($string)
+{
+    // find periods with a word before but not after.
+    return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.escape.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.escape.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.escape.php	(revision 795)
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     escape<br>
+ * Purpose:  Escape the string according to escapement type
+ * @link http://smarty.php.net/manual/en/language.modifier.escape.php
+ *          escape (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param html|htmlall|url|quotes|hex|hexentity|javascript
+ * @return string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
+{
+    switch ($esc_type) {
+        case 'html':
+            return htmlspecialchars($string, ENT_QUOTES, $char_set);
+
+        case 'htmlall':
+            return htmlentities($string, ENT_QUOTES, $char_set);
+
+        case 'url':
+            return rawurlencode($string);
+
+        case 'urlpathinfo':
+            return str_replace('%2F','/',rawurlencode($string));
+            
+        case 'quotes':
+            // escape unescaped single quotes
+            return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+        case 'hex':
+            // escape every character into hex
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '%' . bin2hex($string[$x]);
+            }
+            return $return;
+            
+        case 'hexentity':
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '&#x' . bin2hex($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'decentity':
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '&#' . ord($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'javascript':
+            // escape quotes and backslashes, newlines, etc.
+            return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
+            
+        case 'mail':
+            // safe way to display e-mail address on a web page
+            return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
+            
+        case 'nonstd':
+           // escape non-standard chars, such as ms document quotes
+           $_res = '';
+           for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
+               $_ord = ord(substr($string, $_i, 1));
+               // non-standard char, escape it
+               if($_ord >= 126){
+                   $_res .= '&#' . $_ord . ';';
+               }
+               else {
+                   $_res .= substr($string, $_i, 1);
+               }
+           }
+           return $_res;
+
+        default:
+            return $string;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_paragraphs.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_paragraphs.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_paragraphs.php	(revision 795)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_paragraphs<br>
+ * Purpose:  count the number of paragraphs in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_paragraphs (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_paragraphs($string)
+{
+    // count \r or \n characters
+    return count(preg_split('/[\r\n]+/', $string));
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/compiler.assign.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/compiler.assign.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/compiler.assign.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign} compiler function plugin
+ *
+ * Type:     compiler function<br>
+ * Name:     assign<br>
+ * Purpose:  assign a value to a template variable
+ * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> (initial author)
+ * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
+ * @param string containing var-attribute and value-attribute
+ * @param Smarty_Compiler
+ */
+function smarty_compiler_assign($tag_attrs, &$compiler)
+{
+    $_params = $compiler->_parse_attrs($tag_attrs);
+
+    if (!isset($_params['var'])) {
+        $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
+        return;
+    }
+
+    if (!isset($_params['value'])) {
+        $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
+        return;
+    }
+
+    return "\$this->assign({$_params['var']}, {$_params['value']});";
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.strip.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.strip.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.strip.php	(revision 795)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip<br>
+ * Purpose:  Replace all repeated spaces, newlines, tabs
+ *           with a single space or supplied replacement string.<br>
+ * Example:  {$var|strip} {$var|strip:"&nbsp;"}
+ * Date:     September 25th, 2002
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.php
+ *          strip (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version  1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_strip($text, $replace = ' ')
+{
+    return preg_replace('!\s+!', $replace, $text);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_words.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_words.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_words.php	(revision 795)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_words<br>
+ * Purpose:  count the number of words in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
+ *          count_words (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_words($string)
+{
+    // split text by ' ',\r,\n,\f,\t
+    $split_array = preg_split('/\s+/',$string);
+    // count matches that contain alphanumerics
+    $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
+
+    return count($word_count);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.cat.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.cat.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.cat.php	(revision 795)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     cat<br>
+ * Date:     Feb 24, 2003
+ * Purpose:  catenate a value to a variable
+ * Input:    string to catenate
+ * Example:  {$var|cat:"foo"}
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_cat($string, $cat)
+{
+    return $string . $cat;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.debug_print_var.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.debug_print_var.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.debug_print_var.php	(revision 795)
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty debug_print_var modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     debug_print_var<br>
+ * Purpose:  formats variable contents for display in the console
+ * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
+ *          debug_print_var (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array|object
+ * @param integer
+ * @param integer
+ * @return string
+ */
+function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
+{
+    $_replace = array(
+        "\n" => '<i>\n</i>',
+        "\r" => '<i>\r</i>',
+        "\t" => '<i>\t</i>'
+    );
+
+    switch (gettype($var)) {
+        case 'array' :
+            $results = '<b>Array (' . count($var) . ')</b>';
+            foreach ($var as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                    . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
+                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                    $depth--;
+            }
+            break;
+        case 'object' :
+            $object_vars = get_object_vars($var);
+            $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
+            foreach ($object_vars as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                    . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
+                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                    $depth--;
+            }
+            break;
+        case 'boolean' :
+        case 'NULL' :
+        case 'resource' :
+            if (true === $var) {
+                $results = 'true';
+            } elseif (false === $var) {
+                $results = 'false';
+            } elseif (null === $var) {
+                $results = 'null';
+            } else {
+                $results = htmlspecialchars((string) $var);
+            }
+            $results = '<i>' . $results . '</i>';
+            break;
+        case 'integer' :
+        case 'float' :
+            $results = htmlspecialchars((string) $var);
+            break;
+        case 'string' :
+            $results = strtr($var, $_replace);
+            if (strlen($var) > $length ) {
+                $results = substr($var, 0, $length - 3) . '...';
+            }
+            $results = htmlspecialchars('"' . $results . '"');
+            break;
+        case 'unknown type' :
+        default :
+            $results = strtr((string) $var, $_replace);
+            if (strlen($results) > $length ) {
+                $results = substr($results, 0, $length - 3) . '...';
+            }
+            $results = htmlspecialchars($results);
+    }
+
+    return $results;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.replace.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.replace.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.replace.php	(revision 795)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     replace<br>
+ * Purpose:  simple search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php
+ *          replace (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_replace($string, $search, $replace)
+{
+    return str_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.eval.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.eval.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.eval.php	(revision 795)
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {eval} function plugin
+ *
+ * Type:     function<br>
+ * Name:     eval<br>
+ * Purpose:  evaluate a template variable as a template<br>
+ * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ */
+function smarty_function_eval($params, &$smarty)
+{
+
+    if (!isset($params['var'])) {
+        $smarty->trigger_error("eval: missing 'var' parameter");
+        return;
+    }
+
+    if($params['var'] == '') {
+        return;
+    }
+
+    $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
+
+    ob_start();
+    $smarty->_eval('?>' . $_var_compiled);
+    $_contents = ob_get_contents();
+    ob_end_clean();
+
+    if (!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_contents);
+    } else {
+        return $_contents;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.string_format.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.string_format.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.string_format.php	(revision 795)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     string_format<br>
+ * Purpose:  format strings via sprintf
+ * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
+ *          string_format (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_string_format($string, $format)
+{
+    return sprintf($format, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.nl2br.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.nl2br.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.nl2br.php	(revision 795)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty plugin
+ *
+ * Type:     modifier<br>
+ * Name:     nl2br<br>
+ * Date:     Feb 26, 2003
+ * Purpose:  convert \r\n, \r or \n to <<br>>
+ * Input:<br>
+ *         - contents = contents to replace
+ *         - preceed_test = if true, includes preceeding break tags
+ *           in replacement
+ * Example:  {$text|nl2br}
+ * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
+ *          nl2br (Smarty online manual)
+ * @version  1.0
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_nl2br($string)
+{
+    return nl2br($string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.strip_tags.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.strip_tags.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.strip_tags.php	(revision 795)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip_tags<br>
+ * Purpose:  strip html tags from text
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
+ *          strip_tags (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_strip_tags($string, $replace_with_space = true)
+{
+    if ($replace_with_space)
+        return preg_replace('!<[^>]*?>!', ' ', $string);
+    else
+        return strip_tags($string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.default.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.default.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.default.php	(revision 795)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     default<br>
+ * Purpose:  designate default value for empty variables
+ * @link http://smarty.php.net/manual/en/language.modifier.default.php
+ *          default (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_default($string, $default = '')
+{
+    if (!isset($string) || $string === '')
+        return $default;
+    else
+        return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.capitalize.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.capitalize.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.capitalize.php	(revision 795)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty capitalize modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     capitalize<br>
+ * Purpose:  capitalize words in the string
+ * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
+ *      capitalize (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_capitalize($string, $uc_digits = false)
+{
+    smarty_modifier_capitalize_ucfirst(null, $uc_digits);
+    return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
+}
+
+function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
+{
+    static $_uc_digits = false;
+    
+    if(isset($uc_digits)) {
+        $_uc_digits = $uc_digits;
+        return;
+    }
+    
+    if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
+        return ucfirst($string[0]);
+    else
+        return $string[0];
+}
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.date_format.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.date_format.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.date_format.php	(revision 795)
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Include the {@link shared.make_timestamp.php} plugin
+ */
+require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
+/**
+ * Smarty date_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     date_format<br>
+ * Purpose:  format datestamps via strftime<br>
+ * Input:<br>
+ *         - string: input date string
+ *         - format: strftime format for output
+ *         - default_date: default date if $string is empty
+ * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
+ *          date_format (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string|void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
+{
+    if ($string != '') {
+        $timestamp = smarty_make_timestamp($string);
+    } elseif ($default_date != '') {
+        $timestamp = smarty_make_timestamp($default_date);
+    } else {
+        return;
+    }
+    if (DIRECTORY_SEPARATOR == '\\') {
+        $_win_from = array('%D',       '%h', '%n', '%r',          '%R',    '%t', '%T');
+        $_win_to   = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
+        if (strpos($format, '%e') !== false) {
+            $_win_from[] = '%e';
+            $_win_to[]   = sprintf('%\' 2d', date('j', $timestamp));
+        }
+        if (strpos($format, '%l') !== false) {
+            $_win_from[] = '%l';
+            $_win_to[]   = sprintf('%\' 2d', date('h', $timestamp));
+        }
+        $format = str_replace($_win_from, $_win_to, $format);
+    }
+    return strftime($format, $timestamp);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.cycle.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.cycle.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.cycle.php	(revision 795)
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ *
+ * Type:     function<br>
+ * Name:     cycle<br>
+ * Date:     May 3, 2002<br>
+ * Purpose:  cycle through given values<br>
+ * Input:
+ *         - name = name of cycle (optional)
+ *         - values = comma separated list of values to cycle,
+ *                    or an array of values to cycle
+ *                    (this can be left out for subsequent calls)
+ *         - reset = boolean - resets given var to true
+ *         - print = boolean - print var or not. default is true
+ *         - advance = boolean - whether or not to advance the cycle
+ *         - delimiter = the value delimiter, default is ","
+ *         - assign = boolean, assigns to template var instead of
+ *                    printed.
+ *
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version  1.3
+ * @param array
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_cycle($params, &$smarty)
+{
+    static $cycle_vars;
+    
+    $name = (empty($params['name'])) ? 'default' : $params['name'];
+    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+            
+    if (!in_array('values', array_keys($params))) {
+        if(!isset($cycle_vars[$name]['values'])) {
+            $smarty->trigger_error("cycle: missing 'values' parameter");
+            return;
+        }
+    } else {
+        if(isset($cycle_vars[$name]['values'])
+            && $cycle_vars[$name]['values'] != $params['values'] ) {
+            $cycle_vars[$name]['index'] = 0;
+        }
+        $cycle_vars[$name]['values'] = $params['values'];
+    }
+
+    $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
+    
+    if(is_array($cycle_vars[$name]['values'])) {
+        $cycle_array = $cycle_vars[$name]['values'];
+    } else {
+        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
+    }
+    
+    if(!isset($cycle_vars[$name]['index']) || $reset ) {
+        $cycle_vars[$name]['index'] = 0;
+    }
+    
+    if (isset($params['assign'])) {
+        $print = false;
+        $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+    }
+        
+    if($print) {
+        $retval = $cycle_array[$cycle_vars[$name]['index']];
+    } else {
+        $retval = null;
+    }
+
+    if($advance) {
+        if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
+            $cycle_vars[$name]['index'] = 0;
+        } else {
+            $cycle_vars[$name]['index']++;
+        }
+    }
+    
+    return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_characters.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_characters.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.count_characters.php	(revision 795)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_characteres<br>
+ * Purpose:  count the number of characters in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
+ *          count_characters (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean include whitespace in the character count
+ * @return integer
+ */
+function smarty_modifier_count_characters($string, $include_spaces = false)
+{
+    if ($include_spaces)
+       return(strlen($string));
+
+    return preg_match_all("/[^\s]/",$string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.lower.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.lower.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.lower.php	(revision 795)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     lower<br>
+ * Purpose:  convert string to lowercase
+ * @link http://smarty.php.net/manual/en/language.modifier.lower.php
+ *          lower (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_lower($string)
+{
+    return strtolower($string);
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/block.textformat.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/block.textformat.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/block.textformat.php	(revision 795)
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ *
+ * Type:     block function<br>
+ * Name:     textformat<br>
+ * Purpose:  format text a certain way with preset styles
+ *           or custom wrap/indent settings<br>
+ * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
+ *       (Smarty online manual)
+ * @param array
+ * <pre>
+ * Params:   style: string (email)
+ *           indent: integer (0)
+ *           wrap: integer (80)
+ *           wrap_char string ("\n")
+ *           indent_char: string (" ")
+ *           wrap_boundary: boolean (true)
+ * </pre>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string contents of the block
+ * @param Smarty clever simulation of a method
+ * @return string string $content re-formatted
+ */
+function smarty_block_textformat($params, $content, &$smarty)
+{
+    if (is_null($content)) {
+        return;
+    }
+
+    $style = null;
+    $indent = 0;
+    $indent_first = 0;
+    $indent_char = ' ';
+    $wrap = 80;
+    $wrap_char = "\n";
+    $wrap_cut = false;
+    $assign = null;
+    
+    foreach ($params as $_key => $_val) {
+        switch ($_key) {
+            case 'style':
+            case 'indent_char':
+            case 'wrap_char':
+            case 'assign':
+                $$_key = (string)$_val;
+                break;
+
+            case 'indent':
+            case 'indent_first':
+            case 'wrap':
+                $$_key = (int)$_val;
+                break;
+
+            case 'wrap_cut':
+                $$_key = (bool)$_val;
+                break;
+
+            default:
+                $smarty->trigger_error("textformat: unknown attribute '$_key'");
+        }
+    }
+
+    if ($style == 'email') {
+        $wrap = 72;
+    }
+
+    // split into paragraphs
+    $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
+    $_output = '';
+
+    for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
+        if ($_paragraphs[$_x] == '') {
+            continue;
+        }
+        // convert mult. spaces & special chars to single space
+        $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
+        // indent first line
+        if($indent_first > 0) {
+            $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
+        }
+        // wordwrap sentences
+        $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
+        // indent lines
+        if($indent > 0) {
+            $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
+        }
+    }
+    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
+
+    return $assign ? $smarty->assign($assign, $_output) : $_output;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.popup.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.popup.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.popup.php	(revision 795)
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup} function plugin
+ *
+ * Type:     function<br>
+ * Name:     popup<br>
+ * Purpose:  make text pop up in windows via overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup($params, &$smarty)
+{
+    $append = '';
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'text':
+            case 'trigger':
+            case 'function':
+            case 'inarray':
+                $$_key = (string)$_value;
+                if ($_key == 'function' || $_key == 'inarray')
+                    $append .= ',' . strtoupper($_key) . ",'$_value'";
+                break;
+
+            case 'caption':
+            case 'closetext':
+            case 'status':
+                $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
+                break;
+
+            case 'fgcolor':
+            case 'bgcolor':
+            case 'textcolor':
+            case 'capcolor':
+            case 'closecolor':
+            case 'textfont':
+            case 'captionfont':
+            case 'closefont':
+            case 'fgbackground':
+            case 'bgbackground':
+            case 'caparray':
+            case 'capicon':
+            case 'background':
+            case 'frame':
+                $append .= ',' . strtoupper($_key) . ",'$_value'";
+                break;
+
+            case 'textsize':
+            case 'captionsize':
+            case 'closesize':
+            case 'width':
+            case 'height':
+            case 'border':
+            case 'offsetx':
+            case 'offsety':
+            case 'snapx':
+            case 'snapy':
+            case 'fixx':
+            case 'fixy':
+            case 'padx':
+            case 'pady':
+            case 'timeout':
+            case 'delay':
+                $append .= ',' . strtoupper($_key) . ",$_value";
+                break;
+
+            case 'sticky':
+            case 'left':
+            case 'right':
+            case 'center':
+            case 'above':
+            case 'below':
+            case 'noclose':
+            case 'autostatus':
+            case 'autostatuscap':
+            case 'fullhtml':
+            case 'hauto':
+            case 'vauto':
+            case 'mouseoff':
+            case 'followmouse':
+            case 'closeclick':
+                if ($_value) $append .= ',' . strtoupper($_key);
+                break;
+
+            default:
+                $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
+        }
+    }
+
+    if (empty($text) && !isset($inarray) && empty($function)) {
+        $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
+        return false;
+    }
+
+    if (empty($trigger)) { $trigger = "onmouseover"; }
+
+    $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
+    $retval .= $append . ');"';
+    if ($trigger == 'onmouseover')
+       $retval .= ' onmouseout="nd();"';
+
+
+    return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_radios.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_radios.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_radios.php	(revision 795)
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_radios} function plugin
+ *
+ * File:       function.html_radios.php<br>
+ * Type:       function<br>
+ * Name:       html_radios<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of radio input types<br>
+ * Input:<br>
+ *           - name       (optional) - string default "radio"
+ *           - values     (required) - array
+ *           - options    (optional) - associative array
+ *           - checked    (optional) - array default not set
+ *           - separator  (optional) - ie <br> or &nbsp;
+ *           - output     (optional) - the output next to each radio button
+ *           - assign     (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+   
+    $name = 'radio';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $label_ids = false;
+    $output = null;
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = (string)$_val;
+                break;
+
+            case 'checked':
+            case 'selected':
+                if(is_array($_val)) {
+                    $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+                } else {
+                    $selected = (string)$_val;
+                }
+                break;
+
+            case 'labels':
+            case 'label_ids':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'radios':
+                $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+
+    } else {
+
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
+
+}
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
+    $_output = '';
+    if ($labels) {
+      if($label_ids) {
+          $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
+          $_output .= '<label for="' . $_id . '">';
+      } else {
+          $_output .= '<label>';           
+      }
+   }
+   $_output .= '<input type="radio" name="'
+        . smarty_function_escape_special_chars($name) . '" value="'
+        . smarty_function_escape_special_chars($value) . '"';
+
+   if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
+
+    if ((string)$value==$selected) {
+        $_output .= ' checked="checked"';
+    }
+    $_output .= $extra . ' />' . $output;
+    if ($labels) $_output .= '</label>';
+    $_output .=  $separator;
+
+    return $_output;
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.assign_debug_info.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.assign_debug_info.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.assign_debug_info.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign_debug_info} function plugin
+ *
+ * Type:     function<br>
+ * Name:     assign_debug_info<br>
+ * Purpose:  assign debug info to the template<br>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
+ *              {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
+ * @param Smarty
+ */
+function smarty_function_assign_debug_info($params, &$smarty)
+{
+    $assigned_vars = $smarty->_tpl_vars;
+    ksort($assigned_vars);
+    if (@is_array($smarty->_config[0])) {
+        $config_vars = $smarty->_config[0];
+        ksort($config_vars);
+        $smarty->assign("_debug_config_keys", array_keys($config_vars));
+        $smarty->assign("_debug_config_vals", array_values($config_vars));
+    }
+    
+    $included_templates = $smarty->_smarty_debug_info;
+    
+    $smarty->assign("_debug_keys", array_keys($assigned_vars));
+    $smarty->assign("_debug_vals", array_values($assigned_vars));
+    
+    $smarty->assign("_debug_tpls", $included_templates);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/outputfilter.trimwhitespace.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/outputfilter.trimwhitespace.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/outputfilter.trimwhitespace.php	(revision 795)
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ *
+ * File:     outputfilter.trimwhitespace.php<br>
+ * Type:     outputfilter<br>
+ * Name:     trimwhitespace<br>
+ * Date:     Jan 25, 2003<br>
+ * Purpose:  trim leading white space and blank lines from
+ *           template source after it gets interpreted, cleaning
+ *           up code and saving bandwidth. Does not affect
+ *           <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
+ * Install:  Drop into the plugin directory, call
+ *           <code>$smarty->load_filter('output','trimwhitespace');</code>
+ *           from application.
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
+ * @version  1.3
+ * @param string
+ * @param Smarty
+ */
+function smarty_outputfilter_trimwhitespace($source, &$smarty)
+{
+    // Pull out the script blocks
+    preg_match_all("!<script[^>]+>.*?</script>!is", $source, $match);
+    $_script_blocks = $match[0];
+    $source = preg_replace("!<script[^>]+>.*?</script>!is",
+                           '@@@SMARTY:TRIM:SCRIPT@@@', $source);
+
+    // Pull out the pre blocks
+    preg_match_all("!<pre>.*?</pre>!is", $source, $match);
+    $_pre_blocks = $match[0];
+    $source = preg_replace("!<pre>.*?</pre>!is",
+                           '@@@SMARTY:TRIM:PRE@@@', $source);
+
+    // Pull out the textarea blocks
+    preg_match_all("!<textarea[^>]+>.*?</textarea>!is", $source, $match);
+    $_textarea_blocks = $match[0];
+    $source = preg_replace("!<textarea[^>]+>.*?</textarea>!is",
+                           '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
+
+    // remove all leading spaces, tabs and carriage returns NOT
+    // preceeded by a php close tag.
+    $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
+
+    // replace textarea blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
+
+    // replace pre blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
+
+    // replace script blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
+
+    return $source;
+}
+
+function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
+    $_len = strlen($search_str);
+    $_pos = 0;
+    for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
+        if (($_pos=strpos($subject, $search_str, $_pos))!==false)
+            $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
+        else
+            break;
+
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_table.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_table.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_table.php	(revision 795)
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_table} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_table<br>
+ * Date:     Feb 17, 2003<br>
+ * Purpose:  make an html table from an array of data<br>
+ * Input:<br>
+ *         - loop = array to loop through
+ *         - cols = number of columns, comma separated list of column names
+ *                  or array of column names
+ *         - rows = number of rows
+ *         - table_attr = table attributes
+ *         - th_attr = table heading attributes (arrays are cycled)
+ *         - tr_attr = table row attributes (arrays are cycled)
+ *         - td_attr = table cell attributes (arrays are cycled)
+ *         - trailpad = value to pad trailing cells with
+ *         - caption = text for caption element 
+ *         - vdir = vertical direction (default: "down", means top-to-bottom)
+ *         - hdir = horizontal direction (default: "right", means left-to-right)
+ *         - inner = inner loop (default "cols": print $loop line by line,
+ *                   $loop will be printed column by column otherwise)
+ *
+ *
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols="first,second,third" tr_attr=$colors}
+ * </pre>
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
+ * @author credit to boots <boots dot smarty at yahoo dot com>
+ * @version  1.1
+ * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
+ *          (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_table($params, &$smarty)
+{
+    $table_attr = 'border="1"';
+    $tr_attr = '';
+    $th_attr = '';
+    $td_attr = '';
+    $cols = $cols_count = 3;
+    $rows = 3;
+    $trailpad = '&nbsp;';
+    $vdir = 'down';
+    $hdir = 'right';
+    $inner = 'cols';
+    $caption = '';
+
+    if (!isset($params['loop'])) {
+        $smarty->trigger_error("html_table: missing 'loop' parameter");
+        return;
+    }
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'loop':
+                $$_key = (array)$_value;
+                break;
+
+            case 'cols':
+                if (is_array($_value) && !empty($_value)) {
+                    $cols = $_value;
+                    $cols_count = count($_value);
+                } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
+                    $cols = explode(',', $_value);
+                    $cols_count = count($cols);
+                } elseif (!empty($_value)) {
+                    $cols_count = (int)$_value;
+                } else {
+                    $cols_count = $cols;
+                }
+                break;
+
+            case 'rows':
+                $$_key = (int)$_value;
+                break;
+
+            case 'table_attr':
+            case 'trailpad':
+            case 'hdir':
+            case 'vdir':
+            case 'inner':
+            case 'caption':
+                $$_key = (string)$_value;
+                break;
+
+            case 'tr_attr':
+            case 'td_attr':
+            case 'th_attr':
+                $$_key = $_value;
+                break;
+        }
+    }
+
+    $loop_count = count($loop);
+    if (empty($params['rows'])) {
+        /* no rows specified */
+        $rows = ceil($loop_count/$cols_count);
+    } elseif (empty($params['cols'])) {
+        if (!empty($params['rows'])) {
+            /* no cols specified, but rows */
+            $cols_count = ceil($loop_count/$rows);
+        }
+    }
+
+    $output = "<table $table_attr>\n";
+
+    if (!empty($caption)) {
+        $output .= '<caption>' . $caption . "</caption>\n";
+    }
+
+    if (is_array($cols)) {
+        $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
+        $output .= "<thead><tr>\n";
+
+        for ($r=0; $r<$cols_count; $r++) {
+            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
+            $output .= $cols[$r];
+            $output .= "</th>\n";
+        }
+        $output .= "</tr></thead>\n";
+    }
+
+    $output .= "<tbody>\n";
+    for ($r=0; $r<$rows; $r++) {
+        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+        $rx =  ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
+
+        for ($c=0; $c<$cols_count; $c++) {
+            $x =  ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
+            if ($inner!='cols') {
+                /* shuffle x to loop over rows*/
+                $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
+            }
+
+            if ($x<$loop_count) {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+            } else {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+            }
+        }
+        $output .= "</tr>\n";
+    }
+    $output .= "</tbody>\n";
+    $output .= "</table>\n";
+    
+    return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no) {
+    if(!is_array($var)) {
+        $ret = $var;
+    } else {
+        $ret = $var[$no % count($var)];
+    }
+    
+    return ($ret) ? ' '.$ret : '';
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.wordwrap.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.wordwrap.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.wordwrap.php	(revision 795)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty wordwrap modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     wordwrap<br>
+ * Purpose:  wrap a string of text at a given length
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
+ *          wordwrap (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
+{
+    return wordwrap($string,$length,$break,$cut);
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.regex_replace.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.regex_replace.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.regex_replace.php	(revision 795)
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty regex_replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     regex_replace<br>
+ * Purpose:  regular expression search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ *          regex_replace (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string|array
+ * @param string|array
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace)
+{
+    if (($pos = strpos($search,"\0")) !== false)
+      $search = substr($search,0,$pos);
+    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
+        /* remove eval-modifier from $search */
+        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
+    }
+       
+    return preg_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_options.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_options.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_options.php	(revision 795)
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_options} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_options<br>
+ * Input:<br>
+ *           - name       (optional) - string default "select"
+ *           - values     (required if no options supplied) - array
+ *           - options    (required if no values supplied) - associative array
+ *           - selected   (optional) - string default not set
+ *           - output     (required if not options supplied) - array
+ * Purpose:  Prints the list of <option> tags generated from
+ *           the passed parameters
+ * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
+ *      (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    
+    $name = null;
+    $values = null;
+    $options = null;
+    $selected = array();
+    $output = null;
+    
+    $extra = '';
+    
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+                $$_key = (string)$_val;
+                break;
+            
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+                
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'selected':
+                $$_key = array_map('strval', array_values((array)$_val));
+                break;
+                
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = '';
+
+    if (isset($options)) {
+        
+        foreach ($options as $_key=>$_val)
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+
+    } else {
+        
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+        }
+
+    }
+
+    if(!empty($name)) {
+        $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+    }
+
+    return $_html_result;
+
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected) {
+    if(!is_array($value)) {
+        $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
+            smarty_function_escape_special_chars($key) . '"';
+        if (in_array((string)$key, $selected))
+            $_html_result .= ' selected="selected"';
+        $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
+    } else {
+        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
+    }
+    return $_html_result;
+}
+
+function smarty_function_html_options_optgroup($key, $values, $selected) {
+    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+    foreach ($values as $key => $value) {
+        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
+    }
+    $optgroup_html .= "</optgroup>\n";
+    return $optgroup_html;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.counter.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.counter.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.counter.php	(revision 795)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {counter} function plugin
+ *
+ * Type:     function<br>
+ * Name:     counter<br>
+ * Purpose:  print out a counter value
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
+ *       (Smarty online manual)
+ * @param array parameters
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_counter($params, &$smarty)
+{
+    static $counters = array();
+
+    $name = (isset($params['name'])) ? $params['name'] : 'default';
+    if (!isset($counters[$name])) {
+        $counters[$name] = array(
+            'start'=>1,
+            'skip'=>1,
+            'direction'=>'up',
+            'count'=>1
+            );
+    }
+    $counter =& $counters[$name];
+
+    if (isset($params['start'])) {
+        $counter['start'] = $counter['count'] = (int)$params['start'];
+    }
+
+    if (!empty($params['assign'])) {
+        $counter['assign'] = $params['assign'];
+    }
+
+    if (isset($counter['assign'])) {
+        $smarty->assign($counter['assign'], $counter['count']);
+    }
+    
+    if (isset($params['print'])) {
+        $print = (bool)$params['print'];
+    } else {
+        $print = empty($counter['assign']);
+    }
+
+    if ($print) {
+        $retval = $counter['count'];
+    } else {
+        $retval = null;
+    }
+
+    if (isset($params['skip'])) {
+        $counter['skip'] = $params['skip'];
+    }
+    
+    if (isset($params['direction'])) {
+        $counter['direction'] = $params['direction'];
+    }
+
+    if ($counter['direction'] == "down")
+        $counter['count'] -= $counter['skip'];
+    else
+        $counter['count'] += $counter['skip'];
+    
+    return $retval;
+    
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_select_time.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_select_time.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_select_time.php	(revision 795)
@@ -0,0 +1,194 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_select_time} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_time<br>
+ * Purpose:  Prints the dropdowns for time selection
+ * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
+ *          (Smarty online manual)
+ * @author Roberto Berto <roberto@berto.net>
+ * @credits Monte Ohrt <monte AT ohrt DOT com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+    /* Default values. */
+    $prefix             = "Time_";
+    $time               = time();
+    $display_hours      = true;
+    $display_minutes    = true;
+    $display_seconds    = true;
+    $display_meridian   = true;
+    $use_24_hours       = true;
+    $minute_interval    = 1;
+    $second_interval    = 1;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Hour]",
+       "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
+       Can be combined with prefix. */
+    $field_array        = null;
+    $all_extra          = null;
+    $hour_extra         = null;
+    $minute_extra       = null;
+    $second_extra       = null;
+    $meridian_extra     = null;
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'prefix':
+            case 'time':
+            case 'field_array':
+            case 'all_extra':
+            case 'hour_extra':
+            case 'minute_extra':
+            case 'second_extra':
+            case 'meridian_extra':
+                $$_key = (string)$_value;
+                break;
+
+            case 'display_hours':
+            case 'display_minutes':
+            case 'display_seconds':
+            case 'display_meridian':
+            case 'use_24_hours':
+                $$_key = (bool)$_value;
+                break;
+
+            case 'minute_interval':
+            case 'second_interval':
+                $$_key = (int)$_value;
+                break;
+
+            default:
+                $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
+        }
+    }
+
+    $time = smarty_make_timestamp($time);
+
+    $html_result = '';
+
+    if ($display_hours) {
+        $hours       = $use_24_hours ? range(0, 23) : range(1, 12);
+        $hour_fmt = $use_24_hours ? '%H' : '%I';
+        for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
+            $hours[$i] = sprintf('%02d', $hours[$i]);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Hour"';
+        }
+        if (null !== $hour_extra){
+            $html_result .= ' ' . $hour_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        $html_result .= smarty_function_html_options(array('output'          => $hours,
+                                                           'values'          => $hours,
+                                                           'selected'      => strftime($hour_fmt, $time),
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_minutes) {
+        $all_minutes = range(0, 59);
+        for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
+            $minutes[] = sprintf('%02d', $all_minutes[$i]);
+        $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Minute"';
+        }
+        if (null !== $minute_extra){
+            $html_result .= ' ' . $minute_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => $minutes,
+                                                           'values'          => $minutes,
+                                                           'selected'      => $selected,
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_seconds) {
+        $all_seconds = range(0, 59);
+        for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
+            $seconds[] = sprintf('%02d', $all_seconds[$i]);
+        $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Second"';
+        }
+        
+        if (null !== $second_extra){
+            $html_result .= ' ' . $second_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => $seconds,
+                                                           'values'          => $seconds,
+                                                           'selected'      => $selected,
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_meridian && !$use_24_hours) {
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Meridian"';
+        }
+        
+        if (null !== $meridian_extra){
+            $html_result .= ' ' . $meridian_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => array('AM', 'PM'),
+                                                           'values'          => array('am', 'pm'),
+                                                           'selected'      => strtolower(strftime('%p', $time)),
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/shared.make_timestamp.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/shared.make_timestamp.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/shared.make_timestamp.php	(revision 795)
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose:  used by other smarty functions to make a timestamp
+ *           from a string.
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_make_timestamp($string)
+{
+    if(empty($string)) {
+        // use "now":
+        $time = time();
+
+    } elseif (preg_match('/^\d{14}$/', $string)) {
+        // it is mysql timestamp format of YYYYMMDDHHMMSS?            
+        $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
+                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
+        
+    } elseif (is_numeric($string)) {
+        // it is a numeric string, we handle it as timestamp
+        $time = (int)$string;
+        
+    } else {
+        // strtotime should handle it
+        $time = strtotime($string);
+        if ($time == -1 || $time === false) {
+            // strtotime() was not able to parse $string, use "now":
+            $time = time();
+        }
+    }
+    return $time;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.mailto.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.mailto.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.mailto.php	(revision 795)
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {mailto} function plugin
+ *
+ * Type:     function<br>
+ * Name:     mailto<br>
+ * Date:     May 21, 2002
+ * Purpose:  automate mailto address link creation, and optionally
+ *           encode them.<br>
+ * Input:<br>
+ *         - address = e-mail address
+ *         - text = (optional) text to display, default is address
+ *         - encode = (optional) can be one of:
+ *                * none : no encoding (default)
+ *                * javascript : encode with javascript
+ *                * javascript_charcode : encode with javascript charcode
+ *                * hex : encode with hexidecimal (no javascript)
+ *         - cc = (optional) address(es) to carbon copy
+ *         - bcc = (optional) address(es) to blind carbon copy
+ *         - subject = (optional) e-mail subject
+ *         - newsgroups = (optional) newsgroup(s) to post to
+ *         - followupto = (optional) address(es) to follow up to
+ *         - extra = (optional) extra tags for the href link
+ *
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
+ *          (Smarty online manual)
+ * @version  1.2
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param    array
+ * @param    Smarty
+ * @return   string
+ */
+function smarty_function_mailto($params, &$smarty)
+{
+    $extra = '';
+
+    if (empty($params['address'])) {
+        $smarty->trigger_error("mailto: missing 'address' parameter");
+        return;
+    } else {
+        $address = $params['address'];
+    }
+
+    $text = $address;
+
+    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+    // so, don't encode it.
+    $search = array('%40', '%2C');
+    $replace  = array('@', ',');
+    $mail_parms = array();
+    foreach ($params as $var=>$value) {
+        switch ($var) {
+            case 'cc':
+            case 'bcc':
+            case 'followupto':
+                if (!empty($value))
+                    $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
+                break;
+                
+            case 'subject':
+            case 'newsgroups':
+                $mail_parms[] = $var.'='.rawurlencode($value);
+                break;
+
+            case 'extra':
+            case 'text':
+                $$var = $value;
+
+            default:
+        }
+    }
+
+    $mail_parm_vals = '';
+    for ($i=0; $i<count($mail_parms); $i++) {
+        $mail_parm_vals .= (0==$i) ? '?' : '&';
+        $mail_parm_vals .= $mail_parms[$i];
+    }
+    $address .= $mail_parm_vals;
+
+    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+    if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
+        $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
+        return;
+    }
+
+    if ($encode == 'javascript' ) {
+        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
+
+        $js_encode = '';
+        for ($x=0; $x < strlen($string); $x++) {
+            $js_encode .= '%' . bin2hex($string[$x]);
+        }
+
+        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
+
+    } elseif ($encode == 'javascript_charcode' ) {
+        $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
+            $ord[] = ord($string[$x]);   
+        }
+
+        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
+        $_ret .= "<!--\n";
+        $_ret .= "{document.write(String.fromCharCode(";
+        $_ret .= implode(',',$ord);
+        $_ret .= "))";
+        $_ret .= "}\n";
+        $_ret .= "//-->\n";
+        $_ret .= "</script>\n";
+        
+        return $_ret;
+        
+        
+    } elseif ($encode == 'hex') {
+
+        preg_match('!^(.*)(\?.*)$!',$address,$match);
+        if(!empty($match[2])) {
+            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
+            return;
+        }
+        $address_encode = '';
+        for ($x=0; $x < strlen($address); $x++) {
+            if(preg_match('!\w!',$address[$x])) {
+                $address_encode .= '%' . bin2hex($address[$x]);
+            } else {
+                $address_encode .= $address[$x];
+            }
+        }
+        $text_encode = '';
+        for ($x=0; $x < strlen($text); $x++) {
+            $text_encode .= '&#x' . bin2hex($text[$x]).';';
+        }
+
+        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
+        return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
+
+    } else {
+        // no encoding
+        return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+    }
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.popup_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.popup_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.popup_init.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup_init} function plugin
+ *
+ * Type:     function<br>
+ * Name:     popup_init<br>
+ * Purpose:  initialize overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup_init($params, &$smarty)
+{
+    $zindex = 1000;
+    
+    if (!empty($params['zindex'])) {
+        $zindex = $params['zindex'];
+    }
+    
+    if (!empty($params['src'])) {
+        return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
+         . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
+    } else {
+        $smarty->trigger_error("popup_init: missing src parameter");
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.debug.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.debug.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.debug.php	(revision 795)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {debug} function plugin
+ *
+ * Type:     function<br>
+ * Name:     debug<br>
+ * Date:     July 1, 2002<br>
+ * Purpose:  popup debug window
+ * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
+ *       (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version  1.0
+ * @param array
+ * @param Smarty
+ * @return string output from {@link Smarty::_generate_debug_output()}
+ */
+function smarty_function_debug($params, &$smarty)
+{
+    if (isset($params['output'])) {
+        $smarty->assign('_smarty_debug_output', $params['output']);
+    }
+    require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+    return smarty_core_display_debug_console(null, $smarty);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.math.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.math.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.math.php	(revision 795)
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {math} function plugin
+ *
+ * Type:     function<br>
+ * Name:     math<br>
+ * Purpose:  handle math computations in template<br>
+ * @link http://smarty.php.net/manual/en/language.function.math.php {math}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_math($params, &$smarty)
+{
+    // be sure equation parameter is present
+    if (empty($params['equation'])) {
+        $smarty->trigger_error("math: missing equation parameter");
+        return;
+    }
+
+    $equation = $params['equation'];
+
+    // make sure parenthesis are balanced
+    if (substr_count($equation,"(") != substr_count($equation,")")) {
+        $smarty->trigger_error("math: unbalanced parenthesis");
+        return;
+    }
+
+    // match all vars in equation, make sure all are passed
+    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
+    $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
+                           'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
+    
+    foreach($match[1] as $curr_var) {
+        if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
+            $smarty->trigger_error("math: function call $curr_var not allowed");
+            return;
+        }
+    }
+
+    foreach($params as $key => $val) {
+        if ($key != "equation" && $key != "format" && $key != "assign") {
+            // make sure value is not empty
+            if (strlen($val)==0) {
+                $smarty->trigger_error("math: parameter $key is empty");
+                return;
+            }
+            if (!is_numeric($val)) {
+                $smarty->trigger_error("math: parameter $key: is not numeric");
+                return;
+            }
+            $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
+        }
+    }
+
+    eval("\$smarty_math_result = ".$equation.";");
+
+    if (empty($params['format'])) {
+        if (empty($params['assign'])) {
+            return $smarty_math_result;
+        } else {
+            $smarty->assign($params['assign'],$smarty_math_result);
+        }
+    } else {
+        if (empty($params['assign'])){
+            printf($params['format'],$smarty_math_result);
+        } else {
+            $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.fetch.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.fetch.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.fetch.php	(revision 795)
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {fetch} plugin
+ *
+ * Type:     function<br>
+ * Name:     fetch<br>
+ * Purpose:  fetch file, web or ftp data and display results
+ * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string|null if the assign parameter is passed, Smarty assigns the
+ *                     result to a template variable
+ */
+function smarty_function_fetch($params, &$smarty)
+{
+    if (empty($params['file'])) {
+        $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
+        return;
+    }
+
+    $content = '';
+    if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
+        $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
+        require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+        if(!smarty_core_is_secure($_params, $smarty)) {
+            $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
+            return;
+        }
+        
+        // fetch the file
+        if($fp = @fopen($params['file'],'r')) {
+            while(!feof($fp)) {
+                $content .= fgets ($fp,4096);
+            }
+            fclose($fp);
+        } else {
+            $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
+            return;
+        }
+    } else {
+        // not a local file
+        if(preg_match('!^http://!i',$params['file'])) {
+            // http fetch
+            if($uri_parts = parse_url($params['file'])) {
+                // set defaults
+                $host = $server_name = $uri_parts['host'];
+                $timeout = 30;
+                $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+                $agent = "Smarty Template Engine ".$smarty->_version;
+                $referer = "";
+                $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+                $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+                $_is_proxy = false;
+                if(empty($uri_parts['port'])) {
+                    $port = 80;
+                } else {
+                    $port = $uri_parts['port'];
+                }
+                if(!empty($uri_parts['user'])) {
+                    $user = $uri_parts['user'];
+                }
+                if(!empty($uri_parts['pass'])) {
+                    $pass = $uri_parts['pass'];
+                }
+                // loop through parameters, setup headers
+                foreach($params as $param_key => $param_value) {
+                    switch($param_key) {
+                        case "file":
+                        case "assign":
+                        case "assign_headers":
+                            break;
+                        case "user":
+                            if(!empty($param_value)) {
+                                $user = $param_value;
+                            }
+                            break;
+                        case "pass":
+                            if(!empty($param_value)) {
+                                $pass = $param_value;
+                            }
+                            break;
+                        case "accept":
+                            if(!empty($param_value)) {
+                                $accept = $param_value;
+                            }
+                            break;
+                        case "header":
+                            if(!empty($param_value)) {
+                                if(!preg_match('![\w\d-]+: .+!',$param_value)) {
+                                    $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
+                                    return;
+                                } else {
+                                    $extra_headers[] = $param_value;
+                                }
+                            }
+                            break;
+                        case "proxy_host":
+                            if(!empty($param_value)) {
+                                $proxy_host = $param_value;
+                            }
+                            break;
+                        case "proxy_port":
+                            if(!preg_match('!\D!', $param_value)) {
+                                $proxy_port = (int) $param_value;
+                            } else {
+                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+                                return;
+                            }
+                            break;
+                        case "agent":
+                            if(!empty($param_value)) {
+                                $agent = $param_value;
+                            }
+                            break;
+                        case "referer":
+                            if(!empty($param_value)) {
+                                $referer = $param_value;
+                            }
+                            break;
+                        case "timeout":
+                            if(!preg_match('!\D!', $param_value)) {
+                                $timeout = (int) $param_value;
+                            } else {
+                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+                                return;
+                            }
+                            break;
+                        default:
+                            $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
+                            return;
+                    }
+                }
+                if(!empty($proxy_host) && !empty($proxy_port)) {
+                    $_is_proxy = true;
+                    $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
+                } else {
+                    $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
+                }
+
+                if(!$fp) {
+                    $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
+                    return;
+                } else {
+                    if($_is_proxy) {
+                        fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+                    } else {
+                        fputs($fp, "GET $uri HTTP/1.0\r\n");
+                    }
+                    if(!empty($host)) {
+                        fputs($fp, "Host: $host\r\n");
+                    }
+                    if(!empty($accept)) {
+                        fputs($fp, "Accept: $accept\r\n");
+                    }
+                    if(!empty($agent)) {
+                        fputs($fp, "User-Agent: $agent\r\n");
+                    }
+                    if(!empty($referer)) {
+                        fputs($fp, "Referer: $referer\r\n");
+                    }
+                    if(isset($extra_headers) && is_array($extra_headers)) {
+                        foreach($extra_headers as $curr_header) {
+                            fputs($fp, $curr_header."\r\n");
+                        }
+                    }
+                    if(!empty($user) && !empty($pass)) {
+                        fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
+                    }
+
+                    fputs($fp, "\r\n");
+                    while(!feof($fp)) {
+                        $content .= fgets($fp,4096);
+                    }
+                    fclose($fp);
+                    $csplit = split("\r\n\r\n",$content,2);
+
+                    $content = $csplit[1];
+
+                    if(!empty($params['assign_headers'])) {
+                        $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
+                    }
+                }
+            } else {
+                $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
+                return;
+            }
+        } else {
+            // ftp fetch
+            if($fp = @fopen($params['file'],'r')) {
+                while(!feof($fp)) {
+                    $content .= fgets ($fp,4096);
+                }
+                fclose($fp);
+            } else {
+                $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
+                return;
+            }
+        }
+
+    }
+
+
+    if (!empty($params['assign'])) {
+        $smarty->assign($params['assign'],$content);
+    } else {
+        return $content;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.indent.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.indent.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.indent.php	(revision 795)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     indent<br>
+ * Purpose:  indent lines of text
+ * @link http://smarty.php.net/manual/en/language.modifier.indent.php
+ *          indent (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @return string
+ */
+function smarty_modifier_indent($string,$chars=4,$char=" ")
+{
+    return preg_replace('!^!m',str_repeat($char,$chars),$string);
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.truncate.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.truncate.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.truncate.php	(revision 795)
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty truncate modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     truncate<br>
+ * Purpose:  Truncate a string to a certain length if necessary,
+ *           optionally splitting in the middle of a word, and
+ *           appending the $etc string or inserting $etc into the middle.
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
+ *          truncate (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...',
+                                  $break_words = false, $middle = false)
+{
+    if ($length == 0)
+        return '';
+
+    if (strlen($string) > $length) {
+        $length -= min($length, strlen($etc));
+        if (!$break_words && !$middle) {
+            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
+        }
+        if(!$middle) {
+            return substr($string, 0, $length) . $etc;
+        } else {
+            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
+        }
+    } else {
+        return $string;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_select_date.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_select_date.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_select_date.php	(revision 795)
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {html_select_date} plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_date<br>
+ * Purpose:  Prints the dropdowns for date selection.
+ *
+ * ChangeLog:<br>
+ *           - 1.0 initial release
+ *           - 1.1 added support for +/- N syntax for begin
+ *                and end year values. (Monte)
+ *           - 1.2 added support for yyyy-mm-dd syntax for
+ *                time value. (Jan Rosier)
+ *           - 1.3 added support for choosing format for
+ *                month values (Gary Loescher)
+ *           - 1.3.1 added support for choosing format for
+ *                day values (Marcus Bointon)
+ *           - 1.3.2 support negative timestamps, force year
+ *             dropdown to include given date unless explicitly set (Monte)
+ *           - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
+ *             of 0000-00-00 dates (cybot, boots)
+ * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
+ *      (Smarty online manual)
+ * @version 1.3.4
+ * @author Andrei Zmievski
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_select_date($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+    /* Default values. */
+    $prefix          = "Date_";
+    $start_year      = strftime("%Y");
+    $end_year        = $start_year;
+    $display_days    = true;
+    $display_months  = true;
+    $display_years   = true;
+    $month_format    = "%B";
+    /* Write months as numbers by default  GL */
+    $month_value_format = "%m";
+    $day_format      = "%02d";
+    /* Write day values using this format MB */
+    $day_value_format = "%d";
+    $year_as_text    = false;
+    /* Display years in reverse order? Ie. 2000,1999,.... */
+    $reverse_years   = false;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Day]",
+       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+    $field_array     = null;
+    /* <select size>'s of the different <select> tags.
+       If not set, uses default dropdown. */
+    $day_size        = null;
+    $month_size      = null;
+    $year_size       = null;
+    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+       An example might be in the template: all_extra ='class ="foo"'. */
+    $all_extra       = null;
+    /* Separate attributes for the tags. */
+    $day_extra       = null;
+    $month_extra     = null;
+    $year_extra      = null;
+    /* Order in which to display the fields.
+       "D" -> day, "M" -> month, "Y" -> year. */
+    $field_order     = 'MDY';
+    /* String printed between the different fields. */
+    $field_separator = "\n";
+    $time = time();
+    $all_empty       = null;
+    $day_empty       = null;
+    $month_empty     = null;
+    $year_empty      = null;
+    $extra_attrs     = '';
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'prefix':
+            case 'time':
+            case 'start_year':
+            case 'end_year':
+            case 'month_format':
+            case 'day_format':
+            case 'day_value_format':
+            case 'field_array':
+            case 'day_size':
+            case 'month_size':
+            case 'year_size':
+            case 'all_extra':
+            case 'day_extra':
+            case 'month_extra':
+            case 'year_extra':
+            case 'field_order':
+            case 'field_separator':
+            case 'month_value_format':
+            case 'month_empty':
+            case 'day_empty':
+            case 'year_empty':
+                $$_key = (string)$_value;
+                break;
+
+            case 'all_empty':
+                $$_key = (string)$_value;
+                $day_empty = $month_empty = $year_empty = $all_empty;
+                break;
+
+            case 'display_days':
+            case 'display_months':
+            case 'display_years':
+            case 'year_as_text':
+            case 'reverse_years':
+                $$_key = (bool)$_value;
+                break;
+
+            default:
+                if(!is_array($_value)) {
+                    $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
+                } else {
+                    $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (preg_match('!^-\d+$!', $time)) {
+        // negative timestamp, use date()
+        $time = date('Y-m-d', $time);
+    }
+    // If $time is not in format yyyy-mm-dd
+    if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
+        $time = $found[1];
+    } else {
+        // use smarty_make_timestamp to get an unix timestamp and
+        // strftime to make yyyy-mm-dd
+        $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
+    }
+    // Now split this in pieces, which later can be used to set the select
+    $time = explode("-", $time);
+
+    // make syntax "+N" or "-N" work with start_year and end_year
+    if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
+        if ($match[1] == '+') {
+            $end_year = strftime('%Y') + $match[2];
+        } else {
+            $end_year = strftime('%Y') - $match[2];
+        }
+    }
+    if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
+        if ($match[1] == '+') {
+            $start_year = strftime('%Y') + $match[2];
+        } else {
+            $start_year = strftime('%Y') - $match[2];
+        }
+    }
+    if (strlen($time[0]) > 0) {
+        if ($start_year > $time[0] && !isset($params['start_year'])) {
+            // force start year to include given date if not explicitly set
+            $start_year = $time[0];
+        }
+        if($end_year < $time[0] && !isset($params['end_year'])) {
+            // force end year to include given date if not explicitly set
+            $end_year = $time[0];
+        }
+    }
+
+    $field_order = strtoupper($field_order);
+
+    $html_result = $month_result = $day_result = $year_result = "";
+
+    $field_separator_count = -1;
+    if ($display_months) {
+    	$field_separator_count++;
+        $month_names = array();
+        $month_values = array();
+        if(isset($month_empty)) {
+            $month_names[''] = $month_empty;
+            $month_values[''] = '';
+        }
+        for ($i = 1; $i <= 12; $i++) {
+            $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
+            $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
+        }
+
+        $month_result .= '<select name=';
+        if (null !== $field_array){
+            $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
+        } else {
+            $month_result .= '"' . $prefix . 'Month"';
+        }
+        if (null !== $month_size){
+            $month_result .= ' size="' . $month_size . '"';
+        }
+        if (null !== $month_extra){
+            $month_result .= ' ' . $month_extra;
+        }
+        if (null !== $all_extra){
+            $month_result .= ' ' . $all_extra;
+        }
+        $month_result .= $extra_attrs . '>'."\n";
+
+        $month_result .= smarty_function_html_options(array('output'     => $month_names,
+                                                            'values'     => $month_values,
+                                                            'selected'   => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
+                                                            'print_result' => false),
+                                                      $smarty);
+        $month_result .= '</select>';
+    }
+
+    if ($display_days) {
+    	$field_separator_count++;
+        $days = array();
+        if (isset($day_empty)) {
+            $days[''] = $day_empty;
+            $day_values[''] = '';
+        }
+        for ($i = 1; $i <= 31; $i++) {
+            $days[] = sprintf($day_format, $i);
+            $day_values[] = sprintf($day_value_format, $i);
+        }
+
+        $day_result .= '<select name=';
+        if (null !== $field_array){
+            $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
+        } else {
+            $day_result .= '"' . $prefix . 'Day"';
+        }
+        if (null !== $day_size){
+            $day_result .= ' size="' . $day_size . '"';
+        }
+        if (null !== $all_extra){
+            $day_result .= ' ' . $all_extra;
+        }
+        if (null !== $day_extra){
+            $day_result .= ' ' . $day_extra;
+        }
+        $day_result .= $extra_attrs . '>'."\n";
+        $day_result .= smarty_function_html_options(array('output'     => $days,
+                                                          'values'     => $day_values,
+                                                          'selected'   => $time[2],
+                                                          'print_result' => false),
+                                                    $smarty);
+        $day_result .= '</select>';
+    }
+
+    if ($display_years) {
+    	$field_separator_count++;
+        if (null !== $field_array){
+            $year_name = $field_array . '[' . $prefix . 'Year]';
+        } else {
+            $year_name = $prefix . 'Year';
+        }
+        if ($year_as_text) {
+            $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
+            if (null !== $all_extra){
+                $year_result .= ' ' . $all_extra;
+            }
+            if (null !== $year_extra){
+                $year_result .= ' ' . $year_extra;
+            }
+            $year_result .= ' />';
+        } else {
+            $years = range((int)$start_year, (int)$end_year);
+            if ($reverse_years) {
+                rsort($years, SORT_NUMERIC);
+            } else {
+                sort($years, SORT_NUMERIC);
+            }
+            $yearvals = $years;
+            if(isset($year_empty)) {
+                array_unshift($years, $year_empty);
+                array_unshift($yearvals, '');
+            }
+            $year_result .= '<select name="' . $year_name . '"';
+            if (null !== $year_size){
+                $year_result .= ' size="' . $year_size . '"';
+            }
+            if (null !== $all_extra){
+                $year_result .= ' ' . $all_extra;
+            }
+            if (null !== $year_extra){
+                $year_result .= ' ' . $year_extra;
+            }
+            $year_result .= $extra_attrs . '>'."\n";
+            $year_result .= smarty_function_html_options(array('output' => $years,
+                                                               'values' => $yearvals,
+                                                               'selected'   => $time[0],
+                                                               'print_result' => false),
+                                                         $smarty);
+            $year_result .= '</select>';
+        }
+    }
+
+    // Loop thru the field_order field
+    for ($i = 0; $i <= 2; $i++){
+        $c = substr($field_order, $i, 1);
+        switch ($c){
+            case 'D':
+                $html_result .= $day_result;
+                break;
+
+            case 'M':
+                $html_result .= $month_result;
+                break;
+
+            case 'Y':
+                $html_result .= $year_result;
+                break;
+        }
+        // Add the field seperator
+        if($i < $field_separator_count) {
+            $html_result .= $field_separator;
+        }
+    }
+
+    return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/shared.escape_special_chars.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/shared.escape_special_chars.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/shared.escape_special_chars.php	(revision 795)
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * escape_special_chars common function
+ *
+ * Function: smarty_function_escape_special_chars<br>
+ * Purpose:  used by other smarty functions to escape
+ *           special chars except for already escaped ones
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_function_escape_special_chars($string)
+{
+    if(!is_array($string)) {
+        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+        $string = htmlspecialchars($string);
+        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
+    }
+    return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_checkboxes.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_checkboxes.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.html_checkboxes.php	(revision 795)
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ *
+ * File:       function.html_checkboxes.php<br>
+ * Type:       function<br>
+ * Name:       html_checkboxes<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of checkbox input types<br>
+ * Input:<br>
+ *           - name       (optional) - string default "checkbox"
+ *           - values     (required) - array
+ *           - options    (optional) - associative array
+ *           - checked    (optional) - array default not set
+ *           - separator  (optional) - ie <br> or &nbsp;
+ *           - output     (optional) - the output next to each checkbox
+ *           - assign     (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+    $name = 'checkbox';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $output = null;
+
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = $_val;
+                break;
+
+            case 'labels':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'checked':
+            case 'selected':
+                $selected = array_map('strval', array_values((array)$_val));
+                break;
+
+            case 'checkboxes':
+                $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    settype($selected, 'array');
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+
+    } else {
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
+
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
+    $_output = '';
+    if ($labels) $_output .= '<label>';
+    $_output .= '<input type="checkbox" name="'
+        . smarty_function_escape_special_chars($name) . '[]" value="'
+        . smarty_function_escape_special_chars($value) . '"';
+
+    if (in_array((string)$value, $selected)) {
+        $_output .= ' checked="checked"';
+    }
+    $_output .= $extra . ' />' . $output;
+    if ($labels) $_output .= '</label>';
+    $_output .=  $separator;
+
+    return $_output;
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/function.config_load.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/function.config_load.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/function.config_load.php	(revision 795)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {config_load} function plugin
+ *
+ * Type:     function<br>
+ * Name:     config_load<br>
+ * Purpose:  load config file vars
+ * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
+ * @param array Format:
+ * <pre>
+ * array('file' => required config file name,
+ *       'section' => optional config file section to load
+ *       'scope' => local/parent/global
+ *       'global' => overrides scope, setting to parent if true)
+ * </pre>
+ * @param Smarty
+ */
+function smarty_function_config_load($params, &$smarty)
+{
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+        }
+
+        $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
+        $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
+        $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
+        $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
+
+        if (!isset($_file) || strlen($_file) == 0) {
+            $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($_scope)) {
+            if ($_scope != 'local' &&
+                $_scope != 'parent' &&
+                $_scope != 'global') {
+                $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        } else {
+            if ($_global) {
+                $_scope = 'parent';
+            } else {
+                $_scope = 'local';
+            }
+        }
+
+        $_params = array('resource_name' => $_file,
+                         'resource_base_path' => $smarty->config_dir,
+                         'get_source' => false);
+        $smarty->_parse_resource_name($_params);
+        $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
+        if (isset($_section))
+            $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
+        else
+            $_compile_file = $smarty->_get_compile_path($_file_path);
+
+        if($smarty->force_compile || !file_exists($_compile_file)) {
+            $_compile = true;
+        } elseif ($smarty->compile_check) {
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             'get_source' => false);
+            $_compile = $smarty->_fetch_resource_info($_params) &&
+                $_params['resource_timestamp'] > filemtime($_compile_file);
+        } else {
+            $_compile = false;
+        }
+
+        if($_compile) {
+            // compile config file
+            if(!is_object($smarty->_conf_obj)) {
+                require_once SMARTY_DIR . $smarty->config_class . '.class.php';
+                $smarty->_conf_obj = new $smarty->config_class();
+                $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
+                $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
+                $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
+                $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
+            }
+
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             $_params['get_source'] = true);
+            if (!$smarty->_fetch_resource_info($_params)) {
+                return;
+            }
+            $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
+            $_config_vars = array_merge($smarty->_conf_obj->get($_file),
+                    $smarty->_conf_obj->get($_file, $_section));
+            if(function_exists('var_export')) {
+                $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
+            } else {
+                $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
+            }
+            $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $smarty);
+        } else {
+            include($_compile_file);
+        }
+
+        if ($smarty->caching) {
+            $smarty->_cache_info['config'][$_file] = true;
+        }
+
+        $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
+        $smarty->_config[0]['files'][$_file] = true;
+
+        if ($_scope == 'parent') {
+                $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
+                $smarty->_config[1]['files'][$_file] = true;
+        } else if ($_scope == 'global') {
+            for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
+                $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
+                $smarty->_config[$i]['files'][$_file] = true;
+            }
+        }
+
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'config',
+                                                'filename'  => $_file.' ['.$_section.'] '.$_scope,
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+        }
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.upper.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.upper.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/plugins/modifier.upper.php	(revision 795)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty upper modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     upper<br>
+ * Purpose:  convert string to uppercase
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php
+ *          upper (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_upper($string)
+{
+    return strtoupper($string);
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/Smarty_Compiler.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/Smarty_Compiler.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/Smarty_Compiler.class.php	(revision 795)
@@ -0,0 +1,2325 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty_Compiler.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://smarty.php.net/
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @version 2.6.19
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @package Smarty
+ */
+
+/* $Id: Smarty_Compiler.class.php 760 2008-04-03 19:15:17Z drovetto $ */
+
+/**
+ * Template compiling class
+ * @package Smarty
+ */
+class Smarty_Compiler extends Smarty {
+
+    // internal vars
+    /**#@+
+     * @access private
+     */
+    var $_folded_blocks         =   array();    // keeps folded template blocks
+    var $_current_file          =   null;       // the current template being compiled
+    var $_current_line_no       =   1;          // line number for error messages
+    var $_capture_stack         =   array();    // keeps track of nested capture buffers
+    var $_plugin_info           =   array();    // keeps track of plugins to load
+    var $_init_smarty_vars      =   false;
+    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');
+    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor
+    var $_si_qstr_regexp        =   null;
+    var $_qstr_regexp           =   null;
+    var $_func_regexp           =   null;
+    var $_reg_obj_regexp        =   null;
+    var $_var_bracket_regexp    =   null;
+    var $_num_const_regexp      =   null;
+    var $_dvar_guts_regexp      =   null;
+    var $_dvar_regexp           =   null;
+    var $_cvar_regexp           =   null;
+    var $_svar_regexp           =   null;
+    var $_avar_regexp           =   null;
+    var $_mod_regexp            =   null;
+    var $_var_regexp            =   null;
+    var $_parenth_param_regexp  =   null;
+    var $_func_call_regexp      =   null;
+    var $_obj_ext_regexp        =   null;
+    var $_obj_start_regexp      =   null;
+    var $_obj_params_regexp     =   null;
+    var $_obj_call_regexp       =   null;
+    var $_cacheable_state       =   0;
+    var $_cache_attrs_count     =   0;
+    var $_nocache_count         =   0;
+    var $_cache_serial          =   null;
+    var $_cache_include         =   null;
+
+    var $_strip_depth           =   0;
+    var $_additional_newline    =   "\n";
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty_Compiler()
+    {
+        // matches double quoted strings:
+        // "foobar"
+        // "foo\"bar"
+        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
+
+        // matches single quoted strings:
+        // 'foobar'
+        // 'foo\'bar'
+        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
+
+        // matches single or double quoted strings
+        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
+
+        // matches bracket portion of vars
+        // [0]
+        // [foo]
+        // [$bar]
+        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
+
+        // matches numerical constants
+        // 30
+        // -12
+        // 13.22
+        $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
+
+        // matches $ vars (not objects):
+        // $foo
+        // $foo.bar
+        // $foo.bar.foobar
+        // $foo[0]
+        // $foo[$bar]
+        // $foo[5][blah]
+        // $foo[5].bar[$foobar][4]
+        $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
+        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
+        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
+                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
+        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
+
+        // matches config vars:
+        // #foo#
+        // #foobar123_foo#
+        $this->_cvar_regexp = '\#\w+\#';
+
+        // matches section vars:
+        // %foo.bar%
+        $this->_svar_regexp = '\%\w+\.\w+\%';
+
+        // matches all valid variables (no quotes, no modifiers)
+        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
+           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
+
+        // matches valid variable syntax:
+        // $foo
+        // $foo
+        // #foo#
+        // #foo#
+        // "text"
+        // "text"
+        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
+
+        // matches valid object call (one level of object nesting allowed in parameters):
+        // $foo->bar
+        // $foo->bar()
+        // $foo->bar("text")
+        // $foo->bar($foo, $bar, "text")
+        // $foo->bar($foo, "foo")
+        // $foo->bar->foo()
+        // $foo->bar->foo->bar()
+        // $foo->bar($foo->bar)
+        // $foo->bar($foo->bar())
+        // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
+        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
+        $this->_obj_restricted_param_regexp = '(?:'
+                . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
+                . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
+        $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
+        $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
+                . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
+        $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
+        $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
+        
+        // matches valid modifier syntax:
+        // |foo
+        // |@foo
+        // |foo:"bar"
+        // |foo:$bar
+        // |foo:"bar":$foobar
+        // |foo|bar
+        // |foo:$foo->bar
+        $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
+           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
+
+        // matches valid function name:
+        // foo123
+        // _foo_bar
+        $this->_func_regexp = '[a-zA-Z_]\w*';
+
+        // matches valid registered object:
+        // foo->bar
+        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
+
+        // matches valid parameter values:
+        // true
+        // $foo
+        // $foo|bar
+        // #foo#
+        // #foo#|bar
+        // "text"
+        // "text"|bar
+        // $foo->bar
+        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
+           . $this->_var_regexp . '|' . $this->_num_const_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
+
+        // matches valid parenthesised function parameters:
+        //
+        // "text"
+        //    $foo, $bar, "text"
+        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
+        $this->_parenth_param_regexp = '(?:\((?:\w+|'
+                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_param_regexp . ')))*)?\))';
+
+        // matches valid function call:
+        // foo()
+        // foo_bar($foo)
+        // _foo_bar($foo,"bar")
+        // foo123($foo,$foo->bar(),"foo")
+        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
+           . $this->_parenth_param_regexp . '))';
+    }
+
+    /**
+     * compile a resource
+     *
+     * sets $compiled_content to the compiled source
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return true
+     */
+    function _compile_file($resource_name, $source_content, &$compiled_content)
+    {
+
+        if ($this->security) {
+            // do not allow php syntax to be executed unless specified
+            if ($this->php_handling == SMARTY_PHP_ALLOW &&
+                !$this->security_settings['PHP_HANDLING']) {
+                $this->php_handling = SMARTY_PHP_PASSTHRU;
+            }
+        }
+
+        $this->_load_filters();
+
+        $this->_current_file = $resource_name;
+        $this->_current_line_no = 1;
+        $ldq = preg_quote($this->left_delimiter, '~');
+        $rdq = preg_quote($this->right_delimiter, '~');
+
+        // run template source through prefilter functions
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) continue;
+                if ($prefilter[3] || is_callable($prefilter[0])) {
+                    $source_content = call_user_func_array($prefilter[0],
+                                                            array($source_content, &$this));
+                    $this->_plugins['prefilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        /* fetch all special blocks */
+        $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
+
+        preg_match_all($search, $source_content, $match,  PREG_SET_ORDER);
+        $this->_folded_blocks = $match;
+        reset($this->_folded_blocks);
+
+        /* replace special blocks by "{php}" */
+        $source_content = preg_replace($search.'e', "'"
+                                       . $this->_quote_replace($this->left_delimiter) . 'php'
+                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+                                       . $this->_quote_replace($this->right_delimiter)
+                                       . "'"
+                                       , $source_content);
+
+        /* Gather all template tags. */
+        preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
+        $template_tags = $_match[1];
+        /* Split content by template tags to obtain non-template content. */
+        $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
+
+        /* loop through text blocks */
+        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
+            /* match anything resembling php tags */
+            if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
+                /* replace tags with placeholders to prevent recursive replacements */
+                $sp_match[1] = array_unique($sp_match[1]);
+                usort($sp_match[1], '_smarty_sort_length');
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
+                }
+                /* process each one */
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
+                        /* echo php contents */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
+                        /* quote php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
+                        /* remove php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
+                    } else {
+                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */
+                        $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
+                    }
+                }
+            }
+        }
+        
+        /* Compile the template tags into PHP code. */
+        $compiled_tags = array();
+        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
+            $this->_current_line_no += substr_count($text_blocks[$i], "\n");
+            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
+            $this->_current_line_no += substr_count($template_tags[$i], "\n");
+        }
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = end($this->_tag_stack);
+            $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
+            return;
+        }
+
+        /* Reformat $text_blocks between 'strip' and '/strip' tags,
+           removing spaces, tabs and newlines. */
+        $strip = false;
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '{strip}') {
+                $compiled_tags[$i] = '';
+                $strip = true;
+                /* remove leading whitespaces */
+                $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
+            }
+            if ($strip) {
+                /* strip all $text_blocks before the next '/strip' */
+                for ($j = $i + 1; $j < $for_max; $j++) {
+                    /* remove leading and trailing whitespaces of each line */
+                    $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
+                    if ($compiled_tags[$j] == '{/strip}') {                       
+                        /* remove trailing whitespaces from the last text_block */
+                        $text_blocks[$j] = rtrim($text_blocks[$j]);
+                    }
+                    $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
+                    if ($compiled_tags[$j] == '{/strip}') {
+                        $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
+                                    if a newline is following the closing strip-tag */
+                        $strip = false;
+                        $i = $j;
+                        break;
+                    }
+                }
+            }
+        }
+        $compiled_content = '';
+        
+        $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
+        
+        /* Interleave the compiled contents and text blocks to get the final result. */
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '') {
+                // tag result empty, remove first newline from following text block
+                $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
+            }
+            // replace legit PHP tags with placeholder
+            $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
+            $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
+            
+            $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
+        }
+        $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
+
+        // escape php tags created by interleaving
+        $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
+        $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
+
+        // recover legit tags
+        $compiled_content = str_replace($tag_guard, '<?', $compiled_content); 
+        
+        // remove \n from the end of the file, if any
+        if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
+            $compiled_content = substr($compiled_content, 0, -1);
+        }
+
+        if (!empty($this->_cache_serial)) {
+            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
+        }
+
+        // run compiled template through postfilter functions
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) continue;
+                if ($postfilter[3] || is_callable($postfilter[0])) {
+                    $compiled_content = call_user_func_array($postfilter[0],
+                                                              array($compiled_content, &$this));
+                    $this->_plugins['postfilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        // put header at the top of the compiled template
+        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
+
+        /* Emit code to load needed plugins. */
+        $this->_plugins_code = '';
+        if (count($this->_plugin_info)) {
+            $_plugins_params = "array('plugins' => array(";
+            foreach ($this->_plugin_info as $plugin_type => $plugins) {
+                foreach ($plugins as $plugin_name => $plugin_info) {
+                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
+                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
+                }
+            }
+            $_plugins_params .= '))';
+            $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
+            $template_header .= $plugins_code;
+            $this->_plugin_info = array();
+            $this->_plugins_code = $plugins_code;
+        }
+
+        if ($this->_init_smarty_vars) {
+            $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
+            $this->_init_smarty_vars = false;
+        }
+
+        $compiled_content = $template_header . $compiled_content;
+        return true;
+    }
+
+    /**
+     * Compile a template tag
+     *
+     * @param string $template_tag
+     * @return string
+     */
+    function _compile_tag($template_tag)
+    {
+        /* Matched comment. */
+        if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
+            return '';
+        
+        /* Split tag into two three parts: command, command modifiers and the arguments. */
+        if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
+                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
+                      (?:\s+(.*))?$
+                    ~xs', $template_tag, $match)) {
+            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        $tag_command = $match[1];
+        $tag_modifier = isset($match[2]) ? $match[2] : null;
+        $tag_args = isset($match[3]) ? $match[3] : null;
+
+        if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
+            /* tag name is a variable or object */
+            $_return = $this->_parse_var_props($tag_command . $tag_modifier);
+            return "<?php echo $_return; ?>" . $this->_additional_newline;
+        }
+
+        /* If the tag name is a registered object, we process it. */
+        if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
+            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
+        }
+
+        switch ($tag_command) {
+            case 'include':
+                return $this->_compile_include_tag($tag_args);
+
+            case 'include_php':
+                return $this->_compile_include_php_tag($tag_args);
+
+            case 'if':
+                $this->_push_tag('if');
+                return $this->_compile_if_tag($tag_args);
+
+            case 'else':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
+                else
+                    $this->_push_tag('else');
+                return '<?php else: ?>';
+
+            case 'elseif':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
+                if ($_open_tag == 'if')
+                    $this->_push_tag('elseif');
+                return $this->_compile_if_tag($tag_args, true);
+
+            case '/if':
+                $this->_pop_tag('if');
+                return '<?php endif; ?>';
+
+            case 'capture':
+                return $this->_compile_capture_tag(true, $tag_args);
+
+            case '/capture':
+                return $this->_compile_capture_tag(false);
+
+            case 'ldelim':
+                return $this->left_delimiter;
+
+            case 'rdelim':
+                return $this->right_delimiter;
+
+            case 'section':
+                $this->_push_tag('section');
+                return $this->_compile_section_start($tag_args);
+
+            case 'sectionelse':
+                $this->_push_tag('sectionelse');
+                return "<?php endfor; else: ?>";
+                break;
+
+            case '/section':
+                $_open_tag = $this->_pop_tag('section');
+                if ($_open_tag == 'sectionelse')
+                    return "<?php endif; ?>";
+                else
+                    return "<?php endfor; endif; ?>";
+
+            case 'foreach':
+                $this->_push_tag('foreach');
+                return $this->_compile_foreach_start($tag_args);
+                break;
+
+            case 'foreachelse':
+                $this->_push_tag('foreachelse');
+                return "<?php endforeach; else: ?>";
+
+            case '/foreach':
+                $_open_tag = $this->_pop_tag('foreach');
+                if ($_open_tag == 'foreachelse')
+                    return "<?php endif; unset(\$_from); ?>";
+                else
+                    return "<?php endforeach; endif; unset(\$_from); ?>";
+                break;
+
+            case 'strip':
+            case '/strip':
+                if (substr($tag_command, 0, 1)=='/') {
+                    $this->_pop_tag('strip');
+                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
+                        $this->_additional_newline = "\n";
+                        return '{' . $tag_command . '}';
+                    }
+                } else {
+                    $this->_push_tag('strip');
+                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */
+                        $this->_additional_newline = "";
+                        return '{' . $tag_command . '}';
+                    }
+                }
+                return '';
+
+            case 'php':
+                /* handle folded tags replaced by {php} */
+                list(, $block) = each($this->_folded_blocks);
+                $this->_current_line_no += substr_count($block[0], "\n");
+                /* the number of matched elements in the regexp in _compile_file()
+                   determins the type of folded tag that was found */
+                switch (count($block)) {
+                    case 2: /* comment */
+                        return '';
+
+                    case 3: /* literal */
+                        return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
+
+                    case 4: /* php */
+                        if ($this->security && !$this->security_settings['PHP_TAGS']) {
+                            $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
+                            return;
+                        }
+                        return '<?php ' . $block[3] .' ?>';
+                }
+                break;
+
+            case 'insert':
+                return $this->_compile_insert_tag($tag_args);
+
+            default:
+                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
+                    return $output;
+                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;
+                } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;                    
+                } else {
+                    $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+
+        }
+    }
+
+
+    /**
+     * compile the custom compiler tag
+     *
+     * sets $output to the compiled custom compiler tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_compiler_tag($tag_command, $tag_args, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the compiler function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['compiler'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['compiler'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "compiler function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_compiler_' . $tag_command;
+            if (!is_callable($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
+            }
+        }
+
+        /*
+         * True return value means that we either found a plugin or a
+         * dynamically registered function. False means that we didn't and the
+         * compiler should now emit code to load custom function plugin for this
+         * tag.
+         */
+        if ($found) {
+            if ($have_function) {
+                $output = call_user_func_array($plugin_func, array($tag_args, &$this));
+                if($output != '') {
+                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
+                                   . $output
+                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
+                }
+            } else {
+                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * compile block function tag
+     *
+     * sets $output to compiled block function tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else
+            $start_tag = true;
+
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the block function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['block'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['block'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "block function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_block_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /*
+         * Even though we've located the plugin function, compilation
+         * happens only once, so the plugin will still need to be loaded
+         * at runtime for future requests.
+         */
+        $this->_add_plugin('block', $tag_command);
+
+        if ($start_tag)
+            $this->_push_tag($tag_command);
+        else
+            $this->_pop_tag($tag_command);
+
+        if ($start_tag) {
+            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
+            $attrs = $this->_parse_attrs($tag_args);
+            $_cache_attrs='';
+            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
+            $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
+            $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
+            $output .= 'while ($_block_repeat) { ob_start(); ?>';
+        } else {
+            $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
+            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
+            if ($tag_modifier != '') {
+                $this->_parse_modifiers($_out_tag_text, $tag_modifier);
+            }
+            $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
+            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
+        }
+
+        return true;
+    }
+
+
+    /**
+     * compile custom function tag
+     *
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the custom function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['function'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['function'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "custom function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_function_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /* declare plugin to be loaded on display of the template that
+           we compile right now */
+        $this->_add_plugin('function', $tag_command);
+
+        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
+        $attrs = $this->_parse_attrs($tag_args);
+        $_cache_attrs = '';
+        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
+
+        $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
+        if($tag_modifier != '') {
+            $this->_parse_modifiers($output, $tag_modifier);
+        }
+
+        if($output != '') {
+            $output =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
+                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
+        }
+
+        return true;
+    }
+
+    /**
+     * compile a registered object tag
+     *
+     * @param string $tag_command
+     * @param array $attrs
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else {
+            $start_tag = true;
+        }
+
+        list($object, $obj_comp) = explode('->', $tag_command);
+
+        $arg_list = array();
+        if(count($attrs)) {
+            $_assign_var = false;
+            foreach ($attrs as $arg_name => $arg_value) {
+                if($arg_name == 'assign') {
+                    $_assign_var = $arg_value;
+                    unset($attrs['assign']);
+                    continue;
+                }
+                if (is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        if($this->_reg_objects[$object][2]) {
+            // smarty object argument format
+            $args = "array(".implode(',', (array)$arg_list)."), \$this";
+        } else {
+            // traditional argument format
+            $args = implode(',', array_values($attrs));
+            if (empty($args)) {
+                $args = '';
+            }
+        }
+
+        $prefix = '';
+        $postfix = '';
+        $newline = '';
+        if(!is_object($this->_reg_objects[$object][0])) {
+            $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
+            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
+            // method
+            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
+                // block method
+                if ($start_tag) {
+                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
+                    $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
+                    $prefix .= "while (\$_block_repeat) { ob_start();";
+                    $return = null;
+                    $postfix = '';
+                } else {
+                    $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
+                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
+                    $postfix = "} array_pop(\$this->_tag_stack);";
+                }
+            } else {
+                // non-block method
+                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
+            }
+        } else {
+            // property
+            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
+        }
+
+        if($return != null) {
+            if($tag_modifier != '') {
+                $this->_parse_modifiers($return, $tag_modifier);
+            }
+
+            if(!empty($_assign_var)) {
+                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";
+            } else {
+                $output = 'echo ' . $return . ';';
+                $newline = $this->_additional_newline;
+            }
+        } else {
+            $output = '';
+        }
+
+        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
+    }
+
+    /**
+     * Compile {insert ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_insert_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $name = $this->_dequote($attrs['name']);
+
+        if (empty($name)) {
+            return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        if (!preg_match('~^\w+$~', $name)) {
+            return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (!empty($attrs['script'])) {
+            $delayed_loading = true;
+        } else {
+            $delayed_loading = false;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $this->_add_plugin('insert', $name, $delayed_loading);
+
+        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if ($arg_name == 'file') {
+                $include_file = $arg_value;
+                continue;
+            } else if ($arg_name == 'assign') {
+                $assign_var = $arg_value;
+                continue;
+            }
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $output = '<?php ';
+
+        if (isset($assign_var)) {
+            $output .= "ob_start();\n";
+        }
+
+        $output .=
+            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
+
+
+        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
+        $output .= "\$this->_smarty_include($_params);\n" .
+        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
+        "unset(\$_smarty_tpl_vars);\n";
+
+        if (isset($assign_var)) {
+            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
+        }
+
+        $output .= ' ?>';
+
+        return $output;
+
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_php_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
+        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
+
+        $arg_list = array();
+        foreach($attrs as $arg_name => $arg_value) {
+            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
+                if(is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+
+    /**
+     * Compile {section ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_section_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        $output = '<?php ';
+        $section_name = $attrs['name'];
+        if (empty($section_name)) {
+            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $output .= "unset(\$this->_sections[$section_name]);\n";
+        $section_props = "\$this->_sections[$section_name]";
+
+        foreach ($attrs as $attr_name => $attr_value) {
+            switch ($attr_name) {
+                case 'loop':
+                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+                    break;
+
+                case 'show':
+                    if (is_bool($attr_value))
+                        $show_attr_value = $attr_value ? 'true' : 'false';
+                    else
+                        $show_attr_value = "(bool)$attr_value";
+                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
+                    break;
+
+                case 'name':
+                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+                    break;
+
+                case 'max':
+                case 'start':
+                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+                    break;
+
+                case 'step':
+                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+                    break;
+
+                default:
+                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+        }
+
+        if (!isset($attrs['show']))
+            $output .= "{$section_props}['show'] = true;\n";
+
+        if (!isset($attrs['loop']))
+            $output .= "{$section_props}['loop'] = 1;\n";
+
+        if (!isset($attrs['max']))
+            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+        else
+            $output .= "if ({$section_props}['max'] < 0)\n" .
+                       "    {$section_props}['max'] = {$section_props}['loop'];\n";
+
+        if (!isset($attrs['step']))
+            $output .= "{$section_props}['step'] = 1;\n";
+
+        if (!isset($attrs['start']))
+            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+        else {
+            $output .= "if ({$section_props}['start'] < 0)\n" .
+                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
+                       "else\n" .
+                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+        }
+
+        $output .= "if ({$section_props}['show']) {\n";
+        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
+            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
+        } else {
+            $output .= "    {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+        }
+        $output .= "    if ({$section_props}['total'] == 0)\n" .
+                   "        {$section_props}['show'] = false;\n" .
+                   "} else\n" .
+                   "    {$section_props}['total'] = 0;\n";
+
+        $output .= "if ({$section_props}['show']):\n";
+        $output .= "
+            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+                 {$section_props}['iteration'] <= {$section_props}['total'];
+                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
+        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+        $output .= "?>";
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {foreach ...} tag.
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_foreach_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['from'])) {
+            return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $from = $attrs['from'];
+
+        if (empty($attrs['item'])) {
+            return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $item = $this->_dequote($attrs['item']);
+        if (!preg_match('~^\w+$~', $item)) {
+            return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($attrs['key'])) {
+            $key  = $this->_dequote($attrs['key']);
+            if (!preg_match('~^\w+$~', $key)) {
+                return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+            }
+            $key_part = "\$this->_tpl_vars['$key'] => ";
+        } else {
+            $key = null;
+            $key_part = '';
+        }
+
+        if (isset($attrs['name'])) {
+            $name = $attrs['name'];
+        } else {
+            $name = null;
+        }
+
+        $output = '<?php ';
+        $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
+        if (isset($name)) {
+            $foreach_props = "\$this->_foreach[$name]";
+            $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
+            $output .= "if ({$foreach_props}['total'] > 0):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+            $output .= "        {$foreach_props}['iteration']++;\n";
+        } else {
+            $output .= "if (count(\$_from)):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+        }
+        $output .= '?>';
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {capture} .. {/capture} tags
+     *
+     * @param boolean $start true if this is the {capture} tag
+     * @param string $tag_args
+     * @return string
+     */
+
+    function _compile_capture_tag($start, $tag_args = '')
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if ($start) {
+            $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
+            $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
+            $append = isset($attrs['append']) ? $attrs['append'] : null;
+            
+            $output = "<?php ob_start(); ?>";
+            $this->_capture_stack[] = array($buffer, $assign, $append);
+        } else {
+            list($buffer, $assign, $append) = array_pop($this->_capture_stack);
+            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
+            if (isset($assign)) {
+                $output .= " \$this->assign($assign, ob_get_contents());";
+            }
+            if (isset($append)) {
+                $output .= " \$this->append($append, ob_get_contents());";
+            }
+            $output .= "ob_end_clean(); ?>";
+        }
+
+        return $output;
+    }
+
+    /**
+     * Compile {if ...} tag
+     *
+     * @param string $tag_args
+     * @param boolean $elseif if true, uses elseif instead of if
+     * @return string
+     */
+    function _compile_if_tag($tag_args, $elseif = false)
+    {
+
+        /* Tokenize args for 'if' tag. */
+        preg_match_all('~(?>
+                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
+                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string
+                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token
+                \b\w+\b                                                        | # valid word token
+                \S+                                                           # anything else
+                )~x', $tag_args, $match);
+
+        $tokens = $match[0];
+
+        if(empty($tokens)) {
+            $_error_msg = $elseif ? "'elseif'" : "'if'";
+            $_error_msg .= ' statement requires arguments'; 
+            $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
+        }
+            
+                
+        // make sure we have balanced parenthesis
+        $token_count = array_count_values($tokens);
+        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
+            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $is_arg_stack = array();
+
+        for ($i = 0; $i < count($tokens); $i++) {
+
+            $token = &$tokens[$i];
+
+            switch (strtolower($token)) {
+                case '!':
+                case '%':
+                case '!==':
+                case '==':
+                case '===':
+                case '>':
+                case '<':
+                case '!=':
+                case '<>':
+                case '<<':
+                case '>>':
+                case '<=':
+                case '>=':
+                case '&&':
+                case '||':
+                case '|':
+                case '^':
+                case '&':
+                case '~':
+                case ')':
+                case ',':
+                case '+':
+                case '-':
+                case '*':
+                case '/':
+                case '@':
+                    break;
+
+                case 'eq':
+                    $token = '==';
+                    break;
+
+                case 'ne':
+                case 'neq':
+                    $token = '!=';
+                    break;
+
+                case 'lt':
+                    $token = '<';
+                    break;
+
+                case 'le':
+                case 'lte':
+                    $token = '<=';
+                    break;
+
+                case 'gt':
+                    $token = '>';
+                    break;
+
+                case 'ge':
+                case 'gte':
+                    $token = '>=';
+                    break;
+
+                case 'and':
+                    $token = '&&';
+                    break;
+
+                case 'or':
+                    $token = '||';
+                    break;
+
+                case 'not':
+                    $token = '!';
+                    break;
+
+                case 'mod':
+                    $token = '%';
+                    break;
+
+                case '(':
+                    array_push($is_arg_stack, $i);
+                    break;
+
+                case 'is':
+                    /* If last token was a ')', we operate on the parenthesized
+                       expression. The start of the expression is on the stack.
+                       Otherwise, we operate on the last encountered token. */
+                    if ($tokens[$i-1] == ')')
+                        $is_arg_start = array_pop($is_arg_stack);
+                    else
+                        $is_arg_start = $i-1;
+                    /* Construct the argument for 'is' expression, so it knows
+                       what to operate on. */
+                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+                    /* Pass all tokens from next one until the end to the
+                       'is' expression parsing function. The function will
+                       return modified tokens, where the first one is the result
+                       of the 'is' expression and the rest are the tokens it
+                       didn't touch. */
+                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
+
+                    /* Replace the old tokens with the new ones. */
+                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+                    /* Adjust argument start so that it won't change from the
+                       current position for the next iteration. */
+                    $i = $is_arg_start;
+                    break;
+
+                default:
+                    if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
+                            // function call
+                            if($this->security &&
+                               !in_array($token, $this->security_settings['IF_FUNCS'])) {
+                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+                            }
+                    } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
+                        // variable function call
+                        $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);                      
+                    } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
+                        // object or variable
+                        $token = $this->_parse_var_props($token);
+                    } elseif(is_numeric($token)) {
+                        // number, skip it
+                    } else {
+                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    }
+                    break;
+            }
+        }
+
+        if ($elseif)
+            return '<?php elseif ('.implode(' ', $tokens).'): ?>';
+        else
+            return '<?php if ('.implode(' ', $tokens).'): ?>';
+    }
+
+
+    function _compile_arg_list($type, $name, $attrs, &$cache_code) {
+        $arg_list = array();
+
+        if (isset($type) && isset($name)
+            && isset($this->_plugins[$type])
+            && isset($this->_plugins[$type][$name])
+            && empty($this->_plugins[$type][$name][4])
+            && is_array($this->_plugins[$type][$name][5])
+            ) {
+            /* we have a list of parameters that should be cached */
+            $_cache_attrs = $this->_plugins[$type][$name][5];
+            $_count = $this->_cache_attrs_count++;
+            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
+
+        } else {
+            /* no parameters are cached */
+            $_cache_attrs = null;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            if (is_null($arg_value))
+                $arg_value = 'null';
+            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
+                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
+            } else {
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+        return $arg_list;
+    }
+
+    /**
+     * Parse is expression
+     *
+     * @param string $is_arg
+     * @param array $tokens
+     * @return array
+     */
+    function _parse_is_expr($is_arg, $tokens)
+    {
+        $expr_end = 0;
+        $negate_expr = false;
+
+        if (($first_token = array_shift($tokens)) == 'not') {
+            $negate_expr = true;
+            $expr_type = array_shift($tokens);
+        } else
+            $expr_type = $first_token;
+
+        switch ($expr_type) {
+            case 'even':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "!(1 & $is_arg)";
+                break;
+
+            case 'odd':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "(1 & $is_arg)";
+                break;
+
+            case 'div':
+                if (@$tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
+                } else {
+                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+                break;
+
+            default:
+                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if ($negate_expr) {
+            $expr = "!($expr)";
+        }
+
+        array_splice($tokens, 0, $expr_end, $expr);
+
+        return $tokens;
+    }
+
+
+    /**
+     * Parse attribute string
+     *
+     * @param string $tag_args
+     * @return array
+     */
+    function _parse_attrs($tag_args)
+    {
+
+        /* Tokenize tag attributes. */
+        preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+                         )+ |
+                         [=]
+                        ~x', $tag_args, $match);
+        $tokens       = $match[0];
+
+        $attrs = array();
+        /* Parse state:
+            0 - expecting attribute name
+            1 - expecting '='
+            2 - expecting attribute value (not '=') */
+        $state = 0;
+
+        foreach ($tokens as $token) {
+            switch ($state) {
+                case 0:
+                    /* If the token is a valid identifier, we set attribute name
+                       and go to state 1. */
+                    if (preg_match('~^\w+$~', $token)) {
+                        $attr_name = $token;
+                        $state = 1;
+                    } else
+                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 1:
+                    /* If the token is '=', then we go to state 2. */
+                    if ($token == '=') {
+                        $state = 2;
+                    } else
+                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 2:
+                    /* If token is not '=', we set the attribute value and go to
+                       state 0. */
+                    if ($token != '=') {
+                        /* We booleanize the token if it's a non-quoted possible
+                           boolean value. */
+                        if (preg_match('~^(on|yes|true)$~', $token)) {
+                            $token = 'true';
+                        } else if (preg_match('~^(off|no|false)$~', $token)) {
+                            $token = 'false';
+                        } else if ($token == 'null') {
+                            $token = 'null';
+                        } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
+                            /* treat integer literally */
+                        } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
+                            /* treat as a string, double-quote it escaping quotes */
+                            $token = '"'.addslashes($token).'"';
+                        }
+
+                        $attrs[$attr_name] = $token;
+                        $state = 0;
+                    } else
+                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+            $last_token = $token;
+        }
+
+        if($state != 0) {
+            if($state == 1) {
+                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+            } else {
+                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        $this->_parse_vars_props($attrs);
+
+        return $attrs;
+    }
+
+    /**
+     * compile multiple variables and section properties tokens into
+     * PHP code
+     *
+     * @param array $tokens
+     */
+    function _parse_vars_props(&$tokens)
+    {
+        foreach($tokens as $key => $val) {
+            $tokens[$key] = $this->_parse_var_props($val);
+        }
+    }
+
+    /**
+     * compile single variable and section properties token into
+     * PHP code
+     *
+     * @param string $val
+     * @param string $tag_attrs
+     * @return string
+     */
+    function _parse_var_props($val)
+    {
+        $val = trim($val);
+
+        if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
+            // $ variable or object
+            $return = $this->_parse_var($match[1]);
+            $modifiers = $match[2];
+            if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
+                $_default_mod_string = implode('|',(array)$this->default_modifiers);
+                $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
+            }
+            $this->_parse_modifiers($return, $modifiers);
+            return $return;
+        } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // double quoted text
+                preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                $return = $this->_expand_quoted_text($match[1]);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($return, $match[2]);
+                }
+                return $return;
+            }
+        elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // numerical constant
+                preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // single quoted text
+                preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // config var
+                return $this->_parse_conf_var($val);
+            }
+        elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // section var
+                return $this->_parse_section_prop($val);
+            }
+        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
+            // literal string
+            return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
+        }
+        return $val;
+    }
+
+    /**
+     * expand quoted text with embedded variables
+     *
+     * @param string $var_expr
+     * @return string
+     */
+    function _expand_quoted_text($var_expr)
+    {
+        // if contains unescaped $, expand it
+        if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
+            $_match = $_match[0];
+            $_replace = array();
+            foreach($_match as $_var) {
+                $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
+            }
+            $var_expr = strtr($var_expr, $_replace);
+            $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
+        } else {
+            $_return = $var_expr;
+        }
+        // replace double quoted literal string with single quotes
+        $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
+        return $_return;
+    }
+
+    /**
+     * parse variable expression into PHP code
+     *
+     * @param string $var_expr
+     * @param string $output
+     * @return string
+     */
+    function _parse_var($var_expr)
+    {
+        $_has_math = false;
+        $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+        if(count($_math_vars) > 1) {
+            $_first_var = "";
+            $_complete_var = "";
+            $_output = "";
+            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
+            foreach($_math_vars as $_k => $_math_var) {
+                $_math_var = $_math_vars[$_k];
+
+                if(!empty($_math_var) || is_numeric($_math_var)) {
+                    // hit a math operator, so process the stuff which came before it
+                    if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
+                        $_has_math = true;
+                        if(!empty($_complete_var) || is_numeric($_complete_var)) {
+                            $_output .= $this->_parse_var($_complete_var);
+                        }
+
+                        // just output the math operator to php
+                        $_output .= $_math_var;
+
+                        if(empty($_first_var))
+                            $_first_var = $_complete_var;
+
+                        $_complete_var = "";
+                    } else {
+                        $_complete_var .= $_math_var;
+                    }
+                }
+            }
+            if($_has_math) {
+                if(!empty($_complete_var) || is_numeric($_complete_var))
+                    $_output .= $this->_parse_var($_complete_var);
+
+                // get the modifiers working (only the last var from math + modifier is left)
+                $var_expr = $_complete_var;
+            }
+        }
+
+        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
+        if(is_numeric(substr($var_expr, 0, 1)))
+            $_var_ref = $var_expr;
+        else
+            $_var_ref = substr($var_expr, 1);
+        
+        if(!$_has_math) {
+            
+            // get [foo] and .foo and ->foo and (...) pieces
+            preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
+                        
+            $_indexes = $match[0];
+            $_var_name = array_shift($_indexes);
+
+            /* Handle $smarty.* variable references as a special case. */
+            if ($_var_name == 'smarty') {
+                /*
+                 * If the reference could be compiled, use the compiled output;
+                 * otherwise, fall back on the $smarty variable generated at
+                 * run-time.
+                 */
+                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
+                    $_output = $smarty_ref;
+                } else {
+                    $_var_name = substr(array_shift($_indexes), 1);
+                    $_output = "\$this->_smarty_vars['$_var_name']";
+                }
+            } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
+                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
+                if(count($_indexes) > 0)
+                {
+                    $_var_name .= implode("", $_indexes);
+                    $_indexes = array();
+                }
+                $_output = $_var_name;
+            } else {
+                $_output = "\$this->_tpl_vars['$_var_name']";
+            }
+
+            foreach ($_indexes as $_index) {
+                if (substr($_index, 0, 1) == '[') {
+                    $_index = substr($_index, 1, -1);
+                    if (is_numeric($_index)) {
+                        $_output .= "[$_index]";
+                    } elseif (substr($_index, 0, 1) == '$') {
+                        if (strpos($_index, '.') !== false) {
+                            $_output .= '[' . $this->_parse_var($_index) . ']';
+                        } else {
+                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
+                        }
+                    } else {
+                        $_var_parts = explode('.', $_index);
+                        $_var_section = $_var_parts[0];
+                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
+                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
+                    }
+                } else if (substr($_index, 0, 1) == '.') {
+                    if (substr($_index, 1, 1) == '$')
+                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
+                    else
+                        $_output .= "['" . substr($_index, 1) . "']";
+                } else if (substr($_index,0,2) == '->') {
+                    if(substr($_index,2,2) == '__') {
+                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif($this->security && substr($_index, 2, 1) == '_') {
+                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif (substr($_index, 2, 1) == '$') {
+                        if ($this->security) {
+                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                        } else {
+                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
+                        }
+                    } else {
+                        $_output .= $_index;
+                    }
+                } elseif (substr($_index, 0, 1) == '(') {
+                    $_index = $this->_parse_parenth_args($_index);
+                    $_output .= $_index;
+                } else {
+                    $_output .= $_index;
+                }
+            }
+        }
+
+        return $_output;
+    }
+
+    /**
+     * parse arguments in function call parenthesis
+     *
+     * @param string $parenth_args
+     * @return string
+     */
+    function _parse_parenth_args($parenth_args)
+    {
+        preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
+        $orig_vals = $match = $match[0];
+        $this->_parse_vars_props($match);
+        $replace = array();
+        for ($i = 0, $count = count($match); $i < $count; $i++) {
+            $replace[$orig_vals[$i]] = $match[$i];
+        }
+        return strtr($parenth_args, $replace);
+    }
+
+    /**
+     * parse configuration variable expression into PHP code
+     *
+     * @param string $conf_var_expr
+     */
+    function _parse_conf_var($conf_var_expr)
+    {
+        $parts = explode('|', $conf_var_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        $var_name = substr($var_ref, 1, -1);
+
+        $output = "\$this->_config[0]['vars']['$var_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+    /**
+     * parse section property expression into PHP code
+     *
+     * @param string $section_prop_expr
+     * @return string
+     */
+    function _parse_section_prop($section_prop_expr)
+    {
+        $parts = explode('|', $section_prop_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
+        $section_name = $match[1];
+        $prop_name = $match[2];
+
+        $output = "\$this->_sections['$section_name']['$prop_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+
+    /**
+     * parse modifier chain into PHP code
+     *
+     * sets $output to parsed modified chain
+     * @param string $output
+     * @param string $modifier_string
+     */
+    function _parse_modifiers(&$output, $modifier_string)
+    {
+        preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
+        list(, $_modifiers, $modifier_arg_strings) = $_match;
+
+        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
+            $_modifier_name = $_modifiers[$_i];
+
+            if($_modifier_name == 'smarty') {
+                // skip smarty modifier
+                continue;
+            }
+
+            preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
+            $_modifier_args = $_match[1];
+
+            if (substr($_modifier_name, 0, 1) == '@') {
+                $_map_array = false;
+                $_modifier_name = substr($_modifier_name, 1);
+            } else {
+                $_map_array = true;
+            }
+
+            if (empty($this->_plugins['modifier'][$_modifier_name])
+                && !$this->_get_plugin_filepath('modifier', $_modifier_name)
+                && function_exists($_modifier_name)) {
+                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
+                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+                } else {
+                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);
+                }
+            }
+            $this->_add_plugin('modifier', $_modifier_name);
+
+            $this->_parse_vars_props($_modifier_args);
+
+            if($_modifier_name == 'default') {
+                // supress notifications of default modifier vars and args
+                if(substr($output, 0, 1) == '$') {
+                    $output = '@' . $output;
+                }
+                if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
+                    $_modifier_args[0] = '@' . $_modifier_args[0];
+                }
+            }
+            if (count($_modifier_args) > 0)
+                $_modifier_args = ', '.implode(', ', $_modifier_args);
+            else
+                $_modifier_args = '';
+
+            if ($_map_array) {
+                $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
+
+            } else {
+
+                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
+
+            }
+        }
+    }
+
+
+    /**
+     * add plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @param boolean? $delayed_loading
+     */
+    function _add_plugin($type, $name, $delayed_loading = null)
+    {
+        if (!isset($this->_plugin_info[$type])) {
+            $this->_plugin_info[$type] = array();
+        }
+        if (!isset($this->_plugin_info[$type][$name])) {
+            $this->_plugin_info[$type][$name] = array($this->_current_file,
+                                                      $this->_current_line_no,
+                                                      $delayed_loading);
+        }
+    }
+
+
+    /**
+     * Compiles references of type $smarty.foo
+     *
+     * @param string $indexes
+     * @return string
+     */
+    function _compile_smarty_ref(&$indexes)
+    {
+        /* Extract the reference name. */
+        $_ref = substr($indexes[0], 1);
+        foreach($indexes as $_index_no=>$_index) {
+            if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
+                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        switch ($_ref) {
+            case 'now':
+                $compiled_ref = 'time()';
+                $_max_index = 1;
+                break;
+
+            case 'foreach':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $_propname = substr($indexes[1], 1);
+                $_max_index = 1;
+                switch ($_propname) {
+                    case 'index':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
+                        break;
+                        
+                    case 'first':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
+                        break;
+
+                    case 'last':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
+                        break;
+                        
+                    case 'show':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
+                        break;
+                        
+                    default:
+                        unset($_max_index);
+                        $compiled_ref = "\$this->_foreach[$_var]";
+                }
+                break;
+
+            case 'section':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $compiled_ref = "\$this->_sections[$_var]";
+                break;
+
+            case 'get':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";
+                break;
+
+            case 'post':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";
+                break;
+
+            case 'cookies':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";
+                break;
+
+            case 'env':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";
+                break;
+
+            case 'server':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";
+                break;
+
+            case 'session':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";
+                break;
+
+            /*
+             * These cases are handled either at run-time or elsewhere in the
+             * compiler.
+             */
+            case 'request':
+                if ($this->request_use_auto_globals) {
+                    $compiled_ref = '$_REQUEST';
+                    break;
+                } else {
+                    $this->_init_smarty_vars = true;
+                }
+                return null;
+
+            case 'capture':
+                return null;
+
+            case 'template':
+                $compiled_ref = "'$this->_current_file'";
+                $_max_index = 1;
+                break;
+
+            case 'version':
+                $compiled_ref = "'$this->_version'";
+                $_max_index = 1;
+                break;
+
+            case 'const':
+                if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
+                    $this->_syntax_error("(secure mode) constants not permitted",
+                                         E_USER_WARNING, __FILE__, __LINE__);
+                    return;
+                }
+                array_shift($indexes);
+                if (preg_match('!^\.\w+$!', $indexes[0])) {
+                    $compiled_ref = '@' . substr($indexes[0], 1);
+                } else {
+                    $_val = $this->_parse_var_props(substr($indexes[0], 1));
+                    $compiled_ref = '@constant(' . $_val . ')';
+                }
+                $_max_index = 1;
+                break;
+
+            case 'config':
+                $compiled_ref = "\$this->_config[0]['vars']";
+                $_max_index = 3;
+                break;
+
+            case 'ldelim':
+                $compiled_ref = "'$this->left_delimiter'";
+                break;
+
+            case 'rdelim':
+                $compiled_ref = "'$this->right_delimiter'";
+                break;
+                
+            default:
+                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if (isset($_max_index) && count($indexes) > $_max_index) {
+            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        array_shift($indexes);
+        return $compiled_ref;
+    }
+
+    /**
+     * compiles call to plugin of type $type with name $name
+     * returns a string containing the function-name or method call
+     * without the paramter-list that would have follow to make the
+     * call valid php-syntax
+     *
+     * @param string $type
+     * @param string $name
+     * @return string
+     */
+    function _compile_plugin_call($type, $name) {
+        if (isset($this->_plugins[$type][$name])) {
+            /* plugin loaded */
+            if (is_array($this->_plugins[$type][$name][0])) {
+                return ((is_object($this->_plugins[$type][$name][0][0])) ?
+                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */
+                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */
+                       ). $this->_plugins[$type][$name][0][1];
+
+            } else {
+                /* function callback */
+                return $this->_plugins[$type][$name][0];
+
+            }
+        } else {
+            /* plugin not loaded -> auto-loadable-plugin */
+            return 'smarty_'.$type.'_'.$name;
+
+        }
+    }
+
+    /**
+     * load pre- and post-filters
+     */
+    function _load_filters()
+    {
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) {
+                    unset($this->_plugins['prefilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) {
+                    unset($this->_plugins['postfilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Quote subpattern references
+     *
+     * @param string $string
+     * @return string
+     */
+    function _quote_replace($string)
+    {
+        return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
+    }
+
+    /**
+     * display Smarty syntax error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     * @param string $file
+     * @param integer $line
+     */
+    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
+    {
+        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
+    }
+
+
+    /**
+     * check if the compilation changes from cacheable to
+     * non-cacheable state with the beginning of the current
+     * plugin. return php-code to reflect the transition.
+     * @return string
+     */
+    function _push_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || 0<$this->_cacheable_state++) return '';
+        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
+        $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
+            . $this->_cache_serial . '#' . $this->_nocache_count
+            . '}\'; endif;';
+        return $_ret;
+    }
+
+
+    /**
+     * check if the compilation changes from non-cacheable to
+     * cacheable state with the end of the current plugin return
+     * php-code to reflect the transition.
+     * @return string
+     */
+    function _pop_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || --$this->_cacheable_state>0) return '';
+        return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
+            . $this->_cache_serial . '#' . ($this->_nocache_count++)
+            . '}\'; endif;';
+    }
+
+
+    /**
+     * push opening tag-name, file-name and line-number on the tag-stack
+     * @param string the opening tag's name
+     */
+    function _push_tag($open_tag)
+    {
+        array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
+    }
+
+    /**
+     * pop closing tag-name
+     * raise an error if this stack-top doesn't match with the closing tag
+     * @param string the closing tag's name
+     * @return string the opening tag's name
+     */
+    function _pop_tag($close_tag)
+    {
+        $message = '';
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
+            if ($close_tag == $_open_tag) {
+                return $_open_tag;
+            }
+            if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
+                return $this->_pop_tag($close_tag);
+            }
+            if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($_open_tag == 'else' || $_open_tag == 'elseif') {
+                $_open_tag = 'if';
+            } elseif ($_open_tag == 'sectionelse') {
+                $_open_tag = 'section';
+            } elseif ($_open_tag == 'foreachelse') {
+                $_open_tag = 'foreach';
+            }
+            $message = " expected {/$_open_tag} (opened line $_line_no).";
+        }
+        $this->_syntax_error("mismatched tag {/$close_tag}.$message",
+                             E_USER_ERROR, __FILE__, __LINE__);
+    }
+
+}
+
+/**
+ * compare to values by their string length
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return 0|-1|1
+ */
+function _smarty_sort_length($a, $b)
+{
+    if($a == $b)
+        return 0;
+
+    if(strlen($a) == strlen($b))
+        return ($a > $b) ? -1 : 1;
+
+    return (strlen($a) > strlen($b)) ? -1 : 1;
+}
+
+
+/* vim: set et: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/debug.tpl
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/debug.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/debug.tpl	(revision 795)
@@ -0,0 +1,157 @@
+{* Smarty *}
+{* debug.tpl, last updated version 2.1.0 *}
+{assign_debug_info}
+{capture assign=debug_output}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+    <title>Smarty Debug Console</title>
+{literal}
+<style type="text/css">
+/* <![CDATA[ */
+body, h1, h2, td, th, p {
+    font-family: sans-serif;
+    font-weight: normal;
+    font-size: 0.9em;
+    margin: 1px;
+    padding: 0;
+}
+
+h1 {
+    margin: 0;
+    text-align: left;
+    padding: 2px;
+    background-color: #f0c040;
+    color:  black;
+    font-weight: bold;
+    font-size: 1.2em;
+ }
+
+h2 {
+    background-color: #9B410E;
+    color: white;
+    text-align: left;
+    font-weight: bold;
+    padding: 2px;
+    border-top: 1px solid black;
+}
+
+body {
+    background: black; 
+}
+
+p, table, div {
+    background: #f0ead8;
+} 
+
+p {
+    margin: 0;
+    font-style: italic;
+    text-align: center;
+}
+
+table {
+    width: 100%;
+}
+
+th, td {
+    font-family: monospace;
+    vertical-align: top;
+    text-align: left;
+    width: 50%;
+}
+
+td {
+    color: green;
+}
+
+.odd {
+    background-color: #eeeeee;
+}
+
+.even {
+    background-color: #fafafa;
+}
+
+.exectime {
+    font-size: 0.8em;
+    font-style: italic;
+}
+
+#table_assigned_vars th {
+    color: blue;
+}
+
+#table_config_vars th {
+    color: maroon;
+}
+/* ]]> */
+</style>
+{/literal}
+</head>
+<body>
+
+<h1>Smarty Debug Console</h1>
+
+<h2>included templates &amp; config files (load time in seconds)</h2>
+
+<div>
+{section name=templates loop=$_debug_tpls}
+    {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
+    <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
+        {$_debug_tpls[templates].filename|escape:html}</font>
+    {if isset($_debug_tpls[templates].exec_time)}
+        <span class="exectime">
+        ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
+        {if %templates.index% eq 0}(total){/if}
+        </span>
+    {/if}
+    <br />
+{sectionelse}
+    <p>no templates included</p>
+{/section}
+</div>
+
+<h2>assigned template variables</h2>
+
+<table id="table_assigned_vars">
+    {section name=vars loop=$_debug_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
+            <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no template variables assigned</p></td></tr>
+    {/section}
+</table>
+
+<h2>assigned config file variables (outer template scope)</h2>
+
+<table id="table_config_vars">
+    {section name=config_vars loop=$_debug_config_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
+            <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no config vars assigned</p></td></tr>
+    {/section}
+</table>
+</body>
+</html>
+{/capture}
+{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
+    {$debug_output}
+{else}
+<script type="text/javascript">
+// <![CDATA[
+    if ( self.name == '' ) {ldelim}
+       var title = 'Console';
+    {rdelim}
+    else {ldelim}
+       var title = 'Console_' + self.name;
+    {rdelim}
+    _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
+    _smarty_console.document.write('{$debug_output|escape:'javascript'}');
+    _smarty_console.document.close();
+// ]]>
+</script>
+{/if}
Index: /sandbox/workflow/branches/993/inc/smarty/module_plugins/function.wf_calendar.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/module_plugins/function.wf_calendar.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/module_plugins/function.wf_calendar.php	(revision 795)
@@ -0,0 +1,278 @@
+<?php
+/**
+ * Interface to jscalendar-1.0
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @author   boots
+ * @author   Sidnei Augusto Drovetto Junior
+ * @version  1.1.2
+ * @link http://www.dynarch.com/projects/calendar/ {dhtml calendar}
+ *          (dynarch.com)
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @param array $params Parameters array Following is the complete list of properties interpreted by Calendar.setup.
+ * All of them have default values, so you can pass only those which you would like
+ * to customize.
+ * - Required: popup (inputField, displayArea, button), flat (flat)
+ * - inputField string null The ID of your input field.
+ * - displayArea string null
+ *    This is the ID of a <span>, <div>, or any other element that you would like
+ *    to use to display the current date. This is generally useful only if the
+ *    input field is hidden, as an area to display the date.
+ * - button string null The ID of the calendar "trigger". This is an element (ordinarily a button or
+ *    an image) that will dispatch a certain event (usually "click") to the function that creates and displays the calendar.
+ *
+ * - eventName string "click" The name of the event that will trigger the calendar. The name should be
+ *    without the "on" prefix, such as "click" instead of "onclick". Virtually
+ *    all users will want to let this have the default value ("click"). Anyway,
+ *    it could be useful if, say, you want the calendar to appear when the input
+ *    field is focused and have no trigger button (in this case use "focus" as the
+ *    event name).
+ *
+ * - ifFormat string "%Y/%m/%d"
+ *   The format string that will be used to enter the date in the input field.
+ *   This format will be honored even if the input field is hidden.
+ *
+ * - daFormat string "%Y/%m/%d"
+ *   Format of the date displayed in the displayArea (if specified).
+ *
+ * - singleClick boolean true
+ *   Wether the calendar is in "single-click mode" or "double-click mode". If
+ *   true (the default) the calendar will be created in single-click mode.
+ *
+ * - disableFunc function null
+ *   A function that receives a JS Date object. It should return true if that
+ *   date has to be disabled, false otherwise. DEPRECATED (see below).
+ *
+ * - dateStatusFunc function null
+ *   A function that receives a JS Date object and returns a boolean or a string.
+ *   This function allows one to set a certain CSS class to some date, therefore
+ *   making it look different. If it returns true then the date will be disabled.
+ *   If it returns false nothing special happens with the given date. If it
+ *   returns a string then that will be taken as a CSS class and appended to the
+ *   date element. If this string is "disabled" then the date is also disabled
+ *   (therefore is like returning true). For more information please also refer
+ *   to section 4.3.8.
+ *
+ * - firstDay integer 0
+ *   Specifies which day is to be displayed as the first day of week. Possible
+ *   values are 0 to 6; 0 means Sunday, 1 means Monday, ..., 6 means Saturday.
+ *   The end user can easily change this too, by clicking on the day name in the
+ *   calendar header.
+ *
+ * - weekNumbers boolean true
+ *   If "true" then the calendar will display week numbers.
+ *
+ * - align string "Bl"
+ *   Alignment of the calendar, relative to the reference element. The reference
+ *   element is dynamically chosen like this: if a displayArea is specified then
+ *   it will be the reference element. Otherwise, the input field is the
+ *   reference element. For the meaning of the alignment characters please
+ *   section 4.3.11.
+ *
+ * - range array [1900, 2999]
+ *   An array having exactly 2 elements, integers. (!) The first [0] element is
+ *   the minimum year that is available, and the second [1] element is the
+ *   maximum year that the calendar will allow.
+ *
+ * - flat string null
+ *   If you want a flat calendar, pass the ID of the parent object in this
+ *   property. If not, pass null here (or nothing at all as null is the default
+ *   value).
+ *
+ * - flatCallback function null
+ *   You should provide this function if the calendar is flat. It will be called
+ *   when the date in the calendar is changed with a reference to the calendar
+ *   object. See section 2.2 for an example of how to setup a flat calendar.
+ *
+ * - onSelect function null
+ *   If you provide a function handler here then you have to manage the
+ *   "click-on-date" event by yourself. Look in the calendar-setup.js and take as
+ *   an example the onSelect handler that you can see there.
+ *
+ * - onClose function null
+ *   This handler will be called when the calendar needs to close. You don't need
+ *   to provide one, but if you do it's your responsibility to hide/destroy the
+ *   calendar. You're on your own. Check the calendar-setup.js file for an
+ *   example.
+ *
+ * - onUpdate function null
+ *   If you supply a function handler here, it will be called right after the
+ *   target field is updated with a new date. You can use this to chain 2
+ *   calendars, for instance to setup a default date in the second just after a
+ *   date was selected in the first.
+ *
+ * - date date null
+ *   This allows you to setup an initial date where the calendar will be
+ *   positioned to. If absent then the calendar will open to the today date.
+ *
+ * - showsTime boolean false
+ *     If this is set to true then the calendar will also allow time selection.
+ *
+ * - timeFormat string "24"
+ *   Set this to "12" or "24" to configure the way that the calendar will display
+ *   time.
+ *
+ * - electric boolean true
+ *   Set this to "false" if you want the calendar to update the field only when
+ *   closed (by default it updates the field at each date change, even if the
+ *   calendar is not closed)
+ *
+ * - position array null
+ *   Specifies the [x, y] position, relative to page's top-left corner, where the
+ *   calendar will be displayed. If not passed then the position will be computed
+ *   based on the "align" parameter. Defaults to "null" (not used).
+ *
+ * - cache boolean false
+ *   Set this to "true" if you want to cache the calendar object. This means that
+ *   a single calendar object will be used for all fields that require a popup
+ *   calendar
+ *
+ * - showOthers boolean false
+ *   If set to "true" then days belonging to months overlapping with the
+ *   currently displayed month will also be displayed in the calendar (but in a
+ *   "faded-out" color)
+ * @access public
+ * @return string código com os parametros de configuração a serem passados ao Calendar.setup
+ */
+function smarty_function_wf_calendar($params, &$smarty)
+{
+	static $requires = array(
+		'flat' => 'string',
+		'inputField' => 'string',
+		'displayArea' => 'string',
+		'button' => 'string'
+	);
+
+	static $allowed = array(
+		'date' => 'date',
+		'eventName' => 'string',
+		'cache' => 'boolean',
+		'multiple' => 'boolean',
+		'singleClick' => 'boolean',
+		'electric' => 'boolean',
+		'position' => 'array',
+		'align' => 'string',
+		'firstDay' => 'integer',
+		'weekNumbers' => 'boolean',
+		'range' => 'array',
+		'showOthers' => 'boolean',
+		'showsTime' => 'boolean',
+		'timeFormat' => 'string',
+		'ifFormat' => 'string',
+		'daFormat' => 'string',
+		'flatCallback' => 'function',
+		'dateStatusFunc' => 'function',
+		'dateTest' => 'function',
+		'onSelect' => 'function',
+		'onClose' => 'function',
+		'onUpdate' => 'function',
+		'name' => 'stromg',
+		'default' => 'boolean',
+		'value' => 'string'
+	);
+
+	$output = '';
+
+	$path = $_SESSION['phpgw_info']['workflow']['server']['webserver_url'] . '/workflow/js/jscalendar/';
+	if (isset($params['path']))
+		$path = $params['path'] . '/';
+
+	$defaults = array(
+		'css' => $path . 'calendar-blue.css',
+		'src' => $path . 'calendar.js',
+		'lang' => $path . 'calendar-br.js',
+		'setup_src' => $path . 'calendar-setup.js',
+		'input_format' => $path . 'calendar-input.js');
+
+	foreach ($defaults as $field => $default)
+	{
+		$_field = "_{$field}";
+		if (array_key_exists($field, $params))
+			$$_field = (empty($params[$field])) ? $default : $params[$field];
+		else
+			$$_field = $default;
+	}
+
+	static $wf_calendarJS = true;
+
+	if ($wf_calendarJS)
+		$output .= <<<EOF
+		<link rel="stylesheet" type="text/css" media="all" href="{$_css}">
+		<script type="text/javascript" src="{$_src}"></script>
+		<script type="text/javascript" src="{$_lang}"></script>
+		<script type="text/javascript" src="{$_setup_src}"></script>
+		<script type="text/javascript" src="{$_input_format}"></script>
+EOF;
+	$wf_calendarJS = false;
+
+	static $deprecated = array(
+		'disableFunc' => 'function'
+	);
+
+	static $all = false;
+	if (!$all)
+		$all = array_merge($requires, $allowed, $deprecated);
+
+	$inputFields = "";
+	if (isset($params['default']) && isset($params['name']))
+		if ($params['default'] == true)
+		{
+			$fieldValue = "";
+			if (isset($params['value']))
+				$fieldValue = $params['value'];
+			$params['inputField'] = $params['name'];
+			$params['button'] = $params['name'] . "-trigger";
+			$params['singleClick'] = true;
+			$inputFields = "<input type=\"text\" id=\"" . $params['inputField']  . "\" name=\"" . $params['inputField']  . "\" value=\"" . $fieldValue  . "\" size=\"10\" maxlength=\"10\" onkeypress=\"return(formatCalendarInput(this, event))\" onfocus=\"if (this.value == '$fieldValue') this.value='';\" onblur=\"if (this.value == '') this.value = '$fieldValue';\"/>";
+			$inputFields .= "\n<button id=\"" . $params['button']  . "\">...</button>";
+		}
+
+	$_params = array();
+
+	foreach ($requires as $required => $type)
+	{
+		if (array_key_exists($required, $params) && !empty($params[$required]))
+		{
+			$_params[$required] = $params[$required];
+		}
+	}
+	if (empty($_params))
+	{
+		$smarty->trigger_error("[wf_calendar] missing required parameter(s)", E_USER_ERROR);
+		return false;
+	}
+
+	foreach ($allowed as $field=>$type)
+	{
+		if (array_key_exists($field, $params) && isset($params[$field]))
+		{
+			$_params[$field] = $params[$field];
+		}
+	}
+
+	foreach ($deprecated as $warn=>$type)
+	{
+		if (array_key_exists($warn, $params))
+		{
+			$smarty->trigger_error("[dhtml_calendar] deprecated parameter '$warn'", E_USER_INFO);
+			$_params[$warn] = $params[$warn];
+		}
+	}
+
+	$_params_out = '';
+	foreach ($_params as $field=>$value)
+	{
+		if (is_bool($value))
+			$value = $value ? 'true' : 'false';
+		else
+			if (!is_numeric($value) && !($all[$field] == 'function'))
+				$value = '"'.$value.'"';
+		if ($_params_out)
+			$_params_out .= ',';
+		$_params_out .= '"' . $field . '":' . $value;
+	}
+
+	$output .= $inputFields . '<script type="text/javascript">Calendar.setup({' . $_params_out . '});</script>';
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/Smarty.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/Smarty.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/Smarty.class.php	(revision 795)
@@ -0,0 +1,1960 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-general-subscribe@lists.php.net
+ *
+ * @link http://smarty.php.net/
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @package Smarty
+ * @version 2.6.19
+ */
+
+/* $Id: Smarty.class.php 760 2008-04-03 19:15:17Z drovetto $ */
+
+/**
+ * DIR_SEP isn't used anymore, but third party apps might
+ */
+if(!defined('DIR_SEP')) {
+    define('DIR_SEP', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * if not defined, include_path will be used. Sets SMARTY_DIR only if user
+ * application has not already defined it.
+ */
+
+if (!defined('SMARTY_DIR')) {
+    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+
+if (!defined('SMARTY_CORE_DIR')) {
+    define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
+}
+
+define('SMARTY_PHP_PASSTHRU',   0);
+define('SMARTY_PHP_QUOTE',      1);
+define('SMARTY_PHP_REMOVE',     2);
+define('SMARTY_PHP_ALLOW',      3);
+
+/**
+ * @package Smarty
+ */
+class Smarty
+{
+    /**#@+
+     * Smarty Configuration Section
+     */
+
+    /**
+     * The name of the directory where templates are located.
+     *
+     * @var string
+     */
+    var $template_dir    =  'templates';
+
+    /**
+     * The directory where compiled templates are located.
+     *
+     * @var string
+     */
+    var $compile_dir     =  'templates_c';
+
+    /**
+     * The directory where config files are located.
+     *
+     * @var string
+     */
+    var $config_dir      =  'configs';
+
+    /**
+     * An array of directories searched for plugins.
+     *
+     * @var array
+     */
+    var $plugins_dir     =  array('plugins');
+
+    /**
+     * If debugging is enabled, a debug console window will display
+     * when the page loads (make sure your browser allows unrequested
+     * popup windows)
+     *
+     * @var boolean
+     */
+    var $debugging       =  false;
+
+    /**
+     * When set, smarty does uses this value as error_reporting-level.
+     *
+     * @var boolean
+     */
+    var $error_reporting  =  null;
+
+    /**
+     * This is the path to the debug console template. If not set,
+     * the default one will be used.
+     *
+     * @var string
+     */
+    var $debug_tpl       =  '';
+
+    /**
+     * This determines if debugging is enable-able from the browser.
+     * <ul>
+     *  <li>NONE => no debugging control allowed</li>
+     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+     * </ul>
+     * @link http://www.foo.dom/index.php?SMARTY_DEBUG
+     * @var string
+     */
+    var $debugging_ctrl  =  'NONE';
+
+    /**
+     * This tells Smarty whether to check for recompiling or not. Recompiling
+     * does not need to happen unless a template or config file is changed.
+     * Typically you enable this during development, and disable for
+     * production.
+     *
+     * @var boolean
+     */
+    var $compile_check   =  true;
+
+    /**
+     * This forces templates to compile every time. Useful for development
+     * or debugging.
+     *
+     * @var boolean
+     */
+    var $force_compile   =  false;
+
+    /**
+     * This enables template caching.
+     * <ul>
+     *  <li>0 = no caching</li>
+     *  <li>1 = use class cache_lifetime value</li>
+     *  <li>2 = use cache_lifetime in cache file</li>
+     * </ul>
+     * @var integer
+     */
+    var $caching         =  0;
+
+    /**
+     * The name of the directory for cache files.
+     *
+     * @var string
+     */
+    var $cache_dir       =  'cache';
+
+    /**
+     * This is the number of seconds cached content will persist.
+     * <ul>
+     *  <li>0 = always regenerate cache</li>
+     *  <li>-1 = never expires</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $cache_lifetime  =  3600;
+
+    /**
+     * Only used when $caching is enabled. If true, then If-Modified-Since headers
+     * are respected with cached content, and appropriate HTTP headers are sent.
+     * This way repeated hits to a cached page do not send the entire page to the
+     * client every time.
+     *
+     * @var boolean
+     */
+    var $cache_modified_check = false;
+
+    /**
+     * This determines how Smarty handles "<?php ... ?>" tags in templates.
+     * possible values:
+     * <ul>
+     *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
+     *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
+     *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
+     *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $php_handling    =  SMARTY_PHP_PASSTHRU;
+
+    /**
+     * This enables template security. When enabled, many things are restricted
+     * in the templates that normally would go unchecked. This is useful when
+     * untrusted parties are editing templates and you want a reasonable level
+     * of security. (no direct execution of PHP in templates for example)
+     *
+     * @var boolean
+     */
+    var $security       =   false;
+
+    /**
+     * This is the list of template directories that are considered secure. This
+     * is used only if {@link $security} is enabled. One directory per array
+     * element.  {@link $template_dir} is in this list implicitly.
+     *
+     * @var array
+     */
+    var $secure_dir     =   array();
+
+    /**
+     * These are the security settings for Smarty. They are used only when
+     * {@link $security} is enabled.
+     *
+     * @var array
+     */
+    var $security_settings  = array(
+                                    'PHP_HANDLING'    => false,
+                                    'IF_FUNCS'        => array('array', 'list',
+                                                               'isset', 'empty',
+                                                               'count', 'sizeof',
+                                                               'in_array', 'is_array',
+                                                               'true', 'false', 'null'),
+                                    'INCLUDE_ANY'     => false,
+                                    'PHP_TAGS'        => false,
+                                    'MODIFIER_FUNCS'  => array('count'),
+                                    'ALLOW_CONSTANTS'  => false
+                                   );
+
+    /**
+     * This is an array of directories where trusted php scripts reside.
+     * {@link $security} is disabled during their inclusion/execution.
+     *
+     * @var array
+     */
+    var $trusted_dir        = array();
+
+    /**
+     * The left delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $left_delimiter  =  '{';
+
+    /**
+     * The right delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $right_delimiter =  '}';
+
+    /**
+     * The order in which request variables are registered, similar to
+     * variables_order in php.ini E = Environment, G = GET, P = POST,
+     * C = Cookies, S = Server
+     *
+     * @var string
+     */
+    var $request_vars_order    = 'EGPCS';
+
+    /**
+     * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
+     * are uses as request-vars or $_*[]-vars. note: if
+     * request_use_auto_globals is true, then $request_vars_order has
+     * no effect, but the php-ini-value "gpc_order"
+     *
+     * @var boolean
+     */
+    var $request_use_auto_globals      = true;
+
+    /**
+     * Set this if you want different sets of compiled files for the same
+     * templates. This is useful for things like different languages.
+     * Instead of creating separate sets of templates per language, you
+     * set different compile_ids like 'en' and 'de'.
+     *
+     * @var string
+     */
+    var $compile_id            = null;
+
+    /**
+     * This tells Smarty whether or not to use sub dirs in the cache/ and
+     * templates_c/ directories. sub directories better organized, but
+     * may not work well with PHP safe mode enabled.
+     *
+     * @var boolean
+     *
+     */
+    var $use_sub_dirs          = false;
+
+    /**
+     * This is a list of the modifiers to apply to all template variables.
+     * Put each modifier in a separate array element in the order you want
+     * them applied. example: <code>array('escape:"htmlall"');</code>
+     *
+     * @var array
+     */
+    var $default_modifiers        = array();
+
+    /**
+     * This is the resource type to be used when not specified
+     * at the beginning of the resource path. examples:
+     * $smarty->display('file:index.tpl');
+     * $smarty->display('db:index.tpl');
+     * $smarty->display('index.tpl'); // will use default resource type
+     * {include file="file:index.tpl"}
+     * {include file="db:index.tpl"}
+     * {include file="index.tpl"} {* will use default resource type *}
+     *
+     * @var array
+     */
+    var $default_resource_type    = 'file';
+
+    /**
+     * The function used for cache file handling. If not set, built-in caching is used.
+     *
+     * @var null|string function name
+     */
+    var $cache_handler_func   = null;
+
+    /**
+     * This indicates which filters are automatically loaded into Smarty.
+     *
+     * @var array array of filter names
+     */
+    var $autoload_filters = array();
+
+    /**#@+
+     * @var boolean
+     */
+    /**
+     * This tells if config file vars of the same name overwrite each other or not.
+     * if disabled, same name variables are accumulated in an array.
+     */
+    var $config_overwrite = true;
+
+    /**
+     * This tells whether or not to automatically booleanize config file variables.
+     * If enabled, then the strings "on", "true", and "yes" are treated as boolean
+     * true, and "off", "false" and "no" are treated as boolean false.
+     */
+    var $config_booleanize = true;
+
+    /**
+     * This tells whether hidden sections [.foobar] are readable from the
+     * tempalates or not. Normally you would never allow this since that is
+     * the point behind hidden sections: the application can access them, but
+     * the templates cannot.
+     */
+    var $config_read_hidden = false;
+
+    /**
+     * This tells whether or not automatically fix newlines in config files.
+     * It basically converts \r (mac) or \r\n (dos) to \n
+     */
+    var $config_fix_newlines = true;
+    /**#@-*/
+
+    /**
+     * If a template cannot be found, this PHP function will be executed.
+     * Useful for creating templates on-the-fly or other special action.
+     *
+     * @var string function name
+     */
+    var $default_template_handler_func = '';
+
+    /**
+     * The file that contains the compiler class. This can a full
+     * pathname, or relative to the php_include path.
+     *
+     * @var string
+     */
+    var $compiler_file        =    'Smarty_Compiler.class.php';
+
+    /**
+     * The class used for compiling templates.
+     *
+     * @var string
+     */
+    var $compiler_class        =   'Smarty_Compiler';
+
+    /**
+     * The class used to load config vars.
+     *
+     * @var string
+     */
+    var $config_class          =   'Config_File';
+
+/**#@+
+ * END Smarty Configuration Section
+ * There should be no need to touch anything below this line.
+ * @access private
+ */
+    /**
+     * where assigned template vars are kept
+     *
+     * @var array
+     */
+    var $_tpl_vars             = array();
+
+    /**
+     * stores run-time $smarty.* vars
+     *
+     * @var null|array
+     */
+    var $_smarty_vars          = null;
+
+    /**
+     * keeps track of sections
+     *
+     * @var array
+     */
+    var $_sections             = array();
+
+    /**
+     * keeps track of foreach blocks
+     *
+     * @var array
+     */
+    var $_foreach              = array();
+
+    /**
+     * keeps track of tag hierarchy
+     *
+     * @var array
+     */
+    var $_tag_stack            = array();
+
+    /**
+     * configuration object
+     *
+     * @var Config_file
+     */
+    var $_conf_obj             = null;
+
+    /**
+     * loaded configuration settings
+     *
+     * @var array
+     */
+    var $_config               = array(array('vars'  => array(), 'files' => array()));
+
+    /**
+     * md5 checksum of the string 'Smarty'
+     *
+     * @var string
+     */
+    var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
+
+    /**
+     * Smarty version number
+     *
+     * @var string
+     */
+    var $_version              = '2.6.19';
+
+    /**
+     * current template inclusion depth
+     *
+     * @var integer
+     */
+    var $_inclusion_depth      = 0;
+
+    /**
+     * for different compiled templates
+     *
+     * @var string
+     */
+    var $_compile_id           = null;
+
+    /**
+     * text in URL to enable debug mode
+     *
+     * @var string
+     */
+    var $_smarty_debug_id      = 'SMARTY_DEBUG';
+
+    /**
+     * debugging information for debug console
+     *
+     * @var array
+     */
+    var $_smarty_debug_info    = array();
+
+    /**
+     * info that makes up a cache file
+     *
+     * @var array
+     */
+    var $_cache_info           = array();
+
+    /**
+     * default file permissions
+     *
+     * @var integer
+     */
+    var $_file_perms           = 0664;
+
+    /**
+     * default dir permissions
+     *
+     * @var integer
+     */
+    var $_dir_perms               = 0771;
+
+    /**
+     * registered objects
+     *
+     * @var array
+     */
+    var $_reg_objects           = array();
+
+    /**
+     * table keeping track of plugins
+     *
+     * @var array
+     */
+    var $_plugins              = array(
+                                       'modifier'      => array(),
+                                       'function'      => array(),
+                                       'block'         => array(),
+                                       'compiler'      => array(),
+                                       'prefilter'     => array(),
+                                       'postfilter'    => array(),
+                                       'outputfilter'  => array(),
+                                       'resource'      => array(),
+                                       'insert'        => array());
+
+
+    /**
+     * cache serials
+     *
+     * @var array
+     */
+    var $_cache_serials = array();
+
+    /**
+     * name of optional cache include file
+     *
+     * @var string
+     */
+    var $_cache_include = null;
+
+    /**
+     * indicate if the current code is used in a compiled
+     * include
+     *
+     * @var string
+     */
+    var $_cache_including = false;
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty()
+    {
+      $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
+                    : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
+    }
+
+    /**
+     * assigns values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to assign
+     */
+    function assign($tpl_var, $value = null)
+    {
+        if (is_array($tpl_var)){
+            foreach ($tpl_var as $key => $val) {
+                if ($key != '') {
+                    $this->_tpl_vars[$key] = $val;
+                }
+            }
+        } else {
+            if ($tpl_var != '')
+                $this->_tpl_vars[$tpl_var] = $value;
+        }
+    }
+
+    /**
+     * assigns values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to assign
+     */
+    function assign_by_ref($tpl_var, &$value)
+    {
+        if ($tpl_var != '')
+            $this->_tpl_vars[$tpl_var] = &$value;
+    }
+
+    /**
+     * appends values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to append
+     */
+    function append($tpl_var, $value=null, $merge=false)
+    {
+        if (is_array($tpl_var)) {
+            // $tpl_var is an array, ignore $value
+            foreach ($tpl_var as $_key => $_val) {
+                if ($_key != '') {
+                    if(!@is_array($this->_tpl_vars[$_key])) {
+                        settype($this->_tpl_vars[$_key],'array');
+                    }
+                    if($merge && is_array($_val)) {
+                        foreach($_val as $_mkey => $_mval) {
+                            $this->_tpl_vars[$_key][$_mkey] = $_mval;
+                        }
+                    } else {
+                        $this->_tpl_vars[$_key][] = $_val;
+                    }
+                }
+            }
+        } else {
+            if ($tpl_var != '' && isset($value)) {
+                if(!@is_array($this->_tpl_vars[$tpl_var])) {
+                    settype($this->_tpl_vars[$tpl_var],'array');
+                }
+                if($merge && is_array($value)) {
+                    foreach($value as $_mkey => $_mval) {
+                        $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
+                    }
+                } else {
+                    $this->_tpl_vars[$tpl_var][] = $value;
+                }
+            }
+        }
+    }
+
+    /**
+     * appends values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to append
+     */
+    function append_by_ref($tpl_var, &$value, $merge=false)
+    {
+        if ($tpl_var != '' && isset($value)) {
+            if(!@is_array($this->_tpl_vars[$tpl_var])) {
+             settype($this->_tpl_vars[$tpl_var],'array');
+            }
+            if ($merge && is_array($value)) {
+                foreach($value as $_key => $_val) {
+                    $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
+                }
+            } else {
+                $this->_tpl_vars[$tpl_var][] = &$value;
+            }
+        }
+    }
+
+
+    /**
+     * clear the given assigned template variable.
+     *
+     * @param string $tpl_var the template variable to clear
+     */
+    function clear_assign($tpl_var)
+    {
+        if (is_array($tpl_var))
+            foreach ($tpl_var as $curr_var)
+                unset($this->_tpl_vars[$curr_var]);
+        else
+            unset($this->_tpl_vars[$tpl_var]);
+    }
+
+
+    /**
+     * Registers custom function to be used in templates
+     *
+     * @param string $function the name of the template function
+     * @param string $function_impl the name of the PHP function to register
+     */
+    function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['function'][$function] =
+            array($function_impl, null, null, false, $cacheable, $cache_attrs);
+
+    }
+
+    /**
+     * Unregisters custom function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_function($function)
+    {
+        unset($this->_plugins['function'][$function]);
+    }
+
+    /**
+     * Registers object to be used in templates
+     *
+     * @param string $object name of template object
+     * @param object &$object_impl the referenced PHP object to register
+     * @param null|array $allowed list of allowed methods (empty = all)
+     * @param boolean $smarty_args smarty argument format, else traditional
+     * @param null|array $block_functs list of methods that are block format
+     */
+    function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+    {
+        settype($allowed, 'array');
+        settype($smarty_args, 'boolean');
+        $this->_reg_objects[$object] =
+            array(&$object_impl, $allowed, $smarty_args, $block_methods);
+    }
+
+    /**
+     * Unregisters object
+     *
+     * @param string $object name of template object
+     */
+    function unregister_object($object)
+    {
+        unset($this->_reg_objects[$object]);
+    }
+
+
+    /**
+     * Registers block function to be used in templates
+     *
+     * @param string $block name of template block
+     * @param string $block_impl PHP function to register
+     */
+    function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['block'][$block] =
+            array($block_impl, null, null, false, $cacheable, $cache_attrs);
+    }
+
+    /**
+     * Unregisters block function
+     *
+     * @param string $block name of template function
+     */
+    function unregister_block($block)
+    {
+        unset($this->_plugins['block'][$block]);
+    }
+
+    /**
+     * Registers compiler function
+     *
+     * @param string $function name of template function
+     * @param string $function_impl name of PHP function to register
+     */
+    function register_compiler_function($function, $function_impl, $cacheable=true)
+    {
+        $this->_plugins['compiler'][$function] =
+            array($function_impl, null, null, false, $cacheable);
+    }
+
+    /**
+     * Unregisters compiler function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_compiler_function($function)
+    {
+        unset($this->_plugins['compiler'][$function]);
+    }
+
+    /**
+     * Registers modifier to be used in templates
+     *
+     * @param string $modifier name of template modifier
+     * @param string $modifier_impl name of PHP function to register
+     */
+    function register_modifier($modifier, $modifier_impl)
+    {
+        $this->_plugins['modifier'][$modifier] =
+            array($modifier_impl, null, null, false);
+    }
+
+    /**
+     * Unregisters modifier
+     *
+     * @param string $modifier name of template modifier
+     */
+    function unregister_modifier($modifier)
+    {
+        unset($this->_plugins['modifier'][$modifier]);
+    }
+
+    /**
+     * Registers a resource to fetch a template
+     *
+     * @param string $type name of resource
+     * @param array $functions array of functions to handle resource
+     */
+    function register_resource($type, $functions)
+    {
+        if (count($functions)==4) {
+            $this->_plugins['resource'][$type] =
+                array($functions, false);
+
+        } elseif (count($functions)==5) {
+            $this->_plugins['resource'][$type] =
+                array(array(array(&$functions[0], $functions[1])
+                            ,array(&$functions[0], $functions[2])
+                            ,array(&$functions[0], $functions[3])
+                            ,array(&$functions[0], $functions[4]))
+                      ,false);
+
+        } else {
+            $this->trigger_error("malformed function-list for '$type' in register_resource");
+
+        }
+    }
+
+    /**
+     * Unregisters a resource
+     *
+     * @param string $type name of resource
+     */
+    function unregister_resource($type)
+    {
+        unset($this->_plugins['resource'][$type]);
+    }
+
+    /**
+     * Registers a prefilter function to apply
+     * to a template before compiling
+     *
+     * @param callback $function
+     */
+    function register_prefilter($function)
+    {
+        $this->_plugins['prefilter'][$this->_get_filter_name($function)]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a prefilter function
+     *
+     * @param callback $function
+     */
+    function unregister_prefilter($function)
+    {
+        unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
+    }
+
+    /**
+     * Registers a postfilter function to apply
+     * to a compiled template after compilation
+     *
+     * @param callback $function
+     */
+    function register_postfilter($function)
+    {
+        $this->_plugins['postfilter'][$this->_get_filter_name($function)]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a postfilter function
+     *
+     * @param callback $function
+     */
+    function unregister_postfilter($function)
+    {
+        unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
+    }
+
+    /**
+     * Registers an output filter function to apply
+     * to a template output
+     *
+     * @param callback $function
+     */
+    function register_outputfilter($function)
+    {
+        $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters an outputfilter function
+     *
+     * @param callback $function
+     */
+    function unregister_outputfilter($function)
+    {
+        unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
+    }
+
+    /**
+     * load a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     */
+    function load_filter($type, $name)
+    {
+        switch ($type) {
+            case 'output':
+                $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
+                require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                smarty_core_load_plugins($_params, $this);
+                break;
+
+            case 'pre':
+            case 'post':
+                if (!isset($this->_plugins[$type . 'filter'][$name]))
+                    $this->_plugins[$type . 'filter'][$name] = false;
+                break;
+        }
+    }
+
+    /**
+     * clear cached content for the given template and cache id
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id name of cache_id
+     * @param string $compile_id name of compile_id
+     * @param string $exp_time expiration time
+     * @return boolean
+     */
+    function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+    {
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        if (!isset($tpl_file))
+            $compile_id = null;
+
+        $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
+
+        if (!empty($this->cache_handler_func)) {
+            return call_user_func_array($this->cache_handler_func,
+                                  array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
+        } else {
+            $_params = array('auto_base' => $this->cache_dir,
+                            'auto_source' => $tpl_file,
+                            'auto_id' => $_auto_id,
+                            'exp_time' => $exp_time);
+            require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+            return smarty_core_rm_auto($_params, $this);
+        }
+
+    }
+
+
+    /**
+     * clear the entire contents of cache (all templates)
+     *
+     * @param string $exp_time expire time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_all_cache($exp_time = null)
+    {
+        return $this->clear_cache(null, null, null, $exp_time);
+    }
+
+
+    /**
+     * test to see if valid cache exists for this template
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|false results of {@link _read_cache_file()}
+     */
+    function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+    {
+        if (!$this->caching)
+            return false;
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        $_params = array(
+            'tpl_file' => $tpl_file,
+            'cache_id' => $cache_id,
+            'compile_id' => $compile_id
+        );
+        require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+        return smarty_core_read_cache_file($_params, $this);
+    }
+
+
+    /**
+     * clear all the assigned template variables.
+     *
+     */
+    function clear_all_assign()
+    {
+        $this->_tpl_vars = array();
+    }
+
+    /**
+     * clears compiled version of specified template resource,
+     * or all compiled template files if one is not specified.
+     * This function is for advanced use only, not normally needed.
+     *
+     * @param string $tpl_file
+     * @param string $compile_id
+     * @param string $exp_time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+    {
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+        $_params = array('auto_base' => $this->compile_dir,
+                        'auto_source' => $tpl_file,
+                        'auto_id' => $compile_id,
+                        'exp_time' => $exp_time,
+                        'extensions' => array('.inc', '.php'));
+        require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+        return smarty_core_rm_auto($_params, $this);
+    }
+
+    /**
+     * Checks whether requested template exists.
+     *
+     * @param string $tpl_file
+     * @return boolean
+     */
+    function template_exists($tpl_file)
+    {
+        $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
+        return $this->_fetch_resource_info($_params);
+    }
+
+    /**
+     * Returns an array containing template variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_template_vars($name=null)
+    {
+        if(!isset($name)) {
+            return $this->_tpl_vars;
+        } elseif(isset($this->_tpl_vars[$name])) {
+            return $this->_tpl_vars[$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;   
+        }
+    }
+
+    /**
+     * Returns an array containing config variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_config_vars($name=null)
+    {
+        if(!isset($name) && is_array($this->_config[0])) {
+            return $this->_config[0]['vars'];
+        } else if(isset($this->_config[0]['vars'][$name])) {
+            return $this->_config[0]['vars'][$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;
+        }
+    }
+
+    /**
+     * trigger Smarty error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     */
+    function trigger_error($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Smarty error: $error_msg", $error_type);
+    }
+
+
+    /**
+     * executes & displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     */
+    function display($resource_name, $cache_id = null, $compile_id = null)
+    {
+        $this->fetch($resource_name, $cache_id, $compile_id, true);
+    }
+
+    /**
+     * executes & returns or displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     * @param boolean $display
+     */
+    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
+    {
+        static $_cache_info = array();
+        
+        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
+               ? $this->error_reporting : error_reporting() & ~E_NOTICE);
+
+        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
+            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+            if (@strstr($_query_string, $this->_smarty_debug_id)) {
+                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
+                    // enable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', true);
+                    $this->debugging = true;
+                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
+                    // disable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', false);
+                    $this->debugging = false;
+                } else {
+                    // enable debugging for this page
+                    $this->debugging = true;
+                }
+            } else {
+                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
+            }
+        }
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                'filename'  => $resource_name,
+                                                'depth'     => 0);
+            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+
+        $this->_compile_id = $compile_id;
+        $this->_inclusion_depth = 0;
+
+        if ($this->caching) {
+            // save old cache_info, initialize cache_info
+            array_push($_cache_info, $this->_cache_info);
+            $this->_cache_info = array();
+            $_params = array(
+                'tpl_file' => $resource_name,
+                'cache_id' => $cache_id,
+                'compile_id' => $compile_id,
+                'results' => null
+            );
+            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+            if (smarty_core_read_cache_file($_params, $this)) {
+                $_smarty_results = $_params['results'];
+                if (!empty($this->_cache_info['insert_tags'])) {
+                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+                }
+                if (!empty($this->_cache_info['cache_serials'])) {
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
+                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
+                }
+
+
+                if ($display) {
+                    if ($this->debugging)
+                    {
+                        // capture time for debugging info
+                        $_params = array();
+                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
+                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
+                    }
+                    if ($this->cache_modified_check) {
+                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
+                        if (@count($this->_cache_info['insert_tags']) == 0
+                            && !$this->_cache_serials
+                            && $_gmt_mtime == $_last_modified_date) {
+                            if (php_sapi_name()=='cgi')
+                                header('Status: 304 Not Modified');
+                            else
+                                header('HTTP/1.1 304 Not Modified');
+
+                        } else {
+                            header('Last-Modified: '.$_gmt_mtime);
+                            echo $_smarty_results;
+                        }
+                    } else {
+                            echo $_smarty_results;
+                    }
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return true;
+                } else {
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return $_smarty_results;
+                }
+            } else {
+                $this->_cache_info['template'][$resource_name] = true;
+                if ($this->cache_modified_check && $display) {
+                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
+                }
+            }
+        }
+
+        // load filters that are marked as autoload
+        if (count($this->autoload_filters)) {
+            foreach ($this->autoload_filters as $_filter_type => $_filters) {
+                foreach ($_filters as $_filter) {
+                    $this->load_filter($_filter_type, $_filter);
+                }
+            }
+        }
+
+        $_smarty_compile_path = $this->_get_compile_path($resource_name);
+
+        // if we just need to display the results, don't perform output
+        // buffering - for speed
+        $_cache_including = $this->_cache_including;
+        $this->_cache_including = false;
+        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+        } else {
+            ob_start();
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+            $_smarty_results = ob_get_contents();
+            ob_end_clean();
+
+            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
+                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
+            }
+        }
+
+        if ($this->caching) {
+            $_params = array('tpl_file' => $resource_name,
+                        'cache_id' => $cache_id,
+                        'compile_id' => $compile_id,
+                        'results' => $_smarty_results);
+            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
+            smarty_core_write_cache_file($_params, $this);
+            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+
+            if ($this->_cache_serials) {
+                // strip nocache-tags from output
+                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
+                                                ,''
+                                                ,$_smarty_results);
+            }
+            // restore initial cache_info
+            $this->_cache_info = array_pop($_cache_info);
+        }
+        $this->_cache_including = $_cache_including;
+
+        if ($display) {
+            if (isset($_smarty_results)) { echo $_smarty_results; }
+            if ($this->debugging) {
+                // capture time for debugging info
+                $_params = array();
+                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                echo smarty_core_display_debug_console($_params, $this);
+            }
+            error_reporting($_smarty_old_error_level);
+            return;
+        } else {
+            error_reporting($_smarty_old_error_level);
+            if (isset($_smarty_results)) { return $_smarty_results; }
+        }
+    }
+
+    /**
+     * load configuration values
+     *
+     * @param string $file
+     * @param string $section
+     * @param string $scope
+     */
+    function config_load($file, $section = null, $scope = 'global')
+    {
+        require_once($this->_get_plugin_filepath('function', 'config_load'));
+        smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
+    }
+
+    /**
+     * return a reference to a registered object
+     *
+     * @param string $name
+     * @return object
+     */
+    function &get_registered_object($name) {
+        if (!isset($this->_reg_objects[$name]))
+        $this->_trigger_fatal_error("'$name' is not a registered object");
+
+        if (!is_object($this->_reg_objects[$name][0]))
+        $this->_trigger_fatal_error("registered '$name' is not an object");
+
+        return $this->_reg_objects[$name][0];
+    }
+
+    /**
+     * clear configuration values
+     *
+     * @param string $var
+     */
+    function clear_config($var = null)
+    {
+        if(!isset($var)) {
+            // clear all values
+            $this->_config = array(array('vars'  => array(),
+                                         'files' => array()));
+        } else {
+            unset($this->_config[0]['vars'][$var]);
+        }
+    }
+
+    /**
+     * get filepath of requested plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @return string|false
+     */
+    function _get_plugin_filepath($type, $name)
+    {
+        $_params = array('type' => $type, 'name' => $name);
+        require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
+        return smarty_core_assemble_plugin_filepath($_params, $this);
+    }
+
+   /**
+     * test if resource needs compiling
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _is_compiled($resource_name, $compile_path)
+    {
+        if (!$this->force_compile && file_exists($compile_path)) {
+            if (!$this->compile_check) {
+                // no need to check compiled file
+                return true;
+            } else {
+                // get file source and timestamp
+                $_params = array('resource_name' => $resource_name, 'get_source'=>false);
+                if (!$this->_fetch_resource_info($_params)) {
+                    return false;
+                }
+                if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
+                    // template not expired, no recompile
+                    return true;
+                } else {
+                    // compile template
+                    return false;
+                }
+            }
+        } else {
+            // compiled template does not exist, or forced compile
+            return false;
+        }
+    }
+
+   /**
+     * compile the template
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _compile_resource($resource_name, $compile_path)
+    {
+
+        $_params = array('resource_name' => $resource_name);
+        if (!$this->_fetch_resource_info($_params)) {
+            return false;
+        }
+
+        $_source_content = $_params['source_content'];
+        $_cache_include    = substr($compile_path, 0, -4).'.inc';
+
+        if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
+            // if a _cache_serial was set, we also have to write an include-file:
+            if ($this->_cache_include_info) {
+                require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
+                smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
+            }
+
+            $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $this);
+
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+   /**
+     * compile the given source
+     *
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return boolean
+     */
+    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
+    {
+        if (file_exists(SMARTY_DIR . $this->compiler_file)) {
+            require_once(SMARTY_DIR . $this->compiler_file);
+        } else {
+            // use include_path
+            require_once($this->compiler_file);
+        }
+
+
+        $smarty_compiler = new $this->compiler_class;
+
+        $smarty_compiler->template_dir      = $this->template_dir;
+        $smarty_compiler->compile_dir       = $this->compile_dir;
+        $smarty_compiler->plugins_dir       = $this->plugins_dir;
+        $smarty_compiler->config_dir        = $this->config_dir;
+        $smarty_compiler->force_compile     = $this->force_compile;
+        $smarty_compiler->caching           = $this->caching;
+        $smarty_compiler->php_handling      = $this->php_handling;
+        $smarty_compiler->left_delimiter    = $this->left_delimiter;
+        $smarty_compiler->right_delimiter   = $this->right_delimiter;
+        $smarty_compiler->_version          = $this->_version;
+        $smarty_compiler->security          = $this->security;
+        $smarty_compiler->secure_dir        = $this->secure_dir;
+        $smarty_compiler->security_settings = $this->security_settings;
+        $smarty_compiler->trusted_dir       = $this->trusted_dir;
+        $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
+        $smarty_compiler->_reg_objects      = &$this->_reg_objects;
+        $smarty_compiler->_plugins          = &$this->_plugins;
+        $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
+        $smarty_compiler->default_modifiers = $this->default_modifiers;
+        $smarty_compiler->compile_id        = $this->_compile_id;
+        $smarty_compiler->_config            = $this->_config;
+        $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
+
+        if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
+            $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
+        }
+        $smarty_compiler->_cache_include = $cache_include_path;
+
+
+        $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
+
+        if ($smarty_compiler->_cache_serial) {
+            $this->_cache_include_info = array(
+                'cache_serial'=>$smarty_compiler->_cache_serial
+                ,'plugins_code'=>$smarty_compiler->_plugins_code
+                ,'include_file_path' => $cache_include_path);
+
+        } else {
+            $this->_cache_include_info = null;
+
+        }
+
+        return $_results;
+    }
+
+    /**
+     * Get the compile path for this resource
+     *
+     * @param string $resource_name
+     * @return string results of {@link _get_auto_filename()}
+     */
+    function _get_compile_path($resource_name)
+    {
+        return $this->_get_auto_filename($this->compile_dir, $resource_name,
+                                         $this->_compile_id) . '.php';
+    }
+
+    /**
+     * fetch the template info. Gets timestamp, and source
+     * if get_source is true
+     *
+     * sets $source_content to the source of the template, and
+     * $resource_timestamp to its time stamp
+     * @param string $resource_name
+     * @param string $source_content
+     * @param integer $resource_timestamp
+     * @param boolean $get_source
+     * @param boolean $quiet
+     * @return boolean
+     */
+
+    function _fetch_resource_info(&$params)
+    {
+        if(!isset($params['get_source'])) { $params['get_source'] = true; }
+        if(!isset($params['quiet'])) { $params['quiet'] = false; }
+
+        $_return = false;
+        $_params = array('resource_name' => $params['resource_name']) ;
+        if (isset($params['resource_base_path']))
+            $_params['resource_base_path'] = $params['resource_base_path'];
+        else
+            $_params['resource_base_path'] = $this->template_dir;
+
+        if ($this->_parse_resource_name($_params)) {
+            $_resource_type = $_params['resource_type'];
+            $_resource_name = $_params['resource_name'];
+            switch ($_resource_type) {
+                case 'file':
+                    if ($params['get_source']) {
+                        $params['source_content'] = $this->_read_file($_resource_name);
+                    }
+                    $params['resource_timestamp'] = filemtime($_resource_name);
+                    $_return = is_file($_resource_name);
+                    break;
+
+                default:
+                    // call resource functions to fetch the template source and timestamp
+                    if ($params['get_source']) {
+                        $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                            call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
+                                                 array($_resource_name, &$params['source_content'], &$this));
+                    } else {
+                        $_source_return = true;
+                    }
+
+                    $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                        call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
+                                             array($_resource_name, &$params['resource_timestamp'], &$this));
+
+                    $_return = $_source_return && $_timestamp_return;
+                    break;
+            }
+        }
+
+        if (!$_return) {
+            // see if we can get a template with the default template handler
+            if (!empty($this->default_template_handler_func)) {
+                if (!is_callable($this->default_template_handler_func)) {
+                    $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
+                } else {
+                    $_return = call_user_func_array(
+                        $this->default_template_handler_func,
+                        array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
+                }
+            }
+        }
+
+        if (!$_return) {
+            if (!$params['quiet']) {
+                $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
+            }
+        } else if ($_return && $this->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+            if (!smarty_core_is_secure($_params, $this)) {
+                if (!$params['quiet'])
+                    $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
+                $params['source_content'] = null;
+                $params['resource_timestamp'] = null;
+                return false;
+            }
+        }
+        return $_return;
+    }
+
+
+    /**
+     * parse out the type and name from the resource
+     *
+     * @param string $resource_base_path
+     * @param string $resource_name
+     * @param string $resource_type
+     * @param string $resource_name
+     * @return boolean
+     */
+
+    function _parse_resource_name(&$params)
+    {
+
+        // split tpl_path by the first colon
+        $_resource_name_parts = explode(':', $params['resource_name'], 2);
+
+        if (count($_resource_name_parts) == 1) {
+            // no resource type given
+            $params['resource_type'] = $this->default_resource_type;
+            $params['resource_name'] = $_resource_name_parts[0];
+        } else {
+            if(strlen($_resource_name_parts[0]) == 1) {
+                // 1 char is not resource type, but part of filepath
+                $params['resource_type'] = $this->default_resource_type;
+                $params['resource_name'] = $params['resource_name'];
+            } else {
+                $params['resource_type'] = $_resource_name_parts[0];
+                $params['resource_name'] = $_resource_name_parts[1];
+            }
+        }
+
+        if ($params['resource_type'] == 'file') {
+            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
+                // relative pathname to $params['resource_base_path']
+                // use the first directory where the file is found
+                foreach ((array)$params['resource_base_path'] as $_curr_path) {
+                    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
+                    if (file_exists($_fullpath) && is_file($_fullpath)) {
+                        $params['resource_name'] = $_fullpath;
+                        return true;
+                    }
+                    // didn't find the file, try include_path
+                    $_params = array('file_path' => $_fullpath);
+                    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                    if(smarty_core_get_include_path($_params, $this)) {
+                        $params['resource_name'] = $_params['new_file_path'];
+                        return true;
+                    }
+                }
+                return false;
+            } else {
+                /* absolute path */
+                return file_exists($params['resource_name']);
+            }
+        } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
+            $_params = array('type' => $params['resource_type']);
+            require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
+            smarty_core_load_resource_plugin($_params, $this);
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Handle modifiers
+     *
+     * @param string|null $modifier_name
+     * @param array|null $map_array
+     * @return string result of modifiers
+     */
+    function _run_mod_handler()
+    {
+        $_args = func_get_args();
+        list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
+        list($_func_name, $_tpl_file, $_tpl_line) =
+            $this->_plugins['modifier'][$_modifier_name];
+
+        $_var = $_args[0];
+        foreach ($_var as $_key => $_val) {
+            $_args[0] = $_val;
+            $_var[$_key] = call_user_func_array($_func_name, $_args);
+        }
+        return $_var;
+    }
+
+    /**
+     * Remove starting and ending quotes from the string
+     *
+     * @param string $string
+     * @return string
+     */
+    function _dequote($string)
+    {
+        if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
+            substr($string, -1) == substr($string, 0, 1))
+            return substr($string, 1, -1);
+        else
+            return $string;
+    }
+
+
+    /**
+     * read in a file
+     *
+     * @param string $filename
+     * @return string
+     */
+    function _read_file($filename)
+    {
+        if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) {
+            $contents = '';
+            while (!feof($fd)) {
+                $contents .= fread($fd, 8192);
+            }
+            fclose($fd);
+            return $contents;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * get a concrete filename for automagically created content
+     *
+     * @param string $auto_base
+     * @param string $auto_source
+     * @param string $auto_id
+     * @return string
+     * @staticvar string|null
+     * @staticvar string|null
+     */
+    function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
+    {
+        $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
+        $_return = $auto_base . DIRECTORY_SEPARATOR;
+
+        if(isset($auto_id)) {
+            // make auto_id safe for directory names
+            $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
+            // split into separate directories
+            $_return .= $auto_id . $_compile_dir_sep;
+        }
+
+        if(isset($auto_source)) {
+            // make source name safe for filename
+            $_filename = urlencode(basename($auto_source));
+            $_crc32 = sprintf('%08X', crc32($auto_source));
+            // prepend %% to avoid name conflicts with
+            // with $params['auto_id'] names
+            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
+                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
+            $_return .= '%%' . $_crc32 . '%%' . $_filename;
+        }
+
+        return $_return;
+    }
+
+    /**
+     * unlink a file, possibly using expiration time
+     *
+     * @param string $resource
+     * @param integer $exp_time
+     */
+    function _unlink($resource, $exp_time = null)
+    {
+        if(isset($exp_time)) {
+            if(time() - @filemtime($resource) >= $exp_time) {
+                return @unlink($resource);
+            }
+        } else {
+            return @unlink($resource);
+        }
+    }
+
+    /**
+     * returns an auto_id for auto-file-functions
+     *
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|null
+     */
+    function _get_auto_id($cache_id=null, $compile_id=null) {
+    if (isset($cache_id))
+        return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
+    elseif(isset($compile_id))
+        return $compile_id;
+    else
+        return null;
+    }
+
+    /**
+     * trigger Smarty plugin error
+     *
+     * @param string $error_msg
+     * @param string $tpl_file
+     * @param integer $tpl_line
+     * @param string $file
+     * @param integer $line
+     * @param integer $error_type
+     */
+    function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
+            $file = null, $line = null, $error_type = E_USER_ERROR)
+    {
+        if(isset($file) && isset($line)) {
+            $info = ' ('.basename($file).", line $line)";
+        } else {
+            $info = '';
+        }
+        if (isset($tpl_line) && isset($tpl_file)) {
+            $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
+        } else {
+            $this->trigger_error($error_msg . $info, $error_type);
+        }
+    }
+
+
+    /**
+     * callback function for preg_replace, to call a non-cacheable block
+     * @return string
+     */
+    function _process_compiled_include_callback($match) {
+        $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
+        ob_start();
+        $_func($this);
+        $_ret = ob_get_contents();
+        ob_end_clean();
+        return $_ret;
+    }
+
+
+    /**
+     * called for included templates
+     *
+     * @param string $_smarty_include_tpl_file
+     * @param string $_smarty_include_vars
+     */
+
+    // $_smarty_include_tpl_file, $_smarty_include_vars
+
+    function _smarty_include($params)
+    {
+        if ($this->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                  'filename'  => $params['smarty_include_tpl_file'],
+                                                  'depth'     => ++$this->_inclusion_depth);
+            $included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
+
+        // config vars are treated as local, so push a copy of the
+        // current ones onto the front of the stack
+        array_unshift($this->_config, $this->_config[0]);
+
+        $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
+
+
+        if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
+            || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
+        {
+            include($_smarty_compile_path);
+        }
+
+        // pop the local vars off the front of the stack
+        array_shift($this->_config);
+
+        $this->_inclusion_depth--;
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
+        }
+
+        if ($this->caching) {
+            $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
+        }
+    }
+
+
+    /**
+     * get or set an array of cached attributes for function that is
+     * not cacheable
+     * @return array
+     */
+    function &_smarty_cache_attrs($cache_serial, $count) {
+        $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
+
+        if ($this->_cache_including) {
+            /* return next set of cache_attrs */
+            $_return = current($_cache_attrs);
+            next($_cache_attrs);
+            return $_return;
+
+        } else {
+            /* add a reference to a new set of cache_attrs */
+            $_cache_attrs[] = array();
+            return $_cache_attrs[count($_cache_attrs)-1];
+
+        }
+
+    }
+
+
+    /**
+     * wrapper for include() retaining $this
+     * @return mixed
+     */
+    function _include($filename, $once=false, $params=null)
+    {
+        if ($once) {
+            return include_once($filename);
+        } else {
+            return include($filename);
+        }
+    }
+
+
+    /**
+     * wrapper for eval() retaining $this
+     * @return mixed
+     */
+    function _eval($code, $params=null)
+    {
+        return eval($code);
+    }
+    
+    /**
+     * Extracts the filter name from the given callback
+     * 
+     * @param callback $function
+     * @return string
+     */
+	function _get_filter_name($function)
+	{
+		if (is_array($function)) {
+			$_class_name = (is_object($function[0]) ?
+				get_class($function[0]) : $function[0]);
+			return $_class_name . '_' . $function[1];
+		}
+		else {
+			return $function;
+		}
+	}
+    
+    /**#@-*/
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_window_open_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_window_open_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_window_open_init.php	(revision 795)
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Insere o código javascript necessário para abrir uma nova janela 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output código do script
+ * @access public 
+ */
+function smarty_function_wf_window_open_init($params, &$smarty)
+{
+$output = <<<EOF
+	<script language="javascript1.2">
+	function wf_open_window(url, name, width, height, position, features) {
+		if (position == 'right') {
+			newScreenX = screen.width - width;
+			newScreenY = 0;
+		} else {
+			if (position == 'center') {
+				newScreenX = (screen.width / 2) - (width / 2);
+				newScreenY = 0;
+			} else {
+				newScreenX = 1;
+				newScreenY = 0;
+			}
+		}
+		
+		name = window.open(url, '', 'width='+width+',height='+height+',' +
+				'screenX='+newScreenX+',left='+newScreenX+',screenY='+newScreenY+',' + 
+						'top='+newScreenY+','+features);	
+	}
+	</script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_user.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_user.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_user.php	(revision 2372)
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Insere os elementos HTML que permitem a seleção de usuários (ids/e-mails)
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @param array $params Array de parametros
+ * - name : o nome do campo que irá receber o id do usuário selecionado (o nome do usuário selecionado estará no campo de formulário de nome "name" seguido do sufixo "_desc"). Quando for configurado para pegar o e-mail, os e-mails estarão no campo com o nome indicado por "name" e, o conteúdo será do tipo: "Usuário Um" , "Usuário Dois" (e assim por diante).
+ * - id_value : valor de id de um usuário previamente selecionado.
+ * - desc_value : nome de um usuário previamente selecionado (é ineficaz especificar somente o nome e não o id para deixar um usuário previamente selecionado).
+ * - get_email : indica se deve ser buscado o e-mail ou o id.
+ * - email_as_textarea : indica se o campo que receberá os emails deve ser um textarea (valor true) ou input type text (valor false). Este parâmetro só tem validade se get_email for true.
+ * - hide_groups : indica se deve-se omitir os grupos na tela de seleção.
+ * - organization : nome da organização que estará previamente selecionada.
+ * - title : texto da tooltip que aparecerá quando o usuário colocar o mouse sobre o ícone para adicionar usuário.
+ * - cols : largura do campo.
+ * - rows : altura do campo.
+ * @return string $output codigo com referencias aos javascripts.
+ * @access public
+ */
+function smarty_function_wf_select_user($params, &$smarty)
+{
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'id_value' => '',
+		'desc_value' => '',
+		'get_email' => false,
+		'email_as_textarea' => false,
+		'hide_groups' => true,
+		'organization' => null,
+		'entities' => null,
+		'title' => '',
+		'cols'=> 80,
+		'hide_organizations' => false,
+		'hide_sectors' => false,
+		'rows'=> 2);
+	$extractParams = array(
+		'name',
+		'id_value',
+		'desc_value',
+		'title',
+		'cols',
+		'rows');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_user] missing required parameter(s): $required", E_USER_ERROR);
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	$name_desc = $name . "_desc";
+
+	if ($params['get_email'] == true)
+	{
+		$extraParams = "mail=1";
+		if ($params['email_as_textarea'])
+		{
+			$output = <<<EOF
+				<textarea id="$name" wrap="virtual" rows="$rows" cols="$cols" name="$name">$desc_value</textarea>
+EOF;
+		} else {
+			$output = <<<EOF
+				<input type="text" name="$name" id="$name" value="$id_value" size="27"/>
+EOF;
+		}
+	}
+	else
+	{
+		$extraParams = "uid=1";
+		$output = <<<EOF
+			<input type="hidden" name="$name" id="$name" value="$id_value"/>
+			<input type="text" name="$name_desc" id="$name_desc" value="$desc_value" readonly="true" size="27"/>
+EOF;
+	}
+
+	if ($params['hide_groups'] == true)
+		$extraParams .= "&hidegroups=1";
+	if (!is_null($params['organization']))
+		$extraParams .= "&change_org=True&organization=" . $params['organization'];
+	if (!is_null($params['entities']))
+		$extraParams .= "&entities=" . $params['entities'];
+	if ($params['hide_organizations'] == true)
+		$extraParams .= "&hideOrganizations=1";
+	if ($params['hide_sectors'] == true)
+		$extraParams .= "&hideSectors=1";
+
+	$image = Factory::getInstance('TemplateServer')->generateImageLink('add_user.png');
+
+$output .= <<<EOF
+	<a alt="$title" title="$title" href="javascript:void(0)" onclick="openParticipants('$name', '$extraParams');"><img border="0" alt="" src="$image" /></a>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_rtf_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_rtf_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_rtf_init.php	(revision 795)
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_rtf_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/rtf.js';
+$output = <<<EOF
+<script language="javascript1.2" src="$jsFile"></script>
+<script language="javascript1.2">
+var formWorkflow = document.getElementsByName('workflow_form')[0];
+if (formWorkflow.addEventListener)
+{
+	formWorkflow.addEventListener("submit", endDocument, true);
+}
+else
+	if (formWorkflow.attachEvent)
+	{
+		formWorkflow.attachEvent("onsubmit", endDocument);
+	}
+</script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_state.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_state.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_state.php	(revision 2372)
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Insere uma combo box que permite ao usuário selecionar um Estado do Brasil. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (Qualquer outro parâmetro passado será incorporado na tag da combo gerada.)
+ * - name: o nome que o elemento HTML receberá. 
+ * - value: o ID do Estado que estará previamente selecionado.
+ * Qualquer outro parâmetro passado será incorporado na tag da combo gerada.
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo que insere a combobox. 
+ * @access public 
+ */
+function smarty_function_wf_select_state($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'value' => 1);
+	$extractParams = array(
+		'name',
+		'value');
+	
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_state] missing required parameter(s): $required", E_USER_ERROR);
+	
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+	
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+	
+	/* parâmetros extras são "acumulados" em uma única variável */
+	$extraParams = array();
+	foreach ($params as $key => $value_params)
+		if (!in_array($key, $extractParams))
+			$extraParams[$key] = $value_params;
+
+	$sql = "SELECT id_state, state_name FROM phpgw_cc_state WHERE id_country = 'BR' ORDER BY state_name";
+
+	$result = Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID->query($sql);
+	$estados = array();
+	while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
+		$estados[$row['id_state']] = $row['state_name'];
+
+	$output = smarty_function_html_options(array_merge(array(
+											'name' => $name,
+											'id' => $name,
+											'options' => $estados,
+											'selected' => $value,
+											'print_result' => false), $extraParams),
+										$smarty);
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_default_template.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_default_template.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_default_template.php	(revision 795)
@@ -0,0 +1,21 @@
+<?php
+/**
+* This plugin does not perform any work. It just exists to "say" to the system that an action
+* should be executed. When this plugin is called,a header and footer are added into the template.
+* The action is performed by: prefilter.wf_default_template.php
+* In a template prefilter, the templates are ran through before they are compiled.
+* @package Smarty
+* @subpackage wf_plugins
+* @version:		1.0
+* @author:		Everton Flávio Rufino Seára - rufino@celepar.pr.gov.br
+*				Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+* @param array null
+* @param object &$smarty null
+* @return void
+* @access public
+*/
+function smarty_function_wf_default_template($params, &$smarty)
+{
+	return;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_ldap_users_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_ldap_users_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_ldap_users_init.php	(revision 795)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string $output codigo com referencias aos javascripts.
+ * @access public
+ */
+function smarty_function_wf_select_ldap_users_init($params, &$smarty)
+{
+	$webServer = $GLOBALS['phpgw_info']['server']['webserver_url'];
+	$jsFilePath = $webServer . '/workflow/js';
+	$localFile = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'js' . SEP . 'jscode' . SEP . 'connector.js';
+	$size = 0;
+	if (@file_exists($localFile))
+		$size = filesize($localFile);
+
+$output = <<<EOF
+<input type="hidden" value="" id="txt_loading">
+<script language='javascript'>var _web_server_url = '$webServer';</script>
+<script type="text/javascript" src="$jsFilePath/jscode/connector.js?$size"></script>
+<script type="text/javascript" src="$jsFilePath/jscode/wf_select_ldap_users.js"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_download_link.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_download_link.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_download_link.php	(revision 795)
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Este plugin tem por finalidade criar links para downloads de arquivos. 
+ * Estes links não apontam para o arquivo que será baixado e sim para uma página que irá enviar o arquivo 
+ * (útil para arquivos que estão no banco de dados). 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - base_url : a URL que irá enviar o arquivo (tratar a requisição). 
+ * - text : texto do link gerado 
+ * - getParams : parâmetro(s) que identifica(m) o(s) download(s).
+ * @param object &$smarty clever simulation of a method  
+ * @return string $output link para uma página que irá enviar o arquivo 
+ * @access public
+ */
+function smarty_function_wf_download_link($params, &$smarty)
+{
+	$requiredParams = array(
+		'getParams');
+	$defaultValues = array(
+		'base_url' => $_SERVER['REQUEST_URI'],
+		'text' => 'download',
+		'getParams' => '');
+	$extractParams = array(
+		'base_url',
+		'text',
+		'getParams');
+	
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_download_link] missing required parameter(s): $required", E_USER_ERROR);
+	
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+	
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+	
+	/* parâmetros extras são "acumulados" em uma única matriz */
+	$extraParams = array();
+	foreach ($params as $key => $value)
+		if (!in_array($key, $extractParams))
+			$extraParams[] = $key . ' = "' . $value . '"';
+	
+	$base_url .= (strpos($base_url, '?') === false) ? '?' : '&';
+	$getParams = '&' . $getParams;
+
+	$output = '<a href="' . $base_url . 'download_mode=true' . $getParams . '" ' . implode(' ', $extraParams)  . '>' . $text . '</a>';
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_window_open.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_window_open.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_window_open.php	(revision 795)
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Abre uma nova janela de browser
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @author Mauricio Luiz Viani
+ * @param array $params Array de parametros
+ * - url: (obrigatório) Endereço completo de uma página a ser aberta na nova janela 
+ * - name: (opcional) Nome do objeto janela a ser criado. Default 'win'
+ * - width: (opcional) Largura, em pixels, da janela. Default 450.
+ * - height: (opcional) Comprimento, em pixels, da janela. Default 550
+ * - features: (opcional) Sequência de parâmetros de configuração da janela. Default: "scrollbars = yes, menubar=yes"
+ * - text (opcional) Texto sobre o qual será montado o link de abertura. Default 'Abrir'
+ * - img: (opcional) Nome de um arquivo de imagem (com extensão) sobre o qual será montado o link. Se informado, inibe o uso de parâmetro text
+ * - button: (opcional) Indica se o link para abrir a nova janela deve ser um botão. Default false. Se informado inibe o parâmetro img.   
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output código
+ * @access public
+ */
+function smarty_function_wf_window_open($params, &$smarty)
+{		
+	$requiredParams = array(
+		'url');
+	$defaultValues = array(
+		'name' => 'win',
+		'width' => '450',
+		'height' => '550',
+		'position' => 'right',
+		'features' => "toolbar=no, scrollbars=yes, menubar=yes",
+		'text' => 'Abrir',
+		'img' => '',
+		'button' => false);
+	$extractParams = array(
+		'url',
+		'name',
+		'width',
+		'height',
+		'position',
+		'features',
+		'text',
+		'img',
+		'button');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_window_open] missing required parameter(s): $required", E_USER_ERROR);
+		
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+			
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	/* parâmetros extras são "acumulados" em uma única matriz */
+	$extraParams = array();
+	foreach ($params as $key => $value)
+		if (!in_array($key, $extractParams))
+			$extraParams[] = $key . ' = "' . $value . '"';
+		
+	$click_command = "wf_open_window('$url', '$name', '$width', '$height', '$position', '$features');";
+	
+	if ($button) {
+		$output = "<input type=\"button\" onclick=\"$click_command\" value=\"$text\" name=\"$text\" " . implode(' ', $extraParams) . "/>";
+	}
+	else {
+			if ($img) {
+				$text = '<img src="' . $smarty->get_template_vars('wf_resources_path') . '/' . $img . '" border="0">';
+			}
+			$output = "<a href=\"javascript:void(0)\" onclick=\"$click_command\" " . implode(' ', $extraParams) . ">$text</a>";
+	}
+		
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_make_link.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_make_link.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_make_link.php	(revision 795)
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Plugin para gerar link de retorno ou link genérico.
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @author Mauricio Luiz Viani
+ * @param array $params Array de parâmetros
+ * - tab: (opcional) número da aba da interface do usuário. Default = 1. Ignorado se for informado o parâmetro url
+ * - text: (opcional) texto sobre o qual será feito o link. Default = 'Voltar'
+ * - url: (opcional) url completa para gerar o link. Se não informado irá gerar um link par a interface do usuário. 
+ * - img: (opcional) nome de um arquivo de imagem (com extensão) sobre o qual será montado o link. Se informado, inibe o uso de parâmetro text.
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string código com o link 
+ * @access public
+ */
+function smarty_function_wf_make_link($params, &$smarty)
+{		
+	$defaultValues = array(
+		'tab' => '1',
+		'text' => 'Voltar',
+		'url' => '',
+		'img' => '');
+	$extractParams = array(
+		'tab',
+		'text',
+		'url',
+		'img');
+		
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+			
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+		
+	if ($img) {
+		$text = "<img src='" . $smarty->get_template_vars('wf_resources_path') . "/" . $img . "' border='0'>";
+	}
+
+	if ($url) {
+		$back_url = $url;
+	} else {
+		$back_url = ''; 
+		$back_url = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/index.php?start_tab=' . $tab;
+	}
+	
+	$output = '<a href="' . $back_url . '">'. $text . '</a>';
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_user_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_user_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_user_init.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_select_user_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/participants.js';
+$output = <<<EOF
+	<script language="javascript1.2" src="$jsFile"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_ldap_users.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_ldap_users.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_ldap_users.php	(revision 2372)
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Este plugin insere um campo input, um botão e uma combo box que permitem ao usuário buscar uma lista de funcionários através
+ * do seu nome, ou parte do nome (atributo 'cn'), no ldap.
+ * O usuário digita o nome a ser buscado no input e clica no botão "Pesquisar". Isso faz uma chamada Ajax que atualiza a combo com
+ * todos os registros encontrados. Esta combo box pode ser atualizada de acordo com as necessidades do usuário através dos atributos
+ * passados por parâmetro. Por exemplo, ela pode apresentar os uid dos registros e passar o uidnumber na submissão do formulário.
+ * Isso é possível quando são informados os parâmetros opt_id e opt_name, sendo uidnumber e uid, respectivamente para esse exemplo.
+ * Os respectivos valores padrão são dn e cn.
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - name: o nome que a combo de seleção do funcionário irá receber.
+ * - handleExpiredSessions: indica se as sessões expiradas devem ser tratadas automaticamente.
+ * - size_input: tamanho do campo input.
+ * - value_btn: texto a ser apresentado no botão.
+ * - class_btn: className do botão.
+ * - opt_id: atributo a ser atribuído ao value das options da combo onde são carregados os registros buscados (valor padrão é 'dn').
+ * - opt_name: atributo a ser atribuído ao innerHTML das options da combo onde são carregados os registros buscados (valor padrão é 'cn').
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string $output codigo que insere os componentes.
+ * @access public
+ */
+function smarty_function_wf_select_ldap_users($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+	$imagesPath = substr(Factory::getInstance('TemplateServer')->generateImageLink(''), 0, -1);
+
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'value_btn'             => 'Pesquisar',
+		'handleExpiredSessions' => true,
+		'size_input'            => '20',
+		'opt_id'                => 'dn',
+		'opt_name'              => 'cn');
+	$extractParams = array(
+		'name',
+		'handleExpiredSessions',
+		'size_input',
+		'value_btn',
+		'class_btn',
+		'opt_id',
+		'opt_name');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_ldap_users] missing required parameter(s): $required", E_USER_ERROR);
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	/* parâmetros extras são "acumulados" em uma única variável */
+	$extraParams = array();
+	foreach ($params as $key => $value_params)
+		if (!in_array($key, $extractParams))
+			$extraParams[$key] = $value_params;
+
+	/* define o nome do campo input, é usado o nome atribuído à combo concatenado ao sufixo "_txt" */
+	$name_input = $name . "_txt";
+
+	/* define o nome do span, é usado o nome atribuído à combo concatenado ao sufixo "_span" */
+	$name_span  = $name . "_span";
+
+	/* define o nome da imagem, é usado o nome atribuído à combo concatenado ao sufixo "_img" */
+	$name_img   = $name . "_img";
+
+	$handleExpiredSessions = ($handleExpiredSessions === true) ? 'true' : 'false';
+
+	/* campos do componente */
+	$output = <<<EOF
+		<input type="text" id="$name_input" name="$name_input" size="$size_input" />
+		<input type="button" class="$class_btn" value="$value_btn" onclick="search_ldap_users_by_cn(document.getElementById('$name_input').value, '$name', '$opt_id', '$opt_name', $handleExpiredSessions)" />
+		&nbsp;<img id="$name_img" border="0" src="$imagesPath/loading.gif" style="display:none">
+		<span id="$name_span" style="display:none">&nbsp;&nbsp;&nbsp;&nbsp;<b>Selecione o nome: </b>
+EOF;
+
+	$output .= smarty_function_html_options(array_merge(array(
+											'name'    => $name,
+											'id'      => $name,
+											'options' => array('-1' => "")),
+											$extraParams),
+										$smarty);
+
+	$output .= <<<EOF
+		</span>
+EOF;
+
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_autocomplete_input_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_autocomplete_input_init.php	(revision 1428)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_autocomplete_input_init.php	(revision 1428)
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade.
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso1
+ * @return string $output codigo com referencias aos javascripts.
+ * @access public
+ */
+function smarty_function_wf_autocomplete_input_init($params, &$smarty)
+{
+	$jsEffects		= $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/scriptaculous/effects.js';
+	$jsControls		= $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/scriptaculous/controls.js';
+	$jsJson			= $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/nano/JSON.js';
+	$jsSha1			= $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/sha1.js';
+	$jsAutocomplete	= $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/wf_autocomplete_input.js';
+	$output = <<<EOF
+	<script type="text/javascript" src="$jsEffects"></script>
+	<script type="text/javascript" src="$jsControls"></script>
+	<script type="text/javascript" src="$jsJson"></script>
+	<script type="text/javascript" src="$jsSha1"></script>
+	<script type="text/javascript" src="$jsAutocomplete"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_option_multiple_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_option_multiple_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_option_multiple_init.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_select_option_multiple_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/wf_select_option_multiple.js';
+	$output = <<<EOF
+	<script language="javascript1.2" src="$jsFile"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_ajax_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_ajax_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_ajax_init.php	(revision 795)
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Insere código que referencia os arquivos de JavaScript responsáveis pela funcionalidade do Ajax.
+ *
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @version 1.1
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @param array $params Array de parametros para a função
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string codigo com referencias aos JavaScripts.
+ * @access public
+ */
+function smarty_function_wf_ajax_init($params, &$smarty)
+{
+	static $wf_ajax_init = false;
+
+	if (!$wf_ajax_init)
+	{
+		$wf_ajax_init = true;
+
+		$serverPath = $GLOBALS['phpgw_info']['server']['webserver_url'];
+		$localPath = PHPGW_SERVER_ROOT;
+
+		$includeFiles = array('JSON', 'function.library', 'NanoRequest.class', 'NanoAjax.class', 'NanoController.class');
+		$output = '<script type="text/javascript" src="' . $serverPath . '/workflow/js/jscode/prototype.js?' . @filesize($localPath . '/workflow/js/jscode/prototype.js') . '"></script>';
+		foreach ($includeFiles as $file)
+			$output .= '<script type="text/javascript" src="' . $serverPath . '/workflow/js/nano/' . $file . '.js?' . @filesize($localPath . '/workflow/js/nano/' . $file . '.js') . '"></script>';
+		return $output;
+	}
+	else
+		return '';
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_city.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_city.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_city.php	(revision 2372)
@@ -0,0 +1,96 @@
+<?php
+/** 
+ * Este plugin insere duas combo boxes que permitem ao usuário selecionar uma cidade do Brasil. 
+ * A primeira combo é utilizada para fazer a seleção de um Estado. Uma vez feita esta seleção, é feita uma chamada Ajax que carrega as cidades daquele Estado na segunda combo.
+ * E, é nesta segunda combo que o usuário efetivamente seleciona a cidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - name: o nome que a combo de seleção de cidade irá receber. 
+ * - value: o ID da cidade que aparecerá inicialmente selecionada. 
+ * - state_name: o nome da combo de seleção de Estado. 
+ * - state_value: o ID do Estado inicialmente selecionado.
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo que insere os comboboxes. 
+ * @access public 
+ */
+function smarty_function_wf_select_city($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('function','wf_select_state');
+
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'value' => 1,
+		'handleExpiredSessions' => true,
+		'state_value' => 1,
+		'state_name' => "_estado_" . rand() . '_' . rand());
+	$extractParams = array(
+		'name',
+		'handleExpiredSessions',
+		'value',
+		'state_value',
+		'state_name');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_city] missing required parameter(s): $required", E_USER_ERROR);
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	/* parâmetros extras são "acumulados" em uma única variável */
+	$extraParams = array();
+	foreach ($params as $key => $value_params)
+		if (!in_array($key, $extractParams))
+			$extraParams[$key] = $value_params;
+
+	$db = &Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID;
+	if (isset($params['value']))
+	{
+		$sql = "SELECT id_state FROM phpgw_cc_city WHERE id_city = ?";
+		$result = $db->query($sql, array($value));
+		if ($result)
+		{
+			$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+			$state_value = $row['id_state'];
+		}
+		else
+		{
+			$state_value = 1;
+			$value = 1;
+		}
+	}
+
+	$handleExpiredSessions = ($handleExpiredSessions === true) ? 'true' : 'false';
+
+	$output = smarty_function_wf_select_state(array(
+											'name' => $state_name,
+											'value' => $state_value,
+											'onchange' => "draw_cities('$name', this.value, null, $handleExpiredSessions);"),
+										$smarty);
+	$output .= '<br/>';
+
+	$sql = "SELECT id_city, city_name FROM phpgw_cc_city WHERE id_state = ? ORDER BY city_name";
+	$result = $db->query($sql, array($state_value));
+	$cities = array();
+	while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
+		$cidades[$row['id_city']] = $row['city_name'];
+
+	$output .= smarty_function_html_options(array_merge(array(
+											'name' => $name,
+											'id' => $name,
+											'options' => $cidades,
+											'selected' => $value,
+											'print_result' => false), $extraParams),
+										$smarty);
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_calendar.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_calendar.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_calendar.php	(revision 795)
@@ -0,0 +1,242 @@
+<?php
+/**
+ * Interface to jscalendar-1.0
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @author   boots
+ * @author   Sidnei Augusto Drovetto Junior
+ * @version  1.1.2
+ * @link http://www.dynarch.com/projects/calendar/ {dhtml calendar}
+ *          (dynarch.com)
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @param array $params Parameters array Following is the complete list of properties interpreted by Calendar.setup.
+ * All of them have default values, so you can pass only those which you would like
+ * to customize.
+ * - Required: popup (inputField, displayArea, button), flat (flat)
+ * - inputField string null The ID of your input field.
+ * - displayArea string null
+ *    This is the ID of a <span>, <div>, or any other element that you would like
+ *    to use to display the current date. This is generally useful only if the
+ *    input field is hidden, as an area to display the date.
+ * - button string null The ID of the calendar "trigger". This is an element (ordinarily a button or
+ *    an image) that will dispatch a certain event (usually "click") to the function that creates and displays the calendar.
+ *
+ * - eventName string "click" The name of the event that will trigger the calendar. The name should be
+ *    without the "on" prefix, such as "click" instead of "onclick". Virtually
+ *    all users will want to let this have the default value ("click"). Anyway,
+ *    it could be useful if, say, you want the calendar to appear when the input
+ *    field is focused and have no trigger button (in this case use "focus" as the
+ *    event name).
+ *
+ * - ifFormat string "%Y/%m/%d"
+ *   The format string that will be used to enter the date in the input field.
+ *   This format will be honored even if the input field is hidden.
+ *
+ * - daFormat string "%Y/%m/%d"
+ *   Format of the date displayed in the displayArea (if specified).
+ * 
+ * - singleClick boolean true
+ *   Wether the calendar is in "single-click mode" or "double-click mode". If
+ *   true (the default) the calendar will be created in single-click mode.
+ * 
+ * - disableFunc function null
+ *   A function that receives a JS Date object. It should return true if that
+ *   date has to be disabled, false otherwise. DEPRECATED (see below).
+ *
+ * - dateStatusFunc function null
+ *   A function that receives a JS Date object and returns a boolean or a string.
+ *   This function allows one to set a certain CSS class to some date, therefore
+ *   making it look different. If it returns true then the date will be disabled.
+ *   If it returns false nothing special happens with the given date. If it
+ *   returns a string then that will be taken as a CSS class and appended to the
+ *   date element. If this string is "disabled" then the date is also disabled
+ *   (therefore is like returning true). For more information please also refer
+ *   to section 4.3.8.
+ * 
+ * - firstDay integer 0
+ *   Specifies which day is to be displayed as the first day of week. Possible
+ *   values are 0 to 6; 0 means Sunday, 1 means Monday, ..., 6 means Saturday.
+ *   The end user can easily change this too, by clicking on the day name in the
+ *   calendar header.
+ *
+ * - weekNumbers boolean true
+ *   If "true" then the calendar will display week numbers.
+ *
+ * - align string "Bl"
+ *   Alignment of the calendar, relative to the reference element. The reference
+ *   element is dynamically chosen like this: if a displayArea is specified then
+ *   it will be the reference element. Otherwise, the input field is the
+ *   reference element. For the meaning of the alignment characters please
+ *   section 4.3.11.
+ *
+ * - range array [1900, 2999]
+ *   An array having exactly 2 elements, integers. (!) The first [0] element is
+ *   the minimum year that is available, and the second [1] element is the
+ *   maximum year that the calendar will allow.
+ * 
+ * - flat string null
+ *   If you want a flat calendar, pass the ID of the parent object in this
+ *   property. If not, pass null here (or nothing at all as null is the default
+ *   value).
+ * 
+ * - flatCallback function null
+ *   You should provide this function if the calendar is flat. It will be called
+ *   when the date in the calendar is changed with a reference to the calendar
+ *   object. See section 2.2 for an example of how to setup a flat calendar.
+ * 
+ * - onSelect function null
+ *   If you provide a function handler here then you have to manage the
+ *   "click-on-date" event by yourself. Look in the calendar-setup.js and take as
+ *   an example the onSelect handler that you can see there.
+ * 
+ * - onClose function null
+ *   This handler will be called when the calendar needs to close. You don't need
+ *   to provide one, but if you do it's your responsibility to hide/destroy the
+ *   calendar. You're on your own. Check the calendar-setup.js file for an
+ *   example.
+ * 
+ * - onUpdate function null
+ *   If you supply a function handler here, it will be called right after the
+ *   target field is updated with a new date. You can use this to chain 2
+ *   calendars, for instance to setup a default date in the second just after a
+ *   date was selected in the first.
+ * 
+ * - date date null
+ *   This allows you to setup an initial date where the calendar will be
+ *   positioned to. If absent then the calendar will open to the today date.
+ *
+ * - showsTime boolean false
+ *     If this is set to true then the calendar will also allow time selection.
+ * 
+ * - timeFormat string "24"
+ *   Set this to "12" or "24" to configure the way that the calendar will display
+ *   time.
+ *
+ * - electric boolean true
+ *   Set this to "false" if you want the calendar to update the field only when
+ *   closed (by default it updates the field at each date change, even if the
+ *   calendar is not closed)
+ *
+ * - position array null
+ *   Specifies the [x, y] position, relative to page's top-left corner, where the
+ *   calendar will be displayed. If not passed then the position will be computed
+ *   based on the "align" parameter. Defaults to "null" (not used).
+ * 
+ * - cache boolean false
+ *   Set this to "true" if you want to cache the calendar object. This means that
+ *   a single calendar object will be used for all fields that require a popup
+ *   calendar
+ * 
+ * - showOthers boolean false
+ *   If set to "true" then days belonging to months overlapping with the
+ *   currently displayed month will also be displayed in the calendar (but in a
+ *   "faded-out" color)
+ * @access public
+ * @return string código com os parametros de configuração a serem passados ao Calendar.setup 
+ */
+function smarty_function_wf_calendar($params, &$smarty)
+{
+	static $requires = array(
+		'flat' => 'string',
+		'inputField' => 'string',
+		'displayArea' => 'string',
+		'button' => 'string');
+
+	static $allowed = array(
+		'date' => 'date',
+		'eventName' => 'string',
+		'cache' => 'boolean',
+		'multiple' => 'boolean',
+		'singleClick' => 'boolean',
+		'electric' => 'boolean',
+		'position' => 'array',
+		'align' => 'string',
+		'firstDay' => 'integer',
+		'weekNumbers' => 'boolean',
+		'range' => 'array',
+		'showOthers' => 'boolean',
+		'showsTime' => 'boolean',
+		'timeFormat' => 'string',
+		'ifFormat' => 'string',
+		'daFormat' => 'string',
+		'flatCallback' => 'function',
+		'dateStatusFunc' => 'function',
+		'dateTest' => 'function',
+		'onSelect' => 'function',
+		'onClose' => 'function',
+		'onUpdate' => 'function',
+		'name' => 'stromg',
+		'default' => 'boolean',
+		'value' => 'string');
+
+	static $deprecated = array(
+		'disableFunc' => 'function');
+
+	static $all = false;
+	if (!$all)
+		$all = array_merge($requires, $allowed, $deprecated);
+	
+	$inputFields = "";
+	if (isset($params['default']) && isset($params['name']))
+		if ($params['default'] == true)
+		{
+			$fieldValue = "";
+			if (isset($params['value']))
+				$fieldValue = $params['value'];
+			$params['inputField'] = $params['name'];
+			$params['button'] = $params['name'] . "-trigger";
+			$params['singleClick'] = true;
+			$inputFields = "<input type=\"text\" id=\"" . $params['inputField']  . "\" name=\"" . $params['inputField']  . "\" value=\"" . $fieldValue  . "\" size=\"10\" maxlength=\"10\" onkeypress=\"return(formatCalendarInput(this, event))\" onfocus=\"if (this.value == '$fieldValue') this.value='';\" onblur=\"if (this.value == '') this.value = '$fieldValue';\"/>";
+			/* utilização de um elemento "input" do tipo "button" (ao invés de um elemento "button") para evitar que o calendário seja acionado ao se pressionar ENTER em nos campos do formulário */
+			//$inputFields .= "\n<button id=\"" . $params['button']  . "\">...</button>";
+			$inputFields .= "\n<input type=\"button\" id=\"" . $params['button']  . "\" value=\"...\"/>";
+		}
+		
+	$_params = array();
+
+	foreach ($requires as $required=>$type)
+	{
+		if (array_key_exists($required, $params) && !empty($params[$required]))
+		{
+			$_params[$required] = $params[$required];
+		}
+	}
+	if (empty($_params))
+	{
+		$smarty->trigger_error("[wf_calendar] missing required parameter(s)", E_USER_ERROR);
+		return false;
+	}
+
+	foreach ($allowed as $field=>$type)
+	{
+		if (array_key_exists($field, $params) && isset($params[$field]))
+		{
+			$_params[$field] = $params[$field];
+		}
+	}
+
+	foreach ($deprecated as $warn=>$type)
+	{
+		if (array_key_exists($warn, $params))
+		{
+			$smarty->trigger_error("[dhtml_calendar] deprecated parameter '$warn'", E_USER_INFO);
+			$_params[$warn] = $params[$warn];
+		}
+	}
+
+	$_params_out = '';
+	foreach ($_params as $field=>$value)
+	{
+		if (is_bool($value))
+			$value = $value ? 'true' : 'false';
+		else
+			if (!is_numeric($value) && !($all[$field] == 'function'))
+				$value = '"'.$value.'"';
+		if ($_params_out)
+			$_params_out .= ',';
+		$_params_out .= '"' . $field . '":' . $value;
+	}
+
+	return $inputFields . '<script type="text/javascript">Calendar.setup({' . $_params_out . '});</script>';
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_fckeditor.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_fckeditor.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_fckeditor.php	(revision 795)
@@ -0,0 +1,109 @@
+<?php
+/**
+* Este plugin insere o editor FCKeditor para edição de texto rico (RTF). 
+* Requires PHP >= 4.3.0
+* @package Smarty
+* @subpackage wf_plugins
+* @version 1.0
+* @author  gazoot (gazoot care of gmail dot com)
+* @author  Sidnei Augusto Drovetto Jr. - drovetto@gmail.com (revision)
+* @param object &$smarty Instância do objeto smarty em uso 
+* @param array $params Parameters array. (Default values for optional parameters are taken from fckeditor.js)<br>
+*  All other parameters used in the function will be put into the<br>
+*  configuration section,CustomConfigurationsPath is useful for example.
+* - name Editor instance name (form field name)
+* - value optional data that control will start with, default is taken from the javascript file
+* - width optional width (css units)
+* - height optional height (css units)
+* - toolbar_set optional what toolbar to use from configuration
+* - check_browser optional check the browser compatibility when rendering the editor
+* - display_errors optional show error messages on errors while rendering the editor
+* @link http://wiki.fckeditor.net/Developer%27s_Guide/Configuration/Configurations_File for more configuration info.
+* @return string $out codigo que insere o FCKeditor
+* @access public
+*/
+function smarty_function_wf_fckeditor($params, &$smarty)
+{
+    /* check for missing parameters */
+	if(!isset($params['name']) || empty($params['name']))
+		$smarty->trigger_error('wf_fckeditor: required parameter "name" missing');
+
+    /* convert the parameters from our naming convention to the one used by the FCKEditor */
+    $paramsConversion = array(
+        'name' =>'InstanceName',
+        'value' => 'Value',
+        'width' => 'Width',
+        'height' => 'Height',
+        'toolbar_set' => 'ToolbarSet',
+        'check_browser' => 'CheckBrowser',
+        'display_errors' => 'DisplayErrors'
+    );
+
+    $paramsCopy = $params;
+    foreach ($paramsConversion as $before => $after)
+    {
+        if (isset($params[$before]))
+        {
+            unset($params[$before]);
+            $params[$after] = $paramsCopy[$before];
+        }
+    }
+
+	static $base_arguments = array();
+	static $config_arguments = array();
+
+	// Test if editor has been loaded before
+	if(!count($base_arguments)) $init = TRUE;
+	else $init = FALSE;
+
+	// BasePath must be specified once.
+    $base_arguments['BasePath'] = $GLOBALS['phpgw_info']['server']['webserver_url'] . SEP . 'workflow' . SEP . 'js' . SEP . 'fckeditor' . SEP;
+
+	$base_arguments['InstanceName'] = $params['InstanceName'];
+
+	if(isset($params['Value'])) $base_arguments['Value'] = $params['Value'];
+	if(isset($params['Width'])) $base_arguments['Width'] = $params['Width'];
+	if(isset($params['Height'])) $base_arguments['Height'] = $params['Height'];
+	if(isset($params['ToolbarSet'])) $base_arguments['ToolbarSet'] = $params['ToolbarSet'];
+	if(isset($params['CheckBrowser'])) $base_arguments['CheckBrowser'] = $params['CheckBrowser'];
+    if(isset($params['DisplayErrors'])) $base_arguments['DisplayErrors'] = $params['DisplayErrors'];
+
+	// Use all other parameters for the config array (replace if needed)
+	$other_arguments = array_diff_assoc($params, $base_arguments);
+	$config_arguments = array_merge($config_arguments, $other_arguments);
+
+	$out = '';
+
+	if($init)
+	{
+		$out .= '<script type="text/javascript" src="' . $base_arguments['BasePath'] . 'fckeditor.js"></script>';
+	}
+
+	$out .= "\n<script type=\"text/javascript\">\n";
+	$out .= "var oFCKeditor = new FCKeditor('" . $base_arguments['InstanceName'] . "');\n";
+
+	foreach($base_arguments as $key => $value)
+	{
+		if(!is_bool($value))
+		{
+			// Fix newlines, javascript cannot handle multiple line strings very well.
+			$value = '"' . preg_replace("/[\r\n]+/", '" + $0"', addslashes($value)) . '"';
+		}
+		$out .= "oFCKeditor.$key = $value; ";
+	}
+
+	foreach($config_arguments as $key => $value)
+	{
+		if(!is_bool($value))
+		{
+			$value = '"' . preg_replace("/[\r\n]+/", '" + $0"', addslashes($value)) . '"';
+		}
+		$out .= "oFCKeditor.Config[\"$key\"] = $value; ";
+	}
+
+	$out .= "\noFCKeditor.Create();\n";
+	$out .= "</script>\n";
+
+	return $out;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_generic_select.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_generic_select.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_generic_select.php	(revision 2372)
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Insere o componente que permite a seleção de itens genéricos. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros. O valor padrão para todos os parâmetros não obrigatórios, é uma string vazia. 
+ * - name: (obrigatório) o nome que irá armazenar o id do item selecionado; 
+ * - container_number: (obrigatório) o número do container onde os itens estão armazenados. 
+ * - id_value: (opcional) o id de um item previamente selecionado (não é visível para o usuário). 
+ * - desc_value: (opcional) o texto de um item inicialmente selecionado (é visível para o usuário). 
+ * - title: (opcional) o título da tooltip quando o usuário passa o mouse sobre o botão de adicionar.   
+ * @param object &$smarty Instância do objeto smarty em uso  
+ * @return string $output código que insere o componente.
+ * @access public  
+ */
+function smarty_function_wf_generic_select($params, &$smarty)
+{
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'id_value' => '',
+		'desc_value' => '',
+		'title' => '',
+		'container_number' => 0);
+	$extractParams = array(
+		'name',
+		'id_value',
+		'desc_value',
+		'title',
+		'container_number');
+	
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_user] missing required parameter(s): $required", E_USER_ERROR);
+	
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+	
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+	
+	$name_desc = $name . "_desc";
+	$digest = md5($_SERVER['REQUEST_URI']);
+	$extraParams = "container_number=$container_number&digest=$digest";
+
+	$output = <<<EOF
+		<input type="hidden" name="$name" id="$name" value="$id_value"/>
+		<input type="text" name="$name_desc" id="$name_desc" value="$desc_value" readonly="true"/>
+EOF;
+
+	$templateServer = &Factory::getInstance('TemplateServer');
+	$imageAdd = $templateServer->generateImageLink('add.png');
+	$imageRemove = $templateServer->generateImageLink('close.png');
+$output .= <<<EOF
+	<a alt="$title" title="$title" href="javascript:void(0)" onclick="openGenericList('$name', '$extraParams');"><img border="0" alt="" src="$imageAdd" /></a>
+	<a alt="$title" title="$title" href="javascript:void(0)" onclick="genericListRemove('$name', '$name_desc');"><img border="0" alt="" src="$imageRemove" /></a>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_autocomplete_input.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_autocomplete_input.php	(revision 2160)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_autocomplete_input.php	(revision 2160)
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Este plugin insere um input que mostra os valores que podem ser selecionados enquanto o usuário digita.
+ * Os valores são preenchidos previamente através de uma requisição ajax: a classe e método que será invocado é passado por parêmetro no momento em que o desenvolvedor utiliza o componente.
+ *
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - name: o nome que o componente irá receber.
+ * - ajaxClass: classe ajax que será utilizada para fazer a consulta.
+ * - ajaxMethod: método da classe que será invocado para preencher a lista de opções.
+ * - methodParam: Parâmetro para o método que será invocado para preencher a lista de opções.
+ * - idValue: (opcional) o id de um item previamente selecionado (não é visível para o usuário).
+ * - textValue: (opcional) o texto de um item inicialmente selecionado (é visível para o usuário).
+ * - minLength: (opcional) número mínimo de caracteres necessários para que as opções apareçam na lista.
+ * - style: (opcional) estilo para o campo input
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string $output codigo que insere os select boxes.
+ * @access public
+ */
+function smarty_function_wf_autocomplete_input($params, &$smarty)
+{
+	$requiredParams = array(
+		'name',
+		'ajaxClass',
+		'ajaxMethod'
+	);
+	$defaultValues = array(
+		'minLength'	=> 1,
+		'style'		=> "width: 200px",
+		'mode'		=> "POPULATE_ON_LOAD"
+	);
+	$extractParams = array(
+		'name',
+		'ajaxClass',
+		'ajaxMethod',
+		'methodParam',
+		'minLength',
+		'idValue',
+		'textValue',
+		'style',
+		'mode'
+	);
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_autocomplete_input] missing required parameter(s): $required", E_USER_ERROR);
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	/* parâmetros extras são "acumulados" em uma única variável */
+	$extraParams = array();
+	foreach ($params as $key => $value_params)
+		if (!in_array($key, $extractParams))
+			$extraParams[$key] = $value_params;
+
+	$name_input = 'input' . $name;
+	$name_list	= 'list' . $name;
+	$name_response = 'response' . $name;
+
+	/* se parâmetro for um array "joga" para o javascript como um objeto JSON */
+	if (is_array($methodParam)){
+		$methodParam = json_encode($methodParam);
+	} else {
+		$sep = "'"; // se não for um objeto passa parâmetro entre aspas
+	}
+
+	/* Cria um objeto JSON com os parâmetros opcionais utilizados pelo javascript */
+	$extraParams = array ('idValue'		=> $idValue
+						, 'textValue'	=> $textValue
+						, 'minLength'	=> $minLength
+	);
+	$extraParams = json_encode($extraParams);
+
+	/* se o componente for do tipo padrão (POPULATE_ON_LOAD), não necessita de função para onkeyup */
+	if ($mode == 'POPULATE_ON_LOAD'){
+		$inputElement = <<<EOF
+		<input id="$name_input" name="$name_input" type="text" value="$textValue" style="$style" onfocus="checkDataLoaded('$name');" onblur="setTimeout('selectAutocompleteElement(\'$name\')', 500);"/>
+EOF;
+	}
+	elseif ($mode == 'REPOPULATE_ON_CHANGE'){
+		$inputElement = <<<EOF
+		<input id="$name_input" name="$name_input" type="text" value="$textValue" style="$style" onblur="setTimeout('selectAutocompleteElement(\'$name\')', 500);" onkeyup="updateCacheRequestsTimeout('$name', '$ajaxClass', '$ajaxMethod', this.value, '$mode')"/>
+EOF;
+	}
+
+	/* Cria todos os elementos HTML necessários para o componente */
+	$output = <<<EOF
+	<input id="$name" name="$name" type="hidden"/>
+	$inputElement
+	<span id="$name_response"></span>
+	<div id="$name_list" class="autocomplete" style="display: none;"></div>
+	<script>autocompleteSelect('$name', '$ajaxClass', '$ajaxMethod', $sep$methodParam$sep, '$mode', $extraParams);</script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_option_multiple.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_option_multiple.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_option_multiple.php	(revision 795)
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Este plugin insere uma combo box e um select box múltiplo que permite ao usuário cadastrar vários ítens de uma lista.
+ * O combo é utilizado para mostrar todos os ítens "cadastráveis", que podem estar em formato de lista normal,
+ * ou uma lista dividida em grupos (utilizando optGroup). Ao selecionar um item, deve-se clicar no botão "Adicionar" para que a seleção seja copiada para o select box,
+ * onde se encontram os itens a serem cadastrados. Ao adicionar um elemento,ele será desabilitado na combo para que não possa ser selecionado novamente.
+ * Para remover um ou mais itens do select, basta selecioná-los e clicar no botão "Remover". Isso vai reabilitá-los na combo.
+ * @author Anderson Tadayuki Saikawa
+ * @author Everton Flávio Rufino Seára
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @version 1.0
+ * @param array $params Array de parametros
+ * - nameTop: o nome que a combo irá receber.
+ * - nameBottom: o nome que o select irá receber.
+ * - arrayTop: lista dos ítens a serem carregados na combo.
+ * - arrayBottom: lista dos ítens a serem carregados no select.
+ * - onChangeTop: chamada da função a ser executada no onChange da combo.
+ * - onChangeBottom: chamada da função a ser executada no onChange do select.
+ * - size: tamanho do select box.
+ * - sortEnableBottom: valor indicando se deve-se executar o sort no select box de baixo.
+ * - diffEnable: valor indicando se deve-se executar o diff entre a combo e o select box.
+ * - style: para definir os estilos do select box
+ * @access public
+ * @return string $output codigo que insere o plugin
+ */
+function smarty_function_wf_select_option_multiple($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+
+	// This function build a "normal" select or an "option group" select
+	function option_multiple_build($name, $array, $onChange, $extraParams, &$smarty)
+	{
+		if (!is_array($array))
+		{
+			return false;
+		}
+
+		$values = array_values($array);
+		// If $array is a matrix, build an option group selectbox
+		if (is_array($values[0]))
+		{
+			$result  = "<select name='$name' id='$name' onchange='enableButton(\"$name\");$onChange'>";
+			$result .= "<option value='-1'></option>";
+
+			foreach ($array as $key => $value)
+			{
+				$result .= "<optgroup label='$key'>";
+				foreach ($value as $optKey => $optValue)
+				{
+					// text-indent style is used on Firefox. IE indents automatically.
+					$result .= "<option value='$optKey' style='text-indent:1cm'>$optValue</option>";
+				}
+				$result .= '</optgroup>';
+			}
+			$result .= '</select>';
+		}
+		// If $array is NOT a matrix, build a normal selectbox
+		else
+		{
+			// Insert a blank option with value=-1
+			$array  = array(-1 => "") + $array;
+			$result = smarty_function_html_options(array_merge(array(
+													'name'     => $name,
+													'id'       => $name,
+													'onchange' => "enableButton('" . $name . "');$onChange",
+													'options'  => $array), $extraParams),
+												$smarty);
+		}
+		return $result;
+	}
+
+	$requiredParams  = array(
+		'nameTop',
+		'nameBottom'		);
+	$defaultValues   = array(
+		'size'             => 8,
+		'style'            => "width:400px",
+		'sortEnableBottom' => true,
+		'diffEnable'       => true);
+	$extractParams   = array(
+		'nameTop',
+		'nameBottom',
+		'arrayTop',
+		'arrayBottom',
+		'onChangeTop',
+		'onChangeBottom',
+		'size',
+		'diffEnable',
+		'sortEnableBottom',
+		'style');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_option_multiple] missing required parameter(s): $required", E_USER_ERROR);
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+	if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	/* parâmetros extras são "acumulados" em uma única variável */
+	$extraParams = array();
+	foreach ($params as $key => $value_params)
+		if (!in_array($key, $extractParams))
+			$extraParams[$key] = $value_params;
+
+	$output = <<<EOF
+				<table valign=top>
+				<tr>
+					<td valign=top>
+EOF;
+	$output .=  option_multiple_build($nameTop, $arrayTop, $onChangeTop, $extraParams, $smarty);
+
+	$output .= <<<EOF
+			<!-- <input type="hidden" name="$name" id="$name" value="$id_value"/> -->
+			&nbsp;&nbsp;<input class="form_botao" type="button" id="btn_$nameTop" value="Adicionar" disabled  onclick="addOption('$nameTop','$nameBottom','$sortEnableBottom')">
+EOF;
+
+	$output .= <<<EOF
+					</td>
+				</tr>
+				<tr>
+					<td valign=top>
+EOF;
+
+	$nameBottomLabel = ucwords( str_replace("_", " ", $nameBottom) );
+	$output .= $nameBottomLabel;
+
+	$output .= <<<EOF
+				<br>
+EOF;
+
+	$output .= smarty_function_html_options(array_merge(array(
+											'multiple' => 'true',
+											'name'     => $nameBottom . "[]",
+											'id'       => $nameBottom,
+											'size'     => $size,
+											'style'    => $style,
+											'onChange' => "enableButton('" . $nameBottom . "');$onChangeBottom",
+											'options'  => $arrayBottom),
+											$extraParams),
+										$smarty);
+
+	$output .= <<<EOF
+					</td>
+				</tr>
+				<tr>
+					<td align=right>
+						<input class="form_botao" type="button" id="btn_$nameBottom" value="Remover" disabled onclick="removeOptions('$nameBottom', '$nameTop')">
+					</td>
+				</tr>
+				</table>
+EOF;
+
+	if($diffEnable)
+	{
+	$output .= <<<EOF
+				<script>selectDiffMultiple('$nameBottom','$nameTop');</script>
+EOF;
+	}
+
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_file_upload.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_file_upload.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_file_upload.php	(revision 795)
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Insere o componente que permite o upload de um ou mais arquivos. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ *  - name: (obrigatório) o nome do componente (que será do tipo "file") que irá conter os arquivos; 
+ *  - max: (opcional) número máximo de arquivos que podem ser enviados simultaneamente. Se nenhum parâmetro for passado, pode-se enviar quantos arquivos forem necessários.
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo que insere o componente 
+ * @access public
+ */
+function smarty_function_wf_file_upload($params, &$smarty)
+{
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'max' => -1);
+	$extractParams = array(
+		'name',
+		'max');
+	
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_file_upload] missing required parameter(s): $required", E_USER_ERROR);
+	
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+	
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+	
+	$divName = $name . "_div";
+	$id = $name;
+	$name .= '[]';
+
+	$output = <<<EOF
+		<input id="$id" type="file" name="$name" />
+		<div id="$divName"></div>
+		<script>
+	    var multi_selector_$id = new MultiSelector(document.getElementById('$divName'), $max);
+	    multi_selector_$id.addElement(document.getElementById('$id'), '$name');
+		</script>
+EOF;
+	
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_duplex_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_duplex_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_duplex_init.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_select_duplex_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/wf_select_duplex.js';
+	$output = <<<EOF
+	<script language="javascript1.2" src="$jsFile"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_users_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_users_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_users_init.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_select_users_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/userControl.js';
+$output = <<<EOF
+	<script language="javascript1.2" src="$jsFile"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/prefilter.wf_default_template.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/prefilter.wf_default_template.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/prefilter.wf_default_template.php	(revision 2372)
@@ -0,0 +1,42 @@
+<?php
+/**
+* This plugin get the current template and adds a header and footer located in "$localPath".
+* @package Smarty
+* @subpackage wf_plugins
+* @version:		1.0	
+* @author		Everton Flávio Rufino Seára - rufino@celepar.pr.gov.br
+* @author		Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+* @param string $tpl Template de entrada
+* @param object &$smarty Instância do objeto smarty em uso 
+* @return string tpl Template with header and footer
+* @access public
+*/
+function smarty_prefilter_wf_default_template($tpl, &$smarty) {
+
+
+	// Get the default smarty delimiter comment
+	$dl = $smarty->left_delimiter;
+	$dr = $smarty->right_delimiter;
+
+	// This first regex just remove the template's comments
+	$pattern = "/{$dl}\*[\s\S]*?\*{$dr}/";
+	// This second one search by the smarty plugin {wf_default_template}
+	$pattern2 = "/{$dl}\s*wf_default_template\s*{$dr}/";
+
+	// Remove the comments
+	$subject = preg_replace($pattern, "", $tpl);
+
+	// Search by the plugin and adds the header and footer if it was found
+	if (preg_match($pattern2, $subject) > 0)
+	{
+		/* get the header and footer location */
+		$templateServer = &Factory::getInstance('TemplateServer');
+		$header = $templateServer->getSystemFile('processes/header.tpl');
+		$footer = $templateServer->getSystemFile('processes/footer.tpl');
+		$tpl = "{include file='{$header}'}" . $tpl . "{include file='{$footer}'}";
+	}
+
+	return $tpl;
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_redir_menu.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_redir_menu.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_redir_menu.php	(revision 2372)
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Este plugin Smarty irá gerar uma lista com as atividades start e standalone,
+ * do processo em execução, em formato de caixa de seleção. Útil para colocar no
+ * formulário de uma atividade interativa, para que os usuários tenham opção de
+ * mover para outras atividades, sem ter que retornar para a interface de usuário, aba "processos".
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @author Mauricio Luiz Viani
+ * @param array $params Array de parametros
+ * - label : (opcional) uma string que será usada como cabeçalho de campo.
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string codigo que insere o selectbox
+ * @access public
+ */
+function smarty_function_wf_redir_menu($params, &$smarty)
+{
+ 	$defaultValues = array(
+		'label' => '');
+	$extractParams = array(
+		'label');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+    $base_url = $GLOBALS['phpgw_info']['server']['webserver_url'];
+	$user_activities = $GLOBALS['workflow']['wf_user_activities']['data'];
+	$pid = $GLOBALS['workflow']['wf_process_id'];
+
+	$select_tag = "<select name=\"redir_menu\" id=\"redir_menu\" onchange=\"redir_link();\" \"print_result=false;\">";
+	$select_tag .= "<option value=\"0\">------- Atividades -------</option>";
+	$user_activities = $GLOBALS['workflow']['wf_user_activities']['data'];
+	$pid = $GLOBALS['workflow']['wf_process_id'];
+
+	foreach($user_activities as $key => $line) {
+		if ($line['wf_p_id'] === $pid) {
+			if ($line['wf_menu_path'] != '!')
+				$select_tag .= "<option value=\"" . $line['wf_activity_id'] . "\">". $line['wf_name'] . "</option>";
+		}
+	}
+
+	$select_tag .= "<option value=\"0\">------- Interfaces -------</option>";
+	$select_tag .= "<option value=\"ce\">Tarefas Pendentes</option>";
+	$select_tag .= "<option value=\"pr\">Processos</option>";
+	$select_tag .= "<option value=\"ac\">Acompanhamento</option>";
+	$select_tag .= "<option value=\"ap\">Aplicações Externas</option>";
+	$select_tag .= "<option value=\"og\">Organograma</option>";
+
+	$user_is_admin = Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']);
+	if ($user_is_admin || ($GLOBALS['phpgw']->acl->check('admin_workflow',1,'workflow'))) {
+		$select_tag .= "<option value=\"ad\">Administração</option>";
+	}
+	if ($user_is_admin ||  ($GLOBALS['phpgw']->acl->check('monitor_workflow',1,'workflow'))) {
+		$select_tag .= "<option value=\"mo\">Monitoramento</option>";
+	}
+
+	$select_tag .= "</select>";
+
+	$output = '<table border="0" align="right"><tr><td>' . $label . '</td><td>';
+	$output .= $select_tag . "</td></tr></table>";
+	$output .= <<<EOF
+	<script language="javascript1.2">
+		function redir_link() {
+			elem = document.getElementById("redir_menu");
+			activity = elem.options[elem.options.selectedIndex].value;
+			switch (activity){
+   				case '0' :
+      				break;
+   				case 'ce' :
+			   		location.href = "$base_url/workflow/index.php?start_tab=0";
+      				break;
+   				case 'pr' :
+      				location.href = "$base_url/workflow/index.php?start_tab=1";
+      				break;
+   				case 'ac' :
+      				location.href = "$base_url/workflow/index.php?start_tab=2";
+      				break;
+   				case 'ap' :
+      				location.href = "$base_url/workflow/index.php?start_tab=3";
+      				break;
+   				case 'og' :
+      				location.href = "$base_url/workflow/index.php?start_tab=4";
+      				break;
+      			case 'ad' :
+      				location.href = "$base_url/index.php?menuaction=workflow.ui_adminprocesses.form";
+      				break;
+				case 'mo' :
+      				location.href = "$base_url/index.php?menuaction=workflow.ui_monitors.form";
+      				break;
+			    default :
+			   		location.href = "$base_url/index.php?menuaction=workflow.run_activity.go&activity_id=" + activity;
+			}
+		}
+	</script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_city_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_city_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_city_init.php	(revision 795)
@@ -0,0 +1,28 @@
+<?php
+/** 
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_select_city_init($params, &$smarty)
+{
+	$webServer = $GLOBALS['phpgw_info']['server']['webserver_url'];
+	$jsFilePath = $webServer . '/workflow/js';
+	$localFile = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'js' . SEP . 'jscode' . SEP . 'connector.js';
+	$size = 0;
+	if (@file_exists($localFile))
+		$size = filesize($localFile);
+
+$output = <<<EOF
+<input type="hidden" value="" id="txt_loading">
+<script language='javascript'>var _web_server_url = '$webServer';</script>
+<script type="text/javascript" src="$jsFilePath/jscode/connector.js?$size"></script>
+<script type="text/javascript" src="$jsFilePath/jscode/wf_select_city.js"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_rtf.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_rtf.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_rtf.php	(revision 795)
@@ -0,0 +1,44 @@
+<?php
+/** 
+ * Este plugin insere um editor de texto rico (RTF). Foram feitas modificações no javascript original do editor que permitem a utilização de mais de um editor por página.
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - name: o nome que o editor de texto rico irá receber. 
+ * - text: o conteúdo inicial do editor.
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo que insere o editor. 
+ * @access public 
+ */
+function smarty_function_wf_rtf($params, &$smarty)
+{
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'text' => "");
+	$extractParams = array(
+		'name',
+		'text');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_rtf] missing required parameter(s): $required", E_USER_ERROR);
+	
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+	
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+	
+	$output = <<<EOF
+<textarea name="$name" id="$name">{$text}</textarea>
+<script language="javascript1.2">initDocument('$name');</script>
+EOF;
+
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_calendar_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_calendar_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_calendar_init.php	(revision 795)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Insere código que regerencia arquivos js e css do jscalendar.
+ * 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @author  boots
+ * @author  Sidnei Augusto Drovetto Junior
+ * @version  1.1.2
+ * @link http://www.dynarch.com/projects/calendar/ {dhtml calendar}
+ *          (dynarch.com)
+ * @param array $params Array de parametros
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string $_out codigo a ser inserido 
+ * @access public
+ */
+function smarty_function_wf_calendar_init($params, &$smarty)
+{
+	$path = "";
+	if (isset($params['path']))
+		$path = $params['path'] . "/";
+	else
+		$path = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscalendar/';
+	$defaults = array(
+		'css' => $path . 'calendar-blue.css',
+		'src' => $path . 'calendar.js',
+		'lang' => $path . 'calendar-br.js',
+		'setup_src' => $path . 'calendar-setup.js',
+		'input_format' => $path . 'calendar-input.js');
+	
+	foreach ($defaults as $field=>$default)
+	{
+		$_field = "_$field";
+		if (array_key_exists($field, $params))
+		{
+			$$_field = (empty($params[$field])) ? $default : $params[$field];
+		}
+		else
+		{
+			$$_field = $default;
+		}
+	}
+
+$_out = <<<EOF
+	<link rel="stylesheet" type="text/css" media="all" href="{$_css}">
+	<script type="text/javascript" src="{$_src}"></script>
+	<script type="text/javascript" src="{$_lang}"></script>
+	<script type="text/javascript" src="{$_setup_src}"></script>
+	<script type="text/javascript" src="{$_input_format}"></script>
+EOF;
+
+	return $_out;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_generic_select_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_generic_select_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_generic_select_init.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros (vazio)
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo com referencias aos javascripts. 
+ * @access public 
+ */
+function smarty_function_wf_generic_select_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/generic_select.js';
+$output = <<<EOF
+	<script language="javascript1.2" src="$jsFile"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_duplex.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_duplex.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_duplex.php	(revision 795)
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Este plugin insere dois select boxes de seleções múltiplas que permitem ao usuário cadastrar vários ítens de uma lista dada. O primeiro select é utilizado para mostrar todos os ítens "cadastráveis". Pode-se selecionar um ou mais ítens que são transferidos para o segundo select através do botão ">>". 
+ * O mesmo pode ser feito do segundo select para o primeiro através do botão "" 
+ * A idéia é realizar o cadastro de todos os ítens contidos no segundo select ao final das operações.  
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - nameLeft: o nome que o select da esquerda irá receber. 
+ * - nameRight: o nome que o select da direita irá receber. 
+ * - arrayLeft: lista dos ítens a serem carregados no select da esquerda. 
+ * - arrayRight: lista dos ítens a serem carregados no select da direita. 
+ * - size: tamanho dos select boxes. 
+ * - diffEnable: valor indicando se deve-se executar o diff entre os select boxes. 
+ * - style: para definir os estilos dos select boxes
+ * @param object &$smarty Instância do objeto smarty em uso 
+ * @return string $output codigo que insere os select boxes. 
+ * @access public 
+ */
+function smarty_function_wf_select_duplex($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+
+	$requiredParams = array(
+		'nameLeft',
+		'nameRight');
+	$defaultValues = array(
+		'size'       => 8,
+		'style'      => "width:200px",
+		'nameLeft'   => "_disponiveis_" . rand(),
+		'nameRight'  => "_cadastrados_" . rand(),
+		'diffEnable' => true);
+	$extractParams = array(
+		'nameLeft',
+		'nameRight',
+		'arrayLeft',
+		'arrayRight',
+		'size',
+		'diffEnable',
+		'style');
+	
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_duplex] missing required parameter(s): $required", E_USER_ERROR);
+	
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+	
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+	
+	/* parâmetros extras são "acumulados" em uma única variável */
+	$extraParams = array();
+	foreach ($params as $key => $value_params)
+		if (!in_array($key, $extractParams))
+			$extraParams[$key] = $value_params;
+
+	$output = <<<EOF
+				<table><tr>
+					<td valign=bottom>
+EOF;
+
+	$nameLeftLabel = ucwords( str_replace("_", " ", $nameLeft) );
+	$output .= $nameLeftLabel;
+
+	$output .= <<<EOF
+				<br>
+EOF;
+
+	$output .= smarty_function_html_options(array_merge(array(
+											'multiple' => 'true',
+											'name'     => $nameLeft . "[]",
+											'id'       => $nameLeft,
+											'size'     => $size,
+											'style'    => $style,
+											'options'  => $arrayLeft), $extraParams),
+										$smarty);
+	$output .= <<<EOF
+					</td>
+					<td valign=middle>
+EOF;
+
+	$output .= <<<EOF
+			<input type="hidden" name="$name" id="$name" value="$id_value"/>
+			<input class="form_botao" type="button" value=">>" onclick="moveOptions('$nameLeft','$nameRight')">
+			<br>
+			<input class="form_botao" type="button" value="<<" onclick="moveOptions('$nameRight','$nameLeft')">
+EOF;
+
+	$output .= <<<EOF
+					</td>
+					<td valign=bottom>
+EOF;
+
+	$nameRightLabel = ucwords( str_replace("_", " ", $nameRight) );
+	$output .= $nameRightLabel;
+
+	$output .= <<<EOF
+				<br>
+EOF;
+
+	$output .= smarty_function_html_options(array_merge(array(
+											'multiple' => 'true',
+											'name'     => $nameRight . "[]",
+											'id'       => $nameRight,
+											'size'     => $size,
+											'style'    => $style,
+											'options'  => $arrayRight), $extraParams),
+										$smarty);
+
+	$output .= <<<EOF
+					</td>
+				</tr></table>
+EOF;
+
+	if($diffEnable)
+	{
+	$output .= <<<EOF
+				<script>selectDiff('$nameRight','$nameLeft');</script>					
+EOF;
+	}
+
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_users.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_users.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_select_users.php	(revision 2372)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Insere código HTML que permite a seleção de vários usuários e grupos
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * - name : o nome do campo que irá receber os usuários e grupos selecionados
+ * - value : usuários e grupos previamente selecionados. Deve estar no formato de matriz, seguindo o seguinte padrão: ::$matriz["u123"]="Nome do usuário 123" ; $matriz["g321"]="Nome do grupo 321" e, assim por diante.
+ * - hide_groups : indica se deve-se omitir os grupos na tela de seleção.
+ * - organization : nome da organização que estará previamente selecionada.
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string $output codigo html.
+ * @access public
+ */
+function smarty_function_wf_select_users($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+	$imagesPath = substr(Factory::getInstance('TemplateServer')->generateImageLink(''), 0, -1);
+	$requiredParams = array(
+		'name');
+	$defaultValues = array(
+		'hide_groups' => false,
+		'organization' => null,
+		'hide_organizations' => false,
+		'hide_sectors' => false,
+		'value' => array());
+	$extractParams = array(
+		'name',
+		'value');
+
+	/* verifica se todos os parâmetros obrigatórios foram passados */
+	foreach ($requiredParams as $required)
+		if (!array_key_exists($required, $params) || (empty($params[$required])))
+			$smarty->trigger_error("[wf_select_users] missing required parameter(s): $required", E_USER_ERROR);
+
+	/* atribui valores default para os parâmetros não passados */
+	foreach ($defaultValues as $key => $value)
+		if (!isset($params[$key]))
+			$params[$key] = $value;
+
+	/* extrai alguns parâmetros da matriz de parâmetros */
+	foreach ($extractParams as $extract)
+		$$extract = $params[$extract];
+
+	$name_desc = $name . "_desc";
+
+	$extraParams = 'usePreffix=1';
+	if ($params['hide_groups'] == true)
+		$extraParams .= "&hidegroups=1";
+	if ($params['organization'] != null)
+		$extraParams .= "&change_org=True&organization=" . $params['organization'];
+	if ($params['hide_organizations'] == true)
+		$extraParams .= "&hideOrganizations=1";
+	if ($params['hide_sectors'] == true)
+		$extraParams .= "&hideSectors=1";
+
+	$output = '<table border="0"><tr><td>';
+	$output .= smarty_function_html_options(array(
+											'name' => $name,
+											'options' => $value,
+											'multiple' => 'multiple',
+											'style' => 'width:250px;height:200px',
+											'id' => $name,
+											'print_result' => false),
+										$smarty);
+	$output .= "</td><td>";
+	$output .= <<<EOF
+		<a href='javascript:void(0)' onclick="openParticipants(500, 270, '$name', '$extraParams');"><img border="0" src="$imagesPath/add_group.png"></a>
+		<br />
+		<a href='javascript:void(0)' onclick="openParticipants(500, 270, '$name', '$extraParams');">Adicionar</a>
+		<br /><br />
+		<a href='javascript:void(0)' onclick="delUsers('$name');"><img border="0" src="$imagesPath/delete_group.png"></a>
+		<br />
+		<a href='javascript:void(0)' onclick="delUsers('$name');">Remover</a>
+EOF;
+	$output .= "</td></tr></table>";
+	return $output;
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_file_upload_init.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_file_upload_init.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/wf_plugins/function.wf_file_upload_init.php	(revision 795)
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Insere código que referencia arquivos de javascript responsáveis pela funcionalidade. 
+ * @package Smarty
+ * @subpackage wf_plugins
+ * @param array $params Array de parametros
+ * @param object &$smarty Instância do objeto smarty em uso
+ * @return string $output codigo com referencias aos javascripts  
+ * @access public
+ */
+function smarty_function_wf_file_upload_init($params, &$smarty)
+{
+	$jsFile = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/workflow/js/jscode/wf_file_upload.js';
+$output = <<<EOF
+	<script language="javascript1.2" src="$jsFile"></script>
+EOF;
+	return $output;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/smarty/Config_File.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/smarty/Config_File.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/smarty/Config_File.class.php	(revision 795)
@@ -0,0 +1,389 @@
+<?php
+
+/**
+ * Config_File class.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://smarty.php.net/
+ * @version 2.6.19
+ * @copyright Copyright: 2001-2005 New Digital Group, Inc.
+ * @author Andrei Zmievski <andrei@php.net>
+ * @access public
+ * @package Smarty
+ */
+
+/* $Id: Config_File.class.php 760 2008-04-03 19:15:17Z drovetto $ */
+
+/**
+ * Config file reading class
+ * @package Smarty
+ */
+class Config_File {
+    /**#@+
+     * Options
+     * @var boolean
+     */
+    /**
+     * Controls whether variables with the same name overwrite each other.
+     */
+    var $overwrite        =    true;
+
+    /**
+     * Controls whether config values of on/true/yes and off/false/no get
+     * converted to boolean values automatically.
+     */
+    var $booleanize        =    true;
+
+    /**
+     * Controls whether hidden config sections/vars are read from the file.
+     */
+    var $read_hidden     =    true;
+
+    /**
+     * Controls whether or not to fix mac or dos formatted newlines.
+     * If set to true, \r or \r\n will be changed to \n.
+     */
+    var $fix_newlines =    true;
+    /**#@-*/
+
+    /** @access private */
+    var $_config_path    = "";
+    var $_config_data    = array();
+    /**#@-*/
+
+    /**
+     * Constructs a new config file class.
+     *
+     * @param string $config_path (optional) path to the config files
+     */
+    function Config_File($config_path = NULL)
+    {
+        if (isset($config_path))
+            $this->set_path($config_path);
+    }
+
+
+    /**
+     * Set the path where configuration files can be found.
+     *
+     * @param string $config_path path to the config files
+     */
+    function set_path($config_path)
+    {
+        if (!empty($config_path)) {
+            if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
+                $this->_trigger_error_msg("Bad config file path '$config_path'");
+                return;
+            }
+            if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
+                $config_path .= DIRECTORY_SEPARATOR;
+            }
+
+            $this->_config_path = $config_path;
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the file, section, and variable name.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @param string $var_name (optional) variable to get info for
+     * @return string|array a value or array of values
+     */
+    function get($file_name, $section_name = NULL, $var_name = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else {
+            $file_name = $this->_config_path . $file_name;
+            if (!isset($this->_config_data[$file_name]))
+                $this->load_file($file_name, false);
+        }
+
+        if (!empty($var_name)) {
+            if (empty($section_name)) {
+                return $this->_config_data[$file_name]["vars"][$var_name];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
+                    return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
+                else
+                    return array();
+            }
+        } else {
+            if (empty($section_name)) {
+                return (array)$this->_config_data[$file_name]["vars"];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
+                    return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
+                else
+                    return array();
+            }
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the key.
+     *
+     * @param $file_name string config key (filename/section/var)
+     * @return string|array same as get()
+     * @uses get() retrieves information from config file and returns it
+     */
+    function &get_key($config_key)
+    {
+        list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
+        $result = &$this->get($file_name, $section_name, $var_name);
+        return $result;
+    }
+
+    /**
+     * Get all loaded config file names.
+     *
+     * @return array an array of loaded config file names
+     */
+    function get_file_names()
+    {
+        return array_keys($this->_config_data);
+    }
+
+
+    /**
+     * Get all section names from a loaded file.
+     *
+     * @param string $file_name config file to get section names from
+     * @return array an array of section names from the specified file
+     */
+    function get_section_names($file_name)
+    {
+        $file_name = $this->_config_path . $file_name;
+        if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        return array_keys($this->_config_data[$file_name]["sections"]);
+    }
+
+
+    /**
+     * Get all global or section variable names.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @return array an array of variables names from the specified file/section
+     */
+    function get_var_names($file_name, $section = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        if (empty($section))
+            return array_keys($this->_config_data[$file_name]["vars"]);
+        else
+            return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
+    }
+
+
+    /**
+     * Clear loaded config data for a certain file or all files.
+     *
+     * @param string $file_name file to clear config data for
+     */
+    function clear($file_name = NULL)
+    {
+        if ($file_name === NULL)
+            $this->_config_data = array();
+        else if (isset($this->_config_data[$file_name]))
+            $this->_config_data[$file_name] = array();
+    }
+
+
+    /**
+     * Load a configuration file manually.
+     *
+     * @param string $file_name file name to load
+     * @param boolean $prepend_path whether current config path should be
+     *                              prepended to the filename
+     */
+    function load_file($file_name, $prepend_path = true)
+    {
+        if ($prepend_path && $this->_config_path != "")
+            $config_file = $this->_config_path . $file_name;
+        else
+            $config_file = $file_name;
+
+        ini_set('track_errors', true);
+        $fp = @fopen($config_file, "r");
+        if (!is_resource($fp)) {
+            $this->_trigger_error_msg("Could not open config file '$config_file'");
+            return false;
+        }
+
+        $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
+        fclose($fp);
+
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * Store the contents of a file manually.
+     *
+     * @param string $config_file file name of the related contents
+     * @param string $contents the file-contents to parse
+     */
+    function set_file_contents($config_file, $contents)
+    {
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * parse the source of a configuration file manually.
+     *
+     * @param string $contents the file-contents to parse
+     */
+    function parse_contents($contents)
+    {
+        if($this->fix_newlines) {
+            // fix mac/dos formatted newlines
+            $contents = preg_replace('!\r\n?!', "\n", $contents);
+        }
+
+        $config_data = array();
+        $config_data['sections'] = array();
+        $config_data['vars'] = array();
+
+        /* reference to fill with data */
+        $vars =& $config_data['vars'];
+
+        /* parse file line by line */
+        preg_match_all('!^.*\r?\n?!m', $contents, $match);
+        $lines = $match[0];
+        for ($i=0, $count=count($lines); $i<$count; $i++) {
+            $line = $lines[$i];
+            if (empty($line)) continue;
+
+            if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
+                /* section found */
+                if (substr($match[1], 0, 1) == '.') {
+                    /* hidden section */
+                    if ($this->read_hidden) {
+                        $section_name = substr($match[1], 1);
+                    } else {
+                        /* break reference to $vars to ignore hidden section */
+                        unset($vars);
+                        $vars = array();
+                        continue;
+                    }
+                } else {                    
+                    $section_name = $match[1];
+                }
+                if (!isset($config_data['sections'][$section_name]))
+                    $config_data['sections'][$section_name] = array('vars' => array());
+                $vars =& $config_data['sections'][$section_name]['vars'];
+                continue;
+            }
+
+            if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
+                /* variable found */
+                $var_name = rtrim($match[1]);
+                if (strpos($match[2], '"""') === 0) {
+                    /* handle multiline-value */
+                    $lines[$i] = substr($match[2], 3);
+                    $var_value = '';
+                    while ($i<$count) {
+                        if (($pos = strpos($lines[$i], '"""')) === false) {
+                            $var_value .= $lines[$i++];
+                        } else {
+                            /* end of multiline-value */
+                            $var_value .= substr($lines[$i], 0, $pos);
+                            break;
+                        }
+                    }
+                    $booleanize = false;
+
+                } else {
+                    /* handle simple value */
+                    $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
+                    $booleanize = $this->booleanize;
+
+                }
+                $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
+            }
+            /* else unparsable line / means it is a comment / means ignore it */
+        }
+        return $config_data;
+    }
+
+    /**#@+ @access private */
+    /**
+     * @param array &$container
+     * @param string $var_name
+     * @param mixed $var_value
+     * @param boolean $booleanize determines whether $var_value is converted to
+     *                            to true/false
+     */
+    function _set_config_var(&$container, $var_name, $var_value, $booleanize)
+    {
+        if (substr($var_name, 0, 1) == '.') {
+            if (!$this->read_hidden)
+                return;
+            else
+                $var_name = substr($var_name, 1);
+        }
+
+        if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
+            $this->_trigger_error_msg("Bad variable name '$var_name'");
+            return;
+        }
+
+        if ($booleanize) {
+            if (preg_match("/^(on|true|yes)$/i", $var_value))
+                $var_value = true;
+            else if (preg_match("/^(off|false|no)$/i", $var_value))
+                $var_value = false;
+        }
+
+        if (!isset($container[$var_name]) || $this->overwrite)
+            $container[$var_name] = $var_value;
+        else {
+            settype($container[$var_name], 'array');
+            $container[$var_name][] = $var_value;
+        }
+    }
+
+    /**
+     * @uses trigger_error() creates a PHP warning/error
+     * @param string $error_msg
+     * @param integer $error_type one of
+     */
+    function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Config_File error: $error_msg", $error_type);
+    }
+    /**#@-*/
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_gui.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_gui.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_gui.inc.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'GUI' . SEP . 'GUI.php');
+
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_gui extends GUI
+	{  /**
+		 * Construtor da classe workflow_gui
+		 * @access public
+		 * @return object
+		 */
+		function workflow_gui()
+		{
+			parent::GUI(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_userinterface.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_userinterface.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_userinterface.inc.php	(revision 2372)
@@ -0,0 +1,1142 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ * @author Sidnei Augusto Drovetto - drovetto@gmail.com
+ */
+class bo_userinterface extends bo_ajaxinterface
+{
+	/**
+	 * @var object Acesso à camada Model
+	 * @access public
+	 */
+	var $so;
+
+	/**
+	 * @var array Informações sobre a organização do usuário
+	 * @access private
+	 */
+	private $organizationInfo;
+
+	/**
+	 * Construtor da classe bo_userinterface
+	 * @access public
+	 * @return object
+	 */
+	function bo_userinterface()
+	{
+		parent::bo_ajaxinterface();
+		$this->so = &Factory::getInstance('so_userinterface');
+		$GLOBALS['ajax']->gui = &Factory::newInstance('GUI');
+	}
+
+	/**
+	 * Retorna os processos do usuário
+	 * @access public
+	 * @return mixed retorna uma string com uma mensagem de erro ou um array com dados dos processos
+	 */
+	function processes()
+	{
+		$account_id = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$result = $GLOBALS['ajax']->gui->gui_list_user_activities($account_id, '0', '-1', "wf_menu_path__ASC, ga.wf_name__ASC", '', '', '', true, true, true, '');
+
+		$errorMessage = $GLOBALS['ajax']->gui->get_error(false);
+		if (!empty($errorMessage))
+		{
+			$this->disconnect_all();
+			return array('error' => $errorMessage);
+		}
+
+		$recset = array();
+		$webserver_url = $_SESSION['phpgw_info']['workflow']['server']['webserver_url'];
+
+		$templateServer =& Factory::getInstance('TemplateServer');
+		foreach ($result['data'] as $line)
+		{
+			/* don't include activities whose menu_path is equal to ! */
+			if ($line['wf_menu_path'] === '!')
+				continue;
+
+			if (file_exists(GALAXIA_PROCESSES . '/' . $line['wf_normalized_name'] . '/resources/icon.png'))
+				$iconweb = $webserver_url . '/workflow/redirect.php?pid=' . $line['wf_p_id'] . '&file=/icon.png';
+			else
+				$iconweb = $templateServer->generateImageLink('navbar.png');
+			$procname_ver = $line['wf_normalized_name'];
+			if (!isset($recset[$procname_ver]))
+			{
+				$recset[$procname_ver]['wf_p_id'] = $line['wf_p_id'];
+				$recset[$procname_ver]['wf_procname'] = $line['wf_procname'];
+				$recset[$procname_ver]['wf_version'] = $line['wf_version'];
+				$recset[$procname_ver]['wf_is_active'] = $line['wf_is_active'];
+				$recset[$procname_ver]['wf_iconfile'] = $iconweb;
+				if ($_SESSION['phpgw_info']['workflow']['server']['use_https'] > 0)
+				{
+					$GLOBALS['ajax']->gui->wf_security->loadConfigValues($line['wf_p_id']);
+					$recset[$procname_ver]['useHTTPS'] = $GLOBALS['ajax']->gui->wf_security->processesConfig[$line['wf_p_id']]['execute_activities_using_secure_connection'];
+				}
+				else
+					$recset[$procname_ver]['useHTTPS'] = 0;
+			}
+			$recset[$procname_ver][] = array('wf_activity_id' 	=> $line['wf_activity_id'],
+										'wf_name' 			=> $line['wf_name'],
+										'wf_menu_path' 		=> $line['wf_menu_path'],
+										'wf_type' 			=> $line['wf_type'],
+										'wf_is_autorouted' 	=> $line['wf_is_autorouted'],
+										'wf_is_interactive' => $line['wf_is_interactive']);
+		}
+
+		$recset = array_values($recset);
+		usort($recset, create_function('$a,$b', 'return strcasecmp($a[\'wf_procname\'] . $a[\'wf_version\'],$b[\'wf_procname\'] . $b[\'wf_version\']);'));
+
+		$this->disconnect_all();
+		return $recset;
+	}
+
+	/**
+	 * Informacoes sobre o processo
+	 * @param $params parametros
+	 * @return array
+	 * @access public
+	 */
+	function process_about($params)
+	{
+		$pid = $params['pid'];
+		$result = array();
+
+		$process = &Factory::newInstance('Process');
+		$process->getProcess($pid);
+		$result['wf_procname'] = $process->name;
+		$result['wf_version'] = $process->version;
+		$result['wf_description'] = $process->description;
+
+		$activ_manager = &Factory::newInstance('ActivityManager');
+		$result['wf_activities'] = $activ_manager->get_process_activities($pid);
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Fornece os dados para a contrução da interface de Tarefas Pendentes
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return array Contendo os dados para construção da interface ou uma mensagem de erro
+	 * @access public
+	 */
+	function inbox($params)
+	{
+		$preferences = $_SESSION['phpgw_info']['workflow']['user']['preferences'];
+
+		/* initialize Paging Class */
+		$itemsPerPage = isset($preferences['ui_items_per_page']) ? $preferences['ui_items_per_page'] : 15;
+		$lightVersion = ((isset($preferences['use_light_interface']) ? $preferences['use_light_interface'] : 0) == 1);
+		$paging = Factory::newInstance('Paging', $itemsPerPage, $_POST);
+
+		/* define the sorting */
+		$sort = 'wf_act_started__DESC';
+		if ($params['sort'])
+			$sort = $params['sort'];
+		else
+			if (isset($preferences['inbox_sort']))
+				$sort = $preferences['inbox_sort'];
+
+		/* make sure that the sorting parameter is one of the expected values */
+		$sortFields = explode('__', strtolower($sort));
+		if (count($sortFields) != 2)
+			$sort = 'wf_act_started__DESC';
+		else
+			if (!(in_array($sortFields[0], array('wf_act_started', 'wf_procname', 'wf_name', 'insname', 'wf_priority')) && in_array($sortFields[1], array('desc', 'asc'))))
+				$sort = 'wf_act_started__DESC';
+			elseif(strpos($sort, 'wf_act_started') === false){
+				$sort = $sort.', wf_act_started__ASC';
+			}
+
+		$params['sort'] = $sort;
+
+		/* get other parameters */
+		$pid = (int) $params['pid'];
+		$search_term = $params['search_term'];
+		$account_id = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$result = $GLOBALS['ajax']->gui->gui_list_user_instances($account_id, 0, -1, $sort, $search_term, "ga.wf_is_interactive = 'y'", false, $pid, true, false, true, false, false, false);
+
+		$errorMessage = $GLOBALS['ajax']->gui->get_error(false);
+		if (!empty($errorMessage))
+		{
+			$this->disconnect_all();
+			return array('error' => $errorMessage);
+		}
+
+		$output = array();
+		$output['sort_param'] = str_replace(', wf_act_started__ASC', '', $sort);
+		$output['instances'] = array();
+		$output['processes'] = array();
+		$list_process = array();
+		$actionKeys = array(
+			'run',
+			'viewrun',
+			'view',
+			'send',
+			'release',
+			'grab',
+			'exception',
+			'resume',
+			'abort',
+			'monitor');
+
+		foreach ($result['data'] as $row)
+		{
+			/* don't show the instance if the user can't run it */
+			if (($row['wf_user'] != $account_id) && ($row['wf_user'] != '*'))
+				continue;
+			if (($row['wf_status'] == 'active') || ($row['wf_status'] == 'exception'))
+			{
+				$availableActions = $GLOBALS['ajax']->gui->getUserActions(
+							$account_id,
+							$row['wf_instance_id'],
+							$row['wf_activity_id'],
+							$row['wf_readonly'],
+							$row['wf_p_id'],
+							$row['wf_type'],
+							$row['wf_is_interactive'],
+							$row['wf_is_autorouted'],
+							$row['wf_act_status'],
+							$row['wf_owner'],
+							$row['wf_status'],
+							$row['wf_user']);
+
+				$row['viewRunAction'] = false;
+				if (isset($availableActions['viewrun']))
+					$row['viewRunAction'] = array('viewActivityID' => $availableActions['viewrun']['link'], 'height' => $availableActions['viewrun']['iframe_height']);
+
+				foreach ($actionKeys as $key)
+					$availableActions[$key] = (isset($availableActions[$key]));
+
+				if ($GLOBALS['ajax']->gui->wf_security->processesConfig[$row['wf_p_id']]['disable_advanced_actions'] == 1)
+				{
+					$availableActions['release'] = false;
+					$availableActions['grab'] = false;
+					$availableActions['exception'] = false;
+					$availableActions['resume'] = false;
+					$availableActions['abort'] = false;
+					$availableActions['monitor'] = false;
+				}
+
+				/* define the advanced actions for javascript usage */
+				$actionsArray = array();
+				$actionsArray[] = array('name' => 'run', 'value' => $availableActions['run'], 'text' => 'Executar');
+				$actionsArray[] = array('name' => 'view', 'value' => $availableActions['view'], 'text' => 'Visualizar');
+				$actionsArray[] = array('name' => 'send', 'value' => $availableActions['send'], 'text' => 'Enviar');
+				$actionsArray[] = array('name' => 'viewrun', 'value' => $availableActions['viewrun'], 'text' => '');
+				$actionsArray[] = ($row['wf_user'] == '*') ?
+					array('name' => 'grab', 'value' => $availableActions['grab'], 'text' => 'Capturar') :
+					array('name' => 'release', 'value' => $availableActions['release'], 'text' => 'Liberar Acesso');
+				$actionsArray[] = ($row['wf_status'] == 'active') ?
+					array('name' => 'exception', 'value' => $availableActions['exception'], 'text' => 'Colocar em Exceção') :
+					array('name' => 'resume', 'value' => $availableActions['resume'], 'text' => 'Retirar de Exceção');
+				$actionsArray[] = array('name' => 'abort', 'value' => $availableActions['abort'], 'text' => 'Abortar');
+
+				$row['wf_actions'] = $actionsArray;
+
+				$row['wf_started'] = date('d/m/Y H:i', $row['wf_started']);
+				$row['wf_act_started'] = date('d/m/Y H:i', $row['wf_act_started']);
+
+				$row['wf_user_fullname'] = '';
+				if ($row['wf_user'] == '*')
+					$row['wf_user_fullname'] = '*';
+				else
+					if ($row['wf_user'] != '')
+						$row['wf_user_fullname'] = Factory::getInstance('WorkflowLDAP')->getName($row['wf_user']);
+
+				/* unset unneeded information */
+				unset($row['wf_ended'], $row['wf_owner'], $row['wf_category'], $row['wf_act_status'], $row['wf_started'], $row['wf_type'], $row['wf_is_interactive'], $row['wf_is_autorouted'], $row['wf_normalized_name'], $row['wf_readonly']);
+				$output['instances'][] = $row;
+			}
+		}
+
+		/* paginate the results */
+		$output['instances'] = $paging->restrictItems($output['instances']);
+		$output['paging_links'] = $paging->commonLinks();
+
+		/* only save different actions set */
+		$actions = array_values(array_map(create_function('$a', 'return unserialize($a);'), array_unique(array_map(create_function('$a', 'return serialize($a[\'wf_actions\']);'), $output['instances']))));
+
+		$actionsArray = array();
+		$userNames = array();
+		$processesInfo = array();
+		$activityNames = array();
+		foreach ($output['instances'] as $key => $value)
+		{
+			$userNames[$value['wf_user']] = $value['wf_user_fullname'];
+			unset($output['instances'][$key]['wf_user_fullname']);
+
+			$processesInfo[$value['wf_p_id']] = array(
+				'name' => $value['wf_procname'] . ' (v' . $value['wf_version'] . ')',
+				'useHTTPS' => (($_SESSION['phpgw_info']['workflow']['server']['use_https'] > 0) ? $GLOBALS['ajax']->gui->wf_security->processesConfig[$value['wf_p_id']]['execute_activities_using_secure_connection'] : 0)
+			);
+			unset($output['instances'][$key]['wf_procname']);
+			unset($output['instances'][$key]['wf_version']);
+
+			$activityNames[$value['wf_activity_id']] = $value['wf_name'];
+			unset($output['instances'][$key]['wf_name']);
+
+			$output['instances'][$key]['wf_actions'] = array_search($value['wf_actions'], $actions);
+			if (is_null($value['insname']))
+				$output['instances'][$key]['insname'] = '';
+		}
+
+		$output['userNames'] = $userNames;
+		$output['processesInfo'] = $processesInfo;
+		$output['activityNames'] = $activityNames;
+		$output['actions'] = $actions;
+
+		/* load all the activities that have at least one instance */
+		$allActivities = $GLOBALS['ajax']->gui->gui_list_user_activities($account_id, 0, -1, "ga.wf_name__ASC", '', "gia.wf_user = '$account_id' OR gia.wf_user = '*'", true);
+		foreach ($allActivities['data'] as $activity)
+			$list_process[$activity['wf_procname'] . " (v" . $activity['wf_version'] . ")"] = $activity['wf_p_id'];
+
+		$this->disconnect_all();
+
+		foreach ($list_process as $processName => $processId)
+			$output['processes'][] = array('name' => $processName, 'pid' => $processId);
+
+		/* some extra params */
+		$output['params'] = $params;
+		$output['light'] = $lightVersion;
+		$output['instancesDigest'] = md5(serialize($output['instances']));
+
+		return $output;
+	}
+
+	/**
+	 * Fornece os dados para a contrução da interface de Tarefas Pendentes (quando os dados estão agrupados)
+	 * @return array Contendo os dados para construção da interface ou uma mensagem de erro
+	 * @access public
+	 */
+	function inbox_group()
+	{
+		$account_id = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$result = $GLOBALS['ajax']->gui->gui_list_user_instances($account_id, 0, -1, 'wf_procname__ASC,wf_name__ASC', '', "ga.wf_is_interactive = 'y'", false, 0, true, false, true, false, false, false);
+
+		$output = array();
+		foreach ($result['data'] as $data)
+		{
+			if (($data['wf_user'] != $account_id) && ($data['wf_user'] != "*"))
+				continue;
+			if (isset($output[$data['wf_activity_id']]))
+				$output[$data['wf_activity_id']]['wf_instances']++;
+			else
+				$output[$data['wf_activity_id']] = array('wf_p_id' => $data['wf_p_id'], 'wf_procname' => $data['wf_procname'], 'wf_version' => $data['wf_version'], 'wf_name' => $data['wf_name'], 'wf_instances' => 1);
+		}
+
+		$errorMessage = $GLOBALS['ajax']->gui->get_error(false);
+		if (!empty($errorMessage))
+		{
+			$this->disconnect_all();
+			return array('error' => $errorMessage);
+		}
+
+		$this->disconnect_all();
+		return array_values($output);
+	}
+
+	/**
+	 * Envia uma instância para próxima atividade
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionSend($params)
+	{
+		$instanceID = (int) $params['instanceID'];
+		$activityID = (int) $params['activityID'];
+		$result = true;
+
+		if (!$GLOBALS['ajax']->gui->gui_send_instance($activityID, $instanceID))
+			$result = array('error' => $GLOBALS['ajax']->gui->get_error(false) . "<br />Você não está autorizado a enviar esta instância.");
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Libera uma instância (atribui a instância para *)
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionRelease($params)
+	{
+		$instanceID = (int) $params['instanceID'];
+		$activityID = (int) $params['activityID'];
+		$result = true;
+
+		if (!$GLOBALS['ajax']->gui->gui_release_instance($activityID, $instanceID))
+			$result = array('error' => $GLOBALS['ajax']->gui->get_error(false) . "<br />Você não está autorizado a liberar esta instância.");
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Captura uma instância (atribui a instância para o usuário atual)
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionGrab($params)
+	{
+		$instanceID = (int) $params['instanceID'];
+		$activityID = (int) $params['activityID'];
+		$result = true;
+
+		if (!$GLOBALS['ajax']->gui->gui_grab_instance($activityID, $instanceID))
+			$result = array('error' => $GLOBALS['ajax']->gui->get_error(false) . "<br />Você não tem permissão para capturar esta instância.");
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Transforma a instância em exceção
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionException($params)
+	{
+		$instanceID = (int) $params['instanceID'];
+		$activityID = (int) $params['activityID'];
+		$result = true;
+
+		if (!$GLOBALS['ajax']->gui->gui_exception_instance($activityID, $instanceID))
+			$result = array('error' => $GLOBALS['ajax']->gui->get_error(false) . "<br />Você não tem permissão para transformar esta instância em exceção.");
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Retira uma instância em exceção
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionResume($params)
+	{
+		$instanceID = (int) $params['instanceID'];
+		$activityID = (int) $params['activityID'];
+		$result = true;
+
+		if (!$GLOBALS['ajax']->gui->gui_resume_instance($activityID, $instanceID))
+			$result = array('error' => $GLOBALS['ajax']->gui->get_error(false) . "<br />Você não tem permissão para retirar de exceção esta instância.");
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Aborta uma instância
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionAbort($params)
+	{
+		$instanceID = (int) $params['instanceID'];
+		$activityID = (int) $params['activityID'];
+		$result = true;
+
+		if (!$GLOBALS['ajax']->gui->gui_abort_instance($activityID, $instanceID))
+			$result = array('error' => $GLOBALS['ajax']->gui->get_error(false) . "<br />Você não tem permissão para abortar esta instância.");
+
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Visualiza dados de uma instância
+	 * @param $params Parâmetros advindos da chamada Ajax
+	 * @return mixed Array contendo uma mensagem de erro ou um booleano (true) informando que a ação foi feita com sucesso
+	 * @access public
+	 */
+	function inboxActionView($params)
+	{
+		$instanceID = $params['instanceID'];
+		$result = $GLOBALS['ajax']->gui->wf_security->checkUserAction(0, $instanceID, 'view');
+
+		$errorMessage = $GLOBALS['ajax']->gui->get_error(false);
+		if (!empty($errorMessage))
+		{
+			$this->disconnect_all();
+			return array('error' => $errorMessage);
+		}
+
+		$instance = &Factory::newInstance('Instance');
+		$instance->getInstance($instanceID);
+
+		$process = &Factory::newInstance('Process');
+		$process->getProcess($instance->pId);
+
+		$result = array(
+			'wf_status' => $instance->status,
+			'wf_p_id' => $instance->pId,
+			'wf_procname' => $process->name,
+			'wf_version' => $process->version,
+			'wf_instance_id' => $instance->instanceId,
+			'wf_priority' => $instance->priority,
+			'wf_owner' => Factory::getInstance('WorkflowLDAP')->getName($instance->owner),
+			'wf_next_activity' => $instance->nextActivity,
+			'wf_next_user' => Factory::getInstance('WorkflowLDAP')->getName($instance->nextUser),
+			'wf_name' => $instance->name,
+			'wf_category' => $instance->category,
+			'wf_started' => date('d/m/Y H:i', $instance->started)
+		);
+
+		$viewActivityID = $GLOBALS['ajax']->gui->gui_get_process_view_activity($instance->pId);
+		if ($viewActivityID !== false)
+			if ($GLOBALS['ajax']->gui->wf_security->checkUserAction($viewActivityID, $instanceID, 'viewrun'))
+				$result['viewRunAction'] = array('viewActivityID' => $viewActivityID, 'height' => $GLOBALS['ajax']->gui->wf_security->processesConfig[$instance->pId]['iframe_view_height'], 'useHTTPS' => (($_SESSION['phpgw_info']['workflow']['server']['use_https'] > 0) ? $GLOBALS['ajax']->gui->wf_security->processesConfig[$instance->pId]['execute_activities_using_secure_connection'] : 0));
+
+    	if ($instance->ended > 0)
+    		$result['wf_ended'] = date('d/m/Y H:i', $instance->ended);
+    	else
+    		$result['wf_ended'] = "";
+
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		foreach ($instance->workitems as $line)
+		{
+    		$line['wf_duration'] = $this->time_diff($line['wf_ended']-$line['wf_started']);
+    		$line['wf_started'] = date('d/m/Y H:i', $line['wf_started']);
+    		$line['wf_ended'] = date('d/m/Y H:i', $line['wf_ended']);
+    		$line['wf_user'] = $ldap->getName($line['wf_user']);
+    		$result['wf_workitems'][] = $line;
+    	}
+
+		foreach ($instance->activities as $line)
+		{
+    		$line['wf_started'] = date('d/m/Y H:i', $line['wf_started']);
+			if ($line['wf_ended'] > 0)
+				$line['wf_ended'] = date('d/m/Y H:i', $line['wf_ended']);
+			else
+				$line['wf_ended'] = "";
+    		$line['wf_user'] = $ldap->getName($line['wf_user']);
+    		$result['wf_activities'][] = $line;
+    	}
+
+    	$show_properties = false;
+
+		$current_user_id = $_SESSION['phpgw_info']['workflow']['account_id'];
+
+		/* check if the current user is a process admin */
+    	$is_admin_process = $GLOBALS['ajax']->acl->check_process_access($current_user_id, $instance->pId);
+    	$is_admin_workflow = $_SESSION['phpgw_info']['workflow']['user_is_admin'];
+		$show_properties = ($is_admin_process || $is_admin_workflow);
+
+		if($show_properties)
+		{
+			foreach ($instance->properties as $key => $value)
+			{
+    			$result['wf_properties']['keys'][] = $key;
+    			$result['wf_properties']['values'][] = wordwrap(htmlspecialchars($value), 80, "<br>", 1);
+    		}
+    	}
+
+		$this->disconnect_all();
+		return $result;
+	}
+
+	/**
+	 * Retorna os idiomas  
+	 * @return array  
+	 * @access public
+	 */	
+	function getLang(){
+			
+		$keys = array();
+		$values = array();
+		$langs = array();
+		foreach($_SESSION['phpgw_info']['workflow']['lang'] as $key => $value) {
+			$keys[] 	= $key;
+			$values[] 	= $value;
+		}
+		array_push($langs,$keys,$values);
+		return $langs;
+	}
+	
+	/**
+	 * Return  a given duration in human readable form, usefull for workitems duration 
+	 * 
+	 *  @param $to
+	 *  @return string a given duration in human readable form, usefull for workitems duration
+	 */
+	function time_diff($to) {
+		$days = (int)($to/(24*3600));
+		$to = $to - ($days*(24*3600));
+		$hours = (int)($to/3600);
+		$to = $to - ($hours*3600);
+		$min = date("i", $to);
+		$to = $to - ($min*60);			
+		$sec = date("s", $to);
+
+		return tra('%1 days, %2:%3:%4',$days,$hours,$min,$sec);
+	}
+	
+	/**
+	 *  Instances
+	 *  @param $params
+	 *  @return string a given duration in human readable form, usefull for workitems duration
+	 *  @access public
+	 */
+	function instances($params)
+	{
+		$preferences = $_SESSION['phpgw_info']['workflow']['user']['preferences'];
+
+		$lightVersion = ((isset($preferences['use_light_interface']) ? $preferences['use_light_interface'] : 0) == 1);
+
+		/* get some parameters */
+		$userID = $_SESSION['phpgw_info']['workflow']['account_id'];
+		$pid = (int) $params['pid'];
+		$active = ($params['active'] == 1);
+
+		$defaultSorting = ($active ? 'wf_act_started__DESC' : 'wf_started__DESC');
+		$availableSortings = $active ?
+			array('wf_act_started', 'wf_procname', 'wf_name', 'insname') :
+			array('wf_started', 'wf_ended', 'wf_procname', 'insname');
+
+		/* define the sorting */
+		$sort = $defaultSorting;
+		if ($params['sort'])
+			$sort = $params['sort'];
+		/* make sure that the sorting parameter is one of the expected values */
+		$sortFields = explode('__', strtolower($sort));
+		if (count($sortFields) != 2)
+			$sort = $defaultSorting;
+		else
+			if (!(in_array($sortFields[0], $availableSortings) && in_array($sortFields[1], array('desc', 'asc'))))
+				$sort = $defaultSorting;
+		$params['sort'] = $sort;
+
+
+		/* retrieve the results */
+		$result = $GLOBALS['ajax']->gui->gui_list_instances_by_owner($userID, 0, -1, $sort, '', '', false, 0, $active, !$active, $active, !$active);
+
+		$errorMessage = $GLOBALS['ajax']->gui->get_error(false);
+		if (!empty($errorMessage))
+		{
+			$this->disconnect_all();
+			return array('error' => $errorMessage);
+		}
+
+		$output['params'] = $params;
+		$output['instances'] = array();
+		$output['processes'] = array();
+		$list_process = array();
+		$cod_process = array();
+
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		$viewActivitiesID = array();
+		foreach ($result['data'] as $row)
+		{
+			if (($pid == 0) || ($row['wf_p_id'] == $pid))
+			{
+				$row['wf_started'] = date('d/m/Y H:i', $row['wf_started']);
+				if ($row['wf_ended'])
+					$row['wf_ended'] = date('d/m/Y H:i', $row['wf_ended']);
+
+				if ($row['wf_act_started'])
+					$row['wf_act_started'] = date('d/m/Y H:i', $row['wf_act_started']);
+
+				$row['wf_user_fullname'] = '';
+				if ($row['wf_user'] != '*' && $row['wf_user'] != '')
+					$row['wf_user_fullname'] = $ldap->getName($row['wf_user']);
+
+				/* load information about the view activity */
+				if (!isset($viewActivitiesID[$row['wf_p_id']]))
+					$viewActivitiesID[$row['wf_p_id']] = $GLOBALS['ajax']->gui->gui_get_process_view_activity($row['wf_p_id']);
+				if ($viewActivitiesID[$row['wf_p_id']] !== false)
+					if ($GLOBALS['ajax']->gui->wf_security->checkUserAction($viewActivitiesID[$row['wf_p_id']], $row['wf_instance_id'], 'viewrun'))
+						$row['viewRunAction'] = array('viewActivityID' => $viewActivitiesID[$row['wf_p_id']], 'height' => $GLOBALS['ajax']->gui->wf_security->processesConfig[$instance->pId]['iframe_view_height']);
+
+				$output['instances'][] = $row;
+			}
+			$processNameAndVersion = $row['wf_procname'] . " (v" . $row['wf_version'] . ")";
+			if (!isset($list_process[$processNameAndVersion]))
+				$list_process[$processNameAndVersion] = array('total' => 1, 'pid' => $row['wf_p_id'], 'name' => $processNameAndVersion);
+			else
+				$list_process[$processNameAndVersion]['total']++;
+		}
+
+		ksort($list_process);
+		$output['processes'] = array_values($list_process);
+
+		$userNames = array();
+		$processesInfo = array();
+		$activityNames = array();
+		foreach ($output['instances'] as $key => $value)
+		{
+			$userNames[$value['wf_user']] = $value['wf_user_fullname'];
+			unset($output['instances'][$key]['wf_user_fullname']);
+
+			$processesInfo[$value['wf_p_id']] = array(
+				'name' => $value['wf_procname'] . ' (v' . $value['wf_version'] . ')',
+				'useHTTPS' => (($_SESSION['phpgw_info']['workflow']['server']['use_https'] > 0) ? $GLOBALS['ajax']->gui->wf_security->processesConfig[$value['wf_p_id']]['execute_activities_using_secure_connection'] : 0)
+			);
+
+			if ($active)
+			{
+				$activityNames[$value['wf_activity_id']] = $value['wf_name'];
+				unset($output['instances'][$key]['wf_name']);
+			}
+
+			if (is_null($value['insname']))
+				$output['instances'][$key]['insname'] = '';
+		}
+
+		$output['userNames'] = $userNames;
+		$output['processesInfo'] = $processesInfo;
+		$output['activityNames'] = $activityNames;
+
+		$output['light'] = $lightVersion;
+
+		if (!isset($params['group_instances']))
+		{
+			/* paginate the result */
+			$itemsPerPage = isset($_SESSION['phpgw_info']['workflow']['user']['preferences']['ui_items_per_page']) ? $_SESSION['phpgw_info']['workflow']['user']['preferences']['ui_items_per_page'] : 15;
+			$paging = Factory::newInstance('Paging', $itemsPerPage, $_POST);
+			$output['instances'] = $paging->restrictItems($output['instances']);
+			$output['paging_links'] = $paging->commonLinks();
+		}
+		else
+			unset($output['instances']);
+
+		$this->disconnect_all();
+
+		return $output;
+	}
+
+	/**
+	 * Aplicacoes externas do usuario
+	 * @return array
+	 * @access public
+	 */
+	function externals()
+	{
+		$webserver_url = $_SESSION['phpgw_info']['workflow']['server']['webserver_url'];
+		$templateServer = &Factory::getInstance('TemplateServer');
+
+		/* load the sites that the user can access */
+		$allowedSites = $this->so->getExternalApplications();
+
+		/* prepare the data for the javascript */
+		$output = array();
+		foreach ($allowedSites as $row)
+		{
+			if ($row['image'] == "")
+				$row['image'] = $templateServer->generateImageLink('navbar.png');
+			else
+				$row['image'] = $webserver_url . '/workflow/redirect.php?file=/external_applications/' . $row['image'];
+
+			if ($row['authentication'] == 1)
+				$row['wf_ext_link'] = (($_SESSION['phpgw_info']['workflow']['server']['use_https'] > 0) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . "$webserver_url/index.php?menuaction=workflow.external_bridge.render&site=" . $row['external_application_id'];
+			else
+				$row['wf_ext_link'] = $row['address'];
+
+			$output[] = $row;
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Verifica se o usuário tem acesso ao Organograma (e se o mesmo está ativo)
+	 * @return mixed true em caso de sucesso ou uma array contendo mensagens sobre o problema (não cadastrado ou organograma não ativo)
+	 * @access private
+	 */
+	private function checkOrgchartAccess()
+	{
+		$this->organizationInfo = $this->so->getUserOrganization($_SESSION['phpgw_info']['workflow']['account_id']);
+		if ($this->organizationInfo === false)
+			return array('warning' => 'Você não está cadastrado em nenhuma organização');
+
+		if ($this->organizationInfo['ativa'] == 'N')
+			return array('warning' => 'Organograma indisponível');
+
+		return true;
+	}
+
+	/**
+	 * Organograma
+	 * @return array com as areas da organizacao 
+	 * @access public
+	 */
+	function orgchart()
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		$this->organizationInfo['areas'] = $this->getHierarchicalArea();
+		return $this->organizationInfo;
+	}
+
+	/**
+	 * Retorna a lista de centros de custo
+	 * @return array Lista de centros de custo
+	 * @access public
+	 */
+	function getCostCenters()
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		return $this->so->getCostCenters($this->organizationInfo['organizacao_id']);
+	}
+
+	/**
+	 * Get the hierarchical Area
+	 * @return array 
+	 * @access public
+	 */
+	function getHierarchicalArea()
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		return $this->so->getHierarchicalArea($this->organizationInfo['organizacao_id']);
+	}
+
+	/**
+	 * Retorna a lista de areas
+	 * @return array lista de areas
+	 * @access public
+	 */
+	function getAreaList()
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		$areas = $this->so->getAreaList($this->organizationInfo['organizacao_id']);
+		for ($i = 0; $i < count($areas); $i++)
+		{
+			$areas[$i]['children'] = false;
+			$areas[$i]['depth'] = 1;
+		}
+
+		return $areas;
+	}
+
+	/**
+	 * Retorna a lista de categorias
+	 * @return array lista de categorias
+	 * @access public
+	 */
+	function getCategoriesList()
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		return $this->so->getCategoriesList($this->organizationInfo['organizacao_id']);
+	}
+
+
+	/**
+	 * Return the area of employee
+	 * @param $params parameters
+	 * @access public
+	 * @return array array of employees
+	 */
+	function getAreaEmployees($params)
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		$employees = $this->so->getAreaEmployees((int) $params['areaID'], $this->organizationInfo['organizacao_id']);
+
+		if ($employees === false)
+			return array('error' => 'Área não encontrada.');
+
+		return $employees;
+	}
+
+	/**
+	 * Return the area of employee
+	 * @param $params parameters
+	 * @access public
+	 * @return array array of employees
+	 */
+	function getCategoryEmployees($params)
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		$employees = $this->so->getCategoryEmployees((int) $params['categoryID'], $this->organizationInfo['organizacao_id']);
+
+		if ($employees === false)
+			return array('error' => 'Categoria não encontrada.');
+
+		usort($employees['employees'], create_function('$a,$b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);'));
+
+		return $employees;
+	}
+
+	/**
+	 * Search Employee
+	 * @param $params
+	 * @access public
+	 * @return array search result
+	 */
+	function searchEmployee($params)
+	{
+		if (!ereg('^([[:alnum:] -]+)$', $params['searchTerm']))
+			return array('error' => 'Parâmetro de busca inválido');
+
+		if (strlen(str_replace(' ', '', $params['searchTerm'])) < 2)
+			return array('error' => 'Utilize ao menos duas letras em sua busca');
+
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		$result = array();
+
+		/* do the search */
+		$result['bytelephone'] = $this->so->searchEmployeeByTelephone($params['searchTerm'], $this->organizationInfo['organizacao_id']);
+		$result['employees'] = $this->so->searchEmployeeByName($params['searchTerm'], $this->organizationInfo['organizacao_id']);
+		$result['bygroup'] = $this->so->searchEmployeeByArea($params['searchTerm'], $this->organizationInfo['organizacao_id']);
+
+		$this->disconnect_all();
+
+		/* if all searches returned false */
+		if (!is_array($result['employees']) and
+			!is_array($result['bygroup']) and
+			!is_array($result['bytelephone']))
+			return array('error' => 'O sistema de busca não pode ser utilizado para sua organização');
+
+		return $result;
+	}
+
+	/**
+	 * Busca informações sobre um funcionário.
+	 * @param array $params Uma array contendo o ID do funcionário cujas informações serão extraídas.
+	 * @return array Informações sobre o funcionário.
+	 * @access public
+	 */
+	function getEmployeeInfo($params)
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		$result = $this->so->getEmployeeInfo((int) $params['funcionario_id'], $this->organizationInfo['organizacao_id']);
+		if (is_array($result['info']))
+		{
+			foreach ($result['info'] as $key => $value)
+			{
+				if ( $value['name'] == 'UIDNumber' )
+				{
+					unset($result['info'][$key]);
+				}
+			}
+			$result['info'] = array_values($result['info']);
+		}
+		return $result;
+	}
+
+	/**
+	 * Busca informações sobre uma área.
+	 * @param array $params Uma array contendo o ID da área cujas informações serão extraídas.
+	 * @return array Informações sobre a área.
+	 * @access public
+	 */
+	function getAreaInfo($params)
+	{
+		/* check for access */
+		if (($checkWarnings = $this->checkOrgchartAccess()) !== true)
+			return $checkWarnings;
+
+		return $this->so->getAreaInfo((int) $params['area_id'], $this->organizationInfo['organizacao_id']);
+	}
+
+	/**
+	 * Retorna a lista de telefones úteis da organização
+	 * @return array Lista de telefones
+	 * @access public
+	 */
+	function getUsefulPhones( )
+	{
+		/* check for access */
+		if ( ($checkWarnings = $this->checkOrgchartAccess( ) ) !== true )
+			return $checkWarnings;
+
+		return $this -> so -> getUsefulPhones( $this -> organizationInfo[ 'organizacao_id' ] );
+	}
+
+	/**
+	 * Retorna a lista as áreas com substituição de chefia
+	 * @return array Lista das áreas com substituição de chefia
+	 * @access public
+	 */
+	function getAreaWithSubtituteBoss( )
+	{
+		/* check for access */
+		if ( ($checkWarnings = $this->checkOrgchartAccess( ) ) !== true )
+			return $checkWarnings;
+
+		return $this -> so -> getAreaWithSubtituteBoss( $this -> organizationInfo[ 'organizacao_id' ] );
+	}
+
+	/**
+	 * Retorna a lista de localidades
+	 * @return array lista de localidades
+	 * @access public
+	 */
+	function getManning( )
+	{
+		/* check for access */
+		if ( ( $checkWarnings = $this->checkOrgchartAccess( ) ) !== true )
+			return $checkWarnings;
+
+		return $this -> so -> getManning( $this -> organizationInfo[ 'organizacao_id' ] );
+	}
+
+	/**
+	 * Return the employees of a manning
+	 * @param $params parameters
+	 * @access public
+	 * @return array array of employees
+	 */
+	function getManningEmployees( $params )
+	{
+		/* check for access */
+		if ( ( $checkWarnings = $this -> checkOrgchartAccess( ) ) !== true )
+			return $checkWarnings;
+
+		$employees = $this -> so -> getManningEmployees( ( int ) $params[ 'locationID' ], $this -> organizationInfo[ 'organizacao_id' ] );
+
+		if ( $employees === false )
+			return array( 'error' => 'Localidade não encontrada.' );
+
+		return $employees;
+	}
+
+	/**
+	 * Return the list of employees in alphabetical order
+	 * @access public
+	 * @return array array of employees
+	 */
+	function getAlphabeticalEmployees( )
+	{
+		/* check for access */
+		if ( ( $checkWarnings = $this -> checkOrgchartAccess( ) ) !== true )
+			return $checkWarnings;
+
+		$employees = $this -> so -> getAlphabeticalEmployees( $this -> organizationInfo[ 'organizacao_id' ] );
+
+		if ( $employees === false )
+			return array( 'error' => 'Localidade não encontrada.' );
+
+		return $employees;
+	}
+
+	function callVoipConnect($params)
+	{
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP);
+
+		$entry = $cachedLDAP->getEntryByID( $_SESSION['phpgw_info']['workflow']['account_id'] );
+		if ( $entry && ! is_null($entry['telephonenumber']) )
+			$fromNumber = $entry['telephonenumber'];
+
+		if ( $fromNumber == false )
+			return false;
+
+		$toNumber	= $params['to'];
+
+		$voipServer	= $_SESSION['phpgw_info']['workflow']['server']['voip_server'];
+		$voipUrl	= $_SESSION['phpgw_info']['workflow']['server']['voip_url'];
+		$voipPort	= $_SESSION['phpgw_info']['workflow']['server']['voip_port'];
+
+		if(!$voipServer || !$voipUrl || !$voipPort)
+			return false;
+
+		$url		= "http://".$voipServer.":".$voipPort.$voipUrl."?magic=1333&acao=liga&ramal=".$fromNumber."&numero=".$toNumber;			
+		$sMethod = 'GET ';
+		$crlf = "\r\n";
+		$sRequest = " HTTP/1.1" . $crlf;
+		$sRequest .= "Host: localhost" . $crlf;
+		$sRequest .= "Accept: */* " . $crlf;
+		$sRequest .= "Connection: Close" . $crlf . $crlf;            
+		$sRequest = $sMethod . $url . $sRequest;    
+		$sockHttp = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);            
+		if (!$sockHttp)  {
+			return false;
+		}
+		$resSocketConnect = socket_connect($sockHttp, $voipServer, $voipPort);
+		if (!$resSocketConnect) {
+			return false;
+		}
+		$resSocketWrite = socket_write($sockHttp, $sRequest, strlen($sRequest));
+		if (!$resSocketWrite) {
+			return false;
+		}    
+		$sResponse = '';    
+		while ($sRead = socket_read($sockHttp, 512)) {
+			$sResponse .= $sRead;
+		}            
+
+		socket_close($sockHttp);            
+		$pos = strpos($sResponse, $crlf . $crlf);
+		return substr($sResponse, $pos + 2 * strlen($crlf));									
+	}
+
+	function isVoipEnabled( )
+	{
+		$voip_enabled = false;
+		$voip_groups = array();
+		if ( $_SESSION['phpgw_info']['workflow']['voip_groups'] )
+		{
+			foreach ( explode(",",$_SESSION['phpgw_info']['workflow']['voip_groups']) as $i => $voip_group )
+			{
+				$a_voip = explode(";",$voip_group);
+				$voip_groups[] = $a_voip[1];
+			}
+
+			foreach($_SESSION['phpgw_info']['workflow']['user_groups'] as $idx => $group)
+			{
+				if(array_search($group,$voip_groups) !== FALSE)
+				{
+					$voip_enabled = true;
+					break;
+				}
+			}
+		}
+
+		return ( $voip_enabled ) ? 'VoipIsEnabled' : 'VoipIsDisabled';
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.Logger.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.Logger.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.Logger.inc.php	(revision 2372)
@@ -0,0 +1,342 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'log/Log.php';
+
+/**
+ * Classe de logs de dentro dos processos e módulo
+ * @package Workflow
+ * @author Guilherme Striquer Bisotto - gbisotto@celepar.pr.gov.br
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @subpackage Job
+ */
+class Logger
+{
+	/**
+	 * @var object $db Objeto de banco de dados já conectado
+	 * @access private
+	 */
+	private $db = null;
+
+	/**
+	 * @var string $logPath Caminho onde será salvo o arquivo de log, caso o tipo de log Log_file seja adicionado à composição
+	 * @access private
+	 */
+	private $logPath = null;
+
+	/**
+	 * @var string $logFileName Nome do arquivo de log, caso o tipo de log Log_file seja adicionado à composição
+	 * @access private
+	 */
+	private $logFileName = 'workflow.log';
+
+	/**
+	 * @var string $curProcessName Nome do processo normalizado, caso o objeto de log seja criado por um processo
+	 * @access private
+	 */
+	private $curProcessName = null;
+
+	/**
+	 * @var array $logsAllowed Logs permitidos no frontend
+	 * @access private
+	 */
+	private $logsAllowed = array();
+
+	/**
+	 * @var array $logTypes Array com ponteiros para os objetos de log adicionados à composição
+	 * @access private
+	 */
+	private $logTypes = array();
+
+	/**
+	 * @var object $log Objeto de log do tipo Log_composite
+	 * @access private
+	 */
+	private $log = null;
+
+	/**
+	 * @var int $logLevel nível de log atualmente configurado
+	 * @access protected
+	 */
+	protected $logLevel = null;
+
+	/**
+	 * Construtor da classe Logger
+	 * @param array $logTypes array com os tipos de logs que se deseja gerar
+	 * @param string $curProcessName nome normalizado do processo que utilizará o log
+	 * @return object Objeto da classe Logger
+	 * @access public
+	 */
+	public function Logger($logTypes = 'file', $curProcessId = null, $curProcessName = null)
+	{
+
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID;
+
+		if(!empty($curProcessName)){
+			$query = '
+				SELECT
+					wf_normalized_name
+				FROM
+					egw_wf_processes';
+
+			if(!($result = $this->db->query($query)))
+				throw new Exception(lang('Cannot execute query'));
+
+			while($row = $result->fetchRow())
+				$processNames[] = $row['wf_normalized_name'];
+
+			if(!in_array($curProcessName, $processNames))
+				throw new Exception(lang('Cannot find the process provided'));
+
+			$this->curProcessName = $curProcessName;
+		}
+
+		$this->configure($curProcessId);
+
+		if(!is_array($logTypes) && !empty($logTypes))
+			$logTypes = array($logTypes);
+
+		$this->log =& Log::factory('composite');
+		foreach($logTypes as $logType){
+			$this->addLogType($logType);
+		}
+	}
+
+	/**
+	 * Configura o objeto de acordo com o contexto
+	 * @params int $curProcessId O Id do processo corrente
+	 * @return null
+	 * @access private
+	 */
+	private function configure($curProcessId = null)
+	{
+		if(!empty($curProcessId)){
+			$query = "
+					SELECT
+						wf_config_name, wf_config_value_int
+					FROM
+						egw_wf_process_config
+					WHERE
+						wf_p_id = $curProcessId
+					AND
+						wf_config_name like 'log_level'
+						";
+			$config_value = array_pop($this->db->query($query)->GetArray(-1));
+			$this->logLevel = $config_value['wf_config_value_int'];
+		} else {
+			$query = "
+					SELECT
+						config_name, config_value
+					FROM
+						phpgw_config
+					WHERE
+						config_app like 'workflow'
+					AND
+						config_name like 'log_level'
+						";
+
+			$result = array_pop($this->db->query($query)->GetArray());
+			$this->logLevel = $result['config_value'];
+		}
+
+		$query = "
+			SELECT
+				config_name, config_value
+			FROM
+				phpgw_config
+			WHERE
+				config_app like 'workflow'
+			AND
+				config_name like 'log_type_%'
+				";
+		$result = $this->db->query($query);
+		while($row = $result->fetchRow()){
+			if($row['config_value'] == 'True'){
+				$this->logsAllowed[] = str_replace('log_type_', '', $row['config_name']);
+			}
+		}
+	}
+	/**
+	 * Configura e salva um objeto de log
+	 * @params string logType tipo de log a ser criado
+	 * @return object Objeto da classe Log_($logType) ou null caso o tipo de log não exista ou não seja permitido no frontend
+	 * @access private
+	 */
+	private function setLogType($logType)
+	{
+		if(in_array($logType, $this->logsAllowed)){
+			$logMethod = 'setLog_'.$logType;
+			if(method_exists($this, $logMethod))
+				$this->logTypes[$logType] =& $this->$logMethod();
+		}
+		return $this->logTypes[$logType];
+	}
+
+	/**
+	 * Adiciona um tipo de log à composição de logs caso ela já não tenha sido adicionada
+	 * @params string $logType tipo de log a ser adicionado
+	 * @return boolean true no caso do tipo de log ter sido adicionado com sucesso, false caso contrário
+	 * @access public
+	 */
+	public function addLogType($logType)
+	{
+		if(!in_array($logType, array_keys($this->logTypes))){
+			$log =& $this->setLogType($logType);
+			if(is_a($log, "Log_$logType")){
+				return $this->log->addChild($log);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Remove um tipo de log da composição de logs
+	 * @params $logType tipo de log a ser removido
+	 * @return object Objeto Log_($logType) removido, ou null caso não tenha removido qualquer um
+	 * @access public
+	 */
+	public function removeLogType($logType)
+	{
+		if(in_array($logType ,array_keys($this->logTypes)) && count($this->logTypes) > 1){
+			$this->log->removeChild($this->logTypes[$logType]);
+			$logRemoved =& $this->logTypes[$logTypes];
+			unset($this->logTypes[$logType]);
+
+			if(count($this->logTypes) == 1){
+				unset($this->log);
+				$this->log =& $this->logTypes[0];
+			}
+		} else {
+			return null;
+		}
+		return $logRemoved;
+	}
+
+	/**
+	 * Configura o log do tipo file
+	 * @return object Objeto do tipo Log_file
+	 * @access private
+	 */
+	private function setLog_file()
+	{
+		if(!empty($this->curProcessName)){
+			$this->logPath = GALAXIA_PROCESSES.SEP.$this->curProcessName.SEP.'logs';
+		} else {
+			$this->logPath = GALAXIA_PROCESSES.SEP.'logs';
+		}
+
+		$conf = array('mode' => 0600, 'timeFormat' => '%X %x');
+		$log =& Log::factory('file', $this->logPath.SEP.$this->logFileName, $this->curProcessName, $conf, $this->logLevel);
+		return $log;
+	}
+
+	/**
+	 * Configura o log do tipo firebug
+	 * @return object Objeto do tipo Log_firebug
+	 * @access private
+	 */
+	private function setLog_firebug()
+	{
+		$log =& Log::factory('firebug', '', $this->curProcessName, array('buffering' => true), $this->logLevel);
+		return $log;
+	}
+
+	/**
+	 * Grava um log do nível emergência (sistema inoperante)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function emerg($message)
+	{
+		return $this->log->log($message, PEAR_LOG_EMERG);
+	}
+
+	/**
+	 * Grava um log do nível alerta (ação imediata requerida)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function alert($message)
+	{
+		return $this->log->log($message, PEAR_LOG_ALERT);
+	}
+
+	/**
+	 * Grava um log do nível crítico (situações críticas)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function crit($message)
+	{
+		return $this->log->log($message, PEAR_LOG_CRIT);
+	}
+
+	/**
+	 * Grava um log do nível erro (situações de erro)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function err($message)
+	{
+		return $this->log->log($message, PEAR_LOG_ERR);
+	}
+
+	/**
+	 * Grava um log do nível aviso (condições de aviso - warning)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function warning($message)
+	{
+		return $this->log->log($message, PEAR_LOG_WARNING);
+	}
+
+	/**
+	 * Grava um log do nível notificação (situações normais, mas significantes)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function notice($message)
+	{
+		return $this->log->log($message, PEAR_LOG_NOTICE);
+	}
+
+	/**
+	 * Grava um log do nível informação (informacional)
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function info($message)
+	{
+		return $this->log->log($message, PEAR_LOG_INFO);
+	}
+
+	/**
+	 * Grava um log do nível debug
+	 * @params string $message Mensagem a ser gravada do log
+	 * @return boolean true em caso de sucesso e false caso contrário
+	 * @access public
+	 */
+	public function debug($message)
+	{
+		return $this->log->log($message, PEAR_LOG_DEBUG);
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_adminjobs.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_adminjobs.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_adminjobs.inc.php	(revision 2372)
@@ -0,0 +1,152 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'class.bo_ajaxinterface.inc.php';
+
+/**
+ * Camada Business para administrar Jobs
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class bo_adminjobs extends bo_ajaxinterface
+{
+	/**
+	 * @var object $so Acesso à camada model.
+	 * @access private
+	 */
+	private $so;
+
+	/**
+	 * Construtor da classe bo_adminjobs
+	 * @return object
+	 * @access public
+	 */
+	function bo_adminjobs()
+	{
+		parent::bo_ajaxinterface();
+		$this->so = &Factory::getInstance('so_adminjobs');
+	}
+
+	/**
+	 * Carrega a lista de todos os jobs de um determinado processo.
+	 * @param array $params Uma array contendo os parâmetros advindos da chamada Ajax
+	 * @return array Lista dos jobs (ordenada por nome)
+	 * @access public
+	 */
+	function loadJobs($params)
+	{
+		$output = $this->so->loadJobs($params['processID']);
+		if (isset($output['error']))
+			return $output;
+
+		usort($output, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+		return $output;
+	}
+
+	/**
+	 * Atualiza um job ou cria um novo job (dependendo dos parâmetros passados)
+	 * @param array $params Uma array contendo os parâmetros advindos da chamada Ajax
+	 * @return array Lista dos jobs (ordenada por nome)
+	 * @access public
+	 */
+	function saveJob($params)
+	{
+		$output = array();
+		if (!empty($params['jobID']))
+			$output = $this->so->updateJob($params['jobID'], $params['processID'], $params['name'], $params['description'], $params['timeStart'], $params['intervalValue'], $params['intervalUnity'], $params['dateType'], $params['weekDays'], $params['monthOffset'], $params['active']);
+		else
+			$output = $this->so->createJob($params['processID'], $params['name'], $params['description'], $params['timeStart'], $params['intervalValue'], $params['intervalUnity'], $params['dateType'], $params['weekDays'], $params['monthOffset'], $params['active']);
+
+		if (count($output['error']) === 0)
+			return $this->loadJobs(array('processID' => $params['processID']));
+		else
+			return $output;
+	}
+
+	/**
+	 * Remove um job (e seus logs)
+	 * @param array $params Uma array contendo os parâmetros advindos da chamada Ajax
+	 * @return void
+	 * @access public
+	 */
+	function removeJob($params)
+	{
+		return $this->so->removeJob($params['jobID']);
+	}
+
+	/**
+	 * Carrega a lista dos logs de um Job
+	 * @param array $params Uma array contendo os parâmetros advindos da chamada Ajax
+	 * @return array Lista dos logs
+	 * @access public
+	 */
+	function loadLogs($params)
+	{
+		$logs = $this->so->loadLogs($params['jobID']);
+		if (isset($logs['error']))
+			return $logs;
+
+		/* paginate the result */
+		$logEntriesPerPage = 30;
+		$paging =& Factory::newInstance('Paging', $logEntriesPerPage, $params);
+		$logs = $paging->restrictItems($logs);
+
+		/* use a more human readable time notation (today, yesterday) */
+		$date = new DateTime();
+		$writtenDates = array();
+		$writtenDates[$date->format('d/m/Y')] = 'Hoje';
+		$date->modify('-1 day');
+		$writtenDates[$date->format('d/m/Y')] = 'Ontem';
+		foreach ($logs as $key => $value)
+		{
+			$logs[$key]['date_time'] = ereg_replace("([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2}) ([[:digit:]]{2}):([[:digit:]]{2}):00", '\3/\2/\1 \4h\5', $value['date_time']);
+			$currentDate = $value['date_time'];
+			if (isset($writtenDates[substr($logs[$key]['date_time'], 0, 10)]))
+				$logs[$key]['human_date_time'] = $writtenDates[substr($logs[$key]['date_time'], 0, 10)] . substr($logs[$key]['date_time'], 10);
+		}
+
+		/* prepare the output */
+		$output = array();
+		$output['logs'] = $logs;
+		$output['pagingLinks'] = $paging->commonLinks();
+		return $output;
+	}
+
+	/**
+	 * Alterna o status do Job entre ativado e desativado
+	 * @param array $params Uma array contendo os parâmetros advindos da chamada Ajax
+	 * @return array Lista dos jobs (ordenada por nome)
+	 * @access public
+	 */
+	function toggleActive($params)
+	{
+		$jobID = (int) $params['jobID'];
+		$output = $this->so->toggleActive($jobID);
+		if (count($output['error']) === 0)
+			return $this->loadJobs(array('processID' => (int) $params['processID']));
+		else
+			return $output;
+	}
+
+	/**
+	 * Executa um determinado Job
+	 * @param array $params Uma array contendo os parâmetros advindos da chamada Ajax
+	 * @return array Uma array contendo a saída da execução do Job (saída padrão e saída de erro) e outras mensagens
+	 * @access public
+	 */
+	function runJob($params)
+	{
+		$jobID = (int) $params['jobID'];
+		return $this->so->runJob($jobID);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.so_external_applications.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.so_external_applications.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.so_external_applications.inc.php	(revision 2372)
@@ -0,0 +1,327 @@
+<?php
+
+	/**************************************************************************\
+	* eGroupWare                                                               *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+/**
+ * Camada Model das Aplicações Externas
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class so_external_applications
+{
+	/**
+	 * @var bool True se o usuário for administrador do expresso
+	 * @access private
+	 */
+	private $isAdmin;
+
+	/**
+	 * @var object Link para a ACL do Workflow
+	 * @access private
+	 */
+	private $acl;
+
+	/**
+	 * @var object Link para o Banco de Dados do Expresso
+	 * @access private
+	 */
+	private $db;
+
+	/**
+	 * @var object Link para o Banco de Dados do Expresso
+	 * @access private
+	 */
+	private $EXTERNAL_APPLICATION_PATH;
+
+	/**
+	 * Checa se o usuário possui acesso à administração das Aplicações Externas
+	 * @return void
+	 * @access private
+	 */
+	private function _checkAccess()
+	{
+		/* the user is an administrator */
+		if ($this->isAdmin)
+			return true;
+		else
+			die(serialize("Você não tem permissão para executar este procedimento!"));
+	}
+
+	/**
+	 * Verifica se houve erro em alguma query do Banco de Dados
+	 * @param object $result O resultado de alguma query
+	 * @return void
+	 * @access private
+	 */
+	private function _checkError($result)
+	{
+		if ($result === false)
+			die(serialize("Ocorreu um erro ao se tentar executar a operação solicitada."));
+	}
+
+	/**
+	 * Grava a imagem no diretório de aplicações externas
+	 * @param string $filename O nome da imagem
+	 * @param string $contents O conteúdo (binário) da imagem
+	 * @return bool Informa se a imagem foi gravada com sucesso ou não
+	 * @access private
+	 */
+	private function _saveImage($filename, $contents)
+	{
+		/* avoid writes outside the external_applications directory */
+		if (strpos($filename, '/') !== false)
+			return false;
+
+		/* create the directories if they don't exist */
+		@mkdir($this->EXTERNAL_APPLICATION_PATH, 0770, true);
+
+		/* perform the write operations */
+		$handler = fopen($this->EXTERNAL_APPLICATION_PATH . '/' . $filename, 'w');
+		if ($handler)
+		{
+			fwrite($handler, $contents);
+			fclose($handler);
+			return true;
+		}
+		else
+			return false;
+	}
+
+	/**
+	 * Verifica a presença de valores inválidos em alguns campos da aplicação externa
+	 * @param string $name O nome da aplicação externa
+	 * @param string $address O endereço da aplicação externa
+	 * @return array Uma array contendo os erros encontrados
+	 * @access private
+	 */
+	private function checkExternalApplicationData($name, $address)
+	{
+		$output = array();
+		$name = trim($name);
+		$address = trim($address);
+
+		if (empty($name))
+			$output[] = 'O nome da aplicação externa não pode ser vazio.';
+
+		if (empty($address))
+			$output[] = 'O endereço da aplicação externa não pode ser vazio.';
+
+		if (preg_match('/^[a-z]+:\/\//i', $address) == 0)
+			$output[] = 'Aparentemente a URL informada não está formatada corretamente.';
+
+		return $output;
+	}
+
+	/**
+	 * Construtor da classe so_external_applications
+	 * @return object
+	 */
+	function so_external_applications()
+	{
+		$this->isAdmin = $_SESSION['phpgw_info']['workflow']['user_is_admin'];
+		$this->acl = &$GLOBALS['ajax']->acl;
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
+		$this->EXTERNAL_APPLICATION_PATH = $_SESSION['phpgw_info']['workflow']['server']['files_dir'] . '/workflow//workflow/external_applications';
+	}
+
+	/**
+	 * Lista todas as aplicações externas
+	 * @return array Lista de aplicações externas
+	 * @access public
+	 */
+	function getExternalApplications()
+	{
+		$this->_checkAccess();
+		$query = "SELECT external_application_id, name FROM egw_wf_external_application ORDER BY name";
+
+		$result = $this->db->query($query);
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return $output;
+	}
+
+	/**
+	 * Retornar informações sobre uma aplicação externa
+	 * @param int $externalApplicationID O ID da aplicação externa
+	 * @return array Array contento informações sobre a aplicação externa
+	 * @access public
+	 */
+	function getExternalApplication($externalApplicationID)
+	{
+		$this->_checkAccess();
+		$query = "SELECT external_application_id, name, description, image, address, authentication, post, intranet_only FROM egw_wf_external_application WHERE (external_application_id = ?)";
+
+		$result = $this->db->query($query, array($externalApplicationID));
+		$this->_checkError($result);
+
+		$output = $result->GetArray(-1);
+		for ($i = 0; $i < count($output); $i++)
+			for ($j = 0; $j < $result->_numOfFields; $j++)
+				unset($output[$i][$j]);
+
+		return isset($output[0]) ? $output[0] : false;
+	}
+
+	/**
+	 * Adiciona uma aplicação externa
+	 * @param string $name O nome da aplicação externa
+	 * @param string $description A descrição da aplicação externa
+	 * @param string $address O endereço da aplicação externa
+	 * @param string $image O nome da imagem da aplicação externa
+	 * @param int $authentication Indica se a aplicação externa autentica (1) ou não (0)
+	 * @param string $post Os dados que são postados para a aplicação externa (caso necessite de autenticação)
+	 * @param int $intranetOnly Indica se a aplicação externa só será visível na Intranet (1 somente Intranet e 2 para cliente de qualquer origem)
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário
+	 * @access public
+	 */
+	function addExternalApplication($name, $description, $address, $image, $authentication, $post, $intranetOnly)
+	{
+		$this->_checkAccess();
+
+		if (count($errors = $this->checkExternalApplicationData($name, $address)) > 0)
+			return array('error' => implode("\n", $errors));
+
+		/* decode the supplied image */
+		if ($image != '')
+		{
+			$image = str_replace(' ', '+', $image);
+			$imageData = base64_decode($image);
+			if ($imageData !== false)
+				$imageData = unserialize($imageData);
+			if ($imageData !== false)
+			{
+				$image = strtolower(end(explode('.', $imageData['name'])));
+				if (($image != 'png') && ($image != 'jpg') && ($image != 'gif'))
+					return array('error' => 'A imagem enviada não é do tipo JPG, PNG ou GIF');
+			}
+			else
+				$image = '';
+		}
+
+		if (strlen($image) > 0)
+			$query = "INSERT INTO egw_wf_external_application(name, description, address, image, authentication, post, intranet_only) VALUES(?, ?, ?, currVAL('seq_egw_wf_external_application') || '.$image', ?, ?, ?)";
+		else
+			$query = "INSERT INTO egw_wf_external_application(name, description, address, authentication, post, intranet_only) VALUES(?, ?, ?, ?, ?, ?)";
+
+		$this->db->StartTrans();
+		$result = $this->db->query($query, array($name, $description, $address, $authentication, $post, $intranetOnly));
+
+		if ((strlen($image) > 0) && ($result !== false))
+		{
+			$currentID = $this->db->getOne("SELECT currVAL('seq_egw_wf_external_application')");
+			$this->_saveImage($currentID . '.' . $image, $imageData['contents']);
+		}
+
+		if ($result === false)
+			$this->db->FailTrans();
+		else
+			$this->db->CompleteTrans();
+
+		$this->_checkError($result);
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Atualiza uma aplicação externa
+	 * @param int $externalApplicationID O ID da aplicação externa
+	 * @param string $name O nome da aplicação externa
+	 * @param string $description A descrição da aplicação externa
+	 * @param string $address O endereço da aplicação externa
+	 * @param string $image O nome da imagem da aplicação externa
+	 * @param int $authentication Indica se a aplicação externa autentica (1) ou não (0)
+	 * @param string $post Os dados que são postados para a aplicação externa (caso necessite de autenticação)
+	 * @param int $removeCurrentImage Indica se a imagem atual da aplicação externa será removida (1 para remover e 0 para não remover)
+	 * @param int $intranetOnly Indica se a aplicação externa só será visível na Intranet (1 somente Intranet e 2 para cliente de qualquer origem)
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário
+	 * @access public
+	 */
+	function updateExternalApplication($externalApplicationID, $name, $description, $address, $image, $authentication, $post, $removeCurrentImage, $intranetOnly)
+	{
+		$this->_checkAccess();
+
+		if (count($errors = $this->checkExternalApplicationData($name, $address)) > 0)
+			return array('error' => implode("\n", $errors));
+
+		/* if a new image is supplied, decode the data */
+		if ($image != '')
+		{
+			$image = str_replace(' ', '+', $image);
+			$imageData = base64_decode($image);
+			if ($imageData !== false)
+				$imageData = unserialize($imageData);
+			if ($imageData !== false)
+			{
+				$image = strtolower(end(explode('.', $imageData['name'])));
+				if (($image != 'png') && ($image != 'jpg') && ($image != 'gif'))
+					return array('error' => 'A imagem enviada não é do tipo JPG, PNG ou GIF');
+				$image = $externalApplicationID . '.' . $image;
+			}
+			else
+				$image = null;
+		}
+		else
+			$image = null;
+
+		/* get the current image */
+		$currentImage = $this->db->getOne('SELECT image FROM egw_wf_external_application WHERE (external_application_id = ?)', array($externalApplicationID));
+
+		/* if necessary, remove the current image */
+		if ((($removeCurrentImage == '1') || (!is_null($image))) && ($currentImage))
+			if (file_exists($this->EXTERNAL_APPLICATION_PATH . '/' . $currentImage))
+				unlink($this->EXTERNAL_APPLICATION_PATH . '/' . $currentImage);
+
+		/* if supplied, save the new image */
+		if (!is_null($image))
+			$this->_saveImage($image, $imageData['contents']);
+		else
+			if ($removeCurrentImage == '0')
+				$image = $currentImage;
+
+		/* update the external application */
+		$query = "UPDATE egw_wf_external_application SET name = ?, description = ?, address = ?, image = ?, authentication = ?, post = ?, intranet_only = ? WHERE (external_application_id = ?)";
+		$result = $this->db->query($query, array($name, $description, $address, $image, $authentication, $post, $intranetOnly, $externalApplicationID));
+		$this->_checkError($result);
+
+		return (($result === false) ? false : true);
+	}
+
+	/**
+	 * Remove uma aplicação externa
+	 * @param int $externalApplicationID O ID da aplicação externa.
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeExternalApplication($externalApplicationID)
+	{
+		$this->_checkAccess();
+
+		/* remove the current image */
+		$currentImage = $this->db->getOne('SELECT image FROM egw_wf_external_application WHERE (external_application_id = ?)', array($externalApplicationID));
+		if ($currentImage)
+			if (file_exists($this->EXTERNAL_APPLICATION_PATH . '/' . $currentImage))
+				unlink($this->EXTERNAL_APPLICATION_PATH . '/' . $currentImage);
+
+		/* remove the external application */
+		$result = $this->db->query('DELETE FROM egw_wf_external_application WHERE (external_application_id = ?)', array($externalApplicationID));
+		$this->_checkError($result);
+
+		$this->acl->removeAdminsFromResource('APX', $externalApplicationID);
+
+		return (($result === false) ? false : true);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_adminsource.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_adminsource.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_adminsource.inc.php	(revision 2372)
@@ -0,0 +1,691 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 		       *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+
+/**
+ * Invalid file name identifier 
+ * @name INVALID_FILE_NAME 
+ */
+define( INVALID_FILE_NAME   , 0 );
+/**
+ * Invalid process id identifier 
+ * @name INVALID_PROCESS_ID 
+ */
+define( INVALID_PROCESS_ID  , 1 );
+/**
+ * File already exists identifier
+ * @name FILE_ALREADY_EXISTS 
+ */
+define( FILE_ALREADY_EXISTS , 2 );
+/**
+ * File created indentifier 
+ * @name FILE_CREATED
+ */
+define( FILE_CREATED	 	, 3 );
+/**
+ * File not created identifier 
+ * @name FILE_NOT_CREATED
+ */
+define( FILE_NOT_CREATED 	, 4 );
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ */
+class bo_adminsource extends bo_ajaxinterface
+{
+
+	/**
+	* @var array $public_functions Array of public functions 
+	* @access public
+	*/
+	var $public_functions = array('export_file' => true
+				      );
+	
+	/**
+	* Construtor
+	*
+	* @access public 
+	*/	
+	function bo_adminsource() {
+		parent::bo_ajaxinterface();		
+		}
+	
+	/**
+	* Assign Unit To File Size
+	* @param integer $value value
+	* @return string file size 
+	* @access public 
+	*/
+	function _assignUnitToFileSize($value)
+	{
+		$fileSizeUnit = array();
+		$fileSizeUnit[] = 'bytes';
+		$fileSizeUnit[] = 'Kb';
+		$fileSizeUnit[] = 'Mb';
+		$fileSizeUnit[] = 'Gb';
+
+		$unitSelect = 0;
+		while ($value > 1024.0)
+		{
+			$value /= 1024.0;
+			$unitSelect++;
+		}
+
+		$output = round($value, 1);
+		$output .= " " . $fileSizeUnit[$unitSelect];
+
+		return $output;
+	}
+
+	/**
+	* Get process toolbar data
+	* @param  array $p process process data
+	* @return array
+	* @access public
+	*/
+	function get_toolbar_data($p)
+	{
+
+		$process_manager = &Factory::newInstance('ProcessManager');
+		$proc_info       = $process_manager->get_process($p['proc_id']);
+
+		$web_server_url  = $_SESSION['phpgw_info']['workflow']['server']['webserver_url'];
+		$img_default_dir = Factory::getInstance('TemplateServer')->generateImageLink('');
+
+		if ($proc_info['wf_is_valid'] == 'y')
+		{
+			$dot_color = 'green';
+			$alt_validity = tra('valid');
+		}
+		else
+		{
+			$dot_color = 'red';
+			$alt_validity = tra('invalid');
+		}
+
+		// if process is active show stop button. Else show start button, but only if it is valid. If it's not valid, don't show any activation or stop button.
+		if ($proc_info['wf_is_active'] == 'y')
+		{
+			$start_stop_link = $web_server_url.'/index.php?menuaction=workflow.ui_adminactivities.form&p_id='. $proc_info['wf_p_id'] .'&deactivate_proc='. $proc_info['wf_p_id'];
+			$start_stop_img  = $img_default_dir.'stop.gif';
+			$start_stop_desc = 'Parar';
+		}
+		elseif ($proc_info['wf_is_valid'] == 'y')
+		{
+			$start_stop_link = $web_server_url.'/index.php?menuaction=workflow.ui_adminactivities.form&p_id='. $proc_info['wf_p_id'] .'&activate_proc='. $proc_info['wf_p_id'];
+			$start_stop_img  = $img_default_dir.'refresh2.gif';
+			$start_stop_desc = 'Ativar';
+		}
+		else
+		{
+			$start_stop_link = '';
+			$start_stop_img  = '';
+		}
+
+		/* load other processes link */
+		$proc_ids = $GLOBALS['ajax']->acl->get_granted_processes($_SESSION['phpgw_info']['workflow']['account_id']);
+		if (count($proc_ids))
+			$where = ' wf_p_id in ('. implode(',',$proc_ids) .') ';
+		else
+			$where = ' wf_p_id = -1 ';
+
+		$processesInfo = &$process_manager->list_processes(0, -1, 'wf_name__asc', '', $where);
+		$otherProcesses = array();
+		foreach ($processesInfo['data'] as $pi)
+			$otherProcesses[] = array("name" => $pi['wf_name'] . " (v" . $pi['wf_version'] . ")", "link" => $web_server_url . "/index.php?menuaction=workflow.ui_adminsource.form&p_id=" . $pi['wf_p_id'], "pid" => $pi['wf_p_id']);
+
+		$toolbar_data = array (
+			'proc_name'					=> $proc_info['wf_name'],
+			'version'					=> $proc_info['wf_version'],
+			'img_validity'				=> $img_default_dir.$dot_color.'_dot.gif',
+			'alt_validity'				=> $alt_validity,
+			'start_stop_link'	  		=> $start_stop_link,
+			'start_stop_img'	  		=> $start_stop_img,
+			'start_stop_desc'	  		=> $start_stop_desc,
+			'link_admin_activities'		=> $web_server_url.'/index.php?menuaction=workflow.ui_adminactivities.form&p_id='. $proc_info['wf_p_id'],
+			'img_activity'				=> $img_default_dir.'Activity.gif',
+			'link_admin_jobs'		=> $web_server_url.'/index.php?menuaction=workflow.ui_adminjobs.form&p_id='. $proc_info['wf_p_id'],
+			'img_job'				=> $img_default_dir.'clock.png',
+			'link_admin_processes'		=> $web_server_url.'/index.php?menuaction=workflow.ui_adminprocesses.form&p_id='. $proc_info['wf_p_id'],
+			'img_change'				=> $img_default_dir.'change.gif',
+			'link_admin_shared_source'	=> $web_server_url.'/index.php?menuaction=workflow.ui_adminsource.form&p_id='. $proc_info['wf_p_id'],
+			'img_code'					=> $img_default_dir.'code.gif',
+			'link_admin_export'			=> $web_server_url.'/index.php?menuaction=workflow.WorkflowUtils.export&p_id='. $proc_info['wf_p_id'],
+			'link_admin_roles'			=> $web_server_url.'/index.php?menuaction=workflow.ui_adminroles.form&p_id='. $proc_info['wf_p_id'],
+			'img_roles'					=> $img_default_dir.'roles.png',
+			'link_graph'				=> $web_server_url.'/index.php?menuaction=workflow.ui_adminactivities.show_graph&p_id=' . $proc_info['wf_p_id'],
+			'img_process'				=> $img_default_dir.'Process.gif',
+			'link_save_process'			=> $web_server_url.'/index.php?menuaction=workflow.ui_adminprocesses.save_process&id='. $proc_info['wf_p_id'],
+			'img_save'					=> $img_default_dir.'save.png',
+			'proc_id'					=> $p['proc_id'],
+			'other_processes'			=> $otherProcesses
+		);
+
+		return $toolbar_data;
+		}
+
+
+	/**
+	* Get process model files
+	* @param  array $p process process data
+	* @return array
+	* @access public
+	*/
+	function get_model_files($p)
+	{
+		switch($p['type'])
+		{
+			case 'include'  : $path = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'js' . SEP . 'adminsource' . SEP . 'inc';
+							  break;
+			case 'template' : $path = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'js' . SEP . 'adminsource' . SEP . 'templates';
+							  break;
+			case 'js'       : $path = PHPGW_SERVER_ROOT . SEP . 'workflow' . SEP . 'js' . SEP . 'local';
+							  break;
+		}
+
+		$col_file_name  = array();
+		$files          = array();
+
+		if ($handle = opendir($path))
+		{
+			while (false !== ($file_name = readdir($handle)))
+			{
+				if (!is_dir($path.SEP.$file_name))
+				{
+					$files[] = array('file_name'     => $file_name);
+					$col_file_name[]  = $file_name;
+				}
+			}
+		}
+
+		array_multisort($col_file_name,SORT_ASC,$files);
+
+		return $files;
+	}
+
+	/**
+	* Get process php files
+	* @param array $p process data
+	* @return array
+	* @access public
+	*/
+	function get_php_files($p)
+	{
+		$process_manager    = &Factory::newInstance('ProcessManager');
+		$proc_info          = $process_manager->get_process($p['proc_id']);
+		$activity_manager   = &Factory::newInstance('ActivityManager');
+		$process_activities = $activity_manager->list_activities($p['proc_id'], 0, -1, 'wf_name__asc', '','',false);
+		$path = GALAXIA_PROCESSES . SEP . $proc_info['wf_normalized_name'] . SEP . 'code' . SEP .'activities' . SEP;
+
+		$files = array();
+
+		$col_file_name  = array();
+		$col_tamanho    = array();
+		$col_modificado = array();
+
+		foreach ($process_activities['data'] as $process_activity)
+		{
+
+			$file_name   = $process_activity['wf_normalized_name'].'.php';
+			$activity_id = $process_activity['wf_activity_id'];
+			$tamanho     = filesize($path.$file_name);
+			$modificado  = date('d/m/Y H:i:s', filemtime($path.$file_name) );
+
+			$files[] = array('file_name'     => $file_name,
+							 'activity_id'   => $activity_id,
+							 'tamanho' 	     => $this->_assignUnitToFileSize($tamanho),
+							 'modificado'    => $modificado,
+							 'tipo_atividade'=> $process_activity['wf_type'],
+							 'interativa'    => $process_activity['wf_is_interactive'],
+							 'proc_name'     => $proc_info['wf_normalized_name'],
+							 'proc_id'		 => $proc_info['wf_p_id'],
+							 'tipo_codigo'   => 'atividade'
+			);
+
+			$col_file_name[]  = $file_name;
+			$col_tamanho[]    = $tamanho;
+			$col_modificado[] = $modificado;
+		}
+
+		if (isset($p['sort']))
+		{
+			$order_by = ($p['order_by'] == 1) ? SORT_ASC : SORT_DESC;
+
+			switch ($p['sort'])
+			{
+				case 'file_name' :  array_multisort($col_file_name,$order_by,$files);
+									break;
+				case 'tamanho'   :  array_multisort($col_tamanho,SORT_NUMERIC,$order_by,$files);
+									break;
+				case 'modificado':  array_multisort($col_modificado,$order_by,$files);
+									break;
+
+			}
+		}
+
+		return $files;
+	}
+
+	/**
+	* Delete process file
+	* @param array $p process data
+	* @return array
+	* @access public
+	*/
+	function delete_file($p)
+	{
+		if ((strpos($p['file_name'],'/') !== false) || (strpos($p['file_name'],'/') !== false))
+			return 'Não foi possível executar a operação solicitada';
+		$process_manager = &Factory::newInstance('ProcessManager');
+		$proc_info = $process_manager->get_process($p['proc_id']);
+		$file_name = $p['file_name'];
+		$proc_name = $proc_info['wf_normalized_name'];
+		$type      = $p['type'];
+		if (strpos($file_name,'/')) return 'Nome de arquivo inválido.';
+		if (!strlen($proc_name)) return 'ID de Processo inválido.';
+
+    switch($type)
+    {
+        case 'atividade':
+            $path =  'activities' . SEP . $file_name;
+            break;
+            case 'template':
+            $path =  'templates' . SEP . $file_name;
+            break;
+        case 'include':
+            $path = $file_name;
+            break;
+    		case 'resource':
+				$path = GALAXIA_PROCESSES . '/' . $proc_info['wf_normalized_name'] . '/resources/' . $file_name;
+            break;
+
+    }
+
+	   	if ($type == 'resource')
+		{
+			$complete_path = $path;
+		}
+		else
+		{
+			$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+		}
+
+		if (file_exists($complete_path))
+		{
+			if (unlink($complete_path))
+			{
+				return 'Arquivo '.$file_name.' excluido com sucesso.';
+			}
+			else
+			{
+				return 'Não foi possivel excluir o arquivo '.$file_name.'.';
+			}
+    }
+		else
+		{
+			return 'O arquivo '.$file_name.' não existe.';
+		}
+	}
+	/**
+	* Create process new file
+	* @param array $p process
+	* @return array
+	* @access public
+	*/
+	function create_file($p)
+	{
+		$process_manager = &Factory::newInstance('ProcessManager');
+		$proc_info = $process_manager->get_process($p['proc_id']);
+		$file_name = $p['file_name'];
+		$proc_name = $proc_info['wf_normalized_name'];
+		$type      = $p['type'];
+
+		if ((strpos($file_name,'/') !== false) || (strpos($file_name,'/') !== false))
+		{
+			return INVALID_FILE_NAME;
+		}
+
+		if (!strlen($proc_name))
+		{
+			return INVALID_PROCESS_ID;
+		}
+
+		switch($type)
+		{
+			case 'atividade':
+				$path =  'activities' . SEP . $file_name;
+				$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+				break;
+			case 'template':
+				$path =  'templates' . SEP . $file_name;
+				$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+				break;
+			case 'include':
+				$path = $file_name;
+				$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+				break;
+			case 'resource':
+				$complete_path = GALAXIA_PROCESSES . '/' . $proc_name . '/resources/' . $file_name;
+				break;
+		}
+
+		if (file_exists($complete_path))
+		{
+			if (!$p['rewrite'])
+			{
+				return FILE_ALREADY_EXISTS;
+			} else {
+				unlink($complete_path);
+			}
+		}
+
+		if ($fp = fopen($complete_path, 'w'))
+		{
+			$basepath = PHPGW_SERVER_ROOT.SEP.'workflow'.SEP.'js'.SEP.'adminsource';
+			switch ($type)
+			{
+			case 'template':  $basepath = $basepath.SEP.'templates';
+				break;
+			case 'include' :  $basepath = $basepath.SEP.'inc';
+				break;
+			}
+
+			if ($type == 'template' || $type == 'include')
+			{
+				if (file_exists($basepath.SEP.$p['modelo']))
+				{
+					fwrite($fp,file_get_contents($basepath.SEP.$p['modelo']));
+				}
+			}
+
+			fclose($fp);
+			return FILE_CREATED;
+		}
+		else
+		{
+			return FILE_NOT_CREATED;
+		}
+	}
+
+	/**
+	* Get process include files
+	* @param  array $p process
+	* @return array
+	* @access public
+	*/
+	function get_include_files($p)
+	{
+		$process_manager    = &Factory::newInstance('ProcessManager');
+		$proc_info          = $process_manager->get_process($p['proc_id']);
+		$path = GALAXIA_PROCESSES . SEP . $proc_info['wf_normalized_name'] . SEP . 'code';
+
+
+		$col_file_name  = array();
+		$col_tamanho    = array();
+		$col_modificado = array();
+		$files          = array();
+
+		if ($handle = opendir($path))
+		{
+			while (false !== ($file_name = readdir($handle)))
+			{
+				if (!is_dir($path.SEP.$file_name))
+				{
+					$tamanho     = filesize($path.SEP.$file_name);
+					$modificado  = date('d/m/Y H:i:s', filemtime($path.SEP.$file_name) );
+
+					$files[] = array('file_name'     => $file_name,
+							 'tamanho' 	     => $this->_assignUnitToFileSize($tamanho),
+							 'modificado'    => $modificado,
+							 'proc_name'     => $proc_info['wf_normalized_name'],
+							 'proc_id'		 => $proc_info['wf_p_id'],
+							 'tipo_codigo'   => 'include'
+					);
+
+					$col_file_name[]  = $file_name;
+					$col_tamanho[]    = $tamanho;
+					$col_modificado[] = $modificado;
+				}
+			}
+		}
+
+
+		if (isset($p['sort']))
+		{
+			$order_by = ($p['order_by'] == 1) ? SORT_ASC : SORT_DESC;
+
+			switch ($p['sort'])
+			{
+				case 'file_name' :  array_multisort($col_file_name,$order_by,$files);
+									break;
+				case 'tamanho'   :  array_multisort($col_tamanho,SORT_NUMERIC,$order_by,$files);
+									break;
+				case 'modificado':  array_multisort($col_modificado,$order_by,$files);
+									break;
+
+			}
+		}
+
+		return $files;
+	}
+
+	/**
+	* Get process template files
+	* @param array $p process data
+	* @return array
+	* @access public
+	*/
+	function get_template_files($p)
+	{
+		$process_manager    = &Factory::newInstance('ProcessManager');
+		$proc_info          = $process_manager->get_process($p['proc_id']);
+		$path = GALAXIA_PROCESSES . SEP . $proc_info['wf_normalized_name'] . SEP . 'code' . SEP .'templates';
+
+		$col_file_name  = array();
+		$col_tamanho    = array();
+		$col_modificado = array();
+
+		if ($handle = opendir($path))
+		{
+			while (false !== ($file_name = readdir($handle)))
+			{
+				if (!is_dir($path.SEP.$file_name))
+				{
+					$tamanho     = filesize($path.SEP.$file_name);
+					$modificado  = date('d/m/Y H:i:s', filemtime($path.SEP.$file_name) );
+
+					$files[] = array('file_name'     => $file_name,
+							 'tamanho' 	     => $this->_assignUnitToFileSize($tamanho),
+							 'modificado'    => $modificado,
+							 'proc_name'     => $proc_info['wf_normalized_name'],
+							 'proc_id'		 => $proc_info['wf_p_id'],
+							 'tipo_codigo'   => 'template'
+					);
+
+					$col_file_name[]  = $file_name;
+					$col_tamanho[]    = $tamanho;
+					$col_modificado[] = $modificado;
+
+				}
+			}
+		}
+
+		if (isset($p['sort']))
+    {
+        $order_by = ($p['order_by'] == 1) ? SORT_ASC : SORT_DESC;
+
+        switch ($p['sort'])
+        {
+            case 'file_name' :  array_multisort($col_file_name,$order_by,$files);
+                                break;
+            case 'tamanho'   :  array_multisort($col_tamanho,SORT_NUMERIC,$order_by,$files);
+                                break;
+            case 'modificado':  array_multisort($col_modificado,$order_by,$files);
+                                break;
+
+        }
+    }
+
+		return $files;
+	}
+
+	/**
+	* Upload process resource
+	*
+	* @param array $p process
+	* @return array
+	* @access public
+	*/
+	function upload_resource($p)
+	{
+		$process_manager = &Factory::newInstance('ProcessManager');
+		$proc_info = $process_manager->get_process($p['proc_id']);
+		$file_name = basename($_FILES['resource_file']['name']);
+
+		$base_path = GALAXIA_PROCESSES . '/' . $proc_info['wf_normalized_name'] . '/resources';
+		$path = $base_path . '/' . $file_name;
+
+
+		if (!strlen($file_name))
+			return 'É necessário selecionar um arquivo.';
+
+		if (!is_dir($base_path))
+			return 'A pasta de resources ainda não foi criada no servidor.';
+
+		if (file_exists($path))
+			return 'O arquivo '.$file_name.' já existe no servidor.';
+
+		if (move_uploaded_file($_FILES['resource_file']['tmp_name'],$path))
+			return 'Upload realizado com sucesso.';
+		else
+			return 'Não foi possível realizar upload do arquivo '.$file_name.'.';
+	}
+
+	/**
+	* Export process file
+	*
+	* @access public
+	*/
+	function export_file()
+	{
+		if (strpos($_REQUEST['file_name'],'/') !== false)
+			return 'Não foi possível executar a operação solicitada';
+		$process_manager    = &Factory::newInstance('ProcessManager');
+		$proc_info          = $process_manager->get_process($_REQUEST['proc_id']);
+
+		$proc_name = $proc_info['wf_normalized_name'];
+		$file_name = $_REQUEST['file_name'];
+		$type      = $_REQUEST['type'];
+
+		switch($type)
+		{
+			case 'atividade':
+				$path =  'activities' . SEP . $file_name;
+				break;
+			case 'template':
+				$path =  'templates' . SEP . $file_name;
+				break;
+			case 'resource':
+				$path = 'resources' . SEP . $file_name;
+				break;
+			case 'include':
+				$path = $file_name;
+				break;
+			default:
+				exit;
+		}
+
+		if ($type == 'resource')
+			$completePath = GALAXIA_PROCESSES . SEP . $proc_name . SEP . $path;
+		else
+			$completePath = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+
+		Factory::getInstance('ResourcesRedirector')->show($completePath, 'application/force-download');
+		exit;
+	}
+
+	/**
+	* Get process resources files
+	*
+	* @param array $p process
+	* @return array
+	* @access public
+	*/
+	function get_resource_files($p)
+	{
+		$process_manager    = &Factory::newInstance('ProcessManager');
+		$proc_info          = $process_manager->get_process($p['proc_id']);
+
+		$path       = GALAXIA_PROCESSES . '/' . $proc_info['wf_normalized_name'] . '/resources';
+
+		if (!is_dir($path))
+			mkdir($path, 0770);
+
+		$col_file_name  = array();
+		$col_tamanho    = array();
+		$col_modificado = array();
+		$col_tipo 		= array();
+
+		if ($handle = opendir($path))
+		{
+			while (false !== ($file_name = readdir($handle)))
+			{
+				if (!is_dir($path.SEP.$file_name))
+				{
+					$tipo        = mime_content_type($path.SEP.$file_name);
+					$tamanho     = filesize($path.SEP.$file_name);
+					$modificado  = date('d/m/Y H:i:s', filemtime($path.SEP.$file_name) );
+
+					$files[] = array(
+							 'file_name'     => $file_name,
+							 'proc_name'     => $proc_info['wf_normalized_name'],
+							 'proc_id'		 => $proc_info['wf_p_id'],
+							 'tamanho' 	     => $this->_assignUnitToFileSize($tamanho),
+							 'tipo' 	     => $tipo,
+							 'modificado'    => $modificado,
+							 'tipo_arquivo'  => 'resource'
+					);
+
+					$col_file_name[]  = $file_name;
+					$col_tamanho[]    = $tamanho;
+					$col_modificado[] = $modificado;
+					$col_tipo[]       = $tipo;
+
+				}
+			}
+		}
+
+		if (isset($p['sort']))
+		{
+			$order_by = ($p['order_by'] == 1) ? SORT_ASC : SORT_DESC;
+
+			switch ($p['sort'])
+			{
+				case 'file_name' :  array_multisort($col_file_name,$order_by,$files);
+									break;
+				case 'tamanho'   :  array_multisort($col_tamanho,SORT_NUMERIC,$order_by,$files);
+									break;
+				case 'modificado':  array_multisort($col_modificado,$order_by,$files);
+									break;
+				case 'tipo'      :  array_multisort($col_tipo,$order_by,$files);
+									break;
+
+			}
+		}
+
+		return $files;
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_orgchart.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_orgchart.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_orgchart.inc.php	(revision 2372)
@@ -0,0 +1,727 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+/**
+ * Camada Business do Organograma.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class bo_orgchart extends bo_ajaxinterface
+{
+	/**
+	 * @var object $so Acesso à camada Model do Organograma.
+	 * @access private
+	 */
+	private $so;
+
+	/**
+	 * Verifica se o valor de uma variável pode ser considerado NULL. Se sim, retorna NULL caso contrário retorna o próprio valor passado.
+	 * @param mixed $value O valor que será verificado.
+	 * @return mixed Será retornado o valor passado no parâmetro ou NULL.
+	 * @access private
+	 */
+	private function _nullReplace($value)
+	{
+		if (($value == 'NULL') || ($value == ''))
+			return null;
+		else
+			return $value;
+	}
+	/**
+	 * Construtor da classe bo_orgchart
+	 * @return object
+	 * @access public
+	 */
+	function bo_orgchart()
+	{
+		parent::bo_ajaxinterface();
+		$this->so = &Factory::getInstance('so_orgchart');
+	}
+
+	/**
+	 * Lista todas as organizações do Organograma.
+	 * @return array Lista de organizações.
+	 * @access public
+	 */
+	function listOrganization()
+	{
+		$result = $this->so->getOrganizations();
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona uma organização.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar uma organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addOrganization($params)
+	{
+		$result = $this->so->addOrganization($params['nome'], $params['descricao'], $params['url_imagem'], $params['ativa'], $params['sitio']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza uma organização.
+	 * @param array $params Uma array contendo os parâmetros da organização que serão modificados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateOrganization($params)
+	{
+		$result = $this->so->updateOrganization($params['nome'], $params['descricao'], $params['url_imagem'], $params['ativa'], $params['organizacao_id'], $params['sitio']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove uma organização.
+	 * @param array $params Uma array contendo o ID da organização que será excluída (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeOrganization($params)
+	{
+		$result = $this->so->removeOrganization($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista os possíveis status dos funcionários.
+	 * @param array $params Uma array contendo o ID da organização de onde os status dos empregados serão listados (Ajax).
+	 * @return array Lista dos possíveis status dos empregados.
+	 * @access public
+	 */
+	function listEmployeeStatus($params)
+	{
+		$result = $this->so->getEmployeeStatus($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona um Status de funcionário.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar um status de funcionário (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addEmployeeStatus($params)
+	{
+		$result = $this->so->addEmployeeStatus($params['organizacao_id'], $params['descricao'], $params['exibir']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza um Status de funcionário.
+	 * @param array $params Uma array contendo os parâmetros do status de funcionário que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateEmployeeStatus($params)
+	{
+		$result = $this->so->updateEmployeeStatus($params['funcionario_status_id'], $params['organizacao_id'], $params['descricao'], $params['exibir']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove um Status de funcionário.
+	 * @param array $params Uma array contendo a organização e o ID do status de funcionário que será excluído (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeEmployeeStatus($params)
+	{
+		$result = $this->so->removeEmployeeStatus($params['funcionario_status_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista as possíveis categorias de uma organização.
+	 * @param array $params Uma array contendo o ID da organização de onde as categorias serão listadas (Ajax).
+	 * @return array Lista dos possíveis categorias.
+	 * @access public
+	 */
+	function listEmployeeCategory($params)
+	{
+		$result = $this->so->getEmployeeCategory($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona uma categoria.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar uma categoria (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addEmployeeCategory($params)
+	{
+		$result = $this->so->addEmployeeCategory($params['organizacao_id'], $params['descricao']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza uma categoria.
+	 * @param array $params Uma array contendo os parâmetros da categoria que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateEmployeeCategory($params)
+	{
+		$result = $this->so->updateEmployeeCategory($params['funcionario_categoria_id'], $params['organizacao_id'], $params['descricao']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove uma categoria.
+	 * @param array $params Uma array contendo o ID da categoria que será excluída e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeEmployeeCategory($params)
+	{
+		$result = $this->so->removeEmployeeCategory($params['funcionario_categoria_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista os possíveis cargos de uma organização.
+	 * @param array $params Uma array contendo o ID da organização de onde os cargos serão listados (Ajax).
+	 * @return array Lista dos possíveis cargos.
+	 * @access public
+	 */
+	function listJobTitle($params)
+	{
+		$result = $this->so->getJobTitle($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona um cargo.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar um cargo (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addJobTitle($params)
+	{
+		$result = $this->so->addJobTitle($params['organizacao_id'], $params['descricao']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza um cargo.
+	 * @param array $params Uma array contendo os parâmetros do cargo que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateJobTitle($params)
+	{
+		$result = $this->so->updateJobTitle($params['cargo_id'], $params['organizacao_id'], $params['descricao']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove um cargo.
+	 * @param array $params Uma array contendo o ID do cargo que será excluído e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeJobTitle($params)
+	{
+		$result = $this->so->removeJobTitle($params['cargo_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista os possíveis status de área.
+	 * @param array $params Uma array contendo o ID da organização de onde os status de área serão listados (Ajax).
+	 * @return array Lista dos possíveis status de área.
+	 * @access public
+	 */
+	function listAreaStatus($params)
+	{
+		$result = $this->so->getAreaStatus($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona um status de área.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar um status de área (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addAreaStatus($params)
+	{
+		$result = $this->so->addAreaStatus($params['organizacao_id'], $params['descricao'], $params['nivel']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza um status de área.
+	 * @param array $params Uma array contendo os parâmetros do status de área que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateAreaStatus($params)
+	{
+		$result = $this->so->updateAreaStatus($params['area_status_id'], $params['organizacao_id'], $params['descricao'], $params['nivel']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove um status de área.
+	 * @param array $params Uma array contendo o ID do status de área que será excluído e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeAreaStatus($params)
+	{
+		$result = $this->so->removeAreaStatus($params['area_status_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista os centros de custo de uma organização.
+	 * @param array $params Uma array contendo o ID da organização dos centros de custo (Ajax).
+	 * @return array Lista dos centros de custo de uma organização.
+	 * @access public
+	 */
+	function listCostCenter($params)
+	{
+		$result = $this->so->getCostCenter($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona um centro de custo.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar um centro de custo (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addCostCenter($params)
+	{
+		$result = $this->so->addCostCenter($params['organizacao_id'], $params['nm_centro_custo'], $params['descricao'], $params['grupo']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza um centro de custo.
+	 * @param array $params Uma array contendo os parâmetros do centro de custo que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateCostCenter($params)
+	{
+		$result = $this->so->updateCostCenter($params['organizacao_id'], $params['nm_centro_custo'], $params['descricao'], $params['grupo'], $params['centro_custo_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove um centro de custo.
+	 * @param array $params Uma array contendo o ID do centro de custo que será excluído e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeCostCenter($params)
+	{
+		$result = $this->so->removeCostCenter($params['centro_custo_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista as localidades de uma organização.
+	 * @param array $params Uma array contendo o ID da organização das localidades (Ajax).
+	 * @return array Lista das localidades de uma organização.
+	 * @access public
+	 */
+	function listLocal($params)
+	{
+		$result = $this->so->getLocal($params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona uma localidade.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar uma localidade (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addLocal($params)
+	{
+		extract( $params );
+		$result = $this->so->addLocal($organizacao_id, $this->_nullReplace($centro_custo_id), $descricao, $empresa, $endereco, $complemento, $cep, $bairro, $cidade, $uf );
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza uma localidade.
+	 * @param array $params Uma array contendo os parâmetros da localidade que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateLocal($params)
+	{
+		extract( $params );
+		$result = $this->so->updateLocal($organizacao_id, $this->_nullReplace($centro_custo_id), $descricao, $localidade_id, $empresa, $endereco, $complemento, $cep, $bairro, $cidade, $uf );
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove uma localidade.
+	 * @param array $params Uma array contendo o ID da localidade que será excluída e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeLocal($params)
+	{
+		$result = $this->so->removeLocal($params['localidade_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista os funcionários de uma área.
+	 * @param array $params Uma array contendo o ID da organização dos funcionários e de uma área desta organização (Ajax).
+	 * @return array Lista dos funcionários de uma área.
+	 * @access public
+	 */
+	function listAreaEmployee($params)
+	{
+		$result = $this->so->getAreaEmployee($params['area_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista de funcionários que satisfazem um determinados critério de busca.
+	 * @param array $params Uma array contendo o ID da organização dos funcionários e o critério de busca (Ajax).
+	 * @return array Lista das localidades de uma organização.
+	 * @access public
+	 */
+	function searchEmployee($params)
+	{
+		if (!ereg('^([[:alnum:] ]+)$', $params['search_term']))
+			die(serialize("Parametro de busca inválido"));
+		$result = $this->so->searchEmployee($params['search_term'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		usort($result, create_function('$a,$b', 'return strcasecmp($a[\'funcionario_id_desc\'],$b[\'funcionario_id_desc\']);'));
+		return $result;
+	}
+
+	/**
+	 * Adiciona um funcionário.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar um funcionário (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addEmployee($params)
+	{
+		$result = $this->so->addEmployee($params['funcionario_id'], $params['organizacao_id'], $params['area_id'], $this->_nullReplace($params['centro_custo_id']), $params['localidade_id'], $params['funcionario_status_id'], $this->_nullReplace($params['cargo_id']), $this->_nullReplace($params['nivel']), $this->_nullReplace($params['funcionario_categoria_id']), $params['titulo']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza funcionário.
+	 * @param array $params Uma array contendo os parâmetros do funcionário que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateEmployee($params)
+	{
+		$result = $this->so->updateEmployee($params['funcionario_id'], $params['organizacao_id'], $params['area_id'], $this->_nullReplace($params['centro_custo_id']), $params['localidade_id'], $params['funcionario_status_id'], $this->_nullReplace($params['cargo_id']), $this->_nullReplace($params['nivel']), $this->_nullReplace($params['funcionario_categoria_id']), $params['titulo']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove um funcionário.
+	 * @param array $params Uma array contendo o ID do funcionário que será excluído e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeEmployee($params)
+	{
+		$result = $this->so->removeEmployee($params['funcionario_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista as áreas de uma organização.
+	 * @param array $params Uma array contendo o ID da organização das áreas (Ajax).
+	 * @return array Lista das áreas de uma organização.
+	 * @access public
+	 */
+	function listArea($params)
+	{
+		$result = $this->so->getArea($params['organizacao_id'], $params['area_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista, hierarquicamente, as áreas de uma organização.
+	 * @param array $params Uma array contendo o ID da organização das áreas (Ajax).
+	 * @return array Lista hierárquica das áreas de uma organização.
+	 * @access public
+	 */
+	function listHierarchicalArea($params)
+	{
+		$result = $this->so->getHierarchicalArea($params['organizacao_id'], null, 0);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona uma área.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar uma área (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addArea($params)
+	{
+		$result = $this->so->addArea($params['centro_custo_id'], $params['organizacao_id'], $params['area_status_id'], $this->_nullReplace($params['titular_funcionario_id']), $this->_nullReplace($params['superior_area_id']), $params['sigla'], $params['descricao'], $params['ativa'], $this->_nullReplace($params['auxiliar_funcionario_id']));
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza uma área.
+	 * @param array $params Uma array contendo os parâmetros da área que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateArea($params)
+	{
+		$result = $this->so->updateArea($params['centro_custo_id'], $params['organizacao_id'], $params['area_status_id'], $this->_nullReplace($params['titular_funcionario_id']), $this->_nullReplace($params['superior_area_id']), $params['sigla'], $params['descricao'], $params['ativa'], $this->_nullReplace($params['auxiliar_funcionario_id']), $params['area_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove uma área.
+	 * @param array $params Uma array contendo o ID da área que será excluído e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeArea($params)
+	{
+		$result = $this->so->removeArea($params['area_id'], $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Busca informações sobre um funcionário.
+	 * @param array $params Uma array contendo o ID do funcionário cujas informações serão extraídas e de sua organização (Ajax).
+	 * @return array Informações sobre o funcionário.
+	 * @access public
+	 */
+	function getEmployeeInfo($params)
+	{
+		$result = $this->so->getEmployeeInfo((int) $params['funcionario_id'], (int) $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Busca informações sobre uma área.
+	 * @param array $params Uma array contendo o ID da área cujas informações serão extraídas e de sua organização (Ajax).
+	 * @return array Informações sobre a área.
+	 * @access public
+	 */
+	function getAreaInfo($params)
+	{
+		$result = $this->so->getAreaInfo((int) $params['area_id'], (int) $params['organizacao_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Lista todos os telefones da organização.
+	 * @param array $params Uma array contendo o ID da organização de onde os telefones serão listados (Ajax).
+	 * @return array Lista de telefones da organização.
+	 * @access public
+	 */
+	function listTelephones( $params )
+	{
+		$result = $this -> so -> getTelephones( $params[ 'organizacao_id' ] );
+		$this -> disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona um telefone a uma organização.
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar um telefone (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function addTelephones( $params )
+	{
+		$result = $this -> so -> addTelephone( $params[ 'organizacao_id' ], $params[ 'descricao' ], $params[ 'numero' ] );
+		$this->disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza um telefone de uma organização.
+	 * @param array $params Uma array contendo os parâmetros de telefone da organização que podem ser alterados (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function updateTelephones( $params )
+	{
+		$result = $this -> so -> updateTelephone( $params[ 'organizacao_id' ], $params[ 'telefone_id' ], $params[ 'descricao' ], $params[ 'numero' ] );
+		$this->disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * Remove um telefone de uma organização.
+	 * @param array $params Uma array contendo o ID do telefone que será excluído e de sua organização (Ajax).
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
+	 * @access public
+	 */
+	function removeTelephones( $params )
+	{
+		$result = $this -> so -> removeTelephone( $params[ 'organizacao_id' ], $params[ 'telefone_id' ] );
+		$this->disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * Add a substitution to an specific area
+	 * @param array $params An array filled by the substitution parameters
+	 * @return bool TRUE if we are successfull, FALSE otherwise
+	 * @access public
+	 */
+	function addSubstitution( $params )
+	{
+		$result = $this -> so -> addSubstitution( $params[ 'organizacao_id' ], $params[ 'area_id' ], $params[ 'substituto_funcionario_id' ], $params[ 'data_inicio' ], $params[ 'data_fim' ] );
+		$this->disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * Update a substitution
+	 * @param array $params An array filled by the substitution parameters
+	 * @return bool TRUE if we are successfull, FALSE otherwise
+	 * @access public
+	 */
+	function updateSubstitution( $params )
+	{
+		$result = $this -> so -> updateSubstitution( $params[ 'organizacao_id' ], $params[ 'area_id' ], $params[ 'substituto_funcionario_id' ], $params[ 'data_inicio' ], $params[ 'data_fim' ], $params['substituicao_id'] );
+		$this->disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * List the substitutions for a given area.
+	 * @param array $params An array containing the areaID
+	 * @return array Substitution's list
+	 * @access public
+	 */
+	function listSubstitution( $params )
+	{
+		$result = $this -> so -> getSubstitutions( $params['organizacao_id'], $params[ 'area_id' ] );
+		$this -> disconnect_all( );
+
+		return $result;
+	}
+
+	/**
+	 * Remove a substitution
+	 * @param array $params An array containing a substitutionID
+	 * @return bool
+	 * @access public
+	 */
+	function removeSubstitution( $params )
+	{
+		$result = $this -> so -> removeSubstitution( $params['organizacao_id'], $params[ 'substituicao_id' ] );
+		$this -> disconnect_all( );
+
+		return $result;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_instancemanager.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_instancemanager.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_instancemanager.inc.php	(revision 2372)
@@ -0,0 +1,22 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'InstanceManager.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_instancemanager extends InstanceManager
+	{  /**
+		 * Construtor da classe workflow_instancemanager
+		 * @access public
+		 * @return object
+		 */
+		function workflow_instancemanager()
+		{
+			parent::InstanceManager(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/nano/JSON.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/JSON.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/nano/JSON.php	(revision 795)
@@ -0,0 +1,788 @@
+<?php
+
+/**
+ * Converts to and from JSON format.
+ *
+ * All strings should be in ASCII or UTF-8 format!
+ *
+ * LICENSE: Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met: Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following
+ * disclaimer. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * @category
+ * @package     Services_JSON
+ * @author      Michal Migurski <mike-json@teczno.com>
+ * @author      Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author      Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright   2005 Michal Migurski
+ * @version     CVS: $Id: JSON.php 366 2007-05-08 19:34:24Z drovetto $
+ * @license     http://www.opensource.org/licenses/bsd-license.php
+ * @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+ */
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_SLICE',   1);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_STR',  2);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_ARR',  3);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_OBJ',  4);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_CMT', 5);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_LOOSE_TYPE', 16);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
+
+/**
+ * Converts to and from JSON format.
+ *
+ * Brief example of use:
+ *
+ * <code>
+ * // create a new instance of Services_JSON
+ * $json = new Services_JSON();
+ *
+ * // convert a complexe value to JSON notation, and send it to the browser
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+ * $output = $json->encode($value);
+ *
+ * print($output);
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+ *
+ * // accept incoming POST data, assumed to be in JSON notation
+ * $input = file_get_contents('php://input', 1000000);
+ * $value = $json->decode($input);
+ * </code>
+ */
+class Services_JSON
+{
+   /**
+    * constructs a new JSON instance
+    *
+    * @param    int     $use    object behavior flags; combine with boolean-OR
+    *
+    *                           possible values:
+    *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
+    *                                   "{...}" syntax creates associative arrays
+    *                                   instead of objects in decode().
+    *                           - SERVICES_JSON_SUPPRESS_ERRORS:  error suppression.
+    *                                   Values which can't be encoded (e.g. resources)
+    *                                   appear as NULL instead of throwing errors.
+    *                                   By default, a deeply-nested resource will
+    *                                   bubble up with an error, so all return values
+    *                                   from encode() should be checked with isError()
+    */
+    function Services_JSON($use = 0)
+    {
+        $this->use = $use;
+    }
+
+   /**
+    * convert a string from one UTF-16 char to one UTF-8 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf16  UTF-16 character
+    * @return   string  UTF-8 character
+    * @access   private
+    */
+    function utf162utf8($utf16)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding')) {
+            return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+        }
+
+        $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+        switch(true) {
+            case ((0x7F & $bytes) == $bytes):
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x7F & $bytes);
+
+            case (0x07FF & $bytes) == $bytes:
+                // return a 2-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xC0 | (($bytes >> 6) & 0x1F))
+                     . chr(0x80 | ($bytes & 0x3F));
+
+            case (0xFFFF & $bytes) == $bytes:
+                // return a 3-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xE0 | (($bytes >> 12) & 0x0F))
+                     . chr(0x80 | (($bytes >> 6) & 0x3F))
+                     . chr(0x80 | ($bytes & 0x3F));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }
+
+   /**
+    * convert a string from one UTF-8 char to one UTF-16 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf8   UTF-8 character
+    * @return   string  UTF-16 character
+    * @access   private
+    */
+    function utf82utf16($utf8)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding')) {
+            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+        }
+
+        switch(strlen($utf8)) {
+            case 1:
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return $utf8;
+
+            case 2:
+                // return a UTF-16 character from a 2-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x07 & (ord($utf8{0}) >> 2))
+                     . chr((0xC0 & (ord($utf8{0}) << 6))
+                         | (0x3F & ord($utf8{1})));
+
+            case 3:
+                // return a UTF-16 character from a 3-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr((0xF0 & (ord($utf8{0}) << 4))
+                         | (0x0F & (ord($utf8{1}) >> 2)))
+                     . chr((0xC0 & (ord($utf8{1}) << 6))
+                         | (0x7F & ord($utf8{2})));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }
+
+   /**
+    * encodes an arbitrary variable into JSON format
+    *
+    * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
+    *                           see argument 1 to Services_JSON() above for array-parsing behavior.
+    *                           if var is a strng, note that encode() always expects it
+    *                           to be in ASCII or UTF-8 format!
+    *
+    * @return   mixed   JSON string representation of input var or an error if a problem occurs
+    * @access   public
+    */
+    function encode($var)
+    {
+        switch (gettype($var)) {
+            case 'boolean':
+                return $var ? 'true' : 'false';
+
+            case 'NULL':
+                return 'null';
+
+            case 'integer':
+                return (int) $var;
+
+            case 'double':
+            case 'float':
+                return (float) $var;
+
+            case 'string':
+                // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+                $ascii = '';
+                $var = utf8_encode($var);
+                $strlen_var = strlen($var);
+
+               /*
+                * Iterate over every character in the string,
+                * escaping with a slash or encoding to UTF-8 where necessary
+                */
+                for ($c = 0; $c < $strlen_var; ++$c) {
+
+                    $ord_var_c = ord($var{$c});
+
+                    switch (true) {
+                        case $ord_var_c == 0x08:
+                            $ascii .= '\b';
+                            break;
+                        case $ord_var_c == 0x09:
+                            $ascii .= '\t';
+                            break;
+                        case $ord_var_c == 0x0A:
+                            $ascii .= '\n';
+                            break;
+                        case $ord_var_c == 0x0C:
+                            $ascii .= '\f';
+                            break;
+                        case $ord_var_c == 0x0D:
+                            $ascii .= '\r';
+                            break;
+
+                        case $ord_var_c == 0x22:
+                        case $ord_var_c == 0x2F:
+                        case $ord_var_c == 0x5C:
+                            // double quote, slash, slosh
+                            $ascii .= '\\'.$var{$c};
+                            break;
+
+                        case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+                            // characters U-00000000 - U-0000007F (same as ASCII)
+                            $ascii .= $var{$c};
+                            break;
+
+                        case (($ord_var_c & 0xE0) == 0xC0):
+                            // characters U-00000080 - U-000007FF, mask 110XXXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+                            $c += 1;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xF0) == 0xE0):
+                            // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}));
+                            $c += 2;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xF8) == 0xF0):
+                            // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}));
+                            $c += 3;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xFC) == 0xF8):
+                            // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}));
+                            $c += 4;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xFE) == 0xFC):
+                            // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}),
+                                         ord($var{$c + 5}));
+                            $c += 5;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+                    }
+                }
+
+                return '"'.$ascii.'"';
+
+            case 'array':
+               /*
+                * As per JSON spec if any array key is not an integer
+                * we must treat the the whole array as an object. We
+                * also try to catch a sparsely populated associative
+                * array with numeric keys here because some JS engines
+                * will create an array with empty indexes up to
+                * max_index which can cause memory issues and because
+                * the keys, which may be relevant, will be remapped
+                * otherwise.
+                *
+                * As per the ECMA and JSON specification an object may
+                * have any string as a property. Unfortunately due to
+                * a hole in the ECMA specification if the key is a
+                * ECMA reserved word or starts with a digit the
+                * parameter is only accessible using ECMAScript's
+                * bracket notation.
+                */
+
+                // treat as a JSON object
+                if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+                    $properties = array_map(array($this, 'name_value'),
+                                            array_keys($var),
+                                            array_values($var));
+
+                    foreach($properties as $property) {
+                        if(Services_JSON::isError($property)) {
+                            return $property;
+                        }
+                    }
+
+                    return '{' . join(',', $properties) . '}';
+                }
+
+                // treat it like a regular array
+                $elements = array_map(array($this, 'encode'), $var);
+
+                foreach($elements as $element) {
+                    if(Services_JSON::isError($element)) {
+                        return $element;
+                    }
+                }
+
+                return '[' . join(',', $elements) . ']';
+
+            case 'object':
+                $vars = get_object_vars($var);
+
+                $properties = array_map(array($this, 'name_value'),
+                                        array_keys($vars),
+                                        array_values($vars));
+
+                foreach($properties as $property) {
+                    if(Services_JSON::isError($property)) {
+                        return $property;
+                    }
+                }
+
+                return '{' . join(',', $properties) . '}';
+
+            default:
+                return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
+                    ? 'null'
+                    : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
+        }
+    }
+
+   /**
+    * array-walking function for use in generating JSON-formatted name-value pairs
+    *
+    * @param    string  $name   name of key to use
+    * @param    mixed   $value  reference to an array element to be encoded
+    *
+    * @return   string  JSON-formatted name-value pair, like '"name":value'
+    * @access   private
+    */
+    function name_value($name, $value)
+    {
+        $encoded_value = $this->encode($value);
+
+        if(Services_JSON::isError($encoded_value)) {
+            return $encoded_value;
+        }
+
+        return $this->encode(strval($name)) . ':' . $encoded_value;
+    }
+
+   /**
+    * reduce a string by removing leading and trailing comments and whitespace
+    *
+    * @param    $str    string      string value to strip of comments and whitespace
+    *
+    * @return   string  string value stripped of comments and whitespace
+    * @access   private
+    */
+    function reduce_string($str)
+    {
+        $str = preg_replace(array(
+
+                // eliminate single line comments in '// ...' form
+                '#^\s*//(.+)$#m',
+
+                // eliminate multi-line comments in '/* ... */' form, at start of string
+                '#^\s*/\*(.+)\*/#Us',
+
+                // eliminate multi-line comments in '/* ... */' form, at end of string
+                '#/\*(.+)\*/\s*$#Us'
+
+            ), '', $str);
+
+        // eliminate extraneous space
+        return trim($str);
+    }
+
+   /**
+    * decodes a JSON string into appropriate variable
+    *
+    * @param    string  $str    JSON-formatted string
+    *
+    * @return   mixed   number, boolean, string, array, or object
+    *                   corresponding to given JSON input string.
+    *                   See argument 1 to Services_JSON() above for object-output behavior.
+    *                   Note that decode() always returns strings
+    *                   in ASCII or UTF-8 format!
+    * @access   public
+    */
+    function decode($str)
+    {
+        $str = $this->reduce_string($str);
+
+        switch (strtolower($str)) {
+            case 'true':
+                return true;
+
+            case 'false':
+                return false;
+
+            case 'null':
+                return null;
+
+            default:
+                $m = array();
+
+                if (is_numeric($str)) {
+                    // Lookie-loo, it's a number
+
+                    // This would work on its own, but I'm trying to be
+                    // good about returning integers where appropriate:
+                    // return (float)$str;
+
+                    // Return float or int, as appropriate
+                    return ((float)$str == (integer)$str)
+                        ? (integer)$str
+                        : (float)$str;
+
+                } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+                    // STRINGS RETURNED IN UTF-8 FORMAT
+                    $delim = substr($str, 0, 1);
+                    $chrs = substr($str, 1, -1);
+                    $utf8 = '';
+                    $strlen_chrs = strlen($chrs);
+
+                    for ($c = 0; $c < $strlen_chrs; ++$c) {
+
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                        $ord_chrs_c = ord($chrs{$c});
+
+                        switch (true) {
+                            case $substr_chrs_c_2 == '\b':
+                                $utf8 .= chr(0x08);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\t':
+                                $utf8 .= chr(0x09);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\n':
+                                $utf8 .= chr(0x0A);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\f':
+                                $utf8 .= chr(0x0C);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\r':
+                                $utf8 .= chr(0x0D);
+                                ++$c;
+                                break;
+
+                            case $substr_chrs_c_2 == '\\"':
+                            case $substr_chrs_c_2 == '\\\'':
+                            case $substr_chrs_c_2 == '\\\\':
+                            case $substr_chrs_c_2 == '\\/':
+                                if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+                                   ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+                                    $utf8 .= $chrs{++$c};
+                                }
+                                break;
+
+                            case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+                                // single, escaped unicode character
+                                $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+                                       . chr(hexdec(substr($chrs, ($c + 4), 2)));
+                                $utf8 .= $this->utf162utf8($utf16);
+                                $c += 5;
+                                break;
+
+                            case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+                                $utf8 .= $chrs{$c};
+                                break;
+
+                            case ($ord_chrs_c & 0xE0) == 0xC0:
+                                // characters U-00000080 - U-000007FF, mask 110XXXXX
+                                //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 2);
+                                ++$c;
+                                break;
+
+                            case ($ord_chrs_c & 0xF0) == 0xE0:
+                                // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 3);
+                                $c += 2;
+                                break;
+
+                            case ($ord_chrs_c & 0xF8) == 0xF0:
+                                // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 4);
+                                $c += 3;
+                                break;
+
+                            case ($ord_chrs_c & 0xFC) == 0xF8:
+                                // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 5);
+                                $c += 4;
+                                break;
+
+                            case ($ord_chrs_c & 0xFE) == 0xFC:
+                                // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 6);
+                                $c += 5;
+                                break;
+
+                        }
+
+                    }
+
+                    return $utf8;
+
+                } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+                    // array, or object notation
+
+                    if ($str{0} == '[') {
+                        $stk = array(SERVICES_JSON_IN_ARR);
+                        $arr = array();
+                    } else {
+                        if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = array();
+                        } else {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = new stdClass();
+                        }
+                    }
+
+                    array_push($stk, array('what'  => SERVICES_JSON_SLICE,
+                                           'where' => 0,
+                                           'delim' => false));
+
+                    $chrs = substr($str, 1, -1);
+                    $chrs = $this->reduce_string($chrs);
+
+                    if ($chrs == '') {
+                        if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                            return $arr;
+
+                        } else {
+                            return $obj;
+
+                        }
+                    }
+
+                    //print("\nparsing {$chrs}\n");
+
+                    $strlen_chrs = strlen($chrs);
+
+                    for ($c = 0; $c <= $strlen_chrs; ++$c) {
+
+                        $top = end($stk);
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+
+                        if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+                            // found a comma that is not inside a string, array, etc.,
+                            // OR we've reached the end of the character list
+                            $slice = substr($chrs, $top['where'], ($c - $top['where']));
+                            array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+                            //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                            if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                                // we are in an array, so just push an element onto the stack
+                                array_push($arr, $this->decode($slice));
+
+                            } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                                // we are in an object, so figure
+                                // out the property name and set an
+                                // element in an associative array,
+                                // for now
+                                $parts = array();
+
+                                if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // "name":value pair
+                                    $key = $this->decode($parts[1]);
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // name:value pair, where name is unquoted
+                                    $key = $parts[1];
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                }
+
+                            }
+
+                        } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+                            // found a quote, and we are not inside a string
+                            array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+                            //print("Found start of string at {$c}\n");
+
+                        } elseif (($chrs{$c} == $top['delim']) &&
+                                 ($top['what'] == SERVICES_JSON_IN_STR) &&
+                                 ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
+                            // found a quote, we're in a string, and it's not escaped
+                            // we know that it's not escaped becase there is _not_ an
+                            // odd number of backslashes at the end of the string so far
+                            array_pop($stk);
+                            //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '[') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-bracket, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+                            //print("Found start of array at {$c}\n");
+
+                        } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+                            // found a right-bracket, and we're in an array
+                            array_pop($stk);
+                            //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '{') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-brace, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+                            //print("Found start of object at {$c}\n");
+
+                        } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+                            // found a right-brace, and we're in an object
+                            array_pop($stk);
+                            //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($substr_chrs_c_2 == '/*') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a comment start, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+                            $c++;
+                            //print("Found start of comment at {$c}\n");
+
+                        } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+                            // found a comment end, and we're in one now
+                            array_pop($stk);
+                            $c++;
+
+                            for ($i = $top['where']; $i <= $c; ++$i)
+                                $chrs = substr_replace($chrs, ' ', $i, 1);
+
+                            //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        }
+
+                    }
+
+                    if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                        return $arr;
+
+                    } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                        return $obj;
+
+                    }
+
+                }
+        }
+    }
+
+    /**
+     * @todo Ultimately, this should just call PEAR::isError()
+     */
+    function isError($data, $code = null)
+    {
+        if (class_exists('pear')) {
+            return PEAR::isError($data, $code);
+        } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
+                                 is_subclass_of($data, 'services_json_error'))) {
+            return true;
+        }
+
+        return false;
+    }
+}
+
+if (class_exists('PEAR_Error')) {
+
+    class Services_JSON_Error extends PEAR_Error
+    {
+        function Services_JSON_Error($message = 'unknown error', $code = null,
+                                     $mode = null, $options = null, $userinfo = null)
+        {
+            parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+        }
+    }
+
+} else {
+
+    /**
+     * @todo Ultimately, this class shall be descended from PEAR_Error
+     */
+    class Services_JSON_Error
+    {
+        function Services_JSON_Error($message = 'unknown error', $code = null,
+                                     $mode = null, $options = null, $userinfo = null)
+        {
+
+        }
+    }
+
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/NanoGuardian.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/NanoGuardian.class.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/nano/NanoGuardian.class.php	(revision 2372)
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * NanoGuardian helps to secure user defined classes against XSS or
+ * SQL injection, etc.; it provides an easy to use interface to
+ * NanoSanitizer
+ *
+ * @package NanoAjax
+ *
+ */
+abstract class NanoGuardian
+{
+    /**
+     * holds a NanoSanitizer object
+     *
+     * @var NanoSanitizer
+     */
+    protected $_mObjNanoSanitizer;
+
+    /**
+     * holds signatures for unsafe parameter variables
+     *
+     * @var array
+     */
+    protected $_mArrSignatures = array();
+
+
+    /**
+     * a Constructor
+     *
+     */
+    public function __construct()
+    {
+        $this->_mObjNanoSanitizer = &Factory::newInstance('NanoSanitizer', new DummyLogger);
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param array $params
+     */
+    protected function _getSanatizedParameter( $params = array() )
+    {
+        $this->_mObjNanoSanitizer->setErrorReporting(true);
+        $this->_mObjNanoSanitizer->loadPresets();
+        $this->_mObjNanoSanitizer->setSignatures($this->_mArrSignatures);
+
+        $this->_mObjNanoSanitizer->setUnSecureData($params);
+
+        return $this->_mObjNanoSanitizer->executeSanitization();
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param array $data
+     */
+    protected function _returnUtf8EncodedData( $data = array() )
+    {
+        array_walk_recursive($data,array($this,'_encodeUtf8'));
+        return $data;
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param mixed $item
+     * @param unknown_type $key
+     */
+    protected function _encodeUtf8( &$item, $key )
+    {
+        $item = utf8_encode($item);
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/NanoUtil.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/NanoUtil.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/nano/NanoUtil.class.php	(revision 795)
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * NanoUtil class provides nice methods often used functionality
+ *
+ * @package NanoAjax
+ *
+ */
+class NanoUtil
+{
+    /**
+     * Enter description here...
+     *
+     * @param string $string
+     * @return boolean
+     */
+    static public function isNotEmptyString( $string = '' )
+    {
+        return ( is_string($string) && '' != $string );
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param array $array
+     * @return boolean
+     */
+    static public function isNotEmptyArray( $array = array() )
+    {
+        return ( is_array($array) && count($array) > 0 );
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param array $array
+     * @param mixed $key
+     * @param string $default
+     * @return mixed
+     */
+    static public function getParam( $array, $key, $default = '' )
+    {
+        return ( ( is_array($array) && isset($key) && array_key_exists($key,$array) )
+                       ? $array[$key]
+                       : $default );
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param array $array
+     * @param unknown_type $key
+     * @param unknown_type $fallback_array
+     * @param unknown_type $fallback_key
+     * @param unknown_type $default
+     * @return unknown
+     */
+    static public function getParamFallback( $array, $key, $fallback_array, $fallback_key, $default = '' )
+    {
+        return ( '' != self::getParam( $array         , $key         , $default ) )
+                     ? self::getParam( $array         , $key         , $default )
+                     : self::getParam( $fallback_array, $fallback_key, $default );
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $object
+     * @param unknown_type $property
+     * @param unknown_type $key
+     * @param unknown_type $default
+     * @return unknown
+     */
+    static public function getProp( $object, $property, $key, $default = '' )
+    {
+        return ( ( is_object($object)
+                   &&
+                   isset($object->$property)
+                   &&
+                   !empty($key)
+                   &&
+                   is_array($object->$property)
+                   &&
+                   isset($object->{$property}[$key]) )
+                      ? $object->{$property}[$key]
+                      : $default );
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @return unknown
+     */
+    static public function getThisScript()
+    {
+        return self::getRawFilename( $_SERVER['SCRIPT_NAME'] );
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @return unknown
+     */
+    static public function getCurrentScriptWithPath()
+    {
+        return $_SERVER['SCRIPT_NAME'];
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @return unknown
+     */
+    static public function getFullUri()
+    {
+    	$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+    	                ? "https://"
+    	                : "http://";
+
+    	return $protocol.$_SERVER['HTTP_HOST'].self::getCurrentScriptWithPath();
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/include/NanoSanitizer.presets.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/include/NanoSanitizer.presets.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/nano/include/NanoSanitizer.presets.inc.php	(revision 795)
@@ -0,0 +1,133 @@
+<?php
+
+return array(
+
+// -----------------------------------------------------------------------------
+// {unsigned} TINYINT (integer) min 0 to 255
+'tinyint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' =>   0,
+                                                                 'max' => 255 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {signed} TINYINT (integer) min -128 to 127
+'signedtinyint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' => -128,
+                                                                 'max' =>  127 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {unsigned} SMALLINT (integer) min 0 to 65535
+'smallint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' =>     0,
+                                                                 'max' => 65535 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {signed} SMALLINT (integer) min -32768 to 32767
+'signedsmallint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' => -32768,
+                                                                 'max' =>  32767 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {unsigned} MEDIUMINT (integer) min 0 to 16777215
+'mediumint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' =>        0,
+                                                                 'max' => 16777215 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {signed} MEDIUMINT (integer) min -8388608 to 8388607
+'signedmediumint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' => -8388608,
+                                                                 'max' =>  8388607 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {unsigned} INTEGER (integer) min 0 to 4294967295
+'integer' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' =>          0,
+                                                                 'max' => 4294967295 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {signed} INTEGER (integer) min -2147483648 to 2147483647
+'signedinteger' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' => -2147483648,
+                                                                 'max' =>  2147483647 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {unsigned} BIGINT (integer) min 0 to 18446744073709551615
+'bigint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' =>                    0,
+                                                                 'max' => 18446744073709551615 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// {signed} BIGINT (integer) min -9223372036854775808 to 9223372036854775807
+'signedbigint' =>
+            array( 'type'    => 'integer',
+                   'methods' => array( array( 'name'   => '_limitIntegerValue',
+                                              'limits' => array( 'min' => -9223372036854775808,
+                                                                 'max' =>  9223372036854775807 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// DEFAULT alphanumeric (string)
+'alphanumeric' =>
+            array( 'type'    => 'string',
+                   'methods' => array( array( 'name'   => '_sanitizeDefaultAlphaNumericString',
+                                              'limits' => array( 'min' =>  0,
+                                                                 'max' => 30 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// PARANOID alphanumeric (string)
+'paranoid_alphanumeric' =>
+            array( 'type'    => 'string',
+                   'methods' => array( array( 'name'   => '_sanitizeParanoidAlphaNumericString',
+                                              'limits' => array( 'min' =>  0,
+                                                                 'max' => 30 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// DEFAULT german alphanumeric (string)
+'german_alphanumeric' =>
+            array( 'type'    => 'string',
+                   'methods' => array( array( 'name'   => '_sanitizeDefaultGermanAlphaNumericString',
+                                              'limits' => array( 'min' =>  0,
+                                                                 'max' => 30 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+// PARANOID german alphanumeric (string)
+'paranoid_germanalphanumeric' =>
+            array( 'type'    => 'string',
+                   'methods' => array( array( 'name'   => '_sanitizeParanoidGermanAlphaNumericString',
+                                              'limits' => array( 'min' =>  0,
+                                                                 'max' => 30 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+'sql_query' =>
+            array( 'type'    => 'string',
+                   'methods' => array( array( 'name'   => '_sanitizeDefaultSqlString',
+                                              'limits' => array( 'min' =>  0,
+                                                                 'max' => 100 ) ) ) ),
+
+// -----------------------------------------------------------------------------
+'paranoid_sql_query' =>
+            array( 'type'    => 'string',
+                   'methods' => array( array( 'name'   => '_sanitizeParanoidSqlString',
+                                              'limits' => array( 'min' =>  0,
+                                                                 'max' => 100 ) ) ) )
+
+);
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/NanoJsonConverter.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/NanoJsonConverter.class.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/nano/NanoJsonConverter.class.php	(revision 2372)
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * NanoJsonConverter
+ *
+ * @package NanoAjax
+ *
+ */
+class NanoJsonConverter
+{
+    /**
+     * JSON object
+     *
+     * @var JSON
+     */
+    protected $_mObjJson;
+
+    /**
+     * holds JSON string data (if manually set)
+     *
+     * @var string
+     */
+    protected $_mStrJsonData    = '';
+
+    /**
+     * holds max read input data (from php:input) [raw input]
+     *
+     * @var integer
+     */
+    protected $_mIntMaxReadSize = 2048;
+
+    /**
+     * holds JSON decoded result (array, object)
+     *
+     * @var mixed
+     */
+    protected $_mMxdJsonResult;
+
+
+    /**
+     * sets max PHP input size (default: 2048 Bytes)
+     *
+     * @param integer $max_input_size
+     */
+    public function setMaxInputSize( $max_input_size = 2048 )
+    {
+        if( is_numeric($max_input_size) )
+        {
+            $this->_mIntMaxReadSize = $max_input_size;
+        }
+    }
+
+    /**
+     * return max input size (for unit tests only)
+     *
+     * @return unknown
+     */
+    public function getMaxInputSize()
+    {
+        return $this->_mIntMaxReadSize;
+    }
+
+    /**
+     * set JSON input string (only for manually setting JSON string, unit tests)
+     *
+     * @param string $json_string
+     */
+    public function setJsonString( $json_string )
+    {
+        if( is_string($json_string) && !empty($json_string) )
+        {
+            $this->_mStrJsonData = $json_string;
+        }
+    }
+
+    /**
+     * return current JSON input String (for testing only)
+     *
+     * @return unknown
+     */
+    public function getJsonString()
+    {
+        return $this->_mStrJsonData;
+    }
+
+    /**
+     * decode JSON string into an assoziative array
+     *
+     * @return array
+     */
+    public function getJsonDecodedAsArray()
+    {
+        $this->_initializeJson( 'array' );
+
+        return (array)$this->_mObjJson->decode( $this->_getJsonData() );
+    }
+
+    /**
+     * decode JSON string into an object (with instance variables)
+     *
+     * @return object
+     */
+    public function getJsonDecodedAsObject()
+    {
+        $this->_initializeJson();
+
+        return (object)$this->_mObjJson->decode( $this->_getJsonData() );
+    }
+
+
+    /**
+     * initializes JSON object with parameter
+     *
+     * @param string $return_type
+     */
+    protected function _initializeJson( $return_type = 'object' )
+    {
+        // initialize JSON object
+        $this->_mObjJson = ( strtolower($return_type) != 'object' )
+                                ? Factory::getInstance('Services_JSON', SERVICES_JSON_LOOSE_TYPE )
+                                : Factory::getInstance('Services_JSON');
+    }
+
+    /**
+     * load string dtaa from raw input or manually set input
+     *
+     * @return string
+     */
+    protected function _getJsonData()
+    {
+        return ($this->getJsonString() == '' )
+                    ? trim(file_get_contents('php://input',$this->_mIntMaxReadSize))
+                    : $this->getJsonString();
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/Logger.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/Logger.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/nano/Logger.class.php	(revision 795)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * NanoController
+ *
+ * @package NanoAjax
+ *
+ */
+class DummyLogger
+{
+    public function add( $entry ) {}
+
+    public function rawAdd( $entry ) {}
+}
+
+class Logger
+{
+    public function add( $entry )
+    {
+        $this->rawAdd( $entry."<br/>\n" );
+    }
+
+    public function rawAdd( $entry )
+    {
+        echo $entry;
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/NanoController.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/NanoController.class.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/nano/NanoController.class.php	(revision 2372)
@@ -0,0 +1,203 @@
+<?php
+
+/**
+ * NanoController
+ *
+ * @package NanoAjax
+ *
+ */
+class NanoController
+{
+    /**
+     * holds NanoJsonConverter object
+     *
+     * @var NanoJsonConverter
+     */
+    protected $_mObjJsonConverter;
+
+    /**
+     * holds JSON object
+     *
+     * @var JSON
+     */
+    protected $_mObjJson;
+
+    /**
+     * path to user classes
+     *
+     * @var string
+     */
+    protected $_mStrClassPath   = '';
+
+    /**
+     * default class suffix
+     *
+     * @var string
+     */
+    protected $_mStrClassSuffix = '.inc.php';
+    protected $_mStrClassPreffix = 'class.ajax.';
+
+    /**
+     * holds NanoRequest object for executing request
+     *
+     * @var NanoRequest
+     */
+    protected $_mObjNanoRequest;
+
+    /**
+     * holds final JSON encoded result of virtual requests
+     *
+     * @var string
+     */
+    protected $_mStrVirtualRequestsResult = '';
+
+
+    /**
+     * Constructor
+     *
+     */
+    function __construct()
+    {
+        $this->_mObjJsonConverter = &Factory::newInstance('NanoJsonConverter');
+        $this->_mObjJson          = &Factory::newInstance('Services_JSON');
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $path
+     */
+    public function setClassPath( $path )
+    {
+        if( is_string($path) && !empty($path) && is_dir($path) && is_readable($path) )
+        {
+            $this->_mStrClassPath = $path . (($path[strlen($path)-1] !== '/') ? '/' : '');
+        }
+        else
+        {
+            $this->_throw(__METHOD__,'php class path ['.$path.'] not valid!!!');
+        }
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $suffix
+     */
+    public function setClassSuffix( $suffix )
+    {
+        if( is_string($suffix) && !empty($suffix) )
+        {
+            $this->_mStrClassSuffix = $suffix;
+        }
+        else
+        {
+            $this->_throw(__METHOD__,'php class suffix not valid!!!');
+        }
+    }
+
+    public function setClassPreffix( $preffix )
+    {
+        if( is_string($preffix) && !empty($preffix) )
+        {
+            $this->_mStrClassPreffix = $preffix;
+        }
+        else
+        {
+            $this->_throw(__METHOD__,'php class preffix not valid!!!');
+        }
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param string $json_data
+     */
+    public function setJsonData( $json_data )
+    {
+        $this->_mObjJsonConverter->setJsonString($json_data);
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param boolean $print_data
+     * @return unknown
+     */
+    public function iterateOverVirtualRequests()
+    {
+        $this->_mObjNanoRequest = &Factory::newInstance('NanoRequest', $this->_mStrClassPath, $this->_mStrClassSuffix, $this->_mStrClassPreffix );
+        $return_data            = array();
+
+        foreach( $this->_mObjJsonConverter->getJsonDecodedAsArray() as $request_identifier => $request_data)
+        {
+            $output = array();
+
+            try
+            {
+                $this->_mObjNanoRequest->setRequestData($request_data);
+
+                $output['data'] = $this->_mObjNanoRequest->executeRequest();
+            }
+            catch (Exception $exception)
+            {
+                $output['exception'] = $exception->getMessage();
+            }
+
+            $return_data[$request_identifier] = $output;
+        }
+
+        $this->_mStrVirtualRequestsResult = $this->_mObjJson->encode( $return_data );
+    }
+
+
+    /**
+     * returns result of virtual request(s) as encoded JSON string
+     *
+     * @return string
+     */
+    public function getResultData()
+    {
+        return $this->_mStrVirtualRequestsResult;
+    }
+
+
+    /**
+     * outputs result of virtual request(s) as encoded JSON string
+     *
+     */
+    public function outputResultData()
+    {
+        echo $this->_mStrVirtualRequestsResult;
+    }
+
+
+    /**
+     * generates an (json) exception and output it
+     *
+     * @param string $method
+     * @param string $msg
+     */
+    protected function _throw( $method, $msg )
+    {
+        die( $this->_mObjJson->encode(array('__NANOAJAX_SYSTEM_EXCEPTION__' => array('exception' => $msg))) );
+    }
+
+    /**
+     * Throw error on all virtual requests
+     *
+     * @param string $message The message of the exception
+     */
+    public function throwErrorOnAllVirtualRequests($message)
+    {
+		$output = array();
+		foreach ($this->_mObjJsonConverter->getJsonDecodedAsArray() as $requestIdentifier => $requestData)
+			$output[$requestIdentifier] = array('exception' => $message);
+        die($this->_mObjJson->encode($output));
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/NanoRequest.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/NanoRequest.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/nano/NanoRequest.class.php	(revision 795)
@@ -0,0 +1,173 @@
+<?php
+
+/**
+ * NanoRequest
+ *
+ * @package NanoAjax
+ *
+ */
+class NanoRequest
+{
+    /**
+     * Enter description here...
+     *
+     * @var array
+     */
+    private $_mArrRequestData = array();
+
+    /**
+     * path to user classes
+     *
+     * @var string
+     */
+    private $_mStrClassPath   = '';
+
+    /**
+     * default class suffix
+     *
+     * @var string
+     */
+    private $_mStrClassSuffix = '.inc.php';
+    private $_mStrClassPreffix = 'class.ajax.';
+
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $request_data
+     */
+    public function __construct( $class_path, $class_suffix, $class_preffix )
+    {
+        $this->_mStrClassPath   = $class_path;
+        $this->_mStrClassSuffix = $class_suffix;
+        $this->_mStrClassPreffix = $class_preffix;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $request_data
+     */
+    public function setRequestData($request_data)
+    {
+        if( $this->_isRequestDataValid($request_data) )
+        {
+            $this->_mArrRequestData = $request_data;
+        }
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @return unknown
+     */
+    public function executeRequest()
+    {
+        $this->_loadUserDefinedClass( $this->_mArrRequestData['parameter']['action'] );
+
+        if( false !== ($userclass = $this->_initializeUserClass($this->_mArrRequestData['parameter']['action'])) )
+        {
+            return $this->_callUserMethod( $userclass, $this->_mArrRequestData['parameter']['mode'], $this->_mArrRequestData['data'] );
+        }
+        else
+        {
+            $this->_throwException('user class ['.$this->_mArrRequestData['parameter']['action'].'] not found!!!');
+        }
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $data
+     * @return unknown
+     */
+    private function _isRequestDataValid( $data )
+    {
+        if( is_array($data) && count($data) > 0 )
+        {
+            if( isset($data['parameter']) && !empty($data['parameter']) )
+            {
+                if( isset($data['parameter']['action']) && !empty($data['parameter']['action']) )
+                {
+                    if( isset($data['parameter']['mode']) && !empty($data['parameter']['mode']) )
+                    {
+                        return true;
+                    }
+                    else
+                    {
+                        $this->_throwException('missing or empty Parameter [mode] in (virtual) request!!!');
+                    }
+                }
+                else
+                {
+                    $this->_throwException('missing or empty Parameter [action] in (virtual) request!!!');
+                }
+            }
+            else
+            {
+                $this->_throwException('missing all parameter data in (virtual) request!!!');
+            }
+        }
+        else
+        {
+            $this->_throwException('invalid formed (virtual) request!!!');
+        }
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $classname
+     */
+    protected function _loadUserDefinedClass( $classname )
+    {
+		( NanoUtil::isNotEmptyString($classname) && /*!class_exists($classname) &&*/ file_exists($this->_mStrClassPath.$this->_mStrClassPreffix.$classname.$this->_mStrClassSuffix) && is_readable($this->_mStrClassPath.$this->_mStrClassPreffix.$classname.$this->_mStrClassSuffix) )
+             ? require_once( $this->_mStrClassPath.$this->_mStrClassPreffix.$classname.$this->_mStrClassSuffix )
+             : $this->_throwException('given class {'.$this->_mStrClassPreffix.$classname.$this->_mStrClassSuffix.
+                                      '} does not exists');
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $classname
+     * @return unknown
+     */
+    protected function _initializeUserClass( $classname )
+    {
+        return ( class_exists($classname) )
+                    ? new $classname()
+                    : false;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $userclass
+     * @param unknown_type $usermethod
+     * @param unknown_type $userdata
+     * @return unknown
+     */
+    protected function _callUserMethod( $userclass, $usermethod, $userdata )
+    {
+        return ( method_exists( $userclass, $usermethod ) )
+                    ? $userclass->$usermethod($userdata)
+                    : $this->_throwException('given user method {'.$usermethod.
+                                             '} does not exists in class ['.
+                                             get_class($userclass).']');
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $msg
+     */
+    private function _throwException( $msg )
+    {
+        throw new Exception($msg);
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/nano/NanoSanitizer.class.php
===================================================================
--- /sandbox/workflow/branches/993/inc/nano/NanoSanitizer.class.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/nano/NanoSanitizer.class.php	(revision 795)
@@ -0,0 +1,770 @@
+<?php
+
+/**
+ * NanoSanitizer
+ *
+ * @package NanoAjax
+ *
+ */
+class NanoSanitizer
+{
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var array
+     */
+    protected $_mArrSignaturePresets       = array();
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var boolean
+     */
+    protected $_mBlnMagicQuotes            = false;
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var array
+     */
+    protected $_mArrUnSecureVariables      = array();
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var array
+     */
+    protected $_mArrSignatures             = array();
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var integer
+     */
+    protected $_mIntCountUnSecureVariables = 0;
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var integer
+     */
+    protected $_mIntCountSignature         = 0;
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var array
+     */
+    protected $_mArrSanitizedVariables     = array();
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var string
+     */
+    protected $_mStrSignaturePreset        = '';
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var boolean
+     */
+    protected $_mBlnReportErrors           = false;
+
+    /**
+     * Enter description here...
+     *
+     * @access protected
+     * @var boolean
+     */
+    protected $_mBlnStopOnError            = false;
+
+    protected $logger;
+
+
+    /**
+     * Constructor, initializes object
+     *
+     * @access public
+     * @return NanoSanitizer
+     */
+    public function __construct($logger)
+    {
+        $this->logger           = $logger;
+        $this->_mBlnMagicQuotes = (bool) get_magic_quotes_gpc();
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $preset_file
+     */
+    public function loadPresets( $preset_file = '' )
+    {
+        $this->_mArrSignaturePresets = ( '' != $preset_file && is_file($preset_file) && is_readable($preset_file) )
+                                            ? include($preset_file)
+                                            : include(dirname(__FILE__).'/include/NanoSanitizer.presets.inc.php');
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param string $signature_preset
+     */
+    public function setSignaturePreset( $signature_preset = '' )
+    {
+        $this->logger->rawAdd('setting signature preset...');
+
+        if( NanoUtil::isNotEmptyString($signature_preset) && array_key_exists($signature_preset,$this->_mArrSignaturePresets) )
+        {
+            $this->_mStrSignaturePreset = $signature_preset;
+            $this->logger->add('done.');
+        }
+        else
+        {
+            $this->_throw( __METHOD__,
+                           ' signatur preset ('.$signature_preset.') {'.
+                           gettype($signature_preset).'} NOT valid!' );
+        }
+    }
+
+
+    /**
+     * Sets the signature array with paramters for later verification
+     *
+     * @param array $signature_array
+     */
+    public function setSignatures( $signatures_array )
+    {
+        $this->logger->rawAdd('setting signatures...');
+
+        if( NanoUtil::isNotEmptyArray($signatures_array) )
+        {
+            $this->_mArrSignatures     = $signatures_array;
+            $this->_mIntCountSignature = count($signatures_array);
+            $this->logger->add('done.');
+        }
+        else
+        {
+            $this->_throw( __METHOD__,
+                           ' signatur array ('.implode('|',$signatures_array).
+                           'is NOT valid!' );
+        }
+    }
+
+    /**
+     * Set variables which will be sanitized
+     *
+     * @param array $variables_array
+     */
+    public function setUnSecureData( $unsecure_variables_array )
+    {
+        $this->logger->rawAdd('setting unsecure variable array...');
+
+        if( is_array($unsecure_variables_array) && count( $unsecure_variables_array ) > 0 )
+        {
+            $this->logger->add('done.');
+            $this->_mArrUnSecureVariables      = $unsecure_variables_array;
+            $this->_mIntCountUnSecureVariables = count($unsecure_variables_array);
+        }
+        else
+        {
+            $this->_throw( __METHOD__, ' unsecure variables array is NOT valid!' );
+        }
+    }
+
+    /**
+     * sets reporting of variable unequality
+     *
+     * @param boolean $bln_switch
+     */
+    public function setErrorReporting( $bln_switch )
+    {
+        if( is_bool($bln_switch) )
+        {
+            $this->_mBlnReportErrors = $bln_switch;
+        }
+    }
+
+    /**
+     * sets reporting of variable unequality
+     *
+     * @param boolean $bln_switch
+     */
+    public function setStopOnError( $bln_switch )
+    {
+        if( is_bool($bln_switch) )
+        {
+            $this->_mBlnStopOnError = $bln_switch;
+        }
+    }
+
+
+    /**
+     * Executes sanitization
+     *
+     */
+    public function executeSanitization()
+    {
+        $this->logger->rawAdd('checking all parameters...');
+        if( false == $this->_areParemetersValid() )
+        {
+            $this->_throw( __METHOD__,
+                           'Signature / Input Variables Error !!! [S:'.
+                           $this->_mIntCountSignature.'|I:'.
+                           $this->_mIntCountUnSecureVariables.']' );
+        }
+        $this->logger->add('valid!');
+        $this->logger->add('<br/>iterating over all sigantures...');
+
+        foreach ($this->_mArrSignatures as $varname => $signature)
+        {
+            $this->logger->rawAdd('<br/>checking variable <b>'.$varname.'</b> is required but not present...');
+
+            if( $this->_isRequiredVariableNotPresent($varname,$signature) )
+            {
+                $this->_throw( __METHOD__,
+                               'Variable ['.$varname.'] is required, but NOT present!' );
+            }
+
+            $this->logger->add('OK. {'.(($this->_isVariableRequired($signature))?'required':'NOT required').'}');
+
+            $this->logger->rawAdd('checking variable exists in unsecure array...');
+
+            if( array_key_exists($varname,$this->_mArrUnSecureVariables) )
+            {
+                $this->logger->add('exists!');
+                $variable_container = trim($this->_mArrUnSecureVariables[$varname]);
+
+                $this->logger->rawAdd('searching for preset in signature...');
+
+                // -------------------------------------------------------------
+                // PRESET:
+                // is preset in signature ?
+                // set preset data to siganture
+                if( true === $this->_isSignaturePresetValid($signature) )
+                {
+                    $this->logger->add('found! {<b>'.NanoUtil::getParam($signature,'preset').'</b>}');
+                    $this->logger->rawAdd('setting signsture preset data to signature...');
+                    $signature = $this->_getSignaturePresetData($signature);
+                    $this->logger->add('done.');
+                }
+                else
+                {
+                    $this->logger->add('NOT found, using given signature.');
+                }
+
+                $this->logger->rawAdd('checking signature given type...');
+
+                // -------------------------------------------------------------
+                // TYPE:
+                // apply type (integer, string, array,...) to variable
+                // { brute force mode }
+                if( $this->_isSignatureVarTypeValid($signature) )
+                {
+                    $this->logger->rawAdd('valid. setting type [<b>'.$signature['type'].'</b>]...');
+                    settype( $variable_container, $signature['type'] );
+                    $this->logger->add('done.');
+                }
+
+                $this->logger->rawAdd('searching for (filter) methods in signature...');
+
+                // -------------------------------------------------------------
+                // METHODS:
+                // apply method(s) to variable
+                if( $this->_isSignatureMethodsValid($signature) )
+                {
+                    $this->logger->add('found.');
+
+                    // check if is not an array
+                    if( !is_array($signature['methods']) )
+                    {
+                        // put methodname into array for later iteration
+                        $signature['methods'] = array($signature['methods']);
+                    }
+
+                    $this->logger->add('iterating over given filter methods...');
+
+                    // iterate over method array
+                    foreach ( $signature['methods'] as $method_data )
+                    {
+                        $this->logger->rawAdd('executing method <b>'.$method_data['name'].'</b>...');
+
+                        if( method_exists( $this, $method_data['name'] ) )
+                        {
+                            // execute method with variable as parameter
+                            $variable_container = $this->$method_data['name']($variable_container,$method_data['limits']);
+                        }
+                        else
+                        {
+                            $logger_message = 'method ['.$method_data['name'].'] NOT found!!!';
+
+                            if( true == $this->_mBlnStopOnError )
+                            {
+                                $this->_throw( __METHOD__,'method ['.$method_data['name'].'] NOT found!!!');
+                            }
+                            else { $this->logger->add('method ['.$method_data['name'].'] NOT found!!!'); }
+                        }
+
+                        $this->logger->add('done.');
+                    }
+                }
+                else
+                {
+                    $this->logger->add('NOT found. (nothing to do)');
+                }
+
+                // -------------------------------------------------------------
+                // REPORTING (report variable change / stop if has changed)
+                if( true == $this->_mBlnReportErrors)
+                {
+                    // -------------------------------------------------------------
+                    // VERIFICATION (is variable changed in value (after sanitization)
+                    if( $this->_isVariableChanged($varname,$variable_container) )
+                    {
+                        $this->logger->add('NOT equal');
+
+                        $message = '~~ Variable <b>'.$varname.'</b> '. /* $logger */
+                        /* $logger */     'seems not to be same after sanitization '.
+                        /* $logger */     '<div style="border:1px solid #CC0000;'.
+                        /* $logger */     'background-color:#EEEEEE"><b>'.
+                        /* $logger */     htmlentities($this->_mArrUnSecureVariables[$varname]).
+                        /* $logger */     '</b>&nbsp;</div> {before} != <div style="'.
+                        /* $logger */     'border:1px solid #CC0000;background-color:'.
+                        /* $logger */     '#EEEEEE"><b>'.$variable_container.
+                        /* $logger */     '</b>&nbsp;</div> {after}';
+
+                        if( true == $this->_mBlnStopOnError )
+                        {
+                            $this->_throw( __METHOD__,$message);
+                        }
+                        else { $this->logger->add($message); }
+                    }
+                    else { $this->logger->add('IS equal'); }
+                }
+
+                // -------------------------------------------------------------
+                // ASSIGNMENT
+                $this->_assignCleanedVariable($varname,$variable_container);
+
+            }
+            else { $this->logger->add('not found! (continue with next)'); }
+        }
+
+        return $this->_mArrSanitizedVariables;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $varname
+     * @param unknown_type $cleaned_variable
+     */
+    protected function _assignCleanedVariable( $varname, $cleaned_variable )
+    {
+        // -------------------------------------------------------------
+        // ASSIGNMENT
+        // set sanitized variable to new (output) array
+        $this->logger->rawAdd('assigning cleaned input variable to output array...');
+        $this->_mArrSanitizedVariables[$varname] = $cleaned_variable;
+        $this->logger->add('done.');
+    }
+
+    protected function _isVariableChanged( $varname, $new_variable )
+    {
+        $this->logger->rawAdd('checking variable has changed while sanitization [<b>'.
+                              htmlentities($this->_mArrUnSecureVariables[$varname]).'</b>] ?? [<b>'.
+                              $new_variable.'</b>]...');
+
+        return ( !empty($this->_mArrUnSecureVariables[$varname]) && $this->_mArrUnSecureVariables[$varname] != (string)$new_variable);
+    }
+
+    protected function _isRequiredVariableNotPresent( $varname, $signature )
+    {
+        return ( false == isset($this->_mArrUnSecureVariables[$varname])
+                 &&
+                 $this->_isVariableRequired($signature) );
+    }
+
+    protected function _isVariableRequired( $signature = array() )
+    {
+        return NanoUtil::getParam($signature,'required',false);
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $signature
+     * @return unknown
+     */
+    protected function _isSignaturePresetValid( $signature = array() )
+    {
+        return ( '' != NanoUtil::getParam($signature,'preset') && array_key_exists(NanoUtil::getParam($signature,'preset'),$this->_mArrSignaturePresets) )
+                    ? true
+                    : false;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $signature
+     * @return unknown
+     */
+    protected function _getSignaturePresetData( $signature = array() )
+    {
+        $preset_signature = $this->_mArrSignaturePresets[$signature['preset']];
+
+        unset($signature['preset']);
+
+        return array_merge($signature,$preset_signature);
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $signature
+     * @return unknown
+     */
+    protected function _isSignatureVarTypeValid( $signature = array() )
+    {
+        return ( '' != NanoUtil::getParam($signature,'type') )
+                    ? true
+                    : false;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $signature
+     * @return unknown
+     */
+    protected function _isSignatureMethodsValid( $signature = array() )
+    {
+        return ( '' != NanoUtil::getParam($signature,'methods') )
+                    ? true
+                    : false;
+    }
+
+    protected function _areParemetersValid()
+    {
+        // Check all needed parameter (arrays) are loaded, not empty
+        // and size of both is equal
+        return ( $this->_mIntCountSignature         > 0
+                 &&
+                 $this->_mIntCountUnSecureVariables > 0
+                 &&
+                 $this->_mIntCountSignature        == $this->_mIntCountUnSecureVariables )
+
+                    // check passed
+                    ? true
+                    // check failed
+                    : true;
+
+    }
+
+    // addslashes wrapper to check for gpc_magic_quotes
+    protected function _addNiceSlashes($string)
+    {
+        // if magic quotes is on the string is already quoted, just return it
+        return (MAGIC_QUOTES)
+
+                    // return raw string
+                    ? $string
+
+                    // add slashes and return new string
+                    : addslashes($string);
+    }
+
+    // internal function for utf8 decoding
+    // PHP's utf8_decode function is a little
+    // screwy
+    protected function _decodeUtf8($string)
+    {
+        return utf8_decode($string);
+        /*
+        return strtr($string,
+        "???????¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ",
+        "SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy");
+        */
+    }
+
+
+    // default string sanitization -- only let the alphanumeric set through
+    protected function _sanitizeDefaultAlphaNumericString($string, $limits = array() )
+    {
+        return $this->_getLimitedString(preg_replace("/[^a-zA-Z0-9_\-\ ]/", "", $string), $limits);
+    }
+
+
+    // paranoid sanitization -- only let the alphanumeric set through
+    protected function _sanitizeParanoidAlphaNumericString($string, $limits = array() )
+    {
+        return $this->_getLimitedString(preg_replace("/[^a-zA-Z0-9]/", "", $string), $limits);
+    }
+
+
+    // default string sanitization -- only let the alphanumeric set through
+    protected function _sanitizeDefaultGermanAlphaNumericString($string, $limits = array() )
+    {
+        return $this->_getLimitedString(preg_replace("/[^a-zA-Z0-9_\-\ äöüÄÖÜß]/", "", $string), $limits);
+    }
+
+
+    // paranoid sanitization -- only let the alphanumeric set through
+    protected function _sanitizeParanoidGermanAlphaNumericString($string, $limits = array() )
+    {
+        return $this->_getLimitedString(preg_replace("/[^a-zA-Z0-9äöüÄÖÜß]/", "", $string), $limits);
+    }
+
+    // sanitize a string in prep for passing a single argument to
+    // system() or exec() or passthru()
+    protected function _sanitizeSystemString($string, $min = null, $max = null )
+    {
+        // no piping, passing possible environment variables ($),
+        // seperate commands, nested execution, file redirection,
+        // background processing, special commands (backspace, etc.), quotes
+        // newlines, or some other special characters
+        $pattern = '/(;|\||`|>|<|&|^|"|'."\n|\r|'".'|{|}|[|]|\)|\()/i';
+
+        $string  = preg_replace($pattern, '', $string);
+
+        //make sure this is only interpretted as ONE argument
+
+        return $this->_getLimitedString('"'.preg_replace('/\$/', '\\\$', $string).'"', $min, $max);
+    }
+
+
+    // sanitize a string for SQL input (simple slash out quotes and slashes)
+    protected function _sanitizeDefaultSqlString($string, $min = null, $max = null)
+    {
+        return $this->_getLimitedString($this->_saveEscapeString($string), $min, $max);
+    }
+
+
+    // sanitize a string for SQL input (simple slash out quotes and slashes)
+    protected function _sanitizeParanoidSqlString($string, $min = null, $max = null)
+    {
+        return $this->_sanitizeDefaultSqlString(strip_tags($string), $min, $max);
+    }
+
+
+    // sanitize a string for HTML (make sure nothing gets interpretted!)
+    protected function _sanitizeHtmlString($string)
+    {
+        $pattern = array( '/\&/',   //  0
+                          '/</',    //  1
+                          "/>/",    //  2
+                          '/\n/',   //  3
+                          '/"/',    //  4
+                          "/'/",    //  5
+                          "/%/",    //  6
+                          '/\(/',   //  7
+                          '/\)/',   //  8
+                          '/\+/',   //  9
+                          '/-/'  ); // 10
+
+        $replace = array( '&amp;',  //  0
+                          '&lt;',   //  1
+                          '&gt;',   //  2
+                          '<br/>',  //  3
+                          '&quot;', //  4
+                          '&#39;',  //  5
+                          '&#37;',  //  6
+                          '&#40;',  //  7
+                          '&#41;',  //  8
+                          '&#43;',  //  9
+                          '&#45;' );// 10
+
+        return preg_replace($pattern, $replace, $string);
+    }
+
+    // make float float!
+    function _sanitizeFloat($float, $min='', $max='')
+    {
+        $float = floatval($float);
+        if((($min != '') && ($float < $min)) || (($max != '') && ($float > $max)))
+        return false;
+        return $float;
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $input
+     * @param unknown_type $min
+     * @param unknown_type $max
+     * @return unknown
+     */
+    function check_float($input, $min='', $max='')
+    {
+        if($input != _sanitizeFloat($input, $min, $max))
+        return false;
+        return true;
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $input
+     * @param unknown_type $min
+     * @param unknown_type $max
+     * @return unknown
+     */
+    function check_sql_string($input, $min='', $max='')
+    {
+        if($input != _sanitizeSqlString($input, $min, $max))
+        return false;
+        return true;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $input
+     * @param unknown_type $min
+     * @param unknown_type $max
+     * @return unknown
+     */
+    function check_ldap_string($input, $min='', $max='')
+    {
+        if($input != sanitize_string($input, $min, $max))
+        return false;
+        return true;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $input
+     * @param unknown_type $min
+     * @param unknown_type $max
+     * @return unknown
+     */
+    function check_system_string($input, $min='', $max='')
+    {
+        if($input != _sanitizeSystemString($input, $min, $max, true))
+        return false;
+        return true;
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $integer
+     * @param array $limits
+     * @return mixed
+     */
+    function _limitIntegerValue($integer, $limits = array() )
+    {
+        return ( $this->_isIntegerInRange($integer, $limits) )
+
+                    ? (( true == $this->_mBlnReportErrors )
+
+                          ? (( true == $this->_mBlnStopOnError )
+
+                                ? $this->_throw(__METHOD__,'Length limit applies!!!')
+                                : $this->logger->add('Length limit applies!!!'))
+
+                          : false)
+
+                    : $integer;
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $string
+     * @param array $limits
+     * @return mixed
+     */
+    protected function _getLimitedString( $string, $limits = array() )
+    {
+        return ( $this->_isStringInRange($string,$limits) )
+
+                    ? (( true == $this->_mBlnReportErrors )
+
+                          ? (( true == $this->_mBlnStopOnError )
+
+                                ? $this->_throw(__METHOD__,'Length limit applies!!!')
+                                : $this->logger->add('Length limit applies!!!'))
+
+                          : false)
+
+                    : $string;
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $string
+     * @param array $limits
+     * @return boolean
+     */
+    protected function _isStringInRange( $string, $limits = array() )
+    {
+        return ( ( isset($limits['min']) && strlen($string) < $limits['min'] )
+                   ||
+                 ( isset($limits['max']) && strlen($string) > $limits['max'] ) );
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $string
+     * @param array $limits
+     * @return boolean
+     */
+    protected function _isIntegerInRange( $integer, $limits = array() )
+    {
+        return ( ( isset($limits['min']) && $integer < $limits['min'] )
+                   ||
+                 ( isset($limits['max']) && $integer > $limits['max'] ) );
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $string
+     * @return string mysql escaped string
+     */
+    private function _saveEscapeString( $string )
+    {
+        if( true == $this->_mBlnMagicQuotes )
+        {
+            $string = stripslashes($string);
+        }
+
+        return mysql_real_escape_string($string);
+    }
+
+
+    /**
+     * Enter description here...
+     *
+     * @param string $method
+     * @param string $msg
+     */
+    private function _throw( $method, $msg )
+    {
+        throw new Exception("[".$method.']: '.$msg);
+    }
+}
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_monitors.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_monitors.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_monitors.inc.php	(revision 2372)
@@ -0,0 +1,1661 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+
+
+/**
+ * DO NOT remove this line. Ever. Somehow, monitors interface will stop working..
+ */
+require_once(PHPGW_API_INC . SEP . 'common_functions.inc.php');
+
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class bo_monitors extends bo_ajaxinterface
+{
+	/* permissions index */
+
+	/**
+	 * @var integer $IP_CHANGE_PRIORITY
+	 * @access public
+	 */
+	var $IP_CHANGE_PRIORITY = 0;
+	/**
+	 * @var integer $IP_CHANGE_USER
+	 * @access public
+	 */
+	var $IP_CHANGE_USER = 1;
+	/**
+	 * @var integer $IP_CHANGE_STATUS
+	 * @access public
+	 */
+	var $IP_CHANGE_STATUS = 2;
+	/**
+	 * @var integer $IP_CHANGE_NAME
+	 * @access public
+	 */
+	var $IP_CHANGE_NAME = 3;
+	/**
+	 * @var integer $IP_CHANGE_ACTIVITY
+	 * @access public
+	 */
+	var $IP_CHANGE_ACTIVITY = 4;
+	/**
+	 * @var integer $IP_VIEW_PROPERTIES
+	 * @access public
+	 */
+	var $IP_VIEW_PROPERTIES = 5;
+	/**
+	 * @var integer $IP_CHANGE_PROPERTIES
+	 * @access public
+	 */
+	var $IP_CHANGE_PROPERTIES = 6;
+	/**
+	 * @var integer $IP_VIEW_STATISTICS
+	 * @access public
+	 */
+	var $IP_VIEW_STATISTICS = 7;
+	/**
+	 * @var integer $IP_REMOVE_COMPLETED_INSTANCES
+	 * @access public
+	 */
+	var $IP_REMOVE_COMPLETED_INSTANCES = 8;
+	/**
+	 * @var integer $IP_REPLACE_USER
+	 * @access public
+	 */
+	var $IP_REPLACE_USER = 9;
+	/**
+	 * @var integer $IP_SEND_EMAILS
+	 * @access public
+	 */
+	var $IP_SEND_EMAILS = 10;
+	/**
+	 * @var object $processManager
+	 * @access public
+	 */
+	var $processManager;
+	/**
+	 * @var object $activityManager
+	 * @access public
+	 */
+	var $activityManager;
+	/**
+	 * @var object $instanceManager
+	 * @access public
+	 */
+	var $instanceManager;
+	/**
+	 * @var object $roleManager
+	 * @access public
+	 */
+	var $roleManager;
+	/**
+	 * @var integer $userID
+	 * @access public
+	 */
+	var $userID;
+
+	/**
+	 * @var bool $isWorkflowAdmin
+	 * @access public
+	 */
+	var $isWorkflowAdmin;
+
+	/**
+	 * @var object $processMonitor
+	 * @access public
+	 */
+	var $processMonitor;
+
+	/**
+	 * Construtor da classe bo_monitors
+	 *
+	 * @access public
+	 * @return object
+	 */
+	function bo_monitors()
+	{
+		parent::bo_ajaxinterface();
+		$GLOBALS['ajax']->gui   = &Factory::newInstance('GUI');
+		$this->userID 			= $_SESSION['phpgw_info']['workflow']['account_id'];
+		$this->isWorkflowAdmin  = $GLOBALS['ajax']->acl->checkWorkflowAdmin($this->userID);
+		$this->processManager   = &Factory::newInstance('ProcessManager');
+		$this->activityManager  = &Factory::newInstance('ActivityManager');
+		$this->instanceManager  = &Factory::newInstance('InstanceManager');
+		$this->roleManager 		= &Factory::newInstance('RoleManager');
+		$this->processMonitor   = &Factory::newInstance('ProcessMonitor');
+	}
+
+	/**
+	 * Verifica se o usuário logado possui acesso ao Monitoramento
+	 *
+	 * @param int $processID O ID do processo que se está tentando monitorar
+	 * @param array $requiredLevel Permissões necessárias
+	 * @return bool true se o usuário tiver permissão ou false caso contrário
+	 * @access private
+	 */
+	private function checkAccess($processID, $requiredLevel = null)
+	{
+		if ($this->isWorkflowAdmin)
+			return true;
+
+		return $GLOBALS['ajax']->acl->checkUserGroupAccessToResource('MON', $this->userID, (int) $processID, $requiredLevel);
+	}
+
+	/**
+	 * Converte os filtros utilizados na interface de monitoramento para código SQL
+	 *
+	 * @param string $filters Uma string contendo dados, serializados, sobre os filtros selecionados
+	 * @return array Uma array onde cada elemento corresponde a um condicional de um filtro
+	 * @access private
+	 */
+	private function convertFiltersToSQL($filters)
+	{
+
+		/* desserializa os dados */
+		$JSON = &Factory::newInstance('Services_JSON');
+		/* desserializa a array principal, depois desserializa cada elemento desta array e, por fim, converte os elementos (que estão em forma de objeto) para array associativa */
+		$filters = array_map('get_object_vars', array_map(array($JSON, 'decode'), $JSON->decode($filters)));
+		$sqlFilters = array();
+
+		/* gera o SQL de acordo com o filtro selecionado */
+		foreach ($filters as $filter)
+		{
+			/* verifica se existe o ID do filtro */
+			if (!isset($filter['id']))
+				continue;
+
+			switch ($filter['id'])
+			{
+				case 'activityDate':
+					$sqlFilters[] = '(DATE_TRUNC(\'DAY\', \'EPOCH\'::TIMESTAMP + (gia.wf_started || \' SECONDS\')::INTERVAL) ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' TO_DATE(\'' . addslashes($filter['date']) . '\', \'DD/MM/YYYY\'))';
+					break;
+
+				case 'instanceName':
+					$sqlFilters[] = '(gi.wf_name ILIKE \'%' . addslashes($filter['name']) . '%\')';
+					break;
+
+				case 'instanceID':
+					$sqlFilters[] = '(gi.wf_instance_id ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' ' . addslashes($filter['number']) . ')';
+					break;
+
+				case 'instancePriority':
+					$sqlFilters[] = '(gi.wf_priority ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' ' . addslashes($filter['priority']) . ')';
+					break;
+
+				case 'instanceDate':
+					$sqlFilters[] = '(DATE_TRUNC(\'DAY\', \'EPOCH\'::TIMESTAMP + (gi.wf_started || \' SECONDS\')::INTERVAL) ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' TO_DATE(\'' . addslashes($filter['date']) . '\', \'DD/MM/YYYY\'))';
+					break;
+
+				case 'instanceEndDate':
+					$sqlFilters[] = '(DATE_TRUNC(\'DAY\', \'EPOCH\'::TIMESTAMP + (gi.wf_ended || \' SECONDS\')::INTERVAL) ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' TO_DATE(\'' . addslashes($filter['date']) . '\', \'DD/MM/YYYY\'))';
+					break;
+
+				case 'instanceStatus':
+					$sqlFilters[] = '(gi.wf_status = \'' . addslashes($filter['status']) . '\')';
+					break;
+
+				case 'instanceActivity':
+					$sqlFilters[] = '(gia.wf_activity_id = \'' . addslashes($filter['activity']) . '\')';
+					break;
+
+				case 'instanceUser':
+					$sqlFilters[] = '(gia.wf_user = \'' . addslashes($filter['user']) . '\')';
+					break;
+
+				case 'instanceOwner':
+					$sqlFilters[] = '(gi.wf_owner = \'' . addslashes($filter['owner']) . '\')';
+					break;
+			}
+		}
+
+		return $sqlFilters;
+	}
+
+	/**
+	 * Lista os processos do usuario
+	 *
+	 * @access public
+	 * @return array lista de processos
+	 */
+	function listProcesses()
+	{
+		if ($this->isWorkflowAdmin)
+		{
+			$permissions = $this->processManager->list_processes(0, -1, 'wf_p_id__ASC');
+			$permissions = array_map(create_function('$a', 'return $a[\'wf_p_id\'];'), $permissions['data']);
+		}
+		else
+		{
+			$permissions = $GLOBALS['ajax']->acl->getUserGroupPermissions('MON', $this->userID);
+		}
+		$processes = array();
+		foreach ($permissions as $pid)
+		{
+			$process = $this->processManager->get_process($pid);
+			if ($process)
+			{
+				$processes['data'][] = $process;
+				if ($this->isWorkflowAdmin)
+					$processes['permissions'][$pid] = array(
+						'number' => 4294967295,
+						'bits' => array_fill(0, 32, true)
+					);
+				else
+					$processes['permissions'][$pid] = $GLOBALS['ajax']->acl->getUserGroupAdminLevel('MON', $this->userID, $pid);
+			}
+		}
+
+		usort($processes['data'], create_function('$a,$b', 'return strnatcasecmp($a[\'wf_name\'],$b[\'wf_name\']);'));
+		return $processes;
+	}
+	/**
+	 * Lista as instancias ativas de um processo
+	 *
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @param bool $completeData Informa se devem ser retornados todos os dados ou somente aqueles necessários para a construção da listagem de instâncias ativas da interface de monitoramento. false por padrão
+	 * @access public
+	 * @return array lista de instancias
+	 */
+	function listInstances($params, $completeData = false)
+	{
+		$output = array();
+
+		/* check if the user has the proper right to list the instances of this process */
+		if (!$this->checkAccess($params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* check for filters */
+		if ($params['filters'])
+			$filters = $this->convertFiltersToSQL($params['filters']);
+		else
+			$filters = array();
+
+		if(empty($params['srt']))
+			$params['srt'] = 2;
+		if(empty($params['ord']))
+		{
+			$params['ord'] = "__ASC";
+		}
+		else
+		{
+
+			// being sure that the prefix "__DESC" or "__ASC" exists, preventing SQL injections
+			$isOrdOK = false;
+			if($params['ord'] == "__DESC") $isOrdOK = true;
+			if($params['ord'] == "__ASC") $isOrdOK = true;
+
+			if(!$isOrdOK) $params['ord'] = "__ASC";
+		}
+
+		switch($params['srt'])
+		{
+			case 1:
+				$order = "wf_instance_id".$params['ord'];
+				break;
+			case 2:
+				$order = "wf_activity_name".$params['ord'];
+				break;
+			case 3:
+				$order = "wf_instance_name".$params['ord'];
+				break;
+			case 4:
+				$order = "wf_priority".$params['ord'];
+				break;
+			case 5:
+				$order = "wf_user".$params['ord'];
+				break;
+			case 6:
+				$order = "wf_status".$params['ord'];
+				break;
+			default:
+				$order = "wf_activity_name".$params['ord'];
+				break;
+		}
+
+		$filters[] = '(gp.wf_p_id = ' . $params['pid'] . ')';
+	   	$filters[] = '(gia.wf_user IS NOT NULL)';
+
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		if (!$completeData)
+		{
+			$paging = Factory::newInstance('Paging', 500, $_POST);
+			$tmp = $this->processMonitor->monitor_list_instances($paging->nextItem, $paging->itemsPerPage, $order, '', implode(' AND ', $filters));
+			$output['data'] = $paging->restrictItems(array_values($tmp['data']), $tmp['cant']);
+			$output['instanceCount'] = $tmp['cant'];
+			$output['pagingData'] = $paging->commonLinks();
+		}
+		else
+		{
+			$tmp = $this->processMonitor->monitor_list_instances(0, -1, $order, '', implode(' AND ', $filters));
+			$output['data'] = array_values($tmp['data']);
+		}
+
+		$userMapping = array('*' => '*');
+		$activityMapping = array();
+		$instanceCount = count($output['data']);
+		$cachedLDAP = &Factory::getInstance('CachedLDAP');
+		for ($i = 0; $i < $instanceCount; $i++)
+		{
+			/* get the user name */
+			$currentInstanceUser = $output['data'][$i]['wf_user'];
+			if (!isset($userMapping[$currentInstanceUser]))
+			{
+				if (substr($currentInstanceUser, 0, 1) == 'p')
+				{
+					$role = $this->roleManager->get_role($output['data'][$i]['wf_p_id'], substr($currentInstanceUser, 1));
+					$userMapping[$currentInstanceUser] = 'Perfil: ' . $role['wf_name'];
+				}
+				else
+				{
+					$name = $ldap->getName($currentInstanceUser);
+					if (empty($name))
+					{
+						$userInfo = $cachedLDAP->getEntryByID($currentInstanceUser);
+						if ($userInfo)
+							$name = "ID: {$currentInstanceUser} - {$userInfo['cn']} (excluído)";
+						else
+							$name = "ID: {$currentInstanceUser}";
+					}
+
+					$userMapping[$currentInstanceUser] = $name;
+				}
+			}
+
+			if ($completeData)
+			{
+				$currentInstanceOwner = $output['data'][$i]['wf_owner'];
+				if (!isset($userMapping[$currentInstanceOwner]))
+					$userMapping[$currentInstanceOwner] = $ldap->getName($currentInstanceOwner);
+			}
+
+			/* get the activity names */
+			if (!isset($activityMapping[$output['data'][$i]['wf_activity_id']]))
+				$activityMapping[$output['data'][$i]['wf_activity_id']] = $output['data'][$i]['wf_activity_name'];
+
+			/* remove unused elements */
+			if (!$completeData)
+				unset(
+					$output['data'][$i]['wf_is_interactive'],
+					$output['data'][$i]['wf_proc_normalized_name'],
+					$output['data'][$i]['wf_owner'],
+					$output['data'][$i]['wf_procname'],
+					$output['data'][$i]['wf_version'],
+					$output['data'][$i]['wf_activity_name'],
+					$output['data'][$i]['wf_type'],
+					$output['data'][$i]['wf_started'],
+					$output['data'][$i]['wf_ended'],
+					$output['data'][$i]['wf_act_status'],
+					$output['data'][$i]['wf_act_started']
+				);
+		}
+		$output['userMapping'] = $userMapping;
+		$output['activityMapping'] = $activityMapping;
+
+		$output['params'] = $params;
+		return $output;
+	}
+
+	/**
+	 * Lista as instancias finalizadas de um processo
+	 *
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @param bool $completeData Informa se devem ser retornados todos os dados ou somente aqueles necessários para a construção da listagem de instâncias finalizadas da interface de monitoramento. false por padrão
+	 * @access public
+	 * @return array lista de instancias
+	 */
+	function listCompletedInstances($params, $completeData = false)
+	{
+		$params['pid'] = (int) $params['pid'];
+		$output = array();
+
+		/* check if the user has the proper right to list the instances of this process */
+		if (!$this->checkAccess($params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* check for filters */
+		if ($params['filters'])
+			$filters = $this->convertFiltersToSQL($params['filters']);
+		else
+			$filters = array();
+
+		if(empty($params['sort']))
+			$params['sort'] = 1;
+
+		if(empty($params['ord']) || ($params['ord'] != '__DESC'))
+			$params['ord'] = '__ASC';
+
+		/* define the sorting criteria */
+		switch($params['sort'])
+		{
+			case 1:
+				$order = 'wf_instance_id';
+				break;
+			case 2:
+				$order = 'wf_instance_name';
+				break;
+			case 3:
+				$order = 'wf_owner';
+				break;
+			case 4:
+				$order = 'wf_priority';
+				break;
+			case 5:
+				$order = 'wf_started';
+				break;
+			case 6:
+				$order = 'wf_ended';
+				break;
+			case 7:
+				$order = 'wf_status';
+				break;
+			default:
+				$order = 'wf_instance_id';
+				break;
+		}
+		$order .= $params['ord'];
+
+		/* load the data */
+		$filters[] = '(gp.wf_p_id = ' . $params['pid'] . ')';
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		if (!$completeData)
+		{
+			$paging = Factory::newInstance('Paging', 500, $_POST);
+			$tmp = $this->processMonitor->monitor_list_completed_instances($paging->nextItem, $paging->itemsPerPage, $order, '', implode(' AND ', $filters));
+			$output['data'] = $paging->restrictItems(array_values($tmp['data']), $tmp['cant']);
+			$output['instanceCount'] = $tmp['cant'];
+			$output['pagingData'] = $paging->commonLinks();
+		}
+		else
+		{
+			$tmp = $this->processMonitor->monitor_list_completed_instances(0, -1, $order, '', implode(' AND ', $filters));
+			$output['data'] = array_values($tmp['data']);
+		}
+
+		$cachedLDAP = &Factory::getInstance('CachedLDAP');
+		$userMapping = array();
+		$instanceCount = count($output['data']);
+		for ($i = 0; $i < $instanceCount; $i++)
+		{
+			/* get the user name */
+			$currentInstanceOwner = $output['data'][$i]['wf_owner'];
+			{
+				$name = $ldap->getName($currentInstanceOwner);
+				if (empty($name))
+				{
+					$userInfo = $cachedLDAP->getEntryByID($currentInstanceOwner);
+					if ($userInfo)
+						$name = "ID: {$currentInstanceOwner} - {$userInfo['cn']} (excluído)";
+					else
+						$name = "ID: {$currentInstanceOwner}";
+				}
+
+				$userMapping[$currentInstanceOwner] = $name;
+			}
+
+			/* format the data */
+			$output['data'][$i]['wf_started'] = date('d/m/Y H:i', $output['data'][$i]['wf_started']);
+			$output['data'][$i]['wf_ended'] = date('d/m/Y H:i', $output['data'][$i]['wf_ended']);
+
+			/* remove unused elements */
+			if (!$completeData)
+				unset(
+					$output['data'][$i]['wf_proc_normalized_name'],
+					$output['data'][$i]['wf_procname'],
+					$output['data'][$i]['wf_version']
+				);
+		}
+		$output['userMapping'] = $userMapping;
+
+		$output['params'] = $params;
+		return $output;
+	}
+
+	/**
+	 * Lista as atividades da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @access public
+	 * @return array
+	 */
+	function listActivities($params)
+	{
+		$pid = (int) $params['pid'];
+		/* check if the user has the proper right to list the activities of this process */
+		if (!$this->checkAccess($pid))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* retrieve all the activities */
+		$activities = $this->activityManager->list_activities($pid, 0, -1, 'wf_name__asc', '', '');
+
+		/* format the output */
+		$output['params'] = $params;
+		$output['data'] = array();
+		foreach ($activities['data'] as $activity)
+			if (($activity['wf_type'] != 'view') && ($activity['wf_type'] != 'standalone') && ($activity['wf_type'] != 'start') && ($activity['wf_is_interactive'] == 'y'))
+				$output['data'][] = array('id' => $activity['wf_activity_id'], 'name' => $activity['wf_name']);
+
+		return $output;
+	}
+	/**
+	 * Lista os usuarios da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @access public
+	 * @return array lista de usuarios
+	 */
+	function listUsers($params)
+	{
+		/* check if the user has the right to view all users from this instance */
+		$instance = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'])) || ($instance['wf_p_id'] != $params['pid']))
+			return 'Você não tem permissão para executar este procedimento!';
+
+		/* retrieve all the users from the activity */
+		$users = $this->roleManager->list_mapped_users($params['pid'], true, array('wf_activity_id' => $params['aid']));
+		asort($users);
+
+		$roles = $this->activityManager->get_activity_roles($params['aid']);
+		usort($roles, create_function('$a,$b', 'return strcasecmp($a[\'wf_name\'],$b[\'wf_name\']);'));
+		$usersOutput['data'] = array();
+		$usersOutput['data'][] = array('id' => '-1', 'name' => 'TODOS');
+		foreach ($roles as $role)
+			$usersOutput['data'][] = array('id' => 'p' . $role['wf_role_id'], 'name' => 'Perfil: ' . $role['wf_name']);
+
+		/* format the output */
+		$usersOutput['params'] = $params;
+		foreach ($users as $id => $name)
+			$usersOutput['data'][] = array('id' => $id, 'name' => $name);
+
+		return $usersOutput;
+	}
+	/**
+	 * Realiza o Update da prioridade de uma instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @access public
+	 * @return array parametros?
+	 */
+	function updatePriority($params)
+	{
+		/* check if the user has the right to update the priority of the instance */
+		$instance = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PRIORITY))) || ($instance['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$this->instanceManager->set_instance_priority($params['iid'], $params['np']);
+		return $params;
+	}
+
+	/**
+	 * Realiza o update do usuario atual da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function updateUser($params)
+	{
+		/* check if the user has the right to update the current user of this instance */
+		$instance = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_USER))) || ($instance['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$output = $params;
+		$user = ($params['user'] == -1) ? '*' : $params['user'];
+		if ($user == '*')
+			$output['fullname'] = '*';
+		else
+			if (substr($user, 0, 1) == 'p')
+			{
+				$role = $this->roleManager->get_role($instance['wf_p_id'], substr($user, 1));
+				$output['fullname'] = 'Perfil: ' . $role['wf_name'];
+			}
+			else
+				$output['fullname'] = Factory::getInstance('WorkflowLDAP')->getName($user);
+
+		$this->instanceManager->set_instance_user($params['iid'], $params['aid'], $user);
+
+		return $output;
+	}
+	/**
+	 * Realiza o update do status da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function updateStatus($params)
+	{
+		/* check if the user has the right to update the status of the instance */
+		$instance = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_STATUS))) || ($instance['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		if ($params['ns'] == 'aborted')
+		{
+			$realInstance = &Factory::newInstance('Instance');
+			$realInstance->getInstance($params['iid']);
+			if (!empty($realInstance->instanceId))
+			{
+				if (!$realInstance->abort())
+				{
+					unset($realInstance);
+					return 'Ocorreu um erro ao abortar a instância selecionada';
+				}
+			}
+			else
+			{
+				unset($realInstance);
+				return 'Não foi possível abortar a instância selecionada';
+			}
+		}
+		else
+			$this->instanceManager->set_instance_status($params['iid'], $params['ns']);
+
+		return $params;
+	}
+
+	/**
+	 * Realiza o update de uma atividade da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function updateActivity($params)
+	{
+		/* check if the user has the right to update change the activity of the instance */
+		$instance = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_ACTIVITY))) || ($instance['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* use next user or * for the new instance */
+		$realInstance = &Factory::newInstance('Instance');
+		$realInstance->getInstance($params['iid'], false, false);
+		$user = $realInstance->getNextUser($params['aid']);
+		$user = ($user == '') ? '*' : $user;
+		$this->instanceManager->set_instance_destination($params['iid'], $params['aid'], $user);
+		$result = $this->activityManager->get_activity($params['aid']);
+		$output = $params;
+		$output['name'] = $result['wf_name'];
+		return $output;
+	}
+
+	/**
+	 * Realiza o update do nome da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function updateName($params)
+	{
+		/* check if the user has the right to update the status of the instance */
+		$instance = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_NAME))) || ($instance['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$this->instanceManager->set_instance_name($params['iid'], $params['nn']);
+		return $params;
+	}
+
+	/**
+	 * Remove instâncias finalizadas
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return int O número de instâncias removidas
+	 * @access public
+	 */
+	function removeCompletedInstances($params)
+	{
+		/* check if the user has the proper right to remove the completed instances of this process */
+		if (!$this->checkAccess($params['pid'], array($this->IP_REMOVE_COMPLETED_INSTANCES)))
+			return array('error' => 'Você não tem permissão para executar este procedimento!');
+
+		/* load the instances */
+		$rawData = $this->listCompletedInstances($params, true);
+
+		/* remove the instances */
+		$instanceCount = 0;
+		if (!empty($rawData['data']))
+			foreach ($rawData['data'] as $instance)
+				if ($this->processMonitor->remove_instance($instance['wf_instance_id']))
+					$instanceCount++;
+		return $instanceCount;
+	}
+
+
+	/**
+	 * Lista as propriedades de uma instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function listInstanceProperties($params)
+	{
+		/* check if the user has the right to view the  instance properties */
+		$instanceInfo = $this->instanceManager->get_instance($params['iid']);
+		if (((!$this->checkAccess($params['pid'], array($this->IP_VIEW_PROPERTIES))) && (!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES)))) || ($instanceInfo['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$maximumDisplaySize = 100;
+		$instance = &Factory::newInstance('Instance');
+		$instance->getInstance($params['iid']);
+
+		$output = array();
+		$output['params'] = $params;
+		foreach ($instance->properties as $name => $value)
+		{
+			$complete = 1;
+			if (strlen($value) > $maximumDisplaySize)
+			{
+				$value = substr($value, 0, $maximumDisplaySize-3) . "...";
+				$complete = 0;
+			}
+			$output[] = array ("name" => $name, "value" => htmlentities($value), "complete" => $complete);
+		}
+		return $output;
+	}
+
+	/**
+	 * Retorna o valor de uma propriedade
+	 *
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function getCompletePropertyValue($params)
+	{
+		/* check if the user has the right to edit the instance properties */
+		$instanceInfo = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES))) || ($instanceInfo['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$instance = &Factory::newInstance('Instance');
+		$instance->getInstance($params['iid']);
+		$output = $params;
+		$output['value'] = $instance->properties[$params['name']];
+		return $output;
+	}
+
+	/**
+	 * Realiza o update de uma propriedade de uma instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @access public
+	 */
+	function updateProperty($params)
+	{
+		/* check if the user has the right to edit the instance properties */
+		$instanceInfo = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES))) || ($instanceInfo['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$maximumDisplaySize = 100;
+
+		$instance = &Factory::newInstance('Instance');
+		$instance->getInstance($params['iid']);
+		$instance->set($params['name'], $params['value']);
+		$instance->sync();
+
+		$output = array();
+		if (strlen($params['value']) > $maximumDisplaySize)
+		{
+			$params['value'] = substr($params['value'], 0, $maximumDisplaySize-3) . "...";
+			$output['complete'] = 0;
+		}
+		else
+		$output['complete'] = 1;
+		$output['value'] = htmlentities($params['value']);
+
+		return $output;
+	}
+
+	/**
+	 * Remove uma propriedade da instancia
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function removeProperty($params)
+	{
+		/* check if the user has the right to remove a property of the instance */
+		$instanceInfo = $this->instanceManager->get_instance($params['iid']);
+		if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES))) || ($instanceInfo['wf_p_id'] != $params['pid']))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$instance = &Factory::newInstance('Instance');
+		$instance->getInstance($params['iid']);
+		$instance->clear($params['name']);
+		$instance->sync();
+
+		$output = $params;
+		return $output;
+	}
+
+	/**
+	 * Mostra as estatisticas
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array
+	 * @access public
+	 */
+	function showStatistics($params)
+	{
+		if (!$this->checkAccess($params['pid'], array($this->IP_VIEW_STATISTICS)))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* common configuration */
+		$output = array();
+		$urlPrefix = 'workflow/inc/class.powergraphic.inc.php?';
+		$powergraphic = &Factory::getInstance('powergraphic');
+		$powergraphic->graphic_1 = $params['pid'];
+		$powergraphic->skin = 1;
+		$powergraphic->credits = 0;
+
+		/* number of instances per month */
+		$powergraphic->type = 4;
+		$powergraphic->title = 'Quantidade de Instancias x Mes';
+		$powergraphic->axis_x = 'Mes';
+		$powergraphic->axis_y = 'No. de Instancias';
+		$aux = $this->processMonitor->stats_instances_per_month($params['pid']);
+		$index = 0;
+		foreach ($aux as $date => $count)
+		{
+			list($year, $month) = explode('-', $date);
+			$powergraphic->x[$index] = $month . '/' . substr($year, -2);
+			$powergraphic->y[$index++] = $count;
+		}
+		if (count($aux) > 0)
+			$output[] = $powergraphic->create_query_string();
+
+		/* number of instances per activity */
+		$powergraphic->x = $powergraphic->y = array();
+		$powergraphic->type = 5;
+		$powergraphic->title = 'Instancias x Atividade';
+		$powergraphic->axis_x = 'Atividade';
+		$powergraphic->axis_y = 'No. de Instancias';
+		$aux = $this->processMonitor->stats_instances_activities($params['pid']);
+		$index = 0;
+		foreach ($aux as $info)
+		{
+			$powergraphic->x[$index] = $info['wf_name'] . " ({$info['count']})";
+			$powergraphic->y[$index++] = $info['count'];
+		}
+		if (count($aux) > 0)
+			$output[] = $powergraphic->create_query_string();
+
+		/* number of instances per user */
+		$powergraphic->x = $powergraphic->y = array();
+		$powergraphic->type = 5;
+		$powergraphic->title = 'Instancias x Usuario';
+		$powergraphic->axis_x = 'Usuario';
+		$powergraphic->axis_y = 'No. de Instancias';
+		$aux = $this->processMonitor->stats_instances_per_user($params['pid']);
+		/* prepare the data */
+		$aux2 = array();
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		foreach ($aux as $user => $count)
+			$aux2[] = array(
+				'user' => $ldap->getName($user) . " ({$count})",
+				'count' => $count
+			);
+		usort($aux2, create_function('$a,$b', 'return strcasecmp($a[\'user\'],$b[\'user\']);'));
+		$index = 0;
+		foreach ($aux2 as $info)
+		{
+			$powergraphic->x[$index] = $info['user'];
+			$powergraphic->y[$index++] = $info['count'];
+		}
+		if (count($aux) > 0)
+			$output[] = $powergraphic->create_query_string();
+
+		/* number of instances per status */
+		$translateStatus = array(
+			'completed' => 'Completada',
+			'active' => 'Ativa',
+			'aborted' => 'Abortada',
+			'exception' => 'Em exceção');
+		$powergraphic->x = $powergraphic->y = array();
+		$powergraphic->type = 5;
+		$powergraphic->title = 'Instancias x Status';
+		$powergraphic->axis_x = 'Status';
+		$powergraphic->axis_y = 'No. de Instancias';
+		$aux = $this->processMonitor->stats_instances_per_status($params['pid']);
+		$index = 0;
+		foreach ($aux as $status => $count)
+		{
+			$powergraphic->x[$index] = $translateStatus[$status] . " ({$count})";
+			$powergraphic->y[$index++] = $count;
+		}
+		if (count($aux) > 0)
+			$output[] = $powergraphic->create_query_string();
+
+		foreach ($output as $key => $value)
+			$output[$key] = $urlPrefix . $value;
+		return $output;
+	}
+
+	/**
+	 * Pega os usuários de instâncias ativas de um determinado processo
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Contendo o nome/id dos usuários
+	 * @access public
+	 */
+	function getUsersInInstances($params)
+	{
+		$pid = (int) $params['pid'];
+		/* check if the user has the proper right to list the users of this process */
+		if (!$this->checkAccess($pid))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* initialize some variables */
+		$users = array();
+		$roles = array();
+		$specialUsers = array();
+
+		/* load the users */
+		$activities = $this->activityManager->get_process_activities($pid);
+		if (!empty($activities))
+			$users = $this->processMonitor->monitor_list_users('wf_activity_id IN (' . implode(',', array_map(create_function('$a', 'return $a[\'wf_activity_id\'];'), $activities)) . ')');
+
+		/* remove the '*' user */
+		if (($asteriskPosition = array_search('*', $users)) !== false)
+			unset($users[$asteriskPosition]);
+
+		/* separate roles from users */
+		foreach ($users as $key => $user)
+		{
+			if (substr($user, 0, 1) == 'p')
+			{
+				$roles[] = $user;
+				unset($users[$key]);
+			}
+		}
+
+		/* load LDAP info and sort the result */
+		$foundUsers = Factory::getInstance('WorkflowLDAP')->getNames($users);
+		usort($foundUsers, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+
+
+		/* special treatment for  users not found in LDAP */
+		if (count($users) > count($foundUsers))
+		{
+			$cachedLDAP = &Factory::getInstance('CachedLDAP');
+			$foundUsersID = array_map(create_function('$a', 'return $a[\'id\'];'), $foundUsers);
+			$missingUsers = array_diff($users, $foundUsersID);
+			foreach ($missingUsers as $missingUser)
+			{
+				$userInfo = $cachedLDAP->getEntryByID($missingUser);
+				if ($userInfo)
+					$name = "ID: {$missingUser} - {$userInfo['cn']} (excluído)";
+				else
+					$name = "ID: {$missingUser}";
+				$specialUsers[] = array('id' => $missingUser, 'name' => $name);
+			}
+		}
+
+		/* load roles info */
+		foreach ($roles as $role)
+		{
+			$roleInfo = $this->roleManager->get_role($pid, substr($role, 1));
+			$specialUsers[] = array('id' => $role, 'name' => 'Perfil: ' . $roleInfo['wf_name']);
+		}
+
+		/* sort the special users */
+		usort($specialUsers, create_function('$a,$b', 'return strnatcasecmp($a[\'name\'],$b[\'name\']);'));
+
+		/* define the output (merging the ordinary users with the "special" ones) */
+		$output = $params;
+		$output['users'] = array_merge($specialUsers, $foundUsers);
+
+		return $output;
+	}
+
+	/**
+	 * Pega os proprietários de instâncias ativas ou inativas de um determinado processo
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Contendo o nome/id dos proprietários
+	 * @access public
+	 */
+	function getInstancesOwners($params)
+	{
+		$pid = (int) $params['pid'];
+
+		/* check if the user has the proper right to list the owners of this process */
+		if (!$this->checkAccess($pid))
+			return 'Você não tem permissão para executar este procedimento!';
+
+		$output = $params;
+		$output['owners'] = array();
+
+		/* load the instances (active ou completed ones) */
+		if ($params['currentList'] == 'active')
+			$instances = $this->listInstances($params, true);
+		else
+			$instances = $this->listCompletedInstances($params, true);
+
+		/* get the owners */
+		if (count($instances['userMapping']) > 0)
+		{
+			if ($params['currentList'] == 'completed')
+			{
+				foreach ($instances['userMapping'] as $id => $name)
+					$output['owners'][] = array('id' => $id, 'name' => $name);
+			}
+			else
+			{
+				foreach ($instances['data'] as $instance)
+					if (!isset($output['owners'][$instance['wf_owner']]))
+						$output['owners'][$instance['wf_owner']] = array('id' => $instance['wf_owner'], 'name' => $instances['userMapping'][$instance['wf_owner']]);
+				$output['owners'] = array_values($output['owners']);
+			}
+		}
+
+		/* sort the owners */
+		usort($output['owners'], create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+
+		return $output;
+	}
+
+	/**
+	 * Pega as atividades das instâncias de um determinado usuário
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Contendo o nome/id das atividades
+	 * @access public
+	 */
+	function getUserActivities($params)
+	{
+		$pid = (int) $params['pid'];
+		$user = (int) $params['user'];
+		/* check if the user has the proper right to list the instances of this process */
+		if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$instances = $this->processMonitor->monitor_list_instances(0, -1, 'wf_activity_name__ASC', null, "gia.wf_user = '{$user}' AND gp.wf_p_id = {$pid}");
+		$activities = array_map('unserialize', array_unique(array_map(create_function('$a', 'return serialize(array(\'id\' => $a[\'wf_activity_id\'], \'name\' => $a[\'wf_activity_name\']));'), $instances['data'])));
+		usort($activities, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
+
+		$output = $params;
+		$output['activities'] = $activities;
+
+		return $output;
+	}
+
+	/**
+	 * Verifica se o novo dono das instâncias já está em todos os perfis necessários. Caso não esteja, envia uma lista com sugestões de perfis
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Contendo informações e sugestões de perfis para adicionar o novo dono das instâncias
+	 * @access public
+	 */
+	function checkUserRoles($params)
+	{
+		$pid = (int) $params['pid'];
+		$oldUser = (int) $params['oldUser'];
+		$newUser = (int) $params['newUser'];
+		$activity = (int) $params['activity'];
+
+		/* check if the user has the proper right to list the instances of this process */
+		if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$activities = array();
+		if ($activity == 0)
+		{
+			$instances = $this->processMonitor->monitor_list_instances(0, -1, 'wf_activity_name__ASC', null, "gia.wf_user = '{$oldUser}' AND gp.wf_p_id = {$pid}");
+			$activities = array_values(array_map('unserialize', array_unique(array_map(create_function('$a', 'return serialize(array(\'id\' => $a[\'wf_activity_id\'], \'name\' => $a[\'wf_activity_name\']));'), $instances['data']))));
+		}
+		else
+		{
+			$activityInfo = $this->activityManager->get_activity($activity);
+			$activities[] = array('id' => $activity, 'name' => $activityInfo['wf_name']);
+		}
+
+		$userRoles = $this->roleManager->getUserRoles($newUser, $pid);
+		foreach ($activities as $key => $value)
+		{
+			$roles = $this->activityManager->get_activity_roles($value['id']);
+			$userExistsInRoles = false;
+			foreach ($roles as $role)
+			{
+				if (in_array($role['wf_role_id'], $userRoles))
+				{
+					$userExistsInRoles = true;
+					break;
+				}
+				else
+					$activities[$key]['possibleRoles'][] = array('id' => $role['wf_role_id'], 'name' => $role['wf_name']);
+			}
+			if ($userExistsInRoles)
+			{
+				unset($activities[$key]);
+				continue;
+			}
+		}
+		$output = $params;
+		$output['roles'] = array_values($activities);
+
+		return $output;
+	}
+
+	/**
+	 * Adiciona um usuário ao perfil indicado
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Contém a saída do método 'checkUserRoles'
+	 * @access public
+	 */
+	function addUserToRole($params)
+	{
+		$pid = (int) $params['pid'];
+		$newUser = (int) $params['newUser'];
+		$role = (int) $params['role'];
+
+		/* check if the user has the proper right to list the instances of this process */
+		if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
+			return "Você não tem permissão para executar este procedimento!";
+
+		/* get the process roles */
+		$processRoles = $this->roleManager->list_roles($pid, 0, -1, 'wf_p_id__ASC', null);
+		$processRoles = array_map(create_function('$a', 'return $a[\'wf_role_id\'];'), $processRoles['data']);
+
+		/* check if the role belongs to the process */
+		if (!in_array($role, $processRoles))
+			return 'Os dados fornecidos estão incorretos.';
+		$this->roleManager->map_user_to_role($pid, $newUser, $role, 'u');
+
+		return $this->checkUserRoles($params);
+	}
+
+	/**
+	 * Troca os usuários das instâncias (de acordo com filtro de atividade e usuário original)
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Contém estatísticas sobre as instâncias alteradas
+	 * @access public
+	 */
+	function replaceUser($params)
+	{
+		$pid = (int) $params['pid'];
+		$oldUser = (int) $params['oldUser'];
+		$newUser = (int) $params['newUser'];
+		$activity = (int) $params['activity'];
+
+		/* check if the user has the proper right to list the instances of this process */
+		if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$instances = $this->processMonitor->monitor_list_instances(0, -1, 'wf_activity_name__ASC', null, "gia.wf_user = '{$oldUser}' AND gp.wf_p_id = {$pid}");
+		$activities = array();
+		if ($activity == 0)
+			$activities = array_unique(array_map(create_function('$a', 'return $a[\'wf_activity_id\'];'), $instances['data']));
+		else
+			$activities[] = $activity;
+
+		$OKCount = 0;
+		$errorCount = 0;
+		foreach ($instances['data'] as $instance)
+		{
+			if (in_array($instance['wf_activity_id'], $activities))
+			{
+				if ($this->instanceManager->set_instance_user($instance['wf_instance_id'], $instance['wf_activity_id'], $newUser))
+					$OKCount++;
+				else
+					$errorCount++;
+			}
+		}
+		$output = $params;
+		$output['OKCount'] = $OKCount;
+		$output['errorCount'] = $errorCount;
+
+		return $output;
+	}
+
+	/**
+	 * Gera os e-mails enviados para alertar sobre determinadas instâncias
+	 * @param array $params Parâmetros repassados por outros métodos e que são advindos de uma chamada Ajax
+	 * @return array Uma array seqüencial onde cada elemento corresponde a uma array contendo as informações de: nome do destinatário, e-mail do destinatário, ID do destinatário, corpo do e-mail e assunto do e-mail
+	 * @access public
+	 */
+	function generateEmails($params)
+	{
+		/* define the type */
+		$type = ($params['emailType'] == 'user') ? 'user' : 'instance';
+
+		/* load the instances and add the username */
+		$rawData = $this->listInstances($params, true);
+		$list = array();
+		foreach ($rawData['data'] as $element)
+			if (($element['wf_user'] != '*') && (substr($element['wf_user'], 0, 1) != 'p'))
+				$list[] = array_merge($element, array('wf_user_name' => $rawData['userMapping'][$element['wf_user']]));
+
+		/* check if there is at least one instance */
+		$output = array();
+		if (count($list) === 0)
+			return $output;
+
+		$BOUserInterface = &Factory::getInstance('bo_userinterface');
+
+		/* initialize some variables */
+		$translationArray = array();
+		$emailBody = $params['emailBody'];
+		$emailSubject = $params['emailSubject'];
+
+		/* if the developer decided to send only one e-mail per user */
+		if ($type === 'user')
+		{
+			/* split the e-mail according to definition */
+			ereg('(.*)%inicio_loop%(.*)%fim_loop%(.*)', $emailBody, $records);
+			if (($records == null) || (count($records) != 4))
+				return array('error' => 'Formato de e-mail inválido');
+
+			/* prepare the list */
+			$userList = array();
+			foreach ($list as $element)
+				$userList[$element['wf_user']][] = $element;
+
+			/* construct the e-mails */
+			foreach ($userList as $user => $instances)
+			{
+				/* add the e-mail header */
+				$email = $records[1];
+				$totalInstances = count($instances);
+				$currentInstance = 1;
+				foreach ($instances as $instance)
+				{
+					/* prepare the translation array */
+					$url = sprintf('%s/index.php?menuaction=workflow.run_activity.go&activity_id=%d&iid=%d', $_SESSION['phpgw_info']['workflow']['server']['webserver_url'], $instance['wf_activity_id'], $instance['wf_instance_id']);
+					$translationArray = array(
+						'%atividade%' => $instance['wf_activity_name'],
+						'%usuario%' => $instance['wf_user_name'],
+						'%processo%' => $instance['wf_procname'],
+						'%identificador%' => $instance['wf_instance_name'],
+						'%tempo_atividade%' => $BOUserInterface->time_diff(mktime() - $instance['wf_act_started']),
+						'%tempo_instancia%' => $BOUserInterface->time_diff(mktime() - $instance['wf_started']),
+						'%prioridade%' => $instance['wf_priority'],
+						'%quantidade_instancia%' => $totalInstances,
+						'%atual_instancia%' => $currentInstance++,
+						'%inicio_atividade%' => date('d/m/Y H\hi', $instance['wf_act_started']),
+						'%inicio_instancia%' => date('d/m/Y H\hi', $instance['wf_started']),
+						'%url%' => $url,
+						'%link%' => sprintf('<a href="%s" target="_blank">%s</a>', $url, $url)
+					);
+
+					$email .= str_replace(array_keys($translationArray), array_values($translationArray), $records[2]);
+				}
+
+				/* add the e-mail footer */
+				$email .= $records[3];
+
+				/* replace, once again, any %variable% (also for the subject) */
+				$email = str_replace(array_keys($translationArray), array_values($translationArray), $email);
+				$subject = str_replace(array_keys($translationArray), array_values($translationArray), $emailSubject);
+
+				/* construct the final e-mail array */
+				$output[] = array(
+					'emailBody' => $email,
+					'emailSubject' => $subject,
+					'user' => $user
+				);
+			}
+		}
+
+		if ($type === 'instance')
+		{
+			/* construct the e-mails */
+			foreach ($list as $instance)
+			{
+				$url = sprintf('%s/index.php?menuaction=workflow.run_activity.go&activity_id=%d&iid=%d', $_SESSION['phpgw_info']['workflow']['server']['webserver_url'], $instance['wf_activity_id'], $instance['wf_instance_id']);
+				$translationArray = array(
+					'%atividade%' => $instance['wf_activity_name'],
+					'%usuario%' => $instance['wf_user_name'],
+					'%processo%' => $instance['wf_procname'],
+					'%identificador%' => $instance['wf_instance_name'],
+					'%tempo_atividade%' => $BOUserInterface->time_diff(mktime() - $instance['wf_act_started']),
+					'%tempo_instancia%' => $BOUserInterface->time_diff(mktime() - $instance['wf_started']),
+					'%prioridade%' => $instance['wf_priority'],
+					'%quantidade_instancia%' => 1,
+					'%atual_instancia%' => 1,
+					'%inicio_atividade%' => date('d/m/Y H\hi', $instance['wf_act_started']),
+					'%inicio_instancia%' => date('d/m/Y H\hi', $instance['wf_started']),
+					'%url%' => $url,
+					'%link%' => sprintf('<a href="%s" target="_blank">%s</a>', $url, $url)
+				);
+
+				/* replace any %variable% for its correspondence (also for the subject) */
+				$email = str_replace(array_keys($translationArray), array_values($translationArray), $emailBody);
+				$subject = str_replace(array_keys($translationArray), array_values($translationArray), $emailSubject);
+
+				/* construct the final e-mail array */
+				$output[] = array(
+					'emailBody' => $email,
+					'emailSubject' => $subject,
+					'user' => $instance['wf_user']
+				);
+			}
+		}
+
+		/* load the recipient e-mail */
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		foreach ($output as $key => $value)
+		{
+			$userData = $ldap->getUserInfo($value['user']);
+			$output[$key]['to'] = $userData['mail'];
+			$output[$key]['username'] = $userData['cn'];
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Gera um preview do e-mail que será enviado
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return string O corpo do primeiro e-mail que seria enviado caso a ação "Enviar" fosse disparada
+	 * @access public
+	 */
+	function previewEmail($params)
+	{
+		/* check if the user has the proper right to send e-mails related to this process */
+		$pid = (int) $params['pid'];
+		if (!$this->checkAccess($pid, array($this->IP_SEND_EMAILS)))
+			return array('error' => 'Você não tem permissão para executar este procedimento!');
+
+		$output = $this->generateEmails($params);
+		if (!isset($output['error']))
+			return array('emailBody' => $output[0]['emailBody'], 'emailCount' => count($output));
+		else
+			return $output;
+	}
+
+	/**
+	 * Envia e-mails para os usuários das instâncias selecionadas
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return int O número de e-mails enviados
+	 * @access public
+	 */
+	function sendMail($params)
+	{
+		/* check if the user has the proper right to send e-mails related to this process */
+		$pid = (int) $params['pid'];
+		if (!$this->checkAccess($pid, array($this->IP_SEND_EMAILS)))
+			return array('error' => 'Você não tem permissão para executar este procedimento!');
+
+		/* generate the e-mails */
+		$emails = $this->generateEmails($params);
+
+		/* check for errors */
+		if (isset($emails['error']) || (count($emails) == 0))
+			return $emails;
+
+		/* prepare the environment to load some configuration values from other module */
+		$GLOBALS['phpgw']->db =& Factory::getInstance('WorkflowObjects')->getDBExpresso();
+		$GLOBALS['phpgw']->common = Factory::getInstance('common');
+		$GLOBALS['phpgw']->session = Factory::getInstance('sessions');
+		function lang($a){return $a;};
+
+		/* get the required configuration */
+		$BOEmailAdmin = Factory::getInstance('bo');
+		$profileList = $BOEmailAdmin->getProfileList();
+		$profile = $BOEmailAdmin->getProfile($profileList[0]['profileID']);
+
+		/**
+		 * XXX - XXX
+		 * It's weird.. There are two almost identical PHPMailer classes.
+		 * The class registered in our factory is under 'EGW_INC_ROOT'.
+		 * The class used here has the same name and it's under another
+		 * directory. For now, let's just include it in the old-fashion
+		 * way, but if someone, someday try to use both classes in the
+		 * same access, it could cause us troubles.
+		 */
+
+		/* configure the PHPMailer class to send the e-mails */
+		require_once '../expressoMail1_2/inc/class.phpmailer.php';
+		$phpMailer = new PHPMailer();
+		$phpMailer->SMTPDebug = false;
+		$phpMailer->IsSMTP();
+		$phpMailer->Host = $profile['smtpServer'];
+		$phpMailer->Port = $profile['smtpPort'];
+		$phpMailer->From = 'no-reply@' . $profile['defaultDomain'];
+		$phpMailer->FromName = 'Workflow Expresso';
+
+		/* send the e-mails */
+		$count = 0;
+		foreach ($emails as $email)
+		{
+			$phpMailer->ClearAllRecipients();
+			$phpMailer->IsHTML(true);
+			$phpMailer->Subject = $email['emailSubject'];
+			$phpMailer->Body = $email['emailBody'];
+			$phpMailer->AddAddress($email['to'], $email['username']);
+			if ($phpMailer->Send())
+				$count++;
+		}
+		return $count;
+	}
+
+	/**
+	 * Lista instâncias inconsistentes.
+	 * @param array $params Parâmetros advindos da chamada Ajax
+	 * @return array Uma array contendo as instâncias de acordo com suas inconsistências
+	 * @access public
+	 */
+	function loadInconsistentInstances($params)
+	{
+		$processID = (int) $params['pid'];
+		/* check if the user has the proper right to send e-mails related to this process */
+		if (!$this->checkAccess($processID))
+			return "Você não tem permissão para executar este procedimento!";
+
+		$output = array(
+			'instances' => array(),
+			'names' => array(),
+			'params' => $params
+		);
+
+		$output['instances'][] = array(
+			'name' => 'Usuários Removidos',
+			'description' => 'Quando uma instância está atribuída a um usuário que não está mais no LDAP.',
+			'items' => $this->inconsistentInstancesRemovedUser($processID)
+		);
+
+		$output['instances'][] = array(
+			'name' => 'Usuários sem Autorização',
+			'description' => 'Quando o usuário que está com a instância não pertence a nenhum dos perfis da atividade desta instância.',
+			'items' => $this->inconsistentInstancesUnauthorizedUsers($processID)
+		);
+
+		$output['instances'][] = array(
+			'name' => 'Instâncias Falhas',
+			'description' => 'Quando uma instância encontra-se em uma atividade não-interativa.',
+			'items' => $this->inconsistentInstancesFailedInstances($processID)
+		);
+
+		$output['instances'][] = array(
+			'name' => 'Instâncias Finalizadas Vinculadas a uma Atividade',
+			'description' => 'Quando uma instância finalizada ou abortada ainda está vinculada a uma atividade.',
+			'items' => $this->inconsistentInstancesUnfinishedActivity($processID)
+		);
+
+		$userIDs = array();
+		foreach ($output['instances'] as $inconsistencyTypes)
+			foreach ($inconsistencyTypes['items'] as $instance)
+				$userIDs[$instance['wf_user']] = '';
+
+		$output['names'] = $this->getNames(array_keys($userIDs), $processID);
+
+		return $output;
+	}
+
+	/**
+	 * Carrega os nomes de usuários/perfis
+	 * @param array $userIDs Uma array contendo os IDs dos usuários/perfis.
+	 * @param int $processID O ID do processo de onde os nomes dos perfis serão extraídos
+	 * @return array Uma array associativa no formato ID => Nome
+	 * @access public
+	 */
+	private function getNames($userIDs, $processID)
+	{
+		$output = array();
+		$cachedLDAP = &Factory::getInstance('CachedLDAP');
+		$ldap = &Factory::getInstance('WorkflowLDAP');
+		foreach ($userIDs as $userID)
+		{
+			if (!isset($output[$userID]))
+			{
+				if ($userID == '*')
+				{
+					$output['*'] = '*';
+					continue;
+				}
+
+				if (substr($userID, 0, 1) == 'p')
+				{
+					$role = $this->roleManager->get_role($processID, substr($userID, 1));
+					$output[$userID] = 'Perfil: ' . $role['wf_name'];
+				}
+				else
+				{
+					$name = $ldap->getName($userID);
+					if (empty($name))
+					{
+						$userInfo = $cachedLDAP->getEntryByID($userID);
+						if ($userInfo)
+							$name = "ID: {$userID} - {$userInfo['cn']} (excluído)";
+						else
+							$name = "ID: {$userID}";
+					}
+
+					$output[$userID] = $name;
+				}
+			}
+		}
+		return $output;
+	}
+
+	/**
+	 * Lista as instâncias inconsistentes: instâncias que estão com usuários que foram removidos do LDAP
+	 * @param int $processID O ID do processo
+	 * @return array Lista das instâncias que satisfazem o critério de inconsistência
+	 * @access public
+	 */
+	private function inconsistentInstancesRemovedUser($processID)
+	{
+		$filters = array();
+		$filters[] = "(gp.wf_p_id = {$processID})";
+	   	$filters[] = '(gia.wf_user IS NOT NULL)';
+
+		$cachedLDAP = &Factory::newInstance('CachedLDAP');
+		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP);
+		$output = array();
+		$instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
+
+		$userIDs = array();
+		foreach ($instanceList['data'] as $instance)
+		{
+			if (substr($instance['wf_user'], 0, 1) == 'p')
+				continue;
+
+			if ($instance['wf_user'] == '*')
+				continue;
+
+			$userIDs[$instance['wf_user']] = true;
+		}
+
+		$validUsers = Factory::getInstance('WorkflowLDAP')->getNames(array_keys($userIDs));
+		array_walk($validUsers, create_function('&$a', '$a = $a[\'id\'];'));
+
+		foreach ($instanceList['data'] as $instance)
+		{
+			if (substr($instance['wf_user'], 0, 1) == 'p')
+				continue;
+
+			if ($instance['wf_user'] == '*')
+				continue;
+
+			if (!in_array($instance['wf_user'], $validUsers))
+				$output[] = $instance;
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Lista as instâncias inconsistentes: instâncias que estão com usuários que não estão em nenhum dos perfis da atividade em que a instância se encontra
+	 * @param int $processID O ID do processo
+	 * @return array Lista das instâncias que satisfazem o critério de inconsistência
+	 * @access public
+	 */
+	private function inconsistentInstancesUnauthorizedUsers($processID)
+	{
+		$output = array();
+		$roleIDs = array();
+		$roles = $this->roleManager->list_roles($processID, 0, -1, 'wf_role_id__ASC', '');
+		foreach ($roles['data'] as $role)
+			$roleIDs[] = $role['wf_role_id'];
+		$activities = $this->activityManager->list_activities($processID, 0, -1, 'wf_name__asc', '', '');
+		$activityUsers = array();
+		foreach ($activities['data'] as $activity)
+		{
+			if ($activity['wf_is_interactive'] == 'y')
+			{
+				$userList = $this->roleManager->list_mapped_users($processID, true, array('wf_activity_id' => $activity['wf_activity_id']));
+				if (!isset($activityUsers[$activity['wf_activity_id']]))
+					$activityUsers[$activity['wf_activity_id']] = array();
+				$activityUsers[$activity['wf_activity_id']] += array_keys($userList);
+			}
+		}
+
+		$filters = array();
+		$filters[] = "(gp.wf_p_id = {$processID})";
+		$filters[] = "(ga.wf_is_interactive = 'y')";
+	   	$filters[] = '(gia.wf_user IS NOT NULL)';
+		$instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
+		foreach ($instanceList['data'] as $instance)
+		{
+			if ($instance['wf_user'] == '*')
+				continue;
+
+			if (substr($instance['wf_user'], 0, 1) == 'p')
+				if (in_array(substr($instance['wf_user'], 1), $roleIDs))
+					continue;
+
+			if (in_array($instance['wf_user'], $activityUsers[$instance['wf_activity_id']]))
+				continue;
+
+			$output[] = $instance;
+		}
+
+		return $output;
+	}
+
+	private function inconsistentInstancesFailedInstances($processID)
+	{
+		$filters = array();
+		$filters[] = "(gp.wf_p_id = {$processID})";
+		$filters[] = "(ga.wf_is_interactive = 'n')";
+		$filters[] = '(gia.wf_started < ' . (date('U') - 60). ')';
+		$instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
+
+		return $instanceList['data'];
+	}
+
+	/**
+	 * Lista as instâncias inconsistentes: instâncias que estão paradas em atividades não-interativas há mais de um minuto
+	 * @param int $processID O ID do processo
+	 * @return array Lista das instâncias que satisfazem o critério de inconsistência
+	 * @access public
+	 */
+	private function inconsistentInstancesUnfinishedActivity($processID)
+	{
+		$filters = array();
+		$filters[] = "(gp.wf_p_id = {$processID})";
+		$filters[] = "(gi.wf_status IN ('aborted', 'completed'))";
+		$filters[] = '(gia.wf_activity_id IS NOT NULL)';
+		$instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
+
+		return $instanceList['data'];
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_agent.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_agent.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.ui_agent.inc.php	(revision 795)
@@ -0,0 +1,247 @@
+<?php
+/**************************************************************************\
+* eGroupWare Workflow - Agents Connector - interface layer                 *
+* ------------------------------------------------------------------------ *
+* This program is free software; you can redistribute it and/or modify it  *
+* under the terms of the GNU General Public License as published           *
+* by the Free Software Foundation; either version 2 of the License, or     *
+* any later version.                                                       *
+\**************************************************************************/
+
+
+/**
+ * Agents abstraction library. interface layer. 
+ * This allows the Workflow Engine to connect to various agents
+ * Agents are external elements for the workflow. It could be
+ * email systems, filesystems, calendars, what you want.
+ * Use this class to make childrens like, for example in the
+ * class.ui_agent_mail_smtp.inc.php for the mail_smtp susbsytem
+ * 
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author regis.leroy@glconseil.com
+ */
+require_once(dirname(__FILE__) . SEP . 'class.WorkflowUtils.inc.php');
+	
+class ui_agent extends WorkflowUtils
+{
+	/**
+	 * @var array $error Local error storage
+	 * @access public
+	 */
+	var $error=Array();
+	/**
+	 * @var array $agent_values store the POST or GET content concerning the agent
+	 * @access public
+	 */
+	var $agent_values = Array();
+	/**
+	 * @var bool $interactivity for runtime mode
+	 * @access public
+	 */ 
+	var $interactivity = false;
+	
+	// concerning Child classes constructors ---------------------------------------------
+	/**
+	 * @var object bo_agent object which have to be set in your child class to the right bo_agent child
+	 * @access public  
+	 */
+	var $bo_agent = null;
+	/**
+	 * @var string $agent_type The type of the agent, on agent of this type for one activity, no more
+	 * @access public
+	 */
+	var $agent_type = '';
+	// -----------------------------------------------------------------------------------
+	
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_agent()
+	{
+		parent::WorkflowUtils();
+	}
+	
+	/**
+	 * Function which must be called (internally) at runtime .The agent MUST know if he is runned in an interactive activity or not.
+	 * For example on non-interactive activities the agents musn't scan the POST content
+	 * @param bool $bool true interactive false non-interactive
+	 * @return void
+	 * @access public
+	 */
+	function setInteractivity($bool)
+	{
+		$this->interactivity = $bool;
+	}
+	/**
+	 * Return errors recorded by this object
+	 * You should always call this function after failed operations on a workflow object to obtain messages
+	 * @param array $as_array if true the result will be send as an array of errors or an empty array. Else, if you do not give any parameter 
+	 * or give a false parameter you will obtain a single string which can be empty or will contain error messages with <br /> html tags.
+	 * @access public
+	 * @return array errors 
+	 */
+	 function get_error($as_array=false) 
+	 {
+	 	$this->error[] = $this->bo_agent->get_error();
+	 	if ($as_array)
+		{
+		 	return $this->error;
+		}
+		$result_str = implode('<br />',$this->error);
+		$this->error= Array();
+		return $result_str;
+		}
+			
+	/**
+	 * Factory: load the agent values stored somewhere via the agent bo object
+	 * @param int $agent_id is the agent id
+	 * @return bool false if the agent cannot be loaded, true else
+	 * @access public
+	 */
+	function load($agent_id)
+	{
+		return ( (isset($this->bo_agent)) && ($this->bo_agent->load($agent_id)));
+	}
+	
+	/**
+	 * Save the agent values somewhere via the agent bo object
+	 * @param array $datas is an array containing comlumns => value pairs
+	 * @return bool false if the agent was not previously loaded or if the save fail, true else
+	 * @access public
+	 */
+	function save(&$datas)
+	{
+		if (!(isset($this->bo_agent)))
+		{ 
+			return false;
+		}
+		else
+		{
+			$ok = $this->bo_agent->set($datas);
+			if ($ok) $ok = $this->bo_agent->save();
+			return $ok;
+		}
+	}
+
+	/**
+	 * Function called at runtime to permit associtaion with the instance and the activity
+	 * we store references to theses objects and we tell the ui object if we are in interactive
+	 * mode or not.
+	 * @param array    $instance 
+	 * @param object   $activity activity
+	 * @return void
+	 * @access public
+	 */
+	function runtime(&$instance, &$activity)
+	{
+		$this->bo_agent->runtime($instance,$activity);
+		$this->setInteractivity($activity->isInteractive());
+	}
+	
+	/**
+	 * This function show the shared part of all agents when showing configuration in the admin activity form
+	 * do not forget to call parent::showAdminActivityOptions ($template_block_name) in the child if you want to display this shared part
+	 * @param string $template_block_name
+	 * @return void
+	 * @access public 
+	 */
+	function showAdminActivityOptions ($template_block_name)
+	{ 
+		$admin_name = 'admin_agent_shared';
+		$this->t->set_file($admin_name, $admin_name . '.tpl');
+		$this->t->set_var(array(
+			'agent_description'	=> $this->bo_agent->getDescription(),
+			'agent_title'		=> $this->bo_agent->getTitle(),
+			'agent_help'		=> $this->bo_agent->getHelp(),
+		));
+		$this->translate_template($admin_name);
+		$this->t->parse($template_block_name, $admin_name);
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the activity_pre code
+	 *
+	 * and before the user code. This code is runned only if the $GLOBALS['workflow']['__leave_activity']
+	 * IS NOT set (i.e.: the user is not cancelling his form in case of interactive activity)
+	 * WARNING : on interactive queries the user code is parsed several times and this function is called
+	 * each time you reach the begining of the code, this means at least the first time when you show the form
+	 * and every time you loop on the form + the last time when you complete the code (if the user did not cancel).
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public
+	 */
+	function run_activity_pre()
+	{
+		return true;
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the activity_pre code
+	 *
+	 * and before the user code. This code is runned only if the $GLOBALS['workflow']['__leave_activity']
+	 * IS set (i.e.: the user is cancelling his form in case of interactive activity)
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public
+	 */
+	function run_leaving_activity_pre()
+	{
+		return true;
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the user code
+	 * 
+	 * and after the activity_pos code. This code is runned only if the $GLOBALS['__activity_completed']
+	 * IS NOT set (i.e.: the user is not yet completing the activity)
+	 * WARNING : on automatic (non-interactive) activities this code is NEVER called. Non-interactive
+	 * activities are completed after the end of the user code and there is no way to re-parse this
+	 * user code after completion.
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public 
+	 */
+	function run_activity_completed_pos()
+	{
+		return true;
+	}
+	
+   /**
+	*  Function called by the running object (run_activity) after the user code
+	* 
+	*  and after the activity_pos code. This code is runned only if the $GLOBALS['__activity_completed']
+	*  IS set (i.e.: the user has completing the activity)
+	*  WARNING : on interactive queries the user code is parsed several times and this function is called
+	*  each time you reach the end of the code without completing, this means at least the first time
+	*  and every time you loop on the form.
+	*  @return bool true or false, if false the $this->error array should contains error messages
+	*  @access public
+ 	*/
+	function run_activity_pos()
+	{
+		return true;
+	}
+	
+	/**
+	 * Retrieve infos set by the user in interactive forms ans store it with the bo_agent object
+	 * @return void
+	 * @access public
+	 */
+	function retrieve_form_settings()
+	{
+		if ($this->interactivity)
+		{
+			$res = Array();
+			$this->agent_values = get_var('wf_agent_'.$this->agent_type, array('POST','GET'),$value);
+			foreach ($this->bo_agent->get(2) as $name => $value)
+			{
+				$res[$name] = (isset($this->agents_values[$name]))? $this->agents_values[$name] : $value;
+			}
+			//store theses values in the bo_object(without saving the values)
+			//htmlentites will be made by the bo's set function
+				$this->bo_agent->set($res);
+			}
+		}
+
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_phpeditor.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_phpeditor.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_phpeditor.inc.php	(revision 2372)
@@ -0,0 +1,90 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once dirname(__FILE__) . SEP . 'engine' . SEP . 'config.ajax.inc.php';
+require_once dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php';
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ */
+class ui_phpeditor extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'form'	=> true,
+	);
+
+	/**
+	 * @var object $bo
+	 * @access public
+	 */
+	var $bo;
+
+	protected $HTMLFile;
+	protected $type;
+
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */
+	function ui_phpeditor()
+	{
+		$this->bo = Factory::getInstance('bo_editor');
+		$this->loadVariables();
+	}
+
+	protected function loadVariables()
+	{
+		$this->HTMLFile = 'editor.html';
+		$this->type = 'php';
+	}
+
+	/**
+	 * Build php editor form
+	 * @access public
+	 * @return void
+	 */
+	function form()
+	{
+		$smarty = Factory::getInstance('workflow_smarty', false);
+		$processManager = &Factory::newInstance('ProcessManager');
+		$proccessInfo = $processManager->get_process($_GET['proc_id']);
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','phpeditor', 'main');
+
+		$css = $this->get_common_css();
+
+		$fileData = $this->bo->get_source($proccessInfo['wf_normalized_name'],$_REQUEST['file_name'],$_REQUEST['type']);
+
+		$smarty->assign('type', $this->type);
+		$smarty->assign('HTMLFile', $this->HTMLFile);
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->assign('txt_loading', lang('loading'));
+		$smarty->assign('processName', $_GET['proc_name']);
+		$smarty->assign('fileName', $_GET['file_name']);
+		$smarty->assign('tipoCodigo', $_GET['type']);
+		$smarty->assign('processID', $_GET['proc_id']);
+		$smarty->assign('activityId', $_GET['activity_id']);
+		$smarty->assign('processNameVersion', "{$proccessInfo['wf_name']} (v{$proccessInfo['wf_version']})");
+		$smarty->assign('fileData', $fileData);
+
+		$smarty->display('editor.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/jobs/class.JobEnum.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/jobs/class.JobEnum.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/jobs/class.JobEnum.inc.php	(revision 795)
@@ -0,0 +1,149 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Classe que enumera os tipos de data
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @final
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+final class DateType
+{
+	/**
+	 * Representa o tipo de data Absoluta
+	 * @name ABSOLUTE_DATE
+	 */
+	const ABSOLUTE_DATE = 0;
+
+	/**
+	 * Representa o tipo de data da Semana
+	 * @name ABSOLUTE_DATE
+	 */
+	const WEEK_DATE = 1;
+
+	/**
+	 * Representa o tipo de data Relativa ao final do mês
+	 * @name RELATIVE_DATE
+	 */
+	const RELATIVE_DATE = 2;
+}
+
+/**
+ * Classe que enumera os tipos de unidades de intervalo
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @final
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+final class DateUnity
+{
+	/**
+	 * Unidade de intervalo que representa Ano
+	 * @name YEAR
+	 */
+	const YEAR = 0;
+
+	/**
+	 * Unidade de intervalo que representa Mês
+	 * @name MONTH
+	 */
+	const MONTH = 1;
+
+	/**
+	 * Unidade de intervalo que representa Semana
+	 * @name WEEK
+	 */
+	const WEEK = 2;
+
+	/**
+	 * Unidade de intervalo que representa Dia
+	 * @name DAY
+	 */
+	const DAY = 3;
+
+	/**
+	 * Unidade de intervalo que representa Hora
+	 * @name HOUR
+	 */
+	const HOUR = 4;
+
+	/**
+	 * Unidade de intervalo que representa Minuto
+	 * @name HOUR
+	 */
+	const MINUTE = 5;
+
+	/**
+	 * Representa a não repetição de jobs
+	 * @name NONE
+	 */
+	const NONE = 6;
+}
+
+/**
+ * Classe que enumera os dias da semana
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @final
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+final class WeekDays
+{
+	/**
+	 * Representa o domingo
+	 * @name SUNDAY
+	 */
+	const SUNDAY = 1;
+
+	/**
+	 * Representa a segunda-feira
+	 * @name MONDAY
+	 */
+	const MONDAY = 2;
+
+	/**
+	 * Representa a terça-feira
+	 * @name TUESDAY
+	 */
+	const TUESDAY = 4;
+
+	/**
+	 * Representa a quarta-feira
+	 * @name WEDNESDAY
+	 */
+	const WEDNESDAY = 8;
+
+	/**
+	 * Representa a quinta-feira
+	 * @name THURSDAY
+	 */
+	const THURSDAY = 16;
+
+	/**
+	 * Representa a sexta-feira
+	 * @name FRIDAY
+	 */
+	const FRIDAY = 32;
+
+	/**
+	 * Representa o sábado
+	 * @name SATURDAY
+	 */
+	const SATURDAY = 64;
+}
+?>
Index: /sandbox/workflow/branches/993/inc/jobs/class.JobDate.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/jobs/class.JobDate.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/jobs/class.JobDate.inc.php	(revision 795)
@@ -0,0 +1,70 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'class.JobEnum.inc.php';
+
+/**
+ * Classe base dos tipos de datas (e intervalos) utilizadas pelos Jobs
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @abstract
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+abstract class JobDate
+{
+	/**
+	 * @var object A data a partir da qual o Job é válido
+	 * @access protected
+	 */
+	protected $startDate;
+
+	/**
+	 * @var array O intervalo de execução do Job. É uma array associativa com os elementos 'unity' e 'value'
+	 * @access protected
+	 */
+	protected $interval;
+
+	/**
+	 * Construtor da classe JobDate
+	 * @param object $startDate A data a partir da qual o Job é válido
+	 * @param array $interval O intervalo de execução do Job
+	 * @return object Objeto da classe JobDate
+	 * @access public
+	 */
+	public function JobDate($startDate, $interval)
+	{
+		$this->startDate = $startDate;
+		$this->setInterval($interval);
+	}
+
+	/**
+	 * Define o intervalo de execução do Job
+	 * @param array $interval O intervalo de execução do Job
+	 * @return void
+	 * @access public
+	 */
+	public function setInterval($interval)
+	{
+		$this->interval = $interval;
+	}
+
+	/**
+	 * Verifica se um Job será executado na data fornecida
+	 * @param object $checkDate A data que será verificada
+	 * @return bool True caso o Job deva ser executado e false caso contrário
+	 * @access public
+	 * @abstract
+	 */
+	abstract public function checkMatchesInterval($checkDate);
+}
+?>
Index: /sandbox/workflow/branches/993/inc/jobs/class.RelativeDate.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/jobs/class.RelativeDate.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/jobs/class.RelativeDate.inc.php	(revision 795)
@@ -0,0 +1,79 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'class.JobDate.inc.php';
+
+/**
+ * Classe para datas relativas ao final do mês
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+class RelativeDate extends JobDate
+{
+	/**
+	 * @var int $dayOffset O número de dias restantes para o final do mês (quando o Job deve ser executado)
+	 * @access private
+	 */
+	private $dayOffset;
+
+	/**
+	 * Construtor da classe RelativeDate
+	 * @param object $startDate A data a partir da qual o Job é válido
+	 * @param array $interval O intervalo de execução do Job
+	 * @param int $dayOffset O número de dias restantes para o final do mês
+	 * @return object Objeto da classe RelativeDate
+	 * @access public
+	 */
+	public function RelativeDate($startDate, $interval, $dayOffset = null)
+	{
+		parent::JobDate($startDate, $interval);
+		if (!is_null($dayOffset))
+			$this->setOffset($dayOffset);
+	}
+
+	/**
+	 * Verifica se um Job será executado na data fornecida
+	 * @param object $checkDate A data que será verificada
+	 * @return bool True caso o Job deva ser executado e false caso contrário
+	 * @access public
+	 */
+	public function checkMatchesInterval($checkDate)
+	{
+		if ($checkDate->format('G:i') !== $this->startDate->format('G:i'))
+			return false;
+
+		$start = ($this->startDate->format('Y') * 12) + $this->startDate->format('n');
+		$check = ($checkDate->format('Y') * 12) + $checkDate->format('n');
+		if ((($check - $start) % $this->interval['value']) !== 0)
+			return false;
+
+		$model = new DateTime($checkDate->format('Y-n-1 G:i:00'));
+		$model->modify('+1 month');
+		$model->modify("-{$this->dayOffset} day");
+
+		return (($checkDate->format('Y-n-j G:i:00') == $model->format('Y-n-j G:i:00')) && ($checkDate->format('U') >= $this->startDate->format('U')));
+	}
+
+	/**
+	 * Define a quantidade de dias restantes para o final do mês (que é quando o Job deve ser executado)
+	 * @param int $dayOffset O número de dias restantes para o final do mês
+	 * @return void
+	 * @access public
+	 */
+	public function setOffset($dayOffset)
+	{
+		$this->dayOffset = $dayOffset;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/jobs/class.WeekDate.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/jobs/class.WeekDate.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/jobs/class.WeekDate.inc.php	(revision 795)
@@ -0,0 +1,122 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'class.JobDate.inc.php';
+
+/**
+ * Classe para dias da semana
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+class WeekDate extends JobDate
+{
+	/**
+	 * @var int $weekDays Inteiro que representa os dias da semana quando o Job será executado
+	 * @access private
+	 */
+	private $weekDays;
+
+	/**
+	 * Construtor da classe WeekDate
+	 * @param object $startDate A data a partir da qual o Job é válido
+	 * @param array $interval O intervalo de execução do Job
+	 * @param int $weekDays Inteiro que representa os dias da semana
+	 * @return object Objeto da classe WeekDate
+	 * @access public
+	 */
+	public function WeekDate($startDate, $interval, $weekDays = null)
+	{
+		parent::JobDate($startDate, $interval);
+		if (!is_null($weekDays))
+			$this->setWeekDays($weekDays);
+	}
+
+	public function checkMatchesInterval($checkDate)
+	{
+		if (($checkDate->format('G:i') == $this->startDate->format('G:i')) && ($this->weekDays & $this->getWeekDay($checkDate)))
+		{
+			$startSunday = new DateTime(date($this->startDate->format('Y-n-j') . ' 00:00:00'));
+			if ($this->getWeekDay($startSunday) != WeekDays::SUNDAY)
+				$startSunday->modify('-' . $startSunday->format('N') . ' day');
+
+			$checkSunday = new DateTime(date($checkDate->format('Y-n-j') . ' 00:00:00'));
+			if ($this->getWeekDay($checkSunday) != WeekDays::SUNDAY)
+				$checkSunday->modify('-' . $checkSunday->format('N') . ' day');
+
+			$weeksBetween = round(($checkSunday->format('U') - $startSunday->format('U')) / 604800);
+
+			if ($this->interval['unity'] == DateUnity::NONE)
+				return ($weeksBetween == 0);
+
+			return ((($weeksBetween % $this->interval['value']) === 0) && ($checkDate->format('U') >= $this->startDate->format('U')));
+		}
+
+		return false;
+	}
+
+	/**
+	 * Pega o inteiro que representa os dias da semana quando o Job será executado
+	 * @return int $weekDays Inteiro que representa os dias da semana
+	 * @access public
+	 */
+	public function getWeekDays($weekDays)
+	{
+		return $this->weekDays;
+	}
+
+	/**
+	 * Define o inteiro que representa os dias da semana quando o Job será executado
+	 * @param int $weekDays Inteiro que representa os dias da semana
+	 * @return void
+	 * @access public
+	 */
+	public function setWeekDays($weekDays)
+	{
+		$this->weekDays = $weekDays;
+	}
+
+	/**
+	 * Pega o dia da semana de uma data
+	 * @param object $date A data
+	 * @return int O inteiro que representa o dia da semana da data
+	 * @access public
+	 */
+	static public function getWeekDay($date)
+	{
+		switch ($date->format('N'))
+		{
+			case 1:
+				return WeekDays::MONDAY;
+
+			case 2:
+				return WeekDays::TUESDAY;
+
+			case 3:
+				return WeekDays::WEDNESDAY;
+
+			case 4:
+				return WeekDays::THURSDAY;
+
+			case 5:
+				return WeekDays::FRIDAY;
+
+			case 6:
+				return WeekDays::SATURDAY;
+
+			case 7:
+				return WeekDays::SUNDAY;
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/jobs/class.AbsoluteDate.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/jobs/class.AbsoluteDate.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/jobs/class.AbsoluteDate.inc.php	(revision 795)
@@ -0,0 +1,93 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'class.JobDate.inc.php';
+
+/**
+ * Classe para datas absolutas e com repetições comuns
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ * @version 1.0
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @package Workflow
+ * @subpackage Job
+ */
+class AbsoluteDate extends JobDate
+{
+	/**
+	 * Verifica se um Job será executado na data fornecida
+	 * @param object $checkDate A data que será verificada
+	 * @return bool True caso o Job deva ser executado e false caso contrário
+	 * @access public
+	 */
+	public function checkMatchesInterval($checkDate)
+	{
+		$preCheck = array();
+
+		switch($this->interval['unity'])
+		{
+			case DateUnity::NONE:
+				$preCheck[] = 'Y';
+			case DateUnity::YEAR:
+				$preCheck[] = 'n';
+			case DateUnity::MONTH:
+				$preCheck[] = 'j';
+			case DateUnity::DAY:
+				$preCheck[] = 'G';
+			case DateUnity::HOUR:
+				$preCheck[] = 'i';
+		}
+
+		$preCheck = implode(':', $preCheck);
+		if ($checkDate->format($preCheck) !== $this->startDate->format($preCheck))
+			return false;
+
+		if ($this->interval['unity'] == DateUnity::NONE)
+			return true;
+
+		if ($this->interval['unity'] == DateUnity::MINUTE)
+		{
+			$start = $this->startDate->format('U') / 60;
+			$check = $checkDate->format('U') / 60;
+			return (((($check - $start) % $this->interval['value']) === 0) && ($check >= $start));
+		}
+
+		if ($this->interval['unity'] == DateUnity::HOUR)
+		{
+			$start = $this->startDate->format('U') / 3600;
+			$check = $checkDate->format('U') / 3600;
+			return (((($check - $start) % $this->interval['value']) === 0) && ($check >= $start));
+		}
+
+		if ($this->interval['unity'] == DateUnity::DAY)
+		{
+			$start = $this->startDate->format('U') / 86400;
+			$check = $checkDate->format('U') / 86400;
+			return (((($check - $start) % $this->interval['value']) === 0) && ($check >= $start));
+		}
+
+		if ($this->interval['unity'] == DateUnity::MONTH)
+		{
+			$start = ($this->startDate->format('Y') * 12) + $this->startDate->format('n');
+			$check = ($checkDate->format('Y') * 12) + $checkDate->format('n');
+			return (((($check - $start) % $this->interval['value']) === 0) && ($check >= $start));
+		}
+
+		if ($this->interval['unity'] == DateUnity::YEAR)
+		{
+			$start = $this->startDate->format('Y');
+			$check = $checkDate->format('Y');
+			return (((($check - $start) % $this->interval['value']) === 0) && ($check >= $start));
+		}
+
+		return false;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ResourcesRedirector.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ResourcesRedirector.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ResourcesRedirector.inc.php	(revision 2372)
@@ -0,0 +1,153 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once 'common.inc.php';
+
+/**
+ * Classe que redireciona requisições de arquivos da área resources dos processos
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class ResourcesRedirector
+{
+	/**
+	 * @var mixed $processInfo Informações sobre o processo (ou false se o processo não foi encontrado)
+	 * @access private
+	 */
+	private $processInfo;
+
+	/**
+	 * @var string $file O nome do arquivo requisitado
+	 * @access private
+	 */
+	private $file;
+
+	/**
+	 * @var int $pid O número do processo onde estão os arquivos
+	 * @access private
+	 */
+	private $pid;
+
+	/**
+	 * Construtor da classe
+	 * @return object
+	 * @access public
+	 */
+	public function ResourcesRedirector()
+	{
+		if (!isset($_SESSION['workflow']['ResourcesRedirector']))
+			$_SESSION['workflow']['ResourcesRedirector'] = array(0 => 'workflow');
+
+		$this->pid = isset($_GET['pid']) ? (int) $_GET['pid'] : 0;
+		$this->file = $_GET['file'];
+		$this->processInfo = false;
+		if (!isset($_SESSION['workflow']['ResourcesRedirector'][$this->pid]))
+		{
+			$result = Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID->query('SELECT wf_normalized_name FROM egw_wf_processes WHERE wf_p_id = ?', array($this->pid));
+			if ($result->numRows() != 1)
+				return;
+			$fields = $result->fetchRow();
+			$_SESSION['workflow']['ResourcesRedirector'][$this->pid] = $fields['wf_normalized_name'];
+		}
+		$this->processInfo = $_SESSION['workflow']['ResourcesRedirector'][$this->pid];
+	}
+
+	/**
+	 * Redireciona a requisição do arquivo contido no resources do processo para o devido lugar
+	 * @return void
+	 * @access public
+	 */
+	public function redirect()
+	{
+		if ($this->processInfo == false)
+			return;
+
+		/* encontra o diretório onde os arquivos estão armazenados */
+		$baseDirectory = '';
+		if (isset($_SESSION['workflow']['ResourcesRedirector']['baseDirectory']))
+		{
+			$baseDirectory = $_SESSION['workflow']['ResourcesRedirector']['baseDirectory'];
+		}
+		else
+		{
+			if (isset($_SESSION['phpgw_info']['workflow']['vfs_basedir']))
+			{
+				$baseDirectory = $_SESSION['phpgw_info']['workflow']['vfs_basedir'];
+			}
+			else
+			{
+				if (isset($_SESSION['phpgw_info']['expressomail']['server']['files_dir']))
+				{
+					$baseDirectory = $_SESSION['phpgw_info']['expressomail']['server']['files_dir'];
+				}
+				else
+				{
+					/* em último caso, tenta buscar a informação em banco de dados */
+					$result = Factory::getInstance('WorkflowObjects')->getDBExpresso()->Link_ID->query('SELECT config_value FROM phpgw_config WHERE config_app = ? AND config_name = ?', array('phpgwapi', 'files_dir'));
+					if (empty($result))
+						return;
+					$fields = $result->fetchRow();
+					$baseDirectory = $fields['config_value'];
+				}
+			}
+			$_SESSION['workflow']['ResourcesRedirector']['baseDirectory'] = $baseDirectory;
+		}
+
+		if ($this->pid != 0)
+			$filename = str_replace('//', '/', $baseDirectory . '/workflow/' . $this->processInfo . '/resources/' . $this->file);
+		else
+			$filename = str_replace('//', '/', $baseDirectory . '/workflow/' . $this->processInfo . '/' . $this->file);
+
+		if (strpos($filename, '..') !== false)
+			return;
+
+		$this->show($filename);
+	}
+
+	/**
+	 * Serve o arquivo indicado (para o navegador)
+	 * @param string $filename Caminho completo do arquivo
+	 * @param string $mimeType O tipo mime do arquivo (se não for fornecido, tenta encontrar o tipo de mime a partir do arquivo)
+	 * @return void
+	 * @access public
+	 */
+	public function show($filename, $mimeType = null)
+	{
+		if (!file_exists($filename))
+			return;
+
+		/* pega o cabeçalho enviado pelo cliente */
+		$headers = apache_request_headers();
+
+		/* verifica se o cliente está validando seu cache e se ele está atualizado */
+		if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == filemtime($filename)))
+		{
+			/* o cache do cliente está atualizado. Apenas envia um 304 (Não modificado) */
+			header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($filename)).' GMT', true, 304);
+		}
+		else
+		{
+			/* verifica se foi fornecido um tipo mime */
+			if (is_null($mimeType))
+				$mimeType = mime_content_type($filename);
+
+			/* arquivo não está em cache ou o cache já expirou */
+			header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($filename)).' GMT', true, 200);
+			header('Content-Length: ' . filesize($filename));
+			header('Content-Type: ' . $mimeType);
+			header('Content-Disposition: filename="' . basename($filename) . '"');
+			echo file_get_contents($filename);
+		}
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/hook_sidebox_menu.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/hook_sidebox_menu.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/hook_sidebox_menu.inc.php	(revision 2372)
@@ -0,0 +1,79 @@
+<?php
+/**************************************************************************\
+* eGroupWare - Knowledge Base                                              *
+* http://www.egroupware.org                                                *
+* -----------------------------------------------                          *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+
+require_once 'common.inc.php';
+require_once 'engine/config.egw.inc.php';
+
+{
+	$workflowACL = Factory::getInstance('workflow_acl');
+	$userID = $GLOBALS['phpgw_info']['user']['account_id'];
+	$apptitle = $GLOBALS['phpgw_info']['apps'][$appname]['title'];
+	$isWorkflowAdmin = $workflowACL->checkWorkflowAdmin($userID);
+	$isEgroupwareAdmin = $GLOBALS['phpgw']->acl->check('run',1,'admin');
+
+	// Configuration
+	$file = array();
+	$menu_title = lang('%1 Configuration', $apptitle);
+
+	// checking for workflow admin acl
+	/* check if the user can administrate processes */
+	if (($GLOBALS['phpgw']->acl->check('admin_workflow',1,'workflow')) || ($isWorkflowAdmin))
+		$file['Admin Processes'] 	= $GLOBALS['phpgw']->link('/index.php','menuaction=workflow.ui_adminprocesses.form');
+
+	/* check if the user can administrate at least on process (this is required for him to move instances) */
+	if ($workflowACL->checkUserGroupAccessToType('PRO', $userID) || $isWorkflowAdmin)
+		$file['Move Instances'] = $GLOBALS['phpgw']->link('/index.php','menuaction=workflow.ui_move_instances.form');
+
+	/* check if the user can administrate the orgchart */
+	if ($workflowACL->checkUserGroupAccessToType('ORG', $userID) || $isWorkflowAdmin)
+		$file['Organization Chart']	= $GLOBALS['phpgw']->link('/index.php','menuaction=workflow.ui_orgchart.draw');
+
+	if ($isWorkflowAdmin)
+		$file['External Applications'] = $GLOBALS['phpgw']->link('/index.php','menuaction=workflow.ui_external_applications.draw');
+
+	/* if the user is the egroupware admin, he can access some privileged areas */
+	if ($isEgroupwareAdmin)
+		$file['Default config values'] 	= $GLOBALS['phpgw']->link('/index.php',array(
+			'menuaction' 	=> 'admin.uiconfig.index',
+			'appname' 	=> $appname,
+		));
+
+	if ($isWorkflowAdmin)
+		$file['Access Control List']= $GLOBALS['phpgw']->link('/index.php','menuaction=workflow.ui_adminaccess.form');
+
+	/* every user can access the preference area */
+	$file['Workflow Preferences'] = $GLOBALS['phpgw']->link('/preferences/preferences.php','appname=workflow');
+
+	/* display the current sidebox */
+	display_sidebox($appname,$menu_title,$file);
+
+	/* check if the user can monitor at least one process */
+	if ($workflowACL->checkUserGroupAccessToType('MON', $userID) || $isWorkflowAdmin)
+	{
+		$file = array();
+		$menu_title 		= lang('%1 Monitoring', $apptitle);
+		$file['Monitors'] 	= $GLOBALS['phpgw']->link('/index.php','menuaction=workflow.ui_monitors.form');
+		display_sidebox($appname,$menu_title,$file);
+	}
+
+	/* link to the main page of the Workflow module */
+	$file = array();
+	$menu_title = lang('%1 Menu', $apptitle);
+	$file['User Interface']      = $GLOBALS['phpgw']->link('/workflow/index.php','');
+
+	/* display the current sidebox */
+	display_sidebox($appname,$menu_title,$file);
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.workflow_wfsecurity.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.workflow_wfsecurity.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.workflow_wfsecurity.inc.php	(revision 2372)
@@ -0,0 +1,23 @@
+<?php
+	require_once 'common.inc.php';
+	// include galaxia's configuration tailored to egroupware
+	require_once('engine/config.egw.inc.php');
+
+	require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'common' . SEP . 'WfSecurity.php');
+	/**
+	 * @package Workflow
+	 * @license http://www.gnu.org/copyleft/gpl.html GPL
+	 */
+	class workflow_wfsecurity extends WfSecurity
+	{
+		/**
+		 * Construtor da classe workflow_wfsecurity
+		 * @access public
+		 * @return object
+		 */
+		function workflow_wfsecurity()
+		{
+			parent::WfSecurity(Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID);
+		}
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_agent_mail_smtp.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_agent_mail_smtp.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_agent_mail_smtp.inc.php	(revision 2372)
@@ -0,0 +1,228 @@
+<?php
+	/**************************************************************************\
+* eGroupWare Workflow - Mail SMTP Agent Connector - interface layer        *
+* ------------------------------------------------------------------------ *
+* This program is free software; you can redistribute it and/or modify it  *
+* under the terms of the GNU General Public License as published           *
+* by the Free Software Foundation; either version 2 of the License, or     *
+* any later version.                                                       *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_agent.inc.php');
+/**
+ * Mail-SMTP Agent : interface layer. 
+ * This class connects the workflow agents calls to the mail_smtp agent business layer
+ * 
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author regis.leroy@glconseil.com
+ */		
+class ui_agent_mail_smtp extends ui_agent
+{
+	/**
+	 * Constructor
+	 * @access public
+	 * @return object
+	 */	
+	function ui_agent_mail_smtp()
+	{
+		parent::ui_agent();
+		$this->agent_type = 'mail_smtp';
+		$this->bo_agent = Factory::getInstance('bo_agent_mail_smtp');
+	}
+
+	/**
+	 * Show Admin Activity Options
+	 * @param string $template_block_name
+	 * @access public
+	 * @return void  
+	 */
+	function showAdminActivityOptions ($template_block_name)
+	{
+		$admin_name = 'admin_agent_'.$this->agent_type;
+		$this->t->set_file($admin_name, $admin_name . '.tpl');
+		$this->t->set_block($admin_name, 'block_ag_config_option_input', 'ag_option_input');
+		$this->t->set_block($admin_name, 'block_ag_config_option_textarea', 'ag_option_textarea');
+		$this->t->set_block($admin_name, 'block_ag_config_option_select_option', 'ag_option_select_option');
+		$this->t->set_block($admin_name, 'block_ag_config_option_select', 'ag_option_select');
+		$options =& $this->bo_agent->getAdminActivityOptions();
+		foreach ($options as $option_name => $option_conf)
+		{
+			if ($option_conf['type'] == 'text')
+			{
+				$size = $option_conf['size'];
+				if ( (!($size)) || ($size > 80)) $size = 80;
+				$this->t->set_var(array(
+					'ag_config_name_i'	=> "wf_agent[".$this->agent_type."][".$option_name."]",
+					'ag_config_label_i'	=> $option_conf['label'],
+					'ag_config_value_i'	=> $option_conf['value'],
+					'ag_config_size_i'	=> 'size="'.$size.'"',
+				));
+				$this->t->parse('ag_option_input','block_ag_config_option_input',true);
+			}
+			if ($option_conf['type'] == 'textarea')
+			{
+				$this->t->set_var(array(
+					'ag_config_name_t'	=> "wf_agent[".$this->agent_type."][".$option_name."]",
+					'ag_config_label_t'	=> $option_conf['label'],
+					'ag_config_value_t'	=> $option_conf['value'],
+				));
+				$this->t->parse('ag_option_textarea','block_ag_config_option_textarea',true);
+			}
+			if ($option_conf['type'] == 'select')
+			{	
+				$this->t->set_var(array(
+					'ag_config_name_s'	=> "wf_agent[".$this->agent_type."][".$option_name."]",
+					'ag_config_label_s'	=> $option_conf['label'],
+				));
+				foreach($option_conf['values'] as $key => $value)
+				{
+					$this->t->set_var(array(
+						'ag_config_value_s_key'		=> $key,
+						'ag_config_value_s_value'	=> $value,
+						'ag_config_value_s_selected'	=> ($option_conf['value']==$key)? 'selected': '',
+					));
+					$this->t->parse('ag_option_select_option','block_ag_config_option_select_option',true);
+				}
+				$this->t->parse('ag_option_select','block_ag_config_option_select',true);
+			}
+		}
+		//show the shared part handled by parent object
+		parent::showAdminActivityOptions('shared_part');
+		$this->translate_template($admin_name);
+		$this->t->parse($template_block_name, $admin_name);
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the activity_pre code
+	 * and before the user code. This code is runned only if the $GLOBALS['workflow']['__leave_activity']
+	 * IS NOT set (i.e.: the user is not cancelling his form in case of interactive activity)
+	 * WARNING : on interactive queries the user code is parsed several times and this function is called
+	 * each time you reach the begining of the code, this means at least the first time when you show the form
+	 * and every time you loop on the form + the last time when you complete the code (if the user did not cancel).
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public
+	 */
+	function run_activity_pre()
+	{
+		//load agent data from database
+		$this->bo_agent->init();
+		
+		//this will send an email only if the configuration says to do so
+		if (!($this->bo_agent->send_start()))
+		{
+			$this->error[] = lang('Smtp Agent has detected some errors when sending email at the beginning of the activity');
+			$ok = false;
+		}
+		else
+		{
+			$ok = true;
+		}
+		$this->error[] = $this->bo_agent->get_error();
+		if ($this->bo_agent->debugmode) echo '<br />START: Mail agent in DEBUG mode:'.implode('<br />',$this->error);
+		return $ok;
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the activity_pre code
+	 * and before the user code. This code is runned only if the $GLOBALS['workflow']['__leave_activity']
+	 * IS set (i.e.: the user is cancelling his form in case of interactive activity)
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public
+	 */
+	function run_leaving_activity_pre()
+	{
+		//actually we never send emails when cancelling
+		return true;
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the user code
+	 * and after the activity_pos code. This code is runned only if the $GLOBALS['__activity_completed']
+	 * IS set (i.e.: the user has completing the activity)
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public
+	 */
+	function run_activity_completed_pos()
+	{
+		//this will send an email only if the configuration says to do so
+		if (!($this->bo_agent->send_completed()))
+		{
+			$this->error[] = lang('Smtp Agent has detected some errors when sending email after completion of the activity');
+			$ok = false;
+		}
+		else
+		{
+			$ok = true;
+		}
+		$this->error[] = $this->bo_agent->get_error();
+		if ($this->bo_agent->debugmode) echo '<br />COMPLETED: Mail agent in DEBUG mode:'.implode('<br />',$this->error);
+		return $ok;
+	}
+	
+	/**
+	 * Function called by the running object (run_activity) after the user code
+	 * and after the activity_pos code. This code is runned only if the $GLOBALS['__activity_completed']
+	 * IS NOT set (i.e.: the user is not yet completing the activity)
+	 * WARNING : on interactive queries the user code is parsed several times and this function is called
+	 * each time you reach the end of the code without completing, this means at least the first time
+	 * and every time you loop on the form.
+	 * This function can call two types of mail sending
+	 * * sending email on POST queries (usefull for interactive forms), retrieving POSTed values
+	 * * sending email at each reach of the end of the code (usefull for automatic activities which 
+	 * completes only after execution of user code (sending after completion is not possible). And we
+	 * musn't retrieve POSTed values in this case because it can concerns previous non-automatic activities
+	 * @return bool true or false, if false the $this->error array should contains error messages
+	 * @access public
+	 */
+	function run_activity_pos()
+	{
+		if ($this->bo_agent->sendOnPosted())
+		{//First case, POSTed emails, we will try to see if there are some POSTed infos
+			//form settings POSTED with wf_agent_mail_smtp['xxx'] values
+			$this->retrieve_form_settings();
+			if (!(isset($this->agent_values['submit_send'])))
+			{
+				return true;
+			}
+			else
+			{
+				//erase agent data with the POSTed values
+				$this->bo_agent->set($this->agent_values);
+				
+				//this will send an email only if the configuration says to do so
+				if (!($this->bo_agent->send_post()))
+				{
+					$this->error[] = lang('Smtp Agent has detected some errors when sending email on demand whith this activity');
+					$ok = false;
+				}
+				else
+				{
+					$ok = true;
+				}
+				$this->error[] = $this->bo_agent->get_error();
+				if ($this->bo_agent->debugmode) echo '<br />POST: Mail agent in DEBUG mode:'.implode('<br />',$this->error);
+				return $ok;
+			}
+		}
+		else
+		{//Second case , not about POSTed values, the bo_agent will see himself he he need
+		// to do something on end of the user code
+			//this will send an email only if the configuration says to do so
+			if (!($this->bo_agent->send_end()))
+			{
+				$this->error[] = lang('Smtp Agent has detected some errors when sending email at the end of this activity');
+				$ok = false;
+			}
+			else
+			{
+				$ok = true;
+			}
+			$this->error[] = $this->bo_agent->get_error();
+			if ($this->bo_agent->debugmode) echo '<br />END: Mail agent in DEBUG mode:'.implode('<br />',$this->error);
+				return $ok;
+			}
+		}
+		
+	}
+?>
Index: /sandbox/workflow/branches/993/inc/phplot/phplot_data.php
===================================================================
--- /sandbox/workflow/branches/993/inc/phplot/phplot_data.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/phplot/phplot_data.php	(revision 795)
@@ -0,0 +1,259 @@
+<?php
+/**
+ * Copyright (C) 2000 Afan Ottenheimer.  Released under
+ * the GPL and PHP licenses as stated in the the README file which
+ * should have been included with this document.
+
+ * This is an subclass for phplot.php and should only be
+ * called after phplot.ini has been called. This extends
+ * phplot by adding additional routines that can be used
+ * to modify the data arrays.
+ *
+ * Data must be a *numerical* array, this is enforced in SetDataValues()
+ * @package Workflow
+ * @subpackage phplot
+ */
+
+require_once("phplot.php");
+
+class PHPlot_Data extends PHPlot 
+{
+    /*!
+     * Constructor
+     */
+    function PHPlot_Data($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
+    { 
+        if (! isset($this->img)) { 
+            $this->PHPlot($which_width, $which_height, $which_output_file, $which_input_file);
+        }
+    }
+    
+    /*!
+     * Will scale all data rows
+     * Maybe later I will do a function that only scales some rows
+     * if $even is TRUE, data will be scaled with "even" factors. 
+     * \note Original code by Thiemo Nagel
+     */
+    function DoScaleData($even, $show_in_legend) 
+    {
+        $offset = 0;        // We use this not to read labels in text-data
+            
+        if ($this->data_type == 'text-data') {
+            $offset = 1;
+        } elseif ($this->data_type != 'data-data') {
+            $this->DrawError('wrong data type!!');
+            return FALSE;
+        }
+
+        // Determine maxima for each data row in array $max
+        // Put maximum of the maxima in $maxmax
+        $maxmax = 0;
+        for($i=0; $i < $this->num_data_rows; $i++) {
+            $rowsize = count($this->data[$i]);
+            for ($j=$offset; $j < $rowsize; $j++) {
+                if ($this->data[$i][$j] > @ $max[$j])
+                    $max[$j] = $this->data[$i][$j];
+                if (@ $max[$j] > $maxmax) 
+                    $maxmax = $max[$j];
+            }
+        }
+        
+        // determine amplification factor $amplify
+        $end = count($max) + $offset;
+        for ($i=$offset; $i < $end; $i++) {
+            if ($max[$i] == 0 || $max[$i] == $maxmax) {
+                $amplify[$i] = 1;  // no divide by zero
+            } else {
+                if ($even) {
+                    $amp = pow(10,round(log10($maxmax / $max[$i]))-1);
+                    if ($amp * $max[$i] * 5 < $maxmax) {
+                        $amp *= 5;
+                    } elseif ($amp * $max[$i] * 2 < $maxmax) {
+                        $amp *= 2;
+                    }
+                } else {
+                    $amp = $maxmax / $max[$i];
+                    $digits = floor(log10($amp));
+                    $amp = round($amp/pow(10,$digits-1))*pow(10,$digits-1);
+                }
+                $amplify[$i] = $amp;
+            }
+            if ($amplify[$i] != 1 && $show_in_legend) 
+                @ $this->legend[$i] .= "*$amplify[$i]";
+        }
+
+        // Amplify data
+        // On my machine, running 1000 iterations over 1000 rows of 12 elements each,
+        // the for loops were 43.2% faster (MBD)
+        for ($i = 0; $i < $this->num_data_rows; $i++) {
+            $rowsize = count($this->data[$i]);
+            for ($j=$offset; $j < $rowsize; $j++) {
+                $this->data[$i][$j] *= $amplify[$j];
+            }
+        }
+
+        //Re-Scale Vertical Ticks if not already set
+        if ( ! $this->y_tick_increment) {
+            $this->SetYTickIncrement() ;
+        }
+
+        return TRUE;
+    } //function DoScaleData
+
+
+    /*!
+     * Computes a moving average of strength $interval for
+     * data row number $datarow, where 0 denotes the first
+     * row of y-data. 
+     *
+     *  \param int    datarow  Index of the row whereupon to make calculations
+     *  \param int    interval Number of elements to use in average ("strength")
+     *  \param bool   show     Whether to tell about the moving average in the legend.
+     *  \param string color    Color for the line to be drawn. This color is darkened. 
+     *                         Can be named or #RRGGBB.
+     *  \param int    width    Width of the line to be drawn.
+     *
+     *  \note Original idea by Theimo Nagel
+     */
+    function DoMovingAverage($datarow, $interval, $show=TRUE, $color=NULL, $width=NULL)
+    {
+        $off = 1;               // Skip record #0 (data label) 
+        
+        $this->PadArrays();
+        
+        if ($interval == 0) {
+            $this->DrawError('DoMovingAverage(): interval can\'t be 0');
+            return FALSE;
+        }
+
+        if ($datarow >= $this->records_per_group) {
+            $this->DrawError("DoMovingAverage(): Data row out of bounds ($datarow >= $this->records_per_group)");
+            return FALSE;
+        }
+        
+        if ($this->data_type == 'text-data') {
+            // Ok. No need to set the offset to skip more records.
+        } elseif ($this->data_type == 'data-data') {
+            $off++;             // first Y value at $data[][2]
+        } else {
+            $this->DrawError('DoMovingAverage(): wrong data type!!');
+            return FALSE;
+        }
+        
+        // Set color:
+        if ($color) {
+            array_push($this->ndx_data_colors, $this->SetIndexDarkColor($color));
+        } else {
+            array_push($this->ndx_data_colors, $this->SetIndexDarkColor($this->data_colors[$datarow]));
+        }
+        // Set line width:
+        if ($width) {
+            array_push($this->line_widths, $width);
+        } else {    
+            array_push($this->line_widths,  $this->line_widths[$datarow] * 2);
+        }
+        // Show in legend?
+        if ($show) {
+            $this->legend[$this->records_per_group-1] = "(MA[$datarow]:$interval)";
+        }
+
+        $datarow += $off;
+        for ($i = 0; $i < $this->num_data_rows; $i++) {
+            $storage[$i % $interval] = @ $this->data[$i][$datarow];
+            $ma = array_sum($storage);
+            $ma /= count($storage);
+            array_push($this->data[$i], $ma);   // Push the data onto the array
+            $this->num_recs[$i]++;              // Tell the drawing functions it is there
+        }
+        $this->records_per_group++;
+//        $this->FindDataLimits();
+        return TRUE;
+    } //function DoMovingAverage()
+
+
+    /**
+     * Computes an exponentially smoothed moving average.
+     * @param int perc "smoothing percentage"
+     * FIXME!!! I haven't checked this.
+     */
+    function DoExponentialMovingAverage($datarow, $perc, $show_in_legend)
+    {
+        if ($this->data_type == 'text-data') {
+            $datarow++;
+        } elseif ($this->data_type != 'data-data') {
+            $this->DrawError('DoWeightedMovingAverage(): wrong data type!!');
+            return FALSE;
+        }
+        
+        if ($show_in_legend) {
+            $this->legend[$datarow] .= " (MA: $interval)";
+        }
+
+        $storage[0] = $this->data[0][$datarow];
+        for ($i=1;$i < $this->num_data_rows; $i++) {
+            $storage[$i] = @ $storage[$i-1] + $perc * ($this->data[$i][$datarow] - $storage[$i-1]);
+            $ma = array_sum($storage);
+            $ma /= count($storage);
+            $this->data[$i][$datarow] = $ma;
+        }
+        return TRUE;
+    } // function DoExponentialMovingAverage()
+
+    
+    /*!
+     * Removes the DataSet of number $index
+     */
+    function DoRemoveDataSet($index) 
+    {
+        $offset = 1;
+        if ($this->data_type == 'data-data') {
+            $offset++;
+        } elseif ($this->data_type != 'text-data') {
+            $this->DrawError('wrong data type!!');
+            return FALSE;
+        }
+    
+        $index += $offset;
+        foreach ($this->data as $key=>$val) {
+            foreach ($val as $key2=>$val2) {
+                if ($key2 >= $index) {
+                    if (isset($this->data[$key][$key2+1])) {
+                        $this->data[$key][$key2] = $this->data[$key][$key2+1];
+                    } else {
+                        unset($this->data[$key][$key2]);
+                    }
+                }
+            }
+        }
+    } // function DoRemoveDataSet
+    
+    
+    /*!
+     * Computes row x divided by row y, stores the result in row x
+     * and deletes row y
+     */
+    function DoDivision($x,$y) 
+    {
+        $offset = 1;
+        if ($this->data_type == 'data-data') {
+            $offset++;
+        } elseif ($this->data_type != 'text-data') {
+            $this->DrawError('wrong data type!!');
+            return FALSE;
+        }
+    
+        $x += $offset; $y += $offset;
+        reset($this->data);
+        while (list($key, $val) = each($this->data)) {
+            if ($this->data[$key][$y] == 0) {
+                $this->data[$key][$x] = 0;
+            } else {
+                $this->data[$key][$x] /= $this->data[$key][$y];
+            }
+        }
+    
+        $this->DoRemoveDataSet($y-$offset);
+    } // function DoDivision
+
+} // class PHPlot_Data extends PHPlot
+?>
Index: /sandbox/workflow/branches/993/inc/phplot/rgb.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/phplot/rgb.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/phplot/rgb.inc.php	(revision 795)
@@ -0,0 +1,755 @@
+<?php
+
+/**
+ * PHPLOT Version 5.0rc3
+ * Copyright (C) 1998-2006 Afan Ottenheimer.  Released under
+ * the GPL and PHP licenses as stated in the the README file which should
+ * have been included with this document.
+ *
+ * @package Workflow
+ * @subpackage phplot
+ */
+
+//Looking forward to the day when memory is so
+//plentiful to be able to set gigantic arrays,
+//we offer this taken from PHPLOT. 
+$ColorArray = array(
+	"snow"			=> array(255, 250, 250),
+	"ghost white"	=> array(248, 248, 255),
+	"GhostWhite"	=> array(248, 248, 255),
+	"white smoke"	=> array(245, 245, 245),
+	"WhiteSmoke"	=> array(245, 245, 245),
+	"gainsboro"		=> array(220, 220, 220),
+	"floral white"	=> array(255, 250, 240),
+	"FloralWhite"	=> array(255, 250, 240),
+	"old lace"		=> array(253, 245, 230),
+	"OldLace"		=> array(253, 245, 230),
+	"linen"			=> array(250, 240, 230),
+	"antique white"	=> array(250, 235, 215),
+	"AntiqueWhite"	=> array(250, 235, 215),
+	"papaya whip"	=> array(255, 239, 213),
+	"PapayaWhip"	=> array(255, 239, 213),
+	"blanched almond"	=> array(255, 235, 205),
+	"BlanchedAlmond"	=> array(255, 235, 205),
+	"bisque"		=> array(255, 228, 196),
+	"peach puff"	=> array(255, 218, 185),
+	"PeachPuff"		=> array(255, 218, 185),
+	"navajo white"	=> array(255, 222, 173),
+	"NavajoWhite"	=> array(255, 222, 173),
+	"moccasin"		=> array(255, 228, 181),
+	"cornsilk"		=> array(255, 248, 220),
+	"ivory"			=> array(255, 255, 240),
+	"lemon chiffon"	=> array(255, 250, 205),
+	"LemonChiffon"	=> array(255, 250, 205),
+	"seashell"		=> array(255, 245, 238),
+	"honeydew"		=> array(240, 255, 240),
+	"mint cream"	=> array(245, 255, 250),
+	"MintCream"		=> array(245, 255, 250),
+	"azure"			=> array(240, 255, 255),
+	"alice blue"	=> array(240, 248, 255),
+	"AliceBlue"		=> array(240, 248, 255),
+	"lavender"		=> array(230, 230, 250),
+	"lavender blush"	=> array(255, 240, 245),
+	"LavenderBlush"		=> array(255, 240, 245),
+	"misty rose"		=> array(255, 228, 225),
+	"MistyRose"		=> array(255, 228, 225),
+	"white"			=> array(255, 255, 255),
+	"black"			=> array(  0,   0,   0),
+	"dark slate gray"	=> array( 47,  79,  79),
+	"DarkSlateGray"		=> array( 47,  79,  79),
+	"dark slate grey"	=> array( 47,  79,  79),
+	"DarkSlateGrey"		=> array( 47,  79,  79),
+	"dim gray"			=> array(105, 105, 105),
+	"DimGray"			=> array(105, 105, 105),
+	"dim grey"			=> array(105, 105, 105),
+	"DimGrey"			=> array(105, 105, 105),
+	"slate gray"		=> array(112, 128, 144),
+	"SlateGray"			=> array(112, 128, 144),
+	"slate grey"		=> array(112, 128, 144),
+	"SlateGrey"			=> array(112, 128, 144),
+	"light slate gray"	=> array(119, 136, 153),
+	"LightSlateGray"	=> array(119, 136, 153),
+	"light slate grey"	=> array(119, 136, 153),
+	"LightSlateGrey"	=> array(119, 136, 153),
+	"gray"			=> array(190, 190, 190),
+	"grey"			=> array(190, 190, 190),
+	"light grey"		=> array(211, 211, 211),
+	"LightGrey"			=> array(211, 211, 211),
+	"light gray"		=> array(211, 211, 211),
+	"LightGray"			=> array(211, 211, 211),
+	"midnight blue"		=> array( 25,  25, 112),
+	"MidnightBlue"		=> array( 25,  25, 112),
+	"navy"			=> array(  0,   0, 128),
+	"navy blue"			=> array(  0,   0, 128),
+	"NavyBlue"			=> array(  0,   0, 128),
+	"cornflower blue"	=> array(100, 149, 237),
+	"CornflowerBlue"	=> array(100, 149, 237),
+	"dark slate blue"	=> array( 72,  61, 139),
+	"DarkSlateBlue"		=> array( 72,  61, 139),
+	"slate blue"		=> array(106,  90, 205),
+	"SlateBlue"			=> array(106,  90, 205),
+	"medium slate blue"	=> array(123, 104, 238),
+	"MediumSlateBlue"	=> array(123, 104, 238),
+	"light slate blue"	=> array(132, 112, 255),
+	"LightSlateBlue"	=> array(132, 112, 255),
+	"medium blue"		=> array(  0,   0, 205),
+	"MediumBlue"		=> array(  0,   0, 205),
+	"royal blue"		=> array( 65, 105, 225),
+	"RoyalBlue"			=> array( 65, 105, 225),
+	"blue"			=> array(  0,   0, 255),
+	"dodger blue"		=> array( 30, 144, 255),
+	"DodgerBlue"		=> array( 30, 144, 255),
+	"deep sky blue"		=> array(  0, 191, 255),
+	"DeepSkyBlue"		=> array(  0, 191, 255),
+	"sky blue"			=> array(135, 206, 235),
+	"SkyBlue"			=> array(135, 206, 235),
+	"light sky blue"	=> array(135, 206, 250),
+	"LightSkyBlue"		=> array(135, 206, 250),
+	"steel blue"		=> array( 70, 130, 180),
+	"SteelBlue"			=> array( 70, 130, 180),
+	"light steel blue"	=> array(176, 196, 222),
+	"LightSteelBlue"	=> array(176, 196, 222),
+	"light blue"		=> array(173, 216, 230),
+	"LightBlue"			=> array(173, 216, 230),
+	"powder blue"		=> array(176, 224, 230),
+	"PowderBlue"		=> array(176, 224, 230),
+	"pale turquoise"	=> array(175, 238, 238),
+	"PaleTurquoise"		=> array(175, 238, 238),
+	"dark turquoise"	=> array(  0, 206, 209),
+	"DarkTurquoise"		=> array(  0, 206, 209),
+	"medium turquoise"	=> array( 72, 209, 204),
+	"MediumTurquoise"	=> array( 72, 209, 204),
+	"turquoise"			=> array( 64, 224, 208),
+	"cyan"			=> array(  0, 255, 255),
+	"light cyan"		=> array(224, 255, 255),
+	"LightCyan"			=> array(224, 255, 255),
+	"cadet blue"		=> array( 95, 158, 160),
+	"CadetBlue"			=> array( 95, 158, 160),
+	"medium aquamarine"	=> array(102, 205, 170),
+	"MediumAquamarine"	=> array(102, 205, 170),
+	"aquamarine"		=> array(127, 255, 212),
+	"dark green"		=> array(  0, 100,   0),
+	"DarkGreen"			=> array(  0, 100,   0),
+	"dark olive green"	=> array( 85, 107,  47),
+	"DarkOliveGreen"	=> array( 85, 107,  47),
+	"dark sea green"	=> array(143, 188, 143),
+	"DarkSeaGreen"		=> array(143, 188, 143),
+	"sea green"			=> array( 46, 139,  87),
+	"SeaGreen"			=> array( 46, 139,  87),
+	"medium sea green"	=> array( 60, 179, 113),
+	"MediumSeaGreen"	=> array( 60, 179, 113),
+	"light sea green"	=> array( 32, 178, 170),
+	"LightSeaGreen"		=> array( 32, 178, 170),
+	"pale green"		=> array(152, 251, 152),
+	"PaleGreen"			=> array(152, 251, 152),
+	"spring green"		=> array(  0, 255, 127),
+	"SpringGreen"		=> array(  0, 255, 127),
+	"lawn green"		=> array(124, 252,   0),
+	"LawnGreen"			=> array(124, 252,   0),
+	"green"			=> array(  0, 255,   0),
+	"chartreuse"		=> array(127, 255,   0),
+	"medium spring green"	=> array(  0, 250, 154),
+	"MediumSpringGreen"		=> array(  0, 250, 154),
+	"green yellow"			=> array(173, 255,  47),
+	"GreenYellow"			=> array(173, 255,  47),
+	"lime green"			=> array( 50, 205,  50),
+	"LimeGreen"			=> array( 50, 205,  50),
+	"yellow green"			=> array(154, 205,  50),
+	"YellowGreen"			=> array(154, 205,  50),
+	"forest green"			=> array( 34, 139,  34),
+	"ForestGreen"			=> array( 34, 139,  34),
+	"olive drab"			=> array(107, 142,  35),
+	"OliveDrab"			=> array(107, 142,  35),
+	"dark khaki"		=> array(189, 183, 107),
+	"DarkKhaki"			=> array(189, 183, 107),
+	"khaki"			=> array(240, 230, 140),
+	"pale goldenrod"	=> array(238, 232, 170),
+	"PaleGoldenrod"		=> array(238, 232, 170),
+	"light goldenrod yellow"	=> array(250, 250, 210),
+	"LightGoldenrodYellow"		=> array(250, 250, 210),
+	"light yellow"			=> array(255, 255, 224),
+	"LightYellow"			=> array(255, 255, 224),
+	"yellow"			=> array(255, 255,   0),
+	"gold"			=> array(255, 215,   0),
+	"light goldenrod"			=> array(238, 221, 130),
+	"LightGoldenrod"			=> array(238, 221, 130),
+	"goldenrod"			=> array(218, 165,  32),
+	"dark goldenrod"			=> array(184, 134,  11),
+	"DarkGoldenrod"			=> array(184, 134,  11),
+	"rosy brown"			=> array(188, 143, 143),
+	"RosyBrown"			=> array(188, 143, 143),
+	"indian red"			=> array(205,  92,  92),
+	"IndianRed"			=> array(205,  92,  92),
+	"saddle brown"			=> array(139,  69,  19),
+	"SaddleBrown"			=> array(139,  69,  19),
+	"sienna"			=> array(160,  82,  45),
+	"peru"			=> array(205, 133,  63),
+	"burlywood"			=> array(222, 184, 135),
+	"beige"			=> array(245, 245, 220),
+	"wheat"			=> array(245, 222, 179),
+	"sandy brown"			=> array(244, 164,  96),
+	"SandyBrown"			=> array(244, 164,  96),
+	"tan"			=> array(210, 180, 140),
+	"chocolate"			=> array(210, 105,  30),
+	"firebrick"			=> array(178,  34,  34),
+	"brown"			=> array(165,  42,  42),
+	"dark salmon"			=> array(233, 150, 122),
+	"DarkSalmon"			=> array(233, 150, 122),
+	"salmon"			=> array(250, 128, 114),
+	"light salmon"			=> array(255, 160, 122),
+	"LightSalmon"			=> array(255, 160, 122),
+	"orange"			=> array(255, 165,   0),
+	"dark orange"			=> array(255, 140,   0),
+	"DarkOrange"			=> array(255, 140,   0),
+	"coral"			=> array(255, 127,  80),
+	"light coral"			=> array(240, 128, 128),
+	"LightCoral"			=> array(240, 128, 128),
+	"tomato"			=> array(255,  99,  71),
+	"orange red"			=> array(255,  69,   0),
+	"OrangeRed"			=> array(255,  69,   0),
+	"red"			=> array(255,   0,   0),
+	"hot pink"			=> array(255, 105, 180),
+	"HotPink"			=> array(255, 105, 180),
+	"deep pink"			=> array(255,  20, 147),
+	"DeepPink"			=> array(255,  20, 147),
+	"pink"			=> array(255, 192, 203),
+	"light pink"		=> array(255, 182, 193),
+	"LightPink"			=> array(255, 182, 193),
+	"pale violet red"	=> array(219, 112, 147),
+	"PaleVioletRed"		=> array(219, 112, 147),
+	"maroon"			=> array(176,  48,  96),
+	"medium violet red"	=> array(199,  21, 133),
+	"MediumVioletRed"	=> array(199,  21, 133),
+	"violet red"		=> array(208,  32, 144),
+	"VioletRed"			=> array(208,  32, 144),
+	"magenta"			=> array(255,   0, 255),
+	"violet"			=> array(238, 130, 238),
+	"plum"			=> array(221, 160, 221),
+	"orchid"			=> array(218, 112, 214),
+	"medium orchid"		=> array(186,  85, 211),
+	"MediumOrchid"		=> array(186,  85, 211),
+	"dark orchid"		=> array(153,  50, 204),
+	"DarkOrchid"		=> array(153,  50, 204),
+	"dark violet"		=> array(148,   0, 211),
+	"DarkViolet"		=> array(148,   0, 211),
+	"blue violet"		=> array(138,  43, 226),
+	"BlueViolet"		=> array(138,  43, 226),
+	"purple"			=> array(160,  32, 240),
+	"medium purple"		=> array(147, 112, 219),
+	"MediumPurple"		=> array(147, 112, 219),
+	"thistle"			=> array(216, 191, 216),
+	"snow1"			=> array(255, 250, 250),
+	"snow2"			=> array(238, 233, 233),
+	"snow3"			=> array(205, 201, 201),
+	"snow4"			=> array(139, 137, 137),
+	"seashell1"			=> array(255, 245, 238),
+	"seashell2"			=> array(238, 229, 222),
+	"seashell3"			=> array(205, 197, 191),
+	"seashell4"			=> array(139, 134, 130),
+	"AntiqueWhite1"			=> array(255, 239, 219),
+	"AntiqueWhite2"			=> array(238, 223, 204),
+	"AntiqueWhite3"			=> array(205, 192, 176),
+	"AntiqueWhite4"			=> array(139, 131, 120),
+	"bisque1"			=> array(255, 228, 196),
+	"bisque2"			=> array(238, 213, 183),
+	"bisque3"			=> array(205, 183, 158),
+	"bisque4"			=> array(139, 125, 107),
+	"PeachPuff1"			=> array(255, 218, 185),
+	"PeachPuff2"			=> array(238, 203, 173),
+	"PeachPuff3"			=> array(205, 175, 149),
+	"PeachPuff4"			=> array(139, 119, 101),
+	"NavajoWhite1"			=> array(255, 222, 173),
+	"NavajoWhite2"			=> array(238, 207, 161),
+	"NavajoWhite3"			=> array(205, 179, 139),
+	"NavajoWhite4"			=> array(139, 121,  94),
+	"LemonChiffon1"			=> array(255, 250, 205),
+	"LemonChiffon2"			=> array(238, 233, 191),
+	"LemonChiffon3"			=> array(205, 201, 165),
+	"LemonChiffon4"			=> array(139, 137, 112),
+	"cornsilk1"			=> array(255, 248, 220),
+	"cornsilk2"			=> array(238, 232, 205),
+	"cornsilk3"			=> array(205, 200, 177),
+	"cornsilk4"			=> array(139, 136, 120),
+	"ivory1"			=> array(255, 255, 240),
+	"ivory2"			=> array(238, 238, 224),
+	"ivory3"			=> array(205, 205, 193),
+	"ivory4"			=> array(139, 139, 131),
+	"honeydew1"			=> array(240, 255, 240),
+	"honeydew2"			=> array(224, 238, 224),
+	"honeydew3"			=> array(193, 205, 193),
+	"honeydew4"			=> array(131, 139, 131),
+	"LavenderBlush1"	=> array(255, 240, 245),
+	"LavenderBlush2"	=> array(238, 224, 229),
+	"LavenderBlush3"	=> array(205, 193, 197),
+	"LavenderBlush4"	=> array(139, 131, 134),
+	"MistyRose1"		=> array(255, 228, 225),
+	"MistyRose2"		=> array(238, 213, 210),
+	"MistyRose3"		=> array(205, 183, 181),
+	"MistyRose4"		=> array(139, 125, 123),
+	"azure1"			=> array(240, 255, 255),
+	"azure2"			=> array(224, 238, 238),
+	"azure3"			=> array(193, 205, 205),
+	"azure4"			=> array(131, 139, 139),
+	"SlateBlue1"		=> array(131, 111, 255),
+	"SlateBlue2"		=> array(122, 103, 238),
+	"SlateBlue3"		=> array(105,  89, 205),
+	"SlateBlue4"		=> array( 71,  60, 139),
+	"RoyalBlue1"		=> array( 72, 118, 255),
+	"RoyalBlue2"		=> array( 67, 110, 238),
+	"RoyalBlue3"		=> array( 58,  95, 205),
+	"RoyalBlue4"		=> array( 39,  64, 139),
+	"blue1"			=> array(  0,   0, 255),
+	"blue2"			=> array(  0,   0, 238),
+	"blue3"			=> array(  0,   0, 205),
+	"blue4"			=> array(  0,   0, 139),
+	"DodgerBlue1"		=> array( 30, 144, 255),
+	"DodgerBlue2"		=> array( 28, 134, 238),
+	"DodgerBlue3"		=> array( 24, 116, 205),
+	"DodgerBlue4"		=> array( 16,  78, 139),
+	"SteelBlue1"		=> array( 99, 184, 255),
+	"SteelBlue2"		=> array( 92, 172, 238),
+	"SteelBlue3"		=> array( 79, 148, 205),
+	"SteelBlue4"		=> array( 54, 100, 139),
+	"DeepSkyBlue1"		=> array(  0, 191, 255),
+	"DeepSkyBlue2"		=> array(  0, 178, 238),
+	"DeepSkyBlue3"		=> array(  0, 154, 205),
+	"DeepSkyBlue4"		=> array(  0, 104, 139),
+	"SkyBlue1"			=> array(135, 206, 255),
+	"SkyBlue2"			=> array(126, 192, 238),
+	"SkyBlue3"			=> array(108, 166, 205),
+	"SkyBlue4"			=> array( 74, 112, 139),
+	"LightSkyBlue1"		=> array(176, 226, 255),
+	"LightSkyBlue2"		=> array(164, 211, 238),
+	"LightSkyBlue3"		=> array(141, 182, 205),
+	"LightSkyBlue4"		=> array( 96, 123, 139),
+	"SlateGray1"		=> array(198, 226, 255),
+	"SlateGray2"		=> array(185, 211, 238),
+	"SlateGray3"		=> array(159, 182, 205),
+	"SlateGray4"		=> array(108, 123, 139),
+	"LightSteelBlue1"	=> array(202, 225, 255),
+	"LightSteelBlue2"	=> array(188, 210, 238),
+	"LightSteelBlue3"	=> array(162, 181, 205),
+	"LightSteelBlue4"	=> array(110, 123, 139),
+	"LightBlue1"		=> array(191, 239, 255),
+	"LightBlue2"		=> array(178, 223, 238),
+	"LightBlue3"		=> array(154, 192, 205),
+	"LightBlue4"		=> array(104, 131, 139),
+	"LightCyan1"		=> array(224, 255, 255),
+	"LightCyan2"		=> array(209, 238, 238),
+	"LightCyan3"		=> array(180, 205, 205),
+	"LightCyan4"		=> array(122, 139, 139),
+	"PaleTurquoise1"	=> array(187, 255, 255),
+	"PaleTurquoise2"	=> array(174, 238, 238),
+	"PaleTurquoise3"	=> array(150, 205, 205),
+	"PaleTurquoise4"	=> array(102, 139, 139),
+	"CadetBlue1"		=> array(152, 245, 255),
+	"CadetBlue2"		=> array(142, 229, 238),
+	"CadetBlue3"		=> array(122, 197, 205),
+	"CadetBlue4"		=> array( 83, 134, 139),
+	"turquoise1"		=> array(  0, 245, 255),
+	"turquoise2"		=> array(  0, 229, 238),
+	"turquoise3"		=> array(  0, 197, 205),
+	"turquoise4"		=> array(  0, 134, 139),
+	"cyan1"			=> array(  0, 255, 255),
+	"cyan2"			=> array(  0, 238, 238),
+	"cyan3"			=> array(  0, 205, 205),
+	"cyan4"			=> array(  0, 139, 139),
+	"DarkSlateGray1"	=> array(151, 255, 255),
+	"DarkSlateGray2"	=> array(141, 238, 238),
+	"DarkSlateGray3"	=> array(121, 205, 205),
+	"DarkSlateGray4"	=> array( 82, 139, 139),
+	"aquamarine1"		=> array(127, 255, 212),
+	"aquamarine2"		=> array(118, 238, 198),
+	"aquamarine3"		=> array(102, 205, 170),
+	"aquamarine4"		=> array( 69, 139, 116),
+	"DarkSeaGreen1"		=> array(193, 255, 193),
+	"DarkSeaGreen2"		=> array(180, 238, 180),
+	"DarkSeaGreen3"		=> array(155, 205, 155),
+	"DarkSeaGreen4"		=> array(105, 139, 105),
+	"SeaGreen1"			=> array( 84, 255, 159),
+	"SeaGreen2"			=> array( 78, 238, 148),
+	"SeaGreen3"			=> array( 67, 205, 128),
+	"SeaGreen4"			=> array( 46, 139,  87),
+	"PaleGreen1"		=> array(154, 255, 154),
+	"PaleGreen2"		=> array(144, 238, 144),
+	"PaleGreen3"		=> array(124, 205, 124),
+	"PaleGreen4"		=> array( 84, 139,  84),
+	"SpringGreen1"		=> array(  0, 255, 127),
+	"SpringGreen2"		=> array(  0, 238, 118),
+	"SpringGreen3"		=> array(  0, 205, 102),
+	"SpringGreen4"		=> array(  0, 139,  69),
+	"green1"			=> array(  0, 255,   0),
+	"green2"			=> array(  0, 238,   0),
+	"green3"			=> array(  0, 205,   0),
+	"green4"			=> array(  0, 139,   0),
+	"chartreuse1"		=> array(127, 255,   0),
+	"chartreuse2"		=> array(118, 238,   0),
+	"chartreuse3"		=> array(102, 205,   0),
+	"chartreuse4"		=> array( 69, 139,   0),
+	"OliveDrab1"		=> array(192, 255,  62),
+	"OliveDrab2"		=> array(179, 238,  58),
+	"OliveDrab3"		=> array(154, 205,  50),
+	"OliveDrab4"		=> array(105, 139,  34),
+	"DarkOliveGreen1"	=> array(202, 255, 112),
+	"DarkOliveGreen2"	=> array(188, 238, 104),
+	"DarkOliveGreen3"	=> array(162, 205,  90),
+	"DarkOliveGreen4"	=> array(110, 139,  61),
+	"khaki1"			=> array(255, 246, 143),
+	"khaki2"			=> array(238, 230, 133),
+	"khaki3"			=> array(205, 198, 115),
+	"khaki4"			=> array(139, 134,  78),
+	"LightGoldenrod1"	=> array(255, 236, 139),
+	"LightGoldenrod2"	=> array(238, 220, 130),
+	"LightGoldenrod3"	=> array(205, 190, 112),
+	"LightGoldenrod4"	=> array(139, 129,  76),
+	"LightYellow1"		=> array(255, 255, 224),
+	"LightYellow2"		=> array(238, 238, 209),
+	"LightYellow3"		=> array(205, 205, 180),
+	"LightYellow4"		=> array(139, 139, 122),
+	"yellow1"			=> array(255, 255,   0),
+	"yellow2"			=> array(238, 238,   0),
+	"yellow3"			=> array(205, 205,   0),
+	"yellow4"			=> array(139, 139,   0),
+	"gold1"			=> array(255, 215,   0),
+	"gold2"			=> array(238, 201,   0),
+	"gold3"			=> array(205, 173,   0),
+	"gold4"			=> array(139, 117,   0),
+	"goldenrod1"		=> array(255, 193,  37),
+	"goldenrod2"		=> array(238, 180,  34),
+	"goldenrod3"		=> array(205, 155,  29),
+	"goldenrod4"		=> array(139, 105,  20),
+	"DarkGoldenrod1"	=> array(255, 185,  15),
+	"DarkGoldenrod2"	=> array(238, 173,  14),
+	"DarkGoldenrod3"	=> array(205, 149,  12),
+	"DarkGoldenrod4"	=> array(139, 101,   8),
+	"RosyBrown1"		=> array(255, 193, 193),
+	"RosyBrown2"		=> array(238, 180, 180),
+	"RosyBrown3"		=> array(205, 155, 155),
+	"RosyBrown4"		=> array(139, 105, 105),
+	"IndianRed1"		=> array(255, 106, 106),
+	"IndianRed2"		=> array(238,  99,  99),
+	"IndianRed3"		=> array(205,  85,  85),
+	"IndianRed4"		=> array(139,  58,  58),
+	"sienna1"			=> array(255, 130,  71),
+	"sienna2"			=> array(238, 121,  66),
+	"sienna3"			=> array(205, 104,  57),
+	"sienna4"			=> array(139,  71,  38),
+	"burlywood1"		=> array(255, 211, 155),
+	"burlywood2"		=> array(238, 197, 145),
+	"burlywood3"		=> array(205, 170, 125),
+	"burlywood4"		=> array(139, 115,  85),
+	"wheat1"			=> array(255, 231, 186),
+	"wheat2"			=> array(238, 216, 174),
+	"wheat3"			=> array(205, 186, 150),
+	"wheat4"			=> array(139, 126, 102),
+	"tan1"			=> array(255, 165,  79),
+	"tan2"			=> array(238, 154,  73),
+	"tan3"			=> array(205, 133,  63),
+	"tan4"			=> array(139,  90,  43),
+	"chocolate1"		=> array(255, 127,  36),
+	"chocolate2"		=> array(238, 118,  33),
+	"chocolate3"		=> array(205, 102,  29),
+	"chocolate4"		=> array(139,  69,  19),
+	"firebrick1"		=> array(255,  48,  48),
+	"firebrick2"		=> array(238,  44,  44),
+	"firebrick3"		=> array(205,  38,  38),
+	"firebrick4"		=> array(139,  26,  26),
+	"brown1"			=> array(255,  64,  64),
+	"brown2"			=> array(238,  59,  59),
+	"brown3"			=> array(205,  51,  51),
+	"brown4"			=> array(139,  35,  35),
+	"salmon1"			=> array(255, 140, 105),
+	"salmon2"			=> array(238, 130,  98),
+	"salmon3"			=> array(205, 112,  84),
+	"salmon4"			=> array(139,  76,  57),
+	"LightSalmon1"		=> array(255, 160, 122),
+	"LightSalmon2"		=> array(238, 149, 114),
+	"LightSalmon3"		=> array(205, 129,  98),
+	"LightSalmon4"		=> array(139,  87,  66),
+	"orange1"			=> array(255, 165,   0),
+	"orange2"			=> array(238, 154,   0),
+	"orange3"			=> array(205, 133,   0),
+	"orange4"			=> array(139,  90,   0),
+	"DarkOrange1"		=> array(255, 127,   0),
+	"DarkOrange2"		=> array(238, 118,   0),
+	"DarkOrange3"		=> array(205, 102,   0),
+	"DarkOrange4"		=> array(139,  69,   0),
+	"coral1"			=> array(255, 114,  86),
+	"coral2"			=> array(238, 106,  80),
+	"coral3"			=> array(205,  91,  69),
+	"coral4"			=> array(139,  62,  47),
+	"tomato1"			=> array(255,  99,  71),
+	"tomato2"			=> array(238,  92,  66),
+	"tomato3"			=> array(205,  79,  57),
+	"tomato4"			=> array(139,  54,  38),
+	"OrangeRed1"		=> array(255,  69,   0),
+	"OrangeRed2"		=> array(238,  64,   0),
+	"OrangeRed3"		=> array(205,  55,   0),
+	"OrangeRed4"		=> array(139,  37,   0),
+	"red1"			=> array(255,   0,   0),
+	"red2"			=> array(238,   0,   0),
+	"red3"			=> array(205,   0,   0),
+	"red4"			=> array(139,   0,   0),
+	"DeepPink1"			=> array(255,  20, 147),
+	"DeepPink2"			=> array(238,  18, 137),
+	"DeepPink3"			=> array(205,  16, 118),
+	"DeepPink4"			=> array(139,  10,  80),
+	"HotPink1"			=> array(255, 110, 180),
+	"HotPink2"			=> array(238, 106, 167),
+	"HotPink3"			=> array(205,  96, 144),
+	"HotPink4"			=> array(139,  58,  98),
+	"pink1"			=> array(255, 181, 197),
+	"pink2"			=> array(238, 169, 184),
+	"pink3"			=> array(205, 145, 158),
+	"pink4"			=> array(139,  99, 108),
+	"LightPink1"		=> array(255, 174, 185),
+	"LightPink2"		=> array(238, 162, 173),
+	"LightPink3"		=> array(205, 140, 149),
+	"LightPink4"		=> array(139,  95, 101),
+	"PaleVioletRed1"	=> array(255, 130, 171),
+	"PaleVioletRed2"	=> array(238, 121, 159),
+	"PaleVioletRed3"	=> array(205, 104, 137),
+	"PaleVioletRed4"	=> array(139,  71,  93),
+	"maroon1"			=> array(255,  52, 179),
+	"maroon2"			=> array(238,  48, 167),
+	"maroon3"			=> array(205,  41, 144),
+	"maroon4"			=> array(139,  28,  98),
+	"VioletRed1"		=> array(255,  62, 150),
+	"VioletRed2"		=> array(238,  58, 140),
+	"VioletRed3"		=> array(205,  50, 120),
+	"VioletRed4"		=> array(139,  34,  82),
+	"magenta1"			=> array(255,   0, 255),
+	"magenta2"			=> array(238,   0, 238),
+	"magenta3"			=> array(205,   0, 205),
+	"magenta4"			=> array(139,   0, 139),
+	"orchid1"			=> array(255, 131, 250),
+	"orchid2"			=> array(238, 122, 233),
+	"orchid3"			=> array(205, 105, 201),
+	"orchid4"			=> array(139,  71, 137),
+	"plum1"			=> array(255, 187, 255),
+	"plum2"			=> array(238, 174, 238),
+	"plum3"			=> array(205, 150, 205),
+	"plum4"			=> array(139, 102, 139),
+	"MediumOrchid1"		=> array(224, 102, 255),
+	"MediumOrchid2"		=> array(209,  95, 238),
+	"MediumOrchid3"		=> array(180,  82, 205),
+	"MediumOrchid4"		=> array(122,  55, 139),
+	"DarkOrchid1"		=> array(191,  62, 255),
+	"DarkOrchid2"		=> array(178,  58, 238),
+	"DarkOrchid3"		=> array(154,  50, 205),
+	"DarkOrchid4"		=> array(104,  34, 139),
+	"purple1"			=> array(155,  48, 255),
+	"purple2"			=> array(145,  44, 238),
+	"purple3"			=> array(125,  38, 205),
+	"purple4"			=> array( 85,  26, 139),
+	"MediumPurple1"		=> array(171, 130, 255),
+	"MediumPurple2"		=> array(159, 121, 238),
+	"MediumPurple3"		=> array(137, 104, 205),
+	"MediumPurple4"		=> array( 93,  71, 139),
+	"thistle1"			=> array(255, 225, 255),
+	"thistle2"			=> array(238, 210, 238),
+	"thistle3"			=> array(205, 181, 205),
+	"thistle4"			=> array(139, 123, 139),
+	"gray0"			=> array(  0,   0,   0),
+	"grey0"			=> array(  0,   0,   0),
+	"gray1"			=> array(  3,   3,   3),
+	"grey1"			=> array(  3,   3,   3),
+	"gray2"			=> array(  5,   5,   5),
+	"grey2"			=> array(  5,   5,   5),
+	"gray3"			=> array(  8,   8,   8),
+	"grey3"			=> array(  8,   8,   8),
+	"gray4"			=> array( 10,  10,  10),
+	"grey4"			=> array( 10,  10,  10),
+	"gray5"			=> array( 13,  13,  13),
+	"grey5"			=> array( 13,  13,  13),
+	"gray6"			=> array( 15,  15,  15),
+	"grey6"			=> array( 15,  15,  15),
+	"gray7"			=> array( 18,  18,  18),
+	"grey7"			=> array( 18,  18,  18),
+	"gray8"			=> array( 20,  20,  20),
+	"grey8"			=> array( 20,  20,  20),
+	"gray9"			=> array( 23,  23,  23),
+	"grey9"			=> array( 23,  23,  23),
+	"gray10"			=> array( 26,  26,  26),
+	"grey10"			=> array( 26,  26,  26),
+	"gray11"			=> array( 28,  28,  28),
+	"grey11"			=> array( 28,  28,  28),
+	"gray12"			=> array( 31,  31,  31),
+	"grey12"			=> array( 31,  31,  31),
+	"gray13"			=> array( 33,  33,  33),
+	"grey13"			=> array( 33,  33,  33),
+	"gray14"			=> array( 36,  36,  36),
+	"grey14"			=> array( 36,  36,  36),
+	"gray15"			=> array( 38,  38,  38),
+	"grey15"			=> array( 38,  38,  38),
+	"gray16"			=> array( 41,  41,  41),
+	"grey16"			=> array( 41,  41,  41),
+	"gray17"			=> array( 43,  43,  43),
+	"grey17"			=> array( 43,  43,  43),
+	"gray18"			=> array( 46,  46,  46),
+	"grey18"			=> array( 46,  46,  46),
+	"gray19"			=> array( 48,  48,  48),
+	"grey19"			=> array( 48,  48,  48),
+	"gray20"			=> array( 51,  51,  51),
+	"grey20"			=> array( 51,  51,  51),
+	"gray21"			=> array( 54,  54,  54),
+	"grey21"			=> array( 54,  54,  54),
+	"gray22"			=> array( 56,  56,  56),
+	"grey22"			=> array( 56,  56,  56),
+	"gray23"			=> array( 59,  59,  59),
+	"grey23"			=> array( 59,  59,  59),
+	"gray24"			=> array( 61,  61,  61),
+	"grey24"			=> array( 61,  61,  61),
+	"gray25"			=> array( 64,  64,  64),
+	"grey25"			=> array( 64,  64,  64),
+	"gray26"			=> array( 66,  66,  66),
+	"grey26"			=> array( 66,  66,  66),
+	"gray27"			=> array( 69,  69,  69),
+	"grey27"			=> array( 69,  69,  69),
+	"gray28"			=> array( 71,  71,  71),
+	"grey28"			=> array( 71,  71,  71),
+	"gray29"			=> array( 74,  74,  74),
+	"grey29"			=> array( 74,  74,  74),
+	"gray30"			=> array( 77,  77,  77),
+	"grey30"			=> array( 77,  77,  77),
+	"gray31"			=> array( 79,  79,  79),
+	"grey31"			=> array( 79,  79,  79),
+	"gray32"			=> array( 82,  82,  82),
+	"grey32"			=> array( 82,  82,  82),
+	"gray33"			=> array( 84,  84,  84),
+	"grey33"			=> array( 84,  84,  84),
+	"gray34"			=> array( 87,  87,  87),
+	"grey34"			=> array( 87,  87,  87),
+	"gray35"			=> array( 89,  89,  89),
+	"grey35"			=> array( 89,  89,  89),
+	"gray36"			=> array( 92,  92,  92),
+	"grey36"			=> array( 92,  92,  92),
+	"gray37"			=> array( 94,  94,  94),
+	"grey37"			=> array( 94,  94,  94),
+	"gray38"			=> array( 97,  97,  97),
+	"grey38"			=> array( 97,  97,  97),
+	"gray39"			=> array( 99,  99,  99),
+	"grey39"			=> array( 99,  99,  99),
+	"gray40"			=> array(102, 102, 102),
+	"grey40"			=> array(102, 102, 102),
+	"gray41"			=> array(105, 105, 105),
+	"grey41"			=> array(105, 105, 105),
+	"gray42"			=> array(107, 107, 107),
+	"grey42"			=> array(107, 107, 107),
+	"gray43"			=> array(110, 110, 110),
+	"grey43"			=> array(110, 110, 110),
+	"gray44"			=> array(112, 112, 112),
+	"grey44"			=> array(112, 112, 112),
+	"gray45"			=> array(115, 115, 115),
+	"grey45"			=> array(115, 115, 115),
+	"gray46"			=> array(117, 117, 117),
+	"grey46"			=> array(117, 117, 117),
+	"gray47"			=> array(120, 120, 120),
+	"grey47"			=> array(120, 120, 120),
+	"gray48"			=> array(122, 122, 122),
+	"grey48"			=> array(122, 122, 122),
+	"gray49"			=> array(125, 125, 125),
+	"grey49"			=> array(125, 125, 125),
+	"gray50"			=> array(127, 127, 127),
+	"grey50"			=> array(127, 127, 127),
+	"gray51"			=> array(130, 130, 130),
+	"grey51"			=> array(130, 130, 130),
+	"gray52"			=> array(133, 133, 133),
+	"grey52"			=> array(133, 133, 133),
+	"gray53"			=> array(135, 135, 135),
+	"grey53"			=> array(135, 135, 135),
+	"gray54"			=> array(138, 138, 138),
+	"grey54"			=> array(138, 138, 138),
+	"gray55"			=> array(140, 140, 140),
+	"grey55"			=> array(140, 140, 140),
+	"gray56"			=> array(143, 143, 143),
+	"grey56"			=> array(143, 143, 143),
+	"gray57"			=> array(145, 145, 145),
+	"grey57"			=> array(145, 145, 145),
+	"gray58"			=> array(148, 148, 148),
+	"grey58"			=> array(148, 148, 148),
+	"gray59"			=> array(150, 150, 150),
+	"grey59"			=> array(150, 150, 150),
+	"gray60"			=> array(153, 153, 153),
+	"grey60"			=> array(153, 153, 153),
+	"gray61"			=> array(156, 156, 156),
+	"grey61"			=> array(156, 156, 156),
+	"gray62"			=> array(158, 158, 158),
+	"grey62"			=> array(158, 158, 158),
+	"gray63"			=> array(161, 161, 161),
+	"grey63"			=> array(161, 161, 161),
+	"gray64"			=> array(163, 163, 163),
+	"grey64"			=> array(163, 163, 163),
+	"gray65"			=> array(166, 166, 166),
+	"grey65"			=> array(166, 166, 166),
+	"gray66"			=> array(168, 168, 168),
+	"grey66"			=> array(168, 168, 168),
+	"gray67"			=> array(171, 171, 171),
+	"grey67"			=> array(171, 171, 171),
+	"gray68"			=> array(173, 173, 173),
+	"grey68"			=> array(173, 173, 173),
+	"gray69"			=> array(176, 176, 176),
+	"grey69"			=> array(176, 176, 176),
+	"gray70"			=> array(179, 179, 179),
+	"grey70"			=> array(179, 179, 179),
+	"gray71"			=> array(181, 181, 181),
+	"grey71"			=> array(181, 181, 181),
+	"gray72"			=> array(184, 184, 184),
+	"grey72"			=> array(184, 184, 184),
+	"gray73"			=> array(186, 186, 186),
+	"grey73"			=> array(186, 186, 186),
+	"gray74"			=> array(189, 189, 189),
+	"grey74"			=> array(189, 189, 189),
+	"gray75"			=> array(191, 191, 191),
+	"grey75"			=> array(191, 191, 191),
+	"gray76"			=> array(194, 194, 194),
+	"grey76"			=> array(194, 194, 194),
+	"gray77"			=> array(196, 196, 196),
+	"grey77"			=> array(196, 196, 196),
+	"gray78"			=> array(199, 199, 199),
+	"grey78"			=> array(199, 199, 199),
+	"gray79"			=> array(201, 201, 201),
+	"grey79"			=> array(201, 201, 201),
+	"gray80"			=> array(204, 204, 204),
+	"grey80"			=> array(204, 204, 204),
+	"gray81"			=> array(207, 207, 207),
+	"grey81"			=> array(207, 207, 207),
+	"gray82"			=> array(209, 209, 209),
+	"grey82"			=> array(209, 209, 209),
+	"gray83"			=> array(212, 212, 212),
+	"grey83"			=> array(212, 212, 212),
+	"gray84"			=> array(214, 214, 214),
+	"grey84"			=> array(214, 214, 214),
+	"gray85"			=> array(217, 217, 217),
+	"grey85"			=> array(217, 217, 217),
+	"gray86"			=> array(219, 219, 219),
+	"grey86"			=> array(219, 219, 219),
+	"gray87"			=> array(222, 222, 222),
+	"grey87"			=> array(222, 222, 222),
+	"gray88"			=> array(224, 224, 224),
+	"grey88"			=> array(224, 224, 224),
+	"gray89"			=> array(227, 227, 227),
+	"grey89"			=> array(227, 227, 227),
+	"gray90"			=> array(229, 229, 229),
+	"grey90"			=> array(229, 229, 229),
+	"gray91"			=> array(232, 232, 232),
+	"grey91"			=> array(232, 232, 232),
+	"gray92"			=> array(235, 235, 235),
+	"grey92"			=> array(235, 235, 235),
+	"gray93"			=> array(237, 237, 237),
+	"grey93"			=> array(237, 237, 237),
+	"gray94"			=> array(240, 240, 240),
+	"grey94"			=> array(240, 240, 240),
+	"gray95"			=> array(242, 242, 242),
+	"grey95"			=> array(242, 242, 242),
+	"gray96"			=> array(245, 245, 245),
+	"grey96"			=> array(245, 245, 245),
+	"gray97"			=> array(247, 247, 247),
+	"grey97"			=> array(247, 247, 247),
+	"gray98"			=> array(250, 250, 250),
+	"grey98"			=> array(250, 250, 250),
+	"gray99"			=> array(252, 252, 252),
+	"grey99"			=> array(252, 252, 252),
+	"gray100"			=> array(255, 255, 255)
+);
+?>
Index: /sandbox/workflow/branches/993/inc/phplot/phplot.php
===================================================================
--- /sandbox/workflow/branches/993/inc/phplot/phplot.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/phplot/phplot.php	(revision 795)
@@ -0,0 +1,4565 @@
+<?php
+
+/**
+ * PHPLOT Version 5.0rc3
+ * Copyright (C) 1998-2006 Afan Ottenheimer.  Released under
+ * the GPL and PHP licenses as stated in the the README file which should
+ * have been included with this document.
+ *
+ * Recent (2003-2004) work by Miguel de Benito Delgado <nonick AT vodafone DOT es>
+ *
+ * Requires PHP 4.3.0 or later
+ * @package Workflow
+ * @subpackage phplot
+ */
+
+if (! defined(__FUNCTION__))
+    define(__FUNCTION__, '__FUNCTION__ Requires at least PHP 4.3.0.');
+
+define ('MINY', -1);        // Indexes in $data (for DrawXDataLine())
+define ('MAXY', -2);
+define ('TOTY', -3);
+
+error_reporting(E_ALL);
+
+class PHPlot {
+
+    /* I have removed internal variable declarations, some isset() checking was required,
+     * but now the variables left are those which can be tweaked by the user. This is intended to
+     * be the first step towards moving most of the Set...() methods into a subclass which will be
+     * used only when strictly necessary. Many users will be able to put default values here in the
+     * class and thus avoid memory overhead and reduce parsing times.
+     */
+    //////////////// CONFIG PARAMETERS //////////////////////
+
+    var $is_inline = FALSE;             // FALSE = Sends headers, TRUE = sends just raw image data
+    var $browser_cache = FALSE;         // FALSE = Sends headers for browser to not cache the image,
+                                        // (only if is_inline = FALSE also)
+
+    var $safe_margin = 5;               // Extra margin used in several places. In pixels
+
+    var $x_axis_position = '';          // Where to draw both axis (world coordinates),
+    var $y_axis_position = '';          // leave blank for X axis at 0 and Y axis at left of plot.
+
+    var $xscale_type = 'linear';        // linear, log
+    var $yscale_type = 'linear';
+
+//Fonts
+    var $use_ttf  = FALSE;                  // Use True Type Fonts?
+    var $ttf_path = '.';                    // Default path to look in for TT Fonts.
+    var $default_ttfont = 'benjamingothic.ttf';
+    var $line_spacing = 4;                  // Pixels between lines.
+
+    // Font angles: 0 or 90 degrees for fixed fonts, any for TTF
+    var $x_label_angle = 0;                 // For labels on X axis (tick and data)
+    var $y_label_angle = 0;                 // For labels on Y axis (tick and data)
+    var $x_title_angle = 0;                 // Don't change this if you don't want to screw things up!
+    var $y_title_angle = 90;                // Nor this.
+    var $title_angle = 0;                   // Or this.
+
+//Formats
+    var $file_format = 'png';
+    var $output_file = '';                  // For output to a file instead of stdout
+
+//Data
+    var $data_type = 'text-data';           // text-data, data-data-error, data-data, text-data-single
+    var $plot_type= 'linepoints';           // bars, lines, linepoints, area, points, pie, thinbarline, squared
+
+    var $label_scale_position = 0.5;        // Shifts data labes in pie charts. 1 = top, 0 = bottom
+    var $group_frac_width = 0.7;            // Bars use this fraction (0 to 1) of a group's space
+    var $bar_extra_space = 0.5;             // Number of extra bar's worth of space in a group
+    var $bar_width_adjust = 1;              // 1 = bars of normal width, must be > 0
+
+    var $y_precision = 1;
+    var $x_precision = 1;
+
+    var $data_units_text = '';              // Units text for 'data' labels (i.e: '€', '$', etc.)
+
+// Titles
+    var $title_txt = '';
+
+    var $x_title_txt = '';
+    var $x_title_pos = 'plotdown';          // plotdown, plotup, both, none
+
+    var $y_title_txt = '';
+    var $y_title_pos = 'plotleft';          // plotleft, plotright, both, none
+
+
+//Labels
+    // There are two types of labels in PHPlot:
+    //    Tick labels: they follow the grid, next to ticks in axis.   (DONE)
+    //                 they are drawn at grid drawing time, by DrawXTicks() and DrawYTicks()
+    //    Data labels: they follow the data points, and can be placed on the axis or the plot (x/y)  (TODO)
+    //                 they are drawn at graph plotting time, by Draw*DataLabel(), called by DrawLines(), etc.
+    //                 Draw*DataLabel() also draws H/V lines to datapoints depending on draw_*_data_label_lines
+
+    // Tick Labels
+    var $x_tick_label_pos = 'plotdown';     // plotdown, plotup, both, xaxis, none
+    var $y_tick_label_pos = 'plotleft';     // plotleft, plotright, both, yaxis, none
+
+    // Data Labels:
+    var $x_data_label_pos = 'plotdown';     // plotdown, plotup, both, plot, all, none
+    var $y_data_label_pos = 'plotleft';     // plotleft, plotright, both, plot, all, plotin, none
+
+    var $draw_x_data_label_lines = FALSE;   // Draw a line from the data point to the axis?
+    var $draw_y_data_label_lines = FALSE;   // TODO
+
+    // Label types: (for tick, data and plot labels)
+    var $x_label_type = '';                 // data, time. Leave blank for no formatting.
+    var $y_label_type = '';                 // data, time. Leave blank for no formatting.
+    var $x_time_format = '%H:%M:%S';        // See http://www.php.net/manual/html/function.strftime.html
+    var $y_time_format = '%H:%M:%S';        // SetYTimeFormat() too...
+
+    // Skipping labels
+    var $x_label_inc = 1;                   // Draw a label every this many (1 = all) (TODO)
+    var $y_label_inc = 1;
+    var $_x_label_cnt = 0;                  // internal count FIXME: work in progress
+
+    // Legend
+    var $legend = '';                       // An array with legend titles
+    var $legend_x_pos = '';
+    var $legend_y_pos = '';
+
+
+//Ticks
+    var $x_tick_length = 5;                 // tick length in pixels for upper/lower axis
+    var $y_tick_length = 5;                 // tick length in pixels for left/right axis
+
+    var $x_tick_cross = 3;                  // ticks cross x axis this many pixels
+    var $y_tick_cross = 3;                  // ticks cross y axis this many pixels
+
+    var $x_tick_pos = 'plotdown';           // plotdown, plotup, both, xaxis, none
+    var $y_tick_pos = 'plotleft';           // plotright, plotleft, both, yaxis, none
+
+    var $num_x_ticks = '';
+    var $num_y_ticks = '';
+
+    var $x_tick_inc = '';                   // Set num_x_ticks or x_tick_inc, not both.
+    var $y_tick_inc = '';                   // Set num_y_ticks or y_tick_inc, not both.
+
+    var $skip_top_tick = FALSE;
+    var $skip_bottom_tick = FALSE;
+    var $skip_left_tick = FALSE;
+    var $skip_right_tick = FALSE;
+
+//Grid Formatting
+    var $draw_x_grid = FALSE;
+    var $draw_y_grid = TRUE;
+
+    var $dashed_grid = TRUE;
+    var $grid_at_foreground = FALSE;        // Chooses whether to draw the grid below or above the graph
+
+//Colors and styles       (all colors can be array (R,G,B) or named color)
+    var $color_array = 'small';             // 'small', 'large' or array (define your own colors)
+                                            // See rgb.inc.php and SetRGBArray()
+    var $i_border = array(194, 194, 194);
+    var $plot_bg_color = 'white';
+    var $bg_color = 'white';
+    var $label_color = 'black';
+    var $text_color = 'black';
+    var $grid_color = 'black';
+    var $light_grid_color = 'gray';
+    var $tick_color = 'black';
+    var $title_color = 'black';
+    var $data_colors = array('SkyBlue', 'green', 'orange', 'blue', 'orange', 'red', 'violet', 'azure1');
+    var $error_bar_colors = array('SkyBlue', 'green', 'orange', 'blue', 'orange', 'red', 'violet', 'azure1');
+    var $data_border_colors = array('black');
+
+    var $line_widths = 1;                  // single value or array
+    var $line_styles = array('solid', 'solid', 'dashed');   // single value or array
+    var $dashed_style = '2-4';              // colored dots-transparent dots
+
+    var $point_sizes = array(5,5,3);         // single value or array
+    var $point_shapes = array('diamond');   // rect, circle, diamond, triangle, dot, line, halfline, cross
+
+    var $error_bar_size = 5;                // right and left size of tee
+    var $error_bar_shape = 'tee';           // 'tee' or 'line'
+    var $error_bar_line_width = 1;          // single value (or array TODO)
+
+    var $plot_border_type = 'sides';        // left, sides, none, full
+    var $image_border_type = 'none';        // 'raised', 'plain', 'none'
+
+    var $shading = 5;                       // 0 for no shading, > 0 is size of shadows in pixels
+
+    var $draw_plot_area_background = FALSE;
+    var $draw_broken_lines = FALSE;          // Tells not to draw lines for missing Y data.
+
+
+//////////////////////////////////////////////////////
+//BEGIN CODE
+//////////////////////////////////////////////////////
+
+    /*!
+     * Constructor: Setup img resource, colors and size of the image, and font sizes.
+     *
+     * \param which_width       int    Image width in pixels.
+     * \param which_height      int    Image height in pixels.
+     * \param which_output_file string Filename for output.
+     * \param which_input_fule  string Path to a file to be used as background.
+     */
+    function PHPlot($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
+    {
+        /*
+         * Please see http://www.php.net/register_shutdown_function
+         * PLEASE NOTE: register_shutdown_function() will take a copy of the object rather than a reference
+         * so we put an ampersand. However, the function registered will work on the object as it
+         * was upon registration. To solve this, one of two methods can be used:
+         *      $obj = new object();
+         *      register_shutdown_function(array(&$obj,'shutdown'));
+         * OR
+         *      $obj = &new object();
+         * HOWEVER, as the second statement assigns $obj a reference to the current object, it might be that
+         * several instances mess things up... (CHECK THIS)
+         *
+         * AND
+         *    as $this->img is set upon construction of the object, problems will not arise for us (for the
+         *    moment maybe, so I put all this here just in case)
+         */
+        register_shutdown_function(array(&$this, '_PHPlot'));
+
+        $this->SetRGBArray($this->color_array);
+
+        $this->background_done = FALSE;     // Set to TRUE after background image is drawn once
+
+        if ($which_output_file)
+            $this->SetOutputFile($which_output_file);
+
+        if ($which_input_file)
+            $this->SetInputFile($which_input_file);
+        else {
+            $this->image_width = $which_width;
+            $this->image_height = $which_height;
+
+            $this->img = ImageCreate($this->image_width, $this->image_height);
+            if (! $this->img)
+                $this->PrintError('PHPlot(): Could not create image resource.');
+
+        }
+
+        $this->SetDefaultStyles();
+        $this->SetDefaultFonts();
+
+        $this->SetTitle('');
+        $this->SetXTitle('');
+        $this->SetYTitle('');
+
+        $this->print_image = TRUE;      // Use for multiple plots per image (TODO: automatic)
+    }
+
+    /*!
+     * Destructor. Image resources not deallocated can be memory hogs, I think
+     * it is safer to automatically call imagedestroy upon script termination than
+     * do it ourselves.
+     * See notes in the constructor code.
+     */
+    function _PHPlot ()
+    {
+        ImageDestroy($this->img);
+        return;
+    }
+
+
+/////////////////////////////////////////////
+//////////////                         COLORS
+/////////////////////////////////////////////
+
+    /*!
+     * Returns an index to a color passed in as anything (string, hex, rgb)
+     *
+     * \param which_color * Color (can be '#AABBCC', 'Colorname', or array(r,g,b))
+     */
+    function SetIndexColor($which_color)
+    {
+        list ($r, $g, $b) = $this->SetRGBColor($which_color);  //Translate to RGB
+        $index = ImageColorExact($this->img, $r, $g, $b);
+        if ($index == -1) {
+            return ImageColorResolve($this->img, $r, $g, $b);
+        } else {
+            return $index;
+        }
+    }
+
+
+    /*!
+     * Returns an index to a slightly darker color than the one requested.
+     */
+    function SetIndexDarkColor($which_color)
+    {
+        list ($r, $g, $b) = $this->SetRGBColor($which_color);
+
+        $r -= 0x30;     $r = ($r < 0) ? 0 : $r;
+        $g -= 0x30;     $g = ($g < 0) ? 0 : $g;
+        $b -= 0x30;     $b = ($b < 0) ? 0 : $b;
+
+        $index = ImageColorExact($this->img, $r, $g, $b);
+        if ($index == -1) {
+            return ImageColorResolve($this->img, $r, $g, $b);
+        } else {
+            return $index;
+        }
+    }
+
+    /*!
+     * Sets/reverts all colors and styles to their defaults. If session is set, then only updates indices,
+     * as they are lost with every script execution, else, sets the default colors by name or value and
+     * then updates indices too.
+     *
+     * FIXME Isn't this too slow?
+     *
+     */
+    function SetDefaultStyles()
+    {
+        /* Some of the Set*() functions use default values when they get no parameters. */
+
+        if (! isset($this->session_set)) {
+            // If sessions are enabled, this variable will be preserved, so upon future executions, we
+            // will have it set, as well as color names (though not color indices, that's why we
+            // need to rebuild them)
+            $this->session_set = TRUE;
+
+            // These only need to be set once
+            $this->SetLineWidths();
+            $this->SetLineStyles();
+            $this->SetDefaultDashedStyle($this->dashed_style);
+            $this->SetPointSizes($this->point_sizes);
+        }
+
+        $this->SetImageBorderColor($this->i_border);
+        $this->SetPlotBgColor($this->plot_bg_color);
+        $this->SetBackgroundColor($this->bg_color);
+        $this->SetLabelColor($this->label_color);
+        $this->SetTextColor($this->text_color);
+        $this->SetGridColor($this->grid_color);
+        $this->SetLightGridColor($this->light_grid_color);
+        $this->SetTickColor($this->tick_color);
+        $this->SetTitleColor($this->title_color);
+        $this->SetDataColors();
+        $this->SetErrorBarColors();
+        $this->SetDataBorderColors();
+    }
+
+
+    /*
+     *
+     */
+    function SetBackgroundColor($which_color)
+    {
+        $this->bg_color= $which_color;
+        $this->ndx_bg_color= $this->SetIndexColor($this->bg_color);
+        return TRUE;
+    }
+
+    /*
+     *
+     */
+    function SetPlotBgColor($which_color)
+    {
+        $this->plot_bg_color= $which_color;
+        $this->ndx_plot_bg_color= $this->SetIndexColor($this->plot_bg_color);
+        return TRUE;
+    }
+
+   /*
+    *
+    */
+    function SetTitleColor($which_color)
+    {
+        $this->title_color= $which_color;
+        $this->ndx_title_color= $this->SetIndexColor($this->title_color);
+        return TRUE;
+    }
+
+    /*
+     *
+     */
+    function SetTickColor ($which_color)
+    {
+        $this->tick_color= $which_color;
+        $this->ndx_tick_color= $this->SetIndexColor($this->tick_color);
+        return TRUE;
+    }
+
+
+    /*
+     *
+     */
+    function SetLabelColor ($which_color)
+    {
+        $this->label_color = $which_color;
+        $this->ndx_title_color= $this->SetIndexColor($this->label_color);
+        return TRUE;
+    }
+
+
+    /*
+     *
+     */
+    function SetTextColor ($which_color)
+    {
+        $this->text_color= $which_color;
+        $this->ndx_text_color= $this->SetIndexColor($this->text_color);
+        return TRUE;
+    }
+
+
+    /*
+     *
+     */
+    function SetLightGridColor ($which_color)
+    {
+        $this->light_grid_color= $which_color;
+        $this->ndx_light_grid_color= $this->SetIndexColor($this->light_grid_color);
+        return TRUE;
+    }
+
+
+    /*
+     *
+     */
+    function SetGridColor ($which_color)
+    {
+        $this->grid_color = $which_color;
+        $this->ndx_grid_color= $this->SetIndexColor($this->grid_color);
+        return TRUE;
+    }
+
+
+    /*
+     *
+     */
+    function SetImageBorderColor($which_color)
+    {
+        $this->i_border = $which_color;
+        $this->ndx_i_border = $this->SetIndexColor($this->i_border);
+        $this->ndx_i_border_dark = $this->SetIndexDarkColor($this->i_border);
+        return TRUE;
+    }
+
+
+    /*
+     *
+     */
+    function SetTransparentColor($which_color)
+    {
+        ImageColorTransparent($this->img, $this->SetIndexColor($which_color));
+        return TRUE;
+    }
+
+
+    /*!
+     * Sets the array of colors to be used. It can be user defined, a small predefined one
+     * or a large one included from 'rgb.inc.php'.
+     *
+     * \param which_color_array If an array, the used as color array. If a string can
+     *        be one of 'small' or 'large'.
+     */
+    function SetRGBArray ($which_color_array)
+    {
+        if ( is_array($which_color_array) ) {           // User defined array
+            $this->rgb_array = $which_color_array;
+            return TRUE;
+        } elseif ($which_color_array == 'small') {      // Small predefined color array
+            $this->rgb_array = array(
+                'white'          => array(255, 255, 255),
+                'snow'           => array(255, 250, 250),
+                'PeachPuff'      => array(255, 218, 185),
+                'ivory'          => array(255, 255, 240),
+                'lavender'       => array(230, 230, 250),
+                'black'          => array(  0,   0,   0),
+                'DimGrey'        => array(105, 105, 105),
+                'gray'           => array(190, 190, 190),
+                'grey'           => array(190, 190, 190),
+                'navy'           => array(  0,   0, 128),
+                'SlateBlue'      => array(106,  90, 205),
+                'blue'           => array(  0,   0, 255),
+                'SkyBlue'        => array(135, 206, 235),
+                'cyan'           => array(  0, 255, 255),
+                'DarkGreen'      => array(  0, 100,   0),
+                'green'          => array(  0, 255,   0),
+                'YellowGreen'    => array(154, 205,  50),
+                'yellow'         => array(255, 255,   0),
+                'orange'         => array(255, 165,   0),
+                'gold'           => array(255, 215,   0),
+                'peru'           => array(205, 133,  63),
+                'beige'          => array(245, 245, 220),
+                'wheat'          => array(245, 222, 179),
+                'tan'            => array(210, 180, 140),
+                'brown'          => array(165,  42,  42),
+                'salmon'         => array(250, 128, 114),
+                'red'            => array(255,   0,   0),
+                'pink'           => array(255, 192, 203),
+                'maroon'         => array(176,  48,  96),
+                'magenta'        => array(255,   0, 255),
+                'violet'         => array(238, 130, 238),
+                'plum'           => array(221, 160, 221),
+                'orchid'         => array(218, 112, 214),
+                'purple'         => array(160,  32, 240),
+                'azure1'         => array(240, 255, 255),
+                'aquamarine1'    => array(127, 255, 212)
+                );
+            return TRUE;
+        } elseif ($which_color_array === 'large')  {    // Large color array
+            include("./rgb.inc.php");
+            $this->rgb_array = $RGBArray;
+        } else {                                        // Default to black and white only.
+            $this->rgb_array = array('white' => array(255, 255, 255), 'black' => array(0, 0, 0));
+        }
+
+        return TRUE;
+    }
+
+    /*!
+     * Returns an array in R, G, B format 0-255
+     *
+     *  \param color_asked array(R,G,B) or string (named color or '#AABBCC')
+     */
+    function SetRGBColor($color_asked)
+    {
+        if ($color_asked == '') { $color_asked = array(0, 0, 0); };
+
+        if ( count($color_asked) == 3 ) {    // already array of 3 rgb
+               $ret_val =  $color_asked;
+        } else {                             // asking for a color by string
+            if(substr($color_asked, 0, 1) == '#') {         // asking in #FFFFFF format.
+                $ret_val = array(hexdec(substr($color_asked, 1, 2)), hexdec(substr($color_asked, 3, 2)),
+                                  hexdec(substr($color_asked, 5, 2)));
+            } else {                                        // asking by color name
+                $ret_val = $this->rgb_array[$color_asked];
+            }
+        }
+        return $ret_val;
+    }
+
+
+    /*!
+     * Sets the colors for the data.
+     */
+    function SetDataColors($which_data = NULL, $which_border = NULL)
+    {
+        if (is_null($which_data) && is_array($this->data_colors)) {
+            // use already set data_colors
+        } else if (! is_array($which_data)) {
+            $this->data_colors = ($which_data) ? array($which_data) : array('blue', 'red', 'green', 'orange');
+        } else {
+            $this->data_colors = $which_data;
+        }
+
+        $i = 0;
+        foreach ($this->data_colors as $col) {
+            $this->ndx_data_colors[$i] = $this->SetIndexColor($col);
+            $this->ndx_data_dark_colors[$i] = $this->SetIndexDarkColor($col);
+            $i++;
+        }
+
+        // For past compatibility:
+        $this->SetDataBorderColors($which_border);
+    } // function SetDataColors()
+
+
+    /*!
+     *
+     */
+    function SetDataBorderColors($which_br = NULL)
+    {
+        if (is_null($which_br) && is_array($this->data_border_colors)) {
+            // use already set data_border_colors
+        } else if (! is_array($which_br)) {
+            // Create new array with specified color
+            $this->data_border_colors = ($which_br) ? array($which_br) : array('black');
+        } else {
+            $this->data_border_colors = $which_br;
+        }
+
+        $i = 0;
+        foreach($this->data_border_colors as $col) {
+            $this->ndx_data_border_colors[$i] = $this->SetIndexColor($col);
+            $i++;
+        }
+    } // function SetDataBorderColors()
+
+
+    /*!
+     * Sets the colors for the data error bars.
+     */
+    function SetErrorBarColors($which_err = NULL)
+    {
+        if (is_null($which_err) && is_array($this->error_bar_colors)) {
+            // use already set error_bar_colors
+        } else if (! is_array($which_err)) {
+            $this->error_bar_colors = ($which_err) ? array($which_err) : array('black');
+        } else {
+            $this->error_bar_colors = $which_err;
+        }
+
+        $i = 0;
+        foreach($this->error_bar_colors as $col) {
+            $this->ndx_error_bar_colors[$i] = $this->SetIndexColor($col);
+            $i++;
+        }
+        return TRUE;
+
+    } // function SetErrorBarColors()
+
+
+    /*!
+     * Sets the default dashed style.
+     *  \param which_style A string specifying order of colored and transparent dots,
+     *         i.e: '4-3' means 4 colored, 3 transparent;
+     *              '2-3-1-2' means 2 colored, 3 transparent, 1 colored, 2 transparent.
+     */
+    function SetDefaultDashedStyle($which_style)
+    {
+        // String: "numcol-numtrans-numcol-numtrans..."
+        $asked = explode('-', $which_style);
+
+        if (count($asked) < 2) {
+            $this->DrawError("SetDefaultDashedStyle(): Wrong parameter '$which_style'.");
+            return FALSE;
+        }
+
+        // Build the string to be eval()uated later by SetDashedStyle()
+        $this->default_dashed_style = 'array( ';
+
+        $t = 0;
+        foreach($asked as $s) {
+            if ($t % 2 == 0) {
+                $this->default_dashed_style .= str_repeat('$which_ndxcol,', $s);
+            } else {
+                $this->default_dashed_style .= str_repeat('IMG_COLOR_TRANSPARENT,', $s);
+            }
+            $t++;
+        }
+        // Remove trailing comma and add closing parenthesis
+        $this->default_dashed_style = substr($this->default_dashed_style, 0, -1);
+        $this->default_dashed_style .= ')';
+
+        return TRUE;
+    }
+
+
+    /*!
+     * Sets the style before drawing a dashed line. Defaults to $this->default_dashed_style
+     *   \param which_ndxcol Color index to be used.
+     */
+    function SetDashedStyle($which_ndxcol)
+    {
+        // See SetDefaultDashedStyle() to understand this.
+        eval ("\$style = $this->default_dashed_style;");
+        return imagesetstyle($this->img, $style);
+    }
+
+
+    /*!
+     * Sets line widths on a per-line basis.
+     */
+    function SetLineWidths($which_lw=NULL)
+    {
+        if (is_null($which_lw)) {
+            // Do nothing, use default value.
+        } else if (is_array($which_lw)) {
+            // Did we get an array with line widths?
+            $this->line_widths = $which_lw;
+        } else {
+            $this->line_widths = array($which_lw);
+        }
+        return TRUE;
+    }
+
+    /*!
+     *
+     */
+    function SetLineStyles($which_ls=NULL)
+    {
+        if (is_null($which_ls)) {
+            // Do nothing, use default value.
+        } else if ( is_array($which_ls)) {
+            // Did we get an array with line styles?
+            $this->line_styles = $which_ls;
+        } else {
+            $this->line_styles = ($which_ls) ? array($which_ls) : array('solid');
+        }
+        return TRUE;
+    }
+
+
+/////////////////////////////////////////////
+//////////////                          FONTS
+/////////////////////////////////////////////
+
+
+    /*!
+     * Sets number of pixels between lines of the same text.
+     */
+    function SetLineSpacing($which_spc)
+    {
+        $this->line_spacing = $which_spc;
+    }
+
+
+    /*!
+     * Enables use of TrueType fonts in the graph. Font initialisation methods
+     * depend on this setting, so when called, SetUseTTF() resets the font
+     * settings
+     */
+    function SetUseTTF($which_ttf)
+    {
+        $this->use_ttf = $which_ttf;
+        $this->SetDefaultFonts();
+        return TRUE;
+    }
+
+    /*!
+     * Sets the directory name to look into for TrueType fonts.
+     */
+    function SetTTFPath($which_path)
+    {
+        // Maybe someone needs really dynamic config. He'll need this:
+        // clearstatcache();
+
+        if (is_dir($which_path) && is_readable($which_path)) {
+            $this->ttf_path = $which_path;
+            return TRUE;
+        } else {
+            $this->PrintError("SetTTFPath(): $which_path is not a valid path.");
+            return FALSE;
+        }
+    }
+
+    /*!
+     * Sets the default TrueType font and updates all fonts to that.
+     * The default font might be a full path, or relative to the TTFPath,
+     * so let SetFont check that it exists.
+     * Side effect: enable use of TrueType fonts.
+     */
+    function SetDefaultTTFont($which_font)
+    {
+        $this->default_ttfont = $which_font;
+        $this->SetUseTTF(TRUE);
+        return TRUE;
+    }
+
+    /*!
+     * Sets fonts to their defaults
+     */
+    function SetDefaultFonts()
+    {
+        // TTF:
+        if ($this->use_ttf) {
+            $this->SetFont('generic', '', 8);
+            $this->SetFont('title', '', 14);
+            $this->SetFont('legend', '', 8);
+            $this->SetFont('x_label', '', 6);
+            $this->SetFont('y_label', '', 6);
+            $this->SetFont('x_title', '', 10);
+            $this->SetFont('y_title', '', 10);
+        }
+        // Fixed:
+        else {
+            $this->SetFont('generic', 2);
+            $this->SetFont('title', 5);
+            $this->SetFont('legend', 2);
+            $this->SetFont('x_label', 1);
+            $this->SetFont('y_label', 1);
+            $this->SetFont('x_title', 3);
+            $this->SetFont('y_title', 3);
+        }
+
+        return TRUE;
+    }
+
+    /*!
+     * Sets Fixed/Truetype font parameters.
+     *  \param $which_elem Is the element whose font is to be changed.
+     *         It can be one of 'title', 'legend', 'generic',
+     *         'x_label', 'y_label', x_title' or 'y_title'
+     *  \param $which_font Can be a number (for fixed font sizes) or
+     *         a string with the font pathname or filename when using TTFonts.
+     *         For TTFonts, an empty string means use the default font.
+     *  \param $which_size Point size (TTF only)
+     * Calculates and updates internal height and width variables.
+     */
+    function SetFont($which_elem, $which_font, $which_size = 12)
+    {
+        // TTF:
+        if ($this->use_ttf) {
+            // Empty font name means use the default font.
+            if (empty($which_font))
+                $which_font = $this->default_ttfont;
+            $path = $which_font;
+
+            // First try the font name directly, if not then try with path.
+            if (!is_file($path) || !is_readable($path)) {
+                $path = $this->ttf_path . '/' . $which_font;
+                if (!is_file($path) || !is_readable($path)) {
+                    $this->DrawError("SetFont(): Can't find TrueType font $which_font");
+                    return FALSE;
+                }
+            }
+
+            switch ($which_elem) {
+            case 'generic':
+                $this->generic_font['font'] = $path;
+                $this->generic_font['size'] = $which_size;
+                break;
+            case 'title':
+                $this->title_font['font'] = $path;
+                $this->title_font['size'] = $which_size;
+                break;
+            case 'legend':
+                $this->legend_font['font'] = $path;
+                $this->legend_font['size'] = $which_size;
+                break;
+            case 'x_label':
+                $this->x_label_font['font'] = $path;
+                $this->x_label_font['size'] = $which_size;
+                break;
+            case 'y_label':
+                $this->y_label_font['font'] = $path;
+                $this->y_label_font['size'] = $which_size;
+                break;
+            case 'x_title':
+                $this->x_title_font['font'] = $path;
+                $this->x_title_font['size'] = $which_size;
+                break;
+            case 'y_title':
+                $this->y_title_font['font'] = $path;
+                $this->y_title_font['size'] = $which_size;
+                break;
+            default:
+                $this->DrawError("SetFont(): Unknown element '$which_elem' specified.");
+                return FALSE;
+            }
+            return TRUE;
+
+        }
+
+        // Fixed fonts:
+        if ($which_font > 5 || $which_font < 0) {
+            $this->DrawError('SetFont(): Non-TTF font size must be 1, 2, 3, 4 or 5');
+            return FALSE;
+        }
+
+        switch ($which_elem) {
+        case 'generic':
+            $this->generic_font['font'] = $which_font;
+            $this->generic_font['height'] = ImageFontHeight($which_font);
+            $this->generic_font['width'] = ImageFontWidth($which_font);
+            break;
+        case 'title':
+           $this->title_font['font'] = $which_font;
+           $this->title_font['height'] = ImageFontHeight($which_font);
+           $this->title_font['width'] = ImageFontWidth($which_font);
+           break;
+        case 'legend':
+            $this->legend_font['font'] = $which_font;
+            $this->legend_font['height'] = ImageFontHeight($which_font);
+            $this->legend_font['width'] = ImageFontWidth($which_font);
+            break;
+        case 'x_label':
+            $this->x_label_font['font'] = $which_font;
+            $this->x_label_font['height'] = ImageFontHeight($which_font);
+            $this->x_label_font['width'] = ImageFontWidth($which_font);
+            break;
+        case 'y_label':
+            $this->y_label_font['font'] = $which_font;
+            $this->y_label_font['height'] = ImageFontHeight($which_font);
+            $this->y_label_font['width'] = ImageFontWidth($which_font);
+            break;
+        case 'x_title':
+            $this->x_title_font['font'] = $which_font;
+            $this->x_title_font['height'] = ImageFontHeight($which_font);
+            $this->x_title_font['width'] = ImageFontWidth($which_font);
+            break;
+        case 'y_title':
+            $this->y_title_font['font'] = $which_font;
+            $this->y_title_font['height'] = ImageFontHeight($which_font);
+            $this->y_title_font['width'] = ImageFontWidth($which_font);
+            break;
+        default:
+            $this->DrawError("SetFont(): Unknown element '$which_elem' specified.");
+            return FALSE;
+        }
+        return TRUE;
+    }
+
+
+    /*!
+     * Returns an array with the size of the bounding box of an
+     * arbitrarily placed (rotated) TrueType text string.
+     */
+    function TTFBBoxSize($size, $angle, $font, $string)
+    {
+        // First, assume angle < 90
+        $arr = ImageTTFBBox($size, 0, $font, $string);
+        $flat_width  = $arr[2] - $arr[0];
+        $flat_height = abs($arr[3] - $arr[5]);
+
+        // Now the bounding box
+        $angle = deg2rad($angle);
+        $width  = ceil(abs($flat_width*cos($angle) + $flat_height*sin($angle))); //Must be integer
+        $height = ceil(abs($flat_width*sin($angle) + $flat_height*cos($angle))); //Must be integer
+
+        return array($width, $height);
+    }
+
+
+    /*!
+     * Draws a string of text. Horizontal and vertical alignment are relative to
+     * to the drawing. That is: vertical text (90 deg) gets centered along y-axis
+     * with v_align = 'center', and adjusted to the left of x-axis with h_align = 'right',
+     *
+     * \note Original multiple lines code submitted by Remi Ricard.
+     * \note Original vertical code submitted by Marlin Viss.
+     */
+    function DrawText($which_font, $which_angle, $which_xpos, $which_ypos, $which_color, $which_text,
+                      $which_halign = 'left', $which_valign = 'bottom')
+    {
+        // TTF:
+        if ($this->use_ttf) {
+            $size = $this->TTFBBoxSize($which_font['size'], $which_angle, $which_font['font'], $which_text);
+            $rads = deg2rad($which_angle);
+
+            if ($which_valign == 'center')
+                $which_ypos += $size[1]/2;
+
+            if ($which_valign == 'bottom')
+                $which_ypos += $size[1];
+
+            if ($which_halign == 'center')
+                $which_xpos -= ($size[0]/2) * cos($rads);
+
+            if ($which_halign == 'left')
+                $which_xpos += $size[0] * sin($rads);
+
+            if ($which_halign == 'right')
+                $which_xpos -= $size[0] * cos($rads);
+
+            ImageTTFText($this->img, $which_font['size'], $which_angle,
+                         $which_xpos, $which_ypos, $which_color, $which_font['font'], $which_text);
+        }
+        // Fixed fonts:
+        else {
+            // Split the text by its lines, and count them
+            $which_text = ereg_replace("\r", "", $which_text);
+            $str = split("\n", $which_text);
+            $nlines = count($str);
+            $spacing = $this->line_spacing * ($nlines - 1);
+
+            // Vertical text:
+            // (Remember the alignment convention with vertical text)
+            if ($which_angle == 90) {
+                // The text goes around $which_xpos.
+                if ($which_halign == 'center')
+                    $which_xpos -= ($nlines * ($which_font['height'] + $spacing))/2;
+
+                // Left alignment requires no modification to $xpos...
+                // Right-align it. $which_xpos designated the rightmost x coordinate.
+                else if ($which_halign == 'right')
+                    $which_xpos += ($nlines * ($which_font['height'] + $spacing));
+
+                $ypos = $which_ypos;
+                for($i = 0; $i < $nlines; $i++) {
+                    // Center the text vertically around $which_ypos (each line)
+                    if ($which_valign == 'center')
+                        $ypos = $which_ypos + (strlen($str[$i]) * $which_font['width']) / 2;
+                    // Make the text finish (vertically) at $which_ypos
+                    if ($which_valign == 'bottom')
+                        $ypos = $which_ypos + strlen($str[$i]) * $which_font['width'];
+
+                    ImageStringUp($this->img, $which_font['font'],
+                                  $i * ($which_font['height'] + $spacing) + $which_xpos,
+                                  $ypos, $str[$i], $which_color);
+                }
+            }
+            // Horizontal text:
+            else {
+                // The text goes above $which_ypos
+                if ($which_valign == 'top')
+                    $which_ypos -= $nlines * ($which_font['height'] + $spacing);
+                // The text is centered around $which_ypos
+                if ($which_valign == 'center')
+                    $which_ypos -= ($nlines * ($which_font['height'] + $spacing))/2;
+                // valign = 'bottom' requires no modification
+
+                $xpos = $which_xpos;
+                for($i = 0; $i < $nlines; $i++) {
+                    // center the text around $which_xpos
+                    if ($which_halign == 'center')
+                        $xpos = $which_xpos - (strlen($str[$i]) * $which_font['width'])/2;
+                    // make the text finish at $which_xpos
+                    if ($which_halign == 'right')
+                        $xpos = $which_xpos - strlen($str[$i]) * $which_font['width'];
+
+                    ImageString($this->img, $which_font['font'], $xpos,
+                                $i * ($which_font['height'] + $spacing) + $which_ypos,
+                                $str[$i], $which_color);
+                }
+            }
+        }
+        return TRUE;
+    } // function DrawText()
+
+
+/////////////////////////////////////////////
+///////////            INPUT / OUTPUT CONTROL
+/////////////////////////////////////////////
+
+    /*!
+     * Sets output file format.
+     */
+    function SetFileFormat($format)
+    {
+        $asked = $this->CheckOption($format, 'jpg, png, gif, wbmp', __FUNCTION__);
+
+        switch ($asked) {
+        case 'jpg':
+            if (imagetypes() & IMG_JPG)
+                $this->file_format = 'jpg';
+                return TRUE;
+            break;
+        case 'png':
+            if (imagetypes() & IMG_PNG)
+                $this->file_format = 'png';
+                return TRUE;
+            break;
+        case 'gif':
+            if (imagetypes() & IMG_GIF)
+                $this->file_format = 'gif';
+                return TRUE;
+            break;
+        case 'wbmp':
+            if (imagetypes() & IMG_WBMP)
+                $this->file_format = 'wbmp';
+                return TRUE;
+            break;
+        default:
+            $this->PrintError("SetFileFormat():File format '$format' not supported");
+            return FALSE;
+        }
+    }
+
+
+    /*!
+     * Selects an input file to be used as graph background and scales or tiles this image
+     * to fit the sizes.
+     *  \param input_file string Path to the file to be used (jpeg, png and gif accepted)
+     *  \param mode       string 'centeredtile', 'tile', 'scale' (the image to the graph's size)
+     */
+    function SetBgImage($input_file, $mode='centeredtile')
+    {
+        $this->bgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
+        $this->bgimg  = $input_file;
+    }
+
+    /*!
+     * Selects an input file to be used as plot area background and scales or tiles this image
+     * to fit the sizes.
+     *  \param input_file string Path to the file to be used (jpeg, png and gif accepted)
+     *  \param mode       string 'centeredtile', 'tile', 'scale' (the image to the graph's size)
+     */
+    function SetPlotAreaBgImage($input_file, $mode='tile')
+    {
+        $this->plotbgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
+        $this->plotbgimg  = $input_file;
+    }
+
+
+    /*!
+     * Sets the name of the file to be used as output file.
+     */
+    function SetOutputFile($which_output_file)
+    {
+        $this->output_file = $which_output_file;
+        return TRUE;
+    }
+
+    /*!
+     * Sets the output image as 'inline', that is: no Content-Type headers are sent
+     * to the browser. Needed if you want to embed the images.
+     */
+    function SetIsInline($which_ii)
+    {
+        $this->is_inline = (bool)$which_ii;
+        return TRUE;
+    }
+
+
+    /*!
+     * Performs the actual outputting of the generated graph, and
+     * destroys the image resource.
+     */
+    function PrintImage()
+    {
+        // Browser cache stuff submitted by Thiemo Nagel
+        if ( (! $this->browser_cache) && (! $this->is_inline)) {
+            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT');
+            header('Cache-Control: no-cache, must-revalidate');
+            header('Pragma: no-cache');
+        }
+
+        switch($this->file_format) {
+        case 'png':
+            if (! $this->is_inline) {
+                Header('Content-type: image/png');
+            }
+            if ($this->is_inline && $this->output_file != '') {
+                ImagePng($this->img, $this->output_file);
+            } else {
+                ImagePng($this->img);
+            }
+            break;
+        case 'jpg':
+            if (! $this->is_inline) {
+                Header('Content-type: image/jpeg');
+            }
+            if ($this->is_inline && $this->output_file != '') {
+                ImageJPEG($this->img, $this->output_file);
+            } else {
+                ImageJPEG($this->img);
+            }
+            break;
+        case 'gif':
+            if (! $this->is_inline) {
+                Header('Content-type: image/gif');
+            }
+            if ($this->is_inline && $this->output_file != '') {
+                ImageGIF($this->img, $this->output_file);
+            } else {
+                ImageGIF($this->img);
+            }
+
+            break;
+        case 'wbmp':        // wireless bitmap, 2 bit.
+            if (! $this->is_inline) {
+                Header('Content-type: image/wbmp');
+            }
+            if ($this->is_inline && $this->output_file != '') {
+                ImageWBMP($this->img, $this->output_file);
+            } else {
+                ImageWBMP($this->img);
+            }
+
+            break;
+        default:
+            $this->PrintError('PrintImage(): Please select an image type!');
+            break;
+        }
+        return TRUE;
+    }
+
+    /*!
+     * Prints an error message to stdout and dies
+     */
+    function PrintError($error_message)
+    {
+        echo "<p><b>Fatal error</b>: $error_message<p>";
+        die;
+    }
+
+    /*!
+     * Prints an error message inline into the generated image and draws it centered
+     * around the given coordinates (defaults to center of the image)
+     *   \param error_message Message to be drawn
+     *   \param where_x       X coordinate
+     *   \param where_y       Y coordinate
+     */
+    function DrawError($error_message, $where_x = NULL, $where_y = NULL)
+    {
+        if (! $this->img)
+            $this->PrintError('_DrawError(): Warning, no image resource allocated. '.
+                              'The message to be written was: '.$error_message);
+
+        $ypos = (! $where_y) ? $this->image_height/2 : $where_y;
+        $xpos = (! $where_x) ? $this->image_width/2 : $where_x;
+        ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height,
+                       ImageColorAllocate($this->img, 255, 255, 255));
+
+        // Switch to built-in fonts, in case of error with TrueType fonts:
+        $this->SetUseTTF(FALSE);
+
+        $this->DrawText($this->generic_font, 0, $xpos, $ypos, ImageColorAllocate($this->img, 0, 0, 0),
+                        wordwrap($error_message), 'center', 'center');
+
+        $this->PrintImage();
+        exit;
+//        return TRUE;
+    }
+
+/////////////////////////////////////////////
+///////////                            LABELS
+/////////////////////////////////////////////
+
+
+    /*!
+     * Sets position for X labels following data points.
+     */
+    function SetXDataLabelPos($which_xdlp)
+    {
+        $this->x_data_label_pos = $this->CheckOption($which_xdlp, 'plotdown, plotup, both, xaxis, all, none',
+                                                      __FUNCTION__);
+        if ($which_xdlp != 'none')
+            $this->x_tick_label_pos = 'none';
+
+        return TRUE;
+    }
+
+    /*!
+     * Sets position for Y labels near data points.
+     * For past compatability we accept plotleft, ...but pass it to SetTickLabelPos
+     * eventually to specify how far up/down or left/right of the data point
+     */
+    function SetYDataLabelPos($which_ydlp, $which_distance_from_point=0)
+    {
+        $this->y_data_label_pos = $this->CheckOption($which_ydlp, 'plotleft, plotright, both, yaxis, all, plotin, none',
+                                                      __FUNCTION__);
+        //This bit in SetYDataLabelPos about plotleft is for those who were 
+        //using this function to set SetYTickLabelPos.
+        if ( ($which_ydlp == 'plotleft') || ($which_ydlp == 'plotright') || 
+             ($which_ydlp == 'both') || ($which_ydlp == 'yaxis') ) { 
+
+            //Call sety_TICK_labelpos instead of sety_DATA_labelpos
+            $this->SetYTickLabelPos($which_ydlp);
+
+        } elseif ($which_ydlp != 'none') { 
+            //right now its plotin or none
+            $this->y_data_label_pos = 'plotin';
+        }
+
+        return TRUE;
+    }
+
+
+    /*!
+     * Sets position for X labels following ticks (hence grid lines)
+     */
+    function SetXTickLabelPos($which_xtlp)
+    {
+        $this->x_tick_label_pos = $this->CheckOption($which_xtlp, 'plotdown, plotup, both, xaxis, all, none',
+                                                      __FUNCTION__);
+        if ($which_xtlp != 'none')
+            $this->x_data_label_pos = 'none';
+
+        return TRUE;
+    }
+
+    /*!
+     * Sets position for Y labels following ticks (hence grid lines)
+     */
+    function SetYTickLabelPos($which_ytlp)
+    {
+        $this->y_tick_label_pos = $this->CheckOption($which_ytlp, 'plotleft, plotright, both, yaxis, all, none',
+                                                      __FUNCTION__);
+        return TRUE;
+    }
+
+    /*!
+     * Sets type for tick and data labels on X axis.
+     * \note 'title' type left for backwards compatibility.
+     */
+    function SetXLabelType($which_xlt)
+    {
+        $this->x_label_type = $this->CheckOption($which_xlt, 'data, time, title', __FUNCTION__);
+        return TRUE;
+    }
+
+    /*!
+     * Sets type for tick and data labels on Y axis.
+     */
+    function SetYLabelType($which_ylt)
+    {
+        $this->y_label_type = $this->CheckOption($which_ylt, 'data, time', __FUNCTION__);
+        return TRUE;
+    }
+
+    function SetXTimeFormat($which_xtf)
+    {
+        $this->x_time_format = $which_xtf;
+        return TRUE;
+    }
+    function SetYTimeFormat($which_ytf)
+    {
+        $this->y_time_format = $which_ytf;
+        return TRUE;
+    }
+
+    function SetXLabelAngle($which_xla)
+    {
+        $this->x_label_angle = $which_xla;
+        return TRUE;
+    }
+
+    function SetYLabelAngle($which_yla)
+    {
+        $this->y_label_angle = $which_yla;
+        return TRUE;
+    }
+
+/////////////////////////////////////////////
+///////////                              MISC
+/////////////////////////////////////////////
+
+    /*!
+     * Checks the valididy of an option.
+     *  \param which_opt  String to check.
+     *  \param which_acc  String of accepted choices.
+     *  \param which_func Name of the calling function, for error messages.
+     *  \note If checking everywhere for correctness slows things down, we could provide a
+     *        child class overriding every Set...() method which uses CheckOption(). Those new
+     *        methods could proceed in the unsafe but faster way.
+     */
+    function CheckOption($which_opt, $which_acc, $which_func)
+    {
+        $asked = trim($which_opt);
+
+        // FIXME: this for backward compatibility, as eregi() fails with empty strings.
+        if ($asked == '')
+            return '';
+
+        $asked = strtolower($asked);
+        if (@ eregi($asked, $which_acc)) {
+            return $asked;
+        } else {
+            $this->DrawError("$which_func(): '$which_opt' not in available choices: '$which_acc'.");
+            return NULL;
+        }
+    }
+
+
+    /*!
+     *  \note Submitted by Thiemo Nagel
+     */
+    function SetBrowserCache($which_browser_cache)
+    {
+        $this->browser_cache = $which_browser_cache;
+        return TRUE;
+    }
+
+    /*!
+     * Whether to show the final image or not
+     */
+    function SetPrintImage($which_pi)
+    {
+        $this->print_image = $which_pi;
+        return TRUE;
+    }
+
+    /*!
+     * Sets the graph's legend. If argument is not an array, appends it to the legend.
+     */
+    function SetLegend($which_leg)
+    {
+        if (is_array($which_leg)) {             // use array
+            $this->legend = $which_leg;
+            return TRUE;
+        } else if (! is_null($which_leg)) {     // append string
+            $this->legend[] = $which_leg;
+            return TRUE;
+        } else {
+            $this->DrawError("SetLegend(): argument must not be null.");
+            return FALSE;
+        }
+    }
+
+    /*!
+     * Specifies the absolute (relative to image's up/left corner) position
+     * of the legend's upper/leftmost corner.
+     *  $which_type not yet used (TODO)
+     */
+    function SetLegendPixels($which_x, $which_y, $which_type=NULL)
+    {
+        $this->legend_x_pos = $which_x;
+        $this->legend_y_pos = $which_y;
+
+        return TRUE;
+    }
+
+    /*!
+     * Specifies the relative (to graph's origin) position of the legend's
+     * upper/leftmost corner. MUST be called after scales are set up.
+     *   $which_type not yet used (TODO)
+     */
+    function SetLegendWorld($which_x, $which_y, $which_type=NULL)
+    {
+        if (! isset($this->scale_is_set))
+            $this->CalcTranslation();
+
+        $this->legend_x_pos = $this->xtr($which_x);
+        $this->legend_y_pos = $this->ytr($which_y);
+
+        return TRUE;
+    }
+
+    /*!
+     * Accepted values are: left, sides, none, full
+     */
+    function SetPlotBorderType($pbt)
+    {
+        $this->plot_border_type = $this->CheckOption($pbt, 'left, sides, none, full', __FUNCTION__);
+    }
+
+    /*!
+     * Accepted values are: raised, plain
+     */
+    function SetImageBorderType($sibt)
+    {
+        $this->image_border_type = $this->CheckOption($sibt, 'raised, plain', __FUNCTION__);
+    }
+
+
+    /*!
+     * \param dpab bool
+     */
+    function SetDrawPlotAreaBackground($dpab)
+    {
+        $this->draw_plot_area_background = (bool)$dpab;
+    }
+
+
+    /*!
+     * \param dyg bool
+     */
+    function SetDrawYGrid($dyg)
+    {
+        $this->draw_y_grid = (bool)$dyg;
+        return TRUE;
+    }
+
+
+    /*!
+     * \param dxg bool
+     */
+    function SetDrawXGrid($dxg)
+    {
+        $this->draw_x_grid = (bool)$dxg;
+        return TRUE;
+    }
+
+
+    /*!
+     * \param ddg bool
+     */
+    function SetDrawDashedGrid($ddg)
+    {
+        $this->dashed_grid = (bool)$ddg;
+        return TRUE;
+    }
+
+
+    /*!
+     * \param dxdl bool
+     */
+    function SetDrawXDataLabelLines($dxdl)
+    {
+        $this->draw_x_data_label_lines = (bool)$dxdl;
+        return TRUE;
+    }
+
+
+    /*!
+     * TODO: draw_y_data_label_lines not implemented.
+     * \param dydl bool
+     */
+    function SetDrawYDataLabelLines($dydl)
+    {
+        $this->draw_y_data_label_lines = $dydl;
+        return TRUE;
+    }
+
+    /*!
+     * Sets the graph's title.
+     * TODO: add parameter to choose title placement: left, right, centered=
+     */
+    function SetTitle($which_title)
+    {
+        $this->title_txt = $which_title;
+
+        if ($which_title == '') {
+            $this->title_height = 0;
+            return TRUE;
+        }
+
+        $str = split("\n", $which_title);
+        $lines = count($str);
+        $spacing = $this->line_spacing * ($lines - 1);
+
+        if ($this->use_ttf) {
+            $size = $this->TTFBBoxSize($this->title_font['size'], 0, $this->title_font['font'], $which_title);
+            $this->title_height = $size[1] * $lines;
+        } else {
+            $this->title_height = ($this->title_font['height'] + $spacing) * $lines;
+        }
+        return TRUE;
+    }
+
+    /*!
+     * Sets the X axis title and position.
+     */
+    function SetXTitle($which_xtitle, $which_xpos = 'plotdown')
+    {
+        if ($which_xtitle == '')
+            $which_xpos = 'none';
+
+        $this->x_title_pos = $this->CheckOption($which_xpos, 'plotdown, plotup, both, none', __FUNCTION__);
+
+        $this->x_title_txt = $which_xtitle;
+
+        $str = split("\n", $which_xtitle);
+        $lines = count($str);
+        $spacing = $this->line_spacing * ($lines - 1);
+
+        if ($this->use_ttf) {
+            $size = $this->TTFBBoxSize($this->x_title_font['size'], 0, $this->x_title_font['font'], $which_xtitle);
+            $this->x_title_height = $size[1] * $lines;
+        } else {
+            $this->x_title_height = ($this->x_title_font['height'] + $spacing) * $lines;
+        }
+
+        return TRUE;
+    }
+
+
+    /*!
+     * Sets the Y axis title and position.
+     */
+    function SetYTitle($which_ytitle, $which_ypos = 'plotleft')
+    {
+        if ($which_ytitle == '')
+            $which_ypos = 'none';
+
+        $this->y_title_pos = $this->CheckOption($which_ypos, 'plotleft, plotright, both, none', __FUNCTION__);
+
+        $this->y_title_txt = $which_ytitle;
+
+        $str = split("\n", $which_ytitle);
+        $lines = count($str);
+        $spacing = $this->line_spacing * ($lines - 1);
+
+        if ($this->use_ttf) {
+            $size = $this->TTFBBoxSize($this->y_title_font['size'], 90, $this->y_title_font['font'],
+                                       $which_ytitle);
+            $this->y_title_width = $size[0] * $lines;
+        } else {
+            $this->y_title_width = ($this->y_title_font['height'] + $spacing) * $lines;
+        }
+
+        return TRUE;
+    }
+
+    /*!
+     * Sets the size of the drop shadow for bar and pie charts.
+     * \param which_s int Size in pixels.
+     */
+    function SetShading($which_s)
+    {
+        $this->shading = (int)$which_s;
+        return TRUE;
+    }
+
+    function SetPlotType($which_pt)
+    {
+        $this->plot_type = $this->CheckOption($which_pt,
+                           'bars, stackedbars, lines, linepoints, area, points, pie, thinbarline, squared',
+                            __FUNCTION__);
+    }
+
+    /*!
+     * Sets the position of Y axis.
+     * \param pos int Position in world coordinates.
+     */
+    function SetYAxisPosition($pos)
+    {
+        $this->y_axis_position = (int)$pos;
+        if (isset($this->scale_is_set)) {
+            $this->CalcTranslation();
+        }
+        return TRUE;
+    }
+
+    /*!
+     * Sets the position of X axis.
+     * \param pos int Position in world coordinates.
+     */
+    function SetXAxisPosition($pos)
+    {
+        $this->x_axis_position = (int)$pos;
+        if (isset($this->scale_is_set)) {
+            $this->CalcTranslation();
+        }
+        return TRUE;
+    }
+
+
+    function SetXScaleType($which_xst)
+    {
+        $this->xscale_type = $this->CheckOption($which_xst, 'linear, log', __FUNCTION__);
+        return TRUE;
+    }
+
+    function SetYScaleType($which_yst)
+    {
+        $this->yscale_type = $this->CheckOption($which_yst, 'linear, log',  __FUNCTION__);
+        return TRUE;
+    }
+
+    function SetPrecisionX($which_prec)
+    {
+        $this->x_precision = $which_prec;
+        $this->SetXLabelType('data');
+        return TRUE;
+    }
+
+    function SetPrecisionY($which_prec)
+    {
+        $this->y_precision = $which_prec;
+        $this->SetYLabelType('data');
+        return TRUE;
+    }
+
+    function SetErrorBarLineWidth($which_seblw)
+    {
+        $this->error_bar_line_width = $which_seblw;
+        return TRUE;
+    }
+
+    function SetLabelScalePosition($which_blp)
+    {
+        //0 to 1
+        $this->label_scale_position = $which_blp;
+        return TRUE;
+    }
+
+    function SetErrorBarSize($which_ebs)
+    {
+        //in pixels
+        $this->error_bar_size = $which_ebs;
+        return TRUE;
+    }
+
+    /*!
+     * Can be one of: 'tee', 'line'
+     */
+    function SetErrorBarShape($which_ebs)
+    {
+        $this->error_bar_shape = $this->CheckOption($which_ebs, 'tee, line', __FUNCTION__);
+    }
+
+    /*!
+     * Sets point shape for each data set via an array.
+     * Shape can be one of: 'halfline', 'line', 'plus', 'cross', 'rect', 'circle', 'dot',
+     * 'diamond', 'triangle', 'trianglemid', or 'none'.
+     */
+    function SetPointShapes($which_pt)
+    {
+        if (is_null($which_pt)) {
+            // Do nothing, use default value.
+        } else if (is_array($which_pt)) {
+            // Did we get an array with point shapes?
+            $this->point_shapes = $which_pt;
+        } else {
+            // Single value into array
+            $this->point_shapes = array($which_pt);
+        }
+
+        foreach ($this->point_shapes as $shape)
+        {
+            // TODO, better check, per element rectification
+            $this->CheckOption($shape,
+               'halfline, line, plus, cross, rect, circle, dot, diamond, triangle, trianglemid, none',
+                __FUNCTION__);
+        }
+
+        // Make both point_shapes and point_sizes same size.
+        $ps = count($this->point_sizes);
+        $pt = count($this->point_shapes);
+
+        if ($ps < $pt) {
+            array_pad_array($this->point_sizes, $pt);
+        } else if ($pt > $ps) {
+            array_pad_array($this->point_shapes, $ps);
+        }
+        return TRUE;
+    }
+
+    /*!
+     * Sets the point size for point plots.
+     * \param ps int Size in pixels.
+     * \note Test this more extensively
+     */
+    function SetPointSizes($which_ps)
+    {
+        if (is_null($which_ps)) {
+            // Do nothing, use default value.
+        } else if (is_array($which_ps)) {
+            // Did we get an array with point sizes?
+            $this->point_sizes = $which_ps;
+        } else {
+            // Single value into array
+            $this->point_sizes = array($which_ps);
+        }
+
+        // Make both point_shapes and point_sizes same size.
+        $ps = count($this->point_sizes);
+        $pt = count($this->point_shapes);
+
+        if ($ps < $pt) {
+            array_pad_array($this->point_sizes, $pt);
+        } else if ($pt > $ps) {
+            array_pad_array($this->point_shapes, $ps);
+        }
+
+        // Fix odd point sizes for point shapes which need it
+        for ($i = 0; $i < $pt; $i++) {
+            if ($this->point_shapes[$i] == 'diamond' or $this->point_shapes[$i] == 'triangle') {
+                if ($this->point_sizes[$i] % 2 != 0) {
+                    $this->point_sizes[$i]++;
+                }
+            }
+        }
+        return TRUE;
+    }
+
+
+    /*!
+     * Tells not to draw lines for missing Y data. Only works with 'lines' and 'squared' plots.
+     * \param bl bool
+     */
+    function SetDrawBrokenLines($bl)
+    {
+        $this->draw_broken_lines = (bool)$bl;
+    }
+
+
+    /*!
+     *  text-data: ('label', y1, y2, y3, ...)
+     *  text-data-single: ('label', data), for some pie charts.
+     *  data-data: ('label', x, y1, y2, y3, ...)
+     *  data-data-error: ('label', x1, y1, e1+, e2-, y2, e2+, e2-, y3, e3+, e3-, ...)
+     */
+    function SetDataType($which_dt)
+    {
+        //The next four lines are for past compatibility.
+        if ($which_dt == 'text-linear') { $which_dt = 'text-data'; };
+        if ($which_dt == 'linear-linear') { $which_dt = 'data-data'; };
+        if ($which_dt == 'linear-linear-error') { $which_dt = 'data-data-error'; };
+        if ($which_dt == 'text-data-pie') { $which_dt = 'text-data-single'; }
+
+
+        $this->data_type = $this->CheckOption($which_dt, 'text-data, text-data-single, '.
+                                                         'data-data, data-data-error', __FUNCTION__);
+        return TRUE;
+    }
+
+    /*!
+     * Copy the array passed as data values. We convert to numerical indexes, for its
+     * use for (or while) loops, which sometimes are faster. Performance improvements
+     * vary from 28% in DrawLines() to 49% in DrawArea() for plot drawing functions.
+     */
+    function SetDataValues(&$which_dv)
+    {
+        unset ($this->data_limits_done);        // Reset this for every new data_set
+        $this->num_data_rows = count($which_dv);
+        $this->total_records = 0;               // Perform some useful calculations.
+        $this->records_per_group = 1;
+        for ($i = 0, $recs = 0; $i < $this->num_data_rows; $i++) {
+            // Copy
+            $this->data[$i] = array_values($which_dv[$i]);   // convert to numerical indices.
+
+            // Compute some values
+            $recs = count($this->data[$i]);
+            $this->total_records += $recs;
+
+            if ($recs > $this->records_per_group)
+                $this->records_per_group = $recs;
+
+            $this->num_recs[$i] = $recs;
+        }
+    }
+
+    /*!
+     * Pad styles arrays for later use by plot drawing functions:
+     * This removes the need for $max_data_colors, etc. and $color_index = $color_index % $max_data_colors
+     * in DrawBars(), DrawLines(), etc.
+     */
+    function PadArrays()
+    {
+        array_pad_array($this->line_widths, $this->records_per_group);
+        array_pad_array($this->line_styles, $this->records_per_group);
+
+        array_pad_array($this->data_colors, $this->records_per_group);
+        array_pad_array($this->data_border_colors, $this->records_per_group);
+        array_pad_array($this->error_bar_colors, $this->records_per_group);
+
+        $this->SetDataColors();
+        $this->SetDataBorderColors();
+        $this->SetErrorBarColors();
+
+        return TRUE;
+    }
+
+
+//////////////////////////////////////////////////////////
+///////////         DATA ANALYSIS, SCALING AND TRANSLATION
+//////////////////////////////////////////////////////////
+
+    /*!
+     * Analizes data and sets up internal maxima and minima
+     * Needed by: CalcMargins(), ...
+     *   Text-Data is different than data-data graphs. For them what
+     *   we have, instead of X values, is # of records equally spaced on data.
+     *   text-data is passed in as $data[] = (title, y1, y2, y3, y4, ...)
+     *   data-data is passed in as $data[] = (title, x, y1, y2, y3, y4, ...)
+     */
+    function FindDataLimits()
+    {
+        // Set some default min and max values before running through the data
+        switch ($this->data_type) {
+        case 'text-data':
+        case 'text-data-single':
+            $minx = 0;
+            $maxx = $this->num_data_rows - 1 ;
+            $miny = $this->data[0][1];
+            $maxy = $miny;
+            break;
+        default:  //Everything else: data-data, etc, take first value
+            $minx = $this->data[0][1];
+            $maxx = $minx;
+            $miny = $this->data[0][2];
+            $maxy = $miny;
+            break;
+        }
+
+        $mine = 0;  // Maximum value for the -error bar (assume error bars always > 0)
+        $maxe = 0;  // Maximum value for the +error bar (assume error bars always > 0)
+        $maxt = 0;  // Maximum number of characters in text labels
+
+        if ($this->plot_type == 'stackedbars') {
+            $maxmaxy = $minminy = 0;
+        } else {
+            $minminy = $miny;
+            $maxmaxy = $maxy;
+        }
+
+        // Process each row of data
+        for ($i=0; $i < $this->num_data_rows; $i++) {
+            $j=0;
+            // Extract maximum text label length
+            $val = @ strlen($this->data[$i][$j++]);
+            $maxt = ($val > $maxt) ? $val : $maxt;
+
+            switch ($this->data_type) {
+            case 'text-data':           // Data is passed in as (title, y1, y2, y3, ...)
+            case 'text-data-single':    // This one is for some pie charts
+                // $numrecs = @ count($this->data[$i]);
+                $maxy = (double)$this->data[$i][$j++];
+                if ($this->plot_type == 'stackedbars') {
+                    $miny = 0;
+                } else {
+                    $miny = $maxy;
+                }
+                for (; $j < $this->num_recs[$i]; $j++) {
+                    $val = (double)$this->data[$i][$j];
+                    if ($this->plot_type == 'stackedbars') {
+                        $maxy += abs($val);      // only positive values for the moment
+                    } else {
+                        $maxy = ($val > $maxy) ? $val : $maxy;
+                        $miny = ($val < $miny) ? $val : $miny;
+                    }
+                }
+                break;
+            case 'data-data':           // Data is passed in as (title, x, y, y2, y3, ...)
+                // X value:
+                $val = (double)$this->data[$i][$j++];
+                $maxx = ($val > $maxx) ? $val : $maxx;
+                $minx = ($val < $minx) ? $val : $minx;
+
+                $miny = $maxy = (double)$this->data[$i][$j++];
+                // $numrecs = @ count($this->data[$i]);
+                for (; $j < $this->num_recs[$i]; $j++) {
+                    $val = (double)$this->data[$i][$j];
+                    $maxy = ($val > $maxy) ? $val : $maxy;
+                    $miny = ($val < $miny) ? $val : $miny;
+                }
+                break;
+            case 'data-data-error':     // Data is passed in as (title, x, y, err+, err-, y2, err2+, err2-,...)
+                // X value:
+                $val = (double)$this->data[$i][$j++];
+                $maxx = ($val > $maxx) ? $val : $maxx;
+                $minx = ($val < $minx) ? $val : $minx;
+
+                $miny = $maxy = (double)$this->data[$i][$j];
+                // $numrecs = @ count($this->data[$i]);
+                for (; $j < $this->num_recs[$i];) {
+                    // Y value:
+                    $val = (double)$this->data[$i][$j++];
+                    $maxy = ($val > $maxy) ? $val : $maxy;
+                    $miny = ($val < $miny) ? $val : $miny;
+                    // Error +:
+                    $val = (double)$this->data[$i][$j++];
+                    $maxe = ($val > $maxe) ? $val : $maxe;
+                    // Error -:
+                    $val = (double)$this->data[$i][$j++];
+                    $mine = ($val > $mine) ? $val : $mine;
+                }
+                $maxy = $maxy + $maxe;
+                $miny = $miny - $mine;      // assume error bars are always > 0
+                break;
+            default:
+                $this->PrintError("FindDataLimits(): Unknown data type '$data_type'.");
+            break;
+            }
+            $this->data[$i][MINY] = $miny;      // This row's min Y, for DrawXDataLine()
+            $this->data[$i][MAXY] = $maxy;      // This row's max Y, for DrawXDataLine()
+
+            $minminy = ($miny < $minminy) ? $miny : $minminy;   // global min
+            $maxmaxy = ($maxy > $maxmaxy) ? $maxy : $maxmaxy;   // global max
+        }
+
+        $this->min_x = $minx;
+        $this->max_x = $maxx;
+        $this->min_y = $minminy;
+        $this->max_y = $maxmaxy;
+        $this->max_t = $maxt;
+
+        $this->data_limits_done = TRUE;
+
+        return TRUE;
+    }
+
+
+    /*!
+     * Calculates image margins on the fly from title positions and sizes,
+     * and tick labels positions and sizes.
+     *
+     * FIXME: fix x_data_label_pos behaviour. Now we are leaving room for it AND x_tick_label_pos
+     *        maybe it shouldn't be so...
+     *
+     * TODO: add x_tick_label_width and y_tick_label_height and use them to calculate
+     *       max_x_labels and max_y_labels, to be used by drawing functions to avoid overlapping.
+     */
+    function CalcMargins()
+    {
+        // Temporary variables for label size calculation
+        $xlab = $this->FormatLabel('x', $this->max_x);
+        $ylab = $this->FormatLabel('y', $this->max_y);
+
+        // dirty fix:
+        // max_t is the maximum data label length (from column 0 of each data row).
+        if ($this->max_t > strlen ($xlab))
+            $xlab = sprintf ("%{$this->max_t}s","_");
+
+        //////// Calculate maximum X/Y axis label height and width:
+
+        // TTFonts:
+        if ($this->use_ttf) {
+            // Maximum X axis label height
+            $size = $this->TTFBBoxSize($this->x_label_font['size'], $this->x_label_angle,
+                                       $this->x_label_font['font'], $xlab);
+            $this->x_tick_label_height = $size[1];
+
+            // Maximum Y axis label width
+            $size = $this->TTFBBoxSize($this->y_label_font['size'], $this->y_label_angle,
+                                        $this->y_label_font['font'], $ylab);
+            $this->y_tick_label_width = $size[0];
+        }
+        // Fixed fonts:
+        else {
+            // Maximum X axis label height
+            if ($this->x_label_angle == 90)
+                $this->x_tick_label_height = strlen($xlab) * $this->x_label_font['width'];
+            else
+                $this->x_tick_label_height = $this->x_label_font['height'];
+
+            // Maximum Y axis label width
+            $this->y_tick_label_width = strlen($ylab) * $this->y_label_font['width'];
+        }
+
+
+        ///////// Calculate margins:
+
+        // Upper title, ticks and tick labels, and data labels:
+        $this->y_top_margin = $this->title_height + $this->safe_margin * 2;
+
+        if ($this->x_title_pos == 'plotup' || $this->x_title_pos == 'both')
+            $this->y_top_margin += $this->x_title_height + $this->safe_margin;
+
+        if ($this->x_tick_label_pos == 'plotup' || $this->x_tick_label_pos == 'both')
+            $this->y_top_margin += $this->x_tick_label_height;
+
+        if ($this->x_tick_pos == 'plotup' || $this->x_tick_pos == 'both')
+            $this->y_top_margin += $this->x_tick_length * 2;
+
+        if ($this->x_data_label_pos == 'plotup' || $this->x_data_label_pos == 'both')
+            $this->y_top_margin += $this->x_tick_label_height;
+
+        // Lower title, ticks and tick labels, and data labels:
+        $this->y_bot_margin = $this->safe_margin * 2;
+
+        if ($this->x_title_pos == 'plotdown' || $this->x_title_pos == 'both')
+            $this->y_bot_margin += $this->x_title_height;
+
+        if ($this->x_tick_pos == 'plotdown' || $this->x_tick_pos == 'both')
+            $this->y_bot_margin += $this->x_tick_length * 2;
+
+        if ($this->x_tick_pos == 'xaxis' && ($this->x_axis_position == '' || $this->x_axis_position == 0))
+            $this->y_bot_margin += $this->x_tick_length * 2;
+
+        if ($this->x_tick_label_pos == 'plotdown' || $this->x_tick_label_pos == 'both')
+            $this->y_bot_margin += $this->x_tick_label_height;
+
+        if ($this->x_tick_label_pos == 'xaxis' && ($this->x_axis_position == '' || $this->x_axis_position == 0))
+            $this->y_bot_margin += $this->x_tick_label_height;
+
+        if ($this->x_data_label_pos == 'plotdown' || $this->x_data_label_pos == 'both')
+            $this->y_bot_margin += $this->x_tick_label_height;
+
+        // Left title, ticks and tick labels:
+        $this->x_left_margin = $this->safe_margin * 2;
+
+        if ($this->y_title_pos == 'plotleft' || $this->y_title_pos == 'both')
+            $this->x_left_margin += $this->y_title_width + $this->safe_margin;
+
+        if ($this->y_tick_label_pos == 'plotleft' || $this->y_tick_label_pos == 'both')
+            $this->x_left_margin += $this->y_tick_label_width;
+
+        if ($this->y_tick_pos == 'plotleft' || $this->y_tick_pos == 'both')
+            $this->x_left_margin += $this->y_tick_length * 2 ;
+
+        // Right title, ticks and tick labels:
+        $this->x_right_margin = $this->safe_margin * 2;
+
+        if ($this->y_title_pos == 'plotright' || $this->y_title_pos == 'both')
+            $this->x_right_margin += $this->y_title_width + $this->safe_margin;
+
+        if ($this->y_tick_label_pos == 'plotright' || $this->y_tick_label_pos == 'both')
+            $this->x_right_margin += $this->y_tick_label_width;
+
+        if ($this->y_tick_pos == 'plotright' || $this->y_tick_pos == 'both')
+            $this->x_right_margin += $this->y_tick_length * 2;
+
+
+        $this->x_tot_margin = $this->x_left_margin + $this->x_right_margin;
+        $this->y_tot_margin = $this->y_top_margin + $this->y_bot_margin;
+
+        return;
+    }
+
+
+    /*!
+     * Set the margins in pixels (left, right, top, bottom)
+     */
+    function SetMarginsPixels($which_lm, $which_rm, $which_tm, $which_bm)
+    {
+
+        $this->x_left_margin = $which_lm;
+        $this->x_right_margin = $which_rm;
+        $this->x_tot_margin = $which_lm + $which_rm;
+
+        $this->y_top_margin = $which_tm;
+        $this->y_bot_margin = $which_bm;
+        $this->y_tot_margin = $which_tm + $which_bm;
+
+        $this->SetPlotAreaPixels();
+
+        return;
+    }
+
+
+    /*!
+     * Sets the limits for the plot area. If no arguments are supplied, uses
+     * values calculated from CalcMargins();
+     * Like in GD, (0,0) is upper left
+     *
+     * This resets the scale if SetPlotAreaWorld() was already called
+     */
+    function SetPlotAreaPixels($x1=NULL, $y1=NULL, $x2=NULL, $y2=NULL)
+    {
+        if ($x2 && $y2) {
+            $this->plot_area = array($x1, $y1, $x2, $y2);
+        } else {
+            if (! isset($this->x_tot_margin))
+                $this->CalcMargins();
+
+            $this->plot_area = array($this->x_left_margin, $this->y_top_margin,
+                                     $this->image_width - $this->x_right_margin,
+                                     $this->image_height - $this->y_bot_margin);
+        }
+        $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0];
+        $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1];
+
+        // Reset the scale with the new plot area.
+        if (isset($this->plot_max_x))
+            $this->CalcTranslation();
+
+        return TRUE;
+
+    }
+
+
+    /*!
+     * Sets minimum and maximum x and y values in the plot using FindDataLimits()
+     * or from the supplied parameters, if any.
+     *
+     * This resets the scale if SetPlotAreaPixels() was already called
+     */
+    function SetPlotAreaWorld($xmin=NULL, $ymin=NULL, $xmax=NULL, $ymax=NULL)
+    {
+        if (! isset($this->data_limits_done)) { // For automatic setting of data we need data limits
+            $this->FindDataLimits() ;
+        }
+
+        if ($xmin === NULL || $xmin === '') {
+            if ($this->data_type == 'text-data')  // Valid for data without X values only.
+                $xmin = 0;
+            else
+                $xmin = $this->min_x;
+        }
+        if ($xmax === NULL || $xmax === '') {
+            if ($this->data_type == 'text-data')  // Valid for data without X values only.
+                $xmax = $this->max_x + 1;
+            else
+                $xmax = $this->max_x;
+        }
+
+        // Leave room above and below the highest and lowest data points.
+
+        if ($ymin === NULL || $ymin === '') {
+            $ymin = floor($this->min_y - abs($this->min_y) * 0.1);
+        }
+        if ($ymax === NULL || $ymax === '') {
+            $ymax = ceil($this->max_y + abs($this->max_y) * 0.1);
+        }
+
+        // Error checking
+
+        if ($ymin == $ymax)     // Minimum height
+            $ymax += 1;
+
+        if ($this->yscale_type == 'log') {
+            if ($ymin <= 0) {
+                $ymin = 1;
+            }
+            if ($ymax <= 0) {
+                $this->PrintError('SetPlotAreaWorld(): Log plots need data greater than 0');
+                return FALSE;
+            }
+        }
+
+        if ($ymax <= $ymin) {
+            $this->DrawError('SetPlotAreaWorld(): Error in data - max not greater than min');
+            return FALSE;
+        }
+
+
+        // Reset (if it was already set) the scale with the new maxs and mins
+
+        $this->plot_min_x = $xmin;
+        $this->plot_max_x = $xmax;
+        $this->plot_min_y = $ymin;
+        $this->plot_max_y = $ymax;
+
+        if (isset($this->plot_area_width)) {
+            $this->CalcTranslation();
+        }
+
+        return TRUE;
+    } //function SetPlotAreaWorld
+
+
+    /*!
+     * For bar plots, which have equally spaced x variables.
+     */
+    function CalcBarWidths()
+    {
+        // group_width is the width of a group, including padding
+        $group_width = $this->plot_area_width / $this->num_data_rows;
+
+        // Actual number of bar spaces in the group. This includes the drawn bars, and
+        // 'bar_extra_space'-worth of extra bars.
+        // Note that 'records_per_group' includes the label, so subtract one to get
+        // the number of points in the group. 'stackedbars' have 1 bar space per group.
+        if ($this->plot_type == 'stackedbars') {
+          $num_spots = 1 + $this->bar_extra_space;
+        } else {
+          $num_spots = $this->records_per_group - 1 + $this->bar_extra_space;
+        }
+
+        // record_bar_width is the width of each bar's allocated area.
+        // If bar_width_adjust=1 this is the width of the bar, otherwise
+        // the bar is centered inside record_bar_width.
+        // The equation is:
+        //   group_frac_width * group_width = record_bar_width * num_spots
+        $this->record_bar_width = $this->group_frac_width * $group_width / $num_spots;
+
+        // Note that the extra space due to group_frac_width and bar_extra_space will be
+        // evenly divided on each side of the group: the drawn bars are centered in the group.
+
+        // Within each bar's allocated space, if bar_width_adjust=1 the bar fills the 
+        // space, otherwise it is centered.
+        // This is the actual drawn bar width:
+        $this->actual_bar_width = $this->record_bar_width * $this->bar_width_adjust;
+        // This is the gap on each side of the bar (0 if bar_width_adjust=1):
+        $this->bar_adjust_gap = ($this->record_bar_width - $this->actual_bar_width) / 2;
+
+        return TRUE;
+    }
+
+    /*!
+     * Calculates scaling stuff...
+     */
+    function CalcTranslation()
+    {
+        if ($this->plot_max_x - $this->plot_min_x == 0) { // Check for div by 0
+            $this->xscale = 0;
+        } else {
+            if ($this->xscale_type == 'log') {
+                $this->xscale = ($this->plot_area_width)/(log10($this->plot_max_x) - log10($this->plot_min_x));
+            } else {
+                $this->xscale = ($this->plot_area_width)/($this->plot_max_x - $this->plot_min_x);
+            }
+        }
+
+        if ($this->plot_max_y - $this->plot_min_y == 0) { // Check for div by 0
+            $this->yscale = 0;
+        } else {
+            if ($this->yscale_type == 'log') {
+                $this->yscale = ($this->plot_area_height)/(log10($this->plot_max_y) - log10($this->plot_min_y));
+            } else {
+                $this->yscale = ($this->plot_area_height)/($this->plot_max_y - $this->plot_min_y);
+            }
+        }
+        // GD defines x = 0 at left and y = 0 at TOP so -/+ respectively
+        if ($this->xscale_type == 'log') {
+            $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * log10($this->plot_min_x) );
+        } else {
+            $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * $this->plot_min_x);
+        }
+        if ($this->yscale_type == 'log') {
+            $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * log10($this->plot_min_y));
+        } else {
+            $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * $this->plot_min_y);
+        }
+
+        $this->scale_is_set = TRUE;
+
+        /************** FIXME?? *************/
+        // There should be a better place for this.
+
+        // User provided y axis position?
+        if ($this->y_axis_position !== '') {
+            // Make sure we draw our axis inside the plot
+            $this->y_axis_position = ($this->y_axis_position < $this->plot_min_x)
+                                     ? $this->plot_min_x : $this->y_axis_position;
+            $this->y_axis_position = ($this->y_axis_position > $this->plot_max_x)
+                                     ? $this->plot_max_x : $this->y_axis_position;
+            $this->y_axis_x_pixels = $this->xtr($this->y_axis_position);
+        } else {
+            // Default to left axis
+            $this->y_axis_x_pixels = $this->xtr($this->plot_min_x);
+        }
+        // User provided x axis position?
+        if ($this->x_axis_position !== '') {
+            // Make sure we draw our axis inside the plot
+            $this->x_axis_position = ($this->x_axis_position < $this->plot_min_y)
+                                     ? $this->plot_min_y : $this->x_axis_position;
+            $this->x_axis_position = ($this->x_axis_position > $this->plot_max_y)
+                                     ? $this->plot_max_y : $this->x_axis_position;
+        } elseif ($this->yscale_type == 'log') {
+            $this->x_axis_position = 1;
+        } else {
+            // Default to axis at 0 or plot_min_y (should be 0 anyway, from SetPlotAreaWorld())
+            // Note x_axis_position must be set because DrawBars and others expect a number.
+            if ($this->plot_min_y <= 0 && 0 <= $this->plot_max_y)
+                $this->x_axis_position = 0;
+            else 
+                $this->x_axis_position = $this->plot_min_y;
+        }
+        $this->x_axis_y_pixels = $this->ytr($this->x_axis_position);
+
+    } // function CalcTranslation()
+
+
+    /*!
+     * Translate X world coordinate into pixel coordinate
+     * Needs values calculated by _CalcTranslation()
+     */
+    function xtr($x_world)
+    {
+        //$x_pixels =  $this->x_left_margin + ($this->image_width - $this->x_tot_margin)*
+        //      (($x_world - $this->plot_min_x) / ($this->plot_max_x - $this->plot_min_x)) ;
+        //which with a little bit of math reduces to ...
+        if ($this->xscale_type == 'log') {
+            $x_pixels = $this->plot_origin_x + log10($x_world) * $this->xscale ;
+        } else {
+            $x_pixels = $this->plot_origin_x + $x_world * $this->xscale ;
+        }
+        return round($x_pixels);
+    }
+
+
+    /*!
+     * Translate Y world coordinate into pixel coordinate.
+     * Needs values calculated by _CalcTranslation()
+     */
+    function ytr($y_world)
+    {
+        if ($this->yscale_type == 'log') {
+            //minus because GD defines y = 0 at top. doh!
+            $y_pixels =  $this->plot_origin_y - log10($y_world) * $this->yscale ;
+        } else {
+            $y_pixels =  $this->plot_origin_y - $y_world * $this->yscale ;
+        }
+        return round($y_pixels);
+    }
+
+    /*!
+     * Formats a tick or data label.
+     *
+     * \note Time formatting suggested by Marlin Viss
+     */
+    function FormatLabel($which_pos, $which_lab)
+    {
+        switch ($which_pos) {
+        case 'x':
+        case 'plotx':
+            switch ($this->x_label_type) {
+            case 'title':
+                $lab = @ $this->data[$which_lab][0];
+                break;
+            case 'data':
+                $lab = number_format($which_lab, $this->x_precision, '.', ',').$this->data_units_text;
+                break;
+            case 'time':
+                $lab = strftime($this->x_time_format, $which_lab);
+                break;
+            default:
+                // Unchanged from whatever format it is passed in
+                $lab = $which_lab;
+            break;
+            }
+            break;
+        case 'y':
+        case 'ploty':
+            switch ($this->y_label_type) {
+            case 'data':
+                $lab = number_format($which_lab, $this->y_precision, '.', ',').$this->data_units_text;
+                break;
+            case 'time':
+                $lab = strftime($this->y_time_format, $which_lab);
+                break;
+            default:
+                // Unchanged from whatever format it is passed in
+                $lab = $which_lab;
+                break;
+            }
+            break;
+        default:
+            $this->PrintError("FormatLabel(): Unknown label type $which_type");
+            return NULL;
+        }
+
+        return $lab;
+    } //function FormatLabel
+
+
+
+/////////////////////////////////////////////
+///////////////                         TICKS
+/////////////////////////////////////////////
+
+    /*!
+     * Use either this or SetNumXTicks() to set where to place x tick marks
+     */
+    function SetXTickIncrement($which_ti=NULL)
+    {
+        if ($which_ti) {
+            $this->x_tick_inc = $which_ti;  //world coordinates
+        } else {
+            if (! isset($this->data_limits_done)) {
+                $this->FindDataLimits();  //Get maxima and minima for scaling
+            }
+            $this->x_tick_inc =  ($this->plot_max_x  - $this->plot_min_x  )/10;
+        }
+        $this->num_x_ticks = ''; //either use num_y_ticks or y_tick_inc, not both
+        return TRUE;
+    }
+
+    /*!
+     * Use either this or SetNumYTicks() to set where to place y tick marks
+     */
+    function SetYTickIncrement($which_ti=NULL)
+    {
+        if ($which_ti) {
+            $this->y_tick_inc = $which_ti;  //world coordinates
+        } else {
+            if (! isset($this->data_limits_done)) {
+                $this->FindDataLimits();  //Get maxima and minima for scaling
+            }
+            if (! isset($this->plot_max_y))
+                $this->SetPlotAreaWorld();
+
+            $this->y_tick_inc =  ($this->plot_max_y  - $this->plot_min_y  )/10;
+        }
+        $this->num_y_ticks = ''; //either use num_y_ticks or y_tick_inc, not both
+        return TRUE;
+    }
+
+
+    function SetNumXTicks($which_nt)
+    {
+        $this->num_x_ticks = $which_nt;
+        $this->x_tick_inc = '';  //either use num_x_ticks or x_tick_inc, not both
+        return TRUE;
+    }
+
+    function SetNumYTicks($which_nt)
+    {
+        $this->num_y_ticks = $which_nt;
+        $this->y_tick_inc = '';  //either use num_y_ticks or y_tick_inc, not both
+        return TRUE;
+    }
+
+    /*!
+     *
+     */
+    function SetYTickPos($which_tp)
+    {
+        $this->y_tick_pos = $this->CheckOption($which_tp, 'plotleft, plotright, both, yaxis, none', __FUNCTION__);
+        return TRUE;
+    }
+    /*!
+     *
+     */
+    function SetXTickPos($which_tp)
+    {
+        $this->x_tick_pos = $this->CheckOption($which_tp, 'plotdown, plotup, both, xaxis, none', __FUNCTION__);
+        return TRUE;
+    }
+
+    /*!
+     * \param skip bool
+     */
+    function SetSkipTopTick($skip)
+    {
+        $this->skip_top_tick = (bool)$skip;
+        return TRUE;
+    }
+
+    /*!
+     * \param skip bool
+     */
+    function SetSkipBottomTick($skip)
+    {
+        $this->skip_bottom_tick = (bool)$skip;
+        return TRUE;
+    }
+
+    /*!
+     * \param skip bool
+     */
+    function SetSkipLeftTick($skip)
+    {
+        $this->skip_left_tick = (bool)$skip;
+        return TRUE;
+    }
+
+    /*!
+     * \param skip bool
+     */
+    function SetSkipRightTick($skip)
+    {
+        $this->skip_right_tick = (bool)$skip;
+        return TRUE;
+    }
+
+    function SetXTickLength($which_xln)
+    {
+        $this->x_tick_length = $which_xln;
+        return TRUE;
+    }
+
+    function SetYTickLength($which_yln)
+    {
+        $this->y_tick_length = $which_yln;
+        return TRUE;
+    }
+
+    function SetXTickCrossing($which_xc)
+    {
+        $this->x_tick_cross = $which_xc;
+        return TRUE;
+    }
+
+    function SetYTickCrossing($which_yc)
+    {
+        $this->y_tick_cross = $which_yc;
+        return TRUE;
+    }
+
+
+/////////////////////////////////////////////
+////////////////////          GENERIC DRAWING
+/////////////////////////////////////////////
+
+    /*!
+     * Fills the background.
+     */
+    function DrawBackground()
+    {
+        // Don't draw this twice if drawing two plots on one image
+        if (! $this->background_done) {
+            if (isset($this->bgimg)) {    // If bgimg is defined, use it
+                $this->tile_img($this->bgimg, 0, 0, $this->image_width, $this->image_height, $this->bgmode);
+            } else {                        // Else use solid color
+                ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height,
+                                     $this->ndx_bg_color);
+            }
+            $this->background_done = TRUE;
+            return TRUE;        // Done
+        }
+        return FALSE;           // Nothing done
+    }
+
+
+    /*!
+     * Fills the plot area background.
+     */
+    function DrawPlotAreaBackground()
+    {
+        if (isset($this->plotbgimg)) {
+            $this->tile_img($this->plotbgimg, $this->plot_area[0], $this->plot_area[1],
+                            $this->plot_area_width, $this->plot_area_height, $this->plotbgmode);
+        }
+        else {
+            if ($this->draw_plot_area_background) {
+                ImageFilledRectangle($this->img, $this->plot_area[0], $this->plot_area[1],
+                                     $this->plot_area[2], $this->plot_area[3], $this->ndx_plot_bg_color);
+            }
+        }
+
+        return TRUE;
+    }
+
+
+    /*!
+     * Tiles an image at some given coordinates.
+     *
+     * \param $file   string Filename of the picture to be used as tile.
+     * \param $xorig  int    X coordinate of the plot where the tile is to begin.
+     * \param $yorig  int    Y coordinate of the plot where the tile is to begin.
+     * \param $width  int    Width of the area to be tiled.
+     * \param $height int    Height of the area to be tiled.
+     * \param $mode   string One of 'centeredtile', 'tile', 'scale'.
+     */
+    function tile_img($file, $xorig, $yorig, $width, $height, $mode)
+    {
+        $size = getimagesize($file);
+        $input_format = $size[2];
+
+        switch($input_format) {
+        case 1:
+            $im = @ imagecreatefromGIF ($file);
+            if (! $im) {
+                $this->PrintError("tile_img:() Unable to open $file as a GIF.");
+                return FALSE;
+            }
+            break;
+        case 2:
+            $im = @ imagecreatefromJPEG ($file);
+            if (! $im) {
+                $this->PrintError("tile_img(): Unable to open $file as a JPG.");
+                return FALSE;
+            }
+            break;
+        case 3:
+            $im = @ imagecreatefromPNG ($file);
+            if (! $im) {
+                $this->PrintError("tile_img(): Unable to open $file as a PNG.");
+                return FALSE;
+            }
+            break;
+        default:
+            $this->PrintError('tile_img(): Please select a gif, jpg, or png image.');
+            return FALSE;
+            break;
+        }
+
+
+        if ($mode == 'scale') {
+            imagecopyresized($this->img, $im, $xorig, $yorig, 0, 0, $width, $height, $size[0],$size[1]);
+            return TRUE;
+        } else if ($mode == 'centeredtile') {
+            $x0 = - floor($size[0]/2);   // Make the tile look better
+            $y0 = - floor($size[1]/2);
+        } else if ($mode = 'tile') {
+            $x0 = 0;
+            $y0 = 0;
+        }
+
+        // Actually draw the tile
+
+        // But first on a temporal image.
+        $tmp = ImageCreate($width, $height);
+        if (! $tmp)
+            $this->PrintError('tile_img(): Could not create image resource.');
+
+        for ($x = $x0; $x < $width; $x += $size[0])
+            for ($y = $y0; $y < $height; $y += $size[1])
+                imagecopy($tmp, $im, $x, $y, 0, 0, $size[0], $size[1]);
+
+        // Copy the temporal image onto the final one.
+        imagecopy($this->img, $tmp, $xorig, $yorig, 0,0, $width, $height);
+
+        // Free resources
+        imagedestroy($tmp);
+        imagedestroy($im);
+
+        return TRUE;
+    }  // function tile_img
+
+
+    /*!
+     * Draws a border around the final image.
+     */
+    function DrawImageBorder()
+    {
+        switch ($this->image_border_type) {
+        case 'raised':
+            ImageLine($this->img, 0, 0, $this->image_width-1, 0, $this->ndx_i_border);
+            ImageLine($this->img, 1, 1, $this->image_width-2, 1, $this->ndx_i_border);
+            ImageLine($this->img, 0, 0, 0, $this->image_height-1, $this->ndx_i_border);
+            ImageLine($this->img, 1, 1, 1, $this->image_height-2, $this->ndx_i_border);
+            ImageLine($this->img, $this->image_width-1, 0, $this->image_width-1,
+                      $this->image_height-1, $this->ndx_i_border_dark);
+            ImageLine($this->img, 0, $this->image_height-1, $this->image_width-1,
+                      $this->image_height-1, $this->ndx_i_border_dark);
+            ImageLine($this->img, $this->image_width-2, 1, $this->image_width-2,
+                      $this->image_height-2, $this->ndx_i_border_dark);
+            ImageLine($this->img, 1, $this->image_height-2, $this->image_width-2,
+                      $this->image_height-2, $this->ndx_i_border_dark);
+            break;
+        case 'plain':
+            ImageLine($this->img, 0, 0, $this->image_width-1, 0, $this->ndx_i_border_dark);
+            ImageLine($this->img, $this->image_width-1, 0, $this->image_width-1,
+                      $this->image_height-1, $this->ndx_i_border_dark);
+            ImageLine($this->img, $this->image_width-1, $this->image_height-1, 0, $this->image_height-1,
+                      $this->ndx_i_border_dark);
+            ImageLine($this->img, 0, 0, 0, $this->image_height-1, $this->ndx_i_border_dark);
+            break;
+        case 'none':
+            break;
+        default:
+            $this->DrawError("DrawImageBorder(): unknown image_border_type: '$this->image_border_type'");
+            return FALSE;
+        }
+        return TRUE;
+    }
+
+
+    /*!
+     * Adds the title to the graph.
+     */
+    function DrawTitle()
+    {
+        // Center of the plot area
+        //$xpos = ($this->plot_area[0] + $this->plot_area_width )/ 2;
+
+        // Center of the image:
+        $xpos = $this->image_width / 2;
+
+        // Place it at almost at the top
+        $ypos = $this->safe_margin;
+
+        $this->DrawText($this->title_font, $this->title_angle, $xpos, $ypos,
+                        $this->ndx_title_color, $this->title_txt, 'center', 'bottom');
+
+        return TRUE;
+
+    }
+
+
+    /*!
+     * Draws the X-Axis Title
+     */
+    function DrawXTitle()
+    {
+        if ($this->x_title_pos == 'none')
+            return;
+
+        // Center of the plot
+        $xpos = ($this->plot_area[2] + $this->plot_area[0]) / 2;
+
+        // Upper title
+        if ($this->x_title_pos == 'plotup' || $this->x_title_pos == 'both') {
+            $ypos = $this->safe_margin + $this->title_height + $this->safe_margin;
+            $this->DrawText($this->x_title_font, $this->x_title_angle,
+                            $xpos, $ypos, $this->ndx_title_color, $this->x_title_txt, 'center');
+        }
+        // Lower title
+        if ($this->x_title_pos == 'plotdown' || $this->x_title_pos == 'both') {
+            $ypos = $this->image_height - $this->x_title_height - $this->safe_margin;
+            $this->DrawText($this->x_title_font, $this->x_title_angle,
+                            $xpos, $ypos, $this->ndx_title_color, $this->x_title_txt, 'center');
+        }
+        return TRUE;
+    }
+
+    /*!
+     * Draws the Y-Axis Title
+     */
+    function DrawYTitle()
+    {
+        if ($this->y_title_pos == 'none')
+            return;
+
+        // Center the title vertically to the plot
+        $ypos = ($this->plot_area[3] + $this->plot_area[1]) / 2;
+
+        if ($this->y_title_pos == 'plotleft' || $this->y_title_pos == 'both') {
+            $xpos = $this->safe_margin;
+            $this->DrawText($this->y_title_font, 90, $xpos, $ypos, $this->ndx_title_color,
+                            $this->y_title_txt, 'left', 'center');
+        }
+        if ($this->y_title_pos == 'plotright' || $this->y_title_pos == 'both') {
+            $xpos = $this->image_width - $this->safe_margin - $this->y_title_width - $this->safe_margin;
+            $this->DrawText($this->y_title_font, 90, $xpos, $ypos, $this->ndx_title_color,
+                            $this->y_title_txt, 'left', 'center');
+        }
+
+        return TRUE;
+    }
+
+
+    /*
+     * \note Horizontal grid lines overwrite horizontal axis with y=0, so call this first, then DrawXAxis()
+     */
+    function DrawYAxis()
+    {
+        // Draw ticks, labels and grid, if any
+        $this->DrawYTicks();
+
+        // Draw Y axis at X = y_axis_x_pixels
+        ImageLine($this->img, $this->y_axis_x_pixels, $this->plot_area[1],
+                  $this->y_axis_x_pixels, $this->plot_area[3], $this->ndx_grid_color);
+
+        return TRUE;
+    }
+
+    /*
+     *
+     */
+    function DrawXAxis()
+    {
+        // Draw ticks, labels and grid
+        $this->DrawXTicks();
+
+        /* This tick and label tend to overlap with regular Y Axis labels,
+         * as Mike Pullen pointed out.
+         *
+        //Draw Tick and Label for X axis
+        if (! $this->skip_bottom_tick) {
+            $ylab =$this->FormatLabel('y', $this->x_axis_position);
+            $this->DrawYTick($ylab, $this->x_axis_y_pixels);
+        }
+        */
+        //Draw X Axis at Y = x_axis_y_pixels
+        ImageLine($this->img, $this->plot_area[0]+1, $this->x_axis_y_pixels,
+                  $this->plot_area[2]-1, $this->x_axis_y_pixels, $this->ndx_grid_color);
+
+        return TRUE;
+    }
+
+    /*!
+     * Draw Just one Tick, called from DrawYTicks() and DrawXAxis()
+     * TODO? Move this inside DrawYTicks() and Modify DrawXAxis() ?
+     */
+    function DrawYTick($which_ylab, $which_ypix)
+    {
+        // Ticks on Y axis
+        if ($this->y_tick_pos == 'yaxis') {
+            ImageLine($this->img, $this->y_axis_x_pixels - $this->y_tick_length, $which_ypix,
+                      $this->y_axis_x_pixels + $this->y_tick_cross, $which_ypix,
+                      $this->ndx_tick_color);
+        }
+
+        // Labels on Y axis
+        if ($this->y_tick_label_pos == 'yaxis') {
+            $this->DrawText($this->y_label_font, $this->y_label_angle,
+                            $this->y_axis_x_pixels - $this->y_tick_length * 1.5, $which_ypix,
+                            $this->ndx_text_color, $which_ylab, 'right', 'center');
+        }
+
+        // Ticks to the left of the Plot Area
+        if (($this->y_tick_pos == 'plotleft') || ($this->y_tick_pos == 'both') ) {
+            ImageLine($this->img, $this->plot_area[0] - $this->y_tick_length,
+                      $which_ypix, $this->plot_area[0] + $this->y_tick_cross,
+                      $which_ypix, $this->ndx_tick_color);
+        }
+
+        // Ticks to the right of the Plot Area
+        if (($this->y_tick_pos == 'plotright') || ($this->y_tick_pos == 'both') ) {
+            ImageLine($this->img, ($this->plot_area[2] + $this->y_tick_length),
+                      $which_ypix, $this->plot_area[2] - $this->y_tick_cross,
+                      $which_ypix, $this->ndx_tick_color);
+        }
+
+        // Labels to the left of the plot area
+        if ($this->y_tick_label_pos == 'plotleft' || $this->y_tick_label_pos == 'both') {
+            $this->DrawText($this->y_label_font, $this->y_label_angle,
+                            $this->plot_area[0] - $this->y_tick_length * 1.5, $which_ypix,
+                            $this->ndx_text_color, $which_ylab, 'right', 'center');
+        }
+        // Labels to the right of the plot area
+        if ($this->y_tick_label_pos == 'plotright' || $this->y_tick_label_pos == 'both') {
+            $this->DrawText($this->y_label_font, $this->y_label_angle,
+                            $this->plot_area[2] + $this->y_tick_length * 1.5, $which_ypix,
+                            $this->ndx_text_color, $which_ylab, 'left', 'center');
+        }
+   } // Function DrawYTick()
+
+
+    /*!
+     * Draws Grid, Ticks and Tick Labels along Y-Axis
+     * Ticks and ticklabels can be left of plot only, right of plot only,
+     * both on the left and right of plot, or crossing a user defined Y-axis
+     * TODO: marks at whole numbers (-10, 10, 20, 30 ...) no matter where the plot begins (-3, 4.7, etc.)
+     */
+    function DrawYTicks()
+    {
+        // Sets the line style for IMG_COLOR_STYLED lines (grid)
+        if ($this->dashed_grid) {
+            $this->SetDashedStyle($this->ndx_light_grid_color);
+            $style = IMG_COLOR_STYLED;
+        } else {
+            $style = $this->ndx_light_grid_color;
+        }
+
+        // maxy is always > miny so delta_y is always positive
+        if ($this->y_tick_inc) {
+            $delta_y = $this->y_tick_inc;
+        } elseif ($this->num_y_ticks) {
+            $delta_y = ($this->plot_max_y - $this->plot_min_y) / $this->num_y_ticks;
+        } else {
+            $delta_y = ($this->plot_max_y - $this->plot_min_y) / 10 ;
+        }
+
+        // NOTE: When working with floats, because of approximations when adding $delta_y,
+        // $y_tmp never equals $y_end  at the for loop, so one spurious line would  get drawn where
+        // not for the substraction to $y_end here.
+        $y_tmp = (double)$this->plot_min_y;
+        $y_end = (double)$this->plot_max_y - ($delta_y/2);
+
+        if ($this->skip_bottom_tick)
+            $y_tmp += $delta_y;
+
+        if ($this->skip_top_tick)
+            $y_end -= $delta_y;
+
+        for (;$y_tmp < $y_end; $y_tmp += $delta_y) {
+            $ylab = $this->FormatLabel('y', $y_tmp);
+            $y_pixels = $this->ytr($y_tmp);
+
+            // Horizontal grid line
+            if ($this->draw_y_grid) {
+                ImageLine($this->img, $this->plot_area[0]+1, $y_pixels, $this->plot_area[2]-1, $y_pixels, $style);
+            }
+
+            // Draw ticks
+            $this->DrawYTick($ylab, $y_pixels);
+        }
+        return TRUE;
+    } // function DrawYTicks
+
+
+    /*!
+     * Draws Grid, Ticks and Tick Labels along X-Axis
+     * Ticks and tick labels can be down of plot only, up of plot only,
+     * both on up and down of plot, or crossing a user defined X-axis
+     *
+     * \note Original vertical code submitted by Marlin Viss
+     */
+    function DrawXTicks()
+    {
+        // Sets the line style for IMG_COLOR_STYLED lines (grid)
+        if ($this->dashed_grid) {
+            $this->SetDashedStyle($this->ndx_light_grid_color);
+            $style = IMG_COLOR_STYLED;
+        } else {
+            $style = $this->ndx_light_grid_color;
+        }
+
+        // Calculate x increment between ticks
+        if ($this->x_tick_inc) {
+            $delta_x = $this->x_tick_inc;
+        } elseif ($this->num_x_ticks) {
+            $delta_x = ($this->plot_max_x - $this->plot_min_x) / $this->num_x_ticks;
+        } else {
+            $delta_x =($this->plot_max_x - $this->plot_min_x) / 10 ;
+        }
+
+        // NOTE: When working with decimals, because of approximations when adding $delta_x,
+        // $x_tmp never equals $x_end  at the for loop, so one spurious line would  get drawn where
+        // not for the substraction to $x_end here.
+        $x_tmp = (double)$this->plot_min_x;
+        $x_end = (double)$this->plot_max_x - ($delta_x/2);
+
+        // Should the leftmost tick be drawn?
+        if ($this->skip_left_tick)
+            $x_tmp += $delta_x;
+
+        // And the rightmost?
+        if (! $this->skip_right_tick)
+            $x_end += $delta_x;
+
+        for (;$x_tmp < $x_end; $x_tmp += $delta_x) {
+            $xlab = $this->FormatLabel('x', $x_tmp);
+            $x_pixels = $this->xtr($x_tmp);
+
+            // Vertical grid lines
+            if ($this->draw_x_grid) {
+                ImageLine($this->img, $x_pixels, $this->plot_area[1], $x_pixels, $this->plot_area[3], $style);
+            }
+
+            // Tick on X Axis
+            if ($this->x_tick_pos == 'xaxis') {
+
+                ImageLine($this->img, $x_pixels, $this->x_axis_y_pixels - $this->x_tick_cross,
+                          $x_pixels, $this->x_axis_y_pixels + $this->x_tick_length, $this->ndx_tick_color);
+            }
+
+            // Label on X axis
+            if ($this->x_tick_label_pos == 'xaxis') {
+                 $this->DrawText($this->x_label_font, $this->x_label_angle, $x_pixels,
+                                $this->x_axis_y_pixels + $this->x_tick_length*1.5, $this->ndx_text_color,
+                                $xlab, 'center', 'bottom');
+            }
+
+            // Top of the plot area tick
+            if ($this->x_tick_pos == 'plotup' || $this->x_tick_pos == 'both') {
+                ImageLine($this->img, $x_pixels, $this->plot_area[1] - $this->x_tick_length,
+                          $x_pixels, $this->plot_area[1] + $this->x_tick_cross, $this->ndx_tick_color);
+            }
+            // Bottom of the plot area tick
+            if ($this->x_tick_pos == 'plotdown' || $this->x_tick_pos == 'both') {
+                ImageLine($this->img, $x_pixels, $this->plot_area[3] + $this->x_tick_length,
+                          $x_pixels, $this->plot_area[3] - $this->x_tick_cross, $this->ndx_tick_color);
+            }
+
+            // Top of the plot area tick label
+            if ($this->x_tick_label_pos == 'plotup' || $this->x_tick_label_pos == 'both') {
+                $this->DrawText($this->x_label_font, $this->x_label_angle, $x_pixels,
+                                $this->plot_area[1] - $this->x_tick_length*1.5, $this->ndx_text_color,
+                                $xlab, 'center', 'top');
+            }
+
+            // Bottom of the plot area tick label
+            if ($this->x_tick_label_pos == 'plotdown' || $this->x_tick_label_pos == 'both') {
+                $this->DrawText($this->x_label_font, $this->x_label_angle, $x_pixels,
+                                $this->plot_area[3] + $this->x_tick_length*1.5, $this->ndx_text_color,
+                                $xlab, 'center', 'bottom');
+            }
+        }
+        return;
+    } // function DrawXTicks
+
+
+    /*!
+     *
+     */
+    function DrawPlotBorder()
+    {
+        switch ($this->plot_border_type) {
+        case 'left':    // for past compatibility
+        case 'plotleft':
+            ImageLine($this->img, $this->plot_area[0], $this->ytr($this->plot_min_y),
+                      $this->plot_area[0], $this->ytr($this->plot_max_y), $this->ndx_grid_color);
+            break;
+        case 'right':
+        case 'plotright':
+            ImageLine($this->img, $this->plot_area[2], $this->ytr($this->plot_min_y),
+                      $this->plot_area[2], $this->ytr($this->plot_max_y), $this->ndx_grid_color);
+            break;
+        case 'both':
+        case 'sides':
+             ImageLine($this->img, $this->plot_area[0], $this->ytr($this->plot_min_y),
+                      $this->plot_area[0], $this->ytr($this->plot_max_y), $this->ndx_grid_color);
+            ImageLine($this->img, $this->plot_area[2], $this->ytr($this->plot_min_y),
+                      $this->plot_area[2], $this->ytr($this->plot_max_y), $this->ndx_grid_color);
+            break;
+        case 'none':
+            //Draw No Border
+            break;
+        case 'full':
+        default:
+            ImageRectangle($this->img, $this->plot_area[0], $this->ytr($this->plot_min_y),
+                           $this->plot_area[2], $this->ytr($this->plot_max_y), $this->ndx_grid_color);
+            break;
+        }
+        return TRUE;
+    }
+
+
+    /*!
+     * Draws the data label associated with a point in the plot at specified x/y world position.
+     * Calling of this function in DrawLines(), etc is decided after x_data_label_pos value.
+     * what the setting is (for plots that need it, like DrawSquared())
+     */
+    function DrawDataLabel($which_font, $which_angle, $x_world, $y_world, $which_color, $which_text,
+                      $which_halign = 'center', $which_valign = 'top', $x_adjustment=0, $y_adjustment=0) 
+    {
+        $data_label = $this->FormatLabel('y', $which_text);
+        //since DrawDataLabel is going to be called alot - perhaps for speed it is better to 
+        //not use this if statement and just always assume which_font is x_label_font (ditto for color).
+        if ( empty($which_font) ) 
+            $which_font = $this->x_label_font;
+
+        $which_angle = empty($which_angle)?'0':$this->x_label_angle;
+
+        if ( empty($which_color) ) 
+            $which_color = $this->ndx_title_color;
+
+        $x_pixels = $this->xtr($x_world) + $x_adjustment;
+        $y_pixels = $this->ytr($y_world) + $y_adjustment;
+
+        $this->DrawText($which_font, $which_angle, $x_pixels, $y_pixels,
+                        $which_color, $which_text, $which_halign, $which_valign);
+
+        return TRUE;
+
+    }
+    /*!
+     * Draws the data label associated with a point in the plot.
+     * This is different from x_labels drawn by DrawXTicks() and care
+     * should be taken not to draw both, as they'd probably overlap.
+     * Calling of this function in DrawLines(), etc is decided after x_data_label_pos value.
+     * Leave the last parameter out, to avoid the drawing of vertical lines, no matter
+     * what the setting is (for plots that need it, like DrawSquared())
+     */
+    function DrawXDataLabel($xlab, $xpos, $row=FALSE)
+    {
+        // FIXME!! not working...
+        if (($this->_x_label_cnt++ % $this->x_label_inc) != 0)
+            return;
+
+        $xlab = $this->FormatLabel('x', $xlab);
+
+        // Labels below the plot area
+        if ($this->x_data_label_pos == 'plotdown' || $this->x_data_label_pos == 'both')
+            $this->DrawText($this->x_label_font, $this->x_label_angle, $xpos,
+                            $this->plot_area[3] + $this->x_tick_length,
+                            $this->ndx_text_color, $xlab, 'center', 'bottom');
+
+        // Labels above the plot area
+        if ($this->x_data_label_pos == 'plotup' || $this->x_data_label_pos == 'both')
+            $this->DrawText($this->x_label_font, $this->x_label_angle, $xpos,
+                            $this->plot_area[1] - $this->x_tick_length ,
+                            $this->ndx_text_color, $xlab, 'center', 'top');
+
+        // $row=0 means this is the first row. $row=FALSE means don't do any rows.
+        if ($row !== FALSE && $this->draw_x_data_label_lines)
+            $this->DrawXDataLine($xpos, $row);
+    }
+
+    /*!
+     * Draws Vertical lines from data points up and down.
+     * Which lines are drawn depends on the value of x_data_label_pos,
+     * and whether this is at all done or not, on draw_x_data_label_lines
+     *
+     * \param xpos int position in pixels of the line.
+     * \param row int index of the data row being drawn.
+     */
+    function DrawXDataLine($xpos, $row)
+    {
+        // Sets the line style for IMG_COLOR_STYLED lines (grid)
+        if($this->dashed_grid) {
+            $this->SetDashedStyle($this->ndx_light_grid_color);
+            $style = IMG_COLOR_STYLED;
+        } else {
+            $style = $this->ndx_light_grid_color;
+        }
+
+        // Lines from the bottom up
+        if ($this->x_data_label_pos == 'both') {
+            ImageLine($this->img, $xpos, $this->plot_area[3], $xpos, $this->plot_area[1], $style);
+        }
+        // Lines coming from the bottom of the plot
+        else if ($this->x_data_label_pos == 'plotdown') {
+            // See FindDataLimits() to see why 'MAXY' index.
+            $ypos = $this->ytr($this->data[$row][MAXY]);
+            ImageLine($this->img, $xpos, $ypos, $xpos, $this->plot_area[3], $style);
+        }
+        // Lines coming from the top of the plot
+        else if ($this->x_data_label_pos == 'plotup') {
+            // See FindDataLimits() to see why 'MINY' index.
+            $ypos = $this->ytr($this->data[$row][MINY]);
+            ImageLine($this->img, $xpos, $this->plot_area[1], $xpos, $ypos, $style);
+        }
+    }
+
+/*
+    function DrawPlotLabel($xlab, $xpos, $ypos)
+    {
+        $this->DrawText($this->x_label_font, $this->x_label_angle, $xpos, $this
+*/
+
+    /*!
+     * Draws the graph legend
+     *
+     * \note Base code submitted by Marlin Viss
+     * FIXME: maximum label length should be calculated more accurately for TT fonts
+     *        Performing a BBox calculation for every legend element, for example.
+     */
+    function DrawLegend($which_x1, $which_y1, $which_boxtype)
+    {
+        // Find maximum legend label length
+        $max_len = 0;
+        foreach ($this->legend as $leg) {
+            $len = strlen($leg);
+            $max_len = ($len > $max_len) ? $len : $max_len;
+        }
+        $max_len += 5;          // Leave room for the boxes and margins
+
+        /////// Calculate legend labels sizes:  FIXME - dirty hack - FIXME
+        // TTF:
+        if ($this->use_ttf) {
+            $size = $this->TTFBBoxSize($this->legend_font['size'], 0,
+                                       $this->legend_font['font'], '_');
+            $char_w = $size[0];
+
+            $size = $this->TTFBBoxSize($this->legend_font['size'], 0,
+                                       $this->legend_font['font'], '|');
+            $char_h = $size[1];
+        }
+        // Fixed fonts:
+        else {
+            $char_w = $this->legend_font['width'];
+            $char_h = $this->legend_font['height'];
+        }
+
+        $v_margin = $char_h/2;                         // Between vertical borders and labels
+        $dot_height = $char_h + $this->line_spacing;   // Height of the small colored boxes
+        $width = $char_w * $max_len;
+
+        //////// Calculate box size
+        // upper Left
+        if ( (! $which_x1) || (! $which_y1) ) {
+            $box_start_x = $this->plot_area[2] - $width;
+            $box_start_y = $this->plot_area[1] + 5;
+        } else {
+            $box_start_x = $which_x1;
+            $box_start_y = $which_y1;
+        }
+
+        // Lower right corner
+        $box_end_y = $box_start_y + $dot_height*(count($this->legend)) + 2*$v_margin;
+        $box_end_x = $box_start_x + $width - 5;
+
+
+        // Draw outer box
+        ImageFilledRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y, $this->ndx_bg_color);
+        ImageRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y, $this->ndx_grid_color);
+
+        $color_index = 0;
+        $max_color_index = count($this->ndx_data_colors) - 1;
+
+        $dot_left_x = $box_end_x - $char_w * 2;
+        $dot_right_x = $box_end_x - $char_w;
+        $y_pos = $box_start_y + $v_margin;
+
+        foreach ($this->legend as $leg) {
+            // Text right aligned to the little box
+            $this->DrawText($this->legend_font, 0, $dot_left_x - $char_w, $y_pos,
+                            $this->ndx_text_color, $leg, 'right');
+            // Draw a box in the data color
+            ImageFilledRectangle($this->img, $dot_left_x, $y_pos + 1, $dot_right_x,
+                                 $y_pos + $dot_height-1, $this->ndx_data_colors[$color_index]);
+            // Draw a rectangle around the box
+            ImageRectangle($this->img, $dot_left_x, $y_pos + 1, $dot_right_x,
+                           $y_pos + $dot_height-1, $this->ndx_text_color);
+
+            $y_pos += $char_h + $this->line_spacing;
+
+            $color_index++;
+            if ($color_index > $max_color_index)
+                $color_index = 0;
+        }
+    } // Function DrawLegend()
+
+
+    /*!
+     * TODO Draws a legend over (or below) an axis of the plot.
+     */
+    function DrawAxisLegend()
+    {
+        // Calculate available room
+        // Calculate length of all items (boxes included)
+        // Calculate number of lines and room it would take. FIXME: this should be known in CalcMargins()
+        // Draw.
+    }
+
+/////////////////////////////////////////////
+////////////////////             PLOT DRAWING
+/////////////////////////////////////////////
+
+
+    /*!
+     * Draws a pie chart. Data has to be 'text-data' type.
+     *
+     *  This can work in two ways: the classical, with a column for each sector
+     *  (computes the column totals and draws the pie with that)
+     *  OR
+     *  Takes each row as a sector and uses it's first value. This has the added
+     *  advantage of using the labels provided, which is not the case with the
+     *  former method. This might prove useful for pie charts from GROUP BY sql queries
+     */
+    function DrawPieChart()
+    {
+        $xpos = $this->plot_area[0] + $this->plot_area_width/2;
+        $ypos = $this->plot_area[1] + $this->plot_area_height/2;
+        $diameter = min($this->plot_area_width, $this->plot_area_height);
+        $radius = $diameter/2;
+
+        // Get sum of each column? One pie slice per column
+        if ($this->data_type === 'text-data') {
+            for ($i = 0; $i < $this->num_data_rows; $i++) {
+                for ($j = 1; $j < $this->num_recs[$i]; $j++) {      // Label ($row[0]) unused in these pie charts
+                    @ $sumarr[$j] += abs($this->data[$i][$j]);      // NOTE!  sum > 0 to make pie charts
+                }
+            }
+        }
+        // Or only one column per row, one pie slice per row?
+        else if ($this->data_type == 'text-data-single') {
+            for ($i = 0; $i < $this->num_data_rows; $i++) {
+                $legend[$i] = $this->data[$i][0];                   // Set the legend to column labels
+                $sumarr[$i] = $this->data[$i][1];
+            }
+        }
+        else if ($this->data_type == 'data-data') {
+            for ($i = 0; $i < $this->num_data_rows; $i++) {
+                for ($j = 2; $j < $this->num_recs[$i]; $j++) {
+                    @ $sumarr[$j] += abs($this->data[$i][$j]);
+                }
+            }
+        }
+        else {
+            $this->DrawError("DrawPieChart(): Data type '$this->data_type' not supported.");
+            return FALSE;
+        }
+
+        $total = array_sum($sumarr);
+
+        if ($total == 0) {
+            $this->DrawError('DrawPieChart(): Empty data set');
+            return FALSE;
+        }
+
+        if ($this->shading) {
+            $diam2 = $diameter / 2;
+        } else {
+            $diam2 = $diameter;
+        }
+        $max_data_colors = count ($this->data_colors);
+
+        for ($h = $this->shading; $h >= 0; $h--) {
+            $color_index = 0;
+            $start_angle = 0;
+            $end_angle = 0;
+            foreach ($sumarr as $val) {
+                // For shaded pies: the last one (at the top of the "stack") has a brighter color:
+                if ($h == 0)
+                    $slicecol = $this->ndx_data_colors[$color_index];
+                else
+                    $slicecol = $this->ndx_data_dark_colors[$color_index];
+
+                $label_txt = number_format(($val / $total * 100), $this->y_precision, '.', ', ') . '%';
+                $val = 360 * ($val / $total);
+
+                // NOTE that imagefilledarc measures angles CLOCKWISE (go figure why),
+                // so the pie chart would start clockwise from 3 o'clock, would it not be
+                // for the reversal of start and end angles in imagefilledarc()
+                $start_angle = $end_angle;
+                $end_angle += $val;
+                $mid_angle = deg2rad($end_angle - ($val / 2));
+
+                // Draw the slice
+                ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
+                               360-$end_angle, 360-$start_angle,
+                               $slicecol, IMG_ARC_PIE);
+
+                // Draw the labels only once
+                if ($h == 0) {
+                    // Draw the outline
+                    if (! $this->shading)
+                        ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
+                                       360-$end_angle, 360-$start_angle,
+                                       $this->ndx_grid_color, IMG_ARC_PIE | IMG_ARC_EDGED |IMG_ARC_NOFILL);
+
+
+                    // The '* 1.2' trick is to get labels out of the pie chart so there are more
+                    // chances they can be seen in small sectors.
+                    $label_x = $xpos + ($diameter * 1.2 * cos($mid_angle)) * $this->label_scale_position;
+                    $label_y = $ypos+$h - ($diam2 * 1.2 * sin($mid_angle)) * $this->label_scale_position;
+
+                    $this->DrawText($this->generic_font, 0, $label_x, $label_y, $this->ndx_grid_color,
+                                    $label_txt, 'center', 'center');
+                }
+                $color_index++;
+                $color_index = $color_index % $max_data_colors;
+            }   // end for
+        }   // end for
+    }
+
+
+    /*!
+     * Supported data formats: data-data-error, text-data-error (doesn't exist yet)
+     * ( data comes in as array("title", x, y, error+, error-, y2, error2+, error2-, ...) )
+     */
+    function DrawDotsError()
+    {
+        if ($this->data_type != 'data-data-error') {
+            $this->DrawError("DrawDotsError(): Data type '$this->data_type' not supported.");
+            return FALSE;
+        }
+
+        // Suppress duplicate X data labels in linepoints mode; let DrawLinesError() do them.
+        $do_labels = ($this->plot_type != 'linepoints');
+
+        for($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $record = 1;                                // Skip record #0 (title)
+
+            $x_now = $this->data[$row][$record++];  // Read it, advance record index
+
+            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates.
+
+            // Draw X Data labels?
+            if ($this->x_data_label_pos != 'none' && $do_labels)
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+            // Now go for Y, E+, E-
+            for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
+                    // Y:
+                    $y_now = $this->data[$row][$record++];
+                    $this->DrawDot($x_now, $y_now, $idx, $this->ndx_data_colors[$idx]);
+
+                    // Error +
+                    $val = $this->data[$row][$record++];
+                    $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape,
+                                         $this->ndx_error_bar_colors[$idx]);
+                    // Error -
+                    $val = $this->data[$row][$record++];
+                    $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape,
+                                         $this->ndx_error_bar_colors[$idx]);
+            }
+        }
+    } // function DrawDotsError()
+
+
+    /*
+     * Supported data types:
+     *  - data-data ("title", x, y1, y2, y3, ...)
+     *  - text-data ("title", y1, y2, y3, ...)
+     */
+    function DrawDots()
+    {
+        $this->CheckOption($this->data_type, 'text-data, data-data', __FUNCTION__);
+
+        // Suppress duplicate X data labels in linepoints mode; let DrawLines() do them.
+        $do_labels = ($this->plot_type != 'linepoints');
+
+        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $rec = 1;                    // Skip record #0 (data label)
+
+            // Do we have a value for X?
+            if ($this->data_type == 'data-data')
+                $x_now = $this->data[$row][$rec++];  // Read it, advance record index
+            else
+                $x_now = 0.5 + $cnt++;       // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            $x_now_pixels = $this->xtr($x_now);
+
+            // Draw X Data labels?
+            if ($this->x_data_label_pos != 'none' && $do_labels)
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+            // Proceed with Y values
+            for($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) {
+                if (is_numeric($this->data[$row][$rec])) {              // Allow for missing Y data
+                    $this->DrawDot($x_now, $this->data[$row][$rec],
+                                   $idx, $this->ndx_data_colors[$idx]);
+                }
+            }
+        }
+    } //function DrawDots
+
+
+    /*!
+     * A clean, fast routine for when you just want charts like stock volume charts
+     */
+    function DrawThinBarLines()
+    {
+        $this->CheckOption($this->data_type, 'text-data, data-data', __FUNCTION__);
+
+        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $rec = 1;                    // Skip record #0 (data label)
+
+            // Do we have a value for X?
+            if ($this->data_type == 'data-data')
+                $x_now = $this->data[$row][$rec++];  // Read it, advance record index
+            else
+                $x_now = 0.5 + $cnt++;       // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            $x_now_pixels = $this->xtr($x_now);
+
+            // Draw X Data labels?
+            if ($this->x_data_label_pos != 'none')
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+            // Proceed with Y values
+            for($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) {
+                if (is_numeric($this->data[$row][$rec])) {              // Allow for missing Y data
+                    ImageSetThickness($this->img, $this->line_widths[$idx]);
+                    // Draws a line from user defined x axis position up to ytr($val)
+                    ImageLine($this->img, $x_now_pixels, $this->x_axis_y_pixels, $x_now_pixels,
+                              $this->ytr($this->data[$row][$rec]), $this->ndx_data_colors[$idx]);
+                }
+            }
+        }
+
+        ImageSetThickness($this->img, 1);
+    }  //function DrawThinBarLines
+
+    /*!
+     *
+     */
+    function DrawYErrorBar($x_world, $y_world, $error_height, $error_bar_type, $color)
+    {
+        /*
+        // TODO: add a parameter to show datalabels next to error bars?
+        // something like this:
+        if ($this->x_data_label_pos == 'plot') {
+            $this->DrawText($this->error_font, 90, $x1, $y2,
+                            $color, $label, 'center', 'top');
+        */
+
+        $x1 = $this->xtr($x_world);
+        $y1 = $this->ytr($y_world);
+        $y2 = $this->ytr($y_world+$error_height) ;
+
+        ImageSetThickness($this->img, $this->error_bar_line_width);
+        ImageLine($this->img, $x1, $y1 , $x1, $y2, $color);
+
+        switch ($error_bar_type) {
+        case 'line':
+            break;
+        case 'tee':
+            ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color);
+            break;
+        default:
+            ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color);
+            break;
+        }
+
+        ImageSetThickness($this->img, 1);
+        return TRUE;
+    }
+
+    /*!
+     * Draws a styled dot. Uses world coordinates.
+     * Supported types: 'halfline', 'line', 'plus', 'cross', 'rect', 'circle', 'dot',
+     * 'diamond', 'triangle', 'trianglemid'
+     */
+    function DrawDot($x_world, $y_world, $record, $color)
+    {
+        // TODO: optimize, avoid counting every time we are called.
+        $record = $record % count ($this->point_shapes);
+
+        $half_point = $this->point_sizes[$record] / 2;
+
+        $x_mid = $this->xtr($x_world);
+        $y_mid = $this->ytr($y_world);
+
+        $x1 = $x_mid - $half_point;
+        $x2 = $x_mid + $half_point;
+        $y1 = $y_mid - $half_point;
+        $y2 = $y_mid + $half_point;
+
+        switch ($this->point_shapes[$record]) {
+        case 'halfline':
+            ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color);
+            break;
+        case 'line':
+            ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
+            break;
+        case 'plus':
+            ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
+            ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
+            break;
+        case 'cross':
+            ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
+            ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
+            break;
+        case 'rect':
+            ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color);
+            break;
+        case 'circle':
+            ImageArc($this->img, $x_mid, $y_mid, $this->point_sizes[$record], $this->point_sizes[$record], 0, 360, $color);
+            break;
+        case 'dot':
+            ImageFilledArc($this->img, $x_mid, $y_mid, $this->point_sizes[$record], $this->point_sizes[$record], 0, 360,
+                           $color, IMG_ARC_PIE);
+            break;
+        case 'diamond':
+            $arrpoints = array( $x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2);
+            ImageFilledPolygon($this->img, $arrpoints, 4, $color);
+            break;
+        case 'triangle':
+            $arrpoints = array( $x1, $y_mid, $x2, $y_mid, $x_mid, $y2);
+            ImageFilledPolygon($this->img, $arrpoints, 3, $color);
+            break;
+        case 'trianglemid':
+            $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y_mid);
+            ImageFilledPolygon($this->img, $arrpoints, 3, $color);
+            break;
+        case 'none':
+            break;
+        default:
+            ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color);
+            break;
+        }
+        return TRUE;
+    }
+
+    /*!
+     * Draw an area plot. Supported data types:
+     *      'text-data'
+     *      'data-data'
+     * NOTE: This function used to add first and last data values even on incomplete
+     *       sets. That is not the behaviour now. As for missing data in between,
+     *       there are two posibilities: replace the point with one on the X axis (previous
+     *       way), or forget about it and use the preceding and following ones to draw the polygon.
+     *       There is the possibility to use both, we just need to add the method to set
+     *       it. Something like SetMissingDataBehaviour(), for example.
+     */
+    function DrawArea()
+    {
+        $incomplete_data_defaults_to_x_axis = FALSE;        // TODO: make this configurable
+
+        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $rec = 1;                                       // Skip record #0 (data label)
+
+            if ($this->data_type == 'data-data')            // Do we have a value for X?
+                $x_now = $this->data[$row][$rec++];         // Read it, advance record index
+            else
+                $x_now = 0.5 + $cnt++;                      // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates
+
+
+            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+            // Proceed with Y values
+            // Create array of points for imagefilledpolygon()
+            for($idx = 0; $rec < $this->num_recs[$row]; $rec++, $idx++) {
+                if (is_numeric($this->data[$row][$rec])) {              // Allow for missing Y data
+                    $y_now_pixels = $this->ytr($this->data[$row][$rec]);
+
+                    $posarr[$idx][] = $x_now_pixels;
+                    $posarr[$idx][] = $y_now_pixels;
+
+                    $num_points[$idx] = isset($num_points[$idx]) ? $num_points[$idx]+1 : 1;
+                }
+                // If there's missing data...
+                else {
+                    if (isset ($incomplete_data_defaults_to_x_axis)) {
+                        $posarr[$idx][] = $x_now_pixels;
+                        $posarr[$idx][] = $this->x_axis_y_pixels;
+                        $num_points[$idx] = isset($num_points[$idx]) ? $num_points[$idx]+1 : 1;
+                    }
+                }
+            }
+        }   // end for
+
+        $end = count($posarr);
+        for ($i = 0; $i < $end; $i++) {
+            // Prepend initial points. X = first point's X, Y = x_axis_y_pixels
+            $x = $posarr[$i][0];
+            array_unshift($posarr[$i], $x, $this->x_axis_y_pixels);
+
+            // Append final points. X = last point's X, Y = x_axis_y_pixels
+            $x = $posarr[$i][count($posarr[$i])-2];
+            array_push($posarr[$i], $x, $this->x_axis_y_pixels);
+
+            $num_points[$i] += 2;
+
+            // Draw the poligon
+            ImageFilledPolygon($this->img, $posarr[$i], $num_points[$i], $this->ndx_data_colors[$i]);
+        }
+
+    } // function DrawArea()
+
+
+    /*!
+     * Draw Lines. Supported data-types:
+     *      'data-data',
+     *      'text-data'
+     * NOTE: Please see the note regarding incomplete data sets on DrawArea()
+     */
+    function DrawLines()
+    {
+        // This will tell us if lines have already begun to be drawn.
+        // It is an array to keep separate information for every line, with a single
+        // variable we would sometimes get "undefined offset" errors and no plot...
+        $start_lines = array_fill(0, $this->records_per_group, FALSE);
+
+        if ($this->data_type == 'text-data') {
+            $lastx[0] = $this->xtr(0);
+            $lasty[0] = $this->xtr(0);
+        }
+
+        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $record = 1;                                    // Skip record #0 (data label)
+
+            if ($this->data_type == 'data-data')            // Do we have a value for X?
+                $x_now = $this->data[$row][$record++];      // Read it, advance record index
+            else
+                $x_now = 0.5 + $cnt++;                      // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates
+
+            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+                if (($line_style = $this->line_styles[$idx]) == 'none')
+                    continue; //Allow suppressing entire line, useful with linepoints
+                if (is_numeric($this->data[$row][$record])) {           //Allow for missing Y data
+                    $y_now_pixels = $this->ytr($this->data[$row][$record]);
+
+                    if ($start_lines[$idx] == TRUE) {
+                        // Set line width, revert it to normal at the end
+                        ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+                        if ($line_style == 'dashed') {
+                            $this->SetDashedStyle($this->ndx_data_colors[$idx]);
+                            ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
+                                      IMG_COLOR_STYLED);
+                        } else {
+                            ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
+                                      $this->ndx_data_colors[$idx]);
+                        }
+
+                    }
+                    $lasty[$idx] = $y_now_pixels;
+                    $lastx[$idx] = $x_now_pixels;
+                    $start_lines[$idx] = TRUE;
+                }
+                // Y data missing... should we leave a blank or not?
+                else if ($this->draw_broken_lines) {
+                    $start_lines[$idx] = FALSE;
+                }
+            }   // end for
+        }   // end for
+
+        ImageSetThickness($this->img, 1);       // Revert to original state for lines to be drawn later.
+    } // function DrawLines()
+
+
+    /*!
+     * Draw lines with error bars - data comes in as
+     *      array("label", x, y, error+, error-, y2, error2+, error2-, ...);
+     */
+    function DrawLinesError()
+    {
+        if ($this->data_type != 'data-data-error') {
+            $this->DrawError("DrawLinesError(): Data type '$this->data_type' not supported.");
+            return FALSE;
+        }
+
+        $start_lines = array_fill(0, $this->records_per_group, FALSE);
+
+        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $record = 1;                                    // Skip record #0 (data label)
+
+            $x_now = $this->data[$row][$record++];          // Read X value, advance record index
+
+            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates.
+
+
+            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+            // Now go for Y, E+, E-
+            for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
+                if (($line_style = $this->line_styles[$idx]) == 'none')
+                    continue; //Allow suppressing entire line, useful with linepoints
+                // Y
+                $y_now = $this->data[$row][$record++];
+                $y_now_pixels = $this->ytr($y_now);
+
+                if ($start_lines[$idx] == TRUE) {
+                    ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+                    if ($line_style == 'dashed') {
+                        $this->SetDashedStyle($this->ndx_data_colors[$idx]);
+                        ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
+                                  IMG_COLOR_STYLED);
+                    } else {
+                        ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
+                                  $this->ndx_data_colors[$idx]);
+                    }
+                }
+
+                // Error+
+                $val = $this->data[$row][$record++];
+                $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape,
+                                     $this->ndx_error_bar_colors[$idx]);
+
+                // Error-
+                $val = $this->data[$row][$record++];
+                $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape,
+                                     $this->ndx_error_bar_colors[$idx]);
+
+                // Update indexes:
+                $start_lines[$idx] = TRUE;   // Tells us if we already drew the first column of points,
+                                             // thus having $lastx and $lasty ready for the next column.
+                $lastx[$idx] = $x_now_pixels;
+                $lasty[$idx] = $y_now_pixels;
+            }   // end while
+        }   // end for
+
+        ImageSetThickness($this->img, 1);   // Revert to original state for lines to be drawn later.
+    }   // function DrawLinesError()
+
+
+
+    /*!
+     * This is a mere copy of DrawLines() with one more line drawn for each point
+     */
+    function DrawSquared()
+    {
+        // This will tell us if lines have already begun to be drawn.
+        // It is an array to keep separate information for every line, for with a single
+        // variable we could sometimes get "undefined offset" errors and no plot...
+        $start_lines = array_fill(0, $this->records_per_group, FALSE);
+
+        if ($this->data_type == 'text-data') {
+            $lastx[0] = $this->xtr(0);
+            $lasty[0] = $this->xtr(0);
+        }
+
+        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+            $record = 1;                                    // Skip record #0 (data label)
+
+            if ($this->data_type == 'data-data')            // Do we have a value for X?
+                $x_now = $this->data[$row][$record++];      // Read it, advance record index
+            else
+                $x_now = 0.5 + $cnt++;                      // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates
+
+            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); // notice there is no last param.
+
+            // Draw Lines
+            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+                if (is_numeric($this->data[$row][$record])) {               // Allow for missing Y data
+                    $y_now_pixels = $this->ytr($this->data[$row][$record]);
+
+                    if ($start_lines[$idx] == TRUE) {
+                        // Set line width, revert it to normal at the end
+                        ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+                        if ($this->line_styles[$idx] == 'dashed') {
+                            $this->SetDashedStyle($this->ndx_data_colors[$idx]);
+                            ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx],
+                                      IMG_COLOR_STYLED);
+                            ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels,
+                                      IMG_COLOR_STYLED);
+                        } else {
+                            ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx],
+                                      $this->ndx_data_colors[$idx]);
+                            ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels,
+                                      $this->ndx_data_colors[$idx]);
+                        }
+                    }
+                    $lastx[$idx] = $x_now_pixels;
+                    $lasty[$idx] = $y_now_pixels;
+                    $start_lines[$idx] = TRUE;
+                }
+                // Y data missing... should we leave a blank or not?
+                else if ($this->draw_broken_lines) {
+                    $start_lines[$idx] = FALSE;
+                }
+            }
+        }   // end while
+
+        ImageSetThickness($this->img, 1);
+    } // function DrawSquared()
+
+
+    /*!
+     * Data comes in as array("title", x, y, y2, y3, ...)
+     */
+    function DrawBars()
+    {
+        if ($this->data_type != 'text-data') {
+            $this->DrawError('DrawBars(): Bar plots must be text-data: use function SetDataType("text-data")');
+            return FALSE;
+        }
+
+        // This is the X offset from the bar group's label center point to the left side of the first bar
+        // in the group. See also CalcBarWidths above.
+        $x_first_bar = (($this->records_per_group - 1) * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
+
+        for ($row = 0; $row < $this->num_data_rows; $row++) {
+            $record = 1;                                    // Skip record #0 (data label)
+
+            $x_now_pixels = $this->xtr(0.5 + $row);         // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+            // Lower left X of first bar in the group:
+            $x1 = $x_now_pixels - $x_first_bar;
+
+            // Draw the bars in the group:
+            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+                if (is_numeric($this->data[$row][$record])) {       // Allow for missing Y data
+                    $x2 = $x1 + $this->actual_bar_width;
+
+                    if ($this->data[$row][$record] < $this->x_axis_position) {
+                        $y1 = $this->x_axis_y_pixels;
+                        $y2 = $this->ytr($this->data[$row][$record]);
+                        $upgoing_bar = False;
+                    } else {
+                        $y1 = $this->ytr($this->data[$row][$record]);
+                        $y2 = $this->x_axis_y_pixels;
+                        $upgoing_bar = True;
+                    }
+
+                    // Draw the bar
+                    ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $this->ndx_data_colors[$idx]);
+
+                    if ($this->shading) {                           // Draw the shade?
+                        ImageFilledPolygon($this->img, array($x1, $y1,
+                                                       $x1 + $this->shading, $y1 - $this->shading,
+                                                       $x2 + $this->shading, $y1 - $this->shading,
+                                                       $x2 + $this->shading, $y2 - $this->shading,
+                                                       $x2, $y2,
+                                                       $x2, $y1),
+                                           6, $this->ndx_data_dark_colors[$idx]);
+                    }
+                    // Or draw a border?
+                    else {
+                        ImageRectangle($this->img, $x1, $y1, $x2,$y2, $this->ndx_data_border_colors[$idx]);
+                    }
+
+                    // Draw optional data labels above the bars (or below, for negative values).
+                    if ( $this->y_data_label_pos == 'plotin') {
+                        if ($upgoing_bar) {
+                          $v_align = 'top';
+                          $y_offset = -5 - $this->shading;
+                        } else {
+                          $v_align = 'bottom';
+                          $y_offset = 2;
+                        }
+                        $this->DrawDataLabel('', NULL, $row+0.5, $this->data[$row][$record], '',
+                                $this->data[$row][$record], 'center', $v_align,
+                                ($idx + 0.5) * $this->record_bar_width - $x_first_bar, $y_offset);
+                    }
+
+                }
+                // Step to next bar in group:
+                $x1 += $this->record_bar_width;
+            }   // end for
+        }   // end for
+    } //function DrawBars
+
+
+    /*!
+     * Data comes in as array("title", x, y, y2, y3, ...)
+     * \note Original stacked bars idea by Laurent Kruk < lolok at users.sourceforge.net >
+     */
+    function DrawStackedBars()
+    {
+        if ($this->data_type != 'text-data') {
+            $this->DrawError('DrawStackedBars(): Bar plots must be text-data: use SetDataType("text-data")');
+            return FALSE;
+        }
+
+        // This is the X offset from the bar's label center point to the left side of the bar.
+        $x_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap;
+
+        for ($row = 0; $row < $this->num_data_rows; $row++) {
+            $record = 1;                                    // Skip record #0 (data label)
+
+            $x_now_pixels = $this->xtr(0.5 + $row);         // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
+                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+            // Lower left and lower right X of the bars in this group:
+            $x1 = $x_now_pixels - $x_first_bar;
+            $x2 = $x1 + $this->actual_bar_width;
+
+            // Draw the bars
+            $oldv = 0;
+            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+                if (is_numeric($this->data[$row][$record])) {       // Allow for missing Y data
+
+                    $y1 = $this->ytr(abs($this->data[$row][$record]) + $oldv);
+                    $y2 = $this->ytr($this->x_axis_position + $oldv);
+                    $oldv += abs($this->data[$row][$record]);
+
+                    // Draw the bar
+                    ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $this->ndx_data_colors[$idx]);
+
+                    if ($this->shading) {                           // Draw the shade?
+                        ImageFilledPolygon($this->img, array($x1, $y1,
+                                                       $x1 + $this->shading, $y1 - $this->shading,
+                                                       $x2 + $this->shading, $y1 - $this->shading,
+                                                       $x2 + $this->shading, $y2 - $this->shading,
+                                                       $x2, $y2,
+                                                       $x2, $y1),
+                                           6, $this->ndx_data_dark_colors[$idx]);
+                    }
+                    // Or draw a border?
+                    else {
+                        ImageRectangle($this->img, $x1, $y1, $x2,$y2, $this->ndx_data_border_colors[$idx]);
+                    }
+                }
+            }   // end for
+        }   // end for
+    } //function DrawStackedBars
+
+
+    /*!
+     *
+     */
+    function DrawGraph()
+    {
+        if (! $this->img) {
+            $this->DrawError('DrawGraph(): No image resource allocated');
+            return FALSE;
+        }
+
+        if (empty($this->data) || ! is_array($this->data)) {
+            $this->DrawError("DrawGraph(): No data array");
+            return FALSE;
+        }
+
+        if (! isset($this->data_limits_done))
+            $this->FindDataLimits();                // Get maxima and minima for scaling
+
+        if ($this->total_records == 0) {            // Check for empty data sets
+            $this->DrawError('Empty data set');
+            return FALSE;
+        }
+
+        $this->CalcMargins();                       // Calculate margins
+
+        if (! isset($this->plot_area_width)) {      // Set plot area pixel values (plot_area[])
+            if ($this->plot_type == 'pie') {
+                // Pie charts can maximize image space usage.
+                $this->SetPlotAreaPixels($this->safe_margin, $this->title_height + $this->safe_margin,
+                                         $this->image_width - $this->safe_margin,
+                                         $this->image_height - $this->safe_margin);
+            } else {
+                $this->SetPlotAreaPixels();
+            }
+        }
+
+        if (! isset($this->plot_max_y))             // Set plot area world values (plot_max_x, etc.)
+            $this->SetPlotAreaWorld();
+
+        /* FIXME!!  this sort of thing should not be done without user's consent
+        if ($this->x_data_label_pos != 'none') {    // Default: do not draw tick stuff if
+            $this->x_tick_label_pos = 'none';       // there are data labels.
+            $this->x_tick_pos = 'none';
+        }
+        */
+        $this->PadArrays();                         // Pad color and style arrays to fit records per group.
+
+        $this->DrawBackground();
+
+        $this->DrawImageBorder();
+
+        $this->DrawPlotAreaBackground();
+
+        $this->DrawTitle();
+        $this->DrawXTitle();
+        $this->DrawYTitle();
+
+        // Pie charts are drawn differently, handle them first
+        if ($this->plot_type == 'pie') {
+            $this->DrawPieChart();
+
+            if ($this->legend)
+                $this->DrawLegend($this->legend_x_pos, $this->legend_y_pos, '');
+
+            if ($this->print_image)
+                $this->PrintImage();
+
+            return;
+        }
+
+        ////// All other chart types:
+
+        if (! $this->grid_at_foreground) {         // Usually one wants grids to go back, but...
+            $this->DrawYAxis();     // Y axis must be drawn before X axis (see DrawYAxis())
+            $this->DrawXAxis();
+        }
+
+        switch ($this->plot_type) {
+        case 'thinbarline':
+            $this->DrawThinBarLines();
+            break;
+        case 'area':
+            $this->DrawArea();
+            break;
+        case 'squared':
+            $this->DrawSquared();
+            break;
+        case 'lines':
+            if ( $this->data_type == 'data-data-error') {
+                $this->DrawLinesError();
+            } else {
+                $this->DrawLines();
+            }
+            break;
+        case 'linepoints':
+            if ( $this->data_type == 'data-data-error') {
+                $this->DrawLinesError();
+                $this->DrawDotsError();
+            } else {
+                $this->DrawLines();
+                $this->DrawDots();
+            }
+            break;
+        case 'points';
+            if ( $this->data_type == 'data-data-error') {
+                $this->DrawDotsError();
+            } else {
+                $this->DrawDots();
+            }
+            break;
+        case 'stackedbars':
+            $this->CalcBarWidths();
+            $this->DrawStackedBars();
+            break;
+        case 'bars':
+        default:
+            $this->plot_type = 'bars';  // Set it if it wasn't already set. (necessary?)
+            $this->CalcBarWidths();
+            $this->DrawBars();
+            break;
+        }   // end switch
+
+        if ($this->grid_at_foreground) {         // Usually one wants grids to go back, but...
+            $this->DrawYAxis();     // Y axis must be drawn before X axis (see DrawYAxis())
+            $this->DrawXAxis();
+        }
+
+        $this->DrawPlotBorder();
+
+        if ($this->legend)
+            $this->DrawLegend($this->legend_x_pos, $this->legend_y_pos, '');
+
+        if ($this->print_image)
+            $this->PrintImage();
+
+    } //function DrawGraph()
+
+/////////////////////////////////////////////
+//////////////////         DEPRECATED METHODS
+/////////////////////////////////////////////
+
+    /*!
+     * Deprecated, use SetYTickPos()
+     */
+    function SetDrawVertTicks($which_dvt)
+    {
+        if ($which_dvt != 1)
+            $this->SetYTickPos('none');
+        return TRUE;
+    }
+
+    /*!
+     * Deprecated, use SetXTickPos()
+     */
+    function SetDrawHorizTicks($which_dht)
+    {
+        if ($which_dht != 1)
+           $this->SetXTickPos('none');
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated Use SetNumXTicks()
+     */
+    function SetNumHorizTicks($n)
+    {
+        return $this->SetNumXTicks($n);
+    }
+
+    /*!
+     * \deprecated Use SetNumYTicks()
+     */
+    function SetNumVertTicks($n)
+    {
+        return $this->SetNumYTicks($n);
+    }
+
+    /*!
+     * \deprecated Use SetXTickIncrement()
+     */
+    function SetHorizTickIncrement($inc)
+    {
+        return $this->SetXTickIncrement($inc);
+    }
+
+
+    /*!
+     * \deprecated Use SetYTickIncrement()
+     */
+    function SetVertTickIncrement($inc)
+    {
+        return $this->SetYTickIncrement($inc);
+    }
+
+    /*!
+     * \deprecated Use SetYTickPos()
+     */
+    function SetVertTickPosition($which_tp)
+    {
+        return $this->SetYTickPos($which_tp);
+    }
+
+    /*!
+     * \deprecated Use SetXTickPos()
+     */
+    function SetHorizTickPosition($which_tp)
+    {
+        return $this->SetXTickPos($which_tp);
+    }
+
+    /*!
+     * \deprecated Use SetFont()
+     */
+    function SetTitleFontSize($which_size)
+    {
+        return $this->SetFont('title', $which_size);
+    }
+
+    /*!
+     * \deprecated Use SetFont()
+     */
+    function SetAxisFontSize($which_size)
+    {
+        $this->SetFont('x_label', $which_size);
+        $this->SetFont('y_label', $which_size);
+    }
+
+    /*!
+     * \deprecated Use SetFont()
+     */
+    function SetSmallFontSize($which_size)
+    {
+        return $this->SetFont('generic', $which_size);
+    }
+
+    /*!
+     * \deprecated Use SetFont()
+     */
+    function SetXLabelFontSize($which_size)
+    {
+        return $this->SetFont('x_title', $which_size);
+    }
+
+    /*!
+     * \deprecated Use SetFont()
+     */
+    function SetYLabelFontSize($which_size)
+    {
+        return $this->SetFont('y_title', $which_size);
+    }
+
+    /*!
+     * \deprecated Use SetXTitle()
+     */
+    function SetXLabel($which_xlab)
+    {
+        return $this->SetXTitle($which_xlab);
+    }
+
+    /*!
+     * \deprecated Use SetYTitle()
+     */
+    function SetYLabel($which_ylab)
+    {
+        return $this->SetYTitle($which_ylab);
+    }
+
+    /*!
+     * \deprecated This is now an Internal function - please set width and
+     *             height via PHPlot() upon object construction
+     */
+    function SetImageArea($which_iw, $which_ih)
+    {
+        $this->image_width = $which_iw;
+        $this->image_height = $which_ih;
+
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated Use SetXTickLength() and SetYTickLength() instead.
+     */
+    function SetTickLength($which_tl)
+    {
+        $this->SetXTickLength($which_tl);
+        $this->SetYTickLength($which_tl);
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated  Use SetYLabelType()
+     */
+    function SetYGridLabelType($which_yglt)
+    {
+        return $this->SetYLabelType($which_yglt);
+    }
+
+    /*!
+     * \deprecated  Use SetXLabelType()
+     */
+    function SetXGridLabelType($which_xglt)
+    {
+        return $this->SetXLabelType($which_xglt);
+    }
+    /*!
+     * \deprecated Use SetYTickLabelPos()
+     */
+    function SetYGridLabelPos($which_yglp)
+    {
+        return $this->SetYTickLabelPos($which_yglp);
+    }
+    /*!
+     * \deprecated Use SetXTickLabelPos()
+     */
+    function SetXGridLabelPos($which_xglp)
+    {
+        return $this->SetXTickLabelPos($which_xglp);
+    }
+
+
+    /*!
+     * \deprecated Use SetXtitle()
+     */
+    function SetXTitlePos($xpos)
+    {
+        $this->x_title_pos = $xpos;
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated Use SetYTitle()
+     */
+    function SetYTitlePos($xpos)
+    {
+        $this->y_title_pos = $xpos;
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated  Use DrawDots()
+     */
+    function DrawDotSeries()
+    {
+        $this->DrawDots();
+    }
+
+    /*!
+     * \deprecated Use SetXLabelAngle()
+     */
+    function SetXDataLabelAngle($which_xdla)
+    {
+        return $this->SetXLabelAngle($which_xdla);
+    }
+
+    /*!
+     * Draw Labels (not grid labels) on X Axis, following data points. Default position is
+     * down of plot. Care must be taken not to draw these and x_tick_labels as they'd probably overlap.
+     *
+     * \deprecated Use SetXDataLabelPos()
+     */
+    function SetDrawXDataLabels($which_dxdl)
+    {
+        if ($which_dxdl == '1' )
+            $this->SetXDataLabelPos('plotdown');
+        else
+            $this->SetXDataLabelPos('none');
+    }
+
+    /*!
+     * \deprecated This method was intended to improve performance by being specially
+     * written for 'data-data'. However, the improvement didn't pay. Use DrawLines() instead
+     */
+    function DrawLineSeries()
+    {
+        return $this->DrawLines();
+    }
+
+    /*!
+     * \deprecated Calculates maximum X-Axis label height. Now inside CalcMargins()
+     */
+    function CalcXHeights()
+    {
+        // TTF
+        if ($this->use_ttf) {
+            $xstr = str_repeat('.', $this->max_t);
+            $size = $this->TTFBBoxSize($this->x_label_font['size'], $this->x_label_angle,
+                                       $this->x_label_font['font'], $xstr);
+            $this->x_tick_label_height = $size[1];
+        }
+        // Fixed font
+        else { // For Non-TTF fonts we can have only angles 0 or 90
+            if ($this->x_label_angle == 90)
+                $this->x_tick_label_height = $this->max_t * $this->x_label_font['width'];
+            else
+                $this->x_tick_label_height = $this->x_label_font['height'];
+        }
+
+        return TRUE;
+    }
+
+
+    /*!
+     * \deprecated Calculates Maximum Y-Axis tick label width. Now inside CalcMargins()
+     */
+    function CalcYWidths()
+    {
+        //the "." is for space. It isn't actually printed
+        $ylab = number_format($this->max_y, $this->y_precision, '.', ', ') . $this->data_units_text . '.';
+
+        // TTF
+        if ($this->use_ttf) {
+            // Maximum Y tick label width
+            $size = $this->TTFBBoxSize($this->y_label_font['size'], 0, $this->y_label_font['font'], $ylab);
+            $this->y_tick_label_width = $size[0];
+
+        }
+        // Fixed font
+        else {
+            // Y axis title width
+            $this->y_tick_label_width = strlen($ylab) * $this->y_label_font['width'];
+        }
+
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated Superfluous.
+     */
+    function DrawLabels()
+    {
+        $this->DrawTitle();
+        $this->DrawXTitle();
+        $this->DrawYTitle();
+    }
+
+    /*!
+     * Set up the image resource 'img'
+     * \deprecated The constructor should init 'img'
+     */
+    function InitImage()
+    {
+        $this->img = ImageCreate($this->image_width, $this->image_height);
+
+        if (! $this->img)
+            $this->PrintError('InitImage(): Could not create image resource');
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated
+     */
+    function SetNewPlotAreaPixels($x1, $y1, $x2, $y2)
+    {
+        //Like in GD 0, 0 is upper left set via pixel Coordinates
+        $this->plot_area = array($x1, $y1, $x2, $y2);
+        $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0];
+        $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1];
+        $this->y_top_margin = $this->plot_area[1];
+
+        if (isset($this->plot_max_x))
+            $this->CalcTranslation();
+
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated Use _SetRGBColor()
+     */
+    function SetColor($which_color)
+    {
+        $this->SetRGBColor($which_color);
+        return TRUE;
+    }
+
+    /*
+     * \deprecated Use SetLineWidths().
+     */
+    function SetLineWidth($which_lw)
+    {
+
+        $this->SetLineWidths($which_lw);
+
+        if (!$this->error_bar_line_width) {
+            $this->SetErrorBarLineWidth($which_lw);
+        }
+        return TRUE;
+    }
+
+    /*!
+     * \deprecated
+     */
+    function DrawDashedLine($x1, $y1, $x2, $y2 , $dash_length, $dash_space, $color)
+    {
+        if ($dash_length)
+            $dashes = array_fill(0, $dash_length, $color);
+        else
+            $dashes = array();
+        if ($dash_space)
+            $spaces = array_fill(0, $dash_space, IMG_COLOR_TRANSPARENT);
+        else
+            $spaces = array();
+
+        $style = array_merge($dashes, $spaces);
+        ImageSetStyle($this->img, $style);
+        ImageLine($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
+    }
+
+    /*!
+     * \deprecated Selects an input file to be used as background for the whole graph.
+     * This resizes the graph to the image's size.
+     */
+    function SetInputFile($which_input_file)
+    {
+        $size = GetImageSize($which_input_file);
+        $input_type = $size[2];
+
+        switch($input_type) {
+        case 1:
+            $im = @ ImageCreateFromGIF ($which_input_file);
+            if (!$im) { // See if it failed
+                $this->PrintError("Unable to open $which_input_file as a GIF");
+                return FALSE;
+            }
+        break;
+        case 3:
+            $im = @ ImageCreateFromPNG ($which_input_file);
+            if (!$im) { // See if it failed
+                $this->PrintError("Unable to open $which_input_file as a PNG");
+                return FALSE;
+            }
+        break;
+        case 2:
+            $im = @ ImageCreateFromJPEG ($which_input_file);
+            if (!$im) { // See if it failed
+                $this->PrintError("Unable to open $which_input_file as a JPG");
+                return FALSE;
+            }
+        break;
+        default:
+            $this->PrintError('SetInputFile(): Please select gif, jpg, or png for image type!');
+            return FALSE;
+        break;
+        }
+
+        // Set Width and Height of Image
+        $this->image_width = $size[0];
+        $this->image_height = $size[1];
+
+        // Deallocate any resources previously allocated
+        if (isset($this->img))
+            imagedestroy($this->img);
+
+        $this->img = $im;
+
+        // Do not overwrite the input file with the background color.
+        $this->background_done = TRUE;
+
+        return TRUE;
+
+    }
+
+
+    /*
+     * \deprecated Use SetPointShapes().
+     */
+    function SetPointShape($which_pt)
+    {
+        $this->SetPointShapes($which_pt);
+        return TRUE;
+    }
+
+    /*
+     * \deprecated Use SetPointSizes().
+     */
+    function SetPointSize($which_ps)
+    {
+        $this->SetPointSizes($which_ps);
+        return TRUE;
+    }
+}  // class PHPlot
+
+
+
+////////////////////////
+
+
+/*!
+ * Pads an array with another or with itself.
+ *  \param arr array  Original array (reference)
+ *  \param size int   Size of the resulting array.
+ *  \param arr2 array If specified, array to use for padding. If unspecified, pad with $arr.
+ */
+function array_pad_array(&$arr, $size, $arr2=NULL)
+{
+    if (! is_array($arr2)) {
+        $arr2 = $arr;                           // copy the original array
+    }
+    while (count($arr) < $size)
+        $arr = array_merge_php4($arr, $arr2);        // append until done
+}
+
+/*!
+ * Fixes problem with array_merge() in PHP5.
+ * \note I simply copied this from a bug report. I am not running php5 yet, so
+ *       I cannot reproduce it, which is why I trust the reporter.
+ */
+function array_merge_php4($array1,$array2)
+{
+    $return=array();
+
+    foreach(func_get_args() as $arg){
+        if(!is_array($arg)){
+        $arg=array($arg);
+        }
+        foreach($arg as $key=>$val){
+            if(!is_int($key)){
+                $return[$key]=$val;
+            }else{
+                $return[]=$val;
+            }
+        }
+    }
+    return $return;
+ }
+
+
+
+
+?>
Index: /sandbox/workflow/branches/993/inc/class.Paging.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.Paging.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.Paging.inc.php	(revision 795)
@@ -0,0 +1,321 @@
+<?php
+/*
+ * Created on 02/07/2006
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+*/
+/**
+ * Database query results paging class
+ * @author Sidnei Augusto Drovetto Junior
+ * @version 1.0
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class Paging
+{
+	/**
+	 * @var int $itemsPerPage Number of page itens 
+	 * @access public
+	 */
+	var $itemsPerPage;
+	/**
+	 * @var int $itemsCount Number of itens
+	 * @access public
+	 */
+	var $itemsCount;
+	/**
+	 * @var int $numberOfPages Total pages
+	 * @access public
+	 */
+	var $numberOfPages;
+	/**
+	 * @var int $currentPage  Actual page
+	 * @access public
+	 */
+	var $currentPage;
+	/**
+	 * @var array $items itens array
+	 * @access public
+	 */
+	var $items;
+    /**
+	 * @var string $baseLink  server Url base
+	 * @access public
+	 */
+	var $baseLink;
+	/**
+	 * @var $newRequest
+	 * @access public
+	 */
+	var $newRequest;
+	/**
+	 * @var int $nextItem number of next item
+	 * @access public
+	 */
+	var $nextItem;
+	/**
+	 * @var int $originalRequest
+	 * @access public
+	 */
+	var $originalRequest;
+
+	/**
+	 * @var string $SQLOrdenacao
+	 * @access public
+	 */
+	var $SQLOrdenacao;
+	/**
+	 * Initialize class Paging atributes
+	 * @acces public 
+	 * 	@return void
+ 	 */
+	function initialize()
+	{
+		$this->currentPage = 0;
+		$this->baseLink = $_SERVER['SCRIPT_NAME'];
+		$this->items = array();
+
+		if (!is_null($this->originalRequest))
+			$this->parseRequest($this->originalRequest);
+	}
+	/**
+	 * Construtor 
+	 * @access public
+	 * @return object
+ 	 */
+	function Paging($pItemsPerPage, $request = null)
+	{
+		$this->itemsPerPage = $pItemsPerPage;
+		$this->originalRequest = $request;
+
+		$this->initialize();
+	}
+	/**
+	 * Parse Request
+	 * @param string $request request
+	 * @return void
+	 */
+	function parseRequest($request)
+	{
+		$this->currentPage = (isset($request['p_page'])) ? $request['p_page'] : 0;
+		if (is_numeric($this->currentPage))
+			$this->currentPage = (int) $this->currentPage;
+		else
+			$this->currentPage = 0;
+
+		$this->newRequest = $this->_cleanRequest("p_page", $request);
+
+		$this->nextItem = $this->currentPage * $this->itemsPerPage;
+	}
+	/**
+	 * Restrict the number of itens 
+	 * @var array $pItems array of page itens 
+	 * @var int   $totalItems number of total items
+	 * @return array page items
+	 * @access public
+	 */
+	function restrictItems($pItems, $totalItems = null)
+	{
+		$start = $this->nextItem;
+		if (is_null($totalItems))
+		{
+			$totalItems = count($pItems);
+			$end = min($start + $this->itemsPerPage, $totalItems);
+			$this->items = array();
+			for ($i = $start; $i < $end; $i++)
+				$this->items[] = $pItems[$i];
+		}
+		else
+			$this->items = $pItems;
+
+		$this->itemsCount = $totalItems;
+		return $this->items;
+	}
+    /**
+	 * Return  pagination Result
+	 * @return array 
+	 * @access public
+	 */
+	function paginationResult()
+	{
+		$this->numberOfPages = ceil(((double) $this->itemsCount / (double) $this->itemsPerPage));
+		$output = array();
+		if ($this->numberOfPages < 2)
+			return $output;
+
+		$charSeparator = empty($this->newRequest) ? "" : "&amp;";
+
+		for ($i = 0; $i < $this->numberOfPages; $i++)
+		{
+			$page = $i;
+			$start = ($i * $this->itemsPerPage) + 1;
+			$end = min($start - 1 + $this->itemsPerPage, $this->itemsCount);
+			$current = array(
+				"link" => $this->baseLink . "?" . $this->newRequest . $charSeparator . "p_page=$page",
+				"pageNumber" => $page + 1,
+				"p_page" => $page,
+				"start" => $start,
+				"end" => $end);
+			$output[] = $current;
+		}
+
+		return $output;
+	}
+    /**
+	 * Limit pagination result
+	 * @var int $numberofLinks number of links 
+	 * @access public
+	 * @return array
+	 */
+	function limitedPaginationResult($numberOfLinks)
+	{
+		$allPaginationResults = $this->paginationResult();
+		$output = array();
+		if (count($allPaginationResults) == 0)
+			return $output;
+
+		$firstPage = max(0, $this->currentPage - $numberOfLinks);
+		$lastPage = min($this->currentPage + $numberOfLinks, $this->numberOfPages);
+		for ($i = $firstPage; $i < $lastPage; $i++)
+			$output[] = $allPaginationResults[$i];
+
+		return $output;
+	}
+    /**
+	 * Pagination Result navigation 
+	 * @access public
+	 * @return array
+	 */
+	function paginationResultNavigation()
+	{
+		$allPaginationResults = $this->paginationResult();
+
+		$output = array();
+		$output['currentPage'] = $this->currentPage + 1;
+
+		if (($this->currentPage > 0) && isset($allPaginationResults[$this->currentPage - 1]))
+			$output['previous'] = $allPaginationResults[$this->currentPage - 1];
+
+		if (($this->currentPage < ($this->numberOfPages - 1)) && isset($allPaginationResults[$this->currentPage + 1]))
+			$output['next'] = $allPaginationResults[$this->currentPage + 1];
+
+		return $output;
+	}
+    /**
+	 * Common Links 
+	 * @var int $numberOfLinks number of links
+	 * @return array $links array of common links 
+	 * @access public
+	 */
+	function commonLinks($numberOfLinks = 10)
+	{
+		$links = array();
+		$paginationLinks = $this->limitedPaginationResult($numberOfLinks);
+		$paginationNavigationLinks = $this->paginationResultNavigation();
+
+		if (count($paginationLinks) == 0)
+			return $links;
+		if (isset($paginationNavigationLinks['previous']))
+		{
+			$tmp = $paginationNavigationLinks['previous'];
+			$tmp['name'] = "anterior";
+			$tmp['do_link'] = true;
+			$links[] = $tmp;
+		}
+
+		for ($i = 0; $i < count($paginationLinks); $i++)
+		{
+			$tmp = $paginationLinks[$i];
+			$tmp['name'] = $tmp['pageNumber'];
+			$tmp['do_link'] = ($paginationNavigationLinks['currentPage'] != $tmp['pageNumber']) ? true : false;
+			$links[] = $tmp;
+		}
+
+		if (isset($paginationNavigationLinks['next']))
+		{
+			$tmp = $paginationNavigationLinks['next'];
+			$tmp['name'] = "próximo";
+			$tmp['do_link'] = true;
+			$links[] = $tmp;
+		}
+
+		return $links;
+	}
+	
+    /**
+	 * Page Autolinks 
+	 * @var int $numberOfLinks number of links
+	 * @var string $linkFormat link format
+	 * @var string $selectedFormat 
+	 * @var string $separator separator
+	 * @var int $totalItems number of total items 
+	 * @access public
+	 */
+	function autoLinks($numberOfLinks = 10, $linkFormat = null, $selectedFormat = null, $separator = " ")
+	{
+		$output = "";
+		$linkList = $this->commonLinks($numberOfLinks);
+
+		if (is_null($linkFormat))
+			$linkFormat = '<a href="%link%">%name%</a>';
+
+		if (is_null($selectedFormat))
+			$selectedFormat = '<strong>%name%</strong>';
+
+		$correspondenceList = array(
+			'%name%' => 'name',
+			'%link%' => 'link',
+			'%pageNumber%' => 'pageNumber',
+			'%p_page%' => 'p_page',
+			'%start%' => 'start',
+			'%end%' => 'end');
+
+		$tmp = array();
+
+		foreach ($linkList as $link)
+		{
+			$format = $link['do_link'] ? $linkFormat : $selectedFormat;
+			foreach ($correspondenceList as $find => $index)
+				$format = str_replace($find, $link[$index], $format);
+			$tmp[] = $format;
+		}
+
+		$output = implode($separator, $tmp);
+
+		return $output;
+	}
+
+    /**
+	 * Clean Request
+	 * @var string $remove
+	 * @var string $request
+	 * @return string 
+	 * @access public
+	 */
+	function _cleanRequest($remove = "", $request = null)
+	{
+    	if (is_null($request))
+        	$request = $_GET;
+	    if (!is_array($remove))
+    	    $remove = array($remove);
+
+	    $tmp = array();
+    	$flagAdd = true;
+
+		/* remove selected variables from posted data */
+	    foreach ($request as $key => $value)
+    	{
+        	$flagAdd = true;
+
+	        foreach ($remove as $rem)
+    	        if (strcasecmp($key, $rem) == 0)
+        	        $flagAdd = false;
+
+	        if ($flagAdd)
+    	        $tmp[] = $key . "=" . urlencode("$value");
+	    }
+    	return implode("&amp;", $tmp);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_orgchart.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_orgchart.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_orgchart.inc.php	(revision 2372)
@@ -0,0 +1,201 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                 *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php');
+
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Mauricio Luiz Viani - viani@celepar.pr.gov.br
+ */
+class ui_orgchart extends ui_ajaxinterface
+{
+	/**
+	 * @var array $public_functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'draw'	=> true,
+		'graph'	=> true
+	);
+	/**
+	 * @var array $workflow_acl
+	 * @access public
+	 */
+	var $workflow_acl;
+	/**
+	 * Construtor
+	 * @access public
+	 */
+	function ui_orgchart()
+	{
+	}
+	/**
+	 * Draw the orgchart admin interface
+	 * @return void
+	 * @access public
+	 */
+	function draw($tab_index = "")
+	{
+		$this->workflow_acl = Factory::getInstance('workflow_acl');
+
+		$isAdmin = $this->workflow_acl->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']);
+		$isOrgchartManager = $this->workflow_acl->checkUserGroupAccessToType('ORG', $GLOBALS['phpgw_info']['user']['account_id']);
+
+		if (!($isAdmin || $isOrgchartManager))
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_orgchart');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => false, 'nonavbar' => false, 'currentapp' => 'workflow');
+		$smarty = Factory::getInstance('workflow_smarty');
+
+		$this->set_wf_session();
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','orgchart', 'main');
+		$javaScripts .= $this->get_js_link('workflow','orgchart', 'utils');
+		$javaScripts .= $this->get_js_link('workflow','orgchart', 'organization');
+		$javaScripts .= $this->get_js_link('workflow','orgchart', 'organizations');
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'lightbox');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'participants');
+
+		$css = $this->get_common_css();
+		$css .= $this->get_css_link('orgchart');
+		$css .= $this->get_css_link('lightbox');
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang('loading'));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('tabIndex', $tab_index);
+		$smarty->assign('css', $css);
+		$smarty->display('orgchart.tpl');
+	}
+
+	/**
+	 * Show the graph
+	 * @access public
+	 * @return void 
+	 */
+	function graph()
+	{
+		if (!isset($_GET['organizationID']))
+			die();
+		$organizationID = $_GET['organizationID'];
+		if (is_numeric($organizationID))
+			$organizationID = (int) $organizationID;
+		else
+			die();
+
+		$config_values = Factory::getInstance('config', 'workflow');
+		$config_values->read_repository();
+		$conf_db = $config_values->config_data;
+		$db = Factory::getInstance('db');
+		$db->connect(
+			$conf_db['database_name'],
+			$conf_db['database_host'],
+			$conf_db['database_port'],
+			$conf_db['database_admin_user'],
+			$conf_db['database_admin_password'],
+			$conf_db['database_type']
+		);
+		$db = $db->Link_ID;
+		$attributes = array();
+		$attributes['ranksep'] = '1.5 equally';
+		$attributes['rankdir'] = 'LR';
+		$graph = &Factory::getInstance('Process_GraphViz', true, $attributes);
+
+
+		/**
+		 * Get Hierarchical Area
+		 * @param organizationID 
+		 * @param $parent 
+		 * @param $depth
+		 * @param $db
+		 * @param $graph
+		 * @return 
+		 */
+		function getHierarchicalArea($organizationID, $parent, $depth, $db, $graph)
+		{
+			/* orgchart graph configuration */
+			$color='black';
+			$fillcolor='lightblue2'; //blue TLS values
+			$fontsize = '10';
+			$color = '0.25,1,0.28'; #dark green in TLS values
+			$arrowsize = 0.8;
+
+			if (is_null($parent))
+				$result = $db->query("SELECT area_id, sigla, titular_funcionario_id FROM area WHERE (superior_area_id IS NULL) AND (organizacao_id = ?) AND (ativa = 'S') ORDER BY sigla", array($organizationID));
+			else
+				$result = $db->query("SELECT area_id, sigla, titular_funcionario_id FROM area WHERE (superior_area_id = ?) AND (ativa = 'S') ORDER BY sigla", array($parent));
+
+			$output = $result->GetArray(-1);
+
+			if (is_null($parent) && (count($output) == 0))
+				return false;
+
+			$ldap = &Factory::getInstance('WorkflowLDAP');
+			for ($i = 0; $i < count($output); $i++)
+			{
+				for ($j = 0; $j < $result->_numOfFields; $j++)
+					unset($output[$i][$j]);
+				if ($output[$i]['titular_funcionario_id'] != '')
+				{
+					$supervisor = $ldap->getName($output[$i]['titular_funcionario_id']);
+					$supervisor = str_replace(array(" da ", " de ", " do ", " das ", " dos "), " ", $supervisor);
+					$supervisorArray = explode(' ', $supervisor);
+					$supervisorName = '';
+					for ($j = 0; $j < count($supervisorArray); $j++)
+						$supervisorName .= (($j == 0) || ($j == count($supervisorArray) - 1)) ? $supervisorArray[$j] . ' ' : $supervisorArray[$j][0] . '. ';
+					$supervisorName = trim(str_replace("Junior", "Jr", $supervisorName));
+				}
+				else
+					$supervisorName = '';
+				/* add the area box */
+				$graph->addNode($output[$i]['area_id'],array(
+					'URL'		=> $output[$i]['area_id'],
+					'label'		=> $output[$i]['sigla'] . '\n' . $supervisorName,
+					'shape'		=> 'box',
+					'color'		=> $color,
+					'fillcolor'	=> $fillcolor,
+					'style'		=> 'filled',
+					'fontsize'	=> $fontsize,
+					'fontname'	=> 'serif'
+					)
+				);
+
+				/* add the conection between areas */
+				if (!is_null($parent))
+					$graph->addEdge(array($parent => $output[$i]['area_id']), array('color'=>$color,arrowsize=>$arrowsize));
+				$output[$i]['children'] = getHierarchicalArea($organizationID, $output[$i]['area_id'], $depth + 1, $db, $graph);
+				$output[$i]['depth'] = $depth;
+			}
+
+			return $output;
+		}
+
+
+		$result = getHierarchicalArea($organizationID, null, 0, $db, $graph);
+		if ($result !== false)
+			$graph->image('png', '/tmp/grafico');
+			else
+				die();
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_editor.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_editor.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_editor.inc.php	(revision 2372)
@@ -0,0 +1,268 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+ * @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
+ */
+class bo_editor extends bo_ajaxinterface
+{	
+	/**
+	 *  Contructor
+	 *  @access public
+	 *  @return object
+	 */
+	function bo_editor() {
+		parent::bo_ajaxinterface();		
+	}
+	/**
+	 *  Get the source
+	 *  @param string $proc_name process name
+	 *  @param string $file_name file name
+	 *  @param string $type type 
+	 *  @access public
+	 *  @return string source data
+	 */
+	function get_source($proc_name, $file_name, $type)
+    {
+		if ((strpos($file_name,'/') !== false) || (strpos($file_name,'/') !== false))
+			exit(0);
+		if ((strpos($proc_name,'/') !== false) || (strpos($proc_name,'/') !== false))
+			exit(0);
+
+        switch($type)
+        {
+            case 'atividade':
+                $path =  'activities' . SEP . $file_name;
+				$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+                break;
+            case 'template':
+                $path =  'templates' . SEP . $file_name;
+				$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+                break;
+            case 'include':
+                $path = $file_name;
+				$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+                break;
+            case 'resource':
+				$complete_path = GALAXIA_PROCESSES . '/' . $proc_name . '/resources/' . $file_name;
+                break;
+		}
+		if (!file_exists($complete_path))
+			exit(0);
+        
+		if (!$file_size = filesize($complete_path)) return '';
+        $fp = fopen($complete_path, 'r');
+        $data = fread($fp, $file_size);
+        fclose($fp);
+
+		//if ($type != 'template') 
+		//{
+			$data = str_replace("\r", "", $data);
+			$data = str_replace("\\", "\\\\", $data);
+			$data = str_replace("\n", "\\n", $data);
+			$data = str_replace('"', '" +String.fromCharCode(34)+ "', $data);
+			$data = str_replace('\'', '" +String.fromCharCode(39)+ "', $data);
+			$data = str_replace('<', '" +String.fromCharCode(60)+ "', $data);
+			$data = str_replace('>', '" +String.fromCharCode(62)+ "', $data);
+			//$data = addslashes($data);
+			$data = str_replace("\t", "\\t", $data);
+			//$data = str_replace("\n", "\\n", $data);
+		//}
+		
+        return $data;
+    }
+	/**
+	 *  Save the source
+	 *  @param string $proc_name process name
+	 *  @param string $file_name file name
+	 *  @param string $type type 
+	 *  @param string $source 
+	 *  @access public
+	 *  @return string
+	 */
+	function save_source($proc_name, $file_name, $type, $source)
+    {
+		if ((strpos($file_name,'/') !== false) || (strpos($file_name,'/') !== false))
+			return 'Não foi possível executar a operação solicitada';
+		if ((strpos($proc_name,'/') !== false) || (strpos($proc_name,'/') !== false))
+			return 'Não foi possível executar a operação solicitada';
+
+        // in case code was filtered
+        //if (!$source) $source = @$GLOBALS['egw_unset_vars']['_POST[source]'];
+
+        switch($type)
+        {
+            case 'atividade':
+                $path =  'activities' . SEP . $file_name;
+        		$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+                break;
+            case 'template':
+                $path = 'templates' . SEP . $file_name;
+        		$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+                break;
+            case 'include':
+                $path = $file_name;
+        		$complete_path = GALAXIA_PROCESSES . SEP . $proc_name . SEP . 'code' . SEP . $path;
+                break;
+            case 'resource':
+				$complete_path = GALAXIA_PROCESSES . '/' . $proc_name . '/resources/' . $file_name;
+                break;
+        }
+
+        // In case you want to be warned when source code is changed:
+        // mail('yourmail@domain.com', 'source changed', "PATH: $complete_path \n\n SOURCE: $source");
+        
+		$erro = false;
+		if ($fp = fopen($complete_path, 'w')) 
+		{
+        	$erro = !fwrite($fp, $source); 
+        	fclose($fp);
+		}
+		else
+		{
+			$erro = true;
+		}
+
+		return ($erro ? 'Erro ao salvar o arquivo.' : 'Arquivo salvo com sucesso.');
+    }
+
+	/**
+	 *  Check process
+	 * 
+	 *  @param integer $pid pid
+	 *  @param  object $activity_manager 
+	 *  @param string $error_str error string  
+	 *  @access public
+	 *  @return string
+	 */
+	function check_process($pid, &$activity_manager, &$error_str)
+    {
+        $valid = $activity_manager->validate_process_activities($pid);
+        if (!$valid)
+        {
+            $errors = $activity_manager->get_error(true);
+            $error_str = '<b>Os seguintes items devem ser corrigidos para ativar o processo:</b>';
+            foreach ($errors as $error)
+            {
+				if (strlen($error) > 0) 
+				{
+                	$error_str .= '<li>'. $error . '<br/>';
+				}
+            }
+            $error_str .= '</ul></small>';
+            return 'n';
+        }
+        else
+        {
+            $error_str = '';
+            return 'y';
+        }
+    }
+    
+	/**
+	 *  Save template source
+	 * 
+	 *  @param array $p process 
+	 *  @access public
+	 *  @return string
+	 */
+	function save_template_source($p)
+	{
+		
+		$proc_name = $p['proc_name'];
+		$file_name = $p['file_name'];
+		$type      = $p['tipo_codigo'];
+		$source    = $p['code'];
+		$msg       = array();
+
+		$msg[] = $this->save_source($p['proc_name'],$p['file_name'], $p['tipo_codigo'], $p['code']);
+		
+		return implode('<br />',$msg);
+	}
+	/**
+	 *  Save resource
+	 * 
+	 *  @param array $p process 
+	 *  @access public
+	 *  @return string
+	 */
+	function save_resource($p)
+	{
+		
+		$proc_name = $p['proc_name'];
+		$file_name = $p['file_name'];
+		$type      = $p['tipo_codigo'];
+		$source    = $p['code'];
+		$msg       = array();
+
+		$msg[] = $this->save_source($p['proc_name'],$p['file_name'], $p['tipo_codigo'], $p['code']);
+		
+		return implode('<br />',$msg);
+	}
+	/**
+	 *  Save php souurce
+	 * 
+	 *  @param array $p process 
+	 *  @access public
+	 *  @return string
+	 */
+	function save_php_source($p)
+	{
+		$proc_name = $p['proc_name'];
+		$file_name = $p['file_name'];
+		$type      = $p['tipo_codigo'];
+		$source    = $p['code'];
+		$msg       = array();
+		$error_str = '';
+
+		$msg[] = $this->save_source($p['proc_name'],$p['file_name'], $p['tipo_codigo'], $p['code']);
+
+		if ($p['tipo_codigo'] != 'include')
+		{
+			$activity_manager   = &Factory::newInstance('ActivityManager');
+
+			if ($this->check_process($p['proc_id'], &$activity_manager, &$error_str) == 'n')
+				$msg[] = $error_str;
+		}
+
+		return implode('<br />',$msg);
+	}
+
+	/**
+	 *  Check syntax
+	 * 
+	 *  @param array $p process 
+	 *  @access public
+	 *  @return string
+	 */
+	function check_syntax($p) 
+	{
+		$code   = $p['code'];
+		$errors = "Check syntax failed.";
+		$fp = fopen('/tmp/check_syn.tmp', 'w'); 
+       	if ($fp) {
+			fwrite($fp, $code); 
+			$errors = `php -l /tmp/check_syn.tmp`;
+			$errors = str_replace("in /tmp/check_syn.tmp","",$errors);
+			$errors = str_replace("parsing /tmp/check_syn.tmp","parsing file",$errors);
+			$errors = str_replace("/tmp/check_syn.tmp","",$errors);
+       		fclose($fp);
+       		unlink('/tmp/check_syn.tmp');
+		}
+		return $errors;
+	}
+
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_monitors.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_monitors.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_monitors.inc.php	(revision 2372)
@@ -0,0 +1,95 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php');
+/**
+ * @package Workflow
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ */
+class ui_monitors extends ui_ajaxinterface
+{
+	/**
+	 * @var $public_functions public functions
+	 * @access public
+	 */
+	var $public_functions = array(
+		'form'	=> true
+	);
+
+	/**
+	 * @var $workflow_acl object for check access rights of workflow
+	 * @access public
+	 */
+	var $workflow_acl;
+
+	function ui_monitors()
+	{
+		$this->set_wf_session();
+		$this->workflow_acl = Factory::getInstance('workflow_acl');
+
+		if (!($this->workflow_acl->checkUserGroupAccessToType('MON', $_SESSION['phpgw_info']['workflow']['account_id']) || ($this->workflow_acl->checkWorkflowAdmin($_SESSION['phpgw_info']['workflow']['account_id']))))
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+	}
+
+	/**
+	 * Draw the interface
+	 * @access public
+	 */
+	function form()
+	{
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('%1 monitoring');
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => false, 'nonavbar' => false, 'currentapp' => 'workflow');
+		$smarty = Factory::getInstance('workflow_smarty');
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','jscalendar', 'calendar');
+		$javaScripts .= $this->get_js_link('workflow','jscalendar', 'calendar-br');
+		$javaScripts .= $this->get_js_link('workflow','jscalendar', 'calendar-setup');
+		$javaScripts .= $this->get_js_link('workflow','jscalendar', 'calendar-input');
+		$javaScripts .= $this->get_js_link('workflow','monitors', 'general');
+		$javaScripts .= $this->get_js_link('workflow','monitors', 'processes');
+		$javaScripts .= $this->get_js_link('workflow','monitors', 'instances');
+		$javaScripts .= $this->get_js_link('workflow','monitors', 'properties');
+		$javaScripts .= $this->get_js_link('workflow','monitors', 'filters');
+		$javaScripts .= $this->get_js_link('workflow','monitors', 'massActions');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'inbox_actions');
+		$javaScripts .= $this->get_js_link('workflow','userinterface', 'common_functions');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'participants');
+		$javaScripts .= $this->get_js_link('workflow','nano', 'JSON');
+		$javaScripts .= $this->get_js_link('workflow','scriptaculous', 'lightbox');
+
+		$css = $this->get_common_css();
+		$css .= $this->get_css_link('monitors');
+		$css .= $this->get_css_link('lightbox');
+		$css .= '<link rel="stylesheet" type="text/css" media="all" href="workflow/js/jscalendar/calendar-blue.css">';
+
+		$tabs = array('Processos');
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->assign('tabs', $tabs);
+		$smarty->display('monitors.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.ui_adminaccess.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.ui_adminaccess.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.ui_adminaccess.inc.php	(revision 2372)
@@ -0,0 +1,93 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once(dirname(__FILE__) . SEP . 'class.ui_ajaxinterface.inc.php');
+
+/**
+* Monta a interface inicial da Lista de Controle de Acesso
+*
+* @package Workflow
+* @author Rodrigo Daniel C de Lira - rodrigo.lira@gmail.com
+* @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+* @license http://www.gnu.org/copyleft/gpl.html GPL
+*/
+class ui_adminaccess extends ui_ajaxinterface
+{
+	/**
+	* Relaciona os métodos públicos da classe
+	*
+	* @var array $public_functions
+	* @access private
+	*/
+	var $public_functions = array(
+		'form'	=> true,
+	);
+
+	/**
+	* Verifica permissão do usuário atual para rodar a lista de controle de acesso
+	* Caso não tenha permissão, emite mensagem e encerra execução
+	*
+	* @return void
+	* @access public
+	*/
+	function ui_adminaccess()
+	{
+		if (!Factory::getInstance('workflow_acl')->checkWorkflowAdmin($GLOBALS['phpgw_info']['user']['account_id']))
+		{
+			$GLOBALS['phpgw']->common->phpgw_header();
+			echo parse_navbar();
+			echo lang('access not permitted');
+			$GLOBALS['phpgw']->log->message('F-Abort, Unauthorized access to workflow.ui_adminprocesses');
+			$GLOBALS['phpgw']->log->commit();
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+	}
+
+	/**
+	* Monta a página inicial da interface de controle de acesso, a partir do template, e
+	* executa o método inicial JavaScript para preencher dadas
+	*
+	* @return void
+	* @access public
+	*/
+	function form()
+	{
+		$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['workflow']['title'] . ' - ' . lang('Access Control List');
+		$GLOBALS['phpgw_info']['flags'] = array('noheader' => false, 'nonavbar' => false, 'currentapp' => 'workflow');
+		$smarty = Factory::getInstance('workflow_smarty');
+
+		$javaScripts = $this->get_common_js();
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'prototype');
+		$javaScripts .= $this->get_js_link('workflow','adminaccess', 'main');
+		$javaScripts .= $this->get_js_link('workflow','adminaccess', 'control_folder');
+		$javaScripts .= $this->get_js_link('workflow','jscode', 'participants');
+
+		$css = $this->get_common_css();
+
+		$tabs = array(
+			'Administração',
+			'Desenvolvimento',
+			'Organograma',
+			'Processos',
+			'Monitoramento',
+			'Aplicações Externas'
+		);
+
+		$smarty->assign('header', $smarty->expressoHeader);
+		$smarty->assign('footer', $smarty->expressoFooter);
+		$smarty->assign('txt_loading', lang("loading"));
+		$smarty->assign('javaScripts', $javaScripts);
+		$smarty->assign('css', $css);
+		$smarty->assign('tabs', $tabs);
+		$smarty->display('adminaccess.tpl');
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.Thread.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.Thread.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/inc/class.Thread.inc.php	(revision 795)
@@ -0,0 +1,171 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/**
+ * Classe que implementa, de forma simples, uma thread
+ * @package Workflow
+ * @author Brian W. Bosh
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com (minor modifications)
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class Thread
+{
+	/**
+	 * @var resource $processReference Referência ao processo em execução
+	 * @access private
+	 */
+	private $processReference;
+
+	/**
+	 * @var array $pipes Pipes do processo
+	 * @access private
+	 */
+	private $pipes;
+
+	/**
+	 * @var string $buffer Buffer da saída padrão
+	 * @access private
+	 */
+	private $buffer;
+
+	/**
+	 * @var float $timeStart Início da execução do processo (em microsegundos)
+	 * @access private
+	 */
+	private $timeStart;
+
+	/**
+	 * @var float $timeEnd Fim da execução do processo (em microsegundos)
+	 * @access private
+	 */
+	private $timeEnd;
+
+	/**
+	 * Construtor da classe Thread
+	 * @param string $file O arquivo PHP que será executado
+	 * @return object Objeto da classe Thread
+	 * @access public
+	 */
+	public function Thread($file)
+	{
+		$this->timeEnd = null;
+		$this->timeStart = microtime(true);
+		$this->buffer = '';
+		$this->pipes = array();
+
+		$descriptor = array(
+			0 => array('pipe', 'r'),
+			1 => array('pipe', 'w'),
+			2 => array('pipe', 'w')
+		);
+
+		$this->processReference = proc_open("php -q {$file} ", $descriptor, $this->pipes);
+		stream_set_blocking($this->pipes[1], 0);
+	}
+
+	/**
+	 * Indica se o processo está ativo ou não
+	 * @return bool Indica se o processo está ativo (true) ou não (false)
+	 * @access public
+	 */
+	public function isActive()
+	{
+		$this->buffer .= $this->listen();
+		$f = stream_get_meta_data($this->pipes[1]);
+		return !$f['eof'];
+	}
+
+	/**
+	 * Libera o recurso do processo (só deve ser chamado quando o processo não estiver mais ativo)
+	 * @return int O código de saída do processo
+	 * @access public
+	 */
+	public function close()
+	{
+		$this->timeEnd = microtime(true);
+		fclose($this->pipes[0]);
+		fclose($this->pipes[1]);
+		fclose($this->pipes[2]);
+		$output = proc_close($this->processReference);
+		$this->processReference = NULL;
+		return $output;
+	}
+
+	/**
+	 * Mata o processo
+	 * @return int O código de finalização do processo
+	 * @access public
+	 */
+	public function kill()
+	{
+		$this->timeEnd = microtime(true);
+		fclose($this->pipes[0]);
+		fclose($this->pipes[1]);
+		fclose($this->pipes[2]);
+		$output = proc_terminate($this->processReference);
+		$this->processReference = null;
+		return $output;
+	}
+
+	/**
+	 * Envia mensagens ao processo
+	 * @param string $thought A mensagem a ser enviada
+	 * @return void
+	 * @access public
+	 */
+	public function tell($thought)
+	{
+		fwrite($this->pipes[0], $thought);
+	}
+
+	/**
+	 * Lê o buffer da saída padrão do processo
+	 * @return string O conteúdo do buffer da saída padrão
+	 * @access public
+	 */
+	public function listen()
+	{
+		$buffer = $this->buffer;
+		$this->buffer = '';
+		while ($r = fgets($this->pipes[1], 1024))
+			$buffer .= $r;
+
+		return $buffer;
+	}
+
+	/**
+	 * Lê o buffer da saída de erro do processo
+	 * @return string O conteúdo do buffer da saída de erro
+	 * @access public
+	 */
+	public function getError()
+	{
+		$buffer = '';
+		while ($r = fgets($this->pipes[2], 1024))
+			$buffer .= $r;
+
+		return $buffer;
+	}
+
+	/**
+	 * Informa o tempo de execução do processo (até o momento)
+	 * @return float O tempo de execução do processo
+	 * @access public
+	 */
+	public function getExecutionTime()
+	{
+		if (!is_null($this->timeEnd))
+			return $this->timeEnd - $this->timeStart;
+		else
+			return microtime(true) - $this->timeStart;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/inc/class.bo_external_applications.inc.php
===================================================================
--- /sandbox/workflow/branches/993/inc/class.bo_external_applications.inc.php	(revision 2372)
+++ /sandbox/workflow/branches/993/inc/class.bo_external_applications.inc.php	(revision 2372)
@@ -0,0 +1,107 @@
+<?php
+
+/**************************************************************************\
+* eGroupWare                                                               *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+require_once('class.bo_ajaxinterface.inc.php');
+/**
+ * Camada Business das Aplicações Externas.
+ * @package Workflow
+ * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GPL
+ */
+class bo_external_applications extends bo_ajaxinterface
+{
+	/**
+	 * @var object Acesso à camada Model das Aplicações Externas.
+	 * @access private
+	 */
+	private $so;
+
+	/**
+	 * Construtor da classe so_orgchart
+	 * @return object
+	 */
+	function bo_external_applications()
+	{
+		parent::bo_ajaxinterface();
+		$this->so = &Factory::getInstance('so_external_applications');
+	}
+
+	/**
+	 * Lista todas as aplicações externas
+	 * @return array Lista de aplicações externas
+	 * @access public
+	 */
+	function getExternalApplications()
+	{
+		$result = $this->so->getExternalApplications();
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Busca informações sobre uma aplicação externa
+	 * @param array $params Uma array contendo os parâmetros necessários para encontrar as informações de uma aplicação externa (Ajax)
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário
+	 * @access public
+	 */
+	function getExternalApplication($params)
+	{
+		$result = $this->so->getExternalApplication((int) $params['external_application_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Adiciona uma aplicação externa
+	 * @param array $params Uma array contendo os parâmetros necessários para adicionar uma aplicação externa (Ajax)
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário
+	 * @access public
+	 */
+	function addExternalApplication($params)
+	{
+		$result = $this->so->addExternalApplication($params['name'], $params['description'], $params['address'], $params['image'], $params['authentication'], $params['post'], $params['intranet_only']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Atualiza uma aplicação externa
+	 * @param array $params Uma array contendo os parâmetros necessários para atualizar uma aplicação externa (Ajax)
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário
+	 * @access public
+	 */
+	function updateExternalApplication($params)
+	{
+		$result = $this->so->updateExternalApplication($params['external_application_id'], $params['name'], $params['description'], $params['address'], $params['image'], $params['authentication'], $params['post'], $params['remove_current_image'], $params['intranet_only']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+
+	/**
+	 * Remove uma aplicação externa
+	 * @param array $params Uma array contendo os parâmetros necessários para remover uma aplicação externa (Ajax)
+	 * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário
+	 * @access public
+	 */
+	function removeExternalApplication($params)
+	{
+		$result = $this->so->removeExternalApplication((int) $params['external_application_id']);
+		$this->disconnect_all();
+
+		return $result;
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/js/jquery/jquery-1.2.6.js
===================================================================
--- /sandbox/workflow/branches/993/js/jquery/jquery-1.2.6.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jquery/jquery-1.2.6.js	(revision 795)
@@ -0,0 +1,32 @@
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
+ * $Rev: 5685 $
+ */
+(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
+return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
+return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
+selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}return values;}else
+return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
+this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
+return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
+jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){var src=target[name],copy=options[name];if(target===copy)continue;if(deep&&copy&&typeof copy=="object"&&!copy.nodeType)target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);else if(copy!==undefined)target[name]=copy;}return target;};var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
+script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){var name,i=0,length=object.length;if(args){if(length==undefined){for(name in object)if(callback.apply(object[name],args)===false)break;}else
+for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
+for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
+jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i<stack.length;i++)if(color(stack[i])){swap[i]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";for(i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem+='';if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
+ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&&notxml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else
+while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
+while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!=null)ret[ret.length]=value;}return ret.concat.apply([],ret);}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
+for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i<args.length)jQuery.event.proxy(fn,args[i++]);return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;event.preventDefault();return args[this.lastToggle++].apply(this,arguments)||false;}));},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
+jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(typeof url!='string')return this._load(url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else
+xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
+jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
+for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
+s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
+e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();
Index: /sandbox/workflow/branches/993/js/experience/experience.panorama.js
===================================================================
--- /sandbox/workflow/branches/993/js/experience/experience.panorama.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/experience/experience.panorama.js	(revision 795)
@@ -0,0 +1,703 @@
+/* -------------------------------------------------------------------------- *
+ *   Experience Javascript Library (version 1.0b)
+ *  (c) 2007 Ahmed Saad <ahmeds@users.sourceforge.net>
+ *
+ *  Experience is freely distributable under the terms of an MIT-style license.
+ *  For details, see project website at http://experience.sf.net
+ * -------------------------------------------------------------------------- */
+
+// Panorama component
+experience.panorama  =  {
+
+    Version : '0.2',
+
+    //// MNEMONICS ////////////////////////////////////////////
+
+    ZOOM_IN : 1,
+    ZOOM_OUT : -1,
+    ZOOM_RESTORE_SIZE : 0,
+    MOVE_DOWN : 1,
+    MOVE_UP :  2,
+    MOVE_RIGHT : 3,
+    MOVE_LEFT : 4,
+
+    Viewer : function(userParams) {
+    
+        //// PRIVATE FIELDS //////////////////////////////////////
+
+        this.Params = $H({
+            ZoomFactor : 0.05, // %
+            MoveBy : 2, // px
+            MoveRate :  15, // ms
+            ReversePanning : false,
+            ReverseScrolling : true, 
+            InnerUpperOffset : 40, // px 
+            ShowStatus : true, 
+            ShowNavigator : true,
+            ShowZoomSelectBox : true,
+            IconDirectory : 'icons',
+            IconExtension : '.gif', 
+            RenderIn: null // an element or an id
+        }),
+
+        this.isBeingDragged = false;
+        this.lastLeft = this.lastTop = this.lastX = this.lastY = null;
+        this.originalWidth = this.originalHeight = null;
+        this.timeOutId = null;
+        this.isMaximizedInstance = false;
+        this.onFullWindowListeners = [];
+        this.onUnFullWindowListeners = [];
+
+        //// PUBLIC METHODS //////////////////////////////////////////////////////
+
+        this.show = experience.panorama.show;
+        this.hide = experience.panorama.hide;
+        this.setImage = experience.panorama.setImage;
+        this.getImage = experience.panorama.getImage;
+        this.addOnFullWindowListener = experience.panorama.addOnFullWindowListener;
+        this.removeOnFullWindowListener = experience.panorama.removeOnFullWindowListener;
+        this.addOnUnFullWindowListener = experience.panorama.addOnUnFullWindowListener;
+        this.removeOnUnFullWindowListener = experience.panorama.removeOnUnFullWindowListener;
+
+        //// PRIVATE METHODS /////////////////////////////////////////////////////
+
+        this.getImageResource = experience.panorama.getImageResource;
+        this.positionImage = experience.panorama.positionImage;
+        this.positionCanvas = experience.panorama.positionCanvas;
+        this.setStatus = experience.panorama.setStatus;
+        this.fireListeners = experience.panorama.fireListeners;
+
+        //// VALIDATION //////////////////////////////////////////////////////////
+
+        if (
+              typeof(userParams['ImageURL']) != 'undefined' &&
+              (
+                typeof(userParams['ImageWidth']) == 'undefined' || 
+                typeof(userParams['ImageHeight']) == 'undefined'
+              )
+           )
+        {
+            throw new Error("Experience::Panorama: You have to specify ImageWidth and ImageHeight when calling " +
+                              "initialize() passing an ImageURL");
+        }
+
+        //// INITIALIZATION /////////////////////////////////////////////
+
+        this.Params.merge(userParams);
+        
+        // construct canvas and all
+        this.canvas = document.createElement('div');
+        this.canvas.className = "panoramaCanvas";
+        this.canvas.style.cursor = experience.panorama.getGrabCursor();
+        this.positionCanvas(this.Params.RenderIn != null);
+
+        // A queue for childern to be added to the canvas
+        var childernQueue = [];
+
+
+        var closeImg = this.closeImg  = document.createElement('img');
+        closeImg.className = 'panoramaCloseIcon';
+        closeImg.title = experience.tr("Close", experience.panorama.Locales);
+        
+        if (this.Params.RenderIn){
+            Event.observe(closeImg, 'click', experience.panorama.toggleFullWindow.bindAsEventListener(this));
+            closeImg.src = this.getImageResource('go_fullwindow');
+            closeImg.title = closeImg.alt = experience.tr("Go Full-Window", experience.panorama.Locales);
+        } else {
+            Event.observe(closeImg, 'click', experience.panorama.hide.bindAsEventListener(this));
+            closeImg.src = this.getImageResource('close');
+            closeImg.title = closeImg.alt = experience.tr("Close", experience.panorama.Locales);
+        }
+
+        childernQueue.push(closeImg);
+
+        var aboutIcon = document.createElement('img');
+        aboutIcon.className = 'panoramaAboutIcon';
+        aboutIcon.src = this.getImageResource('about');
+        aboutIcon.title = aboutIcon.alt = experience.tr("Help", experience.panorama.Locales);
+        Event.observe(aboutIcon, 'click', experience.panorama.showHelp.bindAsEventListener(this));
+        childernQueue.push(aboutIcon);
+
+        
+        var zoomInIcon = document.createElement('img');
+        zoomInIcon.className = 'panoramaZoomInIcon';
+        zoomInIcon.src = this.getImageResource('zoom_in');
+        zoomInIcon.title = zoomInIcon.alt = experience.tr("Zoom In", experience.panorama.Locales);
+        Event.observe(zoomInIcon, 'click', 
+                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_IN));
+        childernQueue.push(zoomInIcon);
+
+      
+        var zoomOutIcon = document.createElement('img');
+        zoomOutIcon.className = 'panoramaZoomOutIcon';
+        zoomOutIcon.src = this.getImageResource('zoom_out');;
+        zoomOutIcon.title = zoomOutIcon.alt = experience.tr("Zoom Out", experience.panorama.Locales);
+        Event.observe(zoomOutIcon, 'click', 
+                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_OUT));
+        childernQueue.push(zoomOutIcon);
+        
+
+        var restoreSizeIcon = document.createElement('img');
+        restoreSizeIcon.className = 'panoramaRestoreSizeIcon';
+        restoreSizeIcon.src = this.getImageResource('restore_size');;
+        restoreSizeIcon.title = restoreSizeIcon.alt =  
+                experience.tr("Restore Original Size", experience.panorama.Locales);
+         Event.observe(restoreSizeIcon, 'click', 
+                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_RESTORE_SIZE));
+        childernQueue.push(restoreSizeIcon);
+
+
+
+        var restorePositionIcon = document.createElement('img');
+        restorePositionIcon.className = 'panoramaRestorePositionIcon';
+        restorePositionIcon.src = this.getImageResource('restore_position');
+        restorePositionIcon.title = restorePositionIcon.alt = 
+            experience.tr("Restore Original Position", experience.panorama.Locales);
+        Event.observe(restorePositionIcon, 'click', 
+            experience.panorama.positionImage.bindAsEventListener(this));
+        childernQueue.push(restorePositionIcon);
+      
+
+        if (this.Params.ShowNavigator){
+
+            var goDownIcon = document.createElement('img');
+            goDownIcon.className = 'panoramaGoDownIcon';
+            goDownIcon.src = this.getImageResource('go_down');
+            goDownIcon.title = goDownIcon.alt =  
+                experience.tr("Scrolling .. ", experience.panorama.Locales);
+            Event.observe(goDownIcon, 'mouseover', 
+                experience.panorama.move.bindAsEventListener(this, 
+                    this.Params.ReverseScrolling? experience.panorama.MOVE_UP : experience.panorama.MOVE_DOWN));
+            Event.observe(goDownIcon, 'mouseout', 
+                experience.panorama.clearMoveTimeout.bindAsEventListener(this));
+            childernQueue.push(goDownIcon);
+            
+            var goUpIcon = document.createElement('img');
+            goUpIcon.className = 'panoramaGoUpIcon';
+            goUpIcon.src = this.getImageResource('go_up');
+            goUpIcon.title = goUpIcon.alt = 
+                experience.tr("Scrolling .. ", experience.panorama.Locales);
+            Event.observe(goUpIcon, 'mouseover', 
+                experience.panorama.move.bindAsEventListener(this, 
+                    this.Params.ReverseScrolling? experience.panorama.MOVE_DOWN : experience.panorama.MOVE_UP));
+            Event.observe(goUpIcon, 'mouseout', 
+                experience.panorama.clearMoveTimeout.bindAsEventListener(this));
+            childernQueue.push(goUpIcon);
+            
+
+            var goRightIcon = document.createElement('img');
+            goRightIcon.className = 'panoramaGoRightIcon';
+            goRightIcon.src = this.getImageResource('go_right');
+            goRightIcon.title = goRightIcon.alt = experience.tr("Scrolling .. ", experience.panorama.Locales);
+            Event.observe(goRightIcon, 'mouseover', experience.panorama.move.bindAsEventListener(this, 
+                    this.Params.ReverseScrolling? experience.panorama.MOVE_LEFT : experience.panorama.MOVE_RIGHT));
+            Event.observe(goRightIcon, 'mouseout', 
+                    experience.panorama.clearMoveTimeout.bindAsEventListener(this));
+            childernQueue.push(goRightIcon);
+            
+
+            var goLeftIcon = document.createElement('img');
+            goLeftIcon.className = 'panoramaGoLeftIcon';
+            goLeftIcon.src = this.getImageResource('go_left');
+            goLeftIcon.title = goLeftIcon.alt =  
+                    experience.tr("Scrolling .. ", experience.panorama.Locales);
+            Event.observe(goLeftIcon, 'mouseover', 
+                    experience.panorama.move.bindAsEventListener(this, 
+                        this.Params.ReverseScrolling? experience.panorama.MOVE_RIGHT : experience.panorama.LEFT));
+            Event.observe(goLeftIcon, 'mouseout', 
+                    experience.panorama.clearMoveTimeout.bindAsEventListener(this));
+            childernQueue.push(goLeftIcon);
+        }
+        
+        if (this.Params.ShowZoomSelectBox){
+            var zoomDropDown = document.createElement('select');
+            zoomDropDown.className = 'panoramaZoomDropdown';
+            this.indicatorOption = document.createElement('option');
+            this.indicatorOption.className = 'panoramaIndicator';
+            this.indicatorOption.innerHTML = '% 100';
+            this.indicatorOption.value = '#';
+            this.indicatorOption.selected = true;
+            zoomDropDown.appendChild(this.indicatorOption);
+            var zoomPercentages = [5, 10, 15, 25, 50, 75, 90, 100, 200, 400];
+            for(var x = 0; x < zoomPercentages.length; x++){
+                var opt = document.createElement('option');
+                opt.innerHTML = zoomPercentages[x];
+                opt.value = zoomPercentages[x]/100;
+                zoomDropDown.appendChild(opt);
+            }
+            Event.observe(zoomDropDown, 'change', 
+                experience.panorama.handleZoomPercentageChange.bindAsEventListener(this));
+            childernQueue.push(zoomDropDown);
+        }
+
+        if (this.Params.ShowStatus){
+            this.status = document.createElement('span');
+            this.status.className = "panoramaStatus";
+            childernQueue.push(this.status);
+            this.setStatus(null, "<img src='" + this.getImageResource('loading') + "' />");
+        }
+
+        this.image = document.createElement('img');
+        this.image.className = "panoramaImage";
+        this.image.src = this.Params.ImageURL;
+        this.image.alt = this.Params.ImageURL;
+        this.image.style.position = "relative";
+        this.image.style.width  =  this.Params.ImageWidth + "px";
+        this.image.style.height =  this.Params.ImageHeight + "px";
+        this.positionImage();
+        childernQueue.push(this.image);
+        
+        Event.observe(this.image, 'load', experience.panorama.setStatus.bindAsEventListener(this, ""));
+        Event.observe(this.image, 'error', 
+                        experience.panorama.setStatus.bindAsEventListener(this, 
+                                experience.tr("Could not load image.", experience.panorama.Locales)));
+
+        // Misc. handlers ..
+        Event.observe(this.canvas, 'mousedown', 
+                experience.panorama.handleMouseDown.bindAsEventListener(this));
+        Event.observe(this.canvas, 'mousemove', 
+                experience.panorama.handleMouseMove.bindAsEventListener(this));
+        Event.observe(document, 'mouseup', 
+                experience.panorama.handleMouseUp.bindAsEventListener(this));
+
+        var wheelHandler = experience.panorama.handleMouseWheel.bindAsEventListener(this);
+        Event.observe(this.canvas, "DOMMouseScroll", wheelHandler, false); // Mozilla
+        Event.observe(this.canvas, "mousewheel", wheelHandler, false);
+
+        // add elements to the canvas (in reverse for proper z-Index ordering)
+        for(var i = childernQueue.length - 1; i >= 0; i--){
+            this.canvas.appendChild(childernQueue[i]);
+        } 
+        
+    },
+
+    //// PUBLIC METHODS ///////////////////////////////////////////////////////    
+
+    show : function(){
+        if(!this.Params.RenderIn){
+            this.fireListeners(this.onFullWindowListeners);
+        }
+
+        this.canvas.style.visibility = 'visible';
+    },
+
+    hide : function(){
+        if(!this.Params.RenderIn){
+            this.fireListeners(this.onUnFullWindowListeners);
+        }
+
+        this.canvas.style.visibility = 'hidden';
+    },
+
+    toggleFullWindow : function(e){
+        //experience.Console.log(this.isMaximizedInstance);
+
+        if (this.isMaximizedInstance){ // minimize
+            this.closeImg.src = this.getImageResource('go_fullwindow');
+            this.closeImg.title = this.closeImg.alt = experience.tr("Go Full-Window", experience.panorama.Locales);
+
+            this.positionCanvas(true);
+            this.isMaximizedInstance = false;
+        } else { // maximize
+            this.closeImg.src = this.getImageResource('unfullwindow');
+            this.closeImg.title = this.closeImg.alt = experience.tr("Restore", experience.panorama.Locales);
+
+            this.positionCanvas(false);
+            this.isMaximizedInstance = true;
+        }
+    },
+
+    getImage : function (){
+        return [this.Params.ImageURL, this.Params.ImageWidth, this.Params.ImageHeight];
+    },
+
+    setImage : function(url, width, height){
+        this.image.src = this.Params.ImageURL = url;
+        this.image.style.width = this.Params.ImageWidth  = width + "px";
+        this.image.style.height = this.Params.ImageHeight = height + "px";
+        this.positionImage();
+    },
+
+    addOnFullWindowListener : function(listener){
+        this.onFullWindowListeners[this.onFullWindowListeners.length] = listener;
+    },
+
+    removeOnFullWindowListener : function(listener){
+        if (this.onFullWindowListeners.include(listener)){
+            this.onFullWindowListeners.splice(this.onFullWindowListeners.indexOf(listener), 1);
+        }
+    },
+
+    addOnUnFullWindowListener : function(listener){
+        this.onUnFullWindowListeners[this.onUnFullWindowListeners.length] = listener;
+    },
+
+    removeOnUnFullWindowListener : function(listener){
+        if (this.onUnFullWindowListeners.include(listener)){
+            this.onUnFullWindowListeners.splice(this.onUnFullWindowListeners.indexOf(listener), 1);
+        }
+    },
+
+    //// PRIVATE METHODS ///////////////////////////////////////////////////////
+
+    fireListeners : function(listeners){
+        for(var i =0; i < listeners.length; i++){
+            listeners[i]();
+        }
+    }, 
+
+    setStatus : function(e, html){
+        if (this.Params.ShowStatus){
+            this.status.innerHTML = html;
+        }
+    },
+
+    showHelp : function(e){
+        alert(experience.tr("HelpText", experience.panorama.Locales));
+    },
+
+    positionImage :  function (e){
+        var image = this.image;
+
+        // detecting canvas width and height doesn't work in KHTML (and WebKit?)
+        if (experience.detectEngine() == "khtml"){
+            image.style.top = image.style.left = this.Params.InnerUpperOffset + "px";
+            return;
+        }
+
+        var canvasWidth  = Element.getWidth(this.canvas);
+        var canvasHeight = Element.getHeight(this.canvas);
+
+        // center if it doesn't fill
+        if (parseFloat(image.style.width) > canvasWidth){
+            image.style.left = this.Params.InnerUpperOffset + "px";
+        } else {
+            image.style.left =  (canvasWidth / 2) -  (parseFloat(image.style.width) / 2) + "px";
+        }
+           
+        if (parseFloat(image.style.height) > canvasHeight){
+            image.style.top = this.Params.InnerUpperOffset + "px";
+        } else {
+            image.style.top =  (canvasHeight / 2) -  (parseFloat(image.style.height) / 2) + "px";
+        }
+    },
+
+    positionCanvas : function (isRenderIn){
+
+        if(this.canvas.parentNode){
+            this.canvas.parentNode.removeChild(this.canvas);
+        }
+
+        if(isRenderIn){
+            if(this.isMaximizedInstance){
+                this.fireListeners(this.onUnFullWindowListeners);
+            }
+
+            $(this.Params.RenderIn).style.position = "relative";
+            this.canvas.style.position = "absolute";
+            this.canvas.style.left = 
+                this.canvas.style.right =
+                this.canvas.style.top = 
+                this.canvas.style.bottom = "0px";
+            this.canvas.style.height = this.canvas.style.width = "100%";
+            this.canvas.style.visibility  = 'visible';
+
+            $(this.Params.RenderIn).appendChild(this.canvas);
+        } else {
+            if(this.Params.RenderIn){
+                this.fireListeners(this.onFullWindowListeners);
+            }
+
+            document.getElementsByTagName('body')[0].appendChild(this.canvas);
+
+            if (experience.detectBrowser() == "ie5" || experience.detectBrowser() == "ie6"){
+                this.canvas.style.position = "absolute";
+                this.canvas.style.setExpression("top", 
+                    "(ignoreMe = document.documentElement.scrollTop? " + 
+                        "document.documentElement.scrollTop : document.body.scrollTop) + 'px'");
+                this.canvas.style.setExpression("height",
+                     "experience.panorama.getInnerWindowDimensions()['height']");
+                this.canvas.style.setExpression("width",
+                     "experience.panorama.getInnerWindowDimensions()['width']");
+            } else {
+                this.canvas.style.position = "fixed"
+            }
+        }
+
+        //experience.Console.log(this.canvas.parentNode.tagName + "," + isRenderIn);
+    },
+
+    /**
+      * Thanks to http://www.quirksmode.org/viewport/compatibility.html 
+      */
+    getInnerWindowDimensions: function (){
+        var x,y;
+        if (self.innerHeight) // all except Explorer
+        {
+            x = self.innerWidth;
+            y = self.innerHeight;
+        }
+        else if (document.documentElement && document.documentElement.clientHeight)
+            // Explorer 6 Strict Mode
+        {
+            x = document.documentElement.clientWidth;
+            y = document.documentElement.clientHeight;
+        }
+        else if (document.body) // other Explorers
+        {
+            x = document.body.clientWidth;
+            y = document.body.clientHeight;
+        }
+
+        return {width: x, height: y};
+    },
+
+    zoom : function(e, delta){
+
+        var zoomFactor = this.Params.ZoomFactor;
+        var newWidth, newHeight, newLeft, newTop = null;
+        
+        // parse current pixel dimensions to floats
+        var pWidth = parseFloat(this.image.style.width);
+        var pHeight = parseFloat(this.image.style.height);
+        
+        if (0 == delta){ // restore original size
+            newWidth = this.Params.ImageWidth;
+            newHeight = this.Params.ImageHeight;
+            
+            // distribute size change
+            newLeft = (parseFloat(this.image.style.left) - ((newWidth - pWidth) / 2));
+            newTop  = (parseFloat(this.image.style.top) - ((newHeight - pHeight) / 2)); 
+        } else if (delta > 0){ // zoom in
+            newWidth = (pWidth + (pWidth * zoomFactor));
+            newHeight = (pHeight + (pHeight * zoomFactor));
+            
+            // distribute size change
+            newLeft = (parseFloat(this.image.style.left) - ((pWidth * zoomFactor) / 2));
+            newTop = (parseFloat(this.image.style.top) - ((pHeight * zoomFactor) / 2)); 
+        } else if (delta < 0){ // zoom out
+            newWidth = (pWidth - (pWidth * zoomFactor));
+            newHeight =  (pHeight - (pHeight * zoomFactor));
+            
+            // distribute size change
+            newLeft = (parseFloat(this.image.style.left) + ((pWidth * zoomFactor) / 2));
+            newTop  = (parseFloat(this.image.style.top)  + ((pHeight * zoomFactor) / 2)); 
+        } else {
+            alert("Invalid delta value:" +  delta);
+            return;
+        }
+
+        var percentage = (newWidth/this.Params.ImageWidth).toFixed(3);
+        this.indicatorOption.innerHTML = "% " + (percentage * 100).toFixed(1);           
+
+        this.image.style.width  = newWidth  + "px";
+        this.image.style.height = newHeight + "px";
+        this.image.style.left   = newLeft   + "px";
+        this.image.style.top    = newTop    + "px";
+
+    },
+
+    move : function (e, toWhere){
+        if (!this.isBeingDragged){
+            var MOVE_BY = this.Params.MoveBy;
+    
+            switch(toWhere){
+                case experience.panorama.MOVE_DOWN:
+                    this.image.style.top = (parseFloat(this.image.style.top) + MOVE_BY) + "px";
+                    break;
+                case experience.panorama.MOVE_UP:
+                    this.image.style.top = (parseFloat(this.image.style.top) - MOVE_BY) + "px";
+                    break;
+                case experience.panorama.MOVE_RIGHT:
+                    this.image.style.left = (parseFloat(this.image.style.left) + MOVE_BY) + "px";
+                    break;
+                case experience.panorama.MOVE_LEFT:
+                    this.image.style.left = (parseFloat(this.image.style.left) - MOVE_BY) + "px";
+                    break;
+                default:
+                    experience.Console.log("Unrecognized 'toWhere' value '" + toWhere + "'");
+                    return;
+            }
+    
+            this.timeOutId = 
+                setTimeout(experience.panorama.move.bind(this, null, toWhere), this.Params.MoveRate);
+        }
+    },
+
+    clearMoveTimeout : function (e){
+         clearTimeout(this.timeOutId);
+    },
+
+    handleZoomPercentageChange : function(e){
+        var percentage = Event.element(e).value;
+
+        if (percentage != '#'){
+            var newWidth, newHeight, newLeft, newTop;
+            
+            newWidth  = this.Params.ImageWidth * percentage;
+            newHeight = this.Params.ImageHeight * percentage;
+            
+            // distribute size change
+            newLeft = parseFloat(this.image.style.left) - 
+                            ((newWidth - parseFloat(this.image.style.width)) / 2);
+            newTop  = parseFloat(this.image.style.top) - 
+                            ((newHeight - parseFloat(this.image.style.height)) / 2); 
+            
+            // apply new size
+            this.image.style.width  = newWidth  + "px";
+            this.image.style.height = newHeight + "px";
+            this.image.style.left   = newLeft   + "px";
+            this.image.style.top    = newTop    + "px";
+            
+            Event.element(e).selectedIndex = 0;
+            Event.element(e).options[0].innerHTML = "% " + (percentage * 100);
+        }
+    },
+
+    handleMouseDown : function(e){
+        if (
+            (
+                Event.element(e) == this.canvas ||
+                Event.element(e) == this.image
+            ) && Event.isLeftClick(e)
+           ){
+
+            this.isBeingDragged = true;
+            this.canvas.style.cursor = experience.panorama.getGrabbingCursor();
+            this.lastLeft = parseFloat(this.image.style.left);
+            this.lastTop  = parseFloat(this.image.style.top);
+            this.lastX = Event.pointerX(e);
+            this.lastY = Event.pointerY(e);
+            
+            // I love Prototype!
+            Event.stop(e);
+        }
+    },
+
+    handleMouseMove : function (e){
+        if (
+            Event.element(e) == this.canvas ||
+            Event.element(e) == this.image
+           ){
+                var sign = this.Params.ReversePanning? -1 : 1;
+                if (this.isBeingDragged){
+                    this.image.style.left =  this.lastLeft + (sign * (Event.pointerX(e) - this.lastX)) + "px"; 
+                    this.image.style.top  =  this.lastTop  + (sign * (Event.pointerY(e) - this.lastY)) + "px"; 
+                }
+                
+                Event.stop(e);
+        }
+    },
+
+    handleMouseUp : function(e){
+        this.isBeingDragged = false;
+        this.canvas.style.cursor = experience.panorama.getGrabCursor();
+    },
+
+    getGrabCursor : function(e) {
+        if(experience.detectEngine() == "gecko"){
+            return '-moz-grab';
+        } else {
+            return 'move';
+        }
+    },
+
+    getGrabbingCursor : function(e){
+        if(experience.detectEngine() == "gecko"){
+            return '-moz-grabbing';
+        } else {
+            return 'move';
+        }
+    },
+
+    /**
+     * See also 
+     *  http://adomas.org/javascript-mouse-wheel/
+     *  http://www.ogonek.net/mousewheel/demo.html
+     */
+    handleMouseWheel: function(event){
+        var delta = 0;
+
+        if (event.wheelDelta) { // IE/Opera. 
+            delta = event.wheelDelta/120;
+            //In Opera 9, delta differs in sign as compared to IE.
+            if (window.opera)
+                delta = -delta;
+        } else if (event.detail) { // Mozilla case. 
+                // In Mozilla, sign of delta is different than in IE.
+                // Also, delta is multiple of 3.
+                delta = -event.detail/3;
+        }
+
+        delta = Math.round(delta); //Safari Round
+
+        // If delta is nonzero, handle it.
+        // Basically, delta is now positive if wheel was scrolled up,
+        // and negative, if wheel was scrolled down.
+        if (delta){
+                experience.panorama.zoom.bindAsEventListener(this, delta)();
+        }
+
+        Event.stop(event);
+    },
+
+    getImageResource : function (resource){
+            return this.Params.IconDirectory + "/" + resource 
+                                        + this.Params.IconExtension;
+    },
+
+
+    Locales : $H({
+        'en_US' : {
+            'HelpText' : "Grab (click and drag) the image to move it around. Use your mouse wheel to zoom in and out the image or, if you don't have one, use the zoom icons in the toolbar. If you hover with your mouse pointer over any of the navigator arrow in the bottom right corner, the image will starting moving in that direction (automatic scrolling.)\n\nPanorama is part of the Experience JavaScript Library.\nFor details, see project website at http://experience.sf.net\n"
+        },
+
+        'ar' : {
+            'Zoom In' : 'ØªÙØšÙØ±',
+            'Zoom Out' : 'ØªØµØºÙØ±',
+            'Restore Original Size' : 'Ø§Ø³ØªØ¹Ø§Ø¯Ø© Ø§ÙØ­Ø¬Ù
+ Ø§ÙØ£ØµÙÙ',
+            'Restore Original Position' : 'Ø§Ø³ØªØ¹Ø§Ø¯Ø© Ø§ÙÙ
+ÙÙØ¹ Ø§ÙØ£ØµÙÙ',
+            'Close' : 'Ø¥ØºÙØ§Ù',
+            'Scrolling .. ' : 'Ø¬Ø§Ø±Ù Ø§ÙØªØ­Ø±ÙÙ ...',
+            'Help': 'Ù
+Ø³Ø§Ø¹Ø¯Ø©',
+            'HelpText' :  'Ø£Ø¬Ø°Øš (Ø£ÙÙØ± Ù Ø¬Ø±) Ø§ÙØµÙØ±Ø© ÙÙ ØªØ­Ø±ÙÙØ§. Ø§Ø³ØªØ®Ø¯Ù
+ Ø¹Ø¬ÙØ© Ø§ÙÙØ£Ø±Ø© ÙØªÙØšÙØ± Ø£Ù ØªØµØºÙØ± Ø§ÙØµÙØ±Ø©. Ø¥Ø°Ø§ ÙÙ
+ ÙÙÙ ÙØ¯ÙÙ ÙØ§Ø­Ø¯Ø©Ø ÙØ§Ø³ØªØ®Ø¯Ù
+ Ø§ÙØ£ÙÙÙÙØ§Øª Ø§ÙØªÙ Ø¹ÙÙ ØŽØ±ÙØ· Ø§ÙØ£Ø¯ÙØ§Øª. Ø¥Ø°Ø§ Ø­Ø±ÙØª Ù
+Ø€ØŽØ± Ø§ÙÙØ£Ø±Ø© ÙÙÙ Ø£Ø­Ø¯Ù Ø£Ø³ÙÙ
+ Ø§ÙÙÙØ§Ù ÙÙ Ø§ÙØ¬Ø§ÙØš Ø§ÙØ£ÙÙ
+Ù Ø§ÙØ³ÙÙÙØ ÙØ³ÙÙ ØªØªØ­Ø±Ù Ø§ÙØµÙØ±Ø© ÙÙ ÙÙ Ø°ÙÙ Ø§ÙØ¥ØªØ¬Ø§Ù (ØªØ­Ø±ÙÙ ØªÙÙØ§ØŠÙ). \n\n ØšØ§ÙÙØ±Ø§Ù
+Ø§ ÙÙ Ø¬Ø²Ø¡ Ù
+Ù Ù
+ÙØªØšØ© Ø¥ÙØ³ØšØ±ÙØšØ³ Ø§ÙØšØ±Ù
+Ø¬ÙØ© ÙØ¬Ø§ÙØ§Ø³ÙØ±ØšØª. \n ÙÙ
+Ø²ÙØ¯ Ù
+Ù Ø§ÙØªÙØ§ØµÙÙØ ÙØ±Ø¬Ù Ø²ÙØ§Ø±Ø© Ù
+ÙÙØ¹ Ø§ÙÙ
+ØŽØ±ÙØ¹ ÙÙ \n http://experience.sf.net',
+            'Could not load image' : 'Ø®Ø·Ø£ Ø£Ø«ÙØ§Ø¡ ØªØ­Ù
+ÙÙ Ø§ÙØµÙØ±Ø©',
+            'Go Full-Window' : 'Ø¥Ù
+ÙØ¡ Ø§ÙÙØ§ÙØ°Ø© ØšØ£ÙÙ
+ÙÙØ§',
+            'Restore' : 'Ø§Ø³ØªØ±Ø¬Ø§Ø¹'
+        },
+        'pt_BR' : {
+            'Zoom In' : 'Aproximar',
+            'Zoom Out' : 'Afastar',
+            'Restore Original Size' : 'Restaurar para o tamanho original',
+            'Restore Original Position' : 'Restaurar para a posição original',
+            'Close' : 'Fechar',
+            'Scrolling .. ' : 'Deslizando ..',
+            'Help': 'Ajuda',
+			'HelpText' :  'Segure (clique e arraste) a imagem para movê-la. Use a roda do mouse para aproximar ou afastar a imagem ou, se você não a possui, use os ícones de zoom na barra de ferramentas. Se você passar o cursor sobre as setas de navegação, no canto inferior direito, a imagem se moverá na direção selecionada (rolagem automática).\n\nPanorama é parte da Experience JavaScript Library.\nPara detalhes, veja o website do projeto em http://experience.sf.net\n',
+            'Could not load image' : 'Não foi possível carregar a imagem',
+            'Go Full-Window' : 'Ir para tela cheia',
+            'Restore' : 'Restaurar'
+        }
+    })
+}
+
Index: /sandbox/workflow/branches/993/js/experience/experience.cloudy.js
===================================================================
--- /sandbox/workflow/branches/993/js/experience/experience.cloudy.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/experience/experience.cloudy.js	(revision 795)
@@ -0,0 +1,96 @@
+/* -------------------------------------------------------------------------- *
+ *   Experience Javascript Library (version 1.0b)
+ *  (c) 2007 Ahmed Saad <ahmeds@users.sourceforge.net>
+ *
+ *  Experience is freely distributable under the terms of an MIT-style license.
+ *  For details, see project website at http://experience.sf.net
+ * -------------------------------------------------------------------------- */
+
+// Cloudy component
+
+experience.cloudy  =  {
+
+    Version : '0.1',
+
+    WeightedList : function (userParams){
+
+        this.Params = $H({
+            MinFontSize : 8, 
+            MaxFontSize : 40, 
+            Unit :  "px",
+            Items : null, // an array of items
+            RenderIn: null, // an element or id
+            ItemCSSClass: "cloudyItem",
+            TipCSSClass:  "cloudyTip"
+        });
+
+        //// PUBLIC METHODS ////////////////////////////////////////////////
+
+        this.render = experience.cloudy.render;
+
+        //// INITIALIZATION ///////////////////////////////////////////////
+
+        this.Params.merge(userParams);
+    },
+
+    /**
+    * Renders the weighted list inside an element (ie a <div>)
+    * Parameters:
+    *  arr: A numerically indexed array of hash-like objects 
+    *       representing items that has the following properties:
+    *        label:  the label of the item (ie tag name)
+    *        weight: a number indicating item weight
+    *        href:   where to link the item
+    *        html:   (optional) a piece of html code (or just text) to 
+    *                 display when hovering over the item 
+    *        handlers: (optional) an object-like hash of event names and 
+    *                   their handlers                            
+    **/
+        
+    render : function(){
+
+        if (this.Params.Items == null){
+            throw new Error ("No Items array was specified in the Items parameter");
+        }
+
+        if (this.Params.RenderIn == null){
+            throw new Error ("No element (or id) was specified in the RenderIn parameter");
+        }
+
+        var arr = this.Params.Items;
+        var min, max, fix;
+        
+        for(var i = 0; i < arr.length; i++){
+            max = (arr[i]["weight"] > max || max == null)? arr[i]["weight"] : max;
+            min = (arr[i]["weight"] < min || min == null)? arr[i]["weight"] : min;
+        } 
+    
+        var fix = max - min == 0? 1 : max - min;
+    
+        for(var i = 0; i < arr.length; i++){
+            var ratio = (1 - (max - arr[i]["weight"]) / fix);
+            var fontSize = this.Params.MinFontSize + (ratio * (this.Params.MaxFontSize - this.Params.MinFontSize)) ;
+            
+            var a  = document.createElement('a');
+            a.href = arr[i]['href']? arr[i]['href'] : '#' ;
+            a.className = this.Params.ItemCSSClass;
+            a.style.fontSize =  fontSize + this.Params.Unit;
+            a.innerHTML =  arr[i]["label"];
+
+            if(typeof(arr[i]["html"]) != 'undefined'){
+                experience.Core.bindTip(a, arr[i]["html"], this.Params.TipCSSClass );
+            }
+
+            if (arr[i]["handlers"]){
+                for(eventName in arr[i]["handlers"]){
+                    Event.observe(a, eventName, arr[i]["handlers"][eventName]);
+                }
+            }
+
+            $(this.Params.RenderIn).appendChild(a);
+            $(this.Params.RenderIn).appendChild(document.createTextNode(' '));
+        } 
+    }
+}
+
+
Index: /sandbox/workflow/branches/993/js/experience/experience.js
===================================================================
--- /sandbox/workflow/branches/993/js/experience/experience.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/experience/experience.js	(revision 795)
@@ -0,0 +1,134 @@
+/* -------------------------------------------------------------------------- *
+ *   Experience Javascript Library (version 1.0b)
+ *  (c) 2007 Ahmed Saad <ahmeds@users.sourceforge.net>
+ *
+ *  Experience is freely distributable under the terms of an MIT-style license.
+ *  For details, see project website at http://experience.sf.net
+ * -------------------------------------------------------------------------- */
+
+// global namespace
+var experience  = {
+    Version : '1.0b',
+
+    Params : $H({
+        Locale: 'pt_BR',  /* The language of strings embeded in code is considered the default */
+        InterfaceDir: 'ltr'
+    }),
+
+    /* The interface to the world */
+    Core :  {
+        initialize : function(userParams){
+            experience.Params.merge(userParams);
+
+            //// PUBLIC METHODS ////////////////////////////
+
+            this.bindTip = experience.bindTip;
+            this.unbindTip = experience.unbindTip;
+        },       
+
+        bindTip : function(element, html, className){
+            element = $(element);
+            element.tipHTML = html;
+            element.tipClass = className ? className : "experienceTip";            
+            Event.observe(element, 'mousemove', experience.showHoverDiv);
+            Event.observe(element, 'mouseout', experience.hideHoverDiv);        
+        },
+    
+        unbindTip : function(element){
+            if ($('experienceTip') &&  $('experienceTip').srcElement == element){
+                experience.hideHoverDiv();
+            }
+    
+            Event.stopObserving(element, 'mousemove', experience.showHoverDiv);
+            Event.stopObserving(element, 'mouseout', experience.hideHoverDiv); 
+        }
+    },
+
+    ///// PRIVATE FUNCTIONS ////////////////////////////////////////////////
+
+    Console : {
+        isEnabled: true,
+        log : function(obj){
+            if (experience.Console.isEnabled){
+                if(window.console){ // Firebug
+                    window.console.log(obj);
+                } else if (typeof(opera) != "undefined"){
+                    opera.postError(Object.inspect(obj));
+                } else {
+                    alert(Object.inspect(obj));
+                }
+            }
+        }
+    },
+
+    // internationalization support 
+    tr : function (str, locales){
+        if (
+            locales.keys().include(this.Params.Locale) &&
+            typeof(locales[this.Params.Locale][str]) != 'undefined'
+        ) {
+            return locales[this.Params.Locale][str];
+        } else {
+            return str;
+        }
+    },
+
+    // browser detection 
+    detectBrowser: function (){
+        if (navigator.userAgent.indexOf("MSIE 5") != -1){
+            return "ie5";
+        } else if (navigator.userAgent.indexOf("MSIE 6") != -1){ 
+            return "ie6";
+        } else if (navigator.userAgent.indexOf("Safari") != -1){
+            return "safari";
+        } else if (navigator.userAgent.indexOf("Firefox") != -1) {
+            return "firefox";
+        } else if (navigator.userAgent.indexOf("Opera") != -1) {
+            return "opera";
+        } else if (navigator.userAgent.indexOf("Konqueror") != -1) {
+            return "konqueror";
+        }
+    },
+
+    detectEngine: function() {
+        var browser = experience.detectBrowser();
+        if (browser == "ie5" || browser == "ie6"){
+            return "trident";
+        } else if (navigator.userAgent.indexOf("AppleWebKit") != -1){
+            return "webkit";
+        } else if (navigator.userAgent.indexOf("KHTML") != -1){
+            return "khtml";
+        } else if ( navigator.userAgent.indexOf("Gecko") != -1 &&
+                    navigator.userAgent.indexOf("like Gecko") == -1 ){
+            return "gecko";
+        } 
+    },
+
+    showHoverDiv : function(e){
+        var el = Event.element(e);
+
+        if (!$('experienceTip')){
+            var div = document.createElement('div');
+            div.id = 'experienceTip';
+            div.style.position = "absolute";
+            document.getElementsByTagName('body')[0].appendChild(div);
+        }
+
+        /* A speed optimization (it's slow to reassign on every call */
+        if (experience.lastTipElement != el){
+            $('experienceTip').className = el.tipClass;
+            $('experienceTip').innerHTML = el.tipHTML;
+            $('experienceTip').srcElement = el;
+        }
+
+        $('experienceTip').style.display = "block";
+        $('experienceTip').style.top = Event.pointerY(e) + 20 + "px";
+        $('experienceTip').style.left = Event.pointerX(e) + "px";
+
+        experience.lastTipElement = el;
+    },
+
+    hideHoverDiv : function(e){
+        $('experienceTip').style.display = "none";
+    }
+}
Index: /sandbox/workflow/branches/993/js/experience/COPYING
===================================================================
--- /sandbox/workflow/branches/993/js/experience/COPYING	(revision 795)
+++ /sandbox/workflow/branches/993/js/experience/COPYING	(revision 795)
@@ -0,0 +1,10 @@
+Copyright (c) 2007 Ahmed Saad
+
+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.
+
+
+Icons are from library of the Tango Desktop Project and a few are from the Pasodoble icon theme which is based on Tango. Both icon sets are licensed under the Creative Commons Attribution Share-Alike license.
Index: /sandbox/workflow/branches/993/js/experience/README
===================================================================
--- /sandbox/workflow/branches/993/js/experience/README	(revision 795)
+++ /sandbox/workflow/branches/993/js/experience/README	(revision 795)
@@ -0,0 +1,7 @@
+See the examples directory for code samples.
+
+Experience Javascript Library (version 1.0b)
+(c) 2007 Ahmed Saad <ahmeds@users.sourceforge.net>
+
+Experience is freely distributable under the terms of an MIT-style license.
+For details, see project website at http://experience.sf.net
Index: /sandbox/workflow/branches/993/js/external_applications/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/external_applications/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/external_applications/main.js	(revision 795)
@@ -0,0 +1,186 @@
+function checkError(data)
+{
+	if (data['error'])
+	{
+		alert(data['error']);
+		return true;
+	}
+
+	return false;
+}
+
+function buildLayout()
+{
+	var content = '';
+	content += '<table><tr><td valign="top"><select size="10" class="externalApplicationList" id="externalApplications" onchange="getExternalApplication(this.value);"></select>';
+	content += '<br/><button onclick="clearApplicationData();">Novo</button>';
+	content += '&nbsp;&nbsp;&nbsp;&nbsp;<button onclick="removeExternalApplication($F(\'externalApplications\'));">Excluir</button></td>';
+	content += '<td valign="top"><div id="externalApplicationData" style="display: none;"><table>';
+	content += '<tr><td><label for="name">Nome</label></td><td><input type="text" id="name" size="30" /></td></tr>';
+	content += '<tr><td><label for="address">Endereço</label></td><td><input type="text" id="address" size="50" /></td></tr>';
+	content += '<tr><td><label for="description">Descrição</label></td><td><textarea id="description" cols="40" rows="3"></textarea></td></tr>';
+	content += '<tr><td valign="top" colspan="2"><label><input type="checkbox" id="intranet_only");"/>Acessível somente na Intranet?</label></td></tr>';
+	content += '<tr><td valign="top"><label><input type="checkbox" id="authentication" onclick="if (this.checked) Effect.BlindDown(\'post_div\'); else Effect.BlindUp(\'post_div\');"/>Autentica?</label></td><td><div id="post_div""><label for="post">Post</label><br/><textarea id="post" cols="40" rows="3"></textarea></div></td></tr>';
+	content += '<tr><td><label for="image">Imagem</label></td>';
+	content += '<td><form action="' + _web_server_url + '/index.php?menuaction=workflow.ui_external_applications.upload_image" target="file_iframe" method="post" enctype="multipart/form-data" name="image_tmp_form" id="image_tmp_form"><input type="file" name="image_tmp" id="image_tmp"/></form>';
+	content += '<div id="image_div"><label><input type="checkbox" id="remove_current_image">Remover imagem atual</label><br/><img id="current_image" src=""/></div>';
+	content += '</td></tr>';
+	content += '<tr><td colspan="2"><button id="buttonSave" onclick="sendContents();">Salvar</button></td></tr>';
+	content += '<tr><td><label for=""></label></td><td></td></tr>';
+	content += '</table></div>';
+	content += '</td></tr></table>';
+	content += '<input type="hidden" id="image" value=""/>';
+	content += '<input type="hidden" id="external_application_id" value=""/>';
+
+	content += '<iframe name="file_iframe" style="display: none;"></iframe>';
+	$('conteudo').innerHTML = content;
+	$('post_div').hide();
+	$('image_div').hide();
+	loadExternalApplications();
+}
+
+function clearApplicationData()
+{
+	$('name').value = '';
+	$('description').value = '';
+	$('address').value = '';
+	$('authentication').checked = false;
+	$('post').value = '';
+	$('external_application_id').value = '';
+	$('image').value = '';
+	$('image_tmp').value = '';
+	$('current_image').src = '';
+	$('remove_current_image').checked = false;
+	$('post_div').hide();
+	$('image_div').hide();
+
+	if (!$('externalApplicationData').visible())
+		Effect.BlindDown('externalApplicationData');
+}
+
+function getExternalApplication(externalApplicationID)
+{
+	function resultGetExternalApplication(data)
+	{
+		if (checkError(data))
+			return;
+
+		if (!data)
+			return;
+
+		clearApplicationData();
+		$('name').value = data['name'];
+		$('description').value = data['description'];
+		$('address').value = data['address'];
+		$('intranet_only').checked = (data['intranet_only'] == '1')? true : false;
+		$('authentication').checked = (data['authentication'] == '1')? true : false;
+		if ($('authentication').checked)
+			$('post_div').show();
+		else
+			$('post_div').hide();
+		$('post').value = data['post'];
+		$('external_application_id').value = data['external_application_id'];
+		if (data['image'])
+		{
+			$('current_image').src = _web_server_url + '/workflow/redirect.php?file=/external_applications/' + data['image'];
+			$('image_div').show();
+		}
+	}
+
+	cExecute('$this.bo_external_applications.getExternalApplication', resultGetExternalApplication, 'external_application_id=' + externalApplicationID);
+}
+
+function loadExternalApplications()
+{
+	function resultLoadExternalApplications(data)
+	{
+		var output = '';
+		for (var i = 0; i < data.length; i++)
+			output += '<option value="' + data[i]['external_application_id'] + '">' + data[i]['name'] + '</option>';
+		var obj = $('externalApplications');
+
+		/* IE MAGIC */
+		if (obj.outerHTML)
+		{
+			obj.innerHTML = '';
+			obj.outerHTML = obj.outerHTML.match(/<select[^>]*>/gi) + output + '</select>';
+		}
+		else
+			obj.innerHTML = output;
+	}
+
+	cExecute('$this.bo_external_applications.getExternalApplications', resultLoadExternalApplications);
+}
+
+function sendContents()
+{
+	if ($F('name') == '')
+	{
+		alert('É necessário informar um nome para a aplicação externa.');
+		return;
+	}
+
+	if ($F('address') == '')
+	{
+		alert('É necessário informar um endereço para a aplicação externa.');
+		return;
+	}
+
+	var address = $F('address');
+
+	if (address.match(/^[a-zA-Z]+:\/\//) == null)
+	{
+		alert('Aparentemente a URL informada não está formatada corretamente.\nTente utilizar o endereço completo. Exemplo:\nhttp://expresso.pr.gov.br');
+		return;
+	}
+
+	function resultSendContents(data)
+	{
+		if (checkError(data))
+			return;
+
+		Effect.BlindUp('externalApplicationData');
+		loadExternalApplications();
+	}
+
+	if (($F('image_tmp') != '') && ($F('image') == ''))
+		$('image_tmp_form').submit();
+	else
+	{
+		var params = 'name=' + escape($F('name'));
+		params += '&description=' + escape($F('description'));
+		params += '&address=' + escape($F('address'));
+		params += '&intranet_only=' + (($F('intranet_only') == 'on') ? '1' : '0');
+		params += '&authentication=' + (($F('authentication') == 'on') ? '1' : '0');
+		params += '&post=' + escape($F('post'));
+		params += '&image=' + $F('image');
+		if ($F('external_application_id') != '') // update
+			cExecute('$this.bo_external_applications.updateExternalApplication', resultSendContents, params + '&external_application_id=' + $F('external_application_id') + '&remove_current_image=' + (($F('remove_current_image') == 'on') ? '1' : '0'));
+		else //insert
+			cExecute('$this.bo_external_applications.addExternalApplication', resultSendContents, params + '&external_application_id=' + $F('external_application_id'));
+	}
+}
+
+function removeExternalApplication(externalApplicationID)
+{
+	if (externalApplicationID == '')
+		return;
+
+	function resultRemoveExternalApplication(data)
+	{
+		if (checkError(data))
+			return;
+
+		loadExternalApplications();
+	}
+
+	if (confirm('Tem certeza que deseja excluir a Aplicação Externa selecionada?'))
+	{
+		cExecute('$this.bo_external_applications.removeExternalApplication', resultRemoveExternalApplication, 'external_application_id=' + externalApplicationID);
+		Effect.BlindUp('externalApplicationData');
+	}
+}
+
+Event.observe(window, 'load', function() {
+	buildLayout();
+});
Index: /sandbox/workflow/branches/993/js/nano/NanoPrototype.lib.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/NanoPrototype.lib.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/NanoPrototype.lib.js	(revision 795)
@@ -0,0 +1,56 @@
+// -----------------------------------------------------------------------------
+// Try these: tries various function for success
+var Try =
+{
+    these: function()
+    {
+        var returnValue;
+
+        for (var i = 0; i < arguments.length; i++)
+        {
+            var lambda = arguments[i];
+
+            try
+            {
+                returnValue = lambda();
+                break;
+            }
+            catch (e) {}
+        }
+
+        return returnValue;
+    }
+};
+
+// -----------------------------------------------------------------------------
+// $() function (wraps document.getElementById)
+function $()
+{
+    var elements = new Array();
+
+    for (var i = 0; i < arguments.length; i++)
+    {
+        var element = arguments[i];
+
+        if (typeof element == 'string')
+        {
+            element = document.getElementById(element);
+        }
+
+        if (arguments.length == 1)
+        {
+            return element;
+        }
+
+        elements.push(element);
+    }
+
+    return elements;
+}
+
+// -----------------------------------------------------------------------------
+// $F() function
+function $F(id)
+{
+    return $(id).value;
+}
Index: /sandbox/workflow/branches/993/js/nano/NanoRequest.class.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/NanoRequest.class.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/NanoRequest.class.js	(revision 795)
@@ -0,0 +1,104 @@
+
+// -----------------------------------------------------------------------------
+// CLASS NanoRequest
+function NanoRequest()
+{
+    /* Instance Variables */
+
+    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    // Public variables
+
+    this.requestParameter = null;
+    this.requestData      = null;
+
+    this.escapeKeys       = false;
+    this.escapeValues     = true;
+
+
+	// #########################################################################
+    // Privileged Method (has public access and can access private vars & funcs)
+
+    this.autoLoadData        = _autoLoadRequestData;
+    this.getAssembledRequest = _assembleRequestData;
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// PRIVATE Methods
+
+	function _autoLoadRequestData( form_id, unique_element_id_string, disabled_element_types )
+	{
+	    this.requestData = new Object();
+
+        for( var i = 0; i < $(form_id).elements.length; i++ )
+        {
+            if( unique_element_id_string == ($(form_id).elements[i].id).substr(0,unique_element_id_string.length) )
+            {
+                this.requestData[_escapeKey($(form_id).elements[i].id)] = _getDataByElementType( $(form_id).elements[i].id );
+            }
+        }
+	}
+
+    function _assembleRequestData()
+    {
+        var tmp = new Object();
+
+        if( null != this.requestParameter && undefined != this.requestParameter )
+        {
+            tmp['parameter'] = this.requestParameter;
+        }
+
+        if( null != this.requestData && undefined != this.requestData )
+        {
+            tmp['data'] = this.requestData;
+        }
+
+        return tmp;
+    }
+
+    function _getDataByElementType( id )
+    {
+        if( $(id) )
+        {
+            switch( $(id).type )
+            {
+                case 'hidden'     :
+                case 'radio'      :
+                case 'select-one' :
+                case 'button'     : return $F(id);
+                                    break;
+
+                case 'password'   :
+                case 'text'       :
+                case 'textarea'   : return _escapeValue( $F(id) );
+                                    break;
+
+                case 'checkbox'   : return ( true == $(id).checked )
+                                                ? $F(id).value
+                                                : 0;
+                                    break;
+
+                default           : alert( 'Form field type: ' + $(id).type +
+                                           ' is NOT defined!!!' );
+            }
+        }
+        else
+        {
+            return '';
+        }
+    }
+
+    function _escapeKey( data )
+    {
+        return ( true  == this.escapeKeys)
+                    ? encodeURIComponent(data)
+                    : data;
+    }
+
+    function _escapeValue( data )
+    {
+        return ( true  == this.escapeValues)
+                    ? encodeURIComponent(data)
+                    : data;
+    }
+
+}
Index: /sandbox/workflow/branches/993/js/nano/function.library.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/function.library.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/function.library.js	(revision 795)
@@ -0,0 +1,83 @@
+
+// -----------------------------------------------------------------------------
+// NanoAjax function library
+//
+
+String.prototype.repeat = function( number )
+{
+	return new Array( number + 1 ).join( this );
+};
+
+String.prototype.ucFirst = function ()
+{
+    return this.substr(0,1).toUpperCase() + this.substr(1,this.length);
+};
+
+String.prototype.nl2br = function ()
+{
+    return this.replace(/\n/g,'<br/>');
+};
+
+String.prototype.ltrim = function ()
+{
+    return (this.replace(/^\s+/,""));
+};
+
+String.prototype.rtrim = function ()
+{
+    return (this.replace(/\s+$/,""));
+};
+
+//combines "leftTrim" and "rightTrim";
+String.prototype.trim = function ()
+{
+    return (this.replace(/\s+$/,"").replace(/^\s+/,""));
+};
+
+//removes n spaces in string to 1 (one) space
+String.prototype.superTrim = function ()
+{
+    return(this.replace(/\s+/g," ").replace(/\s+$/,"").replace(/^\s+/,"")); //"
+};
+
+// removes all spaces from string
+String.prototype.removeWhiteSpaces = function ()
+{
+    return (this.replace(/\s+/g,""));
+};
+
+// fills string with given char and count
+String.prototype.fillChar = function ( fill_char, fill_count, fill_position )
+{
+    var fill_position = (fill_position) ? fill_position : 'left';
+    var str_len       = this.length;
+    var tmp_str       = this;
+
+    if(str_len < fill_count)
+    {
+        while(str_len < fill_count)
+        {
+            tmp_str = ( 'left' == fill_position )
+                            ? (fill_char + tmp_str)
+                            : (tmp_str   + fill_char);
+
+            ++str_len;
+        }
+    }
+
+    return tmp_str;
+};
+
+// like PHP' in_array
+Array.prototype.contains = function( element )
+{
+    for ( var idx = 0; idx < this.length; idx++ )
+    {
+         if( element == this[idx] )
+         {
+             return true;
+         }
+    }
+
+    return false;
+};
Index: /sandbox/workflow/branches/993/js/nano/JSON.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/JSON.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/JSON.js	(revision 795)
@@ -0,0 +1,411 @@
+
+var JSON =
+{
+    // transform [object/number/string/boolean] into JSON-String
+    stringify: function (arg)
+    {
+        var c, i, l, s = '', v;
+
+        switch (typeof arg)
+        {
+            case 'object':  if (arg)
+                            {
+                                if (arg.constructor == Array)
+                                {
+                                    for (i = 0; i < arg.length; ++i)
+                                    {
+                                        v = this.stringify(arg[i]);
+
+                                        if (s)
+                                        {
+                                            s += ',';
+                                        }
+
+                                        s += v;
+                                    }
+                                    return '[' + s + ']';
+                                }
+                                else if (typeof arg.toString != 'undefined')
+                                {
+                                    for (i in arg)
+                                    {
+                                        v = arg[i];
+
+                                        if (typeof v != 'undefined' && typeof v != 'function')
+                                        {
+                                            v = this.stringify(v);
+
+                                            if (s)
+                                            {
+                                                s += ',';
+                                            }
+                                            s += this.stringify(i) + ':' + v;
+                                        }
+                                    }
+                                    return '{' + s + '}';
+                                }
+                            }
+                            return 'null';
+
+            case 'number' : return isFinite(arg) ? String(arg) : 'null';
+
+            case 'string' : l = arg.length;
+                            s = '"';
+
+                            for (i = 0; i < l; i += 1)
+                            {
+                                c = arg.charAt(i);
+                                if (c >= ' ')
+                                {
+                                    if (c == '\\' || c == '"') {
+                                        s += '\\';
+                                    }
+                                    s += c;
+                                }
+                                else
+                                {
+                                    switch (c)
+                                    {
+                                        case '\b':  s += '\\b';
+                                                    break;
+
+                                        case '\f':  s += '\\f';
+                                                    break;
+
+                                        case '\n':  s += '\\n';
+                                                    break;
+
+                                        case '\r':  s += '\\r';
+                                                    break;
+
+                                        case '\t':  s += '\\t';
+                                                    break;
+
+                                        default:    c  = c.charCodeAt();
+                                                    s += '\\u00' + Math.floor(c / 16).toString(16) +
+                                                        (c % 16).toString(16);
+                                    }
+                                }
+                            }
+                            return s + '"';
+
+            case 'boolean': return String(arg);
+
+            default       : return 'null';
+        }
+    },
+
+    parse: function (text)
+    {
+        var at = 0;
+        var ch = ' ';
+
+        function error(m)
+        {
+            throw { name    : 'JSONError',
+                    message : m,
+                    at      : at - 1,
+                    text    : text };
+        }
+
+        function next()
+        {
+            ch = text.charAt(at);
+            at += 1;
+            return ch;
+        }
+
+        function white()
+        {
+            while (ch)
+            {
+                if (ch <= ' ')
+                {
+                    next();
+                }
+                else if (ch == '/')
+                {
+                    switch (next())
+                    {
+                        case '/':   while (next() && ch != '\n' && ch != '\r') {}
+                                    break;
+
+                        case '*':   next();
+                                    for (;;)
+                                    {
+                                        if (ch)
+                                        {
+                                            if (ch == '*')
+                                            {
+                                                if (next() == '/')
+                                                {
+                                                    next();
+                                                    break;
+                                                }
+                                            }
+                                            else
+                                            {
+                                                next();
+                                            }
+                                        }
+                                        else
+                                        {
+                                            error("Unterminated comment");
+                                        }
+                                    }
+                                    break;
+
+                        default:    error("Syntax error");
+                    }
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        function string()
+        {
+            var i, s = '', t, u;
+
+            if (ch == '"')
+            {
+outer:          while (next())
+                {
+                    if (ch == '"')
+                    {
+                        next();
+                        return s;
+                    }
+                    else if (ch == '\\')
+                    {
+                        switch (next())
+                        {
+                            case 'b':   s += '\b';
+                                        break;
+
+                            case 'f':   s += '\f';
+                                        break;
+
+                            case 'n':   s += '\n';
+                                        break;
+
+                            case 'r':   s += '\r';
+                                        break;
+
+                            case 't':   s += '\t';
+                                        break;
+
+                            case 'u':   u = 0;
+                                        for (i = 0; i < 4; i += 1)
+                                        {
+                                            t = parseInt(next(), 16);
+                                            if (!isFinite(t))
+                                            {
+                                                break outer;
+                                            }
+                                            u = u * 16 + t;
+                                        }
+                                        s += String.fromCharCode(u);
+                                        break;
+
+                            default:    s += ch;
+                        }
+                    }
+                    else
+                    {
+                        s += ch;
+                    }
+                }
+            }
+            error("Bad string");
+        }
+
+        function array()
+        {
+            var a = [];
+
+            if (ch == '[')
+            {
+                next();
+                white();
+
+                if (ch == ']')
+                {
+                    next();
+                    return a;
+                }
+
+                while (ch)
+                {
+                    a.push(value());
+                    white();
+
+                    if (ch == ']')
+                    {
+                        next();
+                        return a;
+                    }
+                    else if (ch != ',')
+                    {
+                        break;
+                    }
+
+                    next();
+                    white();
+                }
+            }
+            error("Bad array");
+        }
+
+        function object()
+        {
+            var k, o = {};
+
+            if (ch == '{')
+            {
+                next();
+                white();
+
+                if (ch == '}')
+                {
+                    next();
+                    return o;
+                }
+
+                while (ch)
+                {
+                    k = string();
+                    white();
+
+                    if (ch != ':')
+                    {
+                        break;
+                    }
+
+                    next();
+                    o[k] = value();
+                    white();
+
+                    if (ch == '}')
+                    {
+                        next();
+                        return o;
+                    }
+                    else if (ch != ',')
+                    {
+                        break;
+                    }
+
+                    next();
+                    white();
+                }
+            }
+            error("Bad object");
+        }
+
+        function number()
+        {
+            var n = '', v;
+
+            if (ch == '-')
+            {
+                n = '-';
+                next();
+            }
+
+            while (ch >= '0' && ch <= '9')
+            {
+                n += ch;
+                next();
+            }
+
+            if (ch == '.')
+            {
+                n += '.';
+
+                while (next() && ch >= '0' && ch <= '9')
+                {
+                    n += ch;
+                }
+            }
+
+            if (ch == 'e' || ch == 'E')
+            {
+                n += 'e';
+                next();
+
+                if (ch == '-' || ch == '+')
+                {
+                    n += ch;
+                    next();
+                }
+
+                while (ch >= '0' && ch <= '9')
+                {
+                    n += ch;
+                    next();
+                }
+            }
+
+            v = +n;
+
+            if (!isFinite(v))
+            {
+                ////error("Bad number");
+            }
+            else
+            {
+                return v;
+            }
+        }
+
+        function word()
+        {
+            switch (ch)
+            {
+                case 't':   if (next() == 'r' && next() == 'u' && next() == 'e')
+                            {
+                                next();
+                                return true;
+                            }
+                            break;
+
+                case 'f':   if (next() == 'a' && next() == 'l' && next() == 's' && next() == 'e')
+                            {
+                                next();
+                                return false;
+                            }
+                            break;
+
+                case 'n':   if (next() == 'u' && next() == 'l' && next() == 'l')
+                            {
+                                next();
+                                return null;
+                            }
+                            break;
+            }
+            error("Syntax error");
+        }
+
+        function value()
+        {
+            white();
+
+            switch (ch) {
+                case '{': return object();
+
+                case '[': return array();
+
+                case '"': return string();
+
+                case '-': return number();
+
+                default : return ch >= '0' && ch <= '9' ? number() : word();
+            }
+        }
+
+        return value();
+    }
+};
Index: /sandbox/workflow/branches/993/js/nano/NanoAjaxSelectBox.class.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/NanoAjaxSelectBox.class.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/NanoAjaxSelectBox.class.js	(revision 795)
@@ -0,0 +1,85 @@
+
+// class NanoAjaxSelectBox
+function NanoAjaxSelectBox( selectbox_id )
+{
+    // Pre Check: is
+    if( selectbox_id == null || !$(selectbox_id) )
+    {
+        alert( 'No SelectBox ID given!!!\nTerminating!' );
+        return;
+    }
+
+    // -------------------------------------------------------------------------
+    // Private variables
+
+    var _mObjSelectbox = $(selectbox_id);
+
+	// #########################################################################
+    // Privileged Method (has public access and can access private vars & funcs)
+    this.fillSelectBoxByArray = _fillSelectBoxByArray;
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// PRIVATE Methods
+
+    function _fillSelectBoxByArray( data_array, fields_to_add, pre_entries, index_selected )
+    {
+        var is_selected    = false;
+        var new_data_array = [];
+
+        if( _mObjSelectbox.length > 0)
+        {
+            _deleteAllEntries();
+        }
+
+        if(pre_entries.length > 0)
+        {
+            for(var i=0;i<pre_entries.length;i++)
+            {
+                new_data_array.push(pre_entries[i]);
+            }
+            for(var i=0;i<data_array.length;i++)
+            {
+                new_data_array.push(data_array[i]);
+            }
+        }
+        else
+        {
+            new_data_array = data_array;
+        }
+
+        for( i=0; i<new_data_array.length; i++ )
+        {
+            _addSelectBoxEntry( (fields_to_add.length == 0) ? new_data_array[i] : new_data_array[i][fields_to_add[0]],
+                                (fields_to_add.length == 0) ? new_data_array[i] : new_data_array[i][fields_to_add[1]],
+                                ((i == index_selected) ? true : false),
+                                ((i == index_selected) ? true : false) );
+        }
+    }
+
+    function _addSelectBoxEntry(value, desc, default_entry, is_selected)
+    {
+        _mObjSelectbox.options[_mObjSelectbox.length] = new Option(desc, value, default_entry, is_selected);
+    }
+
+    function _deleteAllEntries()
+    {
+        var i = (_mObjSelectbox.length-1);
+
+        while( _mObjSelectbox.length > 0 )
+        {
+            _mObjSelectbox.options[i] = null;
+            --i;
+        }
+    }
+
+    function _deleteFirstEntry()
+    {
+        _mObjSelectbox.options[0] = null;
+    }
+
+    function _deleteLastEntry()
+    {
+        _mObjSelectbox.options[_mObjSelectbox.length - 1] = null;
+    }
+}
Index: /sandbox/workflow/branches/993/js/nano/NanoAjax.class.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/NanoAjax.class.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/NanoAjax.class.js	(revision 795)
@@ -0,0 +1,340 @@
+
+// -----------------------------------------------------------------------------
+// CLASS NanoAjax
+function NanoAjax()
+{
+    /* Instance Variables */
+
+    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    // Public variables
+
+    this.asynchronousMode  = true;
+    this.requestMethod     = 'POST';
+    this.ajaxServerUrl     = '';
+
+    this.statusTranslation = [ 'initializing...',
+                               'connecting...',
+                               'connection established',
+                               'receiving data...',
+                               'done.',
+                               'decoding received data...',
+                               'processing data...',
+                               'done (processing)!' ];
+
+    this.onStateChangeId   = null;
+
+    this.errorReporting    = true;
+    this.disableExceptionReporting = false;
+
+    // only needed if request method is set to: GET
+    this.preparedGetData   = '';
+
+    // -------------------------------------------------------------------------
+    // Private variables
+
+    var _this              = this;
+    var _xmlHttpRequest    = null;
+
+    var _virtualRequest    = new Object();
+
+    var _responseHeader    = '';
+    var _responseBody      = '';
+
+
+	// #########################################################################
+    // Privileged Method (has public access and can access private vars & funcs)
+
+    // event handler
+    this.onStateChange     = null;
+    this.onSuccess         = null;
+    this.onError           = null;
+    this.onException       = null;
+
+    // public accessable methods
+    this.addVirtualRequest   = _addVirtualRequest;
+    this.isVirtualRequestSet = _isVirtualRequestSet;
+    this.sendRequest         = _executeRequest;
+
+
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// PRIVATE Methods
+
+    /**
+     * checks if virtual request is set
+     *
+     * @access private
+     */
+	function _isVirtualRequestSet()
+	{
+        for ( virtualRequest in _virtualRequest )
+        {
+            return true;
+        }
+
+        return false;
+	}
+
+
+    /**
+     * executes real AJAX request
+     *
+     * @access private
+     */
+    function _executeRequest()
+    {
+        _initializeXmlHttpRequest();
+
+        if( typeof _xmlHttpRequest == 'object' )
+        {
+            this.requestMethod =  this.requestMethod.toUpperCase();
+
+           	_xmlHttpRequest.open( this.requestMethod,      // POST or GET
+           	       	              this.ajaxServerUrl +     // full url to Ajax server
+           	       	              this.preparedGetData,    // with GET parameterdata
+           	                      this.asynchronousMode ); // true = async
+
+           	if( this.requestMethod == 'POST' )
+           	{
+               	// set various header parameter
+                _setPostRequestHeader();
+           	}
+
+            // set function if state changes (handler)
+        	_xmlHttpRequest.onreadystatechange = _readyStateHandler;
+
+            // now realy send (execute) request to NanoAjax server (with JSON string)
+        	_xmlHttpRequest.send( JSON.stringify(_virtualRequest) );
+
+        	// release object preventing memory leaks
+        	delete _xmlHttpRequest;
+        }
+        else
+        {
+            alert('ERROR while creating xmlhttprequest object!!!\n\n'+
+                  'Your System is not able to create a xmlhttprequest object!');
+        }
+    }
+
+
+    /**
+     * ready state handler (called every time state changes)
+     *
+     * @access private
+     */
+    function _readyStateHandler()
+    {
+        if( _this.onStateChange )
+        {
+            _this.onStateChange( _xmlHttpRequest.readyState,
+                                 _this.statusTranslation[_xmlHttpRequest.readyState],
+                                 _this.onStateChangeId );
+        }
+
+        try
+        {
+            if ( // request finished
+                 _xmlHttpRequest.readyState == 4
+                 && // HTTP: OK                      HTTP: not modified
+                 ( _xmlHttpRequest.status == 200 || _xmlHttpRequest.status == 304 )
+               )
+            {
+                _responseHeader = _xmlHttpRequest.getAllResponseHeaders();
+                _responseBody   = _xmlHttpRequest.responseText;
+
+                if( -1 == _checkPhpError( _responseBody ) )
+                {
+                    if( _this.onSuccess )
+                    {
+                        var _json_decoded = _getJsonDecodedResponse(_responseBody);
+
+                        if( true == (exception_response = _checkServerException(_json_decoded)) )
+                        {
+                            _this.onSuccess( _json_decoded );
+                        }
+                        else
+                        {
+                            ( _this.onException )
+                                  ? _this.onException( _responseHeader,
+                                                       _responseBody,
+                                                       exception_response )
+
+                                  : _defaultErrorHandler( 'SERVER-SIDE EXCEPTION',
+                                                          exception_response );
+                        }
+                    }
+                    else
+                    {
+                        alert( 'No \'onSuccess\' handler defined!!!\n\n'+_responseBody );
+                    }
+                }
+                else
+                {
+                    ( _this.onError )
+                        ? _this.onError( _responseBody )
+                        : _defaultErrorHandler( 'SERVER-SIDE ERROR',
+                                                'Request could NOT finished!!!' );
+                }
+
+                _clearVirtualRequestData();
+            }
+        }
+        catch( exception )
+        {
+            _clearVirtualRequestData();
+
+            ( _this.onError )
+                ? _this.onError( exception )
+                : _defaultErrorHandler( 'EXCEPTION', exception );
+        }
+    }
+
+
+    /**
+     * initializing xmlhttprequest object by iterate over all given methods,
+     * to find correct browser implementation.
+     *
+     * @access private
+     */
+    function _initializeXmlHttpRequest()
+    {
+        if( _xmlHttpRequest == undefined || _xmlHttpRequest == null )
+        {
+            _xmlHttpRequest = Try.these
+            (
+                function() { return new ActiveXObject('Msxml2.XMLHTTP')   },
+                function() { return new ActiveXObject('Microsoft.XMLHTTP')},
+                function() { return new XMLHttpRequest()                  }
+            ) || false;
+        }
+    }
+
+
+    /**
+     * sets POST request header
+     *
+     * @access private
+     */
+    function _setPostRequestHeader()
+    {
+        // set method, url and protocol / version
+        _xmlHttpRequest.setRequestHeader( 'Method',
+                                          this.requestMethod + ' ' +
+                                          this.ajaxServerUrl + ' HTTP/1.1' );
+
+        // set content type for POST data
+        _xmlHttpRequest.setRequestHeader( 'Content-Type',
+                                          'application/x-www-form-urlencoded' );
+
+        // close connection after transfer
+        _xmlHttpRequest.setRequestHeader( 'Connection' , 'close' );
+    }
+
+
+    /**
+     * add a virtual request to request container (an object)
+     *
+     * @access private
+     */
+    function _addVirtualRequest( requestIdentifier, requestObject )
+    {
+        if( null != requestObject && undefined != requestObject )
+        {
+            _virtualRequest[requestIdentifier] = requestObject;
+        }
+    }
+
+
+    /**
+     * checks for server side PHP errors
+     *
+     * @access private
+     */
+    function _checkPhpError( response_string )
+    {
+        return (response_string.toLowerCase()).search(/((parse|fatal) error)|(fatal|warning|notice)/);
+    }
+
+
+    /**
+     * checks for server side PHP exceptions
+     *
+     * @access private
+     */
+    function _checkServerException( decoded_json_data )
+    {
+        var request_exception = new Array();
+
+        for( var requestIdentifier in decoded_json_data)
+        {
+            if( decoded_json_data[requestIdentifier]['exception'] )
+            {
+                request_exception.push('Exception happend in (virtual) request : '+
+                                       requestIdentifier+' {request identifier}\n'+
+                                       decoded_json_data[requestIdentifier]['exception'] );
+            }
+        }
+
+        return (request_exception.length > 0 )
+                   ? request_exception.join('\n')
+                   : true;
+    }
+
+
+    /**
+     * default error handler (if none is specified)
+     *
+     * @access private
+     */
+    function _defaultErrorHandler( type_header, message )
+    {
+        if( true == this.errorReporting )
+        {
+            alert( 'NanoAjax Class: '+type_header+' !!!\n'+
+                   ('=').repeat(54)+  '\n'+
+                   '\n'+message +   '\n\n'+
+                   ('=').repeat(54)+'\n\n'+
+                   'Response Header:   \n'+
+                   ('-').repeat(100)+ '\n'+
+                   _responseHeader +  '\n'+
+                   'Response Body:     \n'+
+                   ('-').repeat(100)+ '\n'+
+                   _responseBody );
+        }
+    }
+
+
+    /**
+     *
+     *
+     * @access private
+     */
+    function _getJsonDecodedResponse( response )
+    {
+        if( _this.onStateChange )
+        {
+            _this.onStateChange( 5,
+                                 ((_this.statusTranslation) ? _this.statusTranslation[5] : 5),
+                                 _this.onStateChangeId );
+        }
+        return JSON.parse(response);
+    }
+
+
+    function _clearVirtualRequestData()
+    {
+        _virtualRequest = new Object();
+    }
+
+    /**
+     * debugging, triggers AJAX requests / responses into div container
+     *
+     * @access private
+     */
+    function _triggerAjaxData( data )
+    {
+        if( $('id_AJAX_data') )
+        {
+            $('id_AJAX_data').innerHTML = data + $('id_AJAX_data').innerHTML;
+        }
+    }
+}
Index: /sandbox/workflow/branches/993/js/nano/NanoController.class.js
===================================================================
--- /sandbox/workflow/branches/993/js/nano/NanoController.class.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/nano/NanoController.class.js	(revision 795)
@@ -0,0 +1,185 @@
+// -----------------------------------------------------------------------------
+// Class NanoController
+function NanoController()
+{
+    /* Instance Variables */
+
+    // PRIVATE Variables
+    // create NanoAjax Object (executes AJAX)
+    var _mObjNanoAjax              = new NanoAjax();
+
+    _mObjNanoAjax.onSuccess        = _defaultSuccessHandler;
+    _mObjNanoAjax.onError          = _defaultErrorHandler;
+
+
+	// #########################################################################
+    // Privileged Method (has public access and can access private vars & funcs)
+    this.setServerUrl              = setServerUrl;
+    this.setWfUrl                  = setWfUrl;
+    this.setStatusHandler          = setStatusHandler;
+    this.setStatusTranslation      = setStatusTranslation;
+    this.setStateChangeId          = setStateChangeId;
+    this.setSuccessHandler         = setSuccessHandler;
+    this.setExceptionHandler       = setExceptionHandler;
+    this.setErrorHandler           = setErrorHandler;
+
+    this.disableErrorReporting     = _disableErrorReporting;
+
+    this.addVirtualRequest         = _addVirtualRequest;
+    this.addVirtualAutoloadRequest = _addVirtualAutoloadRequest;
+
+    this.sendRequest               = _sendRequest;
+
+
+    function setServerUrl( url )
+    {
+        if( isNaN(url) && url != '' )
+        {
+            _mObjNanoAjax.ajaxServerUrl = url;
+        }
+    }
+
+    function setWfUrl( )
+    {
+		/* encontra o endereço do próprio javascript */
+		var address = $A(document.getElementsByTagName("script")).findAll(
+			function(s)
+			{
+				return (s.src && s.src.match(/js\/nano\/NanoController\.class\.js(\?.*)?$/));
+			}).first().src;
+		/* pega só até o /workflow/ */
+		address = address.replace(/js\/nano\/NanoController\.class\.js(\?.*)?$/, '');
+
+		/* completa o endereço */
+		address = address + location.href.match(/index\.php\?menuaction=workflow\.run_activity\.go.*$/);
+		address = address.replace(/index\.php\?menuaction=workflow\.run_activity\.go/g, 'index.php?menuaction=workflow.run_activity.goAjax');
+        this.setServerUrl(address);
+    }
+
+    function setStatusHandler( status_handler, div_id )
+    {
+        var div_id = (div_id) ?  div_id : null;
+
+        if( status_handler != '' )
+        {
+            _mObjNanoAjax.onStateChange    = status_handler;
+            _mObjNanoAjax.onStateChangeDiv = div_id;
+
+        }
+    }
+
+    function setStatusTranslation( status_translation )
+    {
+        if( status_translation != '' )
+        {
+            _mObjNanoAjax.statusTranslation = status_translation;
+        }
+    }
+
+    function setStateChangeId( status_change_id )
+    {
+        if( status_change_id != '' && $(status_change_id) )
+        {
+            _mObjNanoAjax.onStateChangeId = status_change_id;
+        }
+    }
+
+    function setSuccessHandler( success_handler )
+    {
+        if( success_handler != '' )
+        {
+            _mObjNanoAjax.onSuccess = success_handler;
+        }
+    }
+
+    function setExceptionHandler( exception_handler )
+    {
+        if( exception_handler != '' )
+        {
+            _mObjNanoAjax.onException = exception_handler;
+        }
+    }
+
+    function setErrorHandler( error_handler )
+    {
+        if( error_handler != '' )
+        {
+            _mObjNanoAjax.onError = error_handler;
+        }
+    }
+
+    function _disableErrorReporting()
+    {
+        _mObjNanoAjax.errorReporting = false;
+    }
+
+    function _addVirtualRequest( identifier, parameter, data )
+    {
+        var req = new NanoRequest();
+
+        // (virtual) request parameter
+        req.requestParameter = parameter;
+
+        // (virtual) request data
+        req.requestData      = data;
+
+        _mObjNanoAjax.addVirtualRequest( identifier, req.getAssembledRequest() );
+    }
+
+    function _addVirtualAutoloadRequest( parameter, form, field_prefix)
+    {
+        var req = new NanoRequest();
+
+        // (virtual) request parameter
+        req.requestParameter = parameter;
+
+        // (virtual) request auto load data from HTML form
+        req.autoLoadData( form, field_prefix );
+
+        _mObjNanoAjax.addVirtualRequest( req.getAssembledRequest() );
+    }
+
+    function _sendRequest()
+    {
+        if( _mObjNanoAjax.ajaxServerUrl != '' && _mObjNanoAjax.ajaxServerUrl.length > 2 )
+        {
+            if( _mObjNanoAjax.isVirtualRequestSet() )
+            {
+                _mObjNanoAjax.sendRequest();
+            }
+            else
+            {
+                alert('No (virtual) Request is set!!!');
+            }
+        }
+        else
+        {
+            alert( 'Server URL is not set correctly!!!');
+        }
+    }
+
+    function _defaultSuccessHandler( decode_json_data )
+    {
+        var output      = '';
+        var row_width   = 90;
+
+        for( i= 0; i < decode_json_data.length; i++)
+        {
+            for( var row in decode_json_data[i] )
+            {
+                output += '(virtual) Request No.: '+row+'\n'+unescape(decode_json_data[i][row])+
+                          '\n'+(('-').repeat(row_width))+'\n';
+            }
+        }
+
+        alert( 'Default \'onSuccess\' handler was called!\n'+
+               'Please define your own handler to fit your individual needs.\n\n\n'+
+               'AJAX Response returns (JSON decoded):\n\n'+
+               (('-').repeat(row_width))+'\n'+output);
+    }
+
+    function _defaultErrorHandler( decode_json_data )
+    {
+        alert( "NanoController ERROR:\n"+decode_json_data );
+    }
+}
Index: /sandbox/workflow/branches/993/js/htmlarea/test.cgi
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/test.cgi	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/test.cgi	(revision 795)
@@ -0,0 +1,21 @@
+#! /usr/bin/perl -w
+#
+#
+#
+
+
+
+use CGI;
+
+print "Content-type: text/html\n\n";
+$c = new CGI;
+$ta = $c->param('ta');
+
+print <<EOF;
+<html>
+<body>
+<textarea style="width: 100%; height: 200px">$ta</textarea>
+$ta
+</body>
+</html>
+EOF
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/pt_br.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/pt_br.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/pt_br.js	(revision 795)
@@ -0,0 +1,59 @@
+// I18N constants
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "pt_br",
+
+	tooltips: {
+		bold:           "Negrito",
+		italic:         "Itálico",
+		underline:      "Sublinhado",
+		strikethrough:  "Riscado",
+		subscript:      "Subescrito",
+		superscript:    "Sobrescrito",
+		justifyleft:    "Alinhar à esquerda",
+		justifycenter:  "Centralizar",
+		justifyright:   "Alinhar à direita",
+		justifyfull:    "Justificar",
+		orderedlist:    "Lista com Números",
+		unorderedlist:  "Lista com Marcadores",
+		outdent:        "Deslocar texto para esquerda",
+		indent:         "Deslocar texto para direita",
+		forecolor:      "Cor de Texto",
+		hilitecolor:    "Cor de Fundo",
+		inserthorizontalrule: "Linha Horizontal",
+		createlink:     "Inserir link WEB",
+		insertimage:    "Inserir / Modificar Imagem",
+		inserttable:    "Inserir Tabela",
+		htmlmode:       "Ver Documento em HTML",
+		popupeditor:    "Aumentar Editor",
+		about:          "Sobre este Editor",
+		showhelp:       "Ajuda",
+		textindicator:  "Estilo Atual",
+		undo:           "Desfazer",
+		redo:           "Refazer",
+		cut:            "Recortar",
+		copy:           "Copiar",
+		paste:          "Colar",
+		lefttoright: 	"Direção do texto : esquerda para direita",
+		righttoleft:	"Direção do texto : direita para esquerda"
+		
+	},
+
+	buttons: {
+		"ok":           "Aceitar",
+		"cancel":       "Cancelar"
+	},
+
+	msg: {
+		"Path":          "Caminho",
+		"TEXT_MODE":     "Está em modo TEXTO. Use o botão [HTML] acima, para ativar modo HTML.",
+		"Moz-Clipboard": "A funções de Cortar/Copiar/Colar no formato RTF (Rich Text Format) " +
+						"foram desabilitadas pelo Browser Mozilla/Firefox, por razões de segurança."+
+					"Clique no botão OK para ver como habilitar essas funções no seu Browser Mozilla/Firefox " +
+					" (instruções do próprio site mozilla.org).\nImportante:Se você liberar,será permitido acessar "+
+					" a Área de Transferência via Script!"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/b5.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/b5.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/b5.js	(revision 795)
@@ -0,0 +1,36 @@
+// I18N constants -- Chinese Big-5
+// by Dave Lo -- dlo@interactivetools.com
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "b5",
+
+	tooltips: {
+		bold:           "²ÊÅé",
+		italic:         "±×Åé",
+		underline:      "©³œu",
+		strikethrough:  "§R°£œu",
+		subscript:      "€UŒÐ",
+		superscript:    "€WŒÐ",
+		justifyleft:    "ŠìžmŸa¥ª",
+		justifycenter:  "Šìžm©~€€",
+		justifyright:   "ŠìžmŸa¥k",
+		justifyfull:    "Šìžm¥ª¥k¥­µ¥",
+		orderedlist:    "¶¶§Ç²M³æ",
+		unorderedlist:  "µL§Ç²M³æ",
+		outdent:        "Žî€pŠæ«eªÅ¥Õ",
+		indent:         "¥[ŒeŠæ«eªÅ¥Õ",
+		forecolor:      "€åŠrÃCŠâ",
+		backcolor:      "­IŽºÃCŠâ",
+		horizontalrule: "€ô¥­œu",
+		createlink:     "Ž¡€J³sµ²",
+		insertimage:    "Ž¡€J¹Ï§Î",
+		inserttable:    "Ž¡€Jªí®æ",
+		htmlmode:       "€ÁŽ«HTML­ì©lœX",
+		popupeditor:    "©ñ€j",
+		about:          "Ãö©ó HTMLArea",
+		help:           "»¡©ú",
+		textindicator:  "ŠrÅéšÒ€l"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/se.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/se.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/se.js	(revision 795)
@@ -0,0 +1,38 @@
+// Swedish version for htmlArea v3.0 - Alpha Release
+// - translated by pat<pat@engvall.nu>
+// termŽs and licenses are equal to htmlarea!
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "se",
+
+	tooltips: {
+		bold:           "Fet",
+		italic:         "Kursiv",
+		underline:      "Understruken",
+		strikethrough:  "Genomstruken",
+		subscript:      "Nedsänkt",
+		superscript:    "Upphöjd",
+		justifyleft:    "Vänsterjustera",
+		justifycenter:  "Centrera",
+		justifyright:   "Högerjustera",
+		justifyfull:    "Marginaljustera",
+		orderedlist:    "Numrerad lista",
+		unorderedlist:  "Punktlista",
+		outdent:        "Minska indrag",
+		indent:         "Öka indrag",
+		forecolor:      "Textfärg",
+		backcolor:      "Bakgrundsfärg",
+		horizontalrule: "Vågrät linje",
+		createlink:     "Infoga länk",
+		insertimage:    "Infoga bild",
+		inserttable:    "Infoga tabell",
+		htmlmode:       "Visa källkod",
+		popupeditor:    "Visa i eget fönster",
+		about:          "Om denna editor",
+		help:           "Hjälp",
+		textindicator:  "Nuvarande stil"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/es.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/es.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/es.js	(revision 795)
@@ -0,0 +1,51 @@
+// I18N constants
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "es",
+
+	tooltips: {
+		bold:           "Negrita",
+		italic:         "Cursiva",
+		underline:      "Subrayado",
+		strikethrough:  "Tachado",
+		subscript:      "Subíndice",
+		superscript:    "Superíndice",
+		justifyleft:    "Alinear a la Izquierda",
+		justifycenter:  "Centrar",
+		justifyright:   "Alinear a la Derecha",
+		justifyfull:    "Justificar",
+		orderedlist:    "Lista Ordenada",
+		unorderedlist:  "Lista No Ordenada",
+		outdent:        "Aumentar Sangría",
+		indent:         "Disminuir Sangría",
+		forecolor:      "Color del Texto",
+		hilitecolor:    "Color del Fondo",
+		inserthorizontalrule: "Línea Horizontal",
+		createlink:     "Insertar Enlace",
+		insertimage:    "Insertar Imagen",
+		inserttable:    "Insertar Tabla",
+		htmlmode:       "Ver Documento en HTML",
+		popupeditor:    "Ampliar Editor",
+		about:          "Acerca del Editor",
+		showhelp:       "Ayuda",
+		textindicator:  "Estilo Actual",
+		undo:           "Deshacer",
+		redo:           "Rehacer",
+		cut:            "Cortar selección",
+		copy:           "Copiar selección",
+		paste:          "Pegar desde el portapapeles"
+	},
+
+	buttons: {
+		"ok":           "Aceptar",
+		"cancel":       "Cancelar"
+	},
+
+	msg: {
+		"Path":         "Ruta",
+		"TEXT_MODE":    "Esta en modo TEXTO. Use el boton [<>] para cambiar a WYSIWIG",
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/si.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/si.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/si.js	(revision 795)
@@ -0,0 +1,63 @@
+// I18N constants
+
+// LANG: "si", ENCODING: ISO-8859-2
+// Author: Tomaz Kregar, x_tomo_x@email.si
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "si",
+
+	tooltips: {
+		bold:           "Krepko",
+		italic:         "LeŸeèe",
+		underline:      "Podèrtano",
+		strikethrough:  "Preèrtano",
+		subscript:      "Podpisano",
+		superscript:    "Nadpisano",
+		justifyleft:    "Poravnaj levo",
+		justifycenter:  "Na sredino",
+		justifyright:   "Poravnaj desno",
+		justifyfull:    "Porazdeli vsebino",
+		orderedlist:    "O¹tevilèevanje",
+		unorderedlist:  "Oznaèevanje",
+		outdent:        "Zmanj¹aj zamik",
+		indent:         "Poveèaj zamik",
+		forecolor:      "Barva pisave",
+		hilitecolor:    "Barva ozadja",
+		horizontalrule: "Vodoravna èrta",
+		createlink:     "Vstavi hiperpovezavo",
+		insertimage:    "Vstavi sliko",
+		inserttable:    "Vstavi tabelo",
+		htmlmode:       "Preklopi na HTML kodo",
+		popupeditor:    "Poveèaj urejevalnik",
+		about:          "Vizitka za urejevalnik",
+		showhelp:       "Pomoè za urejevalnik",
+		textindicator:  "Trenutni slog",
+		undo:           "Razveljavi zadnjo akcijo",
+		redo:           "Uveljavi zadnjo akcijo",
+		cut:            "IzreŸi",
+		copy:           "Kopiraj",
+		paste:          "Prilepi"
+	},
+
+	buttons: {
+		"ok":           "V redu",
+		"cancel":       "Preklièi"
+	},
+
+	msg: {
+		"Path":         "Pot",
+		"TEXT_MODE":    "Si v tekstovnem naèinu.  Uporabi [<>] gumb za prklop nazaj na WYSIWYG."
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/no.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/no.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/no.js	(revision 795)
@@ -0,0 +1,79 @@
+// Norwegian version for htmlArea v3.0 - pre1
+// - translated by ses<ses@online.no>
+// Additional translations by Håvard Wigtil <havardw@extend.no>
+// termŽs and licenses are equal to htmlarea!
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "no",
+
+	tooltips: {
+		bold:                 "Fet",
+		italic:               "Kursiv",
+		underline:            "Understreket",
+		strikethrough:        "Gjennomstreket",
+		subscript:            "Nedsenket",
+		superscript:          "Opphøyet",
+		justifyleft:          "Venstrejuster",
+		justifycenter:        "Midtjuster",
+		justifyright:         "Høyrejuster",
+		justifyfull:          "Blokkjuster",
+		orderedlist:    "Nummerert liste",
+		unorderedlist:  "Punktliste",
+		outdent:              "Reduser innrykk",
+		indent:               "Øke innrykk",
+		forecolor:            "Tekstfarge",
+		hilitecolor:          "Bakgrundsfarge",
+		inserthorizontalrule: "Vannrett linje",
+		createlink:           "Lag lenke",
+		insertimage:          "Sett inn bilde",
+		inserttable:          "Sett inn tabell",
+		htmlmode:             "Vis kildekode",
+		popupeditor:          "Vis i eget vindu",
+		about:                "Om denne editor",
+		showhelp:             "Hjelp",
+		textindicator:        "Nåværende stil",
+                undo:                 "Angrer siste redigering",
+		redo:                 "Gjør om siste angring",
+		cut:                  "Klipp ut område",
+		copy:                 "Kopier område",
+		paste:                "Lim inn",
+		lefttoright:          "Fra venstre mot høyre",
+		righttoleft:          "Fra høyre mot venstre"
+	},
+    
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Avbryt"
+	},
+
+	msg: {
+		"Path":         "Tekstvelger",
+		"TEXT_MODE":    "Du er i tekstmodus  Klikk på [<>] for å gå tilbake til WYSIWIG.",
+                "IE-sucks-full-screen" :
+		// translate here
+                "Visning i eget vindu har kjente problemer med Internet Explorer, " + 
+                "på grunn av problemer med denne nettleseren. Mulige problemer er et uryddig " + 
+                "skjermbilde, manglende editorfunksjoner og/eller at nettleseren crasher. Hvis du bruker Windows 95 eller Windows 98 " +
+                "er det også muligheter for at Windows will crashe.\n\n" +
+                "Trykk 'OK' hvis du vil bruke visning i eget vindu på tross av denne advarselen."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "Avbryt",
+		"Insert/Modify Link"                                : "Rediger lenke",
+		"New window (_blank)"                               : "Eget vindu (_blank)",
+		"None (use implicit)"                               : "Ingen (bruk standardinnstilling)",
+		"OK"                                                : "OK",
+		"Other"                                             : "Annen",
+		"Same frame (_self)"                                : "Samme ramme (_self)",
+		"Target:"                                           : "Mål:",
+		"Title (tooltip):"                                  : "Tittel (tooltip):",
+		"Top frame (_top)"                                  : "Toppramme (_top)",
+		"URL:"                                              : "Adresse:",
+		"You must enter the URL where this link points to"  : "Du må skrive inn en adresse som denne lenken skal peke til"
+	}
+};
+
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/hu.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/hu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/hu.js	(revision 795)
@@ -0,0 +1,90 @@
+// I18N constants
+
+// LANG: "hu", ENCODING: UTF-8
+// Author: MiklÃ³s Somogyi, <somogyine@vnet.hu>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "hu",
+
+	tooltips: {
+		bold:           "FÃ©lkÃ¶vÃ©r",
+		italic:         "DÅlt",
+		underline:      "AlÃ¡hÃºzott",
+		strikethrough:  "ÃthÃºzott",
+		subscript:      "AlsÃ³ index",
+		superscript:    "FelsÅ index",
+		justifyleft:    "Balra zÃ¡rt",
+		justifycenter:  "KÃ¶zÃ©pre zÃ¡rt",
+		justifyright:   "Jobbra zÃ¡rt",
+		justifyfull:    "SorkizÃ¡rt",
+		orderedlist:    "SzÃ¡mozott lista",
+		unorderedlist:  "SzÃ¡mozatlan lista",
+		outdent:        "BehÃºzÃ¡s csÃ¶kkentÃ©se",
+		indent:         "BehÃºzÃ¡s nÃ¶velÃ©se",
+		forecolor:      "KarakterszÃ­n",
+		hilitecolor:    "HÃ¡ttÃ©rszÃ­n",
+		horizontalrule: "ElvÃ¡lasztÃ³ vonal",
+		createlink:     "HiperhivatkozÃ¡s beszÃºrÃ¡sa",
+		insertimage:    "KÃ©p beszÃºrÃ¡sa",
+		inserttable:    "TÃ¡blÃ¡zat beszÃºrÃ¡sa",
+		htmlmode:       "HTML forrÃ¡s be/ki",
+		popupeditor:    "SzerkesztÅ kÃŒlÃ¶n ablakban",
+		about:          "NÃ©vjegy",
+		showhelp:       "SÃºgÃ³",
+		textindicator:  "AktuÃ¡lis stÃ­lus",
+		undo:           "VisszavonÃ¡s",
+		redo:           "Ãjra vÃ©grehajtÃ¡s",
+		cut:            "KivÃ¡gÃ¡s",
+		copy:           "MÃ¡solÃ¡s",
+		paste:          "BeillesztÃ©s",
+		lefttoright:    "IrÃ¡ny balrÃ³l jobbra",
+		righttoleft:    "IrÃ¡ny jobbrÃ³l balra"
+	},
+
+	buttons: {
+		"ok":           "Rendben",
+		"cancel":       "MÃ©gsem"
+	},
+
+	msg: {
+		"Path":         "Hierarchia",
+		"TEXT_MODE":    "ForrÃ¡s mÃ³d. VisszavÃ¡ltÃ¡s [<>] gomb",
+
+		"IE-sucks-full-screen" :
+		// translate here
+		"A teljeskÃ©prenyÅs szerkesztÃ©s hibÃ¡t okozhat Internet Explorer hasznÃ¡lata esetÃ©n, " +
+		"ez a bÃ¶ngÃ©szÅ a hibÃ¡ja, amit nem tudunk kikerÃŒlni. Szemetet Ã©szlelhet a kÃ©prenyÅn, " +
+		"illetve nÃ©hÃ¡ny funkciÃ³ hiÃ¡nyozhat Ã©s/vagy vÃ©letlenszerÅ±en lefagyhat a bÃ¶ngÃ©szÅ. " +
+		"Windows 9x operaciÃ³s futtatÃ¡sa esetÃ©n elÃ©g valÃ³szÃ­nÅ±, hogy 'General Protection Fault' " +
+		"hibÃ¡t okoz Ã©s Ãºjra kell indÃ­tania a szÃ¡mÃ­tÃ³gÃ©pet.\n\n" +
+		"FigyelmeztettÃŒk.  KÃ©rjÃŒk nyomja meg a Rendben gombot, ha mÃ©gis szeretnÃ© megnyitni a " +
+		"szerkesztÅt kÃŒlÃ¶n ablakban."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "MÃ©gsem",
+		"Insert/Modify Link"                                : "HivatkozÃ¡s BeszÃºrÃ¡sa/MÃ³dosÃ­tÃ¡sa",
+		"New window (_blank)"                               : "Ãj ablak (_blank)",
+		"None (use implicit)"                               : "Nincs (use implicit)",
+		"OK"                                                : "OK",
+		"Other"                                             : "MÃ¡s",
+		"Same frame (_self)"                                : "Ugyanabba a keretbe (_self)",
+		"Target:"                                           : "CÃ©l:",
+		"Title (tooltip):"                                  : "CÃ­m (tooltip):",
+		"Top frame (_top)"                                  : "FelsÅ keret (_top)",
+		"URL:"                                              : "URL:",
+		"You must enter the URL where this link points to"  : "Be kell Ã­rnia az URL-t, ahova a hivatkozÃ¡s mutasson"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ja-jis.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ja-jis.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ja-jis.js	(revision 795)
@@ -0,0 +1,37 @@
+// I18N constants -- Japanese JIS
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ja-jis",
+
+	tooltips: {
+		bold:           "$BB@;z(B",
+		italic:         "$B<PBN(B",
+		underline:      "$B2<@~(B",
+		strikethrough:  "$BBG$A>C$7@~(B",
+		subscript:      "$B2<IU$-E:$(;z(B",
+		superscript:    "$B>eIU$-E:$(;z(B",
+		justifyleft:    "$B:84s$;(B",
+		justifycenter:  "$BCf1{4s$;(B",
+		justifyright:   "$B1&4s$;(B",
+		justifyfull:    "$B6QEy3dIU(B",
+		orderedlist:    "$BHV9fIU$-2U>r=q$-(B",
+		unorderedlist:  "$B5-9fIU$-2U>r=q$-(B",
+		outdent:        "$B%$%s%G%s%H2r=|(B",
+		indent:         "$B%$%s%G%s%H@_Dj(B",
+		forecolor:      "$BJ8;z?'(B",
+		backcolor:      "$BGX7J?'(B",
+		horizontalrule: "$B?eJ?@~(B",
+		createlink:     "$B%j%s%/:n@.(B",
+		insertimage:    "$B2hA|A^F~(B",
+		inserttable:    "$B%F!<%V%kA^F~(B",
+		htmlmode:       "HTML$BI=<(@ZBX(B",
+		popupeditor:    "$B%(%G%#%?3HBg(B",
+		about:          "$B%P!<%8%g%s>pJs(B",
+		help:           "$B%X%k%W(B",
+		textindicator:  "$B8=:_$N%9%?%$%k(B"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ro.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ro.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ro.js	(revision 795)
@@ -0,0 +1,80 @@
+// I18N constants
+
+// LANG: "ro", ENCODING: UTF-8
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ro",
+
+	tooltips: {
+		bold:           "ÃngroÅat",
+		italic:         "Italic",
+		underline:      "Subliniat",
+		strikethrough:  "TÄiat",
+		subscript:      "Indice jos",
+		superscript:    "Indice sus",
+		justifyleft:    "Aliniere la stÃ¢nga",
+		justifycenter:  "Aliniere pe centru",
+		justifyright:   "Aliniere la dreapta",
+		justifyfull:    "Aliniere Ã®n ambele pÄrÅ£i",
+		orderedlist:    "ListÄ ordonatÄ",
+		unorderedlist:  "ListÄ marcatÄ",
+		outdent:        "MicÅoreazÄ alineatul",
+		indent:         "MÄreÅte alineatul",
+		forecolor:      "Culoarea textului",
+		hilitecolor:    "Culoare de fundal",
+		horizontalrule: "Linie orizontalÄ",
+		createlink:     "InsereazÄ/modificÄ link",
+		insertimage:    "InsereazÄ/modificÄ imagine",
+		inserttable:    "InsereazÄ un tabel",
+		htmlmode:       "Sursa HTML / WYSIWYG",
+		popupeditor:    "MaximizeazÄ editorul",
+		about:          "Despre editor",
+		showhelp:       "DocumentaÅ£ie (devel)",
+		textindicator:  "Stilul curent",
+		undo:           "AnuleazÄ ultima acÅ£iune",
+		redo:           "Reface ultima acÅ£iune anulatÄ",
+		cut:            "Taie Ã®n clipboard",
+		copy:           "Copie Ã®n clipboard",
+		paste:          "Aduce din clipboard",
+		lefttoright:    "DirecÅ£ia de scriere: stÃ¢nga - dreapta",
+		righttoleft:    "DirecÅ£ia de scriere: dreapta - stÃ¢nga"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "AnuleazÄ"
+	},
+
+	msg: {
+		"Path":         "Calea",
+		"TEXT_MODE":    "EÅti Ã®n modul TEXT.  ApasÄ butonul [<>] pentru a te Ã®ntoarce Ã®n modul WYSIWYG."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "RenunÅ£Ä",
+		"Insert/Modify Link"                                : "InsereazÄ/modifcÄ link",
+		"New window (_blank)"                               : "FereastrÄ nouÄ (_blank)",
+		"None (use implicit)"                               : "Nimic (foloseÅte ce-i implicit)",
+		"OK"                                                : "AcceptÄ",
+		"Other"                                             : "Alt target",
+		"Same frame (_self)"                                : "AceeaÅi fereastrÄ (_self)",
+		"Target:"                                           : "Å¢inta:",
+		"Title (tooltip):"                                  : "Titlul (tooltip):",
+		"Top frame (_top)"                                  : "Fereastra principalÄ (_top)",
+		"URL:"                                              : "URL:",
+		"You must enter the URL where this link points to"  : "Trebuie sÄ introduceÅ£i un URL"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ru.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ru.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ru.js	(revision 795)
@@ -0,0 +1,63 @@
+﻿// I18N constants
+
+// LANG: "ru", ENCODING: UTF-8 | ISO-8859-1
+// Author: Yulya Shtyryakova, <yulya@vdcom.ru>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ru",
+
+	tooltips: {
+		bold:           "Полужирный",
+		italic:         "Наклонный",
+		underline:      "Подчеркнутый",
+		strikethrough:  "Перечеркнутый",
+		subscript:      "Нижний индекс",
+		superscript:    "Верхний индекс",
+		justifyleft:    "По левому краю",
+		justifycenter:  "По центру",
+		justifyright:   "По правому краю",
+		justifyfull:    "По ширине",
+		orderedlist:    "Нумерованный лист",
+		unorderedlist:  "Маркированный лист",
+		outdent:        "Уменьшить отступ",
+		indent:         "Увеличить отступ",
+		forecolor:      "Цвет шрифта",
+		hilitecolor:    "Цвет фона",
+		horizontalrule: "Горизонтальный разделитель",
+		createlink:     "Вставить гиперссылку",
+		insertimage:    "Вставить изображение",
+		inserttable:    "Вставить таблицу",
+		htmlmode:       "Показать Html-код",
+		popupeditor:    "Увеличить редактор",
+		about:          "О редакторе",
+		showhelp:       "Помощь",
+		textindicator:  "Текущий стиль",
+		undo:           "Отменить",
+		redo:           "Повторить",
+		cut:            "Вырезать",
+		copy:           "Копировать",
+		paste:          "Вставить"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Отмена"
+	},
+
+	msg: {
+		"Path":         "Путь",
+		"TEXT_MODE":    "Вы в режиме отображения Html-кода. нажмите кнопку [<>], чтобы переключиться в визуальный режим."
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/gb.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/gb.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/gb.js	(revision 795)
@@ -0,0 +1,36 @@
+// I18N constants -- Chinese GB
+// by Dave Lo -- dlo@interactivetools.com
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "gb",
+
+	tooltips: {
+		bold:           "ŽÖÌå",
+		italic:         "Ð±Ìå",
+		underline:      "µ×Ïß",
+		strikethrough:  "ÉŸ³ýÏß",
+		subscript:      "ÏÂ±ê",
+		superscript:    "ÉÏ±ê",
+		justifyleft:    "Î»ÖÃ¿¿×ó",
+		justifycenter:  "Î»ÖÃŸÓÖÐ",
+		justifyright:   "Î»ÖÃ¿¿ÓÒ",
+		justifyfull:    "Î»ÖÃ×óÓÒÆœµÈ",
+		orderedlist:    "Ë³ÐòÇåµ¥",
+		unorderedlist:  "ÎÞÐòÇåµ¥",
+		outdent:        "ŒõÐ¡ÐÐÇ°¿Õ°×",
+		indent:         "ŒÓ¿íÐÐÇ°¿Õ°×",
+		forecolor:      "ÎÄ×ÖÑÕÉ«",
+		backcolor:      "±³Ÿ°ÑÕÉ«",
+		horizontalrule: "Ë®ÆœÏß",
+		createlink:     "²åÈëÁ¬œá",
+		insertimage:    "²åÈëÍŒÐÎ",
+		inserttable:    "²åÈë±ížñ",
+		htmlmode:       "ÇÐ»»HTMLÔ­ÊŒÂë",
+		popupeditor:    "·ÅŽó",
+		about:          "¹Øì¶ HTMLArea",
+		help:           "ËµÃ÷",
+		textindicator:  "×ÖÌåÀý×Ó"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ch.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ch.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ch.js	(revision 795)
@@ -0,0 +1,94 @@
+// I18N constants
+
+// LANG: "ch", ENCODING: UTF-8
+// Samuel Stone, http://stonemicro.com/
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ch",
+
+	tooltips: {
+		bold:           "ç²é«",
+		italic:         "æé«",
+		underline:      "åºç·",
+		strikethrough:  "åªç·",
+		subscript:      "äžæš",
+		superscript:    "äžæš",
+		justifyleft:    "é å·Š",
+		justifycenter:  "å±
+äž­",
+		justifyright:   "é å³",
+		justifyfull:    "æŽéœ",
+		orderedlist:    "é åºæž
+å®",
+		unorderedlist:  "ç¡åºæž
+å®",
+		outdent:        "äŒžæ",
+		indent:         "çž®æ",
+		forecolor:      "æå­é¡è²",
+		backcolor:      "èæ¯é¡è²",
+		horizontalrule: "æ°Žå¹³ç·",
+		createlink:     "æå
+¥é£çµ",
+		insertimage:    "æå
+¥åå",
+		inserttable:    "æå
+¥è¡šæ Œ",
+		htmlmode:       "åæHTMLåå§ç¢Œ",
+		popupeditor:    "äŒžåºç·šèŒ¯ç³»çµ±",
+		about:          "éæŒ HTMLArea",
+		help:           "èªªæ",
+		textindicator:  "å­é«äŸå­",
+		undo:           "åå",
+		redo:           "éæ¥",
+		cut:            "åªå¶éé¡¹",
+		copy:           "å€å¶éé¡¹",
+		paste:          "èŽŽäž",
+		lefttoright:    "ä»å·Šå°å³",
+		righttoleft:    "ä»å³å°å·Š"
+	},
+
+	buttons: {
+		"ok":           "å¥œ",
+		"cancel":       "åæ¶"
+	},
+
+	msg: {
+		"Path":         "éåŸ",
+		"TEXT_MODE":    "äœ åšçšçŽå­ç·šèŒ¯æ¹åŒ.  çš [<>] æéèœå æèŠå³æåŸ ç·šèŒ¯æ¹åŒ.",
+
+		"IE-sucks-full-screen" :
+		// translate here
+		"æŽé åŒåšInternet Explorer äžåžžåºåé¡, " +
+		"å çºéæ¯ Internet Explorer çç¡ååé¡ïŒæåç¡æ³è§£æ±ºã" +
+		"äœ å¯èœçèŠäžäºååŸïŒæéå°å
+¶ä»åé¡ã" +
+		"æåå·²è­Šåäºäœ . åŠæèŠèœå° æ­£é åŒ è«æ å¥œ.",
+
+		"Moz-Clipboard" :
+		"Unprivileged scripts cannot access Cut/Copy/Paste programatically " +
+		"for security reasons.  Click OK to see a technical note at mozilla.org " +
+		"which shows you how to allow a script to access the clipboard."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "åæ¶",
+		"Insert/Modify Link"                                : "æå
+¥/æ¹å¯«é£çµ",
+		"New window (_blank)"                               : "æ°çªæ·(_blank)",
+		"None (use implicit)"                               : "ç¡(use implicit)",
+		"OK"                                                : "å¥œ",
+		"Other"                                             : "å
+¶ä»",
+		"Same frame (_self)"                                : "æ¬å¡ (_self)",
+		"Target:"                                           : "ç®æšå¡:",
+		"Title (tooltip):"                                  : "äž»é¡ (tooltip):",
+		"Top frame (_top)"                                  : "äžå¡ (_top)",
+		"URL:"                                              : "ç¶²å:",
+		"You must enter the URL where this link points to"  : "äœ å¿
+é èŒžå
+¥äœ èŠè¿ç»çç¶²å"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/nb.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/nb.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/nb.js	(revision 795)
@@ -0,0 +1,36 @@
+// I18N constants
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "nb",
+
+	tooltips: {
+		bold:           "Fet",
+		italic:         "Kursiv",
+		underline:      "Understreket",
+		strikethrough:  "Gjennomstreket",
+		subscript:      "Senket",
+		superscript:    "Hevet",
+		justifyleft:    "Venstrejuster",
+		justifycenter:  "Midtjuster",
+		justifyright:   "Høyrejuster",
+		justifyfull:    "Blokkjuster",
+		orderedlist:    "Nummerert liste",
+		unorderedlist:  "Punktmerket liste",
+		outdent:        "Øke innrykk",
+		indent:         "Reduser innrykk",
+		forecolor:      "Skriftfarge",
+		backcolor:      "Bakgrunnsfarge",
+		horizontalrule: "Horisontal linje",
+		createlink:     "Sett inn lenke",
+		insertimage:    "Sett inn bilde",
+		inserttable:    "Sett inn tabell",
+		htmlmode:       "Vis HTML kode",
+		popupeditor:    "Forstørr redigeringsvindu",
+		about:          "Om..",
+		help:           "Hjelp",
+		textindicator:  "Gjeldende stil"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/el.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/el.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/el.js	(revision 795)
@@ -0,0 +1,92 @@
+// I18N constants
+
+// LANG: "el", ENCODING: UTF-8 | ISO-8859-7
+// Author: Dimitris Glezos, dimitris@glezos.com
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "el",
+
+	tooltips: {
+		bold:           "ÎÎœÏÎ¿ÎœÎ±",
+		italic:         "Î Î»Î¬Î³Î¹Î±",
+		underline:      "Î¥ÏÎ¿Î³ÏÎ±ÎŒÎŒÎ¹ÏÎŒÎ­ÎœÎ±",
+		strikethrough:  "ÎÎ¹Î±Î³ÏÎ±ÎŒÎŒÎ­ÎœÎ±",
+		subscript:      "ÎÎµÎ¯ÎºÏÎ·Ï",
+		superscript:    "ÎÎµÎ¯ÎºÏÎ·Ï",
+		justifyleft:    "Î£ÏÎ¿Î¯ÏÎ¹ÏÎ· ÎÏÎ¹ÏÏÎµÏÎ¬",
+		justifycenter:  "Î£ÏÎ¿Î¯ÏÎ¹ÏÎ· ÎÎ­ÎœÏÏÎ¿",
+		justifyright:   "Î£ÏÎ¿Î¯ÏÎ¹ÏÎ· ÎÎµÎŸÎ¹Î¬",
+		justifyfull:    "Î Î»Î®ÏÎ·Ï Î£ÏÎ¿Î¯ÏÎ¹ÏÎ·",
+		orderedlist:    "ÎÏÎ¯ÎžÎŒÎ·ÏÎ·",
+		unorderedlist:  "ÎÎ¿Ï
+ÎºÎºÎ¯ÎŽÎµÏ",
+		outdent:        "ÎÎµÎ¯ÏÏÎ· ÎÏÎ¿ÏÎ®Ï",
+		indent:         "ÎÏÎŸÎ·ÏÎ· ÎÏÎ¿ÏÎ®Ï",
+		forecolor:      "Î§ÏÏÎŒÎ± ÎÏÎ±ÎŒÎŒÎ±ÏÎ¿ÏÎµÎ¹ÏÎ¬Ï",
+		hilitecolor:    "Î§ÏÏÎŒÎ± ÎŠÏÎœÏÎ¿Ï
+",
+		horizontalrule: "ÎÏÎ¹Î¶ÏÎœÏÎ¹Î± ÎÏÎ±ÎŒÎŒÎ®",
+		createlink:     "ÎÎ¹ÏÎ±Î³ÏÎ³Î® Î£Ï
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+",
+		insertimage:    "ÎÎ¹ÏÎ±Î³ÏÎ³Î®/Î€ÏÎ¿ÏÎ¿ÏÎ¿Î¯Î·ÏÎ· ÎÎ¹ÎºÏÎœÎ±Ï",
+		inserttable:    "ÎÎ¹ÏÎ±Î³ÏÎ³Î® Î Î¯ÎœÎ±ÎºÎ±",
+		htmlmode:       "ÎÎœÎ±Î»Î»Î±Î³Î® ÏÎµ/Î±ÏÏ HTML",
+		popupeditor:    "ÎÎµÎ³Î­ÎœÎžÏ
+ÎœÏÎ· ÎµÏÎµÎŸÎµÏÎ³Î±ÏÏÎ®",
+		about:          "Î Î»Î·ÏÎ¿ÏÎ¿ÏÎ¯ÎµÏ",
+		showhelp:       "ÎÎ¿Î®ÎžÎµÎ¹Î±",
+		textindicator:  "Î Î±ÏÏÎœ ÏÏÏ
+Î»",
+		undo:           "ÎÎœÎ±Î¯ÏÎµÏÎ· ÏÎµÎ»ÎµÏ
+ÏÎ±Î¯Î±Ï ÎµÎœÎ­ÏÎ³ÎµÎ¹Î±Ï",
+		redo:           "ÎÏÎ±ÎœÎ±ÏÎ¿ÏÎ¬ Î±ÏÏ Î±ÎœÎ±Î¯ÏÎµÏÎ·",
+		cut:            "ÎÏÎ¿ÎºÎ¿ÏÎ®",
+		copy:           "ÎÎœÏÎ¹Î³ÏÎ±ÏÎ®",
+		paste:          "ÎÏÎ¹ÎºÏÎ»Î»Î·ÏÎ·",
+        lefttoright:    "ÎÎ±ÏÎµÏÎžÏ
+ÎœÏÎ· Î±ÏÎ¹ÏÏÎµÏÎ¬ ÏÏÎ¿Ï ÎŽÎµÎŸÎ¹Î¬",
+        righttoleft:    "ÎÎ±ÏÎµÏÎžÏ
+ÎœÏÎ· Î±ÏÏ ÎŽÎµÎŸÎ¹Î¬ ÏÏÎ¿Ï ÏÎ± Î±ÏÎ¹ÏÏÎµÏÎ¬"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "ÎÎºÏÏÏÏÎ·"
+	},
+
+	msg: {
+		"Path":         "ÎÎ¹Î±ÎŽÏÎ¿ÎŒÎ®",
+		"TEXT_MODE":    "ÎÎ¯ÏÏÎµ ÏÎµ TEXT MODE.  Î§ÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹Î®ÏÏÎµ ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ [<>] Î³Î¹Î± ÎœÎ± ÎµÏÎ±ÎœÎ­ÏÎžÎµÏÎµ ÏÏÎ¿ WYSIWIG.",
+
+       "IE-sucks-full-screen":	"Î ÎºÎ±ÏÎ¬ÏÏÎ±ÏÎ· ÏÎ»Î®ÏÎ·Ï Î¿ÎžÏÎœÎ·Ï Î­ÏÎµÎ¹ ÏÏÎ¿Î²Î»Î®ÎŒÎ±ÏÎ± ÎŒÎµ ÏÎ¿Îœ Internet Explorer, " +
+       							"Î»ÏÎ³Ï ÏÏÎ±Î»ÎŒÎ¬ÏÏÎœ ÏÏÎ¿Îœ Î¯ÎŽÎ¹Î¿ ÏÎ¿Îœ browser.  ÎÎœ ÏÎ¿ ÏÏÏÏÎ·ÎŒÎ± ÏÎ±Ï ÎµÎ¯ÎœÎ±Î¹ Windows 9x " +
+       							"ÎŒÏÎ¿ÏÎµÎ¯ ÎºÎ±Î¹ ÎœÎ± ÏÏÎµÎ¹Î±ÏÏÎµÎ¯ÏÎµ reboot. ÎÎœ ÎµÎ¯ÏÏÎµ ÏÎ¯Î³Î¿Ï
+ÏÎ¿Î¹, ÏÎ±ÏÎ®ÏÏÎµ ÎÎ."
+       },
+
+       dialogs: {
+               "Cancel"                                            : "ÎÎºÏÏÏÏÎ·",
+               "Insert/Modify Link"                                : "ÎÎ¹ÏÎ±Î³ÏÎ³Î®/Î€ÏÎ¿ÏÎ¿ÏÎ¿Î¯Î·ÏÎ· ÏÏÎœÎŽÎµÏÎŒÎ¿Ï
+",
+               "New window (_blank)"                               : "ÎÎ­Î¿ ÏÎ±ÏÎ¬ÎžÏ
+ÏÎ¿ (_blank)",
+               "None (use implicit)"                               : "ÎÎ±ÎœÎ­ÎœÎ± (ÏÏÎ®ÏÎ· Î±ÏÏÎ»Ï
+ÏÎ¿Ï
+)",
+               "OK"                                                : "ÎÎœÏÎ¬ÎŸÎµÎ¹",
+               "Other"                                             : "ÎÎ»Î»Î¿",
+               "Same frame (_self)"                                : "ÎÎŽÎ¹Î¿ frame (_self)",
+               "Target:"                                           : "Target:",
+               "Title (tooltip):"                                  : "Î€Î¯ÏÎ»Î¿Ï (tooltip):",
+               "Top frame (_top)"                                  : "Î Î¬ÎœÏ frame (_top)",
+               "URL:"                                              : "URL:",
+               "You must enter the URL where this link points to"  : "Î ÏÎ­ÏÎµÎ¹ ÎœÎ± ÎµÎ¹ÏÎ¬Î³ÎµÏÎµ ÏÎ¿ URL ÏÎ¿Ï
+ Î¿ÎŽÎ·Î³ÎµÎ¯ Î±Ï
+ÏÏÏ Î¿ ÏÏÎœÎŽÎµÏÎŒÎ¿Ï"
+       }
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/makefile.xml
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/makefile.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/makefile.xml	(revision 795)
@@ -0,0 +1,3 @@
+<files>
+  <file name="*.js" />
+</files>
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/en.js	(revision 795)
@@ -0,0 +1,93 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "en",
+
+	tooltips: {
+		bold:           "Bold",
+		italic:         "Italic",
+		underline:      "Underline",
+		strikethrough:  "Strikethrough",
+		subscript:      "Subscript",
+		superscript:    "Superscript",
+		justifyleft:    "Justify Left",
+		justifycenter:  "Justify Center",
+		justifyright:   "Justify Right",
+		justifyfull:    "Justify Full",
+		orderedlist:    "Ordered List",
+		unorderedlist:  "Bulleted List",
+		outdent:        "Decrease Indent",
+		indent:         "Increase Indent",
+		forecolor:      "Font Color",
+		hilitecolor:    "Background Color",
+		horizontalrule: "Horizontal Rule",
+		createlink:     "Insert Web Link",
+		insertimage:    "Insert/Modify Image",
+		inserttable:    "Insert Table",
+		htmlmode:       "Toggle HTML Source",
+		popupeditor:    "Enlarge Editor",
+		about:          "About this editor",
+		showhelp:       "Help using editor",
+		textindicator:  "Current style",
+		undo:           "Undoes your last action",
+		redo:           "Redoes your last action",
+		cut:            "Cut selection",
+		copy:           "Copy selection",
+		paste:          "Paste from clipboard",
+		lefttoright:    "Direction left to right",
+		righttoleft:    "Direction right to left"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Cancel"
+	},
+
+	msg: {
+		"Path":         "Path",
+		"TEXT_MODE":    "You are in TEXT MODE.  Use the [<>] button to switch back to WYSIWYG.",
+
+		"IE-sucks-full-screen" :
+		// translate here
+		"The full screen mode is known to cause problems with Internet Explorer, " +
+		"due to browser bugs that we weren't able to workaround.  You might experience garbage " +
+		"display, lack of editor functions and/or random browser crashes.  If your system is Windows 9x " +
+		"it's very likely that you'll get a 'General Protection Fault' and need to reboot.\n\n" +
+		"You have been warned.  Please press OK if you still want to try the full screen editor.",
+
+		"Moz-Clipboard" :
+		"Unprivileged scripts cannot access Cut/Copy/Paste programatically " +
+		"for security reasons.  Click OK to see a technical note at mozilla.org " +
+		"which shows you how to allow a script to access the clipboard."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "Cancel",
+		"Insert/Modify Link"                                : "Insert/Modify Link",
+		"New window (_blank)"                               : "New window (_blank)",
+		"None (use implicit)"                               : "None (use implicit)",
+		"OK"                                                : "OK",
+		"Other"                                             : "Other",
+		"Same frame (_self)"                                : "Same frame (_self)",
+		"Target:"                                           : "Target:",
+		"Title (tooltip):"                                  : "Title (tooltip):",
+		"Top frame (_top)"                                  : "Top frame (_top)",
+		"URL:"                                              : "URL:",
+		"You must enter the URL where this link points to"  : "You must enter the URL where this link points to"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ja-euc.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ja-euc.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ja-euc.js	(revision 795)
@@ -0,0 +1,37 @@
+// I18N constants -- Japanese EUC
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ja-euc",
+
+	tooltips: {
+		bold:           "ÂÀ»ú",
+		italic:         "ŒÐÂÎ",
+		underline:      "²ŒÀþ",
+		strikethrough:  "ÂÇ€ÁŸÃ€·Àþ",
+		subscript:      "²ŒÉÕ€­Åº€š»ú",
+		superscript:    "ŸåÉÕ€­Åº€š»ú",
+		justifyleft:    "ºžŽó€»",
+		justifycenter:  "Ãæ±ûŽó€»",
+		justifyright:   "±ŠŽó€»",
+		justifyfull:    "¶ÑÅù³äÉÕ",
+		orderedlist:    "ÈÖ¹æÉÕ€­²ÕŸòœñ€­",
+		unorderedlist:  "µ­¹æÉÕ€­²ÕŸòœñ€­",
+		outdent:        "¥€¥ó¥Ç¥ó¥È²òœü",
+		indent:         "¥€¥ó¥Ç¥ó¥ÈÀßÄê",
+		forecolor:      "Êž»ú¿§",
+		backcolor:      "ÇØ·Ê¿§",
+		horizontalrule: "¿åÊ¿Àþ",
+		createlink:     "¥ê¥ó¥¯ºîÀ®",
+		insertimage:    "²èÁüÁÞÆþ",
+		inserttable:    "¥Æ¡Œ¥Ö¥ëÁÞÆþ",
+		htmlmode:       "HTMLÉœŒšÀÚÂØ",
+		popupeditor:    "¥š¥Ç¥£¥¿³ÈÂç",
+		about:          "¥Ð¡Œ¥ž¥ç¥óŸðÊó",
+		help:           "¥Ø¥ë¥×",
+		textindicator:  "žœºß€Î¥¹¥¿¥€¥ë"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/fr.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/fr.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/fr.js	(revision 795)
@@ -0,0 +1,97 @@
+// I18N constants
+
+// LANG: "fr", ENCODING: UTF-8 | ISO-8859-1
+// Author: Simon Richard, s.rich@sympatico.ca
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+// All technical terms used in this document are the ones approved
+// by the Office québécois de la langue française.
+// Tous les termes techniques utilisés dans ce document sont ceux
+// approuvés par l'Office québécois de la langue française.
+// http://www.oqlf.gouv.qc.ca/
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "fr",
+
+	tooltips: {
+		bold:           "Gras",
+		italic:         "Italique",
+		underline:      "Souligné",
+		strikethrough:  "Barré",
+		subscript:      "Indice",
+		superscript:    "Exposant",
+		justifyleft:    "Aligné à gauche",
+		justifycenter:  "Centré",
+		justifyright:   "Aligné à droite",
+		justifyfull:    "Justifier",
+		orderedlist:    "Numérotation",
+		unorderedlist:  "Puces",
+		outdent:        "Diminuer le retrait",
+		indent:         "Augmenter le retrait",
+		forecolor:      "Couleur de police",
+		hilitecolor:    "Surlignage",
+		horizontalrule: "Ligne horizontale",
+		createlink:     "Insérer un hyperlien",
+		insertimage:    "Insérer/Modifier une image",
+		inserttable:    "Insérer un tableau",
+		htmlmode:       "Passer au code source",
+		popupeditor:    "Agrandir l'éditeur",
+		about:          "À propos de cet éditeur",
+		showhelp:       "Aide sur l'éditeur",
+		textindicator:  "Style courant",
+		undo:           "Annuler la dernière action",
+		redo:           "Répéter la dernière action",
+		cut:            "Couper la sélection",
+		copy:           "Copier la sélection",
+		paste:          "Coller depuis le presse-papier",
+		lefttoright:    "Direction de gauche à droite",
+		righttoleft:    "Direction de droite à gauche"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Annuler"
+	},
+
+	msg: {
+		"Path":         "Chemin",
+		"TEXT_MODE":    "Vous êtes en MODE TEXTE.  Appuyez sur le bouton [<>] pour retourner au mode tel-tel.",
+
+		"IE-sucks-full-screen" :
+		// translate here
+		"Le mode plein écran peut causer des problèmes sous Internet Explorer, " +
+		"ceci dû à des bogues du navigateur qui ont été impossible à contourner.  " +
+		"Les différents symptômes peuvent être un affichage déficient, le manque de " +
+		"fonctions dans l'éditeur et/ou pannes aléatoires du navigateur.  Si votre " +
+		"système est Windows 9x, il est possible que vous subissiez une erreur de type " +
+		"«General Protection Fault» et que vous ayez à redémarrer votre ordinateur." +
+		"\n\nConsidérez-vous comme ayant été avisé.  Appuyez sur OK si vous désirez tout " +
+		"de même essayer le mode plein écran de l'éditeur."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "Annuler",
+		"Insert/Modify Link"                                : "Insérer/Modifier Lien",
+		"New window (_blank)"                               : "Nouvelle fenêtre (_blank)",
+		"None (use implicit)"                               : "Aucun (par défaut)",
+		"OK"                                                : "OK",
+		"Other"                                             : "Autre",
+		"Same frame (_self)"                                : "Même cadre (_self)",
+		"Target:"                                           : "Cible:",
+		"Title (tooltip):"                                  : "Titre (infobulle):",
+		"Top frame (_top)"                                  : "Cadre du haut (_top)",
+		"URL:"                                              : "Adresse Web:",
+		"You must enter the URL where this link points to"  : "Vous devez entrer l'adresse Web du lien"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/nl.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/nl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/nl.js	(revision 795)
@@ -0,0 +1,90 @@
+// I18N constants
+
+// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1
+// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "nl",
+
+	tooltips: {
+		bold:					"Vet",
+		italic:					"Cursief",
+		underline:				"Onderstrepen",
+		strikethrough:			"Doorhalen",
+		subscript:				"Subscript",
+		superscript:			"Superscript",
+		justifyleft:			"Links uitlijnen",
+		justifycenter:			"Centreren",
+		justifyright:			"Rechts uitlijnen",
+		justifyfull:			"Uitvullen",
+		orderedlist:		"Nummering",
+		unorderedlist:	"Opsommingstekens",
+		outdent:				"Inspringing verkleinen",
+		indent:					"Inspringing vergroten",
+		forecolor:				"Tekstkleur",
+		hilitecolor:			"Achtergrondkleur",
+		inserthorizontalrule:	"Horizontale lijn",
+		createlink:				"Hyperlink invoegen/aanpassen",
+		insertimage:			"Afbeelding invoegen/aanpassen",
+		inserttable:			"Tabel invoegen",
+		htmlmode:				"HTML broncode",
+		popupeditor:			"Vergroot Editor",
+		about:					"Over deze editor",
+		showhelp:				"HTMLArea help",
+		textindicator:			"Huidige stijl",
+		undo:					"Ongedaan maken",
+		redo:					"Herhalen",
+		cut:					"Knippen",
+		copy:					"Kopiëren",
+		paste:					"Plakken",
+		lefttoright:			"Tekstrichting links naar rechts",
+		righttoleft:			"Tekstrichting rechts naar links"
+	},
+
+	buttons: {
+		"ok":					"OK",
+		"cancel":				"Annuleren"
+	},
+
+	msg: {
+		"Path":					"Pad",
+		"TEXT_MODE":			"Je bent in TEKST-mode. Gebruik de [<>] knop om terug te keren naar WYSIWYG-mode.",
+      
+		"IE-sucks-full-screen" :
+		// translate here
+		"Fullscreen-mode veroorzaakt problemen met Internet Explorer door bugs in de webbrowser " +
+		"die we niet kunnen omzeilen. Hierdoor kunnen de volgende effecten optreden: verknoeide teksten, " +
+		"een verlies aan editor-functionaliteit en/of willekeurig vastlopen van de webbrowser. " +
+		"Als u Windows 95 of 98 gebruikt, is het zeer waarschijnlijk dat u een algemene beschermingsfout " +
+		"('General Protection Fault') krijgt en de computer opnieuw zal moeten opstarten.\n\n" +
+		"U bent gewaarschuwd. Druk OK als u toch nog de Fullscreen-editor wil gebruiken."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "Annuleren",
+		"Insert/Modify Link"                                : "Hyperlink invoegen/aanpassen",
+		"New window (_blank)"                               : "Nieuw venster (_blank)",
+		"None (use implicit)"                               : "Geen",
+		"OK"                                                : "OK",
+		"Other"                                             : "Ander",
+		"Same frame (_self)"                                : "Zelfde frame (_self)",
+		"Target:"                                           : "Doel:",
+		"Title (tooltip):"                                  : "Titel (tooltip):",
+		"Top frame (_top)"                                  : "Bovenste frame (_top)",
+		"URL:"                                              : "URL:",
+		"You must enter the URL where this link points to"  : "Geef de URL in waar de link naar verwijst"
+	}
+};
+
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/pl.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/pl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/pl.js	(revision 795)
@@ -0,0 +1,36 @@
+// I18N constants
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "pl",
+
+	tooltips: {
+		bold:           "Pogrubienie",
+		italic:         "Pochylenie",
+		underline:      "Podkrelenie",
+		strikethrough:  "Przekrelenie",
+		subscript:      "Indeks dolny",
+		superscript:    "Indeks górny",
+		justifyleft:    "Wyrównaj do lewej",
+		justifycenter:  "Wyrodkuj",
+		justifyright:   "Wyrównaj do prawej",
+		justifyfull:    "Wyjustuj",
+		orderedlist:    "Numerowanie",
+		unorderedlist:  "Wypunktowanie",
+		outdent:        "Zmniejsz wciêcie",
+		indent:         "Zwiêksz wciêcie",
+		forecolor:      "Kolor czcionki",
+		backcolor:      "Kolor t³a",
+		horizontalrule: "Linia pozioma",
+		createlink:     "Wstaw adres sieci Web",
+		insertimage:    "Wstaw obraz",
+		inserttable:    "Wstaw tabelê",
+		htmlmode:       "Edycja WYSIWYG/w ródle strony",
+		popupeditor:    "Pe³ny ekran",
+		about:          "Informacje o tym edytorze",
+		help:           "Pomoc",
+		textindicator:  "Obecny styl"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/it.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/it.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/it.js	(revision 795)
@@ -0,0 +1,79 @@
+// I18N constants
+
+// LANG: "it", ENCODING: UTF-8 | ISO-8859-1
+// Author: Fabio Rotondo <fabio@rotondo.it>
+// Update for 3.0 rc1: Giovanni Premuda <gpremuda@softwerk.it>
+
+HTMLArea.I18N = {
+
+        // the following should be the filename without .js extension
+        // it will be used for automatically load plugin language.
+        lang: "it",
+
+        tooltips: {
+                bold:           "Grassetto",
+                italic:         "Corsivo",
+                underline:      "Sottolineato",
+                strikethrough:  "Barrato",
+                subscript:      "Pedice",
+                superscript:    "Apice",
+                justifyleft:    "Allinea a sinistra",
+                justifycenter:  "Allinea in centro",
+                justifyright:   "Allinea a destra",
+                justifyfull:    "Giustifica",
+                insertorderedlist:    "Lista ordinata",
+                insertunorderedlist:  "Lista puntata",
+                outdent:        "Decrementa indentazione",
+                indent:         "Incrementa indentazione",
+                forecolor:      "Colore del carattere",
+                hilitecolor:    "Colore di sfondo",
+                inserthorizontalrule: "Linea orizzontale",
+                createlink:     "Inserisci un link",
+                insertimage:    "Inserisci un'immagine",
+                inserttable:    "Inserisci una tabella",
+                htmlmode:       "Visualizzazione HTML",
+                popupeditor:    "Editor a pieno schermo",
+                about:          "Info sull'editor",
+                showhelp:       "Aiuto sull'editor",
+                textindicator:  "Stile corrente",
+                undo:           "Annulla",
+                redo:           "Ripristina",
+                cut:            "Taglia",
+                copy:           "Copia",
+                paste:          "Incolla",
+                lefttoright:    "Scrivi da sinistra a destra",
+                righttoleft:    "Scrivi da destra a sinistra"
+        },
+
+        buttons: {
+                "ok":           "OK",
+                "cancel":       "Annulla"
+        },
+
+        msg: {
+                "Path":         "Percorso",
+                "TEXT_MODE":    "Sei in MODALITA' TESTO. Usa il bottone [<>] per tornare alla modalitÃ  WYSIWYG.",
+                "IE-sucks-full-screen" :
+                // translate here
+                "The full screen mode is known to cause problems with Internet Explorer, " +
+                "due to browser bugs that we weren't able to workaround.  You might experience garbage " +
+                "display, lack of editor functions and/or random browser crashes.  If your system is Windows 9x " +
+                "it's very likely that you'll get a 'General Protection Fault' and need to reboot.\n\n" +
+                "You have been warned.  Please press OK if you still want to try the full screen editor."
+        },
+
+        dialogs: {
+                "Annulla"                                            : "Cancel",
+                "Inserisci/modifica Link"                                : "Insert/Modify Link",
+                "Nuova finestra (_blank)"                               : "New window (_blank)",
+                "Nessuno (usa predefinito)"                               : "None (use implicit)",
+                "OK"                                                : "OK",
+                "Altro"                                             : "Other",
+                "Stessa finestra (_self)"                                : "Same frame (_self)",
+                "Target:"                                           : "Target:",
+                "Title (suggerimento):"                                  : "Title (tooltip):",
+                "Frame principale (_top)"                                  : "Top frame (_top)",
+                "URL:"                                              : "URL:",
+                "You must enter the URL where this link points to"  : "Devi inserire un indirizzo per questo link"
+        }
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/cz.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/cz.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/cz.js	(revision 795)
@@ -0,0 +1,63 @@
+﻿// I18N constants
+
+// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2
+// Author: Jiri Löw, <jirilow@jirilow.com>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "cz",
+
+	tooltips: {
+		bold:           "Tučně",
+		italic:         "Kurzíva",
+		underline:      "Podtržení",
+		strikethrough:  "Přeškrtnutí",
+		subscript:      "Dolní index",
+		superscript:    "Horní index",
+		justifyleft:    "Zarovnat doleva",
+		justifycenter:  "Na střed",
+		justifyright:   "Zarovnat doprava",
+		justifyfull:    "Zarovnat do stran",
+		orderedlist:    "Seznam",
+		unorderedlist:  "Odrážky",
+		outdent:        "Předsadit",
+		indent:         "Odsadit",
+		forecolor:      "Barva písma",
+		hilitecolor:    "Barva pozadí",
+		horizontalrule: "Vodorovná čára",
+		createlink:     "Vložit odkaz",
+		insertimage:    "Vložit obrázek",
+		inserttable:    "Vložit tabulku",
+		htmlmode:       "Přepnout HTML",
+		popupeditor:    "Nové okno editoru",
+		about:          "O této aplikaci",
+		showhelp:       "Nápověda aplikace",
+		textindicator:  "Zvolený styl",
+		undo:           "Vrátí poslední akci",
+		redo:           "Opakuje poslední akci",
+		cut:            "Vyjmout",
+		copy:           "Kopírovat",
+		paste:          "Vložit"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Zrušit"
+	},
+
+	msg: {
+		"Path":         "Cesta",
+		"TEXT_MODE":    "Jste v TEXTOVÉM REŽIMU.  Použijte tlačítko [<>] pro přepnutí do WYSIWIG."
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ja-utf8.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ja-utf8.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ja-utf8.js	(revision 795)
@@ -0,0 +1,37 @@
+﻿// I18N constants -- Japanese UTF-8
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ja-utf8",
+
+	tooltips: {
+		bold:           "太字",
+		italic:         "斜体",
+		underline:      "下線",
+		strikethrough:  "打ち消し線",
+		subscript:      "下付き添え字",
+		superscript:    "上付き添え字",
+		justifyleft:    "左寄せ",
+		justifycenter:  "中央寄せ",
+		justifyright:   "右寄せ",
+		justifyfull:    "均等割付",
+		orderedlist:    "番号付き箇条書き",
+		unorderedlist:  "記号付き箇条書き",
+		outdent:        "インデント解除",
+		indent:         "インデント設定",
+		forecolor:      "文字色",
+		backcolor:      "背景色",
+		horizontalrule: "水平線",
+		createlink:     "リンク作成",
+		insertimage:    "画像挿入",
+		inserttable:    "テーブル挿入",
+		htmlmode:       "HTML表示切替",
+		popupeditor:    "エディタ拡大",
+		about:          "バージョン情報",
+		help:           "ヘルプ",
+		textindicator:  "現在のスタイル"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/lt.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/lt.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/lt.js	(revision 795)
@@ -0,0 +1,88 @@
+// I18N constants
+
+// LANG: "lt", ENCODING: UTF-8
+// Author: Jaroslav Å atkeviÄ, <jaro@akl.lt>
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "en",
+
+	tooltips: {
+		bold:           "ParyÅ¡kinti",
+		italic:         "Kursyvas",
+		underline:      "Pabraukti",
+		strikethrough:  "Perbraukti",
+		subscript:      "Apatinis indeksas",
+		superscript:    "VirÅ¡utinis indeksas",
+		justifyleft:    "Lygiavimas pagal kairÄ",
+		justifycenter:  "Lygiavimas pagal centrÄ
+",
+		justifyright:   "Lygiavimas pagal deÅ¡inÄ",
+		justifyfull:    "Lygiuoti pastraipÄ
+",
+		orderedlist:    "Numeruotas sÄ
+raÅ¡as",
+		unorderedlist:  "SuÅŸenklintas sÄ
+raÅ¡as",
+		outdent:        "SumaÅŸinti paraÅ¡tÄ",
+		indent:         "Padidinti paraÅ¡tÄ",
+		forecolor:      "Å rifto spalva",
+		hilitecolor:    "Fono spalva",
+		horizontalrule: "Horizontali linija",
+		createlink:     "Ä®terpti nuorodÄ
+",
+		insertimage:    "Ä®terpti paveiksliukÄ
+",
+		inserttable:    "Ä®terpti lentelÄ",
+		htmlmode:       "Perjungti Ä¯ HTML/WYSIWYG",
+		popupeditor:    "IÅ¡plÄstas redagavimo ekranas/Enlarge Editor",
+		about:          "Apie redaktoriÅ³",
+		showhelp:       "Pagalba naudojant redaktoriÅ³",
+		textindicator:  "Dabartinis stilius",
+		undo:           "AtÅ¡aukia paskutini jÅ«sÅ³ veiksmÄ
+",
+		redo:           "Pakartoja paskutinÄ¯ atÅ¡auktÄ
+ jÅ«sÅ³ veiksmÄ
+",
+		cut:            "IÅ¡kirpti",
+		copy:           "Kopijuoti",
+		paste:          "Ä®terpti"
+},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "AtÅ¡aukti"
+	},
+
+	msg: {
+		"Path":         "Kelias",
+		"TEXT_MODE":    "JÅ«s esete teksto reÅŸime.  Naudokite [<>] mygtukÄ
+ grÄ¯ÅŸimui Ä¯ WYSIWYG.",
+
+		"IE-sucks-full-screen" :
+		// translate here
+		"The full screen mode is known to cause problems with Internet Explorer, " +
+		"due to browser bugs that we weren't able to workaround.  You might experience garbage " +
+		"display, lack of editor functions and/or random browser crashes.  If your system is Windows 9x " +
+		"it's very likely that you'll get a 'General Protection Fault' and need to reboot.\n\n" +
+		"You have been warned.  Please press OK if you still want to try the full screen editor."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "AtÅ¡aukti",
+		"Insert/Modify Link"                                : "IdÄti/Modifikuoti",
+		"New window (_blank)"                               : "Naujas langas (_blank)",
+		"None (use implicit)"                               : "None (use implicit)",
+		"OK"                                                : "OK",
+		"Other"                                             : "Kitas",
+		"Same frame (_self)"                                : "Same frame (_self)",
+		"Target:"                                           : "Target:",
+		"Title (tooltip):"                                  : "Pavadinimas (tooltip):",
+		"Top frame (_top)"                                  : "Top frame (_top)",
+		"URL:"                                              : "URL:",
+		"You must enter the URL where this link points to"  : "Jus privalote nurodyti URL Ä¯ kuri rodo Å¡itÄ
+ nuoroda"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/lv.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/lv.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/lv.js	(revision 795)
@@ -0,0 +1,55 @@
+// I18N constants
+
+// LANG: "lv", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+// Translated by: Janis Klavins, <janis.klavins@devia.lv>
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "lv",
+
+	tooltips: {
+		bold:           "Trekniem burtiem",
+		italic:         "Kursîvâ",
+		underline:      "Pasvîtrots",
+		strikethrough:  "Pârsvîtrots",
+		subscript:      "Novietot zem rindas",
+		superscript:    "Novietot virs rindas",
+		justifyleft:    "Izlîdzinât pa kreisi",
+		justifycenter:  "Izlîdzinât centrâ",
+		justifyright:   "Izlîdzinât pa labi",
+		justifyfull:    "Izlîdzinât pa visu lapu",
+		orderedlist:    "Numurçts saraksts",
+		unorderedlist:  "Saraksts",
+		outdent:        "Samazinât atkâpi",
+		indent:         "Palielinât atkâpi",
+		forecolor:      "Burtu krâsa",
+		hilitecolor:    "Fona krâsa",
+		horizontalrule: "Horizontâla atdalîtâjsvîtra",
+		createlink:     "Ievietot hipersaiti",
+		insertimage:    "Ievietot attçlu",
+		inserttable:    "Ievietot tabulu",
+		htmlmode:       "Skatît HTML kodu",
+		popupeditor:    "Palielinât Rediìçtâju",
+		about:          "Par ðo rediìçtâju",
+		showhelp:       "Rediìçtâja palîgs",
+		textindicator:  "Patreizçjais stils",
+		undo:           "Atcelt pçdçjo darbîbu",
+		redo:           "Atkârtot pçdçjo darbîbu",
+		cut:            "Izgriezt iezîmçto",
+		copy:           "Kopçt iezîmçto",
+		paste:          "Ievietot iezîmçto"
+	},
+
+	buttons: {
+		"ok":           "Labi",
+		"cancel":       "Atcelt"
+	},
+
+	msg: {
+		"Path":         "Ceïð",
+		"TEXT_MODE":    "Jûs patlaban darbojaties TEKSTA REÞÎMÂ. Lai pârietu atpakaï uz GRAFISKO REÞÎMU (WYSIWIG), lietojiet [<>] pogu."
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/vn.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/vn.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/vn.js	(revision 795)
@@ -0,0 +1,52 @@
+// I18N constants : Vietnamese
+// LANG: "en", ENCODING: UTF-8
+// Author: Nguyá»
+n ÄÃ¬nh Nam, <hncryptologist@yahoo.com>
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "vn",
+
+	tooltips: {
+		bold:           "Äáº­m",
+		italic:         "NghiÃªng",
+		underline:      "Gáº¡ch ChÃ¢n",
+		strikethrough:  "Gáº¡ch XÃ³a",
+		subscript:      "Viáº¿t Xuá»ng DÆ°á»i",
+		superscript:    "Viáº¿t LÃªn TrÃªn",
+		justifyleft:    "CÄn TrÃ¡i",
+		justifycenter:  "CÄn Giá»¯a",
+		justifyright:   "CÄn Pháº£i",
+		justifyfull:    "CÄn Äá»u",
+		orderedlist:    "Danh SÃ¡ch CÃ³ Thá»© Tá»±",
+		unorderedlist:  "Danh SÃ¡ch Phi Thá»© Tá»±",
+		outdent:        "LÃ¹i Ra NgoÃ i",
+		indent:         "Thá»¥t VÃ o Trong",
+		forecolor:      "MÃ u Chá»¯",
+		backcolor:      "MÃ u Ná»n",
+		horizontalrule: "DÃ²ng Káº» Ngang",
+		createlink:     "Táº¡o LiÃªn Káº¿t",
+		insertimage:    "ChÃšn áº¢nh",
+		inserttable:    "ChÃšn Báº£ng",
+		htmlmode:       "Cháº¿ Äá» MÃ£ HTML",
+		popupeditor:    "PhÃ³ng To Ã Soáº¡n Tháº£o",
+		about:          "Tá»± Giá»i Thiá»u",
+		showhelp:       "GiÃºp Äá»¡",
+		textindicator:  "Äá»nh Dáº¡ng Hiá»n Thá»i",
+		undo:           "Undo",
+		redo:           "Redo",
+		cut:            "Cáº¯t",
+		copy:           "Copy",
+		paste:          "DÃ¡n"
+	},
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Há»§y"
+	},
+	msg: {
+		"Path":         "ÄÆ°á»ng Dáº«n",
+		"TEXT_MODE":    "Báº¡n Äang á» cháº¿ Äá» text.  Sá»­ dá»¥ng nÃºt [<>] Äá» chuyá»n láº¡i cháº¿ Äá» WYSIWIG."
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/da.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/da.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/da.js	(revision 795)
@@ -0,0 +1,38 @@
+// danish version for htmlArea v3.0 - Alpha Release
+// - translated by rene<rene@laerke.net>
+// termŽs and licenses are equal to htmlarea!
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "da",
+
+	tooltips: {
+		bold:           "Fed",
+		italic:         "Kursiv",
+		underline:      "Understregning",
+		strikethrough:  "Overstregning ",
+		subscript:      "Sænket skrift",
+		superscript:    "Hævet skrift",
+		justifyleft:    "Venstrejuster",
+		justifycenter:  "Centrer",
+		justifyright:   "Højrejuster",
+		justifyfull:    "Lige margener",
+		orderedlist:    "Opstilling med tal",
+		unorderedlist:  "Opstilling med punkttegn",
+		outdent:        "Formindsk indrykning",
+		indent:         "Forøg indrykning",
+		forecolor:      "Skriftfarve",
+		backcolor:      "Baggrundsfarve",
+		horizontalrule: "Horisontal linie",
+		createlink:     "Indsæt hyperlink",
+		insertimage:    "Indsæt billede",
+		inserttable:    "Indsæt tabel",
+		htmlmode:       "HTML visning",
+		popupeditor:    "Vis editor i popup",
+		about:          "Om htmlarea",
+		help:           "Hjælp",
+		textindicator:  "Anvendt stil"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/de.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/de.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/de.js	(revision 795)
@@ -0,0 +1,79 @@
+// I18N constants
+
+// LANG: "de", ENCODING: ISO-8859-1 for the german umlaut!
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "de",
+
+	tooltips: {
+		bold:           "Fett",
+		italic:         "Kursiv",
+		underline:      "Unterstrichen",
+		strikethrough:  "Durchgestrichen",
+		subscript:      "Hochgestellt",
+		superscript:    "Tiefgestellt",
+        justifyleft:            "Linksbündig",
+        justifycenter:          "Zentriert",
+        justifyright:           "Rechtsbündig",
+		justifyfull:    "Blocksatz",
+        orderedlist:      "Nummerierung",
+        unorderedlist:    "Aufzählungszeichen",
+		outdent:        "Einzug verkleinern",
+        indent:                 "Einzug vergrößern",
+        forecolor:              "Schriftfarbe",
+        backcolor:              "Hindergrundfarbe",
+        hilitecolor:            "Hintergrundfarbe",
+		horizontalrule: "Horizontale Linie",
+        inserthorizontalrule:   "Horizontale Linie",
+        createlink:             "Hyperlink einfügen",
+        insertimage:            "Bild einfügen",
+        inserttable:            "Tabelle einfügen",
+		htmlmode:       "HTML Modus",
+		popupeditor:    "Editor im Popup öffnen",
+        about:                  "Über htmlarea",
+        help:                   "Hilfe",
+		showhelp:       "Hilfe",
+        textindicator:          "Derzeitiger Stil",
+        undo:                   "Rückgängig",
+		redo:           "Wiederholen",
+		cut:            "Ausschneiden",
+		copy:           "Kopieren",
+        paste:                  "Einfügen aus der Zwischenablage",
+        lefttoright:            "Textrichtung von Links nach Rechts",
+        righttoleft:            "Textrichtung von Rechts nach Links"
+	},
+  
+ buttons: {
+		"ok":           "OK",
+		"cancel":       "Abbrechen"
+	},
+
+	msg: {
+		"Path":         "Pfad",
+        "TEXT_MODE":            "Sie sind im Text-Modus. Benutzen Sie den [<>] Knopf um in den visuellen Modus (WYSIWIG) zu gelangen.",
+
+        "Moz-Clipboard" :
+        "Aus Sicherheitsgründen dürfen Skripte normalerweise nicht programmtechnisch auf " +
+        "Ausschneiden/Kopieren/Einfügen zugreifen. Bitte klicken Sie OK um die technische " +
+        "Erläuterung auf mozilla.org zu öffnen, in der erklärt wird, wie einem Skript Zugriff " +
+        "gewährt werden kann."
+    },
+    
+    dialogs: {
+        "OK":                   "OK",
+        "Cancel":               "Abbrechen",
+        "Insert/Modify Link":   "Verknüpfung hinzufügen/ändern",
+        "None (use implicit)":  "k.A. (implizit)",
+        "New window (_blank)":  "Neues Fenster (_blank)",
+        "Same frame (_self)":   "Selber Rahmen (_self)",
+        "Top frame (_top)":     "Oberster Rahmen (_top)",
+        "Other":                "Anderes",
+        "Target:":              "Ziel:",
+        "Title (tooltip):":     "Titel (Tooltip):",
+        "URL:":                 "URL:",
+        "You must enter the URL where this link points to": "Sie müssen eine Ziel-URL angeben für die Verknüpfung angeben"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ee.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ee.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ee.js	(revision 795)
@@ -0,0 +1,63 @@
+// I18N constants
+
+// LANG: "ee", ENCODING: UTF-8 | ISO-8859-1
+// Author: Martin Raie, <albertvill@hot.ee>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ee",
+
+	tooltips: {
+		bold:           "Paks",
+		italic:         "Kursiiv",
+		underline:      "Allakriipsutatud",
+		strikethrough:  "Läbikriipsutatud",
+		subscript:      "Allindeks",
+		superscript:    "Ülaindeks",
+		justifyleft:    "Joonda vasakule",
+		justifycenter:  "Joonda keskele",
+		justifyright:   "Joonda paremale",
+		justifyfull:    "Rööpjoonda",
+		orderedlist:    "Nummerdus",
+		unorderedlist:  "Täpploend",
+		outdent:        "Vähenda taanet",
+		indent:         "Suurenda taanet",
+		forecolor:      "Fondi värv",
+		hilitecolor:    "Tausta värv",
+		inserthorizontalrule: "Horisontaaljoon",
+		createlink:     "Lisa viit",
+		insertimage:    "Lisa pilt",
+		inserttable:    "Lisa tabel",
+		htmlmode:       "HTML/tavaline vaade",
+		popupeditor:    "Suurenda toimeti aken",
+		about:          "Teave toimeti kohta",
+		showhelp:       "Spikker",
+		textindicator:  "Kirjastiil",
+		undo:           "Võta tagasi",
+		redo:           "Tee uuesti",
+		cut:            "Lõika",
+		copy:           "Kopeeri",
+		paste:          "Kleebi"
+	},
+
+	buttons: {
+		"ok":           "OK",
+		"cancel":       "Loobu"
+	},
+
+	msg: {
+		"Path":         "Path",
+		"TEXT_MODE":    "Sa oled tekstireziimis.  Kasuta nuppu [<>] lülitamaks tagasi WYSIWIG reziimi."
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/he.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/he.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/he.js	(revision 795)
@@ -0,0 +1,89 @@
+// I18N constants
+
+// LANG: "he", ENCODING: UTF-8
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "he",
+
+	tooltips: {
+		bold:           "×××××©",
+		italic:         "× ×××",
+		underline:      "×§× ×ª××ª×",
+		strikethrough:  "×§× ×××Š×¢",
+		subscript:      "××ª× ×¢×××",
+		superscript:    "××ª× ×ª××ª×",
+		justifyleft:    " ××©××š ××©×××",
+		justifycenter:  "××©××š ×××š××",
+		justifyright:   "××©××š ×××××",
+		justifyfull:    "××©××š ××©××š× ××××",
+		orderedlist:    "×š×©××× ××××¡×€×š×ª",
+		unorderedlist:  "×š×©××× ×× ××××¡×€×š×ª",
+		outdent:        "××§×× ×× ××¡×",
+		indent:         "×××× ×× ××¡×",
+		forecolor:      "×Š××¢ ×××€×",
+		hilitecolor:    "×Š××¢ ×š×§×¢",
+		horizontalrule: "×§× ×× ××",
+		createlink:     "××× ×¡ ×××€×š-×§××©××š",
+		insertimage:    "××× ×¡/×©× × ×ª××× ×",
+		inserttable:    "××× ×¡ ××××",
+		htmlmode:       "×©× × ××Š× ×§×× HTML",
+		popupeditor:    "×××× ××ª ××¢××š×",
+		about:          "×××××ª ×¢××š× ××",
+		showhelp:       "×¢××š× ××©××××© ××¢××š×",
+		textindicator:  "×¡×× ×× × ××××",
+		undo:           "×××× ××ª ×€×¢×××ª× ××××š×× ×",
+		redo:           "×××Š×¢ ××××© ××ª ××€×¢××× ××××š×× × ×©×××××ª",
+		cut:            "××××š ××××š×",
+		copy:           "××¢×ª×§ ××××š×",
+		paste:          "××××§ ×××××",
+		lefttoright:    "××××× ××©××× ×××××",
+		righttoleft:    "××××× ××××× ××©×××"
+	},
+
+	buttons: {
+		"ok":           "×××©××š",
+		"cancel":       "×××××"
+	},
+
+	msg: {
+		"Path":         "× ×ª×× ×¢××Š××",
+		"TEXT_MODE":    "××ª× ×××Š× ××§×¡× × ×§× (×§××). ××©×ª××© ×××€×ª××š [<>] ××× ×××××š ×××Š× WYSIWYG (×ª×Š×××ª ×¢××Š××).",
+
+		"IE-sucks-full-screen" :
+		// translate here
+		"××Š× ××¡× ××× ×××Š×š ××¢×××ª ×××€××€× Internet Explorer, " +
+		"×¢×§× ××××× ×××€××€× ×× ××××× × ××€×ª××š ××ª ××.  ××ª/× ×¢×××/× ×××××ª ×ª×Š×××ª ×××,  " +
+		"××¢×××ª ××ª×€×§×× ××¢××š× ×/×× ×§×š××¡× ×©× ×××€××€×.  ×× ×××¢×š××ª ×©×× ××× Windows 9x " +
+		"×¡×××š ××× ×× ×©×ª×§××/× 'General Protection Fault' ××ª×××Š/× ×××ª×× ××ª ××××©×.\n\n" +
+		"×š××/× ×××××š×ª.  ×× × ×××¥/× ×××©××š ×× ××ª/× ×¢×××× ×š××Š× ×× ×¡××ª ××ª ××¢××š× ×××¡× ×××."
+	},
+
+	dialogs: {
+		"Cancel"                                            : "×××××",
+		"Insert/Modify Link"                                : "×××¡×£/×©× × ×§××©××š",
+		"New window (_blank)"                               : "×××× ×××© (_blank)",
+		"None (use implicit)"                               : "××× (××©×ª××© ×-frame ××§×××)",
+		"OK"                                                : "OK",
+		"Other"                                             : "×××š",
+		"Same frame (_self)"                                : "×××ª× frame (_self)",
+		"Target:"                                           : "××¢×:",
+		"Title (tooltip):"                                  : "×××ª×š×ª (tooltip):",
+		"Top frame (_top)"                                  : "Frame ×¢×××× (_top)",
+		"URL:"                                              : "URL:",
+		"You must enter the URL where this link points to"  : "×××× ×××ª×× URL ×©×××× ×§××©××š ×× ××Š×××¢"
+
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/fi.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/fi.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/fi.js	(revision 795)
@@ -0,0 +1,46 @@
+// I18N constants
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "en",
+
+	tooltips: {
+		bold:           	"Lihavoitu",
+		italic:         	"Kursivoitu",
+		underline:      	"Alleviivattu",
+		strikethrough:  	"Yliviivattu",
+		subscript:      	"Alaindeksi",
+		superscript:    	"Yläindeksi",
+		justifyleft:    	"Tasaa vasemmat reunat",
+		justifycenter:  	"Keskitä",
+		justifyright:   	"Tasaa oikeat reunat",
+		justifyfull:    	"Tasaa molemmat reunat",
+		orderedlist: 	"Numerointi",
+		unorderedlist: 	"Luettelomerkit",
+		outdent:        	"Lisää sisennystä",
+		indent:         	"Pienennä sisennystä",
+		forecolor:      	"Fontin väri",
+		hilitecolor:    	"Taustaväri",
+		inserthorizontalrule: 	"Vaakaviiva",
+		createlink:     	"Lisää Linkki",
+		insertimage:    	"Lisää Kuva",
+		inserttable:    	"Lisää Taulu",
+		htmlmode:       	"HTML Lähdekoodi vs WYSIWYG",
+		popupeditor:    	"Suurenna Editori",
+		about:          	"Tietoja Editorista",
+		showhelp:           	"Näytä Ohje",
+		textindicator:  	"Nykyinen tyyli",
+		undo:           	"Peruuta viimeinen toiminto",
+		redo:           	"Palauta viimeinen toiminto",
+		cut:            	"Leikkaa maalattu",
+		copy:           	"Kopioi maalattu",
+		paste:          	"Liitä leikepyödältä"
+	},
+
+	buttons: {
+		"ok":           	"Hyväksy",
+		"cancel":       	"Peruuta"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/lang/ja-sjis.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/lang/ja-sjis.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/lang/ja-sjis.js	(revision 795)
@@ -0,0 +1,38 @@
+// I18N constants -- Japanese Shift-JIS
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "ja-sjis",
+
+	tooltips: {
+		bold:           "Ÿ",
+		italic:         "ÎÌ",
+		underline:      "ºü",
+		strikethrough:  "Å¿Áµü",
+		subscript:      "ºt«YŠ",
+		superscript:    "ãt«YŠ",
+		justifyleft:    "¶ñ¹",
+		justifycenter:  "ñ¹",
+		justifyright:   "Eñ¹",
+		justifyfull:    "Ït",
+		orderedlist:    "Ôt«Óð«",
+		unorderedlist:  "Lt«Óð«",
+		outdent:        "Cfgð",
+		indent:         "CfgÝè",
+		forecolor:      "¶F",
+		backcolor:      "wiF",
+		horizontalrule: "
+œü",
+		createlink:     "Nì¬",
+		insertimage:    "æ}ü",
+		inserttable:    "e[u}ü",
+		htmlmode:       "HTML\ŠØÖ",
+		popupeditor:    "GfB^gå",
+		about:          "o[Wîñ",
+		help:           "wv",
+		textindicator:  "»ÝÌX^C"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/nl.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/nl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/nl.js	(revision 795)
@@ -0,0 +1,25 @@
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+FullPage.I18N = {
+	"Alternate style-sheet:":		"Alternatieve style-sheet:",
+	"Background color:":			"Achtergrondkleur:",
+	"Cancel":				"Annuleren",
+	"DOCTYPE:":				"DOCTYPE:",
+	"Document properties":			"Documenteigenschappen ",
+	"Document title:":			"Documenttitel:",
+	"OK":					"Oké",
+	"Primary style-sheet:":			"Primaire style-sheet:",
+	"Text color:":				"Tekstkleur:"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/he.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/he.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/he.js	(revision 795)
@@ -0,0 +1,25 @@
+// I18N for the FullPage plugin
+
+// LANG: "he", ENCODING: UTF-8
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+FullPage.I18N = {
+	"Alternate style-sheet:":		"×××××× ×¡×× ×× ×××š:",
+	"Background color:":			"×Š××¢ ×š×§×¢:",
+	"Cancel":				"×××××",
+	"DOCTYPE:":				"DOCTYPE:",
+	"Document properties":			"×××€××× × ××¡××",
+	"Document title:":			"×××ª×š×ª ××¡××:",
+	"OK":					"×××©××š",
+	"Primary style-sheet:":			"×××××× ×¡×× ×× ×š××©×:",
+	"Text color:":				"×Š××¢ ××§×¡×:"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/lang.php	(revision 795)
@@ -0,0 +1,53 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-FullPage');
+
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+FullPage.I18N = {
+	"Alternate style-sheet:":		"<?php echo lang('Alternate style-sheet:'); ?>",
+	"Background color:":			"<?php echo lang('Background color:'); ?>",
+	"Cancel":				"<?php echo lang('Cancel'); ?>",
+	"DOCTYPE:":				"<?php echo lang('DOCTYPE:'); ?>",
+	"Document properties":			"<?php echo lang('Document properties'); ?>",
+	"Document title:":			"<?php echo lang('Document title:'); ?>",
+	"OK":					"<?php echo lang('OK'); ?>",
+	"Primary style-sheet:":			"<?php echo lang('Primary style-sheet:'); ?>",
+	"Text color:":				"<?php echo lang('Text color:'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/ro.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/ro.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/ro.js	(revision 795)
@@ -0,0 +1,25 @@
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+FullPage.I18N = {
+	"Alternate style-sheet:":		"Template CSS alternativ:",
+	"Background color:":			"Culoare de fundal:",
+	"Cancel":				"RenunÅ£Ä",
+	"DOCTYPE:":				"DOCTYPE:",
+	"Document properties":			"ProprietÄÅ£ile documentului",
+	"Document title:":			"Titlul documentului:",
+	"OK":					"AcceptÄ",
+	"Primary style-sheet:":			"Template CSS principal:",
+	"Text color:":				"Culoare text:"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/lang/en.js	(revision 795)
@@ -0,0 +1,25 @@
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+FullPage.I18N = {
+	"Alternate style-sheet:":		"Alternate style-sheet:",
+	"Background color:":			"Background color:",
+	"Cancel":				"Cancel",
+	"DOCTYPE:":				"DOCTYPE:",
+	"Document properties":			"Document properties",
+	"Document title:":			"Document title:",
+	"OK":					"OK",
+	"Primary style-sheet:":			"Primary style-sheet:",
+	"Text color:":				"Text color:"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/test.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/test.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/test.html	(revision 795)
@@ -0,0 +1,89 @@
+<html>
+  <head>
+    <title>Test of FullPage plugin</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <script type="text/javascript">
+      _editor_url = "../../";
+    </script>
+
+    <!-- load the main HTMLArea files -->
+    <script type="text/javascript" src="../../htmlarea.js"></script>
+    <script type="text/javascript" src="../../lang/en.js"></script>
+    <script type="text/javascript" src="../../dialog.js"></script>
+
+    <!-- <script type="text/javascript" src="popupdiv.js"></script> -->
+    <script type="text/javascript" src="../../popupwin.js"></script>
+
+    <script type="text/javascript">
+      HTMLArea.loadPlugin("TableOperations");
+      HTMLArea.loadPlugin("SpellChecker");
+      HTMLArea.loadPlugin("FullPage");
+
+      function initDocument() {
+        var editor = new HTMLArea("editor");
+        editor.registerPlugin(TableOperations);
+        editor.registerPlugin(SpellChecker);
+        editor.registerPlugin(FullPage);
+        editor.generate();
+      }
+    </script>
+
+    <style type="text/css">
+      @import url(../../htmlarea.css);
+    </style>
+
+  </head>
+
+  <body onload="initDocument()">
+    <h1>Test of FullPage plugin</h1>
+
+    <textarea id="editor" style="height: 30em; width: 100%;">
+      &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
+      &lt;html&gt;
+        &lt;head&gt;
+          &lt;title&gt;FullPage plugin for HTMLArea&lt;/title&gt;
+          &lt;link rel="alternate stylesheet" href="http://dynarch.com/mishoo/css/dark.css" /&gt;
+          &lt;link rel="stylesheet" href="http://dynarch.com/mishoo/css/cool-light.css" /&gt;
+        &lt;/head&gt;
+        &lt;body style="background-color: #ddddee; color: #000077;"&gt;
+          &lt;table style="width:60%; height: 90%; margin: 2% auto 1% auto;" align="center" border="0" cellpadding="0" cellspacing="0"&gt;
+            &lt;tr&gt;
+              &lt;td style="background-color: #ddeedd; border: 2px solid #002; height: 1.5em; padding: 2px; font: bold 24px Verdana;"&gt;
+                FullPage plugin
+              &lt;/td&gt;
+            &lt;/tr&gt;
+            &lt;tr&gt;
+              &lt;td style="background-color: #fff; border: 1px solid #aab; padding: 1em 3em; font: 12px Verdana;"&gt;
+                &lt;p&gt;
+                  This plugin enables one to edit a full HTML file in &lt;a
+                    href="http://dynarch.com/htmlarea/"&gt;HTMLArea&lt;/a&gt;.  This is not
+                  normally possible with just the core editor since it only
+                  retrieves the HTML inside the &lt;code&gt;body&lt;/code&gt; tag.
+                &lt;/p&gt;
+                &lt;p&gt;
+                  It provides the ability to change the &lt;code&gt;DOCTYPE&lt;/code&gt; of
+                  the document, &lt;code&gt;body&lt;/code&gt; &lt;code&gt;bgcolor&lt;/code&gt; and
+                  &lt;code&gt;fgcolor&lt;/code&gt; attributes as well as to add additional
+                  &lt;code&gt;link&lt;/code&gt;-ed stylesheets.  Cool, eh?
+                &lt;/p&gt;
+                &lt;p&gt;
+                  The development of this plugin was initiated and sponsored by
+                  &lt;a href="http://thycotic.com"&gt;Thycotic Software Ltd.&lt;/a&gt;.
+                  That's also cool, isn't it? ;-)
+                &lt;/p&gt;
+              &lt;/td&gt;
+            &lt;/tr&gt;
+          &lt;/table&gt;
+        &lt;/body&gt;
+      &lt;/html&gt;
+    </textarea>
+
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct  1 19:55:37 EEST 2003 -->
+<!-- hhmts start -->
+Last modified on Sat Oct 25 01:06:59 2003
+<!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/popups/docprop.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/popups/docprop.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/popups/docprop.html	(revision 795)
@@ -0,0 +1,131 @@
+<html>
+
+<head>
+  <title>Document properties</title>
+
+<script type="text/javascript" src="../../../popups/popup.js"></script>
+
+<script type="text/javascript">
+
+FullPage = window.opener.FullPage; // load the FullPage plugin and lang file ;-)
+window.resizeTo(400, 100);
+
+  var accepted = {
+      f_doctype       : true,
+      f_title         : true,
+      f_body_bgcolor  : true,
+      f_body_fgcolor  : true,
+      f_base_style    : true,
+      f_alt_style     : true
+  };
+
+var editor = null;
+function Init() {
+  __dlg_translate(FullPage.I18N);
+  __dlg_init();
+  var params = window.dialogArguments;
+  for (var i in params) {
+      if (i in accepted) {
+        var el = document.getElementById(i);
+        el.value = params[i];
+      }
+  }
+  editor = params.editor;
+  document.getElementById("f_title").focus();
+  document.getElementById("f_title").select();
+};
+
+function onOK() {
+  var required = {
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+
+  var param = {};
+  for (var i in accepted) {
+    var el = document.getElementById(i);
+    param[i] = el.value;
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+table .label { text-align: right; width: 12em; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+
+#buttons {
+      margin-top: 1em; border-top: 1px solid #999;
+      padding: 2px; text-align: right;
+}
+</style>
+
+  </head>
+
+  <body onload="Init()">
+
+    <div class="title"><span>Document properties</span></div>
+
+    <table style="width: 100%">
+      <tr>
+        <td class="label"><span>Document title:</span></td>
+        <td><input type="text" id="f_title" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>DOCTYPE:</span></td>
+        <td><input type="text" id="f_doctype" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Primary style-sheet:</span></td>
+        <td><input type="text" id="f_base_style" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Alternate style-sheet:</span></td>
+        <td><input type="text" id="f_alt_style" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Background color:</span></td>
+        <td><input type="text" id="f_body_bgcolor" size="7" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Text color:</span></td>
+        <td><input type="text" id="f_body_fgcolor" size="7" /></td>
+      </tr>
+    </table>
+
+    <div id="buttons">
+      <button type="button" name="ok" onclick="return onOK();"><span>OK</span></button>
+      <button type="button" name="cancel" onclick="return onCancel();"><span>Cancel</span></button>
+    </div>
+
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/full-page.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/full-page.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/FullPage/full-page.js	(revision 795)
@@ -0,0 +1,142 @@
+// FullPage Plugin for HTMLArea-3.0
+// Implementation by Mihai Bazon.  Sponsored by http://thycotic.com
+//
+// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc.
+// This notice MUST stay intact for use (see license.txt).
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon for InteractiveTools.
+//   http://dynarch.com/mishoo
+//
+
+function FullPage(editor) {
+	this.editor = editor;
+
+	var cfg = editor.config;
+	cfg.fullPage = true;
+	var tt = FullPage.I18N;
+	var self = this;
+
+	cfg.registerButton("FP-docprop", tt["Document properties"], editor.imgURL("docprop.gif", "FullPage"), false,
+			   function(editor, id) {
+				   self.buttonPress(editor, id);
+			   });
+
+	// add a new line in the toolbar
+	cfg.toolbar[0].splice(0, 0, "separator");
+	cfg.toolbar[0].splice(0, 0, "FP-docprop");
+};
+
+FullPage._pluginInfo = {
+	name          : "FullPage",
+	version       : "1.0",
+	developer     : "Mihai Bazon",
+	developer_url : "http://dynarch.com/mishoo/",
+	c_owner       : "Mihai Bazon",
+	sponsor       : "Thycotic Software Ltd.",
+	sponsor_url   : "http://thycotic.com",
+	license       : "htmlArea"
+};
+
+FullPage.prototype.buttonPress = function(editor, id) {
+	var self = this;
+	switch (id) {
+	    case "FP-docprop":
+		var doc = editor._doc;
+		var links = doc.getElementsByTagName("link");
+		var style1 = '';
+		var style2 = '';
+		for (var i = links.length; --i >= 0;) {
+			var link = links[i];
+			if (/stylesheet/i.test(link.rel)) {
+				if (/alternate/i.test(link.rel))
+					style2 = link.href;
+				else
+					style1 = link.href;
+			}
+		}
+		var title = doc.getElementsByTagName("title")[0];
+		title = title ? title.innerHTML : '';
+		var init = {
+			f_doctype      : editor.doctype,
+			f_title        : title,
+			f_body_bgcolor : HTMLArea._colorToRgb(doc.body.style.backgroundColor),
+			f_body_fgcolor : HTMLArea._colorToRgb(doc.body.style.color),
+			f_base_style   : style1,
+			f_alt_style    : style2,
+
+			editor         : editor
+		};
+		editor._popupDialog("plugin://FullPage/docprop", function(params) {
+			self.setDocProp(params);
+		}, init);
+		break;
+	}
+};
+
+FullPage.prototype.setDocProp = function(params) {
+	var txt = "";
+	var doc = this.editor._doc;
+	var head = doc.getElementsByTagName("head")[0];
+	var links = doc.getElementsByTagName("link");
+	var style1 = null;
+	var style2 = null;
+	for (var i = links.length; --i >= 0;) {
+		var link = links[i];
+		if (/stylesheet/i.test(link.rel)) {
+			if (/alternate/i.test(link.rel))
+				style2 = link;
+			else
+				style1 = link;
+		}
+	}
+	function createLink(alt) {
+		var link = doc.createElement("link");
+		link.rel = alt ? "alternate stylesheet" : "stylesheet";
+		head.appendChild(link);
+		return link;
+	};
+
+	if (!style1 && params.f_base_style)
+		style1 = createLink(false);
+	if (params.f_base_style)
+		style1.href = params.f_base_style;
+	else if (style1)
+		head.removeChild(style1);
+
+	if (!style2 && params.f_alt_style)
+		style2 = createLink(true);
+	if (params.f_alt_style)
+		style2.href = params.f_alt_style;
+	else if (style2)
+		head.removeChild(style2);
+
+	for (var i in params) {
+		var val = params[i];
+		switch (i) {
+		    case "f_title":
+			var title = doc.getElementsByTagName("title")[0];
+			if (!title) {
+				title = doc.createElement("title");
+				head.appendChild(title);
+			} else while (node = title.lastChild)
+				title.removeChild(node);
+			if (!HTMLArea.is_ie)
+				title.appendChild(doc.createTextNode(val));
+			else
+				doc.title = val;
+			break;
+		    case "f_doctype":
+			this.editor.setDoctype(val);
+			break;
+		    case "f_body_bgcolor":
+			doc.body.style.backgroundColor = val;
+			break;
+		    case "f_body_fgcolor":
+			doc.body.style.color = val;
+			break;
+		}
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/.directory
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/.directory	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/.directory	(revision 795)
@@ -0,0 +1,2 @@
+[URL properties]
+ViewMode=konq_iconview
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/merge_langs
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/merge_langs	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/merge_langs	(revision 795)
@@ -0,0 +1,117 @@
+#!/usr/bin/php -q
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                               *
+* Written by Ralf Becker <RalfBecker@outdoor-training.de>                  *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/* $Id: merge_langs 2 2006-08-04 19:55:17Z celepar $ */
+
+$plugin_dir = realpath(dirname(__FILE__));
+$setup_dir = realpath(dirname(__FILE__).'/../../../setup');
+
+function load_langfile($lang)
+{
+	global $setup_dir;
+	
+	$lang_file = $setup_dir.'/phpgw_'.$lang.'.lang';
+	
+	$arr = array();
+	if (file_exists($lang_file))
+	{
+		foreach(file($lang_file) as $line)
+		{
+			@list($phrase,$app,$lang,$trans) = split("[\t\n\r]",$line);
+			$arr[$phrase] = array(
+				'app' => $app,
+				'trans' => $trans,
+			);
+		}
+	}
+	return $arr;
+}
+
+function save_langfile($lang,$arr)
+{
+	$content = '';
+	ksort($arr);
+	foreach($arr as $phrase => $data)
+	{
+		$content .= "$phrase\t$data[app]\t$lang\t$data[trans]\n";
+	}
+	global $setup_dir;
+	$lang_file = $setup_dir.'/phpgw_'.$lang.'.lang';
+	
+	if ($f = fopen($lang_file,'w'))
+	{
+		fwrite($f,$content);
+	}
+	fclose($f);
+}
+
+$d = opendir($plugin_dir);
+while ($plugin = readdir($d))
+{
+	if (!is_dir($plugin) || $plugin == 'CVS' || $plugin == 'CSS' || $plugin[0] == '.') continue;
+	
+	if (!@file_exists($lang_file = $plugin_dir.'/'.$plugin.'/lang/en.js')) continue;
+	$lang_file = file_get_contents($lang_file);
+	
+	if (!preg_match_all('/"([^"]+)"[ \t:]+"([^"]+)"/',$lang_file,$matches)) continue;
+	$token2en = array();
+	foreach($matches[1] as $n => $token)
+	{
+		$token2en[$token] = $matches[2][$n];
+	}
+	
+	$l = opendir($plugin_dir.'/'.$plugin.'/lang');
+	
+	while ($lang_file = readdir($l))
+	{
+		if (!preg_match('/.js$/',$lang_file)) continue;
+		
+		$lang = substr($lang_file,0,2);
+		$lang_file = $plugin_dir.'/'.$plugin.'/lang/'.$lang_file;
+		echo "\nprocessing: $lang_file\n";
+
+		$lang_file = file_get_contents($lang_file);
+		
+		if (preg_match_all('/"([^"]+)"[ \t:]+"([^"]+)"/',$lang_file,$matches))
+		{
+			$arr = load_langfile($lang);
+			$needs_save = false;
+			
+			foreach($matches[1] as $n => $token)
+			{
+				if (!isset($token2en[$token])) continue;
+
+				$phrase = strtolower($token2en[$token]);
+				
+				if (!$phrase) continue;
+				
+				if (isset($arr[$phrase]))
+				{
+					if ($arr[$phrase]['app'] != 'common' && $arr[$phrase]['app'] != 'htmlarea-'.$plugin)
+					{
+						$arr[$phrase]['app'] = 'common';
+					}
+					continue;
+				}				
+				$arr[$phrase] = array(
+					'app'	=> 'htmlarea-'.$plugin,
+					'trans' => $matches[2][$n],
+				);
+				echo "adding: $phrase = ".$matches[2][$n]."\n";
+				$needs_save = true;
+			}
+			if ($needs_save) save_langfile($lang,$arr);
+		}
+	}
+}
+closedir($d);
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-style.css
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-style.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-style.css	(revision 795)
@@ -0,0 +1,10 @@
+.HA-spellcheck-error { border-bottom: 1px dashed #f00; cursor: default; }
+.HA-spellcheck-same { background-color: #cef; color: #000; }
+.HA-spellcheck-hover { background-color: #433; color: white; }
+.HA-spellcheck-fixed { border-bottom: 1px dashed #0b8; }
+.HA-spellcheck-current { background-color: #9be; color: #000; }
+.HA-spellcheck-suggestions { display: none; }
+
+#HA-spellcheck-dictionaries { display: none; }
+
+a:link, a:visited { color: #55e; }
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-ui.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-ui.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-ui.js	(revision 795)
@@ -0,0 +1,396 @@
+// Spell Checker Plugin for HTMLArea-3.0
+// Sponsored by www.americanbible.org
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+
+// internationalization file was already loaded in parent ;-)
+var SpellChecker = window.opener.SpellChecker;
+var i18n = SpellChecker.I18N;
+
+var HTMLArea = window.opener.HTMLArea;
+var is_ie = HTMLArea.is_ie;
+var editor = SpellChecker.editor;
+var frame = null;
+var currentElement = null;
+var wrongWords = null;
+var modified = false;
+var allWords = {};
+var fixedWords = [];
+var suggested_words = {};
+
+function makeCleanDoc(leaveFixed) {
+	// document.getElementById("status").innerHTML = 'Please wait: rendering valid HTML';
+	var words = wrongWords.concat(fixedWords);
+	for (var i = words.length; --i >= 0;) {
+		var el = words[i];
+		if (!(leaveFixed && /HA-spellcheck-fixed/.test(el.className))) {
+			el.parentNode.insertBefore(el.firstChild, el);
+			el.parentNode.removeChild(el);
+		} else
+			el.className = "HA-spellcheck-fixed";
+	}
+	// we should use innerHTML here, but IE6's implementation fucks up the
+	// HTML to such extent that our poor Perl parser doesn't understand it
+	// anymore.
+	return window.opener.HTMLArea.getHTML(frame.contentWindow.document.body, false, editor);
+};
+
+function recheckClicked() {
+	document.getElementById("status").innerHTML = i18n["Please wait: changing dictionary to"] + ': "' + document.getElementById("f_dictionary").value + '".';
+	var field = document.getElementById("f_content");
+	field.value = makeCleanDoc(true);
+	field.form.submit();
+};
+
+function saveClicked() {
+	if (modified) {
+		editor.setHTML(makeCleanDoc(false));
+	}
+	window.close();
+	return false;
+};
+
+function cancelClicked() {
+	var ok = true;
+	if (modified) {
+		ok = confirm(i18n["QUIT_CONFIRMATION"]);
+	}
+	if (ok) {
+		window.close();
+	}
+	return false;
+};
+
+function replaceWord(el) {
+	var replacement = document.getElementById("v_replacement").value;
+	var this_word_modified = (el.innerHTML != replacement);
+	if (this_word_modified)
+		modified = true;
+	if (el) {
+		el.className = el.className.replace(/\s*HA-spellcheck-(hover|fixed)\s*/g, " ");
+	}
+	el.className += " HA-spellcheck-fixed";
+	el.__msh_fixed = true;
+	if (!this_word_modified) {
+		return false;
+	}
+	el.innerHTML = replacement;
+};
+
+function replaceClicked() {
+	replaceWord(currentElement);
+	var start = currentElement.__msh_id;
+	var index = start;
+	do {
+		++index;
+		if (index == wrongWords.length) {
+			index = 0;
+		}
+	} while ((index != start) && wrongWords[index].__msh_fixed);
+	if (index == start) {
+		index = 0;
+		alert(i18n["Finished list of mispelled words"]);
+	}
+	wrongWords[index].__msh_wordClicked(true);
+	return false;
+};
+
+function revertClicked() {
+	document.getElementById("v_replacement").value = currentElement.__msh_origWord;
+	replaceWord(currentElement);
+	currentElement.className = "HA-spellcheck-error HA-spellcheck-current";
+	return false;
+};
+
+function replaceAllClicked() {
+	var replacement = document.getElementById("v_replacement").value;
+	var ok = true;
+	var spans = allWords[currentElement.__msh_origWord];
+	if (spans.length == 0) {
+		alert("An impossible condition just happened.  Call FBI.  ;-)");
+	} else if (spans.length == 1) {
+		replaceClicked();
+		return false;
+	}
+	/*
+	var message = "The word \"" + currentElement.__msh_origWord + "\" occurs " + spans.length + " times.\n";
+	if (replacement == currentElement.__msh_origWord) {
+		ok = confirm(message + "Ignore all occurrences?");
+	} else {
+		ok = confirm(message + "Replace all occurrences with \"" + replacement + "\"?");
+	}
+	*/
+	if (ok) {
+		for (var i in spans) {
+			if (spans[i] != currentElement) {
+				replaceWord(spans[i]);
+			}
+		}
+		// replace current element the last, so that we jump to the next word ;-)
+		replaceClicked();
+	}
+	return false;
+};
+
+function ignoreClicked() {
+	document.getElementById("v_replacement").value = currentElement.__msh_origWord;
+	replaceClicked();
+	return false;
+};
+
+function ignoreAllClicked() {
+	document.getElementById("v_replacement").value = currentElement.__msh_origWord;
+	replaceAllClicked();
+	return false;
+};
+
+function learnClicked() {
+	alert("Not [yet] implemented");
+	return false;
+};
+
+function internationalizeWindow() {
+	var types = ["div", "span", "button"];
+	for (var i in types) {
+		var tag = types[i];
+		var els = document.getElementsByTagName(tag);
+		for (var j = els.length; --j >= 0;) {
+			var el = els[j];
+			if (el.childNodes.length == 1 && /\S/.test(el.innerHTML)) {
+				var txt = el.innerHTML;
+				if (typeof i18n[txt] != "undefined") {
+					el.innerHTML = i18n[txt];
+				}
+			}
+		}
+	}
+};
+
+function initDocument() {
+	internationalizeWindow();
+	modified = false;
+	frame = document.getElementById("i_framecontent");
+	var field = document.getElementById("f_content");
+	field.value = HTMLArea.getHTML(editor._doc.body, false, editor);
+	field.form.submit();
+	document.getElementById("f_init").value = "0";
+
+	// assign some global event handlers
+
+	var select = document.getElementById("v_suggestions");
+	select.onchange = function() {
+		document.getElementById("v_replacement").value = this.value;
+	};
+	if (is_ie) {
+		select.attachEvent("ondblclick", replaceClicked);
+	} else {
+		select.addEventListener("dblclick", replaceClicked, true);
+	}
+
+	document.getElementById("b_replace").onclick = replaceClicked;
+	// document.getElementById("b_learn").onclick = learnClicked;
+	document.getElementById("b_replall").onclick = replaceAllClicked;
+	document.getElementById("b_ignore").onclick = ignoreClicked;
+	document.getElementById("b_ignall").onclick = ignoreAllClicked;
+	document.getElementById("b_recheck").onclick = recheckClicked;
+	document.getElementById("b_revert").onclick = revertClicked;
+	document.getElementById("b_info").onclick = displayInfo;
+
+	document.getElementById("b_ok").onclick = saveClicked;
+	document.getElementById("b_cancel").onclick = cancelClicked;
+
+	select = document.getElementById("v_dictionaries");
+	select.onchange = function() {
+		document.getElementById("f_dictionary").value = this.value;
+	};
+};
+
+function getAbsolutePos(el) {
+	var r = { x: el.offsetLeft, y: el.offsetTop };
+	if (el.offsetParent) {
+		var tmp = getAbsolutePos(el.offsetParent);
+		r.x += tmp.x;
+		r.y += tmp.y;
+	}
+	return r;
+};
+
+function wordClicked(scroll) {
+	var self = this;
+	if (scroll) (function() {
+		var pos = getAbsolutePos(self);
+		var ws = { x: frame.offsetWidth - 4,
+			   y: frame.offsetHeight - 4 };
+		var wp = { x: frame.contentWindow.document.body.scrollLeft,
+			   y: frame.contentWindow.document.body.scrollTop };
+		pos.x -= Math.round(ws.x/2);
+		if (pos.x < 0) pos.x = 0;
+		pos.y -= Math.round(ws.y/2);
+		if (pos.y < 0) pos.y = 0;
+		frame.contentWindow.scrollTo(pos.x, pos.y);
+	})();
+	if (currentElement) {
+		var a = allWords[currentElement.__msh_origWord];
+		currentElement.className = currentElement.className.replace(/\s*HA-spellcheck-current\s*/g, " ");
+		for (var i in a) {
+			var el = a[i];
+			if (el != currentElement) {
+				el.className = el.className.replace(/\s*HA-spellcheck-same\s*/g, " ");
+			}
+		}
+	}
+	currentElement = this;
+	this.className += " HA-spellcheck-current";
+	var a = allWords[currentElement.__msh_origWord];
+	for (var i in a) {
+		var el = a[i];
+		if (el != currentElement) {
+			el.className += " HA-spellcheck-same";
+		}
+	}
+	// document.getElementById("b_replall").disabled = (a.length <= 1);
+	// document.getElementById("b_ignall").disabled = (a.length <= 1);
+	var txt;
+	if (a.length == 1) {
+		txt = "one occurrence";
+	} else if (a.length == 2) {
+		txt = "two occurrences";
+	} else {
+		txt = a.length + " occurrences";
+	}
+	var suggestions = suggested_words[this.__msh_origWord];
+	if (suggestions)
+		suggestions = suggestions.split(/,/);
+	else
+		suggestions = [];
+	var select = document.getElementById("v_suggestions");
+	document.getElementById("statusbar").innerHTML = "Found " + txt +
+		' for word "<b>' + currentElement.__msh_origWord + '</b>"';
+	for (var i = select.length; --i >= 0;) {
+		select.remove(i);
+	}
+	for (var i = 0; i < suggestions.length; ++i) {
+		var txt = suggestions[i];
+		var option = document.createElement("option");
+		option.value = txt;
+		option.appendChild(document.createTextNode(txt));
+		select.appendChild(option);
+	}
+	document.getElementById("v_currentWord").innerHTML = this.__msh_origWord;
+	if (suggestions.length > 0) {
+		select.selectedIndex = 0;
+		select.onchange();
+	} else {
+		document.getElementById("v_replacement").value = this.innerHTML;
+	}
+	select.style.display = "none";
+	select.style.display = "block";
+	return false;
+};
+
+function wordMouseOver() {
+	this.className += " HA-spellcheck-hover";
+};
+
+function wordMouseOut() {
+	this.className = this.className.replace(/\s*HA-spellcheck-hover\s*/g, " ");
+};
+
+function displayInfo() {
+	var info = frame.contentWindow.spellcheck_info;
+	if (!info)
+		alert("No information available");
+	else {
+		var txt = "** Document information **";
+		for (var i in info) {
+			txt += "\n" + i + " : " + info[i];
+		}
+		alert(txt);
+	}
+	return false;
+};
+
+function finishedSpellChecking() {
+	// initialization of global variables
+	currentElement = null;
+	wrongWords = null;
+	allWords = {};
+	fixedWords = [];
+	suggested_words = frame.contentWindow.suggested_words;
+
+	document.getElementById("status").innerHTML = "HTMLArea Spell Checker (<a href='readme-tech.html' target='_blank' title='Technical information'>info</a>)";
+	var doc = frame.contentWindow.document;
+        var spans = doc.getElementsByTagName("span");
+        var sps = [];
+	var id = 0;
+        for (var i = 0; i < spans.length; ++i) {
+                var el = spans[i];
+                if (/HA-spellcheck-error/.test(el.className)) {
+                        sps.push(el);
+			el.__msh_wordClicked = wordClicked;
+			el.onclick = function(ev) {
+				ev || (ev = window.event);
+				ev && HTMLArea._stopEvent(ev);
+				return this.__msh_wordClicked(false);
+			};
+			el.onmouseover = wordMouseOver;
+			el.onmouseout = wordMouseOut;
+			el.__msh_id = id++;
+			var txt = (el.__msh_origWord = el.firstChild.data);
+			el.__msh_fixed = false;
+			if (typeof allWords[txt] == "undefined") {
+				allWords[txt] = [el];
+			} else {
+				allWords[txt].push(el);
+			}
+                } else if (/HA-spellcheck-fixed/.test(el.className)) {
+			fixedWords.push(el);
+		}
+        }
+	wrongWords = sps;
+	if (sps.length == 0) {
+		if (!modified) {
+			alert(i18n["NO_ERRORS_CLOSING"]);
+			window.close();
+		} else {
+			alert(i18n["NO_ERRORS"]);
+		}
+		return false;
+	}
+	(currentElement = sps[0]).__msh_wordClicked(true);
+	var as = doc.getElementsByTagName("a");
+	for (var i = as.length; --i >= 0;) {
+		var a = as[i];
+		a.onclick = function() {
+			if (confirm(i18n["CONFIRM_LINK_CLICK"] + ":\n" +
+				    this.href + "\n" + i18n["I will open it in a new page."])) {
+				window.open(this.href);
+			}
+			return false;
+		};
+	}
+	var dicts = doc.getElementById("HA-spellcheck-dictionaries");
+	if (dicts) {
+		dicts.parentNode.removeChild(dicts);
+		dicts = dicts.innerHTML.split(/,/);
+		var select = document.getElementById("v_dictionaries");
+		for (var i = select.length; --i >= 0;) {
+			select.remove(i);
+		}
+		for (var i = 0; i < dicts.length; ++i) {
+			var txt = dicts[i];
+			var option = document.createElement("option");
+			if (/^@(.*)$/.test(txt)) {
+				txt = RegExp.$1;
+				option.selected = true;
+			}
+			option.value = txt;
+			option.appendChild(document.createTextNode(txt));
+			select.appendChild(option);
+		}
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/da.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/da.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/da.js	(revision 795)
@@ -0,0 +1,37 @@
+﻿// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Steen Sønderup, <steen@soenderup.com>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "Vil du følge dette link?",
+	"Cancel"                                : "Anuler",
+	"Dictionary"                            : "Ordbog",
+	"Finished list of mispelled words"      : "Listen med stavefejl er gennemgået",
+	"I will open it in a new page."         : "Jeg vil åbne det i en ny side.",
+	"Ignore all"                            : "Ignorer alle",
+	"Ignore"                                : "Ignorer",
+	"NO_ERRORS"                             : "Der blev ikke fundet nogle stavefejl med den valgte ordbog.",
+	"NO_ERRORS_CLOSING"                     : "Stavekontrollen er gennemført, der blev ikke fundet nogle stavefejl.  Lukker...",
+	"OK"                                    : "OK",
+	"Original word"                         : "Oprindeligt ord",
+	"Please wait.  Calling spell checker."  : "Vent venligst.  Henter stavekontrol.",
+	"Please wait: changing dictionary to"   : "Vent venligst: skifter ordbog til",
+	"QUIT_CONFIRMATION"                     : "Alle dine ændringer vil gå tabt, vil du fortsætte?",
+	"Re-check"                              : "Tjek igen",
+	"Replace all"                           : "Erstat alle",
+	"Replace with"                          : "Erstat med",
+	"Replace"                               : "Erstat",
+	"SC-spell-check"                        : "Stavekontrol",
+	"Suggestions"                           : "Forslag",
+	"pliz weit ;-)"                         : "Vent venligst"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/de.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/de.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/de.js	(revision 795)
@@ -0,0 +1,28 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Broxx, <broxx@broxx.com>
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "Wollen Sie diesen Link oeffnen",
+	"Cancel"                                : "Abbrechen",
+	"Dictionary"                            : "Woerterbuch",
+	"Finished list of mispelled words"      : "Liste der nicht bekannten Woerter",
+	"I will open it in a new page."         : "Wird auf neuer Seite geoeffnet",
+	"Ignore all"                            : "Alle ignorieren",
+	"Ignore"                                : "Ignorieren",
+	"NO_ERRORS"                             : "Keine falschen Woerter mit gewaehlten Woerterbuch gefunden",
+	"NO_ERRORS_CLOSING"                     : "Rechtsschreibpruefung wurde ohne Fehler fertiggestellt.  Wird nun geschlossen...",
+	"OK"                                    : "OK",
+	"Original word"                         : "Original Wort",
+	"Please wait.  Calling spell checker."  : "Bitte warten.  Woerterbuch wird durchsucht.",
+	"Please wait: changing dictionary to"   : "Bitte warten: Woerterbuch wechseln zu",
+	"QUIT_CONFIRMATION"                     : "Aenderungen werden nicht uebernommen.  Bitte bestaettigen.",
+	"Re-check"                              : "Neuueberpruefung",
+	"Replace all"                           : "Alle ersetzen",
+	"Replace with"                          : "Ersetzen mit",
+	"Replace"                               : "Ersetzen",
+	"SC-spell-check"                        : "Ueberpruefung",
+	"Suggestions"                           : "Vorschlag",
+	"pliz weit ;-)"                         : "bittsche wartn ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/cz.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/cz.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/cz.js	(revision 795)
@@ -0,0 +1,37 @@
+﻿// I18N constants
+
+// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2
+// Author: Jiri Löw, <jirilow@jirilow.com>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "Prosím potvrďte otevření tohoto odkazu",
+	"Cancel"                                : "Zrušit",
+	"Dictionary"                            : "Slovník",
+	"Finished list of mispelled words"      : "Dokončen seznam chybných slov",
+	"I will open it in a new page."         : "Bude otevřen jej v nové stránce.",
+	"Ignore all"                            : "Ignorovat vše",
+	"Ignore"                                : "Ignorovat",
+	"NO_ERRORS"                             : "Podle zvoleného slovníku nebyla nalezena žádná chybná slova.",
+	"NO_ERRORS_CLOSING"                     : "Kontrola správnosti slov dokončena, nebyla nalezena žádná chybná slova. Ukončování ...",
+	"OK"                                    : "OK",
+	"Original word"                         : "Původní slovo",
+	"Please wait.  Calling spell checker."  : "Prosím čekejte. Komunikuace s kontrolou správnosti slov.",
+	"Please wait: changing dictionary to"   : "Prosím čekejte: změna adresáře na",
+	"QUIT_CONFIRMATION"                     : "Změny budou zrušeny a kontrola správnosti slov ukončena. Prosím potvrďte.",
+	"Re-check"                              : "Překontrolovat",
+	"Replace all"                           : "Zaměnit všechno",
+	"Replace with"                          : "Zaměnit za",
+	"Replace"                               : "Zaměnit",
+	"SC-spell-check"                        : "Kontrola správnosti slov",
+	"Suggestions"                           : "Doporučení",
+	"pliz weit ;-)"                         : "strpení prosím ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/he.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/he.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/he.js	(revision 795)
@@ -0,0 +1,38 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "×× × ××©×š ×©××š×Š×× × ××€×ª×× ×§××©××š ××",
+	"Cancel"                                : "×××××",
+	"Dictionary"                            : "×××××",
+	"Finished list of mispelled words"      : "××¡×ª×××× ×š×©×××ª ×××××× ××××××ª××ª ××××€× ×©×××",
+	"I will open it in a new page."         : "×× × ××€×ª× ××ª ×× ××××× ×××©.",
+	"Ignore all"                            : "××ª×¢×× ××××",
+	"Ignore"                                : "××ª×¢××",
+	"NO_ERRORS"                             : "×× × ××Š×× ××××× ×××××ª××ª ××××€× ×©××× ×¢× ×××××× ×× ×××š.",
+	"NO_ERRORS_CLOSING"                     : "××××§×ª ×××××ª × ×¡×ª××××, ×× × ××Š×× ××××× ×××××ª××ª ××××€× ×©×××.  × ×¡××š ××¢×ª...",
+	"OK"                                    : "×××©××š",
+	"Original word"                         : "××××× ×××§××š××ª",
+	"Please wait.  Calling spell checker."  : "×× × ×××ª×.  ×§××š× ×××××§ ××××ª.",
+	"Please wait: changing dictionary to"   : "×× × ×××ª×: ×××××£ ××××× ×-",
+	"QUIT_CONFIRMATION"                     : "×× ×××× ××ª ××©×× ×××× ×××Š× ×××××§ ×××××ª.  ×× × ××©×š.",
+	"Re-check"                              : "××××§ ××××©",
+	"Replace all"                           : "××××£ ×××",
+	"Replace with"                          : "××××£ ×-",
+	"Replace"                               : "××××£",
+	"Revert"                                : "××××š ×©×× ××××",
+	"SC-spell-check"                        : "××××§×ª ××××ª",
+	"Suggestions"                           : "××Š×¢××ª",
+	"pliz weit ;-)"                         : "×¢× × ×××× ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/hu.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/hu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/hu.js	(revision 795)
@@ -0,0 +1,37 @@
+// I18N constants
+
+// LANG: "hu", ENCODING: UTF-8
+// Author: MiklÃ³s Somogyi, <somogyine@vnet.hu>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "MegerÅsÃ­tÃ©s",
+	"Cancel"                                : "MÃ©gsem",
+	"Dictionary"                            : "SzÃ³tÃ¡r",
+	"Finished list of mispelled words"      : "A tÃ©vesztett szavak listÃ¡jÃ¡nak vÃ©ge",
+	"I will open it in a new page."         : "MegnyitÃ¡s Ãºj lapon",
+	"Ignore all"                            : "Minden elvetÃ©se",
+	"Ignore"                                : "ElvetÃ©s",
+	"NO_ERRORS"                             : "A vÃ¡lasztott szÃ³tÃ¡r szerint nincs tÃ©vesztett szÃ³.",
+	"NO_ERRORS_CLOSING"                     : "A helyesÃ­rÃ¡sellenÅrzÃ©s kÃ©sz, tÃ©vesztett szÃ³ nem fordult elÅ. BezÃ¡rÃ¡s...",
+	"OK"                                    : "Rendben",
+	"Original word"                         : "Eredeti szÃ³",
+	"Please wait.  Calling spell checker."  : "Kis tÃŒrelmet, a helyesÃ­rÃ¡sellenÅrzÅ hÃ­vÃ¡sa folyamatban.",
+	"Please wait: changing dictionary to"   : "Kis tÃŒrelmet, szÃ³tÃ¡r cserÃ©je",
+	"QUIT_CONFIRMATION"                     : "KilÃ©pÃ©s a vÃ¡ltozÃ¡sok eldobÃ¡sÃ¡val. JÃ³vÃ¡hagyja?",
+	"Re-check"                              : "ÃjraellenÅrzÃ©s",
+	"Replace all"                           : "Mind cserÃ©je",
+	"Replace with"                          : "Csere a kÃ¶vetkezÅre:",
+	"Replace"                               : "Csere",
+	"SC-spell-check"                        : "HelyesÃ­rÃ¡sellenÅrzÃ©s",
+	"Suggestions"                           : "Tippek",
+	"pliz weit ;-)"                         : "Kis tÃŒrelmet ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/it.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/it.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/it.js	(revision 795)
@@ -0,0 +1,28 @@
+// I18N constants
+
+// LANG: "it", ENCODING: UTF-8 | ISO-8859-1
+// Author: Fabio Rotondo, <fabio@rotondo.it>
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "Devi confermare l'apertura di questo link",
+	"Cancel"                                : "Annulla",
+	"Dictionary"                            : "Dizionario",
+	"Finished list of mispelled words"      : "La lista delle parole scritte male Ãš terminata",
+	"I will open it in a new page."         : "Lo aprirÃ² in una nuova pagina.",
+	"Ignore all"                            : "Ignora sempre",
+	"Ignore"                                : "Ignora",
+	"NO_ERRORS"                             : "Non sono state trovate parole scritte male con il dizionario selezionato.",
+	"NO_ERRORS_CLOSING"                     : "Controllo completato, non sono state trovate parole scritte male. Sto chiudendo...",
+	"OK"                                    : "OK",
+	"Original word"                         : "Parola originale",
+	"Please wait.  Calling spell checker."  : "Attendere.  Sto invocando lo Spell Checker.",
+	"Please wait: changing dictionary to"   : "Attendere. Cambio il dizionario in",
+	"QUIT_CONFIRMATION"                     : "Questo annullerÃ  le modifiche e chiuderÃ  lo Spell Checker. Conferma.",
+	"Re-check"                              : "Ricontrolla",
+	"Replace all"                           : "Sostituisci sempre",
+	"Replace with"                          : "Stostituisci con",
+	"Replace"                               : "Sostituisci",
+	"SC-spell-check"                        : "Spell-check",
+	"Suggestions"                           : "Suggerimenti",
+	"pliz weit ;-)"                         : "Attendere Prego ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/lang.php	(revision 795)
@@ -0,0 +1,66 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-SpellChecker');
+
+// I18N constants
+
+// LANG:  "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    :  "<?php echo lang('Please confirm that you want to open this link'); ?>",
+	"Cancel"                                :  "<?php echo lang('Cancel'); ?>",
+	"Dictionary"                            :  "<?php echo lang('Dictionary'); ?>",
+	"Finished list of mispelled words"      :  "<?php echo lang('Finished list of mispelled words'); ?>",
+	"I will open it in a new page."         :  "<?php echo lang('I will open it in a new page.'); ?>",
+	"Ignore all"                            :  "<?php echo lang('Ignore all'); ?>",
+	"Ignore"                                :  "<?php echo lang('Ignore'); ?>",
+	"NO_ERRORS"                             :  "<?php echo lang('No mispelled words found with the selected dictionary.'); ?>",
+	"NO_ERRORS_CLOSING"                     :  "<?php echo lang('Spell check complete, didn\'t find any mispelled words.  Closing now...'); ?>",
+	"OK"                                    :  "<?php echo lang('OK'); ?>",
+	"Original word"                         :  "<?php echo lang('Original word'); ?>",
+	"Please wait.  Calling spell checker."  :  "<?php echo lang('Please wait.  Calling spell checker.'); ?>",
+	"Please wait: changing dictionary to"   :  "<?php echo lang('Please wait: changing dictionary to'); ?>",
+	"QUIT_CONFIRMATION"                     :  "<?php echo lang('This will drop changes and quit spell checker.  Please confirm.'); ?>",
+	"Re-check"                              :  "<?php echo lang('Re-check'); ?>",
+	"Replace all"                           :  "<?php echo lang('Replace all'); ?>",
+	"Replace with"                          :  "<?php echo lang('Replace with'); ?>",
+	"Replace"                               :  "<?php echo lang('Replace'); ?>",
+	"Revert"                                :  "<?php echo lang('Revert'); ?>",
+	"SC-spell-check"                        :  "<?php echo lang('Spell-check'); ?>",
+	"Suggestions"                           :  "<?php echo lang('Suggestions'); ?>",
+	"pliz weit ;-)"                         :  "<?php echo lang('pliz weit ;-)'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/ro.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/ro.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/ro.js	(revision 795)
@@ -0,0 +1,37 @@
+// I18N constants
+
+// LANG: "ro", ENCODING: UTF-8
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "VÄ rog confirmaÅ£i cÄ vreÅ£i sÄ deschideÅ£i acest link",
+	"Cancel"                                : "AnuleazÄ",
+	"Dictionary"                            : "DicÅ£ionar",
+	"Finished list of mispelled words"      : "Am terminat lista de cuvinte greÅite",
+	"I will open it in a new page."         : "O voi deschide Ã®ntr-o altÄ fereastrÄ.",
+	"Ignore all"                            : "IgnorÄ toate",
+	"Ignore"                                : "IgnorÄ",
+	"NO_ERRORS"                             : "Nu am gÄsit nici un cuvÃ¢nt greÅit cu acest dicÅ£ionar.",
+	"NO_ERRORS_CLOSING"                     : "Am terminat, nu am detectat nici o greÅealÄ.  Acum Ã®nchid fereastra...",
+	"OK"                                    : "OK",
+	"Original word"                         : "CuvÃ¢ntul original",
+	"Please wait.  Calling spell checker."  : "VÄ rog aÅteptaÅ£i.  Apelez spell-checker-ul.",
+	"Please wait: changing dictionary to"   : "VÄ rog aÅteptaÅ£i.  Schimb dicÅ£ionarul cu",
+	"QUIT_CONFIRMATION"                     : "DoriÅ£i sÄ renunÅ£aÅ£i la modificÄri Åi sÄ Ã®nchid spell-checker-ul?",
+	"Re-check"                              : "ScaneazÄ",
+	"Replace all"                           : "ÃnlocuieÅte toate",
+	"Replace with"                          : "ÃnlocuieÅte cu",
+	"Replace"                               : "ÃnlocuieÅte",
+	"SC-spell-check"                        : "DetecteazÄ greÅeli",
+	"Suggestions"                           : "Sugestii",
+	"pliz weit ;-)"                         : "va rog ashteptatzi ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/lang/en.js	(revision 795)
@@ -0,0 +1,38 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+	"CONFIRM_LINK_CLICK"                    : "Please confirm that you want to open this link",
+	"Cancel"                                : "Cancel",
+	"Dictionary"                            : "Dictionary",
+	"Finished list of mispelled words"      : "Finished list of mispelled words",
+	"I will open it in a new page."         : "I will open it in a new page.",
+	"Ignore all"                            : "Ignore all",
+	"Ignore"                                : "Ignore",
+	"NO_ERRORS"                             : "No mispelled words found with the selected dictionary.",
+	"NO_ERRORS_CLOSING"                     : "Spell check complete, didn't find any mispelled words.  Closing now...",
+	"OK"                                    : "OK",
+	"Original word"                         : "Original word",
+	"Please wait.  Calling spell checker."  : "Please wait.  Calling spell checker.",
+	"Please wait: changing dictionary to"   : "Please wait: changing dictionary to",
+	"QUIT_CONFIRMATION"                     : "This will drop changes and quit spell checker.  Please confirm.",
+	"Re-check"                              : "Re-check",
+	"Replace all"                           : "Replace all",
+	"Replace with"                          : "Replace with",
+	"Replace"                               : "Replace",
+	"Revert"                                : "Revert",
+	"SC-spell-check"                        : "Spell-check",
+	"Suggestions"                           : "Suggestions",
+	"pliz weit ;-)"                         : "pliz weit ;-)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/readme-tech.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/readme-tech.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/readme-tech.html	(revision 795)
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html>
+  <head>
+    <title>HTMLArea Spell Checker</title>
+  </head>
+
+  <body>
+    <h1>HTMLArea Spell Checker</h1>
+
+    <p>The HTMLArea Spell Checker subsystem consists of the following
+      files:</p>
+
+    <ul>
+
+      <li>spell-checker.js &mdash; the spell checker plugin interface for
+        HTMLArea</li>
+
+      <li>spell-checker-ui.html &mdash; the HTML code for the user
+        interface</li>
+
+      <li>spell-checker-ui.js &mdash; functionality of the user
+        interface</li>
+
+      <li>spell-checker-logic.cgi &mdash; Perl CGI script that checks a text
+        given through POST for spelling errors</li>
+
+      <li>spell-checker-style.css &mdash; style for mispelled words</li>
+
+      <li>lang/en.js &mdash; main language file (English).</li>
+
+    </ul>
+
+    <h2>Process overview</h2>
+
+    <p>
+      When an end-user clicks the "spell-check" button in the HTMLArea
+      editor, a new window is opened with the URL of "spell-check-ui.html".
+      This window initializes itself with the text found in the editor (uses
+      <tt>window.opener.SpellChecker.editor</tt> global variable) and it
+      submits the text to the server-side script "spell-check-logic.cgi".
+      The target of the FORM is an inline frame which is used both to
+      display the text and correcting.
+    </p>
+
+    <p>
+      Further, spell-check-logic.cgi calls Aspell for each portion of plain
+      text found in the given HTML.  It rebuilds an HTML file that contains
+      clear marks of which words are incorrect, along with suggestions for
+      each of them.  This file is then loaded in the inline frame.  Upon
+      loading, a JavaScript function from "spell-check-ui.js" is called.
+      This function will retrieve all mispelled words from the HTML of the
+      iframe and will setup the user interface so that it allows correction.
+    </p>
+
+    <h2>The server-side script (spell-check-logic.cgi)</h2>
+
+    <p>
+      <strong>Unicode safety</strong> &mdash; the program <em>is</em>
+      Unicode safe.  HTML entities are expanded into their corresponding
+      Unicode characters.  These characters will be matched as part of the
+      word passed to Aspell.  All texts passed to Aspell are in Unicode
+      (when appropriate).  <strike>However, Aspell seems to not support Unicode
+      yet (<a
+        href="http://mail.gnu.org/archive/html/aspell-user/2000-11/msg00007.html">thread concerning Aspell and Unicode</a>).
+      This mean that words containing Unicode
+      characters that are not in 0..255 are likely to be reported as "mispelled" by Aspell.</strike>
+    </p>
+
+    <p>
+      <strong style="font-variant: small-caps; color:
+      red;">Update:</strong> though I've never seen it mentioned
+      anywhere, it looks that Aspell <em>does</em>, in fact, speak
+      Unicode.  Or else, maybe <code>Text::Aspell</code> does
+      transparent conversion; anyway, this new version of our
+      SpellChecker plugin is, as tests show so far, fully
+      Unicode-safe... well, probably the <em>only</em> freeware
+      Web-based spell-checker which happens to have Unicode support.
+    </p>
+
+    <p>
+      The Perl Unicode manual (man perluniintro) states:
+    </p>
+
+    <blockquote>
+      <em>
+        Starting from Perl 5.6.0, Perl has had the capacity to handle Unicode
+        natively.  Perl 5.8.0, however, is the first recommended release for
+        serious Unicode work.  The maintenance release 5.6.1 fixed many of the
+        problems of the initial Unicode implementation, but for example regular
+        expressions still do not work with Unicode in 5.6.1.
+      </em>
+    </blockquote>
+
+    <p>In other words, do <em>not</em> assume that this script is
+      Unicode-safe on Perl interpreters older than 5.8.0.</p>
+
+    <p>The following Perl modules are required:</p>
+
+    <ul>
+      <li><a href="http://search.cpan.org/search?query=Text%3A%3AAspell&mode=all" target="_blank">Text::Aspell</a></li>
+      <li><a href="http://search.cpan.org/search?query=XML%3A%3ADOM&mode=all" target="_blank">XML::DOM</a></li>
+      <li><a href="http://search.cpan.org/search?query=CGI&mode=all" target="_blank">CGI</a></li>
+    </ul>
+
+    <p>Of these, only Text::Aspell might need to be installed manually.  The
+      others are likely to be available by default in most Perl distributions.</p>
+
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Thu Jul 17 13:22:27 EEST 2003 -->
+<!-- hhmts start --> Last modified: Fri Jan 30 19:14:11 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-logic.cgi
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-logic.cgi	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-logic.cgi	(revision 795)
@@ -0,0 +1,209 @@
+#! /usr/bin/perl -w
+
+# Spell Checker Plugin for HTMLArea-3.0
+# Sponsored by www.americanbible.org
+# Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+#
+# (c) dynarch.com 2003.
+# Distributed under the same terms as HTMLArea itself.
+# This notice MUST stay intact for use (see license.txt).
+#
+
+use strict;
+use utf8;
+use Encode;
+use Text::Aspell;
+use XML::DOM;
+use CGI;
+
+my $TIMER_start = undef;
+eval {
+    use Time::HiRes qw( gettimeofday tv_interval );
+    $TIMER_start = [gettimeofday()];
+};
+# use POSIX qw( locale_h );
+
+binmode STDIN, ':utf8';
+binmode STDOUT, ':utf8';
+
+my $debug = 0;
+
+my $speller = new Text::Aspell;
+my $cgi = new CGI;
+
+my $total_words = 0;
+my $total_mispelled = 0;
+my $total_suggestions = 0;
+my $total_words_suggested = 0;
+
+# FIXME: report a nice error...
+die "Can't create speller!" unless $speller;
+
+my $dict = $cgi->param('dictionary') || $cgi->cookie('dictionary') || 'en';
+
+# add configurable option for this
+$speller->set_option('lang', $dict);
+$speller->set_option('encoding', 'UTF-8');
+#setlocale(LC_CTYPE, $dict);
+
+# ultra, fast, normal, bad-spellers
+# bad-spellers seems to cause segmentation fault
+$speller->set_option('sug-mode', 'normal');
+
+my %suggested_words = ();
+keys %suggested_words = 128;
+
+my $file_content = decode('UTF-8', $cgi->param('content'));
+$file_content = parse_with_dom($file_content);
+
+my $ck_dictionary = $cgi->cookie(-name     => 'dictionary',
+                                 -value    => $dict,
+                                 -expires  => '+30d');
+
+print $cgi->header(-type    => 'text/html; charset: utf-8',
+                   -cookie  => $ck_dictionary);
+
+my $js_suggested_words = make_js_hash(\%suggested_words);
+my $js_spellcheck_info = make_js_hash_from_array
+  ([
+    [ 'Total words'           , $total_words ],
+    [ 'Mispelled words'       , $total_mispelled . ' in dictionary \"'.$dict.'\"' ],
+    [ 'Total suggestions'     , $total_suggestions ],
+    [ 'Total words suggested' , $total_words_suggested ],
+    [ 'Spell-checked in'      , defined $TIMER_start ? (tv_interval($TIMER_start) . ' seconds') : 'n/a' ]
+   ]);
+
+print qq^<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" type="text/css" media="all" href="spell-check-style.css" />
+<script type="text/javascript">
+  var suggested_words = { $js_suggested_words };
+  var spellcheck_info = { $js_spellcheck_info }; </script>
+</head>
+<body onload="window.parent.finishedSpellChecking();">^;
+
+print $file_content;
+if ($cgi->param('init') eq '1') {
+    my @dicts = $speller->dictionary_info();
+    my $dictionaries = '';
+    foreach my $i (@dicts) {
+        next if $i->{jargon};
+        my $name = $i->{name};
+        if ($name eq $dict) {
+            $name = '@'.$name;
+        }
+        $dictionaries .= ',' . $name;
+    }
+    $dictionaries =~ s/^,//;
+    print qq^<div id="HA-spellcheck-dictionaries">$dictionaries</div>^;
+}
+
+print '</body></html>';
+
+# Perl is beautiful.
+sub spellcheck {
+    my $node = shift;
+    my $doc = $node->getOwnerDocument;
+    my $check = sub {                 # called for each word in the text
+        # input is in UTF-8
+        my $word = shift;
+        my $already_suggested = defined $suggested_words{$word};
+        ++$total_words;
+        if (!$already_suggested && $speller->check($word)) {
+            return undef;
+        } else {
+            # we should have suggestions; give them back to browser in UTF-8
+            ++$total_mispelled;
+            if (!$already_suggested) {
+                # compute suggestions for this word
+                my @suggestions = $speller->suggest($word);
+                my $suggestions = decode($speller->get_option('encoding'), join(',', @suggestions));
+                $suggested_words{$word} = $suggestions;
+                ++$total_suggestions;
+                $total_words_suggested += scalar @suggestions;
+            }
+            # HA-spellcheck-error
+            my $err = $doc->createElement('span');
+            $err->setAttribute('class', 'HA-spellcheck-error');
+            my $tmp = $doc->createTextNode;
+            $tmp->setNodeValue($word);
+            $err->appendChild($tmp);
+            return $err;
+        }
+    };
+    while ($node->getNodeValue =~ /([\p{IsWord}']+)/) {
+        my $word = $1;
+        my $before = $`;
+        my $after = $';
+        my $df = &$check($word);
+        if (!$df) {
+            $before .= $word;
+        }
+        {
+            my $parent = $node->getParentNode;
+            my $n1 = $doc->createTextNode;
+            $n1->setNodeValue($before);
+            $parent->insertBefore($n1, $node);
+            $parent->insertBefore($df, $node) if $df;
+            $node->setNodeValue($after);
+        }
+    }
+};
+
+sub check_inner_text {
+    my $node = shift;
+    my $text = '';
+    for (my $i = $node->getFirstChild; defined $i; $i = $i->getNextSibling) {
+        if ($i->getNodeType == TEXT_NODE) {
+            spellcheck($i);
+        }
+    }
+};
+
+sub parse_with_dom {
+    my ($text) = @_;
+    $text = '<spellchecker>'.$text.'</spellchecker>';
+
+    my $parser = new XML::DOM::Parser;
+    if ($debug) {
+        open(FOO, '>:utf8', '/tmp/foo');
+        print FOO $text;
+        close FOO;
+    }
+    my $doc = $parser->parse($text);
+    my $nodes = $doc->getElementsByTagName('*');
+    my $n = $nodes->getLength;
+
+    for (my $i = 0; $i < $n; ++$i) {
+        my $node = $nodes->item($i);
+        if ($node->getNodeType == ELEMENT_NODE) {
+            check_inner_text($node);
+        }
+    }
+
+    my $ret = $doc->toString;
+    $ret =~ s{<spellchecker>(.*)</spellchecker>}{$1}sg;
+    return $ret;
+};
+
+sub make_js_hash {
+    my ($hash) = @_;
+    my $js_hash = '';
+    while (my ($key, $val) = each %$hash) {
+        $js_hash .= ',' if $js_hash;
+        $js_hash .= '"'.$key.'":"'.$val.'"';
+    }
+    return $js_hash;
+};
+
+sub make_js_hash_from_array {
+    my ($array) = @_;
+    my $js_hash = '';
+    foreach my $i (@$array) {
+        $js_hash .= ',' if $js_hash;
+        $js_hash .= '"'.$i->[0].'":"'.$i->[1].'"';
+    }
+    return $js_hash;
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-ui.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-ui.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-check-ui.html	(revision 795)
@@ -0,0 +1,121 @@
+<!--
+
+  Strangely, IE sucks with or without the DOCTYPE switch.
+  I thought it would only suck without it.
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+
+   Spell Checker Plugin for HTMLArea-3.0
+   Sponsored by www.americanbible.org
+   Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+  
+   (c) dynarch.com 2003.
+   Distributed under the same terms as HTMLArea itself.
+   This notice MUST stay intact for use (see license.txt).
+
+
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+  <head>
+    <title>Spell Checker</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <script type="text/javascript" src="spell-check-ui.js"></script>
+
+    <style type="text/css">
+      html, body { height: 100%; margin: 0px; padding: 0px; background-color: #fff;
+      color: #000; }
+      a:link, a:visited { color: #00f; text-decoration: none; }
+      a:hover { color: #f00; text-decoration: underline; }
+
+      table { background-color: ButtonFace; color: ButtonText;
+      font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+
+      iframe { background-color: #fff; color: #000; height: 100%; width: 100%; }
+
+      .controls { width: 13em; }
+      .controls .sectitle { /* background-color: #736c6c; color: #fff;
+      border-top: 1px solid #000; border-bottom: 1px solid #fff; */
+      text-align: center;
+      font-weight: bold; padding: 2px 4px; }
+      .controls .secbody { margin-bottom: 10px; }
+
+      button, select { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+      button { width: 6em; padding: 0px; }
+
+      input, select { font-family: fixed,"andale mono",monospace; }
+
+      #v_currentWord { color: #f00; font-weight: bold; }
+      #statusbar { padding: 7px 0px 0px 5px; }
+      #status { font-weight: bold; }
+    </style>
+
+  </head>
+
+  <body onload="initDocument()">
+
+    <form style="display: none;" action="spell-check-logic.cgi"
+          method="post" target="framecontent"
+          accept-charset="UTF-8"
+          ><input type="hidden" name="content" id="f_content"
+          /><input type="hidden" name="dictionary" id="f_dictionary"
+          /><input type="hidden" name="init" id="f_init" value="1"
+    /></form>
+
+    <table style="height: 100%; width: 100%; border-collapse: collapse;" cellspacing="0" cellpadding="0">
+      <tr>
+        <td colspan="2" style="height: 1em; padding: 2px;">
+          <div style="float: right; padding: 2px;"><span>Dictionary</span>
+            <select id="v_dictionaries" style="width: 10em"></select>
+            <button id="b_recheck">Re-check</button>
+          </div>
+          <span id="status">Please wait.  Calling spell checker.</span>
+        </td>
+      </tr>
+      <tr>
+        <td valign="top" class="controls">
+          <div class="secbody" style="text-align: center">
+            <button id="b_info">Info</button>
+          </div>
+          <div class="sectitle">Original word</div>
+          <div class="secbody" id="v_currentWord" style="text-align:
+          center; margin-bottom: 0px;">pliz weit ;-)</div>
+          <div class="secbody" style="text-align: center">
+            <button id="b_revert">Revert</button>
+          </div>
+          <div class="sectitle">Replace with</div>
+          <div class="secbody">
+            <input type="text" id="v_replacement" style="width: 94%; margin-left: 3%;" /><br />
+            <div style="text-align: center; margin-top: 2px;">
+              <button id="b_replace">Replace</button><button
+                id="b_replall">Replace all</button><br /><button
+                id="b_ignore">Ignore</button><button
+                id="b_ignall">Ignore all</button>
+            </div>
+          </div>
+          <div class="sectitle">Suggestions</div>
+          <div class="secbody">
+            <select size="11" style="width: 94%; margin-left: 3%;" id="v_suggestions"></select>
+          </div>
+        </td>
+
+        <td>
+          <iframe src="about:blank" width="100%" height="100%"
+            id="i_framecontent" name="framecontent"></iframe>
+        </td>
+      </tr>
+      <tr>
+        <td style="height: 1em;" colspan="2">
+          <div style="padding: 4px 2px 2px 2px; float: right;">
+            <button id="b_ok">OK</button>
+            <button id="b_cancel">Cancel</button>
+          </div>
+          <div id="statusbar"></div>
+        </td>
+      </tr>
+    </table>
+
+  </body>
+
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/.htaccess
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/.htaccess	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/.htaccess	(revision 795)
@@ -0,0 +1,1 @@
+Options +ExecCGI
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-checker.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-checker.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/SpellChecker/spell-checker.js	(revision 795)
@@ -0,0 +1,78 @@
+// Spell Checker Plugin for HTMLArea-3.0
+// Sponsored by www.americanbible.org
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+
+function SpellChecker(editor) {
+	this.editor = editor;
+
+	var cfg = editor.config;
+	var tt = SpellChecker.I18N;
+	var bl = SpellChecker.btnList;
+	var self = this;
+
+	// register the toolbar buttons provided by this plugin
+	var toolbar = [];
+	for (var i in bl) {
+		var btn = bl[i];
+		if (!btn) {
+			toolbar.push("separator");
+		} else {
+			var id = "SC-" + btn[0];
+			cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "SpellChecker"), false,
+					   function(editor, id) {
+						   // dispatch button press event
+						   self.buttonPress(editor, id);
+					   }, btn[1]);
+			toolbar.push(id);
+		}
+	}
+
+	for (var i in toolbar) {
+		cfg.toolbar[0].push(toolbar[i]);
+	}
+};
+
+SpellChecker._pluginInfo = {
+	name          : "SpellChecker",
+	version       : "1.0",
+	developer     : "Mihai Bazon",
+	developer_url : "http://dynarch.com/mishoo/",
+	c_owner       : "Mihai Bazon",
+	sponsor       : "American Bible Society",
+	sponsor_url   : "http://www.americanbible.org",
+	license       : "htmlArea"
+};
+
+SpellChecker.btnList = [
+	null, // separator
+	["spell-check"]
+	];
+
+SpellChecker.prototype.buttonPress = function(editor, id) {
+	switch (id) {
+	    case "SC-spell-check":
+		SpellChecker.editor = editor;
+		SpellChecker.init = true;
+		var uiurl = _editor_url + "plugins/SpellChecker/spell-check-ui.html";
+		var win;
+		if (HTMLArea.is_ie) {
+			win = window.open(uiurl, "SC_spell_checker",
+					  "toolbar=no,location=no,directories=no,status=no,menubar=no," +
+					  "scrollbars=no,resizable=yes,width=600,height=450");
+		} else {
+			win = window.open(uiurl, "SC_spell_checker",
+					  "toolbar=no,menubar=no,personalbar=no,width=600,height=450," +
+					  "scrollbars=no,resizable=yes");
+		}
+		win.focus();
+		break;
+	}
+};
+
+// this needs to be global, it's accessed from spell-check-ui.html
+SpellChecker.editor = null;
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/EnterParagraphs/enter-paragraphs.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/EnterParagraphs/enter-paragraphs.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/EnterParagraphs/enter-paragraphs.js	(revision 795)
@@ -0,0 +1,204 @@
+// Modification to htmlArea to insert Paragraphs instead of
+// linebreaks, under Gecko engines, circa January 2004
+// By Adam Wright, for The University of Western Australia
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+function EnterParagraphs(editor, params) {
+	this.editor = editor;
+	// activate only if we're talking to Gecko
+	if (HTMLArea.is_gecko)
+		this.onKeyPress = this.__onKeyPress;
+};
+
+EnterParagraphs._pluginInfo = {
+	name          : "EnterParagraphs",
+	version       : "1.0",
+	developer     : "Adam Wright",
+	developer_url : "http://blog.hipikat.org/",
+	sponsor       : "The University of Western Australia",
+	sponsor_url   : "http://www.uwa.edu.au/",
+	license       : "htmlArea"
+};
+
+// An array of elements who, in html4, by default, have an inline display and can have children
+// we use RegExp here since it should be a bit faster, also cleaner to check
+EnterParagraphs.prototype._html4_inlines_re = /^(a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|kbd|label|q|s|samp|select|small|span|strike|strong|sub|sup|textarea|tt|u|var)$/i;
+
+// Finds the first parent element of a given node whose display is probably not inline
+EnterParagraphs.prototype.parentBlock = function(node) {
+	while (node.parentNode && (node.nodeType != 1 || this._html4_inlines_re.test(node.tagName)))
+		node = node.parentNode;
+	return node;
+};
+
+// Internal function for recursively itterating over a all nodes in a fragment
+// If a callback function returns a non-null value, that is returned and the crawl is therefore broken
+EnterParagraphs.prototype.walkNodeChildren = function(me, callback) {
+	if (me.firstChild) {
+		var myChild = me.firstChild;
+		var retVal;
+		while (myChild) {
+			if ((retVal = callback(this, myChild)) != null)
+				return retVal;
+			if ((retVal = this.walkNodeChildren(myChild, callback)) != null)
+				return retVal;
+			myChild = myChild.nextSibling;
+		}
+	}
+};
+
+// Callback function to be performed on each node in the hierarchy
+// Sets flag to true if we find actual text or an element that's not usually displayed inline
+EnterParagraphs.prototype._isFilling = function(self, node) {
+	if (node.nodeType == 1 && !self._html4_inlines_re.test(node.nodeName))
+		return true;
+	else if (node.nodeType == 3 && node.nodeValue != '')
+		return true;
+	return null;
+	//alert(node.nodeName);
+};
+
+// Inserts a node deeply on the left of a hierarchy of nodes
+EnterParagraphs.prototype.insertDeepLeftText = function(target, toInsert) {
+	var falling = target;
+	while (falling.firstChild && falling.firstChild.nodeType == 1)
+		falling = falling.firstChild;
+	//var refNode = falling.firstChild ? falling.firstChild : null;
+	//falling.insertBefore(toInsert, refNode);
+	falling.innerHTML = toInsert;
+};
+
+// Kind of like a macros, for a frequent query...
+EnterParagraphs.prototype.isElem = function(node, type) {
+	return node.nodeName.toLowerCase() == type.toLowerCase();
+};
+
+// The onKeyPress even that does all the work - nicely breaks the line into paragraphs
+EnterParagraphs.prototype.__onKeyPress = function(ev) {
+
+	if (ev.keyCode == 13 && !ev.shiftKey && this.editor._iframe.contentWindow.getSelection) {
+
+		var editor = this.editor;
+
+		// Get the selection and solid references to what we're dealing with chopping
+		var sel = editor._iframe.contentWindow.getSelection();
+
+		// Set the start and end points such that they're going /forward/ through the document
+		var rngLeft = editor._doc.createRange();		var rngRight = editor._doc.createRange();
+		rngLeft.setStart(sel.anchorNode, sel.anchorOffset);	rngRight.setStart(sel.focusNode, sel.focusOffset);
+		rngLeft.collapse(true);					rngRight.collapse(true);
+
+		var direct = rngLeft.compareBoundaryPoints(rngLeft.START_TO_END, rngRight) < 0;
+
+		var startNode = direct ? sel.anchorNode : sel.focusNode;
+		var startOffset = direct ? sel.anchorOffset : sel.focusOffset;
+		var endNode = direct ? sel.focusNode : sel.anchorNode;
+		var endOffset = direct ? sel.focusOffset : sel.anchorOffset;
+
+		// Find the parent blocks of nodes at either end, and their attributes if they're paragraphs
+		var startBlock = this.parentBlock(startNode);		var endBlock = this.parentBlock(endNode);
+		var attrsLeft = new Array();				var attrsRight = new Array();
+
+		// If a list, let the browser take over, if we're in a paragraph, gather it's attributes
+		if (this.isElem(startBlock, 'li') || this.isElem(endBlock, 'li'))
+			return;
+
+		if (this.isElem(startBlock, 'p')) {
+			for (var i = 0; i < startBlock.attributes.length; i++) {
+				attrsLeft[startBlock.attributes[i].nodeName] = startBlock.attributes[i].nodeValue;
+			}
+		}
+		if (this.isElem(endBlock, 'p')) {
+			for (var i = 0; i < endBlock.attributes.length; i++) {
+				// If we start and end within one paragraph, don't duplicate the 'id'
+				if (endBlock != startBlock || endBlock.attributes[i].nodeName.toLowerCase() != 'id')
+					attrsRight[endBlock.attributes[i].nodeName] = endBlock.attributes[i].nodeValue;
+			}
+		}
+
+		// Look for where to start and end our chopping - within surrounding paragraphs
+		// if they exist, or at the edges of the containing block, otherwise
+		var startChop = startNode;				var endChop = endNode;
+
+		while ((startChop.previousSibling && !this.isElem(startChop.previousSibling, 'p'))
+		       || (startChop.parentNode && startChop.parentNode != startBlock && startChop.parentNode.nodeType != 9))
+			startChop = startChop.previousSibling ? startChop.previousSibling : startChop.parentNode;
+
+		while ((endChop.nextSibling && !this.isElem(endChop.nextSibling, 'p'))
+		       || (endChop.parentNode && endChop.parentNode != endBlock && endChop.parentNode.nodeType != 9))
+			endChop = endChop.nextSibling ? endChop.nextSibling : endChop.parentNode;
+
+		// Set up new paragraphs
+		var pLeft = editor._doc.createElement('p');		var pRight = editor._doc.createElement('p');
+
+		for (var attrName in attrsLeft) {
+			var thisAttr = editor._doc.createAttribute(attrName);
+			thisAttr.value = attrsLeft[attrName];
+			pLeft.setAttributeNode(thisAttr);
+		}
+		for (var attrName in attrsRight) {
+			var thisAttr = editor._doc.createAttribute(attrName);
+			thisAttr.value = attrsRight[attrName];
+			pRight.setAttributeNode(thisAttr);
+		}
+
+		// Get the ranges destined to be stuffed into new paragraphs
+		rngLeft.setStartBefore(startChop);
+		rngLeft.setEnd(startNode,startOffset);
+		pLeft.appendChild(rngLeft.cloneContents());		// Copy into pLeft
+
+		rngRight.setEndAfter(endChop);
+		rngRight.setStart(endNode,endOffset);
+		pRight.appendChild(rngRight.cloneContents());		// Copy into pRight
+
+		// If either paragraph is empty, fill it with a nonbreakable space
+		var foundBlock = false;
+		foundBlock = this.walkNodeChildren(pLeft, this._isFilling);
+		if (foundBlock != true)
+			this.insertDeepLeftText(pLeft, '&nbsp;');
+
+		foundBlock = false;
+		foundBlock = this.walkNodeChildren(pRight, this._isFilling);
+		if (foundBlock != true)
+			this.insertDeepLeftText(pRight, '&nbsp;');
+
+		// Get a range for everything to be replaced and replace it
+		var rngAround = editor._doc.createRange();
+
+		if (!startChop.previousSibling && this.isElem(startChop.parentNode, 'p'))
+			rngAround.setStartBefore(startChop.parentNode);
+		else
+			rngAround.setStart(rngLeft.startContainer, rngLeft.startOffset);
+
+		if (!endChop.nextSibling && this.isElem(endChop.parentNode, 'p'))
+			rngAround.setEndAfter(endChop.parentNode);
+		else
+			rngAround.setEnd(rngRight.endContainer, rngRight.endOffset);
+
+		rngAround.deleteContents();
+		rngAround.insertNode(pRight);
+		rngAround.insertNode(pLeft);
+
+		// Set the selection to the start of the (second) new paragraph
+		if (pRight.firstChild) {
+			while (pRight.firstChild && this._html4_inlines_re.test(pRight.firstChild.nodeName))
+				pRight = pRight.firstChild;
+			// Slip into any inline tags
+			if (pRight.firstChild && pRight.firstChild.nodeType == 3)
+				pRight = pRight.firstChild;	// and text, if they've got it
+
+			var rngCaret = editor._doc.createRange();
+			rngCaret.setStart(pRight, 0);
+			rngCaret.collapse(true);
+
+			sel = editor._iframe.contentWindow.getSelection();
+			sel.removeAllRanges();
+			sel.addRange(rngCaret);
+		}
+
+		// Stop the bubbling
+		HTMLArea._stopEvent(ev);
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/tmp.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/tmp.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/tmp.php	(revision 795)
@@ -0,0 +1,39 @@
+<table border="0" cellspacing="0" 
+cellpadding="0">
+<?php
+//Liste des classes thérapeutiques
+$nomchamp = $_SESSION['activelangue'] . 
+"_dos";
+$sql = "select * from dossiers_dos 
+where idparent_dos = " . FOLDER_ROOT . " order by " . $nomchamp;
+$rs_dos = 
+$utilisateur->parent->phptoolbox->DataAccess->Execute($sql);
+//Il n'y a pas de classes thérapeutiques
+if ($rs_dos->EOF) { ?>
+	<tr>
+		<td class="sstitre"><?php print 
+		$_SESSION['INFOSCOMPTE']['CLASSESTH_EMPTY']; ?></td>
+		<td class="cell">&nbsp;</td>
+		<td>&nbsp;</td>
+		</tr>
+		<?php
+}
+else {
+	$tab_usr_dos = 
+		$utilisateur->gettabclassessouscrites($currentuser->id_usr);
+	//Affiche les classes thérapeutiques
+	while ($row_dos = $rs_dos->FetchRow()) { ?>
+		<tr>
+			<td class="sstitre"><?php print 
+			$row_dos[$nomchamp]; ?></td>
+			<td class="cell"><img 
+			src="images/spaceur.gif" width="15" height="1"></td>
+			<td><input name="coches_dos[]" 
+			type="checkbox" disabled="true" value="<?php print $row_dos['id_dos']; 
+			?>"<?php if (in_array($row_dos['id_dos'],$tab_usr_dos)) print ' 
+			checked'; ?>>
+			</td>
+			</tr>
+			<?php }
+} ?>
+</table>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/upload-image.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/upload-image.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/upload-image.js	(revision 795)
@@ -0,0 +1,262 @@
+// UploadImage Plugin for HTMLArea-3.0
+// Implementation by Mihai Bazon.  Sponsored by http://thycotic.com
+//
+// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc.
+// This notice MUST stay intact for use (see license.txt).
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon for InteractiveTools.
+//   http://dynarch.com/mishoo
+//
+
+function UploadImage(editor) {
+	this.editor = editor;
+
+	var cfg = editor.config;
+//	cfg.fullPage = true;
+	var tt = UploadImage.I18N;
+	var self = this;
+
+/*	cfg.registerButton("UploadImage", tt["Upload Image"], editor.imgURL("up_image.gif", "UploadImage"), false,
+	function(editor, id) {
+		self.buttonPress(editor, id);
+	});
+*/
+	cfg.registerButton("UploadImage", tt["Upload Image"], editor.imgURL("up_image.gif", "UploadImage"), false,
+			   function(editor, id) {
+				   self.buttonPress();
+			   });
+
+	// add a new line in the toolbar
+	cfg.toolbar[0].splice(29, 0, "separator");
+	cfg.toolbar[0].splice(30, 0, "UploadImage");
+};
+
+UploadImage._pluginInfo = {
+	name          : "UploadImage",
+	version       : "1.0",
+	developer     : "Pim Snel",
+	developer_url : "http://lingewoud.com",
+	c_owner       : "Mihai Bazon",
+	sponsor       : "Lingewoud b.v. - Netherlands",
+	sponsor_url   : "http://lingewoud.com",
+	license       : "GPL"
+};
+
+UploadImage.prototype.zzzbuttonPress = function(editor, id) 
+{
+	var self = this;
+	switch (id) 
+	{
+	    case "UploadImage":
+		var doc = editor._doc;
+		var links = doc.getElementsByTagName("link");
+		var style1 = '';
+		var style2 = '';
+		for (var i = links.length; --i >= 0;) 
+		{
+			var link = links[i];
+			if (/stylesheet/i.test(link.rel)) 
+			{
+				if (/alternate/i.test(link.rel))
+					style2 = link.href;
+				else
+					style1 = link.href;
+			}
+		}
+		var title = doc.getElementsByTagName("title")[0];
+		title = title ? title.innerHTML : '';
+
+		var init = 
+		{
+			f_doctype      : editor.doctype,
+			f_title        : title,
+			f_body_bgcolor : HTMLArea._colorToRgb(doc.body.style.backgroundColor),
+			f_body_fgcolor : HTMLArea._colorToRgb(doc.body.style.color),
+			f_base_style   : style1,
+			f_alt_style    : style2,
+
+			editor         : editor
+		};
+
+		Dialog(_editor_url+"plugins/UploadImage/popups/insert_image.php", function(image) 
+		{
+			self._insertImage(image);
+//			self.setDocProp(params);
+//			alert(params[1]);
+		}, init);
+
+/*		editor._popupDialog("plugin://UploadImage/insert_image.php", function(params) {
+				self.setDocProp(params);
+				}, init);*/
+	break;
+	}
+};
+
+
+
+// Called when the user clicks on "InsertImage" button.  If an image is already
+// there, it will just modify it's properties.
+UploadImage.prototype.buttonPress = function(image) {
+	
+	var doc = editor._doc;
+//	var editor = this;	// for nested functions
+	var outparam = null;
+
+	var init = 
+	{
+		f_doctype      : editor.doctype,
+		editor         : editor
+	};
+
+	if (typeof image == "undefined") {
+		image = editor.getParentElement();
+		if (image && !/^img$/i.test(image.tagName))
+			image = null;
+	}
+
+	if (image) outparam = {
+		f_url    : HTMLArea.is_ie ? editor.stripBaseURL(image.src) : image.getAttribute("src"),
+		f_alt    : image.alt,
+		f_border : image.border,
+		f_align  : image.align,
+		f_vert   : image.vspace,
+		f_horiz  : image.hspace
+	};
+
+
+	Dialog(_editor_url+"plugins/UploadImage/popups/insert_image.php", function(param){ 
+	if (!param) {	// user must have pressed Cancel
+	return false;
+	}
+		
+		var img = image;
+//		alert(param.f_url);
+		if (!img) {
+			var sel = editor._getSelection();
+			var range = editor._createRange(sel);
+			editor._doc.execCommand("insertimage", false, param.f_url);
+			
+			if (HTMLArea.is_ie) {
+				img = range.parentElement();
+				// wonder if this works...
+				if (img.tagName.toLowerCase() != "img") {
+					img = img.previousSibling;
+				}
+			} else {
+				img = range.startContainer.previousSibling;
+			}
+		} else {
+			img.src = param.f_url;
+		}
+		for (field in param) {
+			var value = param[field];
+			switch (field) {
+				case "f_alt"    : img.alt	 = value; break;
+				case "f_border" : img.border = parseInt(value || "0"); break;
+				case "f_align"  : img.align	 = value; break;
+				case "f_vert"   : img.vspace = parseInt(value || "0"); break;
+				case "f_horiz"  : img.hspace = parseInt(value || "0"); break;
+			}
+		}
+	}, outparam);
+};
+
+
+
+
+
+UploadImage.prototype.setDocProp = function(params) {
+	var txt = "";
+	var doc = this.editor._doc;
+	var head = doc.getElementsByTagName("head")[0];
+	var links = doc.getElementsByTagName("link");
+	var style1 = null;
+	var style2 = null;
+	for (var i = links.length; --i >= 0;) {
+		var link = links[i];
+		if (/stylesheet/i.test(link.rel)) {
+			if (/alternate/i.test(link.rel))
+				style2 = link;
+			else
+				style1 = link;
+		}
+	}
+	function createLink(alt) {
+		var link = doc.createElement("link");
+		link.rel = alt ? "alternate stylesheet" : "stylesheet";
+		head.appendChild(link);
+		return link;
+	};
+
+	if (!style1 && params.f_base_style)
+		style1 = createLink(false);
+	if (params.f_base_style)
+		style1.href = params.f_base_style;
+	else if (style1)
+		head.removeChild(style1);
+
+	if (!style2 && params.f_alt_style)
+		style2 = createLink(true);
+	if (params.f_alt_style)
+		style2.href = params.f_alt_style;
+	else if (style2)
+		head.removeChild(style2);
+
+
+	//cfg.registerButton("my-sample", "Class: sample", "ed_custom.gif", false,
+			function testinsert(arg1,arg2) {
+			if (HTMLArea.is_ie) {
+			editor.insertHTML("<img src=\"arg1\" alt=\"\" />");
+			var r = editor._doc.selection.createRange();
+			r.move("character", -2);
+			r.moveEnd("character", 2);
+			r.select();
+			} else { // Gecko/W3C compliant
+			var n = editor._doc.createElement("img");
+			n.className = "sample";
+			editor.insertNodeAtSelection(n);
+			var sel = editor._iframe.contentWindow.getSelection();
+			sel.removeAllRanges();
+			var r = editor._doc.createRange();
+			r.setStart(n, 0);
+			r.setEnd(n, 0);
+			sel.addRange(r);
+			}
+			}
+
+			testinsert(params[1]);
+
+			for (var i in params) {
+
+	
+
+//		alert(params[i]);
+		var val = params[i];
+		switch (i) {
+		    case "f_title":
+			var title = doc.getElementsByTagName("title")[0];
+			if (!title) {
+				title = doc.createElement("title");
+				head.appendChild(title);
+			} else while (node = title.lastChild)
+				title.removeChild(node);
+			if (!HTMLArea.is_ie)
+				title.appendChild(doc.createTextNode(val));
+			else
+				doc.title = val;
+			break;
+		    case "f_doctype":
+			this.editor.setDoctype(val);
+			break;
+		    case "f_body_bgcolor":
+			doc.body.style.backgroundColor = val;
+			break;
+		    case "f_body_fgcolor":
+			doc.body.style.color = val;
+			break;
+		}
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/nl.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/nl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/nl.js	(revision 795)
@@ -0,0 +1,25 @@
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+UploadImage.I18N = {
+	"Alternate style-sheet:":		"Alternatieve style-sheet:",
+	"Background color:":			"Achtergrondkleur:",
+	"Cancel":				"Annuleren",
+	"DOCTYPE:":				"DOCTYPE:",
+	"Document properties":			"Documenteigenschappen ",
+	"Document title:":			"Documenttitel:",
+	"OK":					"Oké",
+	"Primary style-sheet:":			"Primaire style-sheet:",
+	"Text color:":				"Tekstkleur:"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/lang.php	(revision 795)
@@ -0,0 +1,54 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-SpellChecker');
+
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+UploadImage.I18N = {
+	"Alternate style-sheet:":		"<?php echo lang('Alternate style-sheet:'); ?>",
+	"Background color:":			"<?php echo lang('Background color:'); ?>",
+	"Cancel":				"<?php echo lang('Cancel'); ?>",
+	"DOCTYPE:":				"<?php echo lang('DOCTYPE:'); ?>",
+	"Document properties":			"<?php echo lang('Document properties'); ?>",
+	"Document title:":			"<?php echo lang('Document title:'); ?>",
+	"OK":					"<?php echo lang('OK'); ?>",
+	"Primary style-sheet:":			"<?php echo lang('Primary style-sheet:'); ?>",
+	"Text color:":				"<?php echo lang('Text color:'); ?>",
+	"Upload Image":				"<?php echo lang('Upload Image'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/lang/en.js	(revision 795)
@@ -0,0 +1,26 @@
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+UploadImage.I18N = {
+	"Alternate style-sheet:":		"Alternate style-sheet:",
+	"Background color:":			"Background color:",
+	"Cancel":				"Cancel",
+	"DOCTYPE:":				"DOCTYPE:",
+	"Document properties":			"Document properties",
+	"Document title:":			"Document title:",
+	"OK":					"OK",
+	"Primary style-sheet:":			"Primary style-sheet:",
+	"Text color:":				"Text color:",
+	"Upload Image":				"Upload Image"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/ImageEditor.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/ImageEditor.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/ImageEditor.php	(revision 795)
@@ -0,0 +1,354 @@
+<?
+/***********************************************************************
+** Title.........:  Online Image Editor
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  ImageEditor.php
+** Last changed..:  31 Aug 2003  
+** Notes.........:  Configuration in config.inc.php 
+**/ 
+    $image = '';
+
+    if(isset($_GET['img']))
+    {
+        $image = $_GET['img'];
+        $path_info = pathinfo(urldecode($image));
+    }
+?>
+<html style="width:700px; height:550;">
+<HEAD>
+<TITLE> Editing: <? echo $path_info['basename']; ?></TITLE>
+<script type="text/javascript" src="../popup.js"></script>
+<script type="text/javascript" src="../../dialog.js"></script>
+<link href="ImageEditor.css" rel="stylesheet" type="text/css">
+<script language="JavaScript" type="text/JavaScript">
+<!--
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+
+function pviiClassNew(obj, new_style) { //v2.6 by PVII
+  obj.className=new_style;
+}
+
+function toggleMarker() 
+{
+    //alert("Toggle");
+    var marker = MM_findObj("markerImg");
+    
+    //alert(marker.src);
+    if(marker != null && marker.src != null) {
+        //alert(marker.src);
+        if(marker.src.indexOf("t_black.gif")>0) {
+            marker.src = "t_white.gif";
+        }
+        else
+            marker.src = "t_black.gif";
+        //alert(marker.src);
+        editor.toggleMarker();
+    }
+}
+
+function updateMarker(mode) 
+{
+    if (mode == 'crop')
+    {
+        var t_cx = MM_findObj('cx');
+        var t_cy = MM_findObj('cy');
+        var t_cw = MM_findObj('cw');
+        var t_ch = MM_findObj('ch');
+
+        editor.setMarker(parseInt(t_cx.value), parseInt(t_cy.value), parseInt(t_cw.value), parseInt(t_ch.value));
+    }
+    else if(mode == 'scale') {
+        var s_sw = MM_findObj('sw');
+        var s_sh = MM_findObj('sh');
+        editor.setMarker(0, 0, parseInt(s_sw.value), parseInt(s_sh.value));
+    }
+}
+
+
+var current_action = null;
+var actions = ['crop', 'scale', 'rotate', 'measure', 'save'];
+function toggle(action) 
+{
+    if(action != current_action) {
+        var toolbar = MM_findObj('bar_'+action);
+        var icon = MM_findObj('icon_'+action);
+        var btn = MM_findObj('btn_'+action);
+        btn.className='iconsSel';
+        current_action = action;
+        toolbar.style.display = "block";
+        icon.style.display = "block";
+        
+        for (var i in actions)
+        {
+            if(current_action != actions[i]) {
+                var tool = MM_findObj('bar_'+actions[i]);
+                tool.style.display = "none";
+                var icon = MM_findObj('icon_'+actions[i]);
+                icon.style.display = "none";
+                var btn =  MM_findObj('btn_'+actions[i]);
+                btn.className = 'icons';
+            }
+        }
+
+        editor.setMode(current_action);
+    }
+    //alert(action);
+}
+
+function changeClass(obj,action) 
+{
+    if(action == current_action) {
+        obj.className = 'iconsSel';
+    }
+    else
+    {
+        obj.className = 'icons';
+    }
+}
+
+function rotatePreset(selection) 
+{
+    var value = selection.options[selection.selectedIndex].value;
+    
+    if(value.length > 0 && parseInt(value) != 0) {
+        var ra = MM_findObj('ra');
+        ra.value = parseInt(value);
+    }
+}
+
+function updateFormat(selection) 
+{
+    var selected = selection.options[selection.selectedIndex].value;
+
+    var values = selected.split(",");
+    //alert(values.length);
+    if(values.length >1) {
+        updateSlider(parseInt(values[1]));
+    }
+
+}
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+function onOK() 
+{
+  __dlg_close(null);
+  return false;
+}
+function Init() {
+  __dlg_init();
+}
+    
+//-->
+</script>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY onLoad="Init();" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
+<table width="100%" height="100%" cellspacing="1" >
+    <tr bgcolor="#EEEEFF" height="40">
+    <td class="topBar" width="60" ><table width="100%" border="0" cellspacing="8" cellpadding="2">
+        <tr> 
+          <td class="icons">
+          <div id="icon_crop" style="display:none">
+            <img src="crop.gif" alt="Crop" width="20" height="20" border="0">
+          </div>
+          <div id="icon_scale" style="display:none">
+            <img src="scale.gif" alt="Resize" width="20" height="20" border="0">
+          </div>
+          <div id="icon_rotate" style="display:none">
+            <img src="rotate.gif" alt="Rotate" width="20" height="20" border="0">
+          </div>
+          <div id="icon_measure" style="display:none">
+            <img src="ruler.gif" alt="Measure" width="20" height="20" border="0">
+          </div>
+          <div id="icon_save" style="display:none">
+            <img src="save.gif" alt="Save" width="20" height="20" border="0">
+          </div>
+          </td>
+        </tr>
+      </table></td>
+      
+    <td>
+<!-- crop -->
+<div id="bar_crop" style="display:none">
+    <table border="0" cellspacing="5" cellpadding="2">
+        <tr> 
+          <td class="topBar">Start X: 
+            <INPUT TYPE="text" id="cx" style="width:3em" NAME="cx" onChange="updateMarker('crop')">
+            Start Y: 
+            <INPUT TYPE="text" id="cy" style="width:3em" NAME="cy" onChange="updateMarker('crop')">
+            Width: 
+            <INPUT TYPE="text" id="cw" style="width:3em" NAME="cw" onChange="updateMarker('crop')">
+            Height: 
+            <INPUT TYPE="text"  id="ch" style="width:3em" NAME="ch" onChange="updateMarker('crop')"> </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" width="30" alt="Cancel" height="30" border="0"></a></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('crop');"><img src="btn_ok.gif" alt="Apply" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table> 
+</div>
+<!-- //crop -->
+<!-- measure -->
+<div id="bar_measure" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr> 
+          <td class="topBar">X: 
+            <span id="sx" class="measureStats"></span>
+            Y: 
+            <span id="sy" class="measureStats"></span></td>
+          <td class="topBar"><img src="div.gif" width="2" height="30"></td>
+          <td class="topBar"> W: 
+            <span id="mw" class="measureStats"></span>
+            H: 
+            <span id="mh" class="measureStats"></span>
+          </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="topBar">A: 
+            <span id="ma" class="measureStats"></span>
+            D: <span id="md" class="measureStats"></span>
+          </td>
+          <td class="icons"><img src="div.gif" width="2" height="30"></td>
+          <td class="icons"><input type="button" name="Button" value="Clear" onClick="editor.reset()"></td>
+        </tr>
+      </table> 
+</div>
+<!-- //measure -->
+<!-- scale -->
+<div id="bar_scale" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr> 
+          <td class="topBar">Width: 
+            <input type="text" id="sw" style="width:3em" name="sw" onChange="updateMarker('scale')"> 
+          </td>
+          <td class="topBar"><img src="locked.gif" width="8" height="14"></td>
+          <td class="topBar"> Height: 
+            <INPUT TYPE="text"  id="sh" style="width:3em" NAME="sh" onChange="updateMarker('scale')"> 
+          </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" alt="Cancel" width="30" height="30" border="0"></a></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('scale');"><img src="btn_ok.gif" alt="Apply" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table>
+</div>
+<!-- //scale -->
+<!-- rotate -->
+<div id="bar_rotate" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr>
+          <td width="115" class="topBar"><select id="flip" name="flip">
+              <option selected>Flip Image</option>
+              <option>-----------------</option>
+              <option value="hoz">Flip Horizontal</option>
+              <option value="ver">Flip Virtical</option>
+            </select></td>
+          <td width="115" class="topBar"><select name="rotate" onChange="rotatePreset(this)">
+              <option selected>Rotate Image</option>
+              <option>-----------------</option>
+              <option value="180">Rotate 180 &deg;</option>
+              <option value="90">Rotate 90 &deg; CW</option>
+              <option value="-90">Rotate 90 &deg; CCW</option>
+            </select></td>
+          <td width="87" class="topBar"> Angle: 
+            <INPUT TYPE="text"  id="ra" style="width:3em" NAME="ra" onChange="updateMarker('rotate')"> 
+          </td>
+          <td width="2"><img src="div.gif" width="2" height="30"></td>
+          <td width="32" class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" alt="Cancel" width="30" height="30" border="0"></a></td>
+          <td width="32" class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('rotate');"><img src="btn_ok.gif" alt="Apply" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table>
+</div>
+<!-- //rotate -->
+<!-- save -->
+<div id="bar_save" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr>
+          <td class="topBar">Filename: 
+            <input type="filename" id="save_filename" value="<? echo $path_info['basename']; ?>" name="textfield"></td>
+          <td class="topBar"> <select name="format" id="save_format" onChange="updateFormat(this)">
+              <option value="" selected>Image Format</option>
+              <option value="">---------------------</option>
+              <option value="jpeg,85">JPEG High</option>
+              <option value="jpeg,60">JPEG Medium</option>
+              <option value="jpeg,35">JPEG Low</option>
+              <option value="png">PNG</option>
+              <option value="gif">GIF</option>
+            </select></td>
+          <td class="topBar">Quality: 
+          </td>
+          <td width="120">
+    <div id="slidercasing"> 
+<div id="slidertrack" style="width:100px"><IMG SRC="spacer.gif" WIDTH="1" HEIGHT="1" BORDER="0" ALT="track"></div>
+                <div id="sliderbar" style="left:50px" onmousedown="captureStart()"><IMG SRC="spacer.gif" WIDTH="1" HEIGHT="1" BORDER="0" ALT="track"></div></div>
+          </td>
+          <td class="topBar"> 
+<INPUT TYPE="text" id="quality" NAME="quality" onChange="updateSlider(this.value)" style="width:2em">
+<script type="text/javascript" src="jscripts/slider.js"></script>
+<script language="JavaScript1.2">
+<!--
+
+updateSlider(85);
+
+//-->
+</script>
+
+
+          </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" alt="Cancel" width="30" height="30" border="0"></a></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('save');"><img src="btn_ok.gif" alt="Apply" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table>
+</div>
+<!--//save -->
+      </td>
+    </tr>
+    <tr>
+        
+    <td bgcolor="#EEEEFF" width="60" valign="top" align="center" nowrap><table width="100%" border="0" cellspacing="8" cellpadding="2">
+        <tr> 
+          <td class="icons" id='btn_crop' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'crop')"><a href="#" class="iconText" onClick="javascript:toggle('crop')"><img src="crop.gif" alt="Crop" width="20" height="20" border="0"><br>
+            Crop</a> </td>
+        </tr>
+        <tr> 
+          <td class="icons" id='btn_scale' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'scale')"><a href="#" class="iconText" onClick="javascript:toggle('scale')"><img src="scale.gif" alt="Resize" width="20" height="20" border="0"><br>
+            Resize</a> </td>
+        </tr>
+        <tr> 
+          <td class="icons" id='btn_rotate' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'rotate')"><a href="#" class="iconText"  onClick="javascript:toggle('rotate')"><img src="rotate.gif" alt="Rotate" width="20" height="20" border="0"><br>
+            Rotate</a> </td>
+        </tr>
+        <tr> 
+          <td class="icons" id='btn_measure' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'measure')"><a href="#" class="iconText"  onClick="javascript:toggle('measure')"><img src="ruler.gif" alt="Measure" width="20" height="20" border="0"><br>
+            Measure</a></td>
+        </tr>
+        <tr> 
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a class="iconText" href="#" onClick="toggleMarker();"><img src="t_black.gif" name="markerImg" id="markerImg" alt="Marker" width="20" height="20" border="0"><br>
+            Marker</a></td>
+        </tr>
+        <tr>
+          <td class="icons" id='btn_save' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'save')"><a href="#" class="iconText"  onClick="javascript:toggle('save')"><img src="save.gif" alt="Save" width="20" height="20" border="0"><br>
+            Save</a> </td>
+        </tr>
+      </table>
+    </td>
+        <td width="99%" >
+        <iframe width="100%" height="100%" id="editor" name="editor" src="load_image.php?img=<? echo $image; ?>" marginwidth="0" marginheight="0" align="top" scrolling="auto" frameborder="0" hspace="0" vspace="0" background="gray">
+        </iframe>
+        </td>
+    </tr>
+</table>
+</BODY>
+</HTML>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/man_image.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/man_image.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/man_image.html	(revision 795)
@@ -0,0 +1,131 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+<script type="text/javascript" src="jscripts/wz_jsgraphics.js"></script>
+<script type="text/javascript" src="jscripts/EditorContent.js"></script>
+<style>
+<!--
+.crop{cursor:crosshair;}
+.selection{
+    border: dotted 1px #000000;
+    position:absolute;
+    width: 0px;
+    height: 1px;
+    z-index:5;
+}
+.selectionWhite{
+    border: dotted 1px #FFFFFF;
+    position:absolute;
+    width: 0px;
+    height: 1px;
+    z-index:5;
+}
+.handleBox{
+    z-index:105;
+}
+
+-->
+</style>
+<script type="text/javascript">
+
+var t_cx = MM_findObj('cx', window.top.document);
+var t_cy = MM_findObj('cy', window.top.document);
+var t_cw = MM_findObj('cw', window.top.document);
+var t_ch = MM_findObj('ch', window.top.document);
+
+var m_sx = MM_findObj('sx', window.top.document);
+var m_sy = MM_findObj('sy', window.top.document);
+var m_w = MM_findObj('mw', window.top.document);
+var m_h = MM_findObj('mh', window.top.document);
+var m_a = MM_findObj('ma', window.top.document);
+var m_d = MM_findObj('md', window.top.document);
+
+var s_sw = MM_findObj('sw', window.top.document);
+var s_sh = MM_findObj('sh', window.top.document);
+
+var r_ra = MM_findObj('ra', window.top.document);
+
+var mode = "<? echo $action; ?>" //crop, scale, measure
+var pattern = "2x2.gif";
+
+function doSubmit(action)
+{
+    var image = escape("<? echo $path.$image; ?>");
+
+    if (action == 'crop')
+    {
+
+        var url = "load_image.php?img="+image+"&action=crop&params="+parseInt(t_cx.value)+','+parseInt(t_cy.value)+','+ parseInt(t_cw.value)+','+parseInt(t_ch.value);
+
+        //alert(url);
+        location.href = url;
+
+        //location.reload();
+    }   
+    else if (action == 'scale')
+    {
+        var url = "load_image.php?img="+image+"&action=scale&params="+parseInt(s_sw.value)+','+parseInt(s_sh.value);
+        //alert(url);
+        location.href = url;
+        
+    }
+    else if (action == 'rotate')
+    {
+        var flip = MM_findObj('flip', window.top.document);
+
+        if(flip.value == 'hoz' || flip.value == 'ver') 
+            location.href = "load_image.php?img="+image+"&action=flip&params="+flip.value;
+        else if (isNaN(parseFloat(r_ra.value))==false)
+            location.href = "load_image.php?img="+image+"&action=rotate&params="+parseFloat(r_ra.value);
+    }
+    else if(action == 'save') {
+        var s_file = MM_findObj('save_filename', window.top.document);
+        var s_format = MM_findObj('save_format', window.top.document);
+        var s_quality = MM_findObj('quality',window.top.document);
+
+        var format = s_format.value.split(",");
+        if(s_file.value.length <= 0) {
+            alert('Please enter a filename to save.');
+        }
+        else
+        {
+            var filename = escape(s_file.value);
+            var quality = parseInt(s_quality.value);
+            var url = "load_image.php?img="+image+"&action=save&params="+format[0]+","+quality+"&file="+filename;
+            //alert(url);
+            location.href = url;
+        }
+    }
+}
+
+
+</script>
+</HEAD>
+
+<BODY bgcolor="#CCCCCC" onLoad="init();">
+<div id="status"></div>
+<div id="ant" class="selection" style="visibility:hidden"><IMG SRC="spacer.gif" WIDTH="0" HEIGHT="0" BORDER="0" ALT="" id="cropContent"></div>
+<table cellpadding="0" cellspacing="0" width="100%" height="100%">
+ <Tr height="100%">
+   <Td align="center" height="100%">
+   <span id="imgCanvas" class="crop"><IMG SRC="<? echo $path.$image; ?>" <? echo $dimensions; ?> BORDER=0 ALT="" id="theImage" name="theImage"></span>
+   </td>
+ </tr>
+</table>
+<script type="text/javascript">
+<!--
+
+var jg_doc = new jsGraphics("imgCanvas"); // draw directly into document
+jg_doc.setColor("#000000"); // black
+
+<?
+    if(isset($save_file) && is_file($BASE_DIR.$path.$save_file)) {
+        echo "alert('$save_file saved')";
+    }
+
+?>
+
+//-->
+</script>
+</BODY>
+</HTML>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/GD.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/GD.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/GD.php	(revision 795)
@@ -0,0 +1,488 @@
+<?php
+/***********************************************************************
+** Title.........:  GD Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  GD.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// |          Alan Knowles <alan@akbkhome.com>                            |
+// +----------------------------------------------------------------------+
+//
+//    Usage :
+//    $img    = new Image_Transform_GD();
+//    $angle  = -78;
+//    $img->load('magick.png');
+//
+//    if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
+//        $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
+//        $img->display();
+//    } else {
+//        echo "Error";
+//    }
+//
+//
+//
+// Image Transformation interface using the GD library
+//
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_GD extends Image_Transform
+{
+    /**
+     * Holds the image file for manipulation
+     */
+    var $imageHandle = '';
+
+    /**
+     * Holds the original image file
+     */
+    var $old_image = '';
+
+    /**
+     * Check settings
+     *
+     * @return mixed true or  or a PEAR error object on error
+     *
+     * @see PEAR::isError()
+     */
+    function Image_Transform_GD()
+    {
+        return;
+    } // End function Image
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+		$this->image = $image;
+        $this->_get_image_details($image);
+        $functionName = 'ImageCreateFrom' . $this->type;
+        $this->imageHandle = $functionName($this->image);
+    } // End load
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => array(255,0,0),
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false // Carry out the scaling of the image before annotation?  Not used for GD
+                                );
+        $params = array_merge($default_params, $params);
+        extract($params);
+
+        if( !is_array($color) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color );
+            } else {
+                include_once('Image/Transform/Driver/ColorsDefs.php');
+                $color = isset($colornames[$color])?$colornames[$color]:false;
+            }
+        }
+
+        $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]);
+
+        if ('ttf' == substr($font, -3)) {
+            ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        } else {
+            ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        }
+        return true;
+    } // End addText
+
+
+    /**
+     * Rotate image by the given angle
+     * Uses a fast rotation algorythm for custom angles
+     * or lines copy for multiple of 90 degrees
+     *
+     * @param int       $angle      Rotation angle
+     * @param array     $options    array(  'autoresize'=>true|false,
+     *                                      'color_mask'=>array(r,g,b), named color or #rrggbb
+     *                                   )
+     * @author Pierre-Alain Joye
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function rotate($angle, $options=null)
+    {
+        if(function_exists('imagerotate')) {
+            $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
+			$this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
+            return true;
+        }
+
+        if ( $options==null ){
+            $autoresize = true;
+            $color_mask = array(255,255,0);
+        } else {
+            extract( $options );
+        }
+
+        while ($angle <= -45) {
+            $angle  += 360;
+        }
+        while ($angle > 270) {
+            $angle  -= 360;
+        }
+
+        $t      = deg2rad($angle);
+
+        if( !is_array($color_mask) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color_mask );
+            } else {
+                include_once('Image/Transform/Driver/ColorDefs.php');
+                $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
+            }
+        }
+
+        // Do not round it, too much lost of quality
+        $cosT   = cos($t);
+        $sinT   = sin($t);
+
+        $img    =& $this->imageHandle;
+
+        $width  = $max_x  = $this->img_x;
+        $height = $max_y  = $this->img_y;
+        $min_y  = 0;
+        $min_x  = 0;
+
+        $x1     = round($max_x/2,0);
+        $y1     = round($max_y/2,0);
+
+        if ( $autoresize ){
+            $t      = abs($t);
+            $a      = round($angle,0);
+            switch((int)($angle)){
+                case 0:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 90:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                case 180:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 270:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                default:
+                    $width2     = (int)(abs(sin($t) * $height + cos($t) * $width));
+                    $height2    = (int)(abs(cos($t) * $height+sin($t) * $width));
+            }
+
+            $width2     -= $width2%2;
+            $height2    -= $height2%2;
+
+            $d_width    = abs($width - $width2);
+            $d_height   = abs($height - $height2);
+            $x_offset   = $d_width/2;
+            $y_offset   = $d_height/2;
+            $min_x2     = -abs($x_offset);
+            $min_y2     = -abs($y_offset);
+            $max_x2     = $width2;
+            $max_y2     = $height2;
+        }
+
+        $img2   = @imagecreate($width2,$height2);
+
+        if ( !is_resource($img2) ){
+            return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
+                                null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+
+        $this->img_x = $width2;
+        $this->img_y = $height2;
+
+
+        imagepalettecopy($img2,$img);
+
+        $mask   = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
+
+        // use simple lines copy for axes angles
+        switch((int)($angle)){
+            case 0:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+                    }
+                }
+                break;
+            case 90:
+                imagefill ($img2, 0, 0,$mask);
+                for ($x = $min_x; $x < $max_x; $x++){
+                    for ($y=$min_y; $y < $max_y; $y++) {
+                        $c  = imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$max_y-$y-1,$x,$c);
+                    }
+                }
+                break;
+            case 180:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
+                    }
+                }
+                break;
+            case 270:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $max_x; $x >= $min_x; $x--){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$y,$max_x-$x-1,$c);
+                    }
+                }
+                break;
+            // simple reverse rotation algo
+            default:
+                $i=0;
+                for ($y = $min_y2; $y < $max_y2; $y++){
+
+                    // Algebra :)
+                    $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
+                    $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);
+
+                    for ($x = $min_x2; $x < $max_x2; $x++){
+
+                        // Check if we are out of original bounces, if we are
+                        // use the default color mask
+                        if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
+                            $c  = imagecolorat ( $img, $x2, $y2);
+                        } else {
+                            $c  = $mask;
+                        }
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+
+                        // round verboten!
+                        $x2  += $cosT;
+                        $y2  -= $sinT;
+                    }
+                }
+                break;
+        }
+        $this->old_image    = $this->imageHandle;
+        $this->imageHandle  =  $img2;
+        return true;
+    }
+
+
+   /**
+    * Resize Action
+    *
+    * For GD 2.01+ the new copyresampled function is used
+    * It uses a bicubic interpolation algorithm to get far
+    * better result.
+    *
+    * @param $new_x int  new width
+    * @param $new_y int  new height
+    *
+    * @return true on success or pear error
+    * @see PEAR::isError()
+    */
+    function _resize($new_x, $new_y) {
+        if ($this->resized === true) {
+            return false; /*PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_x,$new_y);
+        } else {
+            $new_img =ImageCreate($new_x,$new_y);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($new_x, $new_y, $new_width, $new_height) 
+    {
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_width,$new_height);
+        } else {
+            $new_img =ImageCreate($new_width,$new_height);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+   
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal)
+    {
+        if(!$horizontal) {
+            $this->rotate(180);
+        }
+
+        $width = imagesx($this->imageHandle); 
+        $height = imagesy($this->imageHandle); 
+
+        for ($j = 0; $j < $height; $j++) { 
+                $left = 0; 
+                $right = $width-1; 
+
+
+                while ($left < $right) { 
+                    //echo " j:".$j." l:".$left." r:".$right."\n<br>";
+                    $t = imagecolorat($this->imageHandle, $left, $j); 
+                    imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j)); 
+                    imagesetpixel($this->imageHandle, $right, $j, $t); 
+                    $left++; $right--; 
+                } 
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param $filename string  the name of the file to write to
+     * @param $quality  int     output DPI, default is 85
+     * @param $types    string  define the output format, default
+     *                          is the current used format
+     *
+     * @return none
+     */
+    function save($filename, $type = '', $quality = 85)
+    {
+        $type           = $type==''? $this->type : $type;
+        $functionName   = 'image' . $type;
+        $this->old_image = $this->imageHandle;
+        $functionName($this->imageHandle, $filename) ;
+        $this->imageHandle = $this->old_image;
+        $this->resized = false;
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type != '') {
+            $this->type = $type;
+        }
+        $functionName = 'Image' . $this->type;
+        header('Content-type: image/' . strtolower($this->type));
+        $functionName($this->imageHandle, '', $quality);
+        $this->imageHandle = $this->old_image;
+        $this->resized = false;
+        ImageDestroy($this->old_image);
+        $this->free();
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        if ($this->imageHandle){
+            ImageDestroy($this->imageHandle);
+        }
+    }
+
+} // End class ImageGD
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/ImageEditor.css
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/ImageEditor.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/ImageEditor.css	(revision 795)
@@ -0,0 +1,76 @@
+.icons {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    border: 1px solid #EEEEFF;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+
+body, td, p {
+    font: 11px Tahoma,Verdana,sans-serif;
+}
+.iconsOver {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    background-color: #F9F9FF;
+    border: 1px solid #666699;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.topBar {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+}
+.iconsSel {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    border: 1px solid #666699;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.iconText {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-decoration: none;
+    text-align: center;
+}
+.measureStats{
+    width: 50px;
+}
+
+#slidercasing {
+    /*border:1px solid #CCCCCC;
+    background-color:#FFFFFF;*/
+    width:100px;
+    height:5px;
+    position:relative;
+    z-index:4;
+    padding:10px;
+}
+
+
+#slidertrack {
+    position:relative;
+    border:1px solid #CCCCCC;
+    background-color:#FFFFCC;
+    z-index:5;
+    height:5px;
+}
+
+
+#sliderbar {
+    position:absolute;
+    z-index:6;
+    border:1px solid #CCCCCC;
+    background-color:#DDDDDD;
+    width:15px;     
+    padding:0px;
+    height:20px; 
+    cursor: pointer;
+    top:2px;
+}
+
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/test.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/test.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/test.html	(revision 795)
@@ -0,0 +1,332 @@
+<html style="width:580px; height:550;">
+<HEAD>
+<TITLE> New Document </TITLE>
+<META NAME="Generator" CONTENT="EditPlus">
+<META NAME="Author" CONTENT="">
+<META NAME="Keywords" CONTENT="">
+<META NAME="Description" CONTENT="">
+<link href="ImageEditor.css" rel="stylesheet" type="text/css">
+<script language="JavaScript" type="text/JavaScript">
+<!--
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+
+function pviiClassNew(obj, new_style) { //v2.6 by PVII
+  obj.className=new_style;
+}
+
+function toggleMarker() 
+{
+	//alert("Toggle");
+	var marker = MM_findObj("markerImg");
+	
+	//alert(marker.src);
+	if(marker != null && marker.src != null) {
+		//alert(marker.src);
+		if(marker.src.indexOf("t_black.gif")>0) {
+			marker.src = "t_white.gif";
+		}
+		else
+			marker.src = "t_black.gif";
+		//alert(marker.src);
+		editor.toggleMarker();
+	}
+}
+
+function updateMarker(mode) 
+{
+	if (mode == 'crop')
+	{
+		var t_cx = MM_findObj('cx');
+		var t_cy = MM_findObj('cy');
+		var t_cw = MM_findObj('cw');
+		var t_ch = MM_findObj('ch');
+
+		editor.setMarker(parseInt(t_cx.value), parseInt(t_cy.value), parseInt(t_cw.value), parseInt(t_ch.value));
+	}
+	else if(mode == 'scale') {
+		var s_sw = MM_findObj('sw');
+		var s_sh = MM_findObj('sh');
+		editor.setMarker(0, 0, parseInt(s_sw.value), parseInt(s_sh.value));
+	}
+}
+
+
+var current_action = null;
+var actions = ['crop', 'scale', 'rotate', 'measure', 'save'];
+function toggle(action) 
+{
+	if(action != current_action) {
+		var toolbar = MM_findObj('bar_'+action);
+		var icon = MM_findObj('icon_'+action);
+		var btn = MM_findObj('btn_'+action);
+		btn.className='iconsSel';
+		current_action = action;
+		toolbar.style.display = "block";
+		icon.style.display = "block";
+		
+		for (var i in actions)
+		{
+			if(current_action != actions[i]) {
+				var tool = MM_findObj('bar_'+actions[i]);
+				tool.style.display = "none";
+				var icon = MM_findObj('icon_'+actions[i]);
+				icon.style.display = "none";
+				var btn =  MM_findObj('btn_'+actions[i]);
+				btn.className = 'icons';
+			}
+		}
+
+		editor.setMode(current_action);
+	}
+	//alert(action);
+}
+
+function changeClass(obj,action) 
+{
+	if(action == current_action) {
+		obj.className = 'iconsSel';
+	}
+	else
+	{
+		obj.className = 'icons';
+	}
+}
+
+function rotatePreset(selection) 
+{
+	var value = selection.options[selection.selectedIndex].value;
+	
+	if(value.length > 0 && parseInt(value) != 0) {
+		var ra = MM_findObj('ra');
+		ra.value = parseInt(value);
+	}
+}
+
+function updateFormat(selection) 
+{
+	var selected = selection.options[selection.selectedIndex].value;
+
+	var values = selected.split(",");
+	//alert(values.length);
+	if(values.length >1) {
+		updateSlider(parseInt(values[1]));
+	}
+
+}
+
+var editImage = '';
+
+if(location.href.indexOf('?')>0) {
+	var parameters = location.href.split('?');
+		editImage = parameters[1];
+}
+	
+//-->
+</script>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
+<table width="100%" height="100%" cellspacing="1" >
+	<tr bgcolor="#EEEEFF" height="40">
+	<td class="topBar" width="60" ><table width="100%" border="0" cellspacing="8" cellpadding="2">
+        <tr> 
+          <td class="icons">
+		  <div id="icon_crop" style="display:none">
+			<img src="crop.gif" width="20" height="20" border="0">
+		  </div>
+		  <div id="icon_scale" style="display:none">
+			<img src="scale.gif" width="20" height="20" border="0">
+		  </div>
+		  <div id="icon_rotate" style="display:none">
+			<img src="rotate.gif" width="20" height="20" border="0">
+		  </div>
+		  <div id="icon_measure" style="display:none">
+			<img src="ruler.gif" width="20" height="20" border="0">
+		  </div>
+		  <div id="icon_save" style="display:none">
+			<img src="save.gif" width="20" height="20" border="0">
+		  </div>
+		  </td>
+        </tr>
+      </table></td>
+	  
+    <td>
+<!-- crop -->
+<div id="bar_crop" style="display:none">
+	<table border="0" cellspacing="5" cellpadding="2">
+        <tr> 
+          <td class="topBar">Start X: 
+            <INPUT TYPE="text" id="cx" style="width:3em" NAME="cx" onChange="updateMarker('crop')">
+            Start Y: 
+            <INPUT TYPE="text" id="cy" style="width:3em" NAME="cy" onChange="updateMarker('crop')">
+            Width: 
+            <INPUT TYPE="text" id="cw" style="width:3em" NAME="cw" onChange="updateMarker('crop')">
+            Height: 
+            <INPUT TYPE="text"  id="ch" style="width:3em" NAME="ch" onChange="updateMarker('crop')"> </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" width="30" height="30" border="0"></a></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('crop');"><img src="btn_ok.gif" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table> 
+</div>
+<!-- //crop -->
+<!-- measure -->
+<div id="bar_measure" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr> 
+          <td class="topBar">X: 
+            <span id="sx" class="measureStats"></span>
+            Y: 
+            <span id="sy" class="measureStats"></span></td>
+          <td class="topBar"><img src="div.gif" width="2" height="30"></td>
+          <td class="topBar"> W: 
+            <span id="mw" class="measureStats"></span>
+            H: 
+            <span id="mh" class="measureStats"></span>
+          </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="topBar">A: 
+            <span id="ma" class="measureStats"></span>
+            D: <span id="md" class="measureStats"></span>
+          </td>
+          <td class="icons"><img src="div.gif" width="2" height="30"></td>
+          <td class="icons"><input type="button" name="Button" value="Clear" onClick="editor.reset()"></td>
+        </tr>
+      </table> 
+</div>
+<!-- //measure -->
+<!-- scale -->
+<div id="bar_scale" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr> 
+          <td class="topBar">Width: 
+            <input type="text" id="sw" style="width:3em" name="sw" onChange="updateMarker('scale')"> 
+          </td>
+          <td class="topBar"><img src="locked.gif" width="8" height="14"></td>
+          <td class="topBar"> Height: 
+            <INPUT TYPE="text"  id="sh" style="width:3em" NAME="sh" onChange="updateMarker('scale')"> 
+          </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" width="30" height="30" border="0"></a></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('scale');"><img src="btn_ok.gif" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table>
+</div>
+<!-- //scale -->
+<!-- rotate -->
+<div id="bar_rotate" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr>
+          <td width="115" class="topBar"><select id="flip" name="flip">
+              <option selected>Flip Image</option>
+              <option>-----------------</option>
+              <option value="hoz">Flip Horizontal</option>
+              <option value="ver">Flip Virtical</option>
+            </select></td>
+          <td width="115" class="topBar"><select name="rotate" onChange="rotatePreset(this)">
+              <option selected>Rotate Image</option>
+              <option>-----------------</option>
+              <option value="180">Rotate 180 &deg;</option>
+              <option value="90">Rotate 90 &deg; CW</option>
+              <option value="-90">Rotate 90 &deg; CCW</option>
+            </select></td>
+          <td width="87" class="topBar"> Angle: 
+            <INPUT TYPE="text"  id="ra" style="width:3em" NAME="ra" onChange="updateMarker('rotate')"> 
+          </td>
+          <td width="2"><img src="div.gif" width="2" height="30"></td>
+          <td width="32" class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" width="30" height="30" border="0"></a></td>
+          <td width="32" class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('rotate');"><img src="btn_ok.gif" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table>
+</div>
+<!-- //rotate -->
+<!-- save -->
+<div id="bar_save" style="display:none">
+      <table border="0" cellspacing="5" cellpadding="2">
+        <tr>
+          <td class="topBar">Filename: 
+            <input type="filename" id="save_filename" value="padpc_1.jpg" name="textfield"></td>
+          <td class="topBar"> <select name="format" id="save_format" onChange="updateFormat(this)">
+              <option selected>Image Format</option>
+              <option>---------------------</option>
+              <option value="jpeg,85">JPEG High</option>
+              <option value="jpeg,60">JPEG Medium</option>
+              <option value="jpeg,35">JPEG Low</option>
+              <option value="png">PNG</option>
+              <option value="gif">GIF</option>
+            </select></td>
+          <td class="topBar">Quality: 
+		  </td>
+		  <td width="120">
+	<div id="slidercasing">	
+<div id="slidertrack" style="width:100px"><IMG SRC="spacer.gif" WIDTH="1" HEIGHT="1" BORDER="0" ALT="track"></div>
+				<div id="sliderbar" style="left:50px" onmousedown="captureStart()"><IMG SRC="spacer.gif" WIDTH="1" HEIGHT="1" BORDER="0" ALT="track"></div></div>
+		  </td>
+          <td class="topBar"> 
+<INPUT TYPE="text" id="quality" NAME="quality" onChange="updateSlider(this.value)" style="width:2em">
+<script type="text/javascript" src="jscripts/slider.js"></script>
+<script language="JavaScript1.2">
+<!--
+
+updateSlider(85);
+
+//-->
+</script>
+
+
+          </td>
+          <td><img src="div.gif" width="2" height="30"></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.reset();"><img src="btn_cancel.gif" width="30" height="30" border="0"></a></td>
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a href="#" onClick="editor.doSubmit('save');"><img src="btn_ok.gif" width="30" height="30" border="0"></a></td>
+        </tr>
+      </table>
+</div>
+<!--//save -->
+	  </td>
+	</tr>
+	<tr>
+		
+    <td bgcolor="#EEEEFF" width="60" valign="top" align="center" nowrap><table width="100%" border="0" cellspacing="8" cellpadding="2">
+        <tr> 
+          <td class="icons" id='btn_crop' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'crop')"><a href="#" class="iconText" onClick="javascript:toggle('crop')"><img src="crop.gif" width="20" height="20" border="0"><br>
+            Crop</a> </td>
+        </tr>
+        <tr> 
+          <td class="icons" id='btn_scale' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'scale')"><a href="#" class="iconText" onClick="javascript:toggle('scale')"><img src="scale.gif" width="20" height="20" border="0"><br>
+            Resize</a> </td>
+        </tr>
+        <tr> 
+          <td class="icons" id='btn_rotate' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'rotate')"><a href="#" class="iconText"  onClick="javascript:toggle('rotate')"><img src="rotate.gif" width="20" height="20" border="0"><br>
+            Rotate</a> </td>
+        </tr>
+        <tr> 
+          <td class="icons" id='btn_measure' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'measure')"><a href="#" class="iconText"  onClick="javascript:toggle('measure')"><img src="ruler.gif" width="20" height="20" border="0"><br>
+            Measure</a></td>
+        </tr>
+        <tr> 
+          <td class="icons" onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="pviiClassNew(this,'icons')"><a class="iconText" href="#" onClick="toggleMarker();"><img src="t_black.gif" name="markerImg" id="markerImg" width="20" height="20" border="0"><br>
+            Marker</a></td>
+        </tr>
+        <tr>
+          <td class="icons" id='btn_save' onMouseOver="pviiClassNew(this,'iconsOver')" onMouseOut="changeClass(this,'save')"><a href="#" class="iconText"  onClick="javascript:toggle('save')"><img src="save.gif" width="20" height="20" border="0"><br>
+            Save</a> </td>
+        </tr>
+      </table>
+    </td>
+		<td width="99%" >
+		<iframe width="100%" height="100%" id="editor" name="editor" src="load_image.php" marginwidth="0" marginheight="0" align="top" scrolling="auto" frameborder="0" hspace="0" vspace="0" background="gray">
+		</iframe>
+		</td>
+	</tr>
+</table>
+</BODY>
+</HTML>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/IM.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/IM.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/IM.php	(revision 795)
@@ -0,0 +1,230 @@
+<?php
+
+/***********************************************************************
+** Title.........:  ImageMagick Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  IM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// +----------------------------------------------------------------------+
+//
+//
+// Image Transformation interface using command line ImageMagick
+//
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_IM extends Image_Transform
+{
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     *
+     *
+     */
+    function Image_Transform_Driver_IM()
+    {
+        return true;
+    } // End Image_IM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        /*if (!file_exists($image)) {
+            return PEAR::raiseError('The image file ' . $image . ' does\'t exist', true);
+        }*/
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resize Action
+     *
+     * @param int   new_x   new width
+     * @param int   new_y   new height
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+        /*if (isset($this->command['resize'])) {
+            return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true);
+        }*/
+        $this->command['resize'] = "-geometry ${new_x}x${new_y}!";
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+        $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}";
+    }
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal)
+            $this->command['flop'] = "-flop";
+        else
+            $this->command['flip'] = "-flip";
+    }
+    /**
+     * rotate
+     *
+     * @param   int     angle   rotation angle
+     * @param   array   options no option allowed
+     *
+     */
+    function rotate($angle, $options=null)
+    {
+        if ('-' == $angle{0}) {
+            $angle = 360 - substr($angle, 1);
+        }
+         $this->command['rotate'] = "-rotate $angle";
+    } // End rotate
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'resize_first' => false // Carry out the scaling of the image before annotation?
+                                );
+         $params = array_merge($default_params, $params);
+         extract($params);
+         if (true === $resize_first) {
+             // Set the key so that this will be the last item in the array
+            $key = 'ztext';
+         } else {
+            $key = 'text';
+         }
+         $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'";
+         // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
+    } // End addText
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        $this->command['gamma'] = "-gamma $outputgamma";
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param $filename string  the name of the file to write to
+     * @param $quality  quality image dpi, default=75
+     * @param $type     string  (JPG,PNG...)
+     *
+     * @return none
+     */
+    function save($filename, $type='', $quality = 85)
+    {
+        $type == '' ? $this->type : $type;
+        $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert" ' . implode(' ', $this->command) . " -quality $quality "  . ($this->image) . ' ' . ($filename) . ' 2>&1';
+        
+        //echo $cmd;
+        exec($cmd);
+    } // End save
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type == '') {
+            header('Content-type: image/' . $this->type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-");
+        } else {
+            header('Content-type: image/' . $type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($type) . ":-");
+        }
+    }
+
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        return true;
+    }
+
+} // End class ImageIM
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/Transform.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/Transform.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/Transform.php	(revision 795)
@@ -0,0 +1,568 @@
+<?php
+/***********************************************************************
+** Title.........:  Image Transformation Interface
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  Transform.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+                    
+                    Added a few extra,
+                        - create unique filename in a particular directory,
+                          used for temp image files.
+                        - added cropping to GD, NetPBM, ImageMagick
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// |          Alan Knowles <alan@akbkhome.com>                            |
+// |          Vincent Oostindie <vincent@sunlight.tmfweb.nl>              |
+// +----------------------------------------------------------------------+
+//
+//
+// Image Transformation interface
+//
+
+
+/**
+ * The main "Image_Resize" class is a container and base class which
+ * provides the static methods for creating Image objects as well as
+ * some utility functions (maths) common to all parts of Image Resize.
+ *
+ * The object model of DB is as follows (indentation means inheritance):
+ *
+ * Image_Resize The base for each Image implementation.  Provides default
+ * |            implementations (in OO lingo virtual methods) for
+ * |            the actual Image implementations as well as a bunch of
+ * |            maths methods.
+ * |
+ * +-Image_GD   The Image implementation for the PHP GD extension .  Inherits
+ *              Image_Resize
+ *              When calling DB::setup for GD images the object returned is an
+ *              instance of this class.
+ *
+ * @package  Workflow
+ * @version  1.00
+ * @author   Peter Bowyer <peter@mapledesign.co.uk>
+ * @since    PHP 4.0
+ */
+Class Image_Transform
+{
+    /**
+     * Name of the image file
+     * @var string
+     */
+    var $image = '';
+    /**
+     * Type of the image file (eg. jpg, gif png ...)
+     * @var string
+     */
+    var $type = '';
+    /**
+     * Original image width in x direction
+     * @var int
+     */
+    var $img_x = '';
+    /**
+     * Original image width in y direction
+     * @var int
+     */
+    var $img_y = '';
+    /**
+     * New image width in x direction
+     * @var int
+     */
+    var $new_x = '';
+    /**
+     * New image width in y direction
+     * @var int
+     */
+    var $new_y = '';
+    /**
+     * Path the the library used
+     * e.g. /usr/local/ImageMagick/bin/ or
+     * /usr/local/netpbm/
+     */
+    var $lib_path = '';
+    /**
+     * Flag to warn if image has been resized more than once before displaying
+     * or saving.
+     */
+     var $resized = false;
+
+
+     var $uid = '';
+
+     var $lapse_time =900; //15 mins
+
+    /**
+     * Create a new Image_resize object
+     *
+     * @param string $driver name of driver class to initialize
+     *
+     * @return mixed a newly created Image_Transform object, or a PEAR
+     * error object on error
+     *
+     * @see PEAR::isError()
+     * @see Image_Transform::setOption()
+     */
+    function &factory($driver)
+    {
+        if ('' == $driver) {
+            die("No image library specified... aborting.  You must call ::factory() with one parameter, the library to load.");
+
+        }
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+
+        include_once "$driver.php";
+
+        $classname = "Image_Transform_Driver_{$driver}";
+        $obj =& new $classname;
+        return $obj;
+    }
+
+
+    /**
+     * Resize the Image in the X and/or Y direction
+     * If either is 0 it will be scaled proportionally
+     *
+     * @access public
+     *
+     * @param mixed $new_x (0, number, percentage 10% or 0.1)
+     * @param mixed $new_y (0, number, percentage 10% or 0.1)
+     *
+     * @return mixed none or PEAR_error
+     */
+    function resize($new_x = 0, $new_y = 0)
+    {
+        // 0 means keep original size
+        $new_x = (0 == $new_x) ? $this->img_x : $this->_parse_size($new_x, $this->img_x);
+        $new_y = (0 == $new_y) ? $this->img_y : $this->_parse_size($new_y, $this->img_y);
+        // Now do the library specific resizing.
+        return $this->_resize($new_x, $new_y);
+    } // End resize
+
+
+    /**
+     * Scale the image to have the max x dimension specified.
+     *
+     * @param int $new_x Size to scale X-dimension to
+     * @return none
+     */
+    function scaleMaxX($new_x)
+    {
+        $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+        return $this->_resize($new_x, $new_y);
+    } // End resizeX
+
+    /**
+     * Scale the image to have the max y dimension specified.
+     *
+     * @access public
+     * @param int $new_y Size to scale Y-dimension to
+     * @return none
+     */
+    function scaleMaxY($new_y)
+    {
+        $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+        return $this->_resize($new_x, $new_y);
+    } // End resizeY
+
+    /**
+     * Scale Image to a maximum or percentage
+     *
+     * @access public
+     * @param mixed (number, percentage 10% or 0.1)
+     * @return mixed none or PEAR_error
+     */
+    function scale($size)
+    {
+        if ((strlen($size) > 1) && (substr($size,-1) == '%')) {
+            return $this->scaleByPercentage(substr($size, 0, -1));
+        } elseif ($size < 1) {
+            return $this->scaleByFactor($size);
+        } else {
+            return $this->scaleByLength($size);
+        }
+    } // End scale
+
+    /**
+     * Scales an image to a percentage of its original size.  For example, if
+     * my image was 640x480 and I called scaleByPercentage(10) then the image
+     * would be resized to 64x48
+     *
+     * @access public
+     * @param int $size Percentage of original size to scale to
+     * @return none
+     */
+    function scaleByPercentage($size)
+    {
+        return $this->scaleByFactor($size / 100);
+    } // End scaleByPercentage
+
+    /**
+     * Scales an image to a factor of its original size.  For example, if
+     * my image was 640x480 and I called scaleByFactor(0.5) then the image
+     * would be resized to 320x240.
+     *
+     * @access public
+     * @param float $size Factor of original size to scale to
+     * @return none
+     */
+    function scaleByFactor($size)
+    {
+        $new_x = round($size * $this->img_x, 0);
+        $new_y = round($size * $this->img_y, 0);
+        return $this->_resize($new_x, $new_y);
+    } // End scaleByFactor
+
+    /**
+     * Scales an image so that the longest side has this dimension.
+     *
+     * @access public
+     * @param int $size Max dimension in pixels
+     * @return none
+     */
+    function scaleByLength($size)
+    {
+         if ($this->img_x >= $this->img_y) {
+            $new_x = $size;
+            $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+        } else {
+            $new_y = $size;
+            $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+        }
+        return $this->_resize($new_x, $new_y);
+    } // End scaleByLength
+
+
+    /**
+     *
+     * @access public
+     * @return void
+     */
+    function _get_image_details($image)
+    {
+        //echo $image;
+        $data = @GetImageSize($image);
+        #1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte order,
+        # 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC
+        if (is_array($data)){
+            switch($data[2]){
+                case 1:
+                    $type = 'gif';
+                    break;
+                case 2:
+                    $type = 'jpeg';
+                    break;
+                case 3:
+                    $type = 'png';
+                    break;
+                case 4:
+                    $type = 'swf';
+                    break;
+                case 5:
+                    $type = 'psd';
+                case 6:
+                    $type = 'bmp';
+                case 7:
+                case 8:
+                    $type = 'tiff';
+                default:
+                    echo("We do not recognize this image format");
+            }
+            $this->img_x = $data[0];
+            $this->img_y = $data[1];
+            $this->type = $type;
+
+            return true;
+        } else {
+            echo("Cannot fetch image or images details.");
+            return null;
+        }
+        /*
+        $output = array(
+                        'width' => $data[0],
+                        'height' => $data[1],
+                        'type' => $type
+                        );
+        return $output;
+        */
+    }
+
+
+    /**
+     * Parse input and convert
+     * If either is 0 it will be scaled proportionally
+     *
+     * @access private
+     *
+     * @param mixed $new_size (0, number, percentage 10% or 0.1)
+     * @param int $old_size
+     *
+     * @return mixed none or PEAR_error
+     */
+    function _parse_size($new_size, $old_size)
+    {
+        if ('%' == $new_size) {
+            $new_size = str_replace('%','',$new_size);
+            $new_size = $new_size / 100;
+        }
+        if ($new_size > 1) {
+            return (int) $new_size;
+        } elseif ($new_size == 0) {
+            return (int) $old_size;
+        } else {
+            return (int) round($new_size * $old_size, 0);
+        }
+    }
+
+
+    function uniqueStr()
+    {
+      return substr(md5(microtime()),0,6);
+    }
+
+    //delete old tmp files, and allow only 1 file per remote host.
+    function cleanUp($id, $dir)
+    {
+        $d = dir($dir);
+        $id_length = strlen($id);
+
+        while (false !== ($entry = $d->read())) {
+            if (is_file($dir.'/'.$entry) && substr($entry,0,1) == '.' && !ereg($entry, $this->image))
+            {
+                //echo filemtime($this->directory.'/'.$entry)."<br>"; 
+                //echo time();
+
+                if (filemtime($dir.'/'.$entry) + $this->lapse_time < time())
+                    unlink($dir.'/'.$entry);
+
+                if (substr($entry, 1, $id_length) == $id)
+                {
+                    if (is_file($dir.'/'.$entry))
+                        unlink($dir.'/'.$entry);
+                }
+            }
+        }
+        $d->close();
+    }
+
+
+    function createUnique($dir)
+    {
+       $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+        
+       //make sure the the unique temp file does not exists
+        while (file_exists($dir.$unique_str))
+        {
+            $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+        }
+        
+      $this->cleanUp($this->uid, $dir);
+
+       return $unique_str;
+    }
+
+
+    /**
+     * Set the image width
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_img_x($size)
+    {
+        $this->img_x = $size;
+    }
+
+    /**
+     * Set the image height
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_img_y($size)
+    {
+        $this->img_y = $size;
+    }
+
+    /**
+     * Set the image width
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_new_x($size)
+    {
+        $this->new_x = $size;
+    }
+
+    /**
+     * Set the image height
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_new_y($size)
+    {
+        $this->new_y = $size;
+    }
+
+    /**
+     * Get the type of the image being manipulated
+     *
+     * @return string $this->type the image type
+     */
+    function getImageType()
+    {
+        return $this->type;
+    }
+
+    /**
+     *
+     * @access public
+     * @return string web-safe image type
+     */
+    function getWebSafeFormat()
+    {
+        switch($this->type){
+            case 'gif':
+            case 'png':
+                return 'png';
+                break;
+            default:
+                return 'jpeg';
+        } // switch
+    }
+
+    /**
+     * Place holder for the real resize method
+     * used by extended methods to do the resizing
+     *
+     * @access private
+     * @return PEAR_error
+     */
+    function _resize() {
+        return null; //PEAR::raiseError("No Resize method exists", true);
+    }
+
+    /**
+     * Place holder for the real load method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @return PEAR_error
+     */
+    function load($filename) {
+        return null; //PEAR::raiseError("No Load method exists", true);
+    }
+
+    /**
+     * Place holder for the real display method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @param string filename
+     * @return PEAR_error
+     */
+    function display($type, $quality) {
+        return null; //PEAR::raiseError("No Display method exists", true);
+    }
+
+    /**
+     * Place holder for the real save method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @param string filename
+     * @return PEAR_error
+     */
+    function save($filename, $type, $quality) {
+        return null; //PEAR::raiseError("No Save method exists", true);
+    }
+
+    /**
+     * Place holder for the real free method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @return PEAR_error
+     */
+    function free() {
+        return null; //PEAR::raiseError("No Free method exists", true);
+    }
+
+    /**
+     * Reverse of rgb2colorname.
+     *
+     * @access public
+     * @return PEAR_error
+     *
+     * @see rgb2colorname
+     */
+    function colorhex2colorarray($colorhex) {
+        $r = hexdec(substr($colorhex, 1, 2));
+        $g = hexdec(substr($colorhex, 3, 2));
+        $b = hexdec(substr($colorhex, 4, 2));
+        return array($r,$g,$b);
+    }
+
+    /**
+     * Reverse of rgb2colorname.
+     *
+     * @access public
+     * @return PEAR_error
+     *
+     * @see rgb2colorname
+     */
+    function colorarray2colorhex($color) {
+        $color = '#'.dechex($color[0]).dechex($color[1]).dechex($color[2]);
+        return strlen($color)>6?false:$color;
+    }
+
+
+    /* Methods to add to the driver classes in the future */
+    function addText()
+    {
+        return null; //PEAR::raiseError("No addText method exists", true);
+    }
+
+    function addDropShadow()
+    {
+        return null; //PEAR::raiseError("No AddDropShadow method exists", true);
+    }
+
+    function addBorder()
+    {
+        return null; //PEAR::raiseError("No addBorder method exists", true);
+    }
+
+    function crop()
+    {
+        return null; //PEAR::raiseError("No crop method exists", true);
+    }
+
+    function flip() 
+    {
+        return null;
+    }
+
+    function gamma()
+    {
+        return null; //PEAR::raiseError("No gamma method exists", true);
+    }
+}
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/wz_jsgraphics.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/wz_jsgraphics.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/wz_jsgraphics.js	(revision 795)
@@ -0,0 +1,921 @@
+/***********************************************************************
+** Title.........:  Javascript Graphics
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  wz_jsgraphics.js
+** Last changed..:  31 Aug 2003  
+** Notes.........:  Modified for Image Editor, added extra commands
+**/ 
+
+/* This notice must be untouched at all times.
+
+wz_jsgraphics.js    v. 2.03
+The latest version is available at
+http://www.walterzorn.com
+or http://www.devira.com
+or http://www.walterzorn.de
+
+Copyright (c) 2002-2003 Walter Zorn. All rights reserved.
+Created 3. 11. 2002 by Walter Zorn <walter@kreuzotter.de>
+Last modified: 11. 6. 2003
+
+High Performance JavaScript Graphics Library.
+Provides methods
+- to draw lines, rectangles, ellipses, polygons
+  with specifiable line thickness,
+- to fill rectangles and ellipses
+- to draw text.
+NOTE: Operations, functions and branching have rather been optimized
+to efficiency and speed than to shortness of source code.
+
+This program is free software;
+you can redistribute it and/or modify it under the terms of the
+GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License
+at http://www.gnu.org/copyleft/gpl.html for more details.
+*/
+
+
+
+
+
+var jg_ihtm, jg_ie, jg_dom,
+jg_n4 = (document.layers && typeof document.classes != "undefined");
+
+
+
+
+
+function chkDHTM(x, i)
+{
+    x = document.body || null;
+    jg_ie = (x && typeof x.insertAdjacentHTML != "undefined");
+    jg_dom = (x && !jg_ie &&
+        typeof x.appendChild != "undefined" &&
+        typeof document.createRange != "undefined" &&
+        typeof (i = document.createRange()).setStartBefore != "undefined" &&
+        typeof i.createContextualFragment != "undefined");
+    jg_ihtm = (!jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined");
+}
+
+
+
+
+
+function pntDoc()
+{
+    this.wnd.document.write(this.htm);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvDom()
+{
+    var x = document.createRange();
+    x.setStartBefore(this.cnv);
+    x = x.createContextualFragment(this.htm);
+    this.cnv.appendChild(x);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvIe()
+{
+    this.cnv.insertAdjacentHTML("BeforeEnd", this.htm);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvIhtm()
+{
+    this.cnv.innerHTML += this.htm;
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnv()
+{
+    this.htm = '';
+}
+
+
+
+
+
+function mkDiv(x, y, w, h)
+{
+    this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'overflow:hidden;background-color:' + this.color + ';'+
+        '"><\/div>';
+
+    //alert(this.htm);
+}
+
+
+
+
+function mkDivPrint(x, y, w, h)
+{
+    this.htm += '<div style="position:absolute;'+
+        'border-left:' + w + 'px solid ' + this.color + ';'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'overflow:hidden;background-color:' + this.color + ';'+
+        '"><\/div>';
+}
+
+
+
+
+
+function mkLyr(x, y, w, h)
+{
+    this.htm += '<layer '+
+        'left="' + x + '" '+
+        'top="' + y + '" '+
+        'width="' + w + '" '+
+        'height="' + h + '" '+
+        'bgcolor="' + this.color + '"><\/layer>\n';
+}
+
+
+
+
+
+function mkLbl(txt, x, y)
+{
+    this.htm += '<div style="position:absolute;white-space:nowrap;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'font-family:' +  this.ftFam + ';'+
+        'font-size:' + this.ftSz + ';'+
+        'color:' + this.color + ';' + this.ftSty + '">'+
+        txt +
+        '<\/div>';
+}
+
+
+
+
+
+function mkLin(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1;
+
+    if (dx >= dy)
+    {
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx,
+        ox = x;
+        while ((dx--) > 0)
+        {
+            ++x;
+            if (p > 0)
+            {
+                this.mkDiv(ox, y, x-ox, 1);
+                y += yIncr;
+                p += pru;
+                ox = x;
+            }
+            else p += pr;
+        }
+        this.mkDiv(ox, y, x2-ox+1, 1);
+    }
+
+    else
+    {
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy,
+        oy = y;
+        if (y2 <= y1)
+        {
+            while ((dy--) > 0)
+            {
+                if (p > 0)
+                {
+                    this.mkDiv(x++, y, 1, oy-y+1);
+                    y += yIncr;
+                    p += pru;
+                    oy = y;
+                }
+                else
+                {
+                    y += yIncr;
+                    p += pr;
+                }
+            }
+            this.mkDiv(x2, y2, 1, oy-y2+1);
+        }
+        else
+        {
+            while ((dy--) > 0)
+            {
+                y += yIncr;
+                if (p > 0)
+                {
+                    this.mkDiv(x++, oy, 1, y-oy);
+                    p += pru;
+                    oy = y;
+                }
+                else p += pr;
+            }
+            this.mkDiv(x2, oy, 1, y2-oy+1);
+        }
+    }
+}
+
+
+
+
+
+function mkLin2D(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1;
+
+
+    var s = this.stroke;
+    if (dx >= dy)
+    {
+        if (s-0x3 > 0)
+        {
+            var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
+            _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+        }
+        else var _s = s;
+        var ad = Math.ceil(s/2);
+
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx,
+        ox = x;
+        while ((dx--) > 0)
+        {
+            ++x;
+            if (p > 0)
+            {
+                this.mkDiv(ox, y, x-ox+ad, _s);
+                y += yIncr;
+                p += pru;
+                ox = x;
+            }
+            else p += pr;
+        }
+        this.mkDiv(ox, y, x2-ox+ad+1, _s);
+    }
+
+    else
+    {
+        if (s-0x3 > 0)
+        {
+            var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
+            _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+        }
+        else var _s = s;
+        var ad = Math.round(s/2);
+
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy,
+        oy = y;
+        if (y2 <= y1)
+        {
+            ++ad;
+            while ((dy--) > 0)
+            {
+                if (p > 0)
+                {
+                    this.mkDiv(x++, y, _s, oy-y+ad);
+                    y += yIncr;
+                    p += pru;
+                    oy = y;
+                }
+                else
+                {
+                    y += yIncr;
+                    p += pr;
+                }
+            }
+            this.mkDiv(x2, y2, _s, oy-y2+ad);
+        }
+        else
+        {
+            while ((dy--) > 0)
+            {
+                y += yIncr;
+                if (p > 0)
+                {
+                    this.mkDiv(x++, oy, _s, y-oy+ad);
+                    p += pru;
+                    oy = y;
+                }
+                else p += pr;
+            }
+            this.mkDiv(x2, oy, _s, y2-oy+ad+1);
+        }
+    }
+}
+
+
+
+
+
+function mkLinDott(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1,
+    drw = true;
+    if (dx >= dy)
+    {
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx;
+        while ((dx--) > 0)
+        {
+            if (drw) this.mkDiv(x, y, 1, 1);
+            drw = !drw;
+            if (p > 0)
+            {
+                y += yIncr;
+                p += pru;
+            }
+            else p += pr;
+            ++x;
+        }
+        if (drw) this.mkDiv(x, y, 1, 1);
+    }
+
+    else
+    {
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy;
+        while ((dy--) > 0)
+        {
+            if (drw) this.mkDiv(x, y, 1, 1);
+            drw = !drw;
+            y += yIncr;
+            if (p > 0)
+            {
+                ++x;
+                p += pru;
+            }
+            else p += pr;
+        }
+        if (drw) this.mkDiv(x, y, 1, 1);
+    }
+}
+
+
+
+
+
+function mkOv(left, top, width, height)
+{
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = (height&1)+1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    ox = 0, oy = b,
+    aa = (a*a)<<1, bb = (b*b)<<1,
+    st = (aa>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa*((b<<1)-1),
+    w, h;
+    while (y > 0)
+    {
+        if (st < 0)
+        {
+            st += bb*((x<<1)+0x3);
+            tt += (bb<<1)*(++x);
+        }
+        else if (tt < 0)
+        {
+            st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+            tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+            w = x-ox;
+            h = oy-y;
+            if (w&0x2 && h&0x2)
+            {
+                this.mkOvQds(cx, cy, -x+0x2, ox+wod, -oy, oy-1+hod, 1, 1);
+                this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
+            }
+            else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
+            ox = x;
+            oy = y;
+        }
+        else
+        {
+            tt -= aa*((y<<1)-0x3);
+            st -= (aa<<1)*(--y);
+        }
+    }
+    this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
+    this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
+}
+
+
+
+
+
+function mkOv2D(left, top, width, height)
+{
+    var s = this.stroke;
+    width += s-1;
+    height += s-1;
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = (height&1)+1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    aa = (a*a)<<1, bb = (b*b)<<1,
+    st = (aa>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa*((b<<1)-1);
+
+
+    if (s-0x4 < 0 && (!(s-0x2) || width-0x33 > 0 && height-0x33 > 0))
+    {
+        var ox = 0, oy = b,
+        w, h,
+        pxl, pxr, pxt, pxb, pxw;
+        while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+                tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+                w = x-ox;
+                h = oy-y;
+
+                if (w-1)
+                {
+                    pxw = w+1+(s&1);
+                    h = s;
+                }
+                else if (h-1)
+                {
+                    pxw = s;
+                    h += 1+(s&1);
+                }
+                else pxw = h = s;
+                this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
+                ox = x;
+                oy = y;
+            }
+            else
+            {
+                tt -= aa*((y<<1)-0x3);
+                st -= (aa<<1)*(--y);
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
+        this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
+    }
+
+
+    else
+    {
+        var _a = (width-((s-1)<<1))>>1,
+        _b = (height-((s-1)<<1))>>1,
+        _x = 0, _y = _b,
+        _aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
+        _st = (_aa>>1)*(1-(_b<<1)) + _bb,
+        _tt = (_bb>>1) - _aa*((_b<<1)-1),
+
+        pxl = new Array(),
+        pxt = new Array(),
+        _pxb = new Array();
+        pxl[0] = 0;
+        pxt[0] = b;
+        _pxb[0] = _b-1;
+        while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+                pxl[pxl.length] = x;
+                pxt[pxt.length] = y;
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+                tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+                pxl[pxl.length] = x;
+                pxt[pxt.length] = y;
+            }
+            else
+            {
+                tt -= aa*((y<<1)-0x3);
+                st -= (aa<<1)*(--y);
+            }
+
+            if (_y > 0)
+            {
+                if (_st < 0)
+                {
+                    _st += _bb*((_x<<1)+0x3);
+                    _tt += (_bb<<1)*(++_x);
+                    _pxb[_pxb.length] = _y-1;
+                }
+                else if (_tt < 0)
+                {
+                    _st += _bb*((_x<<1)+0x3) - (_aa<<1)*(_y-1);
+                    _tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-0x3);
+                    _pxb[_pxb.length] = _y-1;
+                }
+                else
+                {
+                    _tt -= _aa*((_y<<1)-0x3);
+                    _st -= (_aa<<1)*(--_y);
+                    _pxb[_pxb.length-1]--;
+                }
+            }
+        }
+
+        var ox = 0, oy = b,
+        _oy = _pxb[0],
+        l = pxl.length,
+        w, h;
+        for (var i = 0; i < l; i++)
+        {
+            if (typeof _pxb[i] != "undefined")
+            {
+                if (_pxb[i] < _oy || pxt[i] < oy)
+                {
+                    x = pxl[i];
+                    this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
+                    ox = x;
+                    oy = pxt[i];
+                    _oy = _pxb[i];
+                }
+            }
+            else
+            {
+                x = pxl[i];
+                this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
+                this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+                ox = x;
+                oy = pxt[i];
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
+        this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+    }
+}
+
+
+
+
+
+function mkOvDott(left, top, width, height)
+{
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = height&1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+    st = (aa2>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa2*((b<<1)-1),
+    drw = true;
+    while (y > 0)
+    {
+        if (st < 0)
+        {
+            st += bb*((x<<1)+0x3);
+            tt += (bb<<1)*(++x);
+        }
+        else if (tt < 0)
+        {
+            st += bb*((x<<1)+0x3) - aa4*(y-1);
+            tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+        }
+        else
+        {
+            tt -= aa2*((y<<1)-0x3);
+            st -= aa4*(--y);
+        }
+        if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
+        drw = !drw;
+    }
+}
+
+
+
+
+
+function mkRect(x, y, w, h)
+{
+    var s = this.stroke;
+    this.mkDiv(x, y, w, s);
+    this.mkDiv(x+w, y, s, h);
+    this.mkDiv(x, y+h, w+s, s);
+    this.mkDiv(x, y+s, s, h-s);
+}
+
+
+
+
+
+function mkRectDott(x, y, w, h)
+{
+    this.drawLine(x, y, x+w, y);
+    this.drawLine(x+w, y, x+w, y+h);
+    this.drawLine(x, y+h, x+w, y+h);
+    this.drawLine(x, y, x, y+h);
+}
+
+
+
+
+
+function jsgFont()
+{
+    this.PLAIN = 'font-weight:normal;';
+    this.BOLD = 'font-weight:bold;';
+    this.ITALIC = 'font-style:italic;';
+    this.ITALIC_BOLD = this.ITALIC + this.BOLD;
+    this.BOLD_ITALIC = this.ITALIC_BOLD;
+}
+var Font = new jsgFont();
+
+
+
+
+
+function jsgStroke()
+{
+    this.DOTTED = -1;
+}
+var Stroke = new jsgStroke();
+
+
+
+
+
+function jsGraphics(id, wnd)
+{
+    this.setColor = new Function('arg', 'this.color = arg;');
+
+
+    this.getColor = new Function('return this.color');
+
+    this.setStroke = function(x)
+    {
+        this.stroke = x;
+        if (!(x+1))
+        {
+            this.drawLine = mkLinDott;
+            this.mkOv = mkOvDott;
+            this.drawRect = mkRectDott;
+        }
+        else if (x-1 > 0)
+        {
+            this.drawLine = mkLin2D;
+            this.mkOv = mkOv2D;
+            this.drawRect = mkRect;
+        }
+        else
+        {
+            this.drawLine = mkLin;
+            this.mkOv = mkOv;
+            this.drawRect = mkRect;
+        }
+    };
+
+
+
+    this.setPrintable = function(arg)
+    {
+        this.printable = arg;
+        this.mkDiv = jg_n4? mkLyr : arg? mkDivPrint : mkDiv;
+    };
+
+
+
+    this.setFont = function(fam, sz, sty)
+    {
+        this.ftFam = fam;
+        this.ftSz = sz;
+        this.ftSty = sty || Font.PLAIN;
+    };
+
+
+
+    this.drawPolyline = this.drawPolyLine = function(x, y, s)
+    {
+        var i = x.length-1; while (i >= 0)
+            this.drawLine(x[i], y[i], x[--i], y[i]);
+    };
+
+
+
+    this.fillRect = function(x, y, w, h)
+    {
+        this.mkDiv(x, y, w, h);
+    };
+
+
+    this.fillRectPattern = function(x, y, w, h, url)
+    {
+        this.htm += '<div style="position:absolute;'+
+            'left:' + x + 'px;'+
+            'top:' + y + 'px;'+
+            'width:' + w + 'px;'+
+            'height:' + h + 'px;'+
+            'clip:rect(0,'+w+'px,'+h+'px,0);'+
+            'overflow:hidden;'+
+            //'background-color:' + this.color + ';'+
+            "background-image: url('" + url + "');"+
+            "layer-background-image: url('" + url + "');"+
+            'z-index:100;"><\/div>';
+        //alert(this.htm);
+    }
+
+    this.drawHandle = function(x, y, w, h, cursor)
+    {
+        
+        this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'padding: 2px;overflow:hidden;'+
+        "cursor: '" + cursor + "';"+
+        '" class="handleBox" id="' + cursor + '" ><\/div>';
+    }
+
+    this.drawHandleBox = function(x, y, w, h, cursor)
+    {
+        
+        this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+(w+2)+'px,'+(h+2)+'px,0);'+
+        'overflow:hidden; border: solid 1px '+ this.color+';'+
+        "cursor: '" + cursor + "';"+
+        '" class="handleBox" id="' + cursor + '" ><\/div>';
+
+        
+    }
+
+    this.drawPolygon = function(x, y)
+    {
+        this.drawPolyline(x, y);
+        this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
+    };
+
+
+
+    this.drawEllipse = this.drawOval = function(x, y, w, h)
+    {
+        this.mkOv(x, y, w, h);
+    };
+
+
+
+    this.fillEllipse = this.fillOval = function(left, top, w, h)
+    {
+        var a = (w -= 1)>>1, b = (h -= 1)>>1,
+        wod = (w&1)+1, hod = (h&1)+1,
+        cx = left+a, cy = top+b,
+        x = 0, y = b,
+        ox = 0, oy = b,
+        aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+        st = (aa2>>1)*(1-(b<<1)) + bb,
+        tt = (bb>>1) - aa2*((b<<1)-1),
+        pxl, dw, dh;
+        if (w+1) while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - aa4*(y-1);
+                pxl = cx-x;
+                dw = (x<<1)+wod;
+                tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+                dh = oy-y;
+                this.mkDiv(pxl, cy-oy, dw, dh);
+                this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
+                ox = x;
+                oy = y;
+            }
+            else
+            {
+                tt -= aa2*((y<<1)-0x3);
+                st -= aa4*(--y);
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
+    };
+
+
+
+    this.drawString = mkLbl;
+
+
+
+    this.clear = function()
+    {
+        this.htm = "";
+        if (this.cnv) this.cnv.innerHTML = this.defhtm;
+        
+    };
+
+
+
+    this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
+    {
+        this.mkDiv(xr+cx, yt+cy, w, h);
+        this.mkDiv(xr+cx, yb+cy, w, h);
+        this.mkDiv(xl+cx, yb+cy, w, h);
+        this.mkDiv(xl+cx, yt+cy, w, h);
+    };
+
+
+    this.setStroke(1);
+    this.setPrintable(false);
+    this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
+    this.color = '#000000';
+    this.htm = '';
+    this.wnd = wnd || window;
+
+
+    if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
+    if (typeof id != 'string' || !id) this.paint = pntDoc;
+    else
+    {
+        this.cnv = document.all? (this.wnd.document.all[id] || null)
+            : document.getElementById? (this.wnd.document.getElementById(id) || null)
+            : null;
+        this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
+        this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
+    }
+}
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/EditorContent.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/EditorContent.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/EditorContent.js	(revision 795)
@@ -0,0 +1,694 @@
+/***********************************************************************
+** Title.........:  Online Image Editor Interface
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  EditorContents.js
+** Last changed..:  31 Aug 2003  
+** Notes.........:  Handles most of the interface routines for the ImageEditor.
+**/ 
+
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+var pic_x, pic_y;
+function P7_Snap() { //v2.62 by PVII
+  var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,args=P7_Snap.arguments;a=parseInt(a);
+  for (k=0; k<(args.length-3); k+=4)
+   if ((g=MM_findObj(args[k]))!=null) {
+    el=eval(MM_findObj(args[k+1]));
+    a=parseInt(args[k+2]);b=parseInt(args[k+3]);
+    x=0;y=0;ox=0;oy=0;p="";tx=1;da="document.all['"+args[k]+"']";
+    if(document.getElementById) {
+     d="document.getElementsByName('"+args[k]+"')[0]";
+     if(!eval(d)) {d="document.getElementById('"+args[k]+"')";if(!eval(d)) {d=da;}}
+    }else if(document.all) {d=da;} 
+    if (document.all || document.getElementById) {
+     while (tx==1) {p+=".offsetParent";
+      if(eval(d+p)) {x+=parseInt(eval(d+p+".offsetLeft"));y+=parseInt(eval(d+p+".offsetTop"));
+      }else{tx=0;}}
+     ox=parseInt(g.offsetLeft);oy=parseInt(g.offsetTop);var tw=x+ox+y+oy;
+     if(tw==0 || (navigator.appVersion.indexOf("MSIE 4")>-1 && navigator.appVersion.indexOf("Mac")>-1)) {
+      ox=0;oy=0;if(g.style.left){x=parseInt(g.style.left);y=parseInt(g.style.top);
+      }else{var w1=parseInt(el.style.width);bx=(a<0)?-5-w1:-10;
+      a=(Math.abs(a)<1000)?0:a;b=(Math.abs(b)<1000)?0:b;
+      //alert(event.clientX);
+	  if (event == null) x=document.body.scrollLeft + bx;
+		else x=document.body.scrollLeft + event.clientX + bx;
+	  if (event == null) y=document.body.scrollTop;
+		else y=document.body.scrollTop + event.clientY;}}
+   }else if (document.layers) {x=g.x;y=g.y;var q0=document.layers,dd="";
+    for(var s=0;s<q0.length;s++) {dd='document.'+q0[s].name;
+     if(eval(dd+'.document.'+args[k])) {x+=eval(dd+'.left');y+=eval(dd+'.top');break;}}}
+   if(el) {e=(document.layers)?el:el.style;
+   var xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
+   //alert(xx+":"+yy);
+   if(navigator.appName=="Netscape" && parseInt(navigator.appVersion)>4){xx+="px";yy+="px";}
+   if(navigator.appVersion.indexOf("MSIE 5")>-1 && navigator.appVersion.indexOf("Mac")>-1){
+    xx+=parseInt(document.body.leftMargin);yy+=parseInt(document.body.topMargin);
+    xx+="px";yy+="px";}e.left=xx;e.top=yy;}
+    pic_x = parseInt(xx); pic_y = parseInt(yy);
+    //alert(xx+":"+yy);
+    }
+}
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+var dragapproved=false
+var z,x,y,status, ant, canvas, content, pic_width, pic_height, image, resizeHandle, oa_w, oa_h, oa_x, oa_y, mx2, my2;
+
+
+function init_resize() 
+{
+    if(mode == "scale") 
+    {
+        P7_Snap('theImage','ant',0,0);
+
+        if (canvas == null)
+            canvas = MM_findObj("imgCanvas");
+
+        if (pic_width == null || pic_height == null)
+        {
+            image = MM_findObj("theImage");
+            pic_width = image.width;
+            pic_height = image.height;
+        }
+        
+        if (ant == null)
+            ant = MM_findObj("ant");
+
+        ant.style.left = pic_x; ant.style.top = pic_y;
+        ant.style.width = pic_width; ant.style.height = pic_height;
+        ant.style.visibility = "visible";
+
+        drawBoundHandle();
+        jg_doc.paint();
+    }
+}
+
+function init() 
+{
+    init_crop();
+    init_resize();
+    var markerImg = MM_findObj('markerImg', window.top.document);
+
+    if (markerImg.src.indexOf("t_white.gif")>0)
+        toggleMarker() ;
+}
+
+function init_crop() 
+{
+    //if(mode == "crop") {
+        P7_Snap('theImage','ant',0,0);
+    //}
+}
+
+function setMode(newMode) 
+{
+    mode = newMode;
+    reset();
+}
+
+function reset() 
+{
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    ant.style.visibility = "hidden";
+    ant.style.left = 0;
+    ant.style.top = 0;
+    ant.style.width = 0;
+    ant.style.height = 0;
+
+    mx2 = null;
+    my2 = null;
+
+    jg_doc.clear();
+    if(mode != 'measure')
+        showStatus();   
+
+    if(mode == "scale") {
+        init_resize();
+    }
+
+    P7_Snap('theImage','ant',0,0);
+}
+
+function toggleMarker() 
+{
+    //alert("Toggle");
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    if(ant.className=="selection")
+        ant.className="selectionWhite";
+    else
+        ant.className="selection";
+    
+    if (jg_doc.getColor() == "#000000")
+        jg_doc.setColor("#FFFFFF");
+    else
+        jg_doc.setColor("#000000");
+    
+    drawBoundHandle
+    jg_doc.paint();
+}
+
+
+function move(e)
+{
+    if (dragapproved)
+    {
+        //z.style.left=ns6? temp1+e.clientX-x: temp1+event.clientX-x
+        //z.style.top=ns6? temp2+e.clientY-y : temp2+event.clientY-y
+        var w = ns6? temp1+e.clientX - x : temp1+event.clientX - x;
+        var h = ns6? temp2+e.clientY - y : temp2+event.clientY - y;
+
+        //alert(canvas.style.left);
+        /*if (status !=null)
+        {
+            status.innerHTML  = "x:"+x+" y:"+y+" w:"+w+" h:"+h+" can_h:"+pic_height;
+            status.innerHTML += " can_w:"+pic_width+" px:"+pic_x+" py:"+pic_y;
+            status.innerHTML += " pix:"+image.style.left+" piy:"+image.style.top+" obj:"+obj.id;
+        }*/
+
+        /*jg_doc.clear();
+        jg_doc.fillRectPattern(0,0,Math.abs(w),Math.abs(h),pattern);
+        jg_doc.paint();
+*/
+        if (ant != null)
+        {
+            if (w >= 0)
+            {
+                ant.style.left = x;
+                ant.style.width = w;
+            }
+            else
+            {
+                ant.style.left = x+w;
+                ant.style.width = -1*w;
+            }
+
+            if (h >= 0)
+            {
+                ant.style.top = y;
+                ant.style.height = h;
+            }
+            else
+            {
+                ant.style.top = y+h;
+                ant.style.height = -1*h
+            }
+        }
+        
+        showStatus();
+        return false
+    }
+}
+
+function moveContent(e) 
+{
+    if (dragapproved)
+    {
+
+        var dx =ns6? oa_x + e.clientX-x: oa_x + event.clientX-x
+        var dy =ns6? oa_y + e.clientY-y : oa_y + event.clientY-y
+
+
+        /*if (status !=null)
+        {
+            status.innerHTML  = "x:"+x+" y:"+y+" dx:"+dx+" dy:"+dy;
+        }*/
+
+        ant.style.left = dx;
+        ant.style.top = dy;
+
+        showStatus();
+
+        return false;
+    }
+}
+
+function moveHandle(e) 
+{
+    if (dragapproved)
+    {
+        var w = ns6? e.clientX - x : event.clientX - x;
+        var h = ns6? e.clientY - y : event.clientY - y;
+        
+        switch(resizeHandle) 
+        {
+
+            case "s-resize":
+                if (oa_h + h >= 0)          
+                    ant.style.height = oa_h + h;
+                break;
+            case "e-resize":
+                if(oa_w + w >= 0)
+                    ant.style.width = oa_w + w;
+                break;
+            case "n-resize":
+                if (oa_h - h >= 0)
+                {
+                    ant.style.top = oa_y + h;
+                    ant.style.height = oa_h - h;
+                }
+                break;
+            case "w-resize":
+                if(oa_w - w >= 0) {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                }break;
+            case "nw-resize":
+                if(oa_h - h >= 0 && oa_w - w >= 0) {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                    ant.style.top = oa_y + h;
+                    ant.style.height = oa_h - h;
+                }
+            break;
+            case "ne-resize":
+                if (oa_h - h >= 0 && oa_w + w >= 0){
+                    ant.style.top = oa_y + h;
+                    ant.style.height = oa_h - h;
+                    ant.style.width = oa_w + w;
+                }
+                break;
+            case "se-resize":
+                if (oa_h + h >= 0 && oa_w + w >= 0) 
+                {
+                    ant.style.height = oa_h + h;
+                    ant.style.width = oa_w + w;
+                }
+                break;
+            case "sw-resize":
+                if (oa_h + h >= 0 && oa_w - w >= 0)
+                {
+                    ant.style.height = oa_h + h;
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                }
+        }
+        
+        showStatus();
+        return false;
+        
+    }
+}
+
+function drags(e)
+{
+    if (!ie&&!ns6)
+        return
+    
+    var firedobj=ns6? e.target : event.srcElement
+    var topelement=ns6? "HTML" : "BODY"
+
+    while (firedobj.tagName!=topelement&&
+            !(firedobj.className=="crop" 
+                || firedobj.className=="handleBox" 
+                || firedobj.className=="selection" || firedobj.className=="selectionWhite"))
+    {
+        firedobj=ns6? firedobj.parentNode : firedobj.parentElement
+    }
+
+    if(firedobj.className=="handleBox") {
+        
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = 0;
+                content.height = 0;
+            }
+            //alert(content.width+":"+content.height);
+        }
+        resizeHandle = firedobj.id;
+        
+        /*if(status!=null) {
+            status.innerHTML  = " obj:"+firedobj.id;
+        }*/
+
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+
+        oa_w = parseInt(ant.style.width);
+        oa_h = parseInt(ant.style.height);
+        oa_x = parseInt(ant.style.left);
+        oa_y = parseInt(ant.style.top);
+
+        dragapproved=true
+        document.onmousemove=moveHandle;
+        return false;
+    }
+    else
+    if((firedobj.className == "selection" || firedobj.className=="selectionWhite")&& mode == "crop") {
+        
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+        
+        oa_x = parseInt(ant.style.left);
+        oa_y = parseInt(ant.style.top);
+
+        dragapproved=true
+        document.onmousemove=moveContent;
+        return false;
+    }
+    else
+    if (firedobj.className=="crop" && mode == "crop")
+    {
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = 0;
+                content.height = 0;
+            }
+            //alert(content.width+":"+content.height);
+        }
+
+        if (status == null)
+            status = MM_findObj("status");
+
+        if (ant == null)
+            ant = MM_findObj("ant");
+
+        if (canvas == null)
+            canvas = MM_findObj("imgCanvas");
+        if(content == null) {
+            content = MM_findObj("cropContent");
+        }
+
+        if (pic_width == null || pic_height == null)
+        {
+            image = MM_findObj("theImage");
+            pic_width = image.width;
+            pic_height = image.height;
+        }
+
+        ant.style.visibility = "visible";
+
+        obj = firedobj;
+        dragapproved=true
+        z=firedobj
+        temp1=parseInt(z.style.left+0)
+        temp2=parseInt(z.style.top+0)
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+        document.onmousemove=move
+        return false
+    }
+        else if(firedobj.className=="crop" && mode == "measure") {
+
+            if (ant == null)
+                ant = MM_findObj("ant");
+
+            if (canvas == null)
+                canvas = MM_findObj("imgCanvas");
+
+            x=ns6? e.clientX: event.clientX
+            y=ns6? e.clientY: event.clientY
+
+                //jg_doc.draw
+            dragapproved=true
+            document.onmousemove=measure
+
+            return false
+        }
+}
+
+function measure(e) 
+{
+    if (dragapproved)
+    {
+        mx2 = ns6? e.clientX : event.clientX;
+        my2 = ns6? e.clientY : event.clientY;
+        
+        jg_doc.clear();
+        jg_doc.setStroke(Stroke.DOTTED); 
+        jg_doc.drawLine(x,y,mx2,my2);
+        jg_doc.paint();
+        showStatus();
+        return false;
+    }
+}
+
+function setMarker(nx,ny,nw,nh) 
+{
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    if (canvas == null)
+        canvas = MM_findObj("imgCanvas");
+    if(content == null) {
+        content = MM_findObj("cropContent");
+    }
+
+    if (pic_width == null || pic_height == null)
+    {
+        image = MM_findObj("theImage");
+        pic_width = image.width;
+        pic_height = image.height;
+    }
+
+    ant.style.visibility = "visible";
+
+    nx = pic_x + nx;
+    ny = pic_y + ny;
+
+    if (nw >= 0)
+    {
+        ant.style.left = nx;
+        ant.style.width = nw;
+    }
+    else
+    {
+        ant.style.left = nx+nw;
+        ant.style.width = -1*nw;
+    }
+
+    if (nh >= 0)
+    {
+        ant.style.top = ny;
+        ant.style.height = nh;
+    }
+    else
+    {
+        ant.style.top = ny+nh;
+        ant.style.height = -1*nh
+    }
+
+    
+}
+
+function max(x,y) 
+{
+    if(y > x)
+        return x;
+    else 
+        return y;
+}
+
+function drawBoundHandle() 
+{
+    if(ant == null || ant.style == null) 
+        return false;
+
+    var ah = parseInt(ant.style.height);
+    var aw = parseInt(ant.style.width);
+    var ax = parseInt(ant.style.left);
+    var ay = parseInt(ant.style.top);
+
+    jg_doc.drawHandle(ax-15,ay-15,30,30,"nw-resize"); //upper left
+    jg_doc.drawHandle(ax-15,ay+ah-15,30,30,"sw-resize"); //lower left
+    jg_doc.drawHandle(ax+aw-15,ay-15,30,30,"ne-resize"); //upper right
+    jg_doc.drawHandle(ax+aw-15,ay+ah-15,30,30,"se-resize"); //lower right
+
+    jg_doc.drawHandle(ax+max(15,aw/10),ay-8,aw-2*max(15,aw/10),8,"n-resize"); //top middle
+    jg_doc.drawHandle(ax+max(15,aw/10),ay+ah,aw-2*max(15,aw/10),8,"s-resize"); //bottom middle
+    jg_doc.drawHandle(ax-8, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"w-resize"); //left middle
+    jg_doc.drawHandle(ax+aw, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"e-resize"); //right middle
+
+
+
+    jg_doc.drawHandleBox(ax-4,ay-4,8,8,"nw-resize"); //upper left
+    jg_doc.drawHandleBox(ax-4,ay+ah-4,8,8,"sw-resize"); //lower left
+    jg_doc.drawHandleBox(ax+aw-4,ay-4,8,8,"ne-resize"); //upper right
+    jg_doc.drawHandleBox(ax+aw-4,ay+ah-4,8,8,"se-resize"); //lower right
+
+    jg_doc.drawHandleBox(ax+aw/2-4,ay-4,8,8,"n-resize"); //top middle
+    jg_doc.drawHandleBox(ax+aw/2-4,ay+ah-4,8,8,"s-resize"); //bottom middle
+    jg_doc.drawHandleBox(ax-4, ay+ah/2-4,8,8,"w-resize"); //left middle
+    jg_doc.drawHandleBox(ax+aw-4, ay+ah/2-4,8,8,"e-resize"); //right middle
+
+    //jg_doc.paint();
+}
+
+function showStatus() 
+{
+    if(ant == null || ant.style == null) {
+        return false;
+    }
+
+    if(mode == "measure") {
+        //alert(pic_x);
+        mx1 = x - pic_x;
+        my1 = y - pic_y;
+
+        mw = mx2 - x;
+        mh = my2 - y;
+
+        md = parseInt(Math.sqrt(mw*mw + mh*mh)*100)/100;
+
+        ma = (Math.atan(-1*mh/mw)/Math.PI)*180;
+        if(mw < 0 && mh < 0)
+            ma = ma+180;
+
+        if (mw <0 && mh >0)
+            ma = ma - 180;
+
+        ma = parseInt(ma*100)/100;
+
+        if (m_sx != null && !isNaN(mx1))
+            m_sx.innerHTML = mx1+" px";
+        if (m_sy != null && !isNaN(my1))
+            m_sy.innerHTML = my1+" px";
+        if(m_w != null && !isNaN(mw))
+            m_w.innerHTML = mw + " px";
+        if(m_h != null && !isNaN(mh))
+            m_h.innerHTML = mh + " px";
+
+        if(m_d != null && !isNaN(md))
+            m_d.innerHTML = md + " px";
+        if(m_a != null && !isNaN(ma))
+            m_a.innerHTML = ma + "&deg; ";
+
+        if(r_ra != null &&!isNaN(ma))
+            r_ra.value = ma;            
+
+        //alert("mx1:"+mx1+" my1"+my1);
+        return false;
+    }
+
+    var ah = parseInt(ant.style.height);
+    var aw = parseInt(ant.style.width);
+    var ax = parseInt(ant.style.left);
+    var ay = parseInt(ant.style.top);
+
+    var cx = ax-pic_x<0?0:ax-pic_x;
+    var cy = ay-pic_y<0?0:ay-pic_y;
+    cx = cx>pic_width?pic_width:cx;
+    cy = cy>pic_height?pic_height:cy;
+    
+    var cw = ax-pic_x>0?aw:aw-(pic_x-ax);
+    var ch = ay-pic_y>0?ah:ah-(pic_y-ay);
+
+    ch = ay+ah<pic_y+pic_height?ch:ch-(ay+ah-pic_y-pic_height);
+    cw = ax+aw<pic_x+pic_width?cw:cw-(ax+aw-pic_x-pic_width);
+
+    ch = ch<0?0:ch; cw = cw<0?0:cw;
+    
+    if (ant.style.visibility == "hidden")
+    {
+        cx = ""; cy = ""; cw=""; ch="";
+    }
+
+    if(mode == 'crop') {
+        if(t_cx != null)
+            t_cx.value = cx;
+        if (t_cy != null)   
+            t_cy.value = cy;
+        if(t_cw != null)
+            t_cw.value = cw;
+        if (t_ch != null)   
+            t_ch.value = ch;
+    }
+    else if(mode == 'scale') {
+
+        var sw = aw, sh = ah;
+
+        if (s_sw.value.indexOf('%')>0 && s_sh.value.indexOf('%')>0)
+        {   
+            sw = cw/pic_width;
+            sh = ch/pic_height;
+        }
+        if (s_sw != null)
+            s_sw.value = sw;
+        if (s_sh != null)
+            s_sh.value = sh;
+    }
+
+}
+
+function dragStopped()
+{
+    dragapproved=false;
+
+    if(ant == null || ant.style == null) {
+        return false;
+    }
+
+    if(mode == "measure") {
+        jg_doc.drawLine(x-4,y,x+4,y);
+        jg_doc.drawLine(x,y-4,x,y+4);
+        jg_doc.drawLine(mx2-4,my2,mx2+4,my2);
+        jg_doc.drawLine(mx2,my2-4,mx2,my2+4);
+
+        jg_doc.paint();
+        showStatus();
+        return false;
+    }
+        var ah = parseInt(ant.style.height);
+        var aw = parseInt(ant.style.width);
+        var ax = parseInt(ant.style.left);
+        var ay = parseInt(ant.style.top);
+        jg_doc.clear();
+        
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = aw-1;
+                content.height = ah-1;
+            }
+            //alert(content.width+":"+content.height);
+        }
+        if(mode == "crop") {
+            //alert(pic_y);
+            jg_doc.fillRectPattern(pic_x,pic_y,pic_width,ay-pic_y,pattern);
+            
+            var h1 = ah;
+            var y1 = ay;
+            if (ah+ay >= pic_height+pic_y)
+                h1 = pic_height+pic_y-ay;
+            else if (ay <= pic_y)
+            {
+                h1 = ay+ah-pic_y;
+                y1 = pic_y;
+            }
+            jg_doc.fillRectPattern(pic_x,y1,ax-pic_x,h1,pattern);
+            jg_doc.fillRectPattern(ax+aw,y1,pic_x+pic_width-ax-aw,h1,pattern);
+            jg_doc.fillRectPattern(pic_x,ay+ah,pic_width,pic_height+pic_y-ay-ah,pattern);
+        }
+        else if(mode == "scale") {
+            //alert("Resizing: iw:"+image.width+" nw:"+aw);
+            document.theImage.height = ah;
+            document.theImage.width = aw;
+            document.theImage.style.height = ah+" px";
+            document.theImage.style.width = aw+" px";
+
+            P7_Snap('theImage','ant',0,0);
+
+            //alert("After Resizing: iw:"+image.width+" nw:"+aw);
+        }
+
+        drawBoundHandle();
+        jg_doc.paint();
+    
+        showStatus();
+    return false;
+}
+
+document.onmousedown=drags
+document.onmouseup=dragStopped;
+
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/slider.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/slider.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/jscripts/slider.js	(revision 795)
@@ -0,0 +1,104 @@
+/***********************************************************************
+** Title.........:  Simple Lite Slider for Image Editor
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  slider.php
+** Last changed..:  31 Aug 2003  
+** Notes.........:  Works in IE and Mozilla
+**/ 
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+document.onmouseup = captureStop;
+
+var currentSlider = null,sliderField = null;
+var rangeMin = null, rangeMax= null, sx = -1, sy = -1, initX=0;
+
+function getMouseXY(e) {
+
+    //alert('hello');
+    x = ns6? e.clientX: event.clientX
+    y = ns6? e.clientY: event.clientY
+    
+    if (sx < 0) sx = x; if (sy < 0) sy = y;
+
+    var dx = initX +(x-sx);
+    
+    if (dx <= rangeMin)
+        dx = rangeMin;
+    else if (dx >= rangeMax)
+        dx = rangeMax;
+
+    var range = (dx-rangeMin)/(rangeMax - rangeMin)*100;
+
+    if (currentSlider !=  null)
+        currentSlider.style.left = dx;
+        
+    if (sliderField != null)
+    {
+        sliderField.value = parseInt(range);
+    }
+    return false;
+
+}
+
+function init()
+{
+    if (currentSlider == null)
+        currentSlider = MM_findObj('sliderbar');
+    
+    if (sliderField == null)
+        sliderField = MM_findObj('quality');
+
+    if (rangeMin == null)
+        rangeMin = 3
+    if (rangeMax == null)
+    {
+        var track = MM_findObj('slidertrack');
+        rangeMax = parseInt(track.style.width);
+    }
+
+}
+
+function updateSlider(value)
+{
+    init();
+
+    var newValue = parseInt(value)/100*(rangeMax-rangeMin);
+
+    if (newValue <= rangeMin)
+        newValue = rangeMin;
+    else if (newValue >= rangeMax)
+        newValue = rangeMax;
+
+    if (currentSlider !=  null)
+        currentSlider.style.left = newValue;
+    
+    var range = newValue/(rangeMax - rangeMin)*100;
+
+    if (sliderField != null)
+        sliderField.value = parseInt(range);
+}
+
+function captureStart(){
+    
+    init();
+
+    initX = parseInt(currentSlider.style.left);
+    if (initX > rangeMax)
+        initX = rangeMax;
+    else if (initX < rangeMin)
+        initX = rangeMin;
+
+    document.onmousemove = getMouseXY;
+
+    return false;
+}
+
+function captureStop()
+{
+    sx = -1; sy = -1;
+    document.onmousemove = null;
+    return false;
+}
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/load_image.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/load_image.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/load_image.php	(revision 795)
@@ -0,0 +1,141 @@
+<?
+/***********************************************************************
+** Title.........:  Online Manipulation of Images
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  load_image.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Configuration in config.inc.php 
+
+                   Uses the GD, ImageMagic or NetPBM to manipulate
+                   images online. ImageMagic is preferred as it provides
+                   the best rotation algorithm. Below is a brief comparsion
+                   of the image manipulation packages. Personal preference
+                   is ImageMagick.
+
+                              |     GD     | NetPBM | ImageMagick
+                   ------------------------------------------------
+                   GIF             NO(1)     YES        YES
+                   JPEG            YES(2)    YES        YES
+                   PNG             YES       YES        YES
+                   Cropping        Good      Good       Good
+                   Scaling         Fair      Good       Very Good
+                   Rotation        Poor      Fair       Very Good
+                   Flip            Good      Poor       Good
+                   
+
+                   (1) GIF is support in old GD say version 1.61 and below
+                   (2) Full colour JPEG is not supported in GD versions
+                       less than 2.01 with PHP.
+
+***********************************************************************/
+
+//***************************************************************************
+
+include '../ImageManager/config.inc.php';
+
+// set this to whatever subdir you make
+$path = $BASE_ROOT.'/';
+//$path = $BASE_DIR.'/';
+
+//***************************************************************************
+
+//echo $path;
+
+require_once 'Transform.php';
+
+$action = '';
+
+//get the image file
+$img_file = $_GET['img'];
+
+if($img_file != '') {
+    $path_info = pathinfo(urldecode($img_file));
+    $path = $path_info['dirname']."/";
+    $img_file = $path_info['basename'];
+}
+//var_dump($path);
+//var_dump($path_info);
+
+//get the parameters
+if (isset($_GET['action']))
+    $action = $_GET['action'];
+if (isset($_GET['params']))
+    $params = $_GET['params'];
+if(isset($_GET['file'])) {
+    $save_file = urldecode($_GET['file']);
+}
+
+//manipulate the image if the parameters are valid
+if(isset($params)) {
+    $values =  explode(',',$params,4);
+    if(count($values)>0) {
+        $file = manipulate($img_file, $action, $values);
+    }
+}
+
+//manipulate the images
+function manipulate($img_file, $action, $values)
+{
+    global $path, $save_file, $BASE_DIR,$BASE_ROOT;
+
+	$img_location=$BASE_DIR.$BASE_ROOT.'/';
+    //Load the Image Manipulation Driver
+    $img = Image_Transform::factory(IMAGE_CLASS);
+
+	
+	$img->load($img_location.$img_file);
+    switch ($action) {
+        case 'crop':
+            $img->crop(intval($values[0]),intval($values[1]),intval($values[2]),intval($values[3]));
+        break;
+    case 'scale':
+            $img->resize(intval($values[0]),intval($values[1]));
+        break;
+    case 'rotate':
+            $img->rotate(floatval($values[0]));
+        break;
+    case 'flip':
+        if ($values[0] == 'hoz')
+            $img->flip(true);
+        else if($values[0] == 'ver') 
+            $img->flip(false);
+        break;
+    case 'save':
+
+        if (isset($save_file))
+        {
+            $quality = intval($values[1]);
+            if($quality <0)
+                $quality = 85;
+            $img->save($img_location.$save_file, $values[0], $quality);
+        }
+        break;
+    }
+
+    //get the unique file name
+    $filename = $img->createUnique($img_location);
+    //save the manipulated image 
+    $img->save($img_location.$filename);
+    $img->free();
+
+    $imagesize = @getimagesize($filename);
+    return array($filename, $imagesize[3]);
+}
+
+
+//well, let say the image was not manipulated, or no action parameter was given
+//we will get the image dimension anyway.
+$image = $img_file;
+$size = @getimagesize($image);
+$dimensions = $size[3];
+
+if (isset($file) && is_array($file))
+{
+    $image = $file[0];
+    $dimensions = $file[1];
+}
+
+//now display the image with 
+include 'man_image.html';
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/NetPBM.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/NetPBM.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageEditor/NetPBM.php	(revision 795)
@@ -0,0 +1,253 @@
+<?php
+/***********************************************************************
+** Title.........:  NetPBM Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  NetPBM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// +----------------------------------------------------------------------+
+//
+//
+// Image Transformation interface using command line NetPBM
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_NetPBM extends Image_Transform
+{
+
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     * Class Constructor
+     */
+    function Image_Transform_Driver_NetPBM()
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+            
+        return true;
+    } // End function Image_NetPBM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        //echo $image;
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resizes the image
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+        // there's no technical reason why resize can't be called multiple
+        // times...it's just silly to do so
+
+        $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+                           "pnmscale -width $new_x -height $new_y";
+
+        $this->_set_new_x($new_x);
+        $this->_set_new_y($new_y);
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+        $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+                            "pnmcut -left $crop_x -top $crop_y -width $crop_width -height $crop_height";
+    }
+
+    /**
+     * Rotates the image
+     *
+     * @param int $angle The angle to rotate the image through
+     */
+    function rotate($angle)
+    {
+        $angle = -1*floatval($angle);
+
+        if($angle > 90)
+        {   
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias 90";
+            $this->rotate(-1*($angle-90));
+        }
+        else if ($angle < -90)
+        {
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias -90";
+            $this->rotate(-1*($angle+90));
+        }
+        else
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias $angle";
+    } // End rotate
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal) 
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -lr";
+        else
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -tb";
+    }
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma = 1.0) {
+        $this->command[13] = IMAGE_TRANSFORM_LIB_PATH . "pnmgamma $outputgamma";
+    }
+
+    /**
+     * adds text to an image
+     *
+     * @param   array   options     Array contains options
+     *             array(
+     *                  'text'          // The string to draw
+     *                  'x'             // Horizontal position
+     *                  'y'             // Vertical Position
+     *                  'Color'         // Font color
+     *                  'font'          // Font to be used
+     *                  'size'          // Size of the fonts in pixel
+     *                  'resize_first'  // Tell if the image has to be resized
+     *                                  // before drawing the text
+     *                   )
+     *
+     * @return none
+     */
+    function addText($params)
+    {
+        $default_params = array('text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false);
+        // we ignore 'resize_first' since the more logical approach would be
+        // for the user to just call $this->_resize() _first_ ;)
+        extract(array_merge($default_params, $params));
+        $this->command[] = "ppmlabel -angle $angle -colour $color -size "
+                           ."$size -x $x -y ".$y+$size." -text \"$text\"";
+    } // End addText
+
+    function _postProcess($type, $quality, $save_type)
+    {
+        $type = is_null($type) || $type==''? $this->type : $type;
+        $save_type = is_null($save_type) || $save_type==''? $this->type : $save_type;
+        //echo "TYPE:". $this->type;
+        array_unshift($this->command, IMAGE_TRANSFORM_LIB_PATH
+                      . $type.'topnm '. $this->image);
+        $arg = '';
+        switch(strtolower($save_type)){
+            case 'gif':
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmquant 256";
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type";
+                break;
+            case 'jpg':
+            case 'jpeg':
+                $arg = "--quality=$quality";
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type $arg";
+                break;
+            default:
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmto$save_type $arg";
+                break;
+        } // switch
+        return implode('|', $this->command);
+    } 
+
+    /**
+     * Save the image file
+     *
+     * @param $filename string the name of the file to write to
+     * @param string $type (jpeg,png...);
+     * @param int $quality 75
+     * @return none
+     */
+    function save($filename, $type=null, $quality = 85)
+    {
+        $cmd = $this->_postProcess('', $quality, $type) . ">$filename";
+            
+        //If you are using windows, you need the following line.
+		//$cmd = ereg_replace('/','\\',$cmd);
+        //echo $cmd."##";
+        system($cmd);
+        $this->command = array();
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string $type (jpeg,png...);
+     * @param int $quality 75
+     * @return none
+     */
+    function display($type = null, $quality = 75)
+    {
+        header('Content-type: image/' . $type);
+        $cmd = $this->_postProcess($type, $quality);
+        
+        passthru($cmd);
+        $this->command = array();
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        // there is no image handle here
+        return true;
+    }
+
+
+} // End class ImageIM
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/docprop.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/docprop.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/docprop.html	(revision 795)
@@ -0,0 +1,131 @@
+<html>
+
+<head>
+  <title>Document properties</title>
+
+<script type="text/javascript" src="../../../popups/popup.js"></script>
+
+<script type="text/javascript">
+
+FullPage = window.opener.FullPage; // load the FullPage plugin and lang file ;-)
+window.resizeTo(400, 100);
+
+  var accepted = {
+      f_doctype       : true,
+      f_title         : true,
+      f_body_bgcolor  : true,
+      f_body_fgcolor  : true,
+      f_base_style    : true,
+      f_alt_style     : true
+  };
+
+var editor = null;
+function Init() {
+  __dlg_translate(FullPage.I18N);
+  __dlg_init();
+  var params = window.dialogArguments;
+  for (var i in params) {
+      if (i in accepted) {
+        var el = document.getElementById(i);
+        el.value = params[i];
+      }
+  }
+  editor = params.editor;
+  document.getElementById("f_title").focus();
+  document.getElementById("f_title").select();
+};
+
+function onOK() {
+  var required = {
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+
+  var param = {};
+  for (var i in accepted) {
+    var el = document.getElementById(i);
+    param[i] = el.value;
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+table .label { text-align: right; width: 12em; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+
+#buttons {
+      margin-top: 1em; border-top: 1px solid #999;
+      padding: 2px; text-align: right;
+}
+</style>
+
+  </head>
+
+  <body onload="Init()">
+
+    <div class="title"><span>Document properties</span></div>
+
+    <table style="width: 100%">
+      <tr>
+        <td class="label"><span>Document title:</span></td>
+        <td><input type="text" id="f_title" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>DOCTYPE:</span></td>
+        <td><input type="text" id="f_doctype" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Primary style-sheet:</span></td>
+        <td><input type="text" id="f_base_style" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Alternate style-sheet:</span></td>
+        <td><input type="text" id="f_alt_style" style="width: 100%" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Background color:</span></td>
+        <td><input type="text" id="f_body_bgcolor" size="7" /></td>
+      </tr>
+      <tr>
+        <td class="label"><span>Text color:</span></td>
+        <td><input type="text" id="f_body_fgcolor" size="7" /></td>
+      </tr>
+    </table>
+
+    <div id="buttons">
+      <button type="button" name="ok" onclick="return onOK();"><span>OK</span></button>
+      <button type="button" name="cancel" onclick="return onCancel();"><span>Cancel</span></button>
+    </div>
+
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/insert_image2.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/insert_image2.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/insert_image2.html	(revision 795)
@@ -0,0 +1,216 @@
+<html style="width: 398; height: 218">
+
+<head>
+  <title>Insert Image</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+var preview_window = null;
+
+function Init() {
+  __dlg_init();
+  document.getElementById("f_url").focus();
+};
+
+function onOK() {
+  var required = {
+    "f_url": "You must enter the URL",
+    "f_alt": "Please enter the alternate text"
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+  // pass data back to the calling window
+  var fields = ["f_url", "f_alt", "f_align", "f_border",
+                "f_horiz", "f_vert"];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = document.getElementById(id);
+    param[id] = el.value;
+  }
+  if (preview_window) {
+    preview_window.close();
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  if (preview_window) {
+    preview_window.close();
+  }
+  __dlg_close(null);
+  return false;
+};
+
+function onPreview() {
+  alert("FIXME: preview needs rewritten:\n  show the image inside this window instead of opening a new one.");
+  var f_url = document.getElementById("f_url");
+  var url = f_url.value;
+  if (!url) {
+    alert("You have to enter an URL first");
+    f_url.focus();
+    return false;
+  }
+  var img = new Image();
+  img.src = url;
+  var win = null;
+  if (!document.all) {
+    win = window.open("about:blank", "ha_imgpreview", "toolbar=no,menubar=no,personalbar=no,innerWidth=100,innerHeight=100,scrollbars=no,resizable=yes");
+  } else {
+    win = window.open("about:blank", "ha_imgpreview", "channelmode=no,directories=no,height=100,width=100,location=no,menubar=no,resizable=yes,scrollbars=no,toolbar=no");
+  }
+  preview_window = win;
+  var doc = win.document;
+  var body = doc.body;
+  if (body) {
+    body.innerHTML = "";
+    body.style.padding = "0px";
+    body.style.margin = "0px";
+    var el = doc.createElement("img");
+    el.src = url;
+
+    var table = doc.createElement("table");
+    body.appendChild(table);
+    table.style.width = "100%";
+    table.style.height = "100%";
+    var tbody = doc.createElement("tbody");
+    table.appendChild(tbody);
+    var tr = doc.createElement("tr");
+    tbody.appendChild(tr);
+    var td = doc.createElement("td");
+    tr.appendChild(td);
+    td.style.textAlign = "center";
+
+    td.appendChild(el);
+    win.resizeTo(el.offsetWidth + 30, el.offsetHeight + 30);
+  }
+  win.focus();
+  return false;
+};
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 6em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Image</div>
+
+<form action="" method="get">
+<table border="0" width="100%" style="padding: 0px; margin: 0px">
+  <tbody>
+
+  <tr>
+    <td style="width: 7em; text-align: right">Image URL:</td>
+    <td><input type="text" name="url" id="f_url" style="width:75%"
+      title="Enter the image URL here" />
+      <button name="preview" onclick="return onPreview();"
+      title="Preview the image in a new window">Preview</button>
+    </td>
+  </tr>
+  <tr>
+    <td style="width: 7em; text-align: right">Alternate text:</td>
+    <td><input type="text" name="alt" id="f_alt" style="width:100%"
+      title="For browsers that don't support images" /></td>
+  </tr>
+
+  </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+  title="Positioning of this image">
+  <option value=""                             >Not set</option>
+  <option value="left"                         >Left</option>
+  <option value="right"                        >Right</option>
+  <option value="texttop"                      >Texttop</option>
+  <option value="absmiddle"                    >Absmiddle</option>
+  <option value="baseline" selected="1"        >Baseline</option>
+  <option value="absbottom"                    >Absbottom</option>
+  <option value="bottom"                       >Bottom</option>
+  <option value="middle"                       >Middle</option>
+  <option value="top"                          >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5"
+title="Leave empty for no border" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Horizontal:</div>
+<input type="text" name="horiz" id="f_horiz" size="5"
+title="Horizontal padding" />
+
+<p />
+
+<div class="fr">Vertical:</div>
+<input type="text" name="vert" id="f_vert" size="5"
+title="Vertical padding" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; text-align: right;">
+<hr />
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/insert_image.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/insert_image.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/insert_image.php	(revision 795)
@@ -0,0 +1,448 @@
+<?php
+   /***********************************************************************
+   ** Title.........:	Image Manager for HTMLArea 3.0 Alpha, PHP Version
+   ** Version.......:	1.01
+   ** Author........:	Xiang Wei ZHUO <wei@zhuo.org>
+   ** Filename......:	insert_image.php
+   ** Last changed..:	8 Mar 2003 
+   ** Notes.........:	Configuration in config.inc.php 
+
+   - Only compatible with IE 5.5+
+
+   ***********************************************************************/
+
+   include 'ImageManager/config.inc.php';
+   $no_dir = false;
+   if(!is_dir($BASE_DIR.$BASE_ROOT)) {
+	  $no_dir = true;
+   }
+?>
+<html style="width: 580; height: 440;">
+   <head>
+	  <title>Insert Image</title>
+	  <script type="text/javascript" src="popup.js"></script>
+	  <script type="text/javascript" src="../../../dialog.js"></script>
+	  <script type="text/javascript">
+		 var preview_window = null;
+
+
+
+		 function Init() {
+
+			   __dlg_init();
+			   var doc = MM_findObj("f_url");
+
+			   if(doc != null) {
+					 doc.focus();
+			   }
+		 };
+
+		 function onOK() {
+			   var required = {
+					 "f_url": "You must enter the URL",
+					 "f_alt": "Please enter the alternate text"
+			   };
+			   for (var i in required) {
+					 var el = MM_findObj(i);
+					 if (!el.value) {
+						   alert(required[i]);
+						   el.focus();
+						   return false;
+					 }
+			   }
+			   // pass data back to the calling window
+			   var fields = ["f_url", "f_alt", "f_align", "f_border",
+			   "f_horiz", "f_vert", "f_width", "f_height"];
+			   var param = new Object();
+			   for (var i in fields) {
+					 var id = fields[i];
+					 var el = MM_findObj(id);
+					 if(id == "f_url") 
+//					 param[id] = "<? echo 'http://'.$_SERVER['SERVER_NAME']; ?>" + el.value;
+					 param[id] = "" + el.value;
+					 else
+					 param[id] = el.value;
+			   }
+			   if (preview_window) {
+					 preview_window.close();
+			   }
+			   //alert(param);
+			   __dlg_close(param);
+			   return false;
+		 };
+
+		 function onCancel() {
+			   if (preview_window) {
+					 preview_window.close();
+			   }
+			   __dlg_close(null);
+			   return false;
+		 };
+
+	  </script>
+	  <style type="text/css">
+		 html, body {
+			   background: ButtonFace;
+			   color: ButtonText;
+			   font: 11px Tahoma,Verdana,sans-serif;
+			   margin: 0px;
+			   padding: 0px;
+		 }
+		 body { padding: 5px; }
+		 table {
+			   font: 11px Tahoma,Verdana,sans-serif;
+		 }
+		 form p {
+			   margin-top: 5px;
+			   margin-bottom: 5px;
+		 }
+		 .fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+		 .fr { width: 6em; float: left; padding: 2px 5px; text-align: right; }
+		 fieldset { padding: 0px 10px 5px 5px; }
+		 select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+		 button { width: 70px; }
+		 .space { padding: 2px; }
+
+		 .title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+			border-bottom: 1px solid black; letter-spacing: 2px;
+	  }
+	  form { padding: 0px; margin: 0px; }
+   </style>
+   <style type="text/css">
+	  <!--
+	  .buttonHover {
+			border: 1px solid;
+			border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+			cursor: hand;
+	  }
+	  .buttonOut
+	  {
+			border: 1px solid ButtonFace;
+	  }
+
+	  .separator {
+			position: relative;
+			margin: 3px;
+			border-left: 1px solid ButtonShadow;
+			border-right: 1px solid ButtonHighlight;
+			width: 0px;
+			height: 16px;
+			padding: 0px;
+	  }
+	  .manager
+	  {
+	  }
+	  .statusLayer
+	  {
+			background:#FFFFFF;
+			border: 1px solid #CCCCCC;
+	  }
+	  .statusText {
+			font-family: Verdana, Arial, Helvetica, sans-serif;
+			font-size: 15px;
+			font-weight: bold;
+			color: #6699CC;
+			text-decoration: none;
+	  }
+	  -->
+   </style>
+   <script language="JavaScript" type="text/JavaScript">
+	  <!--
+	  function pviiClassNew(obj, new_style) { //v2.6 by PVII
+		 obj.className=new_style;
+   }
+   function goUpDir() 
+   {
+		 var selection = document.forms[0].dirPath;
+		 var dir = selection.options[selection.selectedIndex].value;
+		 if(dir != '/')
+		 {
+			   imgManager.goUp();	
+			   changeLoadingStatus('load');
+		 }
+
+   }
+
+   function updateDir(selection) 
+   {
+		 var newDir = selection.options[selection.selectedIndex].value;
+		 imgManager.changeDir(newDir);
+		 changeLoadingStatus('load');
+   }
+
+   function newFolder() 
+   {
+		 var selection = document.forms[0].dirPath;
+		 var dir = selection.options[selection.selectedIndex].value;
+		 Dialog("ImageManager/newFolder.html", function(param) {
+			   if (!param) {	// user must have pressed Cancel
+				  return false;
+			}
+			else
+			{
+				  var folder = param['f_foldername'];
+				  if (folder && folder != '') {
+						imgManager.newFolder(dir,folder); 
+				  }
+			}
+	  }, null);
+}
+
+function toggleConstrains(constrains) 
+{
+   if(constrains.checked) 
+   {
+		 document.locked_img.src = "ImageManager/locked.gif";	
+		 checkConstrains('width') 
+   }
+   else
+   {
+		 document.locked_img.src = "ImageManager/unlocked.gif";	
+   }
+											 }
+
+											 function checkConstrains(changed) 
+											 {
+												   //alert(document.form1.constrain_prop);
+												   var constrained = document.form1.constrain_prop.checked;
+
+												   if(constrained) 
+												   {
+														 var orginal_width = parseInt(document.form1.orginal_width.value);
+														 var orginal_height = parseInt(document.form1.orginal_height.value);
+
+														 var width = parseInt(document.form1.f_width.value);
+														 var height = parseInt(document.form1.f_height.value);
+
+														 if(orginal_width > 0 && orginal_height > 0) 
+														 {
+															   if(changed == 'width' && width > 0) {
+																	 document.form1.f_height.value = parseInt((width/orginal_width)*orginal_height);
+															   }
+
+															   if(changed == 'height' && height > 0) {
+																	 document.form1.f_width.value = parseInt((height/orginal_height)*orginal_width);
+															   }
+														 }
+
+												   }
+
+											 }
+
+											 function MM_findObj(n, d) { //v4.01
+												var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+													  d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+												   if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+												   for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+												   if(!x && d.getElementById) x=d.getElementById(n); return x;
+											 }
+
+											 function P7_Snap() { //v2.62 by PVII
+												var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,args=P7_Snap.arguments;a=parseInt(a);
+												for (k=0; k<(args.length-3); k+=4)
+												if ((g=MM_findObj(args[k]))!=null) {
+													  el=eval(MM_findObj(args[k+1]));
+													  a=parseInt(args[k+2]);b=parseInt(args[k+3]);
+													  x=0;y=0;ox=0;oy=0;p="";tx=1;da="document.all['"+args[k]+"']";
+													  if(document.getElementById) {
+															d="document.getElementsByName('"+args[k]+"')[0]";
+															if(!eval(d)) {d="document.getElementById('"+args[k]+"')";if(!eval(d)) {d=da;}}
+													  }else if(document.all) {d=da;} 
+													  if (document.all || document.getElementById) {
+															while (tx==1) {p+=".offsetParent";
+															   if(eval(d+p)) {x+=parseInt(eval(d+p+".offsetLeft"));y+=parseInt(eval(d+p+".offsetTop"));
+														 }else{tx=0;}}
+														 ox=parseInt(g.offsetLeft);oy=parseInt(g.offsetTop);var tw=x+ox+y+oy;
+														 if(tw==0 || (navigator.appVersion.indexOf("MSIE 4")>-1 && navigator.appVersion.indexOf("Mac")>-1)) {
+															   ox=0;oy=0;if(g.style.left){x=parseInt(g.style.left);y=parseInt(g.style.top);
+															   }else{var w1=parseInt(el.style.width);bx=(a<0)?-5-w1:-10;
+															   a=(Math.abs(a)<1000)?0:a;b=(Math.abs(b)<1000)?0:b;
+															   x=document.body.scrollLeft + event.clientX + bx;
+															   y=document.body.scrollTop + event.clientY;}}
+													  }else if (document.layers) {x=g.x;y=g.y;var q0=document.layers,dd="";
+													  for(var s=0;s<q0.length;s++) {dd='document.'+q0[s].name;
+														 if(eval(dd+'.document.'+args[k])) {x+=eval(dd+'.left');y+=eval(dd+'.top');break;}}}
+												   if(el) {e=(document.layers)?el:el.style;
+													  var xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
+													  if(navigator.appName=="Netscape" && parseInt(navigator.appVersion)>4){xx+="px";yy+="px";}
+													  if(navigator.appVersion.indexOf("MSIE 5")>-1 && navigator.appVersion.indexOf("Mac")>-1){
+															xx+=parseInt(document.body.leftMargin);yy+=parseInt(document.body.topMargin);
+															xx+="px";yy+="px";}e.left=xx;e.top=yy;}}
+											 }
+
+											 function MM_showHideLayers() { //v6.0
+												var i,p,v,obj,args=MM_showHideLayers.arguments;
+												for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
+												   if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
+												   obj.visibility=v; }
+										  }
+
+										  function changeLoadingStatus(state) 
+										  {
+												var statusText = null;
+												if(state == 'load') {
+													  statusText = 'Loading Images';	
+												}
+												else if(state == 'upload') {
+													  statusText = 'Uploading Files';
+												}
+												if(statusText != null) {
+													  var obj = MM_findObj('loadingStatus');
+													  if (obj != null && obj.innerHTML != null)
+													  obj.innerHTML = statusText;
+													  MM_showHideLayers('loading','','show')		
+												}
+										  }
+
+										  function refresh()
+										  {
+												var selection = document.forms[0].dirPath;
+												updateDir(selection);
+										  }
+
+
+										  //-->
+									   </script>
+									</head>
+									<body onload="Init(); P7_Snap('dirPath','loading',120,70);">
+									   <div class="title">Insert Image</div>
+									   <form action="ImageManager/images.php" name="form1" method="post" target="imgManager" enctype="multipart/form-data">
+										  <div id="loading" style="position:absolute; left:200px; top:130px; width:184px; height:48px; z-index:1" class="statusLayer">
+											 <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
+												<tr>
+												   <td><div align="center"><span id="loadingStatus" class="statusText">Loading Images</span><img src="ImageManager/dots.gif" width="22" height="12"></div></td>
+												</tr>
+											 </table>
+										  </div>
+										  <table width="100%" border="0" align="center" cellspacing="2" cellpadding="2">
+											 <tr>
+												<td align="center">	  <fieldset>
+													  <legend>Image Manager</legend>
+													  <table width="99%" align="center" border="0" cellspacing="2" cellpadding="2">
+														 <tr>
+															<td><table border="0" cellspacing="1" cellpadding="3">
+																  <tr> 
+																	 <td>Directory</td>
+																	 <td>
+																		<select name="dirPath" id="dirPath" style="width:30em" onChange="updateDir(this)">
+																		   <option value="/">/</option>
+																		   <?
+
+
+																		   function dirs($dir,$abs_path) 
+																		   {
+																			  $d = dir($dir);
+																			  $dirs = array();
+																			  while (false !== ($entry = $d->read())) {
+																				 if(is_dir($dir.'/'.$entry) && substr($entry,0,1) != '.') 
+																				 {
+																					$path['path'] = $dir.'/'.$entry;
+																					$path['name'] = $entry;
+																					$dirs[$entry] = $path;
+																				 }
+																			  }
+																			  $d->close();
+
+																			  ksort($dirs);
+																			  for($i=0; $i<count($dirs); $i++) 
+																			  {
+																				 $name = key($dirs);
+																				 $current_dir = $abs_path.'/'.$dirs[$name]['name'];
+																				 echo "<option value=\"$current_dir\">$current_dir</option>\n";
+																				 dirs($dirs[$name]['path'],$current_dir);
+																				 next($dirs);
+																			  }
+																		   }
+
+																		   if($no_dir == false) {
+																			  dirs($BASE_DIR.$BASE_ROOT,'');	
+																		   }
+																		?>
+																	 </select>
+																  </td>
+																  <td class="buttonOut" onMouseOver="pviiClassNew(this,'buttonHover')" onMouseOut="pviiClassNew(this,'buttonOut')">
+																	 <a href="#" onClick="javascript:goUpDir();"><img src="ImageManager/btnFolderUp.gif" width="15" height="15" border="0" alt="Up"></a></td>
+																  <? if ($SAFE_MODE == false) { ?>
+																  <td><div class="separator"></div></td>
+																  <td class="buttonOut" onMouseOver="pviiClassNew(this,'buttonHover')" onMouseOut="pviiClassNew(this,'buttonOut')">
+																	 <a href="#" onClick="javascript:newFolder();"><img src="ImageManager/btnFolderNew.gif" width="15" height="15" border="0" alt="New Folder"></a></td>
+																  <? } ?>
+															   </tr>
+														 </table></td>
+													  </tr>
+													  <tr>
+														 <td align="center" bgcolor="white"><div name="manager" class="manager">
+															   <iframe src="ImageManager/images.php" name="imgManager" id="imgManager" width="520" height="150" marginwidth="0" marginheight="0" align="top" scrolling="auto" frameborder="0" hspace="0" vspace="0" background="white"></iframe>
+															</div>
+														 </td>
+													  </tr>
+												   </table>
+											 </fieldset></td>
+										  </tr>
+										  <tr>
+											 <td><table border="0" align="center" cellpadding="2" cellspacing="2">
+												   <tr> 
+													  <td nowrap><div align="right">Image File </div></td>
+													  <td><input name="url" id="f_url" type="text" style="width:20em" size="30"></td>
+													  <td rowspan="3">&nbsp;</td>
+													  <td><div align="right">Width </div></td>
+													  <td><input name="width" id="f_width" type="text" size="5" style="width:4em" onChange="javascript:checkConstrains('width');"></td>
+													  <td rowspan="2"><img src="ImageManager/locked.gif" name="locked_img" width="25" height="32" id="locked_img" alt="Locked"></td>
+													  <td rowspan="3">&nbsp;</td>
+													  <td><div align="right">V Space</div></td>
+													  <td><input name="vert" id="f_vert" type="text" size="5" style="width:4em"></td>
+												   </tr>
+												   <tr> 
+													  <td nowrap><div align="right">Alt </div></td>
+													  <td><input type="text" style="width:20em" name="alt" id="f_alt"></td>
+													  <td><div align="right">Height </div></td>
+													  <td><input name="height" id="f_height" type="text" size="5" style="width:4em" onChange="javascript:checkConstrains('height');"></td>
+													  <td><div align="right">H Space</div></td>
+													  <td><input name="horiz" id="f_horiz" type="text" size="5" style="width:4em"></td>
+												   </tr>
+												   <tr> 
+													  <td><div align="right">Upload </div></td>
+													  <td><input type="file" name="upload" id="upload"> 
+														 <input type="submit" style="width:5em" value="Upload" onClick="javascript:changeLoadingStatus('upload');" />
+													  </td>
+													  <td><div align="right">Align</div></td>
+													  <td colspan="2"><select name="align" ID="f_align" style="width:7em">
+															<OPTION id="optNotSet" value=""> Not set </OPTION>
+															<OPTION id="optLeft" value="left"> Left </OPTION>
+															<OPTION id="optRight" value="right"> Right </OPTION>
+															<OPTION id="optTexttop" value="textTop"> Texttop </OPTION>
+															<OPTION id="optAbsMiddle" value="absMiddle"> Absmiddle </OPTION>
+															<OPTION id="optBaseline" value="baseline" SELECTED> Baseline </OPTION>
+															<OPTION id="optAbsBottom" value="absBottom"> Absbottom </OPTION>
+															<OPTION id="optBottom" value="bottom"> Bottom </OPTION>
+															<OPTION id="optMiddle" value="middle"> Middle </OPTION>
+															<OPTION id="optTop" value="top"> Top </OPTION>
+													  </select></td>
+													  <td><div align="right">Border</div></td>
+													  <td><input name="border" id="f_border" type="text" size="5" style="width:4em"></td>
+												   </tr>
+												   <tr> 
+													  <td colspan="3">&nbsp;</td>
+													  <td><div align="right">
+															<input type="hidden" name="orginal_width" id="orginal_width">
+															<input type="hidden" name="orginal_height" id="orginal_height">
+															<input type="checkbox" name="constrain_prop" id="constrain_prop" checked onClick="javascript:toggleConstrains(this);">
+													  </div></td>
+													  <td colspan="5">Constrain Proportions</td>
+												   </tr>
+												</table>
+
+											 </td>
+										  </tr>
+										  <tr>
+											 <td><div style="text-align: right;"> 
+												   <hr />
+												   <button type="button" name="ok" onclick="return refresh();">Refresh</button>
+												   <button type="button" name="ok" onclick="return onOK();">OK</button>
+												   <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+											 </div></td>
+										  </tr>
+									   </table>
+									</form>
+								 </body>
+							  </html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/newFolder.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/newFolder.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/newFolder.html	(revision 795)
@@ -0,0 +1,89 @@
+<html style="width: 280; height: 150;">
+<head>
+<title>New Folder</title>
+<style type="text/css">
+<!--
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+//-->
+</style>
+<script type="text/javascript" src="../popup.js"></script>
+<script type="text/javascript" src="../../dialog.js"></script>
+<script type="text/javascript">
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+function onOK() 
+{
+	 // pass data back to the calling window
+  var fields = ["f_foldername"];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = MM_findObj(id);
+    param[id] = el.value;
+  }
+  __dlg_close(param);
+  return false;
+}
+function Init() {
+  __dlg_init();
+ MM_findObj("f_foldername").focus();
+}
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+</script>
+</head>
+<body onload="Init()">
+<div class="title">New Folder</div>
+<form action="" method="get">
+  <table width="100%" border="0" cellspacing="0" cellpadding="0">
+    <tr>
+      <td> <table border="0" cellspacing="2" cellpadding="2">
+          <tr>
+            <td>Folder Name:</td>
+            <td><input name="foldername" type="text" id="f_foldername"></td>
+          </tr>
+        </table></td>
+    <tr>
+      <td><div style="text-align: right;"> 
+          <hr />
+          <button type="button" name="ok" onclick="return onOK();">OK</button>
+          <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+        </div></td>
+    </tr>
+  </table>
+</form>
+<p>&nbsp;</p><br />
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/thumbs.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/thumbs.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/thumbs.php	(revision 795)
@@ -0,0 +1,91 @@
+<?php 
+/***********************************************************************
+** Title.........:	Thumbnail generator, with cache.
+** Version.......:	1.0
+** Author........:	Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:	thumbs.php
+** Last changed..:	1 Mar 2003 
+** Notes.........:	Configuration in config.inc.php
+
+                    - if the thumbnail does not exists or the source
+					  file is newer, create a new thumbnail.
+
+***********************************************************************/
+
+
+include 'config.inc.php';
+require_once '../ImageEditor/Transform.php';
+
+$img = $BASE_DIR.urldecode($_GET['img']);
+
+if(is_file($img)) {
+	make_thumbs(urldecode($_GET['img']));
+}
+
+
+function make_thumbs($img) 
+{
+	global $BASE_DIR, $BASE_URL;
+
+
+	$path_info = pathinfo($img);
+	$path = $path_info['dirname']."/";
+	$img_file = $path_info['basename'];
+
+	$thumb = $path.'.'.$img_file;
+
+	$img_info = getimagesize($BASE_DIR.$path.$img_file);
+	$w = $img_info[0]; $h = $img_info[1];
+	
+	$nw = 96; $nh = 96;
+
+	if($w <= $nw && $h <= $nh) {
+		header('Location: '.$BASE_URL.$path.$img_file);
+		exit();		
+	}
+
+	if(is_file($BASE_DIR.$thumb)) {
+
+		$t_mtime = filemtime($BASE_DIR.$thumb);
+		$o_mtime = filemtime($BASE_DIR.$img);
+
+		if($t_mtime > $o_mtime) {
+			//echo $BASE_URL.$path.'.'.$img_file;
+			header('Location: '.$BASE_URL.$path.'.'.$img_file);
+			exit();		
+		}
+	}
+
+	$img_thumbs = Image_Transform::factory(IMAGE_CLASS);
+	$img_thumbs->load($BASE_DIR.$path.$img_file);
+
+
+	if ($w > $h) 
+         $nh = unpercent(percent($nw, $w), $h);          
+    else if ($h > $w) 
+         $nw = unpercent(percent($nh, $h), $w); 
+
+	$img_thumbs->resize($nw, $nh);
+
+	$img_thumbs->save($BASE_DIR.$thumb);
+	$img_thumbs->free();
+
+	chmod($BASE_DIR.$thumb, 0666);
+
+	if(is_file($BASE_DIR.$thumb)) {
+		//echo "Made:".$BASE_URL.$path.'.'.$img_file;
+		header('Location: '.$BASE_URL.$path.'.'.$img_file);
+		exit();
+	}
+}
+function percent($p, $w) 
+    { 
+    return (real)(100 * ($p / $w)); 
+    } 
+
+function unpercent($percent, $whole) 
+    { 
+    return (real)(($percent * $whole) / 100); 
+    } 
+
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/images.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/images.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/images.php	(revision 795)
@@ -0,0 +1,658 @@
+<?
+/***********************************************************************
+** Title.........:	Image Manager, draws the thumbnails and directies
+** Version.......:	1.01
+** Author........:	Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:	images.php
+** Last changed..:	8 Mar 2003 
+** Notes.........:	Configuration in config.inc.php 
+
+                    Functions
+                     - create a new folder,
+                     - delete folder,
+                     - upload new image
+                     - use cached thumbnail views
+
+***********************************************************************/
+
+include 'config.inc.php';
+
+if(isset($_GET['dir'])) {
+	$dirParam = $_GET['dir'];
+
+	if(strlen($dirParam) > 0) 
+	{
+		if(substr($dirParam,0,1)=='/') 
+			$IMG_ROOT .= $dirParam;		
+		else
+			$IMG_ROOT = $dirParam;			
+	}	
+}
+
+$refresh_dirs = false;
+$clearUploads = false;
+
+if(strrpos($IMG_ROOT, '/')!= strlen($IMG_ROOT)-1) 
+	$IMG_ROOT .= '/';
+
+
+if(isset($_GET['create']) && isset($_GET['dir']) && $SAFE_MODE == false) 
+{
+	create_folder();	
+}
+
+if(isset($_GET['delFile']) && isset($_GET['dir'])) 
+{
+	delete_file($_GET['delFile']);	
+}
+
+if(isset($_GET['delFolder']) && isset($_GET['dir'])) 
+{
+	delete_folder($_GET['delFolder']);	
+}
+
+if(isset($_FILES['upload']) && is_array($_FILES['upload']) && isset($_POST['dirPath'])) 
+{
+
+	$dirPathPost = $_POST['dirPath'];
+
+	if(strlen($dirPathPost) > 0) 
+	{
+		if(substr($dirPathPost,0,1)=='/') 
+			$IMG_ROOT .= $dirPathPost;		
+		else
+			$IMG_ROOT = $dirPathPost;			
+	}
+
+	if(strrpos($IMG_ROOT, '/')!= strlen($IMG_ROOT)-1) 
+		$IMG_ROOT .= '/';
+
+	do_upload($_FILES['upload'], $BASE_DIR.$BASE_ROOT.$dirPathPost.'/');
+}
+
+function do_upload($file, $dest_dir) 
+{
+	global $clearUploads;
+
+	if(is_file($file['tmp_name'])) 
+	{
+		//var_dump($file); echo "DIR:$dest_dir";
+		move_uploaded_file($file['tmp_name'], $dest_dir.$file['name']);	
+		chmod($dest_dir.$file['name'], 0666);
+	}
+
+
+
+	$clearUploads = true;
+}
+
+function delete_folder($folder) 
+{
+	global $BASE_DIR, $refresh_dirs;
+	//var_dump($BASE_DIR);
+	$del_folder = dir_name($BASE_DIR).$folder;
+	//echo $del_folder;
+	if(is_dir($del_folder) && num_files($del_folder) <= 0) {
+		//echo $del_folder.'<br>';
+		rm_all_dir($del_folder);
+		$refresh_dirs = true;
+	}
+}
+
+function rm_all_dir($dir) 
+{
+	//$dir = dir_name($dir);
+	//echo "OPEN:".$dir.'<Br>';
+	if(is_dir($dir)) 
+	{
+		$d = @dir($dir);
+		
+		while (false !== ($entry = $d->read())) 
+		{
+			//echo "#".$entry.'<br>';
+			if($entry != '.' && $entry != '..') 
+			{
+				$node = $dir.'/'.$entry;
+				//echo "NODE:".$node;
+				if(is_file($node)) {
+					//echo " - is file<br>";
+					unlink($node);
+				}
+				else if(is_dir($node)) {
+					//echo " -	is Dir<br>";
+					rm_all_dir($node);
+				}
+			}
+		}
+		$d->close();
+
+		rmdir($dir);
+	}
+	//echo "RM: $dir <br>";
+}
+
+function delete_file($file) 
+{
+	global $BASE_DIR;
+	
+	$del_image = dir_name($BASE_DIR).$file;
+
+	$del_thumb = dir_name($del_image).'.'.basename($del_image);
+
+	if(is_file($del_image)) {
+		unlink($del_image);	
+	}
+
+	if(is_file($del_thumb)) {
+		unlink($del_thumb);	
+	}
+}
+
+function create_folder() 
+{
+	global $BASE_DIR, $IMG_ROOT, $refresh_dirs;
+	
+	$folder_name = $_GET['foldername'];
+
+	if(strlen($folder_name) >0) 
+	{
+		$folder = $BASE_DIR.$IMG_ROOT.$folder_name;
+
+		if(!is_dir($folder) && !is_file($folder))
+		{
+			mkdir($folder,0777);	
+			chmod($folder,0777);
+			$refresh_dirs = true;
+		}
+	}
+}
+
+function num_files($dir) 
+{
+	$total = 0;
+
+	if(is_dir($dir)) 
+	{
+		$d = @dir($dir);
+
+		while (false !== ($entry = $d->read())) 
+		{
+			//echo $entry."<br>";
+			if(substr($entry,0,1) != '.') {
+				$total++;
+			}
+		}
+		$d->close();
+	}
+	return $total;
+}
+
+function dirs($dir,$abs_path) 
+{
+	$d = dir($dir);
+		//echo "Handle: ".$d->handle."<br>\n";
+		//echo "Path: ".$d->path."<br>\n";
+		$dirs = array();
+		while (false !== ($entry = $d->read())) {
+			if(is_dir($dir.'/'.$entry) && substr($entry,0,1) != '.') 
+			{
+				//dirs($dir.'/'.$entry, $prefix.$prefix);
+				//echo $prefix.$entry."<br>\n";
+				$path['path'] = $dir.'/'.$entry;
+				$path['name'] = $entry;
+				$dirs[$entry] = $path;
+			}
+		}
+		$d->close();
+	
+		ksort($dirs);
+		for($i=0; $i<count($dirs); $i++) 
+		{
+			$name = key($dirs);
+			$current_dir = $abs_path.'/'.$dirs[$name]['name'];
+			echo ", \"$current_dir\"\n";
+			dirs($dirs[$name]['path'],$current_dir);
+			next($dirs);
+		}
+}
+
+function parse_size($size) 
+{
+	if($size < 1024) 
+		return $size.' btyes';	
+	else if($size >= 1024 && $size < 1024*1024) 
+	{
+		return sprintf('%01.2f',$size/1024.0).' Kb';	
+	}
+	else
+	{
+		return sprintf('%01.2f',$size/(1024.0*1024)).' Mb';	
+	}
+}
+
+function show_image($img, $file, $info, $size) 
+{
+	global $BASE_DIR, $BASE_URL, $newPath;
+
+	$img_path = dir_name($img);
+	$img_file = basename($img);
+
+	$thumb_image = 'thumbs.php?img='.urlencode($img);
+
+	$img_url = $BASE_URL.$img_path.'/'.$img_file;
+
+	$filesize = parse_size($size);
+
+?>
+<td>
+<table width="102" border="0" cellpadding="0" cellspacing="2">
+  <tr> 
+    <td align="center" class="imgBorder" onMouseOver="pviiClassNew(this,'imgBorderHover')" onMouseOut="pviiClassNew(this,'imgBorder')">
+	<a href="javascript:;" onClick="javascript:imageSelected('<? echo $img_url; ?>', <? echo $info[0];?>, <? echo $info[1]; ?>,'<? echo $file; ?>');"><img src="<? echo $thumb_image; ?>" alt="<? echo $file; ?> - <? echo $filesize; ?>" border="0"></a></td>
+  </tr>
+  <tr> 
+    <td><table width="100%" border="0" cellspacing="0" cellpadding="2">
+        <tr> 
+          <td width="1%" class="buttonOut" onMouseOver="pviiClassNew(this,'buttonHover')" onMouseOut="pviiClassNew(this,'buttonOut')">
+			<a href="javascript:;" onClick="javascript:preview('<? echo $img_url; ?>', '<? echo $file; ?>', ' <? echo $filesize; ?>',<? echo $info[0].','.$info[1]; ?>);"><img src="edit_pencil.gif" width="15" height="15" border="0"></a></td>
+          <td width="1%" class="buttonOut" onMouseOver="pviiClassNew(this,'buttonHover')" onMouseOut="pviiClassNew(this,'buttonOut')">
+			<a href="images.php?delFile=<? echo $img_url; ?>&dir=<? echo $newPath; ?>" onClick="return deleteImage('<? echo $file; ?>');"><img src="edit_trash.gif" width="15" height="15" border="0"></a></td>
+          <td width="98%" class="imgCaption"><? echo $info[0].'x'.$info[1]; ?></td>
+        </tr>
+      </table></td>
+  </tr>
+</table>
+</td>
+<?
+}
+
+function show_dir($path, $dir) 
+{
+	global $newPath, $BASE_DIR, $BASE_URL;
+
+	$num_files = num_files($BASE_DIR.$path);
+?>
+<td>
+<table width="102" border="0" cellpadding="0" cellspacing="2">
+  <tr> 
+    <td align="center" class="imgBorder" onMouseOver="pviiClassNew(this,'imgBorderHover')" onMouseOut="pviiClassNew(this,'imgBorder')">
+	  <a href="images.php?dir=<? echo $path; ?>" onClick="changeLoadingStatus('load')">
+		<img src="folder.gif" width="80" height="80" border=0 alt="<? echo $dir; ?>">
+	  </a>
+	</td>
+  </tr>
+  <tr> 
+    <td><table width="100%" border="0" cellspacing="1" cellpadding="2">
+        <tr> 
+          <td width="1%" class="buttonOut" onMouseOver="pviiClassNew(this,'buttonHover')" onMouseOut="pviiClassNew(this,'buttonOut')">
+			<a href="images.php?delFolder=<? echo $BASE_URL.$path; ?>&dir=<? echo $newPath; ?>" onClick="return deleteFolder('<? echo $dir; ?>', <? echo $num_files; ?>);"><img src="edit_trash.gif" width="15" height="15" border="0"></a></td>
+          <td width="99%" class="imgCaption"><? echo $dir; ?></td>
+        </tr>
+      </table></td>
+  </tr>
+</table>
+</td>
+<?	
+}
+
+function draw_no_results() 
+{
+?>
+<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+    <td><div align="center" style="font-size:large;font-weight:bold;color:#CCCCCC;font-family: Helvetica, sans-serif;">No Images Found</div></td>
+  </tr>
+</table>
+<?	
+}
+
+function draw_no_dir() 
+{
+	global $BASE_DIR, $BASE_ROOT;
+?>
+<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+    <td><div align="center" style="font-size:small;font-weight:bold;color:#CC0000;font-family: Helvetica, sans-serif;">Configuration Problem: &quot;<? echo $BASE_DIR.$BASE_ROOT; ?>&quot; does not exist.</div></td>
+  </tr>
+</table>
+<?	
+}
+
+
+function draw_table_header() 
+{
+	echo '<table border="0" cellpadding="0" cellspacing="2">';
+	echo '<tr>';
+}
+
+function draw_table_footer() 
+{
+	echo '</tr>';
+	echo '</table>';
+}
+
+?>
+<html>
+<head>
+<title>Image Browser</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<style type="text/css">
+<!--
+.imgBorder {
+	height: 96px;
+	border: 1px solid threedface;
+	vertical-align: middle;
+}
+.imgBorderHover {
+	height: 96px;
+	border: 1px solid threedface;
+	vertical-align: middle;
+	background: #FFFFCC;
+	cursor: hand;
+}
+
+.buttonHover {
+	border: 1px solid;
+	border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+	cursor: hand;
+	background: #FFFFCC;
+}
+.buttonOut
+{
+ border: 1px solid;
+ border-color: white;
+}
+
+.imgCaption {
+	font-size: 9pt;
+	font-family: "MS Shell Dlg", Helvetica, sans-serif;
+	text-align: center;
+}
+.dirField {
+	font-size: 9pt;
+	font-family: "MS Shell Dlg", Helvetica, sans-serif;
+	width:110px;
+}
+
+-->
+</style>
+<?
+	$dirPath = eregi_replace($BASE_ROOT,'',$IMG_ROOT);
+
+	$paths = explode('/', $dirPath);
+	$upDirPath = '/';
+	for($i=0; $i<count($paths)-2; $i++) 
+	{
+		$path = $paths[$i];
+		if(strlen($path) > 0) 
+		{
+			$upDirPath .= $path.'/';
+		}
+	}
+
+	$slashIndex = strlen($dirPath);
+	$newPath = $dirPath;
+	if($slashIndex > 1 && substr($dirPath, $slashIndex-1, $slashIndex) == '/')
+	{
+		$newPath = substr($dirPath, 0,$slashIndex-1);
+	}
+?>
+<script type="text/javascript" src="../popup.js"></script>
+<script type="text/javascript" src="../../../../dialog.js"></script>
+<script language="JavaScript" type="text/JavaScript">
+<!--
+function pviiClassNew(obj, new_style) { //v2.6 by PVII
+  obj.className=new_style;
+}
+
+function goUp() 
+{
+	location.href = "ImageManager/images.php?dir=<? echo $upDirPath; ?>";
+}
+
+function changeDir(newDir) 
+{
+	location.href = "ImageManager/images.php?dir="+newDir;
+}
+
+function newFolder(oldDir, newFolder) 
+{
+	location.href = "ImageManager/images.php?dir="+oldDir+'&create=folder&foldername='+newFolder;
+}
+
+function updateDir() 
+{
+	var newPath = "<? echo $newPath; ?>";
+	if(window.top.document.forms[0] != null) {
+		
+	var allPaths = window.top.document.forms[0].dirPath.options;
+	//alert("new:"+newPath);
+	for(i=0; i<allPaths.length; i++) 
+	{
+		//alert(allPaths.item(i).value);
+		allPaths.item(i).selected = false;
+		if((allPaths.item(i).value)==newPath) 
+		{
+			allPaths.item(i).selected = true;
+		}
+	}
+
+<?
+	if($clearUploads) {
+?>
+	var topDoc = window.top.document.forms[0];
+	topDoc.upload.value = null;
+	//topDoc.upload.disabled = true;
+<?
+	}
+?>
+
+	}
+
+}
+
+<? if ($refresh_dirs) { ?>
+function refreshDirs() 
+{
+	var allPaths = window.top.document.forms[0].dirPath.options;
+	var fields = ["/" <? dirs($BASE_DIR.$BASE_ROOT,'');?>];
+
+	var newPath = "<? echo $newPath; ?>";
+
+	while(allPaths.length > 0) 
+	{
+		for(i=0; i<allPaths.length; i++) 
+		{
+			allPaths.remove(i);	
+		}		
+	}
+
+	for(i=0; i<fields.length; i++) 
+	{
+		var newElem =	document.createElement("OPTION");
+		var newValue = fields[i];
+		newElem.text = newValue;
+		newElem.value = newValue;
+
+		if(newValue == newPath) 
+			newElem.selected = true;	
+		else
+			newElem.selected = false;
+
+		allPaths.add(newElem);
+	}
+}
+refreshDirs();
+<? } ?>
+
+function imageSelected(filename, width, height, alt) 
+{
+	var topDoc = window.top.document.forms[0];
+	topDoc.f_url.value = filename;
+	topDoc.f_width.value= width;
+	topDoc.f_height.value = height;
+	topDoc.f_alt.value = alt;
+	topDoc.orginal_width.value = width;
+	topDoc.orginal_height.value = height;
+	
+}
+
+function preview(file, image, size, width, height) 
+{
+	/*
+	var predoc = '<img src="'+file+'" alt="'+image+' ('+width+'x'+height+', '+size+')">';
+	var w = 450;
+	var h = 400;
+	var LeftPosition=(screen.width)?(screen.width-w)/2:100;
+	var TopPosition=(screen.height)?(screen.height-h)/2:100;
+     
+	 var win = window.open('','image_preview','toolbar=no,location=no,menubar=no,status=yes,scrollbars=yes,resizable=yes,width='+w+',height='+h+',top='+TopPosition+',left='+LeftPosition);
+     var doc=win.document.open();
+
+     doc.writeln('<html>\n<head>\n<title>Image Preview - '+image+' ('+width+'x'+height+', '+size+')</title>');
+     doc.writeln('</head>\n<body>');
+     doc.writeln(predoc);
+     doc.writeln('</body>\n</html>\n');
+     doc=win.document.close();
+     win.focus();*/
+	//alert(file);
+	 Dialog("../ImageEditor/ImageEditor.php?img="+escape(file), function(param) {
+		if (!param) {	// user must have pressed Cancel
+			return false;
+		}
+	}, null);
+     return;
+}
+
+function deleteImage(file) 
+{
+	if(confirm("Delete image \""+file+"\"?")) 
+		return true;
+
+	return false;
+}
+
+function deleteFolder(folder, numFiles) 
+{
+	if(numFiles > 0) {
+		alert("There are "+numFiles+" files/folders in \""+folder+"\".\n\nPlease delete all files/folder in \""+folder+"\" first.");
+		return false;
+	}
+
+	if(confirm("Delete folder \""+folder+"\"?")) 
+		return true;
+
+	return false;
+}
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+function MM_showHideLayers() { //v6.0
+  var i,p,v,obj,args=MM_showHideLayers.arguments;
+  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i],window.top.document))!=null) { v=args[i+2];
+    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
+    obj.visibility=v; }
+}
+
+function changeLoadingStatus(state) 
+{
+	var statusText = null;
+	if(state == 'load') {
+		statusText = 'Loading Images';	
+	}
+	else if(state == 'upload') {
+		statusText = 'Uploading Files';
+	}
+	if(statusText != null) {
+		var obj = MM_findObj('loadingStatus', window.top.document);
+		//alert(obj.innerHTML);
+		if (obj != null && obj.innerHTML != null)
+			obj.innerHTML = statusText;
+		MM_showHideLayers('loading','','show')		
+	}
+}
+
+//-->
+</script>
+</head>
+<body onLoad="updateDir();" bgcolor="#FFFFFF">
+
+<?
+//var_dump($_GET);
+//echo $dirParam.':'.$upDirPath;
+//echo '<br>';
+$d = @dir($BASE_DIR.$IMG_ROOT);
+
+if($d) 
+{
+	//var_dump($d);
+	$images = array();
+	$folders = array();
+	while (false !== ($entry = $d->read())) 
+	{
+		$img_file = $IMG_ROOT.$entry; 
+
+		if(is_file($BASE_DIR.$img_file) && substr($entry,0,1) != '.') 
+		{
+			$image_info = @getimagesize($BASE_DIR.$img_file);
+			if(is_array($image_info)) 
+			{
+				$file_details['file'] = $img_file;
+				$file_details['img_info'] = $image_info;
+				$file_details['size'] = filesize($BASE_DIR.$img_file);
+				$images[$entry] = $file_details;
+				//show_image($img_file, $entry, $image_info);
+			}
+		}
+		else if(is_dir($BASE_DIR.$img_file) && substr($entry,0,1) != '.') 
+		{
+			$folders[$entry] = $img_file;
+			//show_dir($img_file, $entry);	
+		}
+	}
+	$d->close();	
+	
+	if(count($images) > 0 || count($folders) > 0) 
+	{	
+		//now sort the folders and images by name.
+		ksort($images);
+		ksort($folders);
+
+		draw_table_header();
+
+		for($i=0; $i<count($folders); $i++) 
+		{
+			$folder_name = key($folders);		
+			show_dir($folders[$folder_name], $folder_name);
+			next($folders);
+		}
+		for($i=0; $i<count($images); $i++) 
+		{
+			$image_name = key($images);
+			show_image($images[$image_name]['file'], $image_name, $images[$image_name]['img_info'], $images[$image_name]['size']);
+			next($images);
+		}
+		draw_table_footer();
+	}
+	else
+	{
+		draw_no_results();
+	}
+}
+else
+{
+	draw_no_dir();
+}
+
+?>
+<script language="JavaScript" type="text/JavaScript">
+MM_showHideLayers('loading','','hide')
+</script>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/config.inc.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/config.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/ImageManager/config.inc.php	(revision 795)
@@ -0,0 +1,64 @@
+<?
+
+//************************** BEGIN CONFIGURATION *****************************//
+
+//example, this is the actual file system path
+//of the web server document root. e.g.
+// Filesystem == /home/web/www.yourdomain.com 
+$BASE_DIR = $GLOBALS[UploadImageBaseDir];
+$BASE_URL = $GLOBALS[UploadImageBaseURL];
+$BASE_ROOT = $GLOBALS[UploadImageRelativePath];
+
+var_dump($BASE_DIR);
+var_dump($BASE_URL);
+var_dump($BASE_ROOT);
+
+//$BASE_DIR = $_SERVER['DOCUMENT_ROOT'];
+//$BASE_DIR = '/home/www';
+
+//the path where the browser sees the document root (i.e. http://www.yourdomain.com/)
+//$BASE_URL = 'https://192.168.0.2/';
+
+//this is where the images will be stored relative to the $BASE_DIR (and $BASE_URL)
+//this directory MUST be readable AND writable by the web server.
+//$BASE_ROOT = ''; 
+
+//The image manipulation library to use, either GD or ImageMagick or NetPBM
+//valid definitions are 'GD' or 'IM' or 'NetPBM'.
+define('IMAGE_CLASS', 'GD'); // 
+
+//After defining which library to use, if it is NetPBM or IM, you need to
+//specify where the binary for the selected library are. And of course
+//your server and PHP must be able to execute them (i.e. safe mode is OFF).
+//If you have safe mode ON, or don't have the binaries, your choice is
+//GD only. GD does not require the following definition.
+define('IMAGE_TRANSFORM_LIB_PATH', '/usr/bin/netpbm/');
+//define('IMAGE_TRANSFORM_LIB_PATH', '"D:\\Program Files\\ImageMagick\\');
+
+
+//In safe mode, directory creation is not permitted.
+$SAFE_MODE = false;
+
+//************************** END CONFIGURATION *****************************//
+
+$IMG_ROOT = $BASE_ROOT;
+
+if(strrpos($BASE_DIR, '/')!= strlen($BASE_DIR)-1) 
+	$BASE_DIR .= '/';
+
+if(strrpos($BASE_URL, '/')!= strlen($BASE_URL)-1) 
+$BASE_URL .= '/';
+
+//Built in function of dirname is faulty
+//It assumes that the directory nane can not contain a . (period)
+function dir_name($dir) 
+{
+	$lastSlash = intval(strrpos($dir, '/'));
+	if($lastSlash == strlen($dir)-1){
+		return substr($dir, 0, $lastSlash);
+	}
+	else
+		return dirname($dir);
+}
+
+?>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/popup.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/popup.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/UploadImage/popups/popup.js	(revision 795)
@@ -0,0 +1,50 @@
+function __dlg_onclose() {
+	if (!document.all) {
+		opener.Dialog._return(null);
+	}
+};
+
+function __dlg_init() {
+
+	if (!document.all) {
+		// init dialogArguments, as IE gets it
+		window.dialogArguments = opener.Dialog._arguments;
+		window.sizeToContent();
+		window.sizeToContent();	// for reasons beyond understanding,
+					// only if we call it twice we get the
+					// correct size.
+		window.addEventListener("unload", __dlg_onclose, true);
+		/*
+		// center on parent
+		var px1 = opener.screenX;
+		var px2 = opener.screenX + opener.outerWidth;
+		var py1 = opener.screenY;
+		var py2 = opener.screenY + opener.outerHeight;
+		var x = (px2 - px1 - window.outerWidth) / 2;
+		var y = (py2 - py1 - window.outerHeight) / 2; */
+
+		//centre on screen instead
+
+		var x = (screen.width - window.outerWidth) / 2;
+		var y = (screen.height - window.outerHeight) / 2;
+
+		window.moveTo(x, y);
+		var body = document.body;
+		window.innerHeight = body.offsetHeight;
+		window.innerWidth = body.offsetWidth;
+	} else {
+		var body = document.body;
+		window.dialogHeight = body.offsetHeight + 50 + "px";
+		window.dialogWidth = body.offsetWidth + "px";
+	}
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+	if (document.all) {	// IE
+		window.returnValue = val;
+	} else {
+		opener.Dialog._return(val);
+	}
+	window.close();
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/CSS/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/CSS/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/CSS/lang/en.js	(revision 795)
@@ -0,0 +1,2 @@
+// none yet; this file is a stub.
+CSS.I18N = {};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/CSS/css.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/CSS/css.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/CSS/css.js	(revision 795)
@@ -0,0 +1,115 @@
+// Simple CSS (className) plugin for the editor
+// Sponsored by http://www.miro.com.au
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo.
+//
+// (c) dynarch.com 2003
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+
+function CSS(editor, params) {
+	this.editor = editor;
+	var cfg = editor.config;
+	var toolbar = cfg.toolbar;
+	var self = this;
+	var i18n = CSS.I18N;
+	var plugin_config = params[0];
+	var combos = plugin_config.combos;
+
+	var first = true;
+	for (var i = combos.length; --i >= 0;) {
+		var combo = combos[i];
+		var id = "CSS-class" + i;
+		var css_class = {
+			id         : id,
+			options    : combo.options,
+			action     : function(editor) { self.onSelect(editor, this, combo.context, combo.updatecontextclass); },
+			refresh    : function(editor) { self.updateValue(editor, this); },
+			context    : combo.context
+		};
+		cfg.registerDropdown(css_class);
+
+		// prepend to the toolbar
+		toolbar[1].splice(0, 0, first ? "separator" : "space");
+		toolbar[1].splice(0, 0, id);
+		if (combo.label)
+			toolbar[1].splice(0, 0, "T[" + combo.label + "]");
+		first = false;
+	}
+};
+
+CSS._pluginInfo = {
+	name          : "CSS",
+	version       : "1.0",
+	developer     : "Mihai Bazon",
+	developer_url : "http://dynarch.com/mishoo/",
+	c_owner       : "Mihai Bazon",
+	sponsor       : "Miro International",
+	sponsor_url   : "http://www.miro.com.au",
+	license       : "htmlArea"
+};
+
+CSS.prototype.onSelect = function(editor, obj, context, updatecontextclass) {
+	var tbobj = editor._toolbarObjects[obj.id];
+	var index = tbobj.element.selectedIndex;
+	var className = tbobj.element.value;
+
+	// retrieve parent element of the selection
+	var parent = editor.getParentElement();
+	var surround = true;
+
+	var is_span = (parent && parent.tagName.toLowerCase() == "span");
+	var update_parent = (context && updatecontextclass && parent && parent.tagName.toLowerCase() == context);
+
+	if (update_parent) {
+		parent.className = className;
+		editor.updateToolbar();
+		return;
+	}
+
+	if (is_span && index == 0 && !/\S/.test(parent.style.cssText)) {
+		while (parent.firstChild) {
+			parent.parentNode.insertBefore(parent.firstChild, parent);
+		}
+		parent.parentNode.removeChild(parent);
+		editor.updateToolbar();
+		return;
+	}
+
+	if (is_span) {
+		// maybe we could simply change the class of the parent node?
+		if (parent.childNodes.length == 1) {
+			parent.className = className;
+			surround = false;
+			// in this case we should handle the toolbar updation
+			// ourselves.
+			editor.updateToolbar();
+		}
+	}
+
+	// Other possibilities could be checked but require a lot of code.  We
+	// can't afford to do that now.
+	if (surround) {
+		// shit happens ;-) most of the time.  this method works, but
+		// it's dangerous when selection spans multiple block-level
+		// elements.
+		editor.surroundHTML("<span class='" + className + "'>", "</span>");
+	}
+};
+
+CSS.prototype.updateValue = function(editor, obj) {
+	var select = editor._toolbarObjects[obj.id].element;
+	var parent = editor.getParentElement();
+	if (typeof parent.className != "undefined" && /\S/.test(parent.className)) {
+		var options = select.options;
+		var value = parent.className;
+		for (var i = options.length; --i >= 0;) {
+			var option = options[i];
+			if (value == option.value) {
+				select.selectedIndex = i;
+				return;
+			}
+		}
+	}
+	select.selectedIndex = 0;
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/context-menu.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/context-menu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/context-menu.js	(revision 795)
@@ -0,0 +1,415 @@
+// Context Menu Plugin for HTMLArea-3.0
+// Sponsored by www.americanbible.org
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+
+HTMLArea.loadStyle("menu.css", "ContextMenu");
+
+function ContextMenu(editor) {
+	this.editor = editor;
+};
+
+ContextMenu._pluginInfo = {
+	name          : "ContextMenu",
+	version       : "1.0",
+	developer     : "Mihai Bazon",
+	developer_url : "http://dynarch.com/mishoo/",
+	c_owner       : "dynarch.com",
+	sponsor       : "American Bible Society",
+	sponsor_url   : "http://www.americanbible.org",
+	license       : "htmlArea"
+};
+
+ContextMenu.prototype.onGenerate = function() {
+	var self = this;
+	var doc = this.editordoc = this.editor._iframe.contentWindow.document;
+	HTMLArea._addEvents(doc, ["contextmenu"],
+			    function (event) {
+				    return self.popupMenu(HTMLArea.is_ie ? self.editor._iframe.contentWindow.event : event);
+			    });
+	this.currentMenu = null;
+};
+
+ContextMenu.prototype.getContextMenu = function(target) {
+	var self = this;
+	var editor = this.editor;
+	var config = editor.config;
+	var menu = [];
+	var tbo = this.editor.plugins.TableOperations;
+	if (tbo) tbo = tbo.instance;
+	var i18n = ContextMenu.I18N;
+
+	var selection = editor.hasSelectedText();
+	if (selection)
+		menu.push([ i18n["Cut"], function() { editor.execCommand("cut"); }, null, config.btnList["cut"][1] ],
+			  [ i18n["Copy"], function() { editor.execCommand("copy"); }, null, config.btnList["copy"][1] ]);
+	menu.push([ i18n["Paste"], function() { editor.execCommand("paste"); }, null, config.btnList["paste"][1] ]);
+
+	var currentTarget = target;
+	var elmenus = [];
+
+	var link = null;
+	var table = null;
+	var tr = null;
+	var td = null;
+	var img = null;
+
+	function tableOperation(opcode) {
+		tbo.buttonPress(editor, opcode);
+	};
+
+	for (; target; target = target.parentNode) {
+		var tag = target.tagName;
+		if (!tag)
+			continue;
+		tag = tag.toLowerCase();
+		switch (tag) {
+		    case "img":
+			img = target;
+			elmenus.push(null,
+				     [ i18n["Image Properties"],
+				       function() {
+					       editor._insertImage(img);
+				       },
+				       i18n["Show the image properties dialog"],
+				       config.btnList["insertimage"][1] ]
+				);
+			break;
+		    case "a":
+			link = target;
+			elmenus.push(null,
+				     [ i18n["Modify Link"],
+				       function() { editor.execCommand("createlink", true); },
+				       i18n["Current URL is"] + ': ' + link.href,
+				       config.btnList["createlink"][1] ],
+
+				     [ i18n["Check Link"],
+				       function() { window.open(link.href); },
+				       i18n["Opens this link in a new window"] ],
+
+				     [ i18n["Remove Link"],
+				       function() {
+					       if (confirm(i18n["Please confirm that you want to unlink this element."] + "\n" +
+							   i18n["Link points to:"] + " " + link.href)) {
+						       while (link.firstChild)
+							       link.parentNode.insertBefore(link.firstChild, link);
+						       link.parentNode.removeChild(link);
+					       }
+				       },
+				       i18n["Unlink the current element"] ]
+				);
+			break;
+		    case "td":
+			td = target;
+			if (!tbo) break;
+			elmenus.push(null,
+				     [ i18n["Cell Properties"],
+				       function() { tableOperation("TO-cell-prop"); },
+				       i18n["Show the Table Cell Properties dialog"],
+				       config.btnList["TO-cell-prop"][1] ]
+				);
+			break;
+		    case "tr":
+			tr = target;
+			if (!tbo) break;
+			elmenus.push(null,
+				     [ i18n["Row Properties"],
+				       function() { tableOperation("TO-row-prop"); },
+				       i18n["Show the Table Row Properties dialog"],
+				       config.btnList["TO-row-prop"][1] ],
+
+				     [ i18n["Insert Row Before"],
+				       function() { tableOperation("TO-row-insert-above"); },
+				       i18n["Insert a new row before the current one"],
+				       config.btnList["TO-row-insert-above"][1] ],
+
+				     [ i18n["Insert Row After"],
+				       function() { tableOperation("TO-row-insert-under"); },
+				       i18n["Insert a new row after the current one"],
+				       config.btnList["TO-row-insert-under"][1] ],
+
+				     [ i18n["Delete Row"],
+				       function() { tableOperation("TO-row-delete"); },
+				       i18n["Delete the current row"],
+				       config.btnList["TO-row-delete"][1] ]
+				);
+			break;
+		    case "table":
+			table = target;
+			if (!tbo) break;
+			elmenus.push(null,
+				     [ i18n["Table Properties"],
+				       function() { tableOperation("TO-table-prop"); },
+				       i18n["Show the Table Properties dialog"],
+				       config.btnList["TO-table-prop"][1] ],
+
+				     [ i18n["Insert Column Before"],
+				       function() { tableOperation("TO-col-insert-before"); },
+				       i18n["Insert a new column before the current one"],
+				       config.btnList["TO-col-insert-before"][1] ],
+
+				     [ i18n["Insert Column After"],
+				       function() { tableOperation("TO-col-insert-after"); },
+				       i18n["Insert a new column after the current one"],
+				       config.btnList["TO-col-insert-after"][1] ],
+
+				     [ i18n["Delete Column"],
+				       function() { tableOperation("TO-col-delete"); },
+				       i18n["Delete the current column"],
+				       config.btnList["TO-col-delete"][1] ]
+				);
+			break;
+		    case "body":
+			elmenus.push(null,
+				     [ i18n["Justify Left"],
+				       function() { editor.execCommand("justifyleft"); }, null,
+				       config.btnList["justifyleft"][1] ],
+				     [ i18n["Justify Center"],
+				       function() { editor.execCommand("justifycenter"); }, null,
+				       config.btnList["justifycenter"][1] ],
+				     [ i18n["Justify Right"],
+				       function() { editor.execCommand("justifyright"); }, null,
+				       config.btnList["justifyright"][1] ],
+				     [ i18n["Justify Full"],
+				       function() { editor.execCommand("justifyfull"); }, null,
+				       config.btnList["justifyfull"][1] ]
+				);
+			break;
+		}
+	}
+
+	if (selection && !link)
+		menu.push(null, [ i18n["Make link"],
+				  function() { editor.execCommand("createlink", true); },
+				  i18n["Create a link"],
+				  config.btnList["createlink"][1] ]);
+
+	for (var i in elmenus)
+		menu.push(elmenus[i]);
+
+	menu.push(null,
+		  [ i18n["Remove the"] + " &lt;" + currentTarget.tagName + "&gt; " + i18n["Element"],
+		    function() {
+			    if (confirm(i18n["Please confirm that you want to remove this element:"] + " " + currentTarget.tagName)) {
+				    var el = currentTarget;
+				    var p = el.parentNode;
+				    p.removeChild(el);
+				    if (HTMLArea.is_gecko) {
+					    if (p.tagName.toLowerCase() == "td" && !p.hasChildNodes())
+						    p.appendChild(editor._doc.createElement("br"));
+					    editor.forceRedraw();
+					    editor.focusEditor();
+					    editor.updateToolbar();
+					    if (table) {
+						    var save_collapse = table.style.borderCollapse;
+						    table.style.borderCollapse = "collapse";
+						    table.style.borderCollapse = "separate";
+						    table.style.borderCollapse = save_collapse;
+					    }
+				    }
+			    }
+		    },
+		    i18n["Remove this node from the document"] ]);
+	return menu;
+};
+
+ContextMenu.prototype.popupMenu = function(ev) {
+	var self = this;
+	var i18n = ContextMenu.I18N;
+	if (this.currentMenu)
+		this.currentMenu.parentNode.removeChild(this.currentMenu);
+	function getPos(el) {
+		var r = { x: el.offsetLeft, y: el.offsetTop };
+		if (el.offsetParent) {
+			var tmp = getPos(el.offsetParent);
+			r.x += tmp.x;
+			r.y += tmp.y;
+		}
+		return r;
+	};
+	function documentClick(ev) {
+		ev || (ev = window.event);
+		if (!self.currentMenu) {
+			alert(i18n["How did you get here? (Please report!)"]);
+			return false;
+		}
+		var el = HTMLArea.is_ie ? ev.srcElement : ev.target;
+		for (; el != null && el != self.currentMenu; el = el.parentNode);
+		if (el == null)
+			self.closeMenu();
+		//HTMLArea._stopEvent(ev);
+		//return false;
+	};
+	var keys = [];
+	function keyPress(ev) {
+		ev || (ev = window.event);
+		HTMLArea._stopEvent(ev);
+		if (ev.keyCode == 27) {
+			self.closeMenu();
+			return false;
+		}
+		var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
+		for (var i = keys.length; --i >= 0;) {
+			var k = keys[i];
+			if (k[0].toLowerCase() == key)
+				k[1].__msh.activate();
+		}
+	};
+	self.closeMenu = function() {
+		self.currentMenu.parentNode.removeChild(self.currentMenu);
+		self.currentMenu = null;
+		HTMLArea._removeEvent(document, "mousedown", documentClick);
+		HTMLArea._removeEvent(self.editordoc, "mousedown", documentClick);
+		if (keys.length > 0)
+			HTMLArea._removeEvent(self.editordoc, "keypress", keyPress);
+		if (HTMLArea.is_ie)
+			self.iePopup.hide();
+	};
+	var target = HTMLArea.is_ie ? ev.srcElement : ev.target;
+	var ifpos = getPos(self.editor._iframe);
+	var x = ev.clientX + ifpos.x;
+	var y = ev.clientY + ifpos.y;
+
+	var div;
+	var doc;
+	if (!HTMLArea.is_ie) {
+		doc = document;
+	} else {
+		// IE stinks
+		var popup = this.iePopup = window.createPopup();
+		doc = popup.document;
+		doc.open();
+		doc.write("<html><head><style type='text/css'>@import url(" + _editor_url + "plugins/ContextMenu/menu.css); html, body { padding: 0px; margin: 0px; overflow: hidden; border: 0px; }</style></head><body unselectable='yes'></body></html>");
+		doc.close();
+	}
+	div = doc.createElement("div");
+	if (HTMLArea.is_ie)
+		div.unselectable = "on";
+	div.oncontextmenu = function() { return false; };
+	div.className = "htmlarea-context-menu";
+	if (!HTMLArea.is_ie)
+		div.style.left = div.style.top = "0px";
+	doc.body.appendChild(div);
+
+	var table = doc.createElement("table");
+	div.appendChild(table);
+	table.cellSpacing = 0;
+	table.cellPadding = 0;
+	var parent = doc.createElement("tbody");
+	table.appendChild(parent);
+
+	var options = this.getContextMenu(target);
+	for (var i = 0; i < options.length; ++i) {
+		var option = options[i];
+		var item = doc.createElement("tr");
+		parent.appendChild(item);
+		if (HTMLArea.is_ie)
+			item.unselectable = "on";
+		else item.onmousedown = function(ev) {
+			HTMLArea._stopEvent(ev);
+			return false;
+		};
+		if (!option) {
+			item.className = "separator";
+			var td = doc.createElement("td");
+			td.className = "icon";
+			var IE_IS_A_FUCKING_SHIT = '>';
+			if (HTMLArea.is_ie) {
+				td.unselectable = "on";
+				IE_IS_A_FUCKING_SHIT = " unselectable='on' style='height=1px'>&nbsp;";
+			}
+			td.innerHTML = "<div" + IE_IS_A_FUCKING_SHIT + "</div>";
+			var td1 = td.cloneNode(true);
+			td1.className = "label";
+			item.appendChild(td);
+			item.appendChild(td1);
+		} else {
+			var label = option[0];
+			item.className = "item";
+			item.__msh = {
+				item: item,
+				label: label,
+				action: option[1],
+				tooltip: option[2] || null,
+				icon: option[3] || null,
+				activate: function() {
+					self.closeMenu();
+					self.editor.focusEditor();
+					this.action();
+				}
+			};
+			label = label.replace(/_([a-zA-Z0-9])/, "<u>$1</u>");
+			if (label != option[0])
+				keys.push([ RegExp.$1, item ]);
+			label = label.replace(/__/, "_");
+			var td1 = doc.createElement("td");
+			if (HTMLArea.is_ie)
+				td1.unselectable = "on";
+			item.appendChild(td1);
+			td1.className = "icon";
+			if (item.__msh.icon)
+				td1.innerHTML = "<img align='middle' src='" + item.__msh.icon + "' />";
+			var td2 = doc.createElement("td");
+			if (HTMLArea.is_ie)
+				td2.unselectable = "on";
+			item.appendChild(td2);
+			td2.className = "label";
+			td2.innerHTML = label;
+			item.onmouseover = function() {
+				this.className += " hover";
+				self.editor._statusBarTree.innerHTML = this.__msh.tooltip || '&nbsp;';
+			};
+			item.onmouseout = function() { this.className = "item"; };
+			item.oncontextmenu = function(ev) {
+				this.__msh.activate();
+				if (!HTMLArea.is_ie)
+					HTMLArea._stopEvent(ev);
+				return false;
+			};
+			item.onmouseup = function(ev) {
+				var timeStamp = (new Date()).getTime();
+				if (timeStamp - self.timeStamp > 500)
+					this.__msh.activate();
+				if (!HTMLArea.is_ie)
+					HTMLArea._stopEvent(ev);
+				return false;
+			};
+			//if (typeof option[2] == "string")
+			//item.title = option[2];
+		}
+	}
+
+	if (!HTMLArea.is_ie) {
+		var dx = x + div.offsetWidth - window.innerWidth + 4;
+		var dy = y + div.offsetHeight - window.innerHeight + 4;
+		if (dx > 0) x -= dx;
+		if (dy > 0) y -= dy;
+		div.style.left = x + "px";
+		div.style.top = y + "px";
+	} else {
+		// determine the size (did I mention that IE stinks?)
+		var foobar = document.createElement("div");
+		foobar.className = "htmlarea-context-menu";
+		foobar.innerHTML = div.innerHTML;
+		document.body.appendChild(foobar);
+		var w = foobar.offsetWidth;
+		var h = foobar.offsetHeight;
+		document.body.removeChild(foobar);
+		this.iePopup.show(ev.screenX, ev.screenY, w, h);
+	}
+
+	this.currentMenu = div;
+	this.timeStamp = (new Date()).getTime();
+
+	HTMLArea._addEvent(document, "mousedown", documentClick);
+	HTMLArea._addEvent(this.editordoc, "mousedown", documentClick);
+	if (keys.length > 0)
+		HTMLArea._addEvent(this.editordoc, "keypress", keyPress);
+
+	HTMLArea._stopEvent(ev);
+	return false;
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/de.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/de.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/de.js	(revision 795)
@@ -0,0 +1,59 @@
+﻿// I18N constants
+
+// LANG: "de", ENCODING: UTF-8 | ISO-8859-1
+
+// translated: <]{MJ}[>  i@student.ethz.ch
+
+
+ContextMenu.I18N = {
+	// Items that appear in menu.  Please note that an underscore (_)
+	// character in the translation (right column) will cause the following
+	// letter to become underlined and be shortcut for that menu option.
+
+	"Cut"                                                   : "Ausschneiden",
+	"Copy"                                                  : "Kopieren",
+	"Paste"                                                 : "Einfügen",
+	"Image Properties"                                      : "_Bild Einstellungen...",
+	"Modify Link"                                           : "_Link ändern...",
+	"Check Link"                                            : "Link testen...",
+	"Remove Link"                                           : "Link entfernen...",
+	"Cell Properties"                                       : "Z_ellen Einstellungen...",
+	"Row Properties"                                        : "Ze_ilen Einstellungen...",
+	"Insert Row Before"                                     : "Zeile einfügen v_or Position",
+	"Insert Row After"                                      : "Zeile einfügen n_ach Position",
+	"Delete Row"                                            : "Zeile löschen",
+	"Table Properties"                                      : "_Tabellen Einstellungen...",
+	"Insert Column Before"                                  : "Spalte einfügen vo_r Position",
+	"Insert Column After"                                   : "Spalte einfügen na_ch Position",
+	"Delete Column"                                         : "Spalte löschen",
+	"Justify Left"                                          : "Links ausrichten",
+	"Justify Center"                                        : "Zentriert",
+	"Justify Right"                                         : "Rechts ausrichten",
+	"Justify Full"                                          : "Blocksatz",
+	"Make link"                                             : "Lin_k erstellen...",
+	"Remove the"                                            : "",
+	"Element"                                               : "Element entfernen...",
+
+	// Other labels (tooltips and alert/confirm box messages)
+
+	"Please confirm that you want to remove this element:"  : "Wollen sie dieses Element wirklich entfernen ?",
+	"Remove this node from the document"                    : "Dieses Element aus dem Dokument entfernen",
+	"How did you get here? (Please report!)"                : "How did you get here? (Please report!)",
+	"Show the image properties dialog"                      : "Fenster für die Bild-Einstellungen anzeigen",
+	"Modify URL"                                            : "URL ändern",
+	"Current URL is"                                        : "Aktuelle URL ist",
+	"Opens this link in a new window"                       : "Diesen Link in neuem Fenster öffnen",
+	"Please confirm that you want to unlink this element."  : "Wollen sie diesen Link wirklich entfernen ?",
+	"Link points to:"                                       : "Link zeigt auf:",
+	"Unlink the current element"                            : "Link auf Element entfernen",
+	"Show the Table Cell Properties dialog"                 : "Zellen-Einstellungen anzeigen",
+	"Show the Table Row Properties dialog"                  : "Zeilen-Einstellungen anzeigen",
+	"Insert a new row before the current one"               : "Zeile einfügen vor der aktuellen Position",
+	"Insert a new row after the current one"                : "Zeile einfügen nach der aktuellen Position",
+	"Delete the current row"                                : "Zeile löschen",
+	"Show the Table Properties dialog"                      : "Show the Table Properties dialog",
+	"Insert a new column before the current one"            : "Spalte einfügen vor der aktuellen Position",
+	"Insert a new column after the current one"             : "Spalte einfügen nach der aktuellen Position",
+	"Delete the current column"                             : "Spalte löschen",
+	"Create a link"                                         : "Link erstellen"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/nl.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/nl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/nl.js	(revision 795)
@@ -0,0 +1,66 @@
+// I18N constants
+
+// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1
+// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+ContextMenu.I18N = {
+	// Items that appear in menu.  Please note that an underscore (_)
+	// character in the translation (right column) will cause the following
+	// letter to become underlined and be shortcut for that menu option.
+
+	"Cut"                                                   : "Knippen",
+	"Copy"                                                  : "Kopiëren",
+	"Paste"                                                 : "Plakken",
+	"Image Properties"                                      : "Eigenschappen afbeelding...",
+	"Modify Link"                                           : "Hyperlin_k aanpassen...",
+	"Check Link"                                            : "Controleer hyperlin_k...",
+	"Remove Link"                                           : "Ve_rwijder hyperlink...",
+	"Cell Properties"                                       : "C_eleigenschappen...",
+	"Row Properties"                                        : "Rijeigenscha_ppen...",
+	"Insert Row Before"                                     : "Rij invoegen boven",
+	"Insert Row After"                                      : "Rij invoegen onder",
+	"Delete Row"                                            : "Rij _verwijderen",
+	"Table Properties"                                      : "_Tabeleigenschappen...",
+	"Insert Column Before"                                  : "Kolom invoegen voor",
+	"Insert Column After"                                   : "Kolom invoegen na",
+	"Delete Column"                                         : "Kolom verwijderen",
+	"Justify Left"                                          : "Links uitlijnen",
+	"Justify Center"                                        : "Centreren",
+	"Justify Right"                                         : "Rechts uitlijnen",
+	"Justify Full"                                          : "Uitvullen",
+	"Make link"                                             : "Maak hyperlin_k...",
+	"Remove the"                                            : "Verwijder het",
+	"Element"                                               : "element...",
+
+	// Other labels (tooltips and alert/confirm box messages)
+
+	"Please confirm that you want to remove this element:"  : "Is het werkelijk de bedoeling dit element te verwijderen:",
+	"Remove this node from the document"                    : "Verwijder dit punt van het document",
+	"How did you get here? (Please report!)"                : "Hoe kwam je hier? (A.U.B. doorgeven!)",
+	"Show the image properties dialog"                      : "Laat het afbeeldingseigenschappen dialog zien",
+	"Modify URL"                                            : "Aanpassen URL",
+	"Current URL is"                                        : "Huidig URL is",
+	"Opens this link in a new window"                       : "Opend deze hyperlink in een nieuw venster",
+	"Please confirm that you want to unlink this element."  : "Is het werkelijk de bedoeling dit element te unlinken.",
+	"Link points to:"                                       : "Hyperlink verwijst naar:",
+	"Unlink the current element"                            : "Unlink het huidige element",
+	"Show the Table Cell Properties dialog"                 : "Laat de tabel celeigenschappen dialog zien",
+	"Show the Table Row Properties dialog"                  : "Laat de tabel rijeigenschappen dialog zien",
+	"Insert a new row before the current one"               : "Voeg een nieuwe rij in boven de huidige",
+	"Insert a new row after the current one"                : "Voeg een nieuwe rij in onder de huidige",
+	"Delete the current row"                                : "Verwijder de huidige rij",
+	"Show the Table Properties dialog"                      : "Laat de tabel eigenschappen dialog zien",
+	"Insert a new column before the current one"            : "Voeg een nieuwe kolom in voor de huidige",
+	"Insert a new column after the current one"             : "Voeg een nieuwe kolom in na de huidige",
+	"Delete the current column"                             : "Verwijder de huidige kolom",
+	"Create a link"                                         : "Maak een hyperlink"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/he.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/he.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/he.js	(revision 795)
@@ -0,0 +1,66 @@
+// I18N constants
+
+// LANG: "he", ENCODING: UTF-8
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+ContextMenu.I18N = {
+	// Items that appear in menu.  Please note that an underscore (_)
+	// character in the translation (right column) will cause the following
+	// letter to become underlined and be shortcut for that menu option.
+
+	"Cut"                                                   : "××××š",
+	"Copy"                                                  : "××¢×ª×§",
+	"Paste"                                                 : "××××§",
+	"Image Properties"                                      : "_×××€××× × ×ª××× ×...",
+	"Modify Link"                                           : "_×©× × ×§××©××š...",
+	"Check Link"                                            : "×××_×§ ×§××©××š...",
+	"Remove Link"                                           : "_××¡×š ×§××©××š...",
+	"Cell Properties"                                       : "×××€××× × ×ª_×...",
+	"Row Properties"                                        : "×××€××× × _×××š...",
+	"Insert Row Before"                                     : "×_×× ×¡ ×©××š× ××€× ×",
+	"Insert Row After"                                      : "××× _×¡ ×©××š× ×××š×",
+	"Delete Row"                                            : "_×××§ ×©××š×",
+	"Table Properties"                                      : "×××€××× × ×_×××...",
+	"Insert Column Before"                                  : "××× ×¡ _×××š ××€× ×",
+	"Insert Column After"                                   : "××× ×¡ ×_××š ×××š×",
+	"Delete Column"                                         : "××_×§ ×××š",
+	"Justify Left"                                          : "××©××š ××©×××",
+	"Justify Center"                                        : "××©××š ×××š××",
+	"Justify Right"                                         : "××©××š ×××××",
+	"Justify Full"                                          : "××©××š ××©××š× ××××",
+	"Make link"                                             : "×Š××š ×§×_×©××š...",
+	"Remove the"                                            : "××¡×š ××ª ×××× × ×-",
+	"Element"                                               : "...",
+
+	// Other labels (tooltips and alert/confirm box messages)
+
+	"Please confirm that you want to remove this element:"  : "×× × ××©×š ×©××š×Š×× × ×××¡××š ××ª ××××× × ×××:",
+	"Remove this node from the document"                    : "××¡×š× ×©× node ×× ××××¡××",
+	"How did you get here? (Please report!)"                : "××× ×××¢×ª ×× ×? (×× × ××××!)",
+	"Show the image properties dialog"                      : "××Š×× ××ª ×××× ×××-×©×× ×©× ×××€××× × ×ª××× ×",
+	"Modify URL"                                            : "×©×× ×× URL",
+	"Current URL is"                                        : "URL × ×××× ×××",
+	"Opens this link in a new window"                       : "×€×ª×××ª ×§××©××š ×× ××××× ×××©",
+	"Please confirm that you want to unlink this element."  : "×× × ××©×š ×©××ª× ×š××Š× ×× ×ª×§ ××ª ×××× × ××.",
+	"Link points to:"                                       : "××§××©××š ××Š×××¢ ××:",
+	"Unlink the current element"                            : "× ××ª××§ ××ª ××××× × ×× ××××",
+	"Show the Table Cell Properties dialog"                 : "××Š×× ××ª ×××× ×××-×©×× ×©× ×××€××× × ×ª× ×××××",
+	"Show the Table Row Properties dialog"                  : "××Š×× ××ª ×××× ×××-×©×× ×©× ×××€××× × ×©××š× ×××××",
+	"Insert a new row before the current one"               : "×××¡×€×ª ×©××š× ×××©× ××€× × ×× ×××××ª",
+	"Insert a new row after the current one"                : "×××¡×€×ª ×©××š× ×××©× ×××š× ×× ×××××ª",
+	"Delete the current row"                                : "××××§×ª ××ª ××©××š× ×× ×××××ª",
+	"Show the Table Properties dialog"                      : "××Š×× ××ª ×××× ×××-×©×× ×©× ×××€××× × ××××",
+	"Insert a new column before the current one"            : "×××¡×€×ª ×××š ×××© ××€× × ×× ××××",
+	"Insert a new column after the current one"             : "×××¡×€×ª ×××š ×××© ×××š× ×× ××××",
+	"Delete the current column"                             : "××××§×ª ××ª ××××š ×× ××××",
+	"Create a link"                                         : "××Š××š×ª ×§××©××š"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/lang.php	(revision 795)
@@ -0,0 +1,94 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-ContextMenu');
+
+// I18N constants
+
+// LANG:  "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+ContextMenu.I18N = {
+	// Items that appear in menu.  Please note that an underscore (_)
+	// character in the translation (right column) will cause the following
+	// letter to become underlined and be shortcut for that menu option.
+
+	"Cut"                                                   :  "<?php echo lang('Cut'); ?>",
+	"Copy"                                                  :  "<?php echo lang('Copy'); ?>",
+	"Paste"                                                 :  "<?php echo lang('Paste'); ?>",
+	"Image Properties"                                      :  "<?php echo lang('_Image Properties...'); ?>",
+	"Modify Link"                                           :  "<?php echo lang('_Modify Link...'); ?>",
+	"Check Link"                                            :  "<?php echo lang('Chec_k Link...'); ?>",
+	"Remove Link"                                           :  "<?php echo lang('_Remove Link...'); ?>",
+	"Cell Properties"                                       :  "<?php echo lang('C_ell Properties...'); ?>",
+	"Row Properties"                                        :  "<?php echo lang('Ro_w Properties...'); ?>",
+	"Insert Row Before"                                     :  "<?php echo lang('I_nsert Row Before'); ?>",
+	"Insert Row After"                                      :  "<?php echo lang('In_sert Row After'); ?>",
+	"Delete Row"                                            :  "<?php echo lang('_Delete Row'); ?>",
+	"Table Properties"                                      :  "<?php echo lang('_Table Properties...'); ?>",
+	"Insert Column Before"                                  :  "<?php echo lang('Insert _Column Before'); ?>",
+	"Insert Column After"                                   :  "<?php echo lang('Insert C_olumn After'); ?>",
+	"Delete Column"                                         :  "<?php echo lang('De_lete Column'); ?>",
+	"Justify Left"                                          :  "<?php echo lang('Justify Left'); ?>",
+	"Justify Center"                                        :  "<?php echo lang('Justify Center'); ?>",
+	"Justify Right"                                         :  "<?php echo lang('Justify Right'); ?>",
+	"Justify Full"                                          :  "<?php echo lang('Justify Full'); ?>",
+	"Make link"                                             :  "<?php echo lang('Make lin_k...'); ?>",
+	"Remove the"                                            :  "<?php echo lang('Remove the'); ?>",
+	"Element"                                               :  "<?php echo lang('Element...'); ?>",
+
+	// Other labels (tooltips and alert/confirm box messages)
+
+	"Please confirm that you want to remove this element:"  :  "<?php echo lang('Please confirm that you want to remove this element:'); ?>",
+	"Remove this node from the document"                    :  "<?php echo lang('Remove this node from the document'); ?>",
+	"How did you get here? (Please report!)"                :  "<?php echo lang('How did you get here? (Please report!)'); ?>",
+	"Show the image properties dialog"                      :  "<?php echo lang('Show the image properties dialog'); ?>",
+	"Modify URL"                                            :  "<?php echo lang('Modify URL'); ?>",
+	"Current URL is"                                        :  "<?php echo lang('Current URL is'); ?>",
+	"Opens this link in a new window"                       :  "<?php echo lang('Opens this link in a new window'); ?>",
+	"Please confirm that you want to unlink this element."  :  "<?php echo lang('Please confirm that you want to unlink this element.'); ?>",
+	"Link points to:"                                       :  "<?php echo lang('Link points to:'); ?>",
+	"Unlink the current element"                            :  "<?php echo lang('Unlink the current element'); ?>",
+	"Show the Table Cell Properties dialog"                 :  "<?php echo lang('Show the Table Cell Properties dialog'); ?>",
+	"Show the Table Row Properties dialog"                  :  "<?php echo lang('Show the Table Row Properties dialog'); ?>",
+	"Insert a new row before the current one"               :  "<?php echo lang('Insert a new row before the current one'); ?>",
+	"Insert a new row after the current one"                :  "<?php echo lang('Insert a new row after the current one'); ?>",
+	"Delete the current row"                                :  "<?php echo lang('Delete the current row'); ?>",
+	"Show the Table Properties dialog"                      :  "<?php echo lang('Show the Table Properties dialog'); ?>",
+	"Insert a new column before the current one"            :  "<?php echo lang('Insert a new column before the current one'); ?>",
+	"Insert a new column after the current one"             :  "<?php echo lang('Insert a new column after the current one'); ?>",
+	"Delete the current column"                             :  "<?php echo lang('Delete the current column'); ?>",
+	"Create a link"                                         :  "<?php echo lang('Create a link'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/el.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/el.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/el.js	(revision 795)
@@ -0,0 +1,81 @@
+// I18N constants
+
+// LANG: "el", ENCODING: UTF-8 | ISO-8859-7
+// Author: Dimitris Glezos, dimitris@glezos.com
+
+ContextMenu.I18N = {
+	// Items that appear in menu.  Please note that an underscore (_)
+	// character in the translation (right column) will cause the following
+	// letter to become underlined and be shortcut for that menu option.
+
+	"Cut"                                                   : "ÎÏÎ¿ÎºÎ¿ÏÎ®",
+	"Copy"                                                  : "ÎÎœÏÎ¹Î³ÏÎ±ÏÎ®",
+	"Paste"                                                 : "ÎÏÎ¹ÎºÏÎ»Î»Î·ÏÎ·",
+	"Image Properties"                                      : "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎÎ¹ÎºÏÎœÎ±Ï...",
+	"Modify Link"                                           : "Î€ÏÎ¿ÏÎ¿ÏÎ¿Î¯Î·ÏÎ· ÏÏ
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+...",
+	"Check Link"                                            : "ÎÎ»ÎµÎ³ÏÎ¿Ï ÏÏ
+ÎœÎŽÎ­ÏÎŒÏÎœ...",
+	"Remove Link"                                           : "ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÏÏ
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+...",
+	"Cell Properties"                                       : "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎºÎµÎ»Î¹Î¿Ï...",
+	"Row Properties"                                        : "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ Î³ÏÎ±ÎŒÎŒÎ®Ï...",
+	"Insert Row Before"                                     : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® Î³ÏÎ±ÎŒÎŒÎ®Ï ÏÏÎ¹Îœ",
+	"Insert Row After"                                      : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® Î³ÏÎ±ÎŒÎŒÎ®Ï ÎŒÎµÏÎ¬",
+	"Delete Row"                                            : "ÎÎ¹Î±Î³ÏÎ±ÏÎ® Î³ÏÎ±ÎŒÎŒÎ®Ï",
+	"Table Properties"                                      : "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÏÎ¯ÎœÎ±ÎºÎ±...",
+	"Insert Column Before"                                  : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÏÏÎ®Î»Î·Ï ÏÏÎ¹Îœ",
+	"Insert Column After"                                   : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÏÏÎ®Î»Î·Ï ÎŒÎµÏÎ¬",
+	"Delete Column"                                         : "ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÏÏÎ®Î»Î·Ï",
+	"Justify Left"                                          : "Î£ÏÎ¿Î¯ÏÎ·ÏÎ· ÎÏÎ¹ÏÏÎµÏÎ¬",
+	"Justify Center"                                        : "Î£ÏÎ¿Î¯ÏÎ·ÏÎ· ÎÎ­ÎœÏÏÎ¿",
+	"Justify Right"                                         : "Î£ÏÎ¿Î¯ÏÎ·ÏÎ· ÎÎµÎŸÎ¹Î¬",
+	"Justify Full"                                          : "Î Î»Î®ÏÎ·Ï Î£ÏÎ¿Î¯ÏÎ·ÏÎ·",
+	"Make link"                                             : "ÎÎ·ÎŒÎ¹Î¿Ï
+ÏÎ³Î¯Î± ÏÏ
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+...",
+	"Remove the"                                            : "ÎÏÎ±Î¯ÏÎµÏÎ·",
+	"Element"                                               : "ÏÏÎ¿Î¹ÏÎµÎ¯Î¿Ï
+...",
+
+	// Other labels (tooltips and alert/confirm box messages)
+
+	"Please confirm that you want to remove this element:"  : "ÎÎ¯ÏÏÎµ Î²Î­Î²Î±Î¹Î¿Ï ÏÏÏ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î±ÏÎ±Î¹ÏÎ­ÏÎµÏÎµ ÏÎ¿ ÏÏÎ¿Î¹ÏÎµÎ¯Î¿ ",
+	"Remove this node from the document"                    : "ÎÏÎ±Î¯ÏÎµÏÎ· Î±Ï
+ÏÎ¿Ï ÏÎ¿Ï
+ ÎºÏÎŒÎ²Î¿Ï
+ Î±ÏÏ ÏÎ¿ Î­Î³Î³ÏÎ±ÏÎ¿",
+	"How did you get here? (Please report!)"                : "Î ÏÏ Î®ÏÎžÎ±ÏÎµ ÎŒÎ­ÏÏÎ¹ ÎµÎŽÏ; (Î Î±ÏÎ±ÎºÎ±Î»Î¿ÏÎŒÎµ Î±ÎœÎ±ÏÎ­ÏÎµÏÎµ ÏÎ¿!)",
+	"Show the image properties dialog"                      : "ÎÎŒÏÎ¬ÎœÎ¹ÏÎ· ÎŽÎ¹Î±Î»ÏÎ³Î¿Ï
+ ÎŒÎµ ÏÎ¹Ï ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎµÎ¹ÎºÏÎœÎ±Ï",
+	"Modify URL"                                            : "Î€ÏÎ¿ÏÎ¿ÏÎ¿Î¯Î·ÏÎ· URL",
+	"Current URL is"                                        : "Î€Î¿ ÏÏÎ­ÏÏÎœ URL ÎµÎ¯ÎœÎ±Î¹",
+	"Opens this link in a new window"                       : "ÎÎœÎ¿Î¯Î³ÎµÎ¹ Î±Ï
+ÏÏ ÏÎ¿Îœ ÏÏÎœÎŽÎµÏÎŒÎ¿ ÏÎµ Î­ÎœÎ± ÎœÎ­Î¿ ÏÎ±ÏÎ¬ÎžÏ
+ÏÎ¿",
+	"Please confirm that you want to unlink this element."  : "ÎÎ¯ÏÏÎµ Î²Î­Î²Î±Î¹Î¿Ï ÏÏÏ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î±ÏÎ±Î¹ÏÎ­ÏÎµÏÎµ ÏÎ¿Îœ ÏÏÎœÎŽÎµÏÎŒÎ¿ Î±ÏÏ Î±Ï
+ÏÏ ÏÎ¿ ÏÏÎ¿Î¹ÏÎµÎ¯Î¿:",
+	"Link points to:"                                       : "Î ÏÏÎœÎŽÎµÎŒÎ¿Ï Î¿ÎŽÎ·Î³ÎµÎ¯ ÎµÎŽÏ:",
+	"Unlink the current element"                            : "ÎÏÎ±Î¯ÏÎµÏÎ· ÏÏ
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+ Î±ÏÏ ÏÎ¿ ÏÎ±ÏÏÎœ ÏÏÎ¿Î¹ÏÎµÎ¯Î¿",
+	"Show the Table Cell Properties dialog"                 : "ÎÎŒÏÎ¬ÎœÎ¹ÏÎ· ÎŽÎ¹Î±Î»ÏÎ³Î¿Ï
+ ÎŒÎµ ÏÎ¹Ï ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎºÎµÎ»Î¹Î¿Ï Î Î¯ÎœÎ±ÎºÎ±",
+	"Show the Table Row Properties dialog"                  : "ÎÎŒÏÎ¬ÎœÎ¹ÏÎ· ÎŽÎ¹Î±Î»ÏÎ³Î¿Ï
+ ÎŒÎµ ÏÎ¹Ï ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ Î³ÏÎ±ÎŒÎŒÎ®Ï Î Î¯ÎœÎ±ÎºÎ±",
+	"Insert a new row before the current one"               : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÎŒÎ¹Î±Ï ÎœÎ­Î±Ï Î³ÏÎ±ÎŒÎŒÎ®Ï ÏÏÎ¹Îœ ÏÎ·Îœ ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ·",
+	"Insert a new row after the current one"                : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÎŒÎ¹Î±Ï ÎœÎ­Î±Ï Î³ÏÎ±ÎŒÎŒÎ®Ï ÎŒÎµÏÎ¬ ÏÎ·Îœ ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ·",
+	"Delete the current row"                                : "ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ·Ï Î³ÏÎ±ÎŒÎŒÎ®Ï",
+	"Show the Table Properties dialog"                      : "ÎÎŒÏÎ¬ÎœÎ¹ÏÎ· ÎŽÎ¹Î±Î»ÏÎ³Î¿Ï
+ ÎŒÎµ ÏÎ¹Ï ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ Î Î¯ÎœÎ±ÎºÎ±",
+	"Insert a new column before the current one"            : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÎœÎ­Î±Ï ÏÏÎ®Î»Î·Ï ÏÏÎ¹Îœ ÏÎ·Îœ ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ·",
+	"Insert a new column after the current one"             : "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÎœÎ­Î±Ï ÏÏÎ®Î»Î·Ï ÎŒÎµÏÎ¬ ÏÎ·Îœ ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ·",
+	"Delete the current column"                             : "ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ·Ï ÏÏÎ®Î»Î·Ï",
+	"Create a link"                                         : "ÎÎ·ÎŒÎ¹Î¿Ï
+ÏÎ³Î¯Î± ÏÏ
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/lang/en.js	(revision 795)
@@ -0,0 +1,66 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+ContextMenu.I18N = {
+	// Items that appear in menu.  Please note that an underscore (_)
+	// character in the translation (right column) will cause the following
+	// letter to become underlined and be shortcut for that menu option.
+
+	"Cut"                                                   : "Cut",
+	"Copy"                                                  : "Copy",
+	"Paste"                                                 : "Paste",
+	"Image Properties"                                      : "_Image Properties...",
+	"Modify Link"                                           : "_Modify Link...",
+	"Check Link"                                            : "Chec_k Link...",
+	"Remove Link"                                           : "_Remove Link...",
+	"Cell Properties"                                       : "C_ell Properties...",
+	"Row Properties"                                        : "Ro_w Properties...",
+	"Insert Row Before"                                     : "I_nsert Row Before",
+	"Insert Row After"                                      : "In_sert Row After",
+	"Delete Row"                                            : "_Delete Row",
+	"Table Properties"                                      : "_Table Properties...",
+	"Insert Column Before"                                  : "Insert _Column Before",
+	"Insert Column After"                                   : "Insert C_olumn After",
+	"Delete Column"                                         : "De_lete Column",
+	"Justify Left"                                          : "Justify Left",
+	"Justify Center"                                        : "Justify Center",
+	"Justify Right"                                         : "Justify Right",
+	"Justify Full"                                          : "Justify Full",
+	"Make link"                                             : "Make lin_k...",
+	"Remove the"                                            : "Remove the",
+	"Element"                                               : "Element...",
+
+	// Other labels (tooltips and alert/confirm box messages)
+
+	"Please confirm that you want to remove this element:"  : "Please confirm that you want to remove this element:",
+	"Remove this node from the document"                    : "Remove this node from the document",
+	"How did you get here? (Please report!)"                : "How did you get here? (Please report!)",
+	"Show the image properties dialog"                      : "Show the image properties dialog",
+	"Modify URL"                                            : "Modify URL",
+	"Current URL is"                                        : "Current URL is",
+	"Opens this link in a new window"                       : "Opens this link in a new window",
+	"Please confirm that you want to unlink this element."  : "Please confirm that you want to unlink this element.",
+	"Link points to:"                                       : "Link points to:",
+	"Unlink the current element"                            : "Unlink the current element",
+	"Show the Table Cell Properties dialog"                 : "Show the Table Cell Properties dialog",
+	"Show the Table Row Properties dialog"                  : "Show the Table Row Properties dialog",
+	"Insert a new row before the current one"               : "Insert a new row before the current one",
+	"Insert a new row after the current one"                : "Insert a new row after the current one",
+	"Delete the current row"                                : "Delete the current row",
+	"Show the Table Properties dialog"                      : "Show the Table Properties dialog",
+	"Insert a new column before the current one"            : "Insert a new column before the current one",
+	"Insert a new column after the current one"             : "Insert a new column after the current one",
+	"Delete the current column"                             : "Delete the current column",
+	"Create a link"                                         : "Create a link"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/1.pl
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/1.pl	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/1.pl	(revision 795)
@@ -0,0 +1,38 @@
+#! /usr/bin/perl -w
+
+use strict;
+
+my $file = 'context-menu.js';
+my $outfile = $file.'-i18n';
+my $langfile = 'en.js';
+
+open FILE, "<$file";
+#open OUTFILE, ">$outfile";
+#open LANGFILE, ">$langfile";
+my %texts = ();
+while (<FILE>) {
+    if (/"(.*?)"/) {
+        my $inline = $_;
+        chomp $inline;
+        my $key = $1;
+        my $val = $1;
+        print "Key: [$key]: ";
+        my $line = <STDIN>;
+        if (defined $line) {
+            chomp $line;
+            if ($line =~ /(\S+)/) {
+                $key = $1;
+                print "-- using $key\n";
+            }
+            $texts{$val} = $key;
+        } else {
+            print " -- skipped...\n";
+        }
+    }
+}
+#close LANGFILE;
+#close OUTFILE;
+close FILE;
+
+print "\n\n\n";
+print '"', join("\"\n\"", sort keys %texts), '"', "\n";
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/menu.css
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/menu.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ContextMenu/menu.css	(revision 795)
@@ -0,0 +1,64 @@
+/* styles for the ContextMenu /HTMLArea */
+/* The ContextMenu plugin is (c) dynarch.com 2003. */
+/* Distributed under the same terms as HTMLArea itself */
+
+div.htmlarea-context-menu {
+  position: absolute;
+  border: 1px solid #aca899;
+  padding: 2px;
+  background-color: #fff;
+  cursor: default;
+  z-index: 1000;
+}
+
+div.htmlarea-context-menu table {
+  font: 11px tahoma,verdana,sans-serif;
+  border-collapse: collapse;
+}
+
+div.htmlarea-context-menu tr.item td.icon img {
+  width: 18px;
+  height: 18px;
+}
+
+div.htmlarea-context-menu tr.item td.icon {
+  padding: 0px 3px;
+  height: 18px;
+  background-color: #cdf;
+}
+
+div.htmlarea-context-menu tr.item td.label {
+  padding: 1px 10px 1px 3px;
+}
+
+div.htmlarea-context-menu tr.separator td {
+  padding: 2px 0px;
+}
+
+div.htmlarea-context-menu tr.separator td div {
+  border-top: 1px solid #aca899;
+  overflow: hidden;
+  position: relative;
+}
+
+div.htmlarea-context-menu tr.separator td.icon {
+  background-color: #cdf;
+}
+
+div.htmlarea-context-menu tr.separator td.icon div {
+/*  margin-left: 3px; */
+  border-color: #fff;
+}
+
+div.htmlarea-context-menu tr.separator td.label div {
+  margin-right: 3px;
+}
+
+div.htmlarea-context-menu tr.item.hover {
+  background-color: #316ac5;
+  color: #fff;
+}
+
+div.htmlarea-context-menu tr.item.hover td.icon {
+  background-color: #619af5;
+}
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/lang/en.js	(revision 795)
@@ -0,0 +1,16 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Sponsored by http://www.systemconcept.de
+// Author: Holger Hees, <hhees@systemconcept.de>
+//
+// (c) systemconcept.de 2004
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+CharacterMap.I18N = {
+	"CharacterMapTooltip"       : "Insert special character",
+	"Insert special character"  : "Insert special character",
+	"HTML value:"               : "HTML value:",
+	"Cancel"                    : "Cancel"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/character-map.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/character-map.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/character-map.js	(revision 795)
@@ -0,0 +1,69 @@
+// Character Map plugin for HTMLArea
+// Sponsored by http://www.systemconcept.de
+// Implementation by Holger Hees based on HTMLArea XTD 1.5 (http://mosforge.net/projects/htmlarea3xtd/)
+// Original Author - Bernhard Pfeifer novocaine@gmx.net
+//
+// (c) systemconcept.de 2004
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+function CharacterMap(editor) {
+        this.editor = editor;
+
+        var cfg = editor.config;
+	var toolbar = cfg.toolbar;
+	var self = this;
+	var i18n = CharacterMap.I18N;
+
+	cfg.registerButton({
+                id       : "insertcharacter",
+                tooltip  : i18n["CharacterMapTooltip"],
+                image    : editor.imgURL("ed_charmap.gif", "CharacterMap"),
+                textMode : false,
+                action   : function(editor) {
+                                self.buttonPress(editor);
+                           }
+            })
+
+	var a, i, j, found = false;
+	for (i = 0; !found && i < toolbar.length; ++i) {
+		a = toolbar[i];
+		for (j = 0; j < a.length; ++j) {
+			if (a[j] == "inserthorizontalrule") {
+				found = true;
+				break;
+			}
+		}
+	}
+	if (found)
+	    a.splice(j, 0, "insertcharacter");
+        else{
+            toolbar[1].splice(0, 0, "separator");
+	    toolbar[1].splice(0, 0, "insertcharacter");
+        }
+};
+
+CharacterMap._pluginInfo = {
+	name          : "CharacterMap",
+	version       : "1.0",
+	developer     : "Holger Hees & Bernhard Pfeifer",
+	developer_url : "http://www.systemconcept.de/",
+	c_owner       : "Holger Hees & Bernhard Pfeifer",
+	sponsor       : "System Concept GmbH & Bernhard Pfeifer",
+	sponsor_url   : "http://www.systemconcept.de/",
+	license       : "htmlArea"
+};
+
+CharacterMap.prototype.buttonPress = function(editor) {
+    editor._popupDialog( "plugin://CharacterMap/select_character", function( entity )
+    {
+        if ( !entity )
+        {
+            //user must have pressed Cancel
+            return false;
+        }
+
+        editor.insertHTML( entity );
+
+    }, null);
+}
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/popups/select_character.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/popups/select_character.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/CharacterMap/popups/select_character.html	(revision 795)
@@ -0,0 +1,251 @@
+<html>
+<head>
+<title>Insert special character</title>
+<style type="text/css">
+@import url(../../../htmlarea.css);
+td.character {
+    font-family: Verdana,Arial,Helvetica,sans-serif;
+    font-size: 14px;
+    font-weight: bold;
+    text-align: center;
+    background: #FFF;
+    padding: 4px;
+}
+
+td.character-hilite {
+    background: Highlight;
+    color: HighlightText;
+}
+
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+table .label { text-align: right; width: 8em; }
+
+.title { background: none; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+#buttons {
+      margin-top: 1em; border-top: 1px solid #999;
+      padding: 2px; text-align: right;
+}
+</style>
+<script type="text/javascript" src="../../../popups/popup.js"></script>
+<script type="text/javascript">
+// HTMLSource based on HTMLArea XTD 1.5 (http://mosforge.net/projects/htmlarea3xtd/) modified by Holger Hees
+// Original Author - Bernhard Pfeifer novocaine@gmx.net
+
+CharacterMap = window.opener.CharacterMap; // load the CharacterMap plugin and lang file ;-)
+window.resizeTo(480, 300);
+// center on parent
+var x = opener.screenX + (opener.outerWidth - window.outerWidth) / 2;
+var y = opener.screenY + (opener.outerHeight - window.outerHeight) / 2;
+window.moveTo(x, y);
+
+function _CloseOnEsc()
+{
+    if ( event.keyCode == 27 )
+    {
+        window.close();
+        return;
+    }
+}
+
+function Init()                                                         // run on page load
+{
+   __dlg_translate(CharacterMap.I18N);
+   __dlg_init();
+    document.body.onkeypress = _CloseOnEsc;
+
+    var character = '';                                                   // set default input to empty
+    View( null, character );
+}
+
+var oldView = null;
+function View( td, character )               // preview character
+{
+    if (oldView)
+        oldView.className = oldView.className.replace(/\s+character-hilite/, '');
+    document.getElementById( 'characterPreview' ).value = character;
+    document.getElementById( 'showCharacter' ).value = character;
+    if (td)
+        (oldView = td).className += " character-hilite";
+}
+
+function Set( string )                // return character
+{
+    var character = string;
+
+    __dlg_close( character );
+}
+
+function onCancel()                   // cancel selection
+{
+    __dlg_close( null );
+
+    return false;
+};
+
+</script>
+</head>
+<body style="background: Buttonface; margin: 0px; padding: 0px" onload="Init();self.focus();">
+<form method="get" style="margin:2px; padding:2px" onSubmit="Set(document.getElementById('showCharacter').value); return false;">
+<table border="0" cellspacing="0" cellpadding="4" width="100%">
+ <tr>
+  <td style="background: Buttonface" valign="center"><div style="padding: 1px; white-space: nowrap; font-family: tahoma,arial,sans-serif; font-size: 11px; font-weight: normal;">HTML value:<div id="characterPreview"></div></div></td>
+  <td style="background: Buttonface" valign="center"><input type="text" name="showcharacter" id="showCharacter" value="" size="15" style="background: #fff; font-size: 11px;" /></td>
+  <td style="background: Buttonface" width="100%"></td>
+ </tr>
+</table>
+</form>
+<table border="0" cellspacing="1" cellpadding="0" width="100%" style="cursor: pointer; background: #ADAD9C; border: 1px inset;">
+<tr>
+<td class="character" onMouseOver="View(this,'&amp;Yuml;')" onClick="Set('&Yuml;')">&Yuml;</td>
+<td class="character" onMouseOver="View(this,'&amp;scaron;')" onClick="Set('&scaron;')">&scaron;</td>
+<td class="character" onMouseOver="View(this,'&amp;#064;')" onClick="Set('&#064;')">@</td>
+<td class="character" onMouseOver="View(this,'&amp;quot;')" onClick="Set('&quot;')">&quot;</td>
+<td class="character" onMouseOver="View(this,'&amp;iexcl;')" onClick="Set('&iexcl;')">&iexcl;</td>
+<td class="character" onMouseOver="View(this,'&amp;cent;')" onClick="Set('&cent;')">&cent;</td>
+<td class="character" onMouseOver="View(this,'&amp;pound;')" onClick="Set('&pound;')">&pound;</td>
+<td class="character" onMouseOver="View(this,'&amp;curren;')" onClick="Set('&curren;')">&curren;</td>
+<td class="character" onMouseOver="View(this,'&amp;yen;')" onClick="Set('&yen;')">&yen;</td>
+<td class="character" onMouseOver="View(this,'&amp;brvbar;')" onClick="Set('&brvbar;')">&brvbar;</td>
+<td class="character" onMouseOver="View(this,'&amp;sect;')" onClick="Set('&sect;')">&sect;</td>
+<td class="character" onMouseOver="View(this,'&amp;uml;')" onClick="Set('&uml;')">&uml;</td>
+<td class="character" onMouseOver="View(this,'&amp;copy;')" onClick="Set('&copy;')">&copy;</td>
+<td class="character" onMouseOver="View(this,'&amp;ordf;')" onClick="Set('&ordf;')">&ordf;</td>
+<td class="character" onMouseOver="View(this,'&amp;laquo;')" onClick="Set('&laquo;')">&laquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;not;')" onClick="Set('&not;')">&not</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;macr;')" onClick="Set('&macr;')">&macr;</td>
+<td class="character" onMouseOver="View(this,'&amp;deg;')" onClick="Set('&deg;')">&deg;</td>
+<td class="character" onMouseOver="View(this,'&amp;plusmn;')" onClick="Set('&plusmn;')">&plusmn;</td>
+<td class="character" onMouseOver="View(this,'&amp;sup2;')" onClick="Set('&sup2;')">&sup2;</td>
+<td class="character" onMouseOver="View(this,'&amp;sup3;')" onClick="Set('&sup3;')">&sup3;</td>
+<td class="character" onMouseOver="View(this,'&amp;acute;')" onClick="Set('&acute;')">&acute;</td>
+<td class="character" onMouseOver="View(this,'&amp;micro;')" onClick="Set('&micro;')">&micro;</td>
+<td class="character" onMouseOver="View(this,'&amp;para;')" onClick="Set('&para;')">&para;</td>
+<td class="character" onMouseOver="View(this,'&amp;middot;')" onClick="Set('&middot;')">&middot;</td>
+<td class="character" onMouseOver="View(this,'&amp;cedil;')" onClick="Set('&cedil;')">&cedil;</td>
+<td class="character" onMouseOver="View(this,'&amp;sup1;')" onClick="Set('&sup1;')">&sup1;</td>
+<td class="character" onMouseOver="View(this,'&amp;ordm;')" onClick="Set('&ordm;')">&ordm;</td>
+<td class="character" onMouseOver="View(this,'&amp;raquo;')" onClick="Set('&raquo;')">&raquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;frac14;')" onClick="Set('&frac14;')">&frac14;</td>
+<td class="character" onMouseOver="View(this,'&amp;frac12;')" onClick="Set('&frac12;')">&frac12;</td>
+<td class="character" onMouseOver="View(this,'&amp;frac34;')" onClick="Set('&frac34;')">&frac34;</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;iquest;')" onClick="Set('&iquest;')">&iquest;</td>
+<td class="character" onMouseOver="View(this,'&amp;times;')" onClick="Set('&times;')">&times;</td>
+<td class="character" onMouseOver="View(this,'&amp;Oslash;')" onClick="Set('&Oslash;')">&Oslash;</td>
+<td class="character" onMouseOver="View(this,'&amp;divide;')" onClick="Set('&divide;')">&divide;</td>
+<td class="character" onMouseOver="View(this,'&amp;oslash;')" onClick="Set('&oslash;')">&oslash;</td>
+<td class="character" onMouseOver="View(this,'&amp;fnof;')" onClick="Set('&fnof;')">&fnof;</td>
+<td class="character" onMouseOver="View(this,'&amp;circ;')" onClick="Set('&circ;')">&circ;</td>
+<td class="character" onMouseOver="View(this,'&amp;tilde;')" onClick="Set('&tilde;')">&tilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;ndash;')" onClick="Set('&ndash;')">&ndash;</td>
+<td class="character" onMouseOver="View(this,'&amp;mdash;')" onClick="Set('&mdash;')">&mdash;</td>
+<td class="character" onMouseOver="View(this,'&amp;lsquo;')" onClick="Set('&lsquo;')">&lsquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;rsquo;')" onClick="Set('&rsquo;')">&rsquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;sbquo;')" onClick="Set('&sbquo;')">&sbquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;ldquo;')" onClick="Set('&ldquo;')">&ldquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;rdquo;')" onClick="Set('&rdquo;')">&rdquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;bdquo;')" onClick="Set('&bdquo;')">&bdquo;</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;dagger;')" onClick="Set('&dagger;')">&dagger;</td>
+<td class="character" onMouseOver="View(this,'&amp;Dagger;')" onClick="Set('&Dagger;')">&Dagger;</td>
+<td class="character" onMouseOver="View(this,'&amp;bull;')" onClick="Set('&bull;')">&bull;</td>
+<td class="character" onMouseOver="View(this,'&amp;hellip;')" onClick="Set('&hellip;')">&hellip;</td>
+<td class="character" onMouseOver="View(this,'&amp;permil;')" onClick="Set('&permil;')">&permil;</td>
+<td class="character" onMouseOver="View(this,'&amp;lsaquo;')" onClick="Set('&lsaquo;')">&lsaquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;rsaquo;')" onClick="Set('&rsaquo;')">&rsaquo;</td>
+<td class="character" onMouseOver="View(this,'&amp;euro;')" onClick="Set('&euro;')">&euro;</td>
+<td class="character" onMouseOver="View(this,'&amp;trade;')" onClick="Set('&trade;')">&trade;</td>
+<td class="character" onMouseOver="View(this,'&amp;Agrave;')" onClick="Set('&Agrave;')">&Agrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;Aacute;')" onClick="Set('&Aacute;')">&Aacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;Acirc;')" onClick="Set('&Acirc;')">&Acirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;Atilde;')" onClick="Set('&Atilde;')">&Atilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;Auml;')" onClick="Set('&Auml;')">&Auml;</td>
+<td class="character" onMouseOver="View(this,'&amp;Aring;')" onClick="Set('&Aring;')">&Aring;</td>
+<td class="character" onMouseOver="View(this,'&amp;AElig;')" onClick="Set('&AElig;')">&AElig;</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;Ccedil;')" onClick="Set('&Ccedil;')">&Ccedil;</td>
+<td class="character" onMouseOver="View(this,'&amp;Egrave;')" onClick="Set('&Egrave;')">&Egrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;Eacute;')" onClick="Set('&Eacute;')">&Eacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ecirc;')" onClick="Set('&Ecirc;')">&Ecirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;Euml;')" onClick="Set('&Euml;')">&Euml;</td>
+<td class="character" onMouseOver="View(this,'&amp;Igrave;')" onClick="Set('&Igrave;')">&Igrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;Iacute;')" onClick="Set('&Iacute;')">&Iacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;Icirc;')" onClick="Set('&Icirc;')">&Icirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;Iuml;')" onClick="Set('&Iuml;')">&Iuml;</td>
+<td class="character" onMouseOver="View(this,'&amp;ETH;')" onClick="Set('&ETH;')">&ETH;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ntilde;')" onClick="Set('&Ntilde;')">&Ntilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ograve;')" onClick="Set('&Ograve;')">&Ograve;</td>
+<td class="character" onMouseOver="View(this,'&amp;Oacute;')" onClick="Set('&Oacute;')">&Oacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ocirc;')" onClick="Set('&Ocirc;')">&Ocirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;Otilde;')" onClick="Set('&Otilde;')">&Otilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ouml;')" onClick="Set('&Ouml;')">&Ouml;</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;reg;')" onClick="Set('&reg;')">&reg;</td>
+<td class="character" onMouseOver="View(this,'&amp;times;')" onClick="Set('&times;')">&times;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ugrave;')" onClick="Set('&Ugrave;')">&Ugrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;Uacute;')" onClick="Set('&Uacute;')">&Uacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;Ucirc;')" onClick="Set('&Ucirc;')">&Ucirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;Uuml;')" onClick="Set('&Uuml;')">&Uuml;</td>
+<td class="character" onMouseOver="View(this,'&amp;Yacute;')" onClick="Set('&Yacute;')">&Yacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;THORN;')" onClick="Set('&THORN;')">&THORN;</td>
+<td class="character" onMouseOver="View(this,'&amp;szlig;')" onClick="Set('&szlig;')">&szlig;</td>
+<td class="character" onMouseOver="View(this,'&amp;agrave;')" onClick="Set('&agrave;')">&agrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;aacute;')" onClick="Set('&aacute;')">&aacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;acirc;')" onClick="Set('&acirc;')">&acirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;atilde;')" onClick="Set('&atilde;')">&atilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;auml;')" onClick="Set('&auml;')">&auml;</td>
+<td class="character" onMouseOver="View(this,'&amp;aring;')" onClick="Set('&aring;')">&aring;</td>
+<td class="character" onMouseOver="View(this,'&amp;aelig;')" onClick="Set('&aelig;')">&aelig;</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;ccedil;')" onClick="Set('&ccedil;')">&ccedil;</td>
+<td class="character" onMouseOver="View(this,'&amp;egrave;')" onClick="Set('&egrave;')">&egrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;eacute;')" onClick="Set('&eacute;')">&eacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;ecirc;')" onClick="Set('&ecirc;')">&ecirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;euml;')" onClick="Set('&euml;')">&euml;</td>
+<td class="character" onMouseOver="View(this,'&amp;igrave;')" onClick="Set('&igrave;')">&igrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;iacute;')" onClick="Set('&iacute;')">&iacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;icirc;')" onClick="Set('&icirc;')">&icirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;iuml;')" onClick="Set('&iuml;')">&iuml;</td>
+<td class="character" onMouseOver="View(this,'&amp;eth;')" onClick="Set('&eth;')">&eth;</td>
+<td class="character" onMouseOver="View(this,'&amp;ntilde;')" onClick="Set('&ntilde;')">&ntilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;ograve;')" onClick="Set('&ograve;')">&ograve;</td>
+<td class="character" onMouseOver="View(this,'&amp;oacute;')" onClick="Set('&oacute;')">&oacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;ocirc;')" onClick="Set('&ocirc;')">&ocirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;otilde;')" onClick="Set('&otilde;')">&otilde;</td>
+<td class="character" onMouseOver="View(this,'&amp;ouml;')" onClick="Set('&ouml;')">&ouml;</td>
+</tr><tr>
+<td class="character" onMouseOver="View(this,'&amp;divide;')" onClick="Set('&divide;')">&divide;</td>
+<td class="character" onMouseOver="View(this,'&amp;oslash;')" onClick="Set('&oslash;')">&oslash;</td>
+<td class="character" onMouseOver="View(this,'&amp;ugrave;')" onClick="Set('&ugrave;')">&ugrave;</td>
+<td class="character" onMouseOver="View(this,'&amp;uacute;')" onClick="Set('&uacute;')">&uacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;ucirc;')" onClick="Set('&ucirc;')">&ucirc;</td>
+<td class="character" onMouseOver="View(this,'&amp;uuml;')" onClick="Set('&uuml;')">&uuml;</td>
+<td class="character" onMouseOver="View(this,'&amp;yacute;')" onClick="Set('&yacute;')">&yacute;</td>
+<td class="character" onMouseOver="View(this,'&amp;thorn;')" onClick="Set('&thorn;')">&thorn;</td>
+<td class="character" onMouseOver="View(this,'&amp;yuml;')" onClick="Set('&yuml;')">&yuml;</td>
+<td class="character" onMouseOver="View(this,'&amp;OElig;')" onClick="Set('&OElig;')">&OElig;</td>
+<td class="character" onMouseOver="View(this,'&amp;oelig;')" onClick="Set('&oelig;')">&oelig;</td>
+<td class="character" onMouseOver="View(this,'&amp;Scaron;')" onClick="Set('&Scaron;')">&Scaron;</td>
+<td class="character">&nbsp;</td>
+<td class="character">&nbsp;</td>
+<td class="character">&nbsp;</td>
+<td class="character">&nbsp;</td>
+</table><br />
+<form style="text-align: center;"><button type="button" name="cancel" onclick="return onCancel();" class="submitInsertTable">Cancel</button></form>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/da.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/da.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/da.js	(revision 795)
@@ -0,0 +1,90 @@
+﻿// I18N constants
+
+// LANG: "da", ENCODING: UTF-8 | ISO-8859-1
+// Author: Steen Sønderup, <steen@soenderup.com>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":											"Placer",
+	"All four sides":									"Alle fire sider",
+	"Background":										"Baggrund",
+	"Baseline":											"Bundlinie",
+	"Border":											"Kant",
+	"Borders":											"Kanter",
+	"Bottom":											"Bund",
+	"CSS Style":										"Stil [CSS]",
+	"Caption":											"Titel",
+	"Cell Properties":									"Celle egenskaber",
+	"Center":											"Centrer",
+	"Char":												"Plads",
+	"Collapsed borders":								"Sammensmelt rammer",
+	"Color":											"Farve",
+	"Description":										"Beskrivelse",
+	"FG Color":											"Font farve",
+	"Float":											"Justering",
+	"Frames":											"Udvendig",
+	"Height":											"Højde",
+	"How many columns would you like to merge?":		"Hvor mange kollonner vil du samle?",
+	"How many rows would you like to merge?":			"Hvor mange rækker vil du samle?",
+	"Image URL":										"Billede URL",
+	"Justify":											"Lige margener",
+	"Layout":											"Opsætning",
+	"Left":												"Venstre",
+	"Margin":											"Margen",
+	"Middle":											"Centrer",
+	"No rules":											"Ingen rammer",
+	"No sides":											"Ingen sider",
+	"None":												"Ingen",
+	"Padding":											"Margen",
+	"Please click into some cell":						"Klik på en celle",
+	"Right":											"Højre",
+	"Row Properties":									"Række egenskaber",
+	"Rules will appear between all rows and columns":	"Rammer mellem rækker og kolonner",
+	"Rules will appear between columns only":			"Kun rammer mellem kolonner",
+	"Rules will appear between rows only":				"Kun rammer mellem rækker",
+	"Rules":											"Invendig",
+	"Spacing and padding":								"Afstand og margen",
+	"Spacing":											"Afstand",
+	"Summary":											"Beskrivelse",
+	"TO-cell-delete":									"Slet celle",
+	"TO-cell-insert-after":								"Indsæt celle efter",
+	"TO-cell-insert-before":							"Indsæt celle før",
+	"TO-cell-merge":									"Sammensæt celler",
+	"TO-cell-prop":										"Celle egenskaber",
+	"TO-cell-split":									"Opdel celle",
+	"TO-col-delete":									"Slet kollonne",
+	"TO-col-insert-after":								"Indsæt kolonne efter",
+	"TO-col-insert-before":								"Indsæt kolonne før",
+	"TO-col-split":										"Opdel kolonne",
+	"TO-row-delete":									"Slet række",
+	"TO-row-insert-above":								"Indsæt række før",
+	"TO-row-insert-under":								"Indsæt række efter",
+	"TO-row-prop":										"Række egenskaber",
+	"TO-row-split":										"Opdel række",
+	"TO-table-prop":									"Tabel egenskaber",
+	"Table Properties":									"Tabel egenskaber",
+	"Text align":										"Tekst",
+	"The bottom side only":								"Kun i bunden",
+	"The left-hand side only":							"Kun i højre side",
+	"The right and left sides only":					"Kun i siderne",
+	"The right-hand side only":							"Kun i venstre side",
+	"The top and bottom sides only":					"Kun i top og bund",
+	"The top side only":								"Kun i toppen",
+	"Top":												"Top",	
+	"Unset color":										"Farve ikke valgt",
+	"Vertical align":									"Vertikal placering",
+	"Width":											"Bredde",
+	"not-del-last-cell":								"Du kan ikke slette den sidste celle i en række.",
+	"not-del-last-col":									"Du kan ikke slette den sidste kolonne i en tabel.",
+	"not-del-last-row":									"Du kan ikke slette den sidste række i en tabel.",
+	"percent":											"procent",
+	"pixels":											"pixel"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/de.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/de.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/de.js	(revision 795)
@@ -0,0 +1,81 @@
+// I18N constants
+
+// LANG: "de", ENCODING: UTF-8 | ISO-8859-1
+// Author: broxx, <broxx@broxx.com>
+
+TableOperations.I18N = {
+	"Align":					  "Ausrichten",
+	"All four sides":				  "Alle 4 Seiten",
+	"Background":					  "Hintergrund",
+	"Baseline":                                       "Basislinie",
+	"Border":					  "Rand",
+	"Borders":					  "Raender",
+	"Bottom":                                         "Unten",
+	"CSS Style":					  "Style [CSS]",
+	"Caption":					  "Ueberschrift",
+	"Cell Properties":                                "Zellen",
+	"Center":					  "Zentrieren",
+	"Char":                                           "Zeichen",
+	"Collapsed borders":                              "Collapsed borders",
+	"Color":					  "Farbe",
+	"Description":					  "Beschreibung",
+	"FG Color":					  "FG Farbe",
+	"Float":                                          "Ausrichtung",
+	"Frames":					  "Rahmen",
+	"Height":                                         "Hoehe",
+	"How many columns would you like to merge?":      "Wieviele Spalten willst du verbinden?",
+	"How many rows would you like to merge?":         "Wieviele Zeilen willst du verbinden?",
+	"Image URL":					  "Bild URL",
+	"Justify":                                        "Justieren",
+	"Layout":					  "Layout",
+	"Left":						  "Links",
+	"Margin":                                         "Rand",
+	"Middle":                                         "Mitte",
+	"No rules":					  "Keine Balken",
+	"No sides":					  "Keine Seiten",
+	"None":                                           "Keine",
+	"Padding":					  "Auffuellung",
+	"Please click into some cell":                    "Waehle eine Zelle",
+	"Right":					  "Rechts",
+	"Row Properties":                                 "Reihen",
+	"Rules will appear between all rows and columns": "Balken zwischen Reihen und Spalten",
+	"Rules will appear between columns only":	  "Balken zwischen Spalten",
+	"Rules will appear between rows only":		  "Balken zwischen Reihen",
+	"Rules":					  "Balken",
+	"Spacing and padding":                            "Abstaende",
+	"Spacing":					  "Abstand",
+	"Summary":					  "Zusammenfassung",
+	"TO-cell-delete":				  "Zelle loeschen",
+	"TO-cell-insert-after":				  "Zelle einfuegen nach",
+	"TO-cell-insert-before":			  "Zelle einfuegen bevor",
+	"TO-cell-merge":				  "Zellen zusammenfuegen",
+	"TO-cell-prop":					  "Zelleinstellungen",
+	"TO-cell-split":				  "Zellen aufteilen",
+	"TO-col-delete":				  "Spalte loeschen",
+	"TO-col-insert-after":				  "Spalte einfuegen nach",
+	"TO-col-insert-before":				  "Spalte einfuegen bevor",
+	"TO-col-split":					  "Spalte aufteilen",
+	"TO-row-delete":				  "Reihe loeschen",
+	"TO-row-insert-above":				  "Reihe einfuegen vor",
+	"TO-row-insert-under":				  "Reihe einfuegen nach",
+	"TO-row-prop":					  "Reiheneinstellungen",
+	"TO-row-split":					  "Reihen aufteilen",
+	"TO-table-prop":				  "Tabelle",
+	"Table Properties":				  "Tabelle",
+	"Text align":                                     "Ausrichtung",
+	"The bottom side only":				  "Nur untere Seite",
+	"The left-hand side only":			  "Nur linke Seite",
+	"The right and left sides only":		  "Nur linke und rechte Seite",
+	"The right-hand side only":			  "Nur rechte Seite",
+	"The top and bottom sides only":		  "Nur obere und untere Seite",
+	"The top side only":				  "Nur obere Seite",
+	"Top":                                            "Oben",	
+	"Unset color":                                    "Farbe",
+	"Vertical align":                                 "Ausrichtung",
+	"Width":					  "Breite",
+	"not-del-last-cell":				  "Letzte Zelle in dieser Reihe!",
+	"not-del-last-col":				  "Letzte Spalte in dieser Tabelle!",
+	"not-del-last-row":				  "Letzte Reihe in dieser Tabelle",
+	"percent":					  "%",
+	"pixels":					  "pixels"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/nl.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/nl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/nl.js	(revision 795)
@@ -0,0 +1,90 @@
+// I18N constants
+
+// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1
+// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":											"Uitlijning",
+	"All four sides":									"Alle 4 zijden",
+	"Background":										"Achtergrond",
+	"Baseline":											"Basis",
+	"Border":											"Rand",
+	"Borders":											"Randen",
+	"Bottom":											"Onder",
+	"CSS Style":										"CSS Style",
+	"Caption":											"Opmerking",
+	"Cell Properties":									"Celeigenschappen",
+	"Center":											"Centreren",
+	"Char":												"Karakter",
+	"Collapsed borders":								"Geen randen",
+	"Color":											"Kleur",
+	"Description":										"Omschrijving",
+	"FG Color":											"Voorgrond",
+	"Float":											"Zwevend",
+	"Frames":											"Frames",
+	"Height":											"Hoogte",
+	"How many columns would you like to merge?":		"Hoeveel kolommen wilt u samenvoegen?",
+	"How many rows would you like to merge?":			"Hoeveel rijen wilt u samenvoegen?",
+	"Image URL":										"Afbeelding URL",
+	"Justify":											"Uitvullen",
+	"Layout":											"Opmaak",
+	"Left":												"Links",
+	"Margin":											"Marge",
+	"Middle":											"Midden",
+	"No rules":											"Geen regels",
+	"No sides":											"Geen zijlijnen",
+	"None":												"Geen",
+	"Padding":											"Celmarge",
+	"Please click into some cell":						"Klik in een cel a.u.b.",
+	"Right":											"Rechts",
+	"Row Properties":									"Rijeigenschappen",
+	"Rules will appear between all rows and columns":	"Regels verschijnen tussen alle rijen en kolommen",
+	"Rules will appear between columns only":	  		"Regels verschijnen enkel tussen de kolommen",
+	"Rules will appear between rows only":				"Regels verschijnen enkel tussen de rijen",
+	"Rules":					  						"Regels",
+	"Spacing and padding":                           	"Celmarge en afstand tussen cellen",
+	"Spacing":											"marge",
+	"Summary":											"Overzicht",
+	"TO-cell-delete":				  					"Cel verwijderen",
+	"TO-cell-insert-after":				  				"Voeg cel toe achter",
+	"TO-cell-insert-before":			  				"Voeg cel toe voor",
+	"TO-cell-merge":									"Cellen samenvoegen",
+	"TO-cell-prop":										"Celeigenschappen",
+	"TO-cell-split":									"Cel splitsen",
+	"TO-col-delete":									"Kolom verwijderen",
+	"TO-col-insert-after":								"Kolom invoegen achter",
+	"TO-col-insert-before":								"Kolom invoegen voor",
+	"TO-col-split":										"Kolom splitsen",
+	"TO-row-delete":									"Rij verwijderen",
+	"TO-row-insert-above":								"Rij invoegen boven",
+	"TO-row-insert-under":								"Rij invoegen onder",
+	"TO-row-prop":										"Rij eigenschappen",
+	"TO-row-split":										"Rij splitsen",
+	"TO-table-prop":				  					"Tabel eigenschappen",
+	"Table Properties":				  					"Tabel eigenschappen",
+	"Text align":                                     	"Text uitlijning",
+	"The bottom side only":				  				"Enkel aan de onderkant",
+	"The left-hand side only":			 				"Enkel aan de linkerkant",
+	"The right and left sides only":		 			"Enkel aan de linker en rechterkant",
+	"The right-hand side only":							"Enkel aan de rechterkant",
+	"The top and bottom sides only":					"Enkel aan de bovenen onderkant",
+	"The top side only":								"Enkel aan de bovenkant",
+	"Top":												"Boven",
+	"Unset color":										"Wis kleur",
+	"Vertical align":									"Vertikale uitlijning",
+	"Width":					 						"Breedte",
+	"not-del-last-cell":								"HTMLArea kan de laatste cel in deze tabel niet verwijderen.",
+	"not-del-last-col":									"HTMLArea kan de laatste kolom in deze tabel niet verwijderen.",
+	"not-del-last-row":									"HTMLArea kan de laatste rij in deze tabel niet verwijderen.",
+	"percent":											"procent",
+	"pixels":											"pixels"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/cz.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/cz.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/cz.js	(revision 795)
@@ -0,0 +1,90 @@
+﻿// I18N constants
+
+// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2
+// Author: Jiri Löw, <jirilow@jirilow.com>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":					  "Zarovnání",
+	"All four sides":				  "Všechny čtyři strany",
+	"Background":					  "Pozadí",
+	"Baseline":                                       "Základní linka",
+	"Border":					  "Obrys",
+	"Borders":					  "Obrysy",
+	"Bottom":                                         "Dolů",
+	"CSS Style":					  "Kaskádové styly (CSS)",
+	"Caption":					  "Titulek",
+	"Cell Properties":                                "Vlastnosti buňky",
+	"Center":					  "Na střed",
+	"Char":                                           "Znak",
+	"Collapsed borders":                              "Stlačené okraje",
+	"Color":					  "Barva",
+	"Description":					  "Popis",
+	"FG Color":					  "Barva popředí",
+	"Float":                                          "Obtékání",
+	"Frames":					  "Rámečky",
+	"Height":                                         "Výška",
+	"How many columns would you like to merge?":      "Kolik sloupců si přejete spojit?",
+	"How many rows would you like to merge?":         "Kolik řádků si přejete spojit?",
+	"Image URL":					  "Adresa obrázku",
+	"Justify":                                        "Do stran",
+	"Layout":					  "Rozložení",
+	"Left":						  "Vlevo",
+	"Margin":                                         "Okraj",
+	"Middle":                                         "Na střed",
+	"No rules":					  "Žádné čáry",
+	"No sides":					  "Žádné strany",
+	"None":                                           "Žádné",
+	"Padding":					  "Odsazování",
+	"Please click into some cell":                    "Prosím klikněte do některé buňky",
+	"Right":					  "Vpravo",
+	"Row Properties":                                 "Vlastnosti řádku",
+	"Rules will appear between all rows and columns": "Čáry mezi všemi řádky i sloupci",
+	"Rules will appear between columns only":	  "Čáry pouze mezi sloupci",
+	"Rules will appear between rows only":		  "Čáry pouze mezi řádky",
+	"Rules":					  "Čáry",
+	"Spacing and padding":                            "Mezery a odsazování",
+	"Spacing":					  "Mezery",
+	"Summary":					  "Shrnutí",
+	"TO-cell-delete":				  "Smazat buňku",
+	"TO-cell-insert-after":				  "Vložit buňku za",
+	"TO-cell-insert-before":			  "Vložit buňku před",
+	"TO-cell-merge":				  "Spojit buňky",
+	"TO-cell-prop":					  "Vlastnosti buňky",
+	"TO-cell-split":				  "Rozdělit buňku",
+	"TO-col-delete":				  "Smazat sloupec",
+	"TO-col-insert-after":				  "Vložit sloupec za",
+	"TO-col-insert-before":				  "Vložit sloupec před",
+	"TO-col-split":					  "Rozdělit sloupec",
+	"TO-row-delete":				  "Smazat řádek",
+	"TO-row-insert-above":				  "Smazat řádek nad",
+	"TO-row-insert-under":				  "Smazat řádek pod",
+	"TO-row-prop":					  "Vlastnosti řádku",
+	"TO-row-split":					  "Rozdělit řádek",
+	"TO-table-prop":				  "Vlastnosti tabulky",
+	"Table Properties":				  "Vlastnosti tabulky",
+	"Text align":                                     "Zarovnání textu",
+	"The bottom side only":				  "Pouze spodní strana",
+	"The left-hand side only":			  "Pouze levá strana",
+	"The right and left sides only":		  "Pouze levá a pravá strana",
+	"The right-hand side only":			  "Pouze pravá strana",
+	"The top and bottom sides only":		  "Pouze horní a dolní strana",
+	"The top side only":				  "Pouze horní strana",
+	"Top":                                            "Nahoru",	
+	"Unset color":                                    "Zrušit barvu",
+	"Vertical align":                                 "Svislé zarovnání",
+	"Width":					  "Šířka",
+	"not-del-last-cell":				  "HTMLArea zbaběle odmítá smazat poslední buňku v řádku.",
+	"not-del-last-col":				  "HTMLArea zbaběle odmítá smazat poslední sloupec v tabulce.",
+	"not-del-last-row":				  "HTMLArea zbaběle odmítá smazat poslední řádek v tabulce.",
+	"percent":					  "procent",
+	"pixels":					  "pixelů"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/he.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/he.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/he.js	(revision 795)
@@ -0,0 +1,90 @@
+// I18N constants
+
+// LANG: "he", ENCODING: UTF-8
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":					  "××©××š",
+	"All four sides":				  "×× ××š××¢×ª ××Š××××",
+	"Background":					  "×š×§×¢",
+	"Baseline":                                       "×§× ××¡××¡",
+	"Border":					  "××××",
+	"Borders":					  "××××××ª",
+	"Bottom":                                         "×ª××ª××",
+	"CSS Style":					  "×¡×× ×× [CSS]",
+	"Caption":					  "×××ª×š×ª",
+	"Cell Properties":                                "×××€××× × ×ª×",
+	"Center":					  "××š××",
+	"Char":                                           "×ª×",
+	"Collapsed borders":                              "××××××ª ×§××š×¡××",
+	"Color":					  "×Š××¢",
+	"Description":					  "×ª××××š",
+	"FG Color":					  "×Š××¢ ×§××××",
+	"Float":                                          "××š××£",
+	"Frames":					  "××¡××š××ª",
+	"Height":                                         "××××",
+	"How many columns would you like to merge?":      "××× ×××š×× ××š×Š×× × ××××?",
+	"How many rows would you like to merge?":         "××× ×©××š××ª ××š×Š×× × ××××?",
+	"Image URL":					  "URL ××ª××× ×",
+	"Justify":                                        "××©××š",
+	"Layout":					  "×€×š××¡×",
+	"Left":						  "×©×××",
+	"Margin":                                         "×©×××××",
+	"Middle":                                         "×××Š×¢",
+	"No rules":					  "××× ×§××××",
+	"No sides":					  "××× ×Š××××",
+	"None":                                           "×××",
+	"Padding":					  "×š×××× ××©×××××",
+	"Please click into some cell":                    "×× × ×××¥ ×¢× ×ª× ×××©××",
+	"Right":					  "××××",
+	"Row Properties":                                 "×××€××× × ×©××š×",
+	"Rules will appear between all rows and columns": "×§×××× ×××€××¢× ××× ×× ××©××š××ª ×××××š××",
+	"Rules will appear between columns only":	  "×§×××× ×××€××¢× ××× ×××š×× ××××",
+	"Rules will appear between rows only":		  "×§×××× ×××€××¢× ××× ×©××š××ª ××××",
+	"Rules":					  "×§××××",
+	"Spacing and padding":                            "×š×××× ××©×××××",
+	"Spacing":					  "×š××××",
+	"Summary":					  "×¡××××",
+	"TO-cell-delete":				  "×××§ ×ª×",
+	"TO-cell-insert-after":				  "××× ×¡ ×ª× ×××š×",
+	"TO-cell-insert-before":			  "××× ×¡ ×ª× ××€× ×",
+	"TO-cell-merge":				  "××× ×ª×××",
+	"TO-cell-prop":					  "×××€××× × ×ª×",
+	"TO-cell-split":				  "×€×Š× ×ª×",
+	"TO-col-delete":				  "×××§ ×××š",
+	"TO-col-insert-after":				  "××× ×¡ ×××š ×××š×",
+	"TO-col-insert-before":				  "××× ×¡ ×××š ××€× ×",
+	"TO-col-split":					  "×€×Š× ×××š",
+	"TO-row-delete":				  "×××§ ×©××š×",
+	"TO-row-insert-above":				  "××× ×¡ ×©××š× ××€× ×",
+	"TO-row-insert-under":				  "××× ×¡ ×©××š× ×××š×",
+	"TO-row-prop":					  "×××€××× × ×©××š×",
+	"TO-row-split":					  "×€×Š× ×©××š×",
+	"TO-table-prop":				  "×××€××× × ××××",
+	"Table Properties":				  "×××€××× × ××××",
+	"Text align":                                     "××©××š ××§×¡×",
+	"The bottom side only":				  "××Š× ××ª××ª×× ××××",
+	"The left-hand side only":			  "××Š× ××©×××× ××××",
+	"The right and left sides only":		  "××Š×××× ×××× × ×××©×××× ××××",
+	"The right-hand side only":			  "××Š× ×××× × ××××",
+	"The top and bottom sides only":		  "××Š×××× ××¢×××× ×××ª××ª×× ××××",
+	"The top side only":				  "××Š× ××¢×××× ××××",
+	"Top":                                            "×¢××××",	
+	"Unset color":                                    "×Š××¢ ×× × ×××š",
+	"Vertical align":                                 "×××©××š ×× ××",
+	"Width":					  "×š×××",
+	"not-del-last-cell":				  "HTMLArea ××¡×š× ××€××× ××ª ×××××§ ××ª ××ª× ××××š×× ××©××š×.",
+	"not-del-last-col":				  "HTMLArea ××¡×š× ××€××× ××ª ×××××§ ××ª ××××š ××××š×× ×××××.",
+	"not-del-last-row":				  "HTMLArea ××¡×š× ××€××× ××ª ×××××§ ××ª ××©××š× ××××š×× × ×××××.",
+	"percent":					  "××××",
+	"pixels":					  "×€××§×¡×××"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/hu.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/hu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/hu.js	(revision 795)
@@ -0,0 +1,63 @@
+// I18N constants
+
+// LANG: "hu", ENCODING: UTF-8
+// Author: MiklÃ³s Somogyi, <somogyine@vnet.hu>
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+	// the following should be the filename without .js extension
+	// it will be used for automatically load plugin language.
+	lang: "hu",
+
+	tooltips: {
+		bold:           "FÃ©lkÃ¶vÃ©r",
+		italic:         "DÅlt",
+		underline:      "AlÃ¡hÃºzott",
+		strikethrough:  "ÃthÃºzott",
+		subscript:      "AlsÃ³ index",
+		superscript:    "FelsÅ index",
+		justifyleft:    "Balra zÃ¡rt",
+		justifycenter:  "KÃ¶zÃ©pre zÃ¡rt",
+		justifyright:   "Jobbra zÃ¡rt",
+		justifyfull:    "SorkizÃ¡rt",
+		orderedlist:    "SzÃ¡mozott lista",
+		unorderedlist:  "SzÃ¡mozatlan lista",
+		outdent:        "BehÃºzÃ¡s csÃ¶kkentÃ©se",
+		indent:         "BehÃºzÃ¡s nÃ¶velÃ©se",
+		forecolor:      "KarakterszÃ­n",
+		hilitecolor:    "HÃ¡ttÃ©rszÃ­n",
+		horizontalrule: "ElvÃ¡lasztÃ³ vonal",
+		createlink:     "HiperhivatkozÃ¡s beszÃºrÃ¡sa",
+		insertimage:    "KÃ©p beszÃºrÃ¡sa",
+		inserttable:    "TÃ¡blÃ¡zat beszÃºrÃ¡sa",
+		htmlmode:       "HTML forrÃ¡s be/ki",
+		popupeditor:    "SzerkesztÅ kÃŒlÃ¶n ablakban",
+		about:          "NÃ©vjegy",
+		showhelp:       "SÃºgÃ³",
+		textindicator:  "AktuÃ¡lis stÃ­lus",
+		undo:           "VisszavonÃ¡s",
+		redo:           "Ãjra vÃ©grehajtÃ¡s",
+		cut:            "KivÃ¡gÃ¡s",
+		copy:           "MÃ¡solÃ¡s",
+		paste:          "BeillesztÃ©s"
+	},
+
+	buttons: {
+		"ok":           "Rendben",
+		"cancel":       "MÃ©gsem"
+	},
+
+	msg: {
+		"Path":         "Hierarchia",
+		"TEXT_MODE":    "ForrÃ¡s mÃ³d. VisszavÃ¡ltÃ¡s [<>] gomb"
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/it.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/it.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/it.js	(revision 795)
@@ -0,0 +1,81 @@
+// I18N constants
+
+// LANG: "it", ENCODING: UTF-8 | ISO-8859-1
+// Author: Fabio Rotondo <fabio@rotondo.it>
+
+TableOperations.I18N = {
+	"Align":					  "Allinea",
+	"All four sides":				  "Tutti e quattro i lati",
+	"Background":					  "Sfondo",
+	"Baseline":                                       "Allineamento",
+	"Border":					  "Bordo",
+	"Borders":					  "Bordi",
+	"Bottom":                                         "Basso",
+	"CSS Style":					  "Stile [CSS]",
+	"Caption":					  "Titolo",
+	"Cell Properties":                                "ProprietÃ  della Cella",
+	"Center":					  "Centra",
+	"Char":                                           "Carattere",
+	"Collapsed borders":                              "Bordi chiusi",
+	"Color":					  "Colore",
+	"Description":					  "Descrizione",
+	"FG Color":					  "Colore Principale",
+	"Float":                                          "Fluttuante",
+	"Frames":					  "Frames",
+	"Height":                                         "Altezza",
+	"How many columns would you like to merge?":      "Quante colonne vuoi unire?",
+	"How many rows would you like to merge?":         "Quante righe vuoi unire?",
+	"Image URL":					  "URL dell'Immagine",
+	"Justify":                                        "Justifica",
+	"Layout":					  "Layout",
+	"Left":						  "Sinistra",
+	"Margin":                                         "Margine",
+	"Middle":                                         "Centrale",
+	"No rules":					  "Nessun righello",
+	"No sides":					  "Nessun lato",
+	"None":                                           "Nulla",
+	"Padding":					  "Padding",
+	"Please click into some cell":                    "Per favore, clicca in una cella",
+	"Right":					  "Destra",
+	"Row Properties":                                 "ProprietÃ  della Riga",
+	"Rules will appear between all rows and columns": "Le linee appariranno tra tutte le righe e colonne",
+	"Rules will appear between columns only":	  "Le linee appariranno solo tra le colonne",
+	"Rules will appear between rows only":		  "Le linee appariranno solo tra le righe",
+	"Rules":					  "Linee",
+	"Spacing and padding":                            "Spaziatura e Padding",
+	"Spacing":					  "Spaziatura",
+	"Summary":					  "Sommario",
+	"TO-cell-delete":				  "Cancella cella",
+	"TO-cell-insert-after":				  "Inserisci cella dopo",
+	"TO-cell-insert-before":			  "Inserisci cella prima",
+	"TO-cell-merge":				  "Unisci celle",
+	"TO-cell-prop":					  "ProprietÃ  della cella",
+	"TO-cell-split":				  "Dividi cella",
+	"TO-col-delete":				  "Cancella colonna",
+	"TO-col-insert-after":				  "Inserisci colonna dopo",
+	"TO-col-insert-before":				  "Inserisci colonna prima",
+	"TO-col-split":					  "Dividi colonna",
+	"TO-row-delete":				  "Cancella riga",
+	"TO-row-insert-above":				  "Inserisci riga prima",
+	"TO-row-insert-under":				  "Inserisci riga dopo",
+	"TO-row-prop":					  "ProprietÃ  della riga",
+	"TO-row-split":					  "Dividi riga",
+	"TO-table-prop":				  "ProprietÃ  della Tabella",
+	"Table Properties":				  "ProprietÃ  della Tabella",
+	"Text align":                                     "Allineamento del Testo",
+	"The bottom side only":				  "Solo la parte inferiore",
+	"The left-hand side only":			  "Solo la parte sinistra",
+	"The right and left sides only":		  "Solo destra e sinistra",
+	"The right-hand side only":			  "Solo la parte destra",
+	"The top and bottom sides only":		  "Solo sopra e sotto",
+	"The top side only":				  "Solo la parte sopra",
+	"Top":                                            "Alto",	
+	"Unset color":                                    "Rimuovi colore",
+	"Vertical align":                                 "Allineamento verticale",
+	"Width":					  "Larghezza",
+	"not-del-last-cell":				  "HTMLArea si rifiuta codardamente di cancellare l'ultima cella nella riga.",
+	"not-del-last-col":				  "HTMLArea si rifiuta codardamente di cancellare l'ultima colonna nella tabella.",
+	"not-del-last-row":				  "HTMLArea si rifiuta codardamente di cancellare l'ultima riga nella tabella.",
+	"percent":					  "percento",
+	"pixels":					  "pixels"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/lang.php	(revision 795)
@@ -0,0 +1,118 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-TableOperations');
+
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http: //dynarch.com/mishoo
+
+// FOR TRANSLATORS: 
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+TableOperations.I18N = {
+	"Align": "<?php echo lang('Align'); ?>",
+	"All four sides": "<?php echo lang('All four sides'); ?>",
+	"Background": "<?php echo lang('Background'); ?>",
+	"Baseline": "<?php echo lang('Baseline'); ?>",
+	"Border": "<?php echo lang('Border'); ?>",
+	"Borders": "<?php echo lang('Borders'); ?>",
+	"Bottom": "<?php echo lang('Bottom'); ?>",
+	"CSS Style": "<?php echo lang('Style [CSS]'); ?>",
+	"Caption": "<?php echo lang('Caption'); ?>",
+	"Cell Properties": "<?php echo lang('Cell Properties'); ?>",
+	"Center": "<?php echo lang('Center'); ?>",
+	"Char": "<?php echo lang('Char'); ?>",
+	"Collapsed borders": "<?php echo lang('Collapsed borders'); ?>",
+	"Color": "<?php echo lang('Color'); ?>",
+	"Description": "<?php echo lang('Description'); ?>",
+	"FG Color": "<?php echo lang('FG Color'); ?>",
+	"Float": "<?php echo lang('Float'); ?>",
+	"Frames": "<?php echo lang('Frames'); ?>",
+	"Height": "<?php echo lang('Height'); ?>",
+	"How many columns would you like to merge?": "<?php echo lang('How many columns would you like to merge?'); ?>",
+	"How many rows would you like to merge?": "<?php echo lang('How many rows would you like to merge?'); ?>",
+	"Image URL": "<?php echo lang('Image URL'); ?>",
+	"Justify": "<?php echo lang('Justify'); ?>",
+	"Layout": "<?php echo lang('Layout'); ?>",
+	"Left": "<?php echo lang('Left'); ?>",
+	"Margin": "<?php echo lang('Margin'); ?>",
+	"Middle": "<?php echo lang('Middle'); ?>",
+	"No rules": "<?php echo lang('No rules'); ?>",
+	"No sides": "<?php echo lang('No sides'); ?>",
+	"None": "<?php echo lang('None'); ?>",
+	"Padding": "<?php echo lang('Padding'); ?>",
+	"Please click into some cell": "<?php echo lang('Please click into some cell'); ?>",
+	"Right": "<?php echo lang('Right'); ?>",
+	"Row Properties": "<?php echo lang('Row Properties'); ?>",
+	"Rules will appear between all rows and columns": "<?php echo lang('Rules will appear between all rows and columns'); ?>",
+	"Rules will appear between columns only": "<?php echo lang('Rules will appear between columns only'); ?>",
+	"Rules will appear between rows only": "<?php echo lang('Rules will appear between rows only'); ?>",
+	"Rules": "<?php echo lang('Rules'); ?>",
+	"Spacing and padding": "<?php echo lang('Spacing and padding'); ?>",
+	"Spacing": "<?php echo lang('Spacing'); ?>",
+	"Summary": "<?php echo lang('Summary'); ?>",
+	"TO-cell-delete": "<?php echo lang('Delete cell'); ?>",
+	"TO-cell-insert-after": "<?php echo lang('Insert cell after'); ?>",
+	"TO-cell-insert-before": "<?php echo lang('Insert cell before'); ?>",
+	"TO-cell-merge": "<?php echo lang('Merge cells'); ?>",
+	"TO-cell-prop": "<?php echo lang('Cell properties'); ?>",
+	"TO-cell-split": "<?php echo lang('Split cell'); ?>",
+	"TO-col-delete": "<?php echo lang('Delete column'); ?>",
+	"TO-col-insert-after": "<?php echo lang('Insert column after'); ?>",
+	"TO-col-insert-before": "<?php echo lang('Insert column before'); ?>",
+	"TO-col-split": "<?php echo lang('Split column'); ?>",
+	"TO-row-delete": "<?php echo lang('Delete row'); ?>",
+	"TO-row-insert-above": "<?php echo lang('Insert row before'); ?>",
+	"TO-row-insert-under": "<?php echo lang('Insert row after'); ?>",
+	"TO-row-prop": "<?php echo lang('Row properties'); ?>",
+	"TO-row-split": "<?php echo lang('Split row'); ?>",
+	"TO-table-prop": "<?php echo lang('Table properties'); ?>",
+	"Table Properties": "<?php echo lang('Table Properties'); ?>",
+	"Text align": "<?php echo lang('Text align'); ?>",
+	"The bottom side only": "<?php echo lang('The bottom side only'); ?>",
+	"The left-hand side only": "<?php echo lang('The left-hand side only'); ?>",
+	"The right and left sides only": "<?php echo lang('The right and left sides only'); ?>",
+	"The right-hand side only": "<?php echo lang('The right-hand side only'); ?>",
+	"The top and bottom sides only": "<?php echo lang('The top and bottom sides only'); ?>",
+	"The top side only": "<?php echo lang('The top side only'); ?>",
+	"Top": "<?php echo lang('Top'); ?>",	
+	"Unset color": "<?php echo lang('Unset color'); ?>",
+	"Vertical align": "<?php echo lang('Vertical align'); ?>",
+	"Width": "<?php echo lang('Width'); ?>",
+	"not-del-last-cell": "<?php echo lang('HTMLArea cowardly refuses to delete the last cell in row.'); ?>",
+	"not-del-last-col": "<?php echo lang('HTMLArea cowardly refuses to delete the last column in table.'); ?>",
+	"not-del-last-row": "<?php echo lang('HTMLArea cowardly refuses to delete the last row in table.'); ?>",
+	"percent": "<?php echo lang('percent'); ?>",
+	"pixels": "<?php echo lang('pixels'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/no.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/no.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/no.js	(revision 795)
@@ -0,0 +1,91 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, <mishoo@infoiasi.ro>
+// translated into Norwegia: ses@online.no  11.11.03
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":					  	"Juster",
+	"All four sides":			  	"Alle fire sider",
+	"Background":					"Bakgrund",
+	"Baseline":                   	"Grunnlinje",
+	"Border":					  	"Kantlinje",
+	"Borders":					  	"Kantlinjer",
+	"Bottom":                     	"Bunn",
+	"CSS Style":					"Stil [CSS]",
+	"Caption":					  	"Overskrift",
+	"Cell Properties":              "Celleegenskaper",
+	"Center":					  	"Sentrer",
+	"Char":                         "Tegn",
+	"Collapsed borders":            "Fjern kantlinjer",
+	"Color":					  	"Farge",
+	"Description":					"Beskrivelse",
+	"FG Color":					  	"FG farge",
+	"Float":                        "Flytende",
+	"Frames":					  	"rammer",
+	"Height":                       "Høyde",
+	"How many columns would you like to merge?":      "Hvor mange kolonner vil du slå sammen?",
+	"How many rows would you like to merge?":         "Hvor mange rader vil du slå sammen?",
+	"Image URL":					"Bildets URL",
+	"Justify":                      "Juster",
+	"Layout":					  	"Layout",
+	"Left":						  	"Venstre",
+	"Margin":                       "Marg",
+	"Middle":                       "Midten",
+	"No rules":					  	"Ingen linjal",
+	"No sides":					  	"Ingen sider",
+	"None":                         "Ingen",
+	"Padding":					  	"Luft",
+	"Please click into some cell":  "Klikk i en eller annen celle",
+	"Right":					  	"Høyre",
+	"Row Properties":               "Egenskaper for rad",
+	"Rules will appear between all rows and columns": "Linjer vil synes mellom alle rader og kolonner",
+	"Rules will appear between columns only":	  "Linjer vil synes kun mellom kolonner",
+	"Rules will appear between rows only":		  "Linjer vil synes kun mellom rader",
+	"Rules":					  	"Linjer",
+	"Spacing and padding":          "Luft",
+	"Spacing":					  	"Luft",
+	"Summary":					  	"Sammendrag",
+	"TO-cell-delete":				"Slett celle",
+	"TO-cell-insert-after":			"Sett inn celle etter",
+	"TO-cell-insert-before":		"Sett inn celle foran",
+	"TO-cell-merge":				"Slå sammen celler",
+	"TO-cell-prop":					"Egenskaper for celle",
+	"TO-cell-split":				"Del celle",
+	"TO-col-delete":				"Slett kolonne",
+	"TO-col-insert-after":			"Skyt inn kolonne etter",
+	"TO-col-insert-before":			"Skyt inn kolonne før",
+	"TO-col-split":					"Del kolonne",
+	"TO-row-delete":				"Slett rad",
+	"TO-row-insert-above":			"Skyt inn rad foran",
+	"TO-row-insert-under":			"Skyt inn rad etter",
+	"TO-row-prop":					"Egenskaper for rad",
+	"TO-row-split":					"Del rad",
+	"TO-table-prop":				"Tabellegenskaper",
+	"Table Properties":				"Tabellegenskaper",
+	"Text align":                   "Juster tekst",
+	"The bottom side only":			"Bunnen kun",
+	"The left-hand side only":		"Venstresiden kun",
+	"The right and left sides only":	"Høyre- og venstresiden kun",
+	"The right-hand side only":			"Høyresiden kun",
+	"The top and bottom sides only":	"The top and bottom sides only",
+	"The top side only":				"Overkanten kun",
+	"Top":                          "Overkant",	
+	"Unset color":                  "Ikke-bestemt farge",
+	"Vertical align":               "Vertikal justering",
+	"Width":					  	"Bredde",
+	"not-del-last-cell":			"HTMLArea nekter å slette siste cellen i tabellen.",
+	"not-del-last-col":				"HTMLArea nekter å slette siste kolonnen i tabellen.",
+	"not-del-last-row":				"HTMLArea nekter å slette siste raden i tabellen.",
+	"percent":					  	"prosent",
+	"pixels":					  	"billedpunkter"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/fi.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/fi.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/fi.js	(revision 795)
@@ -0,0 +1,66 @@
+TableOperations.I18N = {
+	"Align":					  "Kohdistus",
+	"All four sides":				  "Kaikki neljä sivua",
+	"Background":					  "Tausta",
+	"Baseline":                                       "Takaraja",
+	"Border":					  "Reuna",
+	"Borders":					  "Reunat",
+	"Bottom":                                         "Alle",
+	"CSS Style":					  "Tyyli [CSS]",
+	"Caption":					  "Otsikko",
+	"Cell Properties":                                "Solun asetukset",
+	"Center":					  "Keskelle",
+	"Char":                                           "Merkki",
+	"Collapsed borders":                              "Luhistetut reunat",
+	"Color":					  "Väri",
+	"Description":					  "Kuvaus",
+	"FG Color":					  "FG Väri",
+	"Frames":					  "Kehykset",
+	"Image URL":					  "Kuvan osoite",
+	"Layout":					  "Sommittelu",
+	"Left":						  "Vasen",
+	"Margin":                                         "Marginaali",
+	"Middle":                                         "Keskelle",
+	"No rules":					  "Ei viivoja",
+	"No sides":					  "Ei sivuja",
+	"Padding":					  "Palstantäyte",
+	"Right":					  "Oikea",
+	"Row Properties":                                 "Rivin asetukset",
+	"Rules will appear between all rows and columns": "Viivat jokaisen rivin ja sarakkeen välillä",
+	"Rules will appear between columns only":	  "Viivat ainoastaan sarakkeiden välillä",
+	"Rules will appear between rows only":		  "Viivat ainoastaan rivien välillä",
+	"Rules":					  "Viivat",
+	"Spacing":					  "Palstatila",
+	"Summary":					  "Yhteenveto",
+	"TO-cell-delete":				  "Poista solu",
+	"TO-cell-insert-after":				  "Lisää solu perään",
+	"TO-cell-insert-before":			  "Lisää solu ennen",
+	"TO-cell-merge":				  "Yhdistä solut",
+	"TO-cell-prop":					  "Solun asetukset",
+	"TO-cell-split":				  "Jaa solu",
+	"TO-col-delete":				  "Poista sarake",
+	"TO-col-insert-after":				  "Lisää sarake perään",
+	"TO-col-insert-before":				  "Lisää sarake ennen",
+	"TO-col-split":					  "Jaa sarake",
+	"TO-row-delete":				  "Poista rivi",
+	"TO-row-insert-above":				  "Lisää rivi yläpuolelle",
+	"TO-row-insert-under":				  "Lisää rivi alapuolelle",
+	"TO-row-prop":					  "Rivin asetukset",
+	"TO-row-split":					  "Jaa rivi",
+	"TO-table-prop":				  "Taulukon asetukset",
+	"Top":                                            "Ylös",	
+	"Table Properties":				  "Taulukon asetukset",
+	"The bottom side only":				  "Ainoastaan alapuolelle",
+	"The left-hand side only":			  "Ainoastaan vasenreuna",
+	"The right and left sides only":		  "Oikea- ja vasenreuna",
+	"The right-hand side only":			  "Ainoastaan oikeareuna",
+	"The top and bottom sides only":		  "Ylä- ja alapuoli.",
+	"The top side only":				  "Ainoastaan yläpuoli",
+	"Vertical align":                                 "Vertikaali kohdistus",
+	"Width":					  "Leveys",
+	"not-del-last-cell":				  "Ei voida poistaa viimeistä solua rivistä.",
+	"not-del-last-col":				  "Ei voida poistaa viimeistä saraketta taulusta.",
+	"not-del-last-row":				  "Ei voida poistaa viimeistä riviä taulusta.",
+	"percent":					  "prosenttia",
+	"pixels":					  "pikseliä"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/el.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/el.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/el.js	(revision 795)
@@ -0,0 +1,98 @@
+// I18N constants
+
+// LANG: "el", ENCODING: UTF-8 | ISO-8859-7
+// Author: Dimitris Glezos, dimitris@glezos.com
+
+TableOperations.I18N = {
+	"Align":					  "Î£ÏÎ¿Î¯ÏÎ·ÏÎ·",
+	"All four sides":				  "ÎÎ±Î¹ Î¿Î¹ 4 ÏÎ»ÎµÏ
+ÏÎ­Ï",
+	"Background":					  "ÎŠÏÎœÏÎ¿",
+	"Baseline":                                       "Baseline",
+	"Border":					  "Î ÎµÏÎ¯Î³ÏÎ±ÎŒÎŒÎ±",
+	"Borders":					  "Î ÎµÏÎ¹Î³ÏÎ¬ÎŒÎŒÎ±ÏÎ±",
+	"Bottom":                                         "ÎÎ¬ÏÏ ÎŒÎ­ÏÎ¿Ï",
+	"CSS Style":					  "Î£ÏÏ
+Î» [CSS]",
+	"Caption":					  "ÎÎµÎ¶Î¬ÎœÏÎ±",
+	"Cell Properties":                                "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎÎµÎ»Î¹Î¿Ï",
+	"Center":					  "ÎÎ­ÎœÏÏÎ¿",
+	"Char":                                           "Î§Î±ÏÎ±ÎºÏÎ®ÏÎ±Ï",
+	"Collapsed borders":                              "Î£Ï
+ÎŒÏÏÏ
+Î³ÎŒÎ­ÎœÎ± ÏÎµÏÎ¹Î³ÏÎ¬ÎŒÎŒÎ±ÏÎ±",
+	"Color":					  "Î§ÏÏÎŒÎ±",
+	"Description":					  "Î ÎµÏÎ¹Î³ÏÎ±ÏÎ®",
+	"FG Color":					  "Î§ÏÏÎŒÎ± Î±ÎœÏÎ¹ÎºÎµÎ¹ÎŒÎ­ÎœÏÎœ",
+	"Float":                                          "Float",
+	"Frames":					  "Frames",
+	"Height":                                         "ÎÏÎ¿Ï",
+	"How many columns would you like to merge?":      "Î ÏÏÎµÏ ÏÏÎ®Î»ÎµÏ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÎµÎœÏÏÎµÏÎµ;",
+	"How many rows would you like to merge?":         "Î ÏÏÎµÏ Î³ÏÎ±ÎŒÎŒÎ­Ï ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÎµÎœÏÏÎµÏÎµ;",
+	"Image URL":					  "URL ÎµÎ¹ÎºÏÎœÎ±Ï",
+	"Justify":                                        "Î Î»Î®ÏÎ·Ï ÏÏÎ¿Î¯ÏÎ·ÏÎ·",
+	"Layout":					  "ÎÎ¹Î¬ÏÎ±ÎŸÎ·",
+	"Left":						  "ÎÏÎ¹ÏÏÎµÏÎ¬",
+	"Margin":                                         "Î ÎµÏÎ¹ÎžÏÏÎ¹Î¿",
+	"Middle":                                         "ÎÎ­ÎœÏÏÎ¿",
+	"No rules":					  "Î§ÏÏÎ¯Ï ÎÏÎ±ÎŒÎŒÎ­Ï",
+	"No sides":					  "No sides",
+	"None":                                           "Î€Î¯ÏÎ¿ÏÎ±",
+	"Padding":					  "ÎÏÎ¿ÏÎ®",
+	"Please click into some cell":                    "ÎÎ¬ÎœÏÎµ ÎºÎ»Î¹Îº ÎŒÎ­ÏÎ± ÏÎµ ÎºÎ¬ÏÎ¿Î¹Î¿ ÎºÎµÎ»Î¯",
+	"Right":					  "ÎÎµÎŸÎ¹Î¬",
+	"Row Properties":                                 "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎÏÎ±ÎŒÎŒÎ®Ï",
+	"Rules will appear between all rows and columns": "ÎÏÎ±ÎŒÎŒÎ­Ï ÎžÎ± ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÎŒÎµÏÎ±ÎŸÏ ÏÎ»ÏÎœ ÏÏÎœ Î³ÏÎ±ÎŒÎŒÏÎœ ÎºÎ±Î¹ ÏÏÎ·Î»ÏÎœ",
+	"Rules will appear between columns only":	  "ÎÏÎ±ÎŒÎŒÎ­Ï ÎžÎ± ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÎŒÏÎœÎ¿ ÎŒÎµÏÎ±ÎŸÏ ÏÏÎ·Î»ÏÎœ",
+	"Rules will appear between rows only":		  "ÎÏÎ±ÎŒÎŒÎ­Ï ÎžÎ± ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÎŒÏÎœÎ¿ ÎŒÎµÏÎ±ÎŸÏ Î³ÏÎ±ÎŒÎŒÏÎœ",
+	"Rules":					  "ÎÏÎ±ÎŒÎŒÎ­Ï",
+	"Spacing and padding":                            "ÎÏÎ¿ÏÏÎ¬ÏÎµÎ¹Ï ÎºÎ±Î¹ ÎµÏÎ¿ÏÎ­Ï",
+	"Spacing":					  "ÎÏÎ¿ÏÏÎ¬ÏÎµÎ¹Ï",
+	"Summary":					  "Î£ÏÎœÎ¿ÏÎ·",
+	"TO-cell-delete":				  "ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÎºÎµÎ»Î¹Î¿Ï",
+	"TO-cell-insert-after":				  "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÎºÎµÎ»Î¹Î¿Ï ÎŒÎµÏÎ¬",
+	"TO-cell-insert-before":			  "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÎºÎµÎ»Î¹Î¿Ï ÏÏÎ¹Îœ",
+	"TO-cell-merge":				  "Î£Ï
+Î³ÏÏÎœÎµÏ
+ÏÎ· ÎºÎµÎ»Î¹ÏÎœ",
+	"TO-cell-prop":					  "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÎºÎµÎ»Î¹Î¿Ï",
+	"TO-cell-split":				  "ÎÎ¹Î±Î¯ÏÎµÏÎ· ÎºÎµÎ»Î¹Î¿Ï",
+	"TO-col-delete":				  "ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÏÏÎ®Î»Î·Ï",
+	"TO-col-insert-after":				  "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÏÏÎ®Î»Î·Ï ÎŒÎµÏÎ¬",
+	"TO-col-insert-before":				  "ÎÎ¹ÏÎ±Î³ÏÎ³Î® ÏÏÎ®Î»Î·Ï ÏÏÎ¹Îœ",
+	"TO-col-split":					  "ÎÎ¹Î±Î¯ÏÎµÏÎ· ÏÏÎ®Î»Î·Ï",
+	"TO-row-delete":				  "ÎÎ¹Î±Î³ÏÎ±ÏÎ® Î³ÏÎ±ÎŒÎŒÎ®Ï",
+	"TO-row-insert-above":				  "ÎÎ¹ÏÎ±Î³ÏÎ³Î® Î³ÏÎ±ÎŒÎŒÎ®Ï ÎŒÎµÏÎ¬",
+	"TO-row-insert-under":				  "ÎÎ¹ÏÎ±Î³ÏÎ³Î® Î³ÏÎ±ÎŒÎŒÎ®Ï ÏÏÎ¹Îœ",
+	"TO-row-prop":					  "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ Î³ÏÎ±ÎŒÎŒÎ®Ï",
+	"TO-row-split":					  "ÎÎ¹Î±Î¯ÏÎµÏÎ· Î³ÏÎ±ÎŒÎŒÎ®Ï",
+	"TO-table-prop":				  "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÏÎ¯ÎœÎ±ÎºÎ±",
+	"Table Properties":				  "ÎÎŽÎ¹ÏÏÎ·ÏÎµÏ ÏÎ¯ÎœÎ±ÎºÎ±",
+	"Text align":                                     "Î£ÏÎ¿Î¯ÏÎ·ÏÎ· ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+",
+	"The bottom side only":				  "Î ÎºÎ¬ÏÏ ÏÎ»ÎµÏ
+ÏÎ¬ ÎŒÏÎœÎ¿",
+	"The left-hand side only":			  "Î Î±ÏÎ¹ÏÏÎµÏÎ® ÏÎ»ÎµÏ
+ÏÎ¬ ÎŒÏÎœÎ¿",
+	"The right and left sides only":		  "ÎÎ¹ ÎŽÎµÎŸÎ¹Î­Ï ÎºÎ±Î¹ Î±ÏÎ¹ÏÏÎµÏÎ­Ï ÏÎ»ÎµÏ
+ÏÎ­Ï ÎŒÏÎœÎ¿",
+	"The right-hand side only":			  "Î ÎŽÎµÎŸÎ¹Î¬ ÏÎ»ÎµÏ
+ÏÎ¬ ÎŒÏÎœÎ¿",
+	"The top and bottom sides only":		  "ÎÎ¹ ÏÎ¬ÎœÏ ÎºÎ±Î¹ ÎºÎ¬ÏÏ ÏÎ»ÎµÏ
+ÏÎ­Ï ÎŒÏÎœÎ¿",
+	"The top side only":				  "Î ÏÎ¬ÎœÏ ÏÎ»ÎµÏ
+ÏÎ¬ ÎŒÏÎœÎ¿",
+	"Top":                                            "Î Î¬ÎœÏ",	
+	"Unset color":                                    "ÎÎœÎ±Î¯ÏÎµÏÎ· ÏÏÏÎŒÎ±ÏÎ¿Ï",
+	"Vertical align":                                 "ÎÎ±ÏÎ±ÎºÏÏÏ
+ÏÎ· ÏÏÎ¿Î¯ÏÎ·ÏÎ·",
+	"Width":					  "Î Î»Î¬ÏÎ¿Ï",
+	"not-del-last-cell":				  "ÎÎµÎœ ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± ÎŽÎ¹Î±Î³ÏÎ±ÏÎµÎ¯ ÏÎ¿ ÏÎµÎ»ÎµÏ
+ÏÎ±Î¯Î¿ ÎºÎµÎ»Î¯ ÏÎµ ÎŒÎ¹Î± Î³ÏÎ±ÎŒÎŒÎ®.",
+	"not-del-last-col":				  "ÎÎµÎœ ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± ÎŽÎ¹Î±Î³ÏÎ±ÏÎµÎ¯ Î· ÏÎµÎ»ÎµÏ
+ÏÎ±Î¯Î± ÏÏÎ®Î»Î· ÏÎµ Î­ÎœÎ± ÏÎ¯ÎœÎ±ÎºÎ±.",
+	"not-del-last-row":				  "ÎÎµÎœ ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± ÎŽÎ¹Î±Î³ÏÎ±ÏÎµÎ¯ Î· ÏÎµÎ»ÎµÏ
+ÏÎ±Î¯Î± Î³ÏÎ±ÎŒÎŒÎ® ÏÎµ Î­ÎœÎ± ÏÎ¯ÎœÎ±ÎºÎ±.",
+	"percent":					  "ÏÎ¿Î¹Ï ÎµÎºÎ±ÏÏÎœ",
+	"pixels":					  "pixels"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/ro.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/ro.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/ro.js	(revision 795)
@@ -0,0 +1,90 @@
+// I18N constants
+
+// LANG: "ro", ENCODING: UTF-8
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":					  "Aliniere",
+	"All four sides":				  "Toate pÄrÅ£ile",
+	"Background":					  "Fundal",
+	"Baseline":                                       "Baseline",
+	"Border":					  "Chenar",
+	"Borders":					  "Chenare",
+	"Bottom":                                         "Jos",
+	"CSS Style":					  "Stil [CSS]",
+	"Caption":					  "Titlu de tabel",
+	"Cell Properties":                                "ProprietÄÅ£ile celulei",
+	"Center":					  "Centru",
+	"Char":                                           "Caracter",
+	"Collapsed borders":                              "Chenare asimilate",
+	"Color":					  "Culoare",
+	"Description":					  "Descriere",
+	"FG Color":					  "Culoare text",
+	"Float":                                          "PoziÅ£ie",
+	"Frames":					  "Chenare",
+	"Height":                                         "ÃnÄlÅ£imea",
+	"How many columns would you like to merge?":      "CÃ¢te coloane vrei sÄ uneÅti?",
+	"How many rows would you like to merge?":         "CÃ¢te linii vrei sÄ uneÅti?",
+	"Image URL":					  "URL-ul imaginii",
+	"Justify":                                        "Justify",
+	"Layout":					  "Aranjament",
+	"Left":						  "StÃ¢nga",
+	"Margin":                                         "Margine",
+	"Middle":                                         "Mijloc",
+	"No rules":					  "FÄrÄ linii",
+	"No sides":					  "FÄrÄ pÄrÅ£i",
+	"None":                                           "Nimic",
+	"Padding":					  "SpaÅ£iere",
+	"Please click into some cell":                    "VÄ rog sÄ daÅ£i click Ã®ntr-o celulÄ",
+	"Right":					  "Dreapta",
+	"Row Properties":                                 "ProprietÄÅ£ile liniei",
+	"Rules will appear between all rows and columns": "Vor apÄrea linii Ã®ntre toate rÃ¢ndurile Åi coloanele",
+	"Rules will appear between columns only":	  "Vor apÄrea doar linii verticale",
+	"Rules will appear between rows only":		  "Vor apÄrea doar linii orizontale",
+	"Rules":					  "Linii",
+	"Spacing and padding":                            "SpaÅ£ierea",
+	"Spacing":					  "Ãntre celule",
+	"Summary":					  "Sumar",
+	"TO-cell-delete":				  "Återge celula",
+	"TO-cell-insert-after":				  "InsereazÄ o celulÄ la dreapta",
+	"TO-cell-insert-before":			  "InsereazÄ o celulÄ la stÃ¢nga",
+	"TO-cell-merge":				  "UneÅte celulele",
+	"TO-cell-prop":					  "ProprietÄÅ£ile celulei",
+	"TO-cell-split":				  "Ãmparte celula",
+	"TO-col-delete":				  "Återge coloana",
+	"TO-col-insert-after":				  "InsereazÄ o coloanÄ la dreapta",
+	"TO-col-insert-before":				  "InsereazÄ o coloanÄ la stÃ¢nga",
+	"TO-col-split":					  "Ãmparte coloana",
+	"TO-row-delete":				  "Återge rÃ¢ndul",
+	"TO-row-insert-above":				  "InsereazÄ un rÃ¢nd Ã®nainte",
+	"TO-row-insert-under":				  "InsereazÄ un rÃ¢nd dupÄ",
+	"TO-row-prop":					  "ProprietÄÅ£ile rÃ¢ndului",
+	"TO-row-split":					  "Ãmparte rÃ¢ndul",
+	"TO-table-prop":				  "ProprietÄÅ£ile tabelei",
+	"Table Properties":				  "ProprietÄÅ£ile tabelei",
+	"Text align":                                     "Aliniere",
+	"The bottom side only":				  "Doar partea de jos",
+	"The left-hand side only":			  "Doar partea din stÃ¢nga",
+	"The right and left sides only":		  "Partea din stÃ¢nga Åi cea din dreapta",
+	"The right-hand side only":			  "Doar partea din dreapta",
+	"The top and bottom sides only":		  "Partea de sus si cea de jos",
+	"The top side only":				  "Doar partea de sus",
+	"Top":                                            "Sus",	
+	"Unset color":                                    "DezactiveazÄ culoarea",
+	"Vertical align":                                 "Aliniere pe verticalÄ",
+	"Width":					  "LÄÅ£ime",
+	"not-del-last-cell":				  "HTMLArea refuzÄ cu laÅitate sÄ ÅteargÄ ultima celulÄ din rÃ¢nd.",
+	"not-del-last-col":				  "HTMLArea refuzÄ cu laÅitate sÄ ÅteargÄ ultima coloamÄ din tabela.",
+	"not-del-last-row":				  "HTMLArea refuzÄ cu laÅitate sÄ ÅteargÄ ultimul rÃ¢nd din tabela.",
+	"percent":					  "procente",
+	"pixels":					  "pixeli"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/makefile.xml
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/makefile.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/makefile.xml	(revision 795)
@@ -0,0 +1,3 @@
+<files>
+  <file name="*.js" />
+</files>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/lang/en.js	(revision 795)
@@ -0,0 +1,90 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+TableOperations.I18N = {
+	"Align":					  "Align",
+	"All four sides":				  "All four sides",
+	"Background":					  "Background",
+	"Baseline":                                       "Baseline",
+	"Border":					  "Border",
+	"Borders":					  "Borders",
+	"Bottom":                                         "Bottom",
+	"CSS Style":					  "Style [CSS]",
+	"Caption":					  "Caption",
+	"Cell Properties":                                "Cell Properties",
+	"Center":					  "Center",
+	"Char":                                           "Char",
+	"Collapsed borders":                              "Collapsed borders",
+	"Color":					  "Color",
+	"Description":					  "Description",
+	"FG Color":					  "FG Color",
+	"Float":                                          "Float",
+	"Frames":					  "Frames",
+	"Height":                                         "Height",
+	"How many columns would you like to merge?":      "How many columns would you like to merge?",
+	"How many rows would you like to merge?":         "How many rows would you like to merge?",
+	"Image URL":					  "Image URL",
+	"Justify":                                        "Justify",
+	"Layout":					  "Layout",
+	"Left":						  "Left",
+	"Margin":                                         "Margin",
+	"Middle":                                         "Middle",
+	"No rules":					  "No rules",
+	"No sides":					  "No sides",
+	"None":                                           "None",
+	"Padding":					  "Padding",
+	"Please click into some cell":                    "Please click into some cell",
+	"Right":					  "Right",
+	"Row Properties":                                 "Row Properties",
+	"Rules will appear between all rows and columns": "Rules will appear between all rows and columns",
+	"Rules will appear between columns only":	  "Rules will appear between columns only",
+	"Rules will appear between rows only":		  "Rules will appear between rows only",
+	"Rules":					  "Rules",
+	"Spacing and padding":                            "Spacing and padding",
+	"Spacing":					  "Spacing",
+	"Summary":					  "Summary",
+	"TO-cell-delete":				  "Delete cell",
+	"TO-cell-insert-after":				  "Insert cell after",
+	"TO-cell-insert-before":			  "Insert cell before",
+	"TO-cell-merge":				  "Merge cells",
+	"TO-cell-prop":					  "Cell properties",
+	"TO-cell-split":				  "Split cell",
+	"TO-col-delete":				  "Delete column",
+	"TO-col-insert-after":				  "Insert column after",
+	"TO-col-insert-before":				  "Insert column before",
+	"TO-col-split":					  "Split column",
+	"TO-row-delete":				  "Delete row",
+	"TO-row-insert-above":				  "Insert row before",
+	"TO-row-insert-under":				  "Insert row after",
+	"TO-row-prop":					  "Row properties",
+	"TO-row-split":					  "Split row",
+	"TO-table-prop":				  "Table properties",
+	"Table Properties":				  "Table Properties",
+	"Text align":                                     "Text align",
+	"The bottom side only":				  "The bottom side only",
+	"The left-hand side only":			  "The left-hand side only",
+	"The right and left sides only":		  "The right and left sides only",
+	"The right-hand side only":			  "The right-hand side only",
+	"The top and bottom sides only":		  "The top and bottom sides only",
+	"The top side only":				  "The top side only",
+	"Top":                                            "Top",	
+	"Unset color":                                    "Unset color",
+	"Vertical align":                                 "Vertical align",
+	"Width":					  "Width",
+	"not-del-last-cell":				  "HTMLArea cowardly refuses to delete the last cell in row.",
+	"not-del-last-col":				  "HTMLArea cowardly refuses to delete the last column in table.",
+	"not-del-last-row":				  "HTMLArea cowardly refuses to delete the last row in table.",
+	"percent":					  "percent",
+	"pixels":					  "pixels"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/table-operations.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/table-operations.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/table-operations.js	(revision 795)
@@ -0,0 +1,1159 @@
+// Table Operations Plugin for HTMLArea-3.0
+// Implementation by Mihai Bazon.  Sponsored by http://www.bloki.com
+//
+// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc.
+// This notice MUST stay intact for use (see license.txt).
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon for InteractiveTools.
+//   http://dynarch.com/mishoo
+//
+
+// Object that will encapsulate all the table operations provided by
+// HTMLArea-3.0 (except "insert table" which is included in the main file)
+function TableOperations(editor) {
+	this.editor = editor;
+
+	var cfg = editor.config;
+	var tt = TableOperations.I18N;
+	var bl = TableOperations.btnList;
+	var self = this;
+
+	// register the toolbar buttons provided by this plugin
+	var toolbar = ["linebreak"];
+	for (var i in bl) {
+		var btn = bl[i];
+		if (!btn) {
+			toolbar.push("separator");
+		} else {
+			var id = "TO-" + btn[0];
+			cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "TableOperations"), false,
+					   function(editor, id) {
+						   // dispatch button press event
+						   self.buttonPress(editor, id);
+					   }, btn[1]);
+			toolbar.push(id);
+		}
+	}
+
+	// add a new line in the toolbar
+	cfg.toolbar.push(toolbar);
+};
+
+TableOperations._pluginInfo = {
+	name          : "TableOperations",
+	version       : "1.0",
+	developer     : "Mihai Bazon",
+	developer_url : "http://dynarch.com/mishoo/",
+	c_owner       : "Mihai Bazon",
+	sponsor       : "Zapatec Inc.",
+	sponsor_url   : "http://www.bloki.com",
+	license       : "htmlArea"
+};
+
+/************************
+ * UTILITIES
+ ************************/
+
+// retrieves the closest element having the specified tagName in the list of
+// ancestors of the current selection/caret.
+TableOperations.prototype.getClosest = function(tagName) {
+	var editor = this.editor;
+	var ancestors = editor.getAllAncestors();
+	var ret = null;
+	tagName = ("" + tagName).toLowerCase();
+	for (var i in ancestors) {
+		var el = ancestors[i];
+		if (el.tagName.toLowerCase() == tagName) {
+			ret = el;
+			break;
+		}
+	}
+	return ret;
+};
+
+// this function requires the file PopupDiv/PopupWin to be loaded from browser
+TableOperations.prototype.dialogTableProperties = function() {
+	var i18n = TableOperations.I18N;
+	// retrieve existing values
+	var table = this.getClosest("table");
+	// this.editor.selectNodeContents(table);
+	// this.editor.updateToolbar();
+
+	var dialog = new PopupWin(this.editor, i18n["Table Properties"], function(dialog, params) {
+		TableOperations.processStyle(params, table);
+		for (var i in params) {
+			var val = params[i];
+			switch (i) {
+			    case "f_caption":
+				if (/\S/.test(val)) {
+					// contains non white-space characters
+					var caption = table.getElementsByTagName("caption")[0];
+					if (!caption) {
+						caption = dialog.editor._doc.createElement("caption");
+						table.insertBefore(caption, table.firstChild);
+					}
+					caption.innerHTML = val;
+				} else {
+					// search for caption and delete it if found
+					var caption = table.getElementsByTagName("caption")[0];
+					if (caption) {
+						caption.parentNode.removeChild(caption);
+					}
+				}
+				break;
+			    case "f_summary":
+				table.summary = val;
+				break;
+			    case "f_width":
+				table.style.width = ("" + val) + params.f_unit;
+				break;
+			    case "f_align":
+				table.align = val;
+				break;
+			    case "f_spacing":
+				table.cellSpacing = val;
+				break;
+			    case "f_padding":
+				table.cellPadding = val;
+				break;
+			    case "f_borders":
+				table.border = val;
+				break;
+			    case "f_frames":
+				table.frame = val;
+				break;
+			    case "f_rules":
+				table.rules = val;
+				break;
+			}
+		}
+		// various workarounds to refresh the table display (Gecko,
+		// what's going on?! do not disappoint me!)
+		dialog.editor.forceRedraw();
+		dialog.editor.focusEditor();
+		dialog.editor.updateToolbar();
+		var save_collapse = table.style.borderCollapse;
+		table.style.borderCollapse = "collapse";
+		table.style.borderCollapse = "separate";
+		table.style.borderCollapse = save_collapse;
+	},
+
+	// this function gets called when the dialog needs to be initialized
+	function (dialog) {
+
+		var f_caption = "";
+		var capel = table.getElementsByTagName("caption")[0];
+		if (capel) {
+			f_caption = capel.innerHTML;
+		}
+		var f_summary = table.summary;
+		var f_width = parseInt(table.style.width);
+		isNaN(f_width) && (f_width = "");
+		var f_unit = /%/.test(table.style.width) ? 'percent' : 'pixels';
+		var f_align = table.align;
+		var f_spacing = table.cellSpacing;
+		var f_padding = table.cellPadding;
+		var f_borders = table.border;
+		var f_frames = table.frame;
+		var f_rules = table.rules;
+
+		function selected(val) {
+			return val ? " selected" : "";
+		};
+
+		// dialog contents
+		dialog.content.style.width = "400px";
+		dialog.content.innerHTML = " \
+<div class='title'\
+ style='background: url(" + dialog.baseURL + dialog.editor.imgURL("table-prop.gif", "TableOperations") + ") #fff 98% 50% no-repeat'>" + i18n["Table Properties"] + "\
+</div> \
+<table style='width:100%'> \
+  <tr> \
+    <td> \
+      <fieldset><legend>" + i18n["Description"] + "</legend> \
+       <table style='width:100%'> \
+        <tr> \
+          <td class='label'>" + i18n["Caption"] + ":</td> \
+          <td class='value'><input type='text' name='f_caption' value='" + f_caption + "'/></td> \
+        </tr><tr> \
+          <td class='label'>" + i18n["Summary"] + ":</td> \
+          <td class='value'><input type='text' name='f_summary' value='" + f_summary + "'/></td> \
+        </tr> \
+       </table> \
+      </fieldset> \
+    </td> \
+  </tr> \
+  <tr><td id='--HA-layout'></td></tr> \
+  <tr> \
+    <td> \
+      <fieldset><legend>" + i18n["Spacing and padding"] + "</legend> \
+       <table style='width:100%'> \
+"+//        <tr> \
+//           <td class='label'>" + i18n["Width"] + ":</td> \
+//           <td><input type='text' name='f_width' value='" + f_width + "' size='5' /> \
+//             <select name='f_unit'> \
+//               <option value='%'" + selected(f_unit == "percent") + ">" + i18n["percent"] + "</option> \
+//               <option value='px'" + selected(f_unit == "pixels") + ">" + i18n["pixels"] + "</option> \
+//             </select> &nbsp;&nbsp;" + i18n["Align"] + ": \
+//             <select name='f_align'> \
+//               <option value='left'" + selected(f_align == "left") + ">" + i18n["Left"] + "</option> \
+//               <option value='center'" + selected(f_align == "center") + ">" + i18n["Center"] + "</option> \
+//               <option value='right'" + selected(f_align == "right") + ">" + i18n["Right"] + "</option> \
+//             </select> \
+//           </td> \
+//         </tr> \
+"        <tr> \
+          <td class='label'>" + i18n["Spacing"] + ":</td> \
+          <td><input type='text' name='f_spacing' size='5' value='" + f_spacing + "' /> &nbsp;" + i18n["Padding"] + ":\
+            <input type='text' name='f_padding' size='5' value='" + f_padding + "' /> &nbsp;&nbsp;" + i18n["pixels"] + "\
+          </td> \
+        </tr> \
+       </table> \
+      </fieldset> \
+    </td> \
+  </tr> \
+  <tr> \
+    <td> \
+      <fieldset><legend>Frame and borders</legend> \
+        <table width='100%'> \
+          <tr> \
+            <td class='label'>" + i18n["Borders"] + ":</td> \
+            <td><input name='f_borders' type='text' size='5' value='" + f_borders + "' /> &nbsp;&nbsp;" + i18n["pixels"] + "</td> \
+          </tr> \
+          <tr> \
+            <td class='label'>" + i18n["Frames"] + ":</td> \
+            <td> \
+              <select name='f_frames'> \
+                <option value='void'" + selected(f_frames == "void") + ">" + i18n["No sides"] + "</option> \
+                <option value='above'" + selected(f_frames == "above") + ">" + i18n["The top side only"] + "</option> \
+                <option value='below'" + selected(f_frames == "below") + ">" + i18n["The bottom side only"] + "</option> \
+                <option value='hsides'" + selected(f_frames == "hsides") + ">" + i18n["The top and bottom sides only"] + "</option> \
+                <option value='vsides'" + selected(f_frames == "vsides") + ">" + i18n["The right and left sides only"] + "</option> \
+                <option value='lhs'" + selected(f_frames == "lhs") + ">" + i18n["The left-hand side only"] + "</option> \
+                <option value='rhs'" + selected(f_frames == "rhs") + ">" + i18n["The right-hand side only"] + "</option> \
+                <option value='box'" + selected(f_frames == "box") + ">" + i18n["All four sides"] + "</option> \
+              </select> \
+            </td> \
+          </tr> \
+          <tr> \
+            <td class='label'>" + i18n["Rules"] + ":</td> \
+            <td> \
+              <select name='f_rules'> \
+                <option value='none'" + selected(f_rules == "none") + ">" + i18n["No rules"] + "</option> \
+                <option value='rows'" + selected(f_rules == "rows") + ">" + i18n["Rules will appear between rows only"] + "</option> \
+                <option value='cols'" + selected(f_rules == "cols") + ">" + i18n["Rules will appear between columns only"] + "</option> \
+                <option value='all'" + selected(f_rules == "all") + ">" + i18n["Rules will appear between all rows and columns"] + "</option> \
+              </select> \
+            </td> \
+          </tr> \
+        </table> \
+      </fieldset> \
+    </td> \
+  </tr> \
+  <tr> \
+    <td id='--HA-style'></td> \
+  </tr> \
+</table> \
+";
+		var st_prop = TableOperations.createStyleFieldset(dialog.doc, dialog.editor, table);
+		var p = dialog.doc.getElementById("--HA-style");
+		p.appendChild(st_prop);
+		var st_layout = TableOperations.createStyleLayoutFieldset(dialog.doc, dialog.editor, table);
+		p = dialog.doc.getElementById("--HA-layout");
+		p.appendChild(st_layout);
+		dialog.modal = true;
+		dialog.addButtons("ok", "cancel");
+		dialog.showAtElement(dialog.editor._iframe, "c");
+	});
+};
+
+// this function requires the file PopupDiv/PopupWin to be loaded from browser
+TableOperations.prototype.dialogRowCellProperties = function(cell) {
+	var i18n = TableOperations.I18N;
+	// retrieve existing values
+	var element = this.getClosest(cell ? "td" : "tr");
+	var table = this.getClosest("table");
+	// this.editor.selectNodeContents(element);
+	// this.editor.updateToolbar();
+
+	var dialog = new PopupWin(this.editor, i18n[cell ? "Cell Properties" : "Row Properties"], function(dialog, params) {
+		TableOperations.processStyle(params, element);
+		for (var i in params) {
+			var val = params[i];
+			switch (i) {
+			    case "f_align":
+				element.align = val;
+				break;
+			    case "f_char":
+				element.ch = val;
+				break;
+			    case "f_valign":
+				element.vAlign = val;
+				break;
+			}
+		}
+		// various workarounds to refresh the table display (Gecko,
+		// what's going on?! do not disappoint me!)
+		dialog.editor.forceRedraw();
+		dialog.editor.focusEditor();
+		dialog.editor.updateToolbar();
+		var save_collapse = table.style.borderCollapse;
+		table.style.borderCollapse = "collapse";
+		table.style.borderCollapse = "separate";
+		table.style.borderCollapse = save_collapse;
+	},
+
+	// this function gets called when the dialog needs to be initialized
+	function (dialog) {
+
+		var f_align = element.align;
+		var f_valign = element.vAlign;
+		var f_char = element.ch;
+
+		function selected(val) {
+			return val ? " selected" : "";
+		};
+
+		// dialog contents
+		dialog.content.style.width = "400px";
+		dialog.content.innerHTML = " \
+<div class='title'\
+ style='background: url(" + dialog.baseURL + dialog.editor.imgURL(cell ? "cell-prop.gif" : "row-prop.gif", "TableOperations") + ") #fff 98% 50% no-repeat'>" + i18n[cell ? "Cell Properties" : "Row Properties"] + "</div> \
+<table style='width:100%'> \
+  <tr> \
+    <td id='--HA-layout'> \
+"+//      <fieldset><legend>" + i18n["Layout"] + "</legend> \
+//        <table style='width:100%'> \
+//         <tr> \
+//           <td class='label'>" + i18n["Align"] + ":</td> \
+//           <td> \
+//             <select name='f_align'> \
+//               <option value='left'" + selected(f_align == "left") + ">" + i18n["Left"] + "</option> \
+//               <option value='center'" + selected(f_align == "center") + ">" + i18n["Center"] + "</option> \
+//               <option value='right'" + selected(f_align == "right") + ">" + i18n["Right"] + "</option> \
+//               <option value='char'" + selected(f_align == "char") + ">" + i18n["Char"] + "</option> \
+//             </select> \
+//             &nbsp;&nbsp;" + i18n["Char"] + ": \
+//             <input type='text' style='font-family: monospace; text-align: center' name='f_char' size='1' value='" + f_char + "' /> \
+//           </td> \
+//         </tr><tr> \
+//           <td class='label'>" + i18n["Vertical align"] + ":</td> \
+//           <td> \
+//             <select name='f_valign'> \
+//               <option value='top'" + selected(f_valign == "top") + ">" + i18n["Top"] + "</option> \
+//               <option value='middle'" + selected(f_valign == "middle") + ">" + i18n["Middle"] + "</option> \
+//               <option value='bottom'" + selected(f_valign == "bottom") + ">" + i18n["Bottom"] + "</option> \
+//               <option value='baseline'" + selected(f_valign == "baseline") + ">" + i18n["Baseline"] + "</option> \
+//             </select> \
+//           </td> \
+//         </tr> \
+//        </table> \
+//       </fieldset> \
+"    </td> \
+  </tr> \
+  <tr> \
+    <td id='--HA-style'></td> \
+  </tr> \
+</table> \
+";
+		var st_prop = TableOperations.createStyleFieldset(dialog.doc, dialog.editor, element);
+		var p = dialog.doc.getElementById("--HA-style");
+		p.appendChild(st_prop);
+		var st_layout = TableOperations.createStyleLayoutFieldset(dialog.doc, dialog.editor, element);
+		p = dialog.doc.getElementById("--HA-layout");
+		p.appendChild(st_layout);
+		dialog.modal = true;
+		dialog.addButtons("ok", "cancel");
+		dialog.showAtElement(dialog.editor._iframe, "c");
+	});
+};
+
+// this function gets called when some button from the TableOperations toolbar
+// was pressed.
+TableOperations.prototype.buttonPress = function(editor, button_id) {
+	this.editor = editor;
+	var mozbr = HTMLArea.is_gecko ? "<br />" : "";
+	var i18n = TableOperations.I18N;
+
+	// helper function that clears the content in a table row
+	function clearRow(tr) {
+		var tds = tr.getElementsByTagName("td");
+		for (var i = tds.length; --i >= 0;) {
+			var td = tds[i];
+			td.rowSpan = 1;
+			td.innerHTML = mozbr;
+		}
+	};
+
+	function splitRow(td) {
+		var n = parseInt("" + td.rowSpan);
+		var nc = parseInt("" + td.colSpan);
+		td.rowSpan = 1;
+		tr = td.parentNode;
+		var itr = tr.rowIndex;
+		var trs = tr.parentNode.rows;
+		var index = td.cellIndex;
+		while (--n > 0) {
+			tr = trs[++itr];
+			var otd = editor._doc.createElement("td");
+			otd.colSpan = td.colSpan;
+			otd.innerHTML = mozbr;
+			tr.insertBefore(otd, tr.cells[index]);
+		}
+		editor.forceRedraw();
+		editor.updateToolbar();
+	};
+
+	function splitCol(td) {
+		var nc = parseInt("" + td.colSpan);
+		td.colSpan = 1;
+		tr = td.parentNode;
+		var ref = td.nextSibling;
+		while (--nc > 0) {
+			var otd = editor._doc.createElement("td");
+			otd.rowSpan = td.rowSpan;
+			otd.innerHTML = mozbr;
+			tr.insertBefore(otd, ref);
+		}
+		editor.forceRedraw();
+		editor.updateToolbar();
+	};
+
+	function splitCell(td) {
+		var nc = parseInt("" + td.colSpan);
+		splitCol(td);
+		var items = td.parentNode.cells;
+		var index = td.cellIndex;
+		while (nc-- > 0) {
+			splitRow(items[index++]);
+		}
+	};
+
+	function selectNextNode(el) {
+		var node = el.nextSibling;
+		while (node && node.nodeType != 1) {
+			node = node.nextSibling;
+		}
+		if (!node) {
+			node = el.previousSibling;
+			while (node && node.nodeType != 1) {
+				node = node.previousSibling;
+			}
+		}
+		if (!node) {
+			node = el.parentNode;
+		}
+		editor.selectNodeContents(node);
+	};
+
+	switch (button_id) {
+		// ROWS
+
+	    case "TO-row-insert-above":
+	    case "TO-row-insert-under":
+		var tr = this.getClosest("tr");
+		if (!tr) {
+			break;
+		}
+		var otr = tr.cloneNode(true);
+		clearRow(otr);
+		tr.parentNode.insertBefore(otr, /under/.test(button_id) ? tr.nextSibling : tr);
+		editor.forceRedraw();
+		editor.focusEditor();
+		break;
+	    case "TO-row-delete":
+		var tr = this.getClosest("tr");
+		if (!tr) {
+			break;
+		}
+		var par = tr.parentNode;
+		if (par.rows.length == 1) {
+			alert(i18n["not-del-last-row"]);
+			break;
+		}
+		// set the caret first to a position that doesn't
+		// disappear.
+		selectNextNode(tr);
+		par.removeChild(tr);
+		editor.forceRedraw();
+		editor.focusEditor();
+		editor.updateToolbar();
+		break;
+	    case "TO-row-split":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		splitRow(td);
+		break;
+
+		// COLUMNS
+
+	    case "TO-col-insert-before":
+	    case "TO-col-insert-after":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		var rows = td.parentNode.parentNode.rows;
+		var index = td.cellIndex;
+		for (var i = rows.length; --i >= 0;) {
+			var tr = rows[i];
+			var ref = tr.cells[index + (/after/.test(button_id) ? 1 : 0)];
+			var otd = editor._doc.createElement("td");
+			otd.innerHTML = mozbr;
+			tr.insertBefore(otd, ref);
+		}
+		editor.focusEditor();
+		break;
+	    case "TO-col-split":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		splitCol(td);
+		break;
+	    case "TO-col-delete":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		var index = td.cellIndex;
+		if (td.parentNode.cells.length == 1) {
+			alert(i18n["not-del-last-col"]);
+			break;
+		}
+		// set the caret first to a position that doesn't disappear
+		selectNextNode(td);
+		var rows = td.parentNode.parentNode.rows;
+		for (var i = rows.length; --i >= 0;) {
+			var tr = rows[i];
+			tr.removeChild(tr.cells[index]);
+		}
+		editor.forceRedraw();
+		editor.focusEditor();
+		editor.updateToolbar();
+		break;
+
+		// CELLS
+
+	    case "TO-cell-split":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		splitCell(td);
+		break;
+	    case "TO-cell-insert-before":
+	    case "TO-cell-insert-after":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		var tr = td.parentNode;
+		var otd = editor._doc.createElement("td");
+		otd.innerHTML = mozbr;
+		tr.insertBefore(otd, /after/.test(button_id) ? td.nextSibling : td);
+		editor.forceRedraw();
+		editor.focusEditor();
+		break;
+	    case "TO-cell-delete":
+		var td = this.getClosest("td");
+		if (!td) {
+			break;
+		}
+		if (td.parentNode.cells.length == 1) {
+			alert(i18n["not-del-last-cell"]);
+			break;
+		}
+		// set the caret first to a position that doesn't disappear
+		selectNextNode(td);
+		td.parentNode.removeChild(td);
+		editor.forceRedraw();
+		editor.updateToolbar();
+		break;
+	    case "TO-cell-merge":
+		// !! FIXME: Mozilla specific !!
+		var sel = editor._getSelection();
+		var range, i = 0;
+		var rows = [];
+		var row = null;
+		var cells = null;
+		if (!HTMLArea.is_ie) {
+			try {
+				while (range = sel.getRangeAt(i++)) {
+					var td = range.startContainer.childNodes[range.startOffset];
+					if (td.parentNode != row) {
+						row = td.parentNode;
+						(cells) && rows.push(cells);
+						cells = [];
+					}
+					cells.push(td);
+				}
+			} catch(e) {/* finished walking through selection */}
+			rows.push(cells);
+		} else {
+			// Internet Explorer "browser"
+			var td = this.getClosest("td");
+			if (!td) {
+				alert(i18n["Please click into some cell"]);
+				break;
+			}
+			var tr = td.parentElement;
+			var no_cols = prompt(i18n["How many columns would you like to merge?"], 2);
+			if (!no_cols) {
+				// cancelled
+				break;
+			}
+			var no_rows = prompt(i18n["How many rows would you like to merge?"], 2);
+			if (!no_rows) {
+				// cancelled
+				break;
+			}
+			var cell_index = td.cellIndex;
+			while (no_rows-- > 0) {
+				td = tr.cells[cell_index];
+				cells = [td];
+				for (var i = 1; i < no_cols; ++i) {
+					td = td.nextSibling;
+					if (!td) {
+						break;
+					}
+					cells.push(td);
+				}
+				rows.push(cells);
+				tr = tr.nextSibling;
+				if (!tr) {
+					break;
+				}
+			}
+		}
+		var HTML = "";
+		for (i = 0; i < rows.length; ++i) {
+			// i && (HTML += "<br />");
+			var cells = rows[i];
+			for (var j = 0; j < cells.length; ++j) {
+				// j && (HTML += "&nbsp;");
+				var cell = cells[j];
+				HTML += cell.innerHTML;
+				(i || j) && (cell.parentNode.removeChild(cell));
+			}
+		}
+		var td = rows[0][0];
+		td.innerHTML = HTML;
+		td.rowSpan = rows.length;
+		td.colSpan = rows[0].length;
+		editor.selectNodeContents(td);
+		editor.forceRedraw();
+		editor.focusEditor();
+		break;
+
+		// PROPERTIES
+
+	    case "TO-table-prop":
+		this.dialogTableProperties();
+		break;
+
+	    case "TO-row-prop":
+		this.dialogRowCellProperties(false);
+		break;
+
+	    case "TO-cell-prop":
+		this.dialogRowCellProperties(true);
+		break;
+
+	    default:
+		alert("Button [" + button_id + "] not yet implemented");
+	}
+};
+
+// the list of buttons added by this plugin
+TableOperations.btnList = [
+	// table properties button
+	["table-prop",       "table"],
+	null,			// separator
+
+	// ROWS
+	["row-prop",         "tr"],
+	["row-insert-above", "tr"],
+	["row-insert-under", "tr"],
+	["row-delete",       "tr"],
+	["row-split",        "td[rowSpan!=1]"],
+	null,
+
+	// COLS
+	["col-insert-before", "td"],
+	["col-insert-after",  "td"],
+	["col-delete",        "td"],
+	["col-split",         "td[colSpan!=1]"],
+	null,
+
+	// CELLS
+	["cell-prop",          "td"],
+	["cell-insert-before", "td"],
+	["cell-insert-after",  "td"],
+	["cell-delete",        "td"],
+	["cell-merge",         "tr"],
+	["cell-split",         "td[colSpan!=1,rowSpan!=1]"]
+	];
+
+
+
+//// GENERIC CODE [style of any element; this should be moved into a separate
+//// file as it'll be very useful]
+//// BEGIN GENERIC CODE -----------------------------------------------------
+
+TableOperations.getLength = function(value) {
+	var len = parseInt(value);
+	if (isNaN(len)) {
+		len = "";
+	}
+	return len;
+};
+
+// Applies the style found in "params" to the given element.
+TableOperations.processStyle = function(params, element) {
+	var style = element.style;
+	for (var i in params) {
+		var val = params[i];
+		switch (i) {
+		    case "f_st_backgroundColor":
+			style.backgroundColor = val;
+			break;
+		    case "f_st_color":
+			style.color = val;
+			break;
+		    case "f_st_backgroundImage":
+			if (/\S/.test(val)) {
+				style.backgroundImage = "url(" + val + ")";
+			} else {
+				style.backgroundImage = "none";
+			}
+			break;
+		    case "f_st_borderWidth":
+			style.borderWidth = val;
+			break;
+		    case "f_st_borderStyle":
+			style.borderStyle = val;
+			break;
+		    case "f_st_borderColor":
+			style.borderColor = val;
+			break;
+		    case "f_st_borderCollapse":
+			style.borderCollapse = val ? "collapse" : "";
+			break;
+		    case "f_st_width":
+			if (/\S/.test(val)) {
+				style.width = val + params["f_st_widthUnit"];
+			} else {
+				style.width = "";
+			}
+			break;
+		    case "f_st_height":
+			if (/\S/.test(val)) {
+				style.height = val + params["f_st_heightUnit"];
+			} else {
+				style.height = "";
+			}
+			break;
+		    case "f_st_textAlign":
+			if (val == "char") {
+				var ch = params["f_st_textAlignChar"];
+				if (ch == '"') {
+					ch = '\\"';
+				}
+				style.textAlign = '"' + ch + '"';
+			} else {
+				style.textAlign = val;
+			}
+			break;
+		    case "f_st_verticalAlign":
+			style.verticalAlign = val;
+			break;
+		    case "f_st_float":
+			style.cssFloat = val;
+			break;
+// 		    case "f_st_margin":
+// 			style.margin = val + "px";
+// 			break;
+// 		    case "f_st_padding":
+// 			style.padding = val + "px";
+// 			break;
+		}
+	}
+};
+
+// Returns an HTML element for a widget that allows color selection.  That is,
+// a button that contains the given color, if any, and when pressed will popup
+// the sooner-or-later-to-be-rewritten select_color.html dialog allowing user
+// to select some color.  If a color is selected, an input field with the name
+// "f_st_"+name will be updated with the color value in #123456 format.
+TableOperations.createColorButton = function(doc, editor, color, name) {
+	if (!color) {
+		color = "";
+	} else if (!/#/.test(color)) {
+		color = HTMLArea._colorToRgb(color);
+	}
+
+	var df = doc.createElement("span");
+ 	var field = doc.createElement("input");
+	field.type = "hidden";
+	df.appendChild(field);
+ 	field.name = "f_st_" + name;
+	field.value = color;
+	var button = doc.createElement("span");
+	button.className = "buttonColor";
+	df.appendChild(button);
+	var span = doc.createElement("span");
+	span.className = "chooser";
+	// span.innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
+	span.style.backgroundColor = color;
+	button.appendChild(span);
+	button.onmouseover = function() { if (!this.disabled) { this.className += " buttonColor-hilite"; }};
+	button.onmouseout = function() { if (!this.disabled) { this.className = "buttonColor"; }};
+	span.onclick = function() {
+		if (this.parentNode.disabled) {
+			return false;
+		}
+		editor._popupDialog("select_color.html", function(color) {
+			if (color) {
+				span.style.backgroundColor = "#" + color;
+				field.value = "#" + color;
+			}
+		}, color);
+	};
+	var span2 = doc.createElement("span");
+	span2.innerHTML = "&#x00d7;";
+	span2.className = "nocolor";
+	span2.title = TableOperations.I18N["Unset color"];
+	button.appendChild(span2);
+	span2.onmouseover = function() { if (!this.parentNode.disabled) { this.className += " nocolor-hilite"; }};
+	span2.onmouseout = function() { if (!this.parentNode.disabled) { this.className = "nocolor"; }};
+	span2.onclick = function() {
+		span.style.backgroundColor = "";
+		field.value = "";
+	};
+	return df;
+};
+
+TableOperations.createStyleLayoutFieldset = function(doc, editor, el) {
+	var i18n = TableOperations.I18N;
+	var fieldset = doc.createElement("fieldset");
+	var legend = doc.createElement("legend");
+	fieldset.appendChild(legend);
+	legend.innerHTML = i18n["Layout"];
+	var table = doc.createElement("table");
+	fieldset.appendChild(table);
+	table.style.width = "100%";
+	var tbody = doc.createElement("tbody");
+	table.appendChild(tbody);
+
+	var tagname = el.tagName.toLowerCase();
+	var tr, td, input, select, option, options, i;
+
+	if (tagname != "td" && tagname != "tr" && tagname != "th") {
+		tr = doc.createElement("tr");
+		tbody.appendChild(tr);
+		td = doc.createElement("td");
+		td.className = "label";
+		tr.appendChild(td);
+		td.innerHTML = i18n["Float"] + ":";
+		td = doc.createElement("td");
+		tr.appendChild(td);
+		select = doc.createElement("select");
+		td.appendChild(select);
+		select.name = "f_st_float";
+		options = ["None", "Left", "Right"];
+		for (i in options) {
+			var Val = options[i];
+			var val = options[i].toLowerCase();
+			option = doc.createElement("option");
+			option.innerHTML = i18n[Val];
+			option.value = val;
+			option.selected = (("" + el.style.cssFloat).toLowerCase() == val);
+			select.appendChild(option);
+		}
+	}
+
+	tr = doc.createElement("tr");
+	tbody.appendChild(tr);
+	td = doc.createElement("td");
+	td.className = "label";
+	tr.appendChild(td);
+	td.innerHTML = i18n["Width"] + ":";
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	input = doc.createElement("input");
+	input.type = "text";
+	input.value = TableOperations.getLength(el.style.width);
+	input.size = "5";
+	input.name = "f_st_width";
+	input.style.marginRight = "0.5em";
+	td.appendChild(input);
+	select = doc.createElement("select");
+	select.name = "f_st_widthUnit";
+	option = doc.createElement("option");
+	option.innerHTML = i18n["percent"];
+	option.value = "%";
+	option.selected = /%/.test(el.style.width);
+	select.appendChild(option);
+	option = doc.createElement("option");
+	option.innerHTML = i18n["pixels"];
+	option.value = "px";
+	option.selected = /px/.test(el.style.width);
+	select.appendChild(option);
+	td.appendChild(select);
+
+	select.style.marginRight = "0.5em";
+	td.appendChild(doc.createTextNode(i18n["Text align"] + ":"));
+	select = doc.createElement("select");
+	select.style.marginLeft = select.style.marginRight = "0.5em";
+	td.appendChild(select);
+	select.name = "f_st_textAlign";
+	options = ["Left", "Center", "Right", "Justify"];
+	if (tagname == "td") {
+		options.push("Char");
+	}
+	input = doc.createElement("input");
+	input.name = "f_st_textAlignChar";
+	input.size = "1";
+	input.style.fontFamily = "monospace";
+	td.appendChild(input);
+	for (i in options) {
+		var Val = options[i];
+		var val = Val.toLowerCase();
+		option = doc.createElement("option");
+		option.value = val;
+		option.innerHTML = i18n[Val];
+		option.selected = (el.style.textAlign.toLowerCase() == val);
+		select.appendChild(option);
+	}
+	function setCharVisibility(value) {
+		input.style.visibility = value ? "visible" : "hidden";
+		if (value) {
+			input.focus();
+			input.select();
+		}
+	};
+	select.onchange = function() { setCharVisibility(this.value == "char"); };
+	setCharVisibility(select.value == "char");
+
+	tr = doc.createElement("tr");
+	tbody.appendChild(tr);
+	td = doc.createElement("td");
+	td.className = "label";
+	tr.appendChild(td);
+	td.innerHTML = i18n["Height"] + ":";
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	input = doc.createElement("input");
+	input.type = "text";
+	input.value = TableOperations.getLength(el.style.height);
+	input.size = "5";
+	input.name = "f_st_height";
+	input.style.marginRight = "0.5em";
+	td.appendChild(input);
+	select = doc.createElement("select");
+	select.name = "f_st_heightUnit";
+	option = doc.createElement("option");
+	option.innerHTML = i18n["percent"];
+	option.value = "%";
+	option.selected = /%/.test(el.style.height);
+	select.appendChild(option);
+	option = doc.createElement("option");
+	option.innerHTML = i18n["pixels"];
+	option.value = "px";
+	option.selected = /px/.test(el.style.height);
+	select.appendChild(option);
+	td.appendChild(select);
+
+	select.style.marginRight = "0.5em";
+	td.appendChild(doc.createTextNode(i18n["Vertical align"] + ":"));
+	select = doc.createElement("select");
+	select.name = "f_st_verticalAlign";
+	select.style.marginLeft = "0.5em";
+	td.appendChild(select);
+	options = ["Top", "Middle", "Bottom", "Baseline"];
+	for (i in options) {
+		var Val = options[i];
+		var val = Val.toLowerCase();
+		option = doc.createElement("option");
+		option.value = val;
+		option.innerHTML = i18n[Val];
+		option.selected = (el.style.verticalAlign.toLowerCase() == val);
+		select.appendChild(option);
+	}
+
+	return fieldset;
+};
+
+// Returns an HTML element containing the style attributes for the given
+// element.  This can be easily embedded into any dialog; the functionality is
+// also provided.
+TableOperations.createStyleFieldset = function(doc, editor, el) {
+	var i18n = TableOperations.I18N;
+	var fieldset = doc.createElement("fieldset");
+	var legend = doc.createElement("legend");
+	fieldset.appendChild(legend);
+	legend.innerHTML = i18n["CSS Style"];
+	var table = doc.createElement("table");
+	fieldset.appendChild(table);
+	table.style.width = "100%";
+	var tbody = doc.createElement("tbody");
+	table.appendChild(tbody);
+
+	var tr, td, input, select, option, options, i;
+
+	tr = doc.createElement("tr");
+	tbody.appendChild(tr);
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	td.className = "label";
+	td.innerHTML = i18n["Background"] + ":";
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	var df = TableOperations.createColorButton(doc, editor, el.style.backgroundColor, "backgroundColor");
+	df.firstChild.nextSibling.style.marginRight = "0.5em";
+	td.appendChild(df);
+	td.appendChild(doc.createTextNode(i18n["Image URL"] + ": "));
+	input = doc.createElement("input");
+	input.type = "text";
+	input.name = "f_st_backgroundImage";
+	if (el.style.backgroundImage.match(/url\(\s*(.*?)\s*\)/)) {
+		input.value = RegExp.$1;
+	}
+	// input.style.width = "100%";
+	td.appendChild(input);
+
+	tr = doc.createElement("tr");
+	tbody.appendChild(tr);
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	td.className = "label";
+	td.innerHTML = i18n["FG Color"] + ":";
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	td.appendChild(TableOperations.createColorButton(doc, editor, el.style.color, "color"));
+
+	// for better alignment we include an invisible field.
+	input = doc.createElement("input");
+	input.style.visibility = "hidden";
+	input.type = "text";
+	td.appendChild(input);
+
+	tr = doc.createElement("tr");
+	tbody.appendChild(tr);
+	td = doc.createElement("td");
+	tr.appendChild(td);
+	td.className = "label";
+	td.innerHTML = i18n["Border"] + ":";
+	td = doc.createElement("td");
+	tr.appendChild(td);
+
+	var colorButton = TableOperations.createColorButton(doc, editor, el.style.borderColor, "borderColor");
+	var btn = colorButton.firstChild.nextSibling;
+	td.appendChild(colorButton);
+	// borderFields.push(btn);
+	btn.style.marginRight = "0.5em";
+
+	select = doc.createElement("select");
+	var borderFields = [];
+	td.appendChild(select);
+	select.name = "f_st_borderStyle";
+	options = ["none", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"];
+	var currentBorderStyle = el.style.borderStyle;
+	// Gecko reports "solid solid solid solid" for "border-style: solid".
+	// That is, "top right bottom left" -- we only consider the first
+	// value.
+	(currentBorderStyle.match(/([^\s]*)\s/)) && (currentBorderStyle = RegExp.$1);
+	for (i in options) {
+		var val = options[i];
+		option = doc.createElement("option");
+		option.value = val;
+		option.innerHTML = val;
+		(val == currentBorderStyle) && (option.selected = true);
+		select.appendChild(option);
+	}
+	select.style.marginRight = "0.5em";
+	function setBorderFieldsStatus(value) {
+		for (i in borderFields) {
+			var el = borderFields[i];
+			el.style.visibility = value ? "hidden" : "visible";
+			if (!value && (el.tagName.toLowerCase() == "input")) {
+				el.focus();
+				el.select();
+			}
+		}
+	};
+	select.onchange = function() { setBorderFieldsStatus(this.value == "none"); };
+
+	input = doc.createElement("input");
+	borderFields.push(input);
+	input.type = "text";
+	input.name = "f_st_borderWidth";
+	input.value = TableOperations.getLength(el.style.borderWidth);
+	input.size = "5";
+	td.appendChild(input);
+	input.style.marginRight = "0.5em";
+	var span = doc.createElement("span");
+	span.innerHTML = i18n["pixels"];
+	td.appendChild(span);
+	borderFields.push(span);
+
+	setBorderFieldsStatus(select.value == "none");
+
+	if (el.tagName.toLowerCase() == "table") {
+		// the border-collapse style is only for tables
+		tr = doc.createElement("tr");
+		tbody.appendChild(tr);
+		td = doc.createElement("td");
+		td.className = "label";
+		tr.appendChild(td);
+		input = doc.createElement("input");
+		input.type = "checkbox";
+		input.name = "f_st_borderCollapse";
+		input.id = "f_st_borderCollapse";
+		var val = (/collapse/i.test(el.style.borderCollapse));
+		input.checked = val ? 1 : 0;
+		td.appendChild(input);
+
+		td = doc.createElement("td");
+		tr.appendChild(td);
+		var label = doc.createElement("label");
+		label.htmlFor = "f_st_borderCollapse";
+		label.innerHTML = i18n["Collapsed borders"];
+		td.appendChild(label);
+	}
+
+// 	tr = doc.createElement("tr");
+// 	tbody.appendChild(tr);
+// 	td = doc.createElement("td");
+// 	td.className = "label";
+// 	tr.appendChild(td);
+// 	td.innerHTML = i18n["Margin"] + ":";
+// 	td = doc.createElement("td");
+// 	tr.appendChild(td);
+// 	input = doc.createElement("input");
+// 	input.type = "text";
+// 	input.size = "5";
+// 	input.name = "f_st_margin";
+// 	td.appendChild(input);
+// 	input.style.marginRight = "0.5em";
+// 	td.appendChild(doc.createTextNode(i18n["Padding"] + ":"));
+
+// 	input = doc.createElement("input");
+// 	input.type = "text";
+// 	input.size = "5";
+// 	input.name = "f_st_padding";
+// 	td.appendChild(input);
+// 	input.style.marginLeft = "0.5em";
+// 	input.style.marginRight = "0.5em";
+// 	td.appendChild(doc.createTextNode(i18n["pixels"]));
+
+	return fieldset;
+};
+
+//// END GENERIC CODE -------------------------------------------------------
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/img/makefile.xml
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/img/makefile.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/TableOperations/img/makefile.xml	(revision 795)
@@ -0,0 +1,3 @@
+<files>
+  <file name="*.{gif,jpg,jpeg}" />
+</files>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/lang/lang.php	(revision 795)
@@ -0,0 +1,51 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-ListType');
+
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+ListType.I18N = {
+	"Decimal"                :    "<?php echo lang('Decimal numbers'); ?>",
+	"Lower roman"            :    "<?php echo lang('Lower roman numbers'); ?>",
+	"Upper roman"            :    "<?php echo lang('Upper roman numbers'); ?>",
+	"Lower latin"            :    "<?php echo lang('Lower latin letters'); ?>",
+	"Upper latin"            :    "<?php echo lang('Upper latin letters'); ?>",
+	"Lower greek"            :    "<?php echo lang('Lower greek letters'); ?>",
+	"ListStyleTooltip"       :    "<?php echo lang('Choose list style type (for ordered lists)'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/lang/en.js	(revision 795)
@@ -0,0 +1,23 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+ListType.I18N = {
+	"Decimal"                :    "Decimal numbers",
+	"Lower roman"            :    "Lower roman numbers",
+	"Upper roman"            :    "Upper roman numbers",
+	"Lower latin"            :    "Lower latin letters",
+	"Upper latin"            :    "Upper latin letters",
+	"Lower greek"            :    "Lower greek letters",
+	"ListStyleTooltip"       :    "Choose list style type (for ordered lists)"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/list-type.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/list-type.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/ListType/list-type.js	(revision 795)
@@ -0,0 +1,88 @@
+// ListType Plugin for HTMLArea-3.0
+// Sponsored by MEdTech Unit - Queen's University
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+
+function ListType(editor) {
+	this.editor = editor;
+	var cfg = editor.config;
+	var toolbar = cfg.toolbar;
+	var self = this;
+	var i18n = ListType.I18N;
+	var options = {};
+	options[i18n["Decimal"]] = "decimal";
+	options[i18n["Lower roman"]] = "lower-roman";
+	options[i18n["Upper roman"]] = "upper-roman";
+	options[i18n["Lower latin"]] = "lower-alpha";
+	options[i18n["Upper latin"]] = "upper-alpha";
+	if (!HTMLArea.is_ie)
+		// IE doesn't support this property; even worse, it complains
+		// with a gross error message when we tried to select it,
+		// therefore let's hide it from the damn "browser".
+		options[i18n["Lower greek"]] = "lower-greek";
+	var obj = {
+		id            : "ListType",
+		tooltip       : i18n["ListStyleTooltip"],
+		options       : options,
+		action        : function(editor) { self.onSelect(editor, this); },
+		refresh       : function(editor) { self.updateValue(editor, this); },
+		context       : "ol"
+	};
+	cfg.registerDropdown(obj);
+	var a, i, j, found = false;
+	for (i = 0; !found && i < toolbar.length; ++i) {
+		a = toolbar[i];
+		for (j = 0; j < a.length; ++j) {
+			if (a[j] == "unorderedlist") {
+				found = true;
+				break;
+			}
+		}
+	}
+	if (found)
+		a.splice(j, 0, "space", "ListType", "space");
+};
+
+ListType._pluginInfo = {
+	name          : "ListType",
+	version       : "1.0",
+	developer     : "Mihai Bazon",
+	developer_url : "http://dynarch.com/mishoo/",
+	c_owner       : "dynarch.com",
+	sponsor       : "MEdTech Unit - Queen's University",
+	sponsor_url   : "http://www.queensu.ca/",
+	license       : "htmlArea"
+};
+
+ListType.prototype.onSelect = function(editor, combo) {
+	var tbobj = editor._toolbarObjects[combo.id].element;
+	var parent = editor.getParentElement();
+	while (!/^ol$/i.test(parent.tagName)) {
+		parent = parent.parentNode;
+	}
+	parent.style.listStyleType = tbobj.value;
+};
+
+ListType.prototype.updateValue = function(editor, combo) {
+	var tbobj = editor._toolbarObjects[combo.id].element;
+	var parent = editor.getParentElement();
+	while (parent && !/^ol$/i.test(parent.tagName)) {
+		parent = parent.parentNode;
+	}
+	if (!parent) {
+		tbobj.selectedIndex = 0;
+		return;
+	}
+	var type = parent.style.listStyleType;
+	if (!type) {
+		tbobj.selectedIndex = 0;
+	} else {
+		for (var i = tbobj.firstChild; i; i = i.nextSibling) {
+			i.selected = (type.indexOf(i.value) != -1);
+		}
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/lang/lang.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/lang/lang.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/lang/lang.php	(revision 795)
@@ -0,0 +1,46 @@
+<?php
+/**************************************************************************\
+* eGroupWare - API htmlarea translations (according to lang in user prefs) *
+* http: //www.eGroupWare.org                                                *
+* Modified by Ralf Becker <RalfBecker@outdoor-training.de>                 *
+* This file is derived from htmlareas's lang/en.js file                    *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+
+$GLOBALS['phpgw_info']['flags'] = Array(
+	'currentapp'  => 'home',		// can't be phpgwapi, nor htmlarea (no own directory)
+	'noheader'    => True,
+	'nonavbar'    => True,
+	'noappheader' => True,
+	'noappfooter' => True,
+	'nofooter'    => True,
+	'nocachecontrol' => True			// allow cacheing
+);
+
+include('../../../../../../header.inc.php');
+header('Content-type: text/javascript; charset='.$GLOBALS['phpgw']->translation->charset());
+$GLOBALS['phpgw']->translation->add_app('htmlarea-HtmlTidy');
+
+// I18N constants
+
+// LANG:  "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Adam Wright, http://blog.hipikat.org/
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+?>
+HtmlTidy.I18N = {
+	"tidying"                               :  "<?php echo lang('\n Tidying up the HTML source, please wait...'); ?>",
+	"HT-html-tidy"                          :  "<?php echo lang('HTML Tidy'); ?>"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/lang/en.js	(revision 795)
@@ -0,0 +1,18 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Adam Wright, http://blog.hipikat.org/
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+HtmlTidy.I18N = {
+	"tidying"                               : "\n Tidying up the HTML source, please wait...",
+	"HT-html-tidy"                          : "HTML Tidy"
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy.js	(revision 795)
@@ -0,0 +1,128 @@
+// Plugin for htmlArea to run code through the server's HTML Tidy
+// By Adam Wright, for The University of Western Australia
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+function HtmlTidy(editor) {
+	this.editor = editor;
+
+	var cfg = editor.config;
+	var tt = HtmlTidy.I18N;
+	var bl = HtmlTidy.btnList;
+	var self = this;
+
+	this.onMode = this.__onMode;
+
+	// register the toolbar buttons provided by this plugin
+	var toolbar = [];
+	for (var i in bl) {
+		var btn = bl[i];
+		if (btn == "html-tidy") {
+			var id = "HT-html-tidy";
+			cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "HtmlTidy"), true,
+					   function(editor, id) {
+						   // dispatch button press event
+						   self.buttonPress(editor, id);
+					   }, btn[1]);
+			toolbar.push(id);
+		} else if (btn == "html-auto-tidy") {
+			var ht_class = {
+				id	: "HT-auto-tidy",
+				options	: { "Auto-Tidy" : "auto", "Don't Tidy" : "noauto" },
+				action	: function (editor) { self.__onSelect(editor, this); },
+				refresh	: function (editor) { },
+				context	: "body"
+			};
+			cfg.registerDropdown(ht_class);
+		}
+	}
+
+	for (var i in toolbar) {
+		cfg.toolbar[0].push(toolbar[i]);
+	}
+};
+
+HtmlTidy._pluginInfo = {
+	name          : "HtmlTidy",
+	version       : "1.0",
+	developer     : "Adam Wright",
+	developer_url : "http://blog.hipikat.org/",
+	sponsor       : "The University of Western Australia",
+	sponsor_url   : "http://www.uwa.edu.au/",
+	license       : "htmlArea"
+};
+
+HtmlTidy.prototype.__onSelect = function(editor, obj) {
+	// Get the toolbar element object
+	var elem = editor._toolbarObjects[obj.id].element;
+
+	// Set our onMode event appropriately
+	if (elem.value == "auto")
+		this.onMode = this.__onMode;
+	else
+		this.onMode = null;
+};
+
+HtmlTidy.prototype.__onMode = function(mode) {
+	if ( mode == "textmode" ) {
+		this.buttonPress(this.editor, "HT-html-tidy");
+	}
+};
+
+HtmlTidy.btnList = [
+		    null, // separator
+		    ["html-tidy"],
+		    ["html-auto-tidy"]
+];
+
+HtmlTidy.prototype.onGenerateOnce = function() {
+	var editor = this.editor;
+
+	var ifr = document.createElement("iframe");
+	ifr.name = "htiframe_name";
+	var s = ifr.style;
+	s.position = "absolute";
+	s.width = s.height = s.border = s.left = s.top = s.padding = s.margin = "0px";
+	document.body.appendChild(ifr);
+
+	var frm = '<form id="htiform_id" name="htiform_name" method="post" target="htiframe_name" action="';
+	frm += _editor_url + 'plugins/HtmlTidy/html-tidy-logic.php';
+	frm += '"><textarea name="htisource_name" id="htisource_id">';
+	frm += '</textarea></form>';
+
+	var newdiv = document.createElement('div');
+	newdiv.style.display = "none";
+	newdiv.innerHTML = frm;
+	document.body.appendChild(newdiv);
+};
+
+HtmlTidy.prototype.buttonPress = function(editor, id) {
+	var i18n = HtmlTidy.I18N;
+
+	switch (id) {
+	    case "HT-html-tidy":
+
+		var oldhtml = editor.getHTML();
+
+		// Ask the server for some nice new html, based on the old...
+		var myform = document.getElementById('htiform_id');
+		var txtarea = document.getElementById('htisource_id');
+		txtarea.value = editor.getHTML();
+
+		// Apply the 'meanwhile' text, e.g. "Tidying HTML, please wait..."
+		editor.setHTML(i18n['tidying']);
+
+		// The returning tidying processing script needs to find the editor
+		window._editorRef = editor;
+
+		// ...And send our old source off for processing!
+		myform.submit();
+		break;
+	}
+};
+
+HtmlTidy.prototype.processTidied = function(newSrc) {
+	editor = this.editor;
+	editor.setHTML(newSrc);
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy-config.cfg
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy-config.cfg	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy-config.cfg	(revision 795)
@@ -0,0 +1,29 @@
+// Default configuration file for the htmlArea, HtmlTidy plugin
+// By Adam Wright, for The University of Western Australia
+//
+// Evertything you always wanted to know about HTML Tidy *
+// can be found at http://tidy.sourceforge.net/, and a
+// quick reference to the configuration options exists at
+// http://tidy.sourceforge.net/docs/quickref.html
+//
+// * But were afraid to ask
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+word-2000: yes
+clean: no
+drop-font-tags: yes
+doctype: auto
+drop-empty-paras: yes
+drop-proprietary-attributes: yes
+enclose-block-text: yes
+enclose-text: yes
+escape-cdata: yes
+logical-emphasis: yes
+indent: auto
+indent-spaces: 2
+break-before-br: yes
+output-xhtml: yes
+
+force-output: yes
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy-logic.php
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy-logic.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/html-tidy-logic.php	(revision 795)
@@ -0,0 +1,83 @@
+<?  ###################################################################
+   ##
+  ##  Plugin for htmlArea, to run code through the server's HTML Tidy
+ ##   By Adam Wright, for The University of Western Australia
+##    This is the server-side script, which dirty code is run through.
+##
+##  Distributed under the same terms as HTMLArea itself.
+##  This notice MUST stay intact for use (see license.txt).
+##
+
+	// Get the original source
+	$source = $_POST['htisource_name'];
+	$source = stripslashes($source);
+
+	// Open a tidy process - I hope it's installed!
+	$descriptorspec = array(
+		0 => array("pipe", "r"),
+		1 => array("pipe", "w"),
+		2 => array("file", "/dev/null", "a")
+	);
+	$process = proc_open("tidy -config html-tidy-config.cfg", $descriptorspec, $pipes);
+
+	// Make sure the program started and we got the hooks...
+	// Either way, get some source code into $source
+	if (is_resource($process)) {
+
+		// Feed untidy source into the stdin
+		fwrite($pipes[0], $source);
+		fclose($pipes[0]);
+
+		// Read clean source out to the browser
+		while (!feof($pipes[1])) {
+			//echo fgets($pipes[1], 1024);
+			$newsrc .= fgets($pipes[1], 1024);
+		}
+		fclose($pipes[1]);
+
+		// Clean up after ourselves
+		proc_close($process);
+
+	} else {
+		// Better give them back what they came with, so they don't lose it all...
+		$newsrc = "<body>\n" .$source. "\n</body>";
+	}
+
+	// Split our source into an array by lines
+	$srcLines = explode("\n",$newsrc);
+
+	// Get only the lines between the body tags
+	$startLn = 0;
+	while ( strpos( $srcLines[$startLn++], '<body' ) === false && $startLn < sizeof($srcLines) );
+	$endLn = $startLn;
+	while ( strpos( $srcLines[$endLn++], '</body' ) === false && $endLn < sizeof($srcLines) );
+
+	$srcLines = array_slice( $srcLines, $startLn, ($endLn - $startLn - 1) );
+
+	// Create a set of javascript code to compile a new source string
+	foreach ($srcLines as $line) {
+		$jsMakeSrc .= "\tns += '" . str_replace("'","\'",$line) . "\\n';\n";
+	}
+?>
+
+
+<html>
+  <head>
+    <script type="text/javascript">
+
+function setNewHtml() {
+	var htRef = window.parent._editorRef.plugins['HtmlTidy'];
+	htRef.instance.processTidied(tidyString());
+}
+function tidyString() {
+	var ns = '\n';
+	<?=$jsMakeSrc;?>
+	return ns;
+}
+
+    </script>
+  </head>
+
+  <body id="htiNewBody" onload="setNewHtml()">
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/README
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/README	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/plugins/HtmlTidy/README	(revision 795)
@@ -0,0 +1,104 @@
+// Plugin for htmlArea to run code through the server's HTML Tidy
+// By Adam Wright, for The University of Western Australia
+//
+//   Email:      zeno@ucc.gu.uwa.edu.au
+//   Homepage:   http://blog.hipikat.org/
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// Version: 0.5
+// Released to the outside world: 04/03/04
+
+
+HtmlTidy is a plugin for the popular cross-browser TTY WYSIWYG editor,
+htmlArea (http://www.interactivetools.com/products/htmlarea/). HtmlTidy
+basically queries HTML Tidy (http://tidy.sourceforge.net/) on the
+server side, getting it to make-html-nice, instead of relying on masses
+of javascript, which the client would have to download.
+
+Hi, this is a quick explanation of how to install HtmlTidy. Much better
+documentation is probably required, and you're welcome to write it :)
+
+
+* The HtmlTidy directory you should have found this file in should
+  include the following:
+
+  - README
+        This file, providing help installing the plugin.
+
+  - html-tidy-config.cfg
+        This file contains the configuration options HTML Tidy uses to
+        clean html, and can be modified to suit your organizations
+        requirements.
+
+  - html-tidy-logic.php
+        This is the php script, which is queried with dirty html and is
+        responsible for invoking HTML Tidy, getting nice new html and
+        returning it to the client.
+
+  - html-tidy.js
+        The main htmlArea plugin, providing functionality to tidy html
+        through the htmlArea interface.
+
+  - htmlarea.js.onmode_event.diff
+        At the time of publishing, an extra event handler was required
+        inside the main htmlarea.js file. htmlarea.js may be patched
+        against this file to make the changes reuquired, but be aware
+        that the event handler may either now be in the core or
+        htmlarea.js may have changed enough to invalidate the patch.
+	
+	UPDATE: now it exists in the official htmlarea.js; applying
+	this patch is thus no longer necessary.
+
+  - img/html-tidy.gif
+        The HtmlTidy icon, for the htmlArea toolbar. Created by Dan
+        Petty for The University of Western Australia.
+
+  - lang/en.js
+        English language file. Add your own language files here and
+        please contribute back into the htmlArea community!
+
+  The HtmlArea directory should be extracted to your htmlarea/plugins/
+  directory.
+
+
+* Make sure the onMode event handler mentioned above, regarding
+  htmlarea.js.onmode_event.diff, exists in your htmlarea.js
+
+
+* html-tidy-logic.php should be executable, and your web server should
+  be configured to execute php scripts in the directory
+  html-tidy-logic.php exists in.
+
+
+* HTML Tidy needs to be installed on your server, and 'tidy' should be
+  an alias to it, lying in the PATH known to the user executing such
+  web scripts.
+
+
+* In your htmlArea configuration, do something like this:
+
+    HTMLArea.loadPlugin("HtmlTidy");
+
+    editor = new HTMLArea("doc");
+    editor.registerPlugin("HtmlTidy");
+
+
+* Then, in your htmlArea toolbar configuration, use:
+
+    - "HT-html-tidy"
+        This will create the 'tidy broom' icon on the toolbar, which
+        will attempt to tidy html source when clicked, and;
+
+    - "HT-auto-tidy"
+        This will create an "Auto Tidy" / "Don't Tidy" dropdown, to
+        select whether the source should be tidied automatically when
+        entering source view. On by default, if you'd like it otherwise
+        you can do so programatically after generating the toolbar :)
+        (Or just hack it to be otherwise...)
+    
+
+Thank you.
+
+Any bugs you find can be emailed to zeno@ucc.gu.uwa.edu.au
Index: /sandbox/workflow/branches/993/js/htmlarea/popupdiv.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popupdiv.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popupdiv.js	(revision 795)
@@ -0,0 +1,369 @@
+/** This file is derived from PopupDiv, developed by Mihai Bazon for
+ * SamWare.net.  Modifications were needed to make it usable in HTMLArea.
+ * HTMLArea is a free WYSIWYG online HTML editor from InteractiveTools.com.
+ *
+ * This file does not function standalone.  It is dependent of global functions
+ * defined in HTMLArea-3.0 (htmlarea.js).
+ *
+ * Please see file htmlarea.js for further details.
+ **/
+
+var is_ie = ( (navigator.userAgent.toLowerCase().indexOf("msie") != -1) &&
+	      (navigator.userAgent.toLowerCase().indexOf("opera") == -1) );
+var is_compat = (document.compatMode == "BackCompat");
+
+function PopupDiv(editor, titleText, handler, initFunction) {
+	var self = this;
+
+	this.editor = editor;
+	this.doc = editor._mdoc;
+	this.handler = handler;
+
+	var el = this.doc.createElement("div");
+	el.className = "content";
+
+	var popup = this.doc.createElement("div");
+	popup.className = "dialog popupdiv";
+	this.element = popup;
+	var s = popup.style;
+	s.position = "absolute";
+	s.left = "0px";
+	s.top = "0px";
+
+	var title = this.doc.createElement("div");
+	title.className = "title";
+	this.title = title;
+	popup.appendChild(title);
+
+	HTMLArea._addEvent(title, "mousedown", function(ev) {
+		self._dragStart(is_ie ? window.event : ev);
+	});
+
+	var button = this.doc.createElement("div");
+	button.className = "button";
+	title.appendChild(button);
+	button.innerHTML = "&#x00d7;";
+	title.appendChild(this.doc.createTextNode(titleText));
+	this.titleText = titleText;
+
+	button.onmouseover = function() {
+		this.className += " button-hilite";
+	};
+	button.onmouseout = function() {
+		this.className = this.className.replace(/\s*button-hilite\s*/g, " ");
+	};
+	button.onclick = function() {
+		this.className = this.className.replace(/\s*button-hilite\s*/g, " ");
+		self.close();
+	};
+
+	popup.appendChild(el);
+	this.content = el;
+
+	this.doc.body.appendChild(popup);
+
+	this.dragging = false;
+	this.onShow = null;
+	this.onClose = null;
+	this.modal = false;
+
+	initFunction(this);
+};
+
+PopupDiv.currentPopup = null;
+
+PopupDiv.prototype.showAtElement = function(el, mode) {
+	this.defaultSize();
+	var pos, ew, eh;
+	var popup = this.element;
+	popup.style.display = "block";
+	var w = popup.offsetWidth;
+	var h = popup.offsetHeight;
+	popup.style.display = "none";
+	if (el != window) {
+		pos = PopupDiv.getAbsolutePos(el);
+		ew = el.offsetWidth;
+		eh = el.offsetHeight;
+	} else {
+		pos = {x:0, y:0};
+		var size = PopupDiv.getWindowSize();
+		ew = size.x;
+		eh = size.y;
+	}
+	var FX = false, FY = false;
+	if (mode.indexOf("l") != -1) {
+		pos.x -= w;
+		FX = true;
+	}
+	if (mode.indexOf("r") != -1) {
+		pos.x += ew;
+		FX = true;
+	}
+	if (mode.indexOf("t") != -1) {
+		pos.y -= h;
+		FY = true;
+	}
+	if (mode.indexOf("b") != -1) {
+		pos.y += eh;
+		FY = true;
+	}
+	if (mode.indexOf("c") != -1) {
+		FX || (pos.x += Math.round((ew - w) / 2));
+		FY || (pos.y += Math.round((eh - h) / 2));
+	}
+	this.showAt(pos.x, pos.y);
+};
+
+PopupDiv.prototype.defaultSize = function() {
+	var s = this.element.style;
+	var cs = this.element.currentStyle;
+	var addX = (is_ie && is_compat) ? (parseInt(cs.borderLeftWidth) +
+					   parseInt(cs.borderRightWidth) +
+					   parseInt(cs.paddingLeft) +
+					   parseInt(cs.paddingRight)) : 0;
+	var addY = (is_ie && is_compat) ? (parseInt(cs.borderTopWidth) +
+					   parseInt(cs.borderBottomWidth) +
+					   parseInt(cs.paddingTop) +
+					   parseInt(cs.paddingBottom)) : 0;
+	s.display = "block";
+	s.width = (this.content.offsetWidth + addX) + "px";
+	s.height = (this.content.offsetHeight + this.title.offsetHeight) + "px";
+	s.display = "none";
+};
+
+PopupDiv.prototype.showAt = function(x, y) {
+	this.defaultSize();
+	var s = this.element.style;
+	s.display = "block";
+	s.left = x + "px";
+	s.top = y + "px";
+	this.hideShowCovered();
+
+	PopupDiv.currentPopup = this;
+	HTMLArea._addEvents(this.doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+	HTMLArea._addEvents(this.editor._doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+	if (is_ie && this.modal) {
+		this.doc.body.setCapture(false);
+		this.doc.body.onlosecapture = function() {
+			(PopupDiv.currentPopup) && (this.doc.body.setCapture(false));
+		};
+	}
+	window.event && HTMLArea._stopEvent(window.event);
+
+	if (typeof this.onShow == "function") {
+		this.onShow();
+	} else if (typeof this.onShow == "string") {
+		eval(this.onShow);
+	}
+
+	var field = this.element.getElementsByTagName("input")[0];
+	if (!field) {
+		field = this.element.getElementsByTagName("select")[0];
+	}
+	if (!field) {
+		field = this.element.getElementsByTagName("textarea")[0];
+	}
+	if (field) {
+		field.focus();
+	}
+};
+
+PopupDiv.prototype.close = function() {
+	this.element.style.display = "none";
+	PopupDiv.currentPopup = null;
+	this.hideShowCovered();
+	HTMLArea._removeEvents(this.doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+	HTMLArea._removeEvents(this.editor._doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+	is_ie && this.modal && this.doc.body.releaseCapture();
+	if (typeof this.onClose == "function") {
+		this.onClose();
+	} else if (typeof this.onClose == "string") {
+		eval(this.onClose);
+	}
+	this.element.parentNode.removeChild(this.element);
+};
+
+PopupDiv.prototype.getForm = function() {
+	var forms = this.content.getElementsByTagName("form");
+	return (forms.length > 0) ? forms[0] : null;
+};
+
+PopupDiv.prototype.callHandler = function() {
+	var tags = ["input", "textarea", "select"];
+	var params = new Object();
+	for (var ti in tags) {
+		var tag = tags[ti];
+		var els = this.content.getElementsByTagName(tag);
+		for (var j = 0; j < els.length; ++j) {
+			var el = els[j];
+			params[el.name] = el.value;
+		}
+	}
+	this.handler(this, params);
+	return false;
+};
+
+PopupDiv.getAbsolutePos = function(el) {
+	var r = { x: el.offsetLeft, y: el.offsetTop };
+	if (el.offsetParent) {
+		var tmp = PopupDiv.getAbsolutePos(el.offsetParent);
+		r.x += tmp.x;
+		r.y += tmp.y;
+	}
+	return r;
+};
+
+PopupDiv.getWindowSize = function() {
+	if (window.innerHeight) {
+		return { y: window.innerHeight, x: window.innerWidth };
+	}
+	if (this.doc.body.clientHeight) {
+		return { y: this.doc.body.clientHeight, x: this.doc.body.clientWidth };
+	}
+	return { y: this.doc.documentElement.clientHeight, x: this.doc.documentElement.clientWidth };
+};
+
+PopupDiv.prototype.hideShowCovered = function () {
+	var self = this;
+	function isContained(el) {
+		while (el) {
+			if (el == self.element) {
+				return true;
+			}
+			el = el.parentNode;
+		}
+		return false;
+	};
+	var tags = new Array("applet", "select");
+	var el = this.element;
+
+	var p = PopupDiv.getAbsolutePos(el);
+	var EX1 = p.x;
+	var EX2 = el.offsetWidth + EX1;
+	var EY1 = p.y;
+	var EY2 = el.offsetHeight + EY1;
+
+	if (el.style.display == "none") {
+		EX1 = EX2 = EY1 = EY2 = 0;
+	}
+
+	for (var k = tags.length; k > 0; ) {
+		var ar = this.doc.getElementsByTagName(tags[--k]);
+		var cc = null;
+
+		for (var i = ar.length; i > 0;) {
+			cc = ar[--i];
+			if (isContained(cc)) {
+				cc.style.visibility = "visible";
+				continue;
+			}
+
+			p = PopupDiv.getAbsolutePos(cc);
+			var CX1 = p.x;
+			var CX2 = cc.offsetWidth + CX1;
+			var CY1 = p.y;
+			var CY2 = cc.offsetHeight + CY1;
+
+			if ((CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
+				cc.style.visibility = "visible";
+			} else {
+				cc.style.visibility = "hidden";
+			}
+		}
+	}
+};
+
+PopupDiv.prototype._dragStart = function (ev) {
+	if (this.dragging) {
+		return false;
+	}
+	this.dragging = true;
+	PopupDiv.currentPopup = this;
+	var posX = ev.clientX;
+	var posY = ev.clientY;
+	if (is_ie) {
+		posY += this.doc.body.scrollTop;
+		posX += this.doc.body.scrollLeft;
+	} else {
+		posY += window.scrollY;
+		posX += window.scrollX;
+	}
+	var st = this.element.style;
+	this.xOffs = posX - parseInt(st.left);
+	this.yOffs = posY - parseInt(st.top);
+	HTMLArea._addEvent(this.doc, "mousemove", PopupDiv.dragIt);
+	HTMLArea._addEvent(this.doc, "mouseover", HTMLArea._stopEvent);
+	HTMLArea._addEvent(this.doc, "mouseup", PopupDiv.dragEnd);
+	HTMLArea._stopEvent(ev);
+};
+
+PopupDiv.dragIt = function (ev) {
+	var popup = PopupDiv.currentPopup;
+	if (!(popup && popup.dragging)) {
+		return false;
+	}
+	is_ie && (ev = window.event);
+	var posX = ev.clientX;
+	var posY = ev.clientY;
+	if (is_ie) {
+		posY += this.doc.body.scrollTop;
+		posX += this.doc.body.scrollLeft;
+	} else {
+		posY += window.scrollY;
+		posX += window.scrollX;
+	}
+	popup.hideShowCovered();
+	var st = popup.element.style;
+	st.left = (posX - popup.xOffs) + "px";
+	st.top = (posY - popup.yOffs) + "px";
+	HTMLArea._stopEvent(ev);
+};
+
+PopupDiv.dragEnd = function () {
+	var popup = PopupDiv.currentPopup;
+	if (!popup) {
+		return false;
+	}
+	popup.dragging = false;
+	HTMLArea._removeEvent(popup.doc, "mouseup", PopupDiv.dragEnd);
+	HTMLArea._removeEvent(popup.doc, "mouseover", HTMLArea._stopEvent);
+	HTMLArea._removeEvent(popup.doc, "mousemove", PopupDiv.dragIt);
+	popup.hideShowCovered();
+};
+
+PopupDiv.checkPopup = function (ev) {
+	is_ie && (ev = window.event);
+	var el = is_ie ? ev.srcElement : ev.target;
+	var cp = PopupDiv.currentPopup;
+	for (; (el != null) && (el != cp.element); el = el.parentNode);
+	if (el == null) {
+		cp.modal || ev.type == "mouseover" || cp.close();
+		HTMLArea._stopEvent(ev);
+	}
+};
+
+PopupDiv.prototype.addButtons = function() {
+	var self = this;
+	var div = this.doc.createElement("div");
+	this.content.appendChild(div);
+	div.className = "buttons";
+	for (var i = 0; i < arguments.length; ++i) {
+		var btn = arguments[i];
+		var button = this.doc.createElement("button");
+		div.appendChild(button);
+		button.innerHTML = HTMLArea.I18N.buttons[btn];
+		switch (btn) {
+		    case "ok":
+			button.onclick = function() {
+				self.callHandler();
+				self.close();
+			};
+			break;
+		    case "cancel":
+			button.onclick = function() {
+				self.close();
+			};
+			break;
+		}
+	}
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/htmlarea.css
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/htmlarea.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/htmlarea.css	(revision 795)
@@ -0,0 +1,180 @@
+.htmlarea { background: #fff; }
+
+.htmlarea .toolbar {
+  cursor: default;
+  background: ButtonFace;
+  padding: 1px 1px 2px 1px;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+.htmlarea .toolbar img { border: none; }
+.htmlarea .toolbar .label { padding: 0px 3px; }
+
+.htmlarea .toolbar .button {
+  background: ButtonFace;
+  color: ButtonText;
+  border: 1px solid ButtonFace;
+  padding: 1px;
+  margin: 0px;
+  width: 18px;
+  height: 18px;
+}
+.htmlarea .toolbar .buttonHover {
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
+  padding: 2px 0px 0px 2px;
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.htmlarea .toolbar .buttonPressed {
+  background: ButtonHighlight;
+}
+.htmlarea .toolbar .indicator {
+  padding: 0px 3px;
+  overflow: hidden;
+  width: 20px;
+  text-align: center;
+  cursor: default;
+  border: 1px solid ButtonShadow;
+}
+
+.htmlarea .toolbar .buttonDisabled img {
+  filter: alpha(opacity = 25);
+  -moz-opacity: 0.25;
+}
+
+.htmlarea .toolbar .separator {
+  position: relative;
+  margin: 3px;
+  border-left: 1px solid ButtonShadow;
+  border-right: 1px solid ButtonHighlight;
+  width: 0px;
+  height: 16px;
+  padding: 0px;
+}
+
+.htmlarea .toolbar .space { width: 5px; }
+
+.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }
+
+.htmlarea .toolbar select,
+.htmlarea .toolbar select:hover,
+.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }
+
+.htmlarea .statusBar {
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+  padding: 2px 4px;
+  background-color: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.htmlarea .statusBar .statusBarTree a {
+  padding: 2px 5px;
+  color: #00f;
+}
+
+.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
+.htmlarea .statusBar .statusBarTree a:hover {
+  background-color: Highlight;
+  color: HighlightText;
+  padding: 1px 4px;
+  border: 1px solid HighlightText;
+}
+
+
+/* Hidden DIV popup dialogs (PopupDiv) */
+
+.dialog {
+  color: ButtonText;
+  background: ButtonFace;
+}
+
+.dialog .content { padding: 2px; }
+
+.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.dialog table { border-collapse: collapse; }
+
+.dialog .title {
+  background: #008;
+  color: #ff8;
+  border-bottom: 1px solid #000;
+  padding: 1px 0px 2px 5px;
+  font-size: 12px;
+  font-weight: bold;
+  cursor: default;
+}
+
+.dialog .title .button {
+  float: right;
+  border: 1px solid #66a;
+  padding: 0px 1px 0px 2px;
+  margin-right: 1px;
+  color: #fff;
+  text-align: center;
+}
+
+.dialog .title .button-hilite { border-color: #88f; background: #44c; }
+
+.dialog button {
+  width: 5em;
+  padding: 0px;
+}
+
+.dialog .buttonColor {
+  padding: 1px;
+  cursor: default;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.dialog .buttonColor-hilite {
+  border-color: #000;
+}
+
+.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
+  height: 0.6em;
+  border: 1px solid;
+  padding: 0px 1em;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.dialog .buttonColor .nocolor { padding: 0px; }
+.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+
+.dialog .label { text-align: right; width: 6em; }
+.dialog .value input { width: 100%; }
+.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }
+
+.dialog legend { font-weight: bold; }
+.dialog fieldset table { margin: 2px 0px; }
+
+.popupdiv {
+  border: 2px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.popupwin {
+  padding: 0px;
+  margin: 0px;
+}
+
+.popupwin .title {
+  background: #fff;
+  color: #000;
+  font-weight: bold;
+  font-size: 120%;
+  padding: 3px 10px;
+  margin-bottom: 10px;
+  border-bottom: 1px solid black;
+  letter-spacing: 2px;
+}
+
+form { margin: 0px; border: none; }
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/custom2.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/custom2.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/custom2.html	(revision 795)
@@ -0,0 +1,35 @@
+<html style="width:300px; Height: 60px;">
+ <head>
+  <title>Select Phrase</title>
+<script language="javascript">
+
+var myTitle = window.dialogArguments;
+document.title = myTitle;
+
+
+function returnSelected() {
+  var idx  = document.all.textPulldown.selectedIndex;
+  var text = document.all.textPulldown[idx].text;
+
+  window.returnValue = text;          // set return value
+  window.close();                     // close dialog
+}
+
+</script>
+</head>
+<body bgcolor="#FFFFFF" topmargin=15 leftmargin=0>
+
+<form method=get onSubmit="Set(document.all.ColorHex.value); return false;">
+<div align=center>
+
+<select name="textPulldown">
+<option>The quick brown</option>
+<option>fox jumps over</option>
+<option>the lazy dog.</option>
+</select>
+
+<input type="button" value=" Go " onClick="returnSelected()">
+
+</div>
+</form>
+</body></html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/link.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/link.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/link.html	(revision 795)
@@ -0,0 +1,144 @@
+<html>
+
+<head>
+  <title>Insert/Modify Link</title>
+  <script type="text/javascript" src="popup.js"></script>
+  <script type="text/javascript">
+    window.resizeTo(400, 200);
+
+I18N = window.opener.HTMLArea.I18N.dialogs;
+
+function i18n(str) {
+  return (I18N[str] || str);
+};
+
+function onTargetChanged() {
+  var f = document.getElementById("f_other_target");
+  if (this.value == "_other") {
+    f.style.visibility = "visible";
+    f.select();
+    f.focus();
+  } else f.style.visibility = "hidden";
+};
+
+function Init() {
+  __dlg_translate(I18N);
+  __dlg_init();
+  var param = window.dialogArguments;
+  var target_select = document.getElementById("f_target");
+  if (param) {
+      document.getElementById("f_href").value = param["f_href"];
+      document.getElementById("f_title").value = param["f_title"];
+      comboSelectValue(target_select, param["f_target"]);
+      if (target_select.value != param.f_target) {
+        var opt = document.createElement("option");
+        opt.value = param.f_target;
+        opt.innerHTML = opt.value;
+        target_select.appendChild(opt);
+        opt.selected = true;
+      }
+  }
+  var opt = document.createElement("option");
+  opt.value = "_other";
+  opt.innerHTML = i18n("Other");
+  target_select.appendChild(opt);
+  target_select.onchange = onTargetChanged;
+  document.getElementById("f_href").focus();
+  document.getElementById("f_href").select();
+};
+
+function onOK() {
+  var required = {
+    // f_href shouldn't be required or otherwise removing the link by entering an empty
+    // url isn't possible anymore.
+    // "f_href": i18n("You must enter the URL where this link points to")
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+  // pass data back to the calling window
+  var fields = ["f_href", "f_title", "f_target" ];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = document.getElementById(id);
+    param[id] = el.value;
+  }
+  if (param.f_target == "_other")
+    param.f_target = document.getElementById("f_other_target").value;
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+table .label { text-align: right; width: 8em; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+
+#buttons {
+      margin-top: 1em; border-top: 1px solid #999;
+      padding: 2px; text-align: right;
+}
+</style>
+
+</head>
+
+<body onload="Init()">
+<div class="title">Insert/Modify Link</div>
+
+<table border="0" style="width: 100%;">
+  <tr>
+    <td class="label">URL:</td>
+    <td><input type="text" id="f_href" style="width: 100%" /></td>
+  </tr>
+  <tr>
+    <td class="label">Title (tooltip):</td>
+    <td><input type="text" id="f_title" style="width: 100%" /></td>
+  </tr>
+  <tr>
+    <td class="label">Target:</td>
+    <td><select id="f_target">
+      <option value="">None (use implicit)</option>
+      <option value="_blank">New window (_blank)</option>
+      <option value="_self">Same frame (_self)</option>
+      <option value="_top">Top frame (_top)</option>
+    </select>
+    <input type="text" name="f_other_target" id="f_other_target" size="10" style="visibility: hidden" />
+    </td>
+  </tr>
+</table>
+
+<div id="buttons">
+  <button type="button" name="ok" onclick="return onOK();">OK</button>
+  <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/select_color.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/select_color.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/select_color.html	(revision 795)
@@ -0,0 +1,347 @@
+<!-- note: this version of the color picker is optimized for IE 5.5+ only -->
+
+<html><head><title>Select Color</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+window.resizeTo(240, 182);
+function _CloseOnEsc() {
+  if (event.keyCode == 27) { window.close(); return; }
+}
+
+function Init() {                                                       // run on page load
+  __dlg_init();    // <!-- this can be found in popup.js -->
+  document.body.onkeypress = _CloseOnEsc;
+
+  var color = window.dialogArguments;
+  color = ValidateColor(color) || '000000';
+  View(color);                                                          // set default color
+}
+
+function View(color) {                  // preview color
+  document.getElementById("ColorPreview").style.backgroundColor = '#' + color;
+  document.getElementById("ColorHex").value = '#' + color;
+}
+
+function Set(string) {                   // select color
+  var color = ValidateColor(string);
+  if (color == null) { alert("Invalid color code: " + string); }        // invalid color
+  else {                                                                // valid color
+    View(color);                          // show selected color
+    __dlg_close(color);
+  }
+}
+
+function ValidateColor(string) {                // return valid color code
+  string = string || '';
+  string = string + "";
+  string = string.toUpperCase();
+  var chars = '0123456789ABCDEF';
+  var out   = '';
+
+  for (var i=0; i<string.length; i++) {             // remove invalid color chars
+    var schar = string.charAt(i);
+    if (chars.indexOf(schar) != -1) { out += schar; }
+  }
+
+  if (out.length != 6) { return null; }            // check length
+  return out;
+}
+
+</script>
+</head>
+<body style="background:ButtonFace; margin:0px; padding:0px" onload="Init()">
+
+<form method="get" style="margin:0px; padding:0px" onSubmit="Set(document.getElementById('ColorHex').value); return false;">
+<table border="0px" cellspacing="0px" cellpadding="4" width="100%">
+ <tr>
+  <td style="background:buttonface" valign=center><div style="background-color: #000000; padding: 1; height: 21px; width: 50px"><div id="ColorPreview" style="height: 100%; width: 100%"></div></div></td>
+  <td style="background:buttonface" valign=center><input type="text" name="ColorHex"
+    id="ColorHex" value="" size=15 style="font-size: 12px"></td>
+  <td style="background:buttonface" width=100%></td>
+ </tr>
+</table>
+</form>
+
+<table border="0" cellspacing="1px" cellpadding="0px" width="100%" bgcolor="#000000" style="cursor: hand;">
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#003300 onMouseOver=View('003300') onClick=Set('003300') height="10px" width="10px"></td>
+<td bgcolor=#006600 onMouseOver=View('006600') onClick=Set('006600') height="10px" width="10px"></td>
+<td bgcolor=#009900 onMouseOver=View('009900') onClick=Set('009900') height="10px" width="10px"></td>
+<td bgcolor=#00CC00 onMouseOver=View('00CC00') onClick=Set('00CC00') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#330000 onMouseOver=View('330000') onClick=Set('330000') height="10px" width="10px"></td>
+<td bgcolor=#333300 onMouseOver=View('333300') onClick=Set('333300') height="10px" width="10px"></td>
+<td bgcolor=#336600 onMouseOver=View('336600') onClick=Set('336600') height="10px" width="10px"></td>
+<td bgcolor=#339900 onMouseOver=View('339900') onClick=Set('339900') height="10px" width="10px"></td>
+<td bgcolor=#33CC00 onMouseOver=View('33CC00') onClick=Set('33CC00') height="10px" width="10px"></td>
+<td bgcolor=#33FF00 onMouseOver=View('33FF00') onClick=Set('33FF00') height="10px" width="10px"></td>
+<td bgcolor=#660000 onMouseOver=View('660000') onClick=Set('660000') height="10px" width="10px"></td>
+<td bgcolor=#663300 onMouseOver=View('663300') onClick=Set('663300') height="10px" width="10px"></td>
+<td bgcolor=#666600 onMouseOver=View('666600') onClick=Set('666600') height="10px" width="10px"></td>
+<td bgcolor=#669900 onMouseOver=View('669900') onClick=Set('669900') height="10px" width="10px"></td>
+<td bgcolor=#66CC00 onMouseOver=View('66CC00') onClick=Set('66CC00') height="10px" width="10px"></td>
+<td bgcolor=#66FF00 onMouseOver=View('66FF00') onClick=Set('66FF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000033 onMouseOver=View('000033') onClick=Set('000033') height="10px" width="10px"></td>
+<td bgcolor=#003333 onMouseOver=View('003333') onClick=Set('003333') height="10px" width="10px"></td>
+<td bgcolor=#006633 onMouseOver=View('006633') onClick=Set('006633') height="10px" width="10px"></td>
+<td bgcolor=#009933 onMouseOver=View('009933') onClick=Set('009933') height="10px" width="10px"></td>
+<td bgcolor=#00CC33 onMouseOver=View('00CC33') onClick=Set('00CC33') height="10px" width="10px"></td>
+<td bgcolor=#00FF33 onMouseOver=View('00FF33') onClick=Set('00FF33') height="10px" width="10px"></td>
+<td bgcolor=#330033 onMouseOver=View('330033') onClick=Set('330033') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#336633 onMouseOver=View('336633') onClick=Set('336633') height="10px" width="10px"></td>
+<td bgcolor=#339933 onMouseOver=View('339933') onClick=Set('339933') height="10px" width="10px"></td>
+<td bgcolor=#33CC33 onMouseOver=View('33CC33') onClick=Set('33CC33') height="10px" width="10px"></td>
+<td bgcolor=#33FF33 onMouseOver=View('33FF33') onClick=Set('33FF33') height="10px" width="10px"></td>
+<td bgcolor=#660033 onMouseOver=View('660033') onClick=Set('660033') height="10px" width="10px"></td>
+<td bgcolor=#663333 onMouseOver=View('663333') onClick=Set('663333') height="10px" width="10px"></td>
+<td bgcolor=#666633 onMouseOver=View('666633') onClick=Set('666633') height="10px" width="10px"></td>
+<td bgcolor=#669933 onMouseOver=View('669933') onClick=Set('669933') height="10px" width="10px"></td>
+<td bgcolor=#66CC33 onMouseOver=View('66CC33') onClick=Set('66CC33') height="10px" width="10px"></td>
+<td bgcolor=#66FF33 onMouseOver=View('66FF33') onClick=Set('66FF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000066 onMouseOver=View('000066') onClick=Set('000066') height="10px" width="10px"></td>
+<td bgcolor=#003366 onMouseOver=View('003366') onClick=Set('003366') height="10px" width="10px"></td>
+<td bgcolor=#006666 onMouseOver=View('006666') onClick=Set('006666') height="10px" width="10px"></td>
+<td bgcolor=#009966 onMouseOver=View('009966') onClick=Set('009966') height="10px" width="10px"></td>
+<td bgcolor=#00CC66 onMouseOver=View('00CC66') onClick=Set('00CC66') height="10px" width="10px"></td>
+<td bgcolor=#00FF66 onMouseOver=View('00FF66') onClick=Set('00FF66') height="10px" width="10px"></td>
+<td bgcolor=#330066 onMouseOver=View('330066') onClick=Set('330066') height="10px" width="10px"></td>
+<td bgcolor=#333366 onMouseOver=View('333366') onClick=Set('333366') height="10px" width="10px"></td>
+<td bgcolor=#336666 onMouseOver=View('336666') onClick=Set('336666') height="10px" width="10px"></td>
+<td bgcolor=#339966 onMouseOver=View('339966') onClick=Set('339966') height="10px" width="10px"></td>
+<td bgcolor=#33CC66 onMouseOver=View('33CC66') onClick=Set('33CC66') height="10px" width="10px"></td>
+<td bgcolor=#33FF66 onMouseOver=View('33FF66') onClick=Set('33FF66') height="10px" width="10px"></td>
+<td bgcolor=#660066 onMouseOver=View('660066') onClick=Set('660066') height="10px" width="10px"></td>
+<td bgcolor=#663366 onMouseOver=View('663366') onClick=Set('663366') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#669966 onMouseOver=View('669966') onClick=Set('669966') height="10px" width="10px"></td>
+<td bgcolor=#66CC66 onMouseOver=View('66CC66') onClick=Set('66CC66') height="10px" width="10px"></td>
+<td bgcolor=#66FF66 onMouseOver=View('66FF66') onClick=Set('66FF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000099 onMouseOver=View('000099') onClick=Set('000099') height="10px" width="10px"></td>
+<td bgcolor=#003399 onMouseOver=View('003399') onClick=Set('003399') height="10px" width="10px"></td>
+<td bgcolor=#006699 onMouseOver=View('006699') onClick=Set('006699') height="10px" width="10px"></td>
+<td bgcolor=#009999 onMouseOver=View('009999') onClick=Set('009999') height="10px" width="10px"></td>
+<td bgcolor=#00CC99 onMouseOver=View('00CC99') onClick=Set('00CC99') height="10px" width="10px"></td>
+<td bgcolor=#00FF99 onMouseOver=View('00FF99') onClick=Set('00FF99') height="10px" width="10px"></td>
+<td bgcolor=#330099 onMouseOver=View('330099') onClick=Set('330099') height="10px" width="10px"></td>
+<td bgcolor=#333399 onMouseOver=View('333399') onClick=Set('333399') height="10px" width="10px"></td>
+<td bgcolor=#336699 onMouseOver=View('336699') onClick=Set('336699') height="10px" width="10px"></td>
+<td bgcolor=#339999 onMouseOver=View('339999') onClick=Set('339999') height="10px" width="10px"></td>
+<td bgcolor=#33CC99 onMouseOver=View('33CC99') onClick=Set('33CC99') height="10px" width="10px"></td>
+<td bgcolor=#33FF99 onMouseOver=View('33FF99') onClick=Set('33FF99') height="10px" width="10px"></td>
+<td bgcolor=#660099 onMouseOver=View('660099') onClick=Set('660099') height="10px" width="10px"></td>
+<td bgcolor=#663399 onMouseOver=View('663399') onClick=Set('663399') height="10px" width="10px"></td>
+<td bgcolor=#666699 onMouseOver=View('666699') onClick=Set('666699') height="10px" width="10px"></td>
+<td bgcolor=#669999 onMouseOver=View('669999') onClick=Set('669999') height="10px" width="10px"></td>
+<td bgcolor=#66CC99 onMouseOver=View('66CC99') onClick=Set('66CC99') height="10px" width="10px"></td>
+<td bgcolor=#66FF99 onMouseOver=View('66FF99') onClick=Set('66FF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000CC onMouseOver=View('0000CC') onClick=Set('0000CC') height="10px" width="10px"></td>
+<td bgcolor=#0033CC onMouseOver=View('0033CC') onClick=Set('0033CC') height="10px" width="10px"></td>
+<td bgcolor=#0066CC onMouseOver=View('0066CC') onClick=Set('0066CC') height="10px" width="10px"></td>
+<td bgcolor=#0099CC onMouseOver=View('0099CC') onClick=Set('0099CC') height="10px" width="10px"></td>
+<td bgcolor=#00CCCC onMouseOver=View('00CCCC') onClick=Set('00CCCC') height="10px" width="10px"></td>
+<td bgcolor=#00FFCC onMouseOver=View('00FFCC') onClick=Set('00FFCC') height="10px" width="10px"></td>
+<td bgcolor=#3300CC onMouseOver=View('3300CC') onClick=Set('3300CC') height="10px" width="10px"></td>
+<td bgcolor=#3333CC onMouseOver=View('3333CC') onClick=Set('3333CC') height="10px" width="10px"></td>
+<td bgcolor=#3366CC onMouseOver=View('3366CC') onClick=Set('3366CC') height="10px" width="10px"></td>
+<td bgcolor=#3399CC onMouseOver=View('3399CC') onClick=Set('3399CC') height="10px" width="10px"></td>
+<td bgcolor=#33CCCC onMouseOver=View('33CCCC') onClick=Set('33CCCC') height="10px" width="10px"></td>
+<td bgcolor=#33FFCC onMouseOver=View('33FFCC') onClick=Set('33FFCC') height="10px" width="10px"></td>
+<td bgcolor=#6600CC onMouseOver=View('6600CC') onClick=Set('6600CC') height="10px" width="10px"></td>
+<td bgcolor=#6633CC onMouseOver=View('6633CC') onClick=Set('6633CC') height="10px" width="10px"></td>
+<td bgcolor=#6666CC onMouseOver=View('6666CC') onClick=Set('6666CC') height="10px" width="10px"></td>
+<td bgcolor=#6699CC onMouseOver=View('6699CC') onClick=Set('6699CC') height="10px" width="10px"></td>
+<td bgcolor=#66CCCC onMouseOver=View('66CCCC') onClick=Set('66CCCC') height="10px" width="10px"></td>
+<td bgcolor=#66FFCC onMouseOver=View('66FFCC') onClick=Set('66FFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#0033FF onMouseOver=View('0033FF') onClick=Set('0033FF') height="10px" width="10px"></td>
+<td bgcolor=#0066FF onMouseOver=View('0066FF') onClick=Set('0066FF') height="10px" width="10px"></td>
+<td bgcolor=#0099FF onMouseOver=View('0099FF') onClick=Set('0099FF') height="10px" width="10px"></td>
+<td bgcolor=#00CCFF onMouseOver=View('00CCFF') onClick=Set('00CCFF') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#3300FF onMouseOver=View('3300FF') onClick=Set('3300FF') height="10px" width="10px"></td>
+<td bgcolor=#3333FF onMouseOver=View('3333FF') onClick=Set('3333FF') height="10px" width="10px"></td>
+<td bgcolor=#3366FF onMouseOver=View('3366FF') onClick=Set('3366FF') height="10px" width="10px"></td>
+<td bgcolor=#3399FF onMouseOver=View('3399FF') onClick=Set('3399FF') height="10px" width="10px"></td>
+<td bgcolor=#33CCFF onMouseOver=View('33CCFF') onClick=Set('33CCFF') height="10px" width="10px"></td>
+<td bgcolor=#33FFFF onMouseOver=View('33FFFF') onClick=Set('33FFFF') height="10px" width="10px"></td>
+<td bgcolor=#6600FF onMouseOver=View('6600FF') onClick=Set('6600FF') height="10px" width="10px"></td>
+<td bgcolor=#6633FF onMouseOver=View('6633FF') onClick=Set('6633FF') height="10px" width="10px"></td>
+<td bgcolor=#6666FF onMouseOver=View('6666FF') onClick=Set('6666FF') height="10px" width="10px"></td>
+<td bgcolor=#6699FF onMouseOver=View('6699FF') onClick=Set('6699FF') height="10px" width="10px"></td>
+<td bgcolor=#66CCFF onMouseOver=View('66CCFF') onClick=Set('66CCFF') height="10px" width="10px"></td>
+<td bgcolor=#66FFFF onMouseOver=View('66FFFF') onClick=Set('66FFFF') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990000 onMouseOver=View('990000') onClick=Set('990000') height="10px" width="10px"></td>
+<td bgcolor=#993300 onMouseOver=View('993300') onClick=Set('993300') height="10px" width="10px"></td>
+<td bgcolor=#996600 onMouseOver=View('996600') onClick=Set('996600') height="10px" width="10px"></td>
+<td bgcolor=#999900 onMouseOver=View('999900') onClick=Set('999900') height="10px" width="10px"></td>
+<td bgcolor=#99CC00 onMouseOver=View('99CC00') onClick=Set('99CC00') height="10px" width="10px"></td>
+<td bgcolor=#99FF00 onMouseOver=View('99FF00') onClick=Set('99FF00') height="10px" width="10px"></td>
+<td bgcolor=#CC0000 onMouseOver=View('CC0000') onClick=Set('CC0000') height="10px" width="10px"></td>
+<td bgcolor=#CC3300 onMouseOver=View('CC3300') onClick=Set('CC3300') height="10px" width="10px"></td>
+<td bgcolor=#CC6600 onMouseOver=View('CC6600') onClick=Set('CC6600') height="10px" width="10px"></td>
+<td bgcolor=#CC9900 onMouseOver=View('CC9900') onClick=Set('CC9900') height="10px" width="10px"></td>
+<td bgcolor=#CCCC00 onMouseOver=View('CCCC00') onClick=Set('CCCC00') height="10px" width="10px"></td>
+<td bgcolor=#CCFF00 onMouseOver=View('CCFF00') onClick=Set('CCFF00') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#FF3300 onMouseOver=View('FF3300') onClick=Set('FF3300') height="10px" width="10px"></td>
+<td bgcolor=#FF6600 onMouseOver=View('FF6600') onClick=Set('FF6600') height="10px" width="10px"></td>
+<td bgcolor=#FF9900 onMouseOver=View('FF9900') onClick=Set('FF9900') height="10px" width="10px"></td>
+<td bgcolor=#FFCC00 onMouseOver=View('FFCC00') onClick=Set('FFCC00') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990033 onMouseOver=View('990033') onClick=Set('990033') height="10px" width="10px"></td>
+<td bgcolor=#993333 onMouseOver=View('993333') onClick=Set('993333') height="10px" width="10px"></td>
+<td bgcolor=#996633 onMouseOver=View('996633') onClick=Set('996633') height="10px" width="10px"></td>
+<td bgcolor=#999933 onMouseOver=View('999933') onClick=Set('999933') height="10px" width="10px"></td>
+<td bgcolor=#99CC33 onMouseOver=View('99CC33') onClick=Set('99CC33') height="10px" width="10px"></td>
+<td bgcolor=#99FF33 onMouseOver=View('99FF33') onClick=Set('99FF33') height="10px" width="10px"></td>
+<td bgcolor=#CC0033 onMouseOver=View('CC0033') onClick=Set('CC0033') height="10px" width="10px"></td>
+<td bgcolor=#CC3333 onMouseOver=View('CC3333') onClick=Set('CC3333') height="10px" width="10px"></td>
+<td bgcolor=#CC6633 onMouseOver=View('CC6633') onClick=Set('CC6633') height="10px" width="10px"></td>
+<td bgcolor=#CC9933 onMouseOver=View('CC9933') onClick=Set('CC9933') height="10px" width="10px"></td>
+<td bgcolor=#CCCC33 onMouseOver=View('CCCC33') onClick=Set('CCCC33') height="10px" width="10px"></td>
+<td bgcolor=#CCFF33 onMouseOver=View('CCFF33') onClick=Set('CCFF33') height="10px" width="10px"></td>
+<td bgcolor=#FF0033 onMouseOver=View('FF0033') onClick=Set('FF0033') height="10px" width="10px"></td>
+<td bgcolor=#FF3333 onMouseOver=View('FF3333') onClick=Set('FF3333') height="10px" width="10px"></td>
+<td bgcolor=#FF6633 onMouseOver=View('FF6633') onClick=Set('FF6633') height="10px" width="10px"></td>
+<td bgcolor=#FF9933 onMouseOver=View('FF9933') onClick=Set('FF9933') height="10px" width="10px"></td>
+<td bgcolor=#FFCC33 onMouseOver=View('FFCC33') onClick=Set('FFCC33') height="10px" width="10px"></td>
+<td bgcolor=#FFFF33 onMouseOver=View('FFFF33') onClick=Set('FFFF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990066 onMouseOver=View('990066') onClick=Set('990066') height="10px" width="10px"></td>
+<td bgcolor=#993366 onMouseOver=View('993366') onClick=Set('993366') height="10px" width="10px"></td>
+<td bgcolor=#996666 onMouseOver=View('996666') onClick=Set('996666') height="10px" width="10px"></td>
+<td bgcolor=#999966 onMouseOver=View('999966') onClick=Set('999966') height="10px" width="10px"></td>
+<td bgcolor=#99CC66 onMouseOver=View('99CC66') onClick=Set('99CC66') height="10px" width="10px"></td>
+<td bgcolor=#99FF66 onMouseOver=View('99FF66') onClick=Set('99FF66') height="10px" width="10px"></td>
+<td bgcolor=#CC0066 onMouseOver=View('CC0066') onClick=Set('CC0066') height="10px" width="10px"></td>
+<td bgcolor=#CC3366 onMouseOver=View('CC3366') onClick=Set('CC3366') height="10px" width="10px"></td>
+<td bgcolor=#CC6666 onMouseOver=View('CC6666') onClick=Set('CC6666') height="10px" width="10px"></td>
+<td bgcolor=#CC9966 onMouseOver=View('CC9966') onClick=Set('CC9966') height="10px" width="10px"></td>
+<td bgcolor=#CCCC66 onMouseOver=View('CCCC66') onClick=Set('CCCC66') height="10px" width="10px"></td>
+<td bgcolor=#CCFF66 onMouseOver=View('CCFF66') onClick=Set('CCFF66') height="10px" width="10px"></td>
+<td bgcolor=#FF0066 onMouseOver=View('FF0066') onClick=Set('FF0066') height="10px" width="10px"></td>
+<td bgcolor=#FF3366 onMouseOver=View('FF3366') onClick=Set('FF3366') height="10px" width="10px"></td>
+<td bgcolor=#FF6666 onMouseOver=View('FF6666') onClick=Set('FF6666') height="10px" width="10px"></td>
+<td bgcolor=#FF9966 onMouseOver=View('FF9966') onClick=Set('FF9966') height="10px" width="10px"></td>
+<td bgcolor=#FFCC66 onMouseOver=View('FFCC66') onClick=Set('FFCC66') height="10px" width="10px"></td>
+<td bgcolor=#FFFF66 onMouseOver=View('FFFF66') onClick=Set('FFFF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990099 onMouseOver=View('990099') onClick=Set('990099') height="10px" width="10px"></td>
+<td bgcolor=#993399 onMouseOver=View('993399') onClick=Set('993399') height="10px" width="10px"></td>
+<td bgcolor=#996699 onMouseOver=View('996699') onClick=Set('996699') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#99CC99 onMouseOver=View('99CC99') onClick=Set('99CC99') height="10px" width="10px"></td>
+<td bgcolor=#99FF99 onMouseOver=View('99FF99') onClick=Set('99FF99') height="10px" width="10px"></td>
+<td bgcolor=#CC0099 onMouseOver=View('CC0099') onClick=Set('CC0099') height="10px" width="10px"></td>
+<td bgcolor=#CC3399 onMouseOver=View('CC3399') onClick=Set('CC3399') height="10px" width="10px"></td>
+<td bgcolor=#CC6699 onMouseOver=View('CC6699') onClick=Set('CC6699') height="10px" width="10px"></td>
+<td bgcolor=#CC9999 onMouseOver=View('CC9999') onClick=Set('CC9999') height="10px" width="10px"></td>
+<td bgcolor=#CCCC99 onMouseOver=View('CCCC99') onClick=Set('CCCC99') height="10px" width="10px"></td>
+<td bgcolor=#CCFF99 onMouseOver=View('CCFF99') onClick=Set('CCFF99') height="10px" width="10px"></td>
+<td bgcolor=#FF0099 onMouseOver=View('FF0099') onClick=Set('FF0099') height="10px" width="10px"></td>
+<td bgcolor=#FF3399 onMouseOver=View('FF3399') onClick=Set('FF3399') height="10px" width="10px"></td>
+<td bgcolor=#FF6699 onMouseOver=View('FF6699') onClick=Set('FF6699') height="10px" width="10px"></td>
+<td bgcolor=#FF9999 onMouseOver=View('FF9999') onClick=Set('FF9999') height="10px" width="10px"></td>
+<td bgcolor=#FFCC99 onMouseOver=View('FFCC99') onClick=Set('FFCC99') height="10px" width="10px"></td>
+<td bgcolor=#FFFF99 onMouseOver=View('FFFF99') onClick=Set('FFFF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900CC onMouseOver=View('9900CC') onClick=Set('9900CC') height="10px" width="10px"></td>
+<td bgcolor=#9933CC onMouseOver=View('9933CC') onClick=Set('9933CC') height="10px" width="10px"></td>
+<td bgcolor=#9966CC onMouseOver=View('9966CC') onClick=Set('9966CC') height="10px" width="10px"></td>
+<td bgcolor=#9999CC onMouseOver=View('9999CC') onClick=Set('9999CC') height="10px" width="10px"></td>
+<td bgcolor=#99CCCC onMouseOver=View('99CCCC') onClick=Set('99CCCC') height="10px" width="10px"></td>
+<td bgcolor=#99FFCC onMouseOver=View('99FFCC') onClick=Set('99FFCC') height="10px" width="10px"></td>
+<td bgcolor=#CC00CC onMouseOver=View('CC00CC') onClick=Set('CC00CC') height="10px" width="10px"></td>
+<td bgcolor=#CC33CC onMouseOver=View('CC33CC') onClick=Set('CC33CC') height="10px" width="10px"></td>
+<td bgcolor=#CC66CC onMouseOver=View('CC66CC') onClick=Set('CC66CC') height="10px" width="10px"></td>
+<td bgcolor=#CC99CC onMouseOver=View('CC99CC') onClick=Set('CC99CC') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#CCFFCC onMouseOver=View('CCFFCC') onClick=Set('CCFFCC') height="10px" width="10px"></td>
+<td bgcolor=#FF00CC onMouseOver=View('FF00CC') onClick=Set('FF00CC') height="10px" width="10px"></td>
+<td bgcolor=#FF33CC onMouseOver=View('FF33CC') onClick=Set('FF33CC') height="10px" width="10px"></td>
+<td bgcolor=#FF66CC onMouseOver=View('FF66CC') onClick=Set('FF66CC') height="10px" width="10px"></td>
+<td bgcolor=#FF99CC onMouseOver=View('FF99CC') onClick=Set('FF99CC') height="10px" width="10px"></td>
+<td bgcolor=#FFCCCC onMouseOver=View('FFCCCC') onClick=Set('FFCCCC') height="10px" width="10px"></td>
+<td bgcolor=#FFFFCC onMouseOver=View('FFFFCC') onClick=Set('FFFFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900FF onMouseOver=View('9900FF') onClick=Set('9900FF') height="10px" width="10px"></td>
+<td bgcolor=#9933FF onMouseOver=View('9933FF') onClick=Set('9933FF') height="10px" width="10px"></td>
+<td bgcolor=#9966FF onMouseOver=View('9966FF') onClick=Set('9966FF') height="10px" width="10px"></td>
+<td bgcolor=#9999FF onMouseOver=View('9999FF') onClick=Set('9999FF') height="10px" width="10px"></td>
+<td bgcolor=#99CCFF onMouseOver=View('99CCFF') onClick=Set('99CCFF') height="10px" width="10px"></td>
+<td bgcolor=#99FFFF onMouseOver=View('99FFFF') onClick=Set('99FFFF') height="10px" width="10px"></td>
+<td bgcolor=#CC00FF onMouseOver=View('CC00FF') onClick=Set('CC00FF') height="10px" width="10px"></td>
+<td bgcolor=#CC33FF onMouseOver=View('CC33FF') onClick=Set('CC33FF') height="10px" width="10px"></td>
+<td bgcolor=#CC66FF onMouseOver=View('CC66FF') onClick=Set('CC66FF') height="10px" width="10px"></td>
+<td bgcolor=#CC99FF onMouseOver=View('CC99FF') onClick=Set('CC99FF') height="10px" width="10px"></td>
+<td bgcolor=#CCCCFF onMouseOver=View('CCCCFF') onClick=Set('CCCCFF') height="10px" width="10px"></td>
+<td bgcolor=#CCFFFF onMouseOver=View('CCFFFF') onClick=Set('CCFFFF') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#FF33FF onMouseOver=View('FF33FF') onClick=Set('FF33FF') height="10px" width="10px"></td>
+<td bgcolor=#FF66FF onMouseOver=View('FF66FF') onClick=Set('FF66FF') height="10px" width="10px"></td>
+<td bgcolor=#FF99FF onMouseOver=View('FF99FF') onClick=Set('FF99FF') height="10px" width="10px"></td>
+<td bgcolor=#FFCCFF onMouseOver=View('FFCCFF') onClick=Set('FFCCFF') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+</tr>
+</table>
+
+</body></html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/editor_help.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/editor_help.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/editor_help.html	(revision 795)
@@ -0,0 +1,16 @@
+<html>
+ <head>
+  <title>Editor Help</title>
+  <style>
+    body, td, p, div { font-family: arial; font-size: x-small; }
+  </style>
+ </head>
+<body>
+
+<h2>Editor Help<hr></h2>
+
+Todo...
+
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/old-fullscreen.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/old-fullscreen.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/old-fullscreen.html	(revision 795)
@@ -0,0 +1,131 @@
+<html>
+<head><title>Fullscreen Editor</title>
+<style type="text/css"> body {	margin: 0px; border: 0px; background-color: buttonface; } </style>
+
+<script>
+
+// if we pass the "window" object as a argument and then set opener to
+// equal that we can refer to dialogWindows and popupWindows the same way
+if (window.dialogArguments) { opener = window.dialogArguments; }
+
+var _editor_url = "../";
+document.write('<scr'+'ipt src="' +_editor_url+ 'editor.js" language="Javascript1.2"></scr'+'ipt>');
+
+var parent_objname = location.search.substring(1,location.search.length);  // parent editor objname
+var parent_config  = opener.document.all[parent_objname].config;
+
+var config         = cloneObject( parent_config );
+var objname        = 'editor'; // name of this editor
+
+//  DOMViewerObj = config;
+//  DOMViewerName = 'config';
+//  window.open('/innerHTML/domviewer.htm');  
+
+/* ---------------------------------------------------------------------- *\
+  Function    : 
+  Description : 
+\* ---------------------------------------------------------------------- */
+
+function _CloseOnEsc() {
+  if (event.keyCode == 27) {
+    update_parent();
+    window.close();
+    return;
+  }
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : cloneObject
+  Description : copy an object by value instead of by reference
+  Usage       : var newObj = cloneObject(oldObj);
+\* ---------------------------------------------------------------------- */
+
+function cloneObject(obj) {
+  var newObj          = new Object; 
+
+  // check for array objects
+  if (obj.constructor.toString().indexOf('function Array(') == 1) {
+    newObj = obj.constructor();
+  }
+
+  for (var n in obj) {
+    var node = obj[n];
+    if (typeof node == 'object') { newObj[n] = cloneObject(node); }
+    else                         { newObj[n] = node; }
+  }
+  
+  return newObj;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : resize_editor
+  Description : resize the editor when the user resizes the popup
+\* ---------------------------------------------------------------------- */
+
+function resize_editor() {  // resize editor to fix window
+  var editor = document.all['_editor_editor'];
+
+  newWidth  = document.body.offsetWidth;
+  newHeight = document.body.offsetHeight - editor.offsetTop;
+
+  if (newWidth < 0) { newWidth = 0; }
+  if (newHeight < 0) { newHeight = 0; }
+
+  editor.style.width  = newWidth;
+  editor.style.height = newHeight;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : init
+  Description : run this code on page load
+\* ---------------------------------------------------------------------- */
+
+function init() {
+  // change maximize button to minimize button
+  config.btnList["popupeditor"] = ['popupeditor', 'Minimize Editor',  'update_parent(); window.close();', 'fullscreen_minimize.gif'];
+
+  // set htmlmode button to refer to THIS editor
+  config.btnList["htmlmode"]    = ['HtmlMode',    'View HTML Source', 'editor_setmode(\'editor\')',  'ed_html.gif'];
+
+  // change image url to be relative to current path
+  config.imgURL = "../images/";
+  
+  // generate editor and resize it
+  editor_generate('editor', config);
+  resize_editor();
+
+  // switch mode if needed
+  if (parent_config.mode == 'textedit') { editor_setmode(objname, 'textedit'); }
+
+  // set child window contents
+  var parentHTML = opener.editor_getHTML(parent_objname);
+  editor_setHTML(objname, parentHTML);
+
+  // continuously update parent editor window
+  window.setInterval(update_parent, 333);
+
+  // setup event handlers
+  document.body.onkeypress = _CloseOnEsc;
+  window.onresize = resize_editor;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : update_parent
+  Description : update parent window editor field with contents from child window
+\* ---------------------------------------------------------------------- */
+
+function update_parent() {
+  var childHTML = editor_getHTML(objname);
+  opener.editor_setHTML(parent_objname, childHTML);
+}
+
+
+</script>
+</head>
+<body scroll="no" onload="init()" onunload="update_parent()">
+
+<div style="margin: 0 0 0 0; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; "></div>
+
+<textarea name="editor" style="width:100%; height:300px"></textarea><br>
+
+</body></html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/fullscreen.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/fullscreen.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/fullscreen.html	(revision 795)
@@ -0,0 +1,133 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+  <head>
+    <title>Fullscreen HTMLArea</title>
+    <script type="text/javascript">
+      _editor_url = window.opener._editor_url;
+      _editor_lang = window.opener._editor_lang;
+      var BASE = window.opener.document.baseURI || window.opener.document.URL;
+      var head = document.getElementsByTagName("head")[0];
+      var base = document.createElement("base");
+      base.href = BASE;
+      head.appendChild(base);
+    </script>
+
+    <script type="text/javascript" src="../htmlarea.js"></script>
+
+    <script type="text/javascript">
+	// load HTMLArea scripts that are present in the opener frame
+	var scripts = window.opener.HTMLArea._scripts;
+	for (var i = 4; i < scripts.length; ++i) {
+           document.write("<scr" + "ipt type='text/javascript' src='" + scripts[i] + "'></scr" + "ipt>");
+        }
+    </script>
+
+    <!-- browser takes a coffee break here -->
+    <script type="text/javascript">
+var parent_object  = null;
+var editor	   = null;	// to be initialized later [ function init() ]
+
+/* ---------------------------------------------------------------------- *\
+   Function    : 
+   Description : 
+\* ---------------------------------------------------------------------- */
+
+function _CloseOnEsc(ev) {
+	ev || (ev = window.event);
+	if (ev.keyCode == 27) {
+		// update_parent();
+		window.close();
+		return;
+	}
+}
+
+/* ---------------------------------------------------------------------- *\
+   Function    : resize_editor
+   Description : resize the editor when the user resizes the popup
+\* ---------------------------------------------------------------------- */
+
+function resize_editor() {  // resize editor to fix window
+	var newHeight;
+	if (document.all) {
+		// IE
+		newHeight = document.body.offsetHeight - editor._toolbar.offsetHeight;
+		if (newHeight < 0) { newHeight = 0; }
+	} else {
+		// Gecko
+		newHeight = window.innerHeight - editor._toolbar.offsetHeight;
+	}
+	if (editor.config.statusBar) {
+		newHeight -= editor._statusBar.offsetHeight;
+	}
+	editor._textArea.style.height = editor._iframe.style.height = newHeight + "px";
+}
+
+/* ---------------------------------------------------------------------- *\
+   Function    : init
+   Description : run this code on page load
+\* ---------------------------------------------------------------------- */
+
+function init() {
+	parent_object	   = opener.HTMLArea._object;
+	var config	   = HTMLArea.cloneObject( parent_object.config );
+	config.width	   = "100%";
+	config.height	   = "auto";
+
+	// change maximize button to minimize button
+	config.btnList["popupeditor"] = [ 'Minimize Editor', _editor_url + 'images/fullscreen_minimize.gif', true,
+					  function() { window.close(); } ];
+
+	// generate editor and resize it
+	editor = new HTMLArea("editor", config);
+
+	// register the plugins, if any
+	for (var i in parent_object.plugins) {
+		var plugin = parent_object.plugins[i];
+		editor.registerPlugin2(plugin.name, plugin.args);
+	}
+	// and restore the original toolbar
+        config.toolbar = parent_object.config.toolbar;
+	editor.generate();
+	editor._iframe.style.width = "100%";
+	editor._textArea.style.width = "100%";
+	resize_editor();
+
+	editor.doctype = parent_object.doctype;
+
+	// set child window contents and event handlers, after a small delay
+	setTimeout(function() {
+			   editor.setHTML(parent_object.getInnerHTML());
+
+			   // switch mode if needed
+			   if (parent_object._mode == "textmode") { editor.setMode("textmode"); }
+
+			   // continuously update parent editor window
+			   setInterval(update_parent, 500);
+
+			   // setup event handlers
+			   document.body.onkeypress = _CloseOnEsc;
+			   editor._doc.body.onkeypress = _CloseOnEsc;
+			   editor._textArea.onkeypress = _CloseOnEsc;
+			   window.onresize = resize_editor;
+		   }, 333);			 // give it some time to meet the new frame
+}
+
+/* ---------------------------------------------------------------------- *\
+   Function    : update_parent
+   Description : update parent window editor field with contents from child window
+   \* ---------------------------------------------------------------------- */
+
+function update_parent() {
+	// use the fast version
+	parent_object.setHTML(editor.getInnerHTML());
+}
+
+    </script>
+    <style type="text/css"> html, body { height: 100%; margin: 0px; border: 0px; background-color: buttonface; } </style>
+  </head>
+  <body scroll="no" onload="setTimeout(function(){init();}, 500)" onunload="update_parent()">
+    <form style="margin: 0px; border: 1px solid; border-color: threedshadow threedhighlight threedhighlight threedshadow;">
+      <textarea name="editor" id="editor" style="width:100%; height:300px">&nbsp;</textarea>
+    </form>
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/old_insert_image.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/old_insert_image.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/old_insert_image.html	(revision 795)
@@ -0,0 +1,206 @@
+<!-- based on insimage.dlg -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML 3.2//EN">
+<HTML  id=dlgImage STYLE="width: 432px; height: 194px; ">
+<HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta http-equiv="MSThemeCompatible" content="Yes">
+<TITLE>Insert Image</TITLE>
+<style>
+  html, body, button, div, input, select, fieldset { font-family: MS Shell Dlg; font-size: 8pt; position: absolute; };
+</style>
+<SCRIPT defer>
+
+function _CloseOnEsc() {
+  if (event.keyCode == 27) { window.close(); return; }
+}
+
+function _getTextRange(elm) {
+  var r = elm.parentTextEdit.createTextRange();
+  r.moveToElementText(elm);
+  return r;
+}
+
+window.onerror = HandleError
+
+function HandleError(message, url, line) {
+  var str = "An error has occurred in this dialog." + "\n\n"
+  + "Error: " + line + "\n" + message;
+  alert(str);
+  window.close();
+  return true;
+}
+
+function Init() {
+  var elmSelectedImage;
+  var htmlSelectionControl = "Control";
+  var globalDoc = window.dialogArguments;
+  var grngMaster = globalDoc.selection.createRange();
+  
+  // event handlers  
+  document.body.onkeypress = _CloseOnEsc;
+  btnOK.onclick = new Function("btnOKClick()");
+
+  txtFileName.fImageLoaded = false;
+  txtFileName.intImageWidth = 0;
+  txtFileName.intImageHeight = 0;
+
+  if (globalDoc.selection.type == htmlSelectionControl) {
+    if (grngMaster.length == 1) {
+      elmSelectedImage = grngMaster.item(0);
+      if (elmSelectedImage.tagName == "IMG") {
+        txtFileName.fImageLoaded = true;
+        if (elmSelectedImage.src) {
+          txtFileName.value          = elmSelectedImage.src.replace(/^[^*]*(\*\*\*)/, "$1");  // fix placeholder src values that editor converted to abs paths
+          txtFileName.intImageHeight = elmSelectedImage.height;
+          txtFileName.intImageWidth  = elmSelectedImage.width;
+          txtVertical.value          = elmSelectedImage.vspace;
+          txtHorizontal.value        = elmSelectedImage.hspace;
+          txtBorder.value            = elmSelectedImage.border;
+          txtAltText.value           = elmSelectedImage.alt;
+          selAlignment.value         = elmSelectedImage.align;
+        }
+      }
+    }
+  }
+  txtFileName.value = txtFileName.value || "http://";
+  txtFileName.focus();
+}
+
+function _isValidNumber(txtBox) {
+  var val = parseInt(txtBox);
+  if (isNaN(val) || val < 0 || val > 999) { return false; }
+  return true;
+}
+
+function btnOKClick() {
+  var elmImage;
+  var intAlignment;
+  var htmlSelectionControl = "Control";
+  var globalDoc = window.dialogArguments;
+  var grngMaster = globalDoc.selection.createRange();
+  
+  // error checking
+
+  if (!txtFileName.value || txtFileName.value == "http://") { 
+    alert("Image URL must be specified.");
+    txtFileName.focus();
+    return;
+  }
+  if (txtHorizontal.value && !_isValidNumber(txtHorizontal.value)) {
+    alert("Horizontal spacing must be a number between 0 and 999.");
+    txtHorizontal.focus();
+    return;
+  }
+  if (txtBorder.value && !_isValidNumber(txtBorder.value)) {
+    alert("Border thickness must be a number between 0 and 999.");
+    txtBorder.focus();
+    return;
+  }
+  if (txtVertical.value && !_isValidNumber(txtVertical.value)) {
+    alert("Vertical spacing must be a number between 0 and 999.");
+    txtVertical.focus();
+    return;
+  }
+
+  // delete selected content and replace with image
+  if (globalDoc.selection.type == htmlSelectionControl && !txtFileName.fImageLoaded) {
+    grngMaster.execCommand('Delete');
+    grngMaster = globalDoc.selection.createRange();
+  }
+    
+  idstr = "\" id=\"556e697175657e537472696e67";     // new image creation ID
+  if (!txtFileName.fImageLoaded) {
+    grngMaster.execCommand("InsertImage", false, idstr);
+    elmImage = globalDoc.all['556e697175657e537472696e67'];
+    elmImage.removeAttribute("id");
+    elmImage.removeAttribute("src");
+    grngMaster.moveStart("character", -1);
+  } else {
+    elmImage = grngMaster.item(0);
+    if (elmImage.src != txtFileName.value) {
+      grngMaster.execCommand('Delete');
+      grngMaster = globalDoc.selection.createRange();
+      grngMaster.execCommand("InsertImage", false, idstr);
+      elmImage = globalDoc.all['556e697175657e537472696e67'];
+      elmImage.removeAttribute("id");
+      elmImage.removeAttribute("src");
+      grngMaster.moveStart("character", -1);
+      txtFileName.fImageLoaded = false;
+    }
+    grngMaster = _getTextRange(elmImage);
+  }
+
+  if (txtFileName.fImageLoaded) {
+    elmImage.style.width = txtFileName.intImageWidth;
+    elmImage.style.height = txtFileName.intImageHeight;
+  }
+
+  if (txtFileName.value.length > 2040) {
+    txtFileName.value = txtFileName.value.substring(0,2040);
+  }
+  
+  elmImage.src = txtFileName.value;
+  
+  if (txtHorizontal.value != "") { elmImage.hspace = parseInt(txtHorizontal.value); }
+  else                           { elmImage.hspace = 0; }
+
+  if (txtVertical.value != "") { elmImage.vspace = parseInt(txtVertical.value); }
+  else                         { elmImage.vspace = 0; }
+  
+  elmImage.alt = txtAltText.value;
+
+  if (txtBorder.value != "") { elmImage.border = parseInt(txtBorder.value); }
+  else                       { elmImage.border = 0; }
+
+  elmImage.align = selAlignment.value;
+  grngMaster.collapse(false);
+  grngMaster.select();
+  window.close();
+}
+</SCRIPT>
+</HEAD>
+<BODY id=bdy onload="Init()" style="background: threedface; color: windowtext;" scroll=no>
+
+<DIV id=divFileName style="left: 0.98em; top: 1.2168em; width: 7em; height: 1.2168em; ">Image URL:</DIV>
+<INPUT ID=txtFileName type=text style="left: 8.54em; top: 1.0647em; width: 21.5em;height: 2.1294em; " tabIndex=10 onfocus="select()">
+
+<DIV id=divAltText style="left: 0.98em; top: 4.1067em; width: 6.58em; height: 1.2168em; ">Alternate Text:</DIV>
+<INPUT type=text ID=txtAltText tabIndex=15 style="left: 8.54em; top: 3.8025em; width: 21.5em; height: 2.1294em; " onfocus="select()">
+
+<FIELDSET id=fldLayout style="left: .9em; top: 7.1em; width: 17.08em; height: 7.6em;">
+<LEGEND id=lgdLayout>Layout</LEGEND>
+</FIELDSET>
+
+<FIELDSET id=fldSpacing style="left: 18.9em; top: 7.1em; width: 11em; height: 7.6em;">
+<LEGEND id=lgdSpacing>Spacing</LEGEND>
+</FIELDSET>
+
+<DIV id=divAlign style="left: 1.82em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Alignment:</DIV>
+<SELECT size=1 ID=selAlignment tabIndex=20 style="left: 10.36em; top: 8.8218em; width: 6.72em; height: 1.2168em; ">
+<OPTION id=optNotSet value=""> Not set </OPTION>
+<OPTION id=optLeft value=left> Left </OPTION>
+<OPTION id=optRight value=right> Right </OPTION>
+<OPTION id=optTexttop value=textTop> Texttop </OPTION>
+<OPTION id=optAbsMiddle value=absMiddle> Absmiddle </OPTION>
+<OPTION id=optBaseline value=baseline SELECTED> Baseline </OPTION>
+<OPTION id=optAbsBottom value=absBottom> Absbottom </OPTION>
+<OPTION id=optBottom value=bottom> Bottom </OPTION>
+<OPTION id=optMiddle value=middle> Middle </OPTION>
+<OPTION id=optTop value=top> Top </OPTION>
+</SELECT>
+
+<DIV id=divHoriz style="left: 19.88em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Horizontal:</DIV>
+<INPUT ID=txtHorizontal style="left: 24.92em; top: 8.8218em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=25 onfocus="select()">
+
+<DIV id=divBorder style="left: 1.82em; top: 12.0159em; width: 8.12em; height: 1.2168em; ">Border Thickness:</DIV>
+<INPUT ID=txtBorder style="left: 10.36em; top: 11.5596em; width: 6.72em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=21 onfocus="select()">
+
+<DIV id=divVert style="left: 19.88em; top: 12.0159em; width: 3.64em; height: 1.2168em; ">Vertical:</DIV>
+<INPUT ID=txtVertical style="left: 24.92em; top: 11.5596em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=30 onfocus="select()">
+
+<BUTTON ID=btnOK style="left: 31.36em; top: 1.0647em; width: 7em; height: 2.2em; " type=submit tabIndex=40>OK</BUTTON>
+<BUTTON ID=btnCancel style="left: 31.36em; top: 3.6504em; width: 7em; height: 2.2em; " type=reset tabIndex=45 onClick="window.close();">Cancel</BUTTON>
+
+</BODY>
+</HTML>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/insert_image.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/insert_image.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/insert_image.html	(revision 795)
@@ -0,0 +1,191 @@
+<html>
+
+<head>
+  <title>Insert Image</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+window.resizeTo(400, 100);
+
+function Init() {
+  __dlg_init();
+  var param = window.dialogArguments;
+  if (param) {
+      document.getElementById("f_url").value = param["f_url"];
+      document.getElementById("f_alt").value = param["f_alt"];
+      document.getElementById("f_border").value = param["f_border"];
+      document.getElementById("f_align").value = param["f_align"];
+      document.getElementById("f_vert").value = param["f_vert"];
+      document.getElementById("f_horiz").value = param["f_horiz"];
+      window.ipreview.location.replace(param.f_url);
+  }
+  document.getElementById("f_url").focus();
+};
+
+function onOK() {
+  var required = {
+    "f_url": "You must enter the URL"
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+  // pass data back to the calling window
+  var fields = ["f_url", "f_alt", "f_align", "f_border",
+                "f_horiz", "f_vert"];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = document.getElementById(id);
+    param[id] = el.value;
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+function onPreview() {
+  var f_url = document.getElementById("f_url");
+  var url = f_url.value;
+  if (!url) {
+    alert("You have to enter an URL first");
+    f_url.focus();
+    return false;
+  }
+  window.ipreview.location.replace(url);
+  return false;
+};
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 6em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Image</div>
+<!--- new stuff --->
+<form action="" method="get">
+<table border="0" width="100%" style="padding: 0px; margin: 0px">
+  <tbody>
+
+  <tr>
+    <td style="width: 7em; text-align: right">Image URL:</td>
+    <td><input type="text" name="url" id="f_url" style="width:75%"
+      title="Enter the image URL here" />
+      <button name="preview" onclick="return onPreview();"
+      title="Preview the image in a new window">Preview</button>
+    </td>
+  </tr>
+  <tr>
+    <td style="width: 7em; text-align: right">Alternate text:</td>
+    <td><input type="text" name="alt" id="f_alt" style="width:100%"
+      title="For browsers that don't support images" /></td>
+  </tr>
+
+  </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+  title="Positioning of this image">
+  <option value=""                             >Not set</option>
+  <option value="left"                         >Left</option>
+  <option value="right"                        >Right</option>
+  <option value="texttop"                      >Texttop</option>
+  <option value="absmiddle"                    >Absmiddle</option>
+  <option value="baseline" selected="1"        >Baseline</option>
+  <option value="absbottom"                    >Absbottom</option>
+  <option value="bottom"                       >Bottom</option>
+  <option value="middle"                       >Middle</option>
+  <option value="top"                          >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5"
+title="Leave empty for no border" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Horizontal:</div>
+<input type="text" name="horiz" id="f_horiz" size="5"
+title="Horizontal padding" />
+
+<p />
+
+<div class="fr">Vertical:</div>
+<input type="text" name="vert" id="f_vert" size="5"
+title="Vertical padding" />
+
+<div class="space"></div>
+
+</fieldset>
+<br clear="all" />
+<table width="100%" style="margin-bottom: 0.2em">
+ <tr>
+  <td valign="bottom">
+    Image Preview:<br />
+    <iframe name="ipreview" id="ipreview" frameborder="0" style="border : 1px solid gray;" height="200" width="300" src=""></iframe>
+  </td>
+  <td valign="bottom" style="text-align: right">
+    <button type="button" name="ok" onclick="return onOK();">OK</button><br>
+    <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+  </td>
+ </tr>
+</table>
+</form>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/blank.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/blank.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/blank.html	(revision 795)
@@ -0,0 +1,2 @@
+<html>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/about.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/about.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/about.html	(revision 795)
@@ -0,0 +1,392 @@
+<!--
+
+(c) dynarch.com, 2003-2004
+Author: Mihai Bazon, http://dynarch.com/mishoo
+Distributed as part of HTMLArea 3.0
+
+"You are not expected to understand this...  I don't neither."
+
+                      (from The Linux Kernel Source Code,
+                            ./arch/x86_64/ia32/ptrace.c:90)
+
+;-)
+
+-->
+
+<html style="height: 100%">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>About HTMLArea</title>
+<script type="text/javascript" src="popup.js"></script>
+<script type="text/javascript">
+window.resizeTo(450, 250);
+var TABS = [];
+var CURRENT_TAB = 0;
+var CONTENT_HEIGHT_DIFF = 0;
+var CONTENT_WIDTH_DIFF = 0;
+function selectTab(idx) {
+  var ct = TABS[CURRENT_TAB];
+  ct.className = ct.className.replace(/\s*tab-current\s*/, ' ');
+  ct = TABS[CURRENT_TAB = idx];
+  ct.className += ' tab-current';
+  for (var i = TABS.length; --i >= 0;) {
+    var area = document.getElementById("tab-area-" + i);
+    if (CURRENT_TAB == i) {
+      area.style.display = "block";
+    } else {
+      area.style.display = "none";
+    }
+  }
+  document.body.style.visibility = "hidden";
+  document.body.style.visibility = "visible";
+  document.cookie = "HTMLAREA-ABOUT-TAB=" + idx;
+}
+var editor = null;
+function initDocument() {
+  editor = window.dialogArguments;
+  HTMLArea = window.opener.HTMLArea;
+
+  var plugins = document.getElementById("plugins");
+  var j = 0;
+  var html = "<table width='99%' cellpadding='0' style='margin-top: 1em; collapse-borders: collapse; border: 1px solid #8b8;'>" +
+	  "<thead><tr>" +
+	  "<td>Name</td>" +
+	  "<td>Developer</td>" +
+	  "<td>Sponsored by</td>" +
+	  "<td>License<sup>*</sup></td>" +
+	  "</tr></thead><tbody>";
+  for (var i in editor.plugins) {
+    var info = editor.plugins[i];
+    html += "<tr><td>" + info.name + " v" + info.version + "</td>" + 
+            "<td><a href='" + info.developer_url + "' target='_blank' title='Visit developer website'>" +
+	    info.developer + "</a></td>" +
+	    "<td><a href='" + info.sponsor_url + "' target='_blank' title='Visit sponsor website'>" +
+	    info.sponsor + "</a></td>" +
+	    "<td>" + info.license + "</td></tr>";
+    ++j;
+  }
+
+  if (j) {
+          html += "</tbody></table>" +
+		  "<p><sup>*</sup> License \"htmlArea\" means that the plugin is distributed under the same terms " +
+		  "as HTMLArea itself.  Such plugins are likely to be those included in the official " +
+		  "HTMLArea distribution</p>";
+	  plugins.innerHTML = "<p>The following plugins have been loaded.</p>" + html;
+  } else {
+	  plugins.innerHTML = "<p>No plugins have been loaded</p>";
+  }
+
+  plugins.innerHTML += "<p>User agent reports:<br/>" + navigator.userAgent + "</p>";
+
+  var content = document.getElementById("content");
+  if (window.innerHeight) {
+    CONTENT_HEIGHT_DIFF = window.innerHeight - 250;
+    CONTENT_WIDTH_DIFF = window.innerWidth - content.offsetWidth;
+  } else {
+    CONTENT_HEIGHT_DIFF = document.body.offsetHeight - 250;
+    CONTENT_WIDTH_DIFF = document.body.offsetWidth - 400;
+  }
+  window.onresize();
+  var bar = document.getElementById("tabbar");
+  j = 0;
+  for (var i = bar.firstChild; i; i = i.nextSibling) {
+    TABS.push(i);
+    i.__msh_tab = j;
+    i.onmousedown = function(ev) { selectTab(this.__msh_tab); HTMLArea._stopEvent(ev || window.event); };
+    var area = document.getElementById("tab-area-" + j);
+    if (/tab-current/.test(i.className)) {
+      CURRENT_TAB = j;
+      area.style.display = "block";
+    } else {
+      area.style.display = "none";
+    }
+    ++j;
+  }
+  if (document.cookie.match(/HTMLAREA-ABOUT-TAB=([0-9]+)/))
+    selectTab(RegExp.$1);
+}
+window.onresize = function() {
+  var content = document.getElementById("content");
+  if (window.innerHeight) {
+    content.style.height = (window.innerHeight - CONTENT_HEIGHT_DIFF) + "px";
+    content.style.width = (window.innerWidth - CONTENT_WIDTH_DIFF) + "px";
+  } else {
+    content.style.height = (document.body.offsetHeight - CONTENT_HEIGHT_DIFF) + "px";
+    //content.style.width = (document.body.offsetWidth - CONTENT_WIDTH_DIFF) + "px";
+  }
+}
+</script>
+<style>
+  html,body,textarea,table { font-family: tahoma,verdana,arial; font-size: 11px;
+padding: 0px; margin: 0px; }
+  tt { font-size: 120%; }
+  body { padding: 0px; background: #cea; color: 000; }
+  a:link, a:visited { color: #00f; }
+  a:hover { color: #f00; }
+  a:active { color: #f80; }
+  button { font: 11px tahoma,verdana,sans-serif; background-color: #cea;
+      border-width: 1px; }
+
+  p { margin: 0.5em 0px; }
+
+  h1 { font: bold 130% georgia,"times new roman",serif; margin: 0px; border-bottom: 1px solid #6a6; }
+  h2 { font: bold 110% georgia,"times new roman",serif; margin: 0.7em 0px; }
+
+  thead {
+    font-weight: bold;
+    background-color: #dfb;
+  }
+
+  .logo, .logo-hover {
+    white-space: nowrap;
+    background-color: #8f4; color: #040; padding: 3px; border-bottom: 1px solid #555;
+    height: 5em;
+  }
+  .logo .brand, .logo-hover .brand {
+    margin-left: 0.5em; margin-right: 0.5em; padding-bottom: 0.1em;
+    font-family: impact,'arial black',arial,sans-serif; font-size: 28px;
+    border-bottom: 1px solid #595; text-align: center;
+    cursor: pointer;
+  }
+  .logo-hover {
+    background-color: #fff;
+  }
+  .logo-hover .brand {
+    color: #800;
+    border-color: #04f;
+  }
+  .logo .letter, .logo-hover .letter { position: relative; font-family: monospace; }
+  .logo .letter1 { top: 0.1em; }
+  .logo .letter2 { top: 0.05em; }
+  .logo .letter3 { top: -0.05em; }
+  .logo .letter4 { top: -0.1em; }
+
+  .logo-hover .letter1 { top: -0.1em; }
+  .logo-hover .letter2 { top: -0.05em; }
+  .logo-hover .letter3 { top: 0.05em; }
+  .logo-hover .letter4 { top: 0.1em; }
+  .logo .version, .logo-hover .version { font-family: georgia,"times new roman",serif; }
+  .logo .release {
+    font-size: 90%; margin-bottom: 1em;
+    text-align: center; color: #484;
+  }
+  .logo .visit { display: none; }
+  .logo-hover .release { display: none; }
+  .logo-hover .visit {
+    font-size: 90%; margin-bottom: 1em;
+    text-align: center; color: #448;
+  }
+  .buttons {
+    text-align: right; padding: 3px; background-color: #8f4;
+    border-top: 1px solid #555;
+  }
+  #tabbar {
+    position: relative;
+    left: 10px;
+  }
+  .tab {
+    color: #454;
+    cursor: pointer;
+    margin-left: -5px;
+    float: left; position: relative;
+    border: 1px solid #555;
+    top: -3px; left: -2px;
+    padding: 2px 10px 3px 10px;
+    border-top: none; background-color: #9b7;
+    -moz-border-radius: 0px 0px 4px 4px;
+    z-index: 0;
+  }
+  .tab-current {
+    color: #000;
+    top: -4px;
+    background-color: #cea;
+    padding: 3px 10px 4px 10px;
+    z-index: 10;
+  }
+  table.sponsors { border-top: 1px solid #aca; }
+  table.sponsors td {
+    border-bottom: 1px solid #aca; vertical-align: top;
+  }
+  table.sponsors tr td { padding: 2px 0px; }
+  table.sponsors tr td.sponsor { text-align: right; padding-right: 0.3em; white-space: nowrap; }
+  li, ol, ul { margin-top: 0px; margin-bottom: 0px; }
+</style></head>
+<body onload="__dlg_init(); initDocument();"
+><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;
+      width: 100%; height: 100%;">
+
+<tr style="height: 1em"><td id="tdheader">
+
+<div class="logo">
+<div class="brand"
+onmouseover="this.parentNode.className='logo-hover';"
+onmouseout="this.parentNode.className='logo';"
+onclick="window.open('http://dynarch.com/htmlarea/');">
+<span class="letter letter1">&lt;H</span><span
+class="letter letter2">T</span><span
+class="letter letter3">M</span><span
+class="letter letter4">L</span>Area <span class="letter">/&gt;</span>
+<span class="version"><% $version.$release %></span></div>
+<div class="release">Compiled on <% $time %></div>
+<div class="visit">Go to http://dynarch.com/htmlarea/ [latest milestone release]</div>
+</div>
+
+</td></tr>
+<tr><td id="tdcontent" style="padding: 0.5em;">
+
+<div style="overflow: auto; height: 250px;" id="content">
+<div id="tab-areas">
+
+<div id="tab-area-0">
+
+  <h1>HTMLArea</h1>
+  
+  <p>A free WYSIWYG editor replacement for <tt>&lt;textarea&gt;</tt> fields.<br />
+  For Mozilla 1.3+ (any platform) or Internet Explorer 5.5+ (Windows).
+  </p>
+
+  <p style="text-align: center"
+  >&copy; 2002-2004 <a href="http://interactivetools.com" target="_blank">interactivetools.com</a>, inc.<br />
+  &copy; 2003-2004 <a href="http://dynarch.com" target="_blank">dynarch.com</a> LLC.<br />
+  All Rights Reserved.</p>
+
+  <h2>Project resources</h2>
+
+  <ul>
+  <li><a href="http://sourceforge.net/projects/itools-htmlarea/" target="_blank"
+  >Project page</a> (@ sourceforge.net)</li>
+  <li><a href="http://sourceforge.net/cvs/?group_id=69750" target="_blank"
+  >Anonymous CVS access</a> (@ sourceforge.net)</li>
+  <li><a href="http://sourceforge.net/tracker/?atid=525656&group_id=69750&func=browse" target="_blank"
+  >Bug system</a> (@ sourceforge.net)</li>
+  <li><a href="http://www.interactivetools.com/forum/gforum.cgi?forum=14;" target="_blank"
+  >Forum</a> (@ interactivetools.com)</li>
+  <li><a href="http://www.dynarch.com/htmlarea/" target="_blank"
+  >Last public release</a> (@ dynarch.com)</li>
+  </ul>
+
+  <p>
+  For download section please see the <a href="http://sourceforge.net/projects/itools-htmlarea/" target="_blank"
+  >project page @ SourceForge</a>.
+  </p>
+
+<p style="margin-top: 1em; text-align: center;">Version 3.0 developed and maintained by <a
+href="http://dynarch.com/mishoo/" title="http://dynarch.com/mishoo/" target="_blank">Mihai Bazon</a> / <a
+href="http://dynarch.com" title="http://dynarch.com/" target="_blank">dynarch.com</a></p>
+
+</div>
+
+<div id="tab-area-1">
+<h1>Thank you</h1>
+
+  <p>
+  <a href="http://dynarch.com" target="_blank">dynarch.com</a> would like to thank the following
+  companies/persons for their <em>donations</em> to support development of HTMLArea (listed alphabetically):
+  </p>
+
+  <ul>
+    <li><a href="http://www.computerlove.co.uk" target="_blank">Code Computer Love Ltd.</a> (UK)</li>
+    <li><a href="http://www.neomedia.ro" target="_blank">Neomedia</a> (Romania)</li>
+    <li><a href="http://www.os3.it" target="_blank">OS3</a> (Italy)</li>
+    <li><a href="http://www.softwerk.net" target="_blank">SoftWerk</a> (Italy)</li>
+  </ul>
+
+  <p>Also many thanks to all people at InteractiveTools.com
+  <a href="http://www.interactivetools.com/forum/gforum.cgi?forum=14;">HTMLArea forums</a> for
+  contributing translations, feedback, bug reports and fixes.</p>
+
+  <p>
+  Last but not least, this project wouldn't have existed without
+  <a href="http://interactivetools.com" target="_blank">InteractiveTools.com</a>.
+  </p>
+
+</div>
+
+<div id="tab-area-2">
+<h1>htmlArea License (based on BSD license)</h1>
+
+<p style="text-align: center">Â© 2002-2004, interactivetools.com, inc.<br />
+  Â© 2003-2004 dynarch.com LLC<br />
+  All rights reserved.</p>
+
+<p>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+</p>
+
+<ol>
+<li>
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+</li>
+
+<li>
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+</li>
+
+<li>
+Neither the name of interactivetools.com, inc. nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+</li>
+</ol>
+
+<p>
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+</p>
+
+</div>
+
+<div id="tab-area-3">
+<h1>Plugins</h1>
+<div id="plugins">
+</div>
+</div>
+
+</div></div>
+
+
+</tr></td>
+<tr style="height: 1em"><td id="tdfooter">
+
+
+<div class="buttons">
+<div id="tabbar"
+><div class="tab tab-current"
+>About</div><div class="tab"
+>Thanks</div><div class="tab"
+>License</div><div class="tab"
+>Plugins</div></div>
+<button type="button" onclick="__dlg_close(null);">I agree it's cool</button>
+</div>
+
+</td></tr></table>
+
+</body></html>
+
+<%ARGS>
+  $version => '3.0'
+  $release => 'beta+'
+  $basename => 'HTMLArea-3.0-beta'
+</%ARGS>
+
+<%INIT>;
+if ($release =~ /\S/) {
+    $release = ' <span style="position: relative; top: -0.6em; font-size: 50%; font-weight: normal">[ rev. '.$release.' ]</span>';
+}
+
+use POSIX qw(strftime);
+my $time = strftime '%b %e, %Y %H:%M GMT', gmtime;
+</%INIT>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/insert_table.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/insert_table.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/insert_table.html	(revision 795)
@@ -0,0 +1,174 @@
+<html>
+
+<head>
+  <title>Insert Table</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+window.resizeTo(400, 100);
+
+function Init() {
+  __dlg_init();
+  document.getElementById("f_rows").focus();
+};
+
+function onOK() {
+  var required = {
+    "f_rows": "You must enter a number of rows",
+    "f_cols": "You must enter a number of columns"
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+  var fields = ["f_rows", "f_cols", "f_width", "f_unit",
+                "f_align", "f_border", "f_spacing", "f_padding"];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = document.getElementById(id);
+    param[id] = el.value;
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 7em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Table</div>
+
+<form action="" method="get">
+<table border="0" style="padding: 0px; margin: 0px">
+  <tbody>
+
+  <tr>
+    <td style="width: 4em; text-align: right">Rows:</td>
+    <td><input type="text" name="rows" id="f_rows" size="5" title="Number of rows" value="2" /></td>
+    <td></td>
+    <td></td>
+    <td></td>
+  </tr>
+  <tr>
+    <td style="width: 4em; text-align: right">Cols:</td>
+    <td><input type="text" name="cols" id="f_cols" size="5" title="Number of columns" value="4" /></td>
+    <td style="width: 4em; text-align: right">Width:</td>
+    <td><input type="text" name="width" id="f_width" size="5" title="Width of the table" value="100" /></td>
+    <td><select size="1" name="unit" id="f_unit" title="Width unit">
+      <option value="%" selected="1"  >Percent</option>
+      <option value="px"              >Pixels</option>
+      <option value="em"              >Em</option>
+    </select></td>
+  </tr>
+
+  </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+  title="Positioning of this image">
+  <option value="" selected="1"                >Not set</option>
+  <option value="left"                         >Left</option>
+  <option value="right"                        >Right</option>
+  <option value="texttop"                      >Texttop</option>
+  <option value="absmiddle"                    >Absmiddle</option>
+  <option value="baseline"                     >Baseline</option>
+  <option value="absbottom"                    >Absbottom</option>
+  <option value="bottom"                       >Bottom</option>
+  <option value="middle"                       >Middle</option>
+  <option value="top"                          >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5" value="1"
+title="Leave empty for no border" />
+<!--
+<p />
+
+<div class="fl">Collapse borders:</div>
+<input type="checkbox" name="collapse" id="f_collapse" />
+-->
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Cell spacing:</div>
+<input type="text" name="spacing" id="f_spacing" size="5" value="1"
+title="Space between adjacent cells" />
+
+<p />
+
+<div class="fr">Cell padding:</div>
+<input type="text" name="padding" id="f_padding" size="5" value="1"
+title="Space between content and border in cell" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; border-top: 1px solid #999; padding: 2px; text-align: right;">
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/popups/popup.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popups/popup.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popups/popup.js	(revision 795)
@@ -0,0 +1,108 @@
+// htmlArea v3.0 - Copyright (c) 2002, 2003 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+
+function getAbsolutePos(el) {
+	var r = { x: el.offsetLeft, y: el.offsetTop };
+	if (el.offsetParent) {
+		var tmp = getAbsolutePos(el.offsetParent);
+		r.x += tmp.x;
+		r.y += tmp.y;
+	}
+	return r;
+};
+
+function comboSelectValue(c, val) {
+	var ops = c.getElementsByTagName("option");
+	for (var i = ops.length; --i >= 0;) {
+		var op = ops[i];
+		op.selected = (op.value == val);
+	}
+	c.value = val;
+};
+
+function __dlg_onclose() {
+	opener.Dialog._return(null);
+};
+
+function __dlg_init(bottom) {
+	var body = document.body;
+	var body_height = 0;
+	if (typeof bottom == "undefined") {
+		var div = document.createElement("div");
+		body.appendChild(div);
+		var pos = getAbsolutePos(div);
+		body_height = pos.y;
+	} else {
+		var pos = getAbsolutePos(bottom);
+		body_height = pos.y + bottom.offsetHeight;
+	}
+	window.dialogArguments = opener.Dialog._arguments;
+	if (!document.all) {
+		window.sizeToContent();
+		window.sizeToContent();	// for reasons beyond understanding,
+					// only if we call it twice we get the
+					// correct size.
+		window.addEventListener("unload", __dlg_onclose, true);
+		// center on parent
+		var x = opener.screenX + (opener.outerWidth - window.outerWidth) / 2;
+		var y = opener.screenY + (opener.outerHeight - window.outerHeight) / 2;
+		window.moveTo(x, y);
+		window.innerWidth = body.offsetWidth + 5;
+		window.innerHeight = body_height + 2;
+	} else {
+		// window.dialogHeight = body.offsetHeight + 50 + "px";
+		// window.dialogWidth = body.offsetWidth + "px";
+		window.resizeTo(body.offsetWidth, body_height);
+		var ch = body.clientHeight;
+		var cw = body.clientWidth;
+		window.resizeBy(body.offsetWidth - cw, body_height - ch);
+		var W = body.offsetWidth;
+		var H = 2 * body_height - ch;
+		var x = (screen.availWidth - W) / 2;
+		var y = (screen.availHeight - H) / 2;
+		window.moveTo(x, y);
+	}
+	document.body.onkeypress = __dlg_close_on_esc;
+};
+
+function __dlg_translate(i18n) {
+	var types = ["span", "option", "td", "button", "div"];
+	for (var type in types) {
+		var spans = document.getElementsByTagName(types[type]);
+		for (var i = spans.length; --i >= 0;) {
+			var span = spans[i];
+			if (span.firstChild && span.firstChild.data) {
+				var txt = i18n[span.firstChild.data];
+				if (txt)
+					span.firstChild.data = txt;
+			}
+		}
+	}
+	var txt = i18n[document.title];
+	if (txt)
+		document.title = txt;
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+	opener.Dialog._return(val);
+	window.close();
+};
+
+function __dlg_close_on_esc(ev) {
+	ev || (ev = window.event);
+	if (ev.keyCode == 27) {
+		window.close();
+		return false;
+	}
+	return true;
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/popupwin.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/popupwin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/popupwin.js	(revision 795)
@@ -0,0 +1,139 @@
+// (c) dynarch.com 2003-2004
+// Distributed under the same terms as HTMLArea itself.
+
+function PopupWin(editor, title, handler, initFunction) {
+	this.editor = editor;
+	this.handler = handler;
+	var dlg = window.open("", "__ha_dialog",
+			      "toolbar=no,menubar=no,personalbar=no,width=600,height=600,left=20,top=40" +
+			      "scrollbars=no,resizable=no");
+	this.window = dlg;
+	var doc = dlg.document;
+	this.doc = doc;
+	var self = this;
+
+	var base = document.baseURI || document.URL;
+	if (base && base.match(/(.*)\/([^\/]+)/)) {
+		base = RegExp.$1 + "/";
+	}
+	if (typeof _editor_url != "undefined" && !/^\//.test(_editor_url)) {
+		// _editor_url doesn't start with '/' which means it's relative
+		// FIXME: there's a problem here, it could be http:// which
+		// doesn't start with slash but it's not relative either.
+		base += _editor_url;
+	} else
+		base = _editor_url;
+	if (!/\/$/.test(base)) {
+		// base does not end in slash, add it now
+		base += '/';
+	}
+	this.baseURL = base;
+
+	doc.open();
+	var html = "<html><head><title>" + title + "</title>\n";
+	// html += "<base href='" + base + "htmlarea.js' />\n";
+	html += "<style type='text/css'>@import url(" + base + "htmlarea.css);</style></head>\n";
+	html += "<body class='dialog popupwin' id='--HA-body'></body></html>";
+	doc.write(html);
+	doc.close();
+
+	// sometimes I Hate Mozilla... ;-(
+	function init2() {
+		var body = doc.body;
+		if (!body) {
+			setTimeout(init2, 25);
+			return false;
+		}
+		dlg.title = title;
+		doc.documentElement.style.padding = "0px";
+		doc.documentElement.style.margin = "0px";
+		var content = doc.createElement("div");
+		content.className = "content";
+		self.content = content;
+		body.appendChild(content);
+		self.element = body;
+		initFunction(self);
+		dlg.focus();
+	};
+	init2();
+};
+
+PopupWin.prototype.callHandler = function() {
+	var tags = ["input", "textarea", "select"];
+	var params = new Object();
+	for (var ti in tags) {
+		var tag = tags[ti];
+		var els = this.content.getElementsByTagName(tag);
+		for (var j = 0; j < els.length; ++j) {
+			var el = els[j];
+			var val = el.value;
+			if (el.tagName.toLowerCase() == "input") {
+				if (el.type == "checkbox") {
+					val = el.checked;
+				}
+			}
+			params[el.name] = val;
+		}
+	}
+	this.handler(this, params);
+	return false;
+};
+
+PopupWin.prototype.close = function() {
+	this.window.close();
+};
+
+PopupWin.prototype.addButtons = function() {
+	var self = this;
+	var div = this.doc.createElement("div");
+	this.content.appendChild(div);
+	div.className = "buttons";
+	for (var i = 0; i < arguments.length; ++i) {
+		var btn = arguments[i];
+		var button = this.doc.createElement("button");
+		div.appendChild(button);
+		button.innerHTML = HTMLArea.I18N.buttons[btn];
+		switch (btn) {
+		    case "ok":
+			button.onclick = function() {
+				self.callHandler();
+				self.close();
+				return false;
+			};
+			break;
+		    case "cancel":
+			button.onclick = function() {
+				self.close();
+				return false;
+			};
+			break;
+		}
+	}
+};
+
+PopupWin.prototype.showAtElement = function() {
+	var self = this;
+	// Mozilla needs some time to realize what's goin' on..
+	setTimeout(function() {
+		var w = self.content.offsetWidth + 4;
+		var h = self.content.offsetHeight + 4;
+		// size to content -- that's fuckin' buggy in all fuckin' browsers!!!
+		// so that we set a larger size for the dialog window and then center
+		// the element inside... phuck!
+
+		// center...
+		var el = self.content;
+		var s = el.style;
+		// s.width = el.offsetWidth + "px";
+		// s.height = el.offsetHeight + "px";
+		s.position = "absolute";
+		s.left = (w - el.offsetWidth) / 2 + "px";
+		s.top = (h - el.offsetHeight) / 2 + "px";
+		if (HTMLArea.is_gecko) {
+			self.window.innerWidth = w;
+			self.window.innerHeight = h;
+		} else {
+			self.window.resizeTo(w + 8, h + 35);
+		}
+	}, 25);
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/example.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/example.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/example.html	(revision 795)
@@ -0,0 +1,181 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<script type="text/javascript" src="htmlarea.js"></script>
+<script type="text/javascript" src="lang/en.js"></script>
+<script type="text/javascript" src="dialog.js"></script>
+
+<style type="text/css">
+@import url(htmlarea.css);
+
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+  editor = new HTMLArea("ta");
+
+  // comment the following two lines to see how customization works
+  editor.generate();
+  return false;
+
+  var cfg = editor.config; // this is the default configuration
+  cfg.registerButton({
+    id        : "my-hilite",
+    tooltip   : "Highlight text",
+    image     : "ed_custom.gif",
+    textMode  : false,
+    action    : function(editor) {
+                  editor.surroundHTML("<span class=\"hilite\">", "</span>");
+                },
+    context   : 'table'
+  });
+
+  cfg.toolbar.push(["linebreak", "my-hilite"]); // add the new button to the toolbar
+
+  // BEGIN: code that adds a custom button
+  // uncomment it to test
+  var cfg = editor.config; // this is the default configuration
+  /*
+  cfg.registerButton({
+    id        : "my-hilite",
+    tooltip   : "Highlight text",
+    image     : "ed_custom.gif",
+    textMode  : false,
+    action    : function(editor) {
+                  editor.surroundHTML("<span class=\"hilite\">", "</span>");
+                }
+  });
+  */
+
+function clickHandler(editor, buttonId) {
+  switch (buttonId) {
+    case "my-toc":
+      editor.insertHTML("<h1>Table Of Contents</h1>");
+      break;
+    case "my-date":
+      editor.insertHTML((new Date()).toString());
+      break;
+    case "my-bold":
+      editor.execCommand("bold");
+      editor.execCommand("italic");
+      break;
+    case "my-hilite":
+      editor.surroundHTML("<span class=\"hilite\">", "</span>");
+      break;
+  }
+};
+cfg.registerButton("my-toc",  "Insert TOC", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-date", "Insert date/time", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-bold", "Toggle bold/italic", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-hilite", "Hilite selection", "ed_custom.gif", false, clickHandler);
+
+cfg.registerButton("my-sample", "Class: sample", "ed_custom.gif", false,
+  function(editor) {
+    if (HTMLArea.is_ie) {
+      editor.insertHTML("<span class=\"sample\">&nbsp;&nbsp;</span>");
+      var r = editor._doc.selection.createRange();
+      r.move("character", -2);
+      r.moveEnd("character", 2);
+      r.select();
+    } else { // Gecko/W3C compliant
+      var n = editor._doc.createElement("span");
+      n.className = "sample";
+      editor.insertNodeAtSelection(n);
+      var sel = editor._iframe.contentWindow.getSelection();
+      sel.removeAllRanges();
+      var r = editor._doc.createRange();
+      r.setStart(n, 0);
+      r.setEnd(n, 0);
+      sel.addRange(r);
+    }
+  }
+);
+
+
+  /*
+  cfg.registerButton("my-hilite", "Highlight text", "ed_custom.gif", false,
+    function(editor) {
+      editor.surroundHTML('<span class="hilite">', '</span>');
+    }
+  );
+  */
+  cfg.pageStyle = "body { background-color: #efd; } .hilite { background-color: yellow; } "+
+                  ".sample { color: green; font-family: monospace; }";
+  cfg.toolbar.push(["linebreak", "my-toc", "my-date", "my-bold", "my-hilite", "my-sample"]); // add the new button to the toolbar
+  // END: code that adds a custom button
+
+  editor.generate();
+}
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003.</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="20" cols="80">
+  &lt;p&gt;Here is some sample text: &lt;b&gt;bold&lt;/b&gt;, &lt;i&gt;italic&lt;/i&gt;, &lt;u&gt;underline&lt;/u&gt;. &lt;/p&gt;
+  &lt;p align=center&gt;Different fonts, sizes and colors (all in bold):&lt;/p&gt;
+  &lt;p&gt;&lt;b&gt;
+   &lt;font face="arial"           size="7" color="#000066"&gt;arial&lt;/font&gt;,
+   &lt;font face="courier new"     size="6" color="#006600"&gt;courier new&lt;/font&gt;,
+   &lt;font face="georgia"         size="5" color="#006666"&gt;georgia&lt;/font&gt;,
+   &lt;font face="tahoma"          size="4" color="#660000"&gt;tahoma&lt;/font&gt;,
+   &lt;font face="times new roman" size="3" color="#660066"&gt;times new roman&lt;/font&gt;,
+   &lt;font face="verdana"         size="2" color="#666600"&gt;verdana&lt;/font&gt;,
+   &lt;font face="tahoma"          size="1" color="#666666"&gt;tahoma&lt;/font&gt;
+  &lt;/b&gt;&lt;/p&gt;
+  &lt;p&gt;Click on &lt;a href="http://www.interactivetools.com/"&gt;this link&lt;/a&gt; and then on the link button to the details ... OR ... select some text and click link to create a &lt;b&gt;new&lt;/b&gt; link.&lt;/p&gt;
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/license.txt
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/license.txt	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/license.txt	(revision 795)
@@ -0,0 +1,30 @@
+htmlArea License (based on BSD license)
+Copyright (c) 2002-2004, interactivetools.com, inc.
+Copyright (c) 2003-2004 dynarch.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1) Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+2) Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3) Neither the name of interactivetools.com, inc. nor the names of its
+   contributors may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
Index: /sandbox/workflow/branches/993/js/htmlarea/reference.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/reference.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/reference.html	(revision 795)
@@ -0,0 +1,523 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html> <head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>HTMLArea-3.0 Reference</title>
+
+<style type="text/css">
+  @import url(htmlarea.css);
+  body { font: 14px verdana,sans-serif; background: #fff; color: #000; }
+  h1, h2 { font-family:tahoma,sans-serif; }
+  h1 { border-bottom: 2px solid #000; }
+  h2 { border-bottom: 1px solid #aaa; }
+  h3, h4 { margin-bottom: 0px; font-family: Georgia,serif; font-style: italic; }
+  h4 { font-size: 90%; margin-left: 1em; }
+  acronym { border-bottom: 1px dotted #063; color: #063; }
+  p { margin-left: 2em; margin-top: 0.3em; }
+  li p { margin-left: 0px; }
+  .abstract { padding: 5px; margin: 0px 10em; font-size: 90%; border: 1px dashed #aaa; background: #eee;}
+  li { margin-left: 2em; }
+  em { color: #042; }
+  a { color: #00f; }
+  a:hover { color: #f00; }
+  a:active { color: #f80; }
+  span.browser { font-weight: bold; color: #864; }
+  .fixme { font-size: 20px; font-weight: bold; color: red; background: #fab;
+padding: 5px; text-align: center; }
+  .code {
+   background: #e4efff; padding: 5px; border: 1px dashed #abc; margin-left: 2em; margin-right: 2em;
+   font-family: fixed,"lucidux mono","andale mono","courier new",monospace;
+  }
+  .note, .warning { font-weight: bold; color: #0a0; font-variant: small-caps; }
+  .warning { color: #a00; }
+
+.string {
+  color: #06c;
+} /* font-lock-string-face */
+.comment {
+  color: #840;
+} /* font-lock-comment-face */
+.variable-name {
+  color: #000;
+} /* font-lock-variable-name-face */
+.type {
+  color: #008;
+  font-weight: bold;
+} /* font-lock-type-face */
+.reference {
+  color: #048;
+} /* font-lock-reference-face */
+.preprocessor {
+  color: #808;
+} /* font-lock-preprocessor-face */
+.keyword {
+  color: #00f;
+  font-weight: bold;
+} /* font-lock-keyword-face */
+.function-name {
+  color: #044;
+} /* font-lock-function-name-face */
+.html-tag {
+  font-weight: bold;
+} /* html-tag-face */
+.html-helper-italic {
+  font-style: italic;
+} /* html-helper-italic-face */
+.html-helper-bold {
+  font-weight: bold;
+} /* html-helper-bold-face */
+
+</style>
+
+<script type="text/javascript">
+  _editor_url = './';
+  _editor_lang = 'en';
+</script>
+<script type="text/javascript" src="htmlarea.js"></script>
+<script type="text/javascript" src="dialog.js"></script>
+<script tyle="text/javascript" src="lang/en.js"></script>
+
+</head>
+
+<body onload="HTMLArea.replace('TA')">
+
+
+<h1>HTMLArea-3.0 Documentation</h1>
+
+<div class="abstract" style="color: red; font-weight: bold">
+
+      This documentation contains valid information, but is outdated in the
+      terms that it does not covers all the features of HTMLArea.  A new
+      documentation project will be started, based on LaTeX.
+
+</div>
+
+
+<h2>Introduction</h2>
+
+<h3>What is HTMLArea?</h3>
+
+<p>HTMLArea is a free <acronym title="What You See Is What You Get"
+>WYSIWYG</acronym> editor replacement for <code>&lt;textarea&gt;</code>
+fields.  By adding a few simple lines of JavaScript code to your web page
+you can replace a regular textarea with a rich text editor that lets your
+users do the following:</p>
+
+<ul>
+  <li>Format text to be bold, italicized, or underlined.</li>
+  <li>Change the face, size, style and color.</li>
+  <li>Left, center, or right-justify paragraphs.</li>
+  <li>Make bulleted or numbered lists.</li>
+  <li>Indent or un-indent paragraphs.</li>
+  <li>Insert a horizontal line.</li>
+  <li>Insert hyperlinks and images.</li>
+  <li>View the raw HTML source of what they're editing.</li>
+  <li>and much more...</li>
+</ul>
+
+<p>Some of the interesting features of HTMLArea that set's it apart from
+other web based WYSIWYG editors are as follows:</p>
+
+<ul>
+  <li>It's lightweight, fast loading and can transform a regular textarea
+  into a rich-text editor with a single line of JavaScript.</li>
+  <li>Generates clean, valid HTML.</li>
+  <li>It degrades gracefully to older or non-supported browsers
+  (they get the original textarea field).</li>
+  <li>It's free and can be incorporated into any free or commercial
+  program.</li>
+  <li>It works with any server-side languages (ASP, PHP, Perl, Java,
+  etc).</li>
+  <li>It's written in JavaScript and can be easily viewed, modified or
+  extended.</li>
+  <li>It remembers entered content when a user navigates away and then hits
+  "back" in their browser.</li>
+  <li>Since it replaces existing textareas it doesn't require a lot of code
+  to add it to your pages (just one line).</li>
+  <li>Did we mention it was free? ;-)</li>
+</ul>
+
+<h3>Is it really free?  What's the catch?</h3>
+
+<p>Yes! It's really free. You can use it, modify it, distribute it with your
+software, or do just about anything you like with it.</p>
+
+<h3>What are the browser requirements?</h3>
+
+<p>HTMLArea requires <span class="browser"><a
+href="http://www.microsoft.com/ie">Internet Explorer</a> &gt;= 5.5</span>
+(Windows only), or <span class="browser"><a
+href="http://mozilla.org">Mozilla</a> &gt;= 1.3-Beta</span> on any platform.
+Any browser based on <a href="http://mozilla.org/newlayout">Gecko</a> will
+also work, provided that Gecko version is at least the one included in
+Mozilla-1.3-Beta (for example, <a
+href="http://galeon.sf.net">Galeon-1.2.8</a>).  However, it degrades
+gracefully to other browsers. They will get a regular textarea field
+instead of a WYSIWYG editor.</p>
+
+<h3>Can I see an example of what it looks like?</h3>
+
+<p>Just make sure you're using one of the browsers mentioned above and see
+below.</p>
+
+<form onsubmit="return false;">
+<textarea id="TA" style="width: 100%; height: 15em;">
+<p>Here is some sample text in textarea that's been transformed with <font
+color="#0000CC"><b>HTMLArea</b></font>.<br />
+You can make things <b>bold</b>, <i>italic</i>, <u>underline</u>.  You can change the
+<font size="3">size</font> and <b><font color="#0000CC">c</font><font color="#00CC00">o</font><font color="#00CCCC">l</font><font color="#CC0000">o</font><font color="#CC00CC">r</font><font color="#CCCC00">s</font><font color="#CCCCCC">!</font></b>
+And lots more...</p>
+
+<p align="center"><font size="4" color="#ff0000"><b><u>Try HTMLArea
+today!</u></b></font><br /></p>
+</textarea>
+</form>
+
+<h3>Where can I find out more info, download the latest version and talk to
+other HTMLArea users?</h3>
+
+<p>You can find out more about HTMLArea and download the latest version on
+the <a href="http://dynarch.com/htmlarea/">HTMLArea
+homepage</a> and you can talk to other HTMLArea users and post any comments
+or suggestions you have in the <a
+href="http://www.interactivetools.com/iforum/Open_Source_C3/htmlArea_v3.0_-_Alpha_Release_F14/"
+>HTMLArea forum</a>.</p>
+
+<h2>Keyboard shortcuts</h2>
+
+<p>The editor provides the following key combinations:</p>
+
+<ul>
+  <li>CTRL-A -- select all</li>
+  <li>CTRL-B -- bold</li>
+  <li>CTRL-I -- italic</li>
+  <li>CTRL-U -- underline</li>
+  <li>CTRL-S -- strikethrough</li>
+  <li>CTRL-L -- justify left</li>
+  <li>CTRL-E -- justify center</li>
+  <li>CTRL-R -- justify right</li>
+  <li>CTRL-J -- justify full</li>
+  <li>CTRL-1 .. CTRL-6 -- headings (&lt;h1&gt; .. &lt;h6&gt;)</li>
+  <li>CTRL-0 (zero) -- clean content pasted from Word</li>
+</ul>
+
+<h2>Installation</h2>
+
+<h3>How do I add HTMLArea to my web page?</h3>
+
+<p>It's easy.  First you need to upload HTMLArea files to your website.
+Just follow these steps.</p>
+
+<ol>
+  <li>Download the latest version from the <a
+  href="http://www.interactivetools.com/products/htmlarea/">htmlArea
+  homepage</a>.</li>
+  <li>Unzip the files onto your local computer (making sure to maintain the
+  directory structure contained in the zip).</li>
+  <li>Create a new folder on your website called /htmlarea/ (make sure it's
+  NOT inside the cgi-bin).</li>
+  <li>Transfer all the HTMLArea files from your local computer into the
+  /htmlarea/ folder on your website.</li>
+  <li>Open the example page /htmlarea/examples/core.html with your browser to make
+  sure everything works.</li>
+</ol>
+
+<p>Once htmlArea is on your website all you need to do is add some
+JavaScript to any pages that you want to add WYSIWYG editors to.  Here's how
+to do that.</p>
+
+<ol>
+
+  <li>Define some global variables.  "_editor_url" has to be the absolute
+  URL where HTMLArea resides within your
+  website; as we discussed, this would be â/htmlarea/â.  "_editor_lang" must
+  be the language code in which you want HTMLArea to appear.  This defaults
+  to "en" (English); for a list of supported languages, please look into
+  the "lang" subdirectory in the distribution.
+  <pre class="code"
+  ><span class="function-name">&lt;</span><span class="html-tag">script</span> <span class="variable-name">type=</span><span class="string">&quot;text/javascript&quot;</span><span class="function-name">&gt;</span>
+   _editor_url = <span class="string">&quot;/htmlarea/&quot;</span>;
+   _editor_lang = <span class="string">&quot;en&quot;</span>;
+<span class="function-name">&lt;</span><span class="html-tag">/script</span><span class="function-name">&gt;</span></pre>
+
+  <li>Include the "htmlarea.js" script:
+  <pre class="code"
+  ><span class="function-name">&lt;</span><span class="html-tag">script</span> <span class="variable-name">type=</span><span class="string">&quot;text/javascript&quot;</span> <span class="variable-name">src=</span><span class="string">&quot;/htmlarea/htmlarea.js&quot;</span><span class="function-name">&gt;</span><span class="paren-face-match">&lt;</span><span class="html-tag">/script</span><span class="paren-face-match">&gt;</span></pre>
+  </li>
+
+  <li><p>If you want to change all your &lt;textarea&gt;-s into
+  HTMLArea-s then you can use the simplest way to create HTMLArea:</p>
+  <pre class="code"
+  ><span class="function-name">&lt;</span><span class="html-tag">script</span> <span class="variable-name">type=</span><span class="string">&quot;text/javascript&quot;</span> <span class="variable-name">defer=</span><span class="string">&quot;1&quot;</span><span class="function-name">&gt;</span>
+    HTMLArea.replaceAll<span class="function-name">()</span>;
+<span class="paren-face-match">&lt;</span><span class="html-tag">/script</span><span class="paren-face-match">&gt;</span></pre>
+  <p><span class="note">Note:</span> you can also add the
+  <code>HTMLArea.replaceAll()</code> code to the <code>onload</code>
+  event handler for the <code>body</code> element, if you find it more appropriate.</p>
+
+  <p>A different approach, if you have more than one textarea and only want
+  to change one of them, is to use <code>HTMLArea.replace("id")</code> --
+  pass the <code>id</code> of your textarea.  Do not use the
+  <code>name</code> attribute anymore, it's not a standard solution!</p>
+
+</ol>
+
+<p>This section applies to HTMLArea-3.0 release candidate 1 or later; prior
+to this version, one needed to include more files; however, now HTMLArea is
+able to include other files too (such as stylesheet, language definition
+file, etc.) so you only need to define the editor path and load
+"htmlarea.js".  Nice, eh? ;-)</p>
+
+<h3>I want to change the editor settings, how do I do that?</h3>
+
+<p>While it's true that all you need is one line of JavaScript to create an
+htmlArea WYSIWYG editor, you can also specify more config settings in the
+code to control how the editor works and looks.  Here's an example of some of
+the available settings:</p>
+
+<pre class="code"
+><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config(); <span class="comment">// create a new configuration object
+</span>                                    <span class="comment">// having all the default values
+</span>config.width = '<span class="string">90%</span>';
+config.height = '<span class="string">200px</span>';
+
+<span class="comment">// the following sets a style for the page body (black text on yellow page)
+// and makes all paragraphs be bold by default
+</span>config.pageStyle =
+  '<span class="string">body { background-color: yellow; color: black; font-family: verdana,sans-serif } </span>' +
+  '<span class="string">p { font-width: bold; } </span>';
+
+<span class="comment">// the following replaces the textarea with the given id with a new
+// HTMLArea object having the specified configuration
+</span>HTMLArea.replace('<span class="string">id</span>', config);</pre>
+
+<p><span class="warning">Important:</span> It's recommended that you add
+custom features and configuration to a separate file.  This will ensure you
+that when we release a new official version of HTMLArea you'll have less
+trouble upgrading it.</p>
+
+<h3>How do I customize the toolbar?</h3>
+
+<p>Using the configuration object introduced above allows you to completely
+control what the toolbar contains.  Following is an example of a one-line,
+customized toolbar, much simpler than the default one:</p>
+
+<pre class="code"
+><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+config.toolbar = [
+  ['<span class="string">fontname</span>', '<span class="string">space</span>',
+   '<span class="string">fontsize</span>', '<span class="string">space</span>',
+   '<span class="string">formatblock</span>', '<span class="string">space</span>',
+   '<span class="string">bold</span>', '<span class="string">italic</span>', '<span class="string">underline</span>']
+];
+HTMLArea.replace('<span class="string">id</span>', config);</pre>
+
+<p>The toolbar is an Array of Array objects.  Each array in the toolbar
+defines a new line.  The default toolbar looks like this:</p>
+
+<pre class="code"
+>config.toolbar = [
+[ &quot;<span class="string">fontname</span>&quot;, &quot;<span class="string">space</span>&quot;,
+  &quot;<span class="string">fontsize</span>&quot;, &quot;<span class="string">space</span>&quot;,
+  &quot;<span class="string">formatblock</span>&quot;, &quot;<span class="string">space</span>&quot;,
+  &quot;<span class="string">bold</span>&quot;, &quot;<span class="string">italic</span>&quot;, &quot;<span class="string">underline</span>&quot;, &quot;<span class="string">separator</span>&quot;,
+  &quot;<span class="string">strikethrough</span>&quot;, &quot;<span class="string">subscript</span>&quot;, &quot;<span class="string">superscript</span>&quot;, &quot;<span class="string">separator</span>&quot;,
+  &quot;<span class="string">copy</span>&quot;, &quot;<span class="string">cut</span>&quot;, &quot;<span class="string">paste</span>&quot;, &quot;<span class="string">space</span>&quot;, &quot;<span class="string">undo</span>&quot;, &quot;<span class="string">redo</span>&quot; ],
+		
+[ &quot;<span class="string">justifyleft</span>&quot;, &quot;<span class="string">justifycenter</span>&quot;, &quot;<span class="string">justifyright</span>&quot;, &quot;<span class="string">justifyfull</span>&quot;, &quot;<span class="string">separator</span>&quot;,
+  &quot;<span class="string">insertorderedlist</span>&quot;, &quot;<span class="string">insertunorderedlist</span>&quot;, &quot;<span class="string">outdent</span>&quot;, &quot;<span class="string">indent</span>&quot;, &quot;<span class="string">separator</span>&quot;,
+  &quot;<span class="string">forecolor</span>&quot;, &quot;<span class="string">hilitecolor</span>&quot;, &quot;<span class="string">textindicator</span>&quot;, &quot;<span class="string">separator</span>&quot;,
+  &quot;<span class="string">inserthorizontalrule</span>&quot;, &quot;<span class="string">createlink</span>&quot;, &quot;<span class="string">insertimage</span>&quot;, &quot;<span class="string">inserttable</span>&quot;, &quot;<span class="string">htmlmode</span>&quot;, &quot;<span class="string">separator</span>&quot;,
+  &quot;<span class="string">popupeditor</span>&quot;, &quot;<span class="string">separator</span>&quot;, &quot;<span class="string">showhelp</span>&quot;, &quot;<span class="string">about</span>&quot; ]
+];</pre>
+
+<p>Except three strings, all others in the examples above need to be defined
+in the <code>config.btnList</code> object (detailed a bit later in this
+document).  The three exceptions are: 'space', 'separator' and 'linebreak'.
+These three have the following meaning, and need not be present in
+<code>btnList</code>:</p>
+
+<ul>
+  <li>'space' -- Inserts a space of 5 pixels (the width is configurable by external
+  <acronym title="Cascading Style Sheets">CSS</acronym>) at the current
+  position in the toolbar.</li>
+  <li>'separator' -- Inserts a small vertical separator, for visually grouping related
+  buttons.</li>
+  <li>'linebreak' -- Starts a new line in the toolbar.  Subsequent controls will be
+  inserted on the new line.</li>
+</ul>
+
+<p><span class="warning">Important:</span> It's recommended that you add
+custom features and configuration to a separate file.  This will ensure you
+that when we release a new official version of HTMLArea you'll have less
+trouble upgrading it.</p>
+
+<h3>How do I create custom buttons?</h3>
+
+<p>By design, the toolbar is easily extensible.  For adding a custom button
+one needs to follow two steps.</p>
+
+<h4 id="regbtn">1. Register the button in <code>config.btnList</code>.</h4>
+
+<p>For each button in the toolbar, HTMLArea needs to know the following
+information:</p>
+<ul>
+  <li>a name for it (we call it the ID of the button);</li>
+  <li>the path to an image to be displayed in the toolbar;</li>
+  <li>a tooltip for it;</li>
+  <li>whether the button is enabled or not in text mode;</li>
+  <li>what to do when the button is clicked;</li>
+</ul>
+<p>You need to provide all this information for registering a new button
+too.  The button ID can be any string identifier and it's used when
+defining the toolbar, as you saw above.  We recommend starting
+it with "my-" so that it won't clash with the standard ID-s (those from
+the default toolbar).</p>
+
+<p class="note">Register button example #1</p>
+
+<pre class="code"
+><span class="comment">// get a default configuration
+</span><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+<span class="comment">// register the new button using Config.registerButton.
+// parameters:        button ID,   tooltip,          image,           textMode,
+</span>config.registerButton(&quot;<span class="string">my-hilite</span>&quot;, &quot;<span class="string">Highlight text</span>&quot;, &quot;<span class="string">my-hilite.gif</span>&quot;, <span class="keyword">false</span>,
+<span class="comment">// function that gets called when the button is clicked
+</span>  <span class="keyword">function</span>(editor, id) {
+    editor.surroundHTML('<span class="string">&lt;span class=&quot;hilite&quot;&gt;</span>', '<span class="string">&lt;/span&gt;</span>');
+  }
+);</pre>
+
+<p>An alternate way of calling registerButton is exemplified above.  Though
+the code might be a little bit larger, using this form makes your code more
+maintainable.  It doesn't even needs comments as it's pretty clear.</p>
+
+<p class="note">Register button example #2</p>
+
+<pre class="code"
+><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+config.registerButton({
+  id        : &quot;<span class="string">my-hilite</span>&quot;,
+  tooltip   : &quot;<span class="string">Highlight text</span>&quot;,
+  image     : &quot;<span class="string">my-hilite.gif</span>&quot;,
+  textMode  : <span class="keyword">false</span>,
+  action    : <span class="keyword">function</span>(editor, id) {
+                editor.surroundHTML('<span class="string">&lt;span class=&quot;hilite&quot;&gt;</span>', '<span class="string">&lt;/span&gt;</span>');
+              }
+});</pre>
+
+<p>You might notice that the "action" function receives two parameters:
+<b>editor</b> and <b>id</b>.  In the examples above we only used the
+<b>editor</b> parameter.  But it could be helpful for you to understand
+both:</p>
+
+<ul>
+  <li><b>editor</b> is a reference to the HTMLArea object.  Since our entire
+  code now has an <acronym title="Object Oriented Programming">OOP</acronym>-like
+  design, you need to have a reference to
+  the editor object in order to do things with it.  In previous versions of
+  HTMLArea, in order to identify the object an ID was used -- the ID of the
+  HTML element.  In this version ID-s are no longer necessary.</li>
+
+  <li><b>id</b> is the button ID.  Wondering why is this useful?  Well, you
+  could use the same handler function (presuming that it's not an anonymous
+  function like in the examples above) for more buttons.  You can <a
+  href="#btnex">see an example</a> a bit later in this document.</li>
+</ul>
+
+<h4>2. Inserting it into the toolbar</h4>
+
+<p>At this step you need to specify where in the toolbar to insert the
+button, or just create the whole toolbar again as you saw in the previous
+section.  You use the button ID, as shown in the examples of customizing the
+toolbar in the previous section.</p>
+
+<p>For the sake of completion, following there are another examples.</p>
+
+<p class="note">Append your button to the default toolbar</p>
+
+<pre class="code"
+>config.toolbar.push([ &quot;<span class="string">my-hilite</span>&quot; ]);</pre>
+
+<p class="note">Customized toolbar</p>
+
+<pre class="code"
+>config.toolbar = [
+  ['<span class="string">fontname</span>', '<span class="string">space</span>',
+   '<span class="string">fontsize</span>', '<span class="string">space</span>',
+   '<span class="string">formatblock</span>', '<span class="string">space</span>',
+   '<span class="string">separator</span>', '<span class="string">my-hilite</span>', '<span class="string">separator</span>', '<span class="string">space</span>', <span class="comment">// here's your button
+</span>   '<span class="string">bold</span>', '<span class="string">italic</span>', '<span class="string">underline</span>', '<span class="string">space</span>']
+];</pre>
+
+<p><span class="note">Note:</span> in the example above our new button is
+between two vertical separators.  But this is by no means required.  You can
+put it wherever you like.  Once registered in the btnList (<a
+href="#regbtn">step 1</a>) your custom button behaves just like a default
+button.</p>
+
+<p><span class="warning">Important:</span> It's recommended that you add
+custom features and configuration to a separate file.  This will ensure you
+that when we release a new official version of HTMLArea you'll have less
+trouble upgrading it.</p>
+
+<h4 id="btnex">A complete example</h4>
+
+<p>Please note that it is by no means necessary to include the following
+code into the htmlarea.js file.  On the contrary, it might not work there.
+The configuration system is designed such that you can always customize the
+editor <em>from outside files</em>, thus keeping the htmlarea.js file
+intact.  This will make it easy for you to upgrade your HTMLArea when we
+release a new official version.  OK, I promise it's the last time I said
+this. ;)</p>
+
+<pre class="code"
+><span class="comment">// All our custom buttons will call this function when clicked.
+// We use the <b>buttonId</b> parameter to determine what button
+// triggered the call.
+</span><span class="keyword">function</span> <span class="function-name">clickHandler</span>(editor, buttonId) {
+  <span class="keyword">switch</span> (buttonId) {
+    <span class="keyword">case</span> &quot;<span class="string">my-toc</span>&quot;:
+      editor.insertHTML(&quot;<span class="string">&lt;h1&gt;Table Of Contents&lt;/h1&gt;</span>&quot;);
+      <span class="keyword">break</span>;
+    <span class="keyword">case</span> &quot;<span class="string">my-date</span>&quot;:
+      editor.insertHTML((<span class="keyword">new</span> Date()).toString());
+      <span class="keyword">break</span>;
+    <span class="keyword">case</span> &quot;<span class="string">my-bold</span>&quot;:
+      editor.execCommand(&quot;<span class="string">bold</span>&quot;);
+      editor.execCommand(&quot;<span class="string">italic</span>&quot;);
+      <span class="keyword">break</span>;
+    <span class="keyword">case</span> &quot;<span class="string">my-hilite</span>&quot;:
+      editor.surroundHTML(&quot;<span class="string">&lt;span class=\&quot;hilite\&quot;&gt;</span>&quot;, &quot;<span class="string">&lt;/span&gt;</span>&quot;);
+      <span class="keyword">break</span>;
+  }
+};
+
+<span class="comment">// Create a new configuration object
+</span><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+
+<span class="comment">// Register our custom buttons
+</span>config.registerButton(&quot;<span class="string">my-toc</span>&quot;,  &quot;<span class="string">Insert TOC</span>&quot;, &quot;<span class="string">my-toc.gif</span>&quot;, <span class="keyword">false</span>, clickHandler);
+config.registerButton(&quot;<span class="string">my-date</span>&quot;, &quot;<span class="string">Insert date/time</span>&quot;, &quot;<span class="string">my-date.gif</span>&quot;, <span class="keyword">false</span>, clickHandler);
+config.registerButton(&quot;<span class="string">my-bold</span>&quot;, &quot;<span class="string">Toggle bold/italic</span>&quot;, &quot;<span class="string">my-bold.gif</span>&quot;, <span class="keyword">false</span>, clickHandler);
+config.registerButton(&quot;<span class="string">my-hilite</span>&quot;, &quot;<span class="string">Hilite selection</span>&quot;, &quot;<span class="string">my-hilite.gif</span>&quot;, <span class="keyword">false</span>, clickHandler);
+
+<span class="comment">// Append the buttons to the default toolbar
+</span>config.toolbar.push([&quot;<span class="string">linebreak</span>&quot;, &quot;<span class="string">my-toc</span>&quot;, &quot;<span class="string">my-date</span>&quot;, &quot;<span class="string">my-bold</span>&quot;, &quot;<span class="string">my-hilite</span>&quot;]);
+
+<span class="comment">// Replace an existing textarea with an HTMLArea object having the above config.
+</span>HTMLArea.replace(&quot;<span class="string">textAreaID</span>&quot;, config);</pre>
+
+
+<hr />
+<address>&copy; <a href="http://interactivetools.com" title="Visit our website"
+>InteractiveTools.com</a> 2002-2004.
+<br />
+Â© <a href="http://dynarch.com">dynarch.com</a> 2003-2004<br />
+HTMLArea v3.0 developed by <a
+href="http://dynarch.com/mishoo/">Mihai Bazon</a>.
+<br />
+Documentation written by Mihai Bazon.
+</address>
+<!-- hhmts start --> Last modified: Wed Jan 28 12:18:23 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+</body> </html>
Index: /sandbox/workflow/branches/993/js/htmlarea/example-table-operations.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/example-table-operations.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/example-table-operations.html	(revision 795)
@@ -0,0 +1,116 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="htmlarea.js"></script>
+<script type="text/javascript" src="lang/en.js"></script>
+<script type="text/javascript" src="dialog.js"></script>
+<!-- <script type="text/javascript" src="popupdiv.js"></script> -->
+<script type="text/javascript" src="popupwin.js"></script>
+
+<!-- load the TableOperations plugin files -->
+<script type="text/javascript" src="plugins/TableOperations/table-operations.js"></script>
+<script type="text/javascript" src="plugins/TableOperations/lang/en.js"></script>
+
+<style type="text/css">
+@import url(htmlarea.css);
+
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+  // create an editor for the "ta" textbox
+  editor = new HTMLArea("ta");
+
+  // register the TableOperations plugin with our editor
+  editor.registerPlugin("TableOperations");
+
+  editor.generate();
+  return false;
+}
+
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003.</p>
+
+<p>Page that demonstrates the additional features of the
+<tt>TableOperations</tt> plugin (sponsored by <a
+href="http://www.bloki.com">Zapatec Inc.</a>).</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<h1>Plugin: <tt>TableOperations</tt></h1>
+
+<p>This page exemplifies the table operations toolbar, provided by the
+TableOperations plugin.</p>
+
+<p>Following there is a table.</p>
+
+<table border="1" style="border: 2px solid rgb(255, 0, 0); width: 80%; background-image: none; border-collapse: collapse; color: rgb(153, 102, 0); background-color: rgb(255, 255, 51);" align="center" cellspacing="2" cellpadding="1" summary="">
+  <caption>This <span style="font-weight: bold;">is</span> a table</caption>
+  <tbody>
+  <tr style="border-style: none; background-image: none; background-color: rgb(255, 255, 153);" char="." align="left" valign="middle"> <td>1.1</td> <td>1.2</td> <td>1.3</td> <td>1.4</td> </tr>
+  <tr> <td>2.1</td> <td style="border: 1px solid rgb(51, 51, 255); background-image: none; background-color: rgb(102, 255, 255); color: rgb(0, 0, 51);" char="." align="left" valign="middle">2.2</td> <td>2.3</td> <td>2.4</td> </tr>
+  <tr> <td>3.1</td> <td>3.2</td> <td style="border: 2px dashed rgb(51, 204, 102); background-image: none; background-color: rgb(102, 255, 153); color: rgb(0, 51, 0);" char="." align="left" valign="middle">3.3</td> <td>3.4</td> </tr>
+  <tr> <td style="background-color: rgb(255, 204, 51);">4.1</td> <td style="background-color: rgb(255, 204, 51);">4.2</td> <td style="background-color: rgb(255, 204, 51);">4.3</td> <td style="background-color: rgb(255, 204, 51);">4.4</td> </tr>
+  </tbody>
+</table>
+
+<p>Text after the table</p>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/images/makefile.xml
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/images/makefile.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/images/makefile.xml	(revision 795)
@@ -0,0 +1,3 @@
+<files>
+  <file name="*.{gif,jpg,jpeg}" />
+</files>
Index: /sandbox/workflow/branches/993/js/htmlarea/htmlarea.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/htmlarea.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/htmlarea.js	(revision 795)
@@ -0,0 +1,2245 @@
+// htmlArea v3.0 - Copyright (c) 2002-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+
+if (typeof _editor_url == "string") {
+	// Leave exactly one backslash at the end of _editor_url
+	_editor_url = _editor_url.replace(/\x2f*$/, '/');
+} else {
+	alert("WARNING: _editor_url is not set!  You should set this variable to the editor files path; it should preferably be an absolute path, like in '/htmlarea/', but it can be relative if you prefer.  Further we will try to load the editor files correctly but we'll probably fail.");
+	_editor_url = '';
+}
+
+// make sure we have a language
+if (typeof _editor_lang == "string") {
+	_editor_lang = _editor_lang.toLowerCase();
+} else {
+	_editor_lang = "en";
+}
+
+// Creates a new HTMLArea object.  Tries to replace the textarea with the given
+// ID with it.
+function HTMLArea(textarea, config) {
+	if (HTMLArea.checkSupportedBrowser()) {
+		if (typeof config == "undefined") {
+			this.config = new HTMLArea.Config();
+		} else {
+			this.config = config;
+		}
+		this._htmlArea = null;
+		this._textArea = textarea;
+		this._editMode = "wysiwyg";
+		this.plugins = {};
+		this._timerToolbar = null;
+		this._timerUndo = null;
+		this._undoQueue = new Array(this.config.undoSteps);
+		this._undoPos = -1;
+		this._customUndo = false;
+		this._mdoc = document; // cache the document, we need it in plugins
+		this.doctype = '';
+	}
+};
+
+// load some scripts
+(function() {
+	var scripts = HTMLArea._scripts = [ _editor_url + "htmlarea.js",
+					    _editor_url + "dialog.js",
+					    _editor_url + "popupwin.js",
+					    _editor_url + "lang/" + _editor_lang + ".js" ];
+	var head = document.getElementsByTagName("head")[0];
+	// start from 1, htmlarea.js is already loaded
+	for (var i = 1; i < scripts.length; ++i) {
+		var script = document.createElement("script");
+		script.src = scripts[i];
+		head.appendChild(script);
+	}
+})();
+
+// cache some regexps
+HTMLArea.RE_tagName = /(<\/|<)\s*([^ \t\n>]+)/ig;
+HTMLArea.RE_doctype = /(<!doctype((.|\n)*?)>)\n?/i;
+HTMLArea.RE_head    = /<head>((.|\n)*?)<\/head>/i;
+HTMLArea.RE_body    = /<body>((.|\n)*?)<\/body>/i;
+
+HTMLArea.Config = function () {
+	this.version = "3.0";
+
+	this.width = "auto";
+	this.height = "auto";
+
+	// enable creation of a status bar?
+	this.statusBar = true;
+
+	// maximum size of the undo queue
+	this.undoSteps = 20;
+
+	// the time interval at which undo samples are taken
+	this.undoTimeout = 500;	// 1/2 sec.
+
+	// the next parameter specifies whether the toolbar should be included
+	// in the size or not.
+	this.sizeIncludesToolbar = true;
+
+	// if true then HTMLArea will retrieve the full HTML, starting with the
+	// <HTML> tag.
+	this.fullPage = false;
+
+	// style included in the iframe document
+	this.pageStyle = "";
+
+	// set to true if you want Word code to be cleaned upon Paste
+	this.killWordOnPaste = false;
+
+	// BaseURL included in the iframe document
+	this.baseURL = document.baseURI || document.URL;
+	if (this.baseURL && this.baseURL.match(/(.*)\/([^\/]+)/))
+		this.baseURL = RegExp.$1 + "/";
+
+	// URL-s
+	this.imgURL = "images/";
+	this.popupURL = "popups/";
+
+	/** CUSTOMIZING THE TOOLBAR
+	 * -------------------------
+	 *
+	 * It is recommended that you customize the toolbar contents in an
+	 * external file (i.e. the one calling HTMLArea) and leave this one
+	 * unchanged.  That's because when we (InteractiveTools.com) release a
+	 * new official version, it's less likely that you will have problems
+	 * upgrading HTMLArea.
+	 */
+	this.toolbar = [
+		[ "fontname", "space",
+		  "fontsize", "space",
+		  "formatblock", "space",
+		  "bold", "italic", "underline", "strikethrough", "separator",
+		  "subscript", "superscript", "separator",
+		  "copy", "cut", "paste", "space", "undo", "redo" ],
+
+		[ "justifyleft", "justifycenter", "justifyright", "justifyfull", "separator",
+		  "lefttoright", "righttoleft", "separator",
+		  "orderedlist", "unorderedlist", "outdent", "indent", "separator",
+		  "forecolor", "hilitecolor", "separator",
+		  "inserthorizontalrule", "createlink", "insertimage", "inserttable", "htmlmode", "separator",
+		  "popupeditor", "separator", "showhelp", "about" ]
+	];
+
+	this.fontname = {
+		"Arial":	   'arial,helvetica,sans-serif',
+		"Courier New":	   'courier new,courier,monospace',
+		"Georgia":	   'georgia,times new roman,times,serif',
+		"Tahoma":	   'tahoma,arial,helvetica,sans-serif',
+		"Times New Roman": 'times new roman,times,serif',
+		"Verdana":	   'verdana,arial,helvetica,sans-serif',
+		"impact":	   'impact',
+		"WingDings":	   'wingdings'
+	};
+
+	this.fontsize = {
+		"1 (8 pt)":  "1",
+		"2 (10 pt)": "2",
+		"3 (12 pt)": "3",
+		"4 (14 pt)": "4",
+		"5 (18 pt)": "5",
+		"6 (24 pt)": "6",
+		"7 (36 pt)": "7"
+	};
+
+	this.formatblock = {
+		"Heading 1": "h1",
+		"Heading 2": "h2",
+		"Heading 3": "h3",
+		"Heading 4": "h4",
+		"Heading 5": "h5",
+		"Heading 6": "h6",
+		"Normal": "p",
+		"Address": "address",
+		"Formatted": "pre"
+	};
+
+	this.customSelects = {};
+
+	function cut_copy_paste(e, cmd, obj) {
+		e.execCommand(cmd);
+	};
+
+	// ADDING CUSTOM BUTTONS: please read below!
+	// format of the btnList elements is "ID: [ ToolTip, Icon, Enabled in text mode?, ACTION ]"
+	//    - ID: unique ID for the button.  If the button calls document.execCommand
+	//	    it's wise to give it the same name as the called command.
+	//    - ACTION: function that gets called when the button is clicked.
+	//              it has the following prototype:
+	//                 function(editor, buttonName)
+	//              - editor is the HTMLArea object that triggered the call
+	//              - buttonName is the ID of the clicked button
+	//              These 2 parameters makes it possible for you to use the same
+	//              handler for more HTMLArea objects or for more different buttons.
+	//    - ToolTip: default tooltip, for cases when it is not defined in the -lang- file (HTMLArea.I18N)
+	//    - Icon: path to an icon image file for the button (TODO: use one image for all buttons!)
+	//    - Enabled in text mode: if false the button gets disabled for text-only mode; otherwise enabled all the time.
+	this.btnList = {
+		bold: [ "Bold", "ed_format_bold.gif", false, function(e) {e.execCommand("bold");} ],
+		italic: [ "Italic", "ed_format_italic.gif", false, function(e) {e.execCommand("italic");} ],
+		underline: [ "Underline", "ed_format_underline.gif", false, function(e) {e.execCommand("underline");} ],
+		strikethrough: [ "Strikethrough", "ed_format_strike.gif", false, function(e) {e.execCommand("strikethrough");} ],
+		subscript: [ "Subscript", "ed_format_sub.gif", false, function(e) {e.execCommand("subscript");} ],
+		superscript: [ "Superscript", "ed_format_sup.gif", false, function(e) {e.execCommand("superscript");} ],
+		justifyleft: [ "Justify Left", "ed_align_left.gif", false, function(e) {e.execCommand("justifyleft");} ],
+		justifycenter: [ "Justify Center", "ed_align_center.gif", false, function(e) {e.execCommand("justifycenter");} ],
+		justifyright: [ "Justify Right", "ed_align_right.gif", false, function(e) {e.execCommand("justifyright");} ],
+		justifyfull: [ "Justify Full", "ed_align_justify.gif", false, function(e) {e.execCommand("justifyfull");} ],
+		orderedlist: [ "Ordered List", "ed_list_num.gif", false, function(e) {e.execCommand("insertorderedlist");} ],
+		unorderedlist: [ "Bulleted List", "ed_list_bullet.gif", false, function(e) {e.execCommand("insertunorderedlist");} ],
+		outdent: [ "Decrease Indent", "ed_indent_less.gif", false, function(e) {e.execCommand("outdent");} ],
+		indent: [ "Increase Indent", "ed_indent_more.gif", false, function(e) {e.execCommand("indent");} ],
+		forecolor: [ "Font Color", "ed_color_fg.gif", false, function(e) {e.execCommand("forecolor");} ],
+		hilitecolor: [ "Background Color", "ed_color_bg.gif", false, function(e) {e.execCommand("hilitecolor");} ],
+		inserthorizontalrule: [ "Horizontal Rule", "ed_hr.gif", false, function(e) {e.execCommand("inserthorizontalrule");} ],
+		createlink: [ "Insert Web Link", "ed_link.gif", false, function(e) {e.execCommand("createlink", true);} ],
+		insertimage: [ "Insert/Modify Image", "ed_image.gif", false, function(e) {e.execCommand("insertimage");} ],
+		inserttable: [ "Insert Table", "insert_table.gif", false, function(e) {e.execCommand("inserttable");} ],
+		htmlmode: [ "Toggle HTML Source", "ed_html.gif", true, function(e) {e.execCommand("htmlmode");} ],
+		popupeditor: [ "Enlarge Editor", "fullscreen_maximize.gif", true, function(e) {e.execCommand("popupeditor");} ],
+		about: [ "About this editor", "ed_about.gif", true, function(e) {e.execCommand("about");} ],
+		showhelp: [ "Help using editor", "ed_help.gif", true, function(e) {e.execCommand("showhelp");} ],
+		undo: [ "Undoes your last action", "ed_undo.gif", false, function(e) {e.execCommand("undo");} ],
+		redo: [ "Redoes your last action", "ed_redo.gif", false, function(e) {e.execCommand("redo");} ],
+		cut: [ "Cut selection", "ed_cut.gif", false, cut_copy_paste ],
+		copy: [ "Copy selection", "ed_copy.gif", false, cut_copy_paste ],
+		paste: [ "Paste from clipboard", "ed_paste.gif", false, cut_copy_paste ],
+		lefttoright: [ "Direction left to right", "ed_left_to_right.gif", false, function(e) {e.execCommand("lefttoright");} ],
+		righttoleft: [ "Direction right to left", "ed_right_to_left.gif", false, function(e) {e.execCommand("righttoleft");} ]
+	};
+	/* ADDING CUSTOM BUTTONS
+	 * ---------------------
+	 *
+	 * It is recommended that you add the custom buttons in an external
+	 * file and leave this one unchanged.  That's because when we
+	 * (InteractiveTools.com) release a new official version, it's less
+	 * likely that you will have problems upgrading HTMLArea.
+	 *
+	 * Example on how to add a custom button when you construct the HTMLArea:
+	 *
+	 *   var editor = new HTMLArea("your_text_area_id");
+	 *   var cfg = editor.config; // this is the default configuration
+	 *   cfg.btnList["my-hilite"] =
+	 *	[ function(editor) { editor.surroundHTML('<span style="background:yellow">', '</span>'); }, // action
+	 *	  "Highlight selection", // tooltip
+	 *	  "my_hilite.gif", // image
+	 *	  false // disabled in text mode
+	 *	];
+	 *   cfg.toolbar.push(["linebreak", "my-hilite"]); // add the new button to the toolbar
+	 *
+	 * An alternate (also more convenient and recommended) way to
+	 * accomplish this is to use the registerButton function below.
+	 */
+	// initialize tooltips from the I18N module and generate correct image path
+	for (var i in this.btnList) {
+		var btn = this.btnList[i];
+		btn[1] = _editor_url + this.imgURL + btn[1];
+		if (typeof HTMLArea.I18N.tooltips[i] != "undefined") {
+			btn[0] = HTMLArea.I18N.tooltips[i];
+		}
+	}
+};
+
+/** Helper function: register a new button with the configuration.  It can be
+ * called with all 5 arguments, or with only one (first one).  When called with
+ * only one argument it must be an object with the following properties: id,
+ * tooltip, image, textMode, action.  Examples:
+ *
+ * 1. config.registerButton("my-hilite", "Hilite text", "my-hilite.gif", false, function(editor) {...});
+ * 2. config.registerButton({
+ *      id       : "my-hilite",      // the ID of your button
+ *      tooltip  : "Hilite text",    // the tooltip
+ *      image    : "my-hilite.gif",  // image to be displayed in the toolbar
+ *      textMode : false,            // disabled in text mode
+ *      action   : function(editor) { // called when the button is clicked
+ *                   editor.surroundHTML('<span class="hilite">', '</span>');
+ *                 },
+ *      context  : "p"               // will be disabled if outside a <p> element
+ *    });
+ */
+HTMLArea.Config.prototype.registerButton = function(id, tooltip, image, textMode, action, context) {
+	var the_id;
+	if (typeof id == "string") {
+		the_id = id;
+	} else if (typeof id == "object") {
+		the_id = id.id;
+	} else {
+		alert("ERROR [HTMLArea.Config::registerButton]:\ninvalid arguments");
+		return false;
+	}
+	// check for existing id
+	if (typeof this.customSelects[the_id] != "undefined") {
+		// alert("WARNING [HTMLArea.Config::registerDropdown]:\nA dropdown with the same ID already exists.");
+	}
+	if (typeof this.btnList[the_id] != "undefined") {
+		// alert("WARNING [HTMLArea.Config::registerDropdown]:\nA button with the same ID already exists.");
+	}
+	switch (typeof id) {
+	    case "string": this.btnList[id] = [ tooltip, image, textMode, action, context ]; break;
+	    case "object": this.btnList[id.id] = [ id.tooltip, id.image, id.textMode, id.action, id.context ]; break;
+	}
+};
+
+/** The following helper function registers a dropdown box with the editor
+ * configuration.  You still have to add it to the toolbar, same as with the
+ * buttons.  Call it like this:
+ *
+ * FIXME: add example
+ */
+HTMLArea.Config.prototype.registerDropdown = function(object) {
+	// check for existing id
+	if (typeof this.customSelects[object.id] != "undefined") {
+		// alert("WARNING [HTMLArea.Config::registerDropdown]:\nA dropdown with the same ID already exists.");
+	}
+	if (typeof this.btnList[object.id] != "undefined") {
+		// alert("WARNING [HTMLArea.Config::registerDropdown]:\nA button with the same ID already exists.");
+	}
+	this.customSelects[object.id] = object;
+};
+
+/** Call this function to remove some buttons/drop-down boxes from the toolbar.
+ * Pass as the only parameter a string containing button/drop-down names
+ * delimited by spaces.  Note that the string should also begin with a space
+ * and end with a space.  Example:
+ *
+ *   config.hideSomeButtons(" fontname fontsize textindicator ");
+ *
+ * It's useful because it's easier to remove stuff from the defaul toolbar than
+ * create a brand new toolbar ;-)
+ */
+HTMLArea.Config.prototype.hideSomeButtons = function(remove) {
+	var toolbar = this.toolbar;
+	for (var i in toolbar) {
+		var line = toolbar[i];
+		for (var j = line.length; --j >= 0; ) {
+			if (remove.indexOf(" " + line[j] + " ") >= 0) {
+				var len = 1;
+				if (/separator|space/.test(line[j + 1])) {
+					len = 2;
+				}
+				line.splice(j, len);
+			}
+		}
+	}
+};
+
+/** Helper function: replace all TEXTAREA-s in the document with HTMLArea-s. */
+HTMLArea.replaceAll = function(config) {
+	var tas = document.getElementsByTagName("textarea");
+	for (var i = tas.length; i > 0; (new HTMLArea(tas[--i], config)).generate()){};
+};
+
+/** Helper function: replaces the TEXTAREA with the given ID with HTMLArea. */
+HTMLArea.replace = function(id, config) {
+	var ta = HTMLArea.getElementById("textarea", id);
+	return ta ? (new HTMLArea(ta, config)).generate() : null;
+};
+
+// Creates the toolbar and appends it to the _htmlarea
+HTMLArea.prototype._createToolbar = function () {
+	var editor = this;	// to access this in nested functions
+
+	var toolbar = document.createElement("div");
+	this._toolbar = toolbar;
+	toolbar.className = "toolbar";
+	toolbar.unselectable = "1";
+	toolbar.style.width = this.config.width - 4;
+	var tb_row = null;
+	var tb_objects = new Object();
+	this._toolbarObjects = tb_objects;
+
+	// creates a new line in the toolbar
+	function newLine() {
+		var table = document.createElement("table");
+		table.border = "0px";
+		table.cellSpacing = "0px";
+		table.cellPadding = "0px";
+		toolbar.appendChild(table);
+		// TBODY is required for IE, otherwise you don't see anything
+		// in the TABLE.
+		var tb_body = document.createElement("tbody");
+		table.appendChild(tb_body);
+		tb_row = document.createElement("tr");
+		tb_body.appendChild(tb_row);
+	}; // END of function: newLine
+	// init first line
+	newLine();
+
+	// updates the state of a toolbar element.  This function is member of
+	// a toolbar element object (unnamed objects created by createButton or
+	// createSelect functions below).
+	function setButtonStatus(id, newval) {
+		var oldval = this[id];
+		var el = this.element;
+		if (oldval != newval) {
+			switch (id) {
+			    case "enabled":
+				if (newval) {
+					HTMLArea._removeClass(el, "buttonDisabled");
+					el.disabled = false;
+				} else {
+					HTMLArea._addClass(el, "buttonDisabled");
+					el.disabled = true;
+				}
+				break;
+			    case "active":
+				if (newval) {
+					HTMLArea._addClass(el, "buttonPressed");
+				} else {
+					HTMLArea._removeClass(el, "buttonPressed");
+				}
+				break;
+			}
+			this[id] = newval;
+		}
+	}; // END of function: setButtonStatus
+
+	// this function will handle creation of combo boxes.  Receives as
+	// parameter the name of a button as defined in the toolBar config.
+	// This function is called from createButton, above, if the given "txt"
+	// doesn't match a button.
+	function createSelect(txt) {
+		var options = null;
+		var el = null;
+		var cmd = null;
+		var customSelects = editor.config.customSelects;
+		var context = null;
+		var tooltip = "";
+		switch (txt) {
+		    case "fontsize":
+		    case "fontname":
+		    case "formatblock":
+			// the following line retrieves the correct
+			// configuration option because the variable name
+			// inside the Config object is named the same as the
+			// button/select in the toolbar.  For instance, if txt
+			// == "formatblock" we retrieve config.formatblock (or
+			// a different way to write it in JS is
+			// config["formatblock"].
+			options = editor.config[txt];
+			cmd = txt;
+			break;
+		    default:
+			// try to fetch it from the list of registered selects
+			cmd = txt;
+			var dropdown = customSelects[cmd];
+			if (typeof dropdown != "undefined") {
+				options = dropdown.options;
+				context = dropdown.context;
+				if (typeof dropdown.tooltip != "undefined") {
+					tooltip = dropdown.tooltip;
+				}
+			} else {
+				alert("ERROR [createSelect]:\nCan't find the requested dropdown definition");
+			}
+			break;
+		}
+		if (options) {
+			el = document.createElement("select");
+			el.title = tooltip;
+			var obj = {
+				name	: txt, // field name
+				element : el,	// the UI element (SELECT)
+				enabled : true, // is it enabled?
+				text	: false, // enabled in text mode?
+				cmd	: cmd, // command ID
+				state	: setButtonStatus, // for changing state
+				context : context
+			};
+			tb_objects[txt] = obj;
+			for (var i in options) {
+				var op = document.createElement("option");
+				op.appendChild(document.createTextNode(i));
+				op.value = options[i];
+				el.appendChild(op);
+			}
+			HTMLArea._addEvent(el, "change", function () {
+				editor._comboSelected(el, txt);
+			});
+		}
+		return el;
+	}; // END of function: createSelect
+
+	// appends a new button to toolbar
+	function createButton(txt) {
+		// the element that will be created
+		var el = null;
+		var btn = null;
+		switch (txt) {
+		    case "separator":
+			el = document.createElement("div");
+			el.className = "separator";
+			break;
+		    case "space":
+			el = document.createElement("div");
+			el.className = "space";
+			break;
+		    case "linebreak":
+			newLine();
+			return false;
+		    case "textindicator":
+			el = document.createElement("div");
+			el.appendChild(document.createTextNode("A"));
+			el.className = "indicator";
+			el.title = HTMLArea.I18N.tooltips.textindicator;
+			var obj = {
+				name	: txt, // the button name (i.e. 'bold')
+				element : el, // the UI element (DIV)
+				enabled : true, // is it enabled?
+				active	: false, // is it pressed?
+				text	: false, // enabled in text mode?
+				cmd	: "textindicator", // the command ID
+				state	: setButtonStatus // for changing state
+			};
+			tb_objects[txt] = obj;
+			break;
+		    default:
+			btn = editor.config.btnList[txt];
+		}
+		if (!el && btn) {
+			el = document.createElement("div");
+			el.title = btn[0];
+			el.className = "button";
+			// let's just pretend we have a button object, and
+			// assign all the needed information to it.
+			var obj = {
+				name	: txt, // the button name (i.e. 'bold')
+				element : el, // the UI element (DIV)
+				enabled : true, // is it enabled?
+				active	: false, // is it pressed?
+				text	: btn[2], // enabled in text mode?
+				cmd	: btn[3], // the command ID
+				state	: setButtonStatus, // for changing state
+				context : btn[4] || null // enabled in a certain context?
+			};
+			tb_objects[txt] = obj;
+			// handlers to emulate nice flat toolbar buttons
+			HTMLArea._addEvent(el, "mouseover", function () {
+				if (obj.enabled) {
+					HTMLArea._addClass(el, "buttonHover");
+				}
+			});
+			HTMLArea._addEvent(el, "mouseout", function () {
+				if (obj.enabled) with (HTMLArea) {
+					_removeClass(el, "buttonHover");
+					_removeClass(el, "buttonActive");
+					(obj.active) && _addClass(el, "buttonPressed");
+				}
+			});
+			HTMLArea._addEvent(el, "mousedown", function (ev) {
+				if (obj.enabled) with (HTMLArea) {
+					_addClass(el, "buttonActive");
+					_removeClass(el, "buttonPressed");
+					_stopEvent(is_ie ? window.event : ev);
+				}
+			});
+			// when clicked, do the following:
+			HTMLArea._addEvent(el, "click", function (ev) {
+				if (obj.enabled) with (HTMLArea) {
+					_removeClass(el, "buttonActive");
+					_removeClass(el, "buttonHover");
+					obj.cmd(editor, obj.name, obj);
+					_stopEvent(is_ie ? window.event : ev);
+				}
+			});
+			var img = document.createElement("img");
+			img.src = btn[1];
+			img.style.width = "18px";
+			img.style.height = "18px";
+			el.appendChild(img);
+		} else if (!el) {
+			el = createSelect(txt);
+		}
+		if (el) {
+			var tb_cell = document.createElement("td");
+			tb_row.appendChild(tb_cell);
+			tb_cell.appendChild(el);
+		} else {
+			alert("FIXME: Unknown toolbar item: " + txt);
+		}
+		return el;
+	};
+
+	var first = true;
+	for (var i in this.config.toolbar) {
+		if (!first) {
+			createButton("linebreak");
+		} else {
+			first = false;
+		}
+		var group = this.config.toolbar[i];
+		for (var j in group) {
+			var code = group[j];
+			if (/^([IT])\[(.*?)\]/.test(code)) {
+				// special case, create text label
+				var l7ed = RegExp.$1 == "I"; // localized?
+				var label = RegExp.$2;
+				if (l7ed) {
+					label = HTMLArea.I18N.custom[label];
+				}
+				var tb_cell = document.createElement("td");
+				tb_row.appendChild(tb_cell);
+				tb_cell.className = "label";
+				tb_cell.innerHTML = label;
+			} else {
+				createButton(code);
+			}
+		}
+	}
+
+	this._htmlArea.appendChild(toolbar);
+};
+
+HTMLArea.prototype._createStatusBar = function() {
+	var statusbar = document.createElement("div");
+	statusbar.className = "statusBar";
+	this._htmlArea.appendChild(statusbar);
+	this._statusBar = statusbar;
+	// statusbar.appendChild(document.createTextNode(HTMLArea.I18N.msg["Path"] + ": "));
+	// creates a holder for the path view
+	div = document.createElement("span");
+	div.className = "statusBarTree";
+	div.innerHTML = HTMLArea.I18N.msg["Path"] + ": ";
+	this._statusBarTree = div;
+	this._statusBar.appendChild(div);
+	if (!this.config.statusBar) {
+		// disable it...
+		statusbar.style.display = "none";
+	}
+};
+
+// Creates the HTMLArea object and replaces the textarea with it.
+HTMLArea.prototype.generate = function () {
+	var editor = this;	// we'll need "this" in some nested functions
+	// get the textarea
+	var textarea = this._textArea;
+	if (typeof textarea == "string") {
+		// it's not element but ID
+		this._textArea = textarea = HTMLArea.getElementById("textarea", textarea);
+	}
+	this._ta_size = {
+		w: textarea.offsetWidth,
+		h: textarea.offsetHeight
+	};
+	textarea.style.display = "none";
+
+	// create the editor framework
+	var htmlarea = document.createElement("div");
+	htmlarea.className = "htmlarea";
+	htmlarea.style.width = this.config.width;
+	this._htmlArea = htmlarea;
+
+	// insert the editor before the textarea.
+	textarea.parentNode.insertBefore(htmlarea, textarea);
+
+	if (textarea.form) {
+		// we have a form, on submit get the HTMLArea content and
+		// update original textarea.
+		var f = textarea.form;
+		if (typeof f.onsubmit == "function") {
+			var funcref = f.onsubmit;
+			if (typeof f.__msh_prevOnSubmit == "undefined") {
+				f.__msh_prevOnSubmit = [];
+			}
+			f.__msh_prevOnSubmit.push(funcref);
+		}
+		f.onsubmit = function() {
+			editor._textArea.value = editor.getHTML();
+			var a = this.__msh_prevOnSubmit;
+			// call previous submit methods if they were there.
+			if (typeof a != "undefined") {
+				for (var i in a) {
+					a[i]();
+				}
+			}
+		};
+	}
+
+	// add a handler for the "back/forward" case -- on body.unload we save
+	// the HTML content into the original textarea.
+	try {
+		window.onunload = function() {
+			editor._textArea.value = editor.getHTML();
+		};
+	} catch(e) {};
+
+	// creates & appends the toolbar
+	this._createToolbar();
+
+	// create the IFRAME
+	var iframe = document.createElement("iframe");
+
+	// workaround for the HTTPS problem
+	// iframe.setAttribute("src", "javascript:void(0);");
+	iframe.src = _editor_url + "popups/blank.html";
+
+	htmlarea.appendChild(iframe);
+
+	this._iframe = iframe;
+
+	// creates & appends the status bar, if the case
+	this._createStatusBar();
+
+	// remove the default border as it keeps us from computing correctly
+	// the sizes.  (somebody tell me why doesn't this work in IE)
+
+	if (!HTMLArea.is_ie) {
+		iframe.style.borderWidth = "1px";
+	// iframe.frameBorder = "1";
+	// iframe.marginHeight = "0";
+	// iframe.marginWidth = "0";
+	}
+
+	// size the IFRAME according to user's prefs or initial textarea
+	var height = (this.config.height == "auto" ? (this._ta_size.h + "px") : this.config.height);
+	height = parseInt(height);
+	var width = (this.config.width == "auto" ? (this._ta_size.w + "px") : this.config.width);
+	width = parseInt(width);
+
+	if (!HTMLArea.is_ie) {
+		height -= 2;
+		width -= 2;
+	}
+
+	iframe.style.width = width + "px";
+	if (this.config.sizeIncludesToolbar) {
+		// substract toolbar height
+		height -= this._toolbar.offsetHeight;
+		height -= this._statusBar.offsetHeight;
+	}
+	if (height < 0) {
+		height = 0;
+	}
+	iframe.style.height = height + "px";
+
+	// the editor including the toolbar now have the same size as the
+	// original textarea.. which means that we need to reduce that a bit.
+	textarea.style.width = iframe.style.width;
+ 	textarea.style.height = iframe.style.height;
+
+	// IMPORTANT: we have to allow Mozilla a short time to recognize the
+	// new frame.  Otherwise we get a stupid exception.
+	function initIframe() {
+		var doc = editor._iframe.contentWindow.document;
+		if (!doc) {
+			// Try again..
+			// FIXME: don't know what else to do here.  Normally
+			// we'll never reach this point.
+			if (HTMLArea.is_gecko) {
+				setTimeout(initIframe, 100);
+				return false;
+			} else {
+				alert("ERROR: IFRAME can't be initialized.");
+			}
+		}
+		if (HTMLArea.is_gecko) {
+			// enable editable mode for Mozilla
+			doc.designMode = "on";
+		}
+		editor._doc = doc;
+		if (!editor.config.fullPage) {
+			doc.open();
+			var html = "<html>\n";
+			html += "<head>\n";
+			if (editor.config.baseURL)
+				html += '<base href="' + editor.config.baseURL + '" />';
+			html += "<style>" + editor.config.pageStyle +
+				" html,body { border: 0px; }</style>\n";
+			html += "</head>\n";
+			html += "<body>\n";
+			html += editor._textArea.value;
+			html += "</body>\n";
+			html += "</html>";
+			doc.write(html);
+			doc.close();
+		} else {
+			var html = editor._textArea.value;
+			if (html.match(HTMLArea.RE_doctype)) {
+				editor.setDoctype(RegExp.$1);
+				html = html.replace(HTMLArea.RE_doctype, "");
+			}
+			doc.open();
+			doc.write(html);
+			doc.close();
+		}
+
+		if (HTMLArea.is_ie) {
+			// enable editable mode for IE.	 For some reason this
+			// doesn't work if done in the same place as for Gecko
+			// (above).
+			doc.body.contentEditable = true;
+		}
+
+		editor.focusEditor();
+		// intercept some events; for updating the toolbar & keyboard handlers
+		HTMLArea._addEvents
+			(doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"],
+			 function (event) {
+				 return editor._editorEvent(HTMLArea.is_ie ? editor._iframe.contentWindow.event : event);
+			 });
+
+		// check if any plugins have registered refresh handlers
+		for (var i in editor.plugins) {
+			var plugin = editor.plugins[i].instance;
+			if (typeof plugin.onGenerate == "function")
+				plugin.onGenerate();
+			if (typeof plugin.onGenerateOnce == "function") {
+				plugin.onGenerateOnce();
+				plugin.onGenerateOnce = null;
+			}
+		}
+
+		setTimeout(function() {
+			editor.updateToolbar();
+		}, 250);
+
+		if (typeof editor.onGenerate == "function")
+			editor.onGenerate();
+	};
+	setTimeout(initIframe, 100);
+};
+
+// Switches editor mode; parameter can be "textmode" or "wysiwyg".  If no
+// parameter was passed this function toggles between modes.
+HTMLArea.prototype.setMode = function(mode) {
+	if (typeof mode == "undefined") {
+		mode = ((this._editMode == "textmode") ? "wysiwyg" : "textmode");
+	}
+	switch (mode) {
+	    case "textmode":
+		this._textArea.value = this.getHTML();
+		this._iframe.style.display = "none";
+		this._textArea.style.display = "block";
+		if (this.config.statusBar) {
+			this._statusBar.innerHTML = HTMLArea.I18N.msg["TEXT_MODE"];
+		}
+		break;
+	    case "wysiwyg":
+		if (HTMLArea.is_gecko) {
+			// disable design mode before changing innerHTML
+			try {
+				this._doc.designMode = "off";
+			} catch(e) {};
+		}
+		if (!this.config.fullPage)
+			this._doc.body.innerHTML = this.getHTML();
+		else
+			this.setFullHTML(this.getHTML());
+		this._iframe.style.display = "block";
+		this._textArea.style.display = "none";
+		if (HTMLArea.is_gecko) {
+			// we need to refresh that info for Moz-1.3a
+			try {
+				this._doc.designMode = "on";
+			} catch(e) {};
+		}
+		if (this.config.statusBar) {
+			this._statusBar.innerHTML = '';
+			this._statusBar.appendChild(document.createTextNode(HTMLArea.I18N.msg["Path"] + ": "));
+			this._statusBar.appendChild(this._statusBarTree);
+		}
+		break;
+	    default:
+		alert("Mode <" + mode + "> not defined!");
+		return false;
+	}
+	this._editMode = mode;
+	this.focusEditor();
+
+	for (var i in this.plugins) {
+		var plugin = this.plugins[i].instance;
+		if (typeof plugin.onMode == "function") plugin.onMode(mode);
+	}
+};
+
+HTMLArea.prototype.setFullHTML = function(html) {
+	var save_multiline = RegExp.multiline;
+	RegExp.multiline = true;
+	if (html.match(HTMLArea.RE_doctype)) {
+		this.setDoctype(RegExp.$1);
+		html = html.replace(HTMLArea.RE_doctype, "");
+	}
+	RegExp.multiline = save_multiline;
+	if (!HTMLArea.is_ie) {
+		if (html.match(HTMLArea.RE_head))
+			this._doc.getElementsByTagName("head")[0].innerHTML = RegExp.$1;
+		if (html.match(HTMLArea.RE_body))
+			this._doc.getElementsByTagName("body")[0].innerHTML = RegExp.$1;
+	} else {
+		var html_re = /<html>((.|\n)*?)<\/html>/i;
+		html = html.replace(html_re, "$1");
+		this._doc.open();
+		this._doc.write(html);
+		this._doc.close();
+		this._doc.body.contentEditable = true;
+		return true;
+	}
+};
+
+/***************************************************
+ *  Category: PLUGINS
+ ***************************************************/
+
+// this is the variant of the function above where the plugin arguments are
+// already packed in an array.  Externally, it should be only used in the
+// full-screen editor code, in order to initialize plugins with the same
+// parameters as in the opener window.
+HTMLArea.prototype.registerPlugin2 = function(plugin, args) {
+	if (typeof plugin == "string")
+		plugin = eval(plugin);
+	if (typeof plugin == "undefined") {
+		/* FIXME: This should never happen. But why does it do? */
+		return false;
+	}
+	var obj = new plugin(this, args);
+	if (obj) {
+		var clone = {};
+		var info = plugin._pluginInfo;
+		for (var i in info)
+			clone[i] = info[i];
+		clone.instance = obj;
+		clone.args = args;
+		this.plugins[plugin._pluginInfo.name] = clone;
+	} else
+		alert("Can't register plugin " + plugin.toString() + ".");
+};
+
+// Create the specified plugin and register it with this HTMLArea
+HTMLArea.prototype.registerPlugin = function() {
+	var plugin = arguments[0];
+	var args = [];
+	for (var i = 1; i < arguments.length; ++i)
+		args.push(arguments[i]);
+	this.registerPlugin2(plugin, args);
+};
+
+// static function that loads the required plugin and lang file, based on the
+// language loaded already for HTMLArea.  You better make sure that the plugin
+// _has_ that language, otherwise shit might happen ;-)
+HTMLArea.loadPlugin = function(pluginName) {
+	var dir = _editor_url + "plugins/" + pluginName;
+	var plugin = pluginName.replace(/([a-z])([A-Z])([a-z])/g,
+					function (str, l1, l2, l3) {
+						return l1 + "-" + l2.toLowerCase() + l3;
+					}).toLowerCase() + ".js";
+	var plugin_file = dir + "/" + plugin;
+	var plugin_lang = dir + "/lang/" + HTMLArea.I18N.lang + ".js";
+	HTMLArea._scripts.push(plugin_file, plugin_lang);
+	document.write("<script type='text/javascript' src='" + plugin_file + "'></script>");
+	document.write("<script type='text/javascript' src='" + plugin_lang + "'></script>");
+};
+
+HTMLArea.loadStyle = function(style, plugin) {
+	var url = _editor_url || '';
+	if (typeof plugin != "undefined") {
+		url += "plugins/" + plugin + "/";
+	}
+	url += style;
+	document.write("<style type='text/css'>@import url(" + url + ");</style>");
+};
+HTMLArea.loadStyle("htmlarea.css");
+
+/***************************************************
+ *  Category: EDITOR UTILITIES
+ ***************************************************/
+
+// The following function is a slight variation of the word cleaner code posted
+// by Weeezl (user @ InteractiveTools forums).
+HTMLArea.prototype._wordClean = function() {
+	var D = this.getInnerHTML();
+	if (D.indexOf('class=Mso') >= 0) {
+
+		// make one line
+		D = D.replace(/\r\n/g, ' ').
+			replace(/\n/g, ' ').
+			replace(/\r/g, ' ').
+			replace(/\&nbsp\;/g,' ');
+
+		// keep tags, strip attributes
+		D = D.replace(/ class=[^\s|>]*/gi,'').
+			//replace(/<p [^>]*TEXT-ALIGN: justify[^>]*>/gi,'<p align="justify">').
+			replace(/ style=\"[^>]*\"/gi,'').
+			replace(/ align=[^\s|>]*/gi,'');
+
+		//clean up tags
+		D = D.replace(/<b [^>]*>/gi,'<b>').
+			replace(/<i [^>]*>/gi,'<i>').
+			replace(/<li [^>]*>/gi,'<li>').
+			replace(/<ul [^>]*>/gi,'<ul>');
+
+		// replace outdated tags
+		D = D.replace(/<b>/gi,'<strong>').
+			replace(/<\/b>/gi,'</strong>');
+
+		// mozilla doesn't like <em> tags
+		D = D.replace(/<em>/gi,'<i>').
+			replace(/<\/em>/gi,'</i>');
+
+		// kill unwanted tags
+		D = D.replace(/<\?xml:[^>]*>/g, '').       // Word xml
+			replace(/<\/?st1:[^>]*>/g,'').     // Word SmartTags
+			replace(/<\/?[a-z]\:[^>]*>/g,'').  // All other funny Word non-HTML stuff
+			replace(/<\/?font[^>]*>/gi,'').    // Disable if you want to keep font formatting
+			replace(/<\/?span[^>]*>/gi,' ').
+			replace(/<\/?div[^>]*>/gi,' ').
+			replace(/<\/?pre[^>]*>/gi,' ').
+			replace(/<\/?h[1-6][^>]*>/gi,' ');
+
+		//remove empty tags
+		//D = D.replace(/<strong><\/strong>/gi,'').
+		//replace(/<i><\/i>/gi,'').
+		//replace(/<P[^>]*><\/P>/gi,'');
+
+		// nuke double tags
+		oldlen = D.length + 1;
+		while(oldlen > D.length) {
+			oldlen = D.length;
+			// join us now and free the tags, we'll be free hackers, we'll be free... ;-)
+			D = D.replace(/<([a-z][a-z]*)> *<\/\1>/gi,' ').
+				replace(/<([a-z][a-z]*)> *<([a-z][^>]*)> *<\/\1>/gi,'<$2>');
+		}
+		D = D.replace(/<([a-z][a-z]*)><\1>/gi,'<$1>').
+			replace(/<\/([a-z][a-z]*)><\/\1>/gi,'<\/$1>');
+
+		// nuke double spaces
+		D = D.replace(/  */gi,' ');
+
+		this.setHTML(D);
+		this.updateToolbar();
+	}
+};
+
+HTMLArea.prototype.forceRedraw = function() {
+	this._doc.body.style.visibility = "hidden";
+	this._doc.body.style.visibility = "visible";
+	// this._doc.body.innerHTML = this.getInnerHTML();
+};
+
+// focuses the iframe window.  returns a reference to the editor document.
+HTMLArea.prototype.focusEditor = function() {
+	return this._doc;
+	/*
+	switch (this._editMode) {
+	    // notice the try { ... } catch block to avoid some rare exceptions in FireFox
+	    // (perhaps also in other Gecko browsers). Manual focus by user is required in
+        // case of an error. Somebody has an idea?
+	    case "wysiwyg" : try { this._iframe.contentWindow.focus() } catch (e) {} break;
+	    case "textmode": try { this._textArea.focus() } catch (e) {} break;
+	    default	   : alert("ERROR: mode " + this._editMode + " is not defined");
+	}
+	return this._doc;
+	*/
+};
+
+// takes a snapshot of the current text (for undo)
+HTMLArea.prototype._undoTakeSnapshot = function() {
+	++this._undoPos;
+	if (this._undoPos >= this.config.undoSteps) {
+		// remove the first element
+		this._undoQueue.shift();
+		--this._undoPos;
+	}
+	// use the fasted method (getInnerHTML);
+	var take = true;
+	var txt = this.getInnerHTML();
+	if (this._undoPos > 0)
+		take = (this._undoQueue[this._undoPos - 1] != txt);
+	if (take) {
+		this._undoQueue[this._undoPos] = txt;
+	} else {
+		this._undoPos--;
+	}
+};
+
+HTMLArea.prototype.undo = function() {
+	if (this._undoPos > 0) {
+		var txt = this._undoQueue[--this._undoPos];
+		if (txt) this.setHTML(txt);
+		else ++this._undoPos;
+	}
+};
+
+HTMLArea.prototype.redo = function() {
+	if (this._undoPos < this._undoQueue.length - 1) {
+		var txt = this._undoQueue[++this._undoPos];
+		if (txt) this.setHTML(txt);
+		else --this._undoPos;
+	}
+};
+
+// updates enabled/disable/active state of the toolbar elements
+HTMLArea.prototype.updateToolbar = function(noStatus) {
+	var doc = this._doc;
+	var text = (this._editMode == "textmode");
+	var ancestors = null;
+	if (!text) {
+		ancestors = this.getAllAncestors();
+		if (this.config.statusBar && !noStatus) {
+			this._statusBarTree.innerHTML = HTMLArea.I18N.msg["Path"] + ": "; // clear
+			for (var i = ancestors.length; --i >= 0;) {
+				var el = ancestors[i];
+				if (!el) {
+					// hell knows why we get here; this
+					// could be a classic example of why
+					// it's good to check for conditions
+					// that are impossible to happen ;-)
+					continue;
+				}
+				var a = document.createElement("a");
+				a.href = "#";
+				a.el = el;
+				a.editor = this;
+				a.onclick = function() {
+					this.blur();
+					this.editor.selectNodeContents(this.el);
+					this.editor.updateToolbar(true);
+					return false;
+				};
+				a.oncontextmenu = function() {
+					// TODO: add context menu here
+					this.blur();
+					var info = "Inline style:\n\n";
+					info += this.el.style.cssText.split(/;\s*/).join(";\n");
+					alert(info);
+					return false;
+				};
+				var txt = el.tagName.toLowerCase();
+				a.title = el.style.cssText;
+				if (el.id) {
+					txt += "#" + el.id;
+				}
+				if (el.className) {
+					txt += "." + el.className;
+				}
+				a.appendChild(document.createTextNode(txt));
+				this._statusBarTree.appendChild(a);
+				if (i != 0) {
+					this._statusBarTree.appendChild(document.createTextNode(String.fromCharCode(0xbb)));
+				}
+			}
+		}
+	}
+
+	for (var i in this._toolbarObjects) {
+		var btn = this._toolbarObjects[i];
+		var cmd = i;
+		var inContext = true;
+		if (btn.context && !text) {
+			inContext = false;
+			var context = btn.context;
+			var attrs = [];
+			if (/(.*)\[(.*?)\]/.test(context)) {
+				context = RegExp.$1;
+				attrs = RegExp.$2.split(",");
+			}
+			context = context.toLowerCase();
+			var match = (context == "*");
+			for (var k in ancestors) {
+				if (!ancestors[k]) {
+					// the impossible really happens.
+					continue;
+				}
+				if (match || (ancestors[k].tagName.toLowerCase() == context)) {
+					inContext = true;
+					for (var ka in attrs) {
+						if (!eval("ancestors[k]." + attrs[ka])) {
+							inContext = false;
+							break;
+						}
+					}
+					if (inContext) {
+						break;
+					}
+				}
+			}
+		}
+		btn.state("enabled", (!text || btn.text) && inContext);
+		if (typeof cmd == "function") {
+			continue;
+		}
+		// look-it-up in the custom dropdown boxes
+		var dropdown = this.config.customSelects[cmd];
+		if ((!text || btn.text) && (typeof dropdown != "undefined")) {
+			dropdown.refresh(this);
+			continue;
+		}
+		switch (cmd) {
+		    case "fontname":
+		    case "fontsize":
+		    case "formatblock":
+			if (!text) try {
+				var value = ("" + doc.queryCommandValue(cmd)).toLowerCase();
+				if (!value) {
+					// FIXME: what do we do here?
+					break;
+				}
+				// HACK -- retrieve the config option for this
+				// combo box.  We rely on the fact that the
+				// variable in config has the same name as
+				// button name in the toolbar.
+				var options = this.config[cmd];
+				var k = 0;
+				// btn.element.selectedIndex = 0;
+				for (var j in options) {
+					// FIXME: the following line is scary.
+					if ((j.toLowerCase() == value) ||
+					    (options[j].substr(0, value.length).toLowerCase() == value)) {
+						btn.element.selectedIndex = k;
+						break;
+					}
+					++k;
+				}
+			} catch(e) {};
+			break;
+		    case "textindicator":
+			if (!text) {
+				try {with (btn.element.style) {
+					backgroundColor = HTMLArea._makeColor(
+						doc.queryCommandValue(HTMLArea.is_ie ? "backcolor" : "hilitecolor"));
+					if (/transparent/i.test(backgroundColor)) {
+						// Mozilla
+						backgroundColor = HTMLArea._makeColor(doc.queryCommandValue("backcolor"));
+					}
+					color = HTMLArea._makeColor(doc.queryCommandValue("forecolor"));
+					fontFamily = doc.queryCommandValue("fontname");
+					fontWeight = doc.queryCommandState("bold") ? "bold" : "normal";
+					fontStyle = doc.queryCommandState("italic") ? "italic" : "normal";
+				}} catch (e) {
+					// alert(e + "\n\n" + cmd);
+				}
+			}
+			break;
+		    case "htmlmode": btn.state("active", text); break;
+		    case "lefttoright":
+		    case "righttoleft":
+			var el = this.getParentElement();
+			while (el && !HTMLArea.isBlockElement(el))
+				el = el.parentNode;
+			if (el)
+				btn.state("active", (el.style.direction == ((cmd == "righttoleft") ? "rtl" : "ltr")));
+			break;
+		    default:
+			cmd = cmd.replace(/(un)?orderedlist/i, "insert$1orderedlist");
+			try {
+				btn.state("active", (!text && doc.queryCommandState(cmd)));
+			} catch (e) {}
+		}
+	}
+	// take undo snapshots
+	if (this._customUndo && !this._timerUndo) {
+		this._undoTakeSnapshot();
+		var editor = this;
+		this._timerUndo = setTimeout(function() {
+			editor._timerUndo = null;
+		}, this.config.undoTimeout);
+	}
+
+	// check if any plugins have registered refresh handlers
+	for (var i in this.plugins) {
+		var plugin = this.plugins[i].instance;
+		if (typeof plugin.onUpdateToolbar == "function")
+			plugin.onUpdateToolbar();
+	}
+};
+
+/** Returns a node after which we can insert other nodes, in the current
+ * selection.  The selection is removed.  It splits a text node, if needed.
+ */
+HTMLArea.prototype.insertNodeAtSelection = function(toBeInserted) {
+	if (!HTMLArea.is_ie) {
+		var sel = this._getSelection();
+		var range = this._createRange(sel);
+		// remove the current selection
+		sel.removeAllRanges();
+		range.deleteContents();
+		var node = range.startContainer;
+		var pos = range.startOffset;
+		switch (node.nodeType) {
+		    case 3: // Node.TEXT_NODE
+			// we have to split it at the caret position.
+			if (toBeInserted.nodeType == 3) {
+				// do optimized insertion
+				node.insertData(pos, toBeInserted.data);
+				range = this._createRange();
+				range.setEnd(node, pos + toBeInserted.length);
+				range.setStart(node, pos + toBeInserted.length);
+				sel.addRange(range);
+			} else {
+				node = node.splitText(pos);
+				var selnode = toBeInserted;
+				if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
+					selnode = selnode.firstChild;
+				}
+				node.parentNode.insertBefore(toBeInserted, node);
+				this.selectNodeContents(selnode);
+				this.updateToolbar();
+			}
+			break;
+		    case 1: // Node.ELEMENT_NODE
+			var selnode = toBeInserted;
+			if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
+				selnode = selnode.firstChild;
+			}
+			node.insertBefore(toBeInserted, node.childNodes[pos]);
+			this.selectNodeContents(selnode);
+			this.updateToolbar();
+			break;
+		}
+	} else {
+		return null;	// this function not yet used for IE <FIXME>
+	}
+};
+
+// Returns the deepest node that contains both endpoints of the selection.
+HTMLArea.prototype.getParentElement = function() {
+	var sel = this._getSelection();
+	var range = this._createRange(sel);
+	if (HTMLArea.is_ie) {
+		switch (sel.type) {
+		    case "Text":
+		    case "None":
+			// It seems that even for selection of type "None",
+			// there _is_ a parent element and it's value is not
+			// only correct, but very important to us.  MSIE is
+			// certainly the buggiest browser in the world and I
+			// wonder, God, how can Earth stand it?
+			return range.parentElement();
+		    case "Control":
+			return range.item(0);
+		    default:
+			return this._doc.body;
+		}
+	} else try {
+		var p = range.commonAncestorContainer;
+		if (!range.collapsed && range.startContainer == range.endContainer &&
+		    range.startOffset - range.endOffset <= 1 && range.startContainer.hasChildNodes())
+			p = range.startContainer.childNodes[range.startOffset];
+		/*
+		alert(range.startContainer + ":" + range.startOffset + "\n" +
+		      range.endContainer + ":" + range.endOffset);
+		*/
+		while (p.nodeType == 3) {
+			p = p.parentNode;
+		}
+		return p;
+	} catch (e) {
+		return null;
+	}
+};
+
+// Returns an array with all the ancestor nodes of the selection.
+HTMLArea.prototype.getAllAncestors = function() {
+	var p = this.getParentElement();
+	var a = [];
+	while (p && (p.nodeType == 1) && (p.tagName.toLowerCase() != 'body')) {
+		a.push(p);
+		p = p.parentNode;
+	}
+	a.push(this._doc.body);
+	return a;
+};
+
+// Selects the contents inside the given node
+HTMLArea.prototype.selectNodeContents = function(node, pos) {
+	this.focusEditor();
+	this.forceRedraw();
+	var range;
+	var collapsed = (typeof pos != "undefined");
+	if (HTMLArea.is_ie) {
+		range = this._doc.body.createTextRange();
+		range.moveToElementText(node);
+		(collapsed) && range.collapse(pos);
+		range.select();
+	} else {
+		var sel = this._getSelection();
+		range = this._doc.createRange();
+		range.selectNodeContents(node);
+		(collapsed) && range.collapse(pos);
+		sel.removeAllRanges();
+		sel.addRange(range);
+	}
+};
+
+/** Call this function to insert HTML code at the current position.  It deletes
+ * the selection, if any.
+ */
+HTMLArea.prototype.insertHTML = function(html) {
+	var sel = this._getSelection();
+	var range = this._createRange(sel);
+	if (HTMLArea.is_ie) {
+		range.pasteHTML(html);
+	} else {
+		// construct a new document fragment with the given HTML
+		var fragment = this._doc.createDocumentFragment();
+		var div = this._doc.createElement("div");
+		div.innerHTML = html;
+		while (div.firstChild) {
+			// the following call also removes the node from div
+			fragment.appendChild(div.firstChild);
+		}
+		// this also removes the selection
+		var node = this.insertNodeAtSelection(fragment);
+	}
+};
+
+/**
+ *  Call this function to surround the existing HTML code in the selection with
+ *  your tags.  FIXME: buggy!  This function will be deprecated "soon".
+ */
+HTMLArea.prototype.surroundHTML = function(startTag, endTag) {
+	var html = this.getSelectedHTML();
+	// the following also deletes the selection
+	this.insertHTML(startTag + html + endTag);
+};
+
+/// Retrieve the selected block
+HTMLArea.prototype.getSelectedHTML = function() {
+	var sel = this._getSelection();
+	var range = this._createRange(sel);
+	var existing = null;
+	if (HTMLArea.is_ie) {
+		existing = range.htmlText;
+	} else {
+		existing = HTMLArea.getHTML(range.cloneContents(), false, this);
+	}
+	return existing;
+};
+
+/// Return true if we have some selection
+HTMLArea.prototype.hasSelectedText = function() {
+	// FIXME: come _on_ mishoo, you can do better than this ;-)
+	return this.getSelectedHTML() != '';
+};
+
+HTMLArea.prototype._createLink = function(link) {
+	var editor = this;
+	var outparam = null;
+	if (typeof link == "undefined") {
+		link = this.getParentElement();
+		if (link && !/^a$/i.test(link.tagName))
+			link = null;
+	}
+	if (link) outparam = {
+		f_href   : HTMLArea.is_ie ? editor.stripBaseURL(link.href) : link.getAttribute("href"),
+		f_title  : link.title,
+		f_target : link.target
+	};
+	this._popupDialog("link.html", function(param) {
+		if (!param)
+			return false;
+		var a = link;
+		if (!a) try {
+			editor._doc.execCommand("createlink", false, param.f_href);
+			a = editor.getParentElement();
+			var sel = editor._getSelection();
+			var range = editor._createRange(sel);
+			if (!HTMLArea.is_ie) {
+				a = range.startContainer;
+				if (!/^a$/i.test(a.tagName)) {
+					a = a.nextSibling;
+					if (a == null)
+						a = range.startContainer.parentNode;
+				}
+			}
+		} catch(e) {}
+		else {
+			var href = param.f_href.trim();
+			editor.selectNodeContents(a);
+			if (href == "") {
+				editor._doc.execCommand("unlink", false, null);
+				editor.updateToolbar();
+				return false;
+			}
+			else {
+				a.href = href;
+			}
+		}
+		if (!(a && /^a$/i.test(a.tagName)))
+			return false;
+		a.target = param.f_target.trim();
+		a.title = param.f_title.trim();
+		editor.selectNodeContents(a);
+		editor.updateToolbar();
+	}, outparam);
+};
+
+// Called when the user clicks on "InsertImage" button.  If an image is already
+// there, it will just modify it's properties.
+HTMLArea.prototype._insertImage = function(image) {
+	var editor = this;	// for nested functions
+	var outparam = null;
+	if (typeof image == "undefined") {
+		image = this.getParentElement();
+		if (image && !/^img$/i.test(image.tagName))
+			image = null;
+	}
+	if (image) outparam = {
+		f_url    : HTMLArea.is_ie ? editor.stripBaseURL(image.src) : image.getAttribute("src"),
+		f_alt    : image.alt,
+		f_border : image.border,
+		f_align  : image.align,
+		f_vert   : image.vspace,
+		f_horiz  : image.hspace
+	};
+	this._popupDialog("insert_image.html", function(param) {
+		if (!param) {	// user must have pressed Cancel
+			return false;
+		}
+		var img = image;
+		if (!img) {
+			var sel = editor._getSelection();
+			var range = editor._createRange(sel);
+			editor._doc.execCommand("insertimage", false, param.f_url);
+			if (HTMLArea.is_ie) {
+				img = range.parentElement();
+				// wonder if this works...
+				if (img.tagName.toLowerCase() != "img") {
+					img = img.previousSibling;
+				}
+			} else {
+				img = range.startContainer.previousSibling;
+			}
+		} else {
+			img.src = param.f_url;
+		}
+
+		for (field in param) {
+			var value = param[field];
+			switch (field) {
+			    case "f_alt"    : img.alt	 = value; break;
+			    case "f_border" : img.border = parseInt(value || "0"); break;
+			    case "f_align"  : img.align	 = value; break;
+			    case "f_vert"   : img.vspace = parseInt(value || "0"); break;
+			    case "f_horiz"  : img.hspace = parseInt(value || "0"); break;
+			}
+		}
+	}, outparam);
+};
+
+// Called when the user clicks the Insert Table button
+HTMLArea.prototype._insertTable = function() {
+	var sel = this._getSelection();
+	var range = this._createRange(sel);
+	var editor = this;	// for nested functions
+	this._popupDialog("insert_table.html", function(param) {
+		if (!param) {	// user must have pressed Cancel
+			return false;
+		}
+		var doc = editor._doc;
+		// create the table element
+		var table = doc.createElement("table");
+		// assign the given arguments
+
+		for (var field in param) {
+			var value = param[field];
+			if (!value) {
+				continue;
+			}
+			switch (field) {
+			    case "f_width"   : table.style.width = value + param["f_unit"]; break;
+			    case "f_align"   : table.align	 = value; break;
+			    case "f_border"  : table.border	 = parseInt(value); break;
+			    case "f_spacing" : table.cellSpacing = parseInt(value); break;
+			    case "f_padding" : table.cellPadding = parseInt(value); break;
+			}
+		}
+		var tbody = doc.createElement("tbody");
+		table.appendChild(tbody);
+		for (var i = 0; i < param["f_rows"]; ++i) {
+			var tr = doc.createElement("tr");
+			tbody.appendChild(tr);
+			for (var j = 0; j < param["f_cols"]; ++j) {
+				var td = doc.createElement("td");
+				tr.appendChild(td);
+				// Mozilla likes to see something inside the cell.
+				(HTMLArea.is_gecko) && td.appendChild(doc.createElement("br"));
+			}
+		}
+		if (HTMLArea.is_ie) {
+			range.pasteHTML(table.outerHTML);
+		} else {
+			// insert the table
+			editor.insertNodeAtSelection(table);
+		}
+		return true;
+	}, null);
+};
+
+/***************************************************
+ *  Category: EVENT HANDLERS
+ ***************************************************/
+
+// el is reference to the SELECT object
+// txt is the name of the select field, as in config.toolbar
+HTMLArea.prototype._comboSelected = function(el, txt) {
+	this.focusEditor();
+	var value = el.options[el.selectedIndex].value;
+	switch (txt) {
+	    case "fontname":
+	    case "fontsize": this.execCommand(txt, false, value); break;
+	    case "formatblock":
+		(HTMLArea.is_ie) && (value = "<" + value + ">");
+		this.execCommand(txt, false, value);
+		break;
+	    default:
+		// try to look it up in the registered dropdowns
+		var dropdown = this.config.customSelects[txt];
+		if (typeof dropdown != "undefined") {
+			dropdown.action(this);
+		} else {
+			alert("FIXME: combo box " + txt + " not implemented");
+		}
+	}
+};
+
+// the execCommand function (intercepts some commands and replaces them with
+// our own implementation)
+HTMLArea.prototype.execCommand = function(cmdID, UI, param) {
+	var editor = this;	// for nested functions
+	this.focusEditor();
+	cmdID = cmdID.toLowerCase();
+	switch (cmdID) {
+	    case "htmlmode" : this.setMode(); break;
+	    case "hilitecolor":
+		(HTMLArea.is_ie) && (cmdID = "backcolor");
+	    case "forecolor":
+		this._popupDialog("select_color.html", function(color) {
+			if (color) { // selection not canceled
+				editor._doc.execCommand(cmdID, false, "#" + color);
+			}
+		}, HTMLArea._colorToRgb(this._doc.queryCommandValue(cmdID)));
+		break;
+	    case "createlink":
+		this._createLink();
+		break;
+	    case "popupeditor":
+		// this object will be passed to the newly opened window
+		HTMLArea._object = this;
+		if (HTMLArea.is_ie) {
+			//if (confirm(HTMLArea.I18N.msg["IE-sucks-full-screen"]))
+			{
+				window.open(this.popupURL("fullscreen.html"), "ha_fullscreen",
+					    "toolbar=no,location=no,directories=no,status=no,menubar=no," +
+					    "scrollbars=no,resizable=yes,width=640,height=480");
+			}
+		} else {
+			window.open(this.popupURL("fullscreen.html"), "ha_fullscreen",
+				    "toolbar=no,menubar=no,personalbar=no,width=640,height=480," +
+				    "scrollbars=no,resizable=yes");
+		}
+		break;
+	    case "undo":
+	    case "redo":
+		if (this._customUndo)
+			this[cmdID]();
+		else
+			this._doc.execCommand(cmdID, UI, param);
+		break;
+	    case "inserttable": this._insertTable(); break;
+	    case "insertimage": this._insertImage(); break;
+	    case "about"    : this._popupDialog("about.html", null, this); break;
+	    case "showhelp" : window.open(_editor_url + "reference.html", "ha_help"); break;
+
+	    case "killword": this._wordClean(); break;
+
+	    case "cut":
+	    case "copy":
+	    case "paste":
+		try {
+			if (this.config.killWordOnPaste)
+				this._wordClean();
+			this._doc.execCommand(cmdID, UI, param);
+		} catch (e) {
+			if (HTMLArea.is_gecko) {
+				if (typeof HTMLArea.I18N.msg["Moz-Clipboard"] == "undefined") {
+					HTMLArea.I18N.msg["Moz-Clipboard"] =
+						"Unprivileged scripts cannot access Cut/Copy/Paste programatically " +
+						"for security reasons.  Click OK to see a technical note at mozilla.org " +
+						"which shows you how to allow a script to access the clipboard.\n\n" +
+						"[FIXME: please translate this message in your language definition file.]";
+				}
+				if (confirm(HTMLArea.I18N.msg["Moz-Clipboard"]))
+					window.open("http://mozilla.org/editor/midasdemo/securityprefs.html");
+			}
+		}
+		break;
+	    case "lefttoright":
+	    case "righttoleft":
+		var dir = (cmdID == "righttoleft") ? "rtl" : "ltr";
+		var el = this.getParentElement();
+		while (el && !HTMLArea.isBlockElement(el))
+			el = el.parentNode;
+		if (el) {
+			if (el.style.direction == dir)
+				el.style.direction = "";
+			else
+				el.style.direction = dir;
+		}
+		break;
+	    default: this._doc.execCommand(cmdID, UI, param);
+	}
+	this.updateToolbar();
+	return false;
+};
+
+/** A generic event handler for things that happen in the IFRAME's document.
+ * This function also handles key bindings. */
+HTMLArea.prototype._editorEvent = function(ev) {
+	var editor = this;
+	var keyEvent = (HTMLArea.is_ie && ev.type == "keydown") || (ev.type == "keypress");
+
+	if (keyEvent) {
+		for (var i in editor.plugins) {
+			var plugin = editor.plugins[i].instance;
+			if (typeof plugin.onKeyPress == "function") plugin.onKeyPress(ev);
+		}
+	}
+	if (keyEvent && ev.ctrlKey && !ev.altKey) {
+		var sel = null;
+		var range = null;
+		var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
+		var cmd = null;
+		var value = null;
+		switch (key) {
+		    case 'a':
+			if (!HTMLArea.is_ie) {
+				// KEY select all
+				sel = this._getSelection();
+				sel.removeAllRanges();
+				range = this._createRange();
+				range.selectNodeContents(this._doc.body);
+				sel.addRange(range);
+				HTMLArea._stopEvent(ev);
+			}
+			break;
+
+			// simple key commands follow
+
+		    case 'b': cmd = "bold"; break;
+		    case 'i': cmd = "italic"; break;
+		    case 'u': cmd = "underline"; break;
+		    case 's': cmd = "strikethrough"; break;
+		    case 'l': cmd = "justifyleft"; break;
+		    case 'e': cmd = "justifycenter"; break;
+		    case 'r': cmd = "justifyright"; break;
+		    case 'j': cmd = "justifyfull"; break;
+		    case 'z': cmd = "undo"; break;
+		    case 'y': cmd = "redo"; break;
+		    //case 'v': cmd = "paste"; break;
+
+		    case '0': cmd = "killword"; break;
+
+			// headings
+		    case '1':
+		    case '2':
+		    case '3':
+		    case '4':
+		    case '5':
+		    case '6':
+			cmd = "formatblock";
+			value = "h" + key;
+			if (HTMLArea.is_ie) {
+				value = "<" + value + ">";
+			}
+			break;
+		}
+		if (cmd) {
+			// execute simple command
+			this.execCommand(cmd, false, value);
+			HTMLArea._stopEvent(ev);
+		}
+	}
+	
+	else if (keyEvent) {
+		// other keys here
+		switch (ev.keyCode) {
+		    case 13: // KEY enter
+			if (HTMLArea.is_ie) {	
+				HTMLArea._stopEvent(ev);
+				this.insertHTML("<br>&nbsp;");
+			}
+			break;
+		}
+	}
+	
+	// update the toolbar state after some time
+	if (editor._timerToolbar) {
+		clearTimeout(editor._timerToolbar);
+	}
+	editor._timerToolbar = setTimeout(function() {
+		editor.updateToolbar();
+		editor._timerToolbar = null;
+	}, 50);
+};
+
+// retrieve the HTML
+HTMLArea.prototype.getHTML = function() {
+	switch (this._editMode) {
+	    case "wysiwyg"  :
+		if (!this.config.fullPage) {
+			return HTMLArea.getHTML(this._doc.body, false, this);
+		} else
+			return this.doctype + "\n" + HTMLArea.getHTML(this._doc.documentElement, true, this);
+	    case "textmode" : return this._textArea.value;
+	    default	    : alert("Mode <" + mode + "> not defined!");
+	}
+	return false;
+};
+
+// retrieve the HTML (fastest version, but uses innerHTML)
+HTMLArea.prototype.getInnerHTML = function() {
+	switch (this._editMode) {
+	    case "wysiwyg"  :
+		if (!this.config.fullPage)
+			return this._doc.body.innerHTML;
+		else
+			return this.doctype + "\n" + this._doc.documentElement.innerHTML;
+	    case "textmode" : return this._textArea.value;
+	    default	    : alert("Mode <" + mode + "> not defined!");
+	}
+	return false;
+};
+
+// completely change the HTML inside
+HTMLArea.prototype.setHTML = function(html) {
+	switch (this._editMode) {
+	    case "wysiwyg"  :
+		if (!this.config.fullPage)
+			this._doc.body.innerHTML = html;
+		else
+			// this._doc.documentElement.innerHTML = html;
+			this._doc.body.innerHTML = html;
+		break;
+	    case "textmode" : this._textArea.value = html; break;
+	    default	    : alert("Mode <" + mode + "> not defined!");
+	}
+	return false;
+};
+
+// sets the given doctype (useful when config.fullPage is true)
+HTMLArea.prototype.setDoctype = function(doctype) {
+	this.doctype = doctype;
+};
+
+/***************************************************
+ *  Category: UTILITY FUNCTIONS
+ ***************************************************/
+
+// browser identification
+
+HTMLArea.agt = navigator.userAgent.toLowerCase();
+HTMLArea.is_ie	   = ((HTMLArea.agt.indexOf("msie") != -1) && (HTMLArea.agt.indexOf("opera") == -1));
+HTMLArea.is_opera  = (HTMLArea.agt.indexOf("opera") != -1);
+HTMLArea.is_mac	   = (HTMLArea.agt.indexOf("mac") != -1);
+HTMLArea.is_mac_ie = (HTMLArea.is_ie && HTMLArea.is_mac);
+HTMLArea.is_win_ie = (HTMLArea.is_ie && !HTMLArea.is_mac);
+HTMLArea.is_gecko  = (navigator.product == "Gecko");
+
+// variable used to pass the object to the popup editor window.
+HTMLArea._object = null;
+
+// function that returns a clone of the given object
+HTMLArea.cloneObject = function(obj) {
+	var newObj = new Object;
+
+	// check for array objects
+	if (obj.constructor.toString().indexOf("function Array(") == 1) {
+		newObj = obj.constructor();
+	}
+
+	// check for function objects (as usual, IE is fucked up)
+	if (obj.constructor.toString().indexOf("function Function(") == 1) {
+		newObj = obj; // just copy reference to it
+	} else for (var n in obj) {
+		var node = obj[n];
+		if (typeof node == 'object') { newObj[n] = HTMLArea.cloneObject(node); }
+		else                         { newObj[n] = node; }
+	}
+
+	return newObj;
+};
+
+// FIXME!!! this should return false for IE < 5.5
+HTMLArea.checkSupportedBrowser = function() {
+	if (HTMLArea.is_gecko) {
+		if (navigator.productSub < 20021201) {
+			alert("You need at least Mozilla-1.3 Alpha.\n" +
+			      "Sorry, your Gecko is not supported.");
+			return false;
+		}
+		if (navigator.productSub < 20030210) {
+			alert("Mozilla < 1.3 Beta is not supported!\n" +
+			      "I'll try, though, but it might not work.");
+		}
+	}
+	return HTMLArea.is_gecko || HTMLArea.is_ie;
+};
+
+// selection & ranges
+
+// returns the current selection object
+HTMLArea.prototype._getSelection = function() {
+	if (HTMLArea.is_ie) {
+		return this._doc.selection;
+	} else {
+		return this._iframe.contentWindow.getSelection();
+	}
+};
+
+// returns a range for the current selection
+HTMLArea.prototype._createRange = function(sel) {
+	if (HTMLArea.is_ie) {
+		return sel.createRange();
+	} else {
+		this.focusEditor();
+		if (typeof sel != "undefined") {
+			try {
+				return sel.getRangeAt(0);
+			} catch(e) {
+				return this._doc.createRange();
+			}
+		} else {
+			return this._doc.createRange();
+		}
+	}
+};
+
+// event handling
+
+HTMLArea._addEvent = function(el, evname, func) {
+	if (HTMLArea.is_ie) {
+		el.attachEvent("on" + evname, func);
+	} else {
+		el.addEventListener(evname, func, true);
+	}
+};
+
+HTMLArea._addEvents = function(el, evs, func) {
+	for (var i in evs) {
+		HTMLArea._addEvent(el, evs[i], func);
+	}
+};
+
+HTMLArea._removeEvent = function(el, evname, func) {
+	if (HTMLArea.is_ie) {
+		el.detachEvent("on" + evname, func);
+	} else {
+		el.removeEventListener(evname, func, true);
+	}
+};
+
+HTMLArea._removeEvents = function(el, evs, func) {
+	for (var i in evs) {
+		HTMLArea._removeEvent(el, evs[i], func);
+	}
+};
+
+HTMLArea._stopEvent = function(ev) {
+	if (HTMLArea.is_ie) {
+		ev.cancelBubble = true;
+		ev.returnValue = false;
+	} else {
+		ev.preventDefault();
+		ev.stopPropagation();
+	}
+};
+
+HTMLArea._removeClass = function(el, className) {
+	if (!(el && el.className)) {
+		return;
+	}
+	var cls = el.className.split(" ");
+	var ar = new Array();
+	for (var i = cls.length; i > 0;) {
+		if (cls[--i] != className) {
+			ar[ar.length] = cls[i];
+		}
+	}
+	el.className = ar.join(" ");
+};
+
+HTMLArea._addClass = function(el, className) {
+	// remove the class first, if already there
+	HTMLArea._removeClass(el, className);
+	el.className += " " + className;
+};
+
+HTMLArea._hasClass = function(el, className) {
+	if (!(el && el.className)) {
+		return false;
+	}
+	var cls = el.className.split(" ");
+	for (var i = cls.length; i > 0;) {
+		if (cls[--i] == className) {
+			return true;
+		}
+	}
+	return false;
+};
+
+HTMLArea.isBlockElement = function(el) {
+	var blockTags = " body form textarea fieldset ul ol dl li div " +
+		"p h1 h2 h3 h4 h5 h6 quote pre table thead " +
+		"tbody tfoot tr td iframe address ";
+	return (blockTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
+};
+
+HTMLArea.needsClosingTag = function(el) {
+	var closingTags = " head script style div span tr td tbody table em strong font a title ";
+	return (closingTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
+};
+
+// performs HTML encoding of some given string
+HTMLArea.htmlEncode = function(str) {
+	// we don't need regexp for that, but.. so be it for now.
+	str = str.replace(/&/ig, "&amp;");
+	str = str.replace(/</ig, "&lt;");
+	str = str.replace(/>/ig, "&gt;");
+	str = str.replace(/\x22/ig, "&quot;");
+	// \x22 means '"' -- we use hex reprezentation so that we don't disturb
+	// JS compressors (well, at least mine fails.. ;)
+	return str;
+};
+
+// Retrieves the HTML code from the given node.	 This is a replacement for
+// getting innerHTML, using standard DOM calls.
+HTMLArea.getHTML = function(root, outputRoot, editor) {
+	var html = "";
+	switch (root.nodeType) {
+	    case 1: // Node.ELEMENT_NODE
+	    case 11: // Node.DOCUMENT_FRAGMENT_NODE
+		var closed;
+		var i;
+		var root_tag = (root.nodeType == 1) ? root.tagName.toLowerCase() : '';
+		if (HTMLArea.is_ie && root_tag == "head") {
+			if (outputRoot)
+				html += "<head>";
+			// lowercasize
+			var save_multiline = RegExp.multiline;
+			RegExp.multiline = true;
+			var txt = root.innerHTML.replace(HTMLArea.RE_tagName, function(str, p1, p2) {
+				return p1 + p2.toLowerCase();
+			});
+			RegExp.multiline = save_multiline;
+			html += txt;
+			if (outputRoot)
+				html += "</head>";
+			break;
+		} else if (outputRoot) {
+			closed = (!(root.hasChildNodes() || HTMLArea.needsClosingTag(root)));
+			html = "<" + root.tagName.toLowerCase();
+			var attrs = root.attributes;
+			for (i = 0; i < attrs.length; ++i) {
+				var a = attrs.item(i);
+				if (!a.specified) {
+					continue;
+				}
+				var name = a.nodeName.toLowerCase();
+				if (/_moz_editor_bogus_node/.test(name)) {
+					html = "";
+					break;
+				}
+				if (/_moz|contenteditable|_msh/.test(name)) {
+					// avoid certain attributes
+					continue;
+				}
+				var value;
+				if (name != "style") {
+					// IE5.5 reports 25 when cellSpacing is
+					// 1; other values might be doomed too.
+					// For this reason we extract the
+					// values directly from the root node.
+					// I'm starting to HATE JavaScript
+					// development.  Browser differences
+					// suck.
+					//
+					// Using Gecko the values of href and src are converted to absolute links
+					// unless we get them using nodeValue()
+					if (typeof root[a.nodeName] != "undefined" && name != "href" && name != "src") {
+						value = root[a.nodeName];
+					} else {
+						value = a.nodeValue;
+						// IE seems not willing to return the original values - it converts to absolute
+						// links using a.nodeValue, a.value, a.stringValue, root.getAttribute("href")
+						// So we have to strip the baseurl manually -/
+						if (HTMLArea.is_ie && (name == "href" || name == "src")) {
+							value = editor.stripBaseURL(value);
+						}
+					}
+				} else { // IE fails to put style in attributes list
+					// FIXME: cssText reported by IE is UPPERCASE
+					value = root.style.cssText;
+				}
+				if (/(_moz|^$)/.test(value)) {
+					// Mozilla reports some special tags
+					// here; we don't need them.
+					continue;
+				}
+				html += " " + name + '="' + value + '"';
+			}
+			if (html != "") {
+				html += closed ? " />" : ">";
+			}
+		}
+		for (i = root.firstChild; i; i = i.nextSibling) {
+			html += HTMLArea.getHTML(i, true, editor);
+		}
+		if (outputRoot && !closed) {
+			html += "</" + root.tagName.toLowerCase() + ">";
+		}
+		break;
+	    case 3: // Node.TEXT_NODE
+		// If a text node is alone in an element and all spaces, replace it with an non breaking one
+		// This partially undoes the damage done by moz, which translates '&nbsp;'s into spaces in the data element
+		if ( !root.previousSibling && !root.nextSibling && root.data.match(/^\s*$/i) ) html = '&nbsp;';
+		else html = /^script|style$/i.test(root.parentNode.tagName) ? root.data : HTMLArea.htmlEncode(root.data);
+		break;
+	    case 4: // Node.CDATA_SECTION_NODE
+		// FIXME: it seems we never get here, but I believe we should..
+		//        maybe a browser problem?--CDATA sections are converted to plain text nodes and normalized
+		// CDATA sections should go "as is" without further encoding
+		html = "<![CDATA[" + root.data + "]]>";
+		break;
+	    case 8: // Node.COMMENT_NODE
+		html = "<!--" + root.data + "-->";
+		break;		// skip comments, for now.
+	}
+	return html;
+};
+
+HTMLArea.prototype.stripBaseURL = function(string) {
+	var baseurl = this.config.baseURL;
+
+	// strip to last directory in case baseurl points to a file
+	baseurl = baseurl.replace(/[^\/]+$/, '');
+	var basere = new RegExp(baseurl);
+	string = string.replace(basere, "");
+
+	// strip host-part of URL which is added by MSIE to links relative to server root
+	baseurl = baseurl.replace(/^(https?:\/\/[^\/]+)(.*)$/, '$1');
+	basere = new RegExp(baseurl);
+	return string.replace(basere, "");
+};
+
+String.prototype.trim = function() {
+	a = this.replace(/^\s+/, '');
+	return a.replace(/\s+$/, '');
+};
+
+// creates a rgb-style color from a number
+HTMLArea._makeColor = function(v) {
+	if (typeof v != "number") {
+		// already in rgb (hopefully); IE doesn't get here.
+		return v;
+	}
+	// IE sends number; convert to rgb.
+	var r = v & 0xFF;
+	var g = (v >> 8) & 0xFF;
+	var b = (v >> 16) & 0xFF;
+	return "rgb(" + r + "," + g + "," + b + ")";
+};
+
+// returns hexadecimal color representation from a number or a rgb-style color.
+HTMLArea._colorToRgb = function(v) {
+	if (!v)
+		return '';
+
+	// returns the hex representation of one byte (2 digits)
+	function hex(d) {
+		return (d < 16) ? ("0" + d.toString(16)) : d.toString(16);
+	};
+
+	if (typeof v == "number") {
+		// we're talking to IE here
+		var r = v & 0xFF;
+		var g = (v >> 8) & 0xFF;
+		var b = (v >> 16) & 0xFF;
+		return "#" + hex(r) + hex(g) + hex(b);
+	}
+
+	if (v.substr(0, 3) == "rgb") {
+		// in rgb(...) form -- Mozilla
+		var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/;
+		if (v.match(re)) {
+			var r = parseInt(RegExp.$1);
+			var g = parseInt(RegExp.$2);
+			var b = parseInt(RegExp.$3);
+			return "#" + hex(r) + hex(g) + hex(b);
+		}
+		// doesn't match RE?!  maybe uses percentages or float numbers
+		// -- FIXME: not yet implemented.
+		return null;
+	}
+
+	if (v.substr(0, 1) == "#") {
+		// already hex rgb (hopefully :D )
+		return v;
+	}
+
+	// if everything else fails ;)
+	return null;
+};
+
+// modal dialogs for Mozilla (for IE we're using the showModalDialog() call).
+
+// receives an URL to the popup dialog and a function that receives one value;
+// this function will get called after the dialog is closed, with the return
+// value of the dialog.
+HTMLArea.prototype._popupDialog = function(url, action, init) {
+	Dialog(this.popupURL(url), action, init);
+};
+
+// paths
+
+HTMLArea.prototype.imgURL = function(file, plugin) {
+	if (typeof plugin == "undefined")
+		return _editor_url + file;
+	else
+		return _editor_url + "plugins/" + plugin + "/img/" + file;
+};
+
+HTMLArea.prototype.popupURL = function(file) {
+	var url = "";
+	if (file.match(/^plugin:\/\/(.*?)\/(.*)/)) {
+		var plugin = RegExp.$1;
+		var popup = RegExp.$2;
+		if (!/\.html$/.test(popup))
+			popup += ".html";
+		url = _editor_url + "plugins/" + plugin + "/popups/" + popup;
+	} else
+		url = _editor_url + this.config.popupURL + file;
+	return url;
+};
+
+/**
+ * FIX: Internet Explorer returns an item having the _name_ equal to the given
+ * id, even if it's not having any id.  This way it can return a different form
+ * field even if it's not a textarea.  This workarounds the problem by
+ * specifically looking to search only elements having a certain tag name.
+ */
+HTMLArea.getElementById = function(tag, id) {
+	var el, i, objs = document.getElementsByTagName(tag);
+	for (i = objs.length; --i >= 0 && (el = objs[i]);)
+		if (el.id == id)
+			return el;
+	return null;
+};
+
+
+
+// EOF
+// Local variables: //
+// c-basic-offset:8 //
+// indent-tabs-mode:t //
+// End: //
Index: /sandbox/workflow/branches/993/js/htmlarea/release-notes.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/release-notes.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/release-notes.html	(revision 795)
@@ -0,0 +1,209 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title><% $basename %> release notes</title>
+    <style>
+      .fixme { color: red; }
+    </style>
+  </head>
+
+  <body>
+
+    <h1><% $basename %> release notes</h1>
+
+    <p>This release was compiled on <% $time %>.</p>
+
+    <h2>3.0-rc1</h2>
+
+    <p>Changes since 3.0-Beta:</p>
+
+    <ul>
+      <li>
+        <b>New plugins</b>
+        <ul>
+          <li>
+            ContextMenu plugin (provides a nice context menu with common
+            operations, including table ops, link ops, etc.)
+          </li>
+          <li>
+            CSS plugin (provides an easy way to insert/change CSS classes)
+          </li>
+          <li>
+            FullPage plugin (allows HTMLArea to edit a whole HTML file,
+            not only the content within &lt;body&gt;.)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <b>Changes in the SpellChecker plugin</b>
+        <ul>
+          <li>
+            Many bugfixes: now it works ;-)  Fully Unicode-safe.
+          </li>
+          <li>
+            Speed and bandwidth optimization: reports the list of
+            suggestions only once for each mispelled word; this helps
+            in cases where you have, for instance, the word âHTMLAreaâ
+            in 10 places all over the document; the list of
+            suggestions for it--which is kind of huge--will only be
+            included <em>once</em>.
+          </li>
+          <li>
+            User interface improvements: the highlighted word will
+            remain in view; in cases where it's normally outside, the
+            window will be scrolled to it.
+          </li>
+          <li>
+            Added a "Revert" button for those that change their minds ;-)
+          </li>
+          <li>
+            Added a "Info" button which reports information about the
+            document, retrieved by the server-side spell checker:
+            total number of words, total number of mispelled words,
+            number of suggestions made, spell check time, etc.  More
+            can be easily added.  <span class="fixme">FIXME: this part
+            is not yet internationalized.</span>
+          </li>
+          <li>
+            The server-side spell checker now uses XML::DOM instead of
+            HTML::Parser, which means that it will be unable to parse
+            âtag-soupâ HTML.  It needs valid code.  Usually HTMLArea
+            generates valid code, but on rare occasions it might fail
+            and the spell checker will report a gross error message.
+            This gonna have to be fixed, but instead of making the
+            spell checker accept invalid HTML I prefer to make
+            HTMLArea generate valid code, so changes are to be done in
+            other places ;-)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <b>Changes in the core editor</b>
+        <ul>
+          <li>
+            Easier to setup: you only need to load
+            <tt>htmlarea.js</tt>; other scripts will be loaded
+            automatically.  <a href="reference.html">Documentation</a>
+            and <a href="examples/">examples</a> updated.
+          </li>
+          <li>
+            Better plugin support (they register information about
+            themselves with the editor; can register event handlers for
+            the editor, etc.)
+          </li>
+          <li>
+            New about box; check it out, it's cool ;-)
+          </li>
+          <li>
+            Word cleaner (can be enabled to automatically kill Word crap
+            on paste (see Config.killWordOnPaste); otherwise accessible by
+            pressing CTRL-0 in the editor; a toolbar button will come up
+            soon)
+          </li>
+          <li>
+            Image preview in "insert image" dialog.  Also allows
+            modification of current image, if selected.
+          </li>
+          <li>
+            New "insert link" dialog, allows target and title
+            specification, allows editing links.
+          </li>
+          <li>
+            Implemented support for text direction (left-to-right or
+            right-to-left).
+          </li>
+          <li>
+            Lots of bug fixes!  ... and more, I guess ;-) an
+            automatically generated <a href="ChangeLog">change log</a>
+            is now available.
+          </li>
+        </ul>
+      </li>
+    </ul>
+
+    <p>I don't have the power to go through the <a
+href="http://sourceforge.net/tracker/?atid=525656&group_id=69750&func=browse">bug
+system</a> at SourceForge
+    now.  Some of the bugs reported there may be fixed; I'll update
+    their status, some other time.  If you reported bugs there and now
+    find them to be fixed, please let me know.</p>
+
+    <h2>3.0-Beta</h2>
+
+    <p>Changes since 3.0-Alpha:</p>
+
+    <ul>
+
+      <li>Performance improvements.</li>
+
+      <li>Many bugs fixed.</li>
+
+      <li>Plugin infrastructure.</li>
+
+      <li>TableOperations plugin.</li>
+
+      <li>SpellChecker plugin.</li>
+
+      <li>Status bar.</li>
+
+      <li>API for registering custom buttons and drop-down boxes in the
+        toolbar.</li>
+
+      <li>Toolbar can contain text labels.</li>
+
+      <li>Cut, copy, paste, undo, redo buttons.</li>
+
+    </ul>
+<%doc>
+    <h2>Rationale for Beta</h2>
+
+    <p>Why was this released as "Beta"?  The code is quite stable and it
+    didn't deserve a "Beta" qualification.  However, there are some things
+    left to do for the real 3.0 version.  These things will not affect the
+    API to work with HTMLArea, in other words, you can install the Beta
+    right now and then install the final release without modifying your
+    code.  That's if you don't modify HTMLArea itself.  ;-)</p>
+
+    <h2>To-Do before 3.0 final</h2>
+
+    <ol>
+
+      <li>We should use a single popup interface.  Currently there are two:
+      dialog.js and popupwin.js; dialog.js emulates modal dialogs, which
+      sucks when you want to open "select-color" from another popup and not
+      from the editor itself.  Very buggy in IE.  We should probably use only
+      modeless dialogs (that is, popupwin.js).</li>
+
+      <li>Internationalization for the SpellChecker plugin.</li>
+
+      <li>Internationalization for the TableOperations plugin.</li>
+
+      <li>People who sent translations are invited to re-iterate through
+        their work and make it up-to-date with lang/en.js which is the main
+        lang file for HTMLArea-3.0.  Some things have changed but not all
+        translations are updated.</li>
+
+      <li><strong>Documentation</strong>.</li>
+
+    </ol>
+</%doc>
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Sun Aug  3 16:55:08 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Mar 31 19:18:26 EEST 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
+
+<%ARGS>
+  $project => 'HTMLArea'
+  $version => '3.0'
+  $release => 'rc1'
+  $basename => 'HTMLArea-3.0-rc1'
+</%ARGS>
+
+<%INIT>;
+use POSIX qw(strftime);
+my $time = strftime '%b %e, %Y [%H:%M] GMT', gmtime;
+</%INIT>
Index: /sandbox/workflow/branches/993/js/htmlarea/dialog.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/dialog.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/dialog.js	(revision 795)
@@ -0,0 +1,72 @@
+// htmlArea v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+
+// Though "Dialog" looks like an object, it isn't really an object.  Instead
+// it's just namespace for protecting global symbols.
+
+function Dialog(url, action, init) {
+	if (typeof init == "undefined") {
+		init = window;	// pass this window object by default
+	}
+	Dialog._geckoOpenModal(url, action, init);
+};
+
+Dialog._parentEvent = function(ev) {
+	setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50);
+	if (Dialog._modal && !Dialog._modal.closed) {
+		HTMLArea._stopEvent(ev);
+	}
+};
+
+
+// should be a function, the return handler of the currently opened dialog.
+Dialog._return = null;
+
+// constant, the currently opened dialog
+Dialog._modal = null;
+
+// the dialog will read it's args from this variable
+Dialog._arguments = null;
+
+Dialog._geckoOpenModal = function(url, action, init) {
+	var dlg = window.open(url, "hadialog",
+			      "toolbar=no,menubar=no,personalbar=no,width=10,height=10," +
+			      "scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+	Dialog._modal = dlg;
+	Dialog._arguments = init;
+
+	// capture some window's events
+	function capwin(w) {
+		HTMLArea._addEvent(w, "click", Dialog._parentEvent);
+		HTMLArea._addEvent(w, "mousedown", Dialog._parentEvent);
+		HTMLArea._addEvent(w, "focus", Dialog._parentEvent);
+	};
+	// release the captured events
+	function relwin(w) {
+		HTMLArea._removeEvent(w, "click", Dialog._parentEvent);
+		HTMLArea._removeEvent(w, "mousedown", Dialog._parentEvent);
+		HTMLArea._removeEvent(w, "focus", Dialog._parentEvent);
+	};
+	capwin(window);
+	// capture other frames
+	for (var i = 0; i < window.frames.length; capwin(window.frames[i++]));
+	// make up a function to be called when the Dialog ends.
+	Dialog._return = function (val) {
+		if (val && action) {
+			action(val);
+		}
+		relwin(window);
+		// capture other frames
+		for (var i = 0; i < window.frames.length; relwin(window.frames[i++]));
+		Dialog._modal = null;
+	};
+};
Index: /sandbox/workflow/branches/993/js/htmlarea/index.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/index.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/index.html	(revision 795)
@@ -0,0 +1,210 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html>
+  <head>
+    <title>HTMLArea -- the free, customizable online editor</title>
+
+    <style type="text/css">
+      html, body { font-family: georgia,"times new roman",serif; background-color: #fff; color: #000; }
+      .label { text-align: right; padding-right: 0.3em; }
+      .bline { border-bottom: 1px solid #aaa; }
+    </style>
+  </head>
+
+  <body>
+    <div style="float: right; border: 1px solid #aaa; background-color: #eee; padding: 3px; margin-left: 10px; margin-bottom: 10px;">
+      <table cellspacing="0" cellpadding="0" border="0">
+        <tr>
+          <td class="label">Version:</td><td><% $version %></td>
+        </tr>
+        <tr>
+          <td class="label">Release:</td><td><% $release %> (<a href="release-notes.html">release notes</a>)</td>
+        </tr>
+        <tr>
+          <td class="label bline">Compiled at:</td><td class="bline"><% $time %></td>
+        </tr>
+        <tr>
+          <td class="label">SourceForge page:</td><td><a href="http://sf.net/projects/itools-htmlarea/">http://sf.net/projects/itools-htmlarea/</a></td>
+      </table>
+    </div>
+    <h1>HTMLArea -- the free<br/>customizable online editor</h1>
+
+    <p>
+      HTMLArea is a free, customizable online editor.  It works inside your
+      browser.  It uses a non-standard feature implemented in Internet
+      Explorer 5.5 or better for Windows and Mozilla 1.3 or better (any
+      platform), therefore it will only work in one of these browsers.
+    </p>
+
+    <p>
+      HTMLArea is copyright <a
+      href="http://interactivetools.com">InteractiveTools.com</a> and <a
+      href="http://dynarch.com">Dynarch.com</a> and it is
+      released under a BSD-style license.  HTMLArea is created and developed
+      upto version 2.03 by InteractiveTools.com.  Version 3.0 developed by
+      <a href="http://dynarch.com/mishoo/">Mihai Bazon</a> for
+      InteractiveTools.  It contains code sponsored by third-party companies as well.
+      Please see our About Box for details about who sponsored what plugins.
+    </p>
+
+    <h2>Online demos</h2>
+
+    <ul>
+
+      <li><a href="examples/core.html">HTMLArea standard</a> -- contains the core
+        editor.</li>
+
+      <li><a href="examples/table-operations.html">HTMLArea + tables</a> --
+        loads the <tt>TableOperations</tt> plugin which provides some extra
+        editing features for tables.</li>
+
+      <li><a href="examples/spell-checker.html">HTMLArea + spell checher</a>
+        -- loads the <tt>SpellChecker</tt> plugin which provides what its
+        name says: a spell checker.  This one requires additional support on
+        the server-side.</li>
+
+      <li><a href="examples/full-page.html">HTMLArea Full HTML Editor</a> --
+        loads the <tt>FullPage</tt> plugin which allows you to edit a full
+        HTML page, including &lt;title&gt;, &lt;!DOCTYPE...&gt; and some
+        other options.</li>
+
+      <li><a href="examples/context-menu.html">HTMLArea with Context
+          Menu</a> -- this plugin provides a nice and useful context menu.</li>
+
+      <li><a href="examples/fully-loaded.html">HTMLArea fully loaded</a> --
+        all of the above. ;-)</li>
+
+    </ul>
+
+    <h2>Installation</h2>
+
+    <p>
+      Installation is (or should be) easy.  You need to unpack the ZIP file
+      in a directory accessible through your webserver.  Supposing you
+      unpack in your <tt>DocumentRoot</tt> and your <tt>DocumentRoot</tt> is
+      <tt>/var/www/html</tt> as in a standard RedHat installation, you need
+      to acomplish the following steps: (the example is for a Unix-like
+      operating system)
+    </p>
+
+    <pre style="margin-left: 2em"
+>
+cd /var/www/html
+unzip /path/to/archive/<% $basename %>.zip
+mv <% $basename %> htmlarea
+find htmlarea/ -type f -exec chmod 644 {} \;
+find htmlarea/ -type d -exec chmod 755 {} \;
+find htmlarea/ -name "*.cgi" -exec chmod 755 {} \;</pre>
+
+    <p>
+      <strong>Notes.</strong> You may chose to symlink "htmlarea" to "<%
+      $basename %>", in which case your server needs to be configured to
+      "<tt>FollowSymLinks</tt>".  You need to make sure that *.cgi files are
+      interpreted as CGI scripts.  If you want to use the SpellChecker
+      plugin you need to have a recent version of Perl installed (I
+      recommend 5.8.0) on the server, and the module Text::Aspell, available
+      from CPAN.  More info in "<a
+      href="plugins/SpellChecker/readme-tech.html">plugins/SpellChecker/readme-tech.html</a>".
+    </p>
+
+    <p>About how to setup your pages to use the editor, please read the
+      [outdated yet generally valid] <a
+        href="reference.html">documentation</a>.</p>
+
+    <h2>Status and links</h2>
+
+    <p>HTMLArea has reached version 3.0.  As of this version, it
+      supports:</p>
+
+    <ul>
+
+      <li>Customizable toolbar</li>
+
+      <li>Easy internationalization</li>
+
+      <li>Plugin-based infrastructure</li>
+
+      <li>Delivers W3-compliant HTML (with few exceptions)</li>
+
+      <li>Has a subset of Microsoft Word's keyboard shortcuts</li>
+
+      <li>Full-screen editor</li>
+
+      <li>Advanced table operations (by external plugin
+        "TableOperations")</li>
+
+      <li>Spell checker (by external plugin "SpellChecker")</li>
+
+      <li>probably more... ;-)</li>
+
+    </ul>
+
+    <p>We have a <a
+    href="http://sourceforge.net/projects/itools-htmlarea/">project page</a>
+    at <a href="http://sourceforge.net">SourceForge.net</a>.  There you can
+    also find out <a href="http://sourceforge.net/cvs/?group_id=69750">how
+    to retrieve the code from CVS</a>, or you can <a
+    href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/itools-htmlarea">browse
+    the CVS online</a>.  We also have a <a
+    href="http://sourceforge.net/tracker/?atid=525656&group_id=69750&func=browse">bug
+    system</a>, a <a
+    href="http://sourceforge.net/tracker/?atid=525658&group_id=69750&func=browse">patch
+    tracking system</a> and a <a
+    href="http://sourceforge.net/tracker/?atid=525659&group_id=69750&func=browse">feature
+    request page</a>.</p>
+
+    <p>We invite you to say everything you want about HTMLArea <a
+    href="http://www.interactivetools.com/forum/gforum.cgi?forum=14;">on the
+    forums</a> at InteractiveTools.com.  There you should also find the
+    latest news.</p>
+
+    <p>Sometimes I post news about the latest developments on <a
+    href="http://dynarch.com/mishoo/">my personal homepage</a>.</p>
+
+    <h2>"It doesn't work, what's wrong?"</h2>
+
+    <p>If it doesn't work, you have several options:</p>
+
+    <ul>
+
+      <li>Post a message to the forum.  Describe your problem in as much
+      detail as possible.  Include errors you might find in the JavaScript
+      console (if you are a Mozilla user), or errors displayed by IE (though
+      they're most of the times useless).</li>
+
+      <li>If you're positive that you discovered a bug in HTMLArea then feel
+      free to fill a bug report in our bug system.  If you have the time you
+      should check to see if a similar bug was reported or not; it might be
+      fixed already in the CVS ;-) If you're positive that a similar bug was
+      not yet reported, do fill a bug report and please include as much
+      detail as possible, such as your browser, OS, errors from JavaScript
+      console, etc.</li>
+
+      <li>If you want a new feature to be implemented, post it on the
+      features request and someone will hopefully take care of it.</li>
+
+    </ul>
+
+    <p>You can <a href="mailto:mishoo@infoiasi.ro">contact me directly</a>
+    <em>only</em> if you want to pay me for implementing custom features to
+    HTMLArea.  If you want to sponsor these features (that is, allow them to
+    get back into the public HTMLArea distribution) I'll be cheaper. ;-)</p>
+
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Sun Aug  3 14:11:26 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:54:47 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
+
+<%ARGS>
+  $project => 'HTMLArea'
+  $version => '3.0'
+  $release => 'rc1'
+  $basename => 'HTMLArea-3.0-rc1'
+</%ARGS>
+
+<%INIT>;
+use POSIX qw(strftime);
+my $time = strftime '%b %e, %Y [%H:%M] GMT', gmtime;
+</%INIT>
Index: /sandbox/workflow/branches/993/js/htmlarea/example-spell-checker.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/example-spell-checker.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/example-spell-checker.html	(revision 795)
@@ -0,0 +1,134 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="htmlarea.js"></script>
+<script type="text/javascript" src="lang/en.js"></script>
+<script type="text/javascript" src="dialog.js"></script>
+<!-- <script type="text/javascript" src="popupdiv.js"></script> -->
+<script type="text/javascript" src="popupwin.js"></script>
+
+<!-- load the SpellChecker plugin files -->
+<script type="text/javascript" src="plugins/SpellChecker/spell-checker.js"></script>
+<script type="text/javascript" src="plugins/SpellChecker/lang/en.js"></script>
+
+<style type="text/css">
+@import url(htmlarea.css);
+
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+  // create an editor for the "ta" textbox
+  editor = new HTMLArea("ta");
+
+  // register the SpellChecker plugin
+  editor.registerPlugin("SpellChecker");
+
+  editor.generate();
+  return false;
+}
+
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003.</p>
+
+<p>Plugins:
+      <tt>SpellChecker</tt> (sponsored by <a
+        href="http://americanbible.org">American Bible Society</a>).
+</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<h1>The <tt>SpellChecker</tt> plugin</h1>
+
+      <p>This file deminstrates the <tt>SpellChecker</tt> plugin of
+      HTMLArea.  To inwoke the spell checkert you need to press the
+      <em>spell-check</em> buton in the toolbar.</p>
+
+      <p>The spell-checker uses a serverside script written in Perl.  The
+        Perl script calls <a href="http://aspell.net">aspell</a> for any
+        word in the text and reports wordz that aren't found in the
+        dyctionari.</p>
+
+      <p>The document that yu are reading now <b>intentionaly</b> containes
+        some errorz, so that you have something to corect ;-)</p>
+
+      <p>Credits for the <tt>SpellChecker</tt> plugin go to:</p>
+
+      <ul>
+
+        <li><a href="http://aspell.net">Aspell</a> -- spell
+          checker</li>
+
+        <li>The <a href="http://perl.org">Perl</a> programming language</li>
+
+        <li><tt><a
+              href="http://cpan.org/modules/by-module/Text/Text-Aspell-0.02.readme">Text::Aspell</a></tt>
+          -- Perl interface to Aspell</li>
+
+        <li><a href="http://americanbible.org">American Bible Society</a> --
+          for sponsoring the <tt>SpellChecker</tt> plugin for
+          <tt>HTMLArea</tt></li>
+
+        <li><a href="http://students.infoiasi.ro/~mishoo/">Your humble servant</a> for
+          implementing it ;-)</li>
+
+      </ul>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/example-fully-loaded.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/example-fully-loaded.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/example-fully-loaded.html	(revision 795)
@@ -0,0 +1,137 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="htmlarea.js"></script>
+<script type="text/javascript" src="lang/en.js"></script>
+<script type="text/javascript" src="dialog.js"></script>
+<!-- <script type="text/javascript" src="popupdiv.js"></script> -->
+<script type="text/javascript" src="popupwin.js"></script>
+
+<!-- load the plugins -->
+<script type="text/javascript">
+      // WARNING: using this interface to load plugin
+      // will _NOT_ work if plugins do not have the language
+      // loaded by HTMLArea.
+
+      // In other words, this function generates SCRIPT tags
+      // that load the plugin and the language file, based on the
+      // global variable HTMLArea.I18N.lang (defined in the lang file,
+      // in our case "lang/en.js" loaded above).
+
+      // If this lang file is not found the plugin will fail to
+      // load correctly and nothing will work.
+
+      HTMLArea.loadPlugin("TableOperations");
+      HTMLArea.loadPlugin("SpellChecker");
+</script>
+
+<style type="text/css">
+@import url(htmlarea.css);
+
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+  // create an editor for the "ta" textbox
+  editor = new HTMLArea("ta");
+
+  // register the SpellChecker plugin
+  editor.registerPlugin("TableOperations");
+
+  // register the SpellChecker plugin
+  editor.registerPlugin("SpellChecker");
+
+  editor.generate();
+  return false;
+}
+
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003.</p>
+
+<p>Plugins:
+      <tt>TableOperations<tt> |
+      <tt>SpellChecker</tt>
+</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+      <h1>This is the fully loaded HTMLArea ;-)</h1>
+
+      <p>It loads all the plugins that have been developed so far.</p>
+
+      <table style="background-color: #99f; border: 1px dashed #08f; width:
+        60%; border-collapse: collapse;" align="center">
+        <tr style="background-color: #fdd">
+          <td style="font-weight: bold; border: 1px solid #000;">Plugin</td>
+          <td style="font-weight: bold; border: 1px solid #000;">Sponsor</td>
+        </tr>
+
+        <tr>
+          <td style="font-family: monospace">TableOperations</td>
+          <td><a href="http://bloki.com">Zapatec, Inc.</a></td>
+        </tr>
+
+        <tr>
+          <td style="font-family: monospace">SpellChecker</td>
+          <td><a href="http://americanbible.org">Amerian Bible Society</a></td>
+        </tr>
+      </table>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/full-page.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/full-page.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/full-page.html	(revision 795)
@@ -0,0 +1,75 @@
+<html>
+  <head>
+    <title>Test of FullPage plugin</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <script type="text/javascript">
+      _editor_url = "../";
+      _editor_lang = "en";
+    </script>
+
+    <!-- load the main HTMLArea files -->
+    <script type="text/javascript" src="../htmlarea.js"></script>
+
+    <script type="text/javascript">
+      HTMLArea.loadPlugin("FullPage");
+
+      function initDocument() {
+        var editor = new HTMLArea("editor");
+        editor.registerPlugin(FullPage);
+        editor.generate();
+      }
+    </script>
+
+  </head>
+
+  <body onload="initDocument()">
+    <h1>Test of FullPage plugin</h1>
+
+    <textarea id="editor" style="height: 30em; width: 100%;">
+      &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
+      &lt;html&gt;
+        &lt;head&gt;
+          &lt;title&gt;FullPage plugin for HTMLArea&lt;/title&gt;
+          &lt;link rel="alternate stylesheet" href="http://dynarch.com/mishoo/css/dark.css" /&gt;
+          &lt;link rel="stylesheet" href="http://dynarch.com/mishoo/css/cool-light.css" /&gt;
+        &lt;/head&gt;
+        &lt;body style="background-color: #ddddee; color: #000077;"&gt;
+          &lt;table style="width:60%; height: 90%; margin: 2% auto 1% auto;" align="center" border="0" cellpadding="0" cellspacing="0"&gt;
+            &lt;tr&gt;
+              &lt;td style="background-color: #ddeedd; border: 2px solid #002; height: 1.5em; padding: 2px; font: bold 24px Verdana;"&gt;
+                FullPage plugin
+              &lt;/td&gt;
+            &lt;/tr&gt;
+            &lt;tr&gt;
+              &lt;td style="background-color: #fff; border: 1px solid #aab; padding: 1em 3em; font: 12px Verdana;"&gt;
+                &lt;p&gt;
+                  This plugin enables one to edit a full HTML file in &lt;a
+                    href="http://dynarch.com/htmlarea/"&gt;HTMLArea&lt;/a&gt;.  This is not
+                  normally possible with just the core editor since it only
+                  retrieves the HTML inside the &lt;code&gt;body&lt;/code&gt; tag.
+                &lt;/p&gt;
+                &lt;p&gt;
+                  It provides the ability to change the &lt;code&gt;DOCTYPE&lt;/code&gt; of
+                  the document, &lt;code&gt;body&lt;/code&gt; &lt;code&gt;bgcolor&lt;/code&gt; and
+                  &lt;code&gt;fgcolor&lt;/code&gt; attributes as well as to add additional
+                  &lt;code&gt;link&lt;/code&gt;-ed stylesheets.  Cool, eh?
+                &lt;/p&gt;
+                &lt;p&gt;
+                  The development of this plugin was initiated and sponsored by
+                  &lt;a href="http://thycotic.com"&gt;Thycotic Software Ltd.&lt;/a&gt;.
+                  That's also cool, isn't it? ;-)
+                &lt;/p&gt;
+              &lt;/td&gt;
+            &lt;/tr&gt;
+          &lt;/table&gt;
+        &lt;/body&gt;
+      &lt;/html&gt;
+    </textarea>
+
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct  1 19:55:37 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:07 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/test.cgi
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/test.cgi	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/test.cgi	(revision 795)
@@ -0,0 +1,21 @@
+#! /usr/bin/perl -w
+#
+#
+#
+
+
+
+use CGI;
+
+print "Content-type: text/html\n\n";
+$c = new CGI;
+$ta = $c->param('ta');
+
+print <<EOF;
+<html>
+<body>
+<textarea style="width: 100%; height: 200px">$ta</textarea>
+$ta
+</body>
+</html>
+EOF
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/custom.css
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/custom.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/custom.css	(revision 795)
@@ -0,0 +1,29 @@
+body { background-color: #234; color: #dd8; font-family: tahoma; font-size: 12px; }
+
+a:link, a:visited { color: #8cf; }
+a:hover { color: #ff8; }
+
+h1 { background-color: #456; color: #ff8; padding: 2px 5px; border: 1px solid; border-color: #678 #012 #012 #678; }
+
+/* syntax highlighting (used by the first combo defined for the CSS plugin) */
+
+pre { margin: 0px 1em; padding: 5px 1em; background-color: #000; border: 1px dotted #02d; border-left: 2px solid #04f; }
+.code { color: #f5deb3; }
+.string { color: #00ffff; }
+.comment { color: #8fbc8f; }
+.variable-name { color: #fa8072; }
+.type { color: #90ee90; font-weight: bold; }
+.reference { color: #ee82ee; }
+.preprocessor { color: #faf; }
+.keyword { color: #ffffff; font-weight: bold; }
+.function-name { color: #ace; }
+.html-tag { font-weight: bold; }
+.html-helper-italic { font-style: italic; }
+.warning { color: #ffa500; font-weight: bold; }
+.html-helper-bold { font-weight: bold; }
+
+/* info combo */
+
+.quote { font-style: italic; color: #ee9; }
+.highlight { background-color: yellow; color: #000; }
+.deprecated { text-decoration: line-through; color: #aaa; }
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/fully-loaded.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/fully-loaded.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/fully-loaded.html	(revision 795)
@@ -0,0 +1,256 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor.  We make it relative now, so that the
+    example ZIP file will work anywhere, but please NOTE THAT it's better to
+    have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+  _editor_url = "../";
+  _editor_lang = "en";
+</script>
+
+<!-- load the main HTMLArea file, this will take care of loading the CSS and
+    other required core scripts. -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<!-- load the plugins -->
+<script type="text/javascript">
+      // WARNING: using this interface to load plugin
+      // will _NOT_ work if plugins do not have the language
+      // loaded by HTMLArea.
+
+      // In other words, this function generates SCRIPT tags
+      // that load the plugin and the language file, based on the
+      // global variable HTMLArea.I18N.lang (defined in the lang file,
+      // in our case "lang/en.js" loaded above).
+
+      // If this lang file is not found the plugin will fail to
+      // load correctly and nothing will work.
+
+      HTMLArea.loadPlugin("TableOperations");
+      HTMLArea.loadPlugin("SpellChecker");
+      HTMLArea.loadPlugin("FullPage");
+      HTMLArea.loadPlugin("CSS");
+      HTMLArea.loadPlugin("ContextMenu");
+      HTMLArea.loadPlugin("HtmlTidy");
+      HTMLArea.loadPlugin("ListType");
+</script>
+
+<style type="text/css">
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+
+  // create an editor for the "ta" textbox
+  editor = new HTMLArea("ta");
+
+  // register the FullPage plugin
+  editor.registerPlugin(FullPage);
+
+  // register the SpellChecker plugin
+  editor.registerPlugin(TableOperations);
+
+  // register the SpellChecker plugin
+  editor.registerPlugin(SpellChecker);
+  
+  // register the HtmlTidy plugin
+  editor.registerPlugin(HtmlTidy);
+
+  // register the ListType plugin
+  editor.registerPlugin(ListType);
+
+  // register the CSS plugin
+  editor.registerPlugin(CSS, {
+    combos : [
+      { label: "Syntax:",
+                   // menu text       // CSS class
+        options: { "None"           : "",
+                   "Code" : "code",
+                   "String" : "string",
+                   "Comment" : "comment",
+                   "Variable name" : "variable-name",
+                   "Type" : "type",
+                   "Reference" : "reference",
+                   "Preprocessor" : "preprocessor",
+                   "Keyword" : "keyword",
+                   "Function name" : "function-name",
+                   "Html tag" : "html-tag",
+                   "Html italic" : "html-helper-italic",
+                   "Warning" : "warning",
+                   "Html bold" : "html-helper-bold"
+                 },
+        context: "pre"
+      },
+      { label: "Info:",
+        options: { "None"           : "",
+                   "Quote"          : "quote",
+                   "Highlight"      : "highlight",
+                   "Deprecated"     : "deprecated"
+                 }
+      }
+    ]
+  });
+
+  // add a contextual menu
+  editor.registerPlugin("ContextMenu");
+
+  // load the stylesheet used by our CSS plugin configuration
+  editor.config.pageStyle = "@import url(custom.css);";
+
+  setTimeout(function() {
+    editor.generate();
+  }, 500);
+  return false;
+}
+
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"&gt;
+&lt;html&gt;
+
+&lt;head&gt;
+&lt;title&gt;Passing parameters to JavaScript code&lt;/title&gt;
+&lt;link rel="stylesheet" href="custom.css" /&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+&lt;h1&gt;Passing parameters to JavaScript code&lt;/h1&gt;
+
+&lt;p&gt;Sometimes we need to pass parameters to some JavaScript function that we
+wrote ourselves.  But sometimes it's simply more convenient to include the
+parameter not in the function call, but in the affected HTML elements.
+Usually, all JavaScript calls affect some element, right? ;-)&lt;/p&gt;
+
+&lt;p&gt;Well, here's an original way to do it.  Or at least, I think it's
+original.&lt;/p&gt;
+
+&lt;h2&gt;But first...&lt;/h2&gt;
+
+&lt;p&gt;... an example.  Why would I need such thing?  I have a JS function that
+is called on &lt;code&gt;BODY&lt;/code&gt; &lt;code&gt;onload&lt;/code&gt; handler.  This function
+tries to retrieve the element with the ID "conttoc" and, if present, it will
+&lt;a href="toc.epl" title="Automatic TOC generation"&gt;generate an index&lt;/a&gt;.
+The problem is, this function exists in some external JavaScript library
+that it's loaded in page.  I only needed to pass the parameter from
+&lt;em&gt;one&lt;/em&gt; page.  Thus, it makes sense to pass the parameter from the HTML
+code on &lt;em&gt;that&lt;/em&gt; page, not to affect the others.&lt;/p&gt;
+
+&lt;p&gt;The first idea that came to me was to use some attribute, like "id" or
+"class".  But "id" was locked already, it &lt;em&gt;had&lt;/em&gt; to be "conttoc".  Use
+"class"?  It's not elegant.. what if I really wanted to give it a class, at
+some point?&lt;/p&gt;
+
+&lt;h2&gt;The idea&lt;/h2&gt;
+
+&lt;p&gt;So I thought: what are the HTML elements that do not affect the page
+rendering in any way?  Well, comments.  I mean, &lt;em&gt;comments&lt;/em&gt;, HTML
+comments.  You know, like &lt;code&gt;&amp;lt;!-- this is a comment --&amp;gt;&lt;/code&gt;.&lt;/p&gt;
+
+&lt;p&gt;Though comments do not normally affect the way browser renders the page,
+they are still parsed and are part of the DOM, as well as any other node.
+But this mean that we can access comments from JavaScript code, just like we
+access any other element, right?  Which means that they &lt;em&gt;can&lt;/em&gt; affect
+the way that page finally appears ;-)&lt;/p&gt;
+
+&lt;h2&gt;The code&lt;/h2&gt;
+
+&lt;p&gt;The main part was the idea.  The code is simple ;-)  Suppose we have the
+following HTML code:&lt;/p&gt;
+
+&lt;pre class="code"&gt;&lt;span class="function-name"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html-tag"&gt;div&lt;/span&gt; &lt;span class="variable-name"&gt;id=&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;conttoc&amp;quot;&lt;/span&gt;&lt;span class="paren-face-match"&gt;&amp;gt;&lt;/span&gt;&lt;span class="function-name"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html-tag"&gt;/div&lt;/span&gt;&lt;span class="function-name"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
+
+&lt;p&gt;and our function checks for the presence an element having the ID
+"conttoc", and generates a table of contents into it.  Our code will also
+check if the "conttoc" element's first child is a comment node, and if so
+will parse additional parameters from there, for instance, a desired prefix
+for the links that are to be generated into it.  Why did I need it?  Because
+if the page uses a &lt;code&gt;&amp;lt;base&amp;gt;&lt;/code&gt; element to specify the default
+link prefix, then links like "#gen1" generated by the &lt;a href="toc.epl"&gt;toc
+generator&lt;/a&gt; will not point to that same page as they should, but to the
+page reffered from &lt;code&gt;&amp;lt;base&amp;gt;&lt;/code&gt;.&lt;/p&gt;
+
+&lt;p&gt;So the HTML would now look like this:&lt;/p&gt;
+
+&lt;pre class="code"&gt;&lt;span class="function-name"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html-tag"&gt;div&lt;/span&gt; &lt;span class="variable-name"&gt;id=&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;conttoc&amp;quot;&lt;/span&gt;&lt;span class="function-name"&gt;&amp;gt;&lt;/span&gt;&lt;span class="comment"&gt;&amp;lt;!-- base:link/prefix.html --&amp;gt;&lt;/span&gt;&lt;span class="paren-face-match"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html-tag"&gt;/div&lt;/span&gt;&lt;span class="paren-face-match"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
+
+&lt;p&gt;And our TOC generation function does something like this:&lt;/p&gt;
+
+&lt;pre class="code"&gt;&lt;span class="keyword"&gt;var&lt;/span&gt; &lt;span class="variable-name"&gt;element&lt;/span&gt; = getElementById(&amp;quot;&lt;span class="string"&gt;conttoc&lt;/span&gt;&amp;quot;);
+&lt;span class="keyword"&gt;if&lt;/span&gt; (element.firstChild &amp;amp;&amp;amp; element.firstChild.nodeType == 8) {
+  &lt;span class="comment"&gt;// 8 means Node.COMMENT_NODE.  We're using numeric values
+&lt;/span&gt;  &lt;span class="comment"&gt;// because IE6 does not support constant names.
+&lt;/span&gt;  &lt;span class="keyword"&gt;var&lt;/span&gt; &lt;span class="variable-name"&gt;parameters&lt;/span&gt; = element.firstChild.data;
+  &lt;span class="comment"&gt;// at this point &amp;quot;parameters&amp;quot; contains base:link/prefix.html
+&lt;/span&gt;  &lt;span class="comment"&gt;// ...
+&lt;/span&gt;}&lt;/pre&gt;
+
+&lt;p&gt;So we retrieved the value passed to the script from the HTML code.  This
+was the goal of this article.&lt;/p&gt;
+
+&lt;hr /&gt;
+&lt;address&gt;&lt;a href="http://students.infoiasi.ro/~mishoo/"&gt;Mihai Bazon&lt;/a&gt;&lt;/address&gt;
+&lt;!-- hhmts start --&gt; Last modified on Thu Apr  3 20:34:17 2003
+&lt;!-- hhmts end --&gt;
+&lt;!-- doc-lang: English --&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/spell-checker.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/spell-checker.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/spell-checker.html	(revision 795)
@@ -0,0 +1,132 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor.  We make it relative now, so that the
+    example ZIP file will work anywhere, but please NOTE THAT it's better to
+    have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+  _editor_lang = "en";
+  _editor_url = "../";
+</script>
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+HTMLArea.loadPlugin("SpellChecker");
+var editor = null;
+function initEditor() {
+  // create an editor for the "ta" textbox
+  editor = new HTMLArea("ta");
+
+  // register the SpellChecker plugin
+  editor.registerPlugin(SpellChecker);
+
+  editor.generate();
+  return false;
+}
+
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<p>Plugins:
+      <tt>SpellChecker</tt> (sponsored by <a
+        href="http://americanbible.org">American Bible Society</a>).
+</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<h1>The <tt>SpellChecker</tt> plugin</h1>
+
+      <p>This file deminstrates the <tt>SpellChecker</tt> plugin of
+      HTMLArea.  To inwoke the spell checkert you need to press the
+      <em>spell-check</em> buton in the toolbar.</p>
+
+      <p>The spell-checker uses a serverside script written in Perl.  The
+        Perl script calls <a href="http://aspell.net">aspell</a> for any
+        word in the text and reports wordz that aren't found in the
+        dyctionari.</p>
+
+      <p>The document that yu are reading now <b>intentionaly</b> containes
+        some errorz, so that you have something to corect ;-)</p>
+
+      <p>Credits for the <tt>SpellChecker</tt> plugin go to:</p>
+
+      <ul>
+
+        <li><a href="http://aspell.net">Aspell</a> -- spell
+          checker</li>
+
+        <li>The <a href="http://perl.org">Perl</a> programming language</li>
+
+        <li><tt><a
+              href="http://cpan.org/modules/by-module/Text/Text-Aspell-0.02.readme">Text::Aspell</a></tt>
+          -- Perl interface to Aspell</li>
+
+        <li><a href="http://americanbible.org">American Bible Society</a> --
+          for sponsoring the <tt>SpellChecker</tt> plugin for
+          <tt>HTMLArea</tt></li>
+
+        <li><a href="http://dynarch.com/mishoo/">Your humble servant</a> for
+          implementing it ;-)</li>
+
+      </ul>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/context-menu.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/context-menu.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/context-menu.html	(revision 795)
@@ -0,0 +1,95 @@
+<html>
+  <head>
+    <title>Test of ContextMenu plugin</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <script type="text/javascript">
+      _editor_url = "../";
+      _editor_lang = "en";
+    </script>
+
+    <!-- load the main HTMLArea file -->
+    <script type="text/javascript" src="../htmlarea.js"></script>
+
+    <script type="text/javascript">
+      HTMLArea.loadPlugin("ContextMenu");
+      HTMLArea.loadPlugin("TableOperations");
+
+      function initDocument() {
+        var editor = new HTMLArea("editor");
+        editor.registerPlugin(ContextMenu);
+        editor.registerPlugin(TableOperations);
+        editor.generate();
+      }
+    </script>
+
+  </head>
+
+  <body onload="initDocument()">
+    <h1>Test of ContextMenu plugin</h1>
+
+
+<textarea id="editor" style="height: 30em; width: 100%;">
+&lt;table border="1" style="border: 1px dotted rgb(0, 102, 255); width:
+100%; background-color: rgb(255, 204, 51); background-image: none; float:
+none; text-align: left; vertical-align: top; border-collapse: collapse;"
+summary="" cellspacing="" cellpadding="" frame="box"
+rules="all"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border: 1px solid
+rgb(255, 0, 0); background-color: rgb(0, 51, 51); background-image: none;
+text-align: left; vertical-align: top;"&gt;&lt;a
+href="http://dynarch.com/mishoo/articles.epl?art_id=430"&gt;&lt;img
+src="http://127.0.0.1/~mishoo/htmlarea/examples/pieng.png" alt="" align=""
+border="0" hspace="0" vspace="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td
+style="border: 1px solid rgb(255, 0, 0); background-color: rgb(255, 255, 0);
+background-image: none; text-align: left; vertical-align: top;"&gt;The
+article linked on the left image presents a script that allows Internet
+Explorer to use PNG images.  We hope to be able to implement IE PNG support
+in HTMLArea soon.&lt;br /&gt; &lt;br /&gt; Go on, right-click everywhere and
+test our new context menus.  And be thankful to &lt;a
+href="http://www.americanbible.org/"&gt;American Bible Society&lt;/a&gt; who
+sponsored the development, &lt;a
+href="http://dynarch.com/mishoo/"&gt;mishoo&lt;/a&gt; who made it happen and
+God, Who keeps mishoo alife. ;-)&lt;br /&gt; &lt;br /&gt;&lt;span
+style="font-style: italic;"&gt;P.S.&lt;/span&gt; No animals were harmed
+while producing this movie.&lt;br /&gt;
+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border-style: none;
+background-color: rgb(255, 255, 51); background-image: none; text-align:
+left; vertical-align: top;"&gt;Welcome to HTMLArea, the best online
+editor.&lt;br /&gt;&lt;/td&gt;&lt;td&gt;HTMLArea is a project initiated by
+&lt;a href="http://interactivetools.com/"&gt;InteractiveTools.com&lt;/a&gt;.
+Other companies contributed largely by sponsoring the development of
+additional extensions.  Many thanks to:&lt;br /&gt; &lt;br
+style="font-family: courier new,courier,monospace;" /&gt; &lt;div
+style="margin-left: 40px;"&gt;&lt;a href="http://www.zapatec.com/"
+style="font-family: courier
+new,courier,monospace;"&gt;http://www.zapatec.com&lt;/a&gt;&lt;br
+style="font-family: courier new,courier,monospace;" /&gt; &lt;a
+href="http://www.americanbible.org/" style="font-family: courier
+new,courier,monospace;"&gt;http://www.americanbible.org&lt;/a&gt;&lt;br
+style="font-family: courier new,courier,monospace;" /&gt; &lt;a
+href="http://www.neomedia.ro/" style="font-family: courier
+new,courier,monospace;"&gt;http://www.neomedia.ro&lt;/a&gt;&lt;br
+style="font-family: courier new,courier,monospace;" /&gt; &lt;a
+href="http://www.os3.it/" style="font-family: courier
+new,courier,monospace;"&gt;http://www.os3.it&lt;/a&gt;&lt;br
+style="font-family: courier new,courier,monospace;" /&gt; &lt;a
+href="http://www.miro.com.au/" style="font-family: courier
+new,courier,monospace;"&gt;http://www.miro.com.au&lt;/a&gt;&lt;br
+style="font-family: courier new,courier,monospace;" /&gt; &lt;a
+href="http://www.thycotic.com/" style="font-family: courier
+new,courier,monospace;"&gt;http://www.thycotic.com&lt;/a&gt;&lt;br /&gt;
+&lt;/div&gt; &lt;br /&gt; and to all the posters at <a
+href="http://www.interactivetools.com/iforum/Open_Source_C3/htmlArea_v3.0_-_Alpha_Release_F14/
+">InteractiveTools</a> HTMLArea forums, whose feedback is continually
+useful in polishing HTMLArea.&lt;br /&gt; &lt;br /&gt;&lt;div
+style="text-align: right;"&gt;-- developers and maintainers of version 3,
+&lt;a href="http://dynarch.com/"&gt;dynarch.com&lt;/a&gt;.&lt;br
+/&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
+    </textarea>
+
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct  1 19:55:37 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:29 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/index.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/index.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/index.html	(revision 795)
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>HTMLArea examples index</title>
+</head>
+
+<body>
+<h1>HTMLArea: auto-generated examples index</h1>
+
+<ul>
+% while (<*.html>) {
+% next if /^index.html$/;
+  <li>
+    <a href="<% $_ %>"><% $_ %></a>
+  </li>
+% }
+</ul>
+
+<hr />
+<address>mishoo@infoiasi.ro</address>
+<!-- hhmts start --> Last modified: Sun Feb  1 13:30:39 EET 2004 <!-- hhmts end -->
+</body> </html>
+
+<%INIT>
+my $dir = $m->interp->comp_root;
+$dir =~ s{/+$}{}g;
+#$dir =~ s{/[^/]+$}{}g;
+$dir .= $m->current_comp->dir_path;
+chdir $dir;
+</%INIT>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/2-areas.cgi
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/2-areas.cgi	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/2-areas.cgi	(revision 795)
@@ -0,0 +1,16 @@
+#! /usr/bin/perl -w
+
+use strict;
+use CGI;
+
+my $cgi = new CGI;
+my $text1 = $cgi->param('text1');
+my $text2 = $cgi->param('text2');
+
+print "Content-type: text/html\n\n";
+
+print "<p>You submitted:</p>";
+print "<table border='1'>";
+print "<thead><tr bgcolor='#cccccc'><td width='50%'>text1</td><td width='50%'>text2</td></tr></thead>";
+print "<tbody><tr><td>$text1</td><td>$text2</td></tr></tbody>";
+print "</table>";
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/core.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/core.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/core.html	(revision 795)
@@ -0,0 +1,184 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor.  We make it relative now, so that the
+    example ZIP file will work anywhere, but please NOTE THAT it's better to
+    have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+  _editor_url = "../";
+  _editor_lang = "en";
+</script>
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+  editor = new HTMLArea("ta");
+
+  // comment the following two lines to see how customization works
+  editor.generate();
+  return false;
+
+  var cfg = editor.config; // this is the default configuration
+  cfg.registerButton({
+    id        : "my-hilite",
+    tooltip   : "Highlight text",
+    image     : "ed_custom.gif",
+    textMode  : false,
+    action    : function(editor) {
+                  editor.surroundHTML("<span class=\"hilite\">", "</span>");
+                },
+    context   : 'table'
+  });
+
+  cfg.toolbar.push(["linebreak", "my-hilite"]); // add the new button to the toolbar
+
+  // BEGIN: code that adds a custom button
+  // uncomment it to test
+  var cfg = editor.config; // this is the default configuration
+  /*
+  cfg.registerButton({
+    id        : "my-hilite",
+    tooltip   : "Highlight text",
+    image     : "ed_custom.gif",
+    textMode  : false,
+    action    : function(editor) {
+                  editor.surroundHTML("<span class=\"hilite\">", "</span>");
+                }
+  });
+  */
+
+function clickHandler(editor, buttonId) {
+  switch (buttonId) {
+    case "my-toc":
+      editor.insertHTML("<h1>Table Of Contents</h1>");
+      break;
+    case "my-date":
+      editor.insertHTML((new Date()).toString());
+      break;
+    case "my-bold":
+      editor.execCommand("bold");
+      editor.execCommand("italic");
+      break;
+    case "my-hilite":
+      editor.surroundHTML("<span class=\"hilite\">", "</span>");
+      break;
+  }
+};
+cfg.registerButton("my-toc",  "Insert TOC", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-date", "Insert date/time", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-bold", "Toggle bold/italic", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-hilite", "Hilite selection", "ed_custom.gif", false, clickHandler);
+
+cfg.registerButton("my-sample", "Class: sample", "ed_custom.gif", false,
+  function(editor) {
+    if (HTMLArea.is_ie) {
+      editor.insertHTML("<span class=\"sample\">&nbsp;&nbsp;</span>");
+      var r = editor._doc.selection.createRange();
+      r.move("character", -2);
+      r.moveEnd("character", 2);
+      r.select();
+    } else { // Gecko/W3C compliant
+      var n = editor._doc.createElement("span");
+      n.className = "sample";
+      editor.insertNodeAtSelection(n);
+      var sel = editor._iframe.contentWindow.getSelection();
+      sel.removeAllRanges();
+      var r = editor._doc.createRange();
+      r.setStart(n, 0);
+      r.setEnd(n, 0);
+      sel.addRange(r);
+    }
+  }
+);
+
+
+  /*
+  cfg.registerButton("my-hilite", "Highlight text", "ed_custom.gif", false,
+    function(editor) {
+      editor.surroundHTML('<span class="hilite">', '</span>');
+    }
+  );
+  */
+  cfg.pageStyle = "body { background-color: #efd; } .hilite { background-color: yellow; } "+
+                  ".sample { color: green; font-family: monospace; }";
+  cfg.toolbar.push(["linebreak", "my-toc", "my-date", "my-bold", "my-hilite", "my-sample"]); // add the new button to the toolbar
+  // END: code that adds a custom button
+
+  editor.generate();
+}
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="20" cols="80">
+  &lt;p&gt;Here is some sample text: &lt;b&gt;bold&lt;/b&gt;, &lt;i&gt;italic&lt;/i&gt;, &lt;u&gt;underline&lt;/u&gt;. &lt;/p&gt;
+  &lt;p align=center&gt;Different fonts, sizes and colors (all in bold):&lt;/p&gt;
+  &lt;p&gt;&lt;b&gt;
+   &lt;font face="arial"           size="7" color="#000066"&gt;arial&lt;/font&gt;,
+   &lt;font face="courier new"     size="6" color="#006600"&gt;courier new&lt;/font&gt;,
+   &lt;font face="georgia"         size="5" color="#006666"&gt;georgia&lt;/font&gt;,
+   &lt;font face="tahoma"          size="4" color="#660000"&gt;tahoma&lt;/font&gt;,
+   &lt;font face="times new roman" size="3" color="#660066"&gt;times new roman&lt;/font&gt;,
+   &lt;font face="verdana"         size="2" color="#666600"&gt;verdana&lt;/font&gt;,
+   &lt;font face="tahoma"          size="1" color="#666666"&gt;tahoma&lt;/font&gt;
+  &lt;/b&gt;&lt;/p&gt;
+  &lt;p&gt;Click on &lt;a href="http://www.interactivetools.com/"&gt;this link&lt;/a&gt; and then on the link button to the details ... OR ... select some text and click link to create a &lt;b&gt;new&lt;/b&gt; link.&lt;/p&gt;
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/css.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/css.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/css.html	(revision 795)
@@ -0,0 +1,88 @@
+<html>
+  <head>
+    <title>Test of CSS plugin</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <script type="text/javascript">
+      _editor_url = "../";
+      _editor_lang = "en";
+    </script>
+
+    <!-- load the main HTMLArea files -->
+    <script type="text/javascript" src="../htmlarea.js"></script>
+
+    <script type="text/javascript">
+      HTMLArea.loadPlugin("CSS");
+
+      function initDocument() {
+        var editor = new HTMLArea("editor");
+        editor.config.pageStyle = "@import url(custom.css);";
+        editor.registerPlugin(CSS, {
+          combos : [
+            { label: "Syntax",
+                         // menu text       // CSS class
+              options: { "None"           : "",
+                         "Code" : "code",
+                         "String" : "string",
+                         "Comment" : "comment",
+                         "Variable name" : "variable-name",
+                         "Type" : "type",
+                         "Reference" : "reference",
+                         "Preprocessor" : "preprocessor",
+                         "Keyword" : "keyword",
+                         "Function name" : "function-name",
+                         "Html tag" : "html-tag",
+                         "Html italic" : "html-helper-italic",
+                         "Warning" : "warning",
+                         "Html bold" : "html-helper-bold"
+                       },
+              context: "pre"
+            },
+            { label: "Info",
+              options: { "None"           : "",
+                         "Quote"          : "quote",
+                         "Highlight"      : "highlight",
+                         "Deprecated"     : "deprecated"
+                       }
+            }
+          ]
+        });
+        editor.generate();
+      }
+    </script>
+
+  </head>
+
+  <body onload="initDocument()">
+    <h1>Test of FullPage plugin</h1>
+
+    <textarea id="editor" style="height: 30em; width: 100%;"
+>&lt;h1&gt;&lt;tt&gt;registerDropdown&lt;/tt&gt;&lt;/h1&gt;
+
+&lt;p&gt;Here's some sample code that adds a dropdown to the toolbar.  Go on, do
+        syntax highlighting on it ;-)&lt;/p&gt;
+
+&lt;pre&gt;var the_options = {
+	"Keyword"          : "keyword",
+	"Function name"    : "function-name",
+	"String"           : "string",
+	"Numeric"          : "integer",
+	"Variable name"    : "variable"
+};
+var css_class = {
+	id                 : "CSS-class",
+	tooltip            : i18n["tooltip"],
+	options            : the_options,
+	action             : function(editor) { self.onSelect(editor, this); }
+};
+cfg.registerDropdown(css_class);
+toolbar[0].unshift(["CSS-class"]);&lt;/pre&gt;
+
+&lt;p&gt;Easy, eh? ;-)&lt;/p&gt;</textarea>
+
+    <hr />
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct  1 19:55:37 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:16 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/table-operations.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/table-operations.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/table-operations.html	(revision 795)
@@ -0,0 +1,116 @@
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor.  We make it relative now, so that the
+    example ZIP file will work anywhere, but please NOTE THAT it's better to
+    have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+  _editor_lang = "en";
+  _editor_url = "../";
+</script>
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+// load the plugin files
+HTMLArea.loadPlugin("TableOperations");
+
+var editor = null;
+function initEditor() {
+  // create an editor for the "ta" textbox
+  editor = new HTMLArea("ta");
+
+  // register the TableOperations plugin with our editor
+  editor.registerPlugin(TableOperations);
+
+  editor.generate();
+  return false;
+}
+
+function insertHTML() {
+  var html = prompt("Enter some HTML code here");
+  if (html) {
+    editor.insertHTML(html);
+  }
+}
+function highlight() {
+  editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+     customizing the editor.  It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements.  &copy; <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<p>Page that demonstrates the additional features of the
+<tt>TableOperations</tt> plugin (sponsored by <a
+href="http://www.bloki.com">Zapatec Inc.</a>).</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<h1>Plugin: <tt>TableOperations</tt></h1>
+
+<p>This page exemplifies the table operations toolbar, provided by the
+TableOperations plugin.</p>
+
+<p>Following there is a table.</p>
+
+<table border="1" style="border: 2px solid rgb(255, 0, 0); width: 80%; background-image: none; border-collapse: collapse; color: rgb(153, 102, 0); background-color: rgb(255, 255, 51);" align="center" cellspacing="2" cellpadding="1" summary="">
+  <caption>This <span style="font-weight: bold;">is</span> a table</caption>
+  <tbody>
+  <tr style="border-style: none; background-image: none; background-color: rgb(255, 255, 153);" char="." align="left" valign="middle"> <td>1.1</td> <td>1.2</td> <td>1.3</td> <td>1.4</td> </tr>
+  <tr> <td>2.1</td> <td style="border: 1px solid rgb(51, 51, 255); background-image: none; background-color: rgb(102, 255, 255); color: rgb(0, 0, 51);" char="." align="left" valign="middle">2.2</td> <td>2.3</td> <td>2.4</td> </tr>
+  <tr> <td>3.1</td> <td>3.2</td> <td style="border: 2px dashed rgb(51, 204, 102); background-image: none; background-color: rgb(102, 255, 153); color: rgb(0, 51, 0);" char="." align="left" valign="middle">3.3</td> <td>3.4</td> </tr>
+  <tr> <td style="background-color: rgb(255, 204, 51);">4.1</td> <td style="background-color: rgb(255, 204, 51);">4.2</td> <td style="background-color: rgb(255, 204, 51);">4.3</td> <td style="background-color: rgb(255, 204, 51);">4.4</td> </tr>
+  </tbody>
+</table>
+
+<p>Text after the table</p>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value="  submit  " />
+<input type="button" name="ins" value="  insert html  " onclick="return insertHTML();" />
+<input type="button" name="hil" value="  highlight text  " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/2-areas.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/2-areas.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/2-areas.html	(revision 795)
@@ -0,0 +1,158 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>Example with 2 HTMLAreas in the same form</title>
+    <script type="text/javascript">
+      // the _editor_url is REQUIRED!  don't forget to set it.
+      _editor_url = "../";
+      // implicit language will be "en", but let's set it for brevity
+      _editor_lang = "en";
+    </script>
+    <script type="text/javascript" src="../htmlarea.js"></script>
+    <script type="text/javascript">
+      // load the plugins that we will use
+      // loading is necessary ONLY ONCE, regardless on how many editors you create
+      // basically calling the following functions will load the plugin files as if
+      // we would have wrote script src="..." but with easier and cleaner code
+      HTMLArea.loadPlugin("TableOperations");
+      HTMLArea.loadPlugin("SpellChecker");
+      HTMLArea.loadPlugin("CSS");
+
+      // this function will get called at body.onload
+      function initDocument() {
+        // cache these values as we need to pass it for both editors
+        var css_plugin_args = {
+          combos : [
+            { label: "Syntax",
+                         // menu text       // CSS class
+              options: { "None"           : "",
+                         "Code" : "code",
+                         "String" : "string",
+                         "Comment" : "comment",
+                         "Variable name" : "variable-name",
+                         "Type" : "type",
+                         "Reference" : "reference",
+                         "Preprocessor" : "preprocessor",
+                         "Keyword" : "keyword",
+                         "Function name" : "function-name",
+                         "Html tag" : "html-tag",
+                         "Html italic" : "html-helper-italic",
+                         "Warning" : "warning",
+                         "Html bold" : "html-helper-bold"
+                       },
+              context: "pre"
+            },
+            { label: "Info",
+              options: { "None"           : "",
+                         "Quote"          : "quote",
+                         "Highlight"      : "highlight",
+                         "Deprecated"     : "deprecated"
+                       }
+            }
+          ]
+        };
+
+        //---------------------------------------------------------------------
+        // GENERAL PATTERN
+        //
+	//  1. Instantitate an editor object.
+	//  2. Register plugins (note, it's required to have them loaded).
+	//  3. Configure any other items in editor.config.
+	//  4. generate() the editor
+	//
+	// The above are steps that you use to create one editor.  Nothing new
+	// so far.  In order to create more than one editor, you just have to
+	// repeat those steps for each of one.  Of course, you can register any
+	// plugins you want (no need to register the same plugins for all
+	// editors, and to demonstrate that we'll skip the TableOperations
+	// plugin for the second editor).  Just be careful to pass different
+	// ID-s in the constructor (you don't want to _even try_ to create more
+	// editors for the same TEXTAREA element ;-)).
+	//
+	// So much for the noise, see the action below.
+	//---------------------------------------------------------------------
+
+
+        //---------------------------------------------------------------------
+        // CREATE FIRST EDITOR
+        //
+        var editor1 = new HTMLArea("text-area-1");
+
+        // plugins must be registered _per editor_.  Therefore, we register
+        // plugins for the first editor here, and we will also do this for the
+        // second editor.
+        editor1.registerPlugin(TableOperations);
+        editor1.registerPlugin(SpellChecker);
+        editor1.registerPlugin(CSS, css_plugin_args);
+
+        // custom config must be done per editor.  Here we're importing the
+        // stylesheet used by the CSS plugin.
+        editor1.config.pageStyle = "@import url(custom.css);";
+
+        // generate first editor
+        editor1.generate();
+        //---------------------------------------------------------------------
+
+
+        //---------------------------------------------------------------------
+        // CREATE SECOND EDITOR
+        //
+        var editor2 = new HTMLArea("text-area-2");
+
+        // we are using the same plugins
+        editor2.registerPlugin(TableOperations);
+        editor2.registerPlugin(SpellChecker);
+        editor2.registerPlugin(CSS, css_plugin_args);
+
+        // import the CSS plugin styles
+        editor2.config.pageStyle = "@import url(custom.css);";
+
+        // generate the second editor
+        // IMPORTANT: if we don't give it a timeout, the first editor will
+        // not function in Mozilla.  Soon I'll think about starting to
+        // implement some kind of event that will fire when the editor
+        // finished creating, then we'll be able to chain the generate()
+        // calls in an elegant way.  But right now there's no other solution
+        // than the following.
+        setTimeout(function() {
+          editor2.generate();
+        }, 500);
+        //---------------------------------------------------------------------
+      };
+    </script>
+  </head>
+
+  <body onload="initDocument()">
+    <h1>Example with 2 HTMLAreas in the same form</h1>
+
+    <form action="2-areas.cgi" method="post" target="_blank">
+
+      <input type="submit" value=" Submit " />
+      <br />
+
+      <textarea id="text-area-1" name="text1" style="width: 100%; height: 12em">
+        &lt;h3&gt;HTMLArea #1&lt;/h3&gt;
+        &lt;p&gt;This will submit a field named &lt;em&gt;text1&lt;/em&gt;.&lt;/p&gt;
+      </textarea>
+
+      <br />
+
+      <textarea id="text-area-2" name="text2" style="width: 100%; height: 12em">
+        &lt;h3&gt;Second HTMLArea&lt;/h3&gt; &lt;p&gt;&lt;em&gt;text2&lt;/em&gt; submission.  Both are
+        located in the same FORM element and the script action is
+        2-areas.cgi (see it in the examples directory)&lt;/p&gt;
+      </textarea>
+
+      <br />
+      <input type="submit" value=" Submit " />
+
+    </form>
+
+    <hr>
+    <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Fri Oct 31 09:37:10 EET 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:40 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+  </body>
+</html>
Index: /sandbox/workflow/branches/993/js/htmlarea/examples/list-type.html
===================================================================
--- /sandbox/workflow/branches/993/js/htmlarea/examples/list-type.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmlarea/examples/list-type.html	(revision 795)
@@ -0,0 +1,66 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Example of HTMLArea 3.0 -- ListType plugin</title>
+
+<script type="text/javascript">
+  _editor_lang = "en";
+  _editor_url = "../";
+</script>
+
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+  font-family: Verdana,sans-serif;
+  background-color: #fea;
+  color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+// load the plugin files
+HTMLArea.loadPlugin("ListType");
+var editor = null;
+function initEditor() {
+  editor = new HTMLArea("ta");
+  editor.registerPlugin(ListType);
+  editor.generate();
+  return false;
+}
+</script>
+
+</head>
+
+<body onload="initEditor()">
+
+<h1>HTMLArea :: the ListType plugin</h1>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<p>List style type is selected using the CSS property
+&quot;list-style-type&quot;.  Hopefully it will work with Internet Explorer,
+right? ;-) Let's start the monster to test it out.<br /></p><p>Cool, it
+works.  Except for &quot;lower-greek&quot;, which doesn't seem to be
+supported (and worse, a gross error message is displayed).  Therefore, I
+hide that proerty from IE--it will only be available if the browser is not
+IE.<br /></p><ol style="list-style-type: decimal;"><li>This is a list<br
+/></li><li>with decimal numbers<br /></li><li>blah blah<br /></li><li>dolor
+sic amet<br /></li></ol><ol style="list-style-type: lower-greek;"><li>yet
+another</li><li>list with greek<br /></li><li>letters<br /></li><li>lorem
+ipsum<br /></li><li>yada yada<br /></li></ol>
+
+</textarea>
+
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/resourceeditor/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/resourceeditor/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/resourceeditor/main.js	(revision 795)
@@ -0,0 +1,34 @@
+function show_messages(text) 
+{
+	messages.addText(text);
+}
+
+/*
+function phpeditor_checksyntax()
+{
+	var chkSyntax = function(data) {
+		show_messages(data);
+	}
+	var txtcode;
+
+	txtcode = editor.getContents();
+	frmSend.code.value = txtcode;
+	cExecuteFormData("$this.bo_editor.check_syntax",frmSend,chkSyntax);
+	editor.setInputFocus();
+}
+*/
+
+function phpeditor_salvar()
+{
+	var hndSalvar = function(data) {
+		show_messages(data);
+	};
+	var txtcode;
+
+	document.title = editor.window_title;
+	txtcode = editor.getContents();
+	frmSend.code.value = txtcode;
+	cExecuteFormData("$this.bo_editor.save_resource",frmSend,hndSalvar);
+	editor.setInputFocus();
+	editor.unsaved = false;
+}
Index: /sandbox/workflow/branches/993/js/resourceeditor/highlight.js
===================================================================
--- /sandbox/workflow/branches/993/js/resourceeditor/highlight.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/resourceeditor/highlight.js	(revision 795)
@@ -0,0 +1,709 @@
+    /******************************************************************
+     highlight.js                                           Muze Helene
+     ------------------------------------------------------------------
+     Author: Muze (info@muze.nl)
+     Date: 28 februari 2004
+
+     Copyright 2002 Muze
+
+     This file is part of Helene.
+
+     Helene is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published 
+     by the Free Software Foundation; either version 2 of the License, 
+     or (at your option) any later version.
+ 
+     Helene is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with Helene; if not, write to the Free Software 
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  
+     02111-1307  USA
+
+    -------------------------------------------------------------------
+
+     This file contains the syntax highlighting parser
+
+    ******************************************************************/
+  // Parsing smarty tags http://smarty.php.net/
+  // Cofigure the smarty delimiters below ('{%' and '%}' by default)
+  // Unset this flag if you need to parse only PHP
+  var parseSmarty = true;
+
+	/* states */
+	var YY_STATE_HTML = 0;
+	var YY_STATE_PINP = 1;
+	var YY_STATE_DQSTRING = 2;
+	var YY_STATE_SQSTRING = 3;
+  var YY_STATE_SCRIPT = 4;
+  var YY_STATE_BLOCKCOMMENT = 5;
+
+  /* Smarty states */
+  var YYS_STATE_TAG = 101;
+  var YYS_STATE_PARAM = 102;
+  var YYS_STATE_QPARAM = 103;
+
+	/* tokens */
+	var T_VAR = 0;
+	var T_IDENT = 1;
+	var T_FUNCTION = 2;
+	var T_TOKEN = 3;
+	var T_UNKNOWN = 4;
+	var T_PINP_START = 5;
+	var T_PINP_BLOCK = 6;
+	var T_PINP_END = 7;
+	var T_SPACE = 8;
+	var T_DQUOTE = 9;
+	var T_SQUOTE = 10;
+	var T_ESCAPE = 11;
+	var T_SPECIAL_CHAR = 12;
+	var T_OPERATOR = 13;
+	var T_SINGLE_COMMENTS = 14;
+	var T_BLOCKCOMMENT = 15;
+	var T_BLOCKCOMMENT_END = 16;
+	var T_PHP_START = 17;
+	var T_PHP_END = 18;
+	var T_SCRIPT_START = 19;
+	var T_SCRIPT_END = 20;
+	var T_TAB = 21;
+	var T_EMPTY_LINE = 22;
+
+  /*Smarty tokens*/
+  var TS_SMARTY_START = 101;
+  var TS_SMARTY_END = 102;
+  var TS_KEYWORD = 103;
+  var TS_ATTRIBUTE = 104;
+  var TS_ATTRVALUE = 105;
+  var TS_VAR = 106;
+	var TS_ENDTAG = 107;
+
+	var hLines = new Array();
+	var debug = 0;
+	var scannerPos = 0;
+  var hStyles = new Array();
+	var hStateStyles = new Array();
+
+  // May be there is the better place for it but now there
+  initStyleDefault();
+	// Making object from keywords, it makes a big perfomance overhead in IE
+	// and slightly better perfomance in Mozilla
+	// You can define any amount of keyword groups
+	// Words should match ([a-z0-9][a-z0-9_]*) and should be separated by spaces
+	var hPHPKeywords = cacheKeywords( /// TODO: Add more keywords here 
+		"",
+		"" // standart functions
+		);	
+	var hSmartyKeywords = cacheKeywords(
+		"", 
+		"",
+		""  
+		); 
+
+	function hLineToken(tokenType, tokenData) {
+		this.type = tokenType;
+		this.data = tokenData;
+		this.reallength = tokenData.length;
+    this.newState = -1;
+
+		switch (this.data) {
+			case '<':	
+				this.data='&lt;';
+			break;
+			case '>':
+				this.data='&gt;';
+			break;
+			case '&':
+				this.data='&amp;';
+			break;
+		}
+	
+		switch (this.type) {
+			case T_PINP_START:
+			case T_PHP_START:
+			case T_PINP_END:
+			case T_PHP_END:
+			case T_SCRIPT_START:
+			case T_SINGLE_COMMENTS:
+			case T_BLOCKCOMMENT:
+			case T_BLOCKCOMMENT_END:
+				this.data = this.data.replace(/[<]/g, '&lt;');
+                this.data = this.data.replace(/[>]/g, '&gt;');
+				var myTabRest = scannerPos % 8;
+                var addLength = 8 - myTabRest;
+				this.data = this.data.replace(/[\t]/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
+                scannerPos += (addLength -1);
+			break;
+			case T_SCRIPT_END:
+				this.data = this.data.replace(/[<]/g, '&lt;');
+				this.data = this.data.replace(/[>]/g, '&gt;');
+			case T_SPACE:
+				this.data = this.data.replace(/[ ]/g, '&nbsp;');
+			break;
+			case T_TAB:
+				var myTabRest = scannerPos % 8;
+				var addLength = 8 - myTabRest;
+				// alert( 'scannerPos ' + scannerPos + ' myTabRest ' + myTabRest + ' addLength ' + addLength);
+				this.data = this.data.replace(/[\t]/g, '<span style="padding-left: '+ (addLength*letterWidth) + 'px;"></span>');
+				scannerPos += (addLength -1);
+			break;
+			case T_EMPTY_LINE:
+				this.data = '<span style="padding-left: 1px;"></span>';
+			break;
+		}
+		scannerPos += tokenData.length;
+	}
+
+	function getToken(sData) {
+		var re, match;
+
+		/* empty line, required for Firefox 1.5.x */
+		if (sData == "")
+		{
+			result = new hLineToken(T_EMPTY_LINE, "");
+			return result;
+		}
+
+		/* white space */
+		re = /^([ ]+)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_SPACE, match[1]);
+			return result;
+		}
+
+		re = /^([\t])/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_TAB, match[1]);
+			return result;
+		}
+
+    /* Smarty tokens */
+    if(parseSmarty) {
+      	re = /^\{\$[a-z_][a-z0-9_]*/i;           // Matches $smarty->left_delimiter
+      	match = re.exec(sData);
+      	if(match) {
+        	return new hLineToken(TS_SMARTY_START, match[0]);
+      	}
+
+      	re = /^\{/;           // Matches $smarty->left_delimiter
+      	match = re.exec(sData);
+      	if(match) {
+        	return new hLineToken(TS_SMARTY_START, match[0]);
+      	}
+
+      	re = /^\}/;           // Matches $smarty->right_delimiter
+      	match = re.exec(sData);
+      	if(match) {
+        	return new hLineToken(TS_SMARTY_END, match[0]);
+      	}
+	  
+	  	//re = /^\/[a-z0-9][a-z0-9_]*/i;
+	  	//match = re.exec(sData);
+	  	//if (match) {
+	    //	result = new hLineToken(TS_ENDTAG, match[0]);
+		//	return result;
+	  	//}		
+    }
+    /* end of smarty tokens */
+
+		/* variable or ident */
+		re = /^([$]|->)?([a-z0-9_][a-z0-9_]*)/i;
+		match = re.exec(sData);
+		if (match) {
+			if (match[1]) {
+				result = new hLineToken(T_VAR, match[0]);
+			} else {
+				result = new hLineToken(T_IDENT, match[2]);
+			}
+			return result;
+		}
+
+		/* single tokens */
+		re = /^([(){},"'\\])/;
+		match = re.exec(sData);
+		if (match) {
+			switch (match[1]) {
+				case '\\':
+					result = new hLineToken(T_ESCAPE, match[1]); 
+				break;
+				case '"':
+					result = new hLineToken(T_DQUOTE, match[1]); 
+				break;
+				case "'":
+					result = new hLineToken(T_SQUOTE, match[1]);
+				break;
+				default:
+					result = new hLineToken(T_SPECIAL_CHAR, match[1]);
+				break;
+			}
+			return result;
+		}
+
+		re = /^((\<\!\-\-)|(\-\-\>))/;
+		match = re.exec(sData);
+		if (match) {
+			if (match[2]) {
+				result = new hLineToken(T_BLOCKCOMMENT, match[2]);
+			} else {
+				result = new hLineToken(T_BLOCKCOMMENT_END, match[3]);
+			}
+			return result;
+		}
+
+		/* comments */
+		re = /^(\/\/.*)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_SINGLE_COMMENTS, match[1]);
+			return result;
+		}
+
+		/* php end tags */
+		re = /^(>)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_PHP_END, match[0]);
+			return result;
+		}
+
+		re = /^([\-\+\.\*\/\=\%])/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_OPERATOR, match[1]);
+			return result;
+		}
+
+
+		/* pinp/php tags */
+        re = /^((<))/i;
+		match = re.exec(sData);
+		if (match) {
+			if (match[3]) {
+				result = new hLineToken(T_PINP_END, match[0]);
+			} else
+			if (match[2]) {
+				result = new hLineToken(T_PINP_START, match[0]);
+			} else {
+				result = new hLineToken(T_PINP_START, match[0]);
+			}
+			return result;
+		}
+
+		/* javascript */
+		re = /^<(\/)?script[^>]*>/;
+		match = re.exec(sData);
+		if (match) {
+			if (match[1]) {
+				result = new hLineToken(T_SCRIPT_END, match[0]);
+			} else {
+				result = new hLineToken(T_SCRIPT_START, match[0]);
+			}
+			return result;
+		}
+				
+		return new hLineToken(T_UNKNOWN, sData.charAt(0));
+	}
+
+	function hLineParseString(sData) {
+		var token;
+		this.tokens = new Array();
+
+		scannerPos = 0;
+		do
+		{
+			token = getToken(sData);
+			this.tokens[this.tokens.length] = token;	
+			sData=sData.substring(token.reallength);
+		} while (sData != '');
+	}
+
+      function getElmSpan(token) { /// In the past styles were here
+		var result = '';							// UPDATE: it is better to produce whole span tag here
+    var cls = hStyles[token.type];
+    if(cls!='') result = '<span class="'+cls+'">';
+		else result = '<span>';
+		return result;
+	}
+      function getStateSpan(token) { /// Style span for states
+		var result = '';								// UPDATE: it is better to produce whole span tag here
+    var cls = hStateStyles[token.newState];
+    if(cls!='') result = '<span class="'+cls+'">';
+		else result = '<span>';
+		return result;
+	}
+
+	function hLineDoHighlight(callback) {
+		var state = new Array();
+		var result = '';
+		if (this.lineNo) {
+			/* load parent state */
+			state = state.concat(hLines[this.lineNo-1].getEndState());
+//			alert((this.lineNo-1)+':'+state.length);
+		}
+		for (var i = 0; i<state.length; i++) {
+			if (!state[i].noMultiLine) {
+				result += getStateSpan(state[i]);
+			}
+		}
+		if (this.tokens) {
+			for (var i=0; i<this.tokens.length; i++) {
+				var cState = 0;
+				var token = this.tokens[i];
+				if (state.length) {
+          cState = state[state.length-1].newState; 
+          status = cState;
+				}
+
+        switch (cState) {         // In the past state was the type of opening token
+          case YY_STATE_HTML:     // It is a real state now
+						switch (token.type) {
+              //Smarty highlighting
+              case TS_SMARTY_START:
+                token.newState = YYS_STATE_TAG;
+                result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+                state.push(token);
+              break;
+              //End of smarty highlighting
+							case T_PHP_START:
+							case T_PINP_START:
+								token.newState = YY_STATE_PINP; // We fix the new state here
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token); // But we still saving opening token
+							break;
+							case T_SCRIPT_START:
+                token.newState = YY_STATE_SCRIPT;
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token);
+							break;
+							case T_BLOCKCOMMENT:
+                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
+								result += getStateSpan(token);
+								result += token.data;
+								state.push(token);
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_SCRIPT:
+						switch (token.type) {
+							case T_PHP_START:
+							case T_PINP_START:
+                token.newState = YY_STATE_PINP;
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token);
+							break;
+							case T_SCRIPT_END:
+								result += getElmSpan(token)+token.data+'</span>';
+								result += '</span>';
+								state.pop();
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_PINP:
+						switch (token.type) {
+							case T_IDENT:
+								var lower_data = token.data.toLowerCase();
+								var t = hPHPKeywords[lower_data];
+								if(typeof(t)!='undefined') {
+									result += '<span class="h_phpkeywords'+t+'">';
+								} else {
+									result += getElmSpan(token);
+								}
+								result += token.data + '</span>';
+							break;
+							case T_DQUOTE:
+                token.newState = YY_STATE_DQSTRING;
+							case T_SQUOTE:
+                if(token.newState<0) token.newState = YY_STATE_SQSTRING;
+							case T_BLOCKCOMMENT:
+                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
+								result += getStateSpan(token);
+								result += token.data;
+								state.push(token);
+							break;
+							case T_PHP_END:
+							case T_PINP_END:
+								result += getElmSpan(token)+token.data+'</span>';
+								result += '</span>';
+								state.pop();
+							break;
+							case T_VAR:
+							case T_OPERATOR:
+							case T_SPECIAL_CHAR:
+							case T_SINGLE_COMMENTS:
+								result += getElmSpan(token);
+								result += token.data;
+								result += '</span>';
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_BLOCKCOMMENT:
+						switch (token.type) {
+							case T_BLOCKCOMMENT_END:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_DQSTRING:
+						switch (token.type) {
+              case T_DQUOTE:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							case T_ESCAPE:
+								result += token.data;
+								token = this.tokens[++i];
+								result += token.data;
+							break;
+							case T_VAR:
+								result += getElmSpan(token);
+								result += token.data;
+								result += '</span>';
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_SQSTRING:
+						switch (token.type) {
+                                                      case T_SQUOTE:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							case T_ESCAPE:
+								result += token.data;
+								token = this.tokens[++i];
+								result += token.data;
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YYS_STATE_TAG:
+            switch (token.type) {
+              case TS_SMARTY_END:
+                result += getElmSpan(token) + token.data + '</span></span>';
+                state.pop();
+              break;
+							case TS_ENDTAG:
+								var t = hSmartyKeywords[token.data.substr(1)];
+								if(t==1) {	// Only the first group has closing tags
+									result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
+								} else {
+									result += token.data;
+								}
+							break;
+							case T_VAR:
+                result += getElmSpan(token) + token.data + '</span>';
+                //result += token.data;
+								break;								
+							case T_IDENT:
+								var t = hSmartyKeywords[token.data];
+								if(typeof(t)!='undefined' /*&& 
+									(t>3 ||	// first three groups of keywords may appear
+										(i>0 && this.tokens[i-1].type==TS_SMARTY_START))	// immediately after TS_SMARTY_START token only
+										*/) {
+									result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
+								} else {
+									result += token.data;
+								}
+							break;
+              default:
+							result += token.data;
+              break;
+            }
+          break;
+					default:
+						result += token.data;
+					break;
+				}
+			}
+//			alert(this.lineNo+'::'+this.tokens.length+'::'+result);
+
+		}
+		var stateChanged = 0;
+		if (state.length != this.getEndState().length) {
+			stateChanged = 1;
+		}
+
+		for (i=state.length-1; i>=0; i--) {
+			if (!stateChanged && state[i].type!=this.getEndState()[i].type) {
+				stateChanged = 1;
+			}
+			if (!state[i].noMultiLine) {
+				result += getElmSpan(state[i]);
+			}
+		}
+
+		/* report update */
+		if (callback) {
+//			alert(this.lineNo+"::"+result);
+			if (result) {
+//				alert(this.lineNo+': 2 eol chars: "'+result.substr(result.length-2)+'"');
+			}
+			callback(this.lineNo, result);
+		}
+		this.setEndState(state);
+              if (stateChanged) {
+			if (debug) alert('updating: '+this.lineNo+1); 
+      /// This makes a stack overflow
+      /// so we are returning 'true' that means next line must be updated
+      //~ hLines[this.lineNo+1].doHighlight(callback);
+                      return true;
+		}
+    /// Next line need not be updated
+    return false;
+	}
+
+	function hLineSetEndState(newEndState) {
+//		alert(this.lineNo+': new endstate: '+newEndState.length);
+		var frop=new Array();
+		if (newEndState.length) {
+//			alert(':'+newEndState.toString()+':');
+			this.endState=frop.concat(newEndState); //newEndState; //.toSource();
+		} else {
+			this.endState=new Array();
+		}
+/*
+		var line = hLines[2];
+		if (line) {
+			alert(this.lineNo+'->'+line.endState.length);
+		}
+*/
+	}
+
+	function hLineGetEndState() {
+		return this.endState;
+	}
+
+	function hLineRemove() {
+		if (this.lineNo < (hLines.length-1)) {
+			var len = hLines.length-1;
+			for (var i=this.lineNo; i<len; i++) {
+				hLines[i] = hLines[i+1];
+				hLines[i].lineNo = i;
+			}
+		}
+		hLines.pop();
+	}
+
+	function hLine(lineNo, lineString) {
+		this.lineNo = lineNo;
+		if (lineNo && (lineNo != hLines.length)) {
+			var hLinesLen = hLines.length;
+			for (var i=hLinesLen; i>lineNo; i--) {
+				hLines[i] = hLines[i-1];
+				hLines[i].lineNo = i;
+			}
+		}
+		hLines[lineNo] = this;
+		this.tokens = new Array();
+		this.setEndState = hLineSetEndState;
+		this.setEndState(new Array());
+		this.getEndState = hLineGetEndState;
+		this.remove = hLineRemove;
+
+		this.parseString = hLineParseString;
+		this.parseString(lineString);
+
+		if (debug) alert(this.lineNo);
+		this.doHighlight = hLineDoHighlight;
+	}
+
+	function highlightUpdateLine(lineNo, lineContent, callback) {
+//		alert('update line: '+lineNo+'::'+lineContent);
+		hLines[lineNo].parseString(lineContent);
+              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightDeleteLine(lineNo, callback) {
+//		alert('remove line: '+lineNo);
+		line = hLines[lineNo];
+		line.remove();
+              if (hLines.length && (lineNo < hLines.length))
+      while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightReset() {
+		hLines = new Array();
+		new hLine(0, '');
+	}
+
+	function highlightInsertLine(lineNo, lineContent, callback) {
+		if (lineNo) {
+			lineNo -= 1;
+		}
+//		alert('insert at: '+lineNo+'::'+lineContent);
+		line = new hLine(lineNo, lineContent);
+              while(line.doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightAppendLine(lineNo, lineContent, callback) {
+//		alert('append at: '+(lineNo+1)+'::'+lineContent);
+		line = new hLine(lineNo+1, new String(lineContent));
+              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+  function initStyleDefault() {
+    hStyles[T_PINP_START] =
+    hStyles[T_PINP_END] =
+    hStyles[T_PHP_START] = //'h_pinp';
+    hStyles[T_PHP_END] = //'h_pinp';
+    hStyles[T_VAR] = 'h_var';
+    hStyles[T_IDENT] = 'h_ident';
+    hStyles[T_DQUOTE] = 'h_doublequote';
+    hStyles[T_SQUOTE] = 'h_singlequote';
+    hStyles[T_SPECIAL_CHAR] = 'h_special_char';
+    hStyles[T_OPERATOR] = 'h_operator';
+    hStyles[T_SINGLE_COMMENTS] = 'h_single_comments';
+    hStyles[T_BLOCKCOMMENT] = 'h_blockcomment';
+    hStyles[TS_SMARTY_START] = 'h_smartymarkers';
+    hStyles[TS_SMARTY_END] = 'h_smartymarkers';
+		
+	hStateStyles[YY_STATE_HTML] = '';
+	hStateStyles[YY_STATE_PINP] = 'h_pinp_block';
+	hStateStyles[YY_STATE_DQSTRING] = 'h_doublequote';
+	hStateStyles[YY_STATE_SQSTRING] = 'h_singlequote';
+	hStateStyles[YY_STATE_BLOCKCOMMENT] = 'h_blockcomment';
+	hStateStyles[YY_STATE_SCRIPT] = 'h_scriptblock';
+	hStateStyles[YYS_STATE_TAG] = 'h_smartytag';
+  }
+	function cacheKeywords() {
+		var res = new Object();
+		for(var i=0;i<arguments.length;i++) {
+			var t = String(arguments[i]).split(" ");
+			for(var j=0;j<t.length;j++)
+				res[t[j]]=i+1;
+		}
+		return res;
+	}
Index: /sandbox/workflow/branches/993/js/phpeditor/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/phpeditor/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/phpeditor/main.js	(revision 795)
@@ -0,0 +1,33 @@
+function show_messages(text) 
+{
+	messages.addText(text);
+}
+
+
+function phpeditor_checksyntax()
+{
+	var chkSyntax = function(data) {
+		show_messages(data);
+	};
+	var txtcode;
+
+	txtcode = editor.getContents();
+	frmSend.code.value = txtcode;
+	cExecuteFormData("$this.bo_editor.check_syntax",frmSend,chkSyntax);
+	editor.setInputFocus();
+}
+
+function phpeditor_salvar()
+{
+	var hndSalvar = function(data) {
+		show_messages(data);
+	};
+	var txtcode;
+
+	txtcode = editor.getContents();
+	frmSend.code.value = txtcode;
+	cExecuteFormData("$this.bo_editor.save_php_source",frmSend,hndSalvar);
+	document.title = editor.window_title;
+	editor.setInputFocus();
+	editor.unsaved = false;
+}
Index: /sandbox/workflow/branches/993/js/phpeditor/editor.js
===================================================================
--- /sandbox/workflow/branches/993/js/phpeditor/editor.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/phpeditor/editor.js	(revision 795)
@@ -0,0 +1,1892 @@
+
+   /******************************************************************
+     editor.js                                              Muze Helene
+     ------------------------------------------------------------------
+     Author: Muze (info@muze.nl)
+     Date: 28 februari 2004
+
+     Copyright 2002 Muze
+
+     This file is part of Helene.
+
+     Helene is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published 
+     by the Free Software Foundation; either version 2 of the License, 
+     or (at your option) any later version.
+ 
+     Helene is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with Helene; if not, write to the Free Software 
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  
+     02111-1307  USA
+
+    -------------------------------------------------------------------
+
+     This file contains the basic editor functionality.
+
+    ******************************************************************/
+
+	var currentLine  = 1;
+	var previousLine = 1;
+	var lastLine     = 0;
+	var screenWidth  = 0;
+	var lineHeight   = 16;
+	var contentDiv;
+	var lines;
+	var inputLine;
+	var inputLineEntry;
+	var oldpos=-1;
+	var isDirty=false;
+	var winW = 630;
+	var winH = 460;
+	var inputLineHasFocus = false;
+	var offsetLine = 0;
+	var currInputHeight = lineHeight;
+	var letterWidth = 9;
+	var clickPosOffsetLeft = 0;
+	var longestLine = 0;
+	var adjustTop = 0;
+	var minInputWidth = 0;
+	var addedSpaces=0;
+	var userSelecting = false;
+	var selectIni=-1;
+	var selectLineIni=-1;
+	var keyBinding = new Array();
+	var keyBindings = new Array();
+	var cancelKey = false;
+	var autoIndent = true;
+	var startcoordinate = false;
+	/* Undo/Redo vars */
+	var undoBuffer = [];
+	var redoBuffer = [];
+	var startCursorPos = -1; // Cursor position before text alteration
+	var saveUndo = true;
+	var isMoz = false;
+	var checkPastedReturns = false;
+	var unsaved = false;
+
+	/* states */
+	var holdingdownkey = false;
+	var holdingupkey = false;
+	var holdingdeletekey = false;
+	var holdingbackkey = false;
+	var holdingenterkey = false;
+	var holdingpgdownkey = false;
+	var holdingpgupkey = false;
+
+	/* search variables */
+
+	var str_search = 'texto';
+
+	/* keybindings */
+	keyBindings["default"]            = new Array();			
+	keyBindings["default"]["default"] = do_Default;			// Default action for unrecognized keys
+	keyBindings["default"]["40"]      = do_Down;			// down
+	keyBindings["default"]["s40"]     = do_SelectDown; 		// shift-down
+	keyBindings["default"]["38"]      = do_Up;				// up
+	keyBindings["default"]["s38"]     = do_SelectUp;		// shift-up
+	keyBindings["default"]["37"]      = do_Left;			// left
+	keyBindings["default"]["s37"]     = do_SelectLeft;		// shift-left	
+	keyBindings["default"]["39"]      = do_Right;			// right
+	keyBindings["default"]["s39"]     = do_SelectRight;		// shift-right
+	keyBindings["default"]["8"]       = do_Backspace;		// backspace
+	keyBindings["default"]["46"]      = do_Delete;			// delete
+	keyBindings["default"]["13"]      = do_Linebreak;		// enter
+	keyBindings["default"]["34"]      = do_PageDown;		// page-down
+	keyBindings["default"]["s34"]     = do_SelectPageDown;	// shift-page-down
+	keyBindings["default"]["33"]      = do_PageUp;			// page-up
+	keyBindings["default"]["s33"]     = do_SelectPageUp;	// shift-page-up
+	keyBindings["default"]["36"]      = do_Home;			// home
+	keyBindings["default"]["c36"]     = do_BeginCode;		// ctrl-home
+	keyBindings["default"]["35"]      = do_End;				// End 
+	keyBindings["default"]["c35"]     = do_EndCode;			// ctrl-end 
+	keyBindings["default"]["9"]       = do_Tab;				// Tab
+	keyBindings["default"]["c86"]     = do_Paste;			// ctrl-v
+	keyBindings["default"]["c90"]     = do_Undo;			// ctrl-z
+	keyBindings["default"]["c89"]     = do_Redo;			// ctrl-y
+	keyBindings["default"]["cs90"]    = do_Redo;			// ctrl-shift-z
+	//keyBindings["default"]["c67"]     = do_Copy;			//	ctrl-c
+
+	/* joe bindings */
+	keyBindings["joe"] = new Array();			
+	keyBindings["joe"]["c65"]     = do_Home;			// ctrl-e
+	keyBindings["joe"]["c69"]     = do_End;				// ctrl-a
+	keyBindings["joe"]["c88"]     = do_skipCharsRight;	// ctrl-x
+	keyBindings["joe"]["c90"]     = do_skipCharsLeft;	// ctrl-z
+	keyBindings["joe"]["c75"]     = joe_Ctrlk;			// ctrl-k
+	keyBindings["joe"]["cs189"]   = do_Undo;			// ctrl shift -
+	keyBindings["joe"]["cs54"]    = do_Redo;			// ctrl shift 6
+	keyBindings["joe"]["default"] = joe_Default;
+
+	/* joe ctrl-k bindings */
+	keyBindings["joe"]["ctrl-k"]            = new Array();
+	keyBindings["joe"]["ctrl-k"]["85"]	    = joe_ScrollHome;	// ctrl-k u
+	keyBindings["joe"]["ctrl-k"]["86"]	    = joe_ScrollEnd;	// ctrl-k v
+	keyBindings["joe"]["ctrl-k"]["default"] = joe_Default_Ctrlk;
+
+	/* keybinding to use */
+	keyBinding = keyBindings["default"];
+
+	
+	/* undo buffer constants */
+	var undo = { CHANGE_TEXT: 1, LINE_AFTER: 2, DELETE_LINE: 3 };
+	var window_title;
+
+	function handleMouseWheel(e)
+	{
+		if (!e) e = window.event;
+
+		if ( e.wheelDelta <= 0 || e.detail > 0) 
+		{ 
+			window.scrollBy(0,30); 
+		} 
+		else 
+		{ 
+			window.scrollBy(0,-30); 
+		}
+	}
+
+
+
+	function setInputFocus()
+	{
+		inputLineEntry.focus();
+	}
+
+	function init() {
+		contentDiv      = document.getElementById('content');	
+		codeframeDiv    = document.getElementById('codeframe');
+		lines           = document.getElementById('lines');
+		lineHeight      = lines.childNodes[0].offsetHeight;
+		currInputHeight = lineHeight;
+		lastLine        = lines.childNodes.length;
+		inputLine       = document.getElementById('inputLine');
+		inputLineEntry  = document.getElementById('inputLineEntry');
+		window_title    = window.parent.document.title;
+
+		if (parseInt(navigator.appVersion) > 3) 
+		{
+			if (navigator.appName == "Netscape") 
+			{
+				isMoz = true;
+				winW = window.innerWidth-42;
+				winH = window.innerHeight-2;
+				minInputWidth = winW-16;
+				document.onkeypress = moz_onKeyPress;
+				document.onkeydown  = keyDownHandler;
+				document.onkeyup    = keyUpHandler;
+				init_mozilla_compat();
+				window.addEventListener("DOMMouseScroll", handleMouseWheel, false);
+				/* do some w3c dom magic to get the current font size */
+				var vw         = document.defaultView;
+				var currStyle  = vw.getComputedStyle(lines,"");
+				var fontSize   = currStyle.getPropertyValue("font-size");
+				var fontFamily = currStyle.getPropertyValue("font-family");
+			} 
+			else 
+			if (navigator.appName.indexOf("Microsoft")!=-1) 
+			{
+				winW = document.body.offsetWidth;
+				winH = document.body.offsetHeight;
+				document.onkeydown = keyDownHandler;
+				document.onkeyup   = keyUpHandler;
+				/* get current font size */
+				var fontSize       = lines.currentStyle.fontSize;
+				var fontFamily     = lines.currentStyle.fontFamily;
+				clickPosOffsetLeft = 44;
+				minInputWidth      = winW-60;
+				// To handle clipboard paste
+				inputLineEntry.onpaste = pasteText;
+			} 
+			else 
+			{
+				document.onkeydown = keyDownHandler;
+				/* do some w3c dom magic to get the current font size */
+				var vw         = document.defaultView;
+				var currStyle  = vw.getComputedStyle(lines,"");
+				var fontSize   = currStyle.getPropertyValue("font-size");
+				var fontFamily = currStyle.getPropertyValue("font-family");
+			}
+
+		}
+
+		/* if the user closes the editor without saving his work, a confirmation is required to do so */
+		window.onbeforeunload = confirmExit;
+		function confirmExit()
+		{
+			if (unsaved)
+				return "Existem alterações neste arquivo que serão perdidas caso esta janela seja fechada.";
+		}
+
+		document.getElementById('linenumbers').style.height = winH;
+		updateLineNumbers();
+		inputLine.style.width  = minInputWidth;
+		inputLine.style.height = lineHeight;
+		inputLineEntry.onfocus = inputFocus;
+		inputLineEntry.onblur  = inputBlur;		
+		inputLineEntry.style.fontSize   = fontSize;
+		inputLineEntry.style.fontFamily = fontFamily;
+		inputLineEntry.style.height     = lineHeight;
+		inputLineEntry.style.overflow   = 'hidden';
+
+		// this is needed because MSIE sometimes shifts the textarea a bit...
+		adjustTop = -inputLineEntry.offsetTop;
+
+		/* calculate width, height of one letter, fix padding if needed */
+		var templine = lines.childNodes[0].innerHTML;
+		lines.childNodes[0].innerHTML='<span id="editorLetterWidth">m</span>';
+		letterWidth=document.getElementById("editorLetterWidth").offsetWidth;
+		spanHeight=document.getElementById("editorLetterWidth").offsetHeight;
+		spanTopPadding=document.getElementById("editorLetterWidth").offsetTop;
+		if (lineHeight>spanHeight) {
+			// this is to make background colors span the entire height of the line
+			spanBottomPadding=(lineHeight-spanHeight)-spanTopPadding;
+		} else {
+			spanBottomPadding=0;
+		}
+		if (spanTopPadding || spanBottomPadding) {
+			// get the stylesheet and apply this padding to each span
+			var editorStylesheet=document.styleSheets[0];
+			if (navigator.appName.indexOf("Microsoft")!=-1) {		
+				editorStylesheet.addRule("SPAN", "padding-top: "+spanTopPadding+"px; padding-bottom: "+spanBottomPadding+"px;", 0);
+			} else {
+				editorStylesheet.insertRule("SPAN { padding-top: "+spanTopPadding+"px; padding-bottom: "+spanBottomPadding+"px; }", 0);
+			}
+		}
+		lines.childNodes[0].innerHTML=templine;
+		document.onmousedown = mouseDownHandler;
+		document.onmouseup = mouseUpHandler;
+		window.onresize  = resizeHandler;; 
+		
+		var _temp='';
+		for (var i=0; i<lines.childNodes.length; i++) {
+			// need to remove trailing ' ', which IE puts there.
+			_temp=getLineContent(i+1);
+			if (navigator.appName.indexOf("Microsoft")!=-1) {
+				_temp=_temp.substr(0, _temp.length-1);
+			}
+			if (_temp.length>longestLine) {
+				longestLine=_temp.length;
+			}
+			currLine=new hLine(i, _temp);
+			currLine.doHighlight(applyHighlightedLine);
+		}
+		if ((longestLine*letterWidth)>minInputWidth) {
+			inputLine.style.width=longestLine*letterWidth+4;
+		}
+
+		redrawInputLine();
+	}
+
+	function pasteText() {
+		var content = clipboardData.getData('text');
+		var re = /^([^\n\r]*)(\r\n|\r|\n)/;
+		var match;
+		var lines;
+		var cur = currentLine;
+	
+		if (document.selection) { // For IE only
+			var tr = document.selection.createRange();
+			tr.text = content;
+			content = inputLineEntry.value;
+		} else { // There is nothing to do in Mozilla
+			return;
+		}
+/*
+		match = re.exec(content);
+		if( match && match[1] != null ) {
+			inputLineEntry.value = match[1];
+			isDirty = true;
+			checkDirty();
+			updateLine(currentLine,match[1]);
+			content = content.substr(match[0].length);
+		} else {
+			isDirty = true;
+			checkDirty();
+			updateLine(currentLine,content);
+			content = false;
+		}
+		if(content != false) {
+			while( content != false ) {
+				var trans;
+				match = re.exec(content);
+				if( match && match[1] != null ) {
+					trans = match[1];
+					content = content.substr(match[0].length);
+				} else {
+					trans = content;
+					content = false;
+				}
+				insertLineAfter(cur++,trans);
+			}
+		}
+*/		
+
+		content = content.replace(/\r\n/g, "\n"); 
+		content = content.replace(/\r/g, "\n"); 
+
+		lines = content.split('\n');
+		inputLineEntry.value = lines[0];	
+		isDirty = true;
+		checkDirty();
+		updateLine(currentLine,lines[0]);
+	
+		for (i = 1; i<lines.length; i++) {
+			insertLineAfter(cur++,lines[i]);
+		}
+
+		event.returnValue=false;
+	}
+
+	function init_mozilla_compat() {
+		HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sText) {
+			var r = document.createRange();
+			safewhere = sWhere.toLowerCase();
+			switch (safewhere) {
+				case "beforebegin":
+					r.setStartBefore(this);
+					this.parentNode.insertBefore(r.createContextualFragment(sText), this);
+					break;
+
+				case "afterbegin":
+					r.setStartBefore(this.firstChild);
+					this.insertBefore(r.createContextualFragment(sText), this.firstChild);
+					break;
+
+				case "beforeend":
+					r.setStartAfter(this.lastChild);
+					this.appendChild(r.createContextualFragment(sText));
+					break;
+
+				case "afterend":
+					r.setStartAfter(this);
+					this.parentNode.insertBefore(r.createContextualFragment(sText),
+						this.nextSibling);
+					break;
+			}
+		};
+		Node.prototype.removeNode = function( removeChildren ) {
+			var self = this;
+			if ( Boolean( removeChildren ) )
+			{
+				return this.parentNode.removeChild( self );
+			}
+			else
+			{
+				var range = document.createRange();
+				range.selectNodeContents( self );
+				return this.parentNode.replaceChild( range.extractContents(), self );
+			}
+		};
+	}
+
+	function inputFocus() {
+		inputLineHasFocus=true;
+	}
+
+	function inputBlur() {
+		inputLineHasFocus=false;
+	}
+
+	function applyHighlightedLine(lineNo, highlightedLine) {
+		// the extra span is to correctly calculate the offset of the content
+		// to position the input line
+		setLineContent(lineNo+1, '<span><nobr>'+highlightedLine+'</nobr></span>');
+	}
+
+	function moveDown(amount) {
+		//FIXME: start made with selections
+		//  change moveUp as well
+		//  and change textarea size back again in stopselect
+		if (userSelecting) {
+			if( (currentLine + offsetLine) < lastLine ) { // Don't select past the last line...
+				currInputHeight+=lineHeight;
+				inputLine.style.height=currInputHeight;
+				inputLineEntry.style.height=currInputHeight;
+				inputLineEntry.value+='\n'+getLineContent(currentLine+offsetLine+1);
+
+				offsetLine = inputLineEntry.value.split('\n').length - 1;
+			    window.scrollBy(0,lineHeight);	
+				setCursorPos(selectIni,getCursorPos());
+				return !isMoz;
+			} else {
+				return false;
+			}
+		} else {
+			checkDirty();
+			if (currentLine<lastLine) {
+				previousLine = currentLine;
+				currentLine+=amount;
+				if (currentLine>lastLine) {
+					currentLine=lastLine;
+				}
+				redrawInputLine();
+			}
+			return !isMoz;
+		}
+	}
+
+	function moveUp(amount) {
+		if( userSelecting) {
+			if( offsetLine > 0 ) { // Don't select smaller than 1 line
+				currInputHeight            -= lineHeight;
+				inputLine.style.height      = currInputHeight;
+				inputLineEntry.style.height = currInputHeight;
+				
+				var myValue = inputLineEntry.value;
+				var lines;
+
+				if (isMoz) {
+					myValue = myValue.replace(/(.*)\n(.*[\n]?)$/,"$1"); //remove last line
+				} else {
+					myValue = myValue.replace(/(.*)\r\n(.*)$/,"$1"); //remove last line
+				}
+				
+				inputLineEntry.value = myValue;
+				offsetLine = inputLineEntry.value.split('\n').length - 1;
+			    window.scrollBy(0,-lineHeight);	
+				setCursorPos(selectIni,getCursorPos());
+				return !isMoz;
+			} else {
+				return false;
+			}
+		} else {
+			checkDirty();
+			if (currentLine>1) {
+				previousLine = currentLine;
+				currentLine-=amount;
+				if (currentLine<1) {
+					currentLine=1;
+				}
+				redrawInputLine();
+			}
+			return !isMoz;
+		}
+	}
+
+	function redrawInputLine(dontfocus) {
+		var pos;
+		if (!dontfocus) {
+			var oldline;
+			oldpos = getCursorPos();
+			/*
+			 * we are gona calculate the real old pos by counting tabs for 8
+			 */
+			//oldline = getLineContent(previousLine);
+			newline = getLineContent(currentLine);
+			if (newline.length < oldpos)
+				oldpos = newline.length;
+		}
+		// mozilla sometimes jumps the lines offset around, so we need to get the
+		// offset of the content of the line, not the line itself 
+		var mytop=lines.childNodes[currentLine-1].firstChild.offsetTop+adjustTop;
+		//inputLine.style.top = mytop;
+		inputLine.style.top = (currentLine - 1)*lineHeight;
+		
+		var value=getLineContent(currentLine);
+		inputLineEntry.value=value;
+		if (!dontfocus) {
+			pos = oldpos;
+			setCursorPos(pos);
+//			I don't think this is needed anymore
+//			inputLineEntry.focus(); // scroll into view pls..
+		}
+		startCursorPos = -1;
+		/* update the informatin panel */
+		parent.document.getElementById('info').innerHTML = currentLine + " / " + lines.childNodes.length;
+	}
+
+	function getCursorPos() {
+		// don't set the focus to the input line here, or the screen
+		// will 'dance' around. Its not needed anyway.
+		if (document.selection) {
+			var mtext=document.selection.createRange();
+			var count=0;
+			var moved=0;
+			while (moved=mtext.moveStart('character', -100)) {
+				count-=moved;
+			}
+			chars=mtext.text.length;
+			return chars;
+		} else {
+			var selection=window.getSelection();
+			if (selection.anchorNode) {
+				var len = inputLineEntry.selectionEnd;
+				return len;
+			}
+		}
+	}
+
+
+	function setCursorPos(cursorstart, cursorend, clicked) {
+		var counter;
+		var contents=new String(inputLineEntry.value);
+		if (cursorstart==-1) {
+			cursorstart=contents.length;
+		}
+
+		/*
+		counter = cursorstart;
+		cursorstart = 0;
+		while(counter > 0){
+			if(contents.charAt(cursorstart) == "\t"){
+				counter -= 7;
+			}
+			cursorstart++;
+			counter--;
+		}
+		cursorstart = cursorstart;
+		*/
+
+		if (contents.length<cursorstart && !clicked) {
+			addedSpaces=cursorstart-contents.length+1;
+			for (i=0; i<addedSpaces; i++ ){
+				contents+=' ';
+			}
+			inputLineEntry.value=contents;
+		} else if (clicked) {
+			if (cursorstart>contents.length) {
+				cursorstart=contents.length;
+			}
+			addedSpaces=0;
+		} else {
+			addedSpaces=0;
+		}
+		if (document.selection) {
+			var mtext=inputLineEntry.createTextRange();
+			mtext.collapse(true);
+			mtext.moveStart('character', cursorstart);
+			mtext.collapse(true);
+			if (cursorend) {
+				mtext.moveEnd('character', (cursorend-cursorstart));
+			}
+			mtext.select();
+		} else {
+			// do something Mozilla style
+			if (!cursorend) {
+				cursorend=cursorstart;
+			}
+			// for mozilla, set the focus to scroll the input line into view
+			inputLineEntry.focus();
+			inputLineEntry.setSelectionRange(cursorstart, cursorend);
+		
+/*
+			var selection=window.getSelection();
+			if (selection.anchorNode) {
+				inputLineEntry.selectionStart = cursorstart;
+				if (cursorend) {
+					inputLineEntry.selectionEnd = cursorend;
+				} else {
+					inputLineEntry.selectionEnd = cursorstart;
+				}
+			}
+*/
+		}
+
+		// calculate cursor position in px
+		if (cursorend) {
+			var scrollToChar=cursorend;
+		} else {
+			var scrollToChar=cursorstart;
+		}
+		cursorpx=letterWidth*(scrollToChar+10);
+		if (cursorpx>150) { //(winW-44)) {
+//			don't do this, let IE and mozilla handle it themselves
+//			document.body.scrollLeft=cursorpx+44;
+		} else {
+			document.body.scrollLeft=0;
+		}
+		return false;
+	}
+
+	function removeAddedSpaces() {
+		if (addedSpaces) {
+			var _temp=new String(inputLineEntry.value);
+			_temp=_temp.substr(0, _temp.length-addedSpaces);
+			inputLineEntry.value=_temp;
+			addedSpaces=0;
+		}
+	}
+
+	function getLineContent(lineNo) {
+		var myString = new String();
+		if(lines.childNodes[lineNo-1]){
+			if( typeof(lines.childNodes[lineNo-1].originalInnerText)!="undefined" ) {
+				return lines.childNodes[lineNo-1].originalInnerText;
+			}
+			if (lines.childNodes[lineNo-1].innerText) {
+				return lines.childNodes[lineNo-1].innerText;
+			} else if (document.createRange) {
+				var html = document.createRange();
+				var myLine = lineNo-1;
+				while( lines.childNodes[myLine].tagName != 'LI' ) {
+					myLine++;
+				}
+				html.selectNodeContents(lines.childNodes[myLine]);
+				myString = html.toString();
+				myString = myString.replace(/\n/g, '');
+				myString = myString.replace(/\r/g, '');
+				return myString;
+			}
+		}
+		return "";
+	}
+
+	function getContents() {
+		var i=1;
+		var myContent='';
+		checkDirty();
+		while( lines.childNodes[i-1] ) {
+			myContent = myContent + getLineContent(i) + '\n';
+			i++;
+		}
+		return myContent;
+	}
+
+	function setContents(content) {
+		var myHead;
+        var re = /^([^\n\r]*)(\r\n|\r|\n)/;
+		var match;
+		var originalArray = new Array();
+
+		deleteContents();
+
+		match = re.exec(content);
+		if( match && match[1] != null ) {
+			updateLine(1,match[1]);
+			originalArray[lastLine] = match[1];
+                      content = content.substr(match[0].length);
+		} else {
+			updateLine(1,content);
+			originalArray[lastLine] = content;
+			content = false;
+		}
+		if(content != false) {
+			var htmlcontent = '';
+			while( content != false ) {
+				var trans;
+				match = re.exec(content);
+				if( match && match[1] != null ) {
+					trans = match[1];
+                                      content = content.substr(match[0].length);
+				} else {
+					trans = content;
+					content = false;
+				}
+				lastLine++;
+				originalArray[lastLine] = trans;
+				trans = trans.replace(/[&]/g,"&amp;");
+				trans = trans.replace(/[<]/g,"&lt;");
+				trans = trans.replace(/[>]/g,"&gt;");
+				trans = trans.replace(/[ ]/g,"&nbsp;");
+				trans = trans.replace(/["]/g,"&quot;");
+				htmlcontent += "<li>"+trans+"\n</li>";
+			}
+			if(htmlcontent){
+				lines.childNodes[0].insertAdjacentHTML("AfterEnd",htmlcontent);
+			}
+		}
+		var _temp='';
+		for (var i=1; i<lines.childNodes.length; i++) {
+			lines.childNodes[i].originalInnerText = originalArray[i+1];
+			_temp=getLineContent(i+1);
+			if (_temp.length>longestLine) {
+				longestLine=_temp.length;
+			}
+			
+			currLine=new hLine(i, _temp);
+			currLine.doHighlight(applyHighlightedLine);
+		}
+		if ((longestLine*letterWidth)>minInputWidth) {
+			inputLine.style.width=longestLine*letterWidth+4;
+		}
+		currentLine=1;
+		updateLineNumbers();
+		redrawInputLine();
+		undoBuffer = [];
+		redoBuffer = [];
+
+		//inputLine.style.display = 'none';
+		//document.getElementById('editor').contentWindow.document.designMode = "on";
+	}
+
+	function setKeyBinding(keybind) {
+		if( keyBindings[keybind] ) {
+			keyBinding = keyBindings[keybind];
+		}
+	}
+
+
+	function setAutoIndent(indentvalue) {
+		if( indentvalue == "on" ) {
+			autoIndent = true;
+		} else {
+			autoIndent = false;
+		}
+	}
+
+	function keyUpHandler(evt) {
+
+		var charCode;
+		var iniDelLine;
+
+		if (isMoz) {
+			charCode = (evt.charCode ? evt.charCode : ((evt.keyCode) ? evt.keyCode : evt.which));
+		} else {
+			charCode = window.event.keyCode;
+			evt = window.event;
+		}
+		
+		charCode = parseInt(charCode);
+		
+		holdingupkey     = false;
+		holdingdownkey   = false;
+		holdingdeletekey = false;
+		holdingbackkey 	 = false;
+		holdingpgupkey   = false;
+		holdingpgdownkey = false;
+
+		if ( holdingenterkey ) {
+			redrawInputLine();
+			holdingenterkey = false;
+		}
+
+		if( isMoz && checkPastedReturns ) {
+			fixPastedReturns();
+			checkPastedReturns = false;
+		}
+
+		if ( ( ( evt.ctrlKey ) && ( charCode != 88 ) ) || ( charCode == 67 ) ) 
+			return false;
+	
+		if (userSelecting && 
+		      ( 
+				 isNormalKey(charCode) 
+		    	 || ( charCode == 46 ) /*delete key*/ 
+				 || ( charCode == 8  ) /*bakspace key*/
+			  ) 
+			) {
+				
+			
+			iniDelLine = currentLine + 1;
+			
+			isDirty = true;
+			checkDirty();
+
+			deleteMultipleLines(iniDelLine,currentLine+offsetLine);
+			//for (i=iniDelLine;i<=currentLine+offsetLine;i++)
+			//	deleteLine(iniDelLine);
+
+			stopSelect();
+			//redrawInputLine(true);
+		}
+
+		if (
+			 isNormalKey(charCode) 
+		   	 || ( charCode == 46 ) /*delete key*/ 
+			 || ( charCode == 8  ) /*bakspace key*/
+			 || ( charCode == 13 ) /*enter key*/
+			) 
+		{
+			window.parent.document.title = window_title + ' (+)';
+			unsaved = true;
+		}
+
+		if ( ( charCode == 38 ) && userSelecting ) {
+			//inputLineEntry.setSelectionRange(selectIni, inputLineEntry.value.length);
+			setCursorPos(selectIni,inputLineEntry.value.length);
+		}
+		
+		if (isMoz) {
+			if ( ( charCode == 37 ) && userSelecting ) {
+				if (inputHasLineEnd()) 
+					fixLineGap();
+			}
+		}
+		window.status = 'L: '+currentLine+' C: '+(getCursorPos()+1);
+	}
+
+
+	function fixPastedReturns(mousepaste) {
+		var re = /^([^\n\r]*)(\r\n|\r|\n)/;
+		var match;
+		var content = inputLineEntry.value;
+		var cur = currentLine;
+		var lines;
+		
+		if (isMoz) {
+			if (mousepaste) {
+				content = content.replace(/#/g, ""); //remove # from mozilla browsers!!	
+			} else {
+				content = content.replace(/^#/g, ""); //remove # from mozilla browsers!!	
+			}
+			/*
+			content = content.replace(/\r\n/g, "\n"); 
+			content = content.replace(/\r/g, "\n"); 
+			*/
+		}
+
+		
+		match = re.exec(content);
+		if( match && match[1] != null ) {
+			inputLineEntry.value = match[1];
+			isDirty = true;
+			checkDirty();
+			updateLine(currentLine,match[1]);
+			content = content.substr(match[0].length);
+		} else {
+			content = false;
+		}
+		while( content != false ) {
+			var trans;
+			match = re.exec(content);
+			if( match && match[1] != null ) {
+				trans = match[1];
+				content = content.substr(match[0].length);
+			} else {
+				trans = content;
+				content = false;
+			}
+			insertLineAfter(cur++,trans);
+		}
+	
+		inputLineEntry.focus();
+	
+		/*
+		lines = content.split('\n');
+		inputLineEntry.value = lines[0];	
+		isDirty = true;
+		checkDirty();
+		updateLine(currentLine,lines[0]);
+	
+		for (i = 1; i<lines.length; i++) {
+			insertLineAfter(cur++,lines[i]);
+		}
+		*/
+	}
+
+
+	function moz_onKeyPress(evt) {
+		// Mozilla has a lot of trouble canceling events
+		// an onkeydown event can not be cancelled
+		// so we cancel the onkeypress...
+		if( cancelKey ) {
+			cancelKey = false;
+			return false;
+		} else {
+			if (holdingdownkey) {
+				moveDown(1);
+			}
+			if (holdingupkey) {
+				moveUp(1);
+			}
+			if (holdingpgupkey) {
+				do_PageUp();
+			}
+			if (holdingpgdownkey) {
+				do_PageDown();
+			}
+			if (holdingdeletekey)
+				do_Delete();
+			if (holdingbackkey)
+				do_Backspace();
+			if (holdingenterkey) {
+				//insertLineAfter(currentLine, new String(getLineContent(currentLine)));
+				//updateLine(currentLine-1, '');
+				//setCursorPos(0);
+				//inputLineEntry.focus();
+				insertLineAfter(currentLine, '');
+				//isDirty = true;
+				//checkDirty();
+				//inputLineEntry.focus();
+				//breakCurrentLine();
+			}
+			return true;
+		}
+	}
+	
+	function keyDownHandler(evt) {
+		var charCode;
+		var charString = '';
+		var keyResult;
+
+		
+		evt = (evt) ? evt : ((event) ? event : null );
+		if( evt ) {
+			// Get the key pressed
+			
+			charCode = (evt.charCode ? evt.charCode : ((evt.keyCode) ? evt.keyCode : evt.which));
+
+			// Create the encoded character string 
+
+			charString = charCode;
+			if( evt.shiftKey ) {
+				charString = 's' + charString;
+			}	
+			if( evt.ctrlKey ) {
+				charString = 'c' + charString;
+			}			
+			if( evt.altKey ) {
+				charString = 'a' + charString;
+			}
+
+
+			if( keyBinding[charString] ) {
+				keyResult = keyBinding[charString]();
+			} else {
+				keyResult = keyBinding["default"](charString);
+			}
+
+			if( ! keyResult ) {
+				cancelKey = true;
+				if( evt.preventDefault ) {
+					// This is the DOM way to cancel it but somehow
+					// Mozilla refuses. Maybe another DOM browser will
+					// make use of it :)
+					evt.preventDefault();
+				}
+			}
+
+			return keyResult;
+		}
+	}
+
+
+	function joe_Ctrlk(charString) {
+		keyBinding = keyBindings["joe"]["ctrl-k"];
+		window.status = "ctrl-k ";
+		return false;
+	}
+
+	function joe_Default_Ctrlk(charString) {
+		keyBinding = keyBindings["joe"];
+		window.status = "ctrl-k " + charString;
+		return false;
+	}
+
+	function joe_Default(charString) {
+		var keyBinding;
+		keyBinding = keyBindings["default"];
+		if( keyBinding[charString] ) {
+			return keyBinding[charString]();
+		} else {
+			window.status = charString;
+			return keyBinding["default"](charString);
+		}
+	}
+
+	function joe_ScrollEnd() {
+		keyBinding = keyBindings["joe"];
+		window.status = "ctrl-k v";
+		currentLine = lastLine;
+		redrawInputLine();
+		//window.scroll(800,inputLine.style.top);
+		//window.scroll(0,0);
+		do_End();		
+		return false;
+	}
+	
+	function joe_ScrollHome() {
+		keyBinding = keyBindings["joe"];
+		window.status = "ctrl-k u";
+		currentLine = 1;
+		redrawInputLine();
+		do_Home();
+		return false;
+	}
+
+	function do_Default(charString) {
+		removeAddedSpaces();
+		oldpos=-1;
+		isDirty=true;
+		if(startCursorPos<0) startCursorPos = getCursorPos();
+		return true;
+	}
+	
+	function do_SelectUp() {
+		startSelect();
+		return do_Up(true);
+	}
+	
+	function do_SelectDown() {
+		startSelect();
+		return do_Down(true);
+	}
+	
+	function do_Down(selecting) {
+		if( !selecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() ) {
+				redrawInputLine();
+			}
+		}
+		holdingdownkey = true;
+		return moveDown(1);
+	}
+	
+	function do_Up(selecting) {
+		if( !selecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() )
+				redrawInputLine();
+		}
+		holdingupkey = true;
+		return moveUp(1);
+	}
+	
+	function do_SelectLeft() {
+		startSelect();
+		return do_Left(true);
+	}
+
+	function do_Left(selecting) {
+		var result=true;
+		var content;
+
+		//if (isMoz) {
+			//checkDirty();
+		//}
+
+		if( !selecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() )
+				redrawInputLine();
+		} else {
+			if (!isMoz) {
+				content = inputLineEntry.value;
+				if (content.charAt(getCursorPos()) == '\r') {
+					fixLineGap();
+				}
+			}
+		}
+		if (addedSpaces) {
+			removeAddedSpaces();
+			result=false;
+		}
+		oldpos=-1;
+		return result;
+	}
+
+	function do_SelectRight() {
+		startSelect();
+		return do_Right(true);
+	}
+
+	function do_Right(selecting) {
+		var result=true;
+	
+		//if (isMoz) {
+		//	checkDirty();
+		//}
+		
+		if( !selecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() )
+				redrawInputLine();
+		}
+		//if (currentLine<lastLine) {
+		//	var _currline=getLineContent(currentLine);
+		//	if (getCursorPos()>=_currline.length) {
+		//		moveDown(1);
+		//		setCursorPos(0);
+		//		result=false;
+		//	}
+		//}
+		oldpos=-1;
+		if ( isMoz && ( getCursorPos() == ( inputLineEntry.value.length - 1 ) ) )
+		{
+			setCursorPos(inputLineEntry.value.length);
+		}
+		return result;
+	}
+
+	function do_Backspace() {
+		var result=true;
+		holdingbackkey = true;
+
+		if (addedSpaces) {
+			removeAddedSpaces();
+			result=false;
+		} else {
+			oldpos=-1;
+			if (getCursorPos()==0) {
+				checkDirty();
+				glueCurrentLine(-1);
+				result=false;
+			}
+			isDirty=true;
+		}
+		return result;
+	}
+
+	function do_Delete() {
+		var result=true;
+	
+		holdingdeletekey = true;
+
+		if (addedSpaces) {
+			removeAddedSpaces();
+			result=false;
+		} else {
+			oldpos=-1;
+			if (currentLine<lastLine) {
+				var _editline=inputLineEntry.value;
+				if (getCursorPos()==_editline.length) {
+					if (!isMoz) {
+						document.selection.createRange().text = "";
+					} else {
+						inputLineEntry.value = inputLineEntry.value.substring(0,inputLineEntry.selectionStart) + 
+											   inputLineEntry.value.substring(inputLineEntry.selectionEnd,inputLineEntry.value.length);
+					}
+					checkDirty();
+					if (offsetLine == 0)
+						glueCurrentLine(1);
+					result = false;
+				}
+			}
+			isDirty=true;
+		}
+		return result;
+	}
+
+	function do_Linebreak() {
+		if (userSelecting) 
+			return false;
+		holdingenterkey = true;
+		removeAddedSpaces();
+		oldpos=-1;
+		breakCurrentLine();
+		return false;
+	}
+
+	function do_SelectPageDown() {
+		startSelect();
+		return do_PageDown();
+	}
+
+	function do_PageDown() {
+		holdingpgdownkey = true;
+		moveDown(20);
+		return false;
+	}
+
+	function do_SelectPageUp() {
+		startSelect();
+		return do_PageUp();
+	}
+
+	function do_PageUp() {
+		holdingpgupkey = true;
+		moveUp(20);
+		return false;
+	}
+
+	function do_Home() {
+		if (userSelecting)
+			return false;
+		removeAddedSpaces();
+		setCursorPos(0);
+		window.parent.scrollBy(-2000,0);
+		oldpos = -1;
+		return false;
+	}
+
+	function do_End() {
+		if (userSelecting)
+			return false;
+		removeAddedSpaces();
+		setCursorPos(inputLineEntry.value.length);
+		if (getCursorPos()*letterWidth + linenumbers.style.width > window.parent.innerWidth) {
+			window.parent.scrollBy(getCursorPos()*letterWidth,0);
+		}
+		oldpos = -1;
+		return false;
+	}
+
+	function do_Tab() {
+		var line = inputLineEntry.value;
+		var cursor = getCursorPos();
+		if (userSelecting) 
+			return false;
+		line = line.substr(0,cursor) + "\t" + line.substr(cursor);
+		inputLineEntry.value = line;
+		setCursorPos(cursor + 1);
+		isDirty=true;
+		return false;
+	}
+
+	function do_skipCharsRight() {
+		return skipChars(1);
+	}
+
+	function do_skipCharsLeft() {
+		return skipChars(-1);
+	}
+
+	function do_Paste() {
+		if( isMoz ) {
+			checkPastedReturns = true;
+		}
+		isDirty = true;
+		return true;
+	}
+	
+	function do_Undo() {
+		checkDirty();
+		if(undoBuffer.length<1) {
+			return false;
+		}
+		var u = undoBuffer.pop();
+		UndoIt(u,redoBuffer);
+		return false;
+	}
+	
+	function do_Redo() {
+		if(redoBuffer.length<1) {
+			return false;
+		}
+		var u = redoBuffer.pop();
+		UndoIt(u,undoBuffer);
+		return false;
+	}
+		
+	function UndoIt(u,redoBuffer) {
+		saveUndo = false;
+		switch(u.type) {
+			case undo.CHANGE_TEXT:
+				updateLine(u.line,u.text);
+				redoBuffer.push({ type: u.type, line: u.line, text: u.newText, newText: u.text, cursor: u.newCursor, newCursor: u.cursor });
+			  break;
+			case undo.LINE_AFTER:
+				deleteLine(u.line);
+				redoBuffer.push({ type: undo.DELETE_LINE, line: u.line, text: u.text, cursor: u.newCursor, newCursor: u.cursor });
+			  break;
+			case undo.DELETE_LINE:
+				insertLineAfter(u.line-1,u.text);
+				redoBuffer.push({ type: undo.LINE_AFTER, line: u.line, text: u.text, cursor: u.newCursor, newCursor: u.cursor });
+			  break;
+			default:
+				saveUndo = true;
+				return false;
+		}		
+		currentLine = u.line;
+		inputLineEntry.value = getLineContent(currentLine);
+		redrawInputLine();
+		setCursorPos(u.cursor);
+		saveUndo = true;
+		return true;
+	}
+	
+	function addUndo(ob) {
+		undoBuffer.push(ob);
+		redoBuffer = [];
+	}
+
+	function skipChars(dir) {
+		var cursor, curstate, curchar;
+		function is_letter (l) {
+			if (l >= 'a' && l <= 'z' ||
+				l >= 'A' && l <= 'Z') {
+					return true;
+			} else {
+					return false;
+			}
+		}
+
+		removeAddedSpaces();
+		cursor = getCursorPos();
+		if (dir < 0) {
+			cursor--;
+		}
+		curstate = is_letter(inputLineEntry.value.charAt(cursor));
+		if (!curstate) {
+			/* forward over current state */
+			while (curstate == is_letter(inputLineEntry.value.charAt(cursor+=dir))
+				&& cursor > 0 && cursor < inputLineEntry.value.length){};
+		} else {
+			cursor += dir;
+		}
+
+		curstate = is_letter(inputLineEntry.value.charAt(cursor));
+		/* forward over next state */
+		while (curstate == is_letter(inputLineEntry.value.charAt(cursor+=dir))
+				&& cursor > 0 && cursor < inputLineEntry.value.length);
+
+		if (dir < 0) {
+			cursor++;
+		}
+
+		if (cursor < 0) {
+			cursor = 0;
+		} else if (cursor >= inputLineEntry.value.length) {
+			cursor = inputLineEntry.value.length;
+		}
+
+		setCursorPos(cursor);
+		oldpos = -1;
+		return false;
+	}
+
+
+	function KeyUpHandler() {
+	}
+
+
+	function Coordinate(x, y) {
+		this.x=x;
+		this.y=y;
+	}
+
+	function mouseGetCoordinates(evt) {
+		var target = (evt.target) ? evt.target : evt.srcElement;
+		var clickX = -1;
+		var clickY = -1;
+		if( target && target.nodeName!='HTML' && target.nodeName!='BODY' ) { // HTML(moz) and BODY(IE) means clicked outside of our code..
+			while (target && target.nodeName!='LI' && target.nodeName!='TEXTAREA' && target.nodeName!='DIV') {
+				if( target.parentElement ) {
+					target=target.parentElement;
+				} else {
+					// mozilla style
+					target =  target.parentNode;
+				}
+			}
+			if( target ) {
+				// get click position
+				if (evt.pageX) {
+					var offsetX=evt.pageX - ((target.offsetLeft) ? target.offsetLeft : target.left);
+					var offsetY=evt.pageY - ((target.offsetTop) ? target.offsetTop : target.top);				
+				} else if (evt.offsetX || evt.offsetY) {
+					var offsetX = evt.offsetX;
+					var offsetY = evt.offsetY;	
+				} else if (evt.clientX || evt.clientY) {
+					var offsetX = evt.clientX - ((target.offsetLeft) ? target.offsetLeft : 0);
+					var offsetY = evt.clientY - ((target.offsetTop) ? target.offsetTop : 0);
+				}
+				offsetX-=clickPosOffsetLeft;
+				var clickX=Math.round(offsetX/letterWidth);
+	
+				// find a known container of the mouseclick
+				if (target.nodeName=='LI') {
+					clickY=1;
+					while (target=target.previousSibling) {
+						clickY++;
+					}
+				} else if (target.nodeName=='INPUT') {
+				} else if (target.nodeName=='TEXTAREA') {
+				} else if (target.nodeName=='DIV') {
+				} else {
+					clickY=Math.round(offsetY/lineHeight)+1;
+				}
+			}
+		}
+		if (clickX>-1 && clickY>-1) {
+			return new Coordinate(clickX, clickY);		
+		} else {
+			return false;
+		}
+	}
+
+
+
+	function mouseUpHandler(evt) {
+	
+		evt = (evt) ? evt : event;
+		var coordinate=mouseGetCoordinates(evt);
+		if (coordinate) {
+			checkDirty();
+			if (startcoordinate && 
+					(!(startcoordinate.x==coordinate.x) || 
+					 !(startcoordinate.y==coordinate.y)) ) {
+				if (startcoordinate.y==coordinate.y) {
+					// single line selection
+					if (startcoordinate.x>coordinate.x) {
+						var _temp=coordinate;
+						coordinate=startcoordinate;
+						startcoordinate=_temp;
+					}
+					currentLine=coordinate.y;
+					redrawInputLine(true);
+					setCursorPos(startcoordinate.x, coordinate.x, true);
+					oldpos=-1;
+					evt.cancelBubble=true;
+					return false;
+				} else {
+					// multi line selection
+					if (startcoordinate.y>coordinate.y) {
+						var _temp=coordinate;
+						coordinate=startcoordinate;
+						startcoordinate=_temp;
+					}
+					
+				}
+			} else {
+				// no selection
+				currentLine=coordinate.y;
+				redrawInputLine(true);
+				setCursorPos(coordinate.x, 0, true);
+				oldpos=-1;
+				evt.cancelBubble=true;
+				return false;
+			}
+		}
+
+		if (isMoz && (evt.button == 1))
+		{
+			checkPastedReturns = true;
+			setTimeout("fixmousepaste()",200);
+		}
+
+		
+	}
+
+	function mouseDownHandler(evt) {
+		evt = (evt) ? evt : event;
+		startcoordinate=mouseGetCoordinates(evt);
+
+		stopSelect();
+		if ( inputHasLineEnd() )
+			redrawInputLine();
+	}
+
+	function startSelect() {
+		userSelecting=true;
+		if (selectIni == -1) {
+			selectIni=getCursorPos();
+		}
+		if (selectLineIni == -1) {
+			selectLineIni=currentLine;
+		}
+	}
+
+	function stopSelect() {
+		// Return the inputline to it's original size
+		inputLine.style.height=lineHeight;
+		inputLineEntry.style.height=lineHeight;
+		currInputHeight = lineHeight;
+		offsetLine=0;
+		selectIni = -1;
+		userSelecting=false;
+		// get selected contents, put them in a buffer or something
+	}
+
+	function updateLine(lineNo, lineContent) {
+		lines.childNodes[lineNo-1].originalInnerText = lineContent;
+		highlightUpdateLine(lineNo-1, lineContent, applyHighlightedLine);
+		if (lineContent.length>longestLine) {
+			longestLine=lineContent.length;
+			if( (longestLine*letterWidth) > minInputWidth ) {
+				inputLine.style.width=longestLine*letterWidth+4;
+			}
+		}
+	}
+
+	function setLineContent(lineNo, lineContent) {
+		if(lines.childNodes[lineNo-1]){
+			lines.childNodes[lineNo-1].innerHTML=lineContent;
+			
+			lines.childNodes[lineNo-1].originalInnerHTML=lineContent;
+		}
+	}
+
+	function insertLineAfter(lineNo, lineContent) {
+		var oldCursor = getCursorPos();
+		lines.childNodes[lineNo-1].insertAdjacentHTML("AfterEnd","<li>");
+		highlightAppendLine(lineNo-1, lineContent, false); // do not display this yet
+		currentLine=lineNo+1;
+		updateLine(currentLine, lineContent);
+		oldpos=-1;
+		redrawInputLine(true);
+		updateLineNumbers();
+		lastLine++;
+		if(saveUndo) {
+			undoBuffer.push({type: undo.LINE_AFTER, line: currentLine, text: lineContent, cursor: getCursorPos(), newCursor: oldCursor });
+		}
+	}
+
+	function deleteLine(lineNo) {
+		if(saveUndo) {
+			var content = getLineContent(lineNo);
+			undoBuffer.push({type: undo.DELETE_LINE, line: lineNo, text: content, cursor: getCursorPos() , newCursor: content.length });
+		}
+		lines.childNodes[lineNo-1].removeNode(true);
+		highlightDeleteLine(lineNo-1, applyHighlightedLine);
+		updateLineNumbers();
+		lastLine--;
+	}
+
+	function deleteMultipleLines(lineIni,lineCount)
+	{
+		var i;
+		
+		for (i = lineIni; i <= lineCount; i++)
+		{
+			if(saveUndo) {
+				var content = getLineContent(lineIni);
+				undoBuffer.push({type: undo.DELETE_LINE, line: lineIni, text: content, cursor: getCursorPos() , newCursor: content.length });
+			}
+			lines.childNodes[lineIni-1].removeNode(true);
+			highlightDeleteLine(lineIni-1, applyHighlightedLine);
+			lastLine--;
+		}
+		updateLineNumbers();
+		if ( (currentLine-1)*lineHeight < window.pageYOffset ) 
+		{
+	    	window.scrollTo(0,(currentLine-1)*lineHeight);	
+		}
+	}
+
+	function deleteContents() {
+		var len = lines.childNodes.length;
+		for (var i=len-1; i>0; i--) {
+			lines.childNodes[i].removeNode(true);
+		}
+		setCursorPos(0);
+		highlightReset();
+		updateLineNumbers();
+		lastLine=1;
+		undoBuffer = [];
+		redoBuffer = [];
+	}
+
+
+	function updateLineNumbers() {
+		if (contentDiv.offsetHeight>winH) {
+			document.getElementById('linenumbers').style.height=contentDiv.offsetHeight;
+		}
+		alignLineNumbers(); //fix mozilla align
+	}
+
+
+	function checkDirty() {
+		if (isDirty) {
+			var newContents = inputLineEntry.value;
+			var oldContents = getLineContent(currentLine);
+
+			
+			if(newContents != oldContents) {
+				undoBuffer.push({ type: undo.CHANGE_TEXT, line: currentLine, text: oldContents, newText: newContents,
+					cursor: startCursorPos, newCursor: getCursorPos() });
+				updateLine(currentLine, newContents);
+				isDirty=false;
+				startCursorPos = -1;
+				return true;
+			}
+		} else {
+		}
+		return false;
+	}
+
+	function getLineHead() {
+		var _line = new String(getLineContent(currentLine));
+		var _pos  = getCursorPos();
+		if (_pos == 0) {
+			return '\t';
+		} else {
+			return _line.substr(0, _pos);
+		}
+	}
+
+	function getLineTail() {
+		var _line=new String(getLineContent(currentLine));
+		var _pos=getCursorPos();
+		return _line.substr(_pos);
+	}
+
+	function breakCurrentLine() {
+		checkDirty();
+		var head=getLineHead();
+		var tail=getLineTail();
+		var re = /([\t ]+)/;
+		var match = re.exec(head);
+		var newCursor = 0;
+	
+		if( autoIndent && match ) {
+			tail = match[1] + tail;
+			newCursor = match[1].length;
+		} 
+		insertLineAfter(currentLine, tail);
+		updateLine(currentLine-1, head);
+		setCursorPos(newCursor);
+		inputLineEntry.focus();
+	}
+
+	function glueCurrentLine(direction) {
+		checkDirty();
+		if (direction==-1) { 
+			if (currentLine>1) {
+				var tail=getLineContent(currentLine);
+				var head=getLineContent(currentLine-1);
+				updateLine(currentLine-1, head+tail);
+				deleteLine(currentLine);
+				currentLine--;
+				redrawInputLine();
+				setCursorPos(head.length);
+			}			
+		} else {
+			if (currentLine<lastLine) {
+				var tail=getLineContent(currentLine+1);
+				var head=getLineContent(currentLine);
+				updateLine(currentLine, head+tail);
+				deleteLine(currentLine+1);
+				redrawInputLine();
+			}
+		}
+		updateLineNumbers();
+	}
+
+	function jumpToLine(lineNo) {
+		if(lineNo<=lastLine) {
+			currentLine=lineNo;
+			oldpos=-1;
+			redrawInputLine(true);
+			updateLineNumbers();
+		} else {
+			oldpos=-1;
+			redrawInputLine(true);
+			updateLineNumbers();
+		}
+	}
+
+	function fixmousepaste()
+	{
+		fixPastedReturns(true);
+		checkPastedReturns = false;
+	}
+
+	function do_Copy()
+	{
+	}
+
+	function isNormalKey(charCode)
+	{
+		return ( ( parseInt( charCode ) >= 48 ) && ( parseInt( charCode ) <= 90 ) )  || 
+			   ( ( parseInt( charCode ) >= 96 ) && ( parseInt( charCode ) <= 111 ) ) ||
+			   ( parseInt( charCode ) == 32 ) ||
+			   ( ( parseInt( charCode ) >= 186 ) && ( parseInt( charCode ) <= 222 ) );
+	}
+
+	function inputHasLineEnd()
+	{
+		var re = /\n/;
+		var match;
+		var content;
+		
+		content = inputLineEntry.value;
+		match   = re.exec(content);
+		if( match ) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	function alignLineNumbers()
+	{
+		if (isMoz) {
+			document.getElementById('lines').style.listStyleType='decimal-leading-zero';
+			document.getElementById('lines').style.listStyleType='decimal';
+		}
+	}
+
+	function fixLineGap() {
+		/* synchronize line end with cursor position */
+		
+		var gap;
+		var nlines;
+		var old_cursor_pos = getCursorPos();
+		var newEntry;
+
+		gap    = inputLineEntry.value;
+		gap    = gap.substr(getCursorPos());
+		nlines = gap.split('\n');
+	
+		currInputHeight = currInputHeight - lineHeight*(nlines.length-1);
+		inputLine.style.height      = currInputHeight;
+		inputLineEntry.style.height = currInputHeight;
+		
+		newEntry = inputLineEntry.value;
+		for (i=0; i < nlines.length - 1; i++) {
+			if (isMoz) {
+				newEntry = newEntry.replace(/(.*)\n(.*[\n]?)$/,"$1"); //remove last line
+			} else {
+				newEntry = newEntry.replace(/(.*)\r\n(.*)$/,"$1"); //remove last line
+			}
+		}
+		inputLineEntry.value = newEntry;
+		setCursorPos(selectIni,old_cursor_pos);
+		offsetLine = newEntry.split('\n').length - 1;
+	}
+
+	function do_BeginCode() {
+		jumpToLine(1);
+		inputLineEntry.focus();
+	}
+
+	function do_EndCode() {
+		jumpToLine(lines.childNodes.length);
+		inputLineEntry.focus();
+	}
+
+	function do_Indent() {
+		var old_text = inputLineEntry.value;
+		var old_pos;
+		
+		inputLineEntry.focus();
+
+		if (userSelecting) {
+			for (i = currentLine; i <= (currentLine+offsetLine); i++ ) {
+				old_text = getLineContent(i);
+				old_text = old_text.replace(/^/,"\t"); //add tabs
+				updateLine(i,old_text);
+			}
+			stopSelect();
+			if ( inputHasLineEnd() ) {
+				redrawInputLine();
+			}
+		} else {
+			old_pos  = getCursorPos();
+			old_text = inputLineEntry.value;
+			old_text = old_text.replace(/^/,"\t"); //add tabs
+			inputLineEntry.value = old_text;
+			setCursorPos(old_pos+1);
+		}
+	}
+		
+	function do_Unindent() {
+		var old_text = inputLineEntry.value;
+		var old_pos;
+		
+		inputLineEntry.focus();
+
+		if (userSelecting) {
+			for (i = currentLine; i <= (currentLine+offsetLine); i++ ) {
+				old_text = getLineContent(i);
+				old_text = old_text.replace(/^\t/,""); //del tabs
+				updateLine(i,old_text);
+			}
+			stopSelect();
+			if ( inputHasLineEnd() ) {
+				redrawInputLine();
+			}
+		} else {
+			old_pos  = getCursorPos();
+			old_text = inputLineEntry.value;
+			old_text = old_text.replace(/^\t/,""); //add tabs
+			inputLineEntry.value = old_text;
+			setCursorPos(old_pos-1);
+		}
+
+	}
+
+	function do_Find(text) {
+				
+		var idx;
+		
+		str_search = text;
+		
+		if( userSelecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() )
+				redrawInputLine();
+		}
+
+		str_search.toLowerCase();
+		for (var i=currentLine; i<=lines.childNodes.length; i++) {
+			// need to remove trailing ' ', which IE puts there.
+			_temp = getLineContent(i);
+			_temp.toLowerCase();
+			idx = _temp.indexOf(str_search);
+			if (idx >= 0) {
+				jumpToLine(i);
+				inputLineEntry.focus();
+				setCursorPos(idx,idx+str_search.length);
+				break;
+			}
+		}
+		
+	}
+
+	function do_FindNext(text) {
+		var idx;
+	
+		str_search = text;
+	
+		if( userSelecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() )
+				redrawInputLine();
+		}
+
+		str_search = str_search.toLowerCase();
+		for (var i=currentLine+1; i<=lines.childNodes.length; i++) {
+			// need to remove trailing ' ', which IE puts there.
+			_temp = getLineContent(i);
+			_temp = _temp.toLowerCase();
+			idx = _temp.indexOf(str_search);
+			if (idx >= 0) {
+				jumpToLine(i);
+				inputLineEntry.focus();
+				setCursorPos(idx,idx+str_search.length);
+				break;
+			}
+		}
+	}
+
+
+	function do_Replace() {
+		var idx;
+		var inicio      = false;
+		var ini_line    = currentLine;
+		var str_search;
+		var str_replace;
+		var contents;
+		var reg_exp;
+	
+		if ( str_search == null ) {
+			str_search = 'texto';
+		}
+	
+		if( userSelecting ) {
+			stopSelect();
+			if ( inputHasLineEnd() )
+				redrawInputLine();
+		}
+
+		if ( !( str_search  = prompt('Digite o texto a ser substituido:',str_search) ) ) return;
+		if ( !( str_replace = prompt('Digite o novo texto:','') ) ) return;
+
+		reg_exp = new RegExp(str_search,'ig');
+
+		contents = getContents();
+		setContents(contents.replace(reg_exp, str_replace));
+	}
+
+
+	function resizeHandler()
+	{
+		if (parseInt(navigator.appVersion) > 3) 
+		{
+			if (navigator.appName == "Netscape") 
+			{
+				winW = window.innerWidth-42;
+				winH = window.innerHeight-2;
+				minInputWidth = winW-16;
+			} 
+			else 
+			if (navigator.appName.indexOf("Microsoft")!=-1) 
+			{
+				winW = document.body.offsetWidth;
+				winH = document.body.offsetHeight;
+				minInputWidth      = winW-60;
+				// To handle clipboard paste
+			} 
+		}
+
+		document.getElementById('linenumbers').style.height = winH;
+		updateLineNumbers();
+
+	}
Index: /sandbox/workflow/branches/993/js/phpeditor/highlight.js
===================================================================
--- /sandbox/workflow/branches/993/js/phpeditor/highlight.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/phpeditor/highlight.js	(revision 795)
@@ -0,0 +1,691 @@
+    /******************************************************************
+     highlight.js                                           Muze Helene
+     ------------------------------------------------------------------
+     Author: Muze (info@muze.nl)
+     Date: 28 februari 2004
+
+     Copyright 2002 Muze
+
+     This file is part of Helene.
+
+     Helene is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published 
+     by the Free Software Foundation; either version 2 of the License, 
+     or (at your option) any later version.
+ 
+     Helene is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with Helene; if not, write to the Free Software 
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  
+     02111-1307  USA
+
+    -------------------------------------------------------------------
+
+     This file contains the syntax highlighting parser
+
+    ******************************************************************/
+  // Parsing smarty tags http://smarty.php.net/
+  // Cofigure the smarty delimiters below ('{%' and '%}' by default)
+  // Unset this flag if you need to parse only PHP
+  var parseSmarty = true;
+
+	/* states */
+	var YY_STATE_HTML = 0;
+	var YY_STATE_PINP = 1;
+	var YY_STATE_DQSTRING = 2;
+	var YY_STATE_SQSTRING = 3;
+  var YY_STATE_SCRIPT = 4;
+  var YY_STATE_BLOCKCOMMENT = 5;
+
+  /* Smarty states */
+  var YYS_STATE_TAG = 101;
+  var YYS_STATE_PARAM = 102;
+  var YYS_STATE_QPARAM = 103;
+
+	/* tokens */
+	var T_VAR = 0;
+	var T_IDENT = 1;
+	var T_FUNCTION = 2;
+	var T_TOKEN = 3;
+	var T_UNKNOWN = 4;
+	var T_PINP_START = 5;
+	var T_PINP_BLOCK = 6;
+	var T_PINP_END = 7;
+	var T_SPACE = 8;
+	var T_DQUOTE = 9;
+	var T_SQUOTE = 10;
+	var T_ESCAPE = 11;
+	var T_SPECIAL_CHAR = 12;
+	var T_OPERATOR = 13;
+	var T_SINGLE_COMMENTS = 14;
+	var T_BLOCKCOMMENT = 15;
+	var T_BLOCKCOMMENT_END = 16;
+	var T_PHP_START = 17;
+	var T_PHP_END = 18;
+	var T_SCRIPT_START = 19;
+	var T_SCRIPT_END = 20;
+	var T_TAB = 21;
+	var T_EMPTY_LINE = 22;
+
+  /*Smarty tokens*/
+  var TS_SMARTY_START = 101;
+  var TS_SMARTY_END = 102;
+  var TS_KEYWORD = 103;
+  var TS_ATTRIBUTE = 104;
+  var TS_ATTRVALUE = 105;
+  var TS_VAR = 106;
+	var TS_ENDTAG = 107;
+
+	var hLines = new Array();
+	var debug = 0;
+	var scannerPos = 0;
+  var hStyles = new Array();
+	var hStateStyles = new Array();
+
+  // May be there is the better place for it but now there
+  initStyleDefault();
+	// Making object from keywords, it makes a big perfomance overhead in IE
+	// and slightly better perfomance in Mozilla
+	// You can define any amount of keyword groups
+	// Words should match ([a-z0-9][a-z0-9_]*) and should be separated by spaces
+	var hPHPKeywords = cacheKeywords( /// TODO: Add more keywords here 
+		"for php case default char include int string new endfor real __FILE__ M_LN10 else return switch bool __LINE__ integer long void M_LOG2E break endif endwhile var require extends  while FALSE E_NOTICE M_SQRT1_2 E_WARNING class if float mixed do M_LN2 as continue E_PARSE array function global old_function PHP_VERSION elseif M_1_PI M_2_PI M_EULER M_2_SQRTPI M_PI_2 M_SQRT3 M_PI_4 E_ERROR double endswitch M_LNPI M_SQRT2 M_LOG10E foreach TRUE static M_E object M_PI PHP_OS M_SQRTPI",
+		"echo print count array" // standart functions
+		);	
+	var hSmartyKeywords = cacheKeywords(
+		"if foreach capture section", // Block keywords
+		"include assign math counter else foreachelse sectionelse cycle elseif", // Other keywords
+		"getprices getarticles" // Own plugins for smarty 
+		); 
+
+	function hLineToken(tokenType, tokenData) {
+		this.type = tokenType;
+		this.data = tokenData;
+		this.reallength = tokenData.length;
+    this.newState = -1;
+
+		switch (this.data) {
+			case '<':	
+				this.data='&lt;';
+			break;
+			case '>':
+				this.data='&gt;';
+			break;
+			case '&':
+				this.data='&amp;';
+			break;
+		}
+	
+		switch (this.type) {
+			case T_PINP_START:
+			case T_PHP_START:
+			case T_PINP_END:
+			case T_PHP_END:
+			case T_SCRIPT_START:
+			case T_SINGLE_COMMENTS:
+				this.data = this.data.replace(/[<]/g, '&lt;');
+                this.data = this.data.replace(/[>]/g, '&gt;');
+				var myTabRest = scannerPos % 8;
+                var addLength = 8 - myTabRest;
+				this.data = this.data.replace(/[\t]/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
+                scannerPos += (addLength -1);
+			break;
+			case T_SCRIPT_END:
+				this.data = this.data.replace(/[<]/g, '&lt;');
+				this.data = this.data.replace(/[>]/g, '&gt;');
+			case T_SPACE:
+				this.data = this.data.replace(/[ ]/g, '&nbsp;');
+			break;
+			case T_TAB:
+				var myTabRest = scannerPos % 8;
+				var addLength = 8 - myTabRest;
+				// alert( 'scannerPos ' + scannerPos + ' myTabRest ' + myTabRest + ' addLength ' + addLength);
+				this.data = this.data.replace(/[\t]/g, '<span style="padding-left: '+ (addLength*letterWidth) + 'px;"></span>');
+				scannerPos += (addLength -1);
+			break;
+			case T_EMPTY_LINE:
+				this.data = '<span style="padding-left: 1px;"></span>';
+			break;
+		}
+		scannerPos += tokenData.length;
+	}
+
+	function getToken(sData) {
+		var re, match;
+
+		/* empty line, required for Firefox 1.5.x */
+		if (sData == "")
+		{
+			result = new hLineToken(T_EMPTY_LINE, "");
+			return result;
+		}
+
+		/* white space */
+		re = /^([ ]+)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_SPACE, match[1]);
+			return result;
+		}
+
+		re = /^([\t])/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_TAB, match[1]);
+			return result;
+		}
+
+    /* Smarty tokens */
+    if(parseSmarty) {
+      re = /^\{%/;           // Matches $smarty->left_delimiter
+      match = re.exec(sData);
+      if(match) {
+        return new hLineToken(TS_SMARTY_START, match[0]);
+      }
+
+      re = /^%\}/;           // Matches $smarty->right_delimiter
+      match = re.exec(sData);
+      if(match) {
+        return new hLineToken(TS_SMARTY_END, match[0]);
+      }
+			re = /^\/[a-z0-9][a-z0-9_]*/i;
+			match = re.exec(sData);
+			if (match) {
+				result = new hLineToken(TS_ENDTAG, match[0]);
+				return result;
+			}		
+    }
+    /* end of smarty tokens */
+
+		/* variable or ident */
+		re = /^([$]|->)?([a-z0-9_][a-z0-9_]*)/i;
+		match = re.exec(sData);
+		if (match) {
+			if (match[1]) {
+				result = new hLineToken(T_VAR, match[0]);
+			} else {
+				result = new hLineToken(T_IDENT, match[2]);
+			}
+			return result;
+		}
+
+		/* single tokens */
+		re = /^([(){},"'\\])/;
+		match = re.exec(sData);
+		if (match) {
+			switch (match[1]) {
+				case '\\':
+					result = new hLineToken(T_ESCAPE, match[1]); 
+				break;
+				case '"':
+					result = new hLineToken(T_DQUOTE, match[1]); 
+				break;
+				case "'":
+					result = new hLineToken(T_SQUOTE, match[1]);
+				break;
+				default:
+					result = new hLineToken(T_SPECIAL_CHAR, match[1]);
+				break;
+			}
+			return result;
+		}
+
+		re = /^((\/[*])|([*]\/))/;
+		match = re.exec(sData);
+		if (match) {
+			if (match[2]) {
+				result = new hLineToken(T_BLOCKCOMMENT, match[2]);
+			} else {
+				result = new hLineToken(T_BLOCKCOMMENT_END, match[3]);
+			}
+			return result;
+		}
+
+		/* comments */
+		re = /^(\/\/.*)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_SINGLE_COMMENTS, match[1]);
+			return result;
+		}
+
+		/* php end tags */
+		re = /^([\?\%]>)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_PHP_END, match[0]);
+			return result;
+		}
+
+		re = /^([\-\+\.\*\/\=\%])/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_OPERATOR, match[1]);
+			return result;
+		}
+
+
+		/* pinp/php tags */
+              re = /^((<(\/)?pinp>)|(<[%?]php|<\?|<script[^>]+language[^>]*=[^>]*php[^>]*>))/i;
+		match = re.exec(sData);
+		if (match) {
+			if (match[3]) {
+				result = new hLineToken(T_PINP_END, match[0]);
+			} else
+			if (match[2]) {
+				result = new hLineToken(T_PINP_START, match[0]);
+			} else {
+				result = new hLineToken(T_PINP_START, match[0]);
+			}
+			return result;
+		}
+
+		/* javascript */
+		re = /^<(\/)?script[^>]*>/;
+		match = re.exec(sData);
+		if (match) {
+			if (match[1]) {
+				result = new hLineToken(T_SCRIPT_END, match[0]);
+			} else {
+				result = new hLineToken(T_SCRIPT_START, match[0]);
+			}
+			return result;
+		}
+				
+		return new hLineToken(T_UNKNOWN, sData.charAt(0));
+	}
+
+	function hLineParseString(sData) {
+		var token;
+		this.tokens = new Array();
+
+		scannerPos = 0;
+		do
+		{
+			token = getToken(sData);
+			this.tokens[this.tokens.length] = token;	
+			sData=sData.substring(token.reallength);
+		} while (sData != '');
+	}
+
+      function getElmSpan(token) { /// In the past styles were here
+		var result = '';							// UPDATE: it is better to produce whole span tag here
+    var cls = hStyles[token.type];
+    if(cls!='') result = '<span class="'+cls+'">';
+		else result = '<span>';
+		return result;
+	}
+      function getStateSpan(token) { /// Style span for states
+		var result = '';								// UPDATE: it is better to produce whole span tag here
+    var cls = hStateStyles[token.newState];
+    if(cls!='') result = '<span class="'+cls+'">';
+		else result = '<span>';
+		return result;
+	}
+
+	function hLineDoHighlight(callback) {
+		var state = new Array();
+		var result = '';
+		if (this.lineNo) {
+			/* load parent state */
+			state = state.concat(hLines[this.lineNo-1].getEndState());
+//			alert((this.lineNo-1)+':'+state.length);
+		}
+		for (var i = 0; i<state.length; i++) {
+			if (!state[i].noMultiLine) {
+				result += getStateSpan(state[i]);
+			}
+		}
+		if (this.tokens) {
+			for (var i=0; i<this.tokens.length; i++) {
+				var cState = 0;
+				var token = this.tokens[i];
+				if (state.length) {
+                                      cState = state[state.length-1].newState; 
+          status = cState;
+				}
+
+                              switch (cState) {         // In the past state was the type of opening token
+                                      case YY_STATE_HTML:     // It is a real state now
+						switch (token.type) {
+              //Smarty highlighting
+              case TS_SMARTY_START:
+                token.newState = YYS_STATE_TAG;
+                result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+                state.push(token);
+              break;
+              //End of smarty highlighting
+							case T_PHP_START:
+							case T_PINP_START:
+								token.newState = YY_STATE_PINP; // We fix the new state here
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token); // But we still saving opening token
+							break;
+							case T_SCRIPT_START:
+                token.newState = YY_STATE_SCRIPT;
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token);
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_SCRIPT:
+						switch (token.type) {
+							case T_PHP_START:
+							case T_PINP_START:
+                token.newState = YY_STATE_PINP;
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token);
+							break;
+							case T_SCRIPT_END:
+								result += getElmSpan(token)+token.data+'</span>';
+								result += '</span>';
+								state.pop();
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_PINP:
+						switch (token.type) {
+							case T_IDENT:
+								var t = hPHPKeywords[token.data];
+								if(typeof(t)!='undefined') {
+									result += '<span class="h_phpkeywords'+t+'">';
+								} else {
+									result += getElmSpan(token);
+								}
+								result += token.data + '</span>';
+							break;
+							case T_DQUOTE:
+                token.newState = YY_STATE_DQSTRING;
+							case T_SQUOTE:
+                if(token.newState<0) token.newState = YY_STATE_SQSTRING;
+							case T_BLOCKCOMMENT:
+                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
+								result += getStateSpan(token);
+								result += token.data;
+								state.push(token);
+							break;
+							case T_PHP_END:
+							case T_PINP_END:
+								result += getElmSpan(token)+token.data+'</span>';
+								result += '</span>';
+								state.pop();
+							break;
+							case T_VAR:
+							case T_OPERATOR:
+							case T_SPECIAL_CHAR:
+							case T_SINGLE_COMMENTS:
+								result += getElmSpan(token);
+								result += token.data;
+								result += '</span>';
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_BLOCKCOMMENT:
+						switch (token.type) {
+							case T_BLOCKCOMMENT_END:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_DQSTRING:
+						switch (token.type) {
+                                                      case T_DQUOTE:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							case T_ESCAPE:
+								result += token.data;
+								token = this.tokens[++i];
+								result += token.data;
+							break;
+							case T_VAR:
+								result += getElmSpan(token);
+								result += token.data;
+								result += '</span>';
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_SQSTRING:
+						switch (token.type) {
+                                                      case T_SQUOTE:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							case T_ESCAPE:
+								result += token.data;
+								token = this.tokens[++i];
+								result += token.data;
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YYS_STATE_TAG:
+            switch (token.type) {
+              case TS_SMARTY_END:
+                result += getElmSpan(token) + token.data + '</span></span>';
+                state.pop();
+              break;
+							case TS_ENDTAG:
+								var t = hSmartyKeywords[token.data.substr(1)];
+								if(t==1) {	// Only the first group has closing tags
+									result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
+								} else {
+									result += token.data;
+								}
+							break;
+							case T_VAR:
+                result += getElmSpan(token) + token.data + '</span>';
+								return;								
+							case T_IDENT:
+								var t = hSmartyKeywords[token.data];
+								if(typeof(t)!='undefined' && 
+									(t>3 || 																						// first three groups of keywords may appear
+										(i>0 && this.tokens[i-1].type==TS_SMARTY_START))	// immediately after TS_SMARTY_START token only
+										) {
+									result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
+								} else {
+									result += token.data;
+								}
+							break;
+              default:
+							result += token.data;
+              break;
+            }
+          break;
+					default:
+						result += token.data;
+					break;
+				}
+			}
+//			alert(this.lineNo+'::'+this.tokens.length+'::'+result);
+
+		}
+		var stateChanged = 0;
+		if (state.length != this.getEndState().length) {
+			stateChanged = 1;
+		}
+
+		for (i=state.length-1; i>=0; i--) {
+			if (!stateChanged && state[i].type!=this.getEndState()[i].type) {
+				stateChanged = 1;
+			}
+			if (!state[i].noMultiLine) {
+				result += getElmSpan(state[i]);
+			}
+		}
+
+		/* report update */
+		if (callback) {
+//			alert(this.lineNo+"::"+result);
+			if (result) {
+//				alert(this.lineNo+': 2 eol chars: "'+result.substr(result.length-2)+'"');
+			}
+			callback(this.lineNo, result);
+		}
+		this.setEndState(state);
+              if (stateChanged) {
+			if (debug) alert('updating: '+this.lineNo+1); 
+      /// This makes a stack overflow
+      /// so we are returning 'true' that means next line must be updated
+      //~ hLines[this.lineNo+1].doHighlight(callback);
+                      return true;
+		}
+    /// Next line need not be updated
+    return false;
+	}
+
+	function hLineSetEndState(newEndState) {
+//		alert(this.lineNo+': new endstate: '+newEndState.length);
+		var frop=new Array();
+		if (newEndState.length) {
+//			alert(':'+newEndState.toString()+':');
+			this.endState=frop.concat(newEndState); //newEndState; //.toSource();
+		} else {
+			this.endState=new Array();
+		}
+/*
+		var line = hLines[2];
+		if (line) {
+			alert(this.lineNo+'->'+line.endState.length);
+		}
+*/
+	}
+
+	function hLineGetEndState() {
+		return this.endState;
+	}
+
+	function hLineRemove() {
+		if (this.lineNo < (hLines.length-1)) {
+			var len = hLines.length-1;
+			for (var i=this.lineNo; i<len; i++) {
+				hLines[i] = hLines[i+1];
+				hLines[i].lineNo = i;
+			}
+		}
+		hLines.pop();
+	}
+
+	function hLine(lineNo, lineString) {
+		this.lineNo = lineNo;
+		if (lineNo && (lineNo != hLines.length)) {
+			var hLinesLen = hLines.length;
+			for (var i=hLinesLen; i>lineNo; i--) {
+				hLines[i] = hLines[i-1];
+				hLines[i].lineNo = i;
+			}
+		}
+		hLines[lineNo] = this;
+		this.tokens = new Array();
+		this.setEndState = hLineSetEndState;
+		this.setEndState(new Array());
+		this.getEndState = hLineGetEndState;
+		this.remove = hLineRemove;
+
+		this.parseString = hLineParseString;
+		this.parseString(lineString);
+		
+		if (debug) alert(this.lineNo);
+		this.doHighlight = hLineDoHighlight;
+	}
+
+	function highlightUpdateLine(lineNo, lineContent, callback) {
+//		alert('update line: '+lineNo+'::'+lineContent);
+		hLines[lineNo].parseString(lineContent);
+              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightDeleteLine(lineNo, callback) {
+//		alert('remove line: '+lineNo);
+		line = hLines[lineNo];
+		line.remove();
+              if (hLines.length && (lineNo < hLines.length))
+      while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightReset() {
+		hLines = new Array();
+		new hLine(0, '');
+	}
+
+	function highlightInsertLine(lineNo, lineContent, callback) {
+		if (lineNo) {
+			lineNo -= 1;
+		}
+//		alert('insert at: '+lineNo+'::'+lineContent);
+		line = new hLine(lineNo, lineContent);
+              while(line.doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightAppendLine(lineNo, lineContent, callback) {
+//		alert('append at: '+(lineNo+1)+'::'+lineContent);
+		line = new hLine(lineNo+1, new String(lineContent));
+              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+  function initStyleDefault() {
+    hStyles[T_PINP_START] =
+    hStyles[T_PINP_END] =
+    hStyles[T_PHP_START] = 'h_pinp';
+    hStyles[T_VAR] = 'h_var';
+    hStyles[T_PHP_START] = 'h_script';
+    hStyles[T_IDENT] = 'h_ident';
+    hStyles[T_DQUOTE] = 'h_doublequote';
+    hStyles[T_SQUOTE] = 'h_singlequote';
+    hStyles[T_SPECIAL_CHAR] = 'h_special_char';
+    hStyles[T_OPERATOR] = 'h_operator';
+    hStyles[T_SINGLE_COMMENTS] = 'h_single_comments';
+    hStyles[T_BLOCKCOMMENT] = 'h_blockcomment';
+    hStyles[TS_SMARTY_START] = 'h_smartymarkers';
+    hStyles[TS_SMARTY_END] = 'h_smartymarkers';
+		hStateStyles[YY_STATE_HTML] = '';
+		hStateStyles[YY_STATE_PINP] = 'h_pinp_block';
+		hStateStyles[YY_STATE_DQSTRING] = 'h_doublequote';
+		hStateStyles[YY_STATE_SQSTRING] = 'h_singlequote';
+		hStateStyles[YY_STATE_BLOCKCOMMENT] = 'h_blockcomment';
+		hStateStyles[YY_STATE_SCRIPT] = 'h_scriptblock';
+		hStateStyles[YYS_STATE_TAG] = 'h_smartytag';
+  }
+	function cacheKeywords() {
+		var res = new Object();
+		for(var i=0;i<arguments.length;i++) {
+			var t = String(arguments[i]).split(" ");
+			for(var j=0;j<t.length;j++)
+				res[t[j]]=i+1;
+		}
+		return res;
+	}
Index: /sandbox/workflow/branches/993/js/userinterface/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/main.js	(revision 795)
@@ -0,0 +1,57 @@
+function initUserInterface(startTab)
+{
+	if (!(is_gecko || is_ie6up))
+	{
+		alert('OPSS !! Desculpe, mas seu navegador não suporta o Workflow.\nInstale o Mozilla FireFox 1.0+ ou Internet Explorer 6.0+.');
+		return;
+	}
+
+	initBorders(5);
+	document.getElementById('main_body').style.display = '';
+
+	if (startTab == null)
+		startTab = 1;
+
+	/* converte de string para inteiro (necessário para o switch da função 'changeTab' funcione corretamente) */
+	if (typeof(startTab) == 'string')
+		startTab = parseInt(startTab);
+
+	changeTab(startTab);
+}
+
+function changeTab(newTab)
+{
+	if (alternate_border(newTab) != 0)
+		return;
+
+	switch (newTab)
+	{
+		case 0:
+			draw_inbox_folder(0);
+			break;
+
+		case 1:
+			draw_processes_folder();
+			break;
+
+		case 2:
+			draw_instances_folder();
+			break;
+
+		case 3:
+			draw_externals_folder();
+			break;
+
+		case 4:
+			createOrgchartLayout();
+			break;
+
+		default:
+			draw_processes_folder();
+			break;
+	}
+}
+
+Event.observe(window, 'load', function() {
+	initUserInterface($F('workflowUserInterfaceStartTab'));
+});
Index: /sandbox/workflow/branches/993/js/userinterface/externals.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/externals.js	(revision 1455)
+++ /sandbox/workflow/branches/993/js/userinterface/externals.js	(revision 1455)
@@ -0,0 +1,98 @@
+var externals = function(data)
+{
+	if (_checkError(data))
+		return;
+
+	var content_id_3 = document.getElementById("content_id_3");
+	if (data.length == 0)
+	{
+		var parag = document.createElement("P");
+		parag.className = "text_dsp";
+		parag.innerHTML = "Não existem aplicações externas";
+		content_id_3.appendChild(parag);
+	}
+	else
+	{
+		elem = document.getElementById("table_ext");
+		if (elem) {
+			elem.parentNode.removeChild(elem);
+		}
+
+		draw_externals_grid(data, 3);
+	}
+};
+
+function draw_externals_folder()
+{
+	cExecute ("$this.bo_userinterface.externals", externals, "");
+}
+
+function draw_externals_grid(data, page)
+{
+
+	var content_id_3 = document.getElementById("content_id_3");
+
+	// altura mínima do conteiner
+	if(is_ie){
+		content_id_3.style.height = "260px";
+	} else {
+		content_id_3.style.minHeight = "260px";
+	}
+
+	(function loop(i) {
+
+		if(i < data.length){
+
+			var external_link = data[i].wf_ext_link;
+			var ext = data[i];
+			var ext_name_dsp = ext.name;
+
+			if (ext_name_dsp.length > 40) {
+			    ext_name_dsp = ext_name_dsp.substr(0,40) + "...";
+			}
+
+			var div_element = document.createElement("DIV");
+
+			div_element.style.width = '106px';
+			if(is_ie) {
+				div_element.style.styleFloat = "left";
+				div_element.style.height = '150px';
+			} else {
+				div_element.style.cssFloat = "left";
+				div_element.style.height = '100px'
+			}
+
+			div_element.style.padding    = '7px';
+			div_element.style.paddingTop = "25px";
+
+			div_element.style.cursor = 'pointer';
+			div_element.onclick = function() { var external_window = window.open(external_link,'extwindow'); external_window.opener = null;};
+
+
+			var div_ext_img = document.createElement("DIV");
+			div_ext_img.style.width = "100%";
+			div_ext_img.style.textAlign = 'center';
+			div_ext_img.innerHTML = "<img src ='" + ext.image + "' width='32' height='32'>";
+
+			var div_ext_txt = document.createElement("DIV");
+			div_ext_txt.style.width = "100%";
+			div_ext_txt.style.textAlign = 'center';
+			div_ext_txt.style.paddingTop = '5px';
+			div_ext_txt.innerHTML = '<span style="font-size: 11px !important;">'+ext_name_dsp+'</span>';
+
+			div_element.appendChild(div_ext_img);
+			div_element.appendChild(div_ext_txt);
+
+			content_id_3.appendChild(div_element);
+
+			loop(i+1);
+		}
+	})(0)
+
+	var div_bottom = document.createElement("DIV");
+	div_bottom.style.width = "100%";
+	div_bottom.style.clear = 'both';
+
+	content_id_3.appendChild(div_bottom);
+
+}
Index: /sandbox/workflow/branches/993/js/userinterface/orgchartPrint.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/orgchartPrint.js	(revision 2108)
+++ /sandbox/workflow/branches/993/js/userinterface/orgchartPrint.js	(revision 2108)
@@ -0,0 +1,217 @@
+/**
+* Show / Hide all employees
+*/
+function toggleEmployeesVisibility()
+{
+	if ($('#employeesVisibility').attr('checked'))
+		$('tr.employees').show();
+	else
+		$('tr.employees').hide();
+}
+
+/**
+* Highlight supervisor names?
+*/
+function toggleHighlightSupervisor()
+{
+	if ($('#highlightSupervisor').attr('checked'))
+		$('span.employeesupervisor').css('font-weight', 'bold');
+	else
+		$('span.employeesupervisor').css('font-weight', 'normal');
+}
+
+/**
+* Show / Hide orgchart area path visibility
+*/
+function toggleOrgchartPathVisibility()
+{
+	if ($('#orgchartPathVisibility').attr('checked'))
+		$('span.orgchartPath').css('visibility', 'visible').show();
+	else {
+		if ($('#orgchartPathIndentation').attr('checked'))
+			$('span.orgchartPath').show().css('visibility', 'hidden');
+		else
+			$('span.orgchartPath').hide();
+	}
+}
+
+/**
+* Group by area or show a single list alphabetically ordered
+* For large sets of data this function may be potencially slow
+*/
+function toggleGroupByArea()
+{
+	/* remove the table and compute it again */
+	$('#employee_table').remove();
+
+	if ($('#groupByArea').attr('checked'))
+		showGroupedByArea();
+	else
+		showUngrouped();
+
+	/* updating supervisor highlight and orgchart path visibility */
+	toggleHighlightSupervisor();
+	toggleOrgchartPathVisibility();
+}
+
+/**
+* Centralize the creation of table rows for employees.
+* 'showAreaColumn' specifies whether the second column will be shown
+*/
+function createEmployeeRow(area_id, user_id, showAreaColumn)
+{
+	/* set a special 'class' if the employee is a supervisor one */
+	class_name = 'employee';
+	if (areas[area_id].titular_funcionario_id == areas[area_id].employees[user_id].funcionario_id)
+		class_name += 'supervisor';
+
+	/* creating the row. */
+	element = $('<tr></tr>')
+				/* name: first column */
+				.append(
+						$('<td></td>')
+							.append(
+								$('<span></span>')
+									.addClass(class_name)
+									.append(areas[area_id].employees[user_id].cn)
+							)
+							.css('width', '70%')
+						);
+
+	/* area: second (optional) column */
+	if (showAreaColumn)
+		element.append(
+						$('<td>' + areas[area_id].sigla + '</td>')
+							.css('width', '15%')
+					);
+
+	/* telephone: last column */
+	element.append(
+					$('<td>' + areas[area_id].employees[user_id].telephoneNumber + '</td>')
+						.css('width', '20%')
+					)
+				.addClass('employees');
+
+	return element;
+}
+
+/**
+* Creating a employee table grouped by area
+*/
+function showGroupedByArea()
+{
+	var table = $('<table></table>').css('width', '90%').attr('id', 'employee_table');
+	var i, j;
+
+	/* iterating over areas */
+	for (i=0; i < areas.length; i++) {
+
+		/* inserting area header */
+		table.append(
+				$('<tr></tr>')
+				.append(
+					$('<th></th>')
+						.css('text-align', 'left')
+						.css('height', '30')
+						.append(
+							$('<span></span>')
+								.addClass('orgchartPath')
+								.append(areas[i].orgchartPath)
+								)
+						.append(areas[i].sigla)
+					)
+		);
+
+		/* creating employee rows */
+		for (j=0; j < areas[i].employees.length; j++)
+			table.append(createEmployeeRow(i, j));
+	}
+	$('#areas_content').append(table);
+}
+
+/**
+* Creating employess ordered alphabetically and ungrouped. In this
+* function we implemented a 'merge' of all area's employee arrays.
+*
+* Be careful if you are going to update this code... =)
+*/
+function showUngrouped()
+{
+	var table = $('<table></table>').css('width', '90%').attr('id', 'employee_table');
+	var i, less, end;
+
+	/* creating and reseting indexes */
+	for (i=0; i < areas.length; i++)
+		areas[i].index = 0;
+
+	/* */
+	while (true) {
+		less = -1;
+		end = true;
+
+		/* searching the area with smallest employee name */
+		for (i=0; i < areas.length; i++) {
+
+			/* if this area have employees left */
+			if (areas[i].employees.length > areas[i].index) {
+
+				/* if it's the first area reached in this iteration */
+				if (less == -1)
+					less = i;
+
+				/* updating less */
+				if (areas[i].employees[areas[i].index].cn < areas[less].employees[areas[less].index].cn)
+					less = i;
+
+				/* so, we are not done */
+				end = false;
+			}
+		}
+		/* if we are done */
+		if (end) break;
+
+		/* inserting the row */
+		table.append(createEmployeeRow(less, areas[less].index, true));
+		areas[less].index++;
+	}
+	$('#areas_content').append(table);
+}
+
+/**
+* Print me!
+*/
+function printAction()
+{
+	window.print();
+}
+
+/**
+* Binding events to HTML elements
+*/
+function bindEvents()
+{
+	$('#employeesVisibility').click(toggleEmployeesVisibility);
+	$('#groupByArea').click(toggleGroupByArea);
+	$('#highlightSupervisor').click(toggleHighlightSupervisor);
+	$('#orgchartPathVisibility').click(toggleOrgchartPathVisibility);
+	$('#printButton').click(printAction);
+}
+
+function initialSetup()
+{
+	toggleGroupByArea();
+	toggleEmployeesVisibility();
+	toggleHighlightSupervisor();
+	toggleOrgchartPathVisibility();
+}
+
+/**
+* Call setup functions on body onload.
+*/
+function pageLoad()
+{
+	bindEvents();
+	initialSetup();
+}
+
+$(window).load(pageLoad);
Index: /sandbox/workflow/branches/993/js/userinterface/processes.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/processes.js	(revision 1455)
+++ /sandbox/workflow/branches/993/js/userinterface/processes.js	(revision 1455)
@@ -0,0 +1,360 @@
+/* configuração do menu */
+var MENU_POS = [
+{
+	// tamanho dos itens
+	'height': 19,
+	'width': 255,
+	'auto-width': true,
+	// offset do menu a partir da origem:
+	//  para o nível principal, a origem é o canto superior esquerdo
+	//  para outros níveis, a origem é o canto superior esquerdo do menu pai
+	'block_top': 186,
+	'block_left': 151,
+	// offsets de itens no mesmo nível
+	'top': 19,
+	'left': 0,
+	// tempo, em milisegundos, em que o menu permanece visível após o cursor "sair" do menu
+	'hide_delay': 300,
+	'css' : {
+		'outer' : ['menuExternoOut', 'menuExternoOver'],
+		'inner' : ['menuInternoOut', 'menuInternoOver']
+	}
+},
+{
+	'width': 140,
+	'block_top': 10,
+	'block_left': 30,
+	'css' : {
+		'outer' : ['submenuExternoOut', 'submenuExternoOver'],
+		'inner' : ['submenuInternoOut', 'submenuInternoOver']
+	}
+}
+];
+
+var menuTimer = null;
+var workflowProcessCache = false;
+
+function checkProcessCache()
+{
+	if (workflowProcessCache == false)
+		return;
+	resultProcesses(workflowProcessCache);
+	workflowProcessCache = false;
+}
+
+function resultProcesses(data)
+{
+	if (_checkError(data))
+		return;
+
+	var content_id_1 = $("content_id_1");
+	if (content_id_1.style.display == 'none')
+	{
+		workflowProcessCache = data;
+		content_id_1.innerHTML = '<span></span>';
+		return;
+	}
+
+	if (data.length == 0)
+	{
+		var parag = document.createElement("P");
+		parag.className = "text_dsp";
+		parag.innerHTML = "Não existem processos disponíveis";
+		content_id_1.appendChild(parag);
+	}
+	else
+	{
+		elem = document.getElementById("table_tools");
+		if (elem)
+			elem.parentNode.removeChild(elem);
+		elem = document.getElementById("table_proc");
+		if (elem)
+			elem.parentNode.removeChild(elem);
+		draw_processes_grid(data, 1);
+	}
+}
+function draw_processes_folder()
+{
+	cExecute("$this.bo_userinterface.processes", resultProcesses);
+}
+
+function draw_processes_grid(data, page)
+{
+	var content_id_1 = document.getElementById("content_id_1");
+
+	if(is_ie){
+		content_id_1.style.height = "260px";
+	} else {
+		content_id_1.style.minHeight = "260px";
+	}
+
+	var div_conteiner = document.createElement("DIV");
+
+	div_conteiner.style.paddingRight = '100px';
+	content_id_1.appendChild(div_conteiner);
+
+	(function loop(i) {
+
+		if(i < data.length){
+
+			var proc = data[i];
+			var proc_name_dsp = proc.wf_procname;
+
+			if (proc_name_dsp.length > 40) {
+			    proc_name_dsp = proc_name_dsp.substr(0,40) + "...";
+			}
+
+			var div_element = document.createElement("DIV");
+
+			div_element.style.width = '106px';
+
+			if(is_ie) {
+				div_element.style.styleFloat = "left";
+				div_element.style.height = '150px';
+			} else {
+				div_element.style.cssFloat = "left";
+				div_element.style.height = '100px'
+			}
+
+			div_element.style.padding = '7px';
+			div_element.style.paddingTop = "25px";
+			div_element.style.cursor = 'pointer';
+
+			var index = i;
+
+			div_element.onclick = function() { displayProcessMenu(index); };
+			div_element.onmouseover = function() { menuTimer = setTimeout("displayProcessMenu('" + index + "')",400);};
+			div_element.onmouseout = function() { if (menuTimer) clearTimeout(menuTimer); };
+
+			var div_proc_img = document.createElement("DIV");
+			div_proc_img.style.width = "100%";
+			div_proc_img.style.textAlign = 'center';
+			div_proc_img.innerHTML = '<img src="' + proc.wf_iconfile + '" id="processImage_' + i + '" width="32" height="32">';
+
+			var div_proc_txt = document.createElement("DIV");
+			div_proc_txt.style.width = "100%";
+			div_proc_txt.style.textAlign = 'center';
+			div_proc_txt.style.paddingTop = '5px';
+			div_proc_txt.innerHTML = '<span style="font-size: 11px !important;">'+proc_name_dsp+'</span>';
+			div_proc_txt.innerHTML += '<br><span class="version_dsp"> (v' + proc.wf_version + ')</span></p>';
+			div_element.appendChild(div_proc_img);
+			div_element.appendChild(div_proc_txt);
+
+			div_conteiner.appendChild(div_element);
+
+			createProcessMenu(i, data[i]);
+
+			loop(i+1);
+		}
+	})(0)
+
+	var div_bottom = document.createElement("DIV");
+	div_bottom.style.width = "100%";
+	div_bottom.style.clear = 'both';
+
+	div_conteiner.appendChild(div_bottom);
+}
+
+function createProcessMenu(index, data)
+{
+	/* based on the wf_menu_path activity property, generates a javascript object */
+	var preFormatedMenu = new Array();
+	var currentLevel;
+	var urlPreffix = getInstanceURL(0, 0, data['useHTTPS']);
+	urlPreffix = urlPreffix.substr(0, urlPreffix.lastIndexOf('/'));
+
+	for (var i = 0; i < data.length; i++)
+	{
+		var currentMenu = new Array();
+		currentMenu['name'] = data[i].wf_name;
+		currentMenu['url'] = urlPreffix + '/index.php?menuaction=workflow.run_activity.go&activity_id=' + data[i].wf_activity_id;
+		if ((data[i].wf_menu_path != '') && (data[i].wf_menu_path != null))
+		{
+			var levels = data[i].wf_menu_path.split('/');
+			currentLevel = preFormatedMenu;
+			for (var j = 0; j < levels.length; j++)
+			{
+				var currentTitle = levels[j];
+				if (currentLevel[currentTitle])
+				{
+					currentLevel = currentLevel[currentTitle];
+					continue;
+				}
+				else
+				{
+					currentLevel[currentTitle] = new Array();
+					currentLevel = currentLevel[currentTitle];
+				}
+			}
+			currentLevel[currentLevel.length] = currentMenu;
+		}
+		else
+			preFormatedMenu[preFormatedMenu.length] = currentMenu;
+	}
+
+	/* generate standard actions menu */
+	var graphMenu = new Array();
+	graphMenu['name'] = 'Gráfico do Processo';
+	graphMenu['url'] = "javascript:draw_process_graph(" + data['wf_p_id'] + ",\\'" + data['wf_procname'] + "\\');";
+	preFormatedMenu[preFormatedMenu.length] = graphMenu;
+	var aboutMenu = new Array();
+	aboutMenu['name'] = 'Sobre o Processo';
+	aboutMenu['url'] = "javascript:draw_folder_about(" + data['wf_p_id'] + ");";
+	preFormatedMenu[preFormatedMenu.length] = aboutMenu;
+
+	/* recursivamente, constrói o texto que representa o objeto reconhecido pela engine do Tigra menu */
+	function generateMenuText(root)
+	{
+		var output = '';
+		for (i in root)
+		{
+			if (typeof root[i] != "function")
+			{
+				if (node)
+					output += ",\n";
+				output += '[';
+				var node = root[i];
+				if (node['url'])
+					output += "'" + node['name'] + "', '" + node['url'] + "', null";
+				else
+					output += "'" + i + '...'  + "', null, null,\n" + generateMenuText(node);
+				output += ']';
+			}
+		}
+		return output;
+	}
+
+	/* generate the menu in a way that the Tigra menu engine will understand */
+	var menuItens = eval('[' + generateMenuText(preFormatedMenu) + '];');
+
+	var menuDiv = document.createElement("DIV");
+	menuDiv.setAttribute("id", "menuDiv_" + index);
+	menuDiv.style.display = 'none';
+	$("content_id_1").appendChild(menuDiv);
+
+	/* define the menu position */
+	var processImage = $("processImage_" + index);
+	MENU_POS[0]['block_left'] = Position.cumulativeOffset(processImage)[0] + processImage.getWidth();
+	MENU_POS[0]['block_top'] = Position.cumulativeOffset(processImage)[1];
+
+	/* create the menu */
+	new menu (menuItens, MENU_POS, menuDiv);
+}
+
+function displayProcessMenu(id)
+{
+	for (var i = 0; i < A_MENUS.length; i++)
+		if (i == id){
+
+			var processImage = $("processImage_" + id);
+			var posX = Position.cumulativeOffset(processImage)[0] + processImage.getWidth();
+			var posY = Position.cumulativeOffset(processImage)[1];
+
+			var firstItem = $("menuDiv_" + id).firstChild;
+
+			var deltaX = (posX - parseFloat(firstItem.style.left));
+			var deltaY = (posY - parseFloat(firstItem.style.top));
+
+			if(deltaX != 0){
+
+				var items = $("menuDiv_" + id).childNodes;
+
+				for(j = 0; j < items.length; j++){
+					if(items[j].style != null) {
+						items[j].style.left = parseFloat(items[j].style.left) + deltaX + 'px';
+						items[j].style.top  = parseFloat(items[j].style.top)  + deltaY + 'px';
+					}
+				}
+			}
+
+			$("menuDiv_" + i).show();
+
+		} else
+			$("menuDiv_" + i).hide();
+}
+
+function draw_process_graph(pid, proc_name)
+{
+	border_id = create_border("Gráfico - " + proc_name);
+	var div = $("content_id_" + border_id);
+	div.style.height = '420px';
+	var imgPreLoad = new Image();
+	imgPreLoad.src = "../index.php?menuaction=workflow.ui_adminactivities.show_graph&p_id=" + pid;
+	function displayPanorama()
+	{
+		var viewer = new experience.panorama.Viewer({
+				ImageURL: imgPreLoad.src,
+				ImageWidth: imgPreLoad.width,
+				ImageHeight: imgPreLoad.height,
+				IconDirectory: 'js/experience/icons',
+				RenderIn: "content_id_" + border_id
+			});
+		viewer.show();
+	}
+	imgPreLoad.onload = displayPanorama;
+}
+
+function draw_folder_about(pid) {
+
+	var proc_about_handler = function(data) {
+		border_id = create_border("Sobre - " + data['wf_procname']);
+		content = document.getElementById("content_id_" + border_id);
+
+		var table_proc = document.createElement("TABLE");
+		var tbody_proc = document.createElement("TBODY");
+		table_proc.className = "info_table";
+		table_proc.width = "90%";
+		table_proc.align = "center";
+		tr_element = document.createElement("TR");
+		tr_element.className = "info_tr_header";
+		td_element = document.createElement("TD");
+		td_element.innerHTML = "Processo " + data['wf_procname'] + " (v" + data['wf_version'] + ")";
+		tr_element.appendChild(td_element);
+		tbody_proc.appendChild(tr_element);
+		tr_element = document.createElement("TR");
+		tr_element.className = "info_tr_simple";
+		td_element = document.createElement("TD");
+		td_element.innerHTML = data['wf_description'];
+		tr_element.appendChild(td_element);
+		tbody_proc.appendChild(tr_element);
+		table_proc.appendChild(tbody_proc);
+
+		content.innerHTML = "&nbsp;";
+		content.appendChild(table_proc);
+		content.appendChild(document.createElement("BR"));
+
+		var table_activ = document.createElement("TABLE");
+		var tbody_activ = document.createElement("TBODY");
+		table_activ.className = "info_table";
+		table_activ.width = "90%";
+		table_activ.align = "center";
+		tr_element = document.createElement("TR");
+		tr_element.className = "info_tr_header";
+		td_element = document.createElement("TD");
+		td_element.colSpan = "2";
+		td_element.innerHTML = "Atividades do Processo";
+		tr_element.appendChild(td_element);
+		tbody_activ.appendChild(tr_element);
+
+		for (ix = 0; ix < data['wf_activities'].length; ix++) {
+			tr_element = document.createElement("TR");
+			tr_element.className = "info_tr_simple";
+			td_element1 = document.createElement("TD");
+			td_element1.className = "info_td_activ";
+			td_element1.width = "35%";
+			td_element1.innerHTML = activity_icon(data['wf_activities'][ix]['wf_type'], data['wf_activities'][ix]['wf_is_interactive']) + " " + data['wf_activities'][ix]['wf_name'];
+			td_element2 = document.createElement("TD");
+			td_element2.width = "65%";
+			td_element2.innerHTML = data['wf_activities'][ix]['wf_description'];
+			tr_element.appendChild(td_element1);
+			tr_element.appendChild(td_element2);
+			tbody_activ.appendChild(tr_element);
+		}
+
+		table_activ.appendChild(tbody_activ);
+		content.appendChild(table_activ);
+		content.appendChild(document.createElement("BR"));
+	};
+	params = "pid=" + pid;
+	cExecute ("$this.bo_userinterface.process_about", proc_about_handler, params);
+}
Index: /sandbox/workflow/branches/993/js/userinterface/instances.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/instances.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/instances.js	(revision 795)
@@ -0,0 +1,339 @@
+/* armazena os parâmetro passados para a construção da interface */
+var workflowInstancesParams;
+
+/* armazena os nomes dos usuários que possuem as instâncias */
+var workflowInstancesUserNames;
+
+/* armazena informações dos processos */
+var workflowInstancesProcessesInfo;
+
+/* armazena os nomes das atividades */
+var workflowInstancesActivityNames;
+
+/* armazena a lista de processos cujas instâncias o usuário pode acessar */
+var workflowInstancesProcesses;
+
+/* array que relaciona um status a uma imagem */
+var workflowInstancesStatusImages = Array();
+workflowInstancesStatusImages['active'] = 'i_active.png';
+workflowInstancesStatusImages['exception'] = 'i_waiting.png';
+workflowInstancesStatusImages['completed'] = 'i_completed.png';
+workflowInstancesStatusImages['aborted'] = 'i_aborted.png';
+
+/* array que relaciona um status a um texto */
+var workflowInstancesStatusText = Array();
+workflowInstancesStatusText['active'] = 'Ativa';
+workflowInstancesStatusText['exception'] = 'Exceção';
+workflowInstancesStatusText['completed'] = 'Completa';
+workflowInstancesStatusText['aborted'] = 'Abortada';
+
+/**
+ * Recebe os dados do Ajax e chama os métodos para construção da interface
+ * @param array data Os dados retornados por Ajax
+ * @return void
+ */
+function instances(data)
+{
+	if (_checkError(data))
+		return;
+
+	workflowInboxLightVersion = data['light'];
+	workflowInstancesProcessesInfo = data['processesInfo'];
+	workflowInstancesParams = data['params'];
+	workflowInstancesActivityNames = data['activityNames'];
+	workflowInstancesUserNames = data['userNames'];
+	workflowInstancesProcesses = data['processes'];
+
+	var information = $('workflowInstancesInformation');
+	if (information)
+		information.remove();
+
+	var currentInstancesMenu = $('table_tools_instances');
+	var currentInstancesElements = $('table_elements_instances');
+	if (currentInstancesElements)
+		currentInstancesElements.remove();
+
+	if (currentInstancesMenu)
+		currentInstancesMenu.remove();
+	createInstancesMenu(data['instances'].length);
+	if (data['instances'].length > 0)
+	{
+		createInstances(data['instances'], data['paging_links']);
+	}
+	else
+	{
+		var pagingContainer = $('td_tools_instances_3');
+		if (pagingContainer)
+			pagingContainer.innerHTML = '';
+		if (workflowInstancesParams['active'] == '1')
+			$('content_id_2').innerHTML += '<p class="text_dsp" id="workflowInstancesInformation">Nenhum registro ativo foi encontrado.</p>';
+		else
+			$('content_id_2').innerHTML += '<p class="text_dsp" id="workflowInstancesInformation">Nenhum registro encerrado foi encontrado.</p>';
+	}
+}
+
+/**
+ * Busca os dados, por Ajax, para a construção da interface
+ * @param int p_page O número da página (quando houver paginação) que está sendo exibida
+ * @param string sort A ordenação selecionada
+ * @param int pid O ID do processo que se quer filtrar (ao utilizar 0 (zero), todos os processos serão exibidos
+ * @param char active Indica se estão sendo exibidas as instâncias ativas ('1') ou inativas ('0')
+ * @return void
+ */
+function draw_instances_folder(p_page, sort, pid, active)
+{
+	var p_page = (p_page == null) ? 0 : p_page;
+	var sort = (sort == null) ? 0 : sort;
+	var pid = (pid == null) ? 0 : pid;
+	var active = (active == null) ? '1' : active;
+	var params = 'sort=' + sort + '&pid=' + pid +'&active=' + active + '&p_page=' + p_page;
+	cExecute('$this.bo_userinterface.instances', instances, params);
+}
+
+/**
+ * Cria o menu da interface
+ * @param int count O número de instâncias listadas
+ * @return void
+ */
+function createInstancesMenu(count)
+{
+	var content = '<div id="instancesExtraContent"></div>';
+	content += '<table id="table_tools_instances" width="100%">';
+	content += '<td id="td_tools_instances_1" width="370">';
+	content += '<ul class="horizontalMenu">';
+	content += '<li><a href="javascript:workflowInstancesAlternate()">' + ((workflowInboxLightVersion) ? '' : '<img src="templateFile.php?file=images/alternate.png"/>&nbsp;') + 'Alternar</a></li>';
+	if (count > 0)
+	{
+		content += '<li><a href="javascript:group_instances()">' + ((workflowInboxLightVersion) ? '' : '<img src="templateFile.php?file=images/group.png"/>&nbsp;') + 'Agrupar</a></li>';
+		content += '<li id="instancesProcessFilterButton"><a href="javascript:showInstancesProcessFilter()">' + ((workflowInboxLightVersion) ? '' : '<img src="templateFile.php?file=images/filter.png"/>&nbsp;') + 'Filtrar por Processo...</a></li>';
+	}
+	content += '</ul>';
+	content += '</td>';
+	content += '<td id="td_tools_instances_2">';
+	content += '</td>';
+	content += '<td id="td_tools_instances_3" align="right"></td>';
+	content += '</tr>';
+	content += '</table>';
+
+	$('content_id_2').innerHTML = content;
+}
+
+/**
+ * Cria a tabela das instâncias
+ * @param array data As instâncias que serão listadas
+ * @param array paging Dados da paginação
+ * @return void
+ */
+function createInstances(data, paging)
+{
+	var content = '';
+	content += '<table id="table_elements_instances" cellpadding="2" class="inboxElements">';
+	content += '<tr>';
+	if (workflowInstancesParams['active'] == '0')
+	{
+		content += '<th width="13%" align="left">' + createInstancesSortingHeaders('Início Processo', 'wf_started') + '</th>';
+		content += '<th width="13%" align="left">' + createInstancesSortingHeaders('Fim do Processo', 'wf_ended') + '</th>';
+		content += '<th width="40%" align="left">' + createInstancesSortingHeaders('Processo', 'wf_procname') + '</th>';
+		content += '<th width="22%" align="left">' + createInstancesSortingHeaders('Identificador', 'insname') + '</th>';
+		content += '<th width="7%" align="left">Situação</th>';
+		content += '<th width="5%" align="left">Ações</th>';
+	}
+	if (workflowInstancesParams['active'] == '1')
+	{
+		content += '<th width="15%" align="left">' + createInstancesSortingHeaders('Início da Atividade', 'wf_act_started') + '</th>';
+		content += '<th width="20%" align="left">' + createInstancesSortingHeaders('Processo', 'wf_procname') + '</th>';
+		content += '<th width="12%" align="left">' + createInstancesSortingHeaders('Identificador', 'insname') + '</th>';
+		content += '<th width="21%" align="left">' + createInstancesSortingHeaders('Atividade', 'wf_name') + '</th>';
+		content += '<th width="7%" align="left">Situação</th>';
+		content += '<th width="20%" align="left">Atribuído a</th>';
+		content += '<th width="5%" align="left">Ações</th>';
+	}
+	content += '</tr>';
+
+	var instancesLimit = data.length;
+	var current;
+	for (var i = 0; i < instancesLimit; i++)
+	{
+		current = data[i];
+		content += '<tr>';
+		if (workflowInstancesParams['active'] == '0')
+		{
+			content += '<td>' + current['wf_started'] + '</td>';
+			content += '<td>' + current['wf_ended'] + '</td>';
+			if (current['viewRunAction'])
+				content += '<td onclick="toggleHiddenView(\'instances\', ' + current['wf_instance_id'] + ', 0, ' + current['viewRunAction']['viewActivityID'] + ', ' + workflowInstancesProcessesInfo[current['wf_p_id']]['useHTTPS'] + ');" style="cursor: pointer;">';
+			else
+				content += '<td>';
+			content += ((workflowInboxLightVersion) ? workflowInboxPriority[current['wf_priority']] : ('<img src="templateFile.php?file=images/pr' + current['wf_priority'] + '.png"/>&nbsp;'));
+			content += workflowInstancesProcessesInfo[current['wf_p_id']]['name'] + '</td>';
+			content += '<td>' + current['insname'] + '</td>';
+			content += '<td align="center">' + ((workflowInboxLightVersion) ? workflowInstancesStatusText[current['wf_status']] : '<img src="templateFile.php?file=images/actions/' + workflowInstancesStatusImages[current['wf_status']] + '" alt="' + workflowInstancesStatusText[current['wf_status']] + '" title="' + workflowInstancesStatusText[current['wf_status']] + '"/>') + '</td>';
+			content += '<td><a href="javascript:workflowInboxActionView(' + current['wf_instance_id'] + ', ' + current['wf_activity_id'] + ');">' + ((workflowInboxLightVersion) ? 'Visualizar' : '<img src="templateFile.php?file=images/actions/view.png" alt="visualizar" title="visualizar"/>') + '</a>';
+		}
+		if (workflowInstancesParams['active'] == '1')
+		{
+			content += '<td>' + current['wf_act_started'] + '</td>';
+
+			if (current['viewRunAction'])
+				content += '<td onclick="toggleHiddenView(\'instances\', ' + current['wf_instance_id'] + ', ' + current['wf_activity_id'] + ', ' + current['viewRunAction']['viewActivityID'] + ', ' + workflowInstancesProcessesInfo[current['wf_p_id']]['useHTTPS'] + ');" style="cursor: pointer;">' + workflowInstancesProcessesInfo[current['wf_p_id']]['name'] + '</td>';
+			else
+				content += '<td>' + workflowInstancesProcessesInfo[current['wf_p_id']]['name'] + '</td>';
+			content += '<td>' + current['insname'] + '</td>';
+			content += '<td>' + ((workflowInboxLightVersion) ? workflowInboxPriority[current['wf_priority']] : ('<img src="templateFile.php?file=images/pr' + current['wf_priority'] + '.png"/>&nbsp;'));
+			content += workflowInstancesActivityNames[current['wf_activity_id']] + '</td>';
+			content += '<td align="center">' + ((workflowInboxLightVersion) ? workflowInstancesStatusText[current['wf_status']] : '<img src="templateFile.php?file=images/actions/' + workflowInstancesStatusImages[current['wf_status']] + '" alt="' + workflowInstancesStatusText[current['wf_status']] + '" title="' + workflowInstancesStatusText[current['wf_status']] + '"/>') + '</td>';
+			content += '<td>' + workflowInstancesUserNames[current['wf_user']] + '</td>';
+			content += '<td><a href="javascript:workflowInboxActionView(' + current['wf_instance_id'] + ', ' + current['wf_activity_id'] + ');">' + ((workflowInboxLightVersion) ? 'Visualizar' : '<img src="templateFile.php?file=images/actions/view.png" alt="visualizar" title="visualizar"/>') + '</a>';
+		}
+
+		content += '</tr>';
+		if (current['viewRunAction'])
+			if (workflowInstancesParams['active'] == '0')
+				content += constructHiddenView('instances', 6, current['wf_instance_id'], 0, current['viewRunAction']['height']);
+			else
+				content += constructHiddenView('instances', 7, current['wf_instance_id'],  current['wf_activity_id'], current['viewRunAction']['height']);
+	}
+
+	$('content_id_2').innerHTML += content;
+	$('td_tools_instances_3').innerHTML = createInstancePagingLinks(paging);
+}
+
+/**
+ * Cria os links de paginação
+ * @param array paging Dados da paginação
+ * @return string O código XHTML dos links de paginação
+ */
+function createInstancePagingLinks(pagingData)
+{
+	var output = '';
+	if (pagingData)
+	{
+		var pagingSize = pagingData.length;
+		for (var i = 0; i < pagingSize; i++)
+		{
+			if (pagingData[i].do_link == true)
+				output += '<a href="javascript:draw_instances_folder(' + pagingData[i].p_page + ', \'' + workflowInstancesParams['sort'] + '\', ' + workflowInstancesParams['pid'] + ', \'' + workflowInstancesParams['active'] + '\');">' + pagingData[i].name + '</a>&nbsp;';
+			else
+				output += '<strong>' + pagingData[i].name + '</strong>&nbsp;';
+		}
+	}
+
+	return output;
+}
+
+/**
+ * Cria os links para ordenação das instâncias
+ * @param string O texto do link
+ * @param string A ordenação esperada
+ * @return string O link criado
+ */
+function createInstancesSortingHeaders(text, expectedSort)
+{
+	var currentSort = workflowInstancesParams['sort'].split('__');
+	var theSame = (expectedSort == currentSort[0]);
+	direction = false;
+
+	var output = '';
+	if (theSame)
+	{
+		output += '<strong>';
+		direction = (currentSort[1] == 'ASC');
+	}
+
+	output += '<a href="javascript:sortInstances(\'' + expectedSort + '__' + (direction ? 'DESC' : 'ASC') + '\');">' + text + '</a>';
+
+	if (theSame)
+		output += '<img src="templateFile.php?file=images/arrow_' + (direction ? 'ascendant' : 'descendant') + '.gif"/></strong>';
+
+	return output;
+}
+
+/**
+ * Alterna entre a exibição de instâncias ativas e finalizadas
+ * @return void
+ */
+function workflowInstancesAlternate()
+{
+	if (workflowInstancesParams['active'] == '1')
+		draw_instances_folder(0, workflowInstancesParams['sort'], workflowInstancesParams['pid'], '0');
+	else
+		draw_instances_folder(0, workflowInstancesParams['sort'], workflowInstancesParams['pid'], '1');
+}
+
+/**
+ * Ordena as instâncias de acordo com o critério informado
+ * @param string sort O campo/sentido utilizado na ordenação
+ * @return void
+ */
+function sortInstances(sort)
+{
+	draw_instances_folder(workflowInstancesParams['p_page'], sort, workflowInstancesParams['pid'], workflowInstancesParams['active']);
+}
+
+/**
+ * Cria e exibe o menu listando os processos das instâncias que o usuário iniciou
+ * @return void
+ */
+function showInstancesProcessFilter()
+{
+	/* se o menu já existe, apenas o exibe */
+	if ($('instancesProcessFilter'))
+	{
+		$('instancesExtraContent').style.display = '';
+		return;
+	}
+
+	/* coleta informações sobre posicionamento */
+	var li = $('instancesProcessFilterButton');
+	var offset = Position.cumulativeOffset(li);
+	var height = li.getHeight() - 1;
+
+	/* cria as opções do menu */
+	var content = '<ul id="instancesProcessFilter" onmouseover="$(\'instancesExtraContent\').style.display = \'\'" onmouseout="$(\'instancesExtraContent\').style.display = \'none\'" class="submenu" style="top: ' + (offset[1] + height) + 'px; left: ' + offset[0] + 'px;">';
+	/* insere manualmente a linha para exibir todos os processos */
+	content += '<li><a href="javascript:$(\'instancesExtraContent\').style.display = \'none\';filterProcess(0)">Todos</a></li>';
+	var size = workflowInstancesProcesses.length;
+	for (var i = 0; i < size; i++)
+		content += '<li><a href="javascript:$(\'instancesExtraContent\').style.display = \'none\';filterProcess(' + workflowInstancesProcesses[i].pid +')">' + workflowInstancesProcesses[i].name + '</a></li>';
+	content += '</ul>';
+
+	/* insere o novo conteúdo */
+	$('instancesExtraContent').innerHTML += content;
+}
+
+function filterProcess(pid)
+{
+	draw_instances_folder(workflowInstancesParams['p_page'], workflowInstancesParams['sort'], pid, workflowInstancesParams['active']);
+}
+
+function ConfigMenuStyle_instances(m, max)
+{
+	m.SetPosition('relative',0,0);
+	m.SetCorrection(1,-5);
+	m.SetCellSpacing(0);
+	m.SetBackground('whitesmoke','','','');
+	m.SetItemText('black','center','','','');
+	m.SetItemBorder(1,'buttonface','solid');
+	m.SetItemTextHL('darkblue','center','','','');
+	m.SetItemBackgroundHL('white','','','');
+	m.SetItemBorderHL(1,'black','solid');
+	m.SetItemTextClick('white','center','','','');
+	m.SetItemBackgroundClick('darkblue','','','');
+	m.SetItemBorderClick(1,'black','solid');
+	m.SetBorder(0,'navy','solid');
+
+	m._pop.SetCorrection(4,1);
+	m._pop.SetItemDimension(max * 7 + 30,22);
+	m._pop.SetPaddings(1);
+	m._pop.SetBackground('white','','','');
+	m._pop.SetSeparator(150,'left','black','');
+	m._pop.SetExpandIcon(true,'>',9);
+	m._pop.SetItemBorder(0,'#66CCFF','solid');
+	m._pop.SetItemBorderHL(0,'black','solid');
+	m._pop.SetItemPaddings(0);
+	m._pop.SetItemPaddingsHL(0);
+	m._pop.SetItemText('black','','','','');
+	m._pop.SetItemTextHL('darkblue','','','','');
+	m._pop.SetItemBackground('white','','','');
+	m._pop.SetItemBackgroundHL('whitesmoke','','','');
+}
Index: /sandbox/workflow/branches/993/js/userinterface/orgchart.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/orgchart.js	(revision 2371)
+++ /sandbox/workflow/branches/993/js/userinterface/orgchart.js	(revision 2371)
@@ -0,0 +1,794 @@
+var workflowUserInterfaceEmployeeInfoTimer = null;
+var workflowUserInterfaceAreaInfoTimer = null;
+var workflowUserInterfaceCurrentAreaID = 0;
+var workflowUserInterfaceClickToCall = false;
+
+String.prototype.repeat = function(l)
+{
+	return new Array(l+1).join(this);
+};
+
+/* define the orgchart layout */
+function createOrgchartLayout()
+{
+	var content = '<div id="orgchartMenu"></div>';
+	content += '<div class="orgchartAreas" id="orgchartAreas"></div>';
+	content += '<div class="orgchartEmployees" id="orgchartEmployees"></div>';
+	content += '<div class="orgchartFooter" id="orgchartFooter"></div>';
+	content += '<div id="employeeInfo" class="employeeInfo" style="display: none;"></div>';
+	content += '<div id="areaInfo" class="employeeInfo" style="display: none;"></div>';
+
+	var div = $('content_id_4');
+	div.innerHTML = content;
+
+	draw_orgchart_folder();
+}
+
+/* generates the orgchart menu */
+function createOrgchartMenu(organizationID, imagemURL)
+{
+	var enderecoImagem = '';
+	if ((imagemURL != null) && (imagemURL != ''))
+		enderecoImagem = imagemURL;
+	else
+		enderecoImagem = '../index.php?menuaction=workflow.ui_orgchart.graph&organizationID=' + organizationID;
+
+	var content = '<ul class="horizontalMenu">';
+	content += '<li><a onclick="return false;">Visualizar : <select onclick="this.parentNode.parentNode.parentNode.lastChild.style.display = (this.options[1].selected) ? \'block\' : \'none\' ">'
+	content += '<option onclick="getAlphabeticalEmployees( )">Alfabética</option>'
+	content += '<option onclick="getHierarchicalArea( );" selected="true">Áreas</option>'
+	content += '<option onclick="getCostCenters( );">Centros de Custo</option>'
+	content += '<option onclick="getManning( )">Localidades</option>'
+	content += '<option onclick="getAreaWithSubtituteBoss( )">Substituição de Chefia</option>'
+	content += '<option onclick="getUsefulPhones( );">Telefones Úteis</option>'
+	content += '<option onclick="getCategoriesList( )">Vínculos</option>'
+	content += '</select></a></li>';
+	content += '<li><a href="#" onclick="window.open(\'' + enderecoImagem + '\', \'extwindow\'); return false;"><img src="templateFile.php?file=images/Process.gif">&nbsp;&nbsp;Gráfico</a></li>';
+	content += '<li><a><input type="text" name="search_term" id="search_term" onkeypress="if (((event.which) ? event.which : event.keyCode) == 13) $(\'search_span\').onclick(); return true;" /><span id="search_span" style="cursor: pointer;" onclick="tmp = $$(\'div#orgchartAreas a.destaque\'); if (tmp[0]) tmp[0].removeClassName(\'destaque\'); orgchartSearchEmployee($F(\'search_term\')); return false;">&nbsp;busca&nbsp;</span><img src="templateFile.php?file=images/help.png" title="Informe o nome, área ou telefone a ser pesquisado." style="cursor: help" /></a></li>';
+	content += '<li><a href="#" onclick="printArea(); return false;"><img src="templateFile.php?file=images/imprimir.png" width="16">&nbsp;&nbsp;Imprimir</a></li>';
+	content += '</ul>';
+	content += '<br/>';
+	content += '<br/>';
+
+	$('orgchartMenu').innerHTML = content;
+
+	$( 'search_term' ).focus( );
+}
+
+/* load the initial data */
+function draw_orgchart_folder()
+{
+	$('orgchartMenu').innerHTML = '';
+	$('orgchartAreas').innerHTML = '';
+	$('orgchartEmployees').innerHTML = '<br/><br/><br/><br/><center><i>&nbsp;&nbsp;carregando...<br/><img src="templateFile.php?file=images/loading.gif"></i></center>';
+	$('orgchartFooter').innerHTML = '';
+	$('orgchartMenu').innerHTML = '';
+
+	cExecute("$this.bo_userinterface.isVoipEnabled", function( data )
+	{
+		if ( typeof data == 'string' && data == 'VoipIsEnabled' )
+			workflowUserInterfaceClickToCall = true;
+	}, "");
+
+	cExecute("$this.bo_userinterface.orgchart", orgchart, "");
+}
+
+/* process the initial data */
+function orgchart(data)
+{
+	if (_checkError(data))
+		return;
+
+	/* in case of any warning */
+	if (data['warning'])
+	{
+		$('content_id_4').innerHTML = '<br/><br/><center><strong>' + data['warning'] + '</strong></center><br/><br/>';
+		return;
+	}
+
+	if (data['areas'].length == 0)
+	{
+		$('content_id_4').innerHTML = "<br/><br/><center><strong>Nenhuma área cadastrada.</strong></center><br/><br/>";
+		return;
+	}
+
+	/* continue displaying the data */
+	displayHierarchicalAreas(data['areas']);
+	createOrgchartMenu(data['organizacao_id'], data['url_imagem']);
+	$('orgchartEmployees').innerHTML = '<br/><br/><br/><br/><center><i>faça uma busca ou clique em uma área para ver a lista de funcionários</i></center>';
+}
+
+function displayCostCenters(data)
+{
+	if (_checkError(data))
+		return;
+
+	var div = $('orgchartEmployees');
+	if (data.length == 0)
+	{
+		div.innerHTML = '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+		return;
+	}
+
+	var content = '<center><h2>Centros de Custo</h2></center>';
+	content += '<table class="employeeList">';
+	content += '<tr><th>Nome</th><th>Número</th><th>Grupo</th></tr>';
+	var current;
+	var costCentersCount = data.length;
+	for (var i = 0; i < costCentersCount; i++)
+	{
+		current = data[i];
+		content += '<tr class="linha'+ i%2 + '" onmouseover="this.className=\'highlight0\'" onmouseout="this.className=\'linha' + i%2 + '\'">';
+		content += '<td>' + current['descricao'] + '</td>';
+		content += '<td>' + current['nm_centro_custo'] + '</td>';
+		content += '<td>' + current['grupo'] + '</td>';
+		content += '</tr>';
+	}
+	content += '</table>';
+	div.innerHTML = content;
+}
+
+function displayUsefulPhones( data )
+{
+	if ( _checkError( data ) )
+		return;
+
+	var div = $('orgchartEmployees');
+	if (data.length == 0)
+	{
+		div.innerHTML = '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+		return;
+	}
+
+	var content = '<center><h2>Telefones Úteis</h2></center>';
+	content += '<table class="employeeList">';
+	content += '<tr><th>Localidade</th><th>Número</th></tr>';
+	var current;
+	for (var i = 0; i < data.length; i++)
+	{
+		current = data[i];
+		content += '<tr class="linha'+ i%2 + '" onmouseover="this.className=\'highlight0\'" onmouseout="this.className=\'linha' + i%2 + '\'">';
+		content += '<td>' + current[ 'descricao' ] + '</td>';
+		content += '<td>' + current[ 'numero' ] + '</td>';
+		content += '</tr>';
+	}
+	content += '</table>';
+	div.innerHTML = content;
+}
+
+function displayAreaWithSubtituteBoss( data )
+{
+	if ( _checkError( data ) )
+		return;
+
+	var div = $('orgchartEmployees');
+	if (data.length == 0)
+	{
+		div.innerHTML = '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+		return;
+	}
+
+	var content = '<center><h2>Substituição de Chefia</h2></center>';
+	content += '<table class="employeeList">';
+	content += '<tr><th>Área</th><th>Titular</th><th>Substituto</th><th>Data de início</th><th>Data de término</th></tr>';
+	var current;
+	for (var i = 0; i < data.length; i++)
+	{
+		current = data[i];
+		content += '<tr class="linha'+ i%2 + '" onmouseover="this.className=\'highlight0\'" onmouseout="this.className=\'linha' + i%2 + '\'">';
+		content += '<td>' + current['area'] + '</td>';
+		content += '<td>' + current['titular'] + '</td>';
+		content += '<td>' + current['substituto'] + '</td>';
+		content += '<td>' + current['data_inicio'] + '</td>';
+		content += '<td>' + current['data_fim'] + '</td>';
+		content += '</tr>';
+	}
+	content += '</table>';
+	div.innerHTML = content;
+}
+
+function displayHierarchicalAreas(data)
+{
+	if (_checkError(data))
+		return;
+
+	function recursivePrint(subdata)
+	{
+		for (var i = 0; i < subdata.length; i++)
+		{
+			div.innerHTML += '<br />' + '&nbsp;&nbsp;&nbsp;&nbsp;'.repeat(subdata[i]['depth']) + '<a href="javascript:void(0)" id="area_' + subdata[i]['area_id'] + '" onmouseover="getAreaInfoTimer(event, ' + subdata[i]['area_id'] + '); return false;" onmouseout="hideAreaInfo(); return false;" onclick="tmp = $$(\'div#orgchartAreas a.destaque\'); if (tmp[0]) tmp[0].removeClassName(\'destaque\'); this.addClassName(\'destaque\'); loadAreaEmployees(' + subdata[i]['area_id'] + ', \'' + subdata[i]['sigla'] + '\')">' + subdata[i]['sigla'] + '</a>';
+			if (subdata[i]['children'].length > 0)
+				recursivePrint(subdata[i]['children']);
+		}
+	}
+
+	var div = $('orgchartAreas');
+	div.innerHTML = "<center><strong>ÁREAS</strong></center>";
+	recursivePrint(data);
+}
+
+function getUsefulPhones( )
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	cExecute("$this.bo_userinterface.getUsefulPhones", displayUsefulPhones, "");
+}
+
+function getAreaWithSubtituteBoss( )
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	cExecute("$this.bo_userinterface.getAreaWithSubtituteBoss", displayAreaWithSubtituteBoss, "");
+}
+
+function getCostCenters()
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	cExecute("$this.bo_userinterface.getCostCenters", displayCostCenters, "");
+}
+
+function getHierarchicalArea()
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	cExecute("$this.bo_userinterface.getHierarchicalArea", displayHierarchicalAreas, "");
+}
+
+function getAreaList()
+{
+	cExecute("$this.bo_userinterface.getAreaList", displayHierarchicalAreas, "");
+}
+
+function getCategoriesList()
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	var div = $('orgchartEmployees');
+	div.innerHTML = '';
+
+	function resultGetCategoriesList(data)
+	{
+		if (_checkError(data))
+			return;
+
+		var content = '<center><strong>VÍNCULOS</strong></center>';
+		for (var i = 0; i < data.length; i++)
+			content += '<br/>' + '&nbsp;&nbsp;<a href="javascript:void(0)" id="categoria_' + data[i]['funcionario_categoria_id'] + '" onclick="tmp = $$(\'div#orgchartAreas a.destaque\'); if (tmp[0]) tmp[0].removeClassName(\'destaque\'); this.addClassName(\'destaque\'); loadCategoryEmployees(' + data[i]['funcionario_categoria_id'] + ', \'' + data[i]['descricao'] + '\')">' + data[i]['descricao'] + ' (' + data[i]['contagem'] + ')</a>';
+		content += '<br/><br/>';
+		$('orgchartAreas').innerHTML = content;
+	}
+
+	cExecute("$this.bo_userinterface.getCategoriesList", resultGetCategoriesList, "");
+}
+
+function getManning( )
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	var div = $('orgchartEmployees');
+	div.innerHTML = '';
+
+	function resultGetManning( data )
+	{
+		if ( _checkError( data ) )
+			return;
+
+		var content = '<center><strong>Localidades</strong></center>';
+		for ( var i = 0; i < data.length; i++ )
+			content += '<br/>' + '&nbsp;<a href="javascript:void(0)" id="localidade_' + data[i]['localidade_id'] + '" onclick="tmp = $$(\'div#orgchartAreas a.destaque\'); if (tmp[0]) tmp[0].removeClassName(\'destaque\'); this.addClassName(\'destaque\');loadManningEmployees(' + data[i]['localidade_id'] + ', \'' + data[i]['descricao'] + '\')">' + data[i]['descricao'] + '</a>';
+
+		content += '<br/><br/>';
+
+		$('orgchartAreas').innerHTML = content;
+	}
+
+	cExecute("$this.bo_userinterface.getManning", resultGetManning, "");
+}
+
+function printEmployeesHandler(data)
+{
+	/* check for errors */
+	if (_checkError(data))
+		return;
+
+	var div = $('orgchartEmployees');
+
+	/* no employee to list */
+	if ( ( ! data['employees'] || data['employees'].length == 0 ) && 
+		 ( ! data['bygroup'] || data['bygroup'].length == 0 ) &&
+		 ( ! data['bytelephone'] || data['bytelephone'].length == 0 ) )
+	{
+		div.innerHTML = '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+		return;
+	}
+
+	if ( data['employees'] && data['employees'].length )
+	{
+		/* initialize varivables */
+		var content = '';
+		var employees = data['employees'];
+		var useCategories = false;
+		var useArea = false;
+
+		/* check the informations that will be displayed */
+		if (data['categories'])
+			if (data['categories'].length > 1)
+				useCategories = true;
+		if (employees[0]['area'])
+			useArea = true;
+
+		/* build the display table (headers)*/
+		content += '<table id="employeeList" class="employeeList" style="clear: both">';
+		content += '<tr class="message_header">';
+		content += '<th>Nome</th>';
+		if (useArea)
+			content += '<th>Área</th>';
+		content += '<th>Telefone</th>';
+		content += '</tr>';
+
+		/* if available, insert a menu to filter the categories */
+		if (useCategories)
+		{
+			content += '<tr><td colspan="' + (useArea ? '3' : '2') + '">';
+			content += '<ul class="horizontalMenu">';
+			for (var i = 0; i < data['categories'].length; i++)
+				content += '<li><a href="#" style="height: 2em; line-height: 2em;" onclick="highlightCategory(' + data['categories'][i]['funcionario_categoria_id'] + '); return false;">' + data['categories'][i]['descricao'] + ' (' + data['categories'][i]['contagem'] + ')</a></li>';
+			content += '</ul>';
+			content += '</td></tr>';
+		}
+
+		/* list the employees */
+		var complement = '';
+		for (var i = 0; i < employees.length; i++)
+		{
+			if (employees[i]['chief'])
+				complement = ' <strong>(' + ((employees[i]['chief'] == 1) ? 'Titular' : 'Substituto') + ')</strong>';
+			else
+				complement = '';
+			if (employees[i]['removed'])
+				complement += ' <font color="red">(excluído)</font>';
+			content += '<tr class="linha'+ i%2 + (useCategories ? ' categoria_' + employees[i]['funcionario_categoria_id'] : '') + '" onmouseover="this.className=\'highlight0\'" onmouseout="this.className=\'linha'+ i%2 + (useCategories ? ' categoria_' + employees[i]['funcionario_categoria_id'] : '') + '\'">';
+			content += '<td><a href="javascript:void(0);" onmouseover="getEmployeeInfoTimer(event, ' + employees[i]['funcionario_id'] + '); return false;" onmouseout="hideEmployeeInfo(); return false;">' + employees[i]['cn'] + complement + '</a></td>';
+			if (useArea)
+				content += '<td><a href="javascript:void(0);" onclick="loadAreaEmployees(\''+employees[i]['area_id']+'\', \'' + employees[i]['area'] + '\')">' + employees[i]['area'] + '</a></td>';
+			content += '<td align="center">';
+			if ( ! workflowUserInterfaceClickToCall )
+				content += employees[i]['telephoneNumber'];
+			else
+			{
+				content += '<a href="javascript:void(0);" title="Discar para Telefone Comercial" onclick="callVoipConnect(\''+employees[i]['telephoneNumber']+'\')"';
+				content += '>' + employees[i]['telephoneNumber'] + '</a>';
+			}
+			content += '</td></tr>';
+		}
+		content += '</table>';
+
+		if ( arguments[ 1 ] != 'returnResult' )
+		{
+			/* display the employees list and go to the top of the page */
+			div.innerHTML = content;
+			window.scrollTo(0,0);
+		}
+		else
+			return content;
+	}
+}
+
+function highlightCategory(categoryID)
+{
+	var rows = $('employeeList').childNodes[0].childNodes;
+	var categoryClass = 'categoria_' + categoryID;
+
+	var highlightClass = '';
+	var row;
+	for (var i = 1; i < rows.length; i++)
+	{
+		row = $(rows[i]);
+		/* in case alternated color rows are needed, just change the second 'highlight0' to something else (e.g. 'highlight1' which is alread defined) */
+		highlightClass = row.hasClassName('linha0') ? 'highlight0' : 'highlight0';
+		if (row.hasClassName(categoryClass))
+			row.addClassName(highlightClass);
+		else
+			row.removeClassName(highlightClass);
+	}
+}
+
+function loadAreaEmployees(areaID, areaName)
+{
+	workflowUserInterfaceCurrentAreaID = areaID;
+	$('orgchartEmployees').innerHTML = '';
+	cExecute('$this.bo_userinterface.getAreaEmployees', function( data )
+	{
+		var content = printEmployeesHandler( data, 'returnResult' );
+		if ( content )
+			$('orgchartEmployees').innerHTML = '<center><h2>Área: ' + areaName + '</h2></center>' + content;
+	}, 'areaID=' + areaID);
+}
+
+function loadCategoryEmployees(categoryID, categoryName)
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+	$('orgchartEmployees').innerHTML = '';
+	cExecute('$this.bo_userinterface.getCategoryEmployees', function( data )
+	{
+		var content = printEmployeesHandler( data, 'returnResult' );
+		if ( content )
+			$('orgchartEmployees').innerHTML = '<center><h2>Vínculo: ' + categoryName + '</h2></center>' + content;
+	}, 'categoryID=' + categoryID);
+}
+
+function loadManningEmployees( locationID, locationName )
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+	$('orgchartEmployees').innerHTML = '';
+	cExecute('$this.bo_userinterface.getManningEmployees', function( data )
+	{
+		var content = printEmployeesHandler( data, 'returnResult' );
+		if ( content )
+			$('orgchartEmployees').innerHTML = '<center><h2>Localidade: ' + locationName + '</h2></center>' + content;
+	}, 'locationID=' + locationID);
+}
+
+function getAlphabeticalEmployees( )
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+
+	var div = $('orgchartEmployees');
+	div.innerHTML = '';
+
+	var p_page = 0;
+	if ( arguments.length )
+	{
+		p_page = parseInt(arguments[ 0 ]);
+		if ( isNaN( p_page ) )
+			p_page = 0;
+	}
+	cExecute('$this.bo_userinterface.getAlphabeticalEmployees', function( data )
+	{
+		var pagingData = data['paging_links'];
+		var output = '';
+		if (pagingData)
+		{
+			var pagingSize = pagingData.length;
+			for (var i = 0; i < pagingSize; i++)
+			{
+				if (pagingData[i].do_link == true)
+					output += '<a style="font-size: 13px" href="#" onclick="getAlphabeticalEmployees(' + pagingData[i].p_page + ');">' + pagingData[i].name + '</a>&nbsp;';
+				else
+					output += '<strong style="font-size: 14px">' + pagingData[i].name + '</strong>&nbsp;';
+			}
+		}
+
+		var content = '<center><h2>Vizualização Alfabética</h2></center>';
+		content += printEmployeesHandler( data, 'returnResult' );
+		content += '<br /><center>' + output + '</center>';
+		div.innerHTML = content;
+
+	}, 'p_page='+p_page);
+}
+
+function orgchartSearchEmployee(searchTerm)
+{
+	workflowUserInterfaceCurrentAreaID = 0;
+	var div = $('orgchartEmployees');
+	div.innerHTML = '';
+	cExecute('$this.bo_userinterface.searchEmployee', function( data )
+	{
+		div.innerHTML = '<center><h2>Resultado da Busca</h2>';
+		var content = printEmployeesHandler( data, 'returnResult' );
+		if ( content )
+			div.innerHTML += '</center><span style="color:red">Busca pelo nome: ' + searchTerm.toUpperCase( ) + '</span>' + content;
+
+		// printing records found by group
+		if ( data['bygroup'] && data['bygroup'].length )
+		{
+			employees = [ ];
+			employees[ 'employees' ] = data['bygroup'];
+			content = printEmployeesHandler( employees, 'returnResult' );
+			if ( content )
+				div.innerHTML += '<br/><br/><span style="color:red">Busca pelo setor: ' + searchTerm.toUpperCase( ) + '</span><br/>' + content;
+		}
+
+		// printing records found by telephoneNumber
+		if ( data['bytelephone'] && data['bytelephone'].length )
+		{
+			employees = [ ];
+			employees[ 'employees' ] = data['bytelephone'];
+			content = printEmployeesHandler( employees, 'returnResult' );
+			if ( content )
+				div.innerHTML += '<br/><br/><span style="color:red">Busca pelo telefone: ' + searchTerm.toUpperCase( ) + '</span><br/>' + content;
+		}
+
+	}, 'searchTerm=' + searchTerm);
+}
+
+function printArea()
+{
+	if (workflowUserInterfaceCurrentAreaID == 0)
+		if (!confirm('Tem certeza de que deseja imprimir todo o Organograma?'))
+			return false;
+	var endereco = '../index.php?menuaction=workflow.ui_userinterface.printArea&areaID=' + workflowUserInterfaceCurrentAreaID;
+	window.open(endereco, 'extwindow');
+}
+
+function getEmployeeInfoTimer(e, employeeID)
+{
+	var div = $('employeeInfo');
+	div.style.left = (Event.pointerX(e) - 50) + 'px';
+	div.style.top = (Event.pointerY(e) + 14) + 'px';
+	div.hide();
+
+	if (workflowUserInterfaceEmployeeInfoTimer != null)
+	{
+		workflowUserInterfaceEmployeeInfoTimer = clearTimeout(workflowUserInterfaceEmployeeInfoTimer);
+		workflowUserInterfaceEmployeeInfoTimer = null;
+	}
+
+	workflowUserInterfaceEmployeeInfoTimer = setTimeout('getEmployeeInfo(' + employeeID + ')', 500);
+}
+
+function getEmployeeInfo(employeeID)
+{
+	function resultGetEmployeeInfo(data)
+	{
+		if (workflowUserInterfaceEmployeeInfoTimer == null)
+			return;
+
+		workflowUserInterfaceEmployeeInfoTimer = clearTimeout(workflowUserInterfaceEmployeeInfoTimer);
+		workflowUserInterfaceEmployeeInfoTimer = null;
+
+		var card_data = [ ];
+
+		for (var i = 0; i < data['info'].length; i++)
+			card_data[ data[ 'info' ][ i ][ 'name' ] ] = data[ 'info' ][ i ][ 'value' ];
+
+		var card = document.createElement( 'div' );
+		card.style.fontSize = '12px';
+		card.style.padding = '5px';
+		card.style.marginRight = '70px';
+
+		card.onmouseover = function( )
+		{
+			workflowUserInterfaceEmployeeInfoTimer = clearTimeout(workflowUserInterfaceEmployeeInfoTimer);
+			workflowUserInterfaceEmployeeInfoTimer = null;
+		}
+
+		card.onmouseout = function( )
+		{
+			workflowUserInterfaceEmployeeInfoTimer = setTimeout( "$('employeeInfo').hide( )", 1000 );
+		}
+
+		var photo = document.createElement( 'img' );
+		photo.src = 'showUserPicture.php?userID=' + employeeID;
+		photo.style.position = 'absolute';
+		photo.style.right = '10px';
+
+		card.appendChild( photo );
+
+		if ( card_data[ 'Nome' ] )
+		{
+			var name = document.createElement( 'span' );
+			name.style.fontWeight = 'bold';
+			name.appendChild( document.createTextNode( card_data[ 'Nome' ] ) );
+			card.appendChild( name );
+			card.appendChild( document.createElement( 'br' ) );
+		}
+
+		if ( card_data[ 'Título' ] )
+			var role = card.appendChild( document.createTextNode( card_data[ 'Título' ] ) );
+
+		if ( card_data[ 'Área' ] )
+		{
+			if ( role )
+				card.appendChild( document.createTextNode( ' - ' ) );
+
+			var area = document.createElement( 'a' );
+			area.href = "javascript:void(0)";
+			area.appendChild( document.createTextNode( card_data[ 'Área' ] ) );
+			area.onclick = function( )
+			{
+				loadAreaEmployees( card_data[ 'ÁreaID' ], card_data[ 'Área' ] );
+				$('employeeInfo').hide( );
+			};
+			card.appendChild( area );
+		}
+
+		if ( card_data[ 'Matrícula' ] )
+		{
+			if ( role || area )
+				card.appendChild( document.createElement( 'br' ) );
+			card.appendChild( document.createTextNode( 'Matrícula : ' + card_data[ 'Matrícula' ] ) );
+		}
+
+		card.appendChild( document.createElement( 'br' ) );
+		card.appendChild( document.createElement( 'br' ) );
+
+		if ( card_data[ 'Empresa' ] )
+		{
+			var company = document.createElement( 'span' );
+			company.style.fontWeight = 'bold';
+			company.appendChild( document.createTextNode( card_data[ 'Empresa' ] ) );
+			card.appendChild( company );
+			card.appendChild( document.createElement( 'br' ) );
+		}
+
+		if ( card_data[ 'Endereço' ] )
+			var address = card.appendChild( document.createTextNode( card_data[ 'Endereço' ] ) );
+
+		if ( card_data[ 'Complemento' ] )
+		{
+			if ( address )
+				card.appendChild( document.createTextNode( ' - ' ) );
+			var complement = card.appendChild( document.createTextNode( card_data[ 'Complemento' ] ) );
+		}
+
+		if ( address || complement )
+			card.appendChild( document.createElement( 'br' ) );
+
+		if ( card_data[ 'Cep' ] )
+			var zipcode = card.appendChild( document.createTextNode( card_data[ 'Cep' ] ) );
+
+		if ( card_data[ 'Bairro' ] )
+		{
+			if ( zipcode )
+				card.appendChild( document.createTextNode( ' - ' ) );
+			var district = card.appendChild( document.createTextNode( card_data[ 'Bairro' ] ) );
+		}
+
+		if ( zipcode || district )
+			card.appendChild( document.createElement( 'br' ) );
+
+		if ( card_data[ 'Cidade' ] )
+			var city = card.appendChild( document.createTextNode( card_data[ 'Cidade' ] ) );
+
+		if ( card_data[ 'UF' ] )
+		{
+			if ( city )
+				card.appendChild( document.createTextNode( ' - ' ) );
+			card.appendChild( document.createTextNode( card_data[ 'UF' ] ) );
+		}
+
+		card.appendChild( document.createElement( 'br' ) );
+		card.appendChild( document.createElement( 'br' ) );
+
+		if ( card_data[ 'Telefone' ] )
+		{
+			var phone = document.createElement( ( workflowUserInterfaceClickToCall ) ? 'a' : 'span' );
+			phone.appendChild( document.createTextNode( card_data[ 'Telefone' ] ) );
+			phone.style.paddingLeft = '20px';
+			phone.style.whiteSpace = 'nowrap';
+			phone.style.background = 'url(templateFile.php?file=images/phone.png) no-repeat 0 0';
+
+			var phoneNumber = card_data[ 'Telefone' ];
+			if ( workflowUserInterfaceClickToCall )
+			{
+				phone.title = "Discar para Telefone Comercial"
+				phone.onclick = function( )
+				{
+					callVoipConnect( phoneNumber );
+				}
+			}
+
+			card.appendChild( phone );
+		}
+
+		card.appendChild( document.createElement( 'br' ) );
+		card.appendChild( document.createElement( 'br' ) );
+
+		if ( card_data[ 'e-mail' ] )
+		{
+			var mail = document.createElement( 'a' );
+			mail.appendChild( document.createTextNode( card_data[ 'e-mail' ] ) );
+			mail.href = '../expressoMail1_2/index.php?to=' + card_data[ 'e-mail' ];
+			mail.style.paddingLeft = '20px';
+			mail.style.whiteSpace = 'nowrap';
+			mail.style.background = 'url(templateFile.php?file=images/mail.png) no-repeat 0 0';
+			card.appendChild( mail );
+		}
+
+		card.appendChild( document.createElement( 'br' ) );
+
+		if ( card_data[ 'sitio' ] )
+		{
+			var sitio = document.createElement( 'a' );
+			sitio.target = '_blank';
+			sitio.href = card_data[ 'sitio' ];
+			sitio.appendChild( document.createTextNode( card_data[ 'sitio' ] ) );
+			sitio.style.paddingLeft = '20px';
+			sitio.style.background = 'url(templateFile.php?file=images/sitio.png) no-repeat 0 2px';
+			card.appendChild( sitio );
+		}
+
+		var pageYLimit = document.body.scrollTop + document.body.clientHeight;
+		var div = $('employeeInfo');
+
+		div.innerHTML = '';
+		div.appendChild( card );
+
+		if ((parseInt(div.style.top.replace(/px/g, '')) + div.getHeight()) > pageYLimit)
+			div.style.top = (parseInt(div.style.top.replace(/px/g, '')) - (div.getHeight() - 50)) + 'px';
+		else
+			div.style.top = ( parseInt(div.style.top.replace(/px/g, '')) - 50 ) + 'px';
+
+		div.show();
+	}
+	cExecute('$this.bo_userinterface.getEmployeeInfo', resultGetEmployeeInfo, 'funcionario_id=' + employeeID);
+}
+
+function hideEmployeeInfo()
+{
+	if (workflowUserInterfaceEmployeeInfoTimer != null)
+	{
+		workflowUserInterfaceEmployeeInfoTimer = clearTimeout(workflowUserInterfaceEmployeeInfoTimer);
+		workflowUserInterfaceEmployeeInfoTimer = null;
+	}
+	workflowUserInterfaceEmployeeInfoTimer = setTimeout( "$('employeeInfo').hide()", 1000 );
+}
+
+function getAreaInfoTimer(e, areaID)
+{
+	var div = $('areaInfo');
+	div.style.left = (Event.pointerX(e) + 20) + 'px';
+	div.style.top = (Event.pointerY(e) + 14) + 'px';
+
+	if (workflowUserInterfaceAreaInfoTimer != null)
+	{
+		workflowUserInterfaceAreaInfoTimer = clearTimeout(workflowUserInterfaceAreaInfoTimer);
+		workflowUserInterfaceAreaInfoTimer = null;
+	}
+
+	workflowUserInterfaceAreaInfoTimer = setTimeout('getAreaInfo(' + areaID + ')', 500);
+}
+
+function getAreaInfo(areaID)
+{
+	function resultGetAreaInfo(data)
+	{
+		if (workflowUserInterfaceAreaInfoTimer == null)
+			return;
+
+		workflowUserInterfaceAreaInfoTimer = clearTimeout(workflowUserInterfaceAreaInfoTimer);
+		workflowUserInterfaceAreaInfoTimer = null;
+
+		var content = '';
+		content += '<table><tr>';
+		content += '<td valign="top" style="padding-left: 12px;">';
+		for (var i = 0; i < data['info'].length; i++)
+			content += '<strong>' + data['info'][i]['name'] + '</strong>: ' + data['info'][i]['value'] + '<br/>';
+
+		content += '</td></tr></table>';
+		var pageYLimit = document.body.scrollTop + document.body.clientHeight;
+		var div = $('areaInfo');
+		div.innerHTML = content;
+
+		if ((parseInt(div.style.top.replace(/px/g, '')) + div.getHeight()) > pageYLimit)
+			div.style.top = (parseInt(div.style.top.replace(/px/g, '')) - (div.getHeight())) + 'px';
+		div.show();
+	}
+	cExecute('$this.bo_userinterface.getAreaInfo', resultGetAreaInfo, 'area_id=' + areaID);
+}
+
+function hideAreaInfo()
+{
+	if (workflowUserInterfaceAreaInfoTimer != null)
+	{
+		workflowUserInterfaceAreaInfoTimer = clearTimeout(workflowUserInterfaceAreaInfoTimer);
+		workflowUserInterfaceAreaInfoTimer = null;
+	}
+	$('areaInfo').hide();
+}
+
+function callVoipConnect( phoneNumber )
+{
+	var handler_connectVoip = function(data){
+		if(!data) {
+			alert("Error contacting VoIP server.");
+		}
+		else{
+			alert("Requesting a VoIP call"+":\n"+data);
+		}
+	}
+
+	cExecute( '$this.bo_userinterface.callVoipConnect&to='+phoneNumber+"&typePhone=com", handler_connectVoip );
+}
Index: /sandbox/workflow/branches/993/js/userinterface/inbox_group.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/inbox_group.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/inbox_group.js	(revision 795)
@@ -0,0 +1,170 @@
+function group_inbox()
+{
+	var inbox_group = function(data)
+	{
+		if (_checkError(data))
+			return;
+		draw_inbox_group(data);
+	};
+
+	/* interrompe a tualização automática das tarefas pendentes (já que o usuário está na interface agrupada) */
+	workflowInboxStopRefreshInterval();
+	/* indica que na próxima chamada ajax que traz as instâncias, a interface de tarefas pendentes deverá ser reconstruída */
+	workflowInstancesDigest = null;
+
+	cExecute ("$this.bo_userinterface.inbox_group", inbox_group);
+}
+
+function draw_inbox_group(data) {
+	
+	killElement("table_tools_inbox");
+	killElement("table_elements_inbox");
+
+	var content_id_0 = document.getElementById("content_id_0");
+	var table_element = document.createElement("TABLE");
+	var tbody_element = document.createElement("TBODY");
+	table_element.setAttribute("id", "table_tools_inbox_group");
+	table_element.setAttribute("width", "auto");
+	tr_element = document.createElement("TR");
+	td_element1 = document.createElement("TD");
+	td_element1.setAttribute("id", "td_tools_inbox_group_1");
+	td_element1.setAttribute("width", "270");
+	tr_element.appendChild(td_element1);
+	td_element2 = document.createElement("TD");
+	td_element2.setAttribute("id", "td_tools_inbox_group_2");
+	td_element2.setAttribute("valign", "middle");
+	tr_element.appendChild(td_element2);			
+	td_element3 = document.createElement("TD");
+	td_element3.setAttribute("id", "td_tools_inbox_group_3");			
+	tr_element.appendChild(td_element3);
+	tbody_element.appendChild(tr_element);
+	table_element.appendChild(tbody_element);
+	content_id_0.appendChild(table_element);	
+
+	construct_menu_inbox_group(td_element1.id);
+	
+	//Construindo o cabeçalho da lista
+	var table_element = document.createElement("TABLE");
+	var tbody_element = document.createElement("TBODY");
+			
+	table_element.setAttribute("id", "table_elements_inbox_group");
+	table_element.className = "table_elements";
+	table_element.setAttribute("cellPadding", "2");
+		
+	tbody_element.setAttribute("id", "tbody_elements_inbox_group");
+			
+	tr_element = document.createElement("TR");
+	tr_element.className = "table_elements_tr_header";
+	
+	td_element1 = document.createElement("TD");
+	td_element1.setAttribute("width", "33%");
+	td_element1.align = "left";
+	td_element1.innerHTML = "Processo";
+		
+	td_element2 = document.createElement("TD");
+	td_element2.setAttribute("width", "33%");
+	td_element2.align = "left";
+	td_element2.innerHTML = "Atividade";	
+	
+	td_element3 = document.createElement("TD");
+	td_element3.setAttribute("width", "33%");
+	td_element3.align = "left";
+	td_element3.innerHTML = "Quantidade";	
+
+	tr_element.appendChild(td_element1);
+	tr_element.appendChild(td_element2);
+	tr_element.appendChild(td_element3);	
+	tbody_element.appendChild(tr_element);
+	table_element.appendChild(tbody_element);
+	content_id_0.appendChild(table_element);
+	
+	//inserindo elementos na lista
+	for (var i=0; i<(data.length); i++){
+		tr_element = construct_inbox_group_list(data[i]);
+		tbody_element.appendChild(tr_element);
+	}	
+}
+
+function construct_menu_inbox_group(id) {
+	var max_length = 0;
+	mmain_inbox_group = new TMainMenu("mmain_inbox_group",'horizontal');
+	_group = new TPopMenu("Desagrupar",_icon_dir + "/ungroup.png",'f',"javascript:ungroup_inbox();","");
+	
+	mmain_inbox_group.Add(_group);
+	ConfigMenuStyle_inbox(mmain_inbox_group);	
+	mmain_inbox_group.Build(id);
+	document.getElementById(mmain_inbox_group._id).style.visibility='visible';
+}
+
+function construct_inbox_group_list(data){
+
+	var tr_element = document.createElement("TR");
+	tr_element.className = 'table_elements_tr_line';
+	tr_element.style.cursor = "pointer";
+	tr_element.onclick = function() { filter_activity_inbox(data.wf_p_id); };
+
+	td_element1 = document.createElement("TD");
+	td_element1.setAttribute("width", "33%");
+	td_element1.align = "left";
+	td_element1.innerHTML = data.wf_procname + " (v" + data.wf_version +")";
+
+	td_element2 = document.createElement("TD");
+	td_element2.setAttribute("width", "33%");
+	td_element2.align = "left";
+	td_element2.innerHTML = data.wf_name;
+
+	td_element3 = document.createElement("TD");
+	td_element3.setAttribute("width", "33%");
+	td_element3.align = "left";
+	td_element3.innerHTML = data.wf_instances;
+
+	tr_element.appendChild(td_element1);
+	tr_element.appendChild(td_element2);
+	tr_element.appendChild(td_element3);	
+
+	return tr_element;
+}
+
+function ungroup_inbox(){
+	killElement("table_tools_inbox_group");
+	killElement("table_elements_inbox_group");
+	draw_inbox_folder();
+}
+
+function filter_activity_inbox(proc) {
+	killElement("table_tools_inbox_group");
+	killElement("table_elements_inbox_group");
+	filterInbox(proc);
+}
+
+function ConfigMenuStyle_inbox(m, max)
+{
+	m.SetPosition('relative',0,0);
+	m.SetCorrection(1,-5);
+	m.SetCellSpacing(0);
+	m.SetBackground('whitesmoke','','','');
+	m.SetItemText('black','center','','','');
+	m.SetItemBorder(1,'buttonface','solid');
+	m.SetItemTextHL('darkblue','center','','','');
+	m.SetItemBackgroundHL('white','','','');
+	m.SetItemBorderHL(1,'black','solid');
+	m.SetItemTextClick('white','center','','','');
+	m.SetItemBackgroundClick('darkblue','','','');
+	m.SetItemBorderClick(1,'black','solid');
+	m.SetBorder(0,'navy','solid');
+
+	m._pop.SetCorrection(4,1);
+	m._pop.SetItemDimension(max * 7 + 30,22);
+	m._pop.SetPaddings(1);
+	m._pop.SetBackground('white','','','');
+	m._pop.SetSeparator(150,'left','black','');
+	m._pop.SetExpandIcon(true,'>',9);
+	m._pop.SetItemBorder(0,'#66CCFF','solid');
+	m._pop.SetItemBorderHL(0,'black','solid');
+	m._pop.SetItemPaddings(0);
+	m._pop.SetItemPaddingsHL(0);
+	m._pop.SetItemText('black','','','','');
+	m._pop.SetItemTextHL('darkblue','','','','');
+	m._pop.SetItemBackground('white','','','');
+	m._pop.SetItemBackgroundHL('whitesmoke','','','');
+}
Index: /sandbox/workflow/branches/993/js/userinterface/inbox.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/inbox.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/inbox.js	(revision 795)
@@ -0,0 +1,565 @@
+/* armazena os parâmetro passados para a construção da caixa de entrada */
+var workflowInboxParams;
+
+/* um digest (MD5) das instâncias exibidas (para saber quando ocorreu a última atualização */
+var workflowInstancesDigest = null;
+
+/* armazena os nomes dos usuários que possuem as instâncias */
+var workflowInboxUserNames;
+
+/* armazena informações dos processos */
+var workflowInboxProcessesInfo;
+
+/* armazena os nomes das atividades */
+var workflowInboxActivityNames;
+
+/* armazena os conjuntos de ações */
+var workflowInboxActions;
+
+/* armazena a lista de processos cujas instâncias o usuário pode acessar */
+var workflowInboxProcesses;
+
+/* indica se o usuário utiliza a versão leve da interface */
+var workflowInboxLightVersion;
+
+/* indica se a interface está configurada para auto atualização */
+var workflowInboxAutoRefresh = true;
+
+/* armazena o tempo entre cada atualização, em milisegundos */
+var workflowInboxRefreshTimeInterval = 120000;
+
+/* armazena a referência do "interval" utilizado para atualização */
+var workflowInboxRefreshInterval = null;
+
+/* armazena a função (e parâmetros) que deve ser chamada para a atualização */
+var workflowInboxRefreshFunction = '';
+
+/* número de atividades view abertas na interface (usado para evitar atualização no caso de alguma view estar aberta) */
+var workflowInboxOpenedViewActivities = 0;
+
+
+/**
+ * Recria os headers da caixa de entrada sem a necessidade de
+ * recarregar todos os dados. É utilizado para o caso do resultado
+ * ser igual ao conjunto de dados mostrados
+ * @params string sortParam Nome da coluna do banco que é o parâmetro order by
+ * @params object Paging Objeto de paginação
+ * @return null
+ * @access public
+ */
+function redrawInboxHeaders(sortParam, paging)
+{
+	workflowInboxParams['sort'] = sortParam;
+
+	content = '<th width="13%" align="left">' + createSortingHeaders('Data', 'wf_act_started') + '</th>';
+	content += '<th width="20%" align="left">' + createSortingHeaders('Processo', 'wf_procname') + '</th>';
+	content += '<th width="10%" align="left">' + createSortingHeaders('Identificador', 'insname') + '</th>';
+	content += '<th width="3%" align="left">' + createSortingHeaders('P', 'wf_priority') + '</th>';
+	content += '<th width="20%" align="left">' + createSortingHeaders('Atividade', 'wf_name') + '</th>';
+	content += '<th width="20%" align="left">Atribuído a</th>';
+	content += '<th width="7%" align="left">Ações</th>';
+
+	$('table_elements_inbox').firstChild.firstChild.innerHTML = content;
+	$('td_tools_inbox_3').innerHTML = createPagingLinks(paging);
+
+	return;
+}
+
+/**
+ * Recebe os dados do Ajax e chama os métodos para construção da interface
+ * @param array data Os dados retornados por Ajax
+ * @return void
+ */
+function inbox(data)
+{
+	if (_checkError(data))
+		return;
+
+	if (workflowInstancesDigest == data['instancesDigest']){
+		if(workflowInboxParams && (workflowInboxParams['sort'] != data['sort_param'])){
+			redrawInboxHeaders(data['sort_param'], data['paging_links']);
+		}
+		return;
+	}
+
+	workflowInstancesDigest = data['instancesDigest'];
+
+	var currentSearchField = '';
+	var busca = $('busca');
+	if (busca)
+		currentSearchField = busca.value;
+	var flagSearchPerformed = false;
+
+	if (data['params']['search_term'])
+		if (data['params']['search_term'] != '')
+			flagSearchPerformed = true;
+
+	workflowInboxUserNames = data['userNames'];
+	workflowInboxProcessesInfo = data['processesInfo'];
+	workflowInboxActivityNames = data['activityNames'];
+	workflowInboxProcesses = data['processes'];
+	workflowInboxActions = data['actions'];
+	workflowInboxParams = data['params'];
+	workflowInboxLightVersion = data['light'];
+
+	var information = $('workflowInboxInformation');
+	if (information)
+		information.remove();
+
+	var currentInboxMenu = $('table_tools_inbox');
+	var currentInboxElements = $('table_elements_inbox');
+	if (currentInboxElements)
+		currentInboxElements.remove();
+
+	if (data['instances'].length > 0)
+	{
+		if (!currentInboxMenu)
+			createInboxMenu();
+		createInbox(data['instances'], data['paging_links']);
+	}
+	else
+	{
+		if ((!flagSearchPerformed) && currentInboxMenu)
+			currentInboxMenu.remove();
+		var pagingContainer = $('td_tools_inbox_3');
+		if (pagingContainer)
+			pagingContainer.innerHTML = '';
+		$('content_id_0').innerHTML += '<p class="text_dsp" id="workflowInboxInformation">Não existem atividades a serem executadas</p>';
+	}
+
+	busca = $('busca');
+	if (busca)
+	{
+		if (flagSearchPerformed)
+			busca.value = data['params']['search_term'];
+		else
+			if (currentSearchField != '')
+				busca.value = currentSearchField;
+		busca.focus();
+	}
+}
+
+/**
+ * Cria o menu da interface
+ * @return void
+ */
+function createInboxMenu()
+{
+	var content = '<div id="extraContent"></div>';
+	content += '<table id="table_tools_inbox" width="100%">';
+	content += '<td id="td_tools_inbox_1" width="470">';
+	content += '<ul class="horizontalMenu">';
+	content += '<li><a href="javascript:group_inbox()">' + ((workflowInboxLightVersion) ? '' : '<img src="templateFile.php?file=images/group.png"/>&nbsp;') + 'Agrupar</a></li>';
+	content += '<li id="processFilterButton"><a href="javascript:showProcessFilter()">' + ((workflowInboxLightVersion) ? '' : '<img src="templateFile.php?file=images/filter.png"/>&nbsp;') + 'Filtrar por Processo...</a></li>';
+	content += '<li><a href="doc/manual_do_usuario.pdf">' + ((workflowInboxLightVersion) ? '' : '<img src="templateFile.php?file=images/help.png"/>&nbsp;') + 'Ajuda</a></li>';
+	content += '<li id="refreshButton"><a href="javascript:workflowInboxRefreshNow()" id="refreshLink"' + (((!workflowInboxAutoRefresh) && workflowInboxLightVersion) ? ' style="color: gray !important"' : '') + '>' + ((workflowInboxLightVersion) ? '' : '<img id="reloadImage" src="templateFile.php?file=images/reload' + ((workflowInboxAutoRefresh) ? '' : '_bw') + '.png"/>&nbsp;') + 'Atualizar</a><a href="javascript:showRefreshMenu()" style="padding: 0px;"><img src="templateFile.php?file=images/arrow_ascendant.gif" style="padding-top: 11px"/></a></li>';
+	content += '</ul>';
+	content += '</td>';
+	content += '<td id="td_tools_inbox_2" valign="middle" align="left" width="270">';
+	content += '&nbsp;Busca: <input type="text" size="15" id="busca" name="busca" onkeypress="if (((window.Event) ? event.which : event.keyCode) == 13) $(\'searchInboxButton\').onclick(); return true;"/>&nbsp;<a href="#" id="searchInboxButton" onclick="searchInbox($F(\'busca\')); $(\'show_all\').show(); return false;">filtrar</a>&nbsp;&nbsp;<a href="#" id="show_all" onclick="$(\'busca\').value = \'\'; searchInbox(\'\'); this.hide(); return false;" style="display: none;">todos</a>';
+	content += '</td>';
+	content += '<td id="td_tools_inbox_3" align="right"></td>';
+	content += '</tr>';
+	content += '</table>';
+
+	$('content_id_0').innerHTML = content;
+}
+
+/**
+ * Cria a tabela das instâncias
+ * @param array data As instâncias que serão listadas
+ * @param array paging Dados da paginação
+ * @return void
+ */
+function createInbox(data, paging)
+{
+	var content = '';
+	content += '<table id="table_elements_inbox" cellpadding="2" class="inboxElements">';
+	content += '<tr>';
+	content += '<th width="13%" align="left">' + createSortingHeaders('Data', 'wf_act_started') + '</th>';
+	content += '<th width="20%" align="left">' + createSortingHeaders('Processo', 'wf_procname') + '</th>';
+	content += '<th width="10%" align="left">' + createSortingHeaders('Identificador', 'insname') + '</th>';
+	content += '<th width="3%" align="left">' + createSortingHeaders('P', 'wf_priority') + '</th>';
+	content += '<th width="20%" align="left">' + createSortingHeaders('Atividade', 'wf_name') + '</th>';
+	content += '<th width="20%" align="left">Atribuído a</th>';
+	content += '<th width="7%" align="left">Ações</th>';
+	content += '</tr>';
+
+	var inboxLimit = data.length;
+	var current;
+	for (var i = 0; i < inboxLimit; i++)
+	{
+		current = data[i];
+		content += '<tr>';
+		content += '<td>' + current['wf_act_started'] + '</td>';
+		if (current['viewRunAction'])
+			content += '<td onclick="toggleHiddenView(\'inbox\', ' + current['wf_instance_id'] + ', ' + current['wf_activity_id'] + ', ' + current['viewRunAction']['viewActivityID'] + ', ' + workflowInboxProcessesInfo[current['wf_p_id']]['useHTTPS'] + ');" style="cursor: pointer;">' + workflowInboxProcessesInfo[current['wf_p_id']]['name'] + '</td>';
+		else
+			content += '<td>' + workflowInboxProcessesInfo[current['wf_p_id']]['name'] + '</td>';
+		content += '<td>' + current['insname'] + '</td>';
+
+		content += '<td>';
+		content += ((workflowInboxLightVersion) ? workflowInboxPriority[current['wf_priority']] : ('<img src="templateFile.php?file=images/pr' + current['wf_priority'] + '.png"/>&nbsp;'));
+		if (current['wf_status'] != 'active')
+			content += ((workflowInboxLightVersion) ? '<font color="red">Exc.</font>' : '<img src="templateFile.php?file=images/exception.png"/></td>') + '&nbsp;';
+		content += '<td>'+workflowInboxActivityNames[current['wf_activity_id']] + '</td>';
+
+		content += '<td>' + workflowInboxUserNames[current['wf_user']] + '</td>';
+		content += '<td>' + constructActions(current['wf_instance_id'], current['wf_activity_id'], current['wf_p_id'], current['wf_actions']) + '</td>';
+		content += '</tr>';
+		if (current['viewRunAction'])
+			content += constructHiddenView('inbox', 6, current['wf_instance_id'], current['wf_activity_id'], current['viewRunAction']['height']);
+	}
+
+	$('content_id_0').innerHTML += content;
+	$('td_tools_inbox_3').innerHTML = createPagingLinks(paging);
+}
+
+/**
+ * Cria os links para ordenação das instâncias
+ * @param string O texto do link
+ * @param string A ordenação esperada
+ * @return string O link criado
+ */
+function createSortingHeaders(text, expectedSort)
+{
+	workflowInboxParams['sort'] = workflowInboxParams['sort'].split(',').shift();
+	var currentSort = workflowInboxParams['sort'].split('__');
+	var theSame = (expectedSort == currentSort[0]);
+	direction = false;
+
+	var output = '';
+	if (theSame)
+	{
+		output += '<strong>';
+		direction = (currentSort[1] == 'ASC');
+	}
+
+	output += '<a href="javascript:sortInbox(\'' + expectedSort + '__' + (direction ? 'DESC' : 'ASC') + '\');">' + text + '</a>';
+
+	if (theSame)
+		output += '<img src="templateFile.php?file=images/arrow_' + (direction ? 'ascendant' : 'descendant') + '.gif"/></strong>';
+
+	return output;
+}
+
+/**
+ * Cria e exibe o menu listando os processos das instâncias que o usuário pode ver
+ * @return void
+ */
+function showProcessFilter()
+{
+	hideExtraContents();
+	/* se o menu já existe, apenas o exibe */
+	if ($('processFilter'))
+	{
+		$('divProcessFilter').style.display = '';
+		$('extraContent').style.display = '';
+		return;
+	}
+
+	/* coleta informações sobre posicionamento */
+	var li = $('processFilterButton');
+	var offset = Position.cumulativeOffset(li);
+	var height = li.getHeight() - 1;
+
+	/* cria as opções do menu */
+	var content = '<div id="divProcessFilter"><ul id="processFilter" onmouseover="$(\'divProcessFilter\').style.display = \'\'; $(\'extraContent\').style.display = \'\'" onmouseout="$(\'divProcessFilter\').style.display = \'none\'; $(\'extraContent\').style.display = \'none\'" class="submenu" style="top: ' + (offset[1] + height) + 'px; left: ' + offset[0] + 'px;">';
+	/* insere manualmente a linha para exibir todos os processos */
+	content += '<li><a href="javascript:$(\'divProcessFilter\').style.display = \'none\';filterInbox(0)">Todos</a></li>';
+	var size = workflowInboxProcesses.length;
+	for (var i = 0; i < size; i++)
+		content += '<li><a href="javascript:$(\'divProcessFilter\').style.display = \'none\';filterInbox(' + workflowInboxProcesses[i].pid +')">' + workflowInboxProcesses[i].name + '</a></li>';
+	content += '</ul>';
+
+	/* insere o novo conteúdo */
+	var extraContent = $('extraContent');
+	extraContent.innerHTML += content;
+	extraContent.style.display = '';
+}
+
+/**
+ * Cria e exibe o menu de atualização da interface de Tarefas Pendentes
+ * @return void
+ */
+function showRefreshMenu()
+{
+	hideExtraContents();
+
+	/* se o menu já existe, apenas o exibe */
+	if ($('refreshMenu'))
+	{
+		$('divRefreshMenu').style.display = '';
+		$('extraContent').style.display = '';
+		return;
+	}
+
+	/* coleta informações sobre posicionamento */
+	var li = $('refreshButton');
+	var offset = Position.cumulativeOffset(li);
+	var height = li.getHeight() - 1;
+
+	/* cria as opções do menu */
+	var content = '<div id="divRefreshMenu"><ul id="refreshMenu" onmouseover="$(\'divRefreshMenu\').style.display = \'\'; $(\'extraContent\').style.display = \'\'" onmouseout="$(\'divRefreshMenu\').style.display = \'none\'; $(\'extraContent\').style.display = \'none\'" class="submenu" style="top: ' + (offset[1] + height) + 'px; left: ' + offset[0] + 'px;">';
+	/* insere manualmente a linha para exibir todos os processos */
+	content += '<li><a href="javascript:$(\'divRefreshMenu\').style.display = \'none\';workflowInboxStopAutoRefresh()">Interromper Atualização Automática</a></li>';
+	content += '<li><a href="javascript:$(\'divRefreshMenu\').style.display = \'none\';workflowInboxStartAutoRefresh()">Ativar Atualização Automática</a></li>';
+	content += '<li><a href="javascript:$(\'divRefreshMenu\').style.display = \'none\';workflowInboxRefreshNow();">Atualizar Agora</a></li>';
+
+	/* insere o novo conteúdo */
+	var extraContent = $('extraContent');
+	extraContent.innerHTML += content;
+	extraContent.style.display = '';
+}
+
+/**
+ * Oculta todos os elementos dentro do div 'extraContent'
+ * @return void
+ */
+function hideExtraContents()
+{
+	$A($('extraContent').childNodes).each(function(item)
+		{
+			item.style.display = 'none';
+		});
+}
+
+/**
+ * Constrói o menu de ações de acordo com a permissão do usuário
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @param int processID O ID do processo
+ * @param int actionID O ID do conjunto de ações
+ * @return string O código XHTML do menu de ações
+ */
+function constructActions(instanceID, activityID, processID, actionID)
+{
+	var actions = workflowInboxActions[actionID];
+	var content = '';
+
+	var instanceURL = getInstanceURL(instanceID, activityID, workflowInboxProcessesInfo[processID]['useHTTPS']);
+
+	if (workflowInboxLightVersion)
+	{
+		if (actions[0]['value'])
+			content += '<a href="' + instanceURL + '">Exec.</a>';
+		else
+			content += 'Exec';
+		content += '&nbsp;<a href="javascript:constructMoreActions(' + instanceID + ', ' + activityID + ', ' + actionID + ');">Mais</a>';
+	}
+	else
+	{
+		content += '<a href="' + instanceURL + '"><img src="templateFile.php?file=images/actions/' + ((actions[0].value) ? '' : 'no_') + 'run.png" alt="' + actions[0].text + '" title="' + actions[0].text + '"/></a>&nbsp;';
+		for (var i = 0; i < actions.length; i++)
+			if (actions[i].name == 'view')
+			content += '<a href="javascript:workflowInboxAction' + actions[i].name.charAt(0).capitalize() + actions[i].name.substr(1) + '(' + instanceID + ', ' + activityID + ');"><img src="templateFile.php?file=images/actions/' + ((actions[i].value) ? '' : 'no_') + actions[i].name + '.png" alt="' + actions[i].text + '" title="' + actions[i].text + '"/></a>&nbsp;';
+		content += '<a href="javascript:constructMoreActions(' + instanceID + ', ' + activityID + ', ' + actionID + ');"><img src="templateFile.php?file=images/more_down.png" alt="Mais Ações" title="Mais Ações"/></a>';
+	}
+	content += '<div id="advancedActionsMenu_' + instanceID + '_' + activityID + '" onmouseout="this.hide();" onmouseover="this.show();" style="display: none; width: 150px;" class="advancedActions"></div>';
+
+	return content;
+}
+
+/**
+ * Constrói o menu de ações avançadas de acordo com a permissão do usuário
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @param int actionID O ID do conjunto de ações
+ * @return string O código XHTML do menu de ações avançadas
+ */
+function constructMoreActions(instanceID, activityID, actionID)
+{
+	var content = '';
+	var div = $('advancedActionsMenu_' + instanceID + '_' + activityID);
+
+	if (!div.innerHTML)
+	{
+		var actions = workflowInboxActions[actionID];
+		if (workflowInboxLightVersion)
+		{
+			for (var i = 0; i < actions.length; i++)
+				if ((actions[i].name != 'run') && (actions[i].name != 'viewrun'))
+					if (actions[i].value)
+						content += '<a href="javascript:workflowInboxAction' + actions[i].name.charAt(0).capitalize() + actions[i].name.substr(1) + '(' + instanceID + ', ' + activityID + ');">&nbsp;' + actions[i].text + '</a><br/>';
+					else
+						content += '&nbsp;' + actions[i].text + '<br/>';
+		}
+		else
+		{
+			for (var i = 0; i < actions.length; i++)
+				if ((actions[i].name != 'run') && (actions[i].name != 'viewrun') && (actions[i].name != 'view'))
+					if (actions[i].value)
+						content += '<a href="javascript:workflowInboxAction' + actions[i].name.charAt(0).capitalize() + actions[i].name.substr(1) + '(' + instanceID + ', ' + activityID + ');"><img src="templateFile.php?file=images/actions/' + actions[i].name + '.png"/>&nbsp;' + actions[i].text + '</a><br/>';
+					else
+						content += '<img src="templateFile.php?file=images/actions/no_' + actions[i].name + '.png"/>&nbsp;' + actions[i].text + '<br/>';
+		}
+		div.innerHTML = content;
+	}
+
+	var offset = Position.cumulativeOffset(div.parentNode);
+	div.style.top = (offset[1] + 20) + 'px';
+	div.style.left = (offset[0] - 80) + 'px';
+
+	if (div.visible())
+		div.hide();
+	else
+		div.show();
+}
+
+/**
+ * Cria os links de paginação
+ * @param array paging Dados da paginação
+ * @return string O código XHTML dos links de paginação
+ */
+function createPagingLinks(pagingData)
+{
+	var output = '';
+	if (pagingData)
+	{
+		var pagingSize = pagingData.length;
+		for (var i = 0; i < pagingSize; i++)
+		{
+			if (pagingData[i].do_link == true)
+				output += '<a href="javascript:draw_inbox_folder(' + pagingData[i].p_page + ', \'' + workflowInboxParams['sort'] + '\', ' + workflowInboxParams['pid'] + ', \'' + workflowInboxParams['search_term'] + '\');">' + pagingData[i].name + '</a>&nbsp;';
+			else
+				output += '<strong>' + pagingData[i].name + '</strong>&nbsp;';
+		}
+	}
+
+	return output;
+}
+
+/**
+ * Ordena as instâncias da interface
+ * @param string sort A ordenação selecionada
+ * @return void
+ */
+function sortInbox(sort)
+{
+	draw_inbox_folder(0, sort, workflowInboxParams['pid'], workflowInboxParams['search_term']);
+}
+
+/**
+ * Faz uma busca nas instâncias da interface
+ * @param string search_term A string que será procurada
+ * @return void
+ */
+function searchInbox(search_term)
+{
+	draw_inbox_folder(0, workflowInboxParams['sort'], workflowInboxParams['pid'], escape(search_term));
+}
+
+/**
+ * Filtra a interface para exibir somente as instâncias de um determinado processo
+ * @param int pid O ID do processo que se quer filtrar (ao utilizar 0 (zero), todos os processos serão exibidos
+ * @return void
+ */
+function filterInbox(pid)
+{
+	draw_inbox_folder(null, workflowInboxParams['sort'], pid, workflowInboxParams['search_term']);
+}
+
+/**
+ * Busca os dados, por Ajax, para a reconstrução da interface
+ * @param int p_page O número da página (quando houver paginação) que está sendo exibida
+ * @param string sort A ordenação selecionada
+ * @param int pid O ID do processo que se quer filtrar (ao utilizar 0 (zero), todos os processos serão exibidos
+ * @param string search_term A string que será procurada
+ * @return void
+ */
+function draw_inbox_folder(p_page, sort, pid, search_term)
+{
+	var p_page = (p_page == null) ? 0 : p_page;
+	var sort = (sort == null) ? 0 : sort;
+	var pid = (pid == null) ? 0 : pid;
+	var search_term = (search_term == null) ? '' : search_term;
+
+	workflowInboxRefreshFunction = 'cExecute("$this.bo_userinterface.inbox", inbox, "sort=' + sort + '&pid=' + pid + '&p_page=' + p_page + '&search_term=' + search_term + '")';
+	if (workflowInboxAutoRefresh)
+		workflowInboxStartRefreshInterval();
+
+	cExecute("$this.bo_userinterface.inbox", inbox, "sort=" + sort + "&pid=" + pid + "&p_page=" + p_page + "&search_term=" + search_term);
+}
+
+/**
+ * Atualiza a lista de instâncias
+ * @return void
+ */
+function workflowInboxRefreshNow()
+{
+	if (workflowInboxRefreshFunction != '')
+		eval(workflowInboxRefreshFunction);
+	else
+		draw_inbox_folder();
+}
+
+/**
+ * Pára o "interval" que chama a função de atualização
+ * @return void
+ */
+function workflowInboxStopRefreshInterval()
+{
+	if (workflowInboxRefreshInterval)
+	{
+		clearInterval(workflowInboxRefreshInterval);
+		workflowInboxRefreshInterval = null;
+	}
+}
+
+/**
+ * Inicia o "interval" que chama a função de atualização
+ * @return void
+ */
+function workflowInboxStartRefreshInterval()
+{
+	workflowInboxStopRefreshInterval();
+	workflowInboxRefreshInterval = setInterval('workflowInboxRefresh()', workflowInboxRefreshTimeInterval);
+}
+
+/**
+ * Pára a atualização automática
+ * @return void
+ */
+function workflowInboxStopAutoRefresh()
+{
+	workflowInboxAutoRefresh = false;
+	workflowInboxStopRefreshInterval();
+	if (workflowInboxLightVersion)
+		$('refreshLink').style.setProperty('color', 'gray', 'important');
+	else
+		$('reloadImage').src = 'templateFile.php?file=images/reload_bw.png';
+}
+
+/**
+ * Inicia a atualização automática
+ * @return void
+ */
+function workflowInboxStartAutoRefresh()
+{
+	workflowInboxAutoRefresh = true;
+	workflowInboxStartRefreshInterval();
+	if (workflowInboxLightVersion)
+		$('refreshLink').style.setProperty('color', 'black', 'important');
+	else
+		$('reloadImage').src = 'templateFile.php?file=images/reload.png';
+}
+
+/**
+ * Função que é chamada pelo "interval" para atualizar, automaticamente, a lista de instâncias
+ * @return void
+ */
+function workflowInboxRefresh()
+{
+	/* verifica se a aba aberta é a de "Tarefas Pendentes" */
+	if (tabStack[tabStack.length - 1] != 0)
+		return;
+
+	if ($('divProgressBar').style.visibility == 'visible')
+		return;
+
+	if (workflowInboxOpenedViewActivities > 0)
+		return;
+
+	/* atualiza a lista de instâncias */
+	workflowInboxRefreshNow();
+}
Index: /sandbox/workflow/branches/993/js/userinterface/inbox_actions.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/inbox_actions.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/inbox_actions.js	(revision 795)
@@ -0,0 +1,107 @@
+/**
+ * Faz uma chamada Ajax para executar uma ação qualquer
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @param string action A ação que será executada
+ * @param string message A mensagem que será exibida após a execução da ação solicitada
+ * @return void
+ */
+function inboxGeneralAction(instanceID, activityID, action, message)
+{
+	function actionHandler(data)
+	{
+		if (_checkError(data))
+			return false;
+
+		if (data == true)
+		{
+			write_msg(message);
+			draw_inbox_folder(workflowInboxParams['p_page'], workflowInboxParams['sort'], workflowInboxParams['pid'], workflowInboxParams['search_term']);
+		}
+	};
+
+	cExecute ('$this.bo_userinterface.' + action, actionHandler, 'instanceID=' + instanceID + "&activityID=" + activityID);
+}
+
+/**
+ * Solicita o envio da instância para a próxima atividade
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @return void
+ */
+function workflowInboxActionSend(instanceID, activityID)
+{
+	inboxGeneralAction(instanceID, activityID, 'inboxActionSend', 'A instância foi enviada para a próxima atividade.');
+}
+
+/**
+ * Solicita a liberação de uma instância
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @return void
+ */
+function workflowInboxActionRelease(instanceID, activityID)
+{
+	inboxGeneralAction(instanceID, activityID, 'inboxActionRelease', 'O acesso à instância foi liberado.');
+}
+
+/**
+ * Solicita a captura de um instância
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @return void
+ */
+function workflowInboxActionGrab(instanceID, activityID)
+{
+	inboxGeneralAction(instanceID, activityID, 'inboxActionGrab', 'A instância foi atribuída para você.');
+}
+
+/**
+ * Solicita a transformação de uma instância em exceção
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @return void
+ */
+function workflowInboxActionException(instanceID, activityID)
+{
+	inboxGeneralAction(instanceID, activityID, 'inboxActionException', 'A instância foi transformada em exceção.');
+}
+
+/**
+ * Solicita a retirada da instância de exceção
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @return void
+ */
+function workflowInboxActionResume(instanceID, activityID)
+{
+	inboxGeneralAction(instanceID, activityID, 'inboxActionResume', 'A instância foi retirada de exceção.');
+}
+
+/**
+ * Solicita que uma instância seja abortada
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @return void
+ */
+function workflowInboxActionAbort(instanceID, activityID)
+{
+	inboxGeneralAction(instanceID, activityID, 'inboxActionAbort', 'A instância foi abortada.');
+}
+
+/**
+ * Solicita a visualização de informações sobre a instância
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade (desnecessário)
+ * @return void
+ */
+function workflowInboxActionView(instanceID, activityID)
+{
+	function viewHandler(data)
+	{
+		if (_checkError(data))
+			return false;
+		drawViewInstance(data);
+	};
+	cExecute ("$this.bo_userinterface.inboxActionView", viewHandler, 'instanceID=' + instanceID);
+}
Index: /sandbox/workflow/branches/993/js/userinterface/common_functions.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/common_functions.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/common_functions.js	(revision 795)
@@ -0,0 +1,209 @@
+activityStatusTranslation = new Array();
+activityStatusTranslation['running'] = 'Em execução';
+activityStatusTranslation['completed'] = 'Completada';
+
+instanceStatusTranslation = new Array();
+instanceStatusTranslation['completed'] = 'Completada';
+instanceStatusTranslation['active'] = 'Ativa';
+instanceStatusTranslation['aborted'] = 'Abortada';
+instanceStatusTranslation['exception'] = 'Em exceção';
+
+workflowInboxPriority = new Array();
+workflowInboxPriority[0] = '<font color="#dedede"><b>&bull;</b></font>&nbsp;';
+workflowInboxPriority[1] = '<font color="#7ec65b"><b>&bull;</b></font>&nbsp;';
+workflowInboxPriority[2] = '<font color="#efea4e"><b>&bull;</b></font>&nbsp;';
+workflowInboxPriority[3] = '<font color="#fc9e34"><b>&bull;</b></font>&nbsp;';
+workflowInboxPriority[4] = '<font color="#e31b23"><b>&bull;</b></font>&nbsp;';
+
+var workflowCommonExpressoIndexPath = null;
+
+/* abre uma nova aba para mostrar os dados da instancia */
+function drawViewInstance(data)
+{
+	var borderID = create_border("Visualizar Instância");
+
+	var content = '<br/>';
+	content += '<table class="info_table" width="90%" align="center">';
+	content += '<tr class="info_tr_header"><td colspan="5">Instância de ' + data['wf_procname'] + '(v' + data['wf_version'] + ')</td></tr>';
+	content += '<tr class="info_tr_sub_header">';
+	content += '<td width="19%">Criado em</td>';
+	content += '<td width="19%">Finalizado em</td>';
+	content += '<td width="10%">Prioridade</td>';
+	content += '<td width="13%">Situação</td>';
+	content += '<td width="39%">Proprietário</td>';
+	content += '</tr>';
+	content += '<tr class="info_tr_simple">';
+	content += '<td>' + data['wf_started'] + '</td>';
+	content += '<td>' + data['wf_ended'] + '</td>';
+	content += '<td align="center">' + data['wf_priority'] + '</td>';
+	content += '<td>' + instanceStatusTranslation[data['wf_status']] + '</td>';
+	content += '<td>' + data['wf_owner'] + '</td>';
+	content += '</tr>';
+	content += '</table>';
+
+	content += '<br/>';
+	content += '<table class="info_table" width="90%" align="center">';
+	content += '<tr class="info_tr_header"><td colspan="4">Histórico</td></tr>';
+	content += '<tr class="info_tr_sub_header">';
+	content += '<td width="30%">Atividade</td>';
+	content += '<td width="20%">Iniciado em</td>';
+	content += '<td width="20%">Duração</td>';
+	content += '<td width="30%">Usuário</td>';
+	content += '</tr>';
+
+	var current;
+	var workitemCount = data['wf_workitems'].length;
+	for (var i = 0; i < workitemCount; i++)
+	{
+		current = data['wf_workitems'][i];
+		content += '<tr class="info_tr_simple">';
+		content += '<td>' + activity_icon(current['wf_type'], current['wf_is_interactive']) + " " + current['wf_name'];
+		content += '<td>' + current['wf_started'] + '</td>';
+		content += '<td>' + current['wf_duration'] + '</td>';
+		content += '<td>' + current['wf_user'] + '</td>';
+		content += '</tr>';
+	}
+	content += '</table>';
+
+	if ((data['wf_status'] == 'active') || (data['wf_status'] == 'exception'))
+	{
+		content += '<br/>';
+		content += '<table class="info_table" width="90%" align="center">';
+		content += '<tr class="info_tr_header"><td colspan="4">Atividades em Andamento</td></tr>';
+		content += '<tr class="info_tr_sub_header">';
+		content += '<td width="30%">Nome</td>';
+		content += '<td width="20%">Iniciado em</td>';
+		content += '<td width="20%">Situação</td>';
+		content += '<td width="30%">Usuário</td>';
+		content += '</tr>';
+
+		var current;
+		var activityCount = data['wf_activities'].length;
+		for (var i = 0; i < activityCount; i++)
+		{
+			current = data['wf_activities'][i];
+			content += '<tr class="info_tr_simple">';
+			content += '<td>' + activity_icon(current['wf_type'], current['wf_is_interactive']) + " " + current['wf_name'];
+			content += '<td>' + current['wf_started'] + '</td>';
+			content += '<td>' + activityStatusTranslation[current['wf_status']] + '</td>';
+			content += '<td>' + ((current['wf_user']) ? current['wf_user'] : '*') + '</td>';
+			content += '</tr>';
+		}
+
+		content += '</table>';
+	}
+
+	if(data['wf_properties'] != null)
+	{
+		content += '<br/>';
+		content += '<table class="info_table" width="90%" align="center">';
+		content += '<tr class="info_tr_header"><td colspan="2">Propriedades</td></tr>';
+		content += '<tr class="info_tr_sub_header">';
+		content += '<td width="30%">Nome</td>';
+		content += '<td width="70%">Valor</td>';
+		content += '</tr>';
+
+		var propertiesCount = data['wf_properties']['keys'].length;
+		for (var i = 0; i < propertiesCount; i++)
+		{
+			content += '<tr class="info_tr_simple">';
+			content += '<td>' + data['wf_properties']['keys'][i] + '</td>';
+			content += '<td>' + data['wf_properties']['values'][i] + '</td>';
+			content += '</tr>';
+		}
+		content += '</table>';
+	}
+
+	if (data['viewRunAction'])
+	{
+		var viewActivity = data['viewRunAction'];
+		content += '<br/>';
+		content += '<table class="info_table" width="90%" align="center">';
+		content += '<tr class="info_tr_header"><td>Atividade View do Processo</td></tr>';
+		content += '<tr class="info_tr_simple">';
+		content += '<td width="100%"><iframe src="' + getInstanceURL(data['wf_instance_id'], viewActivity['viewActivityID'], viewActivity['useHTTPS']) + '" width="100%" ' + ((viewActivity['height'] > 0) ? ' height="' + viewActivity['height'] + '"' : '') + '></iframe></td>';
+		content += '</tr>';
+		content += '</table>';
+	}
+
+	$('content_id_' + borderID).innerHTML = content;
+}
+
+/**
+ * Constrói um iframe oculto para os processos que possuem sua própria atividade do tipo view
+ * @param string preffix O prefixo usado para nomear o iframe oculto
+ * @param int numberOfColumns A quantidade de colunas da tabela
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @param int height A altura do iframe
+ * @return string O código XHTML do iframe
+ */
+function constructHiddenView(preffix, numberOfColumns, instanceID, activityID, height)
+{
+	var output = '';
+	output += '<tr class="table_elements_tr_line" id="' + preffix + '_hiddenView_' + instanceID + '_' + activityID + '" style="display: none;">';
+	output += '<td colspan="' + numberOfColumns + '" align="left"><iframe width="100%" ' + ((height > 0) ? ' height="' + height + '"' : '') + '></iframe>';
+	output += '</td></tr>';
+	return output;
+}
+
+/**
+ * Exibe ou oculta o iframe da atividade View
+ * @param string preffix O prefixo usado para nomear o iframe oculto
+ * @param int instanceID O ID da instância
+ * @param int activityID O ID da atividade
+ * @param int viewActivityID O ID da atividade View
+ * @return void
+ */
+function toggleHiddenView(preffix, instanceID, activityID, viewActivityID, useHTTPS)
+{
+	var tr = $(preffix + '_hiddenView_' + instanceID + '_' + activityID);
+	var iframe = tr.childNodes[0].childNodes[0];
+
+	function openView(obj)
+	{
+		workflowInboxOpenedViewActivities++;
+		if (obj.element.src == '')
+			obj.element.src = getInstanceURL(instanceID, viewActivityID, useHTTPS);
+	}
+
+	function closeView(obj)
+	{
+		workflowInboxOpenedViewActivities--;
+		if (workflowInboxOpenedViewActivities < 0)
+			workflowInboxOpenedViewActivities = 0;
+		tr.hide();
+	}
+
+	if (tr.visible())
+	{
+		new Effect.BlindUp(iframe, {duration: 0.2, afterFinish: closeView});
+	}
+	else
+	{
+		tr.show();
+		new Effect.BlindDown(iframe, {duration: 0.2, afterFinish: openView});
+	}
+}
+
+function getInstanceURL(instanceID, activityID, useHTTPS)
+{
+	if (workflowCommonExpressoIndexPath == null)
+	{
+		workflowCommonExpressoIndexPath = $A(document.getElementsByTagName("script")).findAll(
+			function(s)
+			{
+				return (s.src && s.src.match(/\/workflow\/js\/userinterface\/common_functions\.js(\?.*)?$/));
+			}).first().src;
+		/* pega só até o /workflow/ */
+		workflowCommonExpressoIndexPath = workflowCommonExpressoIndexPath.replace(/\/workflow\/js\/userinterface\/common_functions\.js(\?.*)?$/, '');
+
+		/* se não possuir o endereço completo, tenta montá-lo utilizando a informação da página atual (IE MAGIC) */
+		if (workflowCommonExpressoIndexPath.match(/^https?:\/\//) == null)
+			workflowCommonExpressoIndexPath = location.href.substr(0, location.href.indexOf('/', location.href.indexOf('//') + 2)) + workflowCommonExpressoIndexPath;
+	}
+	var output = instanceURL = workflowCommonExpressoIndexPath + '/index.php?menuaction=workflow.run_activity.go&iid=' + instanceID + '&activity_id=' + activityID;
+	if (useHTTPS == 1)
+		output = output.replace(/http:/, 'https:');
+	return output;
+}
Index: /sandbox/workflow/branches/993/js/userinterface/instances_group.js
===================================================================
--- /sandbox/workflow/branches/993/js/userinterface/instances_group.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/userinterface/instances_group.js	(revision 795)
@@ -0,0 +1,124 @@
+
+function group_instances()
+{
+	var instances = function(data)
+	{
+		if (_checkError(data))
+			return;
+
+		draw_instances_group(data.processes);
+	};
+
+	var params = "sort=" + workflowInstancesParams['sort'] + "&pid=0" + "&active=" + workflowInstancesParams['active'] + "&group_instances=1";
+	cExecute ("$this.bo_userinterface.instances", instances, params);
+}
+
+function draw_instances_group(data)
+{
+	$('content_id_2').innerHTML = '';
+
+	var content_id_2 = document.getElementById("content_id_2");
+	var table_element = document.createElement("TABLE");
+	var tbody_element = document.createElement("TBODY");
+	table_element.setAttribute("id", "table_tools_instances_group");
+	table_element.setAttribute("width", "auto");
+	tr_element = document.createElement("TR");
+	td_element1 = document.createElement("TD");
+	td_element1.setAttribute("id", "td_tools_instances_group_1");
+	td_element1.setAttribute("width", "270");
+	tr_element.appendChild(td_element1);
+	td_element2 = document.createElement("TD");
+	td_element2.setAttribute("id", "td_tools_instances_group_2");
+	td_element2.setAttribute("valign", "middle");
+	tr_element.appendChild(td_element2);			
+	td_element3 = document.createElement("TD");
+	td_element3.setAttribute("id", "td_tools_instances_group_3");			
+	tr_element.appendChild(td_element3);
+	tbody_element.appendChild(tr_element);
+	table_element.appendChild(tbody_element);
+	content_id_2.appendChild(table_element);	
+
+	construct_menu_instances_group(td_element1.id);
+	
+	//Construindo o cabeçalho da lista
+	var table_element = document.createElement("TABLE");
+	var tbody_element = document.createElement("TBODY");
+			
+	table_element.setAttribute("id", "table_elements_instances_group");
+	table_element.className = "table_elements";
+	table_element.setAttribute("cellPadding", "2");
+		
+	tbody_element.setAttribute("id", "tbody_elements_instances_group");
+			
+	tr_element = document.createElement("TR");
+	tr_element.className = "table_elements_tr_header";
+	
+	td_element1 = document.createElement("TD");
+	td_element1.setAttribute("width", "50%");
+	td_element1.align = "left";
+	td_element1.innerHTML = "Processo";
+		
+	td_element2 = document.createElement("TD");
+	td_element2.setAttribute("width", "50%");
+	td_element2.align = "left";
+	td_element2.innerHTML = "Quantidade";	
+
+	tr_element.appendChild(td_element1);
+	tr_element.appendChild(td_element2);
+	tbody_element.appendChild(tr_element);
+	table_element.appendChild(tbody_element);
+	content_id_2.appendChild(table_element);
+	
+	//inserindo elementos na lista
+	for (var i=0; i<(data.length); i++){
+		tr_element = construct_instances_group_list(data[i]);
+		tbody_element.appendChild(tr_element);
+	}	
+}
+
+function construct_menu_instances_group(id) {
+	var max_length = 0;
+	mmain_instances_group = new TMainMenu("mmain_instances_group",'horizontal');
+	_group = new TPopMenu("Desagrupar",_icon_dir + "/ungroup.png",'f',"javascript:ungroup_instances();","");
+	
+	mmain_instances_group.Add(_group);
+	ConfigMenuStyle_instances(mmain_instances_group);	
+	mmain_instances_group.Build(id);
+	document.getElementById(mmain_instances_group._id).style.visibility='visible';
+}
+
+function construct_instances_group_list(data){
+
+	var tr_element = document.createElement("TR");
+	tr_element.className = 'table_elements_tr_line';
+	tr_element.style.cursor = "pointer";
+	tr_element.onclick = function() { filter_activity_instances(data.pid); };
+
+	td_element1 = document.createElement("TD");
+	td_element1.setAttribute("width", "50%");
+	td_element1.align = "left";
+	td_element1.innerHTML = data.name;
+
+	td_element2 = document.createElement("TD");
+	td_element2.setAttribute("width", "50%");
+	td_element2.align = "left";
+	td_element2.innerHTML = data.total;
+
+	tr_element.appendChild(td_element1);
+	tr_element.appendChild(td_element2);	
+
+	return tr_element;
+}
+
+function ungroup_instances(){
+	killElement("table_tools_instances_group");
+	killElement("table_elements_instances_group");
+	pid = 0;
+	draw_instances_folder();
+}
+
+function filter_activity_instances(code) {
+	killElement("table_tools_instances_group");
+	killElement("table_elements_instances_group");
+	filterProcess(code);
+}
Index: /sandbox/workflow/branches/993/js/scriptaculous/prototype.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/prototype.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/prototype.js	(revision 795)
@@ -0,0 +1,2520 @@
+/*  Prototype JavaScript framework, version 1.5.0
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.5.0',
+  BrowserFeatures: {
+    XPath: !!document.evaluate
+  },
+
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+  emptyFunction: function() {},
+  K: function(x) { return x }
+};
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+};
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+  for (var property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+};
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (object === undefined) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : object.toString();
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({}, object);
+  }
+});
+
+Function.prototype.bind = function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+};
+
+Function.prototype.bindAsEventListener = function(object) {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function(event) {
+    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+  }
+};
+
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    var digits = this.toString(16);
+    if (this < 16) return '0' + digits;
+    return digits;
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  }
+});
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) {}
+    }
+
+    return returnValue;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.callback(this);
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+};
+String.interpret = function(value){
+  return value == null ? '' : String(value);
+};
+
+Object.extend(String.prototype, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(replacement);
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.prepareReplacement(replacement);
+    count = count === undefined ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  },
+
+  scan: function(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return this;
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = truncation === undefined ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : this;
+  },
+
+  strip: function() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  },
+
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var div = document.createElement('div');
+    var text = document.createTextNode(this);
+    div.appendChild(text);
+    return div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = document.createElement('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return {};
+
+    return match[1].split(separator || '&').inject({}, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var name = decodeURIComponent(pair[0]);
+        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+        if (hash[name] !== undefined) {
+          if (hash[name].constructor != Array)
+            hash[name] = [hash[name]];
+          if (value) hash[name].push(value);
+        }
+        else hash[name] = value;
+      }
+      return hash;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  camelize: function() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  },
+
+  capitalize: function(){
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.replace(/\\/g, '\\\\');
+    if (useDoubleQuotes)
+      return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    else
+      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (typeof replacement == 'function') return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+};
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern  = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    return this.template.gsub(this.pattern, function(match) {
+      var before = match[1];
+      if (before == '\\') return match[2];
+      return before + String.interpret(object[match[3]]);
+    });
+  }
+};
+
+var $break    = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+  each: function(iterator) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        try {
+          iterator(value, index++);
+        } catch (e) {
+          if (e != $continue) throw e;
+        }
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator) {
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.map(iterator);
+  },
+
+  all: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!(iterator || Prototype.K)(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator) {
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!(iterator || Prototype.K)(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(pattern, iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      var stringValue = value.toString();
+      if (stringValue.match(pattern))
+        results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  include: function(object) {
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator) {
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator) {
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      ((iterator || Prototype.K)(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator) {
+    return this.map(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (typeof args.last() == 'function')
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+};
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) {
+    return iterable.toArray();
+  } else {
+    var results = [];
+    for (var i = 0, length = iterable.length; i < length; i++)
+      results.push(iterable[i]);
+    return results;
+  }
+};
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+  Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(value && value.constructor == Array ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  indexOf: function(object) {
+    for (var i = 0, length = this.length; i < length; i++)
+      if (this[i] == object) return i;
+    return -1;
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function() {
+    return this.inject([], function(array, value) {
+      return array.include(value) ? array : array.concat([value]);
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+};
+
+if(window.opera){
+  Array.prototype.concat = function(){
+    var array = [];
+    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      if(arguments[i].constructor == Array) {
+        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  }
+};
+var Hash = function(obj) {
+  Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+  toQueryString: function(obj) {
+    var parts = [];
+
+	  this.prototype._each.call(obj, function(pair) {
+      if (!pair.key) return;
+
+      if (pair.value && pair.value.constructor == Array) {
+        var values = pair.value.compact();
+        if (values.length < 2) pair.value = values.reduce();
+        else {
+        	key = encodeURIComponent(pair.key);
+          values.each(function(value) {
+            value = value != undefined ? encodeURIComponent(value) : '';
+            parts.push(key + '=' + encodeURIComponent(value));
+          });
+          return;
+        }
+      }
+      if (pair.value == undefined) pair[1] = '';
+      parts.push(pair.join('='));
+	  });
+
+    return parts.join('&');
+  }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+  _each: function(iterator) {
+    for (var key in this) {
+      var value = this[key];
+      if (value && value == Hash.prototype[key]) continue;
+
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  merge: function(hash) {
+    return $H(hash).inject(this, function(mergedHash, pair) {
+      mergedHash[pair.key] = pair.value;
+      return mergedHash;
+    });
+  },
+
+  remove: function() {
+    var result;
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      var value = this[arguments[i]];
+      if (value !== undefined){
+        if (result === undefined) result = value;
+        else {
+          if (result.constructor != Array) result = [result];
+          result.push(value)
+        }
+      }
+      delete this[arguments[i]];
+    }
+    return result;
+  },
+
+  toQueryString: function() {
+    return Hash.toQueryString(this);
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  },
+
+  customInspect: function() {
+    return '{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}';
+  }
+});
+
+function $H(object) {
+  if (object && object.constructor == Hash) return object;
+  return new Hash(object);
+};
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+};
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+};
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (typeof responder[callback] == 'function') {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) {}
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate: function() {
+    Ajax.activeRequestCount++;
+  },
+  onComplete: function() {
+    Ajax.activeRequestCount--;
+  }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+  setOptions: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   ''
+    };
+    Object.extend(this.options, options || {});
+
+    this.options.method = this.options.method.toLowerCase();
+    if (typeof this.options.parameters == 'string')
+      this.options.parameters = this.options.parameters.toQueryParams();
+  }
+};
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  _complete: false,
+
+  initialize: function(url, options) {
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = this.options.parameters;
+
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    params = Hash.toQueryString(params);
+    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_=';
+
+    // when GET, append parameters to URL
+    if (this.method == 'get' && params)
+      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
+    try {
+      Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous)
+        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      var body = this.method == 'post' ? (this.options.postBody || params) : null;
+
+      this.transport.send(body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (typeof extras.push == 'function')
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    return !this.transport.status
+        || (this.transport.status >= 200 && this.transport.status < 300);
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState];
+    var transport = this.transport, json = this.evalJSON();
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + this.transport.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(transport, json);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      if ((this.getHeader('Content-type') || 'text/javascript').strip().
+        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+          this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + state, this, transport, json);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalJSON: function() {
+    try {
+      var json = this.getHeader('X-JSON');
+      return json ? eval('(' + json + ')') : null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+  initialize: function(container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    };
+
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+
+    var onComplete = this.options.onComplete || Prototype.emptyFunction;
+    this.options.onComplete = (function(transport, param) {
+      this.updateContent();
+      onComplete(transport, param);
+    }).bind(this);
+
+    this.request(url);
+  },
+
+  updateContent: function() {
+    var receiver = this.container[this.success() ? 'success' : 'failure'];
+    var response = this.transport.responseText;
+
+    if (!this.options.evalScripts) response = response.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (this.options.insertion)
+        new this.options.insertion(receiver, response);
+      else
+        receiver.update(response);
+    }
+
+    if (this.success()) {
+      if (this.onComplete)
+        setTimeout(this.onComplete.bind(this), 10);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(container, url, options) {
+    this.setOptions(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = {};
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(request) {
+    if (this.options.decay) {
+      this.decay = (request.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = request.responseText;
+    }
+    this.timer = setTimeout(this.onTimerEvent.bind(this),
+      this.decay * this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (typeof element == 'string')
+    element = document.getElementById(element);
+  return Element.extend(element);
+};
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(query.snapshotItem(i));
+    return results;
+  };
+};
+
+document.getElementsByClassName = function(className, parentElement) {
+  if (Prototype.BrowserFeatures.XPath) {
+    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+    return document._getElementsByXPath(q, parentElement);
+  } else {
+    var children = ($(parentElement) || document.body).getElementsByTagName('*');
+    var elements = [], child;
+    for (var i = 0, length = children.length; i < length; i++) {
+      child = children[i];
+      if (Element.hasClassName(child, className))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element)
+  var Element = new Object();
+
+Element.extend = function(element) {
+  if (!element || _nativeExtensions || element.nodeType == 3) return element;
+
+  if (!element._extended && element.tagName && element != window) {
+    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+    if (element.tagName == 'FORM')
+      Object.extend(methods, Form.Methods);
+    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+      Object.extend(methods, Form.Element.Methods);
+
+    Object.extend(methods, Element.Methods.Simulated);
+
+    for (var property in methods) {
+      var value = methods[property];
+      if (typeof value == 'function' && !(property in element))
+        element[property] = cache.findOrStore(value);
+    }
+  }
+
+  element._extended = true;
+  return element;
+};
+
+Element.extend.cache = {
+  findOrStore: function(value) {
+    return this[value] = this[value] || function() {
+      return value.apply(null, [this].concat($A(arguments)));
+    }
+  }
+};
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: function(element, html) {
+    html = typeof html == 'undefined' ? '' : html.toString();
+    $(element).innerHTML = html.stripScripts();
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  replace: function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    if (element.outerHTML) {
+      element.outerHTML = html.stripScripts();
+    } else {
+      var range = element.ownerDocument.createRange();
+      range.selectNodeContents(element);
+      element.parentNode.replaceChild(
+        range.createContextualFragment(html.stripScripts()), element);
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*'));
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (typeof selector == 'string')
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    return Selector.findElement($(element).ancestors(), expression, index);
+  },
+
+  down: function(element, expression, index) {
+    return Selector.findElement($(element).descendants(), expression, index);
+  },
+
+  previous: function(element, expression, index) {
+    return Selector.findElement($(element).previousSiblings(), expression, index);
+  },
+
+  next: function(element, expression, index) {
+    return Selector.findElement($(element).nextSiblings(), expression, index);
+  },
+
+  getElementsBySelector: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  getElementsByClassName: function(element, className) {
+    return document.getElementsByClassName(className, element);
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (document.all && !window.opera) {
+      var t = Element._attributeTranslations;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name])  name = t.names[name];
+      var attribute = element.attributes[name];
+      if(attribute) return attribute.nodeValue;
+    }
+    return element.getAttribute(name);
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    if (elementClassName.length == 0) return false;
+    if (elementClassName == className ||
+        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      return true;
+    return false;
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).add(className);
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).remove(className);
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+    return element;
+  },
+
+  observe: function() {
+    Event.observe.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  stopObserving: function() {
+    Event.stopObserving.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.match(/^\s*$/);
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Position.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    if (['float','cssFloat'].include(style))
+      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+    style = style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      if (document.defaultView && document.defaultView.getComputedStyle) {
+        var css = document.defaultView.getComputedStyle(element, null);
+        value = css ? css[style] : null;
+      } else if (element.currentStyle) {
+        value = element.currentStyle[style];
+      }
+    }
+
+    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+      value = element['offset'+style.capitalize()] + 'px';
+
+    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+    if(style == 'opacity') {
+      if(value) return parseFloat(value);
+      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if(value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+    return value == 'auto' ? null : value;
+  },
+
+  setStyle: function(element, style) {
+    element = $(element);
+    for (var name in style) {
+      var value = style[name];
+      if(name == 'opacity') {
+        if (value == 1) {
+          value = (/Gecko/.test(navigator.userAgent) &&
+            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else if(value == '') {
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else {
+          if(value < 0.00001) value = 0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+              'alpha(opacity='+value*100+')';
+        }
+      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+      element.style[name.camelize()] = value;
+    }
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      if (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = element.style.overflow || 'auto';
+    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+  colspan:   "colSpan",
+  rowspan:   "rowSpan",
+  valign:    "vAlign",
+  datetime:  "dateTime",
+  accesskey: "accessKey",
+  tabindex:  "tabIndex",
+  enctype:   "encType",
+  maxlength: "maxLength",
+  readonly:  "readOnly",
+  longdesc:  "longDesc"
+};
+
+Element._attributeTranslations.values = {
+  _getAttr: function(element, attribute) {
+    return element.getAttribute(attribute, 2);
+  },
+
+  _flag: function(element, attribute) {
+    return $(element).hasAttribute(attribute) ? attribute : null;
+  },
+
+  style: function(element) {
+    return element.style.cssText.toLowerCase();
+  },
+
+  title: function(element) {
+    var node = element.getAttributeNode('title');
+    return node.specified ? node.nodeValue : null;
+  }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+  href: Element._attributeTranslations.values._getAttr,
+  src:  Element._attributeTranslations.values._getAttr,
+  disabled: Element._attributeTranslations.values._flag,
+  checked:  Element._attributeTranslations.values._flag,
+  readonly: Element._attributeTranslations.values._flag,
+  multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = t.names[attribute] || attribute;
+    return $(element).getAttributeNode(attribute).specified;
+  }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+  Element.Methods.update = function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    var tagName = element.tagName.toUpperCase();
+    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+      var div = document.createElement('div');
+      switch (tagName) {
+        case 'THEAD':
+        case 'TBODY':
+          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
+          depth = 2;
+          break;
+        case 'TR':
+          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
+          depth = 3;
+          break;
+        case 'TD':
+          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
+          depth = 4;
+      }
+      $A(element.childNodes).each(function(node){
+        element.removeChild(node)
+      });
+      depth.times(function(){ div = div.firstChild });
+
+      $A(div.childNodes).each(
+        function(node){ element.appendChild(node) });
+    } else {
+      element.innerHTML = html.stripScripts();
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  }
+};
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+    var className = 'HTML' + tag + 'Element';
+    if(window[className]) return;
+    var klass = window[className] = {};
+    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+  });
+
+Element.addMethods = function(methods) {
+  Object.extend(Element.Methods, methods || {});
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    var cache = Element.extend.cache;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = cache.findOrStore(value);
+    }
+  }
+
+  if (typeof HTMLElement != 'undefined') {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Form.Methods, HTMLFormElement.prototype);
+    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+      copy(Form.Element.Methods, klass.prototype);
+    });
+    _nativeExtensions = true;
+  }
+};
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+  this.adjacency = adjacency;
+};
+
+Abstract.Insertion.prototype = {
+  initialize: function(element, content) {
+    this.element = $(element);
+    this.content = content.stripScripts();
+
+    if (this.adjacency && this.element.insertAdjacentHTML) {
+      try {
+        this.element.insertAdjacentHTML(this.adjacency, this.content);
+      } catch (e) {
+        var tagName = this.element.tagName.toUpperCase();
+        if (['TBODY', 'TR'].include(tagName)) {
+          this.insertContent(this.contentFromAnonymousTable());
+        } else {
+          throw e;
+        }
+      }
+    } else {
+      this.range = this.element.ownerDocument.createRange();
+      if (this.initializeRange) this.initializeRange();
+      this.insertContent([this.range.createContextualFragment(this.content)]);
+    }
+
+    setTimeout(function() {content.evalScripts()}, 10);
+  },
+
+  contentFromAnonymousTable: function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+    return $A(div.childNodes[0].childNodes[0].childNodes);
+  }
+};
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+  initializeRange: function() {
+    this.range.setStartBefore(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment, this.element);
+    }).bind(this));
+  }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(true);
+  },
+
+  insertContent: function(fragments) {
+    fragments.reverse(false).each((function(fragment) {
+      this.element.insertBefore(fragment, this.element.firstChild);
+    }).bind(this));
+  }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.appendChild(fragment);
+    }).bind(this));
+  }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+  initializeRange: function() {
+    this.range.setStartAfter(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment,
+        this.element.nextSibling);
+    }).bind(this));
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+  initialize: function(expression) {
+    this.params = {classNames: []};
+    this.expression = expression.toString().strip();
+    this.parseExpression();
+    this.compileMatcher();
+  },
+
+  parseExpression: function() {
+    function abort(message) { throw 'Parse error in selector: ' + message; }
+
+    if (this.expression == '')  abort('empty expression');
+
+    var params = this.params, expr = this.expression, match, modifier, clause, rest;
+    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+      params.attributes = params.attributes || [];
+      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+      expr = match[1];
+    }
+
+    if (expr == '*') return this.params.wildcard = true;
+
+    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+      modifier = match[1], clause = match[2], rest = match[3];
+      switch (modifier) {
+        case '#':       params.id = clause; break;
+        case '.':       params.classNames.push(clause); break;
+        case '':
+        case undefined: params.tagName = clause.toUpperCase(); break;
+        default:        abort(expr.inspect());
+      }
+      expr = rest;
+    }
+
+    if (expr.length > 0) abort(expr.inspect());
+  },
+
+  buildMatchExpression: function() {
+    var params = this.params, conditions = [], clause;
+
+    if (params.wildcard)
+      conditions.push('true');
+    if (clause = params.id)
+      conditions.push('element.readAttribute("id") == ' + clause.inspect());
+    if (clause = params.tagName)
+      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+    if ((clause = params.classNames).length > 0)
+      for (var i = 0, length = clause.length; i < length; i++)
+        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
+    if (clause = params.attributes) {
+      clause.each(function(attribute) {
+        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
+        var splitValueBy = function(delimiter) {
+          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+        };
+
+        switch (attribute.operator) {
+          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
+          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+          case '|=':      conditions.push(
+                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+                          ); break;
+          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
+          case '':
+          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
+          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
+        }
+      });
+    }
+
+    return conditions.join(' && ');
+  },
+
+  compileMatcher: function() {
+    this.match = new Function('element', 'if (!element.tagName) return false; element = $(element); return ' + this.buildMatchExpression());
+  },
+
+  findElements: function(scope) {
+    var element;
+
+    if (element = $(this.params.id))
+      if (this.match(element))
+        if (!scope || Element.childOf(element, scope))
+          return [element];
+
+    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+    var results = [];
+    for (var i = 0, length = scope.length; i < length; i++)
+      if (this.match(element = scope[i]))
+        results.push(Element.extend(element));
+
+    return results;
+  },
+
+  toString: function() {
+    return this.expression;
+  }
+};
+
+Object.extend(Selector, {
+  matchElements: function(elements, expression) {
+    var selector = new Selector(expression);
+    return elements.select(selector.match.bind(selector)).map(Element.extend);
+  },
+
+  findElement: function(elements, expression, index) {
+    if (typeof expression == 'number') index = expression, expression = false;
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    return expressions.map(function(expression) {
+      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+        var selector = new Selector(expr);
+        return results.inject([], function(elements, result) {
+          return elements.concat(selector.findElements(result || element));
+        });
+      });
+    }).flatten();
+  }
+});
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+};
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, getHash) {
+    var data = elements.inject({}, function(result, element) {
+      if (!element.disabled && element.name) {
+        var key = element.name, value = $(element).getValue();
+        if (value != undefined) {
+          value = escape(value);
+          if (result[key]) {
+            if (result[key].constructor != Array) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return getHash ? data : Hash.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, getHash) {
+    return Form.serializeElements(Form.getElements(form), getHash);
+  },
+
+  getElements: function(form) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.blur();
+      element.disabled = 'true';
+    });
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.disabled = '';
+    });
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    return $(form).getElements().find(function(element) {
+      return element.type != 'hidden' && !element.disabled &&
+        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  }
+};
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+};
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = {};
+        pair[element.name] = value;
+        return Hash.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+      !['button', 'reset', 'submit'].include(element.type) ) )
+      element.select();
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = false;
+    return element;
+  }
+};
+
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element);
+      default:
+        return Form.Element.Serializers.textarea(element);
+    }
+  },
+
+  inputSelector: function(element) {
+    return element.checked ? element.value : null;
+  },
+
+  textarea: function(element) {
+    return element.value;
+  },
+
+  select: function(element) {
+    return this[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {};
+Abstract.TimedObserver.prototype = {
+  initialize: function(element, frequency, callback) {
+    this.frequency = frequency;
+    this.element   = $(element);
+    this.callback  = callback;
+
+    this.lastValue = this.getValue();
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    var value = this.getValue();
+    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+      ? this.lastValue != value : String(this.lastValue) != String(value));
+    if (changed) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+};
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {};
+Abstract.EventObserver.prototype = {
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback.bind(this));
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+};
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) {
+  var Event = new Object();
+};
+
+Object.extend(Event, {
+  KEY_BACKSPACE: 8,
+  KEY_TAB:       9,
+  KEY_RETURN:   13,
+  KEY_ESC:      27,
+  KEY_LEFT:     37,
+  KEY_UP:       38,
+  KEY_RIGHT:    39,
+  KEY_DOWN:     40,
+  KEY_DELETE:   46,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
+
+  element: function(event) {
+    return event.target || event.srcElement;
+  },
+
+  isLeftClick: function(event) {
+    return (((event.which) && (event.which == 1)) ||
+            ((event.button) && (event.button == 1)));
+  },
+
+  pointerX: function(event) {
+    return event.pageX || (event.clientX +
+      (document.documentElement.scrollLeft || document.body.scrollLeft));
+  },
+
+  pointerY: function(event) {
+    return event.pageY || (event.clientY +
+      (document.documentElement.scrollTop || document.body.scrollTop));
+  },
+
+  stop: function(event) {
+    if (event.preventDefault) {
+      event.preventDefault();
+      event.stopPropagation();
+    } else {
+      event.returnValue = false;
+      event.cancelBubble = true;
+    }
+  },
+
+  // find the first node with the given tagName, starting from the
+  // node the event was triggered on; traverses the DOM upwards
+  findElement: function(event, tagName) {
+    var element = Event.element(event);
+    while (element.parentNode && (!element.tagName ||
+        (element.tagName.toUpperCase() != tagName.toUpperCase())))
+      element = element.parentNode;
+    return element;
+  },
+
+  observers: false,
+
+  _observeAndCache: function(element, name, observer, useCapture) {
+    if (!this.observers) this.observers = [];
+    if (element.addEventListener) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.addEventListener(name, observer, useCapture);
+    } else if (element.attachEvent) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.attachEvent('on' + name, observer);
+    }
+  },
+
+  unloadCache: function() {
+    if (!Event.observers) return;
+    for (var i = 0, length = Event.observers.length; i < length; i++) {
+      Event.stopObserving.apply(this, Event.observers[i]);
+      Event.observers[i][0] = null;
+    }
+    Event.observers = false;
+  },
+
+  observe: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.attachEvent))
+      name = 'keydown';
+
+    Event._observeAndCache(element, name, observer, useCapture);
+  },
+
+  stopObserving: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.detachEvent))
+      name = 'keydown';
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, observer, useCapture);
+    } else if (element.detachEvent) {
+      try {
+        element.detachEvent('on' + name, observer);
+      } catch (e) {}
+    }
+  }
+});
+
+/* prevent memory leaks in IE */
+if (navigator.appVersion.match(/\bMSIE\b/))
+  Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  realOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if(element.tagName=='BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  offsetParent: function(element) {
+    if (element.offsetParent) return element.offsetParent;
+    if (element == document.body) return element;
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return element;
+
+    return document.body;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = this.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = this.realOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = this.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  page: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent==document.body)
+        if (Element.getStyle(element,'position')=='absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!window.opera || element.tagName=='BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return [valueL, valueT];
+  },
+
+  clone: function(source, target) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || {});
+
+    // find page position of source
+    source = $(source);
+    var p = Position.page(source);
+
+    // find coordinate system to use
+    target = $(target);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(target,'position') == 'absolute') {
+      parent = Position.offsetParent(target);
+      delta = Position.page(parent);
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
+    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.style.position == 'absolute') return;
+    Position.prepare();
+
+    var offsets = Position.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.style.position == 'relative') return;
+    Position.prepare();
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+  }
+};
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+  Position.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return [valueL, valueT];
+  }
+};
+
+Element.addMethods();
Index: /sandbox/workflow/branches/993/js/scriptaculous/builder.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/builder.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/builder.js	(revision 795)
@@ -0,0 +1,131 @@
+// script.aculo.us builder.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Builder = {
+  NODEMAP: {
+    AREA: 'map',
+    CAPTION: 'table',
+    COL: 'table',
+    COLGROUP: 'table',
+    LEGEND: 'fieldset',
+    OPTGROUP: 'select',
+    OPTION: 'select',
+    PARAM: 'object',
+    TBODY: 'table',
+    TD: 'table',
+    TFOOT: 'table',
+    TH: 'table',
+    THEAD: 'table',
+    TR: 'table'
+  },
+  // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+  //       due to a Firefox bug
+  node: function(elementName) {
+    elementName = elementName.toUpperCase();
+    
+    // try innerHTML approach
+    var parentTag = this.NODEMAP[elementName] || 'div';
+    var parentElement = document.createElement(parentTag);
+    try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+      parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+    } catch(e) {}
+    var element = parentElement.firstChild || null;
+      
+    // see if browser added wrapping tags
+    if(element && (element.tagName != elementName))
+      element = element.getElementsByTagName(elementName)[0];
+    
+    // fallback to createElement approach
+    if(!element) element = document.createElement(elementName);
+    
+    // abort if nothing could be created
+    if(!element) return;
+
+    // attributes (or text)
+    if(arguments[1])
+      if(this._isStringOrNumber(arguments[1]) ||
+        (arguments[1] instanceof Array)) {
+          this._children(element, arguments[1]);
+        } else {
+          var attrs = this._attributes(arguments[1]);
+          if(attrs.length) {
+            try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+              parentElement.innerHTML = "<" +elementName + " " +
+                attrs + "></" + elementName + ">";
+            } catch(e) {}
+            element = parentElement.firstChild || null;
+            // workaround firefox 1.0.X bug
+            if(!element) {
+              element = document.createElement(elementName);
+              for(attr in arguments[1]) 
+                element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+            }
+            if(element.tagName != elementName)
+              element = parentElement.getElementsByTagName(elementName)[0];
+            }
+        } 
+
+    // text, or array of children
+    if(arguments[2])
+      this._children(element, arguments[2]);
+
+     return element;
+  },
+  _text: function(text) {
+     return document.createTextNode(text);
+  },
+
+  ATTR_MAP: {
+    'className': 'class',
+    'htmlFor': 'for'
+  },
+
+  _attributes: function(attributes) {
+    var attrs = [];
+    for(attribute in attributes)
+      attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
+          '="' + attributes[attribute].toString().escapeHTML() + '"');
+    return attrs.join(" ");
+  },
+  _children: function(element, children) {
+    if(typeof children=='object') { // array can hold nodes and text
+      children.flatten().each( function(e) {
+        if(typeof e=='object')
+          element.appendChild(e);
+        else
+          if(Builder._isStringOrNumber(e))
+            element.appendChild(Builder._text(e));
+      });
+    } else
+      if(Builder._isStringOrNumber(children)) 
+         element.appendChild(Builder._text(children));
+  },
+  _isStringOrNumber: function(param) {
+    return(typeof param=='string' || typeof param=='number');
+  },
+  build: function(html) {
+    var element = this.node('div');
+    $(element).update(html.strip());
+    return element.down();
+  },
+  dump: function(scope) { 
+    if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope 
+  
+    var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
+      "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
+      "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
+      "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
+      "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
+      "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
+  
+    tags.each( function(tag){ 
+      scope[tag] = function() { 
+        return Builder.node.apply(Builder, [tag].concat($A(arguments)));  
+      } 
+    });
+  }
+};
Index: /sandbox/workflow/branches/993/js/scriptaculous/effects.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/effects.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/effects.js	(revision 795)
@@ -0,0 +1,956 @@
+// script.aculo.us effects.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+//  Justin Palmer (http://encytemedia.com/)
+//  Mark Pilgrim (http://diveintomark.org/)
+//  Martin Bialasinki
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/ 
+
+// converts rgb() and #xxx to #xxxxxx format,  
+// returns self (or first argument) if not convertable  
+String.prototype.parseColor = function() {  
+  var color = '#';  
+  if(this.slice(0,4) == 'rgb(') {  
+    var cols = this.slice(4,this.length-1).split(',');  
+    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
+  } else {  
+    if(this.slice(0,1) == '#') {  
+      if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
+      if(this.length==7) color = this.toLowerCase();  
+    }  
+  }  
+  return(color.length==7 ? color : (arguments[0] || this));  
+};
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {  
+  return $A($(element).childNodes).collect( function(node) {
+    return (node.nodeType==3 ? node.nodeValue : 
+      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+  }).flatten().join('');
+};
+
+Element.collectTextNodesIgnoreClass = function(element, className) {  
+  return $A($(element).childNodes).collect( function(node) {
+    return (node.nodeType==3 ? node.nodeValue : 
+      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
+        Element.collectTextNodesIgnoreClass(node, className) : ''));
+  }).flatten().join('');
+};
+
+Element.setContentZoom = function(element, percent) {
+  element = $(element);  
+  element.setStyle({fontSize: (percent/100) + 'em'});   
+  if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+  return element;
+};
+
+Element.getOpacity = function(element){
+  element = $(element);
+  var opacity;
+  if (opacity = element.getStyle('opacity'))  
+    return parseFloat(opacity);  
+  if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))  
+    if(opacity[1]) return parseFloat(opacity[1]) / 100;  
+  return 1.0;  
+};
+
+Element.setOpacity = function(element, value){  
+  element= $(element);  
+  if (value == 1){
+    element.setStyle({ opacity: 
+      (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 
+      0.999999 : 1.0 });
+    if(/MSIE/.test(navigator.userAgent) && !window.opera)  
+      element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
+  } else {  
+    if(value < 0.00001) value = 0;  
+    element.setStyle({opacity: value});
+    if(/MSIE/.test(navigator.userAgent) && !window.opera)  
+      element.setStyle(
+        { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+            'alpha(opacity='+value*100+')' });  
+  }
+  return element;
+};
+ 
+Element.getInlineOpacity = function(element){  
+  return $(element).style.opacity || '';
+};
+
+Element.forceRerendering = function(element) {
+  try {
+    element = $(element);
+    var n = document.createTextNode(' ');
+    element.appendChild(n);
+    element.removeChild(n);
+  } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Array.prototype.call = function() {
+  var args = arguments;
+  this.each(function(f){ f.apply(this, args) });
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+  _elementDoesNotExistError: {
+    name: 'ElementDoesNotExistError',
+    message: 'The specified DOM element does not exist, but is required for this effect to operate'
+  },
+  tagifyText: function(element) {
+    if(typeof Builder == 'undefined')
+      throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+      
+    var tagifyStyle = 'position:relative';
+    if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
+    
+    element = $(element);
+    $A(element.childNodes).each( function(child) {
+      if(child.nodeType==3) {
+        child.nodeValue.toArray().each( function(character) {
+          element.insertBefore(
+            Builder.node('span',{style: tagifyStyle},
+              character == ' ' ? String.fromCharCode(160) : character), 
+              child);
+        });
+        Element.remove(child);
+      }
+    });
+  },
+  multiple: function(element, effect) {
+    var elements;
+    if(((typeof element == 'object') || 
+        (typeof element == 'function')) && 
+       (element.length))
+      elements = element;
+    else
+      elements = $(element).childNodes;
+      
+    var options = Object.extend({
+      speed: 0.1,
+      delay: 0.0
+    }, arguments[2] || {});
+    var masterDelay = options.delay;
+
+    $A(elements).each( function(element, index) {
+      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+    });
+  },
+  PAIRS: {
+    'slide':  ['SlideDown','SlideUp'],
+    'blind':  ['BlindDown','BlindUp'],
+    'appear': ['Appear','Fade']
+  },
+  toggle: function(element, effect) {
+    element = $(element);
+    effect = (effect || 'appear').toLowerCase();
+    var options = Object.extend({
+      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+    }, arguments[2] || {});
+    Effect[element.visible() ? 
+      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+  }
+};
+
+var Effect2 = Effect; // deprecated
+
+/* ------------- transitions ------------- */
+
+Effect.Transitions = {
+  linear: Prototype.K,
+  sinoidal: function(pos) {
+    return (-Math.cos(pos*Math.PI)/2) + 0.5;
+  },
+  reverse: function(pos) {
+    return 1-pos;
+  },
+  flicker: function(pos) {
+    return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+  },
+  wobble: function(pos) {
+    return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+  },
+  pulse: function(pos, pulses) { 
+    pulses = pulses || 5; 
+    return (
+      Math.round((pos % (1/pulses)) * pulses) == 0 ? 
+            ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 
+        1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
+      );
+  },
+  none: function(pos) {
+    return 0;
+  },
+  full: function(pos) {
+    return 1;
+  }
+};
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create();
+Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+  initialize: function() {
+    this.effects  = [];
+    this.interval = null;
+  },
+  _each: function(iterator) {
+    this.effects._each(iterator);
+  },
+  add: function(effect) {
+    var timestamp = new Date().getTime();
+    
+    var position = (typeof effect.options.queue == 'string') ? 
+      effect.options.queue : effect.options.queue.position;
+    
+    switch(position) {
+      case 'front':
+        // move unstarted effects after this effect  
+        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+            e.startOn  += effect.finishOn;
+            e.finishOn += effect.finishOn;
+          });
+        break;
+      case 'with-last':
+        timestamp = this.effects.pluck('startOn').max() || timestamp;
+        break;
+      case 'end':
+        // start effect after last queued effect has finished
+        timestamp = this.effects.pluck('finishOn').max() || timestamp;
+        break;
+    }
+    
+    effect.startOn  += timestamp;
+    effect.finishOn += timestamp;
+
+    if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+      this.effects.push(effect);
+    
+    if(!this.interval) 
+      this.interval = setInterval(this.loop.bind(this), 40);
+  },
+  remove: function(effect) {
+    this.effects = this.effects.reject(function(e) { return e==effect });
+    if(this.effects.length == 0) {
+      clearInterval(this.interval);
+      this.interval = null;
+    }
+  },
+  loop: function() {
+    var timePos = new Date().getTime();
+    this.effects.invoke('loop', timePos);
+  }
+});
+
+Effect.Queues = {
+  instances: $H(),
+  get: function(queueName) {
+    if(typeof queueName != 'string') return queueName;
+    
+    if(!this.instances[queueName])
+      this.instances[queueName] = new Effect.ScopedQueue();
+      
+    return this.instances[queueName];
+  }
+};
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.DefaultOptions = {
+  transition: Effect.Transitions.sinoidal,
+  duration:   1.0,   // seconds
+  fps:        25.0,  // max. 25fps due to Effect.Queue implementation
+  sync:       false, // true for combining
+  from:       0.0,
+  to:         1.0,
+  delay:      0.0,
+  queue:      'parallel'
+};
+
+Effect.Base = function() {};
+Effect.Base.prototype = {
+  position: null,
+  start: function(options) {
+    this.options      = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
+    this.currentFrame = 0;
+    this.state        = 'idle';
+    this.startOn      = this.options.delay*1000;
+    this.finishOn     = this.startOn + (this.options.duration*1000);
+    this.event('beforeStart');
+    if(!this.options.sync)
+      Effect.Queues.get(typeof this.options.queue == 'string' ? 
+        'global' : this.options.queue.scope).add(this);
+  },
+  loop: function(timePos) {
+    if(timePos >= this.startOn) {
+      if(timePos >= this.finishOn) {
+        this.render(1.0);
+        this.cancel();
+        this.event('beforeFinish');
+        if(this.finish) this.finish(); 
+        this.event('afterFinish');
+        return;  
+      }
+      var pos   = (timePos - this.startOn) / (this.finishOn - this.startOn);
+      var frame = Math.round(pos * this.options.fps * this.options.duration);
+      if(frame > this.currentFrame) {
+        this.render(pos);
+        this.currentFrame = frame;
+      }
+    }
+  },
+  render: function(pos) {
+    if(this.state == 'idle') {
+      this.state = 'running';
+      this.event('beforeSetup');
+      if(this.setup) this.setup();
+      this.event('afterSetup');
+    }
+    if(this.state == 'running') {
+      if(this.options.transition) pos = this.options.transition(pos);
+      pos *= (this.options.to-this.options.from);
+      pos += this.options.from;
+      this.position = pos;
+      this.event('beforeUpdate');
+      if(this.update) this.update(pos);
+      this.event('afterUpdate');
+    }
+  },
+  cancel: function() {
+    if(!this.options.sync)
+      Effect.Queues.get(typeof this.options.queue == 'string' ? 
+        'global' : this.options.queue.scope).remove(this);
+    this.state = 'finished';
+  },
+  event: function(eventName) {
+    if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+    if(this.options[eventName]) this.options[eventName](this);
+  },
+  inspect: function() {
+    return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
+  }
+};
+
+Effect.Parallel = Class.create();
+Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
+  initialize: function(effects) {
+    this.effects = effects || [];
+    this.start(arguments[1]);
+  },
+  update: function(position) {
+    this.effects.invoke('render', position);
+  },
+  finish: function(position) {
+    this.effects.each( function(effect) {
+      effect.render(1.0);
+      effect.cancel();
+      effect.event('beforeFinish');
+      if(effect.finish) effect.finish(position);
+      effect.event('afterFinish');
+    });
+  }
+});
+
+Effect.Event = Class.create();
+Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+  initialize: function() {
+    var options = Object.extend({
+      duration: 0
+    }, arguments[0] || {});
+    this.start(options);
+  },
+  update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create();
+Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    // make this work on IE on elements without 'layout'
+    if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+      this.element.setStyle({zoom: 1});
+    var options = Object.extend({
+      from: this.element.getOpacity() || 0.0,
+      to:   1.0
+    }, arguments[1] || {});
+    this.start(options);
+  },
+  update: function(position) {
+    this.element.setOpacity(position);
+  }
+});
+
+Effect.Move = Class.create();
+Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      x:    0,
+      y:    0,
+      mode: 'relative'
+    }, arguments[1] || {});
+    this.start(options);
+  },
+  setup: function() {
+    // Bug in Opera: Opera returns the "real" position of a static element or
+    // relative element that does not have top/left explicitly set.
+    // ==> Always set top and left for position relative elements in your stylesheets 
+    // (to 0 if you do not need them) 
+    this.element.makePositioned();
+    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
+    if(this.options.mode == 'absolute') {
+      // absolute movement, so we need to calc deltaX and deltaY
+      this.options.x = this.options.x - this.originalLeft;
+      this.options.y = this.options.y - this.originalTop;
+    }
+  },
+  update: function(position) {
+    this.element.setStyle({
+      left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
+      top:  Math.round(this.options.y  * position + this.originalTop)  + 'px'
+    });
+  }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+  return new Effect.Move(element, 
+    Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
+};
+
+Effect.Scale = Class.create();
+Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
+  initialize: function(element, percent) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      scaleX: true,
+      scaleY: true,
+      scaleContent: true,
+      scaleFromCenter: false,
+      scaleMode: 'box',        // 'box' or 'contents' or {} with provided values
+      scaleFrom: 100.0,
+      scaleTo:   percent
+    }, arguments[2] || {});
+    this.start(options);
+  },
+  setup: function() {
+    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+    this.elementPositioning = this.element.getStyle('position');
+    
+    this.originalStyle = {};
+    ['top','left','width','height','fontSize'].each( function(k) {
+      this.originalStyle[k] = this.element.style[k];
+    }.bind(this));
+      
+    this.originalTop  = this.element.offsetTop;
+    this.originalLeft = this.element.offsetLeft;
+    
+    var fontSize = this.element.getStyle('font-size') || '100%';
+    ['em','px','%','pt'].each( function(fontSizeType) {
+      if(fontSize.indexOf(fontSizeType)>0) {
+        this.fontSize     = parseFloat(fontSize);
+        this.fontSizeType = fontSizeType;
+      }
+    }.bind(this));
+    
+    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+    
+    this.dims = null;
+    if(this.options.scaleMode=='box')
+      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+    if(/^content/.test(this.options.scaleMode))
+      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+    if(!this.dims)
+      this.dims = [this.options.scaleMode.originalHeight,
+                   this.options.scaleMode.originalWidth];
+  },
+  update: function(position) {
+    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+    if(this.options.scaleContent && this.fontSize)
+      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+  },
+  finish: function(position) {
+    if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+  },
+  setDimensions: function(height, width) {
+    var d = {};
+    if(this.options.scaleX) d.width = Math.round(width) + 'px';
+    if(this.options.scaleY) d.height = Math.round(height) + 'px';
+    if(this.options.scaleFromCenter) {
+      var topd  = (height - this.dims[0])/2;
+      var leftd = (width  - this.dims[1])/2;
+      if(this.elementPositioning == 'absolute') {
+        if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
+        if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+      } else {
+        if(this.options.scaleY) d.top = -topd + 'px';
+        if(this.options.scaleX) d.left = -leftd + 'px';
+      }
+    }
+    this.element.setStyle(d);
+  }
+});
+
+Effect.Highlight = Class.create();
+Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
+    this.start(options);
+  },
+  setup: function() {
+    // Prevent executing on elements not in the layout flow
+    if(this.element.getStyle('display')=='none') { this.cancel(); return; }
+    // Disable background image during the effect
+    this.oldStyle = {
+      backgroundImage: this.element.getStyle('background-image') };
+    this.element.setStyle({backgroundImage: 'none'});
+    if(!this.options.endcolor)
+      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+    if(!this.options.restorecolor)
+      this.options.restorecolor = this.element.getStyle('background-color');
+    // init color calculations
+    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+  },
+  update: function(position) {
+    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+      return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
+  },
+  finish: function() {
+    this.element.setStyle(Object.extend(this.oldStyle, {
+      backgroundColor: this.options.restorecolor
+    }));
+  }
+});
+
+Effect.ScrollTo = Class.create();
+Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    this.start(arguments[1] || {});
+  },
+  setup: function() {
+    Position.prepare();
+    var offsets = Position.cumulativeOffset(this.element);
+    if(this.options.offset) offsets[1] += this.options.offset;
+    var max = window.innerHeight ? 
+      window.height - window.innerHeight :
+      document.body.scrollHeight - 
+        (document.documentElement.clientHeight ? 
+          document.documentElement.clientHeight : document.body.clientHeight);
+    this.scrollStart = Position.deltaY;
+    this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
+  },
+  update: function(position) {
+    Position.prepare();
+    window.scrollTo(Position.deltaX, 
+      this.scrollStart + (position*this.delta));
+  }
+});
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+  element = $(element);
+  var oldOpacity = element.getInlineOpacity();
+  var options = Object.extend({
+  from: element.getOpacity() || 1.0,
+  to:   0.0,
+  afterFinishInternal: function(effect) { 
+    if(effect.options.to!=0) return;
+    effect.element.hide().setStyle({opacity: oldOpacity}); 
+  }}, arguments[1] || {});
+  return new Effect.Opacity(element,options);
+};
+
+Effect.Appear = function(element) {
+  element = $(element);
+  var options = Object.extend({
+  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+  to:   1.0,
+  // force Safari to render floated elements properly
+  afterFinishInternal: function(effect) {
+    effect.element.forceRerendering();
+  },
+  beforeSetup: function(effect) {
+    effect.element.setOpacity(effect.options.from).show(); 
+  }}, arguments[1] || {});
+  return new Effect.Opacity(element,options);
+};
+
+Effect.Puff = function(element) {
+  element = $(element);
+  var oldStyle = { 
+    opacity: element.getInlineOpacity(), 
+    position: element.getStyle('position'),
+    top:  element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height
+  };
+  return new Effect.Parallel(
+   [ new Effect.Scale(element, 200, 
+      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
+     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
+     Object.extend({ duration: 1.0, 
+      beforeSetupInternal: function(effect) {
+        Position.absolutize(effect.effects[0].element)
+      },
+      afterFinishInternal: function(effect) {
+         effect.effects[0].element.hide().setStyle(oldStyle); }
+     }, arguments[1] || {})
+   );
+};
+
+Effect.BlindUp = function(element) {
+  element = $(element);
+  element.makeClipping();
+  return new Effect.Scale(element, 0,
+    Object.extend({ scaleContent: false, 
+      scaleX: false, 
+      restoreAfterFinish: true,
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping();
+      } 
+    }, arguments[1] || {})
+  );
+};
+
+Effect.BlindDown = function(element) {
+  element = $(element);
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false,
+    scaleFrom: 0,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping();
+    }
+  }, arguments[1] || {}));
+};
+
+Effect.SwitchOff = function(element) {
+  element = $(element);
+  var oldOpacity = element.getInlineOpacity();
+  return new Effect.Appear(element, Object.extend({
+    duration: 0.4,
+    from: 0,
+    transition: Effect.Transitions.flicker,
+    afterFinishInternal: function(effect) {
+      new Effect.Scale(effect.element, 1, { 
+        duration: 0.3, scaleFromCenter: true,
+        scaleX: false, scaleContent: false, restoreAfterFinish: true,
+        beforeSetup: function(effect) { 
+          effect.element.makePositioned().makeClipping();
+        },
+        afterFinishInternal: function(effect) {
+          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+        }
+      })
+    }
+  }, arguments[1] || {}));
+};
+
+Effect.DropOut = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.getStyle('top'),
+    left: element.getStyle('left'),
+    opacity: element.getInlineOpacity() };
+  return new Effect.Parallel(
+    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
+      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+    Object.extend(
+      { duration: 0.5,
+        beforeSetup: function(effect) {
+          effect.effects[0].element.makePositioned(); 
+        },
+        afterFinishInternal: function(effect) {
+          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+        } 
+      }, arguments[1] || {}));
+};
+
+Effect.Shake = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.getStyle('top'),
+    left: element.getStyle('left') };
+    return new Effect.Move(element, 
+      { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+        effect.element.undoPositioned().setStyle(oldStyle);
+  }}) }}) }}) }}) }}) }});
+};
+
+Effect.SlideDown = function(element) {
+  element = $(element).cleanWhitespace();
+  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+  var oldInnerBottom = element.down().getStyle('bottom');
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false, 
+    scaleFrom: window.opera ? 0 : 1,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makePositioned();
+      effect.element.down().makePositioned();
+      if(window.opera) effect.element.setStyle({top: ''});
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },
+    afterUpdateInternal: function(effect) {
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
+    },
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping().undoPositioned();
+      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+    }, arguments[1] || {})
+  );
+};
+
+Effect.SlideUp = function(element) {
+  element = $(element).cleanWhitespace();
+  var oldInnerBottom = element.down().getStyle('bottom');
+  return new Effect.Scale(element, window.opera ? 0 : 1,
+   Object.extend({ scaleContent: false, 
+    scaleX: false, 
+    scaleMode: 'box',
+    scaleFrom: 100,
+    restoreAfterFinish: true,
+    beforeStartInternal: function(effect) {
+      effect.element.makePositioned();
+      effect.element.down().makePositioned();
+      if(window.opera) effect.element.setStyle({top: ''});
+      effect.element.makeClipping().show();
+    },  
+    afterUpdateInternal: function(effect) {
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' });
+    },
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
+      effect.element.down().undoPositioned();
+    }
+   }, arguments[1] || {})
+  );
+};
+
+// Bug in opera makes the TD containing this element expand for a instance after finish 
+Effect.Squish = function(element) {
+  return new Effect.Scale(element, window.opera ? 1 : 0, { 
+    restoreAfterFinish: true,
+    beforeSetup: function(effect) {
+      effect.element.makeClipping(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping(); 
+    }
+  });
+};
+
+Effect.Grow = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    direction: 'center',
+    moveTransition: Effect.Transitions.sinoidal,
+    scaleTransition: Effect.Transitions.sinoidal,
+    opacityTransition: Effect.Transitions.full
+  }, arguments[1] || {});
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    height: element.style.height,
+    width: element.style.width,
+    opacity: element.getInlineOpacity() };
+
+  var dims = element.getDimensions();    
+  var initialMoveX, initialMoveY;
+  var moveX, moveY;
+  
+  switch (options.direction) {
+    case 'top-left':
+      initialMoveX = initialMoveY = moveX = moveY = 0; 
+      break;
+    case 'top-right':
+      initialMoveX = dims.width;
+      initialMoveY = moveY = 0;
+      moveX = -dims.width;
+      break;
+    case 'bottom-left':
+      initialMoveX = moveX = 0;
+      initialMoveY = dims.height;
+      moveY = -dims.height;
+      break;
+    case 'bottom-right':
+      initialMoveX = dims.width;
+      initialMoveY = dims.height;
+      moveX = -dims.width;
+      moveY = -dims.height;
+      break;
+    case 'center':
+      initialMoveX = dims.width / 2;
+      initialMoveY = dims.height / 2;
+      moveX = -dims.width / 2;
+      moveY = -dims.height / 2;
+      break;
+  }
+  
+  return new Effect.Move(element, {
+    x: initialMoveX,
+    y: initialMoveY,
+    duration: 0.01, 
+    beforeSetup: function(effect) {
+      effect.element.hide().makeClipping().makePositioned();
+    },
+    afterFinishInternal: function(effect) {
+      new Effect.Parallel(
+        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+          new Effect.Scale(effect.element, 100, {
+            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
+            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+        ], Object.extend({
+             beforeSetup: function(effect) {
+               effect.effects[0].element.setStyle({height: '0px'}).show(); 
+             },
+             afterFinishInternal: function(effect) {
+               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
+             }
+           }, options)
+      )
+    }
+  });
+};
+
+Effect.Shrink = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    direction: 'center',
+    moveTransition: Effect.Transitions.sinoidal,
+    scaleTransition: Effect.Transitions.sinoidal,
+    opacityTransition: Effect.Transitions.none
+  }, arguments[1] || {});
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    height: element.style.height,
+    width: element.style.width,
+    opacity: element.getInlineOpacity() };
+
+  var dims = element.getDimensions();
+  var moveX, moveY;
+  
+  switch (options.direction) {
+    case 'top-left':
+      moveX = moveY = 0;
+      break;
+    case 'top-right':
+      moveX = dims.width;
+      moveY = 0;
+      break;
+    case 'bottom-left':
+      moveX = 0;
+      moveY = dims.height;
+      break;
+    case 'bottom-right':
+      moveX = dims.width;
+      moveY = dims.height;
+      break;
+    case 'center':  
+      moveX = dims.width / 2;
+      moveY = dims.height / 2;
+      break;
+  }
+  
+  return new Effect.Parallel(
+    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+    ], Object.extend({            
+         beforeStartInternal: function(effect) {
+           effect.effects[0].element.makePositioned().makeClipping(); 
+         },
+         afterFinishInternal: function(effect) {
+           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+       }, options)
+  );
+};
+
+Effect.Pulsate = function(element) {
+  element = $(element);
+  var options    = arguments[1] || {};
+  var oldOpacity = element.getInlineOpacity();
+  var transition = options.transition || Effect.Transitions.sinoidal;
+  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
+  reverser.bind(transition);
+  return new Effect.Opacity(element, 
+    Object.extend(Object.extend({  duration: 2.0, from: 0,
+      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+    }, options), {transition: reverser}));
+};
+
+Effect.Fold = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height };
+  element.makeClipping();
+  return new Effect.Scale(element, 5, Object.extend({   
+    scaleContent: false,
+    scaleX: false,
+    afterFinishInternal: function(effect) {
+    new Effect.Scale(element, 1, { 
+      scaleContent: false, 
+      scaleY: false,
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping().setStyle(oldStyle);
+      } });
+  }}, arguments[1] || {}));
+};
+
+['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
+ 'collectTextNodes','collectTextNodesIgnoreClass'].each( 
+  function(f) { Element.Methods[f] = Element[f]; }
+);
+
+Element.Methods.visualEffect = function(element, effect, options) {
+  s = effect.gsub(/_/, '-').camelize();
+  effect_class = s.charAt(0).toUpperCase() + s.substring(1);
+  new Effect[effect_class](element, options);
+  return $(element);
+};
+
+Element.addMethods();
Index: /sandbox/workflow/branches/993/js/scriptaculous/unittest.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/unittest.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/unittest.js	(revision 795)
@@ -0,0 +1,557 @@
+// script.aculo.us unittest.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
+//           (c) 2005, 2006 Michael Schuerig (http://www.schuerig.de/michael/)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// experimental, Firefox-only
+Event.simulateMouse = function(element, eventName) {
+  var options = Object.extend({
+    pointerX: 0,
+    pointerY: 0,
+    buttons:  0,
+    ctrlKey:  false,
+    altKey:   false,
+    shiftKey: false,
+    metaKey:  false
+  }, arguments[2] || {});
+  var oEvent = document.createEvent("MouseEvents");
+  oEvent.initMouseEvent(eventName, true, true, document.defaultView, 
+    options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, 
+    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
+  
+  if(this.mark) Element.remove(this.mark);
+  this.mark = document.createElement('div');
+  this.mark.appendChild(document.createTextNode(" "));
+  document.body.appendChild(this.mark);
+  this.mark.style.position = 'absolute';
+  this.mark.style.top = options.pointerY + "px";
+  this.mark.style.left = options.pointerX + "px";
+  this.mark.style.width = "5px";
+  this.mark.style.height = "5px;";
+  this.mark.style.borderTop = "1px solid red;";
+  this.mark.style.borderLeft = "1px solid red;";
+  
+  if(this.step)
+    alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
+  
+  $(element).dispatchEvent(oEvent);
+};
+
+// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
+// You need to downgrade to 1.0.4 for now to get this working
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
+Event.simulateKey = function(element, eventName) {
+  var options = Object.extend({
+    ctrlKey: false,
+    altKey: false,
+    shiftKey: false,
+    metaKey: false,
+    keyCode: 0,
+    charCode: 0
+  }, arguments[2] || {});
+
+  var oEvent = document.createEvent("KeyEvents");
+  oEvent.initKeyEvent(eventName, true, true, window, 
+    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
+    options.keyCode, options.charCode );
+  $(element).dispatchEvent(oEvent);
+};
+
+Event.simulateKeys = function(element, command) {
+  for(var i=0; i<command.length; i++) {
+    Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
+  }
+};
+
+var Test = {};
+Test.Unit = {};
+
+// security exception workaround
+Test.Unit.inspect = Object.inspect;
+
+Test.Unit.Logger = Class.create();
+Test.Unit.Logger.prototype = {
+  initialize: function(log) {
+    this.log = $(log);
+    if (this.log) {
+      this._createLogTable();
+    }
+  },
+  start: function(testName) {
+    if (!this.log) return;
+    this.testName = testName;
+    this.lastLogLine = document.createElement('tr');
+    this.statusCell = document.createElement('td');
+    this.nameCell = document.createElement('td');
+    this.nameCell.className = "nameCell";
+    this.nameCell.appendChild(document.createTextNode(testName));
+    this.messageCell = document.createElement('td');
+    this.lastLogLine.appendChild(this.statusCell);
+    this.lastLogLine.appendChild(this.nameCell);
+    this.lastLogLine.appendChild(this.messageCell);
+    this.loglines.appendChild(this.lastLogLine);
+  },
+  finish: function(status, summary) {
+    if (!this.log) return;
+    this.lastLogLine.className = status;
+    this.statusCell.innerHTML = status;
+    this.messageCell.innerHTML = this._toHTML(summary);
+    this.addLinksToResults();
+  },
+  message: function(message) {
+    if (!this.log) return;
+    this.messageCell.innerHTML = this._toHTML(message);
+  },
+  summary: function(summary) {
+    if (!this.log) return;
+    this.logsummary.innerHTML = this._toHTML(summary);
+  },
+  _createLogTable: function() {
+    this.log.innerHTML =
+    '<div id="logsummary"></div>' +
+    '<table id="logtable">' +
+    '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
+    '<tbody id="loglines"></tbody>' +
+    '</table>';
+    this.logsummary = $('logsummary');
+    this.loglines = $('loglines');
+  },
+  _toHTML: function(txt) {
+    return txt.escapeHTML().replace(/\n/g,"<br/>");
+  },
+  addLinksToResults: function(){ 
+    $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
+      td.title = "Run only this test";
+      Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
+    });
+    $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
+      td.title = "Run all tests";
+      Event.observe(td, 'click', function(){ window.location.search = "";});
+    });
+  }
+};
+
+Test.Unit.Runner = Class.create();
+Test.Unit.Runner.prototype = {
+  initialize: function(testcases) {
+    this.options = Object.extend({
+      testLog: 'testlog'
+    }, arguments[1] || {});
+    this.options.resultsURL = this.parseResultsURLQueryParameter();
+    this.options.tests      = this.parseTestsQueryParameter();
+    if (this.options.testLog) {
+      this.options.testLog = $(this.options.testLog) || null;
+    }
+    if(this.options.tests) {
+      this.tests = [];
+      for(var i = 0; i < this.options.tests.length; i++) {
+        if(/^test/.test(this.options.tests[i])) {
+          this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
+        }
+      }
+    } else {
+      if (this.options.test) {
+        this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
+      } else {
+        this.tests = [];
+        for(var testcase in testcases) {
+          if(/^test/.test(testcase)) {
+            this.tests.push(
+               new Test.Unit.Testcase(
+                 this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, 
+                 testcases[testcase], testcases["setup"], testcases["teardown"]
+               ));
+          }
+        }
+      }
+    }
+    this.currentTest = 0;
+    this.logger = new Test.Unit.Logger(this.options.testLog);
+    setTimeout(this.runTests.bind(this), 1000);
+  },
+  parseResultsURLQueryParameter: function() {
+    return window.location.search.parseQuery()["resultsURL"];
+  },
+  parseTestsQueryParameter: function(){
+    if (window.location.search.parseQuery()["tests"]){
+        return window.location.search.parseQuery()["tests"].split(',');
+    };
+  },
+  // Returns:
+  //  "ERROR" if there was an error,
+  //  "FAILURE" if there was a failure, or
+  //  "SUCCESS" if there was neither
+  getResult: function() {
+    var hasFailure = false;
+    for(var i=0;i<this.tests.length;i++) {
+      if (this.tests[i].errors > 0) {
+        return "ERROR";
+      }
+      if (this.tests[i].failures > 0) {
+        hasFailure = true;
+      }
+    }
+    if (hasFailure) {
+      return "FAILURE";
+    } else {
+      return "SUCCESS";
+    }
+  },
+  postResults: function() {
+    if (this.options.resultsURL) {
+      new Ajax.Request(this.options.resultsURL, 
+        { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
+    }
+  },
+  runTests: function() {
+    var test = this.tests[this.currentTest];
+    if (!test) {
+      // finished!
+      this.postResults();
+      this.logger.summary(this.summary());
+      return;
+    }
+    if(!test.isWaiting) {
+      this.logger.start(test.name);
+    }
+    test.run();
+    if(test.isWaiting) {
+      this.logger.message("Waiting for " + test.timeToWait + "ms");
+      setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
+    } else {
+      this.logger.finish(test.status(), test.summary());
+      this.currentTest++;
+      // tail recursive, hopefully the browser will skip the stackframe
+      this.runTests();
+    }
+  },
+  summary: function() {
+    var assertions = 0;
+    var failures = 0;
+    var errors = 0;
+    var messages = [];
+    for(var i=0;i<this.tests.length;i++) {
+      assertions +=   this.tests[i].assertions;
+      failures   +=   this.tests[i].failures;
+      errors     +=   this.tests[i].errors;
+    }
+    return (
+      (this.options.context ? this.options.context + ': ': '') + 
+      this.tests.length + " tests, " + 
+      assertions + " assertions, " + 
+      failures   + " failures, " +
+      errors     + " errors");
+  }
+};
+
+Test.Unit.Assertions = Class.create();
+Test.Unit.Assertions.prototype = {
+  initialize: function() {
+    this.assertions = 0;
+    this.failures   = 0;
+    this.errors     = 0;
+    this.messages   = [];
+  },
+  summary: function() {
+    return (
+      this.assertions + " assertions, " + 
+      this.failures   + " failures, " +
+      this.errors     + " errors" + "\n" +
+      this.messages.join("\n"));
+  },
+  pass: function() {
+    this.assertions++;
+  },
+  fail: function(message) {
+    this.failures++;
+    this.messages.push("Failure: " + message);
+  },
+  info: function(message) {
+    this.messages.push("Info: " + message);
+  },
+  error: function(error) {
+    this.errors++;
+    this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
+  },
+  status: function() {
+    if (this.failures > 0) return 'failed';
+    if (this.errors > 0) return 'error';
+    return 'passed';
+  },
+  assert: function(expression) {
+    var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
+    try { expression ? this.pass() : 
+      this.fail(message); }
+    catch(e) { this.error(e); }
+  },
+  assertEqual: function(expected, actual) {
+    var message = arguments[2] || "assertEqual";
+    try { (expected == actual) ? this.pass() :
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) + 
+        '", actual "' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertEnumEqual: function(expected, actual) {
+    var message = arguments[2] || "assertEnumEqual";
+    try { $A(expected).length == $A(actual).length && 
+      expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
+        this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + 
+          ', actual ' + Test.Unit.inspect(actual)); }
+    catch(e) { this.error(e); }
+  },
+  assertNotEqual: function(expected, actual) {
+    var message = arguments[2] || "assertNotEqual";
+    try { (expected != actual) ? this.pass() : 
+      this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertIdentical: function(expected, actual) { 
+    var message = arguments[2] || "assertIdentical"; 
+    try { (expected === actual) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + Test.Unit.inspect(actual) + '"'); } 
+    catch(e) { this.error(e); } 
+  },
+  assertNotIdentical: function(expected, actual) { 
+    var message = arguments[2] || "assertNotIdentical"; 
+    try { !(expected === actual) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + Test.Unit.inspect(actual) + '"'); } 
+    catch(e) { this.error(e); } 
+  },
+  assertNull: function(obj) {
+    var message = arguments[1] || 'assertNull';
+    try { (obj==null) ? this.pass() : 
+      this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertMatch: function(expected, actual) {
+    var message = arguments[2] || 'assertMatch';
+    var regex = new RegExp(expected);
+    try { (regex.exec(actual)) ? this.pass() :
+      this.fail(message + ' : regex: "' +  Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertHidden: function(element) {
+    var message = arguments[1] || 'assertHidden';
+    this.assertEqual("none", element.style.display, message);
+  },
+  assertNotNull: function(object) {
+    var message = arguments[1] || 'assertNotNull';
+    this.assert(object != null, message);
+  },
+  assertType: function(expected, actual) {
+    var message = arguments[2] || 'assertType';
+    try { 
+      (actual.constructor == expected) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + (actual.constructor) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertNotOfType: function(expected, actual) {
+    var message = arguments[2] || 'assertNotOfType';
+    try { 
+      (actual.constructor != expected) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + (actual.constructor) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertInstanceOf: function(expected, actual) {
+    var message = arguments[2] || 'assertInstanceOf';
+    try { 
+      (actual instanceof expected) ? this.pass() : 
+      this.fail(message + ": object was not an instance of the expected type"); }
+    catch(e) { this.error(e); } 
+  },
+  assertNotInstanceOf: function(expected, actual) {
+    var message = arguments[2] || 'assertNotInstanceOf';
+    try { 
+      !(actual instanceof expected) ? this.pass() : 
+      this.fail(message + ": object was an instance of the not expected type"); }
+    catch(e) { this.error(e); } 
+  },
+  assertRespondsTo: function(method, obj) {
+    var message = arguments[2] || 'assertRespondsTo';
+    try {
+      (obj[method] && typeof obj[method] == 'function') ? this.pass() : 
+      this.fail(message + ": object doesn't respond to [" + method + "]"); }
+    catch(e) { this.error(e); }
+  },
+  assertReturnsTrue: function(method, obj) {
+    var message = arguments[2] || 'assertReturnsTrue';
+    try {
+      var m = obj[method];
+      if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
+      m() ? this.pass() : 
+      this.fail(message + ": method returned false"); }
+    catch(e) { this.error(e); }
+  },
+  assertReturnsFalse: function(method, obj) {
+    var message = arguments[2] || 'assertReturnsFalse';
+    try {
+      var m = obj[method];
+      if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
+      !m() ? this.pass() : 
+      this.fail(message + ": method returned true"); }
+    catch(e) { this.error(e); }
+  },
+  assertRaise: function(exceptionName, method) {
+    var message = arguments[2] || 'assertRaise';
+    try { 
+      method();
+      this.fail(message + ": exception expected but none was raised"); }
+    catch(e) {
+      (e.name==exceptionName) ? this.pass() : this.error(e); 
+    }
+  },
+  assertElementsMatch: function() {
+    var expressions = $A(arguments), elements = $A(expressions.shift());
+    if (elements.length != expressions.length) {
+      this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
+      return false;
+    }
+    elements.zip(expressions).all(function(pair, index) {
+      var element = $(pair.first()), expression = pair.last();
+      if (element.match(expression)) return true;
+      this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
+    }.bind(this)) && this.pass();
+  },
+  assertElementMatches: function(element, expression) {
+    this.assertElementsMatch([element], expression);
+  },
+  benchmark: function(operation, iterations) {
+    var startAt = new Date();
+    (iterations || 1).times(operation);
+    var timeTaken = ((new Date())-startAt);
+    this.info((arguments[2] || 'Operation') + ' finished ' + 
+       iterations + ' iterations in ' + (timeTaken/1000)+'s' );
+    return timeTaken;
+  },
+  _isVisible: function(element) {
+    element = $(element);
+    if(!element.parentNode) return true;
+    this.assertNotNull(element);
+    if(element.style && Element.getStyle(element, 'display') == 'none')
+      return false;
+    
+    return this._isVisible(element.parentNode);
+  },
+  assertNotVisible: function(element) {
+    this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
+  },
+  assertVisible: function(element) {
+    this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
+  },
+  benchmark: function(operation, iterations) {
+    var startAt = new Date();
+    (iterations || 1).times(operation);
+    var timeTaken = ((new Date())-startAt);
+    this.info((arguments[2] || 'Operation') + ' finished ' + 
+       iterations + ' iterations in ' + (timeTaken/1000)+'s' );
+    return timeTaken;
+  }
+};
+
+Test.Unit.Testcase = Class.create();
+Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
+  initialize: function(name, test, setup, teardown) {
+    Test.Unit.Assertions.prototype.initialize.bind(this)();
+    this.name           = name;
+    
+    if(typeof test == 'string') {
+      test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
+      test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
+      this.test = function() {
+        eval('with(this){'+test+'}');
+      }
+    } else {
+      this.test = test || function() {};
+    }
+    
+    this.setup          = setup || function() {};
+    this.teardown       = teardown || function() {};
+    this.isWaiting      = false;
+    this.timeToWait     = 1000;
+  },
+  wait: function(time, nextPart) {
+    this.isWaiting = true;
+    this.test = nextPart;
+    this.timeToWait = time;
+  },
+  run: function() {
+    try {
+      try {
+        if (!this.isWaiting) this.setup.bind(this)();
+        this.isWaiting = false;
+        this.test.bind(this)();
+      } finally {
+        if(!this.isWaiting) {
+          this.teardown.bind(this)();
+        }
+      }
+    }
+    catch(e) { this.error(e); }
+  }
+});
+
+// *EXPERIMENTAL* BDD-style testing to please non-technical folk
+// This draws many ideas from RSpec http://rspec.rubyforge.org/
+
+Test.setupBDDExtensionMethods = function(){
+  var METHODMAP = {
+    shouldEqual:     'assertEqual',
+    shouldNotEqual:  'assertNotEqual',
+    shouldEqualEnum: 'assertEnumEqual',
+    shouldBeA:       'assertType',
+    shouldNotBeA:    'assertNotOfType',
+    shouldBeAn:      'assertType',
+    shouldNotBeAn:   'assertNotOfType',
+    shouldBeNull:    'assertNull',
+    shouldNotBeNull: 'assertNotNull',
+    
+    shouldBe:        'assertReturnsTrue',
+    shouldNotBe:     'assertReturnsFalse',
+    shouldRespondTo: 'assertRespondsTo'
+  };
+  Test.BDDMethods = {};
+  for(m in METHODMAP) {
+    Test.BDDMethods[m] = eval(
+      'function(){'+
+      'var args = $A(arguments);'+
+      'var scope = args.shift();'+
+      'scope.'+METHODMAP[m]+'.apply(scope,(args || []).concat([this])); }');
+  }
+  [Array.prototype, String.prototype, Number.prototype].each(
+    function(p){ Object.extend(p, Test.BDDMethods) }
+  );
+};
+
+Test.context = function(name, spec, log){
+  Test.setupBDDExtensionMethods();
+  
+  var compiledSpec = {};
+  var titles = {};
+  for(specName in spec) {
+    switch(specName){
+      case "setup":
+      case "teardown":
+        compiledSpec[specName] = spec[specName];
+        break;
+      default:
+        var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
+        var body = spec[specName].toString().split('\n').slice(1);
+        if(/^\{/.test(body[0])) body = body.slice(1);
+        body.pop();
+        body = body.map(function(statement){ 
+          return statement.strip()
+        });
+        compiledSpec[testName] = body.join('\n');
+        titles[testName] = specName;
+    }
+  }
+  new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
+};
Index: /sandbox/workflow/branches/993/js/scriptaculous/lightbox.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/lightbox.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/lightbox.js	(revision 795)
@@ -0,0 +1,205 @@
+/*
+Created By: Chris Campbell
+Website: http://particletree.com
+Date: 2/1/2006
+
+Inspired by the lightbox implementation found at http://www.huddletogether.com/projects/lightbox/
+*/
+
+/*-------------------------------GLOBAL VARIABLES------------------------------------*/
+
+var detect = navigator.userAgent.toLowerCase();
+var OS,browser,version,total,thestring;
+
+/*-----------------------------------------------------------------------------------------------*/
+
+//Browser detect script origionally created by Peter Paul Koch at http://www.quirksmode.org/
+
+function getBrowserInfo() {
+	if (checkIt('konqueror')) {
+		browser = "Konqueror";
+		OS = "Linux";
+	}
+	else if (checkIt('safari')) browser 	= "Safari";
+	else if (checkIt('omniweb')) browser 	= "OmniWeb";
+	else if (checkIt('opera')) browser 		= "Opera";
+	else if (checkIt('webtv')) browser 		= "WebTV";
+	else if (checkIt('icab')) browser 		= "iCab";
+	else if (checkIt('msie')) browser 		= "Internet Explorer";
+	else if (!checkIt('compatible')) {
+		browser = "Netscape Navigator";
+		version = detect.charAt(8);
+	}
+	else browser = "An unknown browser";
+
+	if (!version) version = detect.charAt(place + thestring.length);
+
+	if (!OS) {
+		if (checkIt('linux')) OS 		= "Linux";
+		else if (checkIt('x11')) OS 	= "Unix";
+		else if (checkIt('mac')) OS 	= "Mac";
+		else if (checkIt('win')) OS 	= "Windows";
+		else OS 								= "an unknown operating system";
+	}
+}
+
+function checkIt(string) {
+	place = detect.indexOf(string) + 1;
+	thestring = string;
+	return place;
+}
+
+/*-----------------------------------------------------------------------------------------------*/
+
+Event.observe(window, 'load', lb_initialize, false);
+Event.observe(window, 'load', getBrowserInfo, false);
+Event.observe(window, 'unload', Event.unloadCache, false);
+
+var lightbox = Class.create();
+
+lightbox.prototype = {
+
+	yPos : 0,
+	xPos : 0,
+
+	initialize: function(ctrl) {
+		this.content = ctrl.onclick;
+		Event.observe(ctrl, 'click', this.activate.bindAsEventListener(this), false);
+		ctrl.onclick = function(){return false;};
+	},
+	
+	// Turn everything on - mainly the IE fixes
+	activate: function(){
+		if (browser == 'Internet Explorer'){
+			this.getScroll();
+			this.prepareIE('100%', 'hidden');
+			this.setScroll(0,0);
+			this.hideSelects('hidden');
+		}
+		this.displayLightbox("block");
+	},
+	
+	// Ie requires height to 100% and overflow hidden or else you can scroll down past the lightbox
+	prepareIE: function(height, overflow){
+		bod = document.getElementsByTagName('body')[0];
+		bod.style.height = height;
+		bod.style.overflow = overflow;
+  
+		htm = document.getElementsByTagName('html')[0];
+		htm.style.height = height;
+		htm.style.overflow = overflow; 
+	},
+	
+	// In IE, select elements hover on top of the lightbox
+	hideSelects: function(visibility){
+		selects = document.getElementsByTagName('select');
+		for(i = 0; i < selects.length; i++) {
+			selects[i].style.visibility = visibility;
+		}
+	},
+	
+	// Taken from lightbox implementation found at http://www.huddletogether.com/projects/lightbox/
+	getScroll: function(){
+		if (self.pageYOffset) {
+			this.yPos = self.pageYOffset;
+		} else if (document.documentElement && document.documentElement.scrollTop){
+			this.yPos = document.documentElement.scrollTop; 
+		} else if (document.body) {
+			this.yPos = document.body.scrollTop;
+		}
+	},
+	
+	setScroll: function(x, y){
+		window.scrollTo(x, y); 
+	},
+	
+	displayLightbox: function(display){
+		$('overlay').style.display = display;
+		$('lightbox').style.display = display;
+		if(display != 'none') this.processInfo();
+	},
+	
+	// Begin Ajax request based off of the href of the clicked linked
+	loadInfo: function() {
+		var myAjax = new Ajax.Request(
+        this.content,
+        {method: 'post', parameters: "", onComplete: this.processInfo.bindAsEventListener(this)}
+		);
+		
+	},
+	
+	// Display Ajax response
+	processInfo: function(response){
+		info = "<div id='lbContent'></div>";
+		new Insertion.Before($('lbLoadMessage'), info);
+		this.content();
+		$('lightbox').className = "done";
+		//this.actions();
+	},
+	
+	// Search through new links within the lightbox, and attach click event
+	/*
+	actions: function(){
+		lbActions = document.getElementsByClassName('lbAction');
+
+		for(i = 0; i < lbActions.length; i++) {
+			Event.observe(lbActions[i], 'click', this[lbActions[i].rel].bindAsEventListener(this), false);
+			lbActions[i].onclick = function(){return false;};
+		}
+	},
+*/
+	
+	// Example of creating your own functionality once lightbox is initiated
+	insert: function(e){
+	   link = Event.element(e).parentNode;
+	   Element.remove($('lbContent'));
+	 
+	   var myAjax = new Ajax.Request(
+			  link.href,
+			  {method: 'post', parameters: "", onComplete: this.processInfo.bindAsEventListener(this)}
+	   );
+	 
+	},
+	
+	// Example of creating your own functionality once lightbox is initiated
+	deactivate: function(){
+		Element.remove($('lbContent'));
+		
+		if (browser == "Internet Explorer"){
+			this.setScroll(0,this.yPos);
+			this.prepareIE("auto", "auto");
+			this.hideSelects("visible");
+		}
+		
+		this.displayLightbox("none");
+	}
+};
+
+/*-----------------------------------------------------------------------------------------------*/
+
+// Onload, make all links that need to trigger a lightbox active
+function lb_initialize(){
+	if (!$('overlay'))
+		addLightboxMarkup();
+	lbox = document.getElementsByClassName('lbOn');
+	for(i = 0; i < lbox.length; i++) {
+		valid = new lightbox(lbox[i]);
+	}
+}
+
+// Add in markup necessary to make this work. Basically two divs:
+// Overlay holds the shadow
+// Lightbox is the centered square that the content is put into.
+function addLightboxMarkup() {
+	bod 				= document.getElementsByTagName('body')[0];
+	overlay 			= document.createElement('div');
+	overlay.id		= 'overlay';
+	lb					= document.createElement('div');
+	lb.id				= 'lightbox';
+	lb.className 	= 'loading';
+	lb.innerHTML	= '<div id="lbLoadMessage">' +
+						  '<p>Loading</p>' +
+						  '</div>';
+	bod.appendChild(overlay);
+	bod.appendChild(lb);
+}
Index: /sandbox/workflow/branches/993/js/scriptaculous/scriptaculous.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/scriptaculous.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/scriptaculous.js	(revision 795)
@@ -0,0 +1,51 @@
+// script.aculo.us scriptaculous.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// 
+// 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.
+//
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Scriptaculous = {
+  Version: '1.6.5',
+  require: function(libraryName) {
+    // inserting via DOM fails in Safari 2.0, so brute force approach
+    document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
+  },
+  load: function() {
+    if((typeof Prototype=='undefined') || 
+       (typeof Element == 'undefined') || 
+       (typeof Element.Methods=='undefined') ||
+       parseFloat(Prototype.Version.split(".")[0] + "." +
+                  Prototype.Version.split(".")[1]) < 1.5)
+       throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");
+    
+    $A(document.getElementsByTagName("script")).findAll( function(s) {
+      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+    }).each( function(s) {
+      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
+      var includes = s.src.match(/\?.*load=([a-z,]*)/);
+      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
+       function(include) { Scriptaculous.require(path+include+'.js') });
+    });
+  }
+};
+
+Scriptaculous.load();
Index: /sandbox/workflow/branches/993/js/scriptaculous/dragdrop.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/dragdrop.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/dragdrop.js	(revision 795)
@@ -0,0 +1,944 @@
+// script.aculo.us dragdrop.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if(typeof Effect == 'undefined')
+  throw("dragdrop.js requires including script.aculo.us' effects.js library");
+
+var Droppables = {
+  drops: [],
+
+  remove: function(element) {
+    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
+  },
+
+  add: function(element) {
+    element = $(element);
+    var options = Object.extend({
+      greedy:     true,
+      hoverclass: null,
+      tree:       false
+    }, arguments[1] || {});
+
+    // cache containers
+    if(options.containment) {
+      options._containers = [];
+      var containment = options.containment;
+      if((typeof containment == 'object') && 
+        (containment.constructor == Array)) {
+        containment.each( function(c) { options._containers.push($(c)) });
+      } else {
+        options._containers.push($(containment));
+      }
+    }
+    
+    if(options.accept) options.accept = [options.accept].flatten();
+
+    Element.makePositioned(element); // fix IE
+    options.element = element;
+
+    this.drops.push(options);
+  },
+  
+  findDeepestChild: function(drops) {
+    deepest = drops[0];
+      
+    for (i = 1; i < drops.length; ++i)
+      if (Element.isParent(drops[i].element, deepest.element))
+        deepest = drops[i];
+    
+    return deepest;
+  },
+
+  isContained: function(element, drop) {
+    var containmentNode;
+    if(drop.tree) {
+      containmentNode = element.treeNode; 
+    } else {
+      containmentNode = element.parentNode;
+    }
+    return drop._containers.detect(function(c) { return containmentNode == c });
+  },
+  
+  isAffected: function(point, element, drop) {
+    return (
+      (drop.element!=element) &&
+      ((!drop._containers) ||
+        this.isContained(element, drop)) &&
+      ((!drop.accept) ||
+        (Element.classNames(element).detect( 
+          function(v) { return drop.accept.include(v) } ) )) &&
+      Position.within(drop.element, point[0], point[1]) );
+  },
+
+  deactivate: function(drop) {
+    if(drop.hoverclass)
+      Element.removeClassName(drop.element, drop.hoverclass);
+    this.last_active = null;
+  },
+
+  activate: function(drop) {
+    if(drop.hoverclass)
+      Element.addClassName(drop.element, drop.hoverclass);
+    this.last_active = drop;
+  },
+
+  show: function(point, element) {
+    if(!this.drops.length) return;
+    var affected = [];
+    
+    if(this.last_active) this.deactivate(this.last_active);
+    this.drops.each( function(drop) {
+      if(Droppables.isAffected(point, element, drop))
+        affected.push(drop);
+    });
+        
+    if(affected.length>0) {
+      drop = Droppables.findDeepestChild(affected);
+      Position.within(drop.element, point[0], point[1]);
+      if(drop.onHover)
+        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+      
+      Droppables.activate(drop);
+    }
+  },
+
+  fire: function(event, element) {
+    if(!this.last_active) return;
+    Position.prepare();
+
+    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
+      if (this.last_active.onDrop) 
+        this.last_active.onDrop(element, this.last_active.element, event);
+  },
+
+  reset: function() {
+    if(this.last_active)
+      this.deactivate(this.last_active);
+  }
+};
+
+var Draggables = {
+  drags: [],
+  observers: [],
+  
+  register: function(draggable) {
+    if(this.drags.length == 0) {
+      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
+      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
+      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
+      
+      Event.observe(document, "mouseup", this.eventMouseUp);
+      Event.observe(document, "mousemove", this.eventMouseMove);
+      Event.observe(document, "keypress", this.eventKeypress);
+    }
+    this.drags.push(draggable);
+  },
+  
+  unregister: function(draggable) {
+    this.drags = this.drags.reject(function(d) { return d==draggable });
+    if(this.drags.length == 0) {
+      Event.stopObserving(document, "mouseup", this.eventMouseUp);
+      Event.stopObserving(document, "mousemove", this.eventMouseMove);
+      Event.stopObserving(document, "keypress", this.eventKeypress);
+    }
+  },
+  
+  activate: function(draggable) {
+    if(draggable.options.delay) { 
+      this._timeout = setTimeout(function() { 
+        Draggables._timeout = null; 
+        window.focus(); 
+        Draggables.activeDraggable = draggable; 
+      }.bind(this), draggable.options.delay); 
+    } else {
+      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+      this.activeDraggable = draggable;
+    }
+  },
+  
+  deactivate: function() {
+    this.activeDraggable = null;
+  },
+  
+  updateDrag: function(event) {
+    if(!this.activeDraggable) return;
+    var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    // Mozilla-based browsers fire successive mousemove events with
+    // the same coordinates, prevent needless redrawing (moz bug?)
+    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
+    this._lastPointer = pointer;
+    
+    this.activeDraggable.updateDrag(event, pointer);
+  },
+  
+  endDrag: function(event) {
+    if(this._timeout) { 
+      clearTimeout(this._timeout); 
+      this._timeout = null; 
+    }
+    if(!this.activeDraggable) return;
+    this._lastPointer = null;
+    this.activeDraggable.endDrag(event);
+    this.activeDraggable = null;
+  },
+  
+  keyPress: function(event) {
+    if(this.activeDraggable)
+      this.activeDraggable.keyPress(event);
+  },
+  
+  addObserver: function(observer) {
+    this.observers.push(observer);
+    this._cacheObserverCallbacks();
+  },
+  
+  removeObserver: function(element) {  // element instead of observer fixes mem leaks
+    this.observers = this.observers.reject( function(o) { return o.element==element });
+    this._cacheObserverCallbacks();
+  },
+  
+  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
+    if(this[eventName+'Count'] > 0)
+      this.observers.each( function(o) {
+        if(o[eventName]) o[eventName](eventName, draggable, event);
+      });
+    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
+  },
+  
+  _cacheObserverCallbacks: function() {
+    ['onStart','onEnd','onDrag'].each( function(eventName) {
+      Draggables[eventName+'Count'] = Draggables.observers.select(
+        function(o) { return o[eventName]; }
+      ).length;
+    });
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Draggable = Class.create();
+Draggable._dragging    = {};
+
+Draggable.prototype = {
+  initialize: function(element) {
+    var defaults = {
+      handle: false,
+      reverteffect: function(element, top_offset, left_offset) {
+        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
+        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+          queue: {scope:'_draggable', position:'end'}
+        });
+      },
+      endeffect: function(element) {
+        var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
+        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 
+          queue: {scope:'_draggable', position:'end'},
+          afterFinish: function(){ 
+            Draggable._dragging[element] = false 
+          }
+        }); 
+      },
+      zindex: 1000,
+      revert: false,
+      scroll: false,
+      scrollSensitivity: 20,
+      scrollSpeed: 15,
+      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
+      delay: 0
+    };
+    
+    if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')
+      Object.extend(defaults, {
+        starteffect: function(element) {
+          element._opacity = Element.getOpacity(element);
+          Draggable._dragging[element] = true;
+          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 
+        }
+      });
+    
+    var options = Object.extend(defaults, arguments[1] || {});
+
+    this.element = $(element);
+    
+    if(options.handle && (typeof options.handle == 'string'))
+      this.handle = this.element.down('.'+options.handle, 0);
+    
+    if(!this.handle) this.handle = $(options.handle);
+    if(!this.handle) this.handle = this.element;
+    
+    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
+      options.scroll = $(options.scroll);
+      this._isScrollChild = Element.childOf(this.element, options.scroll);
+    }
+
+    Element.makePositioned(this.element); // fix IE    
+
+    this.delta    = this.currentDelta();
+    this.options  = options;
+    this.dragging = false;   
+
+    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+    Event.observe(this.handle, "mousedown", this.eventMouseDown);
+    
+    Draggables.register(this);
+  },
+  
+  destroy: function() {
+    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+    Draggables.unregister(this);
+  },
+  
+  currentDelta: function() {
+    return([
+      parseInt(Element.getStyle(this.element,'left') || '0'),
+      parseInt(Element.getStyle(this.element,'top') || '0')]);
+  },
+  
+  initDrag: function(event) {
+    if(typeof Draggable._dragging[this.element] != 'undefined' &&
+      Draggable._dragging[this.element]) return;
+    if(Event.isLeftClick(event)) {    
+      // abort on form elements, fixes a Firefox issue
+      var src = Event.element(event);
+      if(src.tagName && (
+        src.tagName=='INPUT' ||
+        src.tagName=='SELECT' ||
+        src.tagName=='OPTION' ||
+        src.tagName=='BUTTON' ||
+        src.tagName=='TEXTAREA')) return;
+        
+      var pointer = [Event.pointerX(event), Event.pointerY(event)];
+      var pos     = Position.cumulativeOffset(this.element);
+      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
+      
+      Draggables.activate(this);
+      Event.stop(event);
+    }
+  },
+  
+  startDrag: function(event) {
+    this.dragging = true;
+    
+    if(this.options.zindex) {
+      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
+      this.element.style.zIndex = this.options.zindex;
+    }
+    
+    if(this.options.ghosting) {
+      this._clone = this.element.cloneNode(true);
+      Position.absolutize(this.element);
+      this.element.parentNode.insertBefore(this._clone, this.element);
+    }
+    
+    if(this.options.scroll) {
+      if (this.options.scroll == window) {
+        var where = this._getWindowScroll(this.options.scroll);
+        this.originalScrollLeft = where.left;
+        this.originalScrollTop = where.top;
+      } else {
+        this.originalScrollLeft = this.options.scroll.scrollLeft;
+        this.originalScrollTop = this.options.scroll.scrollTop;
+      }
+    }
+    
+    Draggables.notify('onStart', this, event);
+        
+    if(this.options.starteffect) this.options.starteffect(this.element);
+  },
+  
+  updateDrag: function(event, pointer) {
+    if(!this.dragging) this.startDrag(event);
+    Position.prepare();
+    Droppables.show(pointer, this.element);
+    Draggables.notify('onDrag', this, event);
+    
+    this.draw(pointer);
+    if(this.options.change) this.options.change(this);
+    
+    if(this.options.scroll) {
+      this.stopScrolling();
+      
+      var p;
+      if (this.options.scroll == window) {
+        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
+      } else {
+        p = Position.page(this.options.scroll);
+        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
+        p[1] += this.options.scroll.scrollTop + Position.deltaY;
+        p.push(p[0]+this.options.scroll.offsetWidth);
+        p.push(p[1]+this.options.scroll.offsetHeight);
+      }
+      var speed = [0,0];
+      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
+      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
+      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
+      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
+      this.startScrolling(speed);
+    }
+    
+    // fix AppleWebKit rendering
+    if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+    
+    Event.stop(event);
+  },
+  
+  finishDrag: function(event, success) {
+    this.dragging = false;
+
+    if(this.options.ghosting) {
+      Position.relativize(this.element);
+      Element.remove(this._clone);
+      this._clone = null;
+    }
+
+    if(success) Droppables.fire(event, this.element);
+    Draggables.notify('onEnd', this, event);
+
+    var revert = this.options.revert;
+    if(revert && typeof revert == 'function') revert = revert(this.element);
+    
+    var d = this.currentDelta();
+    if(revert && this.options.reverteffect) {
+      this.options.reverteffect(this.element, 
+        d[1]-this.delta[1], d[0]-this.delta[0]);
+    } else {
+      this.delta = d;
+    }
+
+    if(this.options.zindex)
+      this.element.style.zIndex = this.originalZ;
+
+    if(this.options.endeffect) 
+      this.options.endeffect(this.element);
+      
+    Draggables.deactivate(this);
+    Droppables.reset();
+  },
+  
+  keyPress: function(event) {
+    if(event.keyCode!=Event.KEY_ESC) return;
+    this.finishDrag(event, false);
+    Event.stop(event);
+  },
+  
+  endDrag: function(event) {
+    if(!this.dragging) return;
+    this.stopScrolling();
+    this.finishDrag(event, true);
+    Event.stop(event);
+  },
+  
+  draw: function(point) {
+    var pos = Position.cumulativeOffset(this.element);
+    if(this.options.ghosting) {
+      var r   = Position.realOffset(this.element);
+      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
+    }
+    
+    var d = this.currentDelta();
+    pos[0] -= d[0]; pos[1] -= d[1];
+    
+    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
+      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
+      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
+    }
+    
+    var p = [0,1].map(function(i){ 
+      return (point[i]-pos[i]-this.offset[i]) 
+    }.bind(this));
+    
+    if(this.options.snap) {
+      if(typeof this.options.snap == 'function') {
+        p = this.options.snap(p[0],p[1],this);
+      } else {
+      if(this.options.snap instanceof Array) {
+        p = p.map( function(v, i) {
+          return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
+      } else {
+        p = p.map( function(v) {
+          return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
+      }
+    }}
+    
+    var style = this.element.style;
+    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
+      style.left = p[0] + "px";
+    if((!this.options.constraint) || (this.options.constraint=='vertical'))
+      style.top  = p[1] + "px";
+    
+    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
+  },
+  
+  stopScrolling: function() {
+    if(this.scrollInterval) {
+      clearInterval(this.scrollInterval);
+      this.scrollInterval = null;
+      Draggables._lastScrollPointer = null;
+    }
+  },
+  
+  startScrolling: function(speed) {
+    if(!(speed[0] || speed[1])) return;
+    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
+    this.lastScrolled = new Date();
+    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
+  },
+  
+  scroll: function() {
+    var current = new Date();
+    var delta = current - this.lastScrolled;
+    this.lastScrolled = current;
+    if(this.options.scroll == window) {
+      with (this._getWindowScroll(this.options.scroll)) {
+        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
+          var d = delta / 1000;
+          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
+        }
+      }
+    } else {
+      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
+      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
+    }
+    
+    Position.prepare();
+    Droppables.show(Draggables._lastPointer, this.element);
+    Draggables.notify('onDrag', this);
+    if (this._isScrollChild) {
+      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+      if (Draggables._lastScrollPointer[0] < 0)
+        Draggables._lastScrollPointer[0] = 0;
+      if (Draggables._lastScrollPointer[1] < 0)
+        Draggables._lastScrollPointer[1] = 0;
+      this.draw(Draggables._lastScrollPointer);
+    }
+    
+    if(this.options.change) this.options.change(this);
+  },
+  
+  _getWindowScroll: function(w) {
+    var T, L, W, H;
+    with (w.document) {
+      if (w.document.documentElement && documentElement.scrollTop) {
+        T = documentElement.scrollTop;
+        L = documentElement.scrollLeft;
+      } else if (w.document.body) {
+        T = body.scrollTop;
+        L = body.scrollLeft;
+      }
+      if (w.innerWidth) {
+        W = w.innerWidth;
+        H = w.innerHeight;
+      } else if (w.document.documentElement && documentElement.clientWidth) {
+        W = documentElement.clientWidth;
+        H = documentElement.clientHeight;
+      } else {
+        W = body.offsetWidth;
+        H = body.offsetHeight
+      }
+    }
+    return { top: T, left: L, width: W, height: H };
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var SortableObserver = Class.create();
+SortableObserver.prototype = {
+  initialize: function(element, observer) {
+    this.element   = $(element);
+    this.observer  = observer;
+    this.lastValue = Sortable.serialize(this.element);
+  },
+  
+  onStart: function() {
+    this.lastValue = Sortable.serialize(this.element);
+  },
+  
+  onEnd: function() {
+    Sortable.unmark();
+    if(this.lastValue != Sortable.serialize(this.element))
+      this.observer(this.element)
+  }
+};
+
+var Sortable = {
+  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+  
+  sortables: {},
+  
+  _findRootElement: function(element) {
+    while (element.tagName != "BODY") {  
+      if(element.id && Sortable.sortables[element.id]) return element;
+      element = element.parentNode;
+    }
+  },
+
+  options: function(element) {
+    element = Sortable._findRootElement($(element));
+    if(!element) return;
+    return Sortable.sortables[element.id];
+  },
+  
+  destroy: function(element){
+    var s = Sortable.options(element);
+    
+    if(s) {
+      Draggables.removeObserver(s.element);
+      s.droppables.each(function(d){ Droppables.remove(d) });
+      s.draggables.invoke('destroy');
+      
+      delete Sortable.sortables[s.element.id];
+    }
+  },
+
+  create: function(element) {
+    element = $(element);
+    var options = Object.extend({ 
+      element:     element,
+      tag:         'li',       // assumes li children, override with tag: 'tagname'
+      dropOnEmpty: false,
+      tree:        false,
+      treeTag:     'ul',
+      overlap:     'vertical', // one of 'vertical', 'horizontal'
+      constraint:  'vertical', // one of 'vertical', 'horizontal', false
+      containment: element,    // also takes array of elements (or id's); or false
+      handle:      false,      // or a CSS class
+      only:        false,
+      delay:       0,
+      hoverclass:  null,
+      ghosting:    false,
+      scroll:      false,
+      scrollSensitivity: 20,
+      scrollSpeed: 15,
+      format:      this.SERIALIZE_RULE,
+      onChange:    Prototype.emptyFunction,
+      onUpdate:    Prototype.emptyFunction
+    }, arguments[1] || {});
+
+    // clear any old sortable with same element
+    this.destroy(element);
+
+    // build options for the draggables
+    var options_for_draggable = {
+      revert:      true,
+      scroll:      options.scroll,
+      scrollSpeed: options.scrollSpeed,
+      scrollSensitivity: options.scrollSensitivity,
+      delay:       options.delay,
+      ghosting:    options.ghosting,
+      constraint:  options.constraint,
+      handle:      options.handle };
+
+    if(options.starteffect)
+      options_for_draggable.starteffect = options.starteffect;
+
+    if(options.reverteffect)
+      options_for_draggable.reverteffect = options.reverteffect;
+    else
+      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
+        element.style.top  = 0;
+        element.style.left = 0;
+      };
+
+    if(options.endeffect)
+      options_for_draggable.endeffect = options.endeffect;
+
+    if(options.zindex)
+      options_for_draggable.zindex = options.zindex;
+
+    // build options for the droppables  
+    var options_for_droppable = {
+      overlap:     options.overlap,
+      containment: options.containment,
+      tree:        options.tree,
+      hoverclass:  options.hoverclass,
+      onHover:     Sortable.onHover
+    };
+    
+    var options_for_tree = {
+      onHover:      Sortable.onEmptyHover,
+      overlap:      options.overlap,
+      containment:  options.containment,
+      hoverclass:   options.hoverclass
+    };
+
+    // fix for gecko engine
+    Element.cleanWhitespace(element); 
+
+    options.draggables = [];
+    options.droppables = [];
+
+    // drop on empty handling
+    if(options.dropOnEmpty || options.tree) {
+      Droppables.add(element, options_for_tree);
+      options.droppables.push(element);
+    }
+
+    (this.findElements(element, options) || []).each( function(e) {
+      // handles are per-draggable
+      var handle = options.handle ? 
+        $(e).down('.'+options.handle,0) : e;    
+      options.draggables.push(
+        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
+      Droppables.add(e, options_for_droppable);
+      if(options.tree) e.treeNode = element;
+      options.droppables.push(e);      
+    });
+    
+    if(options.tree) {
+      (Sortable.findTreeElements(element, options) || []).each( function(e) {
+        Droppables.add(e, options_for_tree);
+        e.treeNode = element;
+        options.droppables.push(e);
+      });
+    }
+
+    // keep reference
+    this.sortables[element.id] = options;
+
+    // for onupdate
+    Draggables.addObserver(new SortableObserver(element, options.onUpdate));
+
+  },
+
+  // return all suitable-for-sortable elements in a guaranteed order
+  findElements: function(element, options) {
+    return Element.findChildren(
+      element, options.only, options.tree ? true : false, options.tag);
+  },
+  
+  findTreeElements: function(element, options) {
+    return Element.findChildren(
+      element, options.only, options.tree ? true : false, options.treeTag);
+  },
+
+  onHover: function(element, dropon, overlap) {
+    if(Element.isParent(dropon, element)) return;
+
+    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
+      return;
+    } else if(overlap>0.5) {
+      Sortable.mark(dropon, 'before');
+      if(dropon.previousSibling != element) {
+        var oldParentNode = element.parentNode;
+        element.style.visibility = "hidden"; // fix gecko rendering
+        dropon.parentNode.insertBefore(element, dropon);
+        if(dropon.parentNode!=oldParentNode) 
+          Sortable.options(oldParentNode).onChange(element);
+        Sortable.options(dropon.parentNode).onChange(element);
+      }
+    } else {
+      Sortable.mark(dropon, 'after');
+      var nextElement = dropon.nextSibling || null;
+      if(nextElement != element) {
+        var oldParentNode = element.parentNode;
+        element.style.visibility = "hidden"; // fix gecko rendering
+        dropon.parentNode.insertBefore(element, nextElement);
+        if(dropon.parentNode!=oldParentNode) 
+          Sortable.options(oldParentNode).onChange(element);
+        Sortable.options(dropon.parentNode).onChange(element);
+      }
+    }
+  },
+  
+  onEmptyHover: function(element, dropon, overlap) {
+    var oldParentNode = element.parentNode;
+    var droponOptions = Sortable.options(dropon);
+        
+    if(!Element.isParent(dropon, element)) {
+      var index;
+      
+      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
+      var child = null;
+            
+      if(children) {
+        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
+        
+        for (index = 0; index < children.length; index += 1) {
+          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
+            offset -= Element.offsetSize (children[index], droponOptions.overlap);
+          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
+            child = index + 1 < children.length ? children[index + 1] : null;
+            break;
+          } else {
+            child = children[index];
+            break;
+          }
+        }
+      }
+      
+      dropon.insertBefore(element, child);
+      
+      Sortable.options(oldParentNode).onChange(element);
+      droponOptions.onChange(element);
+    }
+  },
+
+  unmark: function() {
+    if(Sortable._marker) Sortable._marker.hide();
+  },
+
+  mark: function(dropon, position) {
+    // mark on ghosting only
+    var sortable = Sortable.options(dropon.parentNode);
+    if(sortable && !sortable.ghosting) return; 
+
+    if(!Sortable._marker) {
+      Sortable._marker = 
+        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
+          hide().addClassName('dropmarker').setStyle({position:'absolute'});
+      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+    }    
+    var offsets = Position.cumulativeOffset(dropon);
+    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
+    
+    if(position=='after')
+      if(sortable.overlap == 'horizontal') 
+        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
+      else
+        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
+    
+    Sortable._marker.show();
+  },
+  
+  _tree: function(element, options, parent) {
+    var children = Sortable.findElements(element, options) || [];
+  
+    for (var i = 0; i < children.length; ++i) {
+      var match = children[i].id.match(options.format);
+
+      if (!match) continue;
+      
+      var child = {
+        id: encodeURIComponent(match ? match[1] : null),
+        element: element,
+        parent: parent,
+        children: [],
+        position: parent.children.length,
+        container: $(children[i]).down(options.treeTag)
+      };
+      
+      /* Get the element containing the children and recurse over it */
+      if (child.container)
+        this._tree(child.container, options, child);
+      
+      parent.children.push (child);
+    }
+
+    return parent; 
+  },
+
+  tree: function(element) {
+    element = $(element);
+    var sortableOptions = this.options(element);
+    var options = Object.extend({
+      tag: sortableOptions.tag,
+      treeTag: sortableOptions.treeTag,
+      only: sortableOptions.only,
+      name: element.id,
+      format: sortableOptions.format
+    }, arguments[1] || {});
+    
+    var root = {
+      id: null,
+      parent: null,
+      children: [],
+      container: element,
+      position: 0
+    };
+    
+    return Sortable._tree(element, options, root);
+  },
+
+  /* Construct a [i] index for a particular node */
+  _constructIndex: function(node) {
+    var index = '';
+    do {
+      if (node.id) index = '[' + node.position + ']' + index;
+    } while ((node = node.parent) != null);
+    return index;
+  },
+
+  sequence: function(element) {
+    element = $(element);
+    var options = Object.extend(this.options(element), arguments[1] || {});
+    
+    return $(this.findElements(element, options) || []).map( function(item) {
+      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
+    });
+  },
+
+  setSequence: function(element, new_sequence) {
+    element = $(element);
+    var options = Object.extend(this.options(element), arguments[2] || {});
+    
+    var nodeMap = {};
+    this.findElements(element, options).each( function(n) {
+        if (n.id.match(options.format))
+            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
+        n.parentNode.removeChild(n);
+    });
+   
+    new_sequence.each(function(ident) {
+      var n = nodeMap[ident];
+      if (n) {
+        n[1].appendChild(n[0]);
+        delete nodeMap[ident];
+      }
+    });
+  },
+  
+  serialize: function(element) {
+    element = $(element);
+    var options = Object.extend(Sortable.options(element), arguments[1] || {});
+    var name = encodeURIComponent(
+      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
+    
+    if (options.tree) {
+      return Sortable.tree(element, arguments[1]).children.map( function (item) {
+        return [name + Sortable._constructIndex(item) + "[id]=" + 
+                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
+      }).flatten().join('&');
+    } else {
+      return Sortable.sequence(element, arguments[1]).map( function(item) {
+        return name + "[]=" + encodeURIComponent(item);
+      }).join('&');
+    }
+  }
+};
+
+// Returns true if child is contained within element
+Element.isParent = function(child, element) {
+  if (!child.parentNode || child == element) return false;
+  if (child.parentNode == element) return true;
+  return Element.isParent(child.parentNode, element);
+};
+
+Element.findChildren = function(element, only, recursive, tagName) {    
+  if(!element.hasChildNodes()) return null;
+  tagName = tagName.toUpperCase();
+  if(only) only = [only].flatten();
+  var elements = [];
+  $A(element.childNodes).each( function(e) {
+    if(e.tagName && e.tagName.toUpperCase()==tagName &&
+      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
+        elements.push(e);
+    if(recursive) {
+      var grandchildren = Element.findChildren(e, only, recursive, tagName);
+      if(grandchildren) elements.push(grandchildren);
+    }
+  });
+
+  return (elements.length>0 ? elements.flatten() : []);
+};
+
+Element.offsetSize = function (element, type) {
+  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
+};
Index: /sandbox/workflow/branches/993/js/scriptaculous/slider.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/slider.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/slider.js	(revision 795)
@@ -0,0 +1,278 @@
+// script.aculo.us slider.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Marty Haught, Thomas Fuchs 
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if(!Control) var Control = {};
+Control.Slider = Class.create();
+
+// options:
+//  axis: 'vertical', or 'horizontal' (default)
+//
+// callbacks:
+//  onChange(value)
+//  onSlide(value)
+Control.Slider.prototype = {
+  initialize: function(handle, track, options) {
+    var slider = this;
+    
+    if(handle instanceof Array) {
+      this.handles = handle.collect( function(e) { return $(e) });
+    } else {
+      this.handles = [$(handle)];
+    }
+    
+    this.track   = $(track);
+    this.options = options || {};
+
+    this.axis      = this.options.axis || 'horizontal';
+    this.increment = this.options.increment || 1;
+    this.step      = parseInt(this.options.step || '1');
+    this.range     = this.options.range || $R(0,1);
+    
+    this.value     = 0; // assure backwards compat
+    this.values    = this.handles.map( function() { return 0 });
+    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
+    this.options.startSpan = $(this.options.startSpan || null);
+    this.options.endSpan   = $(this.options.endSpan || null);
+
+    this.restricted = this.options.restricted || false;
+
+    this.maximum   = this.options.maximum || this.range.end;
+    this.minimum   = this.options.minimum || this.range.start;
+
+    // Will be used to align the handle onto the track, if necessary
+    this.alignX = parseInt(this.options.alignX || '0');
+    this.alignY = parseInt(this.options.alignY || '0');
+    
+    this.trackLength = this.maximumOffset() - this.minimumOffset();
+
+    this.handleLength = this.isVertical() ? 
+      (this.handles[0].offsetHeight != 0 ? 
+        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
+      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
+        this.handles[0].style.width.replace(/px$/,""));
+
+    this.active   = false;
+    this.dragging = false;
+    this.disabled = false;
+
+    if(this.options.disabled) this.setDisabled();
+
+    // Allowed values array
+    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+    if(this.allowedValues) {
+      this.minimum = this.allowedValues.min();
+      this.maximum = this.allowedValues.max();
+    }
+
+    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
+    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
+    this.eventMouseMove = this.update.bindAsEventListener(this);
+
+    // Initialize handles in reverse (make sure first handle is active)
+    this.handles.each( function(h,i) {
+      i = slider.handles.length-1-i;
+      slider.setValue(parseFloat(
+        (slider.options.sliderValue instanceof Array ? 
+          slider.options.sliderValue[i] : slider.options.sliderValue) || 
+         slider.range.start), i);
+      Element.makePositioned(h); // fix IE
+      Event.observe(h, "mousedown", slider.eventMouseDown);
+    });
+    
+    Event.observe(this.track, "mousedown", this.eventMouseDown);
+    Event.observe(document, "mouseup", this.eventMouseUp);
+    Event.observe(document, "mousemove", this.eventMouseMove);
+    
+    this.initialized = true;
+  },
+  dispose: function() {
+    var slider = this;    
+    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
+    Event.stopObserving(document, "mouseup", this.eventMouseUp);
+    Event.stopObserving(document, "mousemove", this.eventMouseMove);
+    this.handles.each( function(h) {
+      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+    });
+  },
+  setDisabled: function(){
+    this.disabled = true;
+  },
+  setEnabled: function(){
+    this.disabled = false;
+  },  
+  getNearestValue: function(value){
+    if(this.allowedValues){
+      if(value >= this.allowedValues.max()) return(this.allowedValues.max());
+      if(value <= this.allowedValues.min()) return(this.allowedValues.min());
+      
+      var offset = Math.abs(this.allowedValues[0] - value);
+      var newValue = this.allowedValues[0];
+      this.allowedValues.each( function(v) {
+        var currentOffset = Math.abs(v - value);
+        if(currentOffset <= offset){
+          newValue = v;
+          offset = currentOffset;
+        } 
+      });
+      return newValue;
+    }
+    if(value > this.range.end) return this.range.end;
+    if(value < this.range.start) return this.range.start;
+    return value;
+  },
+  setValue: function(sliderValue, handleIdx){
+    if(!this.active) {
+      this.activeHandleIdx = handleIdx || 0;
+      this.activeHandle    = this.handles[this.activeHandleIdx];
+      this.updateStyles();
+    }
+    handleIdx = handleIdx || this.activeHandleIdx || 0;
+    if(this.initialized && this.restricted) {
+      if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
+        sliderValue = this.values[handleIdx-1];
+      if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
+        sliderValue = this.values[handleIdx+1];
+    }
+    sliderValue = this.getNearestValue(sliderValue);
+    this.values[handleIdx] = sliderValue;
+    this.value = this.values[0]; // assure backwards compat
+    
+    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
+      this.translateToPx(sliderValue);
+    
+    this.drawSpans();
+    if(!this.dragging || !this.event) this.updateFinished();
+  },
+  setValueBy: function(delta, handleIdx) {
+    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
+      handleIdx || this.activeHandleIdx || 0);
+  },
+  translateToPx: function(value) {
+    return Math.round(
+      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
+      (value - this.range.start)) + "px";
+  },
+  translateToValue: function(offset) {
+    return ((offset/(this.trackLength-this.handleLength) * 
+      (this.range.end-this.range.start)) + this.range.start);
+  },
+  getRange: function(range) {
+    var v = this.values.sortBy(Prototype.K); 
+    range = range || 0;
+    return $R(v[range],v[range+1]);
+  },
+  minimumOffset: function(){
+    return(this.isVertical() ? this.alignY : this.alignX);
+  },
+  maximumOffset: function(){
+    return(this.isVertical() ? 
+      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
+        this.track.style.height.replace(/px$/,"")) - this.alignY : 
+      (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
+        this.track.style.width.replace(/px$/,"")) - this.alignY);
+  },  
+  isVertical:  function(){
+    return (this.axis == 'vertical');
+  },
+  drawSpans: function() {
+    var slider = this;
+    if(this.spans)
+      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
+    if(this.options.startSpan)
+      this.setSpan(this.options.startSpan,
+        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
+    if(this.options.endSpan)
+      this.setSpan(this.options.endSpan, 
+        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
+  },
+  setSpan: function(span, range) {
+    if(this.isVertical()) {
+      span.style.top = this.translateToPx(range.start);
+      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
+    } else {
+      span.style.left = this.translateToPx(range.start);
+      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
+    }
+  },
+  updateStyles: function() {
+    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
+    Element.addClassName(this.activeHandle, 'selected');
+  },
+  startDrag: function(event) {
+    if(Event.isLeftClick(event)) {
+      if(!this.disabled){
+        this.active = true;
+        
+        var handle = Event.element(event);
+        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
+        var track = handle;
+        if(track==this.track) {
+          var offsets  = Position.cumulativeOffset(this.track); 
+          this.event = event;
+          this.setValue(this.translateToValue( 
+           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
+          ));
+          var offsets  = Position.cumulativeOffset(this.activeHandle);
+          this.offsetX = (pointer[0] - offsets[0]);
+          this.offsetY = (pointer[1] - offsets[1]);
+        } else {
+          // find the handle (prevents issues with Safari)
+          while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
+            handle = handle.parentNode;
+            
+          if(this.handles.indexOf(handle)!=-1) {
+            this.activeHandle    = handle;
+            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+            this.updateStyles();
+            
+            var offsets  = Position.cumulativeOffset(this.activeHandle);
+            this.offsetX = (pointer[0] - offsets[0]);
+            this.offsetY = (pointer[1] - offsets[1]);
+          }
+        }
+      }
+      Event.stop(event);
+    }
+  },
+  update: function(event) {
+   if(this.active) {
+      if(!this.dragging) this.dragging = true;
+      this.draw(event);
+      // fix AppleWebKit rendering
+      if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+      Event.stop(event);
+   }
+  },
+  draw: function(event) {
+    var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    var offsets = Position.cumulativeOffset(this.track);
+    pointer[0] -= this.offsetX + offsets[0];
+    pointer[1] -= this.offsetY + offsets[1];
+    this.event = event;
+    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
+    if(this.initialized && this.options.onSlide)
+      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
+  },
+  endDrag: function(event) {
+    if(this.active && this.dragging) {
+      this.finishDrag(event, true);
+      Event.stop(event);
+    }
+    this.active = false;
+    this.dragging = false;
+  },  
+  finishDrag: function(event, success) {
+    this.active = false;
+    this.dragging = false;
+    this.updateFinished();
+  },
+  updateFinished: function() {
+    if(this.initialized && this.options.onChange) 
+      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
+    this.event = null;
+  }
+};
Index: /sandbox/workflow/branches/993/js/scriptaculous/controls.js
===================================================================
--- /sandbox/workflow/branches/993/js/scriptaculous/controls.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/scriptaculous/controls.js	(revision 795)
@@ -0,0 +1,834 @@
+// script.aculo.us controls.js v1.6.5, Wed Nov 08 14:17:49 CET 2006
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+//           (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
+// Contributors:
+//  Richard Livsey
+//  Rahul Bhargava
+//  Rob Wills
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// Autocompleter.Base handles all the autocompletion functionality 
+// that's independent of the data source for autocompletion. This
+// includes drawing the autocompletion menu, observing keyboard
+// and mouse events, and similar.
+//
+// Specific autocompleters need to provide, at the very least, 
+// a getUpdatedChoices function that will be invoked every time
+// the text inside the monitored textbox changes. This method 
+// should get the text for which to provide autocompletion by
+// invoking this.getToken(), NOT by directly accessing
+// this.element.value. This is to allow incremental tokenized
+// autocompletion. Specific auto-completion logic (AJAX, etc)
+// belongs in getUpdatedChoices.
+//
+// Tokenized incremental autocompletion is enabled automatically
+// when an autocompleter is instantiated with the 'tokens' option
+// in the options parameter, e.g.:
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
+// will incrementally autocomplete with a comma as the token.
+// Additionally, ',' in the above example can be replaced with
+// a token array, e.g. { tokens: [',', '\n'] } which
+// enables autocompletion on multiple tokens. This is most 
+// useful when one of the tokens is \n (a newline), as it 
+// allows smart autocompletion after linebreaks.
+
+if(typeof Effect == 'undefined')
+  throw("controls.js requires including script.aculo.us' effects.js library");
+
+var Autocompleter = {};
+Autocompleter.Base = function() {};
+Autocompleter.Base.prototype = {
+  baseInitialize: function(element, update, options) {
+    this.element     = $(element); 
+    this.update      = $(update);  
+    this.hasFocus    = false; 
+    this.changed     = false; 
+    this.active      = false; 
+    this.index       = 0;     
+    this.entryCount  = 0;
+
+    if(this.setOptions)
+      this.setOptions(options);
+    else
+      this.options = options || {};
+
+    this.options.paramName    = this.options.paramName || this.element.name;
+    this.options.tokens       = this.options.tokens || [];
+    this.options.frequency    = this.options.frequency || 0.4;
+    this.options.minChars     = this.options.minChars || 1;
+    this.options.onShow       = this.options.onShow || 
+      function(element, update){ 
+        if(!update.style.position || update.style.position=='absolute') {
+          update.style.position = 'absolute';
+          Position.clone(element, update, {
+            setHeight: false, 
+            offsetTop: element.offsetHeight
+          });
+        }
+        Effect.Appear(update,{duration:0.15});
+      };
+    this.options.onHide = this.options.onHide || 
+      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
+
+    if(typeof(this.options.tokens) == 'string') 
+      this.options.tokens = new Array(this.options.tokens);
+
+    this.observer = null;
+    
+    this.element.setAttribute('autocomplete','off');
+
+    Element.hide(this.update);
+
+    Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
+    Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
+  },
+
+  show: function() {
+    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
+    if(!this.iefix && 
+      (navigator.appVersion.indexOf('MSIE')>0) &&
+      (navigator.userAgent.indexOf('Opera')<0) &&
+      (Element.getStyle(this.update, 'position')=='absolute')) {
+      new Insertion.After(this.update, 
+       '<iframe id="' + this.update.id + '_iefix" '+
+       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+      this.iefix = $(this.update.id+'_iefix');
+    }
+    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
+  },
+  
+  fixIEOverlapping: function() {
+    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+    this.iefix.style.zIndex = 1;
+    this.update.style.zIndex = 2;
+    Element.show(this.iefix);
+  },
+
+  hide: function() {
+    this.stopIndicator();
+    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
+    if(this.iefix) Element.hide(this.iefix);
+  },
+
+  startIndicator: function() {
+    if(this.options.indicator) Element.show(this.options.indicator);
+  },
+
+  stopIndicator: function() {
+    if(this.options.indicator) Element.hide(this.options.indicator);
+  },
+
+  onKeyPress: function(event) {
+    if(this.active)
+      switch(event.keyCode) {
+       case Event.KEY_TAB:
+       case Event.KEY_RETURN:
+         this.selectEntry();
+         Event.stop(event);
+       case Event.KEY_ESC:
+         this.hide();
+         this.active = false;
+         Event.stop(event);
+         return;
+       case Event.KEY_LEFT:
+       case Event.KEY_RIGHT:
+         return;
+       case Event.KEY_UP:
+         this.markPrevious();
+         this.render();
+         if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+         return;
+       case Event.KEY_DOWN:
+         this.markNext();
+         this.render();
+         if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+         return;
+      }
+     else 
+       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
+         (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
+
+    this.changed = true;
+    this.hasFocus = true;
+
+    if(this.observer) clearTimeout(this.observer);
+      this.observer = 
+        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
+  },
+
+  activate: function() {
+    this.changed = false;
+    this.hasFocus = true;
+    this.getUpdatedChoices();
+  },
+
+  onHover: function(event) {
+    var element = Event.findElement(event, 'LI');
+    if(this.index != element.autocompleteIndex) 
+    {
+        this.index = element.autocompleteIndex;
+        this.render();
+    }
+    Event.stop(event);
+  },
+  
+  onClick: function(event) {
+    var element = Event.findElement(event, 'LI');
+    this.index = element.autocompleteIndex;
+    this.selectEntry();
+    this.hide();
+  },
+  
+  onBlur: function(event) {
+    // needed to make click events working
+    setTimeout(this.hide.bind(this), 250);
+    this.hasFocus = false;
+    this.active = false;     
+  }, 
+  
+  render: function() {
+    if(this.entryCount > 0) {
+      for (var i = 0; i < this.entryCount; i++)
+        this.index==i ? 
+          Element.addClassName(this.getEntry(i),"selected") : 
+          Element.removeClassName(this.getEntry(i),"selected");
+        
+      if(this.hasFocus) { 
+        this.show();
+        this.active = true;
+      }
+    } else {
+      this.active = false;
+      this.hide();
+    }
+  },
+  
+  markPrevious: function() {
+    if(this.index > 0) this.index--;
+      else this.index = this.entryCount-1;
+    this.getEntry(this.index).scrollIntoView(true);
+  },
+  
+  markNext: function() {
+    if(this.index < this.entryCount-1) this.index++;
+      else this.index = 0;
+    this.getEntry(this.index).scrollIntoView(false);
+  },
+  
+  getEntry: function(index) {
+    return this.update.firstChild.childNodes[index];
+  },
+  
+  getCurrentEntry: function() {
+    return this.getEntry(this.index);
+  },
+  
+  selectEntry: function() {
+    this.active = false;
+    this.updateElement(this.getCurrentEntry());
+  },
+
+  updateElement: function(selectedElement) {
+    if (this.options.updateElement) {
+      this.options.updateElement(selectedElement);
+      return;
+    }
+    var value = '';
+    if (this.options.select) {
+      var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
+      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
+    } else
+      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+    
+    var lastTokenPos = this.findLastToken();
+    if (lastTokenPos != -1) {
+      var newValue = this.element.value.substr(0, lastTokenPos + 1);
+      var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
+      if (whitespace)
+        newValue += whitespace[0];
+      this.element.value = newValue + value;
+    } else {
+      this.element.value = value;
+    }
+    this.element.focus();
+    
+    if (this.options.afterUpdateElement)
+      this.options.afterUpdateElement(this.element, selectedElement);
+  },
+
+  updateChoices: function(choices) {
+    if(!this.changed && this.hasFocus) {
+      this.update.innerHTML = choices;
+      Element.cleanWhitespace(this.update);
+      Element.cleanWhitespace(this.update.down());
+
+      if(this.update.firstChild && this.update.down().childNodes) {
+        this.entryCount = 
+          this.update.down().childNodes.length;
+        for (var i = 0; i < this.entryCount; i++) {
+          var entry = this.getEntry(i);
+          entry.autocompleteIndex = i;
+          this.addObservers(entry);
+        }
+      } else { 
+        this.entryCount = 0;
+      }
+
+      this.stopIndicator();
+      this.index = 0;
+      
+      if(this.entryCount==1 && this.options.autoSelect) {
+        this.selectEntry();
+        this.hide();
+      } else {
+        this.render();
+      }
+    }
+  },
+
+  addObservers: function(element) {
+    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+  },
+
+  onObserverEvent: function() {
+    this.changed = false;   
+    if(this.getToken().length>=this.options.minChars) {
+      this.startIndicator();
+      this.getUpdatedChoices();
+    } else {
+      this.active = false;
+      this.hide();
+    }
+  },
+
+  getToken: function() {
+    var tokenPos = this.findLastToken();
+    if (tokenPos != -1)
+      var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
+    else
+      var ret = this.element.value;
+
+    return /\n/.test(ret) ? '' : ret;
+  },
+
+  findLastToken: function() {
+    var lastTokenPos = -1;
+
+    for (var i=0; i<this.options.tokens.length; i++) {
+      var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
+      if (thisTokenPos > lastTokenPos)
+        lastTokenPos = thisTokenPos;
+    }
+    return lastTokenPos;
+  }
+};
+
+Ajax.Autocompleter = Class.create();
+Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
+  initialize: function(element, update, url, options) {
+    this.baseInitialize(element, update, options);
+    this.options.asynchronous  = true;
+    this.options.onComplete    = this.onComplete.bind(this);
+    this.options.defaultParams = this.options.parameters || null;
+    this.url                   = url;
+  },
+
+  getUpdatedChoices: function() {
+    entry = encodeURIComponent(this.options.paramName) + '=' + 
+      encodeURIComponent(this.getToken());
+
+    this.options.parameters = this.options.callback ?
+      this.options.callback(this.element, entry) : entry;
+
+    if(this.options.defaultParams) 
+      this.options.parameters += '&' + this.options.defaultParams;
+
+    new Ajax.Request(this.url, this.options);
+  },
+
+  onComplete: function(request) {
+    this.updateChoices(request.responseText);
+  }
+
+});
+
+// The local array autocompleter. Used when you'd prefer to
+// inject an array of autocompletion options into the page, rather
+// than sending out Ajax queries, which can be quite slow sometimes.
+//
+// The constructor takes four parameters. The first two are, as usual,
+// the id of the monitored textbox, and id of the autocompletion menu.
+// The third is the array you want to autocomplete from, and the fourth
+// is the options block.
+//
+// Extra local autocompletion options:
+// - choices - How many autocompletion choices to offer
+//
+// - partialSearch - If false, the autocompleter will match entered
+//                    text only at the beginning of strings in the 
+//                    autocomplete array. Defaults to true, which will
+//                    match text at the beginning of any *word* in the
+//                    strings in the autocomplete array. If you want to
+//                    search anywhere in the string, additionally set
+//                    the option fullSearch to true (default: off).
+//
+// - fullSsearch - Search anywhere in autocomplete array strings.
+//
+// - partialChars - How many characters to enter before triggering
+//                   a partial match (unlike minChars, which defines
+//                   how many characters are required to do any match
+//                   at all). Defaults to 2.
+//
+// - ignoreCase - Whether to ignore case when autocompleting.
+//                 Defaults to true.
+//
+// It's possible to pass in a custom function as the 'selector' 
+// option, if you prefer to write your own autocompletion logic.
+// In that case, the other options above will not apply unless
+// you support them.
+
+Autocompleter.Local = Class.create();
+Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
+  initialize: function(element, update, array, options) {
+    this.baseInitialize(element, update, options);
+    this.options.array = array;
+  },
+
+  getUpdatedChoices: function() {
+    this.updateChoices(this.options.selector(this));
+  },
+
+  setOptions: function(options) {
+    this.options = Object.extend({
+      choices: 10,
+      partialSearch: true,
+      partialChars: 2,
+      ignoreCase: true,
+      fullSearch: false,
+      selector: function(instance) {
+        var ret       = []; // Beginning matches
+        var partial   = []; // Inside matches
+        var entry     = instance.getToken();
+        var count     = 0;
+
+        for (var i = 0; i < instance.options.array.length &&  
+          ret.length < instance.options.choices ; i++) { 
+
+          var elem = instance.options.array[i];
+          var foundPos = instance.options.ignoreCase ? 
+            elem.toLowerCase().indexOf(entry.toLowerCase()) : 
+            elem.indexOf(entry);
+
+          while (foundPos != -1) {
+            if (foundPos == 0 && elem.length != entry.length) { 
+              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
+                elem.substr(entry.length) + "</li>");
+              break;
+            } else if (entry.length >= instance.options.partialChars && 
+              instance.options.partialSearch && foundPos != -1) {
+              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
+                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
+                  foundPos + entry.length) + "</li>");
+                break;
+              }
+            }
+
+            foundPos = instance.options.ignoreCase ? 
+              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
+              elem.indexOf(entry, foundPos + 1);
+
+          }
+        }
+        if (partial.length)
+          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
+        return "<ul>" + ret.join('') + "</ul>";
+      }
+    }, options || {});
+  }
+});
+
+// AJAX in-place editor
+//
+// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function(field) {
+  setTimeout(function() {
+    Field.activate(field);
+  }, 1);
+};
+
+Ajax.InPlaceEditor = Class.create();
+Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
+Ajax.InPlaceEditor.prototype = {
+  initialize: function(element, url, options) {
+    this.url = url;
+    this.element = $(element);
+
+    this.options = Object.extend({
+      okButton: true,
+      okText: "ok",
+      cancelLink: true,
+      cancelText: "cancel",
+      savingText: "Saving...",
+      clickToEditText: "Click to edit",
+      okText: "ok",
+      rows: 1,
+      onComplete: function(transport, element) {
+        new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
+      },
+      onFailure: function(transport) {
+        alert("Error communicating with the server: " + transport.responseText.stripTags());
+      },
+      callback: function(form) {
+        return Form.serialize(form);
+      },
+      handleLineBreaks: true,
+      loadingText: 'Loading...',
+      savingClassName: 'inplaceeditor-saving',
+      loadingClassName: 'inplaceeditor-loading',
+      formClassName: 'inplaceeditor-form',
+      highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
+      highlightendcolor: "#FFFFFF",
+      externalControl: null,
+      submitOnBlur: false,
+      ajaxOptions: {},
+      evalScripts: false
+    }, options || {});
+
+    if(!this.options.formId && this.element.id) {
+      this.options.formId = this.element.id + "-inplaceeditor";
+      if ($(this.options.formId)) {
+        // there's already a form with that name, don't specify an id
+        this.options.formId = null;
+      }
+    }
+    
+    if (this.options.externalControl) {
+      this.options.externalControl = $(this.options.externalControl);
+    }
+    
+    this.originalBackground = Element.getStyle(this.element, 'background-color');
+    if (!this.originalBackground) {
+      this.originalBackground = "transparent";
+    }
+    
+    this.element.title = this.options.clickToEditText;
+    
+    this.onclickListener = this.enterEditMode.bindAsEventListener(this);
+    this.mouseoverListener = this.enterHover.bindAsEventListener(this);
+    this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
+    Event.observe(this.element, 'click', this.onclickListener);
+    Event.observe(this.element, 'mouseover', this.mouseoverListener);
+    Event.observe(this.element, 'mouseout', this.mouseoutListener);
+    if (this.options.externalControl) {
+      Event.observe(this.options.externalControl, 'click', this.onclickListener);
+      Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
+      Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
+    }
+  },
+  enterEditMode: function(evt) {
+    if (this.saving) return;
+    if (this.editing) return;
+    this.editing = true;
+    this.onEnterEditMode();
+    if (this.options.externalControl) {
+      Element.hide(this.options.externalControl);
+    }
+    Element.hide(this.element);
+    this.createForm();
+    this.element.parentNode.insertBefore(this.form, this.element);
+    if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);
+    // stop the event to avoid a page refresh in Safari
+    if (evt) {
+      Event.stop(evt);
+    }
+    return false;
+  },
+  createForm: function() {
+    this.form = document.createElement("form");
+    this.form.id = this.options.formId;
+    Element.addClassName(this.form, this.options.formClassName);
+    this.form.onsubmit = this.onSubmit.bind(this);
+
+    this.createEditField();
+
+    if (this.options.textarea) {
+      var br = document.createElement("br");
+      this.form.appendChild(br);
+    }
+
+    if (this.options.okButton) {
+      okButton = document.createElement("input");
+      okButton.type = "submit";
+      okButton.value = this.options.okText;
+      okButton.className = 'editor_ok_button';
+      this.form.appendChild(okButton);
+    }
+
+    if (this.options.cancelLink) {
+      cancelLink = document.createElement("a");
+      cancelLink.href = "#";
+      cancelLink.appendChild(document.createTextNode(this.options.cancelText));
+      cancelLink.onclick = this.onclickCancel.bind(this);
+      cancelLink.className = 'editor_cancel';      
+      this.form.appendChild(cancelLink);
+    }
+  },
+  hasHTMLLineBreaks: function(string) {
+    if (!this.options.handleLineBreaks) return false;
+    return string.match(/<br/i) || string.match(/<p>/i);
+  },
+  convertHTMLLineBreaks: function(string) {
+    return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
+  },
+  createEditField: function() {
+    var text;
+    if(this.options.loadTextURL) {
+      text = this.options.loadingText;
+    } else {
+      text = this.getText();
+    }
+
+    var obj = this;
+    
+    if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
+      this.options.textarea = false;
+      var textField = document.createElement("input");
+      textField.obj = this;
+      textField.type = "text";
+      textField.name = "value";
+      textField.value = text;
+      textField.style.backgroundColor = this.options.highlightcolor;
+      textField.className = 'editor_field';
+      var size = this.options.size || this.options.cols || 0;
+      if (size != 0) textField.size = size;
+      if (this.options.submitOnBlur)
+        textField.onblur = this.onSubmit.bind(this);
+      this.editField = textField;
+    } else {
+      this.options.textarea = true;
+      var textArea = document.createElement("textarea");
+      textArea.obj = this;
+      textArea.name = "value";
+      textArea.value = this.convertHTMLLineBreaks(text);
+      textArea.rows = this.options.rows;
+      textArea.cols = this.options.cols || 40;
+      textArea.className = 'editor_field';      
+      if (this.options.submitOnBlur)
+        textArea.onblur = this.onSubmit.bind(this);
+      this.editField = textArea;
+    }
+    
+    if(this.options.loadTextURL) {
+      this.loadExternalText();
+    }
+    this.form.appendChild(this.editField);
+  },
+  getText: function() {
+    return this.element.innerHTML;
+  },
+  loadExternalText: function() {
+    Element.addClassName(this.form, this.options.loadingClassName);
+    this.editField.disabled = true;
+    new Ajax.Request(
+      this.options.loadTextURL,
+      Object.extend({
+        asynchronous: true,
+        onComplete: this.onLoadedExternalText.bind(this)
+      }, this.options.ajaxOptions)
+    );
+  },
+  onLoadedExternalText: function(transport) {
+    Element.removeClassName(this.form, this.options.loadingClassName);
+    this.editField.disabled = false;
+    this.editField.value = transport.responseText.stripTags();
+    Field.scrollFreeActivate(this.editField);
+  },
+  onclickCancel: function() {
+    this.onComplete();
+    this.leaveEditMode();
+    return false;
+  },
+  onFailure: function(transport) {
+    this.options.onFailure(transport);
+    if (this.oldInnerHTML) {
+      this.element.innerHTML = this.oldInnerHTML;
+      this.oldInnerHTML = null;
+    }
+    return false;
+  },
+  onSubmit: function() {
+    // onLoading resets these so we need to save them away for the Ajax call
+    var form = this.form;
+    var value = this.editField.value;
+    
+    // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
+    // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
+    // to be displayed indefinitely
+    this.onLoading();
+    
+    if (this.options.evalScripts) {
+      new Ajax.Request(
+        this.url, Object.extend({
+          parameters: this.options.callback(form, value),
+          onComplete: this.onComplete.bind(this),
+          onFailure: this.onFailure.bind(this),
+          asynchronous:true, 
+          evalScripts:true
+        }, this.options.ajaxOptions));
+    } else  {
+      new Ajax.Updater(
+        { success: this.element,
+          // don't update on failure (this could be an option)
+          failure: null }, 
+        this.url, Object.extend({
+          parameters: this.options.callback(form, value),
+          onComplete: this.onComplete.bind(this),
+          onFailure: this.onFailure.bind(this)
+        }, this.options.ajaxOptions));
+    }
+    // stop the event to avoid a page refresh in Safari
+    if (arguments.length > 1) {
+      Event.stop(arguments[0]);
+    }
+    return false;
+  },
+  onLoading: function() {
+    this.saving = true;
+    this.removeForm();
+    this.leaveHover();
+    this.showSaving();
+  },
+  showSaving: function() {
+    this.oldInnerHTML = this.element.innerHTML;
+    this.element.innerHTML = this.options.savingText;
+    Element.addClassName(this.element, this.options.savingClassName);
+    this.element.style.backgroundColor = this.originalBackground;
+    Element.show(this.element);
+  },
+  removeForm: function() {
+    if(this.form) {
+      if (this.form.parentNode) Element.remove(this.form);
+      this.form = null;
+    }
+  },
+  enterHover: function() {
+    if (this.saving) return;
+    this.element.style.backgroundColor = this.options.highlightcolor;
+    if (this.effect) {
+      this.effect.cancel();
+    }
+    Element.addClassName(this.element, this.options.hoverClassName)
+  },
+  leaveHover: function() {
+    if (this.options.backgroundColor) {
+      this.element.style.backgroundColor = this.oldBackground;
+    }
+    Element.removeClassName(this.element, this.options.hoverClassName);
+    if (this.saving) return;
+    this.effect = new Effect.Highlight(this.element, {
+      startcolor: this.options.highlightcolor,
+      endcolor: this.options.highlightendcolor,
+      restorecolor: this.originalBackground
+    });
+  },
+  leaveEditMode: function() {
+    Element.removeClassName(this.element, this.options.savingClassName);
+    this.removeForm();
+    this.leaveHover();
+    this.element.style.backgroundColor = this.originalBackground;
+    Element.show(this.element);
+    if (this.options.externalControl) {
+      Element.show(this.options.externalControl);
+    }
+    this.editing = false;
+    this.saving = false;
+    this.oldInnerHTML = null;
+    this.onLeaveEditMode();
+  },
+  onComplete: function(transport) {
+    this.leaveEditMode();
+    this.options.onComplete.bind(this)(transport, this.element);
+  },
+  onEnterEditMode: function() {},
+  onLeaveEditMode: function() {},
+  dispose: function() {
+    if (this.oldInnerHTML) {
+      this.element.innerHTML = this.oldInnerHTML;
+    }
+    this.leaveEditMode();
+    Event.stopObserving(this.element, 'click', this.onclickListener);
+    Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
+    Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
+    if (this.options.externalControl) {
+      Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
+      Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
+      Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
+    }
+  }
+};
+
+Ajax.InPlaceCollectionEditor = Class.create();
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
+  createEditField: function() {
+    if (!this.cached_selectTag) {
+      var selectTag = document.createElement("select");
+      var collection = this.options.collection || [];
+      var optionTag;
+      collection.each(function(e,i) {
+        optionTag = document.createElement("option");
+        optionTag.value = (e instanceof Array) ? e[0] : e;
+        if((typeof this.options.value == 'undefined') && 
+          ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
+        if(this.options.value==optionTag.value) optionTag.selected = true;
+        optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
+        selectTag.appendChild(optionTag);
+      }.bind(this));
+      this.cached_selectTag = selectTag;
+    }
+
+    this.editField = this.cached_selectTag;
+    if(this.options.loadTextURL) this.loadExternalText();
+    this.form.appendChild(this.editField);
+    this.options.callback = function(form, value) {
+      return "value=" + encodeURIComponent(value);
+    }
+  }
+});
+
+// Delayed observer, like Form.Element.Observer, 
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create();
+Form.Element.DelayedObserver.prototype = {
+  initialize: function(element, delay, callback) {
+    this.delay     = delay || 0.5;
+    this.element   = $(element);
+    this.callback  = callback;
+    this.timer     = null;
+    this.lastValue = $F(this.element); 
+    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
+  },
+  delayedListener: function(event) {
+    if(this.lastValue == $F(this.element)) return;
+    if(this.timer) clearTimeout(this.timer);
+    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+    this.lastValue = $F(this.element);
+  },
+  onTimerEvent: function() {
+    this.timer = null;
+    this.callback(this.element, $F(this.element));
+  }
+};
Index: /sandbox/workflow/branches/993/js/adminjobs/actions.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminjobs/actions.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminjobs/actions.js	(revision 795)
@@ -0,0 +1,325 @@
+function editJob(jobObjectJason)
+{
+	clearForm();
+	$('saving').hide();
+	$('actions').show();
+	Effect.BlindUp('jobList');
+	var jobObject = $H(jobObjectJason);
+	loadJobInfo(jobObject);
+	Effect.BlindDown('jobForm');
+}
+
+function clearForm()
+{
+	var dateObject = new Date();
+	$('jobID').value = '';
+	$('name').value = '';
+	$('_description').value = '';
+	$('active').checked = true;
+	$('startDate').value = ((dateObject.getDate() < 10) ? '0' + dateObject.getDate() : dateObject.getDate()) + '/' + ((dateObject.getMonth() < 10) ? '0' + (dateObject.getMonth()+1) : (dateObject.getMonth() + 1)) + '/' + dateObject.getFullYear();
+	$('executionTime_Hour').value = ((dateObject.getHours() < 10) ? '0' + dateObject.getHours() : dateObject.getHours());
+	$('executionTime_Minute').value = ((dateObject.getMinutes() < 10) ? '0' + dateObject.getMinutes() : dateObject.getMinutes());
+	$('repeatJob').checked = false;
+	$('dateType_0').checked = true;
+	$('absoluteDateIntervalValue').value = 1;
+	$('absoluteDateIntervalUnity').value = DateUnity.DAY;
+	$('weekDateIntervalValue').value = 1;
+	for (var i = 0; i < 7; i++)
+		$('weekDateDay_' + i).checked = false;
+	$('relativeDateIntervalValue').value = 1;
+	$('relativeDateMonthOffset').value = 1;
+}
+
+function loadJobInfo(jobObject)
+{
+	$('jobID').value = jobObject['job_id'];
+	$('name').value = jobObject['name'];
+	$('_description').value = jobObject['description'];
+	$('active').checked = (jobObject['active'] == 't')
+	var dateTime = jobObject['time_start'].split(' ');
+	var datePart = dateTime[0].split('-');
+	var timePart = dateTime[1].split(':');
+	$('startDate').value = datePart[2] + '/' + datePart[1] + '/' + datePart[0];
+	$('executionTime_Hour').value = timePart[0];
+	$('executionTime_Minute').value = timePart[1];
+	$('repeatJob').checked = (parseInt(jobObject['interval_unity']) != DateUnity.NONE);
+
+	$('dateType_' + jobObject['date_type']).checked = true;
+	if (jobObject['interval_value'] == 0)
+		jobObject['interval_value'] = 1;
+	if (parseInt(jobObject['interval_unity']) == DateUnity.NONE)
+		jobObject['interval_unity'] = DateUnity.DAY;
+
+	switch (parseInt(jobObject['date_type']))
+	{
+		case DateType.ABSOLUTE_DATE:
+			loadJobInfoAbsoluteDate(jobObject);
+			break;
+
+		case DateType.WEEK_DATE:
+			loadJobInfoWeekDate(jobObject);
+			break;
+
+		case DateType.RELATIVE_DATE:
+			loadJobInfoRelativeDate(jobObject);
+			break;
+	}
+	clickRepeatJob();
+}
+
+function loadJobInfoAbsoluteDate(jobObject)
+{
+	$('absoluteDateIntervalValue').value = jobObject['interval_value'];
+	$('absoluteDateIntervalUnity').value = jobObject['interval_unity'];
+}
+
+function loadJobInfoWeekDate(jobObject)
+{
+	$('weekDateIntervalValue').value = jobObject['interval_value'];
+	var weekDays = parseInt(jobObject['week_days']);
+	for (var i = 0; i < 7; i++)
+		if (weekDays & Math.pow(2, i))
+			$('weekDateDay_' + i).checked = true;
+}
+
+function loadJobInfoRelativeDate(jobObject)
+{
+	$('relativeDateIntervalValue').value = jobObject['interval_value'];
+	$('relativeDateMonthOffset').value = jobObject['month_offset'];
+}
+
+function saveJob()
+{
+	function resultSaveJob(data)
+	{
+		if (!checkError(data))
+		{
+			resultLoadJobList(data);
+			Effect.BlindUp('jobForm');
+			Effect.BlindDown('jobList');
+		}
+		else
+		{
+			$('saving').hide();
+			$('actions').show();
+		}
+	}
+
+	var startDate = $F('startDate').split('/');
+	var intervalValue;
+	var intervalUnity;
+	if ($F('repeatJob') != 'on')
+	{
+		intervalValue = 0;
+		intervalUnity = DateUnity.NONE;
+	}
+	else
+	{
+		switch (getSelectedDateType())
+		{
+			case DateType.ABSOLUTE_DATE:
+				intervalValue = $F('absoluteDateIntervalValue');
+				intervalUnity = $F('absoluteDateIntervalUnity');
+				break;
+
+			case DateType.WEEK_DATE:
+				intervalValue = $F('weekDateIntervalValue');
+				intervalUnity = DateUnity.WEEK;
+				break;
+
+			case DateType.RELATIVE_DATE:
+				intervalValue = $F('relativeDateIntervalValue');
+				intervalUnity = DateUnity.MONTH;
+				break;
+		}
+	}
+	var weekDays = 0;
+	var currentWeekDay;
+	for (var i = 0; i < 7; i++)
+	{
+		currentWeekDay = $F('weekDateDay_' + i);
+		if (currentWeekDay != null)
+			weekDays = weekDays | currentWeekDay;
+	}
+
+	var params =
+	{
+		jobID: $F('jobID'),
+		processID: $F('processID'),
+		name: escape($F('name')),
+		description : escape($F('_description')),
+		timeStart: escape(startDate[2] + '-' + startDate[1] + '-' + startDate[0] + ' ' + $F('executionTime_Hour') + ':' + $F('executionTime_Minute') + ':00'),
+		intervalValue: intervalValue,
+		intervalUnity: intervalUnity,
+		dateType: getSelectedDateType(),
+		weekDays: weekDays,
+		monthOffset: $F('relativeDateMonthOffset'),
+		active: ($F('active') == 'on')
+	};
+
+	$('actions').hide();
+	$('saving').show();
+
+	cExecute('$this.bo_adminjobs.saveJob', resultSaveJob, $H(params).toQueryString());
+}
+
+function removeJob(jobID)
+{
+	function resultRemoveJob(data)
+	{
+		if (checkError(data))
+			return;
+		Effect.Fade('job_' + jobID);
+	}
+
+	cExecute('$this.bo_adminjobs.removeJob', resultRemoveJob, 'jobID=' + jobID);
+}
+
+function newJob()
+{
+	clearForm();
+	clickRepeatJob();
+	$('saving').hide();
+	$('actions').show();
+	Effect.BlindUp('jobList');
+	Effect.BlindDown('jobForm');
+}
+
+function loadLogs(jobID, p_page)
+{
+	function resultLoadLogs(data)
+	{
+		if (checkError(data))
+			return;
+		var content = '<h2>Job: ' + $('job_' + jobID).childNodes[1].firstChild.innerHTML + '</h2>';
+		content += '<button onclick="Effect.BlindUp(\'logList\'); Effect.BlindDown(\'jobList\'); return false;">Voltar</button><br/><br/>';
+
+		if (data['logs'].length > 0)
+		{
+			var pagingLinks = '';
+			if (data['pagingLinks'])
+			{
+				var pagingSize = data['pagingLinks'].length;
+				for (var i = 0; i < pagingSize; i++)
+				{
+					if (data['pagingLinks'][i]['do_link'] == true)
+						pagingLinks += '<a href="javascript:loadLogs(' + jobID + ', ' + data['pagingLinks'][i]['p_page'] + ');">' + data['pagingLinks'][i]['name'] + '</a>&nbsp;';
+					else
+						pagingLinks += '<strong>' + data['pagingLinks'][i]['name'] + '</strong>&nbsp;';
+				}
+			}
+			content += pagingLinks;
+
+			var trClasses = new Array();
+			trClasses[JobStatus.JOB_SUCCESS] = 'success';
+			trClasses[JobStatus.JOB_FAIL] = 'fail';
+			trClasses[JobStatus.FAIL] = 'fail';
+			trClasses[JobStatus.ERROR] = 'error';
+			trClasses[JobStatus.UNKNOWN] = 'unknown';
+
+			content += '<table class="logList" id="logListTable">';
+			var currentDate;
+			var currentLog;
+			for (var i = 0; i < data['logs'].length; i++)
+			{
+				currentLog = data['logs'][i];
+				currentDate = currentLog['human_date_time'] ? currentLog['human_date_time'] : currentLog['date_time'];
+				content += '<tr class="' + trClasses[parseInt(currentLog['status'])] + '">';
+				content += '<td class="logListIcon">&nbsp;</td>'
+				content += '<td class="logDate" title="' + currentLog['date_time'] + '"><center>' + currentDate.replace(/ /, '<br/>') + '</center></td>';
+				content += '<td class="logResult">' + currentLog['result'] + '</td>';
+				content += '</tr>';
+			}
+			content += '</table>';
+		}
+		else
+		{
+			content += '<center>Este Job ainda não foi executado e, portanto, não possui entradas de log.</center><br/>';
+		}
+
+		content += '<br/><button onclick="Effect.BlindUp(\'logList\'); Effect.BlindDown(\'jobList\'); return false;">Voltar</button>';
+
+		$('logList').innerHTML = content;
+		if ($('jobList').visible())
+			Effect.BlindUp('jobList');
+		Effect.BlindDown('logList');
+	}
+
+	if (!p_page)
+		p_page = 0;
+
+	if ($('logList').visible())
+	{
+		function recall()
+		{
+			loadLogs(jobID, p_page);
+		}
+
+		new Effect.BlindUp($('logList'), {afterFinish: recall});
+		return;
+	}
+
+	cExecute('$this.bo_adminjobs.loadLogs', resultLoadLogs, 'jobID=' + jobID + '&p_page=' + p_page);
+}
+
+function toggleActive(jobID)
+{
+	function resultToggleActive(data)
+	{
+		if (!checkError(data))
+		{
+			Effect.BlindUp('jobList', {
+					afterFinish: function()
+					{
+						resultLoadJobList(data);
+						Effect.BlindDown('jobList');
+					}
+				});
+		}
+	}
+
+	cExecute('$this.bo_adminjobs.toggleActive', resultToggleActive, 'jobID=' + jobID + '&processID=' + $F('processID'));
+}
+
+function runJob(jobID)
+{
+	function resultRunJob(data)
+	{
+		if (checkError(data))
+			return;
+		var content = '<h2>Job: ' + $('job_' + jobID).childNodes[1].firstChild.innerHTML + '</h2>';
+		if (data['output']['messages'])
+		{
+			content += '<table class="jobResult">';
+			content += '<tr><th>Mensagens</th></tr>';
+			content += '<tr><td><pre>' + data['output']['messages'].join("\n\n") + '</pre></td></tr>';
+			content += '</table><br/><br/>';
+		}
+
+		if (data['output']['default'])
+		{
+			content += '<table class="jobResult">';
+			content += '<tr><th>Saída Default</th></tr>';
+			content += '<tr><td><pre>' + data['output']['default'] + '</pre></td></tr>';
+			content += '</table><br/><br/>';
+		}
+
+		if (data['output']['error'])
+		{
+			content += '<table class="jobResult">';
+			content += '<tr><th>Saída de Erro</th></tr>';
+			content += '<tr><td><pre>' + data['output']['error'] + '</pre></td></tr>';
+			content += '</table><br/><br/>';
+		}
+
+		if (!data['output']['default'] && !data['output']['error'])
+			content += '<i>Nenhuma saída foi produzida pelo job</i><br/><br/>';
+		content += '<button onclick="Effect.BlindUp(\'jobResult\'); Effect.BlindDown(\'jobList\'); return false;">Voltar</button>';
+
+		$('jobResult').innerHTML = content;
+		Effect.BlindUp('jobList');
+		Effect.BlindDown('jobResult');
+	}
+
+	cExecute('$this.bo_adminjobs.runJob', resultRunJob, 'jobID=' + jobID);
+}
Index: /sandbox/workflow/branches/993/js/adminjobs/interface.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminjobs/interface.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminjobs/interface.js	(revision 795)
@@ -0,0 +1,86 @@
+function addEventWatchers()
+{
+	$('repeatJob').observe('click', clickRepeatJob);
+	for (var i = 0; i < 3; i++)
+		$('dateType_' + i).observe('click', clickRepeatJob);
+}
+
+function getSelectedDateType()
+{
+	for (var i = 0; i < 3; i++)
+		if ($F('dateType_' + i) != null)
+			return i;
+
+}
+
+function clickRepeatJob(event)
+{
+	for (var i = 0; i < 3; i++)
+	{
+		$('repeatDate_' + i).hide();
+		var obj = $('date_' + i);
+		if (obj)
+			obj.hide();
+	}
+
+	var selectedDateType = getSelectedDateType();
+	var obj = $('date_' + selectedDateType);
+	if (obj)
+		obj.show();
+
+	if ($F('repeatJob') == 'on')
+		$('repeatDate_' + selectedDateType).show();
+}
+
+function loadJobList()
+{
+	$('jobList').innerHTML = '<img src="workflow/templateFile.php?file=images/loading.gif"/> Carregando lista de jobs ...';
+
+	cExecute("$this.bo_adminjobs.loadJobs", resultLoadJobList, "processID=" + $F('processID'));
+}
+
+function resultLoadJobList(data)
+{
+	if (checkError(data))
+		return;
+
+	var content = '';
+	if (data.length > 0)
+	{
+		content += '<table class="jobList">';
+		for (var i = 0; i < data.length; i++)
+		{
+			var dataHash = new Hash();
+			for (j in data[i])
+				if (typeof data[i][j] != 'function')
+					dataHash[j] = data[i][j];
+
+			content += '<tr id="job_' + data[i]['job_id'] + '">';
+			content += '<td class="jobListIcon"><a href="javascript:void(0)" onclick="if (confirm(\'Tem certeza que deseja ' + ((data[i]['active'] == 't') ? 'desativar' : 'ativar') + ' o Job?\')) toggleActive(' + data[i]['job_id'] + '); return false;" title="Clique aqui para ' + ((data[i]['active'] == 't') ? 'desativar' : 'ativar') + ' o Job"><img src="workflow/templateFile.php?file=images/' + ((data[i]['active'] == 't') ? 'apply.png' : 'button_cancel.png') + '"/></a></td>';
+			content += '<td>';
+			content += '<h1>' + data[i]['name'] + '</h1>';
+			content += '<h3>' + getRepetitionSummary(data[i]) + '</h3>';
+			content += '</td>';
+
+			/* ações */
+			content += '<td class="jobListActions">';
+			content += '<a href="javascript:void(0)" onclick="if (confirm(\'Tem certeza que deseja executar este Job\')) runJob(' + data[i]['job_id'] + '); return false;"><img src="workflow/templateFile.php?file=images/process.png" title="Executar Job" alt="Executar Job"/></a>';
+			content += '<a href="javascript:void(0)" onclick="editJob(' + dataHash.customInspect() + ');"><img src="workflow/templateFile.php?file=images/edit.png" title="Editar Job" alt="Editar Job"/></a>';
+			content += '<a href="javascript:void(0)" onclick="loadLogs(' + data[i]['job_id'] + ', 0); return false;"><img src="workflow/templateFile.php?file=images/log.png"/ title="Ver Logs" alt="Ver Logs"></a>';
+			content += '&nbsp;&nbsp;&nbsp;';
+			content += '<a href="javascript:void(0)" onclick="if (confirm(\'Tem certeza que deseja remover este Job?\')) removeJob(' + data[i]['job_id'] + '); return false;"><img src="workflow/templateFile.php?file=images/remove.png" title="Excluir Job" alt="Excluir Job"/></a>';
+			content += '</td>';
+
+			content += '</tr>';
+		}
+		content += '</table><br/>';
+	}
+	else
+	{
+		content += '<br/><br/><br/>';
+		content += '<center><b>Não existem Jobs cadastrados neste Processo</b></center>';
+		content += '<br/><br/><br/>';
+	}
+	content += '<ul class="horizontalMenu"><li><a href="javascript:void(0)" onclick="newJob(); return false;"><img src="workflow/templateFile.php?file=images/new_job.png" width="20"> Novo</a></li></ul>';
+	$('jobList').innerHTML = content;
+}
Index: /sandbox/workflow/branches/993/js/adminjobs/utils.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminjobs/utils.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminjobs/utils.js	(revision 795)
@@ -0,0 +1,257 @@
+var DateUnity =
+	{
+		YEAR: 0,
+		MONTH: 1,
+		WEEK: 2,
+		DAY: 3,
+		HOUR: 4,
+		MINUTE: 5,
+		NONE: 6
+	};
+
+var DateType =
+	{
+		ABSOLUTE_DATE: 0,
+		WEEK_DATE: 1,
+		RELATIVE_DATE: 2
+	};
+
+var WeekDays =
+	{
+		SUNDAY: 1,
+		MONDAY: 2,
+		TUESDAY: 4,
+		WEDNESDAY: 8,
+		THURSDAY: 16,
+		FRIDAY: 32,
+		SATURDAY: 64
+	};
+
+var JobStatus =
+	{
+		JOB_SUCCESS: 0,
+		JOB_FAIL: 1,
+		FAIL: 2,
+		ERROR: 3,
+		UNKNOWN: 4
+	};
+
+function getRepetitionSummary(jobInfo)
+{
+	switch (parseInt(jobInfo['date_type']))
+	{
+		case DateType.ABSOLUTE_DATE:
+			return getRepetitionSummaryAbsoluteDate(jobInfo);
+
+		case DateType.WEEK_DATE:
+			return getRepetitionSummaryWeekDate(jobInfo);
+
+		case DateType.RELATIVE_DATE:
+			return getRepetitionSummaryRelativeDate(jobInfo);
+	}
+}
+
+function getRepetitionSummaryAbsoluteDate(jobInfo)
+{
+	var output = 'Executado';
+
+	if (parseInt(jobInfo['interval_unity']) == DateUnity.NONE)
+	{
+		var data = jobInfo['time_start'].split(' ')[0].split('-');
+		output += ' no dia ' + data[2] + '/' + data[1] + '/' + data[0];
+	}
+	else
+	{
+		output += ' uma vez';
+		var plural = (jobInfo['interval_value'] > 1);
+		if ((parseInt(jobInfo['interval_unity']) == DateUnity.HOUR) && (jobInfo['interval_value'] == 2))
+			output += ' a cada duas';
+		else
+			output += plural ? ' a cada ' + jobInfo['interval_value'] : ' por';
+		switch (parseInt(jobInfo['interval_unity']))
+		{
+			case DateUnity.YEAR:
+				output += plural ? ' anos' : ' ano';
+				break;
+
+			case DateUnity.MONTH:
+				output += plural ? ' meses' : ' mês';
+				break;
+
+			case DateUnity.DAY:
+				output += plural ? ' dias' : ' dia';
+				break;
+
+			case DateUnity.HOUR:
+				output += plural ? ' horas' : ' hora';
+				break;
+
+			case DateUnity.MINUTE:
+				output += plural ? ' minutos' : ' minuto';
+				break;
+		}
+	}
+	return output;
+}
+
+function getRepetitionSummaryWeekDate(jobInfo)
+{
+	var output = 'Executado';
+
+	function numberToWeekDays(num, plural)
+	{
+		var output = '';
+		if (num & WeekDays.SUNDAY)
+			output += 'domingo' + (plural ? 's ' : ' ');
+
+		if (plural)
+			output = (output == '') ? 'às;' : 'aos;' + output;
+
+		if (num & WeekDays.MONDAY)
+			output += 'segunda' + (plural ? 's ' : ' ');
+
+		if (num & WeekDays.TUESDAY)
+			output += 'terça' + (plural ? 's ' : ' ');
+
+		if (num & WeekDays.WEDNESDAY)
+			output += 'quarta' + (plural ? 's ' : ' ');
+
+		if (num & WeekDays.THURSDAY)
+			output += 'quinta' + (plural ? 's ' : ' ');
+
+		if (num & WeekDays.FRIDAY)
+			output += 'sexta' + (plural ? 's ' : ' ');
+
+		if (num & WeekDays.SATURDAY)
+			output += 'sábado' + (plural ? 's ' : ' ');
+
+		output = output.substr(0, output.length-1).replace(/ /g, ', ').replace(/;/g, ' ');
+
+		var lastComma = output.lastIndexOf(', ');
+		if (lastComma != -1)
+			output = output.substr(0, lastComma) + ' e' + output.substr(lastComma + 1);
+
+		return output;
+
+	}
+
+	var plural = (parseInt(jobInfo['interval_unity']) == DateUnity.WEEK);
+	switch (parseInt(jobInfo['week_days']))
+	{
+		case 0:
+			return 'Não é executado';
+			break;
+
+		case 62:
+			output += plural ? ' nos dias da semana' : ' nos dias';
+			break;
+
+		case 65:
+			output += plural ? ' nos finais de semana' : ' no fim de semana';
+			break;
+
+		case 127:
+			output += ' todos os dias da semana';
+			break;
+
+		default:
+			output += ' ' + numberToWeekDays(jobInfo['week_days'], plural);
+	}
+
+	if (parseInt(jobInfo['interval_unity']) == DateUnity.NONE)
+	{
+		var data = jobInfo['time_start'].split(' ')[0].split('-');
+		output += ' da semana do dia ' + data[2] + '/' + data[1] + '/' + data[0];
+		return output;
+	}
+
+	switch (parseInt(jobInfo['interval_value']))
+	{
+		case 1:
+			break;
+
+		case 2:
+			output += ' a cada duas semanas';
+			break;
+
+		default:
+			output += ' a cada ' + jobInfo['interval_value'] + ' semanas';
+	}
+
+	return output;
+}
+
+function getRepetitionSummaryRelativeDate(jobInfo)
+{
+	var output = 'Executado';
+
+	switch (parseInt(jobInfo['month_offset']))
+	{
+		case 1:
+			output += ' no último dia do mês';
+			break;
+
+		case 2:
+			output += ' no penúltimo dia do mês';
+			break;
+
+		case 3:
+			output += ' no antepenúltimo dia do mês';
+			break;
+
+		default:
+			output += ' quando faltar ' + jobInfo['month_offset'] + ' dias para o fim do mês';
+	}
+
+	if (parseInt(jobInfo['interval_unity']) == DateUnity.NONE)
+	{
+		var data = jobInfo['time_start'].split(' ')[0].split('-');
+		output += ' ' + data[1] + '/' + data[0];
+		return output;
+	}
+
+	if (jobInfo['interval_value'] == 1)
+		return output;
+
+	switch (parseInt(jobInfo['interval_value']))
+	{
+		case 2:
+			output += '. Repete bimestralmente';
+			break;
+
+		case 3:
+			output += '. Repete trimestralmente';
+			break;
+
+		case 6:
+			output += '. Repete semestralmente';
+			break;
+
+		case 12:
+			output += '. Repete anualmente';
+			break;
+
+		default:
+			output += '. Repete a cada ' + jobInfo['interval_value'] + ' meses';
+	}
+
+	return output;
+}
+
+function checkError(data)
+{
+	if (data)
+	{
+		if (data['error'])
+		{
+			if (typeof(data['error']) == 'string')
+				alert(data['error']);
+			else
+				if (typeof(data['error']) == 'object')
+					alert(data['error'].join("\n"));
+				return true;
+			}
+		}
+
+	return false;
+}
Index: /sandbox/workflow/branches/993/js/jscalendar/calendar-input.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscalendar/calendar-input.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscalendar/calendar-input.js	(revision 795)
@@ -0,0 +1,42 @@
+function formatCalendarInput(campo, e)
+{
+	var key = '';
+	var valor = '';
+	var valorLimpo = '';
+	var len = 0;
+	var lenLimpo = 0;
+	var strCheck = '0123456789';
+
+	/* permite algumas teclas */
+	var whichCode = (e.which) ? e.which : e.keyCode;
+	if (whichCode == 13)
+		return true;  // Enter
+	if (whichCode == 8)
+		return true;  // Delete
+	if (whichCode == 0)
+		return true;  // Tab
+
+	key = String.fromCharCode(whichCode);
+	if (strCheck.indexOf(key) == -1)
+		return false;  // não é um caractere válido
+	
+	valor = campo.value;
+	len = valor.length;
+
+	for (var i = 0; i < len; i++)
+		if (strCheck.indexOf(valor.charAt(i)) != -1)
+			valorLimpo += valor.charAt(i);
+	
+	valorLimpo += key;
+	lenLimpo = valorLimpo.length;
+	var valorNovo = '';
+	for (var i = 0; i < lenLimpo; i++)
+	{
+		valorNovo += valorLimpo.charAt(i);
+		if ((i == 1) || (i == 3))
+			valorNovo += '/';
+	}
+
+	campo.value = valorNovo;
+	return false;
+}
Index: /sandbox/workflow/branches/993/js/jscalendar/calendar-setup.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscalendar/calendar-setup.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscalendar/calendar-setup.js	(revision 795)
@@ -0,0 +1,208 @@
+/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
+ * ---------------------------------------------------------------------------
+ *
+ * The DHTML Calendar
+ *
+ * Details and latest version at:
+ * http://dynarch.com/mishoo/calendar.epl
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ *
+ * This file defines helper functions for setting up the calendar.  They are
+ * intended to help non-programmers get a working calendar on their site
+ * quickly.  This script should not be seen as part of the calendar.  It just
+ * shows you what one can do with the calendar, while in the same time
+ * providing a quick and simple method for setting it up.  If you need
+ * exhaustive customization of the calendar creation process feel free to
+ * modify this code to suit your needs (this is recommended and much better
+ * than modifying calendar.js itself).
+ */
+
+
+/**
+ *  This function "patches" an input field (or other element) to use a calendar
+ *  widget for date selection.
+ *
+ *  The "params" is a single object that can have the following properties:
+ *
+ *    prop. name   | description
+ *  -------------------------------------------------------------------------------------------------
+ *   inputField    | the ID of an input field to store the date
+ *   displayArea   | the ID of a DIV or other element to show the date
+ *   button        | ID of a button or other element that will trigger the calendar
+ *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
+ *   ifFormat      | date format that will be stored in the input field
+ *   daFormat      | the date format that will be used to display the date in displayArea
+ *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
+ *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
+ *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
+ *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
+ *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
+ *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
+ *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
+ *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
+ *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
+ *   onClose       | function that gets called when the calendar is closed.  [default]
+ *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
+ *   date          | the date that the calendar will be initially displayed to
+ *   showsTime     | default: false; if true the calendar will include a time selector
+ *   timeFormat    | the time format; can be "12" or "24", default is "12"
+ *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
+ *   step          | configures the step of the years in drop-down boxes; default: 2
+ *   position      | configures the calendar absolute position; default: null
+ *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
+ *   showOthers    | if "true" (but default: "false") it will show days from other months too
+ *
+ *  None of them is required, they all have default values.  However, if you
+ *  pass none of "inputField", "displayArea" or "button" you'll get a warning
+ *  saying "nothing to setup".
+ */
+Calendar.setup = function (params) {
+	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };
+
+	param_default("inputField",     null);
+	param_default("displayArea",    null);
+	param_default("button",         null);
+	param_default("eventName",      "click");
+	param_default("ifFormat",       "%d/%m/%Y");
+	param_default("daFormat",       "%d/%m/%Y");
+	param_default("singleClick",    true);
+	param_default("disableFunc",    null);
+	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
+	param_default("dateText",       null);
+	param_default("firstDay",       null);
+	param_default("align",          "Br");
+	param_default("range",          [1900, 2999]);
+	param_default("weekNumbers",    true);
+	param_default("flat",           null);
+	param_default("flatCallback",   null);
+	param_default("onSelect",       null);
+	param_default("onClose",        null);
+	param_default("onUpdate",       null);
+	param_default("date",           null);
+	param_default("showsTime",      false);
+	param_default("timeFormat",     "24");
+	param_default("electric",       true);
+	param_default("step",           2);
+	param_default("position",       null);
+	param_default("cache",          false);
+	param_default("showOthers",     false);
+	param_default("multiple",       null);
+
+	var tmp = ["inputField", "displayArea", "button"];
+	for (var i in tmp) {
+		if (typeof params[tmp[i]] == "string") {
+			params[tmp[i]] = document.getElementById(params[tmp[i]]);
+		}
+	}
+	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
+		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
+		return false;
+	}
+
+	function onSelect(cal) {
+		var p = cal.params;
+		var update = (cal.dateClicked || p.electric);
+		if (update && p.inputField) {
+			p.inputField.value = cal.date.print(p.ifFormat);
+			if (typeof p.inputField.onchange == "function")
+				p.inputField.onchange();
+		}
+		if (update && p.displayArea)
+			p.displayArea.innerHTML = cal.date.print(p.daFormat);
+		if (update && typeof p.onUpdate == "function")
+			p.onUpdate(cal);
+		if (update && p.flat) {
+			if (typeof p.flatCallback == "function")
+				p.flatCallback(cal);
+		}
+		if (update && p.singleClick && cal.dateClicked)
+			cal.callCloseHandler();
+	};
+
+	if (params.flat != null) {
+		if (typeof params.flat == "string")
+			params.flat = document.getElementById(params.flat);
+		if (!params.flat) {
+			alert("Calendar.setup:\n  Flat specified but can't find parent.");
+			return false;
+		}
+		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
+		cal.showsOtherMonths = params.showOthers;
+		cal.showsTime = params.showsTime;
+		cal.time24 = (params.timeFormat == "24");
+		cal.params = params;
+		cal.weekNumbers = params.weekNumbers;
+		cal.setRange(params.range[0], params.range[1]);
+		cal.setDateStatusHandler(params.dateStatusFunc);
+		cal.getDateText = params.dateText;
+		if (params.ifFormat) {
+			cal.setDateFormat(params.ifFormat);
+		}
+		if (params.inputField && typeof params.inputField.value == "string") {
+			cal.parseDate(params.inputField.value);
+		}
+		cal.create(params.flat);
+		cal.show();
+		return false;
+	}
+
+	var triggerEl = params.button || params.displayArea || params.inputField;
+	triggerEl["on" + params.eventName] = function() {
+		var dateEl = params.inputField || params.displayArea;
+		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
+		var mustCreate = false;
+		var cal = window.calendar;
+		if (dateEl)
+		{
+			/* corrige problemas relacionados ao horÃ¡rio de verÃ£o */
+			var dateElValue = dateEl.value || dateEl.innerHTML;
+			if (dateFmt.indexOf('%H') == -1)
+			{
+				dateFmt += ' %H:%M';
+				dateElValue += ' 06:42';
+			}
+			params.date = Date.parseDate(dateElValue, dateFmt);
+		}
+		if (!(cal && params.cache)) {
+			window.calendar = cal = new Calendar(params.firstDay,
+							     params.date,
+							     params.onSelect || onSelect,
+							     params.onClose || function(cal) { cal.hide(); });
+			cal.showsTime = params.showsTime;
+			cal.time24 = (params.timeFormat == "24");
+			cal.weekNumbers = params.weekNumbers;
+			mustCreate = true;
+		} else {
+			if (params.date)
+				cal.setDate(params.date);
+			cal.hide();
+		}
+		if (params.multiple) {
+			cal.multiple = {};
+			for (var i = params.multiple.length; --i >= 0;) {
+				var d = params.multiple[i];
+				var ds = d.print("%Y%m%d");
+				cal.multiple[ds] = d;
+			}
+		}
+		cal.showsOtherMonths = params.showOthers;
+		cal.yearStep = params.step;
+		cal.setRange(params.range[0], params.range[1]);
+		cal.params = params;
+		cal.setDateStatusHandler(params.dateStatusFunc);
+		cal.getDateText = params.dateText;
+		cal.setDateFormat(dateFmt);
+		if (mustCreate)
+			cal.create();
+		cal.refresh();
+		if (!params.position)
+			cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
+		else
+			cal.showAt(params.position[0], params.position[1]);
+		return false;
+	};
+
+	return cal;
+};
Index: /sandbox/workflow/branches/993/js/jscalendar/calendar-en.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscalendar/calendar-en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscalendar/calendar-en.js	(revision 795)
@@ -0,0 +1,127 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible.  We strongly believe that
+// Unicode is the answer to a real internationalized world.  Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary.  We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+//   Calendar._SDN_len = N; // short day name length
+//   Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ "Sun");
+
+// First day of the week. "0" means display Sunday first, "1" means display
+// Monday first, etc.
+Calendar._FD = 0;
+
+// full month names
+Calendar._MN = new Array
+("January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "About the calendar";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Date selection:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
+"- Hold mouse button on any of the above buttons for faster selection.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Time selection:\n" +
+"- Click on any of the time parts to increase it\n" +
+"- or Shift-click to decrease it\n" +
+"- or click and drag for faster selection.";
+
+Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
+Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
+Calendar._TT["GO_TODAY"] = "Go Today";
+Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
+Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
+Calendar._TT["SEL_DATE"] = "Select date";
+Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
+Calendar._TT["PART_TODAY"] = " (today)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Display %s first";
+
+// This may be locale-dependent.  It specifies the week-end days, as an array
+// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Close";
+Calendar._TT["TODAY"] = "Today";
+Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "Time:";
Index: /sandbox/workflow/branches/993/js/jscalendar/calendar.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscalendar/calendar.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscalendar/calendar.js	(revision 795)
@@ -0,0 +1,1806 @@
+/*  Copyright Mihai Bazon, 2002-2005  |  www.bazon.net/mishoo
+ * -----------------------------------------------------------
+ *
+ * The DHTML Calendar, version 1.0 "It is happening again"
+ *
+ * Details and latest version at:
+ * www.dynarch.com/projects/calendar
+ *
+ * This script is developed by Dynarch.com.  Visit us at www.dynarch.com.
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ */
+
+
+/** The Calendar object constructor. */
+Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
+	// member variables
+	this.activeDiv = null;
+	this.currentDateEl = null;
+	this.getDateStatus = null;
+	this.getDateToolTip = null;
+	this.getDateText = null;
+	this.timeout = null;
+	this.onSelected = onSelected || null;
+	this.onClose = onClose || null;
+	this.dragging = false;
+	this.hidden = false;
+	this.minYear = 1970;
+	this.maxYear = 2050;
+	this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
+	this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
+	this.isPopup = true;
+	this.weekNumbers = true;
+	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
+	this.showsOtherMonths = false;
+	this.dateStr = dateStr;
+	this.ar_days = null;
+	this.showsTime = false;
+	this.time24 = true;
+	this.yearStep = 2;
+	this.hiliteToday = true;
+	this.multiple = null;
+	// HTML elements
+	this.table = null;
+	this.element = null;
+	this.tbody = null;
+	this.firstdayname = null;
+	// Combo boxes
+	this.monthsCombo = null;
+	this.yearsCombo = null;
+	this.hilitedMonth = null;
+	this.activeMonth = null;
+	this.hilitedYear = null;
+	this.activeYear = null;
+	// Information
+	this.dateClicked = false;
+
+	// one-time initializations
+	if (typeof Calendar._SDN == "undefined") {
+		// table of short day names
+		if (typeof Calendar._SDN_len == "undefined")
+			Calendar._SDN_len = 3;
+		var ar = new Array();
+		for (var i = 8; i > 0;) {
+			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
+		}
+		Calendar._SDN = ar;
+		// table of short month names
+		if (typeof Calendar._SMN_len == "undefined")
+			Calendar._SMN_len = 3;
+		ar = new Array();
+		for (var i = 12; i > 0;) {
+			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
+		}
+		Calendar._SMN = ar;
+	}
+};
+
+// ** constants
+
+/// "static", needed for event handlers.
+Calendar._C = null;
+
+/// detect a special case of "web browser"
+Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
+		   !/opera/i.test(navigator.userAgent) );
+
+Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
+
+/// detect Opera browser
+Calendar.is_opera = /opera/i.test(navigator.userAgent);
+
+/// detect KHTML-based browsers
+Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
+
+// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
+//        library, at some point.
+
+Calendar.getAbsolutePos = function(el) {
+	var SL = 0, ST = 0;
+	var is_div = /^div$/i.test(el.tagName);
+	if (is_div && el.scrollLeft)
+		SL = el.scrollLeft;
+	if (is_div && el.scrollTop)
+		ST = el.scrollTop;
+	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
+	if (el.offsetParent) {
+		var tmp = this.getAbsolutePos(el.offsetParent);
+		r.x += tmp.x;
+		r.y += tmp.y;
+	}
+	return r;
+};
+
+Calendar.isRelated = function (el, evt) {
+	var related = evt.relatedTarget;
+	if (!related) {
+		var type = evt.type;
+		if (type == "mouseover") {
+			related = evt.fromElement;
+		} else if (type == "mouseout") {
+			related = evt.toElement;
+		}
+	}
+	while (related) {
+		if (related == el) {
+			return true;
+		}
+		related = related.parentNode;
+	}
+	return false;
+};
+
+Calendar.removeClass = function(el, className) {
+	if (!(el && el.className)) {
+		return;
+	}
+	var cls = el.className.split(" ");
+	var ar = new Array();
+	for (var i = cls.length; i > 0;) {
+		if (cls[--i] != className) {
+			ar[ar.length] = cls[i];
+		}
+	}
+	el.className = ar.join(" ");
+};
+
+Calendar.addClass = function(el, className) {
+	Calendar.removeClass(el, className);
+	el.className += " " + className;
+};
+
+// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
+Calendar.getElement = function(ev) {
+	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
+	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
+		f = f.parentNode;
+	return f;
+};
+
+Calendar.getTargetElement = function(ev) {
+	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
+	while (f.nodeType != 1)
+		f = f.parentNode;
+	return f;
+};
+
+Calendar.stopEvent = function(ev) {
+	ev || (ev = window.event);
+	if (Calendar.is_ie) {
+		ev.cancelBubble = true;
+		ev.returnValue = false;
+	} else {
+		ev.preventDefault();
+		ev.stopPropagation();
+	}
+	return false;
+};
+
+Calendar.addEvent = function(el, evname, func) {
+	if (el.attachEvent) { // IE
+		el.attachEvent("on" + evname, func);
+	} else if (el.addEventListener) { // Gecko / W3C
+		el.addEventListener(evname, func, true);
+	} else {
+		el["on" + evname] = func;
+	}
+};
+
+Calendar.removeEvent = function(el, evname, func) {
+	if (el.detachEvent) { // IE
+		el.detachEvent("on" + evname, func);
+	} else if (el.removeEventListener) { // Gecko / W3C
+		el.removeEventListener(evname, func, true);
+	} else {
+		el["on" + evname] = null;
+	}
+};
+
+Calendar.createElement = function(type, parent) {
+	var el = null;
+	if (document.createElementNS) {
+		// use the XHTML namespace; IE won't normally get here unless
+		// _they_ "fix" the DOM2 implementation.
+		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
+	} else {
+		el = document.createElement(type);
+	}
+	if (typeof parent != "undefined") {
+		parent.appendChild(el);
+	}
+	return el;
+};
+
+// END: UTILITY FUNCTIONS
+
+// BEGIN: CALENDAR STATIC FUNCTIONS
+
+/** Internal -- adds a set of events to make some element behave like a button. */
+Calendar._add_evs = function(el) {
+	with (Calendar) {
+		addEvent(el, "mouseover", dayMouseOver);
+		addEvent(el, "mousedown", dayMouseDown);
+		addEvent(el, "mouseout", dayMouseOut);
+		if (is_ie) {
+			addEvent(el, "dblclick", dayMouseDblClick);
+			el.setAttribute("unselectable", true);
+		}
+	}
+};
+
+Calendar.findMonth = function(el) {
+	if (typeof el.month != "undefined") {
+		return el;
+	} else if (typeof el.parentNode.month != "undefined") {
+		return el.parentNode;
+	}
+	return null;
+};
+
+Calendar.findYear = function(el) {
+	if (typeof el.year != "undefined") {
+		return el;
+	} else if (typeof el.parentNode.year != "undefined") {
+		return el.parentNode;
+	}
+	return null;
+};
+
+Calendar.showMonthsCombo = function () {
+	var cal = Calendar._C;
+	if (!cal) {
+		return false;
+	}
+	var cal = cal;
+	var cd = cal.activeDiv;
+	var mc = cal.monthsCombo;
+	if (cal.hilitedMonth) {
+		Calendar.removeClass(cal.hilitedMonth, "hilite");
+	}
+	if (cal.activeMonth) {
+		Calendar.removeClass(cal.activeMonth, "active");
+	}
+	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
+	Calendar.addClass(mon, "active");
+	cal.activeMonth = mon;
+	var s = mc.style;
+	s.display = "block";
+	if (cd.navtype < 0)
+		s.left = cd.offsetLeft + "px";
+	else {
+		var mcw = mc.offsetWidth;
+		if (typeof mcw == "undefined")
+			// Konqueror brain-dead techniques
+			mcw = 50;
+		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
+	}
+	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
+};
+
+Calendar.showYearsCombo = function (fwd) {
+	var cal = Calendar._C;
+	if (!cal) {
+		return false;
+	}
+	var cal = cal;
+	var cd = cal.activeDiv;
+	var yc = cal.yearsCombo;
+	if (cal.hilitedYear) {
+		Calendar.removeClass(cal.hilitedYear, "hilite");
+	}
+	if (cal.activeYear) {
+		Calendar.removeClass(cal.activeYear, "active");
+	}
+	cal.activeYear = null;
+	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
+	var yr = yc.firstChild;
+	var show = false;
+	for (var i = 12; i > 0; --i) {
+		if (Y >= cal.minYear && Y <= cal.maxYear) {
+			yr.innerHTML = Y;
+			yr.year = Y;
+			yr.style.display = "block";
+			show = true;
+		} else {
+			yr.style.display = "none";
+		}
+		yr = yr.nextSibling;
+		Y += fwd ? cal.yearStep : -cal.yearStep;
+	}
+	if (show) {
+		var s = yc.style;
+		s.display = "block";
+		if (cd.navtype < 0)
+			s.left = cd.offsetLeft + "px";
+		else {
+			var ycw = yc.offsetWidth;
+			if (typeof ycw == "undefined")
+				// Konqueror brain-dead techniques
+				ycw = 50;
+			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
+		}
+		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
+	}
+};
+
+// event handlers
+
+Calendar.tableMouseUp = function(ev) {
+	var cal = Calendar._C;
+	if (!cal) {
+		return false;
+	}
+	if (cal.timeout) {
+		clearTimeout(cal.timeout);
+	}
+	var el = cal.activeDiv;
+	if (!el) {
+		return false;
+	}
+	var target = Calendar.getTargetElement(ev);
+	ev || (ev = window.event);
+	Calendar.removeClass(el, "active");
+	if (target == el || target.parentNode == el) {
+		Calendar.cellClick(el, ev);
+	}
+	var mon = Calendar.findMonth(target);
+	var date = null;
+	if (mon) {
+		date = new Date(cal.date);
+		if (mon.month != date.getMonth()) {
+			date.setMonth(mon.month);
+			cal.setDate(date);
+			cal.dateClicked = false;
+			cal.callHandler();
+		}
+	} else {
+		var year = Calendar.findYear(target);
+		if (year) {
+			date = new Date(cal.date);
+			if (year.year != date.getFullYear()) {
+				date.setFullYear(year.year);
+				cal.setDate(date);
+				cal.dateClicked = false;
+				cal.callHandler();
+			}
+		}
+	}
+	with (Calendar) {
+		removeEvent(document, "mouseup", tableMouseUp);
+		removeEvent(document, "mouseover", tableMouseOver);
+		removeEvent(document, "mousemove", tableMouseOver);
+		cal._hideCombos();
+		_C = null;
+		return stopEvent(ev);
+	}
+};
+
+Calendar.tableMouseOver = function (ev) {
+	var cal = Calendar._C;
+	if (!cal) {
+		return;
+	}
+	var el = cal.activeDiv;
+	var target = Calendar.getTargetElement(ev);
+	if (target == el || target.parentNode == el) {
+		Calendar.addClass(el, "hilite active");
+		Calendar.addClass(el.parentNode, "rowhilite");
+	} else {
+		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
+			Calendar.removeClass(el, "active");
+		Calendar.removeClass(el, "hilite");
+		Calendar.removeClass(el.parentNode, "rowhilite");
+	}
+	ev || (ev = window.event);
+	if (el.navtype == 50 && target != el) {
+		var pos = Calendar.getAbsolutePos(el);
+		var w = el.offsetWidth;
+		var x = ev.clientX;
+		var dx;
+		var decrease = true;
+		if (x > pos.x + w) {
+			dx = x - pos.x - w;
+			decrease = false;
+		} else
+			dx = pos.x - x;
+
+		if (dx < 0) dx = 0;
+		var range = el._range;
+		var current = el._current;
+		var count = Math.floor(dx / 10) % range.length;
+		for (var i = range.length; --i >= 0;)
+			if (range[i] == current)
+				break;
+		while (count-- > 0)
+			if (decrease) {
+				if (--i < 0)
+					i = range.length - 1;
+			} else if ( ++i >= range.length )
+				i = 0;
+		var newval = range[i];
+		el.innerHTML = newval;
+
+		cal.onUpdateTime();
+	}
+	var mon = Calendar.findMonth(target);
+	if (mon) {
+		if (mon.month != cal.date.getMonth()) {
+			if (cal.hilitedMonth) {
+				Calendar.removeClass(cal.hilitedMonth, "hilite");
+			}
+			Calendar.addClass(mon, "hilite");
+			cal.hilitedMonth = mon;
+		} else if (cal.hilitedMonth) {
+			Calendar.removeClass(cal.hilitedMonth, "hilite");
+		}
+	} else {
+		if (cal.hilitedMonth) {
+			Calendar.removeClass(cal.hilitedMonth, "hilite");
+		}
+		var year = Calendar.findYear(target);
+		if (year) {
+			if (year.year != cal.date.getFullYear()) {
+				if (cal.hilitedYear) {
+					Calendar.removeClass(cal.hilitedYear, "hilite");
+				}
+				Calendar.addClass(year, "hilite");
+				cal.hilitedYear = year;
+			} else if (cal.hilitedYear) {
+				Calendar.removeClass(cal.hilitedYear, "hilite");
+			}
+		} else if (cal.hilitedYear) {
+			Calendar.removeClass(cal.hilitedYear, "hilite");
+		}
+	}
+	return Calendar.stopEvent(ev);
+};
+
+Calendar.tableMouseDown = function (ev) {
+	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
+		return Calendar.stopEvent(ev);
+	}
+};
+
+Calendar.calDragIt = function (ev) {
+	var cal = Calendar._C;
+	if (!(cal && cal.dragging)) {
+		return false;
+	}
+	var posX;
+	var posY;
+	if (Calendar.is_ie) {
+		posY = window.event.clientY + document.body.scrollTop;
+		posX = window.event.clientX + document.body.scrollLeft;
+	} else {
+		posX = ev.pageX;
+		posY = ev.pageY;
+	}
+	cal.hideShowCovered();
+	var st = cal.element.style;
+	st.left = (posX - cal.xOffs) + "px";
+	st.top = (posY - cal.yOffs) + "px";
+	return Calendar.stopEvent(ev);
+};
+
+Calendar.calDragEnd = function (ev) {
+	var cal = Calendar._C;
+	if (!cal) {
+		return false;
+	}
+	cal.dragging = false;
+	with (Calendar) {
+		removeEvent(document, "mousemove", calDragIt);
+		removeEvent(document, "mouseup", calDragEnd);
+		tableMouseUp(ev);
+	}
+	cal.hideShowCovered();
+};
+
+Calendar.dayMouseDown = function(ev) {
+	var el = Calendar.getElement(ev);
+	if (el.disabled) {
+		return false;
+	}
+	var cal = el.calendar;
+	cal.activeDiv = el;
+	Calendar._C = cal;
+	if (el.navtype != 300) with (Calendar) {
+		if (el.navtype == 50) {
+			el._current = el.innerHTML;
+			addEvent(document, "mousemove", tableMouseOver);
+		} else
+			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
+		addClass(el, "hilite active");
+		addEvent(document, "mouseup", tableMouseUp);
+	} else if (cal.isPopup) {
+		cal._dragStart(ev);
+	}
+	if (el.navtype == -1 || el.navtype == 1) {
+		if (cal.timeout) clearTimeout(cal.timeout);
+		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
+	} else if (el.navtype == -2 || el.navtype == 2) {
+		if (cal.timeout) clearTimeout(cal.timeout);
+		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
+	} else {
+		cal.timeout = null;
+	}
+	return Calendar.stopEvent(ev);
+};
+
+Calendar.dayMouseDblClick = function(ev) {
+	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
+	if (Calendar.is_ie) {
+		document.selection.empty();
+	}
+};
+
+Calendar.dayMouseOver = function(ev) {
+	var el = Calendar.getElement(ev);
+	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
+		return false;
+	}
+	if (el.ttip) {
+		if (el.ttip.substr(0, 1) == "_") {
+			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
+		}
+		el.calendar.tooltips.innerHTML = el.ttip;
+	}
+	if (el.navtype != 300) {
+		Calendar.addClass(el, "hilite");
+		if (el.caldate) {
+			Calendar.addClass(el.parentNode, "rowhilite");
+		}
+	}
+	return Calendar.stopEvent(ev);
+};
+
+Calendar.dayMouseOut = function(ev) {
+	with (Calendar) {
+		var el = getElement(ev);
+		if (isRelated(el, ev) || _C || el.disabled)
+			return false;
+		removeClass(el, "hilite");
+		if (el.caldate)
+			removeClass(el.parentNode, "rowhilite");
+		if (el.calendar)
+			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
+		return stopEvent(ev);
+	}
+};
+
+/**
+ *  A generic "click" handler :) handles all types of buttons defined in this
+ *  calendar.
+ */
+Calendar.cellClick = function(el, ev) {
+	var cal = el.calendar;
+	var closing = false;
+	var newdate = false;
+	var date = null;
+	if (typeof el.navtype == "undefined") {
+		if (cal.currentDateEl) {
+			Calendar.removeClass(cal.currentDateEl, "selected");
+			Calendar.addClass(el, "selected");
+			closing = (cal.currentDateEl == el);
+			if (!closing) {
+				cal.currentDateEl = el;
+			}
+		}
+		cal.date.setDateOnly(el.caldate);
+		date = cal.date;
+		var other_month = !(cal.dateClicked = !el.otherMonth);
+		if (!other_month && !cal.currentDateEl)
+			cal._toggleMultipleDate(new Date(date));
+		else
+			newdate = !el.disabled;
+		// a date was clicked
+		if (other_month)
+			cal._init(cal.firstDayOfWeek, date);
+	} else {
+		if (el.navtype == 200) {
+			Calendar.removeClass(el, "hilite");
+			cal.callCloseHandler();
+			return;
+		}
+		date = new Date(cal.date);
+		if (el.navtype == 0)
+			date.setDateOnly(new Date()); // TODAY
+		// unless "today" was clicked, we assume no date was clicked so
+		// the selected handler will know not to close the calenar when
+		// in single-click mode.
+		// cal.dateClicked = (el.navtype == 0);
+		cal.dateClicked = false;
+		var year = date.getFullYear();
+		var mon = date.getMonth();
+		function setMonth(m) {
+			var day = date.getDate();
+			var max = date.getMonthDays(m);
+			if (day > max) {
+				date.setDate(max);
+			}
+			date.setMonth(m);
+		};
+		switch (el.navtype) {
+		    case 400:
+			Calendar.removeClass(el, "hilite");
+			var text = Calendar._TT["ABOUT"];
+			if (typeof text != "undefined") {
+				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
+			} else {
+				// FIXME: this should be removed as soon as lang files get updated!
+				text = "Help and about box text is not translated into this language.\n" +
+					"If you know this language and you feel generous please update\n" +
+					"the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
+					"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n" +
+					"Thank you!\n" +
+					"http://dynarch.com/mishoo/calendar.epl\n";
+			}
+			alert(text);
+			return;
+		    case -2:
+			if (year > cal.minYear) {
+				date.setFullYear(year - 1);
+			}
+			break;
+		    case -1:
+			if (mon > 0) {
+				setMonth(mon - 1);
+			} else if (year-- > cal.minYear) {
+				date.setFullYear(year);
+				setMonth(11);
+			}
+			break;
+		    case 1:
+			if (mon < 11) {
+				setMonth(mon + 1);
+			} else if (year < cal.maxYear) {
+				date.setFullYear(year + 1);
+				setMonth(0);
+			}
+			break;
+		    case 2:
+			if (year < cal.maxYear) {
+				date.setFullYear(year + 1);
+			}
+			break;
+		    case 100:
+			cal.setFirstDayOfWeek(el.fdow);
+			return;
+		    case 50:
+			var range = el._range;
+			var current = el.innerHTML;
+			for (var i = range.length; --i >= 0;)
+				if (range[i] == current)
+					break;
+			if (ev && ev.shiftKey) {
+				if (--i < 0)
+					i = range.length - 1;
+			} else if ( ++i >= range.length )
+				i = 0;
+			var newval = range[i];
+			el.innerHTML = newval;
+			cal.onUpdateTime();
+			return;
+		    case 0:
+			// TODAY will bring us here
+			if ((typeof cal.getDateStatus == "function") &&
+			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
+				return false;
+			}
+			break;
+		}
+		if (!date.equalsTo(cal.date)) {
+			cal.setDate(date);
+			newdate = true;
+		} else if (el.navtype == 0)
+			newdate = closing = true;
+	}
+	if (newdate) {
+		ev && cal.callHandler();
+	}
+	if (closing) {
+		Calendar.removeClass(el, "hilite");
+		ev && cal.callCloseHandler();
+	}
+};
+
+// END: CALENDAR STATIC FUNCTIONS
+
+// BEGIN: CALENDAR OBJECT FUNCTIONS
+
+/**
+ *  This function creates the calendar inside the given parent.  If _par is
+ *  null than it creates a popup calendar inside the BODY element.  If _par is
+ *  an element, be it BODY, then it creates a non-popup calendar (still
+ *  hidden).  Some properties need to be set before calling this function.
+ */
+Calendar.prototype.create = function (_par) {
+	var parent = null;
+	if (! _par) {
+		// default parent is the document body, in which case we create
+		// a popup calendar.
+		parent = document.getElementsByTagName("body")[0];
+		this.isPopup = true;
+	} else {
+		parent = _par;
+		this.isPopup = false;
+	}
+	this.date = this.dateStr ? new Date(this.dateStr) : new Date();
+
+	var table = Calendar.createElement("table");
+	this.table = table;
+	table.cellSpacing = 0;
+	table.cellPadding = 0;
+	table.calendar = this;
+	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
+
+	var div = Calendar.createElement("div");
+	this.element = div;
+	div.className = "calendar";
+	if (this.isPopup) {
+		div.style.position = "absolute";
+		div.style.display = "none";
+	}
+	div.appendChild(table);
+
+	var thead = Calendar.createElement("thead", table);
+	var cell = null;
+	var row = null;
+
+	var cal = this;
+	var hh = function (text, cs, navtype) {
+		cell = Calendar.createElement("td", row);
+		cell.colSpan = cs;
+		cell.className = "button";
+		if (navtype != 0 && Math.abs(navtype) <= 2)
+			cell.className += " nav";
+		Calendar._add_evs(cell);
+		cell.calendar = cal;
+		cell.navtype = navtype;
+		cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
+		return cell;
+	};
+
+	row = Calendar.createElement("tr", thead);
+	var title_length = 6;
+	(this.isPopup) && --title_length;
+	(this.weekNumbers) && ++title_length;
+
+	hh("?", 1, 400).ttip = Calendar._TT["INFO"];
+	this.title = hh("", title_length, 300);
+	this.title.className = "title";
+	if (this.isPopup) {
+		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
+		this.title.style.cursor = "move";
+		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
+	}
+
+	row = Calendar.createElement("tr", thead);
+	row.className = "headrow";
+
+	this._nav_py = hh("&#x00ab;", 1, -2);
+	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
+
+	this._nav_pm = hh("&#x2039;", 1, -1);
+	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
+
+	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
+	this._nav_now.ttip = Calendar._TT["GO_TODAY"];
+
+	this._nav_nm = hh("&#x203a;", 1, 1);
+	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
+
+	this._nav_ny = hh("&#x00bb;", 1, 2);
+	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
+
+	// day names
+	row = Calendar.createElement("tr", thead);
+	row.className = "daynames";
+	if (this.weekNumbers) {
+		cell = Calendar.createElement("td", row);
+		cell.className = "name wn";
+		cell.innerHTML = Calendar._TT["WK"];
+	}
+	for (var i = 7; i > 0; --i) {
+		cell = Calendar.createElement("td", row);
+		if (!i) {
+			cell.navtype = 100;
+			cell.calendar = this;
+			Calendar._add_evs(cell);
+		}
+	}
+	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
+	this._displayWeekdays();
+
+	var tbody = Calendar.createElement("tbody", table);
+	this.tbody = tbody;
+
+	for (i = 6; i > 0; --i) {
+		row = Calendar.createElement("tr", tbody);
+		if (this.weekNumbers) {
+			cell = Calendar.createElement("td", row);
+		}
+		for (var j = 7; j > 0; --j) {
+			cell = Calendar.createElement("td", row);
+			cell.calendar = this;
+			Calendar._add_evs(cell);
+		}
+	}
+
+	if (this.showsTime) {
+		row = Calendar.createElement("tr", tbody);
+		row.className = "time";
+
+		cell = Calendar.createElement("td", row);
+		cell.className = "time";
+		cell.colSpan = 2;
+		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";
+
+		cell = Calendar.createElement("td", row);
+		cell.className = "time";
+		cell.colSpan = this.weekNumbers ? 4 : 3;
+
+		(function(){
+			function makeTimePart(className, init, range_start, range_end) {
+				var part = Calendar.createElement("span", cell);
+				part.className = className;
+				part.innerHTML = init;
+				part.calendar = cal;
+				part.ttip = Calendar._TT["TIME_PART"];
+				part.navtype = 50;
+				part._range = [];
+				if (typeof range_start != "number")
+					part._range = range_start;
+				else {
+					for (var i = range_start; i <= range_end; ++i) {
+						var txt;
+						if (i < 10 && range_end >= 10) txt = '0' + i;
+						else txt = '' + i;
+						part._range[part._range.length] = txt;
+					}
+				}
+				Calendar._add_evs(part);
+				return part;
+			};
+			var hrs = cal.date.getHours();
+			var mins = cal.date.getMinutes();
+			var t12 = !cal.time24;
+			var pm = (hrs > 12);
+			if (t12 && pm) hrs -= 12;
+			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
+			var span = Calendar.createElement("span", cell);
+			span.innerHTML = ":";
+			span.className = "colon";
+			var M = makeTimePart("minute", mins, 0, 59);
+			var AP = null;
+			cell = Calendar.createElement("td", row);
+			cell.className = "time";
+			cell.colSpan = 2;
+			if (t12)
+				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
+			else
+				cell.innerHTML = "&nbsp;";
+
+			cal.onSetTime = function() {
+				var pm, hrs = this.date.getHours(),
+					mins = this.date.getMinutes();
+				if (t12) {
+					pm = (hrs >= 12);
+					if (pm) hrs -= 12;
+					if (hrs == 0) hrs = 12;
+					AP.innerHTML = pm ? "pm" : "am";
+				}
+				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
+				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
+			};
+
+			cal.onUpdateTime = function() {
+				var date = this.date;
+				var h = parseInt(H.innerHTML, 10);
+				if (t12) {
+					if (/pm/i.test(AP.innerHTML) && h < 12)
+						h += 12;
+					else if (/am/i.test(AP.innerHTML) && h == 12)
+						h = 0;
+				}
+				var d = date.getDate();
+				var m = date.getMonth();
+				var y = date.getFullYear();
+				date.setHours(h);
+				date.setMinutes(parseInt(M.innerHTML, 10));
+				date.setFullYear(y);
+				date.setMonth(m);
+				date.setDate(d);
+				this.dateClicked = false;
+				this.callHandler();
+			};
+		})();
+	} else {
+		this.onSetTime = this.onUpdateTime = function() {};
+	}
+
+	var tfoot = Calendar.createElement("tfoot", table);
+
+	row = Calendar.createElement("tr", tfoot);
+	row.className = "footrow";
+
+	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
+	cell.className = "ttip";
+	if (this.isPopup) {
+		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
+		cell.style.cursor = "move";
+	}
+	this.tooltips = cell;
+
+	div = Calendar.createElement("div", this.element);
+	this.monthsCombo = div;
+	div.className = "combo";
+	for (i = 0; i < Calendar._MN.length; ++i) {
+		var mn = Calendar.createElement("div");
+		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
+		mn.month = i;
+		mn.innerHTML = Calendar._SMN[i];
+		div.appendChild(mn);
+	}
+
+	div = Calendar.createElement("div", this.element);
+	this.yearsCombo = div;
+	div.className = "combo";
+	for (i = 12; i > 0; --i) {
+		var yr = Calendar.createElement("div");
+		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
+		div.appendChild(yr);
+	}
+
+	this._init(this.firstDayOfWeek, this.date);
+	parent.appendChild(this.element);
+};
+
+/** keyboard navigation, only for popup calendars */
+Calendar._keyEvent = function(ev) {
+	var cal = window._dynarch_popupCalendar;
+	if (!cal || cal.multiple)
+		return false;
+	(Calendar.is_ie) && (ev = window.event);
+	var act = (Calendar.is_ie || ev.type == "keypress"),
+		K = ev.keyCode;
+	if (ev.ctrlKey) {
+		switch (K) {
+		    case 37: // KEY left
+			act && Calendar.cellClick(cal._nav_pm);
+			break;
+		    case 38: // KEY up
+			act && Calendar.cellClick(cal._nav_py);
+			break;
+		    case 39: // KEY right
+			act && Calendar.cellClick(cal._nav_nm);
+			break;
+		    case 40: // KEY down
+			act && Calendar.cellClick(cal._nav_ny);
+			break;
+		    default:
+			return false;
+		}
+	} else switch (K) {
+	    case 32: // KEY space (now)
+		Calendar.cellClick(cal._nav_now);
+		break;
+	    case 27: // KEY esc
+		act && cal.callCloseHandler();
+		break;
+	    case 37: // KEY left
+	    case 38: // KEY up
+	    case 39: // KEY right
+	    case 40: // KEY down
+		if (act) {
+			var prev, x, y, ne, el, step;
+			prev = K == 37 || K == 38;
+			step = (K == 37 || K == 39) ? 1 : 7;
+			function setVars() {
+				el = cal.currentDateEl;
+				var p = el.pos;
+				x = p & 15;
+				y = p >> 4;
+				ne = cal.ar_days[y][x];
+			};setVars();
+			function prevMonth() {
+				var date = new Date(cal.date);
+				date.setDate(date.getDate() - step);
+				cal.setDate(date);
+			};
+			function nextMonth() {
+				var date = new Date(cal.date);
+				date.setDate(date.getDate() + step);
+				cal.setDate(date);
+			};
+			while (1) {
+				switch (K) {
+				    case 37: // KEY left
+					if (--x >= 0)
+						ne = cal.ar_days[y][x];
+					else {
+						x = 6;
+						K = 38;
+						continue;
+					}
+					break;
+				    case 38: // KEY up
+					if (--y >= 0)
+						ne = cal.ar_days[y][x];
+					else {
+						prevMonth();
+						setVars();
+					}
+					break;
+				    case 39: // KEY right
+					if (++x < 7)
+						ne = cal.ar_days[y][x];
+					else {
+						x = 0;
+						K = 40;
+						continue;
+					}
+					break;
+				    case 40: // KEY down
+					if (++y < cal.ar_days.length)
+						ne = cal.ar_days[y][x];
+					else {
+						nextMonth();
+						setVars();
+					}
+					break;
+				}
+				break;
+			}
+			if (ne) {
+				if (!ne.disabled)
+					Calendar.cellClick(ne);
+				else if (prev)
+					prevMonth();
+				else
+					nextMonth();
+			}
+		}
+		break;
+	    case 13: // KEY enter
+		if (act)
+			Calendar.cellClick(cal.currentDateEl, ev);
+		break;
+	    default:
+		return false;
+	}
+	return Calendar.stopEvent(ev);
+};
+
+/**
+ *  (RE)Initializes the calendar to the given date and firstDayOfWeek
+ */
+Calendar.prototype._init = function (firstDayOfWeek, date) {
+	var today = new Date(),
+		TY = today.getFullYear(),
+		TM = today.getMonth(),
+		TD = today.getDate();
+	this.table.style.visibility = "hidden";
+
+	var year = date.getFullYear();
+	if (year < this.minYear) {
+		year = this.minYear;
+		date.setFullYear(year);
+	} else if (year > this.maxYear) {
+		year = this.maxYear;
+		date.setFullYear(year);
+	}
+	this.firstDayOfWeek = firstDayOfWeek;
+	this.date = new Date(date);
+	var month = date.getMonth();
+	var mday = date.getDate();
+	var no_days = date.getMonthDays();
+
+	// calendar voodoo for computing the first day that would actually be
+	// displayed in the calendar, even if it's from the previous month.
+	// WARNING: this is magic. ;-)
+	date.setDate(1);
+	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
+	if (day1 < 0)
+		day1 += 7;
+	date.setDate(-day1);
+	date.setDate(date.getDate() + 1);
+
+	var row = this.tbody.firstChild;
+	var MN = Calendar._SMN[month];
+	var ar_days = this.ar_days = new Array();
+	var weekend = Calendar._TT["WEEKEND"];
+	var dates = this.multiple ? (this.datesCells = {}) : null;
+	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
+		var cell = row.firstChild;
+		if (this.weekNumbers) {
+			cell.className = "day wn";
+			cell.innerHTML = date.getWeekNumber();
+			cell = cell.nextSibling;
+		}
+		row.className = "daysrow";
+		var hasdays = false, iday, dpos = ar_days[i] = [];
+		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
+			iday = date.getDate();
+			var wday = date.getDay();
+			cell.className = "day";
+			cell.pos = i << 4 | j;
+			dpos[j] = cell;
+			var current_month = (date.getMonth() == month);
+			if (!current_month) {
+				if (this.showsOtherMonths) {
+					cell.className += " othermonth";
+					cell.otherMonth = true;
+				} else {
+					cell.className = "emptycell";
+					cell.innerHTML = "&nbsp;";
+					cell.disabled = true;
+					continue;
+				}
+			} else {
+				cell.otherMonth = false;
+				hasdays = true;
+			}
+			cell.disabled = false;
+			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
+			if (dates)
+				dates[date.print("%Y%m%d")] = cell;
+			if (this.getDateStatus) {
+				var status = this.getDateStatus(date, year, month, iday);
+				if (this.getDateToolTip) {
+					var toolTip = this.getDateToolTip(date, year, month, iday);
+					if (toolTip)
+						cell.title = toolTip;
+				}
+				if (status === true) {
+					cell.className += " disabled";
+					cell.disabled = true;
+				} else {
+					if (/disabled/i.test(status))
+						cell.disabled = true;
+					cell.className += " " + status;
+				}
+			}
+			if (!cell.disabled) {
+				cell.caldate = new Date(date);
+				cell.ttip = "_";
+				if (!this.multiple && current_month
+				    && iday == mday && this.hiliteToday) {
+					cell.className += " selected";
+					this.currentDateEl = cell;
+				}
+				if (date.getFullYear() == TY &&
+				    date.getMonth() == TM &&
+				    iday == TD) {
+					cell.className += " today";
+					cell.ttip += Calendar._TT["PART_TODAY"];
+				}
+				if (weekend.indexOf(wday.toString()) != -1)
+					cell.className += cell.otherMonth ? " oweekend" : " weekend";
+			}
+		}
+		if (!(hasdays || this.showsOtherMonths))
+			row.className = "emptyrow";
+	}
+	this.title.innerHTML = Calendar._MN[month] + ", " + year;
+	this.onSetTime();
+	this.table.style.visibility = "visible";
+	this._initMultipleDates();
+	// PROFILE
+	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
+};
+
+Calendar.prototype._initMultipleDates = function() {
+	if (this.multiple) {
+		for (var i in this.multiple) {
+			var cell = this.datesCells[i];
+			var d = this.multiple[i];
+			if (!d)
+				continue;
+			if (cell)
+				cell.className += " selected";
+		}
+	}
+};
+
+Calendar.prototype._toggleMultipleDate = function(date) {
+	if (this.multiple) {
+		var ds = date.print("%Y%m%d");
+		var cell = this.datesCells[ds];
+		if (cell) {
+			var d = this.multiple[ds];
+			if (!d) {
+				Calendar.addClass(cell, "selected");
+				this.multiple[ds] = date;
+			} else {
+				Calendar.removeClass(cell, "selected");
+				delete this.multiple[ds];
+			}
+		}
+	}
+};
+
+Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
+	this.getDateToolTip = unaryFunction;
+};
+
+/**
+ *  Calls _init function above for going to a certain date (but only if the
+ *  date is different than the currently selected one).
+ */
+Calendar.prototype.setDate = function (date) {
+	if (!date.equalsTo(this.date)) {
+		this._init(this.firstDayOfWeek, date);
+	}
+};
+
+/**
+ *  Refreshes the calendar.  Useful if the "disabledHandler" function is
+ *  dynamic, meaning that the list of disabled date can change at runtime.
+ *  Just * call this function if you think that the list of disabled dates
+ *  should * change.
+ */
+Calendar.prototype.refresh = function () {
+	this._init(this.firstDayOfWeek, this.date);
+};
+
+/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
+Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
+	this._init(firstDayOfWeek, this.date);
+	this._displayWeekdays();
+};
+
+/**
+ *  Allows customization of what dates are enabled.  The "unaryFunction"
+ *  parameter must be a function object that receives the date (as a JS Date
+ *  object) and returns a boolean value.  If the returned value is true then
+ *  the passed date will be marked as disabled.
+ */
+Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
+	this.getDateStatus = unaryFunction;
+};
+
+/** Customization of allowed year range for the calendar. */
+Calendar.prototype.setRange = function (a, z) {
+	this.minYear = a;
+	this.maxYear = z;
+};
+
+/** Calls the first user handler (selectedHandler). */
+Calendar.prototype.callHandler = function () {
+	if (this.onSelected) {
+		this.onSelected(this, this.date.print(this.dateFormat));
+	}
+};
+
+/** Calls the second user handler (closeHandler). */
+Calendar.prototype.callCloseHandler = function () {
+	if (this.onClose) {
+		this.onClose(this);
+	}
+	this.hideShowCovered();
+};
+
+/** Removes the calendar object from the DOM tree and destroys it. */
+Calendar.prototype.destroy = function () {
+	var el = this.element.parentNode;
+	el.removeChild(this.element);
+	Calendar._C = null;
+	window._dynarch_popupCalendar = null;
+};
+
+/**
+ *  Moves the calendar element to a different section in the DOM tree (changes
+ *  its parent).
+ */
+Calendar.prototype.reparent = function (new_parent) {
+	var el = this.element;
+	el.parentNode.removeChild(el);
+	new_parent.appendChild(el);
+};
+
+// This gets called when the user presses a mouse button anywhere in the
+// document, if the calendar is shown.  If the click was outside the open
+// calendar this function closes it.
+Calendar._checkCalendar = function(ev) {
+	var calendar = window._dynarch_popupCalendar;
+	if (!calendar) {
+		return false;
+	}
+	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
+	for (; el != null && el != calendar.element; el = el.parentNode);
+	if (el == null) {
+		// calls closeHandler which should hide the calendar.
+		window._dynarch_popupCalendar.callCloseHandler();
+		return Calendar.stopEvent(ev);
+	}
+};
+
+/** Shows the calendar. */
+Calendar.prototype.show = function () {
+	var rows = this.table.getElementsByTagName("tr");
+	for (var i = rows.length; i > 0;) {
+		var row = rows[--i];
+		Calendar.removeClass(row, "rowhilite");
+		var cells = row.getElementsByTagName("td");
+		for (var j = cells.length; j > 0;) {
+			var cell = cells[--j];
+			Calendar.removeClass(cell, "hilite");
+			Calendar.removeClass(cell, "active");
+		}
+	}
+	this.element.style.display = "block";
+	this.hidden = false;
+	if (this.isPopup) {
+		window._dynarch_popupCalendar = this;
+		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
+		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
+		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
+	}
+	this.hideShowCovered();
+};
+
+/**
+ *  Hides the calendar.  Also removes any "hilite" from the class of any TD
+ *  element.
+ */
+Calendar.prototype.hide = function () {
+	if (this.isPopup) {
+		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
+		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
+		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
+	}
+	this.element.style.display = "none";
+	this.hidden = true;
+	this.hideShowCovered();
+};
+
+/**
+ *  Shows the calendar at a given absolute position (beware that, depending on
+ *  the calendar element style -- position property -- this might be relative
+ *  to the parent's containing rectangle).
+ */
+Calendar.prototype.showAt = function (x, y) {
+	var s = this.element.style;
+	s.left = x + "px";
+	s.top = y + "px";
+	this.show();
+};
+
+/** Shows the calendar near a given element. */
+Calendar.prototype.showAtElement = function (el, opts) {
+	var self = this;
+	var p = Calendar.getAbsolutePos(el);
+	if (!opts || typeof opts != "string") {
+		this.showAt(p.x, p.y + el.offsetHeight);
+		return true;
+	}
+	function fixPosition(box) {
+		if (box.x < 0)
+			box.x = 0;
+		if (box.y < 0)
+			box.y = 0;
+		var cp = document.createElement("div");
+		var s = cp.style;
+		s.position = "absolute";
+		s.right = s.bottom = s.width = s.height = "0px";
+		document.body.appendChild(cp);
+		var br = Calendar.getAbsolutePos(cp);
+		document.body.removeChild(cp);
+		if (Calendar.is_ie) {
+			br.y += document.body.scrollTop;
+			br.x += document.body.scrollLeft;
+		} else {
+			br.y += window.scrollY;
+			br.x += window.scrollX;
+		}
+		var tmp = box.x + box.width - br.x;
+		if (tmp > 0) box.x -= tmp;
+		tmp = box.y + box.height - br.y;
+		if (tmp > 0) box.y -= tmp;
+	};
+	this.element.style.display = "block";
+	Calendar.continuation_for_the_fucking_khtml_browser = function() {
+		var w = self.element.offsetWidth;
+		var h = self.element.offsetHeight;
+		self.element.style.display = "none";
+		var valign = opts.substr(0, 1);
+		var halign = "l";
+		if (opts.length > 1) {
+			halign = opts.substr(1, 1);
+		}
+		// vertical alignment
+		switch (valign) {
+		    case "T": p.y -= h; break;
+		    case "B": p.y += el.offsetHeight; break;
+		    case "C": p.y += (el.offsetHeight - h) / 2; break;
+		    case "t": p.y += el.offsetHeight - h; break;
+		    case "b": break; // already there
+		}
+		// horizontal alignment
+		switch (halign) {
+		    case "L": p.x -= w; break;
+		    case "R": p.x += el.offsetWidth; break;
+		    case "C": p.x += (el.offsetWidth - w) / 2; break;
+		    case "l": p.x += el.offsetWidth - w; break;
+		    case "r": break; // already there
+		}
+		p.width = w;
+		p.height = h + 40;
+		self.monthsCombo.style.display = "none";
+		fixPosition(p);
+		self.showAt(p.x, p.y);
+	};
+	if (Calendar.is_khtml)
+		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
+	else
+		Calendar.continuation_for_the_fucking_khtml_browser();
+};
+
+/** Customizes the date format. */
+Calendar.prototype.setDateFormat = function (str) {
+	this.dateFormat = str;
+};
+
+/** Customizes the tooltip date format. */
+Calendar.prototype.setTtDateFormat = function (str) {
+	this.ttDateFormat = str;
+};
+
+/**
+ *  Tries to identify the date represented in a string.  If successful it also
+ *  calls this.setDate which moves the calendar to the given date.
+ */
+Calendar.prototype.parseDate = function(str, fmt) {
+	if (!fmt)
+		fmt = this.dateFormat;
+	this.setDate(Date.parseDate(str, fmt));
+};
+
+Calendar.prototype.hideShowCovered = function () {
+	if (!Calendar.is_ie && !Calendar.is_opera)
+		return;
+	function getVisib(obj){
+		var value = obj.style.visibility;
+		if (!value) {
+			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
+				if (!Calendar.is_khtml)
+					value = document.defaultView.
+						getComputedStyle(obj, "").getPropertyValue("visibility");
+				else
+					value = '';
+			} else if (obj.currentStyle) { // IE
+				value = obj.currentStyle.visibility;
+			} else
+				value = '';
+		}
+		return value;
+	};
+
+	var tags = new Array("applet", "iframe", "select");
+	var el = this.element;
+
+	var p = Calendar.getAbsolutePos(el);
+	var EX1 = p.x;
+	var EX2 = el.offsetWidth + EX1;
+	var EY1 = p.y;
+	var EY2 = el.offsetHeight + EY1;
+
+	for (var k = tags.length; k > 0; ) {
+		var ar = document.getElementsByTagName(tags[--k]);
+		var cc = null;
+
+		for (var i = ar.length; i > 0;) {
+			cc = ar[--i];
+
+			p = Calendar.getAbsolutePos(cc);
+			var CX1 = p.x;
+			var CX2 = cc.offsetWidth + CX1;
+			var CY1 = p.y;
+			var CY2 = cc.offsetHeight + CY1;
+
+			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
+				if (!cc.__msh_save_visibility) {
+					cc.__msh_save_visibility = getVisib(cc);
+				}
+				cc.style.visibility = cc.__msh_save_visibility;
+			} else {
+				if (!cc.__msh_save_visibility) {
+					cc.__msh_save_visibility = getVisib(cc);
+				}
+				cc.style.visibility = "hidden";
+			}
+		}
+	}
+};
+
+/** Internal function; it displays the bar with the names of the weekday. */
+Calendar.prototype._displayWeekdays = function () {
+	var fdow = this.firstDayOfWeek;
+	var cell = this.firstdayname;
+	var weekend = Calendar._TT["WEEKEND"];
+	for (var i = 0; i < 7; ++i) {
+		cell.className = "day name";
+		var realday = (i + fdow) % 7;
+		if (i) {
+			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
+			cell.navtype = 100;
+			cell.calendar = this;
+			cell.fdow = realday;
+			Calendar._add_evs(cell);
+		}
+		if (weekend.indexOf(realday.toString()) != -1) {
+			Calendar.addClass(cell, "weekend");
+		}
+		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
+		cell = cell.nextSibling;
+	}
+};
+
+/** Internal function.  Hides all combo boxes that might be displayed. */
+Calendar.prototype._hideCombos = function () {
+	this.monthsCombo.style.display = "none";
+	this.yearsCombo.style.display = "none";
+};
+
+/** Internal function.  Starts dragging the element. */
+Calendar.prototype._dragStart = function (ev) {
+	if (this.dragging) {
+		return;
+	}
+	this.dragging = true;
+	var posX;
+	var posY;
+	if (Calendar.is_ie) {
+		posY = window.event.clientY + document.body.scrollTop;
+		posX = window.event.clientX + document.body.scrollLeft;
+	} else {
+		posY = ev.clientY + window.scrollY;
+		posX = ev.clientX + window.scrollX;
+	}
+	var st = this.element.style;
+	this.xOffs = posX - parseInt(st.left);
+	this.yOffs = posY - parseInt(st.top);
+	with (Calendar) {
+		addEvent(document, "mousemove", calDragIt);
+		addEvent(document, "mouseup", calDragEnd);
+	}
+};
+
+// BEGIN: DATE OBJECT PATCHES
+
+/** Adds the number of days array to the Date object. */
+Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
+
+/** Constants used for time computations */
+Date.SECOND = 1000 /* milliseconds */;
+Date.MINUTE = 60 * Date.SECOND;
+Date.HOUR   = 60 * Date.MINUTE;
+Date.DAY    = 24 * Date.HOUR;
+Date.WEEK   =  7 * Date.DAY;
+
+Date.parseDate = function(str, fmt) {
+	var today = new Date();
+	var y = 0;
+	var m = -1;
+	var d = 0;
+	var a = str.split(/\W+/);
+	var b = fmt.match(/%./g);
+	var i = 0, j = 0;
+	var hr = 0;
+	var min = 0;
+	for (i = 0; i < a.length; ++i) {
+		if (!a[i])
+			continue;
+		switch (b[i]) {
+		    case "%d":
+		    case "%e":
+			d = parseInt(a[i], 10);
+			break;
+
+		    case "%m":
+			m = parseInt(a[i], 10) - 1;
+			break;
+
+		    case "%Y":
+		    case "%y":
+			y = parseInt(a[i], 10);
+			(y < 100) && (y += (y > 29) ? 1900 : 2000);
+			break;
+
+		    case "%b":
+		    case "%B":
+			for (j = 0; j < 12; ++j) {
+				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
+			}
+			break;
+
+		    case "%H":
+		    case "%I":
+		    case "%k":
+		    case "%l":
+			hr = parseInt(a[i], 10);
+			break;
+
+		    case "%P":
+		    case "%p":
+			if (/pm/i.test(a[i]) && hr < 12)
+				hr += 12;
+			else if (/am/i.test(a[i]) && hr >= 12)
+				hr -= 12;
+			break;
+
+		    case "%M":
+			min = parseInt(a[i], 10);
+			break;
+		}
+	}
+	if (isNaN(y)) y = today.getFullYear();
+	if (isNaN(m)) m = today.getMonth();
+	if (isNaN(d)) d = today.getDate();
+	if (isNaN(hr)) hr = today.getHours();
+	if (isNaN(min)) min = today.getMinutes();
+	if (y != 0 && m != -1 && d != 0)
+		return new Date(y, m, d, hr, min, 0);
+	y = 0; m = -1; d = 0;
+	for (i = 0; i < a.length; ++i) {
+		if (a[i].search(/[a-zA-Z]+/) != -1) {
+			var t = -1;
+			for (j = 0; j < 12; ++j) {
+				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
+			}
+			if (t != -1) {
+				if (m != -1) {
+					d = m+1;
+				}
+				m = t;
+			}
+		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
+			m = a[i]-1;
+		} else if (parseInt(a[i], 10) > 31 && y == 0) {
+			y = parseInt(a[i], 10);
+			(y < 100) && (y += (y > 29) ? 1900 : 2000);
+		} else if (d == 0) {
+			d = a[i];
+		}
+	}
+	if (y == 0)
+		y = today.getFullYear();
+	if (m != -1 && d != 0)
+		return new Date(y, m, d, hr, min, 0);
+	return today;
+};
+
+/** Returns the number of days in the current month */
+Date.prototype.getMonthDays = function(month) {
+	var year = this.getFullYear();
+	if (typeof month == "undefined") {
+		month = this.getMonth();
+	}
+	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
+		return 29;
+	} else {
+		return Date._MD[month];
+	}
+};
+
+/** Returns the number of day in the year. */
+Date.prototype.getDayOfYear = function() {
+	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
+	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
+	var time = now - then;
+	return Math.floor(time / Date.DAY);
+};
+
+/** Returns the number of the week in year, as defined in ISO 8601. */
+Date.prototype.getWeekNumber = function() {
+	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
+	var DoW = d.getDay();
+	d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
+	var ms = d.valueOf(); // GMT
+	d.setMonth(0);
+	d.setDate(4); // Thu in Week 1
+	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
+};
+
+/** Checks date and time equality */
+Date.prototype.equalsTo = function(date) {
+	return ((this.getFullYear() == date.getFullYear()) &&
+		(this.getMonth() == date.getMonth()) &&
+		(this.getDate() == date.getDate()) &&
+		(this.getHours() == date.getHours()) &&
+		(this.getMinutes() == date.getMinutes()));
+};
+
+/** Set only the year, month, date parts (keep existing time) */
+Date.prototype.setDateOnly = function(date) {
+	var tmp = new Date(date);
+	this.setDate(1);
+	this.setFullYear(tmp.getFullYear());
+	this.setMonth(tmp.getMonth());
+	this.setDate(tmp.getDate());
+};
+
+/** Prints the date in a string according to the given format. */
+Date.prototype.print = function (str) {
+	var m = this.getMonth();
+	var d = this.getDate();
+	var y = this.getFullYear();
+	var wn = this.getWeekNumber();
+	var w = this.getDay();
+	var s = {};
+	var hr = this.getHours();
+	var pm = (hr >= 12);
+	var ir = (pm) ? (hr - 12) : hr;
+	var dy = this.getDayOfYear();
+	if (ir == 0)
+		ir = 12;
+	var min = this.getMinutes();
+	var sec = this.getSeconds();
+	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
+	s["%A"] = Calendar._DN[w]; // full weekday name
+	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
+	s["%B"] = Calendar._MN[m]; // full month name
+	// FIXME: %c : preferred date and time representation for the current locale
+	s["%C"] = 1 + Math.floor(y / 100); // the century number
+	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
+	s["%e"] = d; // the day of the month (range 1 to 31)
+	// FIXME: %D : american date style: %m/%d/%y
+	// FIXME: %E, %F, %G, %g, %h (man strftime)
+	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
+	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
+	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
+	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
+	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
+	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
+	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
+	s["%n"] = "\n";		// a newline character
+	s["%p"] = pm ? "PM" : "AM";
+	s["%P"] = pm ? "pm" : "am";
+	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
+	// FIXME: %R : the time in 24-hour notation %H:%M
+	s["%s"] = Math.floor(this.getTime() / 1000);
+	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
+	s["%t"] = "\t";		// a tab character
+	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
+	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
+	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
+	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
+	// FIXME: %x : preferred date representation for the current locale without the time
+	// FIXME: %X : preferred time representation for the current locale without the date
+	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
+	s["%Y"] = y;		// year with the century
+	s["%%"] = "%";		// a literal '%' character
+
+	var re = /%./g;
+	if (!Calendar.is_ie5 && !Calendar.is_khtml)
+		return str.replace(re, function (par) { return s[par] || par; });
+
+	var a = str.match(re);
+	for (var i = 0; i < a.length; i++) {
+		var tmp = s[a[i]];
+		if (tmp) {
+			re = new RegExp(a[i], 'g');
+			str = str.replace(re, tmp);
+		}
+	}
+
+	return str;
+};
+
+Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
+Date.prototype.setFullYear = function(y) {
+	var d = new Date(this);
+	d.__msh_oldSetFullYear(y);
+	if (d.getMonth() != this.getMonth())
+		this.setDate(28);
+	this.__msh_oldSetFullYear(y);
+};
+
+// END: DATE OBJECT PATCHES
+
+
+// global object that remembers the calendar
+window._dynarch_popupCalendar = null;
Index: /sandbox/workflow/branches/993/js/jscalendar/calendar-blue.css
===================================================================
--- /sandbox/workflow/branches/993/js/jscalendar/calendar-blue.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscalendar/calendar-blue.css	(revision 795)
@@ -0,0 +1,232 @@
+/* The main calendar widget.  DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+  border: 1px solid #556;
+  font-size: 11px;
+  color: #000;
+  cursor: default;
+  background: #eef;
+  font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+  text-align: center;    /* They are the navigation buttons */
+  padding: 2px;          /* Make the buttons seem like they're pressing */
+}
+
+.calendar .nav {
+  background: #778 url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+  font-weight: bold;      /* Pressing it will take you to the current date */
+  text-align: center;
+  background: #fff;
+  color: #000;
+  padding: 2px;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+  background: #778;
+  color: #fff;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+  background: #bdf;
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+  border-bottom: 1px solid #556;
+  padding: 2px;
+  text-align: center;
+  color: #000;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+  color: #a66;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+  background-color: #aaf;
+  color: #000;
+  border: 1px solid #04f;
+  padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+  background-color: #77c;
+  padding: 2px 0px 0px 2px;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+  width: 2em;
+  color: #456;
+  text-align: right;
+  padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+  font-size: 80%;
+  color: #bbb;
+}
+.calendar tbody .day.othermonth.oweekend {
+  color: #fbb;
+}
+
+.calendar table .wn {
+  padding: 2px 3px 2px 2px;
+  border-right: 1px solid #000;
+  background: #bdf;
+}
+
+.calendar tbody .rowhilite td {
+  background: #def;
+}
+
+.calendar tbody .rowhilite td.wn {
+  background: #eef;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+  background: #def;
+  padding: 1px 3px 1px 1px;
+  border: 1px solid #bbb;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+  background: #cde;
+  padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+  font-weight: bold;
+  border: 1px solid #000;
+  padding: 1px 3px 1px 1px;
+  background: #fff;
+  color: #000;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+  color: #a66;
+}
+
+.calendar tbody td.today { /* Cell showing selected date */
+  font-weight: bold;
+  color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+  visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+  display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+  text-align: center;
+  background: #556;
+  color: #fff;
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+  background: #fff;
+  color: #445;
+  border-top: 1px solid #556;
+  padding: 1px;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+  background: #aaf;
+  border: 1px solid #04f;
+  color: #000;
+  padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+  background: #77c;
+  padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+  position: absolute;
+  display: none;
+  top: 0px;
+  left: 0px;
+  width: 4em;
+  cursor: default;
+  border: 1px solid #655;
+  background: #def;
+  color: #000;
+  font-size: 90%;
+  z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+  text-align: center;
+  padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+  width: 4em;
+}
+
+.calendar .combo .hilite {
+  background: #acf;
+}
+
+.calendar .combo .active {
+  border-top: 1px solid #46a;
+  border-bottom: 1px solid #46a;
+  background: #eef;
+  font-weight: bold;
+}
+
+.calendar td.time {
+  border-top: 1px solid #000;
+  padding: 1px 0px;
+  text-align: center;
+  background-color: #f4f0e8;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+  padding: 0px 3px 0px 4px;
+  border: 1px solid #889;
+  font-weight: bold;
+  background-color: #fff;
+}
+
+.calendar td.time .ampm {
+  text-align: center;
+}
+
+.calendar td.time .colon {
+  padding: 0px 2px 0px 3px;
+  font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+  border-color: #000;
+  background-color: #667;
+  color: #fff;
+}
+
+.calendar td.time span.active {
+  border-color: #f00;
+  background-color: #000;
+  color: #0f0;
+}
Index: /sandbox/workflow/branches/993/js/jscalendar/calendar-br.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscalendar/calendar-br.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscalendar/calendar-br.js	(revision 795)
@@ -0,0 +1,127 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible.  We strongly believe that
+// Unicode is the answer to a real internationalized world.  Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Domingo",
+ "Segunda",
+ "Terça",
+ "Quarta",
+ "Quinta",
+ "Sexta",
+ "Sábado",
+ "Domingo");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary.  We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+//   Calendar._SDN_len = N; // short day name length
+//   Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Dom",
+ "Seg",
+ "Ter",
+ "Qua",
+ "Qui",
+ "Sex",
+ "Sáb",
+ "Dom");
+
+// First day of the week. "0" means display Sunday first, "1" means display
+// Monday first, etc.
+Calendar._FD = 0;
+
+// full month names
+Calendar._MN = new Array
+("Janeiro",
+ "Fevereiro",
+ "Março",
+ "Abril",
+ "Maio",
+ "Junho",
+ "Julho",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Dezembro");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Fev",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Set",
+ "Out",
+ "Nov",
+ "Dez");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Sobre o calendárior";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Date selection:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
+"- Hold mouse button on any of the above buttons for faster selection.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Time selection:\n" +
+"- Click on any of the time parts to increase it\n" +
+"- or Shift-click to decrease it\n" +
+"- or click and drag for faster selection.";
+
+Calendar._TT["PREV_YEAR"] = "Ano anterior (segure para menu)";
+Calendar._TT["PREV_MONTH"] = "Mês anterior (segure para menu)";
+Calendar._TT["GO_TODAY"] = "Ir para a data atual";
+Calendar._TT["NEXT_MONTH"] = "Próximo mês (segure para menu)";
+Calendar._TT["NEXT_YEAR"] = "Próximo ano (segure para menu)";
+Calendar._TT["SEL_DATE"] = "Selecione uma data";
+Calendar._TT["DRAG_TO_MOVE"] = "Segure para mover";
+Calendar._TT["PART_TODAY"] = " (hoje)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Exibir %s primeiro";
+
+// This may be locale-dependent.  It specifies the week-end days, as an array
+// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Fechar";
+Calendar._TT["TODAY"] = "Hoje";
+Calendar._TT["TIME_PART"] = "(Shift-)Clique ou arraste para mudar o valor";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%d de %B de %Y";
+
+Calendar._TT["WK"] = "sem";
+Calendar._TT["TIME"] = "Hora:";
Index: /sandbox/workflow/branches/993/js/jscode/prototype.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/prototype.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/prototype.js	(revision 795)
@@ -0,0 +1,2520 @@
+/*  Prototype JavaScript framework, version 1.5.0
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.5.0',
+  BrowserFeatures: {
+    XPath: !!document.evaluate
+  },
+
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+  emptyFunction: function() {},
+  K: function(x) { return x }
+};
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+};
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+  for (var property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+};
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (object === undefined) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : object.toString();
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({}, object);
+  }
+});
+
+Function.prototype.bind = function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+};
+
+Function.prototype.bindAsEventListener = function(object) {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function(event) {
+    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+  }
+};
+
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    var digits = this.toString(16);
+    if (this < 16) return '0' + digits;
+    return digits;
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  }
+});
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) {}
+    }
+
+    return returnValue;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.callback(this);
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+};
+String.interpret = function(value){
+  return value == null ? '' : String(value);
+};
+
+Object.extend(String.prototype, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(replacement);
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.prepareReplacement(replacement);
+    count = count === undefined ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  },
+
+  scan: function(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return this;
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = truncation === undefined ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : this;
+  },
+
+  strip: function() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  },
+
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var div = document.createElement('div');
+    var text = document.createTextNode(this);
+    div.appendChild(text);
+    return div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = document.createElement('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return {};
+
+    return match[1].split(separator || '&').inject({}, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var name = decodeURIComponent(pair[0]);
+        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+        if (hash[name] !== undefined) {
+          if (hash[name].constructor != Array)
+            hash[name] = [hash[name]];
+          if (value) hash[name].push(value);
+        }
+        else hash[name] = value;
+      }
+      return hash;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  camelize: function() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  },
+
+  capitalize: function(){
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.replace(/\\/g, '\\\\');
+    if (useDoubleQuotes)
+      return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    else
+      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (typeof replacement == 'function') return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+};
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern  = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    return this.template.gsub(this.pattern, function(match) {
+      var before = match[1];
+      if (before == '\\') return match[2];
+      return before + String.interpret(object[match[3]]);
+    });
+  }
+};
+
+var $break    = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+  each: function(iterator) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        try {
+          iterator(value, index++);
+        } catch (e) {
+          if (e != $continue) throw e;
+        }
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator) {
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.map(iterator);
+  },
+
+  all: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!(iterator || Prototype.K)(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator) {
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!(iterator || Prototype.K)(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(pattern, iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      var stringValue = value.toString();
+      if (stringValue.match(pattern))
+        results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  include: function(object) {
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator) {
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator) {
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      ((iterator || Prototype.K)(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator) {
+    return this.map(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (typeof args.last() == 'function')
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+};
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) {
+    return iterable.toArray();
+  } else {
+    var results = [];
+    for (var i = 0, length = iterable.length; i < length; i++)
+      results.push(iterable[i]);
+    return results;
+  }
+};
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+  Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(value && value.constructor == Array ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  indexOf: function(object) {
+    for (var i = 0, length = this.length; i < length; i++)
+      if (this[i] == object) return i;
+    return -1;
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function() {
+    return this.inject([], function(array, value) {
+      return array.include(value) ? array : array.concat([value]);
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+};
+
+if(window.opera){
+  Array.prototype.concat = function(){
+    var array = [];
+    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      if(arguments[i].constructor == Array) {
+        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  }
+};
+var Hash = function(obj) {
+  Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+  toQueryString: function(obj) {
+    var parts = [];
+
+	  this.prototype._each.call(obj, function(pair) {
+      if (!pair.key) return;
+
+      if (pair.value && pair.value.constructor == Array) {
+        var values = pair.value.compact();
+        if (values.length < 2) pair.value = values.reduce();
+        else {
+        	key = encodeURIComponent(pair.key);
+          values.each(function(value) {
+            value = value != undefined ? encodeURIComponent(value) : '';
+            parts.push(key + '=' + encodeURIComponent(value));
+          });
+          return;
+        }
+      }
+      if (pair.value == undefined) pair[1] = '';
+      parts.push(pair.join('='));
+	  });
+
+    return parts.join('&');
+  }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+  _each: function(iterator) {
+    for (var key in this) {
+      var value = this[key];
+      if (value && value == Hash.prototype[key]) continue;
+
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  merge: function(hash) {
+    return $H(hash).inject(this, function(mergedHash, pair) {
+      mergedHash[pair.key] = pair.value;
+      return mergedHash;
+    });
+  },
+
+  remove: function() {
+    var result;
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      var value = this[arguments[i]];
+      if (value !== undefined){
+        if (result === undefined) result = value;
+        else {
+          if (result.constructor != Array) result = [result];
+          result.push(value)
+        }
+      }
+      delete this[arguments[i]];
+    }
+    return result;
+  },
+
+  toQueryString: function() {
+    return Hash.toQueryString(this);
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  },
+
+  customInspect: function() {
+    return '{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}';
+  }
+});
+
+function $H(object) {
+  if (object && object.constructor == Hash) return object;
+  return new Hash(object);
+};
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+};
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+};
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (typeof responder[callback] == 'function') {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) {}
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate: function() {
+    Ajax.activeRequestCount++;
+  },
+  onComplete: function() {
+    Ajax.activeRequestCount--;
+  }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+  setOptions: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   ''
+    };
+    Object.extend(this.options, options || {});
+
+    this.options.method = this.options.method.toLowerCase();
+    if (typeof this.options.parameters == 'string')
+      this.options.parameters = this.options.parameters.toQueryParams();
+  }
+};
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  _complete: false,
+
+  initialize: function(url, options) {
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = this.options.parameters;
+
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    params = Hash.toQueryString(params);
+    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_=';
+
+    // when GET, append parameters to URL
+    if (this.method == 'get' && params)
+      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
+    try {
+      Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous)
+        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      var body = this.method == 'post' ? (this.options.postBody || params) : null;
+
+      this.transport.send(body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (typeof extras.push == 'function')
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    return !this.transport.status
+        || (this.transport.status >= 200 && this.transport.status < 300);
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState];
+    var transport = this.transport, json = this.evalJSON();
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + this.transport.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(transport, json);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      if ((this.getHeader('Content-type') || 'text/javascript').strip().
+        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+          this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + state, this, transport, json);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalJSON: function() {
+    try {
+      var json = this.getHeader('X-JSON');
+      return json ? eval('(' + json + ')') : null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+  initialize: function(container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    };
+
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+
+    var onComplete = this.options.onComplete || Prototype.emptyFunction;
+    this.options.onComplete = (function(transport, param) {
+      this.updateContent();
+      onComplete(transport, param);
+    }).bind(this);
+
+    this.request(url);
+  },
+
+  updateContent: function() {
+    var receiver = this.container[this.success() ? 'success' : 'failure'];
+    var response = this.transport.responseText;
+
+    if (!this.options.evalScripts) response = response.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (this.options.insertion)
+        new this.options.insertion(receiver, response);
+      else
+        receiver.update(response);
+    }
+
+    if (this.success()) {
+      if (this.onComplete)
+        setTimeout(this.onComplete.bind(this), 10);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(container, url, options) {
+    this.setOptions(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = {};
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(request) {
+    if (this.options.decay) {
+      this.decay = (request.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = request.responseText;
+    }
+    this.timer = setTimeout(this.onTimerEvent.bind(this),
+      this.decay * this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (typeof element == 'string')
+    element = document.getElementById(element);
+  return Element.extend(element);
+};
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(query.snapshotItem(i));
+    return results;
+  };
+};
+
+document.getElementsByClassName = function(className, parentElement) {
+  if (Prototype.BrowserFeatures.XPath) {
+    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+    return document._getElementsByXPath(q, parentElement);
+  } else {
+    var children = ($(parentElement) || document.body).getElementsByTagName('*');
+    var elements = [], child;
+    for (var i = 0, length = children.length; i < length; i++) {
+      child = children[i];
+      if (Element.hasClassName(child, className))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element)
+  var Element = new Object();
+
+Element.extend = function(element) {
+  if (!element || _nativeExtensions || element.nodeType == 3) return element;
+
+  if (!element._extended && element.tagName && element != window) {
+    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+    if (element.tagName == 'FORM')
+      Object.extend(methods, Form.Methods);
+    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+      Object.extend(methods, Form.Element.Methods);
+
+    Object.extend(methods, Element.Methods.Simulated);
+
+    for (var property in methods) {
+      var value = methods[property];
+      if (typeof value == 'function' && !(property in element))
+        element[property] = cache.findOrStore(value);
+    }
+  }
+
+  element._extended = true;
+  return element;
+};
+
+Element.extend.cache = {
+  findOrStore: function(value) {
+    return this[value] = this[value] || function() {
+      return value.apply(null, [this].concat($A(arguments)));
+    }
+  }
+};
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: function(element, html) {
+    html = typeof html == 'undefined' ? '' : html.toString();
+    $(element).innerHTML = html.stripScripts();
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  replace: function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    if (element.outerHTML) {
+      element.outerHTML = html.stripScripts();
+    } else {
+      var range = element.ownerDocument.createRange();
+      range.selectNodeContents(element);
+      element.parentNode.replaceChild(
+        range.createContextualFragment(html.stripScripts()), element);
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*'));
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (typeof selector == 'string')
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    return Selector.findElement($(element).ancestors(), expression, index);
+  },
+
+  down: function(element, expression, index) {
+    return Selector.findElement($(element).descendants(), expression, index);
+  },
+
+  previous: function(element, expression, index) {
+    return Selector.findElement($(element).previousSiblings(), expression, index);
+  },
+
+  next: function(element, expression, index) {
+    return Selector.findElement($(element).nextSiblings(), expression, index);
+  },
+
+  getElementsBySelector: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  getElementsByClassName: function(element, className) {
+    return document.getElementsByClassName(className, element);
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (document.all && !window.opera) {
+      var t = Element._attributeTranslations;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name])  name = t.names[name];
+      var attribute = element.attributes[name];
+      if(attribute) return attribute.nodeValue;
+    }
+    return element.getAttribute(name);
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    if (elementClassName.length == 0) return false;
+    if (elementClassName == className ||
+        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      return true;
+    return false;
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).add(className);
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).remove(className);
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+    return element;
+  },
+
+  observe: function() {
+    Event.observe.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  stopObserving: function() {
+    Event.stopObserving.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.match(/^\s*$/);
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Position.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    if (['float','cssFloat'].include(style))
+      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+    style = style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      if (document.defaultView && document.defaultView.getComputedStyle) {
+        var css = document.defaultView.getComputedStyle(element, null);
+        value = css ? css[style] : null;
+      } else if (element.currentStyle) {
+        value = element.currentStyle[style];
+      }
+    }
+
+    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+      value = element['offset'+style.capitalize()] + 'px';
+
+    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+    if(style == 'opacity') {
+      if(value) return parseFloat(value);
+      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if(value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+    return value == 'auto' ? null : value;
+  },
+
+  setStyle: function(element, style) {
+    element = $(element);
+    for (var name in style) {
+      var value = style[name];
+      if(name == 'opacity') {
+        if (value == 1) {
+          value = (/Gecko/.test(navigator.userAgent) &&
+            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else if(value == '') {
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else {
+          if(value < 0.00001) value = 0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+              'alpha(opacity='+value*100+')';
+        }
+      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+      element.style[name.camelize()] = value;
+    }
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      if (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = element.style.overflow || 'auto';
+    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+  colspan:   "colSpan",
+  rowspan:   "rowSpan",
+  valign:    "vAlign",
+  datetime:  "dateTime",
+  accesskey: "accessKey",
+  tabindex:  "tabIndex",
+  enctype:   "encType",
+  maxlength: "maxLength",
+  readonly:  "readOnly",
+  longdesc:  "longDesc"
+};
+
+Element._attributeTranslations.values = {
+  _getAttr: function(element, attribute) {
+    return element.getAttribute(attribute, 2);
+  },
+
+  _flag: function(element, attribute) {
+    return $(element).hasAttribute(attribute) ? attribute : null;
+  },
+
+  style: function(element) {
+    return element.style.cssText.toLowerCase();
+  },
+
+  title: function(element) {
+    var node = element.getAttributeNode('title');
+    return node.specified ? node.nodeValue : null;
+  }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+  href: Element._attributeTranslations.values._getAttr,
+  src:  Element._attributeTranslations.values._getAttr,
+  disabled: Element._attributeTranslations.values._flag,
+  checked:  Element._attributeTranslations.values._flag,
+  readonly: Element._attributeTranslations.values._flag,
+  multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = t.names[attribute] || attribute;
+    return $(element).getAttributeNode(attribute).specified;
+  }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+  Element.Methods.update = function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    var tagName = element.tagName.toUpperCase();
+    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+      var div = document.createElement('div');
+      switch (tagName) {
+        case 'THEAD':
+        case 'TBODY':
+          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
+          depth = 2;
+          break;
+        case 'TR':
+          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
+          depth = 3;
+          break;
+        case 'TD':
+          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
+          depth = 4;
+      }
+      $A(element.childNodes).each(function(node){
+        element.removeChild(node)
+      });
+      depth.times(function(){ div = div.firstChild });
+
+      $A(div.childNodes).each(
+        function(node){ element.appendChild(node) });
+    } else {
+      element.innerHTML = html.stripScripts();
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  }
+};
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+    var className = 'HTML' + tag + 'Element';
+    if(window[className]) return;
+    var klass = window[className] = {};
+    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+  });
+
+Element.addMethods = function(methods) {
+  Object.extend(Element.Methods, methods || {});
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    var cache = Element.extend.cache;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = cache.findOrStore(value);
+    }
+  }
+
+  if (typeof HTMLElement != 'undefined') {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Form.Methods, HTMLFormElement.prototype);
+    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+      copy(Form.Element.Methods, klass.prototype);
+    });
+    _nativeExtensions = true;
+  }
+};
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+  this.adjacency = adjacency;
+};
+
+Abstract.Insertion.prototype = {
+  initialize: function(element, content) {
+    this.element = $(element);
+    this.content = content.stripScripts();
+
+    if (this.adjacency && this.element.insertAdjacentHTML) {
+      try {
+        this.element.insertAdjacentHTML(this.adjacency, this.content);
+      } catch (e) {
+        var tagName = this.element.tagName.toUpperCase();
+        if (['TBODY', 'TR'].include(tagName)) {
+          this.insertContent(this.contentFromAnonymousTable());
+        } else {
+          throw e;
+        }
+      }
+    } else {
+      this.range = this.element.ownerDocument.createRange();
+      if (this.initializeRange) this.initializeRange();
+      this.insertContent([this.range.createContextualFragment(this.content)]);
+    }
+
+    setTimeout(function() {content.evalScripts()}, 10);
+  },
+
+  contentFromAnonymousTable: function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+    return $A(div.childNodes[0].childNodes[0].childNodes);
+  }
+};
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+  initializeRange: function() {
+    this.range.setStartBefore(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment, this.element);
+    }).bind(this));
+  }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(true);
+  },
+
+  insertContent: function(fragments) {
+    fragments.reverse(false).each((function(fragment) {
+      this.element.insertBefore(fragment, this.element.firstChild);
+    }).bind(this));
+  }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.appendChild(fragment);
+    }).bind(this));
+  }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+  initializeRange: function() {
+    this.range.setStartAfter(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment,
+        this.element.nextSibling);
+    }).bind(this));
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+  initialize: function(expression) {
+    this.params = {classNames: []};
+    this.expression = expression.toString().strip();
+    this.parseExpression();
+    this.compileMatcher();
+  },
+
+  parseExpression: function() {
+    function abort(message) { throw 'Parse error in selector: ' + message; }
+
+    if (this.expression == '')  abort('empty expression');
+
+    var params = this.params, expr = this.expression, match, modifier, clause, rest;
+    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+      params.attributes = params.attributes || [];
+      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+      expr = match[1];
+    }
+
+    if (expr == '*') return this.params.wildcard = true;
+
+    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+      modifier = match[1], clause = match[2], rest = match[3];
+      switch (modifier) {
+        case '#':       params.id = clause; break;
+        case '.':       params.classNames.push(clause); break;
+        case '':
+        case undefined: params.tagName = clause.toUpperCase(); break;
+        default:        abort(expr.inspect());
+      }
+      expr = rest;
+    }
+
+    if (expr.length > 0) abort(expr.inspect());
+  },
+
+  buildMatchExpression: function() {
+    var params = this.params, conditions = [], clause;
+
+    if (params.wildcard)
+      conditions.push('true');
+    if (clause = params.id)
+      conditions.push('element.readAttribute("id") == ' + clause.inspect());
+    if (clause = params.tagName)
+      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+    if ((clause = params.classNames).length > 0)
+      for (var i = 0, length = clause.length; i < length; i++)
+        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
+    if (clause = params.attributes) {
+      clause.each(function(attribute) {
+        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
+        var splitValueBy = function(delimiter) {
+          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+        };
+
+        switch (attribute.operator) {
+          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
+          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+          case '|=':      conditions.push(
+                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+                          ); break;
+          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
+          case '':
+          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
+          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
+        }
+      });
+    }
+
+    return conditions.join(' && ');
+  },
+
+  compileMatcher: function() {
+    this.match = new Function('element', 'if (!element.tagName) return false; element = $(element); return ' + this.buildMatchExpression());
+  },
+
+  findElements: function(scope) {
+    var element;
+
+    if (element = $(this.params.id))
+      if (this.match(element))
+        if (!scope || Element.childOf(element, scope))
+          return [element];
+
+    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+    var results = [];
+    for (var i = 0, length = scope.length; i < length; i++)
+      if (this.match(element = scope[i]))
+        results.push(Element.extend(element));
+
+    return results;
+  },
+
+  toString: function() {
+    return this.expression;
+  }
+};
+
+Object.extend(Selector, {
+  matchElements: function(elements, expression) {
+    var selector = new Selector(expression);
+    return elements.select(selector.match.bind(selector)).map(Element.extend);
+  },
+
+  findElement: function(elements, expression, index) {
+    if (typeof expression == 'number') index = expression, expression = false;
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    return expressions.map(function(expression) {
+      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+        var selector = new Selector(expr);
+        return results.inject([], function(elements, result) {
+          return elements.concat(selector.findElements(result || element));
+        });
+      });
+    }).flatten();
+  }
+});
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+};
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, getHash) {
+    var data = elements.inject({}, function(result, element) {
+      if (!element.disabled && element.name) {
+        var key = element.name, value = $(element).getValue();
+        if (value != undefined) {
+          value = escape(value);
+          if (result[key]) {
+            if (result[key].constructor != Array) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return getHash ? data : Hash.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, getHash) {
+    return Form.serializeElements(Form.getElements(form), getHash);
+  },
+
+  getElements: function(form) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.blur();
+      element.disabled = 'true';
+    });
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.disabled = '';
+    });
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    return $(form).getElements().find(function(element) {
+      return element.type != 'hidden' && !element.disabled &&
+        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  }
+};
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+};
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = {};
+        pair[element.name] = value;
+        return Hash.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+      !['button', 'reset', 'submit'].include(element.type) ) )
+      element.select();
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = false;
+    return element;
+  }
+};
+
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element);
+      default:
+        return Form.Element.Serializers.textarea(element);
+    }
+  },
+
+  inputSelector: function(element) {
+    return element.checked ? element.value : null;
+  },
+
+  textarea: function(element) {
+    return element.value;
+  },
+
+  select: function(element) {
+    return this[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {};
+Abstract.TimedObserver.prototype = {
+  initialize: function(element, frequency, callback) {
+    this.frequency = frequency;
+    this.element   = $(element);
+    this.callback  = callback;
+
+    this.lastValue = this.getValue();
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    var value = this.getValue();
+    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+      ? this.lastValue != value : String(this.lastValue) != String(value));
+    if (changed) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+};
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {};
+Abstract.EventObserver.prototype = {
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback.bind(this));
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+};
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) {
+  var Event = new Object();
+};
+
+Object.extend(Event, {
+  KEY_BACKSPACE: 8,
+  KEY_TAB:       9,
+  KEY_RETURN:   13,
+  KEY_ESC:      27,
+  KEY_LEFT:     37,
+  KEY_UP:       38,
+  KEY_RIGHT:    39,
+  KEY_DOWN:     40,
+  KEY_DELETE:   46,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
+
+  element: function(event) {
+    return event.target || event.srcElement;
+  },
+
+  isLeftClick: function(event) {
+    return (((event.which) && (event.which == 1)) ||
+            ((event.button) && (event.button == 1)));
+  },
+
+  pointerX: function(event) {
+    return event.pageX || (event.clientX +
+      (document.documentElement.scrollLeft || document.body.scrollLeft));
+  },
+
+  pointerY: function(event) {
+    return event.pageY || (event.clientY +
+      (document.documentElement.scrollTop || document.body.scrollTop));
+  },
+
+  stop: function(event) {
+    if (event.preventDefault) {
+      event.preventDefault();
+      event.stopPropagation();
+    } else {
+      event.returnValue = false;
+      event.cancelBubble = true;
+    }
+  },
+
+  // find the first node with the given tagName, starting from the
+  // node the event was triggered on; traverses the DOM upwards
+  findElement: function(event, tagName) {
+    var element = Event.element(event);
+    while (element.parentNode && (!element.tagName ||
+        (element.tagName.toUpperCase() != tagName.toUpperCase())))
+      element = element.parentNode;
+    return element;
+  },
+
+  observers: false,
+
+  _observeAndCache: function(element, name, observer, useCapture) {
+    if (!this.observers) this.observers = [];
+    if (element.addEventListener) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.addEventListener(name, observer, useCapture);
+    } else if (element.attachEvent) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.attachEvent('on' + name, observer);
+    }
+  },
+
+  unloadCache: function() {
+    if (!Event.observers) return;
+    for (var i = 0, length = Event.observers.length; i < length; i++) {
+      Event.stopObserving.apply(this, Event.observers[i]);
+      Event.observers[i][0] = null;
+    }
+    Event.observers = false;
+  },
+
+  observe: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.attachEvent))
+      name = 'keydown';
+
+    Event._observeAndCache(element, name, observer, useCapture);
+  },
+
+  stopObserving: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.detachEvent))
+      name = 'keydown';
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, observer, useCapture);
+    } else if (element.detachEvent) {
+      try {
+        element.detachEvent('on' + name, observer);
+      } catch (e) {}
+    }
+  }
+});
+
+/* prevent memory leaks in IE */
+if (navigator.appVersion.match(/\bMSIE\b/))
+  Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  realOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if(element.tagName=='BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  offsetParent: function(element) {
+    if (element.offsetParent) return element.offsetParent;
+    if (element == document.body) return element;
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return element;
+
+    return document.body;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = this.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = this.realOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = this.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  page: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent==document.body)
+        if (Element.getStyle(element,'position')=='absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!window.opera || element.tagName=='BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return [valueL, valueT];
+  },
+
+  clone: function(source, target) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || {});
+
+    // find page position of source
+    source = $(source);
+    var p = Position.page(source);
+
+    // find coordinate system to use
+    target = $(target);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(target,'position') == 'absolute') {
+      parent = Position.offsetParent(target);
+      delta = Position.page(parent);
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
+    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.style.position == 'absolute') return;
+    Position.prepare();
+
+    var offsets = Position.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.style.position == 'relative') return;
+    Position.prepare();
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+  }
+};
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+  Position.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return [valueL, valueT];
+  }
+};
+
+Element.addMethods();
Index: /sandbox/workflow/branches/993/js/jscode/abas.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/abas.js	(revision 2371)
+++ /sandbox/workflow/branches/993/js/jscode/abas.js	(revision 2371)
@@ -0,0 +1,129 @@
+var tabStack = new Array();
+
+function initBorders(num)
+{
+	for (ix=0; ix < num; ix++)
+	{
+		BordersArray[ix] = new setBorderAttributes(ix);
+	}
+}
+
+function setBorderAttributes(ID)
+{
+	this.border_id = "border_id_"+ID;
+	this.sequence = ID; 
+}
+
+function alternate_border(ID)
+{
+	if (!document.getElementById("border_id_"+ID))
+		return;
+	tabStack.push(ID);
+	var len = BordersArray.length;
+	for (var i=0; i < len; i++)
+	{
+		m = document.getElementById(BordersArray[i].border_id);
+		m.className = 'menu';
+		c = document.getElementById("content_id_"+BordersArray[i].sequence);
+		if (is_ie) {
+			c.className = "conteudo_div_ie";
+		}
+		c.style.display = 'none';
+	}
+	
+	m = document.getElementById("border_id_"+ID);
+	m.className = 'menu-sel';
+	c = document.getElementById("content_id_"+ID);
+	c.style.display = '';
+		
+	return c.childNodes.length;
+}
+
+function create_border(borderTitle)
+{
+	var ID = (BordersArray[(BordersArray.length-1)].sequence + 1);
+	
+	td = document.createElement("TD");
+	td.id="border_id_" + ID;
+	td.setAttribute("width", "auto");
+	td.className = "menu";
+	td.setAttribute("align", "right");
+	td.onclick = function(){alternate_border(ID);};
+	td.setAttribute("noWrap","true");
+	
+	borderTitle = borderTitle ?  borderTitle : "Sem assunto";
+	td.title = borderTitle;
+
+	if (borderTitle.length > 30){
+		borderTitle = borderTitle.substring(0,30) + "...";
+	}
+	
+	td.innerHTML = "&nbsp;&nbsp;" + borderTitle + " <img style='cursor:pointer' onclick=delete_border('" + ID + "') src='" + _icon_dir + "/close_button.gif'>";
+		
+	bb = document.getElementById("border_blank");
+	parent_bb = bb.parentNode; //Pego o tbody
+	parent_bb.insertBefore(td, bb);
+	
+	BordersArray[BordersArray.length] = new setBorderAttributes(ID);
+	
+	var div = document.createElement("DIV");
+	div.id = "content_id_" + ID;
+	if (is_ie) {
+		div.className = "conteudo_div_ie";
+	} else {
+		div.className = "conteudo";
+	}
+	div.style.display='';
+
+	document.getElementById("main_body").appendChild(div);
+	alternate_border(ID);
+	
+	return ID;
+}
+
+function delete_border(ID)
+{
+	for (i=0;i<BordersArray.length;i++)
+	{
+		m = document.getElementById(BordersArray[i].border_id);
+		if (m.className == 'menu-sel')
+			border_selected = BordersArray[i].border_id;
+	}
+	
+	if ('border_id_' + ID == border_selected)
+	{
+		var previousTab;
+		var nextTab = -1;
+		while (tabStack.length > 0)
+		{
+			previousTab = tabStack.pop();
+			if (previousTab != ID)
+				if (document.getElementById('content_id_' + previousTab))
+				{
+					nextTab = previousTab;
+					break;
+				}
+		}
+		if (nextTab == -1)
+			nextTab = (BordersArray[i-2].sequence == ID) ? 0 : BordersArray[i-2].sequence;
+		this.alternate_border(nextTab);
+	}
+
+	// Remove TD, title
+	border = document.getElementById('border_id_' + ID);
+	border.parentNode.removeChild(border);
+	// Remove Div Content
+	content = document.getElementById('content_id_' + ID);
+	content.parentNode.removeChild(content);
+	
+	var new_BordersArray = new Array();
+	j = 0;
+	for (i=0;i<BordersArray.length;i++)
+	{
+		if (document.getElementById(BordersArray[i].border_id) != null){
+			new_BordersArray[j] = BordersArray[i];
+			j++;	
+		}
+	}
+	BordersArray = new_BordersArray;	
+}
Index: /sandbox/workflow/branches/993/js/jscode/sniff_browser.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/sniff_browser.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/sniff_browser.js	(revision 795)
@@ -0,0 +1,204 @@
+//<!--
+// Ultimate client-side JavaScript client sniff. Version 3.03
+// (C) Netscape Communications 1999-2001.  Permission granted to reuse and distribute.
+// Revised 17 May 99 to add is_nav5up and is_ie5up (see below).
+// Revised 20 Dec 00 to add is_gecko and change is_nav5up to is_nav6up
+//                      also added support for IE5.5 Opera4&5 HotJava3 AOLTV
+// Revised 22 Feb 01 to correct Javascript Detection for IE 5.x, Opera 4, 
+//                      correct Opera 5 detection
+//                      add support for winME and win2k
+//                      synch with browser-type-oo.js
+// Revised 26 Mar 01 to correct Opera detection
+// Revised 02 Oct 01 to add IE6 detection
+
+// Everything you always wanted to know about your JavaScript client
+// but were afraid to ask. Creates "is_" variables indicating:
+// (1) browser vendor:
+//     is_nav, is_ie, is_opera, is_hotjava, is_webtv, is_TVNavigator, is_AOLTV
+// (2) browser version number:
+//     is_major (integer indicating major version number: 2, 3, 4 ...)
+//     is_minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...)
+// (3) browser vendor AND major version number
+//     is_nav2, is_nav3, is_nav4, is_nav4up, is_nav6, is_nav6up, is_gecko, is_ie3,
+//     is_ie4, is_ie4up, is_ie5, is_ie5up, is_ie5_5, is_ie5_5up, is_ie6, is_ie6up, is_hotjava3, is_hotjava3up,
+//     is_opera2, is_opera3, is_opera4, is_opera5, is_opera5up
+// (4) JavaScript version number:
+//     is_js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
+// (5) OS platform and version:
+//     is_win, is_win16, is_win32, is_win31, is_win95, is_winnt, is_win98, is_winme, is_win2k
+//     is_os2
+//     is_mac, is_mac68k, is_macppc
+//     is_unix
+//     is_sun, is_sun4, is_sun5, is_suni86
+//     is_irix, is_irix5, is_irix6
+//     is_hpux, is_hpux9, is_hpux10
+//     is_aix, is_aix1, is_aix2, is_aix3, is_aix4
+//     is_linux, is_sco, is_unixware, is_mpras, is_reliant
+//     is_dec, is_sinix, is_freebsd, is_bsd
+//     is_vms
+//
+// See http://www.it97.de/JavaScript/JS_tutorial/bstat/navobj.html and
+// http://www.it97.de/JavaScript/JS_tutorial/bstat/Browseraol.html
+// for detailed lists of userAgent strings.
+//
+// Note: you don't want your Nav4 or IE4 code to "turn off" or
+// stop working when new versions of browsers are released, so
+// in conditional code forks, use is_ie5up ("IE 5.0 or greater") 
+// is_opera5up ("Opera 5.0 or greater") instead of is_ie5 or is_opera5
+// to check version in code which you want to work on future
+// versions.
+
+    // convert all characters to lowercase to simplify testing
+    var agt=navigator.userAgent.toLowerCase();
+
+    // *** BROWSER VERSION ***
+    // Note: On IE5, these return 4, so use is_ie5up to detect IE5.
+    var is_major = parseInt(navigator.appVersion);
+    var is_minor = parseFloat(navigator.appVersion);
+
+    // Note: Opera and WebTV spoof Navigator.  We do strict client detection.
+    // If you want to allow spoofing, take out the tests for opera and webtv.
+    var is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
+                && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
+                && (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
+    var is_nav2 = (is_nav && (is_major == 2));
+    var is_nav3 = (is_nav && (is_major == 3));
+    var is_nav4 = (is_nav && (is_major == 4));
+    var is_nav4up = (is_nav && (is_major >= 4));
+    var is_navonly      = (is_nav && ((agt.indexOf(";nav") != -1) ||
+                          (agt.indexOf("; nav") != -1)) );
+    var is_nav6 = (is_nav && (is_major == 5));
+    var is_nav6up = (is_nav && (is_major >= 5));
+    var is_gecko = (agt.indexOf('gecko') != -1);
+
+
+    var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
+    var is_ie3    = (is_ie && (is_major < 4));
+    var is_ie4    = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
+    var is_ie4up  = (is_ie && (is_major >= 4));
+    var is_ie5    = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")!=-1) );
+    var is_ie5_5  = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.5") !=-1));
+    var is_ie5up  = (is_ie && !is_ie3 && !is_ie4);
+    var is_ie5_5up =(is_ie && !is_ie3 && !is_ie4 && !is_ie5);
+    var is_ie6    = (is_ie && (is_major == 4) && (agt.indexOf("msie 6.")!=-1) );
+    var is_ie6up  = (is_ie && !is_ie3 && !is_ie4 && !is_ie5 && !is_ie5_5);
+
+    // KNOWN BUG: On AOL4, returns false if IE3 is embedded browser
+    // or if this is the first browser window opened.  Thus the
+    // variables is_aol, is_aol3, and is_aol4 aren't 100% reliable.
+    var is_aol   = (agt.indexOf("aol") != -1);
+    var is_aol3  = (is_aol && is_ie3);
+    var is_aol4  = (is_aol && is_ie4);
+    var is_aol5  = (agt.indexOf("aol 5") != -1);
+    var is_aol6  = (agt.indexOf("aol 6") != -1);
+
+    var is_opera = (agt.indexOf("opera") != -1);
+    var is_opera2 = (agt.indexOf("opera 2") != -1 || agt.indexOf("opera/2") != -1);
+    var is_opera3 = (agt.indexOf("opera 3") != -1 || agt.indexOf("opera/3") != -1);
+    var is_opera4 = (agt.indexOf("opera 4") != -1 || agt.indexOf("opera/4") != -1);
+    var is_opera5 = (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1);
+    var is_opera5up = (is_opera && !is_opera2 && !is_opera3 && !is_opera4);
+
+    var is_webtv = (agt.indexOf("webtv") != -1); 
+
+    var is_TVNavigator = ((agt.indexOf("navio") != -1) || (agt.indexOf("navio_aoltv") != -1)); 
+    var is_AOLTV = is_TVNavigator;
+
+    var is_hotjava = (agt.indexOf("hotjava") != -1);
+    var is_hotjava3 = (is_hotjava && (is_major == 3));
+    var is_hotjava3up = (is_hotjava && (is_major >= 3));
+
+    // *** JAVASCRIPT VERSION CHECK ***
+    var is_js;
+    if (is_nav2 || is_ie3) is_js = 1.0;
+    else if (is_nav3) is_js = 1.1;
+    else if (is_opera5up) is_js = 1.3;
+    else if (is_opera) is_js = 1.1;
+    else if ((is_nav4 && (is_minor <= 4.05)) || is_ie4) is_js = 1.2;
+    else if ((is_nav4 && (is_minor > 4.05)) || is_ie5) is_js = 1.3;
+    else if (is_hotjava3up) is_js = 1.4;
+    else if (is_nav6 || is_gecko) is_js = 1.5;
+    // NOTE: In the future, update this code when newer versions of JS
+    // are released. For now, we try to provide some upward compatibility
+    // so that future versions of Nav and IE will show they are at
+    // *least* JS 1.x capable. Always check for JS version compatibility
+    // with > or >=.
+    else if (is_nav6up) is_js = 1.5;
+    // NOTE: ie5up on mac is 1.4
+    else if (is_ie5up) is_js = 1.3;
+
+    // HACK: no idea for other browsers; always check for JS version with > or >=
+    else is_js = 0.0;
+
+    // *** PLATFORM ***
+    var is_win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) );
+    // NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
+    //        Win32, so you can't distinguish between Win95 and WinNT.
+    var is_win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1));
+
+    // is this a 16 bit compiled version?
+    var is_win16 = ((agt.indexOf("win16")!=-1) || 
+               (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1) || 
+               (agt.indexOf("windows 16-bit")!=-1) );  
+
+    var is_win31 = ((agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
+                    (agt.indexOf("windows 16-bit")!=-1));
+
+    var is_winme = ((agt.indexOf("win 9x 4.90")!=-1));
+    var is_win2k = ((agt.indexOf("windows nt 5.0")!=-1));
+
+    // NOTE: Reliable detection of Win98 may not be possible. It appears that:
+    //       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
+    //       - On Mercury client, the 32-bit version will return "Win98", but
+    //         the 16-bit version running on Win98 will still return "Win95".
+    var is_win98 = ((agt.indexOf("win98")!=-1) || (agt.indexOf("windows 98")!=-1));
+    var is_winnt = ((agt.indexOf("winnt")!=-1) || (agt.indexOf("windows nt")!=-1));
+    var is_win32 = (is_win95 || is_winnt || is_win98 || 
+                    ((is_major >= 4) && (navigator.platform == "Win32")) ||
+                    (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1));
+
+    var is_os2   = ((agt.indexOf("os/2")!=-1) || 
+                    (navigator.appVersion.indexOf("OS/2")!=-1) ||   
+                    (agt.indexOf("ibm-webexplorer")!=-1));
+
+    var is_mac    = (agt.indexOf("mac")!=-1);
+    // hack ie5 js version for mac
+    if (is_mac && is_ie5up) is_js = 1.4;
+    var is_mac68k = (is_mac && ((agt.indexOf("68k")!=-1) || 
+                               (agt.indexOf("68000")!=-1)));
+    var is_macppc = (is_mac && ((agt.indexOf("ppc")!=-1) || 
+                                (agt.indexOf("powerpc")!=-1)));
+
+    var is_sun   = (agt.indexOf("sunos")!=-1);
+    var is_sun4  = (agt.indexOf("sunos 4")!=-1);
+    var is_sun5  = (agt.indexOf("sunos 5")!=-1);
+    var is_suni86= (is_sun && (agt.indexOf("i86")!=-1));
+    var is_irix  = (agt.indexOf("irix") !=-1);    // SGI
+    var is_irix5 = (agt.indexOf("irix 5") !=-1);
+    var is_irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1));
+    var is_hpux  = (agt.indexOf("hp-ux")!=-1);
+    var is_hpux9 = (is_hpux && (agt.indexOf("09.")!=-1));
+    var is_hpux10= (is_hpux && (agt.indexOf("10.")!=-1));
+    var is_aix   = (agt.indexOf("aix") !=-1);      // IBM
+    var is_aix1  = (agt.indexOf("aix 1") !=-1);    
+    var is_aix2  = (agt.indexOf("aix 2") !=-1);    
+    var is_aix3  = (agt.indexOf("aix 3") !=-1);    
+    var is_aix4  = (agt.indexOf("aix 4") !=-1);    
+    var is_linux = (agt.indexOf("inux")!=-1);
+    var is_sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1);
+    var is_unixware = (agt.indexOf("unix_system_v")!=-1); 
+    var is_mpras    = (agt.indexOf("ncr")!=-1); 
+    var is_reliant  = (agt.indexOf("reliantunix")!=-1);
+    var is_dec   = ((agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1) || 
+           (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1) || 
+           (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1)); 
+    var is_sinix = (agt.indexOf("sinix")!=-1);
+    var is_freebsd = (agt.indexOf("freebsd")!=-1);
+    var is_bsd = (agt.indexOf("bsd")!=-1);
+    var is_unix  = ((agt.indexOf("x11")!=-1) || is_sun || is_irix || is_hpux || 
+                 is_sco ||is_unixware || is_mpras || is_reliant || 
+                 is_dec || is_sinix || is_aix || is_linux || is_bsd || is_freebsd);
+
+    var is_vms   = ((agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1));
+
+//--> end hide JavaScript
Index: /sandbox/workflow/branches/993/js/jscode/adminInterface.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/adminInterface.js	(revision 1710)
+++ /sandbox/workflow/branches/993/js/jscode/adminInterface.js	(revision 1710)
@@ -0,0 +1,21 @@
+function toggleTableVisibility(tableID)
+{
+	var rows = document.getElementById(tableID).rows;
+	var visibility = (rows[1].style.display == '') ? 'none' : '';
+	for (var i = 1; i < rows.length; i++)
+		rows[i].style.display = visibility;
+	document.getElementById('toggleLink').innerHTML = (visibility == 'none') ? 'Expandir' : 'Contrair';
+}
+
+function toggleDefaultUserVisibility(divIndex)
+{
+	document.getElementById('div_default_user_option_0').style.display = (divIndex==0)? 'block':'none';
+	document.getElementById('div_default_user_option_1').style.display = (divIndex==1)? 'block':'none';
+
+	if (divIndex == 1){
+		document.getElementById('default_user_temp').value = document.getElementById('default_user').value;
+		document.getElementById('default_user').value = document.getElementById('default_roles').value;
+	} else if (divIndex == 0){
+		document.getElementById('default_user').value = document.getElementById('default_user_temp').value;
+	}
+}
Index: /sandbox/workflow/branches/993/js/jscode/generic_select.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/generic_select.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/generic_select.js	(revision 795)
@@ -0,0 +1,93 @@
+var target;
+var target_desc;
+var source;
+
+function genericListSetLists(source_id,target_id)
+{
+	target   		= window.opener.document.getElementById(target_id);
+	target_desc 	= window.opener.document.getElementById(target_id + "_desc");
+	source 			= window.document.getElementById(source_id);
+}
+
+function genericCheckShortcuts(e)
+{
+	var whichCode = (e.which) ? e.which : e.keyCode;
+	var handled = false;
+
+	if (whichCode == 13) /* ENTER */
+		handled = true;
+
+	if (whichCode == 27) /* ESC */
+	{
+		document.getElementById("closeButton").onclick();
+		handled = true;
+	}
+
+	if (whichCode == 38) /* key up */
+	{
+		if (source.selectedIndex > 0)
+			if (!source[source.selectedIndex - 1].disabled)
+				source.selectedIndex--;
+		handled = true;
+	}
+
+	if (whichCode == 40) /* key down */
+	{
+		if (source.selectedIndex < source.length - 1)
+			if (!source[source.selectedIndex + 1].disabled)
+				source.selectedIndex++;
+		handled = true;
+	}
+
+	return handled;
+}
+
+function genericListOptionFinder(oText, e)
+{
+	if (genericCheckShortcuts(e))
+		return true;
+
+	var searchText = oText.value.toUpperCase();
+	var textSize = searchText.length;
+	for(i = 0; i < source.length; i++)
+	if(source[i].text.substring(0 ,textSize).toUpperCase() == searchText)
+	{
+		source.value = source[i].value;
+		break;
+	}
+}
+
+function genericListAdd()
+{
+	for (var i = 0 ; i < source.length ; i++)
+		if (source.options[i].selected)
+		{
+			target.value = source.options[i].value;
+			target_desc.value = source.options[i].text;
+			break;
+		}
+}
+
+function genericListRemove(target_name, target_desc_name)
+{
+	var target = document.getElementById(target_name);
+	var target_desc = document.getElementById(target_desc_name);
+	target.value = '';
+	target_desc.value = '';
+}
+
+function openGenericList(target, option)
+{
+	newWidth   = 350;
+	newHeight  = 500;
+	newScreenX = screen.width - newWidth;
+	newScreenY = 0;
+	page = 'index.php?menuaction=workflow.ui_generic_select.form';
+	if (target)
+		page += "&target_element=" + target;
+
+	if (option)
+		page += "&" + option;
+
+	window.open(page,'','width='+newWidth+',height='+newHeight+',screenX='+newScreenX+',left='+newScreenX+',screenY='+newScreenY+',top='+newScreenY+',toolbar=no,scrollbars=no,resizable=no');
+}
Index: /sandbox/workflow/branches/993/js/jscode/wf_autocomplete_input.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wf_autocomplete_input.js	(revision 2160)
+++ /sandbox/workflow/branches/993/js/jscode/wf_autocomplete_input.js	(revision 2160)
@@ -0,0 +1,257 @@
+var _cache = new Array();
+var autocompleterObjs = new Array();
+var myTimer;
+
+/* Verifica se o componente já foi populado (usado quando o tipo do componente é POPULATE_ON_LOAD) */
+function checkDataLoaded(elementId)
+{
+	if (_cache['elements'][elementId]['populated'] !== true
+		&& _cache['requests'][_cache['elements'][elementId]['hash']]['populated'] == true)
+	{
+		autocompletePopulate(elementId);
+	}
+}
+
+function showResult(elementId)
+{
+	var index = $(elementId).value;
+	var textResponse = (index == -1)? "Nenhum resultado encontrado!" : "OK";
+	$('response' + elementId).innerHTML = textResponse;
+	$('response' + elementId).className = (index == -1)? "span_message_error" : "span_message_success";
+}
+
+/* Faz a verificação se o conteúdo digitado tem um correspondente na lista */
+function selectAutocompleteElement(elementId)
+{
+	if ($('input' + elementId) == null) return -1;
+	var value = $('input' + elementId).value;
+	var items = new Object();
+	if(_cache['requests'][_cache['elements'][elementId]['hash']] != undefined)
+		items = _cache['requests'][_cache['elements'][elementId]['hash']]['data'];
+	var index = autocompleteIndexOf(items, value);
+	$(elementId).value = index;
+
+	$('response' + elementId).innerHTML = typeof(items);
+	showResult(elementId);
+}
+
+/* Percorre o objeto comparando cada item com o valor digitado no componente, e retorna o índice, se encontrar */
+function autocompleteIndexOf(items, value)
+{
+	for (key in items){
+		if(items.hasOwnProperty(key)){
+			if (items[key].toLowerCase() == value.toLowerCase()){
+				return key;
+			}
+		}
+	}
+	return -1;
+}
+
+function arrayValues(items)
+{
+	var i = 0;
+	var arr = Array();
+	for (key in items){
+		arr[i++] = items[key];
+	}
+	return arr;
+}
+
+function removeAccents(text) {
+	var accents = 'áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ';
+	var normalLetters = 'aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC';
+	var newText = '';
+
+	for (i = 0; i < text.length; i++) {
+		if (accents.search(text.substr(i, 1)) >= 0) {
+			newText += normalLetters.substr(accents.search(text.substr(i, 1)), 1);
+		}
+		else {
+			newText += text.substr(i, 1);
+		}
+	}
+
+	return newText;
+}
+
+/* Cria, ou recria, o objeto autocompleter do componente, carregando a lista com os valores que já devem estar no cache */
+function autocompletePopulate(elementId)
+{
+	if (_cache['elements'][elementId]['populated'] == null){
+		var items = _cache['requests'][_cache['elements'][elementId]['hash']]['data'];
+		var values = arrayValues(items);
+		autocompleterObjs[elementId] = new Autocompleter.Local('input' + elementId, 'list' + elementId, values, {
+			'choices':9,
+			'partialChars': _cache['elements'][elementId]['minLength']
+		});
+		_cache['elements'][elementId]['populated'] = true;
+	}
+}
+
+/* Cria array para armazenar os elementos */
+function createCacheElementsArray(){
+	if(_cache['elements'] == null)
+		_cache['elements'] = new Array();
+}
+
+/* Cria array para armazenar os valores das requisições ajax */
+function createCacheRequestsArray(){
+	if(_cache['requests'] == null)
+		_cache['requests'] = new Array();
+}
+
+/* Seta os valores do componente no _cache */
+function createCacheElement(elementId, ajaxClass, ajaxMethod, methodParam, componentMode, extraParams){
+	// se o parâmetro for um objeto, transforma em uma string para gerar o hash
+	var _param = (typeof(methodParam) == 'object')? JSON.stringify(methodParam) : methodParam;
+
+	// se o componente tiver que ser populado em sua criação, calcula o hash
+	if (componentMode == 'POPULATE_ON_LOAD'){
+		var str = ajaxClass + ajaxMethod + _param;
+		// Cria hash que identifica classe, método e parâmetro.
+		// Componente verifica se hash já existe para não fazer requisições ajax desnecessárias
+		var hash = new SHA1(str).hexdigest();
+	}
+	// senão, não há a necessidade de calcular o hash, pois a lista será carregada posteriormente
+	else
+		var hash = "";
+
+	if(extraParams['minLength'] == null){
+		extraParams['minLength'] = 1;
+	}
+
+	if (extraParams['idValue'] != null){
+		if (extraParams['textValue'] != null){
+			// se texto do input já foi preenchido no momento da montagem do componente, não escreve via javascript
+			if ($('input' + elementId).value.lenght == 0)
+				$('input' + elementId).value = extraParams['textValue'];
+
+			$(elementId).value = extraParams['idValue'];
+			showResult(elementId);
+		}
+	}
+
+	createCacheElementsArray();
+
+	if(_cache['elements'][elementId] == null){
+		_cache['elements'][elementId] = new Array();
+		_cache['elements'][elementId]['hash'] = hash;
+		_cache['elements'][elementId]['minLength'] = extraParams['minLength'];
+	} else {
+		// por algum motivo componente já existe.
+		// Se o _cache na posição hash não for null, requisição ajax já foi feita.
+		// Se o objeto já foi populado e está sendo escrito novamente, manda popular denovo
+		//   (isso pode acontecer quando o componente é escrito através de javascript)
+		if(_cache['requests'][hash] != null)
+			if (_cache['requests'][hash]['populated'] == true){
+				_cache['elements'][elementId]['populated'] = null;
+				autocompletePopulate(elementId);
+			}
+	}
+}
+
+function catchJsonError(dados){ return false; }
+
+/* Controle de timeout para chamar a função updateCacheRequests quando o usuário ficar 0.3 segundos sem digitar. (chamada no onkeyup do componente do tipo REPOPULATE_ON_CHANGE) */
+function updateCacheRequestsTimeout(elementId, ajaxClass, ajaxMethod, methodParam, componentMode){
+	clearTimeout(myTimer);
+	myTimer = setTimeout("updateCacheRequests('" + elementId + "', '" + ajaxClass + "', '" + ajaxMethod + "', '" + methodParam + "', '" + componentMode + "')", 300);
+}
+
+/* Função que faz o gerenciamento das chamadas ajax e atualiza a lista de opções para seleção. */
+var updateCacheRequests = function(elementId, ajaxClass, ajaxMethod, methodParam, componentMode){
+	// se o parâmetro for um objeto, transforma em uma string para gerar o hash
+	var _param = (typeof(methodParam) == 'object')? JSON.stringify(methodParam) : methodParam;
+	var str = ajaxClass + ajaxMethod + _param;
+	// Cria hash que identifica classe, método e parâmetro.
+	// Componente verifica se hash já existe para não fazer requisições ajax desnecessárias
+	var hash = new SHA1(str).hexdigest();
+
+	if(_cache['requests'][hash] == null){
+		_cache['requests'][hash] = new Array();
+		_cache['requests'][hash]['populated'] = null;
+		_cache['requests'][hash]['data'] = new Array();
+
+		if (componentMode == 'POPULATE_ON_LOAD'){
+			func = function (dados)
+			{
+				var result = dados[ajaxMethod]['data'];
+				if (result !== false){
+					// guarda valores localmente
+					_cache['requests'][hash]['data'] = result;
+					_cache['requests'][hash]['populated'] = true;
+					// Envia dados para o componente
+					autocompletePopulate(elementId);
+				}
+			};
+
+			// Faz a requisição ajax/Json
+			var nc = new NanoController();
+			nc.setWfUrl();
+			nc.setSuccessHandler(func);
+			nc.setExceptionHandler(catchJsonError);
+			nc.setErrorHandler(catchJsonError);
+			nc.addVirtualRequest(ajaxMethod,
+				{
+					action: ajaxClass,
+					mode:   ajaxMethod
+				}, methodParam);
+			nc.sendRequest();
+		}
+		else{
+			if(_param.length >= 3){
+				func = function (dados)
+				{
+					var result = dados[ajaxMethod]['data'];
+					if(typeof(result) == "object" && result.length != 0){
+						// guarda valores localmente
+						_cache['requests'][hash]['data'] = result;
+						_cache['requests'][hash]['populated'] = true;
+						_cache['elements'][elementId]['hash'] = hash;
+						var values = arrayValues(result);
+						autocompleterObjs[elementId].options.array = values;
+						autocompleterObjs[elementId].getUpdatedChoices();
+					}
+				};
+
+				// Faz a requisição ajax/Json
+				var nc = new NanoController();
+				nc.setWfUrl();
+				nc.setSuccessHandler(func);
+				nc.setExceptionHandler(catchJsonError);
+				nc.setErrorHandler(catchJsonError);
+				nc.addVirtualRequest(ajaxMethod,
+					{
+						action: ajaxClass,
+						mode:   ajaxMethod
+					}, removeAccents(methodParam));
+				nc.sendRequest();
+			}
+		}
+	}
+	else{
+		// Se for do modo que deve repopular a lista a cada tecla pressionada e o _cache referente à entrada digitada já estiver populada
+		if (componentMode == 'REPOPULATE_ON_CHANGE' && _cache['requests'][hash]['populated']){
+			_cache['elements'][elementId]['hash'] = hash;
+			var values = arrayValues(_cache['requests'][hash]['data']);
+			autocompleterObjs[elementId].options.array = values;
+		}
+	}
+}
+
+/* Função que prepara o _cache, criando e setando os valores para cada componente */
+function autocompleteSelect(elementId, ajaxClass, ajaxMethod, methodParam, componentMode, extraParams)
+{
+	createCacheElement(elementId, ajaxClass, ajaxMethod, methodParam, componentMode, extraParams);
+	createCacheRequestsArray();
+
+	// Se o componente é do tipo que deve repopular a lista a cada tecla, cria um objeto autocompleter com a lista vazia
+	if(componentMode == 'REPOPULATE_ON_CHANGE')
+		autocompleterObjs[elementId] = new Autocompleter.Local('input' + elementId, 'list' + elementId, new Array(), {
+			'choices':9,
+			'partialChars': _cache['elements'][elementId]['minLength']
+		});
+
+	updateCacheRequests(elementId, ajaxClass, ajaxMethod, methodParam, componentMode);
+}
Index: /sandbox/workflow/branches/993/js/jscode/wf_select_option_multiple.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wf_select_option_multiple.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/wf_select_option_multiple.js	(revision 795)
@@ -0,0 +1,220 @@
+/*
+* Add selected item of selectbox "from" to "to" and
+* disable it in "from"
+*/
+function addOption(from, to, sort) {
+	fromList = eval('document.forms[0].' + from);
+	toList   = eval('document.forms[0].' + to);
+	button   = eval('document.forms[0].btn_' + from);
+
+	if(fromList.selectedIndex != -1 && !fromList.options[fromList.selectedIndex].disabled){
+		txt = new String(fromList.options[fromList.selectedIndex].text);
+		val = fromList.options[fromList.selectedIndex].value;
+
+		toList.options[toList.length] = new Option(txt,val);
+		fromList.options[fromList.selectedIndex].disabled = true;
+		// if is IE, emulates disabled
+		if(navigator.appName == "Microsoft Internet Explorer")
+			fromList.options[fromList.selectedIndex].style.color = "gray";
+		fromList.selectedIndex = -1;
+		$(button).disable();
+
+		if(sort){
+			// sort selectbox "to"
+			sortOptions(to);
+		}
+	}
+}
+
+/*
+* Remove selected options of selectbox "from" and enable them in selectbox "to"
+*/
+function removeOptions(from, to) {
+	fromList = eval('document.forms[0].' + from);
+	toList = eval('document.forms[0].' + to);
+	// get color style of the selected option of fromList
+	var color = fromList.options[fromList.selectedIndex].style.color;
+	// walk through "from" list searching the selected items,
+	// enable them in the "to" and remove from "from"
+	for (i = 0; i < fromList.options.length; i++) {
+		var current = fromList.options[i];
+		if (current.selected) {
+			val = current.value;
+			for (j = 0; j < toList.options.length; j++){
+				if (toList.options[j].value == val){
+					toList.options[j].disabled = false;
+					// if is IE, emulates enabled
+					if(navigator.appName == "Microsoft Internet Explorer")
+						toList.options[j].style.color = color;
+					break;
+				}
+			}
+			fromList.options[i] = null;
+			i--;
+		}
+	}
+	button = eval('document.forms[0].btn_' + from);
+	$(button).disable();
+}
+
+/*
+* Check if there is a selected item in the selectbox objName and enable or disable its related button
+*/
+function enableButton(objName)
+{
+	select = eval('document.forms[0].' + objName);
+	var buttonName = 'btn_' + objName;
+	button = eval('document.forms[0].' + buttonName);
+    if (select.selectedIndex != -1 && select.options[select.selectedIndex].value != -1){
+		$(button).enable();
+	} else {
+		$(button).disable();
+	}
+}
+
+
+/*
+* Populate selectbox with the array elements
+*/
+function populateSelect(objName, array) {
+	obj = eval('document.forms[0].' + objName);
+
+	while(obj.firstChild)
+		obj.removeChild(obj.firstChild);
+
+	// walk through array and add elements to the selectbox
+	for (i = 0; i < array.length; i++) {
+		if( isArray(array[i]) ) {
+			obj.options[obj.length] = new Option(array[i].text, array[i].value);
+		}
+	}
+}
+
+/*
+* Populate the selectboxes.
+* @param objNameT      Top selectbox name
+* @param arrayT        Array with the elements of the top selectbox
+* @param sortT         Boolean value to sort the top selectbox
+* @param objNameB      Bottom selectbox name
+* @param arrayB        Array with the elements of the bottom selectbox
+* @param sortB         Boolean value to sort the bottom selectbox
+* @param bool execDiff This value indicates if the user wants to execute the diff function
+*/
+function populateSelects(objNameT, arrayT, sortT,
+						 objNameB, arrayB, sortB,
+						 execDiff) {
+	if( isArray(arrayT) )
+		populateSelect(objNameT, arrayT);
+
+	if( isArray(arrayB) )
+		populateSelect(objNameB, arrayB);
+
+	if( sortT )
+		sortOptions(objNameT);
+
+	if( sortB )
+		sortOptions(objNameB);
+
+	if(execDiff)
+		selectDiffMultiple( objNameB, objNameT )
+}
+
+/*
+* Select all items in a selectbox.
+*/
+function selectAllOptions( objName ) {
+	obj = eval('document.forms[0].' + objName);
+
+	for(i = 0; i < obj.length; i++) {
+		obj.options[i].selected = true;
+	}
+}
+
+/*
+* Check if the parameter is an array.
+* Return true if it's an array, and false, if it's not.
+*/
+function isArray( obj ) {
+	if (typeof obj == 'object') {
+		var criterion = obj.constructor.toString().match(/array/i);
+		return (criterion != null);
+	}
+	return false;
+}
+
+/*
+* Get the values of a selectbox and return them in an array.
+*/
+function select2array(objName) {
+	obj = eval('document.forms[0].' + objName);
+
+	if(obj){
+		array = new Array();
+
+		for(i = 0; i < obj.length; i++) {
+			array[i] = new Array(2);
+			array[i].text  = obj.options[i].text;
+			array[i].value = obj.options[i].value;
+		}
+
+		return array;
+	}
+	return null;
+}
+
+/*
+* Copy the values of an array to a selectbox.
+*/
+function array2select(array, objName) {
+	obj = eval('document.forms[0].' + objName);
+
+	if( isArray(array) ) {
+		for(i = 0; i < obj.length; i++) {
+			obj.options[i].text  = array[i].text;
+			obj.options[i].value = array[i].value;
+		}
+	}
+}
+
+/*
+* Redefine the javascript sort function.
+* We need to compare the attributes a.text and b.text.
+*/
+function sortFunction(a, b) {
+	if(a.text > b.text)
+		return 1;
+	if(a.text < b.text)
+		return -1;
+	return 0;
+}
+
+/*
+* Sort the elements of a selectbox.
+*/
+function sortOptions(objName) {
+	arrTexts = select2array(objName);
+	arrTexts.sort(sortFunction);
+	array2select(arrTexts, objName);
+}
+
+/*
+* Difference between two selectboxes. Remove the elements of the objName2
+* that are found in objName1.
+*/
+function selectDiffMultiple(objName1, objName2) {
+	array1 = select2array(objName1);
+	array2 = select2array(objName2);
+	obj2 = eval('document.forms[0].' + objName2);
+
+	for( var i = 0; i < array1.length; i++ ) {
+		for(var j = 0; j < array2.length; j++) {
+			if(array1[i].value == array2[j].value){
+				obj2.options[j].disabled = true;
+				// if is IE, emulates disabled
+				if(navigator.appName == "Microsoft Internet Explorer")
+					obj2.options[j].style.color = "gray";
+				break;
+			}
+		}
+	}
+}
Index: /sandbox/workflow/branches/993/js/jscode/wf_file_upload.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wf_file_upload.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/wf_file_upload.js	(revision 795)
@@ -0,0 +1,162 @@
+/**
+ * Convert a single file-input element into a 'multiple' input list
+ *
+ * Usage:
+ *
+ *   1. Create a file input element (no name)
+ *      eg. <input type="file" id="first_file_element">
+ *
+ *   2. Create a DIV for the output to be written to
+ *      eg. <div id="files_list"></div>
+ *
+ *   3. Instantiate a MultiSelector object, passing in the DIV and an (optional) maximum number of files
+ *      eg. var multi_selector = new MultiSelector( document.getElementById( 'files_list' ), 3 );
+ *
+ *   4. Add the first element
+ *      eg. multi_selector.addElement( document.getElementById( 'first_file_element' ) );
+ *
+ *   5. That's it.
+ *
+ *   You might (will) want to play around with the addListRow() method to make the output prettier.
+ *
+ *   You might also want to change the line 
+ *       element.name = 'file_' + this.count;
+ *   ...to a naming convention that makes more sense to you.
+ * 
+ * Licence:
+ *   Use this however/wherever you like, just don't blame me if it breaks anything.
+ *
+ * Credit:
+ *   If you're nice, you'll leave this bit:
+ *  
+ *   Class by Stickman -- http://www.the-stickman.com
+ *      with thanks to:
+ *      [for Safari fixes]
+ *         Luis Torrefranca -- http://www.law.pitt.edu
+ *         and
+ *         Shawn Parker & John Pennypacker -- http://www.fuzzycoconut.com
+ *      [for duplicate name bug]
+ *         'neal'
+ * Modified by: Sidnei Augusto Drovetto Junior
+ */
+function MultiSelector( list_target, max )
+{
+
+	// Where to write the list
+	this.list_target = list_target;
+	// How many elements?
+	this.count = 0;
+	// How many elements?
+	this.id = 0;
+	// Is there a maximum?
+	if( max )
+		this.max = max;
+	else
+		this.max = -1;
+	
+	/**
+	 * Add a new file input element
+	 */
+	this.addElement = function(element, name)
+	{
+		// Make sure it's a file input element
+		if( element.tagName == 'INPUT' && element.type == 'file' )
+		{
+			// Element name -- what number am I?
+			//element.name = 'file_' + this.id++;
+			this.id++;
+			element.name = name;
+
+			// Add reference to this object
+			element.multi_selector = this;
+
+			// What to do when a file is selected
+			element.onchange = function()
+			{
+				// New file input
+				var new_element = document.createElement( 'input' );
+				new_element.type = 'file';
+
+				// Add new element
+				this.parentNode.insertBefore( new_element, this );
+
+				// Apply 'update' to element
+				this.multi_selector.addElement(new_element, name);
+
+				// Update list
+				this.multi_selector.addListRow( this );
+
+				// Hide this: we can't use display:none because Safari doesn't like it
+				this.style.position = 'absolute';
+				this.style.left = '-1000px';
+
+			};
+			// If we've reached maximum number, disable input element
+			if( this.max != -1 && this.count >= this.max )
+			{
+				element.disabled = true;
+			};
+
+			// File element counter
+			this.count++;
+			// Most recent element
+			this.current_element = element;
+			
+		}
+		else
+		{
+			// This can only be applied to file input elements!
+			alert( 'Erro: não é um input de arquivo' );
+		};
+
+	};
+
+	/**
+	 * Add a new row to the list of files
+	 */
+	this.addListRow = function( element )
+	{
+		// Row div
+		var new_row = document.createElement( 'div' );
+
+		// Delete button
+		var new_row_button = document.createElement( 'a' );
+		new_row_button.href = '#';
+		new_row_button.innerHTML = 'remover';
+
+		// References
+		new_row.element = element;
+
+		// Delete function
+		new_row_button.onclick= function()
+		{
+			// Remove element from form
+			this.parentNode.element.parentNode.removeChild( this.parentNode.element );
+
+			// Remove this row from the list
+			this.parentNode.parentNode.removeChild( this.parentNode );
+
+			// Decrement counter
+			this.parentNode.element.multi_selector.count--;
+
+			// Re-enable input element (if it's disabled)
+			this.parentNode.element.multi_selector.current_element.disabled = false;
+
+			// Appease Safari
+			//    without it Safari wants to reload the browser window
+			//    which nixes your already queued uploads
+			return false;
+		};
+
+		// Set row value
+		new_row.innerHTML = element.value + '&nbsp;&nbsp;';
+
+		// Add button
+		new_row.appendChild( new_row_button );
+
+		// Add it to the list
+		this.list_target.appendChild( new_row );
+		
+	};
+
+};
Index: /sandbox/workflow/branches/993/js/jscode/userControl.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/userControl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/userControl.js	(revision 795)
@@ -0,0 +1,41 @@
+window.document.workflow_form.onsubmit = selectAll;
+
+function selectAll()
+{
+	var formulario = document.getElementsByTagName('SELECT');
+	for (var i = 0; i < formulario.length; i++)
+	{
+		if (formulario[i].type == 'select-multiple')
+		{
+			var userList = formulario[i];
+			for(var j = 0; j < userList.length; j++)
+				userList.options[j].selected = true;
+		}
+	}
+}
+
+function openParticipants(newWidth, newHeight, target_element, option)
+{
+	newScreenX = screen.width - newWidth;
+	newScreenY = 0;
+
+	var page = 'index.php?menuaction=workflow.ui_participants.form';
+	if (target_element)
+		page += "&target_element=" + target_element;
+	if (option)
+		page += "&" + option;
+
+	window.open(page,'','width='+newWidth+',height='+newHeight+',screenX='+newScreenX+',left='+newScreenX+',screenY='+newScreenY+',top='+newScreenY+',toolbar=no,scrollbars=no,resizable=no');
+}
+
+function delUsers(target_element)
+{
+	target = window.document.getElementById(target_element);
+	for(var i = 0;i < target.options.length; i++)
+	{
+		if(target.options[i].selected)
+		{
+			target.options[i--] = null;
+		}
+	}
+}
Index: /sandbox/workflow/branches/993/js/jscode/common_functions.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/common_functions.js	(revision 2042)
+++ /sandbox/workflow/branches/993/js/jscode/common_functions.js	(revision 2042)
@@ -0,0 +1,119 @@
+function Element(element){
+	return document.getElementById(element);
+}
+
+function killElement(param){
+	var elem = document.getElementById(param);
+	if (elem)
+		elem.parentNode.removeChild(elem);
+}
+
+function load_lang(){
+
+	var handler_load_lang = function(data){
+		array_lang = data;
+	};
+  	cExecute("$this.bo_userinterface.getLang",handler_load_lang);
+}
+
+function write_msg(msg) {
+	var msg = '<table width=100% class="msg_erro_table"><tr><th width="40%"></th><th noWrap class="msg_erro_th">'+msg+'</th><th width="40%"></th></tr><tbody></tbody><table>';
+	var divAppboxHeader = document.getElementById("divAppboxHeader");
+	divAppboxHeader.innerHTML = msg;
+	setTimeout("Element('divAppboxHeader').innerHTML = '<table align=center border=0 width=100%><tr><td align=center><span class=msg_erro_text>Workflow</span></td></tr></table>'", 5000);
+}
+
+function write_errors(msg_errors) {
+	alert(msg_errors.replace(/<br \/>/gi, "\n"));
+}
+
+function activity_icon(type, is_interactive) {
+
+	switch(type)
+	{
+		case 'activity':
+			ic = "mini_" + ((is_interactive == 'y') ? 'blue_' : '') + "rectangle.gif";
+			break;
+		case 'switch':
+			ic = "mini_" + ((is_interactive == 'y')? 'blue_':'') + "diamond.gif";
+			break;
+		case 'start':
+			ic = "mini_" + ((is_interactive == 'y')? 'blue_':'') + "circle.gif";
+			break;
+		case 'end':
+			ic = "mini_" + ((is_interactive == 'y')? 'blue_':'') + "dbl_circle.gif";
+			break;
+		case 'split':
+			ic = "mini_" + ((is_interactive == 'y')? 'blue_':'') + "triangle.gif";
+			break;
+		case 'join':
+			ic = "mini_" + ((is_interactive == 'y')? 'blue_':'') + "inv_triangle.gif";
+			break;
+		case 'standalone':
+			ic = "mini_" + ((is_interactive == 'y')? 'blue_':'') + "hexagon.gif";
+			break;
+		default:
+			ic = "no-activity.gif";
+	}
+
+	var result = '<img src="' + _icon_dir + 'activities/' + ic + '" alt="' + type + '" title="' + type + '" />';
+	return result;
+}
+
+function get_icon(img_name, title, attributes)
+{
+	if (attributes == null) {
+		attributes = '';
+	}
+	return "<img " + attributes  + " src='" + _icon_dir + img_name + "' alt='" + title + "' title='" + title + "'>";
+}
+
+function get_link(link,text,attributes)
+{
+	if (attributes == null) {
+		attributes = '';
+	}
+
+	return "<a href=" + link + " " + attributes  + ">" + text + "</a>";
+}
+
+function _checkError(data)
+{
+	if (data['error'])
+	{
+		alert(data['error'].replace(/<br \/>/gi, "\n"));
+		if (data['url'])
+			window.location = data['url'];
+		return true;
+	}
+
+	return false;
+}
+
+function formatDateField(e, obj)
+{
+	// assuring it works on IE
+	var e = window.event || e;
+	var code = e.charCode || e.keyCode;
+	
+	switch (code) {
+		case (8): // backspace
+		case (9): // tab
+		case (35): // end
+		case (36): // home
+		case (37): // left arrow
+		case (39): // right arrow
+		case (46): // delete
+			return true;
+	}
+
+	if (obj.value.length == 2)
+		obj.value += '/';
+	else if (obj.value.length == 5)
+		obj.value += '/';
+	else if (obj.value.length >= 10)
+		return false;
+
+	// just numbers!
+	return ((code >= 48) && (code <= 57))? true : false;
+}
Index: /sandbox/workflow/branches/993/js/jscode/lightbox.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/lightbox.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/lightbox.js	(revision 795)
@@ -0,0 +1,437 @@
+/*
+	Lightbox JS: Fullsize Image Overlays 
+	by Lokesh Dhakar - http://www.huddletogether.com
+
+	For more information on this script, visit:
+	http://huddletogether.com/projects/lightbox/
+
+	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
+	(basically, do anything you want, just leave my name and link)
+	
+	Table of Contents
+	-----------------
+	Configuration
+	
+	Functions
+	- getPageScroll()
+	- getPageSize()
+	- pause()
+	- getKey()
+	- listenKey()
+	- showLightbox()
+	- hideLightbox()
+	- initLightbox()
+	- addLoadEvent()
+	
+	Function Calls
+	- addLoadEvent(initLightbox)
+
+*/
+
+
+
+//
+// Configuration
+//
+
+// If you would like to use a custom loading image or close button reference them in the next two lines.
+var loadingImage = 'workflow/templateFile.php?file=images/lb_loading.gif';		
+var closeButton = 'workflow/templateFile.php?file=images/lb_close.gif';		
+
+
+
+
+
+//
+// getPageScroll()
+// Returns array with x,y page scroll values.
+// Core code from - quirksmode.org
+//
+function getPageScroll(){
+
+	var yScroll;
+
+	if (self.pageYOffset) {
+		yScroll = self.pageYOffset;
+	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
+		yScroll = document.documentElement.scrollTop;
+	} else if (document.body) {// all other Explorers
+		yScroll = document.body.scrollTop;
+	}
+
+	arrayPageScroll = new Array('',yScroll) 
+	return arrayPageScroll;
+}
+
+
+
+//
+// getPageSize()
+// Returns array with page width, height and window width, height
+// Core code from - quirksmode.org
+// Edit for Firefox by pHaez
+//
+function getPageSize(){
+	
+	var xScroll, yScroll;
+	
+	if (window.innerHeight && window.scrollMaxY) {	
+		xScroll = document.body.scrollWidth;
+		yScroll = window.innerHeight + window.scrollMaxY;
+	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
+		xScroll = document.body.scrollWidth;
+		yScroll = document.body.scrollHeight;
+	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+		xScroll = document.body.offsetWidth;
+		yScroll = document.body.offsetHeight;
+	}
+	
+	var windowWidth, windowHeight;
+	if (self.innerHeight) {	// all except Explorer
+		windowWidth = self.innerWidth;
+		windowHeight = self.innerHeight;
+	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+		windowWidth = document.documentElement.clientWidth;
+		windowHeight = document.documentElement.clientHeight;
+	} else if (document.body) { // other Explorers
+		windowWidth = document.body.clientWidth;
+		windowHeight = document.body.clientHeight;
+	}	
+	
+	// for small pages with total height less then height of the viewport
+	if(yScroll < windowHeight){
+		pageHeight = windowHeight;
+	} else { 
+		pageHeight = yScroll;
+	}
+
+	// for small pages with total width less then width of the viewport
+	if(xScroll < windowWidth){	
+		pageWidth = windowWidth;
+	} else {
+		pageWidth = xScroll;
+	}
+
+
+	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
+	return arrayPageSize;
+}
+
+
+//
+// pause(numberMillis)
+// Pauses code execution for specified time. Uses busy code, not good.
+// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
+//
+function pause(numberMillis) {
+	var now = new Date();
+	var exitTime = now.getTime() + numberMillis;
+	while (true) {
+		now = new Date();
+		if (now.getTime() > exitTime)
+			return;
+	}
+}
+
+//
+// getKey(key)
+// Gets keycode. If 'x' is pressed then it hides the lightbox.
+//
+
+function getKey(e){
+	if (e == null) { // ie
+		keycode = event.keyCode;
+	} else { // mozilla
+		keycode = e.which;
+	}
+	key = String.fromCharCode(keycode).toLowerCase();
+	
+	if(key == 'x'){ hideLightbox(); }
+}
+
+
+//
+// listenKey()
+//
+function listenKey () {	document.onkeypress = getKey; }
+	
+
+//
+// showLightbox()
+// Preloads images. Pleaces new image in lightbox then centers and displays.
+//
+function showLightbox(objLink)
+{
+	// prep objects
+	var objOverlay = document.getElementById('overlay');
+	var objLightbox = document.getElementById('lightbox');
+	var objCaption = document.getElementById('lightboxCaption');
+	var objImage = document.getElementById('lightboxImage');
+	var objLoadingImage = document.getElementById('loadingImage');
+	var objLightboxDetails = document.getElementById('lightboxDetails');
+
+	
+	var arrayPageSize = getPageSize();
+	var arrayPageScroll = getPageScroll();
+
+	// center loadingImage if it exists
+	if (objLoadingImage) {
+		objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
+		objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
+		objLoadingImage.style.display = 'block';
+	}
+
+	// set height of Overlay to take up whole page and show
+	objOverlay.style.height = (arrayPageSize[1] + 'px');
+	objOverlay.style.display = 'block';
+
+	// preload image
+	imgPreload = new Image();
+
+	imgPreload.onload=function(){
+		objImage.src = objLink.href;
+
+		// center lightbox and make sure that the top and left values are not negative
+		// and the image placed outside the viewport
+		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
+		var lightboxLeft = ((arrayPageSize[0] - 20 - ((imgPreload.width < 65) ? 65 : imgPreload.width)) / 2);
+		
+		objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
+		objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";
+
+
+		objLightboxDetails.style.width = ((imgPreload.width < 65) ? '65' : imgPreload.width) + 'px';
+		
+		if(objLink.getAttribute('title')){
+			objCaption.style.display = 'block';
+			//objCaption.style.width = imgPreload.width + 'px';
+			objCaption.innerHTML = objLink.getAttribute('title');
+		} else {
+			objCaption.style.display = 'none';
+		}
+		
+		// A small pause between the image loading and displaying is required with IE,
+		// this prevents the previous image displaying for a short burst causing flicker.
+		if (navigator.appVersion.indexOf("MSIE")!=-1){
+			pause(250);
+		} 
+
+		if (objLoadingImage) {	objLoadingImage.style.display = 'none'; }
+
+		// Hide select boxes as they will 'peek' through the image in IE
+		selects = document.getElementsByTagName("select");
+        for (i = 0; i != selects.length; i++) {
+                selects[i].style.visibility = "hidden";
+        }
+
+	
+		objLightbox.style.display = 'block';
+
+		// After image is loaded, update the overlay height as the new image might have
+		// increased the overall page height.
+		arrayPageSize = getPageSize();
+		objOverlay.style.height = (arrayPageSize[1] + 'px');
+		
+		// Check for 'x' keypress
+		listenKey();
+
+		return false;
+	}
+
+	imgPreload.src = objLink.href;
+	
+}
+
+
+
+
+
+//
+// hideLightbox()
+//
+function hideLightbox()
+{
+	// get objects
+	objOverlay = document.getElementById('overlay');
+	objLightbox = document.getElementById('lightbox');
+
+	// hide lightbox and overlay
+	objOverlay.style.display = 'none';
+	objLightbox.style.display = 'none';
+
+	// make select boxes visible
+	selects = document.getElementsByTagName("select");
+    for (i = 0; i != selects.length; i++) {
+		selects[i].style.visibility = "visible";
+	}
+
+	// disable keypress listener
+	document.onkeypress = '';
+}
+
+
+
+
+//
+// initLightbox()
+// Function runs on window load, going through link tags looking for rel="lightbox".
+// These links receive onclick events that enable the lightbox display for their targets.
+// The function also inserts html markup at the top of the page which will be used as a
+// container for the overlay pattern and the inline image.
+//
+function initLightbox()
+{
+	
+	if (!document.getElementsByTagName){ return; }
+	var anchors = document.getElementsByTagName("a");
+
+	// loop through all anchor tags
+	for (var i=0; i<anchors.length; i++){
+		var anchor = anchors[i];
+
+		if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
+			anchor.onclick = function () {showLightbox(this); return false;}
+		}
+	}
+
+	// the rest of this code inserts html at the top of the page that looks like this:
+	//
+	// <div id="overlay">
+	//		<a href="#" onclick="hideLightbox(); return false;"><img id="loadingImage" /></a>
+	//	</div>
+	// <div id="lightbox">
+	//		<a href="#" onclick="hideLightbox(); return false;" title="Click anywhere to close image">
+	//			<img id="closeButton" />		
+	//			<img id="lightboxImage" />
+	//		</a>
+	//		<div id="lightboxDetails">
+	//			<div id="lightboxCaption"></div>
+	//			<div id="keyboardMsg"></div>
+	//		</div>
+	// </div>
+	
+	var objBody = document.getElementsByTagName("body").item(0);
+	
+	// create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
+	var objOverlay = document.createElement("div");
+	objOverlay.setAttribute('id','overlay');
+	objOverlay.onclick = function () {hideLightbox(); return false;}
+	objOverlay.style.display = 'none';
+	objOverlay.style.position = 'absolute';
+	objOverlay.style.top = '0';
+	objOverlay.style.left = '0';
+	objOverlay.style.zIndex = '90';
+ 	objOverlay.style.width = '100%';
+	objBody.insertBefore(objOverlay, objBody.firstChild);
+	
+	var arrayPageSize = getPageSize();
+	var arrayPageScroll = getPageScroll();
+
+	// preload and create loader image
+	var imgPreloader = new Image();
+	
+	// if loader image found, create link to hide lightbox and create loadingimage
+	imgPreloader.onload=function(){
+
+		var objLoadingImageLink = document.createElement("a");
+		objLoadingImageLink.setAttribute('href','#');
+		objLoadingImageLink.onclick = function () {hideLightbox(); return false;}
+		objOverlay.appendChild(objLoadingImageLink);
+		
+		var objLoadingImage = document.createElement("img");
+		objLoadingImage.src = loadingImage;
+		objLoadingImage.setAttribute('id','loadingImage');
+		objLoadingImage.style.position = 'absolute';
+		objLoadingImage.style.zIndex = '150';
+		objLoadingImageLink.appendChild(objLoadingImage);
+
+		imgPreloader.onload=function(){};	//	clear onLoad, as IE will flip out w/animated gifs
+
+		return false;
+	}
+
+	imgPreloader.src = loadingImage;
+
+	// create lightbox div, same note about styles as above
+	var objLightbox = document.createElement("div");
+	objLightbox.setAttribute('id','lightbox');
+	objLightbox.style.display = 'none';
+	objLightbox.style.position = 'absolute';
+	objLightbox.style.zIndex = '100';	
+	objBody.insertBefore(objLightbox, objOverlay.nextSibling);
+	
+	// create link
+	var objLink = document.createElement("a");
+	objLink.setAttribute('href','#');
+	objLink.setAttribute('title','Clique para fechar');
+	objLink.onclick = function () {hideLightbox(); return false;}
+	objLightbox.appendChild(objLink);
+
+	// preload and create close button image
+	var imgPreloadCloseButton = new Image();
+
+	// if close button image found, 
+	imgPreloadCloseButton.onload=function(){
+
+		var objCloseButton = document.createElement("img");
+		objCloseButton.src = closeButton;
+		objCloseButton.setAttribute('id','closeButton');
+		objCloseButton.style.position = 'absolute';
+		objCloseButton.style.zIndex = '200';
+		objLink.appendChild(objCloseButton);
+
+		return false;
+	}
+
+	imgPreloadCloseButton.src = closeButton;
+
+	// create image
+	var objImage = document.createElement("img");
+	objImage.setAttribute('id','lightboxImage');
+	objLink.appendChild(objImage);
+	
+	// create details div, a container for the caption and keyboard message
+	var objLightboxDetails = document.createElement("div");
+	objLightboxDetails.setAttribute('id','lightboxDetails');
+	objLightbox.appendChild(objLightboxDetails);
+
+	// create caption
+	var objCaption = document.createElement("div");
+	objCaption.setAttribute('id','lightboxCaption');
+	objCaption.style.display = 'none';
+	objLightboxDetails.appendChild(objCaption);
+
+	// create keyboard message
+	var objKeyboardMsg = document.createElement("div");
+	objKeyboardMsg.setAttribute('id','keyboardMsg');
+	objKeyboardMsg.innerHTML = 'pressione <a href="#" onclick="hideLightbox(); return false;"><kbd>x</kbd></a> para fechar';
+	objLightboxDetails.appendChild(objKeyboardMsg);
+
+
+}
+
+
+
+
+//
+// addLoadEvent()
+// Adds event to window.onload without overwriting currently assigned onload functions.
+// Function found at Simon Willison's weblog - http://simon.incutio.com/
+//
+function addLoadEvent(func)
+{	
+	var oldonload = window.onload;
+	if (typeof window.onload != 'function'){
+    	window.onload = func;
+	} else {
+		window.onload = function(){
+		oldonload();
+		func();
+		}
+	}
+
+}
+
+
+
+addLoadEvent(initLightbox);	// run initLightbox onLoad
Index: /sandbox/workflow/branches/993/js/jscode/wz_dragdrop.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wz_dragdrop.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/wz_dragdrop.js	(revision 795)
@@ -0,0 +1,1427 @@
+/* This notice must be untouched at all times.
+
+wz_dragdrop.js    v. 4.55
+The latest version is available at
+http://www.walterzorn.com
+or http://www.devira.com
+or http://www.walterzorn.de
+
+Copyright (c) 2002-2003 Walter Zorn. All rights reserved.
+Created 26. 8. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
+Last modified: 23. 5. 2004
+
+This DHTML & Drag&Drop Library adds Drag&Drop functionality
+to the following types of html-elements:
+- images, even if not positioned via layers,
+  nor via stylesheets or any other kind of "hard-coding"
+- relatively and absolutely positioned layers (DIV elements).
+Moreover, it provides extended DHTML abilities.
+
+This program is free software;
+you can redistribute it and/or modify it under the terms of the
+GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License
+at http://www.gnu.org/copyleft/gpl.html for more details.
+*/
+
+
+// PATH TO THE TRANSPARENT 1*1 PX IMAGE (required by NS 4 as spacer)
+var spacer = 'transparentpixel.gif';
+
+
+
+
+//window.onerror = new Function('return true;');
+
+
+// Optional commands passed to SET_DHTML() on the html-page (g: may be applied globally, i: individually)
+var CLONE            = 'C10nE';   // i  img      clone image
+var COPY             = 'C0pY';    // i  img      create copies
+var DETACH_CHILDREN  = 'd37aCH';  // i  lyr      detach images
+var HORIZONTAL       = 'H0r1Z';   // i  img,lyr  horizontally draggable only
+var MAXHEIGHT        = 'm7x8I';   // i  img,lyr  maximum height limit, "
+var MAXOFFBOTTOM     = 'm7xd0wN'; // i  img,lyr  downward offset limit
+var MAXOFFLEFT       = 'm7x23Ft'; // i  img,lyr  leftward offset limit
+var MAXOFFRIGHT      = 'm7x0Ff8'; // i  img,lyr  rightward offset limit
+var MAXOFFTOP        = 'm7xu9';   // i  img,lyr  upward offset limit
+var MAXWIDTH         = 'm7xW1';   // i  img,lyr  maximum width limit, use with resizable or scalable
+var MINWIDTH         = 'm1nw1';   // i  img,lyr  minimum width limit, "
+var MINHEIGHT        = 'm1n8I';   // i  img,lyr  minimum height limit, "
+var NO_ALT           = 'no81T';   // gi img      disable alt and title attributes
+var NO_DRAG          = 'N0d4Ag';  // i  img,lyr  disable draggability
+var RESET_Z          = 'r35E7z';  // gi img,lyr  reset z-index when dropped
+var RESIZABLE        = 'r5IZbl';  // gi img,lyr  resizable if <ctrl> or <shift> pressed
+var SCALABLE         = 'SCLbl';   // gi img,lyr  scalable           "
+var SCROLL           = 'sC8lL';   // gi img,lyr  enable auto scroll functionality
+var VERTICAL         = 'V3Rt1C';  // i  img,lyr  vertically draggable only
+
+var dd_cursors = new Array(
+	'c:default',
+	'c:crosshair',
+	'c:e-resize',
+	'c:hand',
+	'c:help',
+	'c:move',
+	'c:n-resize',
+	'c:ne-resize',
+	'c:nw-resize',
+	'c:s-resize',
+	'c:se-resize',
+	'c:sw-resize',
+	'c:text',
+	'c:w-resize',
+	'c:wait'
+);
+var dd_i = dd_cursors.length; while(dd_i--)
+	eval('var CURSOR_' + (dd_cursors[dd_i].substring(2).toUpperCase().replace('-', '_')) + ' = "' + dd_cursors[dd_i] + '";');
+
+var dd_u = "undefined";
+
+function WZDD()
+{
+	this.n = navigator.userAgent.toLowerCase();
+	this.db = (document.compatMode && document.compatMode.toLowerCase() != "backcompat")?
+		document.documentElement
+		: (document.body || null);
+	this.op = !!(window.opera && document.getElementById);
+	this.op6 = !!(this.op && !(this.db && this.db.innerHTML));
+	if (this.op && !this.op6) document.onmousedown = new Function('e',
+		'if (((e = e || window.event).target || e.srcElement).tagName == "IMAGE") return false;'
+	);
+	this.ie = !!(this.n.indexOf("msie") >= 0 && document.all && this.db && !this.op);
+	this.iemac = !!(this.ie && this.n.indexOf("mac") >= 0);
+	this.ie4 = !!(this.ie && !document.getElementById);
+	this.n4 = !!(document.layers && typeof document.classes != dd_u);
+	this.n6 = !!(typeof window.getComputedStyle != dd_u && typeof document.createRange != dd_u);
+	this.w3c = !!(!this.op && !this.ie && !this.n6 && document.getElementById);
+	this.ce = !!(document.captureEvents && document.releaseEvents);
+	this.px = (this.n4 || this.op6)? '' : 'px';
+}
+var dd = new WZDD();
+
+dd.Int = function(d_x, d_y)
+{
+	return isNaN(d_y = parseInt(d_x))? 0 : d_y;
+};
+
+dd.getWndW = function()
+{
+	return dd.Int(
+		(dd.db && !dd.op && !dd.w3c && dd.db.clientWidth)? dd.db.clientWidth
+		: (window.innerWidth || 0)
+	);
+};
+
+dd.getWndH = function()
+{
+	return dd.Int(
+		(dd.db && !dd.op && !dd.w3c && dd.db.clientHeight)? dd.db.clientHeight
+		: (window.innerHeight || 0)
+	);
+};
+
+dd.getScrollX = function()
+{
+	return dd.Int(window.pageXOffset || (dd.db? dd.db.scrollLeft : 0));
+};
+
+dd.getScrollY = function()
+{
+	return dd.Int(window.pageYOffset || (dd.db? dd.db.scrollTop : 0));
+};
+
+dd.getPageXY = function(d_o)
+{
+	if (dd.n4 && d_o)
+	{
+		dd.x = d_o.pageX || 0;
+		dd.y = d_o.pageY || 0;
+	}
+	else
+	{
+		dd.x = dd.y = 0; //global helper vars
+		while (d_o)
+		{
+			dd.x += dd.Int(d_o.offsetLeft);
+			dd.y += dd.Int(d_o.offsetTop);
+			d_o = d_o.offsetParent || null;
+		}
+	}
+};
+
+dd.getCssXY = function(d_o)
+{
+	if (d_o.div)
+	{
+		if (dd.n4)
+		{
+			d_o.cssx = d_o.div.x;
+			d_o.cssy = d_o.div.y;
+		}
+		else if (dd.ie4)
+		{
+			d_o.cssx = d_o.css.pixelLeft;
+			d_o.cssy = d_o.css.pixelTop;
+		}
+		else
+		{
+			d_o.css.left = d_o.css.top = 0 + dd.px;
+			dd.getPageXY(d_o.div);
+			d_o.cssx = d_o.x - dd.x;
+			d_o.cssy = d_o.y - dd.y;
+			d_o.css.left = d_o.cssx + dd.px;
+			d_o.css.top = d_o.cssy + dd.px;
+		}
+	}
+	else
+	{
+		d_o.cssx = 0;
+		d_o.cssy = 0;
+	}
+};
+
+dd.getImgW = function(d_o)
+{
+	return d_o? dd.Int(d_o.width) : 0;
+};
+
+dd.getImgH = function(d_o)
+{
+	return d_o? dd.Int(d_o.height) : 0;
+};
+
+dd.getDivW = function(d_o)
+{
+	return dd.Int(
+		dd.n4? (d_o.div? d_o.div.clip.width : 0)
+		: d_o.div? (d_o.div.offsetWidth || d_o.css.pixelWidth || d_o.css.width || 0)
+		: 0
+	);
+};
+
+dd.getDivH = function(d_o)
+{
+	return dd.Int(
+		dd.n4? (d_o.div? d_o.div.clip.height : 0)
+		: d_o.div? (d_o.div.offsetHeight || d_o.css.pixelHeight || d_o.css.height || 0)
+		: 0
+	);
+};
+
+dd.getWH = function(d_o)
+{
+	d_o.w = dd.getDivW(d_o);
+	d_o.h = dd.getDivH(d_o);
+	if (d_o.css)
+	{
+		d_o.css.width = d_o.w + dd.px;
+		d_o.css.height = d_o.h + dd.px;
+		d_o.dw = dd.getDivW(d_o)-d_o.w;
+		d_o.dh = dd.getDivH(d_o)-d_o.h;
+		d_o.css.width = (d_o.w-d_o.dw) + dd.px;
+		d_o.css.height = (d_o.h-d_o.dh) + dd.px;
+	}
+	else d_o.dw = d_o.dh = 0;
+};
+
+dd.getCssProp = function(d_o, d_pn6, d_pstyle, d_pn4)
+{
+	if (d_o && dd.n6) return ''+window.getComputedStyle(d_o, null).getPropertyValue(d_pn6);
+	if (d_o && d_o.currentStyle) return ''+eval('d_o.currentStyle.'+d_pstyle);
+	if (d_o && d_o.style) return ''+eval('d_o.style.'+d_pstyle);
+	if (d_o && dd.n4) return ''+eval('d_o.'+d_pn4);
+	return '';
+};
+
+dd.getDiv = function(d_x, d_d)
+{
+	d_d = d_d || document;
+	if (dd.n4)
+	{
+		if (d_d.layers[d_x]) return d_d.layers[d_x];
+		for (var d_i = d_d.layers.length; d_i--;)
+		{
+			var d_y = dd.getDiv(d_x, d_d.layers[d_i].document);
+			if (d_y) return d_y;
+		}
+	}
+	if (dd.ie) return d_d.all[d_x] || null;
+	if (d_d.getElementById) return d_d.getElementById(d_x) || null;
+	return null;
+};
+
+dd.getImg = function(d_o, d_nm, d_xy, d_w)
+{
+	d_w = d_w || window;
+	var d_img;
+	if ((d_img = d_w.document.images[d_nm]) && d_img.name == d_nm)
+	{
+		if (d_xy)
+		{
+			if (dd.n4)
+			{
+				dd.getPageXY(d_w);
+				d_o.defx = d_img.x + dd.x;
+				d_o.defy = d_img.y + dd.y;
+			}
+			else
+			{
+				dd.getPageXY(d_img);
+				d_o.defx = dd.x;
+				d_o.defy = dd.y;
+			}
+		}
+		return d_img;
+	}
+	if (dd.n4) for (var d_i = d_w.document.layers.length; d_i--;)
+	{
+		var d_y = dd.getImg(d_o, d_nm, d_xy, d_w.document.layers[d_i]);
+		if (d_y) return d_y;
+	}
+	return null;
+};
+
+dd.getParent = function(d_o)
+{
+	if (dd.n4)
+	{
+		for (var d_p, d_i = dd.elements.length; d_i--;)
+		{
+			if (!((d_p = dd.elements[d_i]).is_image) && d_p.div && (d_p.div.document.layers[d_o.name] || d_o.oimg && d_p.div.document.images[d_o.oimg.name]))
+				d_p.addChild(d_o, d_p.detach, 1);
+		}
+	}
+	else
+	{
+		var d_p = d_o.is_image? dd.getImg(d_o, d_o.oimg.name) : (d_o.div || null);
+		while (d_p && !!(d_p = d_p.offsetParent || d_p.parentNode || null))
+		{
+			if (d_p.ddObj)
+			{
+				d_p.ddObj.addChild(d_o, d_p.ddObj.detach, 1);
+				break;
+			}
+		}
+	}
+};
+
+dd.getCmd = function(d_o, d_cmd, d_cmdStr)
+{
+	var d_i = d_o.id.indexOf(d_cmd), d_j,
+	d_y = (d_i >= 0)*1;
+	if (d_y)
+	{
+		d_j = d_i+d_cmd.length;
+		if (d_cmdStr) d_o.cmd += d_o.id.substring(d_i, d_j);
+		d_o.id = d_o.id.substring(0, d_i) + d_o.id.substring(d_j);
+	}
+	return d_y;
+};
+
+dd.getCmdVal = function(d_o, d_cmd, d_cmdStr, int0)
+{
+	var d_i = d_o.id.indexOf(d_cmd), d_j,
+	d_y = (d_o.id.indexOf(d_cmd) >= 0)? dd.Int(d_o.id.substring(d_o.id.indexOf(d_cmd)+d_cmd.length)) : int0? -1 : 0;
+	if (!int0 && d_y || int0 && d_y >= 0)
+	{
+		d_j = d_i+d_cmd.length+d_y.toString().length;
+		if (d_cmdStr) d_o.cmd += d_o.id.substring(d_i, d_j);
+		d_o.id = d_o.id.substring(0, d_i) + d_o.id.substring(d_j);
+	}
+	return d_y;
+};
+
+dd.addElt = function(d_o, d_p)
+{
+	dd.elements[dd.elements.length] = dd.elements[d_o.name] = d_o;
+	if (d_p) d_p.copies[d_p.copies.length] = d_p.copies[d_o.name] = d_o;
+};
+
+dd.mkWzDom = function()
+{
+	var d_i = dd.elements.length; while(d_i--) dd.getParent(dd.elements[d_i]);
+	d_i = dd.elements.length; while(d_i--)
+		d_o = dd.elements[d_i];
+		if (d_o.children && !d_o.parent)
+		{
+			var d_j = d_o.children.length; while(d_j--)
+				d_o.children[d_j].setZ(d_o.z+d_o.children[d_j].z, 1);
+		}
+};
+
+dd.addProps = function(d_o)
+{
+	var d_i, d_c;
+	if (d_o.is_image)
+	{
+		d_o.div = dd.getDiv(d_o.id);
+		if (d_o.div && typeof d_o.div.style != "undefined") d_o.css = d_o.div.style;
+		d_o.nimg = (dd.n4 && d_o.div)? d_o.div.document.images[0] : (document.images[d_o.id+'NImG'] || null);
+		if (!d_o.noalt && !dd.noalt)
+		{
+			d_o.nimg.alt = d_o.oimg.alt || '';
+			if (d_o.oimg.title) d_o.nimg.title = d_o.oimg.title;
+		}
+		d_o.bgColor = '';
+	}
+	else
+	{
+		d_o.bgColor = dd.getCssProp(d_o.div, 'background-color','backgroundColor','bgColor').toLowerCase();
+		if (dd.n6 && d_o.div)
+		{
+			if ((d_c = d_o.bgColor).indexOf('rgb') >= 0)
+			{
+				d_c = d_c.substring(4, d_c.length-1).split(',');
+				d_o.bgColor = '#';
+				for (var d_i = 0; d_i < d_c.length; d_i++) d_o.bgColor += parseInt(d_c[d_i]).toString(0x10);
+			}
+			else d_o.bgColor = d_c;
+		}
+	}
+	if (dd.scalable) d_o.scalable = d_o.resizable^1;
+	else if (dd.resizable) d_o.resizable = d_o.scalable^1;
+	d_o.setZ(d_o.defz);
+	d_o.cursor = d_o.cursor || dd.cursor || 'auto';
+	d_o._setCrs(d_o.nodrag? 'auto' : d_o.cursor);
+	d_o.visible = true;
+};
+
+dd.initz = function()
+{
+	if (!(dd && (dd.n4 || dd.n6 || dd.ie || dd.op || dd.w3c))) return;
+	if (dd.op6) WINSZ(2);
+	else if (dd.n6 || dd.ie || dd.op && !dd.op6 || dd.w3c) dd.recalc(1);
+	var d_drag = (document.onmousemove == DRAG),
+	d_resize = (document.onmousemove == RESIZE);
+	if (dd.loadFunc) dd.loadFunc();
+	if (d_drag && document.onmousemove != DRAG) dd.setEvtHdl(1, DRAG);
+	else if (d_resize && document.onmousemove != RESIZE) dd.setEvtHdl(1, RESIZE);
+	if ((d_drag || d_resize) && document.onmouseup != DROP) dd.setEvtHdl(2, DROP);
+	dd.setEvtHdl(0, PICK);
+};
+
+dd.finlz = function()
+{
+	if (dd.ie && dd.elements)
+	{
+		var d_i = dd.elements.length; while (d_i--)
+			dd.elements[d_i].del();
+	}
+};
+
+dd.setEvtHdl = function(d_typ, d_func)
+{
+	if (!d_typ)
+	{
+		if (document.onmousedown != d_func) dd.downFunc = document.onmousedown || null;
+		document.onmousedown = d_func;
+	}
+	else if (d_typ&1)
+	{
+		if (document.onmousemove != d_func) dd.moveFunc = document.onmousemove || null;
+		document.onmousemove = d_func;
+	}
+	else
+	{
+		if (document.onmouseup != d_func) dd.upFunc = document.onmouseup || null;
+		document.onmouseup = d_func;
+	}
+	if (dd.ce)
+	{
+		var d_e = (!d_typ)? Event.MOUSEDOWN : (d_typ&1)? Event.MOUSEMOVE : Event.MOUSEUP;
+		d_func? document.captureEvents(d_e) : document.releaseEvents(d_e);
+	}
+};
+
+dd.evt = function(d_e)
+{
+	this.but = (this.e = d_e || window.event).which || this.e.button || 0;
+	this.button = (this.e.type == 'mousedown')? this.but
+		: (dd.e && dd.e.button)? dd.e.button
+		: 0;
+	this.src = this.e.target || this.e.srcElement || null;
+	this.src.tag = (this.src.tagName || this.src).toString().toLowerCase();
+	this.x = dd.Int(this.e.pageX || this.e.clientX || 0);
+	this.y = dd.Int(this.e.pageY || this.e.clientY || 0);
+	if (dd.ie)
+	{
+		this.x += dd.getScrollX() - (dd.ie && !dd.iemac)*1;
+		this.y += dd.getScrollY() - (dd.ie && !dd.iemac)*1;
+	}
+	this.modifKey = this.e.modifiers? (this.e.modifiers&Event.SHIFT_MASK || this.e.modifiers&Event.CONTROL_MASK)
+		: (this.e.shiftKey || this.e.ctrlKey || false);
+};
+
+dd.recalc = function(d_x)
+{
+	if (dd.elements)
+	{
+		var d_o, d_i = dd.elements.length; while(d_i--)
+		{
+			if (!(d_o = dd.elements[d_i]).is_image && d_o.div)
+			{
+				dd.getWH(d_o);
+				if (d_o.div.pos_rel)
+				{
+					dd.getPageXY(d_o.div);
+					var d_dx = dd.x - d_o.x, d_dy = dd.y - d_o.y;
+					d_o.defx += d_dx;
+					d_o.x += d_dx;
+					d_o.defy += d_dy;
+					d_o.y += d_dy;
+					var d_p, d_j = d_o.children.length; while(d_j--)
+					{
+						if (!(d_p = d_o.children[d_j]).detached && (d_o != d_p.defparent || !(d_p.is_image && dd.getImg(d_p, d_p.oimg.name, 1))))
+						{
+							d_p.defx += d_dx;
+							d_p.defy += d_dy;
+							d_p.moveBy(d_dx, d_dy);
+						}
+					}
+				}
+			}
+			else if (d_o.is_image && !dd.op6 && !dd.n4)
+			{
+				if (dd.n6 && d_x && !d_o.defw) d_o.resizeTo(d_o.defw = dd.getImgW(d_o.oimg), d_o.defh = dd.getImgH(d_o.oimg));
+				var d_defx = d_o.defx, d_defy = d_o.defy;
+				if (!(d_o.parent && d_o.parent != d_o.defparent) && (d_x || !d_o.detached || d_o.horizontal || d_o.vertical) && dd.getImg(d_o, d_o.oimg.name, 1))
+					d_o.moveBy(d_o.defx-d_defx, d_o.defy-d_defy);
+			}
+		}
+	   }
+};
+
+
+
+function WINSZ(d_x)
+{
+	if (d_x)
+	{
+		if (dd.n4 || dd.op6 && d_x&2)
+		{
+			dd.iW = innerWidth;
+			dd.iH = innerHeight;
+			if (dd.op6) setTimeout("WINSZ()", 0x1ff);
+		}
+		window.onresize = new Function('WINSZ();');
+	}
+	else if ((dd.n4 || dd.op6) && (innerWidth != dd.iW || innerHeight != dd.iH)) location.reload();
+	else if (dd.op6) setTimeout("WINSZ()", 0x1ff);
+	else if (!dd.n4) setTimeout('dd.recalc()', 0xa);
+}
+WINSZ(1);
+
+
+
+function DDObj(d_o, d_i)
+{
+	this.id = d_o;
+	this.cmd = '';
+	this.cpy_n = dd.getCmdVal(this, COPY);
+	this.maxoffb = dd.getCmdVal(this, MAXOFFBOTTOM, 0, 1);
+	this.maxoffl = dd.getCmdVal(this, MAXOFFLEFT, 0, 1);
+	this.maxoffr = dd.getCmdVal(this, MAXOFFRIGHT, 0, 1);
+	this.maxofft = dd.getCmdVal(this, MAXOFFTOP, 0, 1);
+	var d_j = dd_cursors.length; while(d_j--)
+		if (dd.getCmd(this, dd_cursors[d_j], 1)) this.cursor = dd_cursors[d_j].substring(2);
+	this.clone = dd.getCmd(this, CLONE, 1);
+	this.detach = dd.getCmd(this, DETACH_CHILDREN);
+	this.scalable = dd.getCmd(this, SCALABLE, 1);
+	this.horizontal = dd.getCmd(this, HORIZONTAL);
+	this.noalt = dd.getCmd(this, NO_ALT, 1);
+	this.nodrag = dd.getCmd(this, NO_DRAG);
+	this.scroll = dd.getCmd(this, SCROLL, 1);
+	this.resizable = dd.getCmd(this, RESIZABLE, 1);
+	this.re_z = dd.getCmd(this, RESET_Z, 1);
+	this.vertical = dd.getCmd(this, VERTICAL);
+	this.maxw = dd.getCmdVal(this, MAXWIDTH, 1, 1);
+	this.minw = Math.abs(dd.getCmdVal(this, MINWIDTH, 1, 1));
+	this.maxh = dd.getCmdVal(this, MAXHEIGHT, 1, 1);
+	this.minh = Math.abs(dd.getCmdVal(this, MINHEIGHT, 1, 1));
+
+	this.name = this.id + (d_i || '');
+	this.oimg = dd.getImg(this, this.id, 1);
+	this.is_image = !!this.oimg;
+	this.copies = new Array();
+	this.children = new Array();
+	this.parent = this.original = null;
+	if (this.oimg)
+	{
+		this.id += 'div' + (d_i || '');
+		this.w = dd.getImgW(this.oimg);
+		this.h = dd.getImgH(this.oimg);
+		this.dw = this.dh = 0;
+		this.defz = dd.Int(dd.getCssProp(this.oimg, 'z-index','zIndex','zIndex')) || 1;
+		this.defsrc = this.src = this.oimg.src;
+		this.htm = '<img name="' + this.id + 'NImG"'+
+			' src="' + this.oimg.src + '" '+
+			'width="' + this.w + '" height="' + this.h + '">';
+		this.t_htm = '<div id="' + this.id +
+			'" style="position:absolute;'+
+			'left:' + (this.cssx = this.x = this.defx) + 'px;'+
+			'top:' + (this.cssy = this.y = this.defy) + 'px;'+
+			'width:' + this.w + 'px;'+
+			'height:' + this.h + 'px;">'+
+			this.htm + '<\/div>';
+	}
+	else
+	{
+		if (!!(this.div = dd.getDiv(this.id)) && typeof this.div.style != "undefined") this.css = this.div.style;
+		dd.getWH(this);
+		if (this.div)
+		{
+			this.div.ddObj = this;
+			this.div.pos_rel = ((this.div.parentNode? this.div.parentNode.tagName : this.div.parentElement? this.div.parentElement.tagName : '').toString().toLowerCase().indexOf('body') < 0);
+		}
+		dd.getPageXY(this.div);
+		this.defx = this.x = dd.x;
+		this.defy = this.y = dd.y;
+		dd.getCssXY(this);
+		this.defz = dd.Int(dd.getCssProp(this.div, 'z-index','zIndex','zIndex'));
+	}
+	this.defw = this.w || 0;
+	this.defh = this.h || 0;
+}
+
+DDObj.prototype.moveBy = function(d_x, d_y, d_kds, d_o)
+{
+	if (!this.div) return;
+	this.x += (d_x = dd.Int(d_x));
+	this.y += (d_y = dd.Int(d_y));
+	if (!d_kds || this.is_image || this.parent != this.defparent)
+	{
+		(d_o = this.css || this.div).left = (this.cssx += d_x) + dd.px;
+		d_o.top = (this.cssy += d_y) + dd.px;
+	}
+	var d_i = this.children.length; while (d_i--)
+	{
+		if (!(d_o = this.children[d_i]).detached) d_o.moveBy(d_x, d_y, 1);
+		d_o.defx += d_x;
+		d_o.defy += d_y;
+	}
+};
+
+DDObj.prototype.moveTo = function(d_x, d_y)
+{
+	this.moveBy(dd.Int(d_x)-this.x, dd.Int(d_y)-this.y);
+};
+
+DDObj.prototype.hide = function(d_m, d_o, d_p)
+{
+	if (this.div && this.visible)
+	{
+		d_p = this.css || this.div;
+		if (d_m && !dd.n4)
+		{
+			this.display = dd.getCssProp(this.div, "display", "display", "display");
+			if (this.oimg)
+			{
+				this.oimg.display = dd.getCssProp(this.oimg, "display", "display", "display");
+				this.oimg.style.display = "none";
+			}
+			d_p.display = "none";
+			dd.recalc();
+		}
+		else d_p.visibility = "hidden";
+	}
+	this.visible = false;
+	var d_i = this.children.length; while (d_i--)
+		if (!(d_o = this.children[d_i]).detached) d_o.hide(d_m);
+};
+
+DDObj.prototype.show = function(d_o, d_p)
+{
+	if (this.div)
+	{
+		d_p = this.css || this.div;
+		if (d_p.display && d_p.display == "none")
+		{
+			d_p.display = this.display || "block";
+			if (this.oimg) this.oimg.style.display = this.oimg.display || "inline";
+			dd.recalc();
+		}
+		else d_p.visibility = "visible";
+	}
+	this.visible = true;
+	var d_i = this.children.length; while (d_i--)
+		if (!(d_o = this.children[d_i]).detached) d_o.show();
+};
+
+DDObj.prototype.resizeTo = function(d_w, d_h, d_o)
+{
+	if (!this.div) return;
+	d_w = (this.w = dd.Int(d_w))-this.dw;
+	d_h = (this.h = dd.Int(d_h))-this.dh;
+	if (dd.n4)
+	{
+		this.div.resizeTo(d_w, d_h);
+		if (this.is_image)
+		{
+			this.write('<img src="' + this.src + '" width="' + d_w + '" height="' + d_h + '">');
+			(this.nimg = this.div.document.images[0]).src = this.src;
+		}
+	}
+	else if (typeof this.css.pixelWidth != "undefined")
+	{
+		this.css.pixelWidth = d_w;
+		this.css.pixelHeight = d_h;
+		if (this.is_image)
+		{
+			(d_o = this.nimg.style).pixelWidth = d_w;
+			d_o.pixelHeight = d_h;
+		}
+	}
+	else
+	{
+		this.css.width = d_w + dd.px;
+		this.css.height = d_h + dd.px;
+		if (this.is_image)
+		{
+			(d_o = this.nimg).width = d_w;
+			d_o.height = d_h;
+			if (!d_o.complete) d_o.src = this.src;
+		}
+	}
+};
+
+DDObj.prototype.resizeBy = function(d_dw, d_dh)
+{
+	this.resizeTo(this.w+dd.Int(d_dw), this.h+dd.Int(d_dh));
+};
+
+DDObj.prototype.swapImage = function(d_x, d_cp)
+{
+	if (!this.nimg) return;
+	this.nimg.src = d_x;
+	this.src = this.nimg.src;
+	if (d_cp)
+	{
+		var d_i = this.copies.length; while (d_i--)
+			this.copies[d_i].src = this.copies[d_i].nimg.src = this.nimg.src;
+	}
+};
+
+DDObj.prototype.setBgColor = function(d_x)
+{
+	if (dd.n4 && this.div) this.div.bgColor = d_x;
+	else if (this.css) this.css.background = d_x;
+	this.bgColor = d_x;
+};
+
+DDObj.prototype.write = function(d_x, d_o)
+{
+	this.text = d_x;
+	if (!this.div) return;
+	if (dd.n4)
+	{
+		(d_o = this.div.document).open();
+		d_o.write(d_x);
+		d_o.close();
+		dd.getWH(this);
+	}
+	else if (!dd.op6)
+	{
+		this.css.height = 'auto';
+		this.div.innerHTML = d_x;
+		if (!dd.ie4) dd.recalc();
+		if (dd.ie4 || dd.n6) setTimeout('dd.recalc();', 0); // n6.0: recalc twice
+	}
+};
+
+DDObj.prototype.copy = function(d_n, d_p)
+{
+	if (!this.oimg) return;
+	d_n = d_n || 1;
+	while (d_n--)
+	{
+		var d_l = this.copies.length,
+		d_o = new DDObj(this.name+this.cmd, d_l+1);
+		if (dd.n4)
+		{
+			d_o.id = (d_p = new Layer(d_o.w)).name;
+			d_p.clip.height = d_o.h;
+			d_p.visibility = 'show';
+			(d_p = d_p.document).open();
+			d_p.write(d_o.htm);
+			d_p.close();
+		}
+		else if (dd.db.insertAdjacentHTML) dd.db.insertAdjacentHTML("AfterBegin", d_o.t_htm);
+		else if (document.createElement && dd.db && dd.db.appendChild)
+		{
+			dd.db.appendChild(d_p = document.createElement('div'));
+			d_p.innerHTML = d_o.htm;
+			d_p.id = d_o.id;
+			d_p.style.position = 'absolute';
+			d_p.style.width = d_o.w + 'px';
+			d_p.style.height = d_o.h + 'px';
+		}
+		else if (dd.db && dd.db.innerHTML) dd.db.innerHTML += d_o.t_htm;
+		d_o.defz = this.defz+1+d_l;
+		dd.addProps(d_o);
+		d_o.original = this;
+		dd.addElt(d_o, this);
+		if (this.parent)
+		{
+			this.parent.addChild(d_o, this.detached);
+			d_o.defparent = this.defparent;
+		}
+		d_o.moveTo(d_o.defx = this.defx, d_o.defy = this.defy);
+		if (dd.n4) d_o.defsrc = d_o.src = this.defsrc;
+		d_o.swapImage(this.src);
+	}
+};
+
+DDObj.prototype.addChild = function(d_kd, detach, defp)
+{
+	if (typeof d_kd != "object") d_kd = dd.elements[d_kd];
+	if (d_kd.parent && d_kd.parent == this || d_kd == this || !d_kd.is_image && d_kd.defparent && !defp) return;
+
+	this.children[this.children.length] = this.children[d_kd.name] = d_kd;
+	d_kd.detached = detach || 0;
+	if (defp) d_kd.defparent = this;
+	else if (this == d_kd.defparent && d_kd.is_image) dd.getImg(this, d_kd.oimg.name, 1);
+	if (!d_kd.defparent || this != d_kd.defparent)
+	{
+		d_kd.defx = d_kd.x;
+		d_kd.defy = d_kd.y;
+	}
+	if (!detach)
+	{
+		d_kd.defz = d_kd.defz+this.defz-(d_kd.parent? d_kd.parent.defz : 0)+(!d_kd.is_image*1);
+		d_kd.setZ(d_kd.z+this.z-(d_kd.parent? d_kd.parent.z : 0)+(!d_kd.is_image*1), 1);
+	}
+	if (d_kd.parent) d_kd.parent._removeChild(d_kd, 1);
+	d_kd.parent = this;
+};
+
+DDObj.prototype._removeChild = function(d_kd, d_newp)
+{
+	if (typeof d_kd != "object") d_kd = this.children[d_kd];
+	var d_oc = this.children, d_nc = new Array();
+	for (var d_i = 0; d_i < d_oc.length; d_i++)
+		if (d_oc[d_i] != d_kd) d_nc[d_nc.length] = d_oc[d_i];
+	this.children = d_nc;
+	d_kd.parent = null;
+	if (!d_newp)
+	{
+		d_kd.detached = d_kd.defp = 0;
+		if (d_kd.is_image) dd.getImg(d_kd, d_kd.oimg.name, 1);
+	}
+};
+
+DDObj.prototype.attachChild = function(d_kd)
+{
+	(d_kd = (typeof d_kd != "object")? this.children[d_kd]: d_kd).detached = 0;
+	d_kd.setZ(d_kd.defz + this.z-this.defz, 1);
+};
+
+DDObj.prototype.detachChild = function(d_kd)
+{
+	(d_kd = (typeof d_kd != "object")? this.children[d_kd]: d_kd).detached = 1;
+};
+
+DDObj.prototype.setZ = function(d_x, d_kds)
+{
+	if (d_kds)
+	{
+		var d_dz = d_x-this.z,
+		d_i = this.children.length; while (d_i--)
+			if (!(d_o = this.children[d_i]).detached) d_o.setZ(d_o.z+d_dz, 1);
+	}
+	dd.z = Math.max(dd.z, this.z = this.div? ((this.css || this.div).zIndex = d_x) : 0);
+};
+
+DDObj.prototype.maximizeZ = function()
+{
+	this.setZ(dd.z+1, 1);
+};
+
+DDObj.prototype._resetZ = function(d_o)
+{
+	if (this.re_z || dd.re_z)
+	{
+		this.setZ(this.defz);
+		var d_i = this.children.length; while (d_i--)
+			if (!(d_o = this.children[d_i]).detached) d_o.setZ(d_o.defz);
+	}
+};
+
+DDObj.prototype.setOpacity = function(d_x)
+{
+	this.opacity = d_x;
+	this._setOpaRel(1.0, 1);
+};
+DDObj.prototype._setOpaRel = function(d_x, d_kd, d_y, d_o)
+{
+	if(this.css && (this.diaphan || d_kd))
+	{
+		d_y = this.opacity*d_x;
+		if(typeof this.css.MozOpacity != dd_u) this.css.MozOpacity = d_y;
+		else if(typeof this.css.filter != dd_u)
+			this.css.filter = "Alpha(opacity="+parseInt(100*d_y)+")";
+		else this.css.opacity = d_y;
+		var d_i = this.children.length; while(d_i--)
+			if(!(d_o = this.children[d_i]).detached) d_o._setOpaRel(d_x, 1);
+	}
+};
+
+DDObj.prototype.setCursor = function(d_x)
+{
+	this._setCrs(this.cursor = (d_x.indexOf('c:')+1)? d_x.substring(2) : d_x);
+};
+
+DDObj.prototype._setCrs = function(d_x)
+{
+	if (this.css) this.css.cursor = ((!dd.ie || dd.iemac) && d_x == 'hand')? 'pointer' : d_x;
+};
+
+DDObj.prototype.setDraggable = function(d_x)
+{
+	this.nodrag = !d_x*1;
+	this._setCrs(d_x? this.cursor : 'auto');
+};
+
+DDObj.prototype.setResizable = function(d_x)
+{
+	this.resizable = d_x*1;
+	if (d_x) this.scalable = 0;
+};
+
+DDObj.prototype.setScalable = function(d_x)
+{
+	this.scalable = d_x*1;
+	if (d_x) this.resizable = 0;
+};
+
+DDObj.prototype.del = function(d_os, d_o)
+{
+	if (this.parent && this.parent._removeChild) this.parent._removeChild(this);
+	if (this.original)
+	{
+		this.hide();
+		if (this.original.copies)
+		{
+			d_os = new Array();
+			for (var d_i = 0; d_i < this.original.copies.length; d_i++)
+				if ((d_o = this.original.copies[d_i]) != this) d_os[d_os.length] = d_os[d_o.name] = d_o;
+			this.original.copies = d_os;
+		}
+	}
+	else if (this.is_image)
+	{
+		this.hide();
+		if (this.oimg)
+		{
+		  if (dd.n4) this.oimg.src = this.defsrc;
+		  else this.oimg.style.visibility = 'visible';
+		}
+	}
+	else if (this.moveTo)
+	{
+		if (this.css) this.css.cursor = 'default';
+		this.moveTo(this.defx, this.defy);
+		this.resizeTo(this.defw, this.defh);
+	}
+	d_os = new Array();
+	for (var d_i = 0; d_i < dd.elements.length; d_i++)
+	{
+		if ((d_o = dd.elements[d_i]) != this) d_os[d_os.length] = d_os[d_o.name] = d_o;
+		else d_o._free();
+	}
+	dd.elements = d_os;
+	if (!dd.op6 && !dd.n4) dd.recalc();
+};
+
+DDObj.prototype._free = function()
+{
+	for (var d_i in this)
+		this[d_i] = null;
+	dd.elements[this.name] = null;
+};
+
+
+
+dd.n4RectVis = function(vis)
+{
+	for (var d_i = 4; d_i--;)
+	{
+		dd.rectI[d_i].visibility = dd.rectA[d_i].visibility = vis? 'show' : 'hide';
+		if (vis) dd.rectI[d_i].zIndex = dd.rectA[d_i].zIndex = dd.z+2;
+	}
+};
+
+dd.n4RectPos = function(d_o, d_x, d_y, d_w, d_h)
+{
+	d_o.x = d_x;
+	d_o.y = d_y;
+	d_o.clip.width = d_w;
+	d_o.clip.height = d_h;
+};
+
+// NN4: draw img resize rectangle
+dd.n4Rect = function(d_w, d_h)
+{
+	if (!dd.rectI)
+	{
+		dd.rectI = new Array();
+		dd.rectA = new Array();
+	}
+	if (!dd.rectI[0])
+	{
+		for (var d_i = 4; d_i--;)
+		{
+			(dd.rectI[d_i] = new Layer(1)).bgColor = '#000000';
+			(dd.rectA[d_i] = new Layer(1)).bgColor = '#ffffff';
+		}
+	}
+	if (!dd.rectI[0].visibility || dd.rectI[0].visibility == 'hide') dd.n4RectVis(1);
+	dd.obj.w = d_w;
+	dd.obj.h = d_h;
+	for (var d_i = 4; d_i--;)
+	{
+		dd.n4RectPos(dd.rectI[d_i], dd.obj.x + (!(d_i-1)? (dd.obj.w-1) : 0), dd.obj.y + (!(d_i-2)? (dd.obj.h-1) : 0), d_i&1 || dd.obj.w, !(d_i&1) || dd.obj.h);
+		dd.n4RectPos(dd.rectA[d_i], !(d_i-1)? dd.rectI[1].x+1 : (dd.obj.x-1), !(d_i-2)? dd.rectI[2].y+1 : (dd.obj.y-1), d_i&1 || dd.obj.w+2, !(d_i&1) || dd.obj.h+2);
+	}
+};
+
+dd.reszTo = function(d_w, d_h)
+{
+	if (dd.n4 && dd.obj.is_image) dd.n4Rect(d_w, d_h);
+	else dd.obj.resizeTo(d_w, d_h);
+};
+
+dd.embedVis = function(d_vis)
+{
+	var d_o = new Array('iframe', 'applet', 'embed', 'object');
+	var d_i = d_o.length; while (d_i--)
+	{
+		var d_p = dd.ie? document.all.tags(d_o[d_i]) : document.getElementsByTagName? document.getElementsByTagName(d_o[d_i]) : null;
+		if (d_p)
+		{
+			var d_j = d_p.length; while (d_j--)
+			{
+				var d_q = d_p[d_j];
+				while (d_q.offsetParent || d_q.parentNode)
+				{
+					if ((d_q = d_q.parentNode || d_q.offsetParent || null) == dd.obj.div)
+					{
+						d_p[d_j].style.visibility = d_vis;
+						break;
+					}
+				}
+			}
+		}
+	}
+};
+
+dd.maxOffX = function(d_x, d_y)
+{
+	return (
+		(dd.obj.maxoffl+1 && (d_y = dd.obj.defx-dd.obj.maxoffl)-d_x > 0
+		|| dd.obj.maxoffr+1 && (d_y = dd.obj.defx+dd.obj.maxoffr)-d_x < 0)? d_y
+		: d_x
+	);
+};
+
+dd.maxOffY = function(d_x, d_y)
+{
+	return (
+		(dd.obj.maxofft+1 && (d_y = dd.obj.defy-dd.obj.maxofft)-d_x > 0
+		|| dd.obj.maxoffb+1 && (d_y = dd.obj.defy+dd.obj.maxoffb)-d_x < 0)? d_y
+		: d_x
+	);
+};
+
+dd.inWndW = function(d_x, d_y)
+{
+	var d_wx = dd.getScrollX(),
+	d_ww = dd.getWndW();
+	return (
+		((d_y = d_wx+2)-d_x > 0) || ((d_y = d_wx+d_ww+dd.obj.w-2)-d_x < 0)? d_y
+		: d_x
+	);
+};
+
+dd.inWndH = function(d_x, d_y)
+{
+	var d_wy = dd.getScrollY(),
+	d_wh = dd.getWndH();
+	return (
+		((d_y = d_wy+2)-d_x > 0) || ((d_y = d_wy+d_wh+dd.obj.h-2)-d_x < 0)? d_y
+		: d_x
+	);
+};
+
+// These two funcs limit the size of element when mouseresized.
+// Implemented 22.5.2003 by Gregor Lï¿œtolf <gregor@milou.ch>, modified by Walter Zorn
+dd.limW = function(d_w)
+{
+	return (
+		(dd.obj.minw-d_w > 0)? dd.obj.minw
+		: (dd.obj.maxw > 0 && dd.obj.maxw-d_w < 0)? dd.obj.maxw
+		: d_w
+	);
+};
+
+dd.limH = function(d_h)
+{
+	return (
+		(dd.obj.minh-d_h > 0)? dd.obj.minh
+		: (dd.obj.maxh > 0 && dd.obj.maxh-d_h < 0)? dd.obj.maxh
+		: d_h
+	);
+};
+
+
+// Optional autoscroll-page functionality. Courtesy Cedric Savarese.
+// Implemented by Walter Zorn
+function DDScroll()
+{
+	if (!dd.obj || !dd.obj.scroll && !dd.scroll || dd.op || dd.ie4 || dd.whratio)
+	{
+		dd.scrx = dd.scry = 0;
+		return;
+	}
+	var d_bnd = 0x1c,
+	d_wx = dd.getScrollX(), d_wy = dd.getScrollY();
+	if (dd.msmoved)
+	{
+		var d_ww = dd.getWndW(), d_wh = dd.getWndH(), d_y;
+		dd.scrx = ((d_y = dd.e.x-d_ww-d_wx+d_bnd) > 0)? (d_y>>=2)*d_y
+			: ((d_y = d_wx+d_bnd-dd.e.x) > 0)? -(d_y>>=2)*d_y
+			: 0;
+		dd.scry = ((d_y = dd.e.y-d_wh-d_wy+d_bnd) > 0)? (d_y>>=2)*d_y
+			: ((d_y = d_wy+d_bnd-dd.e.y) > 0)? -(d_y>>=2)*d_y
+			: 0;
+	}
+	if (dd.scrx || dd.scry)
+	{
+		window.scrollTo(
+			d_wx + (dd.scrx = dd.obj.is_resized? dd.limW(dd.obj.w+dd.scrx)-dd.obj.w : dd.obj.vertical? 0 : (dd.maxOffX(dd.obj.x+dd.scrx)-dd.obj.x)),
+			d_wy + (dd.scry = dd.obj.is_resized? dd.limH(dd.obj.h+dd.scry)-dd.obj.h : dd.obj.horizontal? 0 : (dd.maxOffY(dd.obj.y+dd.scry)-dd.obj.y))
+		);
+		dd.obj.is_dragged? dd.obj.moveTo(dd.obj.x+dd.getScrollX()-d_wx, dd.obj.y+dd.getScrollY()-d_wy)
+			: dd.reszTo(dd.obj.w+dd.getScrollX()-d_wx, dd.obj.h+dd.getScrollY()-d_wy);
+	}
+	dd.msmoved = 0;
+	window.setTimeout('DDScroll()', 0x33);
+}
+
+
+
+function PICK(d_ev)
+{
+	dd.e = new dd.evt(d_ev);
+	if (dd.e.x >= dd.getWndW()+dd.getScrollX() || dd.e.y >= dd.getWndH()+dd.getScrollY()) return true; // on scrollbar
+	var d_o, d_cmp = -1, d_i = dd.elements.length; while (d_i--)
+	{
+		d_o = dd.elements[d_i];
+		if (dd.n4 && dd.e.but > 1 && dd.e.src == d_o.oimg && !d_o.clone) return false;
+		if (d_o.visible && dd.e.but <= 1 && !d_o.nodrag && dd.e.x >= d_o.x && dd.e.x <= d_o.x+d_o.w && dd.e.y >= d_o.y && dd.e.y <= d_o.y+d_o.h)
+		{
+			if (d_o.z > d_cmp && dd.e.src.tag.indexOf('input') < 0 && dd.e.src.tag.indexOf('textarea') < 0 && dd.e.src.tag.indexOf('select') < 0 && dd.e.src.tag.indexOf('option') < 0)
+			{
+				d_cmp = d_o.z;
+				dd.obj = d_o;
+			}
+		}
+	}
+	if (dd.obj)
+	{
+		dd.e.e.cancelBubble = true;
+		var d_rsz = dd.e.modifKey && (dd.obj.resizable || dd.obj.scalable);
+		if (dd.op && !dd.op6)
+		{
+			(d_o = document.getElementById('OpBlUr')).style.pixelLeft = dd.e.x;
+			d_o.style.pixelTop = dd.e.y;
+			(d_o = d_o.children[0].children[0]).focus();
+			d_o.blur();
+		}
+		else if (dd.ie && !dd.ie4)
+		{
+			if (document.selection && document.selection.empty) document.selection.empty();
+			dd.db.onselectstart = function()
+			{
+				event.returnValue = false;
+			};
+		}
+		if (d_rsz)
+		{
+			dd.obj._setCrs('se-resize');
+			dd.obj.is_resized = 1;
+			dd.whratio = dd.obj.scalable? dd.obj.defw/dd.obj.defh : 0;
+			if (dd.ie)
+			{
+				if (dd.ie4)
+				{
+					window.dd_x = dd.getScrollX();
+					window.dd_y = dd.getScrollY();
+				}
+				setTimeout(
+					'if (dd.obj && document.selection && document.selection.empty)'+
+					'{'+
+						'document.selection.empty();'+
+						'if (dd.ie4) window.scrollTo(window.dd_x, window.dd_y);'+
+					'}'
+				,0);
+			}
+			dd.setEvtHdl(1, RESIZE);
+			dd.reszTo(dd.obj.w, dd.obj.h);
+		}
+		else if (!dd.obj.nodrag)
+		{
+			dd.obj.is_dragged = 1;
+			dd.setEvtHdl(1, DRAG);
+		}
+		dd.setEvtHdl(2, DROP);
+		dd.embedVis('hidden');
+		dd.obj.maximizeZ();
+		dd.ofx = dd.obj.x+dd.obj.w-dd.e.x;
+		dd.ofy = dd.obj.y+dd.obj.h-dd.e.y;
+		if (window.my_PickFunc) my_PickFunc();
+		DDScroll();
+		return !(
+			dd.obj.is_resized
+			|| dd.n4 && dd.obj.is_image
+			|| dd.n6 || dd.w3c
+		);
+	}
+	if (dd.downFunc) return dd.downFunc(d_ev);
+	return true;
+}
+
+function DRAG(d_ev)
+{
+	if (!dd.obj || !dd.obj.visible) return true;
+	if (dd.ie4 || dd.w3c || dd.n6 || dd.obj.children.length > 0xf)
+	{
+		if (dd.wait) return false;
+		dd.wait = 1;
+		setTimeout('dd.wait = 0;', 5);
+	}
+	dd.e = new dd.evt(d_ev);
+	if (dd.ie && !dd.e.but)
+	{
+		DROP(d_ev);
+		return true;
+	}
+	dd.msmoved = 1;
+	dd.obj.moveTo(
+		dd.obj.vertical? dd.obj.x : dd.maxOffX(dd.inWndW(dd.ofx+dd.e.x)-dd.obj.w),
+		dd.obj.horizontal? dd.obj.y : dd.maxOffY(dd.inWndH(dd.ofy+dd.e.y)-dd.obj.h)
+	);
+
+	if (window.my_DragFunc) my_DragFunc();
+	return false;
+}
+
+function RESIZE(d_ev)
+{
+	if (!dd.obj || !dd.obj.visible) return true;
+	if (dd.wait) return false;
+	dd.wait = 1;
+	setTimeout('dd.wait = 0;', 5);
+	dd.e = new dd.evt(d_ev);
+	if (dd.ie && !dd.e.but)
+	{
+		DROP(d_ev);
+		return true;
+	}
+	dd.msmoved = 1;
+	var d_w = dd.limW(dd.inWndW(dd.ofx+dd.e.x)-dd.obj.x);
+	if (!dd.whratio) var d_h = dd.limH(dd.inWndH(dd.ofy+dd.e.y)-dd.obj.y);
+	else
+	{
+		var d_h = dd.limH(dd.inWndH(Math.round(d_w/dd.whratio)+dd.obj.y)-dd.obj.y);
+		d_w = Math.round(d_h*dd.whratio);
+	}
+	dd.reszTo(d_w, d_h);
+	if (window.my_ResizeFunc) my_ResizeFunc();
+	return false;
+}
+
+function DROP(d_ev)
+{
+	if (dd.obj)
+	{
+		if (dd.obj.is_dragged)
+		{
+			if (!dd.obj.is_image) dd.getWH(dd.obj);
+		}
+		else if (dd.n4)
+		{
+			if (dd.obj.is_image)
+			{
+				dd.n4RectVis(0);
+				dd.obj.resizeTo(dd.obj.w, dd.obj.h);
+			}
+		}
+		if (!dd.n4 && !dd.op6 || !dd.obj.is_image) dd.recalc();
+		dd.setEvtHdl(1, dd.moveFunc);
+		dd.setEvtHdl(2, dd.upFunc);
+		if (dd.db) dd.db.onselectstart = null;
+		dd.obj._setCrs(dd.obj.cursor);
+		dd.embedVis('visible');
+		dd.obj._resetZ();
+		if (window.my_DropFunc)
+		{
+			dd.e = new dd.evt(d_ev);
+			my_DropFunc();
+		}
+		dd.msmoved = dd.obj.is_dragged = dd.obj.is_resized = dd.whratio = 0;
+		dd.obj = null;
+	}
+	dd.setEvtHdl(0, PICK);
+}
+
+
+
+function SET_DHTML()
+{
+	dd.elements = new Array();
+	var d_a = SET_DHTML.arguments, d_ai, d_htm = '', d_o, d_i = d_a.length; while (d_i--)
+	{
+		if (dd.op6)
+		{
+			var d_t0 = (new Date()).getTime();
+			while ((new Date()).getTime()-d_t0 < 0x99){};
+		}
+		if (!(d_ai = d_a[d_i]).indexOf('c:')) dd.cursor = d_ai.substring(2);
+		else if (d_ai == NO_ALT) dd.noalt = 1;
+		else if (d_ai == SCROLL) dd.scroll = 1;
+		else if (d_ai == RESET_Z) dd.re_z = 1;
+		else if (d_ai == RESIZABLE) dd.resizable = 1;
+		else if (d_ai == SCALABLE) dd.scalable = 1;
+		else
+		{
+			d_o = new DDObj(d_ai);
+			dd.addElt(d_o);
+			d_htm += d_o.t_htm || '';
+			if (d_o.oimg && d_o.cpy_n)
+			{
+				var d_j = 0; while (d_j < d_o.cpy_n)
+				{
+					var d_p = new DDObj(d_o.name+d_o.cmd, ++d_j);
+					dd.addElt(d_p, d_o);
+					d_p.defz = d_o.defz+d_j;
+					d_p.original = d_o;
+					d_htm += d_p.t_htm;
+				}
+			}
+		}
+	}
+	if (dd.n4 || dd.n6 || dd.ie || dd.op || dd.w3c) document.write(
+		(dd.n4? '<div style="position:absolute;"><\/div>\n'
+		: (dd.op && !dd.op6)? '<div id="OpBlUr" style="position:absolute;visibility:hidden;width:0px;height:0px;"><form><input type="text" style="width:0px;height:0px;"><\/form><\/div>'
+		: '') + d_htm
+	);
+	dd.z = 0x33;
+	d_i = dd.elements.length; while (d_i--)
+	{
+		dd.addProps(d_o = dd.elements[d_i]);
+		if (d_o.is_image && !d_o.original && !d_o.clone)
+			dd.n4? d_o.oimg.src = spacer : d_o.oimg.style.visibility = 'hidden';
+	}
+	dd.mkWzDom();
+	if (window.onload) dd.loadFunc = window.onload;
+	window.onload = dd.initz;
+	window.onunload = dd.finlz;
+	dd.setEvtHdl(0, PICK);
+}
+
+function ADD_DHTML(d_o) // layers only!
+{
+	d_o = new DDObj(d_o);
+	dd.addElt(d_o);
+	dd.addProps(d_o);
+	dd.mkWzDom();
+}
+
+
+
+
+////////////////////////////////////////////////////////////
+// If not needed, all code below this line may be removed
+
+
+// For backward compatibility
+dd.d = document;            // < v. 2.72
+var RESET_ZINDEX = RESET_Z; // < 3.44
+var KEYDOWN_RESIZE = RESIZABLE; // < 4.43
+var CURSOR_POINTER = CURSOR_HAND; // < 4.44
+var NO_SCROLL = '';         // < v. 4.49
+
+
+
+
+////////////////////////////////////////////////////////////
+// FUNCTIONS FOR EXTENDED SCRIPTING
+// Use these for your own extensions,
+// or to call functions defined elsewhere
+
+
+
+/* my_PickFunc IS AUTOMATICALLY CALLED WHEN AN ITEM STARTS TO BE DRAGGED.
+The following objects/properties are accessible from here:
+
+- dd.e: current mouse event
+- dd.e.property: access to a property of the current mouse event.
+  Mostly requested properties:
+  - dd.e.x: document-related x co-ordinate
+  - dd.e.y: document-related y co-ord
+  - dd.e.src: target of mouse event (not identical with the drag drop object itself).
+  - dd.e.button: currently pressed mouse button. Left button: dd.e.button <= 1
+
+- dd.obj: reference to currently dragged item.
+- dd.obj.property: access to any property of that item.
+- dd.obj.method(): for example dd.obj.resizeTo() or dd.obj.swapImage() .
+  Mostly requested properties:
+	- dd.obj.name: image name or layer ID passed to SET_DHTML();
+	- dd.obj.x and dd.obj.y: co-ordinates;
+	- dd.obj.w and dd.obj.h: size;
+	- dd.obj.is_dragged: 1 while item is dragged, else 0;
+	- dd.obj.is_resized: 1 while item is resized, i.e. if <ctrl> or <shift> is pressed, else 0
+
+For more properties and details, visit the API documentation
+at http://www.walterzorn.com/dragdrop/api_e.htm (english) or
+http://www.walterzorn.de/dragdrop/api.htm (german)    */
+function my_PickFunc()
+{
+}
+
+
+
+
+/* my_DragFunc IS CALLED WHILE AN ITEM IS DRAGGED
+See the description of my_PickFunc above for what's accessible from here. */
+function my_DragFunc()
+{
+	//window.status = 'dd.elements.' + dd.obj.name + '.x  = ' + dd.obj.x + '     dd.elements.' + dd.obj.name + '.y = ' + dd.obj.y;
+}
+
+
+
+
+/* my_ResizeFunc IS CALLED WHILE AN ITEM IS RESIZED
+See the description of my_PickFunc above for what's accessible from here. */
+function my_ResizeFunc()
+{
+	//window.status = 'dd.elements.' + dd.obj.name + '.w  = ' + dd.obj.w + '     dd.elements.' + dd.obj.name + '.h = ' + dd.obj.h;
+}
+
+
+
+
+/* THIS ONE IS CALLED ONCE AN ITEM IS DROPPED
+See the description of my_PickFunc for what's accessible from here.
+Here may be investigated, for example, what's the name (dd.obj.name)
+of the dropped item, and where (dd.obj.x, dd.obj.y) it has been dropped... */
+function my_DropFunc()
+{
+}
+
+
Index: /sandbox/workflow/branches/993/js/jscode/globals.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/globals.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/globals.js	(revision 795)
@@ -0,0 +1,3 @@
+var BordersArray = new Array();
+var array_lang = new Array();
+var _icon_dir = _web_server_url + "/workflow/templateFile.php?file=images/";
Index: /sandbox/workflow/branches/993/js/jscode/base64.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/base64.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/base64.js	(revision 795)
@@ -0,0 +1,65 @@
+// This code was written by Tyler Akins and has been placed in the
+// public domain. It would be nice if you left this header intact.
+// Base64 code from Tyler Akins -- http://rumkin.com
+
+keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+function encode64(input) {
+	var output = "";
+	var chr1, chr2, chr3;
+	var enc1, enc2, enc3, enc4;
+	var i = 0;
+
+	do {
+		chr1 = input.charCodeAt(i++);
+		chr2 = input.charCodeAt(i++);
+		chr3 = input.charCodeAt(i++);
+
+		enc1 = chr1 >> 2;
+		enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+		enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+		enc4 = chr3 & 63;
+
+		if (isNaN(chr2)) {
+			enc3 = enc4 = 64;
+		} else if (isNaN(chr3)) {
+			enc4 = 64;
+		}
+
+		output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
+		keyStr.charAt(enc3) + keyStr.charAt(enc4);
+	} while (i < input.length);
+	return output;
+}
+
+function decode64(input) {
+	var output = "";
+	var chr1, chr2, chr3;
+	var enc1, enc2, enc3, enc4;
+	var i = 0;
+
+	// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
+	input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+	do {
+		enc1 = keyStr.indexOf(input.charAt(i++));
+		enc2 = keyStr.indexOf(input.charAt(i++));
+		enc3 = keyStr.indexOf(input.charAt(i++));
+		enc4 = keyStr.indexOf(input.charAt(i++));
+
+		chr1 = (enc1 << 2) | (enc2 >> 4);
+		chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+		chr3 = ((enc3 & 3) << 6) | enc4;
+
+		output = output + String.fromCharCode(chr1);
+
+		if (enc3 != 64) {
+			output = output + String.fromCharCode(chr2);
+		}
+		if (enc4 != 64) {
+			output = output + String.fromCharCode(chr3);
+		}
+	} while (i < input.length);
+
+	return output;
+}
Index: /sandbox/workflow/branches/993/js/jscode/debug.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/debug.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/debug.js	(revision 795)
@@ -0,0 +1,21 @@
+function editField(random, key)
+{
+	var tableCell = document.getElementById(random + '_' + key + '_td');
+	tableCell.innerHTML = '<input type="text" id="' + random + '_' + key + '_edit" value="' + document.getElementById(random + '_' + key).value + '"/>';
+	tableCell.nextSibling.innerHTML = '<a href="#" onclick="setField(\'' + random + '\', \'' + key + '\'); return false;">ok</a>';
+	document.getElementById(random + '_' + key + '_edit').focus();
+}
+
+function setField(random, key)
+{
+	var tableCell = document.getElementById(random + '_' + key + '_td');
+	document.getElementById(random + '_' + key).value = document.getElementById(random + '_' + key + '_edit').value;
+	tableCell.innerHTML = document.getElementById(random + '_' + key + '_edit').value;
+	tableCell.nextSibling.innerHTML = '<a href="#" onclick="editField(\'' + random + '\', \'' + key + '\'); return false;">editar</a>';
+}
+
+function toggleTableDisplay(tableElement)
+{
+	for (var i = 1; i < tableElement.rows.length; i++)
+		tableElement.rows[i].style.display = (tableElement.rows[i].style.display == 'none') ? '' : 'none';
+}
Index: /sandbox/workflow/branches/993/js/jscode/consiste.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/consiste.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/consiste.js	(revision 795)
@@ -0,0 +1,29 @@
+// Use essa função para validar datas no formado dd/mm/yyyy
+function check_date(input,caption)
+{
+    var re   = /[0-3][0-9]\/[0-1][0-9]\/[1-2][0-9][0-9][0-9]/;
+    var data = input.value;
+
+    if (!data.match(re))
+    {
+        alert('Data Inválida ('+caption+'). Utilize o formato dd/mm/yyyy');
+        return false;
+    } else {
+        return true;
+    }
+}
+
+// Use essa função para validar numeros
+function check_num(input,caption)
+{
+    var re   = /[0-9]+/;
+    var num = input.value;
+
+    if (!num.match(re))
+    {
+        alert('Número Inválido ('+caption+').');
+        return false;
+    } else {
+        return true;
+    }
+}
Index: /sandbox/workflow/branches/993/js/jscode/niftycube.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/niftycube.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/niftycube.js	(revision 795)
@@ -0,0 +1,298 @@
+/* Nifty Corners Cube - rounded corners with CSS and Javascript
+Copyright 2006 Alessandro Fulciniti (a.fulciniti@html.it)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+var niftyOk=(document.getElementById && document.createElement && Array.prototype.push);
+var niftyCss=false;
+
+String.prototype.find=function(what){
+return(this.indexOf(what)>=0 ? true : false);
+}
+
+var oldonload=window.onload;
+if(typeof(NiftyLoad)!='function') NiftyLoad=function(){};
+if(typeof(oldonload)=='function')
+    window.onload=function(){oldonload();AddCss();NiftyLoad()};
+else window.onload=function(){AddCss();NiftyLoad()};
+
+function AddCss(){
+niftyCss=true;
+var l=CreateEl("link");
+l.setAttribute("type","text/css");
+l.setAttribute("rel","stylesheet");
+l.setAttribute("href","niftyCorners.css");
+l.setAttribute("media","screen");
+document.getElementsByTagName("head")[0].appendChild(l);
+}
+
+function Nifty(selector,options){
+if(niftyOk==false) return;
+if(niftyCss==false) AddCss();
+var i,v=selector.split(","),h=0;
+if(options==null) options="";
+if(options.find("fixed-height"))
+    h=getElementsBySelector(v[0])[0].offsetHeight;
+for(i=0;i<v.length;i++)
+    Rounded(v[i],options);
+if(options.find("height")) SameHeight(selector,h);
+}
+
+function Rounded(selector,options){
+var i,top="",bottom="",v=new Array();
+if(options!=""){
+    options=options.replace("left","tl bl");
+    options=options.replace("right","tr br");
+    options=options.replace("top","tr tl");
+    options=options.replace("bottom","br bl");
+    options=options.replace("transparent","alias");
+    if(options.find("tl")){
+        top="both";
+        if(!options.find("tr")) top="left";
+        }
+    else if(options.find("tr")) top="right";
+    if(options.find("bl")){
+        bottom="both";
+        if(!options.find("br")) bottom="left";
+        }
+    else if(options.find("br")) bottom="right";
+    }
+if(top=="" && bottom=="" && !options.find("none")){top="both";bottom="both";}
+v=getElementsBySelector(selector);
+for(i=0;i<v.length;i++){
+    FixIE(v[i]);
+    if(top!="") AddTop(v[i],top,options);
+    if(bottom!="") AddBottom(v[i],bottom,options);
+    }
+}
+
+function AddTop(el,side,options){
+var d=CreateEl("b"),lim=4,border="",p,i,btype="r",bk,color;
+d.style.marginLeft="-"+getPadding(el,"Left")+"px";
+d.style.marginRight="-"+getPadding(el,"Right")+"px";
+if(options.find("alias") || (color=getBk(el))=="transparent"){
+    color="transparent";bk="transparent"; border=getParentBk(el);btype="t";
+    }
+else{
+    bk=getParentBk(el); border=Mix(color,bk);
+    }
+d.style.background=bk;
+d.className="niftycorners";
+p=getPadding(el,"Top");
+if(options.find("small")){
+    d.style.marginBottom=(p-2)+"px";
+    btype+="s"; lim=2;
+    }
+else if(options.find("big")){
+    d.style.marginBottom=(p-10)+"px";
+    btype+="b"; lim=8;
+    }
+else d.style.marginBottom=(p-5)+"px";
+for(i=1;i<=lim;i++)
+    d.appendChild(CreateStrip(i,side,color,border,btype));
+el.style.paddingTop="0";
+el.insertBefore(d,el.firstChild);
+}
+
+function AddBottom(el,side,options){
+var d=CreateEl("b"),lim=4,border="",p,i,btype="r",bk,color;
+d.style.marginLeft="-"+getPadding(el,"Left")+"px";
+d.style.marginRight="-"+getPadding(el,"Right")+"px";
+if(options.find("alias") || (color=getBk(el))=="transparent"){
+    color="transparent";bk="transparent"; border=getParentBk(el);btype="t";
+    }
+else{
+    bk=getParentBk(el); border=Mix(color,bk);
+    }
+d.style.background=bk;
+d.className="niftycorners";
+p=getPadding(el,"Bottom");
+if(options.find("small")){
+    d.style.marginTop=(p-2)+"px";
+    btype+="s"; lim=2;
+    }
+else if(options.find("big")){
+    d.style.marginTop=(p-10)+"px";
+    btype+="b"; lim=8;
+    }
+else d.style.marginTop=(p-5)+"px";
+for(i=lim;i>0;i--)
+    d.appendChild(CreateStrip(i,side,color,border,btype));
+el.style.paddingBottom=0;
+el.appendChild(d);
+}
+
+function CreateStrip(index,side,color,border,btype){
+var x=CreateEl("b");
+x.className=btype+index;
+x.style.backgroundColor=color;
+x.style.borderColor=border;
+if(side=="left"){
+    x.style.borderRightWidth="0";
+    x.style.marginRight="0";
+    }
+else if(side=="right"){
+    x.style.borderLeftWidth="0";
+    x.style.marginLeft="0";
+    }
+return(x);
+}
+
+function CreateEl(x){
+return(document.createElement(x));
+}
+
+function FixIE(el){
+if(el.currentStyle!=null && el.currentStyle.hasLayout!=null && el.currentStyle.hasLayout==false)
+    el.style.display="inline-block";
+}
+
+function SameHeight(selector,maxh){
+var i,v=selector.split(","),t,j,els=[],gap;
+for(i=0;i<v.length;i++){
+    t=getElementsBySelector(v[i]);
+    els=els.concat(t);
+    }
+for(i=0;i<els.length;i++){
+    if(els[i].offsetHeight>maxh) maxh=els[i].offsetHeight;
+    els[i].style.height="auto";
+    }
+for(i=0;i<els.length;i++){
+    gap=maxh-els[i].offsetHeight;
+    if(gap>0){
+        t=CreateEl("b");t.className="niftyfill";t.style.height=gap+"px";
+        nc=els[i].lastChild;
+        if(nc.className=="niftycorners")
+            els[i].insertBefore(t,nc);
+        else els[i].appendChild(t);
+        }
+    }
+}
+
+function getElementsBySelector(selector){
+var i,j,selid="",selclass="",tag=selector,tag2="",v2,k,f,a,s=[],objlist=[],c;
+if(selector.find("#")){ //id selector like "tag#id"
+    if(selector.find(" ")){  //descendant selector like "tag#id tag"
+        s=selector.split(" ");
+        var fs=s[0].split("#");
+        if(fs.length==1) return(objlist);
+        f=document.getElementById(fs[1]);
+        if(f){
+            v=f.getElementsByTagName(s[1]);
+            for(i=0;i<v.length;i++) objlist.push(v[i]);
+            }
+        return(objlist);
+        }
+    else{
+        s=selector.split("#");
+        tag=s[0];
+        selid=s[1];
+        if(selid!=""){
+            f=document.getElementById(selid);
+            if(f) objlist.push(f);
+            return(objlist);
+            }
+        }
+    }
+if(selector.find(".")){      //class selector like "tag.class"
+    s=selector.split(".");
+    tag=s[0];
+    selclass=s[1];
+    if(selclass.find(" ")){   //descendant selector like tag1.classname tag2
+        s=selclass.split(" ");
+        selclass=s[0];
+        tag2=s[1];
+        }
+    }
+var v=document.getElementsByTagName(tag);  // tag selector like "tag"
+if(selclass==""){
+    for(i=0;i<v.length;i++) objlist.push(v[i]);
+    return(objlist);
+    }
+for(i=0;i<v.length;i++){
+    c=v[i].className.split(" ");
+    for(j=0;j<c.length;j++){
+        if(c[j]==selclass){
+            if(tag2=="") objlist.push(v[i]);
+            else{
+                v2=v[i].getElementsByTagName(tag2);
+                for(k=0;k<v2.length;k++) objlist.push(v2[k]);
+                }
+            }
+        }
+    }
+return(objlist);
+}
+
+function getParentBk(x){
+var el=x.parentNode,c;
+while(el.tagName.toUpperCase()!="HTML" && (c=getBk(el))=="transparent")
+    el=el.parentNode;
+if(c=="transparent") c="#FFFFFF";
+return(c);
+}
+
+function getBk(x){
+var c=getStyleProp(x,"backgroundColor");
+if(c==null || c=="transparent" || c.find("rgba(0, 0, 0, 0)"))
+    return("transparent");
+if(c.find("rgb")) c=rgb2hex(c);
+return(c);
+}
+
+function getPadding(x,side){
+var p=getStyleProp(x,"padding"+side);
+if(p==null || !p.find("px")) return(0);
+return(parseInt(p));
+}
+
+function getStyleProp(x,prop){
+if(x.currentStyle)
+    return(x.currentStyle[prop]);
+if(document.defaultView.getComputedStyle)
+    return(document.defaultView.getComputedStyle(x,'')[prop]);
+return(null);
+}
+
+function rgb2hex(value){
+var hex="",v,h,i;
+var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
+var h=regexp.exec(value);
+for(i=1;i<4;i++){
+    v=parseInt(h[i]).toString(16);
+    if(v.length==1) hex+="0"+v;
+    else hex+=v;
+    }
+return("#"+hex);
+}
+
+function Mix(c1,c2){
+var i,step1,step2,x,y,r=new Array(3);
+if(c1.length==4)step1=1;
+else step1=2;
+if(c2.length==4) step2=1;
+else step2=2;
+for(i=0;i<3;i++){
+    x=parseInt(c1.substr(1+step1*i,step1),16);
+    if(step1==1) x=16*x+x;
+    y=parseInt(c2.substr(1+step2*i,step2),16);
+    if(step2==1) y=16*y+y;
+    r[i]=Math.floor((x*50+y*50)/100);
+    r[i]=r[i].toString(16);
+    if(r[i].length==1) r[i]="0"+r[i];
+    }
+return("#"+r[0]+r[1]+r[2]);
+}
Index: /sandbox/workflow/branches/993/js/jscode/get_form_fields.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/get_form_fields.js	(revision 2160)
+++ /sandbox/workflow/branches/993/js/jscode/get_form_fields.js	(revision 2160)
@@ -0,0 +1,54 @@
+/**
+* Gets all fields that have the id starting with "_".
+* It's usefull when you have to validate fields with an ajax call, for example.
+* Returns an array of elements.
+*/
+function get_form_fields(form_id){
+	var elems = document.forms[form_id].elements;
+	var arr   = new Object();
+	var j     = 0;
+	for(var i = 0; i < elems.length; i++){
+		if(elems[i].id.substr(0,1) == "_"){
+			// if the element is a radiobutton and is NOT checked, goes to the next element
+			if(elems[i].type == "radio" && !elems[i].checked){
+				continue;
+			}
+
+			if(elems[i].type == "select-multiple"){
+				var selectBoxMultiple = elems[i];
+				var selectArr = new Array();
+				for(k = 0; k < elems[i].length; k++){
+					var option = selectBoxMultiple.options[k];
+					if(option.selected){
+						if(option.value != ''){
+							selectArr.push(option.value);
+						} else {
+							selectArr.push(option.innerHTML);
+						}
+					}
+				}
+
+				arr[elems[i].id] = selectArr;
+				j++;
+				continue;
+			}
+
+			// if the element has [] in the end of its name, return its values (or checked elements) like an array
+			if(elems[i].name.substr(-2,2) == "[]"){
+				elem_name = elems[i].name.substr(0, elems[i].name.length - 2);
+				if(arr[elem_name] == undefined){
+					arr[elem_name] = new Array();
+				}
+
+				if(elems[i].type != "checkbox")
+					arr[elem_name].push(elems[i].value);
+				else if(elems[i].checked)
+					arr[elem_name].push(elems[i].value);
+			}
+
+			arr[elems[i].id] = elems[i].value;
+			j++;
+		}
+	}
+	return arr;
+}
Index: /sandbox/workflow/branches/993/js/jscode/connector.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/connector.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/connector.js	(revision 795)
@@ -0,0 +1,586 @@
+/****************************************** Public variables *************************************************/
+var debug_controller =false;
+var files = new Array();
+var progressBar;
+
+  if (document.all)
+	{
+		navigator.userAgent.toLowerCase().indexOf('msie 5') != -1 ? is_ie5 = true : is_ie5 = false;
+		is_ie = true;
+		is_moz1_6 = false;
+		is_mozilla = false;
+		is_ns4 = false;
+	}
+	else if (document.getElementById)
+	{
+		navigator.userAgent.toLowerCase().match('mozilla.*rv[:]1\.6.*gecko') ? is_moz1_6 = true : is_moz1_6 = false;
+		is_ie = false;
+		is_ie5 = false;
+		is_mozilla = true;
+		is_ns4 = false;
+	}
+	else if (document.layers)
+	{
+		is_ie = false;
+		is_ie5 = false;
+		is_moz1_6 = false;
+		is_mozilla = false;
+		is_ns4 = true;
+	}	
+
+/****************************************** Connector Class *************************************************/
+	// Constructor
+	function cConnector()
+	{
+		this.requests = new Array();
+		this.oxmlhttp = null;
+		this.isVisibleBar = false;
+		this.tid = 0;
+		this.progressBar = null;
+		this.oldX = 0;
+		this.oldY = 0;
+	};
+	
+	cConnector.prototype.buildBar = function()
+		{			
+			div = document.getElementById('divProgressBar');
+		
+			if(! div) {												
+				div = document.createElement("DIV");
+				div.style.visibility	= "hidden";		
+				div.style.width = "103px";
+				div.id = 'divProgressBar';
+				div.align = "center";
+				div.innerHTML = '&nbsp;&nbsp;<font face="Verdana" size="2" color="WHITE">'+document.getElementById('txt_loading').value+'...</font>&nbsp;';
+				div.style.background = "#cc4444";
+				div.style.position = 'fixed';
+				div.style.top = '0px';
+				div.style.right = '0px';
+				document.body.appendChild(div);																
+				div = document.getElementById('divProgressBar');				
+				
+				if(is_ie) {
+					var elem = document.all[div.id]; 
+					elem.style.position="absolute";
+					var root = document.body;
+					var posX = elem.offsetLeft-root.scrollLeft;
+					var posY = elem.offsetTop-root.scrollTop;
+					root.onscroll = function() {
+						//elem.style.left = (posX + root.scrollLeft) + "px";
+						elem.style.right = '0px';
+						elem.style.top = (posY + root.scrollTop) + "px";
+					};
+					document.body.insertAdjacentHTML("beforeEnd", '<iframe id="divBlank" src="about:blank" style="position:absolute; visibility:hidden" scrolling="no" frameborder="0"></iframe>');
+					
+				}
+				
+				if(debug_controller) {
+					div = document.createElement("DIV");
+					div.style.width	= "800px";
+					div.style.height= "400px";
+					div.id = "debug_controller";
+					div.align='right';
+					document.body.appendChild(div);																
+				}
+			}								
+	};	
+//------------------------------------ BEGIN: Functions for Connector HTTPRequest  -------------------------------------------------//	
+	// Serialize Data Method
+	cConnector.prototype.serialize = function(data)
+	{	var _thisObject = this;		
+		var f = function(data)
+		{
+			var str_data;
+	
+			if (data == null || 
+				(typeof(data) == 'string' && data == ''))
+			{
+				str_data = 'N;';
+			}
+	
+			else switch(typeof(data))
+			{
+				case 'object':
+					var arrayCount = 0;
+	
+					str_data = '';
+	
+					for (i in data)
+					{
+						if (i == 'length')
+						{
+							continue;
+						}
+						
+						arrayCount++;
+						switch (typeof(i))
+						{
+							case 'number':
+								str_data += 'i:' + i + ';' + _thisObject.serialize(data[i]);
+								break;
+	
+							case 'string':
+								str_data += 's:' + i.length + ':"' + i + '";' + _thisObject.serialize(data[i]);
+								break;
+	
+							default:
+								showMessage(Element('cc_msg_err_serialize_data_unknown').value);
+								break;
+						}
+					}
+	
+					if (!arrayCount)
+					{
+						str_data = 'N;';	
+					}
+					else
+					{
+						str_data = 'a:' + arrayCount + ':{' + str_data + '}';
+					}
+					
+					break;
+			
+				case 'string':
+					str_data = 's:' + data.length + ':"' + data + '";';
+					break;
+					
+				case 'number':
+					str_data = 'i:' + data + ';';
+					break;
+	
+				case 'boolean':
+					str_data = 'b:' + (data ? '1' : '0') + ';';
+					break;
+	
+				default:
+					showMessage(Element('cc_msg_err_serialize_data_unknown').value);
+					return null;
+			}
+	
+			return str_data;
+		};
+	
+		var sdata = f(data);
+		return sdata;
+	};
+	cConnector.prototype.matchBracket = function(strG, iniPosG)
+	{
+		_thisObject = this;
+		var f = function (str, iniPos)
+		{
+			var nOpen, nClose = iniPos;
+		
+			do 
+			{
+				nOpen = str.indexOf('{', nClose+1);
+				nClose = str.indexOf('}', nClose+1);
+
+				if (nOpen == -1)
+				{
+					return nClose;
+				}
+			
+				if (nOpen < nClose )
+				{
+					nClose = _thisObject.matchBracket(str, nOpen);
+				}
+			
+			} while (nOpen < nClose);
+
+			return nClose;
+		};
+
+		return f(strG, iniPosG);
+	};
+	
+		
+	//Unserialize Data Method
+	cConnector.prototype.unserialize = function(str)
+	{
+		
+		_thisObject = this;
+		
+		var f = function (str)
+		{
+			switch (str.charAt(0))
+			{
+				case 'a':
+					
+					var data = new Array();
+					var n = parseInt( str.substring( str.indexOf(':')+1, str.indexOf(':',2) ) );
+					var arrayContent = str.substring(str.indexOf('{')+1, str.lastIndexOf('}'));
+				
+					for (var i = 0; i < n; i++)
+					{
+						var pos = 0;
+	
+						/* Process Index */
+						var indexStr = arrayContent.substr(pos, arrayContent.indexOf(';')+1);
+						var index = _thisObject.unserialize(indexStr);
+						pos = arrayContent.indexOf(';', pos)+1;
+						
+						/* Process Content */
+						var part = null;
+						switch (arrayContent.charAt(pos))
+						{
+							case 'a':
+								var pos_ = _thisObject.matchBracket(arrayContent, arrayContent.indexOf('{', pos))+1;
+								part = arrayContent.substring(pos, pos_);
+								pos = pos_;
+								data[index] = _thisObject.unserialize(part);
+								break;
+						
+							case 's':
+								var pval = arrayContent.indexOf(':', pos+2);
+								var val  = parseInt(arrayContent.substring(pos+2, pval));
+								pos = pval + val + 4;
+								data[index] = arrayContent.substr(pval+2, val);
+								break;
+	
+							default:
+								part = arrayContent.substring(pos, arrayContent.indexOf(';', pos)+1);
+								pos = arrayContent.indexOf(';', pos)+1;
+								data[index] = _thisObject.unserialize(part);
+								break;
+						}
+						arrayContent = arrayContent.substr(pos);
+					}
+					break;
+					
+				case 's':
+					var pos = str.indexOf(':', 2);
+					var val = parseInt(str.substring(2,pos));
+					var data = str.substr(pos+2, val);
+					str = str.substr(pos + 4 + val);
+					break;
+	
+				case 'i':
+				;
+				case 'd':
+					var pos = str.indexOf(';');
+					var data = parseInt(str.substring(2,pos));
+					str = str.substr(pos + 1);
+					break;
+				
+				case 'N':
+					var data = null;
+					str = str.substr(str.indexOf(';') + 1);
+					break;
+	
+				case 'b':
+					var data = str.charAt(2) == '1' ? true : false;
+					break;
+			}
+			
+			return data;
+		};
+	
+		return f(str);
+	};
+
+	//Create XMLHTTP object Method
+	cConnector.prototype.createXMLHTTP = function ()
+	{	
+		try
+		{ 
+			this.oxmlhttp = new XMLHttpRequest();
+			this.oxmlhttp.overrideMimeType('text/xml');
+		}
+		catch (e)
+		{ 
+			try
+			{
+				this.oxmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
+			}
+			catch (e1)
+			{ 
+				try
+				{
+					this.oxmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
+				}
+				catch (e2)
+				{
+					this.oxmlhttp = null;
+				}
+			}
+		}
+	
+	};
+	
+	// Request Constructor Connector	
+	cConnector.prototype.newRequest = function (id, target, method, handler, data)
+	{				
+		
+		if (this.requests[id]) {
+			return false;
+		}
+	
+		this.createXMLHTTP();
+		var oxmlhttp = this.oxmlhttp;
+		var _thisObject = this;		
+		
+		if (! oxmlhttp)		
+			return false;
+				
+		this.requests[id] = oxmlhttp;
+		this.buildBar();		
+		this.showProgressBar();
+		
+		var sub_handler = function ()
+		{			
+			var progressBar = _thisObject.progressBar;
+			
+			try
+			{
+				if (oxmlhttp.readyState == 4 )
+				{
+					
+					switch (oxmlhttp.status)
+					{
+						
+						case 200:
+							if (typeof(handler) == 'function')
+							{																
+								_thisObject.hideProgressBar();																
+								var data = _thisObject.unserialize(oxmlhttp.responseText);
+								if(debug_controller) {
+									document.getElementById("debug_controller").innerHTML += oxmlhttp.responseText;
+									document.getElementById("debug_controller").innerHTML += "<br>-------------------------------------------------------------------------------------<br>";
+								}									
+								handler(data, oxmlhttp);
+								delete _thisObject.requests[id];								
+								_thisObject.requests[id] = null;
+							}
+
+							break;
+
+						case 404:
+							
+							alert('Page Not Found!');
+							break;
+
+						default:												
+					}
+				}
+			}
+			catch (e)
+			{			
+				_thisObject.hideProgressBar();
+				if(debug_controller)
+					alert(e+"\n"+oxmlhttp.responseText);
+			}
+						
+		};
+
+		try
+		{ 
+			
+			if (method == '' || method == 'GET')
+			{								
+				oxmlhttp.open("GET",target,true);
+				if (typeof(handler) == 'function')
+				{	
+					oxmlhttp.onreadystatechange =  sub_handler;					
+					oxmlhttp.send(null);					
+				}		
+				
+			}
+			else if (method == 'POST')
+			{
+				oxmlhttp.open("POST",target, true);
+				oxmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
+				if (typeof(handler) == 'function')
+				{
+					oxmlhttp.onreadystatechange = sub_handler;
+					oxmlhttp.send(data);
+				}				
+				
+			}
+		}
+		catch(e)
+		{	
+			_thisObject.hideProgressBar();
+			if(debug_controller)
+				alert(e);		 
+		}
+						
+		return true;
+	};
+	// Cancel Request Connector
+	cConnector.prototype.cancelRequest = function (id)
+	{
+		if (!this.requests[id])
+		{
+			return false;
+		}
+
+		this.requests[id].abort();
+	};
+//------------------------------------  END: Functions for Connector HTTPRequest  -------------------------------------------------//
+
+//	----------------------------------- BEGIN: Functions for build Bar Progress ---------------------------------------------------------//
+	cConnector.prototype.hideProgressBar = function ()
+	{
+		div = document.getElementById('divProgressBar');
+		div.style.visibility = 'hidden';
+	
+		if(is_ie) {
+			divB = document.getElementById('divBlank');	
+			divB.style.visibility = 'hidden';
+		}
+		this.isVisibleBar = false;
+	};
+	
+	cConnector.prototype.showProgressBar = function(){
+		div.style.visibility = 'visible';			
+
+		this.isVisibleBar = true;
+	};
+//------------------------------------  END: Functions for Progress Bar  -------------------------------------------------//
+
+
+
+	// Default Controller File
+	var DEFAULT_URL = _web_server_url + '/workflow/controller.php?action=';
+	// connector object
+	var connector = new cConnector();
+	var isExecuteForm = false;
+	var id = null;
+
+	// 	Function executes AJAX
+	// 	cExecute (url, handler, params)
+	//	url: 'module.class.method'
+	//  handle: function handle() receive response.
+	//  params: parameters for POST method
+	//	form: form element (for upload files)	
+	function cExecute(url, handler, params, form) {
+		isExecuteForm = false;
+		if(form) {
+			cExecuteForm(url, form);
+			return;
+		}
+		
+		url = DEFAULT_URL + url;
+			
+		if(params)		 
+			method = "POST";
+			 	
+		 else 
+			method = "GET";
+			 
+		 id = url;
+		connector.newRequest(id, url, method, handler, params);
+	}
+
+	/*
+		Esta função pode ser utilizada para executar um submit de uma form de forma
+		transparente para o usuário, de forma que o retorno do submit seja tratado pelo
+		handler ajax
+	*/ 	
+	function cExecuteFormData(url, form, handler){
+        connector.buildBar();
+        isExecuteForm = true;
+        connector.showProgressBar();
+        if(! (divUpload = document.getElementById('divUpload'))) {
+            divUpload       = document.createElement('DIV');
+            divUpload.id    = 'divUpload';
+            document.body.appendChild(divUpload);
+        }
+
+		if(! (el = document.getElementById('_form_data'))) {			
+			el			= document.createElement('input');
+			el.type	= 'hidden';
+			el.id		= '_form_data';	
+			el.name	= '_form_data';
+			form.appendChild(el);
+		}
+
+        form._form_data.value = url;
+		divUpload.innerHTML= "<iframe onload=\"cExecute('$this.ajax.getLastAjaxResponse',"+handler+");\"  style='display:"+(debug_controller ? "" : "none")+";width:"+(debug_controller ? 400 : 0)+";height:"+(debug_controller ? 400 : 0)+";' name='ifrmAjax'></iframe>";
+        form.action =_web_server_url + '/workflow/controller.php';
+		form.target = 'ifrmAjax';
+        form.submit();
+	}
+
+	
+	// This function executes submit values to Controller (POST)
+	// The return is void.
+	// 	cExecuteForm (url, form)
+	//	url: 'module.class.method'
+	//	form: form element (for upload files)	
+	function cExecuteForm(url, form, handler){
+		connector.buildBar();
+		isExecuteForm = true;
+		connector.showProgressBar();
+		if(! (divUpload = document.getElementById('divUpload'))) {
+			divUpload		= document.createElement('DIV');		
+			divUpload.id	= 'divUpload';
+			document.body.appendChild(divUpload);
+		}
+
+		if(! (el = document.getElementById('_action'))) {			
+			el			= document.createElement('input');
+			el.type	= 'hidden';
+			el.id		= '_action';	
+			el.name	= '_action';
+			form.appendChild(el);
+		}
+
+		if(countFiles) {			
+			el			= document.createElement('input');
+			el.type	= 'hidden';	
+			el.name	= 'countFiles';
+			el.value 	= countFiles;
+			form.appendChild(el);						
+		}		
+
+		form._action.value = url;
+		divUpload.innerHTML= "<iframe onload=\"cExecute('$this.functions.getReturnExecuteForm',"+handler+");\"  style='display:"+(debug_controller ? "" : "none")+";width:"+(debug_controller ? 400 : 0)+";height:"+(debug_controller ? 400 : 0)+";' name='uploadFile'></iframe>";
+		form.action ="controller.php";
+		form.target ="uploadFile";		
+		form.submit();
+	}	
+	
+	
+	document.onmousedown=alertBut;
+
+	function alertBut( e, evElement ) {
+    	if( !e ) {
+        	if( window.event ) {
+            	//DOM
+	            e = window.event;
+    	    } else {
+        	    //TOTAL FAILURE, WE HAVE NO WAY OF REFERENCING THE EVENT
+            	return;
+	        }
+    	}
+	    if( typeof( e.which ) == 'number' ) {
+	        //Netscape compatible
+	        e = e.which;
+	    } else {
+	        if( typeof( e.button ) == 'number' ) {
+	            //DOM
+	            e = e.button;
+	   		} 
+	   		else {
+	            //TOTAL FAILURE, WE HAVE NO WAY OF OBTAINING THE BUTTON
+	        	return;
+	        }
+	    }
+	    if( !evElement ) { evElement = this; }
+	
+		if(isExecuteForm) {
+	    	if(confirm("Existe uma ação que ainda está sendo processada. Suspender ação?")) {
+		    	connector.hideProgressBar();
+		    	isExecuteForm = false;
+		    	delete connector.requests[id];								
+				connector.requests[id] = null;
+	    		stop();		    		    		
+	    		return;
+	    	}
+    		else
+    			return false;
+	    }
+	    
+	    
+	}
Index: /sandbox/workflow/branches/993/js/jscode/tigra_menu.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/tigra_menu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/tigra_menu.js	(revision 795)
@@ -0,0 +1,374 @@
+// Title: tigra menu
+// Description: See the demo at url
+// URL: http://www.softcomplex.com/products/tigra_menu/
+// Version: 2.0 (commented source)
+// Date: 04-05-2003 (mm-dd-yyyy)
+// Tech. Support: http://www.softcomplex.com/forum/forumdisplay.php?fid=40
+// Notes: This script is free. Visit official site for further details.
+
+// --------------------------------------------------------------------------------
+// global collection containing all menus on current page
+var A_MENUS = [];
+
+// --------------------------------------------------------------------------------
+// menu class
+function menu (a_items, a_tpl, a_div) {
+	this.menuOutput = '';
+	// browser check
+	if (!document.body || !document.body.style)
+		return;
+
+	// store items structure
+	this.a_config = a_items;
+
+	// store template structure
+	this.a_tpl = a_tpl;
+
+	this.divAppend = a_div;
+
+	// get menu id
+	this.n_id = A_MENUS.length;
+
+	// declare collections
+	this.a_index = [];
+	this.a_children = [];
+
+	// assigh methods and event handlers
+	this.expand      = menu_expand;
+	this.collapse    = menu_collapse;
+
+	this.onclick     = menu_onclick;
+	this.onmouseout  = menu_onmouseout;
+	this.onmouseover = menu_onmouseover;
+	this.onmousedown = menu_onmousedown;
+
+	// default level scope description structure 
+	this.a_tpl_def = {
+		'block_top'  : 16,
+		'block_left' : 16,
+		'top'        : 20,
+		'left'       : 4,
+		'width'      : 120,
+		'auto-width' : false,
+		'height'     : 22,
+		'hide_delay' : 0,
+		'expd_delay' : 0,
+		'css'        : {
+			'inner' : '',
+			'outer' : ''
+		}
+	};
+	
+	// assign methods and properties required to imulate parent item
+	this.getprop = function (s_key) {
+		return this.a_tpl_def[s_key];
+	};
+
+	this.o_root = this;
+	this.n_depth = -1;
+	this.n_x = 0;
+	this.n_y = 0;
+
+	// 	init items recursively
+	for (n_order = 0; n_order < a_items.length; n_order++)
+		new menu_item(this, n_order);
+	
+	redoReference(this);
+
+	// register self in global collection
+	A_MENUS[this.n_id] = this;
+
+	// make root level visible
+	for (var n_order = 0; n_order < this.a_children.length; n_order++)
+	{
+		this.a_children[n_order].e_oelement.style.visibility = 'visible';
+	}
+
+	if (this.a_children.length > 0)
+	{
+		var autoWidth = this.a_children[0].getprop('auto-width');
+		if (autoWidth)
+		{
+			function recursiveWidth(children)
+			{
+				var max = 10;
+				for (var i = 0; i < children.length; i++)
+				{
+					if (children[i]['a_config'][0].length > max)
+						max = children[i]['a_config'][0].length;
+				}
+
+				for (var i = 0; i < children.length; i++)
+				{
+					document.getElementById(children[i].e_oelement.id).style.width = max/1.34 + 'em';
+					if (children[i].a_children)
+						recursiveWidth(children[i].a_children);
+				}
+			}
+
+			recursiveWidth(this.a_children);
+		}
+	}
+}
+
+function redoReference(ref)
+{
+	for (var i = 0; i < ref.a_index.length; i++)
+	{
+		ref.a_index[i].e_oelement = document.getElementById(ref.a_index[i].e_oelement.id);
+		ref.a_index[i].e_ielement = document.getElementById(ref.a_index[i].e_ielement.id);
+	}
+//		ref.a_children[i].e_oelement = document.getElementById(ref.a_children[i].e_oelement.id);
+}
+
+// --------------------------------------------------------------------------------
+function menu_collapse (n_id) {
+	if ((n_id == undefined) && this.divAppend)
+		this.divAppend.style.display = 'none';
+
+	// cancel item open delay
+	clearTimeout(this.o_showtimer);
+
+	// by default collapse to root level
+	var n_tolevel = (n_id ? this.a_index[n_id].n_depth : 0);
+	
+	// hide all items over the level specified
+	for (n_id = 0; n_id < this.a_index.length; n_id++) {
+		var o_curritem = this.a_index[n_id];
+		if (o_curritem.n_depth > n_tolevel && o_curritem.b_visible) {
+			o_curritem.e_oelement.style.visibility = 'hidden';
+			o_curritem.b_visible = false;
+		}
+	}
+
+	// reset current item if mouse has gone out of items
+	if (!n_id)
+		this.o_current = null;
+}
+
+// --------------------------------------------------------------------------------
+function menu_expand (n_id) {
+
+	// expand only when mouse is over some menu item
+	if (this.o_hidetimer)
+		return;
+
+	// lookup current item
+	var o_item = this.a_index[n_id];
+
+	// close previously opened items
+	if (this.o_current && this.o_current.n_depth >= o_item.n_depth)
+		this.collapse(o_item.n_id);
+	this.o_current = o_item;
+
+	// exit if there are no children to open
+	if (!o_item.a_children)
+		return;
+
+	// show direct child items
+	for (var n_order = 0; n_order < o_item.a_children.length; n_order++) {
+		var o_curritem = o_item.a_children[n_order];
+		o_curritem.e_oelement.style.visibility = 'visible';
+		o_curritem.b_visible = true;
+	}
+}
+
+// --------------------------------------------------------------------------------
+//
+// --------------------------------------------------------------------------------
+function menu_onclick (n_id) {
+	// don't go anywhere if item has no link defined
+	return Boolean(this.a_index[n_id].a_config[1]);
+}
+
+// --------------------------------------------------------------------------------
+function menu_onmouseout (n_id) {
+
+	// lookup new item's object	
+	var o_item = this.a_index[n_id];
+
+	// apply rollout
+	o_item.e_oelement.className = o_item.getstyle(0, 0);
+	o_item.e_ielement.className = o_item.getstyle(1, 0);
+	
+	// update status line	
+	o_item.upstatus(7);
+
+	// run mouseover timer
+	this.o_hidetimer = setTimeout('A_MENUS['+ this.n_id +'].collapse();',
+		o_item.getprop('hide_delay'));
+}
+
+// --------------------------------------------------------------------------------
+function menu_onmouseover (n_id) {
+
+	// cancel mouseoute menu close and item open delay
+	clearTimeout(this.o_hidetimer);
+	this.o_hidetimer = null;
+	clearTimeout(this.o_showtimer);
+
+	// lookup new item's object	
+	var o_item = this.a_index[n_id];
+
+	// update status line	
+	o_item.upstatus();
+
+	// apply rollover
+	o_item.e_oelement.className = o_item.getstyle(0, 1);
+	o_item.e_ielement.className = o_item.getstyle(1, 1);
+	
+	// if onclick open is set then no more actions required
+	if (o_item.getprop('expd_delay') < 0)
+		return;
+
+	// run expand timer
+	this.o_showtimer = setTimeout('A_MENUS['+ this.n_id +'].expand(' + n_id + ');',
+		o_item.getprop('expd_delay'));
+
+}
+
+// --------------------------------------------------------------------------------
+// called when mouse button is pressed on menu item
+// --------------------------------------------------------------------------------
+function menu_onmousedown (n_id) {
+	
+	// lookup new item's object	
+	var o_item = this.a_index[n_id];
+
+	// apply mouse down style
+	o_item.e_oelement.className = o_item.getstyle(0, 2);
+	o_item.e_ielement.className = o_item.getstyle(1, 2);
+
+	this.expand(n_id);
+//	this.items[id].switch_style('onmousedown');
+}
+
+
+// --------------------------------------------------------------------------------
+// menu item Class
+function menu_item (o_parent, n_order) {
+
+	// store parameters passed to the constructor
+	this.n_depth  = o_parent.n_depth + 1;
+	this.a_config = o_parent.a_config[n_order + (this.n_depth ? 3 : 0)];
+
+	// return if required parameters are missing
+	if (!this.a_config) return;
+
+	// store info from parent item
+	this.o_root    = o_parent.o_root;
+	this.o_parent  = o_parent;
+	this.n_order   = n_order;
+	this.divAppend = o_parent.divAppend;
+
+	// register in global and parent's collections
+	this.n_id = this.o_root.a_index.length;
+	this.o_root.a_index[this.n_id] = this;
+	o_parent.a_children[n_order] = this;
+
+	// calculate item's coordinates
+	var o_root = this.o_root,
+		a_tpl  = this.o_root.a_tpl;
+
+	// assign methods
+	this.getprop  = mitem_getprop;
+	this.getstyle = mitem_getstyle;
+	this.upstatus = mitem_upstatus;
+
+	this.n_x = n_order
+		? o_parent.a_children[n_order - 1].n_x + this.getprop('left')
+		: o_parent.n_x + this.getprop('block_left');
+
+	this.n_y = n_order
+		? o_parent.a_children[n_order - 1].n_y + this.getprop('top')
+		: o_parent.n_y + this.getprop('block_top');
+
+	// generate item's HMTL
+	var menuText =
+		'<a id="e' + o_root.n_id + '_'
+			+ this.n_id +'o" class="' + this.getstyle(0, 0) + '" href="' + this.a_config[1] + '"'
+			+ (this.a_config[2] && this.a_config[2]['tw'] ? ' target="'
+			+ this.a_config[2]['tw'] + '"' : '') + ' style="position: absolute; top: '
+			+ this.n_y + 'px; left: ' + this.n_x + 'px; width: '
+			+ this.getprop('width') + 'px; height: '
+			+ this.getprop('height') + 'px; visibility: hidden;'
+			+' z-index: ' + this.n_depth + ';" '
+			+ 'onclick="return A_MENUS[' + o_root.n_id + '].onclick('
+			+ this.n_id + ');" onmouseout="A_MENUS[' + o_root.n_id + '].onmouseout('
+			+ this.n_id + ');" onmouseover="A_MENUS[' + o_root.n_id + '].onmouseover('
+			+ this.n_id + ');" onmousedown="A_MENUS[' + o_root.n_id + '].onmousedown('
+			+ this.n_id + ');"><div  id="e' + o_root.n_id + '_'
+			+ this.n_id +'i" class="' + this.getstyle(1, 0) + '">'
+			+ this.a_config[0] + "</div></a>\n"; 
+		;
+	if (this.divAppend)
+		this.divAppend.innerHTML += menuText;
+	else
+		document.write(menuText);
+	
+	this.e_ielement = document.getElementById('e' + o_root.n_id + '_' + this.n_id + 'i');
+	this.e_oelement = document.getElementById('e' + o_root.n_id + '_' + this.n_id + 'o');
+
+	this.b_visible = !this.n_depth;
+
+	// no more initialization if leaf
+	if (this.a_config.length < 4)
+		return;
+
+	// node specific methods and properties
+	this.a_children = [];
+
+	// init downline recursively
+	for (var n_order = 0; n_order < this.a_config.length - 3; n_order++)
+		new menu_item(this, n_order);
+}
+
+// --------------------------------------------------------------------------------
+// reads property from template file, inherits from parent level if not found
+// ------------------------------------------------------------------------------------------
+function mitem_getprop (s_key) {
+
+	// check if value is defined for current level
+	var s_value = null,
+		a_level = this.o_root.a_tpl[this.n_depth];
+
+	// return value if explicitly defined
+	if (a_level)
+		s_value = a_level[s_key];
+
+	// request recursively from parent levels if not defined
+	return (s_value == null ? this.o_parent.getprop(s_key) : s_value);
+}
+// --------------------------------------------------------------------------------
+// reads property from template file, inherits from parent level if not found
+// ------------------------------------------------------------------------------------------
+function mitem_getstyle (n_pos, n_state) {
+
+	var a_css = this.getprop('css');
+	var a_oclass = a_css[n_pos ? 'inner' : 'outer'];
+
+	// same class for all states	
+	if (typeof(a_oclass) == 'string')
+		return a_oclass;
+
+	// inherit class from previous state if not explicitly defined
+	for (var n_currst = n_state; n_currst >= 0; n_currst--)
+		if (a_oclass[n_currst])
+			return a_oclass[n_currst];
+}
+
+// ------------------------------------------------------------------------------------------
+// updates status bar message of the browser
+// ------------------------------------------------------------------------------------------
+function mitem_upstatus (b_clear) {
+	window.setTimeout("window.status=unescape('" + (b_clear
+		? ''
+		: (this.a_config[2] && this.a_config[2]['sb']
+			? escape(this.a_config[2]['sb'])
+			: escape(this.a_config[0]) + (this.a_config[1]
+				? ' ('+ escape(this.a_config[1]) + ')'
+				: ''))) + "')", 10);
+}
+
+// --------------------------------------------------------------------------------
+// that's all folks
Index: /sandbox/workflow/branches/993/js/jscode/rtf.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/rtf.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/rtf.js	(revision 795)
@@ -0,0 +1,68 @@
+// Esse arquivo serve para customizar o editor RTF existente na API do eGroupWare.
+// Foram escondidos alguns botões e também foi traduzido para o português - BR algumas palavras que faltavam.
+// Autor: Nilton E. Buhrer Neto
+// Modificado para uso no workflow
+
+_editor_url = "workflow/js/htmlarea";
+_editor_lang = "pt_br";
+
+document.write('<script');
+document.write(' language="javascript"');
+document.write(' type="text/javascript"');
+document.write(' src="' + _editor_url + '/htmlarea.js">');
+document.write('</script>');
+
+document.write('<script');
+document.write(' language="javascript"');
+document.write(' type="text/javascript"');
+document.write(' src="' + _editor_url + '/plugins/CharacterMap/character-map.js">');
+document.write('</script>');
+
+document.write('<script');
+document.write(' language="javascript"');
+document.write(' type="text/javascript"');
+document.write(' src="' + _editor_url + '/plugins/CharacterMap/lang/en.js">');
+document.write('</script>');
+
+function initDocument(fieldName)
+{
+	if (typeof(this.editor) == "undefined")
+		this.editor = new Array();
+	if (!fieldName)
+		fieldName = "body_rtf";
+
+	var numberOfEditors = this.editor.length;
+
+	this.editor[numberOfEditors] = new HTMLArea(fieldName);
+	this.editor[numberOfEditors].config.formatblock = {
+		"Título 1": "h1",
+		"Título 2": "h2",
+		"Título 3": "h3",
+		"Título 4": "h4",
+		"Título 5": "h5",
+		"Título 6": "h6",
+		"Normal": "p",
+		"Endereço": "address",
+		"Pré-formatado": "pre"
+	};
+
+	this.editor[numberOfEditors].config.hideSomeButtons(" insertimage about cut copy paste htmlmode popupeditor showhelp ");
+
+	this.editor[numberOfEditors].config.height="600";
+	if(screen.width >= 1024)
+		this.editor[numberOfEditors].config.width="713";
+	else
+		this.editor[numberOfEditors].config.width="642";
+
+	this.editor[numberOfEditors].config.statusBar = false;
+	this.editor[numberOfEditors].registerPlugin("CharacterMap");
+
+	this.editor[numberOfEditors].generate();
+}
+
+function endDocument()
+{
+	editor = (this.editor) ? this.editor : parent.editor;
+	for (var i = 0; i < editor.length; i++)
+		editor[i]._textArea.value = editor[i].getInnerHTML();
+}
Index: /sandbox/workflow/branches/993/js/jscode/sha1.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/sha1.js	(revision 1428)
+++ /sandbox/workflow/branches/993/js/jscode/sha1.js	(revision 1428)
@@ -0,0 +1,334 @@
+/*
+ * The JavaScript implementation of the Secure Hash Algorithm 1
+ *
+ *   Copyright (c) 2008  Takanori Ishikawa  <takanori.ishikawa@gmail.com>
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ *   3. Neither the name of the authors nor the names of its contributors
+ *      may be used to endorse or promote products derived from this
+ *      software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * This is the javascript file for code which implements
+ * the Secure Hash Algorithm 1 as defined in FIPS 180-1 published April 17, 1995.
+ *
+ *   Author: Takanori Ishikawa <takanori.ishikawa@gmail.com>
+ *   Copyright: Takanori Ishikawa 2008
+ *   License: BSD License (see above)
+ *
+ * NOTE:
+ *   Only 8-bit string is supported, please use encodeURIComponent() function 
+ *   if you want to hash multibyte string.
+ *
+ * Supported Browsers:
+ *   [Win] IE 6, Firefox 2
+ *   [Mac] Safari 3, Firefox 2
+ *
+ * Usage:
+ *   var hexdigest = new SHA1("Hello.").hexdigest(); // "9b56d519ccd9e1e5b2a725e186184cdc68de0731"
+ *
+ * See Also:
+ *   FIPS 180-1 - Secure Hash Standard
+ *   http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ *
+ */
+
+var SHA1 = (function(){
+
+  /**
+   * Spec is the BDD style test utilities.
+   */
+  var Spec = {
+    /** Replace the Spec.describe function with empty function if false. */
+    enabled: true,
+    
+    /** Indicates whether object 'a' is "equal to" 'b'. */
+    equals: function(a, b) {
+      if (a instanceof Array && b instanceof Array) {
+        if (a.length != b.length) return false;
+        for (var i = 0; i < a.length; i++) if (!Spec.equals(a[i], b[i])) return false;
+        return true;
+      }
+      if ((a != null && b != null) && (typeof a == "object" && typeof b == "object")) {
+        for (var i in a) if (!Spec.equals(a[i], b[i])) return false;
+        return true;
+      }
+      return (a == b);
+    },
+    
+    /** equivalent to xUint's assert */
+    should: function(expection, message) {
+      Spec.currentIndicator++;
+      if (!expection) {
+        var warning = [
+          "[Spec failed",
+          Spec.currentTitle ? " (" + Spec.currentTitle + ")] " : "] ",
+          (message || (Spec.currentMessage + " " + Spec.currentIndicator) || "")
+        ].join("");
+        
+        alert(warning);
+        throw warning;
+      }
+      return !!expection;
+    },
+    
+    /** Write your specification by using describe method. */
+    describe: function(title, spec) {
+      Spec.currentTitle = title;
+      for (var name in spec) {
+        Spec.currentMessage = name;
+        Spec.currentIndicator = 0;
+        spec[name]();
+        Spec.currentIndicator = null;
+      }
+      Spec.currentMessage = Spec.currentTitle = null;
+    },
+    Version: "0.1"
+  };
+  
+  // Other BDD style stuffs.
+  Spec.should.equal = function(a, b, message) { return Spec.should(Spec.equals(a, b), message); };
+  Spec.should.not = function(a, message) { return Spec.should(!a, message); };
+  Spec.should.not.equal = function(a, b, message) { return Spec.should(!Spec.equals(a, b), message); };
+  if (!Spec.enabled) Spec.describe = function(){};
+  
+  
+  // self test
+  Spec.describe("Spec object", {
+    "should": function() {
+      Spec.should(true);
+      Spec.should(1);
+    }, 
+    "should.not": function() {
+      Spec.should.not(false);
+      Spec.should.not(0);
+    },
+    "should.equal": function() {
+      Spec.should.equal(null, null);
+      Spec.should.equal("", "");
+      Spec.should.equal(12345, 12345);
+      Spec.should.equal([0,1,2], [0,1,2]);
+      Spec.should.equal([0,1,[0,1,2]], [0,1,[0,1,2]]);
+      Spec.should.equal({}, {});
+      Spec.should.equal({x:1}, {x:1});
+      Spec.should.equal({x:[1]}, {x:[1]});
+    },
+    "should.not.equal": function() {
+      Spec.should.not.equal([1,2,3], [1,2,3,4]);
+      Spec.should.not.equal({x:1}, [1,2,3,4]);
+    }
+  });
+
+
+  // -----------------------------------------------------------
+  // Utilities
+  // -----------------------------------------------------------
+  // int32 -> hexdigits string (e.g. 0x123 -> '00000123')
+  function strfhex32(i32) {
+    i32 &= 0xffffffff;
+    if (i32 < 0) i32 += 0x100000000;
+    var hex = Number(i32).toString(16);
+    if (hex.length < 8) hex = "00000000".substr(0, 8 - hex.length) + hex;
+    return hex;
+  }
+  Spec.describe("sha1", {
+    "strfhex32": function() {
+      Spec.should.equal(strfhex32(0x0),          "00000000");
+      Spec.should.equal(strfhex32(0x123),        "00000123");
+      Spec.should.equal(strfhex32(0xffffffff),   "ffffffff");
+    }
+  });
+
+  // int32 -> string (e.g. 123 -> '00000000 00000000 00000000 01111011')
+  function strfbits(i32) {
+    if (typeof arguments.callee.ZERO32 == 'undefined') {
+      arguments.callee.ZERO32 = new Array(33).join("0");
+    }
+    
+    var bits = Number(i32).toString(2);
+    // '0' padding 
+    if (bits.length < 32) bits = arguments.callee.ZERO32.substr(0, 32 - bits.length) + bits;
+    // split by 8 bits
+    return bits.replace(/(\d{8})/g, '$1 ')
+               .replace(/^\s*(.*?)\s*$/, '$1');
+  }
+  Spec.describe("sha1", {
+    "strfbits": function() {
+      Spec.should.equal(strfbits(0),   "00000000 00000000 00000000 00000000");
+      Spec.should.equal(strfbits(1),   "00000000 00000000 00000000 00000001");
+      Spec.should.equal(strfbits(123), "00000000 00000000 00000000 01111011");
+    }
+  });
+
+
+  // -----------------------------------------------------------
+  // SHA-1
+  // -----------------------------------------------------------
+  // Returns Number(32bit unsigned integer) array size to fit for blocks (512-bit strings)
+  function padding_size(nbits) {
+    var n = nbits + 1 + 64
+    return 512 * Math.ceil(n / 512) / 32;
+  }
+  Spec.describe("sha1", {
+    "padding_size": function() {
+      Spec.should.equal(padding_size(0),             16);
+      Spec.should.equal(padding_size(1),             16);
+      Spec.should.equal(padding_size(512 - 64 - 1),  16);
+      Spec.should.equal(padding_size(512 - 64),      32);
+    }
+  });
+
+  // 8bit string -> uint32[]
+  function word_array(m) {
+    var nchar = m.length;
+    var size = padding_size(nchar * 8);
+    var words = new Array(size);
+    for (var i = 0, j = 0; i < nchar; ) {
+      words[j++] = ((m.charCodeAt(i++) & 0xff) << 24) | 
+                   ((m.charCodeAt(i++) & 0xff) << 16) | 
+                   ((m.charCodeAt(i++) & 0xff) << 8)  | 
+                   ((m.charCodeAt(i++) & 0xff))
+    }
+    while (j < size) words[j++] = 0;
+    return words;
+  }
+  Spec.describe("sha1", {
+    "word_array": function() {
+      Spec.should.equal(word_array(""), [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+      Spec.should.equal(word_array("1234")[0], 0x31323334);
+    }
+  });
+
+  function write_nbits(words, length, nbits) {
+    if (nbits > 0xffffffff) {
+      var lo = nbits & 0xffffffff;
+      if (lo < 0) lo += 0x100000000;
+      words[length - 1] = lo;
+      words[length - 2] = (nbits - lo) / 0x100000000;
+    } else {
+      words[length - 1] = nbits;
+      words[length - 2] = 0x0;
+    }
+    return words;
+  }
+  Spec.describe("sha1", {
+    "write_nbits": function() {
+      Spec.should.equal(write_nbits([0, 0], 2, 1),             [0, 1]);
+      Spec.should.equal(write_nbits([0, 0], 2, 0xffffffff),    [0, 0xffffffff]);
+      Spec.should.equal(write_nbits([0, 0], 2, 0x100000000),   [1, 0]);
+      Spec.should.equal(write_nbits([0, 0], 2, 0x1ffffffff),   [1, 0xffffffff]);
+      Spec.should.equal(write_nbits([0, 0], 2, 0x12300000000), [0x123, 0]);
+      Spec.should.equal(write_nbits([0, 0], 2, 0x123abcdef12), [0x123, 0xabcdef12]);
+    }
+  });
+
+  function padding(words, nbits) {
+    var i = Math.floor(nbits / 32);
+    
+    words[i] |= (1 << (((i + 1) * 32) - nbits - 1));
+    write_nbits(words, padding_size(nbits), nbits);
+    return words;
+  }
+
+  function digest(words) {
+    var i = 0, t = 0;
+    var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
+    
+    while (i < words.length) {
+      var W = new Array(80);
+      
+      // (a)
+      for (t = 0;  t < 16; t++) W[t] = words[i++];
+      
+      // (b)
+      for (t = 16; t < 80; t++) {
+        var w = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+        W[t] = (w << 1) | (w >>> 31);
+      }
+      
+      // (c)
+      var A = H[0], B = H[1], C = H[2], D = H[3], E = H[4];
+      
+      // (d) TEMP = S5(A) + ft(B,C,D) + E + Wt + Kt;
+      //     E = D; D = C; C = S30(B); B = A; A = TEMP;
+      for (t = 0; t < 80; t++) {
+        var tmp = ((A << 5) | (A >>> 27)) + E + W[t];
+        
+        if      (t >=  0 && t <= 19) tmp += ((B & C) | ((~B) & D))        + 0x5a827999;
+        else if (t >= 20 && t <= 39) tmp += (B ^ C ^ D)                   + 0x6ed9eba1;
+        else if (t >= 40 && t <= 59) tmp += ((B & C) | (B & D) | (C & D)) + 0x8f1bbcdc;
+        else if (t >= 60 && t <= 79) tmp += (B ^ C ^ D)                   + 0xca62c1d6;
+        
+        E = D; D = C; C = ((B << 30) | (B >>> 2)); B = A; A = tmp;
+      }
+      
+      // (e) H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.
+      H[0] = (H[0] + A) & 0xffffffff;
+      H[1] = (H[1] + B) & 0xffffffff;
+      H[2] = (H[2] + C) & 0xffffffff;
+      H[3] = (H[3] + D) & 0xffffffff;
+      H[4] = (H[4] + E) & 0xffffffff;
+      if (H[0] < 0) H[0] += 0x100000000;
+      if (H[1] < 0) H[1] += 0x100000000;
+      if (H[2] < 0) H[2] += 0x100000000;
+      if (H[3] < 0) H[3] += 0x100000000;
+      if (H[4] < 0) H[4] += 0x100000000;
+    }
+    
+    return H;
+  }
+
+  // message: 8bit string
+  var SHA1 = function(message) {
+    this.message = message;
+  }
+
+  SHA1.prototype = {
+    digest: function() {
+      var nbits = this.message.length * 8;
+      var words = padding(word_array(this.message), nbits);
+      return digest(words);
+    },
+
+    hexdigest: function() {
+      var digest = this.digest();
+      for (var i = 0; i < digest.length; i++) digest[i] = strfhex32(digest[i]);
+      return digest.join("");
+    }
+  };
+  
+  Spec.describe("sha1", {
+    "SHA1#hexdigest": function() {
+      Spec.should.equal(new SHA1("").hexdigest(),       "da39a3ee5e6b4b0d3255bfef95601890afd80709");
+      Spec.should.equal(new SHA1("1").hexdigest(),      "356a192b7913b04c54574d18c28d46e6395428ab");
+      Spec.should.equal(new SHA1("Hello.").hexdigest(), "9b56d519ccd9e1e5b2a725e186184cdc68de0731");
+      Spec.should.equal(new SHA1("9b56d519ccd9e1e5b2a725e186184cdc68de0731").hexdigest(), "f042dc98a62cbad68dbe21f11bbc1e9d416d2bf6");
+      Spec.should.equal(new SHA1("MD5abZRVSXZVRcasdfasdddddddddddddddds+BNRJFSLKJFN+SEONBBJFJXLKCJFSE)RUNVXDLILKVJRN)#NVFJ)WVFWRW#)NVS$Q=$dddddddddddddWV;no9wurJFSE)RUNVXDLILKVJRN)#NVFJ)WVFWRW#)NVS$Q=$dddddddddddddWV;no9wurJFSE)RUNVXDLILKVJRN)#NVFJ)WVFWRW#)NVS$Q=$dddddddddddddWV;no9wurJFSE)RUNVXDLILKVJRN)#NVFJ)WVFWRW#)NVS$Q=$dddddddddddddWV;no9wuraddddddasdfasdfd").hexdigest(), "662dbf4ebc9cdb4224766e87634e5ba9e6de672b");
+    }
+  });
+  
+  return SHA1;
+})();
Index: /sandbox/workflow/branches/993/js/jscode/wf_select_duplex.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wf_select_duplex.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/wf_select_duplex.js	(revision 795)
@@ -0,0 +1,239 @@
+/*
+* Move the selected items from selectbox "from" to "to",
+* where "from" and "to" are the selectbox names.
+*/
+function moveOptions(from, to) {
+	fromList = eval('document.forms[0].' + from);
+	toList = eval('document.forms[0].' + to);
+	var sel = false;
+
+	// walk through "from" list searching the selected items,
+	// copy them to "to" and remove from "from"
+	for (i = fromList.options.length - 1; i >= 0; i--)
+	{
+		var current = fromList.options[i];
+		if (current.selected)
+		{
+			sel = true;
+			txt = current.text;
+			val = current.value;
+			toList.options[toList.length] = new Option(txt,val);
+			fromList.options[i] = null;
+		}
+	}
+
+	if (!sel)
+		alert ("Selecione um item!");
+
+	// sort selectbox "to"
+	sortOptions(to);
+}
+
+/*
+* Populate selectbox with the array elements
+*/
+function populateSelect(objName, array) {
+	obj = eval('document.forms[0].' + objName);
+	obj.length = 0;
+
+	// walk through array and add elements to the selectbox
+	for (i = 0; i < array.length; i++) {
+		if( isArray(array[i]) ) {
+			obj.options[obj.length] = new Option(array[i].text, array[i].value);
+		}
+	}
+}
+
+/*
+* Populate the selectboxes.
+* @param objNameL Left selectbox name
+* @param arrayL   Array with the elements of the left selectbox
+* @param sortL    Boolean value to sort the left selectbox
+* @param objNameR Right selectbox name
+* @param arrayR   Array with the elements of the right selectbox
+* @param sortR    Boolean value to sort the right selectbox
+* @param execDiff This value indicates the direction of the diff
+*                 Values:  LEFT  - remove the left elements found in the right selectbox
+*                          RIGHT - remove the right elements found in the left selectbox
+*                          NONE  - don't execute diff
+*/
+function populateSelects(objNameL, arrayL, sortL,
+						 objNameR, arrayR, sortR,
+						 execDiff) {
+	if( isArray(arrayL) )
+		populateSelect(objNameL, arrayL);
+
+	if( isArray(arrayR) )
+		populateSelect(objNameR, arrayR);
+
+	if( sortL )
+		sortOptions(objNameL);
+
+	if( sortR )
+		sortOptions(objNameR);
+
+	switch(execDiff) {
+		case "LEFT":
+			selectDiff( objNameR, objNameL );
+			break;
+		case "RIGHT":
+			selectDiff( objNameL, objNameR );
+			break;
+		default:
+			break;
+	}
+}
+
+/*
+* Select all items in a selectbox.
+*/
+function selectAllOptions( objName ) {
+	obj = eval('document.forms[0].' + objName);
+
+	for(i = 0; i < obj.length; i++) {
+		obj.options[i].selected = true;
+	}
+}
+
+/*
+* Check if the parameter is an array.
+* Return true if it's an array, and false, if it's not.
+*/
+function isArray( obj ) {
+	if (typeof obj == 'object') {
+		var criterion = obj.constructor.toString().match(/array/i);
+		return (criterion != null);
+	}
+	return false;
+}
+
+/*
+* Get the values of a selectbox and return them in an array.
+*/
+function select2array(objName) {
+	obj = eval('document.forms[0].' + objName);
+
+	if(obj){
+		array = new Array();
+
+		for(i = 0; i < obj.length; i++) {
+			array[i] = new Array(2);
+			array[i].text  = obj.options[i].text;
+			array[i].value = obj.options[i].value;
+		}
+
+		return array;
+	}
+	return null;
+}
+
+/*
+* Copy the values of an array to a selectbox.
+*/
+function array2select(array, objName)
+{
+	obj = eval('document.forms[0].' + objName);
+
+	/* remove all elements from the selectbox */
+	for (i = obj.length - 1; i >= 0; i--)
+		obj.options[i] = null;
+
+	if (isArray(array))
+		for (i = 0; i < array.length; i++)
+			obj.options[i] = new Option(array[i].text,array[i].value);
+}
+
+/*
+* Redefine the javascript sort function.
+* We need to compare the attributes a.text and b.text.
+*/
+function sortFunction(a, b) {
+	if(a.text > b.text)
+		return 1;
+	if(a.text < b.text)
+		return -1;
+	return 0;
+}
+
+/*
+* Sort the elements of a selectbox.
+*/
+function sortOptions(objName) {
+	arrTexts = select2array(objName);
+	arrTexts.sort(sortFunction);
+	array2select(arrTexts, objName);
+}
+
+/*
+* Remove the accents of a string.
+*/
+function removeAccents( text ){
+	var accents    = "áàãââÁÀÃÂéêÉÊíÍóõôÓÔÕúüÚÜçÇ";
+	var traduction = "aaaaaAAAAeeEEiIoooOOOuuUUcC";
+	var pos, chr;
+	var newTxt = "";
+
+	for (var i = 0; i < text.length; i++){
+		chr = text.charAt(i);
+		pos  = accents.indexOf(chr);
+		if (pos > -1)
+			newTxt += traduction.charAt(pos);
+		else
+			newTxt += text.charAt(i);
+	}
+	return newTxt;
+}
+
+function search(array, key) {
+	for (i = 0; i < array.length; i++){
+		if (key == array[i].text)
+			return i;
+	}
+	return -1;
+
+}
+
+/*
+* Binary search in a SORTED ARRAY.
+* Returns the element position, or -1.
+*/
+function binarySearch(array, key) {
+	var i, lo, hi;
+
+	// get the first and the last positions of the array,
+	lo = 0;
+	hi = array.length - 1;
+
+	while( lo <= hi ) {
+		// get the middle value
+		var mid = Math.floor((lo + hi) / 2);
+
+		// if the key is in the 'mid' position, return 'mid'
+		if( key == array[mid].text )
+			return mid;
+		// if key > 'mid' text,
+		else if( key > array[mid].text)
+			lo = mid + 1;
+		// key < array[mid]
+		else
+			hi = mid - 1;
+	}
+	return -1;
+}
+
+/*
+* Difference between two selectboxes. Remove the elements of the objName2
+* that are found in objName1.
+*/
+function selectDiff(objName1, objName2) {
+	array1 = select2array(objName1);
+
+	obj2 = eval('document.forms[0].' + objName2);
+
+	for( var i = array1.length - 1; i >= 0; i-- ) {
+		array2 = select2array(objName2);
+		j = search(array2, array1[i].text);
+		if( j != -1 )
+			obj2.options[j] = null;
+	}
+}
Index: /sandbox/workflow/branches/993/js/jscode/wf_select_ldap_users.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wf_select_ldap_users.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/wf_select_ldap_users.js	(revision 795)
@@ -0,0 +1,68 @@
+/************************************************************
+ * Métodos utilizados pelo componente wf_select_ldap_users. *
+ ************************************************************/
+
+/* Método que faz a chamada Ajax para buscar os registros
+ * @param String cn Parte do nome a ser procurado no LDAP
+ * @param String target id da combo onde os registros serão inseridos
+ * @param String opt_id Atributo que será atribuído ao id (value) das options da combo, por padrão é o 'dn'
+ * @param String opt_name Atributo que será atribuído ao name (innerHTML) das options da combo, por padrão é o 'cn'
+ */
+function search_ldap_users_by_cn(cn, target, opt_id, opt_name, handleExpiredSessions)
+{
+/* Método que trata o retorno da chamada Ajax. Atribui os valores retornados à combobox */
+	function result_search_ldap_users_by_cn(data)
+	{
+		if (data['error'])
+		{
+			alert(data['error'].replace(/<br \/>/gi, "\n"));
+			if (data['url'])
+				if (handleExpiredSessions)
+					window.location = data['url'].replace(/\.\./gi, ".");
+
+			return;
+		}
+
+		if (data['msg'] != "")
+		{
+			document.getElementById(data["target"] + "_span").hide();
+			document.getElementById(data['target'] + "_img").hide();
+			alert(data['msg']);
+			return false;
+		}
+		else
+		{
+			var container = document.getElementById(data["target"]);
+			container.innerHTML = "";
+			if(data['values'].length > 1){
+				container.disabled = true;
+				fill_combo_employee(data["target"], data["values"]);
+				container.disabled = false;
+				document.getElementById(data["target"] + "_span").show();
+				document.getElementById(data['target'] + "_img").hide();
+				return true;
+			}
+		}
+	}
+
+	var url = '$this.bo_utils.search_ldap_users_by_cn';
+	var param = "cn=" + cn + "&target=" + target + "&id=" + opt_id + "&name=" + opt_name;
+
+	document.getElementById(target + "_img").show();
+
+	cExecute(url, result_search_ldap_users_by_cn, param);
+}
+
+/* Preenche a combo com os registros recuperados na chamada Ajax */
+function fill_combo_employee(target, values)
+{
+	var container = document.getElementById(target);
+
+	for (var i = 0; i < values.length; i++)
+	{
+		var option = document.createElement("option");
+		option.innerHTML = values[i].name;
+		option.value = values[i].id;
+		container.appendChild(option);
+	}
+}
Index: /sandbox/workflow/branches/993/js/jscode/dJSWin.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/dJSWin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/dJSWin.js	(revision 795)
@@ -0,0 +1,483 @@
+  /****************************************************************************\
+   * Dynamic JS Win - Javascript Object                                       *
+   *                                                                          *
+   * Written by:                                                              *
+   *  - Raphael Derosso Pereira <raphaelpereira@users.sourceforge.net>        *
+   * ------------------------------------------------------------------------ *
+   *  This program is free software; you can redistribute it and/or modify it *
+   *  under the terms of the GNU General Public License as published by the   *
+   *  Free Software Foundation; either version 2 of the License, or (at your  *
+   *  option) any later version.                                              *
+  \****************************************************************************/
+
+if (!window.__DEFINE_DJSWIN__)
+{
+	__DEFINE_DJSWIN__ = true;
+	
+	if (document.all)
+	{
+		navigator.userAgent.toLowerCase().indexOf('msie 5') != -1 ? is_ie5 = true : is_ie5 = false;
+		is_ie = true;
+		is_moz1_6 = false;
+		is_mozilla = false;
+		is_ns4 = false;
+	}
+	else if (document.getElementById)
+	{
+		navigator.userAgent.toLowerCase().match('mozilla.*rv[:]1\.6.*gecko') ? is_moz1_6 = true : is_moz1_6 = false;
+		is_ie = false;
+		is_ie5 = false;
+		is_mozilla = true;
+		is_ns4 = false;
+	}
+	else if (document.layers)
+	{
+		is_ie = false;
+		is_ie5 = false;
+		is_moz1_6 = false;
+		is_mozilla = false;
+		is_ns4 = true;
+	}
+
+	if (!window.dd)
+	{
+		throw("wz_dragdrop lib must be loaded!");
+	}
+		
+	function dJSWin(params)
+	{
+		if (!params || typeof(params) != 'object' || !params.id || !params.width || !params.height || !params.content_id)
+		{
+			throw("Can't create empty window or window without width, height or ID");
+		}
+
+		/* Internal Variables */
+		if (is_ie)
+		{
+			this.winContainer = document.createElement('iframe');
+		}
+		this.clientArea = document.createElement('div');
+		this.title = document.createElement('div');
+		this.title_text = document.createElement('span');
+		this.buttons = new Array();
+		this.button_ext = "";
+		this.state = "";
+		this.shadows = new Array();
+		this.border = new Array();
+		this.content = _dJSWinElement(params.content_id);
+		this.includedContents = params['include_contents'];
+		var _this = this;
+
+		if (is_moz1_6)
+		{
+			var content_ = this.content;
+			this.content = this.content.cloneNode(true);
+
+			content_.id = content_.id+'CLONE';
+			content_.style.display = 'none';
+		}
+
+		this.border['t'] = document.createElement('div');
+		this.border['b'] = document.createElement('div');
+		this.border['l'] = document.createElement('div');
+		this.border['r'] = document.createElement('div');
+
+		this.shadows['r'] = document.createElement('div');
+		this.shadows['b'] = document.createElement('div');
+
+		this.buttons['xDIV'] = document.createElement('div');
+
+		if (params['button_x_img'])
+		{
+			this.buttons['xIMG'] = document.createElement('IMG');
+			this.buttons['xIMG'].src = params['button_x_img'];
+			this.buttons['xIMG'].style.cursor = 'hand';
+			this.buttons['xDIV'].appendChild(this.buttons['xIMG']);
+		}
+		else
+		{
+			this.buttons.xDIV.innerHTML = 'X';
+		}
+
+		if (params['button_y_img'])
+		{
+			var _this = this;
+			
+			this.button_ext = document.createElement('IMG');
+			this.button_ext.id = 'button_ext';
+			this.button_ext.src = params['button_y_img'];
+			this.button_ext.style.position = 'absolute';
+			this.button_ext.style.cursor = 'pointer';
+			this.button_ext.style.top = '1px';
+			this.button_ext.style.left = parseInt(params['width']) - 28	 + 'px';
+			this.button_ext.style.zIndex = '1';
+			this.button_ext.onclick = function(){_this.hide(); _this.state = 1;};
+		}
+		
+		/* Inicialization */
+		this.title.id = params['id'];
+		this.title.style.position = 'absolute';
+		this.title.style.visibility = 'hidden';
+		this.title.style.width = parseInt(params['width']) + 2 + 'px';
+		this.title.style.height = params['title_height'] ? params['title_height'] : '18px';
+		this.title.style.backgroundColor = params['title_color'];
+		this.title.style.top = '0px';
+		this.title.style.left = '0px';
+		this.title.style.zIndex = '1';
+		
+		this.title_text.style.position = 'relative';
+		this.title_text.className = params['title_class'];
+		this.title_text.style.fontWeight = 'bold';
+		this.title_text.style.color = params['title_text_color'] ? params['title_text_color'] : 'black';
+//		this.title_text.style.cursor = 'move';
+		this.title_text.innerHTML = params['title'];
+		this.title_text.style.zIndex = '1';
+
+		if (is_ie)
+		{
+			this.winContainer.id = params['id']+'_winContainer';
+			this.winContainer.style.position = 'absolute';
+			this.winContainer.style.visibility = 'hidden';
+			this.winContainer.style.width  = params['width'];
+			//this.winContainer.style.height = parseInt(params['height']) + parseInt(this.title.style.height) + 'px';
+			this.winContainer.style.height = params['height'];
+	//		this.winContainer.style.top = '0px';
+			this.winContainer.style.top = this.title.style.height;
+			this.winContainer.style.left = '0px';
+			this.winContainer.style.zIndex = '-1';
+	//		this.winContainer.style.backgroundColor = params['bg_color'];
+	//		this.winContainer.className = params['win_class'];
+			this.winContainer.src = '';
+		}
+		
+		this.clientArea.id = params['id']+'_clientArea';
+		this.clientArea.style.position = 'absolute';
+		this.clientArea.style.visibility = 'hidden';
+		this.clientArea.style.width  = parseInt(params['width']) + 2 + 'px';
+		this.clientArea.style.height = params['height'];
+		this.clientArea.style.top = parseInt(this.title.style.height) + 'px';
+		this.clientArea.style.left = '0px';
+		this.clientArea.style.backgroundColor = params['bg_color'];
+//		this.clientArea.style.overflow = 'auto';
+		this.clientArea.className = params['win_class'];
+		
+		this.buttons.xDIV.id = params['id']+'_button';
+		this.buttons.xDIV.style.position = 'absolute';
+		this.buttons.xDIV.style.visibility = 'hidden';
+		this.buttons.xDIV.style.cursor = 'hand';
+		this.buttons.xDIV.style.top = '1px';
+		this.buttons.xDIV.style.left = parseInt(params['width']) - 13 + 'px';
+		this.buttons.xDIV.style.zIndex = '1';
+		this.buttons.xDIV.onclick = function() {_this.close(); _this.state = 2;};
+		
+		this.content.style.visibility = 'hidden';
+		//this.content.style.top = parseInt(this.title.style.height) + 'px';
+		this.content.style.top = '0px';
+		this.content.style.left = '0px';
+		
+		this.shadows.b.id = params['id']+'_shadowb';
+		this.shadows.b.style.position = 'absolute';
+		this.shadows.b.style.visibility = 'hidden';
+		this.shadows.b.style.backgroundColor = '#666';
+		this.shadows.b.style.width = params['width'];
+		this.shadows.b.style.height = '4px';
+		this.shadows.b.style.top = parseInt(this.title.style.height) + parseInt(params['height']) + 'px';
+		this.shadows.b.style.left = '4px';
+		
+		this.shadows.r.id = params['id']+'_shadowr';
+		this.shadows.r.style.position = 'absolute';
+		this.shadows.r.style.visibility = 'hidden';
+		this.shadows.r.style.backgroundColor = '#666';
+		this.shadows.r.style.width = '4px';
+		this.shadows.r.style.height = parseInt(params['height']) + parseInt(this.title.style.height) + 'px';
+		this.shadows.r.style.top  = '4px';
+		this.shadows.r.style.left = params['width'];
+
+		this.border.t.id = params['id']+'_border_t';
+		this.border.b.id = params['id']+'_border_b';
+		this.border.l.id = params['id']+'_border_l';
+		this.border.r.id = params['id']+'_border_r';
+		
+		this.border.t.style.position = 'absolute';
+		this.border.b.style.position = 'absolute';
+		this.border.l.style.position = 'absolute';
+		this.border.r.style.position = 'absolute';
+
+		this.border.t.style.visibility = 'hidden';
+		this.border.b.style.visibility = 'hidden';
+		this.border.l.style.visibility = 'hidden';
+		this.border.r.style.visibility = 'hidden';
+
+		this.border.t.style.backgroundColor = params['title_color'];
+		this.border.b.style.backgroundColor = params['title_color'];
+		this.border.l.style.backgroundColor = params['title_color'];
+		this.border.r.style.backgroundColor = params['title_color'];
+		
+		this.border.t.className = params['title_class'];
+		this.border.b.className = params['title_class'];
+		this.border.l.className = params['title_class'];
+		this.border.r.className = params['title_class'];
+
+		this.border.t.style.border = '0px';
+		this.border.b.style.border = '0px';
+		this.border.l.style.border = '0px';
+		this.border.r.style.border = '0px';
+
+		if (params['border'])
+		{
+			this.border.t.style.width = parseInt(params['width']) + 2 + 'px';
+			this.border.b.style.width = parseInt(params['width']) + 2 + 'px';
+			this.border.l.style.width = '2px';
+			this.border.r.style.width = '2px';
+
+			if (is_ie)
+			{
+				this.border.t.style.height = '0';
+				this.border.b.style.height = '0';
+				this.border.l.style.height = parseInt(params['height']) + parseInt(this.title.style.height) + 2 + 'px';
+				this.border.r.style.height = parseInt(params['height']) + parseInt(this.title.style.height) + 2 + 'px';
+
+				this.border.t.style.top = '0';
+				this.border.b.style.top = parseInt(params['height']) + parseInt(this.title.style.height) + 'px';
+				this.border.l.style.top = '0'; 
+				this.border.r.style.top = '0';
+			}
+			else
+			{
+				this.border.t.style.height = '2px';
+				this.border.b.style.height = '2px';
+				this.border.l.style.height = parseInt(params['height']) + parseInt(this.title.style.height) + 4 + 'px';
+				this.border.r.style.height = parseInt(params['height']) + parseInt(this.title.style.height) + 4 + 'px';
+
+				this.border.t.style.top = '-2px';
+				this.border.b.style.top = parseInt(params['height']) + parseInt(this.title.style.height) + 'px';
+				this.border.l.style.top = '-2px'; 
+				this.border.r.style.top = '-2px';
+			}
+
+			this.border.t.style.left = '-2px';
+			this.border.b.style.left = '-2px';
+			this.border.l.style.left = '-2px';
+			this.border.r.style.left = params['width'];
+
+			//this.winContainer.style.width  = parseInt(this.winContainer.style.width) + 4 + 'px';
+			//this.winContainer.style.height = parseInt(this.winContainer.style.height) + 4 + 'px';
+			//this.clientArea.style.width    = parseInt(this.clientArea.style.width) + 4 + 'px';
+			//this.clientArea.style.height   = parseInt(this.clientArea.style.height) + 4 + 'px';
+
+			//this.title.style.top = parseInt(this.title.style.top) + 2 + 'px';
+			//this.clientArea.style.top = parseInt(this.clientArea.style.top) + 2 + 'px';
+			//this.buttons.xDIV.style.top = parseInt(this.buttons.xDIV.style.top) + 2 + 'px';
+			this.shadows.b.style.top = parseInt(this.shadows.b.style.top) + 2 + 'px';
+			this.shadows.r.style.top = parseInt(this.shadows.r.style.top) + 2 + 'px';
+			//this.content.style.top = parseInt(this.content.style.top) + 2 + 'px';
+
+			//this.title.style.left = parseInt(this.title.style.left) + 2 + 'px';
+			//this.clientArea.style.left = parseInt(this.clientArea.style.left) + 2 + 'px';
+			//this.buttons.xDIV.style.left = parseInt(this.buttons.xDIV.style.left) + 2 + 'px';
+			this.shadows.b.style.left = parseInt(this.shadows.b.style.left) + 2 + 'px';
+			this.shadows.r.style.left = parseInt(this.shadows.r.style.left) + 2 + 'px';
+			//this.content.style.left = '2px';
+		}
+		else
+		{
+			this.border.t.style.width = '0px';
+			this.border.b.style.width = '0px';
+			this.border.l.style.width = '0px';
+			this.border.r.style.width = '0px';
+		}
+		
+		if (!is_moz1_6)
+		{
+			this.content.parentNode.removeChild(this.content);
+		}
+/*
+		this.winContainer.appendChild(this.title);
+		this.winContainer.appendChild(this.buttons.xDIV);
+		this.winContainer.appendChild(this.border.t);
+		this.winContainer.appendChild(this.border.b);
+		this.winContainer.appendChild(this.border.l);
+		this.winContainer.appendChild(this.border.r);
+		this.winContainer.appendChild(this.shadows.r);
+		this.winContainer.appendChild(this.shadows.b);
+		this.winContainer.appendChild(this.content);
+*/
+		if (is_ie)
+		{
+			this.title.appendChild(this.winContainer);
+		}
+		else
+		{
+			this.title.appendChild(this.border.t);
+		}
+		this.title.appendChild(this.title_text);
+		this.title.appendChild(this.clientArea);
+		this.title.appendChild(this.buttons.xDIV);
+		if(this.button_ext){this.title.appendChild(this.button_ext);};		
+		this.title.appendChild(this.border.b);
+		this.title.appendChild(this.border.l);
+		this.title.appendChild(this.border.r);
+		this.title.appendChild(this.shadows.r);
+		this.title.appendChild(this.shadows.b);
+		this.clientArea.appendChild(this.content);
+		
+		document.body.appendChild(this.title);
+
+	}
+
+	dJSWin.prototype.close = function()
+	{
+		var _this = this;
+		_this.state = 0;
+		dd.elements[this.title.id].hide();
+	};
+
+	dJSWin.prototype.open = function()
+	{
+/*		if (is_ie)
+		{
+			this.moveTo(document.body.offsetWidth/2 - dd.elements[this.title.id].w/2,
+			            document.body.offsetHeight/2 - dd.elements[this.winContainer.id].h/2);
+		}
+		else
+		{
+			this.moveTo(window.innerWidth/2 - dd.elements[this.title.id].w/2,
+			            window.innerHeight/2 - dd.elements[this.clientArea.id].h/2);
+		}
+*/
+		if (is_ie)
+		{
+			this.moveTo(document.body.offsetWidth/2 + document.body.scrollLeft - dd.elements[this.title.id].w/2,
+			            document.body.offsetHeight/2 + document.body.scrollTop - dd.elements[this.winContainer.id].h/2);
+		}
+		else
+		{
+			this.moveTo(window.innerWidth/2 + window.pageXOffset - dd.elements[this.title.id].w/2,
+			            window.innerHeight/2 + window.pageYOffset - dd.elements[this.clientArea.id].h/2);
+		}
+		
+		dd.elements[this.title.id].maximizeZ();
+		dd.elements[this.title.id].show();
+	};
+
+	dJSWin.prototype.show = function()
+	{
+		this.open();
+	};
+
+	dJSWin.prototype.hide = function()
+	{
+		this.close();
+	};
+
+	dJSWin.prototype.moveTo = function(x,y)
+	{
+		dd.elements[this.title.id].moveTo(x,y);
+	};
+
+	dJSWin.prototype.x = function()
+	{
+		return dd.elements[this.title.id].x;
+	};
+
+	dJSWin.prototype.y = function()
+	{
+		return dd.elements[this.title.id].y;
+	};
+
+	dJSWin.prototype.draw = function()
+	{
+		if (dd.elements && dd.elements[this.title.id])
+		{
+			return;
+		}
+
+		if (is_ie)
+		{
+			ADD_DHTML(this.winContainer.id+NO_DRAG);
+		}
+		else
+		{
+			ADD_DHTML(this.border.t.id+NO_DRAG);
+		}
+		ADD_DHTML(this.title.id+CURSOR_MOVE);
+		ADD_DHTML(this.clientArea.id+NO_DRAG);
+		ADD_DHTML(this.buttons.xDIV.id+NO_DRAG);
+		ADD_DHTML(this.content.id+NO_DRAG);
+		ADD_DHTML(this.shadows.r.id+NO_DRAG);
+		ADD_DHTML(this.shadows.b.id+NO_DRAG);
+		ADD_DHTML(this.border.b.id+NO_DRAG);
+		ADD_DHTML(this.border.l.id+NO_DRAG);
+		ADD_DHTML(this.border.r.id+NO_DRAG);
+		
+		if (is_ie)
+		{
+			dd.elements[this.title.id].addChild(dd.elements[this.winContainer.id]);
+		}
+		else
+		{
+			dd.elements[this.title.id].addChild(dd.elements[this.border.t.id]);
+		}
+		//dd.elements[this.title.id].setZ(dd.elements[this.border.t.id].z+1);
+		//dd.elements[this.title.id].maximizeZ();
+
+		dd.elements[this.title.id].addChild(dd.elements[this.clientArea.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.buttons.xDIV.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.content.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.shadows.r.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.shadows.b.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.border.b.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.border.l.id]);
+		dd.elements[this.title.id].addChild(dd.elements[this.border.r.id]);
+
+
+		if (typeof(this.includedContents) == 'object')
+		{
+			for (var i in this.includedContents)
+			{
+				ADD_DHTML(this.includedContents[i]+NO_DRAG);
+				dd.elements[this.title.id].addChild(dd.elements[this.includedContents[i]]);
+			}
+		}
+
+//		dd.elements[this.title.id].setZ('-1');
+
+		if (is_ie)
+		{
+			dd.elements[this.title.id].moveTo(document.body.offsetWidth/2 - dd.elements[this.winContainer.id].w/2,
+			                                  document.body.offsetHeight/2 - dd.elements[this.winContainer.id].h/2)
+		}
+		else
+		{
+			dd.elements[this.title.id].moveTo(window.innerWidth/2 - dd.elements[this.clientArea.id].w/2,
+			                                  window.innerHeight/2 - dd.elements[this.clientArea.id].h/2);
+		}
+		
+		dd.elements[this.title.id].hide();
+	};
+
+	function _dJSWinElement(id)
+	{
+		if (document.getElementById)
+		{
+			return document.getElementById(id);
+		}
+		else if (document.all)
+		{
+			return document.all[id];
+		}
+		else
+		{
+			throw("Browser Not Supported!");
+		}
+	}
+
+	if (!dd.elements)
+	{
+		var div = document.createElement('div');
+		div.id = '__NONE__#';
+		div.style.position = 'absolute';
+		
+		SET_DHTML(div.id);
+	}
+}
Index: /sandbox/workflow/branches/993/js/jscode/doiMenuDOM.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/doiMenuDOM.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/doiMenuDOM.js	(revision 795)
@@ -0,0 +1,1240 @@
+/**
+* Bismillaahirrohmaanirrohiim
+* Dhtml MenuBar DOM
+*
+* @package doiMenu
+* @version 1.5.3
+* @author  Donna Iwan Setiawan
+* @Copyright (C) 2003 - 2004 Donna Iwan Setiawan
+* @ All rights reserved
+* @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html
+*/
+var _mmObj ='',_aId;
+var _browser=new TBrowser();var _arRegisterMenu=new Array();var _arRegisterMenuIndex=-1;var _arTriggerMenu=new Array();var _arRegisterPopID=new Array();var _arRegisterPopIndex=new Array();var _arRegisterTriggerPopID=new Array();var _arRegisterTriggerPopIndex=new Array();var _arMMClick=new Array();function Initialize()
+{
+var byk=_arRegisterMenuIndex;for(var i=0;i<=byk;i++)
+_arRegisterMenu[i].Init();}
+function InitResize()
+{
+var byk=_arRegisterMenuIndex;for(var i=0;i<=byk;i++)
+_arRegisterMenu[i].Resize();
+}
+function TBrowser()
+{
+this._name='';this._version='';this._os='';}
+var detect=navigator.userAgent.toLowerCase();var total,thestring;if(checkIt('konqueror'))
+{
+_browser._name="Konqueror";_browser._os="Linux";}
+else if(checkIt('safari')) _browser._name="Safari";else if(checkIt('omniweb')) _browser._name="OmniWeb";else if(checkIt('opera')) _browser._name="Opera";else if(checkIt('webtv')) _browser._name="WebTV";else if(checkIt('icab')) _browser._name="iCab";else if(checkIt('msie')) _browser._name="IE";else if(!checkIt('compatible'))
+{
+_browser._name="Netscape";_browser._version=detect.charAt(8);}
+else _browser._name="none";if(_browser._version=='') _browser._version=detect.charAt(place+thestring.length);if(_browser._os=='')
+{
+if(checkIt('linux')) _browser._os="Linux";else if(checkIt('x11')) _browser._os="Unix";else if(checkIt('mac')) _browser._os="Mac";else if(checkIt('win')) _browser._os="Windows";else _browser._os="none";}
+function checkIt(string)
+{
+place=detect.indexOf(string)+1;thestring=string;return place;}
+function TMainMenu(name,direction)
+{
+_arRegisterMenuIndex++;_arRegisterMenu[_arRegisterMenuIndex]=this;_arRegisterPopID[_arRegisterMenuIndex]=new Array();_arRegisterPopIndex[_arRegisterMenuIndex]=-1;_arRegisterTriggerPopID[_arRegisterMenuIndex]=new Array();_arRegisterTriggerPopIndex[_arRegisterMenuIndex]=-1;_arMMClick[_arRegisterMenuIndex]=true;this._popOnClick=false;this._expandIcon=new TExpandIcon();this._expandIcon._create=false;this._registerMenuIndex=_arRegisterMenuIndex;this._uniqueID=0;this._name=name;this._id='_'+name+'ID';this._index=_arRegisterMenuIndex;
+this._correction=new TCorrection();this._parent=null;this._width='auto';this._direction=direction;if(this._direction=='horizontal')
+{
+this._expandIcon._symbol='&#9660;';}
+else
+{
+this._expandIcon._symbol='&#9658;';}
+this._position='relative';this._top=0;this._left=0;this._cellSpacing=0;this._itemHeight='auto';this._itemWidth='auto';this._background=new TBackground();this._background._color='buttonface';this._pop=new TPopParameter();this._pop._mmName=this._name;this._pop._index=this._index;this._shadow=new TShadow();this._font=new TFont();this._font._family='tahoma,verdana,sans-serif,arial';this._font._size='8pt';this._itemIndex=-1;this._items=new Array();this._itemText=new TText();this._itemText._color='black';this._itemBack=new TBackground();this._itemTextHL=new TText();this._itemTextHL._color='white';
+this._itemBackHL=new TBackground();this._itemBackHL._color='#B6BDD2';this._border=new TBorder();this._itemBorder=new TBorder();this._itemBorderHL=new TBorder();this._itemBorderHL._top='1px navy solid';this._itemBorderHL._right='1px navy solid';this._itemBorderHL._bottom='1px navy solid';this._itemBorderHL._left='1px navy solid';this._itemTextClick=new TText();this._itemTextClick._color='white';this._itemBackClick=new TBackground();this._itemBackClick._color='#B6BDD2';this._itemBorderClick=new TBorder();this._itemBorderClick._top='1px navy solid';this._itemBorderClick._right='1px navy solid';this._itemBorderClick._bottom='1px navy solid';this._itemBorderClick._left='1px navy solid';this._hideObject=new THiddenObject();this._pop._header=new TPopHeader();this._header=new TPopHeader();this._header._font._size='6pt';this._type='';this._initialTop=0;this._initialLeft=0;this._headerClickState=false;this._headerText='Click Here';this.SetHeaderText=SetMMHeaderText;this.Add=AddItem;this.Build=BuildMenu;this.BuildStyle=BuildStyle;this.Draw=DrawMenu;this.Init=InitMenu;this.SetExpandIcon=SetExpandIcon;this.SetParent=SetParent;this.SetType=SetMenuType;this.SetPopOnClick=SetPopOnClick;this.SetWidth=SetWidth;this.SetBorder=SetBorder;this.SetBorderTop=SetBorderTop;this.SetBorderRight=SetBorderRight;this.SetBorderBottom=SetBorderBottom;this.SetBorderLeft=SetBorderLeft;this.SetItemDimension=SetItemDimension;this.SetItemBorder=SetItemBorder;this.SetItemBorderTop=SetItemBorderTop;this.SetItemBorderRight=SetItemBorderRight;this.SetItemBorderBottom=SetItemBorderBottom;this.SetItemBorderLeft=SetItemBorderLeft;this.SetItemBorderHL=SetItemBorderHL;this.SetItemBorderTopHL=SetItemBorderTopHL;this.SetItemBorderRightHL=SetItemBorderRightHL;this.SetItemBorderBottomHL=SetItemBorderBottomHL;this.SetItemBorderLeftHL=SetItemBorderLeftHL;this.SetItemBorderClick=SetItemBorderClick;this.SetItemBorderTopClick=SetItemBorderTopClick;this.SetItemBorderRightClick=SetItemBorderRightClick;this.SetItemBorderBottomClick=SetItemBorderBottomClick;this.SetItemBorderLeftClick=SetItemBorderLeftClick;this.SetShadow=SetShadow;this.SetFont=SetFont;this.SetBackground=SetBackground;this.SetDirection=SetDirection;this.SetPosition=SetPosition;this.SetCorrection=SetCorrection;this.SetCellSpacing=SetCellSpacing;this.SetItemText=SetItemText;this.SetItemTextHL=SetItemTextHL;this.SetItemTextClick=SetItemTextClick;this.SetItemBackground=SetItemBackground;this.SetItemBackgroundHL=SetItemBackgroundHL;this.SetItemBackgroundClick=SetItemBackgroundClick;this.Resize=ResizeMenu;}
+function ResizeMenu()
+{
+if(this._shadow._create)
+{
+if(document.all)
+{
+var elm=document.all(this._id);var shadowElm=document.all('sh_'+this._id);}
+else if(document.getElementById)
+{
+var elm=document.getElementById(this._id);var shadowElm=document.getElementById('sh_'+this._id);}
+var posY=findPosY(elm);var posX=findPosX(elm);if(_browser._name=='IE')
+{
+shadowElm.style.width=elm.offsetWidth+10;shadowElm.childNodes[0].style.width=elm.offsetWidth;shadowElm.style.top=posY;shadowElm.style.left=posX;}
+else
+{
+shadowElm.style.width=elm.offsetWidth;shadowElm.style.top=posY+this._shadow._distance;shadowElm.style.left=posX+this._shadow._distance;}
+}
+}
+function SetDirection(dDirection)
+{
+dDirection=dDirection.toLowerCase();switch(dDirection)
+{
+case 'vertical':
+this._direction='vertical';break;default:
+this._direction='horizontal';}
+}
+function SetMMHeaderText(dText)
+{
+this._headerText=dText;}
+function SetMenuType(dType)
+{
+dType=dType.toLowerCase();switch(dType)
+{
+case 'float':
+this._type='float';break;case 'free':
+this._type='free';break;default :
+this._type='';}
+}
+function TPopHeader()
+{
+this._background=new TBackground();this._background._color='black';this._itemText=new TText();this._itemText._weight='bold';this._itemText._color='white';this._font=new TFont();this._font._family='tahoma,verdana,sans-serif,arial';this._font._size='8pt';this.SetBackground=SetBackground;this.SetFont=SetFont;this.SetText=SetItemText;}
+function THiddenObject()
+{
+this._itemIndex=-1;this._items=new Array();this._isHide=false;this._isShow=true;this.Add=AddItem;this.Hide=HideObject;this.Show=ShowObject;this.Clear=ClearObject;}
+function ClearObject()
+{
+if(this._itemIndex >-1)
+{
+var iMax=this._itemIndex+1;for(var i=0;i<iMax;i++)
+{
+delete this._items[i];}
+this._isHide=false;this._itemIndex=-1;}
+}
+function HideObject()
+{
+if(this._itemIndex >-1)
+{
+var iMax=this._itemIndex+1;for(var i=0;i<iMax;i++)
+{
+if(document.all)
+document.all(this._items[i]).style.visibility="hidden";else if(document.getElementById){
+document.getElementById(this._items[i]).style.visibility="hidden";
+document.getElementById(this._items[i]).style.display="none";
+}
+}
+this._isHide=true;}
+}
+function ShowObject()
+{
+if(this._isHide)
+{
+var iMax=this._itemIndex+1;for(var i=0;i<iMax;i++)
+{
+if(document.all)
+document.all(this._items[i]).style.visibility="visible";else if(document.getElementById){
+document.getElementById(this._items[i]).style.visibility="visible";
+document.getElementById(this._items[i]).style.display="";
+}
+}
+}
+}
+function SetPopOnClick(dBool)
+{
+if(dBool)
+{
+this._popOnClick=true;_arMMClick[this._registerMenuIndex]=false;}else
+{
+this._popOnClick=false;_arMMClick[this._registerMenuIndex]=true;}
+}
+function TPopMenu(label,icon,clickType,clickParam,status)
+{
+this._id='';this._parent=null;this._parentPop=null;this._label=label;this._top=0;this._left=0;this._status=status;this._tmpIcon=icon;this._icon="";this._itemIndex=-1;this._items=new Array();switch(clickType)
+{
+case 'function':
+this._eClick=clickParam;break;case 'f':
+this._eClick="onPopItemMOut(event,this,'',_mmObj);"+clickParam; break;case 'address':
+this._eClick="_openURL('"+clickParam+"')";break;case 'a':
+this._eClick="onPopItemMOut(event,this,'',_mmObj);"+"_openURL('"+clickParam+"')";break;default:
+this._eClick='';}
+this._type='';
+this.Add=AddItem;this.Draw=DrawPopMenu;this.Init=InitPopMenu;this.SetType=SetPopType;this.SetParent=SetParent;}
+function SetPopType(dType)
+{
+dType=dType.toLowerCase();switch(dType)
+{
+case 'header':
+this._type='h';break;case 'h':
+this._type='h';break;default:
+this._type='';}
+}
+function TPopParameter()
+{
+this._index=-1;this._mmName='';this._padding='1px 1px 1px 1px';this._separator=new TSeparator();this._expandIcon=new TExpandIcon();this._correction=new TCorrection();this._font=new TFont();this._font._family='tahoma,verdana,sans-serif,arial';this._font._size='8pt';this._alpha=100;this._itemWidth=200;
+this._itemHeight='auto';this._itemBorder=new TBorder();this._itemBorder._top='0px none solid';this._itemBorder._right='0px none solid';this._itemBorder._bottom='0px none solid';this._itemBorder._left='0px none solid';this._itemPadding='1px 1px 1px 1px'	;this._itemText=new TText();this._itemBack=new TBackground();this._itemBorderHL=new TBorder();this._itemBorderHL._top='1px navy solid';this._itemBorderHL._right='1px navy solid';this._itemBorderHL._bottom='1px navy solid';this._itemBorderHL._left='1px navy solid';this._itemPaddingHL='0px 0px 0px 0px';this._itemTextHL=new TText();this._itemTextHL._color='white';this._itemBackHL=new TBackground();this._itemBackHL._color='#B6BDD2';this._background=new TBackground();this._background._color='whitesmoke';this._border=new TBorder();this._border._top='1px black solid';this._border._right='1px black solid';this._border._bottom='1px black solid';this._border._left='1px black solid';this._shadow=new TShadow();this._header=new TPopHeader();this._timeOut=750;
+this.SetAlpha=SetAlpha;this.SetBorder=SetBorder;this.SetPadding=SetPadding;this.SetPaddings=SetPaddings;this.SetBorderTop=SetBorderTop;this.SetBorderRight=SetBorderRight;this.SetBorderBottom=SetBorderBottom;this.SetBorderLeft=SetBorderLeft;this.SetItemDimension=SetItemDimension;this.SetItemBorder=SetItemBorder;this.SetItemPadding=SetItemPadding;this.SetItemPaddingHL=SetItemPaddingHL;this.SetItemPaddings=SetItemPaddings;this.SetItemPaddingsHL=SetItemPaddingsHL;this.SetItemBorderTop=SetItemBorderTop;this.SetItemBorderRight=SetItemBorderRight;this.SetItemBorderBottom=SetItemBorderBottom;this.SetItemBorderLeft=SetItemBorderLeft;this.SetItemBorderHL=SetItemBorderHL;this.SetItemBorderTopHL=SetItemBorderTopHL;this.SetItemBorderRightHL=SetItemBorderRightHL;this.SetItemBorderBottomHL=SetItemBorderBottomHL;this.SetItemBorderLeftHL=SetItemBorderLeftHL;this.SetShadow=SetShadow;this.SetFont=SetFont;this.SetBackground=SetBackground;this.SetCorrection=SetCorrection;this.SetExpandIcon=SetExpandIcon;this.SetSeparator=SetSeparator;this.SetDelay=SetDelay;this.SetItemText=SetItemText;this.SetItemTextHL=SetItemTextHL;this.SetItemBackground=SetItemBackground;this.SetItemBackgroundHL=SetItemBackgroundHL;}
+function SetAlpha(dAlpha)
+{
+dAlpha=parseInt(dAlpha);this._alpha=dAlpha;}
+function TCorrection()
+{
+this._top=0;this._left=0;}
+function TText()
+{
+this._color='black';this._align='left';this._decoration='none';this._whiteSpace='normal';this._weight='normal';}
+function TShadow()
+{
+this._create=false;this._color='black';this._distance=3;
+}
+function TSeparator()
+{
+this._align='center';
+this._width=200;this._margin="0px 0px 0px 0px";this._border=new TBorder();
+this._border._top='1px black solid';this._border._bottom='1px white solid';}
+function TFont()
+{
+this._family='arial,times,sans-serif';this._size='8pt';}
+function TBackground()
+{
+this._image='none';
+this._repeat='no-repeat';this._color='';this._position='top left';}
+function TExpandIcon()
+{
+this._create=true;this._symbol='&#9658;';this._font=new TFont();this._font._size='6pt';}
+function TBorder()
+{
+this._top='1px gray solid';this._right='1px gray solid';this._bottom='1px gray solid';this._left='1px gray solid';}
+
+function BuildMenu(id)
+{
+var result=this.BuildStyle();
+var level=-1;this.SetParent(this);result+=this.Draw(level++);level++;for(var i=0;i<=this._itemIndex;i++)
+{
+	result+=this._items[i].Draw(level);result+=BuildPopUpMenu(this._items[i],level);}
+	if(is_ie)
+		document.getElementById(id).innerHTML ="&nbsp;";
+	document.getElementById(id).innerHTML += result;
+
+}
+function InitMenu()
+{
+if(document.all)
+var el_menu=document.all(this._id);else if(document.getElementById)
+var el_menu=document.getElementById(this._id);this._position=this._position.toLowerCase();if(this._position=='absolute')
+{
+el_menu.style.top=this._top;el_menu.style.left=this._left;}else
+{
+this._top=findPosY(el_menu);this._left=findPosX(el_menu);}
+el_menu.style.zIndex=100;if((this._type=='free') && (this._position=='absolute'))
+{
+if(document.all)
+var fr_el=document.all('fr_'+this._id);else if(document.getElementById)
+var fr_el=document.getElementById('fr_'+this._id);fr_el.style.top=this._top+'px';fr_el.style.left=this._left+'px';fr_el.style.width=el_menu.offsetWidth;fr_el.style.height=el_menu.offsetHeight;fr_el.style.zIndex=100;}
+if(this._shadow._create)
+{
+if(document.all)
+var sh_el=document.all('sh_'+this._id);else if(document.getElementById)
+var sh_el=document.getElementById('sh_'+this._id);if(_browser._name=='IE')
+{
+sh_el.style.top=this._top+'px';sh_el.style.left=this._left+'px';sh_el.style.width=el_menu.offsetWidth+10+'px';sh_el.style.height=el_menu.offsetHeight+10+'px';sh_el.childNodes[0].style.width=el_menu.offsetWidth+'px';sh_el.childNodes[0].style.height=el_menu.offsetHeight+'px';sh_el.childNodes[0].style.backgroundColor=this._shadow._color;sh_el.style.visibility='visible';}
+else
+{
+if(_browser._name=='Konqueror' && this._position=='relative')
+sh_el.style.visibility='hidden';else
+{
+sh_el.style.top=this._top+this._shadow._distance+'px';sh_el.style.left=this._left+this._shadow._distance+'px';sh_el.style.width=el_menu.offsetWidth+'px';sh_el.style.height=el_menu.offsetHeight+'px';sh_el.style.backgroundColor=this._shadow._color;sh_el.style.visibility='visible';}
+}
+sh_el.style.zIndex=0;}
+for(var i=0;i<=this._itemIndex;i++)
+{
+if(document.all)
+var el_menuitem=document.all('pr_'+this._items[i]._id);else if(document.getElementById)
+var el_menuitem=document.getElementById('pr_'+this._items[i]._id);if(this._items[i]._itemIndex >-1)
+{
+if(document.all)
+var el_pop=document.all(this._items[i]._id);else if(document.getElementById)
+var el_pop=document.getElementById(this._items[i]._id);el_pop.style.zIndex=102;if(this._items[i]._parent._pop._shadow._create)
+{
+if(document.all)
+var sh_el_pop=document.all('sh_'+this._items[i]._id);else if(document.getElementById)
+var sh_el_pop=document.getElementById('sh_'+this._items[i]._id);if(_browser._name=='IE')
+{
+sh_el_pop.style.width=el_pop.offsetWidth+10+'px';sh_el_pop.style.height=el_pop.offsetHeight+10+'px';sh_el_pop.childNodes[0].style.width=el_pop.offsetWidth+'px';sh_el_pop.childNodes[0].style.height=el_pop.offsetHeight+'px';sh_el_pop.childNodes[0].style.backgroundColor=this._items[i]._parent._pop._shadow._color;}
+else
+{
+sh_el_pop.style.width=el_pop.offsetWidth+'px';sh_el_pop.style.height=el_pop.offsetHeight+'px';sh_el_pop.style.backgroundColor=this._items[i]._parent._pop._shadow._color;}
+sh_el_pop.style.zIndex=101;}
+this._items[i].Init(102);}
+}
+el_menu.style.visibility="visible";
+el_menu.style.display="";
+if((this._type=='float') && (this._position=='absolute'))
+{
+this._initialTop=this._top;this._initialLeft=this._left;_floatingMMEffect(this);}
+}
+function SetParent(parent)
+{
+for(var i=0;i<=this._itemIndex;i++)
+{
+this._items[i]._parent=parent;this._items[i]._parentPop=this;this._items[i]._id='_'+parent._name+'-'+parent._uniqueID+"ID";var iIcon=parseInt(this._items[i]._tmpIcon);if((iIcon > 0))
+{
+this._items[i]._icon='<td nowrap style="cursor:pointer;cursor:hand;padding-left:'+iIcon+'px;">';}
+else
+{
+switch(this._items[i]._tmpIcon)
+{
+case "":
+this._items[i]._icon='<td nowrap style="padding-left:24px;">';break;case '0':
+this._items[i]._icon='<td nowrap>';break;default:
+this._items[i]._icon='<td style="cursor:pointer;cursor:hand" nowrap class="TIcon'+this._items[i]._parent._index+'"><img class="TIcon'+this._items[i]._parent._index+'" src="'+this._items[i]._tmpIcon+'" /></td><td style="cursor:pointer;cursor:hand" nowrap>';}
+}
+parent._uniqueID++;this._items[i].SetParent(parent);}
+}
+function DrawMenu(level)
+{
+var result="";if(this._shadow._create)
+{
+if(_browser._name=='IE')
+result+='<div style="position:absolute;display:none;filter: blur( direction=135, strength='+this._shadow._distance+', add=1);" id="sh_'+this._id+'" align="left"><div></div></div>';else
+result+='<div style="position:absolute;display:none;" id="sh_'+this._id+'"></div>';}
+if((this._type=='free') && (this._position=='absolute'))
+{
+result+='<table class="TMenu'+this._index+'" id="fr_'+this._id+'"';result+=' cellspacing="'+this._cellSpacing+'" style="cursor:pointer;cursor:hand;position:absolute;display:none;">';result+='<tr><td nowrap class="TMMHeader'+this._index+'"';result+=' onclick="onMMHeaderClick(event,'+this._name+')"';result+='>'+this._headerText+'</td></tr>';result+='<tr><td nowrap> </td></tr>';result+='</table>';}
+result+='<table class="TMenu'+this._index+'" id="'+this._id+'"';result+=' cellspacing="'+this._cellSpacing+'">';if(this._direction=='horizontal')
+{
+if(this._itemIndex >-1)
+{
+if((this._type=='free') && (this._position=='absolute'))
+{
+var colSpan=this._itemIndex+1;result+='<tr><td nowrap  colspan="'+colSpan+'" class="TMMHeader'+this._index+'"';result+=' onclick="onMMHeaderClick(event,'+this._name+')">'+this._headerText+'</td></tr>';}
+}
+result+='<tr>';}
+else
+{
+if((this._type=='free') && (this._position=='absolute'))
+{
+result+='<td nowrap  class="TMMHeader'+this._index+'"';result+=' onclick="onMMHeaderClick(event,'+this._name+')">'+this._headerText+'</td>';}
+}
+if(this._itemIndex >-1)
+{
+var isExpandIcon=false;for(var i=0;i<=this._itemIndex;i++)
+{
+var result1='';var expandHTML='';result1+='<td nowrap class="TMenuItem'+this._index+'" id="pr_'+this._items[i]._id+'"';if(this._items[i]._itemIndex >-1)
+{
+result1+=' onclick="onMainMOver(event,this,\''+this._items[i]._id+'\','+level+','+this._name+',\''+escape(this._items[i]._status)+'\',true)" onmouseover="onMainMOver(event,this,\''+this._items[i]._id+'\','+level+','+this._name+',\''+escape(this._items[i]._status)+'\')"';if(this._popOnClick)
+result1+='onclick="onMainClick(event,this,\''+this._items[i]._id+'\','+this._name+')"';result1+=' onmouseout="onMainMOut(event,this,\''+this._items[i]._id+'\','+this._name+')"';if(this._items[i]._parent._expandIcon._create)
+{
+//expandHTML='<td nowrap  class="TMMExpand'+this._items[i]._parent._index+'">'+this._items[i]._parent._expandIcon._symbol+'</td>';isExpandIcon=true;
+}
+}
+else
+{
+result1+=' onmouseover="onMainMOver(event,this,\'\','+level+','+this._name+',\''+escape(this._items[i]._status)+'\')"';result1+=' onmouseout="onMainMOut(event,this,\'\','+this._name+')"';result1+=' onclick="onMainMOut(event,this,\'\','+this._name+');'+this._items[i]._eClick+'"';}
+var iIcon=parseInt(this._items[i]._tmpIcon);if((iIcon > 0))
+{
+this._items[i]._icon='<td nowrap  style="padding-left:'+iIcon+'px;">';}
+else
+{
+switch(this._items[i]._tmpIcon)
+{
+case "":
+if(isExpandIcon && expandHTML=='')
+this._items[i]._icon='<td nowrap  style="padding-left:30px;padding-right:16px">';else
+this._items[i]._icon='<td nowrap  style="padding-left:30px">';break;case '0':
+if(isExpandIcon && expandHTML=='')
+this._items[i]._icon='<td nowrap   style="padding-right:16px">';else
+this._items[i]._icon='<td nowrap >';break;default:
+if(isExpandIcon && expandHTML=='')
+this._items[i]._icon='<td nowrap  class="TIcon'+this._items[i]._parent._index+'"><img class="TIcon'+this._items[i]._parent._index+'" src="'+this._items[i]._tmpIcon+'"  /></td><td nowrap   style="padding-right:16px">';else
+this._items[i]._icon='<td nowrap  class="TIcon'+this._items[i]._parent._index+'"><img class="TIcon'+this._items[i]._parent._index+'" src="'+this._items[i]._tmpIcon+'"  /></td><td nowrap >';}
+}
+result1+='><table class="TMenuItemChild'+this._index+'"><tr>'+this._items[i]._icon+this._items[i]._label+'</td>';result1+=expandHTML+'</tr></table></td>';if(this._direction=='horizontal')
+result+=result1;else
+result+='<tr>'+result1+'</tr>';}
+}
+else
+{
+var result1='';result1+='';if(this._direction=='horizontal')
+result+=result1;else
+result+='<tr>'+result1+'</tr>';}
+if(this._direction=='horizontal')
+result+='</tr>';result+='</table>';return result;}
+function DrawPopMenu(level)
+{
+var result="";if(this._itemIndex >-1)
+{
+if(this._parent._pop._shadow._create)
+{
+if(_browser._name=='IE')
+result+='<div style="position:absolute;visibility:hidden;filter: blur( direction=135, strength='+this._parent._pop._shadow._distance+', add=1);" id="sh_'+this._id+'" align="left"><div  onmouseout="hideAll('+this._parent._name+')"></div></div>';else
+result+='<div style="position:absolute;visibility:hidden;" id="sh_'+this._id+'" align="left"></div>';}
+if(is_ie)
+{
+	var lineHeight = this._items.length*26;
+	var lineWidth = this._itemWidth * 1.074;
+	if(lineHeight > 200)
+		lineHeight = 200;
+	sizeMenu="display:none;height:"+lineHeight+"px;overflow-x:hidden;overflow-y:auto;width:" + lineWidth + "px;";
+}
+else
+	sizeMenu="display:none;max-height:50%;overflow:auto;width:" + this._itemWidth +"px;";
+
+result+='<div class="TPopUp'+this._parent._index+'" id="'+this._id+'" style='+sizeMenu+'"background:#FFFFFF;filter:alpha(opacity='+this._parent._pop._alpha+');">';for(var i=0;i<=this._itemIndex;i++)
+{
+if(this._items[i]._label !='-')
+{
+if(this._items[i]._itemIndex >-1)
+{
+result+='<div style="border-right:1px solid #FFFFFF;width:91%" class="TPopUpItem'+this._items[i]._parent._index+'" id="di_'+this._items[i]._id+'">';
+result+='<table border=0 class="TPopUpItem'+this._items[i]._parent._index+'" cellspacing="0" cellpadding="2"';
+result+=' onmouseover="onPopItemMOver(event,this,\''+this._items[i]._id+'\','+level+','+this._items[i]._parent._name+',\''+this._items[i]._status+'\')"';
+result+=' onmouseout="onPopItemMOut(event,this,\''+this._items[i]._id+'\','+this._items[i]._parent._name+')"';
+result+=' id="pr_'+this._items[i]._id+'"><tr>'+this._items[i]._icon+this._items[i]._label+'</td>';
+if(this._items[i]._parent._pop._expandIcon._create)
+	result+='<td nowrap  class="TExpand'+this._items[i]._parent._index+'">'+this._items[i]._parent._pop._expandIcon._symbol;
+
+result+='</tr></table>';result+='</div>';
+}
+else
+{
+if(this._items[i]._type=='h')
+{
+result+='<div class="TPopUpHeader'+this._items[i]._parent._index+'">';result+='<table class="TPopUpHeader'+this._items[i]._parent._index+'" cellspacing="0" cellpadding="2"';result+=' onmouseover="onStaticPopItemMOver(event,'+this._items[i]._parent._name+',\''+this._items[i]._status+'\')"';result+=' onmouseout="onStaticPopItemMOut(event,'+this._items[i]._parent._name+',\''+this._items[i]._status+'\')"';result+='><tr><td nowrap >'+this._items[i]._label;result+='</td></tr></table></div>';
+}else
+{
+result+='<div style="border-right:1px solid #FFFFFF;width:91%" class="TPopUpItem'+this._items[i]._parent._index+'">';
+result+='<table border=0 class="TPopUpItem'+this._items[i]._parent._index+'" cellspacing="0" cellpadding="0" ';
+result+=' onmouseover="onPopItemMOver(event,this,\'\','+level+','+this._items[i]._parent._name+',\''+this._items[i]._status+'\')"';
+result+=' onmouseout="onPopItemMOut(event,this,\'\','+this._items[i]._parent._name+')"';
+result+=' onclick="hideAll('+this._items[i]._parent._name+');'+this._items[i]._eClick+'"';result+='><tr>'+this._items[i]._icon+this._items[i]._label+'</td>';
+//result+='<td nowrap  class="TExpand'+this._items[i]._parent._index+'">';
+result+='</tr></table>';result+='</div>';}
+}
+}
+else
+{
+if(_browser._name=='IE')
+result+='<div style="margin-right:-2px;padding:4px 0px 4px 0px;background-color:'+this._parent._pop._itemBack._color+';" ';else
+result+='<div style="margin-right:0px;padding:4px 0px 4px 0px;background-color:'+this._parent._pop._itemBack._color+';" ';
+result+=' onmouseover="onStaticPopItemMOver(event,'+this._parent._name+',\'\')"';result+=' onmouseout="onStaticPopItemMOut(event,'+this._parent._name+',\'\')"';
+result+=' ><div class="TSeparator'+this._parent._index+'" ';result+='></div></div>';}
+}
+result+='</div>';}
+return result;}
+function AddItem(popMenu)
+{
+this._itemIndex++;this._items[this._itemIndex]=popMenu;}
+function InitPopMenu(zIndex)
+{
+if(this._itemIndex >-1)
+{
+for(var i=0;i<=this._itemIndex;i++)
+{
+if(this._items[i]._itemIndex >-1)
+{
+if(document.all)
+{
+var pr_el=document.all('pr_'+this._items[i]._id);var el=document.all(this._items[i]._id);}
+else if(document.getElementById)
+{
+var pr_el=document.getElementById('pr_'+this._items[i]._id);var el=document.getElementById(this._items[i]._id);}
+zIndex++;el.style.zIndex=zIndex+1;if(this._items[i]._parent._pop._shadow._create)
+{
+if(document.all)
+var sh_el=document.all('sh_'+this._items[i]._id);else if(document.getElementById)
+var sh_el=document.getElementById('sh_'+this._items[i]._id);if(_browser._name=='IE')
+{
+sh_el.style.width=el.offsetWidth+10+'px';sh_el.style.height=el.offsetHeight+10+'px';sh_el.childNodes[0].style.width=el.offsetWidth+'px';sh_el.childNodes[0].style.height=el.offsetHeight+'px';sh_el.childNodes[0].style.backgroundColor=this._items[i]._parent._pop._shadow._color;}
+else
+{
+sh_el.style.width=el.offsetWidth ;sh_el.style.height=el.offsetHeight;sh_el.style.backgroundColor=this._items[i]._parent._pop._shadow._color;}
+sh_el.style.zIndex=zIndex;}
+this._items[i].Init(zIndex+1);}
+}
+}
+}
+function BuildPopUpMenu(popMenu,level)
+{
+var result="";level++;for(var i=0;i<=popMenu._itemIndex;i++)
+{
+result+=popMenu._items[i].Draw(level);result+=BuildPopUpMenu(popMenu._items[i],level);}
+return result;}
+function BuildStyle()
+{
+var result='';var tyH;var tyW;result+='<style type="text/css">';result+='table.TMenu'+this._index+'{';result+='cursor:pointer;cursor:hand';result+=';visibility:hidden';result+=';position:'+this._position;tyW=typeof(this._width);if(tyW=='string')
+{
+this._width=this._width.toLowerCase();if(this._width !='auto' || this._width !='')
+result+=';width:'+this._width+'px';}
+else
+result+=';width:'+this._width+'px';
+result+=';border-top:'+this._border._top;result+=';border-right:'+this._border._right;result+=';border-bottom:'+this._border._bottom;result+=';border-left:'+this._border._left;result+=';background-color:'+this._background._color;result+=';background-image:'+this._background._image;result+=';background-position:'+this._background._position;result+=';background-repeat:'+this._background._repeat;result+=';}';result+='table.TMenuItemChild'+this._index+'{';result+='width:100%';result+=';font-family:'+this._font._family;result+=';font-size:'+this._font._size;result+=';cursor:pointer;cursor:hand;font-weight:'+this._itemText._weight;result+=';text-align:'+this._itemText._align;result+=';color:'+this._itemText._color;result+=';text-decoration:'+this._itemText._decoration;result+=';white-space:'+this._itemText._whiteSpace;result+=';}';
+result+='td.TMenuItem'+this._index+'{';result+='padding: 0px 0px 0px 0px';tyH=typeof(this._itemHeight);tyW=typeof(this._itemWidth);if(tyH=='string')
+{
+if(this._itemHeight.toLowerCase() !='auto' || this._itemHeight !='')
+result+=';height:'+this._itemHeight+'px';}
+else
+result+=';height:'+this._itemHeight+'px';if(tyW=='string')
+{
+if(this._itemWidth.toLowerCase() !='auto' || this._itemWidth !='')
+result+=';width:'+this._itemWidth+'px';
+}
+else;
+//result+=';width:'+this._itemWidth+'px';
+result+=';border-top:'+this._itemBorder._top;result+=';border-right:'+this._itemBorder._right;result+=';border-bottom:'+this._itemBorder._bottom;result+=';border-left:'+this._itemBorder._left;result+=';background-color:'+this._itemBack._color;result+=';background-repeat:'+this._itemBack._repeat;result+=';background-image:'+this._itemBack._image;result+=';background-position:'+this._itemBack._position;result+=';}';result+='td.TMMExpand'+this._index+'{';result+='width:10px';result+=';text-align:right';result+=';padding-right:2px';result+=';font-family:'+this._expandIcon._font._family;result+=';font-size:'+this._expandIcon._font._size;result+=';font-weight:normal';result+=';text-decoration:none !important';result+=';white-space:nowrap !important';result+=';}';result+='td.TMMHeader'+this._index+'{';result+='height:1px';result+=';cursor:pointer;cursor:hand;background-color:'+this._header._background._color;result+=';background-image:'+this._header._background._image;result+=';background-position:'+this._header._background._position;result+=';background-repeat:'+this._header._background._repeat;result+=';text-align:'+this._header._itemText._align;result+=';text-decoration:'+this._header._itemText._decoration;result+=';white-space:'+this._header._itemText._whiteSpace;result+=';font-weight:'+this._header._itemText._weight;result+=';font-family:'+this._header._font._family;result+=';font-size:'+this._header._font._size;result+=';color:'+this._header._itemText._color;result+=';}';result+='div.TPopUp'+this._index+'{';result+='position:absolute';result+=';padding:'+this._pop._padding;result+=';display:none';result+=';width:'+this._pop._itemWidth+'px';result+=';border-top:'+this._pop._border._top;result+=';border-right:'+this._pop._border._right;result+=';border-bottom:'+this._pop._border._bottom;result+=';border-left:'+this._pop._border._left;result+=';background-color:'+this._pop._background._color;result+=';background-image:'+this._pop._background._image;result+=';background-position:'+this._pop._background._position;result+=';background-repeat:'+this._pop._background._repeat;result+=';display:block';result+=';}';result+='table.TPopUpHeader'+this._index+'{';result+='width:100%';result+=';cursor:default';result+=';height:'+this._pop._itemHeight+'px';result+=';text-align:'+this._pop._header._itemText._align;result+=';text-decoration:'+this._pop._header._itemText._decoration;result+=';white-space:'+this._pop._header._itemText._whiteSpace;result+=';font-weight:'+this._pop._header._itemText._weight;result+=';font-family:'+this._pop._header._font._family;result+=';font-size:'+this._pop._header._font._size;result+=';color:'+this._pop._header._itemText._color;result+=';}';result+='div.TPopUpHeader'+this._index+'{';result+=';background-color:'+this._pop._header._background._color;result+=';background-image:'+this._pop._header._background._image;result+=';background-position:'+this._pop._header._background._position;result+=';background-repeat:'+this._pop._header._background._repeat;if(_browser._name=='IE')
+result+=';margin-right:-2px';result+=';}';result+='table.TPopUpItem'+this._index+'{';result+='width:100%';result+=';height:'+this._pop._itemHeight+'px';result+=';cursor:default';result+=';font-family:'+this._pop._font._family;result+=';font-size:'+this._pop._font._size;result+=';color:'+this._pop._itemText._color;result+=';text-align:'+this._pop._itemText._align;result+=';text-decoration:'+this._pop._itemText._decoration;result+=';white-space:'+this._pop._itemText._whiteSpace;result+=';font-weight:'+this._pop._itemText._weight;result+=';}';result+='div.TPopUpItem'+this._index+'{';result+='cursor:pointer;cursor:hand';result+=';background-color:'+this._pop._itemBack._color;result+=';background-image:'+this._pop._itemBack._image;result+=';background-position:'+this._pop._itemBack._position;result+=';background-repeat:'+this._pop._itemBack._repeat;result+=';border-top:'+this._pop._itemBorder._top;result+=';border-right:'+this._pop._itemBorder._right;result+=';border-bottom:'+this._pop._itemBorder._bottom;result+=';border-left:'+this._pop._itemBorder._left;result+=';padding:'+this._pop._itemPadding;result+=';}';result+='div.TPopUpItem'+this._index+'_1{';result+='cursor:default';result+=';background-color :'+this._pop._itemBackHL._color;result+=';background-image:'+this._pop._itemBackHL._image;result+=';background-position:'+this._pop._itemBackHL._position;result+=';background-repeat:'+this._pop._itemBackHL._repeat;result+=';border-top:'+this._pop._itemBorderHL._top;result+=';border-right:'+this._pop._itemBorderHL._right;result+=';border-bottom:'+this._pop._itemBorderHL._bottom;result+=';border-left:'+this._pop._itemBorderHL._left;result+=';padding:'+this._pop._itemPaddingHL;result+=';}';this._pop._separator._width=((this._pop._itemWidth-this._pop._separator._width) < 0)?this._pop._itemWidth:this._pop._separator._width;var _div=Math.floor((this._pop._itemWidth-this._pop._separator._width)/2);switch(this._pop._separator._align)
+{
+case 'left':
+this._pop._separator._margin='0px '+(_div*2)+'px 0px 0px';break;case 'right':
+this._pop._separator._margin='0px 0px 0px '+(_div*2)+'px';break;default:
+this._pop._separator._margin='0px '+_div+'px 0px '+_div+'px';}
+result+='div.TSeparator'+this._index+'{';result+='margin:'+this._pop._separator._margin;result+=';border-top:'+this._pop._separator._border._top;result+=';border-bottom:'+this._pop._separator._border._bottom;result+=';}';result+='td.TExpand'+this._index+'{';result+='width:10px';result+=';text-align:right';result+=';padding-right:2px';result+=';font-family:'+this._pop._expandIcon._font._family;result+=';font-size:'+this._pop._expandIcon._font._size;result+=';font-weight:normal';result+=';text-decoration:none !important';result+=';white-space:nowrap !important';result+=';}';result+='td.TIcon'+this._index+'{';result+='width:24px';result+=';text-align:left';result+=';text-decoration:normal';result+=';white-space:nowrap';result+=';font-weight:normal';result+=';}';result+='img.TIcon'+this._index+'{';result+='vertical-align:middle';result+=';}';result+='</style>';return result;}
+function SetCorrection(dLeft,dTop)
+{
+dLeft=parseInt(dLeft);if(!dLeft)
+this._correction._left=0;else
+this._correction._left=dLeft;dTop=parseInt(dTop);if(!dTop)
+this._correction._top=0;else
+this._correction._top=dTop;}
+function SetPosition(dPosition,dLeft,dTop)
+{
+switch(dPosition)
+{
+case 'absolute':
+this._position=dPosition;break;default:
+this._position='relative';}
+dLeft=parseInt(dLeft);if(!dLeft)
+this._left=0;else
+this._left=dLeft;dTop=parseInt(dTop);if(!dTop)
+this._top=0;else
+this._top=dTop;}
+function SetCellSpacing(dSpace)
+{
+dSpace=parseInt(dSpace);if(!dSpace)
+this._cellSpacing=0;else
+this._cellSpacing=dSpace;}
+function SetWidth(dWidth)
+{
+dWidth=parseInt(dWidth);if(!dWidth)
+this._width='auto';else
+this._width=dWidth;}
+function SetItemDimension(dWidth,dHeight)
+{
+dWidth=parseInt(dWidth);dHeight=parseInt(dHeight);if(!dWidth)
+this._itemWidth='auto';else
+this._itemWidth=dWidth;if(!dHeight)
+this._itemHeight='auto';else
+this._itemHeight=dHeight;}
+function SetBackground(dColor,dImage,dRepeat,dPos)
+{
+(dColor=='')?this._background._color='transparent':this._background._color=dColor;(dImage=='')?this._background._image='none':this._background._image="url('"+dImage+"')";(dRepeat=='')?this._background._repeat='no-repeat':this._background._repeat=dRepeat;(dPos=='')?this._background._position='top left':this._background._position=dPos;}
+function SetItemBackground(dColor,dImage,dRepeat,dPos)
+{
+(dColor=='')?this._itemBack._color='transparent':this._itemBack._color=dColor;(dImage=='')?this._itemBack._image='none':this._itemBack._image="url('"+dImage+"')";(dRepeat=='')?this._itemBack._repeat='no-repeat':this._itemBack._repeat=dRepeat;(dPos=='')?this._itemBack._position='top left':this._itemBack._position=dPos;}
+function SetItemBackgroundHL(dColor,dImage,dRepeat,dPos)
+{
+(dColor=='')?this._itemBackHL._color='transparent':this._itemBackHL._color=dColor;(dImage=='')?this._itemBackHL._image='none':this._itemBackHL._image="url('"+dImage+"')";(dRepeat=='')?this._itemBackHL._repeat='no-repeat':this._itemBackHL._repeat=dRepeat;(dPos=='')?this._itemBackHL._position='top left':this._itemBackHL._position=dPos;}
+function SetItemBackgroundClick(dColor,dImage,dRepeat,dPos)
+{
+(dColor=='')?this._itemBackClick._color='transparent':this._itemBackClick._color=dColor;(dImage=='')?this._itemBackClick._image='none':this._itemBackClick._image="url('"+dImage+"')";(dRepeat=='')?this._itemBackClick._repeat='no-repeat':this._itemBackClick._repeat=dRepeat;(dPos=='')?this._itemBackClick._position='top left':this._itemBackClick._position=dPos;}
+function SetShadow(dCreate,dColor,dDistance)
+{
+if(dCreate)
+{
+this._shadow._create=dCreate;this._shadow._color=dColor;this._shadow._distance=dDistance;}
+}
+function SetFont(dFamily,dSize)
+{
+this._font._family=dFamily;this._font._size=dSize;}
+function SetBorder(dSize,dColor,dType)
+{
+var dBorder=dSize+'px '+dColor+' '+dType;this._border._top=dBorder;this._border._right=dBorder;this._border._bottom=dBorder;this._border._left=dBorder;}
+function SetItemBorder(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorder._top=dBorder;this._itemBorder._right=dBorder;this._itemBorder._bottom=dBorder;this._itemBorder._left=dBorder;}
+function SetItemBorderHL(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderHL._top=dBorder;this._itemBorderHL._right=dBorder;this._itemBorderHL._bottom=dBorder;this._itemBorderHL._left=dBorder;}
+function SetItemBorderClick(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderClick._top=dBorder;this._itemBorderClick._right=dBorder;this._itemBorderClick._bottom=dBorder;this._itemBorderClick._left=dBorder;}
+function SetBorderTop(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._border._top=dBorder;}
+function SetItemBorderTop(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorder._top=dBorder;}
+function SetItemBorderTopHL(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderHL._top=dBorder;}
+function SetItemBorderTopClick(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderClick._top=dBorder;}
+function SetBorderRight(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._border._right=dBorder;}
+function SetItemBorderRight(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorder._right=dBorder;}
+function SetItemBorderRightHL(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderHL._right=dBorder;}
+function SetItemBorderRightClick(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderClick._right=dBorder;}
+function SetBorderBottom(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._border._bottom=dBorder;}
+function SetItemBorderBottom(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorder._bottom=dBorder;}
+function SetItemBorderBottomHL(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderHL._bottom=dBorder;}
+function SetItemBorderBottomClick(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderClick._bottom=dBorder;}
+function SetBorderLeft(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._border._left=dBorder;}
+function SetItemBorderLeft(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorder._left=dBorder;}
+function SetItemBorderLeftHL(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderHL._left=dBorder;}
+function SetItemBorderLeftClick(dSize,dColor,dType)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dBorder=dSize+'px '+dColor+' '+dType;this._itemBorderClick._left=dBorder;}
+function SetItemText(dColor,dAlign,dWeight,dDecoration,dWSpace)
+{
+this._itemText._color=dColor;(dAlign=='')?this._itemText._align='left':this._itemText._align=dAlign;(dWeight=='')?this._itemText._weight='normal':this._itemText._weight=dWeight;(dDecoration=='')?this._itemText._decoration='none':this._itemText._decoration=dDecoration;(dWSpace=='')?this._itemText._whiteSpace='normal':this._itemText._whiteSpace=dWSpace;}
+function SetItemTextHL(dColor,dAlign,dWeight,dDecoration,dWSpace)
+{
+this._itemTextHL._color=dColor;(dAlign=='')?this._itemTextHL._align='left':this._itemTextHL._align=dAlign;(dWeight=='')?this._itemTextHL._weight='normal':this._itemTextHL._weight=dWeight;(dDecoration=='')?this._itemTextHL._decoration='none':this._itemTextHL._decoration=dDecoration;(dWSpace=='')?this._itemTextHL._whiteSpace='normal':this._itemTextHL._whiteSpace=dWSpace;}
+function SetItemTextClick(dColor,dAlign,dWeight,dDecoration,dWSpace)
+{
+this._itemTextClick._color=dColor;(dAlign=='')?this._itemTextClick._align='left':this._itemTextClick._align=dAlign;(dWeight=='')?this._itemTextClick._weight='normal':this._itemTextClick._weight=dWeight;(dDecoration=='')?this._itemTextClick._decoration='none':this._itemTextClick._decoration=dDecoration;(dWSpace=='')?this._itemTextClick._whiteSpace='normal':this._itemTextClick._whiteSpace=dWSpace;}
+function SetPaddings(dSize)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dPad=dSize+'px '+dSize+'px '+dSize+'px '+dSize+'px';this._padding=dPad;}
+function SetItemPaddingsHL(dSize)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dPad=dSize+'px '+dSize+'px '+dSize+'px '+dSize+'px';this._itemPaddingHL=dPad;}
+function SetItemPaddings(dSize)
+{
+dSize=parseInt(dSize);if(!dSize)
+dSize=0;var dPad=dSize+'px '+dSize+'px '+dSize+'px '+dSize+'px';this._itemPadding=dPad;}
+function SetPadding(dTop,dRight,dBottom,dLeft)
+{
+dTop=parseInt(dTop);dRight=parseInt(dRight);dBottom=parseInt(dBottom);dLeft=parseInt(dLeft);if(!dTop) dTop=0;if(!dRight) dRight=0;if(!dBottom) dBottom=0;if(!dLeft) dLeft=0;var dPad=dTop+'px '+dRight+'px '+dBottom+'px '+dLeft+'px';this._padding=dPad;}
+function SetItemPaddingHL(dTop,dRight,dBottom,dLeft)
+{
+dTop=parseInt(dTop);dRight=parseInt(dRight);dBottom=parseInt(dBottom);dLeft=parseInt(dLeft);if(!dTop) dTop=0;if(!dRight) dRight=0;if(!dBottom) dBottom=0;if(!dLeft) dLeft=0;var dPad=dTop+'px '+dRight+'px '+dBottom+'px '+dLeft+'px';this._itemPaddingHL=dPad;}
+function SetItemPadding(dTop,dRight,dBottom,dLeft)
+{
+dTop=parseInt(dTop);dRight=parseInt(dRight);dBottom=parseInt(dBottom);dLeft=parseInt(dLeft);if(!dTop) dTop=0;if(!dRight) dRight=0;if(!dBottom) dBottom=0;if(!dLeft) dLeft=0;var dPad=dTop+'px '+dRight+'px '+dBottom+'px '+dLeft+'px';this._itemPadding=dPad;}
+function SetSeparator(dWidth,dAlign,dColor1,dColor2)
+{
+dWidth=parseInt(dWidth);if(!dWidth)
+dWidth='auto';this._separator._width=dWidth;this._separator._align=dAlign;this._separator._border._top='1px '+dColor1+' solid';(dColor2=='')?this._separator._border._bottom='0px none solid':this._separator._border._bottom='1px '+dColor2+' solid';}
+function SetExpandIcon(dCreate,dSymbol,dSize)
+{
+if(dCreate)
+{
+this._expandIcon._create=true;switch(dSymbol)
+{
+case '' :
+break;default:
+this._expandIcon._symbol=dSymbol;}
+dSize=parseInt(dSize);if(!dSize)
+dSize=6;this._expandIcon._font._size=dSize+'pt';}
+else
+this._expandIcon._create=false;}
+function SetDelay(dTimeOut)
+{
+dTimeOut=parseInt(dTimeOut);if(!dTimeOut)
+dTimeOut=0;this._timeOut=dTimeOut;}
+function findPosX(obj)
+{
+if(_browser._name=="Konqueror")
+var curleft=0;else
+var curleft=0;if(obj.offsetParent)
+{
+while (obj.offsetParent)
+{
+curleft+=obj.offsetLeft;obj=obj.offsetParent;}
+}
+else if(obj.x)
+curleft+=obj.x;return curleft;}
+function findPosY(obj)
+{
+if(_browser._name=="Konqueror")
+var curtop=0;else
+var curtop=0;if(obj.offsetParent)
+{
+while (obj.offsetParent)
+{
+curtop+=obj.offsetTop;obj=obj.offsetParent;}
+}
+else if(obj.y)
+curtop+=obj.y;return curtop;}
+function findTriggerPopID(elmID,mmObj)
+{
+var result=-1;for(var i=0;i<=_arRegisterTriggerPopIndex[mmObj._index];i++)
+{
+if(_arRegisterTriggerPopID[mmObj._index][i]==elmID)
+{
+result=i;break;}
+}
+return result;}
+function saveTriggerPopID(elmID,mmObj)
+{
+_arRegisterTriggerPopIndex[mmObj._index]++;var j=_arRegisterTriggerPopIndex[mmObj._index];_arRegisterTriggerPopID[mmObj._index][j]=elmID;
+if(document.all)
+var el=document.all(elmID);
+else if(document.getElementById)
+var el=document.getElementById(elmID);
+if(el.className && el.className.indexOf("TMenuItem") !=-1)
+{
+el.style.backgroundColor=mmObj._itemBackClick._color;el.style.backgroundImage=mmObj._itemBackClick._image;el.style.backgroundRepeat=mmObj._itemBackClick._repeat;el.style.backgroundPosition=mmObj._itemBackClick._position;el.childNodes[0].style.color=mmObj._itemTextClick._color;el.childNodes[0].style.textAlign=mmObj._itemTextClick._align;el.childNodes[0].style.textDecoration=mmObj._itemTextClick._decoration;el.childNodes[0].style.whiteSpace=mmObj._itemTextClick._whiteSpace;el.childNodes[0].style.fontWeight=mmObj._itemTextClick._weight;
+el.style.borderTop=mmObj._itemBorderClick._top;el.style.borderRight=mmObj._itemBorderClick._right;el.style.borderBottom=mmObj._itemBorderClick._bottom;el.style.borderLeft=mmObj._itemBorderClick._left;
+}
+else
+{
+el.className="TPopUpItem"+mmObj._index+"_1";}
+}
+function removeTriggerPopID(elmID,mmObj)
+{
+var index=findTriggerPopID(elmID,mmObj);
+if(index >-1)
+{
+for(var i=_arRegisterTriggerPopIndex[mmObj._index];i>=index;i--)
+{
+var ID=_arRegisterTriggerPopID[mmObj._index][i];if(document.all)
+var el=document.all(ID);else if(document.getElementById)
+var el=document.getElementById(ID);if(el.className.indexOf("TMenuItem") !=-1)
+{
+el.style.backgroundColor=mmObj._itemBack._color;el.style.backgroundImage=mmObj._itemBack._image;el.style.backgroundRepeat=mmObj._itemBack._repeat;el.style.backgroundPosition=mmObj._itemBack._position;
+el.childNodes[0].style.color=mmObj._itemText._color;el.childNodes[0].style.textAlign=mmObj._itemText._align;el.childNodes[0].style.textDecoration=mmObj._itemText._decoration;el.childNodes[0].style.whiteSpace=mmObj._itemText._whiteSpace;el.childNodes[0].style.fontWeight=mmObj._itemText._weight;el.style.borderTop=mmObj._itemBorder._top;el.style.borderRight=mmObj._itemBorder._right;el.style.borderBottom=mmObj._itemBorder._bottom;el.style.borderLeft=mmObj._itemBorder._left;}
+else
+{
+var IDLen=ID.length;var tableID='pr_'+ID.substr(3,IDLen);if(document.all)
+var elTable=document.all(tableID);else if(document.getElementById)
+var elTable=document.getElementById(tableID);el.className="TPopUpItem"+mmObj._index;elTable.style.color=mmObj._pop._itemText._color;elTable.style.textAlign=mmObj._pop._itemText._align;elTable.style.textDecoration=mmObj._pop._itemText._decoration;elTable.style.whiteSpace=mmObj._pop._itemText._whiteSpace;elTable.style.fontWeight=mmObj._pop._itemText._weight;}
+_arRegisterTriggerPopID[mmObj._index][i]=null;}
+_arRegisterTriggerPopIndex[mmObj._index]=index-1;}
+}
+function removeTriggerPopIDByIndex(index,mmObj)
+{
+if(_arRegisterTriggerPopIndex[mmObj._index] >-1 && index >-1)
+{
+for(var i=_arRegisterTriggerPopIndex[mmObj._index];i>=index;i--)
+{
+var ID=_arRegisterTriggerPopID[mmObj._index][i];if(document.all)
+var el=document.all(ID);else if(document.getElementById)
+var el=document.getElementById(ID);if(el.className.indexOf("TMenuItem") !=-1)
+{
+el.style.backgroundColor=mmObj._itemBack._color;el.style.backgroundImage=mmObj._itemBack._image;el.style.backgroundRepeat=mmObj._itemBack._repeat;el.style.backgroundPosition=mmObj._itemBack._position;
+el.childNodes[0].style.color=mmObj._itemText._color;el.childNodes[0].style.textAlign=mmObj._itemText._align;el.childNodes[0].style.textDecoration=mmObj._itemText._decoration;el.childNodes[0].style.whiteSpace=mmObj._itemText._whiteSpace;el.childNodes[0].style.fontWeight=mmObj._itemText._weight;
+el.style.borderTop=mmObj._itemBorder._top;el.style.borderRight=mmObj._itemBorder._right;el.style.borderBottom=mmObj._itemBorder._bottom;el.style.borderLeft=mmObj._itemBorder._left;}
+else
+{
+var IDLen=ID.length;var tableID='pr_'+ID.substr(3,IDLen);if(document.all)
+var elTable=document.all(tableID);else if(document.getElementById)
+var elTable=document.getElementById(tableID);
+el.className="TPopUpItem"+mmObj._index;elTable.style.color=mmObj._pop._itemText._color;elTable.style.textAlign=mmObj._pop._itemText._align;elTable.style.textDecoration=mmObj._pop._itemText._decoration;elTable.style.whiteSpace=mmObj._pop._itemText._whiteSpace;elTable.style.fontWeight=mmObj._pop._itemText._weight;
+}
+_arRegisterTriggerPopID[mmObj._index][i]=null;}
+_arRegisterTriggerPopIndex[mmObj._index]=index-1;}
+}
+function removeAllTriggerPopID(mmObj)
+{
+if(_arRegisterTriggerPopIndex[mmObj._index] >-1)
+{
+for(var i=_arRegisterTriggerPopIndex[mmObj._index];i>=0;i--)
+{
+var ID=_arRegisterTriggerPopID[mmObj._index][i];if(document.all)
+var el=document.getElementById(ID);else if(document.getElementById)
+var el=document.getElementById(ID);
+if(el && el.className.indexOf("TMenuItem") !=-1)
+{
+if(_arMMClick[mmObj._index])
+{
+el.style.backgroundColor=mmObj._itemBack._color;el.style.backgroundImage=mmObj._itemBack._image;el.style.backgroundRepeat=mmObj._itemBack._repeat;el.style.backgroundPosition=mmObj._itemBack._position;
+el.childNodes[0].style.color=mmObj._itemText._color;el.childNodes[0].style.textAlign=mmObj._itemText._align;el.childNodes[0].style.textDecoration=mmObj._itemText._decoration;el.childNodes[0].style.whiteSpace=mmObj._itemText._whiteSpace;el.childNodes[0].style.fontWeight=mmObj._itemText._weight;
+el.style.borderTop=mmObj._itemBorder._top;el.style.borderRight=mmObj._itemBorder._right;el.style.borderBottom=mmObj._itemBorder._bottom;el.style.borderLeft=mmObj._itemBorder._left;}
+}
+else
+{
+var IDLen=ID.length;var tableID='pr_'+ID.substr(3,IDLen);if(document.all)
+var elTable=document.all(tableID);else if(document.getElementById)
+var elTable=document.getElementById(tableID);
+if(el)
+	el.className="TPopUpItem"+mmObj._index;
+if(elTable)
+{
+	elTable.style.color=mmObj._pop._itemText._color;
+	elTable.style.textAlign=mmObj._pop._itemText._align;elTable.style.textDecoration=mmObj._pop._itemText._decoration;
+	elTable.style.whiteSpace=mmObj._pop._itemText._whiteSpace;elTable.style.fontWeight=mmObj._pop._itemText._weight;
+}
+}
+_arRegisterTriggerPopID[mmObj._index][i]=null;}
+_arRegisterTriggerPopIndex[mmObj._index]=-1;}
+}
+function findRegisteredPopUpMenuID(elmID,mmObj)
+{
+var result=-1;for(var i=0;i<=_arRegisterPopIndex[mmObj._index];i++)
+{
+if(_arRegisterPopID[mmObj._index][i]==elmID)
+{
+result=i;break;}
+}
+return result;}
+function showPopUpMenu(parentElmID,elmID,mmObj,menuType)
+{
+ mmObj = _mmObj;
+_arRegisterPopIndex[mmObj._index]++;var j=_arRegisterPopIndex[mmObj._index];_arRegisterPopID[mmObj._index][j]=elmID;var leftPos=0;var parentLeftPos=0;var topPos=0;var parentTopPos=0;if(document.all)
+{var elm=document.getElementById(elmID);var parentElm=document.getElementById(parentElmID);}else if(document.getElementById)
+{
+var parentElm=document.getElementById(parentElmID);var elm=document.getElementById(elmID);}
+parentLeftPos=findPosX(parentElm);parentTopPos=findPosY(parentElm);var screenPosY=0;var screenPosX=0;if(window.innerHeight)
+{
+screenPosY=window.pageYOffset;
+screenPosX=window.pageXOffset;
+}
+else if(document.documentElement && document.documentElement.scrollTop)
+{
+screenPosY=document.documentElement.scrollTop;
+screenPosX=document.documentElement.scrollLeft;
+}
+else if(document.body)
+{
+screenPosY=document.body.scrollTop;
+screenPosX=document.body.scrollLeft;
+}
+if(menuType=='mm')
+{
+if(mmObj._direction=='horizontal')
+{
+if((parentLeftPos-elm.offsetWidth-mmObj._correction._left) < 0)
+{
+if(parentLeftPos < screenPosX)
+{
+leftPos=parentLeftPos+parentElm.offsetWidth+mmObj._correction._left-1;}
+else
+leftPos=parentLeftPos+mmObj._correction._left-1;}
+else
+{
+if(parentLeftPos-screenPosX+elm.offsetWidth+mmObj._correction._left > document.body.clientWidth)
+{
+if(parentLeftPos+parentElm.offsetWidth-screenPosX > document.body.clientWidth)
+leftPos=parentLeftPos-elm.offsetWidth-mmObj._correction._left;else
+leftPos=parentLeftPos+parentElm.offsetWidth-elm.offsetWidth-mmObj._correction._left-1;}
+else
+{
+if(parentLeftPos < screenPosX)
+{
+leftPos=parentLeftPos+parentElm.offsetWidth+mmObj._correction._left-1;}
+else
+leftPos=parentLeftPos+mmObj._correction._left-1;}
+}
+if((parentTopPos-screenPosY-elm.offsetHeight-mmObj._correction._top) <0)
+topPos=parentTopPos+parentElm.offsetHeight+1+mmObj._correction._top;else
+{
+if(parentTopPos+parentElm.offsetHeight+elm.offsetHeight-screenPosY+mmObj._correction._top < document.body.clientHeight)
+topPos=parentTopPos+parentElm.offsetHeight+1+mmObj._correction._top;else
+topPos=parentTopPos-elm.offsetHeight-mmObj._correction._top;}
+}
+else
+{
+if(parentLeftPos-screenPosX-elm.offsetWidth-mmObj._correction._left<0)
+leftPos=parentLeftPos+parentElm.offsetWidth+mmObj._correction._left+1;else
+{
+if((parentLeftPos-screenPosX+parentElm.offsetWidth+elm.offsetWidth+mmObj._correction._left) < document.body.clientWidth)
+leftPos=parentLeftPos+parentElm.offsetWidth+mmObj._correction._left+1;else
+leftPos=parentLeftPos-elm.offsetWidth-mmObj._correction._left-1;}
+if(parentTopPos-screenPosY-elm.offsetHeight-mmObj._correction._top < 0)
+{
+if(parentTopPos < screenPosY)
+topPos=parentTopPos+parentElm.offsetHeight+mmObj._correction._top-1;else
+topPos=parentTopPos+mmObj._correction._top-1;
+}
+else
+{
+if(parentTopPos-screenPosY+elm.offsetHeight+mmObj._correction._top < document.body.clientHeight)
+{
+topPos=parentTopPos+mmObj._correction._top-1;}
+else
+{
+if(parentTopPos-screenPosY+parentElm.offsetHeight < document.body.clientHeight)
+topPos=parentTopPos+parentElm.offsetHeight-elm.offsetHeight-mmObj._correction._top+1;else
+topPos=parentTopPos-elm.offsetHeight-mmObj._correction._top+1;}
+}
+}
+if(elm.style){
+
+	elm.style.left=leftPos+'px';
+	elm.style.top = topPos+'px';
+}
+if(mmObj._pop._shadow._create)
+{
+if(document.all)
+var shadowElm=document.all('sh_'+elmID);else if(document.getElementById)
+var shadowElm=document.getElementById('sh_'+elmID);if(_browser._name=='IE')
+{
+shadowElm.style.left=leftPos+'px';shadowElm.style.top=topPos+'px';}
+else
+{
+shadowElm.style.left=leftPos+mmObj._pop._shadow._distance+'px';shadowElm.style.top=topPos+mmObj._pop._shadow._distance+'px';}
+shadowElm.style.visibility='visible';}
+}
+else
+{
+topPos=parentTopPos;leftPos=parentLeftPos+parentElm.offsetWidth;if(topPos-elm.offsetHeight < 0)
+topPos=topPos+mmObj._pop._correction._top;else
+{
+if(topPos-screenPosY+elm.offsetHeight < document.body.clientHeight)
+topPos=topPos+mmObj._pop._correction._top-2;else
+topPos=topPos-elm.offsetHeight+parentElm.offsetHeight+mmObj._pop._correction._top+2;}
+if((leftPos-((elm.offsetWidth+mmObj._pop._correction._left+1) * 2)) < 0)
+leftPos=leftPos+mmObj._pop._correction._left-3;else
+{
+if((leftPos-screenPosX+elm.offsetWidth+mmObj._pop._correction._left) > document.body.clientWidth)
+leftPos=leftPos-parentElm.offsetWidth-elm.offsetWidth-mmObj._pop._correction._left+5;else
+leftPos=leftPos+mmObj._pop._correction._left-3;}
+elm.style.top=topPos+'px';elm.style.left=leftPos+'px';if(mmObj._pop._shadow._create)
+{
+if(document.all)
+var shadowElm=document.all('sh_'+elmID);else if(document.getElementById)
+var shadowElm=document.getElementById('sh_'+elmID);if(_browser._name=='IE')
+{
+shadowElm.style.left=leftPos+'px';shadowElm.style.top=topPos+'px';}
+else
+{
+shadowElm.style.left=leftPos+mmObj._pop._shadow._distance+'px';shadowElm.style.top=topPos+mmObj._pop._shadow._distance+'px';}
+shadowElm.style.visibility='visible';}
+}
+
+if(elm.style){
+	elm.style.visibility="visible";
+	elm.style.display="";
+}
+}
+function hidePopUpMenu(elmID,mmObj)
+{
+var index=findRegisteredPopUpMenuID(elmID,mmObj);if(index >-1)
+{
+for(var i=_arRegisterPopIndex[mmObj._index];i>=index;i--)
+{
+var ID=_arRegisterPopID[mmObj._index][i];if(document.all)
+document.all(ID).style.visibility="hidden";else if(document.getElementById){
+document.getElementById(ID).style.visibility="hidden";
+document.getElementById(ID).style.display="none";
+}
+if(mmObj._pop._shadow._create)
+{
+if(document.all)
+document.all('sh_'+ID).style.visibility="hidden";else if(document.getElementById)
+document.getElementById('sh_'+ID).style.visibility="hidden";}
+}
+_arRegisterPopIndex[mmObj._index]=index-1;
+}
+}
+function hidePopUpMenuByIndex(index,mmObj)
+{
+if(_arRegisterPopIndex[mmObj._index] >=index)
+{
+for(var i=_arRegisterPopIndex[mmObj._index];i>=index;i--)
+{
+var ID=_arRegisterPopID[mmObj._index][i];if(document.all)
+document.all(ID).style.visibility="hidden";else if(document.getElementById){
+document.getElementById(ID).style.visibility="hidden";
+document.getElementById(ID).style.display="none";
+}
+if(mmObj._pop._shadow._create)
+{
+if(document.all)
+document.all('sh_'+ID).style.visibility="hidden";else if(document.getElementById)
+document.getElementById('sh_'+ID).style.visibility="hidden";}
+}
+_arRegisterPopIndex[mmObj._index]=index-1;}
+}
+function hideAllPopUpMenu(mmObj)
+{
+var index=_arRegisterPopIndex[mmObj._index];if(index >-1)
+{
+for(i=index;i>=0;i--)
+{
+var ID=_arRegisterPopID[mmObj._index][i];
+if(document.all && document.all(ID).style)
+document.all(ID).style.visibility="hidden";
+else if(document.getElementById){
+	if (document.getElementById(ID)){
+		document.getElementById(ID).style.visibility="hidden";
+		document.getElementById(ID).style.display="none";
+	}
+}
+if(mmObj._pop._shadow._create){
+	if (document.getElementById('sh_'+ID))
+		document.getElementById('sh_'+ID).style.visibility="hidden";
+}
+}
+}
+_arRegisterPopIndex[mmObj._index]=-1;}
+function triggerHideAll(mmObj)
+{
+_arTriggerMenu[mmObj._index]=window.setTimeout('hideAll('+mmObj._name+')',mmObj._pop._timeOut);}
+function clearTriggerHideAll(mmObj)
+{
+window.clearTimeout(_arTriggerMenu[mmObj._index]);}
+function hideAll(mmObj)
+{
+hideAllPopUpMenu(mmObj);removeAllTriggerPopID(mmObj);if(mmObj._popOnClick)
+_arMMClick[mmObj._index]=false;else
+_arMMClick[mmObj._index]=true;window.status='';mmObj._hideObject.Show();}
+function onMainClick(event,elm,popID,mmObj)
+{
+if(!_arMMClick[mmObj._index])
+{
+_arMMClick[mmObj._index]=true;if(popID !='')
+{
+showPopUpMenu(elm.id,popID,mmObj,'mm');saveTriggerPopID(elm.id,mmObj);}
+}
+else
+{
+_arMMClick[mmObj._index]=false;hideAllPopUpMenu(mmObj);removeAllTriggerPopID(mmObj);elm.style.backgroundColor=mmObj._itemBackHL._color;elm.style.backgroundImage=mmObj._itemBackHL._image;elm.style.backgroundRepeat=mmObj._itemBackHL._repeat;elm.style.backgroundPosition=mmObj._itemBackHL._position;
+elm.childNodes[0].style.color=mmObj._itemTextHL._color;elm.childNodes[0].style.textAlign=mmObj._itemTextHL._align;elm.childNodes[0].style.textDecoration=mmObj._itemTextHL._decoration;elm.childNodes[0].style.whiteSpace=mmObj._itemTextHL._whiteSpace;elm.childNodes[0].style.fontWeight=mmObj._itemTextHL._weight;
+elm.style.borderTop=mmObj._itemBorderHL._top;elm.style.borderRight=mmObj._itemBorderHL._right;elm.style.borderBottom=mmObj._itemBorderHL._bottom;elm.style.borderLeft=mmObj._itemBorderHL._left;}
+mmObj._hideObject.Hide();onBubble(event);}
+function onMainMOver(event,elm,popID,level,mmObj,status,onclicked)
+{
+hideAllPopUpMenu(_mmObj);removeAllTriggerPopID(_mmObj);window.status=unescape(status);clearTriggerHideAll(mmObj);
+if(_arRegisterTriggerPopID[mmObj._index][0] !=elm.id)
+{
+if(_arRegisterTriggerPopID[mmObj._index][0] !=null)
+{
+removeAllTriggerPopID(mmObj);}
+if(_arMMClick[mmObj._index])
+{
+hideAllPopUpMenu(mmObj);removeAllTriggerPopID(mmObj);
+if(popID !='')
+{
+_mmObj = mmObj;
+if(onclicked){
+	if(_aId){
+		clearTimeout(_aId);
+		_aId = null;
+	}
+	showPopUpMenu(elm.id,popID,'','mm');
+}
+else
+	_aId = window.setTimeout("showPopUpMenu('"+elm.id+"','"+popID+"','','mm');",500);
+
+saveTriggerPopID(elm.id,mmObj);
+}
+else
+	_popId = '';
+if(mmObj._popOnClick)
+{
+elm.style.backgroundColor=mmObj._itemBackClick._color;elm.style.backgroundImage=mmObj._itemBackClick._image;elm.style.backgroundRepeat=mmObj._itemBackClick._repeat;elm.style.backgroundPosition=mmObj._itemBackClick._position;
+elm.childNodes[0].style.color=mmObj._itemTextClick._color;elm.childNodes[0].style.textAlign=mmObj._itemTextClick._align;elm.childNodes[0].style.textDecoration=mmObj._itemTextClick._decoration;elm.childNodes[0].style.whiteSpace=mmObj._itemTextClick._whiteSpace;elm.childNodes[0].style.fontWeight=mmObj._itemTextClick._weight;
+elm.style.borderTop=mmObj._itemBorderClick._top;elm.style.borderRight=mmObj._itemBorderClick._right;elm.style.borderBottom=mmObj._itemBorderClick._bottom;elm.style.borderLeft=mmObj._itemBorderClick._left;
+}else
+{
+elm.style.backgroundColor=mmObj._itemBackHL._color;elm.style.backgroundImage=mmObj._itemBackHL._image;elm.style.backgroundRepeat=mmObj._itemBackHL._repeat;elm.style.backgroundPosition=mmObj._itemBackHL._position;
+elm.childNodes[0].style.color=mmObj._itemTextHL._color;elm.childNodes[0].style.textAlign=mmObj._itemTextHL._align;elm.childNodes[0].style.textDecoration=mmObj._itemTextHL._decoration;elm.childNodes[0].style.whiteSpace=mmObj._itemTextHL._whiteSpace;elm.childNodes[0].style.fontWeight=mmObj._itemTextHL._weight;
+elm.style.borderTop=mmObj._itemBorderHL._top;elm.style.borderRight=mmObj._itemBorderHL._right;elm.style.borderBottom=mmObj._itemBorderHL._bottom;elm.style.borderLeft=mmObj._itemBorderHL._left;
+mmObj._hideObject.Hide();}
+}
+else
+{
+elm.style.backgroundColor=mmObj._itemBackHL._color;elm.style.backgroundImage=mmObj._itemBackHL._image;elm.style.backgroundRepeat=mmObj._itemBackHL._repeat;elm.style.backgroundPosition=mmObj._itemBackHL._position;
+elm.childNodes[0].style.color=mmObj._itemTextHL._color;elm.childNodes[0].style.textAlign=mmObj._itemTextHL._align;elm.childNodes[0].style.textDecoration=mmObj._itemTextHL._decoration;elm.childNodes[0].style.whiteSpace=mmObj._itemTextHL._whiteSpace;elm.childNodes[0].style.fontWeight=mmObj._itemTextHL._weight;elm.style.borderTop=mmObj._itemBorderHL._top;elm.style.borderRight=mmObj._itemBorderHL._right;elm.style.borderBottom=mmObj._itemBorderHL._bottom;elm.style.borderLeft=mmObj._itemBorderHL._left;
+}
+}
+onBubble(event);}
+function onBubble(event)
+{
+if(!event)
+var event=window.event;event.cancelBubble=true;if(event.stopPropagation)
+event.stopPropagation();}
+function onMainMOut(event,elm,popID,mmObj)
+{
+if(_aId) clearTimeout(_aId);
+if(!_arMMClick[mmObj._index] || popID=='')
+{
+elm.style.backgroundColor=mmObj._itemBack._color;elm.style.backgroundImage=mmObj._itemBack._image;elm.style.backgroundRepeat=mmObj._itemBack._repeat;elm.style.backgroundPosition=mmObj._itemBack._position;
+elm.childNodes[0].style.color=mmObj._itemText._color;elm.childNodes[0].style.textAlign=mmObj._itemText._align;elm.childNodes[0].style.textDecoration=mmObj._itemText._decoration;elm.childNodes[0].style.whiteSpace=mmObj._itemText._whiteSpace;elm.childNodes[0].style.fontWeight=mmObj._itemText._weight;elm.style.borderTop=mmObj._itemBorder._top;elm.style.borderRight=mmObj._itemBorder._right;elm.style.borderBottom=mmObj._itemBorder._bottom;elm.style.borderLeft=mmObj._itemBorder._left;}
+triggerHideAll(mmObj);
+onBubble(event);
+}
+function onStaticPopItemMOver(event,mmObj,status)
+{
+window.status=status;clearTriggerHideAll(mmObj);onBubble(event);}
+function onStaticPopItemMOut(event,mmObj)
+{
+triggerHideAll(mmObj);onBubble(event);}
+function onPopItemMOver(event,elm,popID,level,mmObj,status)
+{
+
+var index=-1;window.status=status;clearTriggerHideAll(mmObj);
+elm.parentNode.className='TPopUpItem'+mmObj._index+'_1';elm.style.color=mmObj._pop._itemTextHL._color;elm.style.textAlign=mmObj._pop._itemTextHL._align;elm.style.textDecoration=mmObj._pop._itemTextHL._decoration;elm.style.whiteSpace=mmObj._pop._itemTextHL._whiteSpace;elm.style.fontWeight=mmObj._pop._itemTextHL._weight;
+if(popID !='')
+{
+index=findRegisteredPopUpMenuID(popID,mmObj);if(index==-1)
+{
+hidePopUpMenuByIndex(level,mmObj);removeTriggerPopIDByIndex(level,mmObj);
+showPopUpMenu(elm.id,popID,mmObj,'pm');saveTriggerPopID('di_'+popID,mmObj);}
+}
+else
+{
+hidePopUpMenuByIndex(level,mmObj);removeTriggerPopIDByIndex(level,mmObj);}
+onBubble(event);}
+function onPopItemMOut(event,elm,popID,mmObj)
+{
+if(popID=='' && mmObj._pop)
+{
+
+elm.parentNode.className='TPopUpItem'+mmObj._index;
+elm.style.color=mmObj._pop._itemText._color;
+elm.style.textAlign=mmObj._pop._itemText._align;
+elm.style.textDecoration=mmObj._pop._itemText._decoration;
+elm.style.whiteSpace=mmObj._pop._itemText._whiteSpace;
+elm.style.fontWeight=mmObj._pop._itemText._weight;
+}
+else if(!mmObj._pop)
+	 return;
+//triggerHideAll(mmObj);
+onBubble(event);}
+window.onload=Initialize;window.onresize=InitResize;if(_browser._name=='Netscape' && _browser._version==4)
+window.captureEvents(event.RESIZE);
+var _mmHeaderMoveObj;var _mmHeaderMoveObjCorrectionX=0;var _mmHeaderMoveObjCorrectionY=0;function onMMHeaderMove(event)
+{
+if(!event)
+event=window.event;var xPos=(event.clientX) ? event.clientX : event.pageX;
+var yPos=(event.clientY) ? event.clientY : event.pageY;
+xPos=parseInt(xPos);if(!xPos) xPos=0;yPos=parseInt(yPos);if(!yPos) yPos=0;if(document.all)
+var frElm=document.all('fr_'+_mmHeaderMoveObj._id);else if(document.getElementById)
+var frElm=document.getElementById('fr_'+_mmHeaderMoveObj._id);xPos=xPos-_mmHeaderMoveObjCorrectionX;yPos=yPos-_mmHeaderMoveObjCorrectionY;if(_mmHeaderMoveObj._shadow._create)
+{
+if(document.all)
+var shElm=document.all('sh_'+_mmHeaderMoveObj._id);else if(document.getElementById)
+var shElm=document.getElementById('sh_'+_mmHeaderMoveObj._id);if(_browser._name=='IE')
+{
+shElm.style.left=xPos;shElm.style.top=yPos;}
+else
+{
+shElm.style.left=xPos+_mmHeaderMoveObj._shadow._distance;shElm.style.top=yPos+_mmHeaderMoveObj._shadow._distance;}
+}
+frElm.style.left=xPos;frElm.style.top=yPos;}
+function onMMDocumentClick(event)
+{
+onMMHeaderClick(event,_mmHeaderMoveObj);}
+function onMMHeaderClick(event,mmObj)
+{
+if(!event)
+event=window.event;if((_browser._name=='IE') || (_browser._name=='Konqueror'))
+{
+var xPos=event.clientX;var yPos=event.clientY;}
+else
+{
+var xPos=event.pageX;var yPos=event.pageY;}
+if(document.all)
+{
+var elm=document.all(mmObj._id);var frElm=document.all('fr_'+mmObj._id);}
+else if(document.getElementById)
+{
+var elm=document.getElementById(mmObj._id);var frElm=document.getElementById('fr_'+mmObj._id);}
+if(mmObj._headerClickState)
+{
+mmObj._headerClickState=false;document.onmousemove=null;_mmHeaderMoveObj=null;if(_browser._name=='Netscape' && _browser._version==4)
+window.releaseEvents(event.MOUSEMOVE);elm.style.top=frElm.style.top;elm.style.left=frElm.style.left;mmObj._left=xPos-_mmHeaderMoveObjCorrectionX;mmObj._top=yPos-_mmHeaderMoveObjCorrectionY;frElm.style.visibility='hidden';elm.style.visibility='visible';frElm.style.display='none';elm.style.display='';}
+else
+{
+_mmHeaderMoveObjCorrectionX=xPos-mmObj._left;_mmHeaderMoveObjCorrectionY=yPos-mmObj._top;elm.style.visibility='hidden';frElm.style.visibility='visible';elm.style.display='none';frElm.style.display='';mmObj._headerClickState=true;_mmHeaderMoveObj=mmObj;document.onmousemove=onMMHeaderMove;if(_browser._name=='Netscape' && _browser._version==4)
+window.captureEvents(event.MOUSEMOVE);
+clearTriggerHideAll(mmObj);
+hideAll(mmObj);}
+onBubble(event);}
+function _floatingMMEffect(mmObj)
+{
+var posX=0;var posY=0;if(window.innerHeight)
+{
+posY=window.pageYOffset;
+posX=window.pageXOffset;
+}
+else if(document.documentElement && document.documentElement.scrollTop)
+{
+posX=document.documentElement.scrollLeft;
+posY=document.documentElement.scrollTop;
+}
+else if(document.body)
+{
+posX=document.body.scrollLeft;
+posY=document.body.scrollTop;
+}
+if(document.all)
+{
+var elm=document.all(mmObj._id);var shadowElm=document.all('sh_'+mmObj._id);}
+else if(document.getElementById)
+{
+var elm=document.getElementById(mmObj._id);var shadowElm=document.getElementById('sh_'+mmObj._id);}
+if(posY < mmObj._initialTop)
+posY=mmObj._initialTop;else posY+=mmObj._initialTop;if(posY==mmObj._top)
+{
+elm.style.top=posY;if(mmObj._shadow._create)
+{
+if(_browser._name=='IE')
+shadowElm.style.top=posY;else
+shadowElm.style.top=posY+mmObj._shadow._distance;}
+}
+mmObj._top=posY;if(posX < mmObj._initialLeft)
+posX=mmObj._initialLeft;else posX+=mmObj._initialLeft;if(posX==mmObj._left)
+{
+elm.style.left=posX;if(mmObj._shadow._create)
+{
+if(_browser._name=='IE')
+shadowElm.style.left=posX;else
+shadowElm.style.left=posX+mmObj._shadow._distance;}
+}
+mmObj._left=posX;temp=setTimeout('_floatingMMEffect('+mmObj._name+')',500);}
+function _openURL(address)
+{
+self.location=address;}
+function OutputAllMenuPosition(mmObj)
+{
+var result='';var dTop=0;var dLeft=0;for(var i=0;i<=mmObj._itemIndex;i++)
+{
+if(document.all)
+{
+var elm=document.all('pr_'+mmObj._items[i]._id);}else if(document.getElementById)
+{
+var elm=document.getElementById('pr_'+mmObj._items[i]._id);}
+dTop=findPosY(elm);dLeft=findPosX(elm);result+='pr_'+mmObj._items[i]._id+' : top='+dTop+',left='+dLeft+'<br>';result+=OutputAllPopMenuPosition('--',mmObj._items[i])
+}
+return result;}
+function OutputAllPopMenuPosition(prefix,pmObj)
+{
+var result='';var dTop=0;var dLeft=0;prefix=prefix+'--';for(var i=0;i<=pmObj._itemIndex;i++)
+{
+if((pmObj._items[i]._label=='-') || (pmObj._items[i]._type=='h') || (pmObj._items[i]._itemIndex==-1))
+{
+dTop=0;dLeft=0;}
+else
+{
+dTop=0;dLeft=0;if(document.all)
+{
+var elm=document.all('di_'+pmObj._items[i]._id);}else if(document.getElementById)
+{
+var elm=document.getElementById('di_'+pmObj._items[i]._id);}
+dTop=findPosY(elm);dLeft=findPosX(elm);}
+result+=prefix+' label : '+pmObj._items[i]._label+' : top='+dTop+',left='+dLeft+'<br>';result+=OutputAllPopMenuPosition(prefix,pmObj._items[i]);}
+return result;}
Index: /sandbox/workflow/branches/993/js/jscode/participants.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/participants.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/participants.js	(revision 795)
@@ -0,0 +1,353 @@
+var participantsClone = null;
+var searchTimer = null;
+var globalSearchEnter = true;
+
+function callAjax(action, mode, handler, parameters)
+{
+	var url = '$this.' + action + '.' + mode;
+	if (parameters)
+		cExecute(url, handler, $H(parameters).toQueryString());
+	else
+		cExecute(url, handler);
+}
+
+function getSectors()
+{
+	function resultGetSectors(data)
+	{
+		setSelectValue($('sector'), data['sectors']);
+		$('sector').onchange = getParticipants;
+		resultGetParticipants(data['participants']);
+	}
+
+	var params = {
+		organization: $F('organization'),
+		entities: $F('entities'),
+		id: $F('id'),
+		usePreffix: $F('usePreffix')
+	};
+	callAjax('bo_participants', 'getSectors', resultGetSectors, params);
+}
+
+function getParticipants()
+{
+	var params = {
+		context: $F('sector'),
+		entities: $F('entities'),
+		id: $F('id'),
+		usePreffix: $F('usePreffix')
+	};
+	callAjax('bo_participants', 'getEntities', resultGetParticipants, params);
+}
+
+function resultGetParticipants(data)
+{
+	$('search').value = '';
+	setSelectValue($('participants'), data);
+	participantsClone = data;
+}
+
+function searchParticipantsTimer(e)
+{
+	if (checkShortcuts((e) ? e : window.event))
+		return true;
+
+	if (searchTimer)
+		clearTimeout(searchTimer);
+
+	searchTimer = setTimeout(function(){searchParticipants($F('search'));}, 250);
+}
+
+function searchParticipants(searchString)
+{
+	var reg = new RegExp("<option[^>]*>[^<]*" + searchString + "[^<]*<\/option>", "gi");
+	setSelectValue($('participants'), participantsClone.match(reg));
+
+	var participants = $('participants');
+	if (participants.options[0])
+		participants.selectedIndex = 0;
+}
+
+function checkShortcuts(e)
+{
+	var whichCode = (e.which) ? e.which : e.keyCode;
+	var handled = false;
+
+	if (whichCode == 13) /* ENTER */
+	{
+		$('addUserLink').onclick();
+		handled = true;
+	}
+
+	if (whichCode == 27) /* ESC */
+	{
+		$('exitLink').onclick();
+		handled = true;
+	}
+
+	if (whichCode == 38) /* key up */
+	{
+		var participants = $('participants');
+		if (participants.selectedIndex > 0)
+			if (!participants[participants.selectedIndex - 1].disabled)
+				participants.selectedIndex--;
+		handled = true;
+	}
+
+	if (whichCode == 40) /* key down */
+	{
+		var participants = $('participants');
+		if (participants.selectedIndex < participants.length - 1)
+			if (!participants[participants.selectedIndex + 1].disabled)
+				participants.selectedIndex++;
+		handled = true;
+	}
+
+	return handled;
+}
+
+if (Event.observe)
+{
+	Event.observe(window, 'load', function() {
+		if (typeof Prototype == 'undefined')
+			return;
+		/* atribui as ações aos eventos */
+		var obj = $('organization');
+		if (obj)
+			obj.onchange = getSectors;
+
+		obj = $('sector');
+		if (obj)
+			obj.onchange = getParticipants;
+
+		obj = $('search');
+		if (obj)
+			obj.onkeydown = searchParticipantsTimer;
+
+		obj = $('participants');
+		if (obj)
+			participantsClone = obj.innerHTML;
+
+		obj = $('exitLink');
+		if (obj)
+			obj.onclick = function(){window.close();};
+
+		obj = $('addUserLink');
+		if (obj)
+			obj.onclick = addUser;
+
+		obj = $('search');
+		if (obj)
+			obj.focus();
+
+		obj = $('useGlobalSearch');
+		if (obj)
+		{
+			obj.onclick = toggleFullSearch;
+			toggleFullSearch();
+		}
+	});
+};
+
+function participantsFilterName(name)
+{
+	if (!$('useGlobalSearch').checked)
+		return name;
+
+	return name.substr(0, name.lastIndexOf('(') - 1);
+}
+
+function addUser()
+{
+	var participants = $('participants');
+	var target = window.opener.document.getElementById($F('target'));
+	var previous = '';
+	var current = '';
+
+	if ((target.tagName == 'INPUT') || (target.tagName == 'TEXTAREA'))
+	{
+		previous = target.value;
+		if ($F('id') == 'mail')
+		{
+			var participantsLength = participants.options.length;
+			var current = null;
+			for (var i = 0; i < participantsLength; i++)
+			{
+				current = participants.options[i];
+				if (current.selected)
+					target.value += '"' + participantsFilterName(current.text) + '" ' + '<' + current.value + '>, ';
+			}
+		}
+		else
+		{
+			if (participants.selectedIndex > -1)
+			{
+				target.value = participants.options[participants.selectedIndex].value.replace('u','');
+				window.opener.document.getElementById(target.id + '_desc').value = participantsFilterName(participants.options[participants.selectedIndex].text);
+			}
+		}
+		current = target.value;
+	}
+	else
+	{
+		previous = target.innerHTML;
+		var options = '';
+		var participantsLength = participants.options.length;
+		var current = null;
+		var insertElement;
+		for (var i = 0; i < participantsLength; i++)
+		{
+			current = participants.options[i];
+			if (current.selected)
+			{
+				/* checa se o elemento que será inserido já existe na select box destino */
+				insertElement = true;
+				for (var j = 0; j < target.options.length; j++)
+					if (target.options[j].value == current.value)
+					{
+						insertElement = false;
+						break;
+					}
+				if (insertElement)
+					options += '<option value="' + current.value + '">' + participantsFilterName(current.text) + '</option>';
+			}
+		}
+		if (options.length > 0)
+		{
+			setSelectValue(target, target.innerHTML + options);
+			/* refaz o link que se perde quando modifica-se o innerHTML da select box */
+			target = window.opener.document.getElementById($F('target'));
+		}
+		current = target.innerHTML;
+	}
+
+	/* se o código do desenvolvedor está esperando o evento onchange, dispara o evento */
+	if (target.onchange)
+		if (current != previous)
+			target.onchange();
+}
+
+function setSelectValue(obj, value)
+{
+	/* IE MAGIC */
+	if (obj.outerHTML)
+	{
+		obj.innerHTML = '';
+		obj.outerHTML = obj.outerHTML.match(/<select[^>]*>/gi) + value + '</select>';
+	}
+	else
+		obj.innerHTML = value;
+}
+
+function participantsRemoveUser(obj)
+{
+	if (obj.tagName == 'INPUT')
+	{
+		obj.value = '';
+		obj = document.getElementById(obj.id + '_desc');
+		if (obj)
+			obj.value = '';
+	}
+	else
+	{
+		for(var i = 0;i < obj.options.length; i++)
+			if(obj.options[i].selected)
+				obj.options[i--] = null;
+	}
+}
+
+function toggleFullSearch()
+{
+	$('search').value = '';
+
+	if ($('useGlobalSearch').checked)
+	{
+		globalSearchEnter = true;
+		if ($('organizationSectors'))
+			$('organizationSectors').hide();
+		if ($('globalSearchTitle'))
+			$('globalSearchTitle').show();
+		setSelectValue($('participants'), '');
+		$('search').onkeydown = globalSearchKeyAnalyzer;
+		$('globalSearchWarnings').innerHTML = 'Para executar a busca, pressione ENTER.';
+	}
+	else
+	{
+		$('globalSearchWarnings').innerHTML = '';
+		if ($('globalSearchTitle'))
+			$('globalSearchTitle').hide();
+		if ($('organizationSectors'))
+			$('organizationSectors').show();
+		searchParticipants('');
+		$('search').onkeydown = searchParticipantsTimer;
+	}
+	$('search').focus();
+}
+
+function checkGlobalSearchShortcuts(e)
+{
+	var whichCode = (e.which) ? e.which : e.keyCode;
+	var handled = false;
+
+	/* ENTER */
+	if ((whichCode == 13) && globalSearchEnter)
+	{
+		performGlobalSearch();
+		handled = true;
+		globalSearchEnter = false;
+	}
+
+	if (handled == false)
+	{
+		handled = checkShortcuts(e);
+		if (handled == true)
+			globalSearchEnter = false;
+	}
+
+	if (handled == false)
+		globalSearchEnter = true;
+
+	return handled;
+}
+
+function globalSearchKeyAnalyzer(e)
+{
+	if (checkGlobalSearchShortcuts((e) ? e : window.event))
+		return true;
+
+}
+
+function performGlobalSearch()
+{
+	function resultPerformGlobalSearch(data)
+	{
+		setSelectValue($('participants'), data['participants']);
+		if (data['warnings'])
+			if (data['warnings'].length > 0)
+				$('globalSearchWarnings').innerHTML = data['warnings'].join('<br/>');
+	}
+
+	$('globalSearchWarnings').innerHTML = '';
+	var params = {
+		searchTerm: $F('search'),
+		entities: $F('entities'),
+		id: $F('id'),
+		usePreffix: $F('usePreffix')
+	};
+	callAjax('bo_participants', 'globalSearch', resultPerformGlobalSearch, params);
+}
+
+function openParticipants(target, option)
+{
+	newWidth   = 500;
+	newHeight  = 290;
+	newScreenX = screen.width - newWidth;
+	newScreenY = 0;
+	page = 'index.php?menuaction=workflow.ui_participants.form';
+	if (target)
+		page += "&target_element=" + target;
+	if (option)
+		page += "&" + option;
+
+	window.open(page,'','width='+newWidth+',height='+newHeight+',screenX='+newScreenX+',left='+newScreenX+',screenY='+newScreenY+',top='+newScreenY+',toolbar=no,scrollbars=no,resizable=no');
+}
Index: /sandbox/workflow/branches/993/js/jscode/wf_select_city.js
===================================================================
--- /sandbox/workflow/branches/993/js/jscode/wf_select_city.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/jscode/wf_select_city.js	(revision 795)
@@ -0,0 +1,55 @@
+var cities = function(data)
+{
+	if (typeof(data) == "string")
+	{
+		write_errors(data);
+		return false;
+	}
+	else
+	{
+		var container = document.getElementById(data["target"]);
+		container.innerHTML = "";
+		container.disabled = true;
+		fill_combo(data["target"], data["cities"]);
+		container.disabled = false;
+		return true;
+	}
+};
+
+function draw_cities(target, state_id, callback, handleExpiredSessions)
+{
+	cExecute("$this.bo_utils.get_cities",
+			function (data)
+			{
+				if (data['error'])
+				{
+					alert(data['error'].replace(/<br \/>/gi, "\n"));
+					if (data['url'])
+						if (handleExpiredSessions)
+							window.location = data['url'].replace(/\.\./gi, ".");
+
+					return;
+				}
+				if (cities(data))
+				{
+					if (callback)
+					{
+						callback();
+					}
+				}
+			}
+			, "state_id=" + state_id + "&target=" + target);
+}
+
+function fill_combo(target, cities)
+{
+	var container = document.getElementById(target);
+
+	for (var i = 0; i < cities.length; i++)
+	{
+		var option = document.createElement("option");
+		option.innerHTML = cities[i].name;
+		option.value = cities[i].id;
+		container.appendChild(option);
+	}
+}
Index: /sandbox/workflow/branches/993/js/adminsource/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/main.js	(revision 989)
+++ /sandbox/workflow/branches/993/js/adminsource/main.js	(revision 989)
@@ -0,0 +1,231 @@
+
+var ID_PHP_FOLDER       = 0;
+var ID_INCLUDES_FOLDER  = 1;
+var ID_TEMPLATES_FOLDER = 2;
+var ID_RESOURCES_FOLDER = 3;
+
+var proc_id=0;
+var php_toolbar;
+var tpl_toolbar;
+var inc_toolbar;
+var res_toolbar;
+var toolbar_name;
+var window_list = new Array;
+
+function show_window(titulo,div,width,height)
+{
+  if (!window_list[div.id]) 
+  {
+    if(is_ie){
+        div.style.height = (height + 10) + 'px';
+        div.style.width = (width + 50) + 'px';
+    } else {
+        div.style.height = height + 'px';
+        div.style.width = width + 'px';
+    }
+
+    div.style.visibility = "hidden";
+    div.style.position = "absolute";
+    div.style.zIndex = "10002";
+    var wHeight = div.offsetHeight + "px";
+    var wWidth =  div.offsetWidth   + "px";
+
+    win = new dJSWin({
+         id: 'window_'+div.id,
+         content_id: div.id,
+         width: wWidth,
+         height: wHeight,
+         title_color: '#3978d6',
+         bg_color: '#eee',
+         title: titulo,
+         title_text_color: 'white',
+         button_x_img: _icon_dir + '/winclose.gif',
+         border: true 
+	});
+
+    win.draw();
+	window_list[div.id] = win;
+  } else {
+	win = window_list[div.id];
+  }
+
+  win.open();
+}
+
+function getFolder(id_folder) 
+{
+	return document.getElementById("content_id_"+id_folder);
+}
+
+function createToolBar(folder_id,show_proc_status) 
+{
+	var table = document.createElement("TABLE");
+    var body  = document.createElement("TBODY");
+	var tr    = document.createElement("TR");
+	var tr2    = document.createElement("TR");
+	var td    = new Array(3);
+	var td2    = new Array(3);
+	var show_proc_status = (show_proc_status == null) ? true : show_proc_status;
+	var folder = getFolder(folder_id);
+
+	var fillToolBar = function(data)
+	{
+
+		var combo = "";
+		combo = '<select id="novoProcesso" onchange="window.location=this.value">';
+		for (var i = 0; i < data['other_processes'].length; i++)
+			combo += '<option value="' + data['other_processes'][i]['link']  + (data['other_processes'][i]['pid'] == data['proc_id'] ? " selected=\"selected\"" : "")  + '">'+ data['other_processes'][i]['name']  + '</option>';
+		combo += '</select>';
+		td[0].innerHTML = 'Processo:<br/>' + combo;
+		if (show_proc_status)
+			td[1].innerHTML = 'Status:<br/><img src='+data['img_validity']+'>&nbsp;<b>' + data['alt_validity'] + '</b>';
+
+		eval(toolbar_name + " = new TMainMenu('"+toolbar_name+"','horizontal')"); 
+		//Start - Stop
+		if ( data['start_stop_img'].length > 0 ) {
+			_start_stop = new TPopMenu((screen.width > 800) ?data['start_stop_desc']:' ',data['start_stop_img'],'a',data['start_stop_link'], data['start_stop_desc']+' Processo');
+	    	eval(toolbar_name+'.Add( _start_stop )');
+		}
+		//Processo
+		_processo = new TPopMenu((screen.width > 800) ?'Editar':' ',data['img_change'],'a',data['link_admin_processes'], 'Editar Dados do Processo');
+	    eval(toolbar_name+'.Add( _processo )');
+		//Atividades
+		_atividades = new TPopMenu((screen.width > 800) ?'Atividades':' ',data['img_activity'],'a',data['link_admin_activities'], 'Atividades do Processo');
+	    eval(toolbar_name+'.Add( _atividades )');
+		//Perfis
+		_perfis = new TPopMenu((screen.width > 800) ?'Perfis':' ',data['img_roles'],'a',data['link_admin_roles'], 'Editar Perfis do Processo');
+	    eval(toolbar_name+'.Add( _perfis )');
+		//Jobs
+		_jobs = new TPopMenu((screen.width > 800) ?'Jobs':' ',data['img_job'],'a',data['link_admin_jobs'], 'Administrar Jobs do Processo');
+	    eval(toolbar_name+'.Add( _jobs )');
+		//Gráfico
+		_grafico = new TPopMenu((screen.width > 800) ?'Gráfico':' ',data['img_process'],'a',data['link_graph'], 'Gráfico do Processo');
+	    eval(toolbar_name+'.Add( _grafico )');
+		//Exportar
+		_exportar = new TPopMenu((screen.width > 800) ?'Exportar':' ',data['img_save'],'a',data['link_admin_export'] ,'Exportar Processo');
+	    eval(toolbar_name+'.Add( _exportar )');
+
+	    eval("setToolBarStyle( "+toolbar_name+" )");
+	    eval(toolbar_name+'.Build(td[2].id)');
+		td[2].setAttribute('align','right');
+	    eval("document.getElementById("+toolbar_name+"._id).style.visibility = 'visible'");
+	};
+
+	for (i = 0; i < td.length; i++ )
+	{
+		td2[i] = document.createElement("TD");
+		td2[i].setAttribute('id','td_tool_bar_'+folder.id+'_'+i);
+		td2[i].setAttribute('valign','center');
+		tr2.appendChild(td2[i]);	
+
+		td[i] = document.createElement("TD");
+		td[i].setAttribute('id','td_main_toolbar_'+folder.id+'_'+i);
+		td[i].setAttribute('valign','center');
+		tr.appendChild(td[i]);	
+	}
+	
+   	table.setAttribute("id", "wf_toolbar_"+folder.id);
+    table.setAttribute("width", "100%");
+    table.setAttribute("cellpadding", "5");
+    table.setAttribute("cellspacing", "0");
+
+	switch (folder_id) 
+	{
+		case ID_PHP_FOLDER : 
+						toolbar_name = 'php_toolbar';
+						break;
+		case ID_INCLUDES_FOLDER : 
+						toolbar_name = 'inc_toolbar';
+						break;
+		case ID_TEMPLATES_FOLDER : 
+						toolbar_name = 'tpl_toolbar';
+						break;
+		case ID_RESOURCES_FOLDER : 
+						toolbar_name = 'res_toolbar';
+						break;
+
+	}
+
+	body.appendChild(tr);
+	body.appendChild(tr2);
+    table.appendChild(body);
+    folder.appendChild(table);
+
+	cExecute ("$this.bo_adminsource.get_toolbar_data", fillToolBar, "proc_id="+proc_id);
+}
+
+function init_user_interface() {
+
+	if ((!is_gecko) && (!is_ie6up)) {
+		alert('Seu navegador não suporta o módulo de Workflow.\nInstale o Mozilla FireFox 1.0+ ou Internet Explorer 6.0+.');
+	} else {
+		BordersArray[0] = new setBorderAttributes(0);
+		BordersArray[1] = new setBorderAttributes(1);
+		BordersArray[2] = new setBorderAttributes(2);
+		BordersArray[3] = new setBorderAttributes(3);
+
+		var main_body = document.getElementById("main_body");
+		main_body.style.display = '';
+		
+		if (alternate_border(ID_PHP_FOLDER) == 0) {
+			draw_php_folder();
+		}
+	}
+}
+
+function setToolBarStyle(t) {
+	t.SetPosition('relative',0,0);
+	t.SetCorrection(1,-5);
+	t.SetCellSpacing(0);	
+	t.SetBackground('whitesmoke','','','');
+	t.SetItemText('black','center','','','');
+	t.SetItemTextHL('darkblue','center','','','');
+	t.SetItemBorder(1,'buttonface','solid');
+	t.SetItemBorderHL(1,'black','solid');
+	t.SetItemBackgroundHL('white','','','');
+	t.SetItemTextClick('white','center','','','');
+	t.SetItemBackgroundClick('darkblue','','','');
+	t.SetItemBorderClick(1,'black','solid');
+	t.SetBorder(0,'navy','solid');
+	
+	t.SetItemDimension(200,22);		
+	t._pop.SetCorrection(4,1);
+	t._pop.SetItemDimension(180,22);		
+	t._pop.SetPaddings(1);
+	t._pop.SetBackground('white','','','');
+	t._pop.SetSeparator(150,'left','black','');
+	t._pop.SetExpandIcon(true,'>',9);
+	t._pop.SetItemBorder(0,'#66CCFF','solid');
+	t._pop.SetItemBorderHL(0,'black','solid');
+	t._pop.SetItemPaddings(0);
+	t._pop.SetItemPaddingsHL(0);
+	t._pop.SetItemText('black','','','','');
+	t._pop.SetItemTextHL('darkblue','','','','');
+	t._pop.SetItemBackground('white','','','');
+	t._pop.SetItemBackgroundHL('whitesmoke','','','');
+}
+
+
+function change_folder(folder_id) 
+{
+	//verifica se a pasta ainda não foi criada
+	if (!alternate_border(folder_id)) {
+		switch (folder_id) 
+		{
+			case ID_PHP_FOLDER       :  draw_php_folder();
+										break;
+			case ID_TEMPLATES_FOLDER : 	draw_templates_folder(); 
+										break;
+			case ID_RESOURCES_FOLDER :  draw_resources_folder();
+										break;
+			case ID_INCLUDES_FOLDER :   draw_includes_folder();
+										break;
+		}
+	}
+}
+
+
+Event.observe(window, 'load', function() {
+	proc_id = $F('workflowAdminSourceProcessID');
+	init_user_interface();
+});
Index: /sandbox/workflow/branches/993/js/adminsource/resources_folder.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/resources_folder.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/resources_folder.js	(revision 795)
@@ -0,0 +1,239 @@
+var res_sort_field = 'file_name';
+var res_sort_asc   = 1;
+
+function sort_resource_list(field)
+{
+	res_sort_field = field;
+	res_sort_asc   = (res_sort_asc == 1) ? 0 : 1;
+
+	redraw_resource_list();
+}
+
+function createResourcesList(folder)
+{
+	var table = document.createElement("TABLE");
+    var body  = document.createElement("TBODY");
+	var tr    = document.createElement("TR");
+	var td    = new Array(5);
+
+	var fillResourcesList = function(data) {
+		var tr;
+		var td;	
+
+		if (data != null) {
+			for (i = 0; i < data.length; i++) {
+				tr = document.createElement("TR");
+				td = new Array(5);
+	
+				for (j = 0; j < td.length; j++) {
+					td[j] = document.createElement('TD');
+				}
+	 
+				tr.className = 'table_elements_tr_line';
+
+				if (i % 2) {
+                    tr.style.backgroundColor = '#FFFFFF';
+                } else {
+                    tr.style.backgroundColor = '#F5F5F5';
+                }
+	
+				file_name = data[i]['file_name'];
+
+				td[0].align = 'left';
+				if ((file_name.indexOf('.css') > 0) || (file_name.indexOf('.js') > 0))
+					td[0].innerHTML = get_link("javascript:void(0)", data[i]['file_name'],"onclick=\"window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_resourceeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type=resource&proc_id="+data[i]['proc_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')\"");
+				else
+					if ((file_name.indexOf('.jpg') > 0) || (file_name.indexOf('.png') > 0) || (file_name.indexOf('.gif') > 0))
+						td[0].innerHTML = '<a rel="lightbox" href="workflow/redirect.php?pid=' + data[i]['proc_id'] + '&file=' + data[i]['file_name'] + '" title="Arquivo: ' + data[i]['file_name'] + '">' + data[i]['file_name'] + '</a>';
+					else
+						td[0].innerHTML = data[i]['file_name'];
+					
+				td[1].align = 'center';
+				td[1].innerHTML = data[i]['tipo'];	
+	
+				td[2].align = 'center';
+				td[2].innerHTML = data[i]['tamanho'];	
+		
+				td[3].align = 'center';
+				td[3].innerHTML = data[i]['modificado'];	
+	
+				td[4].align = 'center';
+			
+				if ((file_name.indexOf('.css') > 0) || (file_name.indexOf('.js') > 0)) {
+					edit_button = get_link("javascript:void(0)", get_icon('phpedit.png','Editar Resource','hspace=1'),"onclick=\"window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_resourceeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type=resource&proc_id="+data[i]['proc_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')\"");
+				} else {
+					edit_button = get_icon('phpeditpb.png','Editar Resource','hspace=1');
+				}
+				
+				td[4].innerHTML = edit_button +  
+								  get_link(_web_server_url+"/index.php?menuaction=workflow.bo_adminsource.export_file&file_name="+escape(data[i]['file_name'])+"&type="+data[i]['tipo_arquivo']+"&proc_id="+proc_id,get_icon('phpexport.png','Exportar Resource','hspace=1'),"") +
+								  get_link("javascript:void(0)", get_icon('del_template.png','Excluir Resource','hspace=1'),"onclick=\"delete_resource('"+data[i]['file_name']+"')\""); 
+	
+				for (j = 0; j < td.length; j++) {
+					tr.appendChild(td[j]);
+				}
+	
+				body.appendChild(tr);
+			}
+		}
+		initLightbox();
+	};
+
+    table.setAttribute("cellPadding", "2");
+    table.className = "table_elements";
+    table.id        = 'resource_list';
+
+	tr.className = "table_elements_tr_header";
+
+	for (i = 0; i < td.length; i++) { 
+		td[i] = document.createElement('TD'); 
+		td[i].style.cursor = 'pointer';
+	}
+	
+	icon_order = (res_sort_asc == 1) ? get_icon('arrow_descendant.gif','Crescente','hspace=1') : get_icon('arrow_ascendant.gif','Decrescente','hspace=1') ;
+
+	td[0].setAttribute('width', '50%');
+	td[0].align = 'left';
+	td[0].innerHTML = 'Nome do Arquivo';
+	td[0].onclick = function() { sort_resource_list('file_name'); };
+	td[0].innerHTML = ( res_sort_field == 'file_name' ) ? td[0].innerHTML = '<b>Nome do Arquivo</b>' + icon_order : td[0].innerHTML;
+		
+	td[1].setAttribute('width', '10%');
+	td[1].align = 'center';
+	td[1].innerHTML = 'Tipo';	
+	td[1].onclick = function() { sort_resource_list('tipo'); };
+	td[1].innerHTML = ( res_sort_field == 'tipo' ) ? td[1].innerHTML = '<b>Tipo</b>' + icon_order : td[1].innerHTML;
+
+	td[2].setAttribute('width', '10%');
+	td[2].align = 'center';
+	td[2].innerHTML = 'Tamanho';	
+	td[2].onclick = function() { sort_resource_list('tamanho'); };
+	td[2].innerHTML = ( res_sort_field == 'tamanho' ) ? td[2].innerHTML = '<b>Tamanho</b>' + icon_order : td[2].innerHTML;
+	
+	td[3].setAttribute('width', '20%');
+	td[3].align = 'center';
+	td[3].innerHTML = 'Modificado';	
+	td[3].onclick = function() { sort_resource_list('modificado'); };
+	td[3].innerHTML = ( res_sort_field == 'modificado' ) ? td[3].innerHTML = '<b>Modificado</b>' + icon_order : td[3].innerHTML;
+
+	td[4].setAttribute('width', '10%');
+	td[4].align = 'center';
+	td[4].innerHTML = 'Ações';	
+
+	for (i = 0; i < td.length; i++) 
+		tr.appendChild(td[i]); 
+
+	body.appendChild(tr);
+	table.appendChild(body);
+	folder.appendChild(table);
+
+	cExecute ("$this.bo_adminsource.get_resource_files", fillResourcesList, "proc_id="+proc_id+"&sort="+res_sort_field+"&order_by="+res_sort_asc);
+}
+
+function new_resource()
+{
+	var createHnd = function(data) {
+		var resources_folder = getFolder(ID_RESOURCES_FOLDER);
+		
+		switch(data) 
+		{
+			case 0: alert('Erro: Nome de arquivo inválido.');
+					break;
+			case 1: alert('Erro: ID de processo inválido.');
+					break;
+			case 2: alert('Arquivo já existe.');
+					break;
+			case 3: alert('Arquivo criado com sucesso.');
+					break;
+			case 4: alert('Não foi possível criar o arquivo.');
+					break;
+
+		}
+		killElement('resource_list');
+		createResourcesList(resources_folder);
+	};
+
+	file_name = prompt('Informe o nome do arquivo:','arquivo.js');
+	if (file_name.length > 0) {
+		cExecute ("$this.bo_adminsource.create_file", createHnd, "rewrite=0&proc_id="+proc_id+"&type=resource&file_name="+file_name);
+	}
+}
+
+function delete_resource(file_name)
+{
+	var deleteHnd = function(data) {
+		//alert(data);
+		redraw_resource_list();
+	};
+
+	if (confirm("Tem certeza que deseja excluir o resource "+file_name+"?")) 
+	{
+		cExecute ("$this.bo_adminsource.delete_file", deleteHnd, "proc_id="+proc_id+"&type=resource&file_name="+file_name);
+	}
+}
+
+function redraw_resource_list()
+{
+	var resources_folder = getFolder(ID_RESOURCES_FOLDER);
+	frmUpload.reset();
+	killElement('resource_list');
+	createResourcesList(resources_folder);
+}
+
+
+function upload_resource() 
+{
+	var uploadHnd = function(data) {
+		var resources_folder = getFolder(ID_RESOURCES_FOLDER);
+		alert(data);
+		redraw_resource_list();
+	};
+
+	cExecuteFormData("$this.bo_adminsource.upload_resource",frmUpload,uploadHnd);
+}
+
+function toggle_upload_row(folder_id)
+{
+	var row = document.getElementById('td_tool_bar_'+folder_id+'_0').parentNode;
+	row.style.display = (row.style.display == 'none') ? '' : 'none';
+}
+
+function draw_resources_toolbar(folder) {
+	var toolbar_row_0 = document.getElementById('td_tool_bar_'+folder.id+'_0').parentNode;
+	var toolbar_cell_1 = document.getElementById('td_main_toolbar_'+folder.id+'_1');
+
+	//toolbar_cell_0.setAttribute('width','10px');
+	 toolbar_row_0.style.display = "none";
+
+    resource_tool = new TMainMenu("resource_tool",'horizontal');
+	resource_tool.Add( new TPopMenu('Novo',_web_server_url+'/workflow/templateFile.php?file=images/new_template.png','f','new_resource()', 'Novo Resource') );
+	resource_tool.Add( new TPopMenu('Importar',_web_server_url+'/workflow/templateFile.php?file=images/up_resource.png','f','toggle_upload_row(\'' + folder.id + '\')', 'Upload Resource') );
+	setToolBarStyle(resource_tool);
+	
+	resource_tool.Build(toolbar_cell_1.id);
+	document.getElementById(resource_tool._id).style.visibility = 'visible';
+
+	/* the use of DOM in this part, is required by MSIE */
+	while (toolbar_row_0.childNodes.length > 0)
+		toolbar_row_0.removeChild(toolbar_row_0.firstChild);
+	var td = document.createElement('TD');
+	td.colSpan = 3;
+	td.id = 'td_tool_bar_' + folder.id + '_0';
+	td.innerHTML = '<form name=frmUpload method=POST enctype="multipart/form-data"><input type="hidden" name="MAX_FILE_SIZE" value="3000000"><input type=hidden name=proc_id value='+proc_id+'><input type=file name=resource_file><button onclick="upload_resource(); return false;">Upload</button>';
+	toolbar_row_0.appendChild(td);
+}
+
+function draw_resources_folder() {
+ 
+	var resources_folder = getFolder(ID_RESOURCES_FOLDER);
+	var toolbar;
+
+	toolbar = document.getElementById("wf_toolbar_"+resources_folder.id);
+	if (toolbar == null) 
+	{
+		createToolBar(ID_RESOURCES_FOLDER,false);
+		draw_resources_toolbar(resources_folder);
+	}
+
+	createResourcesList(resources_folder);
+}
Index: /sandbox/workflow/branches/993/js/adminsource/templates_folder.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/templates_folder.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/templates_folder.js	(revision 795)
@@ -0,0 +1,315 @@
+var tpl_sort_field = 'file_name';
+var tpl_sort_asc   = 1;
+var tpl_toolbar;
+var tpl_rewrite = false;
+
+function set_tpl_rewrite()
+{
+	tpl_rewrite = !tpl_rewrite;
+}
+
+function show_template_window()
+{
+	var showHnd = function(data)
+	{
+		div = document.getElementById('model_template_list');
+		if (!div) {
+			div = document.createElement("DIV");
+			div.style.visibility = "hidden";
+			div.style.position   = "absolute";
+			div.id 				 = "model_template_list";
+		
+			tb = document.createElement("TABLE");
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+
+			td.innerHTML = '<b>Selecione o modelo desejado:</b><br>';
+			se = document.createElement("SELECT");
+			se.setAttribute('name','tplfile');
+			se.setAttribute('size','10');
+			se.setAttribute('id','win_tpl_model');
+			se.style.width = '200px';
+
+			for (i = 0; i < data.length; i++) 
+			{
+				op = document.createElement("OPTION");
+				op.setAttribute('value',data[i]['file_name']);
+				if (i == 0) 
+					op.setAttribute('selected','selected');
+				op.innerHTML = data[i]['file_name'];
+				se.appendChild(op);
+			}
+
+			td.appendChild(se);
+			tb.setAttribute('align','center');
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+		
+			td.innerHTML = '<b>Nome do arquivo a ser criado:</b><br>';
+
+			it = document.createElement("INPUT");
+			it.setAttribute('type','text');
+			it.setAttribute('name','tpl_novo_nome');
+			it.setAttribute('value','arquivo.tpl');
+			it.setAttribute('id','win_tpl_name');
+			it.style.width = '200px';
+
+			td.appendChild(it);
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+
+			ch = document.createElement("INPUT");
+			ch.setAttribute('type','checkbox');
+			ch.setAttribute('name','tplrewrite');
+			ch.setAttribute('onclick','set_tpl_rewrite()');
+			td.appendChild(ch);
+			td.innerHTML += 'Sobrescreve se já existe';
+			td.setAttribute('valign','top');
+
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+			td.setAttribute('align','center');
+
+			bt = document.createElement("INPUT");
+			bt.setAttribute('type','button');
+			bt.setAttribute('value','Ok');
+			bt.setAttribute('name','Ok');
+			bt.setAttribute('onclick','create_new_template()');
+			bt.style.width = '70px';
+			td.appendChild(bt);
+
+			bt = document.createElement("INPUT");
+			bt.setAttribute('type','button');
+			bt.setAttribute('value','Cancelar');
+			bt.setAttribute('name','Cancelar');
+			bt.setAttribute('onclick','win.close()');
+			bt.style.width = '70px';
+			td.appendChild(bt);
+
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			div.appendChild(tb);	
+
+			document.body.appendChild(div);
+		}
+		show_window('Modelos de Template',div,250,270);
+	};
+
+	cExecute ("$this.bo_adminsource.get_model_files", showHnd, "type=template");
+}
+
+function sort_tpl_list(field)
+{
+	var icon_order;
+
+	tpl_sort_field = field;
+	tpl_sort_asc   = (tpl_sort_asc == 1) ? 0 : 1;
+
+	redraw_template_list();
+}
+
+function createTemplateList(folder)
+{
+	var table = document.createElement("TABLE");
+    var body  = document.createElement("TBODY");
+	var tr    = document.createElement("TR");
+	var td    = new Array(4);
+
+	var fillTemplateList = function(data) {
+		var tr;
+		var td;		
+		
+		if (data != null) {
+			for (i = 0; i < data.length; i++) {
+				tr = document.createElement("TR");
+				td = new Array(5);
+	
+				for (j = 0; j < td.length; j++) {
+					td[j] = document.createElement('TD');
+				}
+	 
+				tr.className = 'table_elements_tr_line';
+
+				if (i % 2) {
+                    tr.style.backgroundColor = '#FFFFFF';
+                } else {
+                    tr.style.backgroundColor = '#F5F5F5';
+                }
+
+				td[0].align = 'left';
+				td[0].innerHTML = get_link("javascript:void(0)", data[i]['file_name'],"onclick=\"window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_templateeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+data[i]['proc_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')\"");
+					
+				td[1].align = 'center';
+				td[1].innerHTML = data[i]['tamanho'];	
+		
+				td[2].align = 'center';
+				td[2].innerHTML = data[i]['modificado'];	
+	
+				td[3].align = 'center';
+				td[3].innerHTML = get_link("javascript:void(0)", get_icon('phpedit.png','Editar Template','hspace=1'),"onclick=\"window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_templateeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+data[i]['proc_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')\"") + 
+							      get_link(_web_server_url+"/index.php?menuaction=workflow.bo_adminsource.export_file&file_name="+escape(data[i]['file_name'])+"&type="+data[i]['tipo_codigo']+"&proc_id="+proc_id,get_icon('phpexport.png','Exportar Template','hspace=1'),"") +
+								  get_link("javascript:void(0)", get_icon('del_template.png','Excluir Template','hspace=1'),"onclick=\"delete_template('"+data[i]['file_name']+"')\""); 
+								 	
+				for (j = 0; j < td.length; j++) {
+					tr.appendChild(td[j]);
+				}
+	
+				body.appendChild(tr);
+			}
+		}
+	};
+
+    table.setAttribute("cellPadding", "2");
+    table.className = "table_elements";
+    table.id        = 'template_list';
+
+	tr.className = "table_elements_tr_header";
+
+	for (i = 0; i < td.length; i++) { 
+		td[i] = document.createElement('TD'); 
+		td[i].style.cursor = 'pointer';
+	}
+
+	icon_order = (tpl_sort_asc == 1) ? get_icon('arrow_descendant.gif','Crescente','hspace=1') : get_icon('arrow_ascendant.gif','Decrescente','hspace=1') ;
+	
+	td[0].setAttribute('width', '60%');
+	td[0].align = 'left';
+	td[0].innerHTML = 'Nome do Arquivo';
+	td[0].onclick = function() { sort_tpl_list('file_name'); };
+	td[0].innerHTML = ( tpl_sort_field == 'file_name' ) ? td[0].innerHTML = '<b>Nome do Arquivo</b>' + icon_order : td[0].innerHTML;
+		
+	td[1].setAttribute('width', '10%');
+	td[1].align = 'center';
+	td[1].innerHTML = 'Tamanho';	
+	td[1].onclick = function() { sort_tpl_list('tamanho'); };
+	td[1].innerHTML = ( tpl_sort_field == 'tamanho' ) ? td[1].innerHTML = '<b>Tamanho</b>' + icon_order : td[1].innerHTML;
+	
+	td[2].setAttribute('width', '20%');
+	td[2].align = 'center';
+	td[2].innerHTML = 'Modificado';	
+	td[2].onclick = function() { sort_tpl_list('modificado'); };
+	td[2].innerHTML = ( tpl_sort_field == 'modificado' ) ? td[2].innerHTML = '<b>Modificado</b>' + icon_order : td[2].innerHTML;
+
+	td[3].setAttribute('width', '10%');
+	td[3].align = 'center';
+	td[3].innerHTML = 'Ações';	
+
+	for (i = 0; i < td.length; i++) 
+		tr.appendChild(td[i]); 
+
+	body.appendChild(tr);
+	table.appendChild(body);
+	folder.appendChild(table);
+
+	cExecute ("$this.bo_adminsource.get_template_files", fillTemplateList, "proc_id="+proc_id+"&sort="+tpl_sort_field+"&order_by="+tpl_sort_asc);
+}
+
+function delete_template(file_name)
+{
+	var deleteHnd = function(data) {
+		var templates_folder = getFolder(ID_TEMPLATES_FOLDER);
+		
+		alert(data);
+		killElement('template_list');
+		createTemplateList(templates_folder);
+	};
+
+	if (confirm("Tem certeza que deseja excluir o template "+file_name+"?")) 
+	{
+		cExecute ("$this.bo_adminsource.delete_file", deleteHnd, "proc_id="+proc_id+"&type=template&file_name="+file_name);
+	}
+}
+
+function redraw_template_list()
+{
+	var templates_folder = getFolder(ID_TEMPLATES_FOLDER);
+		
+	killElement('template_list');
+	createTemplateList(templates_folder);
+}
+
+function create_new_template() 
+{
+	var createHnd = function(data) {
+		var templates_folder = getFolder(ID_TEMPLATES_FOLDER);
+	
+		switch(data) 
+		{
+			case 0: alert('Erro: Nome de arquivo inválido.');
+					break;
+			case 1: alert('Erro: ID de processo inválido.');
+					break;
+			case 2: alert('Arquivo já existe.');
+					break;
+			case 3: alert('Arquivo criado com sucesso.');
+					break;
+			case 4: alert('Não foi possível criar o arquivo.');
+					break;
+		}
+
+		killElement('template_list');
+		createTemplateList(templates_folder);
+	};
+
+	tpl_model = document.getElementById('win_tpl_model');
+    modelo = tpl_model.value;
+
+	text = document.getElementById('win_tpl_name');
+	file_name = text.value;
+	if (file_name) {
+		if (tpl_rewrite) {
+			rewrite_file = 1;
+		} else {
+			rewrite_file = 0;
+		}
+		cExecute ("$this.bo_adminsource.create_file", createHnd, "rewrite="+rewrite_file+"&modelo="+modelo+"&proc_id="+proc_id+"&type=template&file_name="+file_name);
+		win.close();
+	} else {
+		alert('É necessário informar o nome do arquivo a ser criado.');
+		text.focus();
+	}
+}
+
+function draw_template_toolbar(folder) {
+	var toolbar_cell = document.getElementById('td_main_toolbar_'+folder.id+'_1');
+
+    template_tool = new TMainMenu("template_tool",'horizontal');
+
+	_new_template = new TPopMenu('Novo Template',_icon_dir + '/new_template.png','f','show_template_window()', 'Insere Novo Template');
+	template_tool.Add( _new_template );
+
+	//_new_template.Add( new TPopMenu('Em Branco',_icon_dir + '/arrow.gif','f','create_new_template(0)', 'Em Branco') );
+	//_new_template.Add( new TPopMenu('Modelo de Consulta',_icon_dir + '/arrow.gif','f','create_new_template(1)', 'Modelo Consulta') );
+	//_new_template.Add( new TPopMenu('Modelo de Cadastro',_icon_dir + '/arrow.gif','f','create_new_template(2)', 'Modelo Cadastro') );
+	//_new_template.Add( new TPopMenu('Modelo de Visualizar',_icon_dir + '/arrow.gif','f','create_new_template(3)', 'Modelo Visualizar') );
+	
+	setToolBarStyle(template_tool);
+	template_tool.Build(toolbar_cell.id);
+	document.getElementById(template_tool._id).style.visibility = 'visible';
+}
+
+function draw_templates_folder() {
+ 
+	var templates_folder = getFolder(ID_TEMPLATES_FOLDER);
+	var toolbar;
+
+	toolbar = document.getElementById("wf_toolbar_"+templates_folder.id);
+
+	if (toolbar == null) 
+	{
+		createToolBar(ID_TEMPLATES_FOLDER,false);
+		draw_template_toolbar(templates_folder);
+	}
+
+	createTemplateList(templates_folder);
+}
Index: /sandbox/workflow/branches/993/js/adminsource/inc/class.model.inc.php
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/inc/class.model.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/inc/class.model.inc.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+class Model extends BaseModel
+{
+	function Model(&$env)
+	{
+		$this->super(&$env);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/js/adminsource/inc/class.controller.inc.php
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/inc/class.controller.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/inc/class.controller.inc.php	(revision 795)
@@ -0,0 +1,9 @@
+<?php
+class Controller extends BaseController
+{
+	function Controller(&$model , &$env)
+	{
+		$this->super(&$model , &$env);
+	}
+}
+?>
Index: /sandbox/workflow/branches/993/js/adminsource/inc/class.atividade.model.inc.php
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/inc/class.atividade.model.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/inc/class.atividade.model.inc.php	(revision 795)
@@ -0,0 +1,11 @@
+<?php
+
+class AtividadeModel extends Model
+{
+	function defaultAction()
+	{
+		return true;
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/js/adminsource/inc/em_branco.php
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/inc/em_branco.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/inc/em_branco.php	(revision 795)
@@ -0,0 +1,3 @@
+<?php
+
+?>
Index: /sandbox/workflow/branches/993/js/adminsource/inc/class.atividade.controller.inc.php
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/inc/class.atividade.controller.inc.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/inc/class.atividade.controller.inc.php	(revision 795)
@@ -0,0 +1,18 @@
+<?php
+
+class AtividadeController extends Controller
+{
+	function __default()
+	{
+		if ($this->model->defaultAction())
+		{
+			/* acao OK */
+		}
+		else
+		{
+			/* acao erro */
+		};
+	}
+}
+
+?>
Index: /sandbox/workflow/branches/993/js/adminsource/includes_folder.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/includes_folder.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/includes_folder.js	(revision 795)
@@ -0,0 +1,310 @@
+var inc_sort_field = 'file_name';
+var inc_sort_asc   = 1;
+var rewrite = false;
+
+function set_rewrite()
+{
+	rewrite = !rewrite;
+}
+
+function show_include_window()
+{
+	var showHnd = function(data)
+	{
+
+		div = document.getElementById('model_include_list');
+		if (!div) {
+
+			div = document.createElement("DIV");
+			div.style.visibility = "hidden";
+			div.style.position   = "absolute";
+			div.id 				 = "model_include_list";
+		
+			tb = document.createElement("TABLE");
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+
+			td.innerHTML = '<b>Selecione o modelo desejado:</b><br>';
+			se = document.createElement("SELECT");
+			se.setAttribute('name','file');
+			se.setAttribute('size','10');
+			se.setAttribute('id','win_include_model');
+			se.style.width = '200px';
+
+			for (i = 0; i < data.length; i++) 
+			{
+				op = document.createElement("OPTION");
+				op.setAttribute('value',data[i]['file_name']);
+				if (i == 0) 
+					op.setAttribute('selected','selected');
+				op.innerHTML = data[i]['file_name'];
+				se.appendChild(op);
+			}
+
+			td.appendChild(se);
+			tb.setAttribute('align','center');
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+		
+			td.innerHTML = '<b>Nome do arquivo a ser criado:</b><br>';
+
+			it = document.createElement("INPUT");
+			it.setAttribute('type','text');
+			it.setAttribute('name','novo_nome');
+			it.setAttribute('value','arquivo.php');
+			it.setAttribute('id','win_include_name');
+			it.style.width = '200px';
+
+			td.appendChild(it);
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+
+			ch = document.createElement("INPUT");
+			ch.setAttribute('type','checkbox');
+			ch.setAttribute('name','rewrite');
+			ch.setAttribute('onclick','set_rewrite()');
+			ch.setAttribute('id','chk_rewrite_file');
+			td.appendChild(ch);
+			td.innerHTML += 'Sobrescreve se já existe';
+			td.setAttribute('valign','top');
+
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			tr = document.createElement("TR");
+			td = document.createElement("TD");
+			td.setAttribute('align','center');
+
+			bt = document.createElement("INPUT");
+			bt.setAttribute('type','button');
+			bt.setAttribute('value','Ok');
+			bt.setAttribute('name','Ok');
+			bt.setAttribute('onclick','create_new_include()');
+			bt.style.width = '70px';
+			td.appendChild(bt);
+
+			bt = document.createElement("INPUT");
+			bt.setAttribute('type','button');
+			bt.setAttribute('value','Cancelar');
+			bt.setAttribute('name','Cancelar');
+			bt.setAttribute('onclick','win.close()');
+			bt.style.width = '70px';
+			td.appendChild(bt);
+
+			tr.appendChild(td);	
+			tb.appendChild(tr);
+
+			div.appendChild(tb);	
+
+			document.body.appendChild(div);
+		}
+		show_window('Modelos de Classe',div,250,270);
+	};
+
+	cExecute ("$this.bo_adminsource.get_model_files", showHnd, "type=include");
+}
+
+
+function sort_include_list(field)
+{
+	inc_sort_field = field;
+	inc_sort_asc   = (inc_sort_asc == 1) ? 0 : 1;
+	redraw_include_list();
+}
+
+function createIncludeList(folder)
+{
+	var table = document.createElement("TABLE");
+    var body  = document.createElement("TBODY");
+	var tr    = document.createElement("TR");
+	var td    = new Array(4);
+
+	var fillIncludeList = function(data) {
+		var tr;
+		var td;		
+		
+		if (data != null) {
+			for (i = 0; i < data.length; i++) {
+				tr = document.createElement("TR");
+				td = new Array(5);
+	
+				for (j = 0; j < td.length; j++) {
+					td[j] = document.createElement('TD');
+				}
+	 
+				tr.className = 'table_elements_tr_line';
+
+				if (i % 2) {
+					tr.style.backgroundColor = '#FFFFFF';
+				} else {
+					tr.style.backgroundColor = '#F5F5F5';
+				}
+
+				td[0].align = 'left';
+				td[0].innerHTML = data[i]['file_name'];
+				td[0].innerHTML = get_link("javascript:void(0)", data[i]['file_name'],"onclick=\"window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_phpeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+data[i]['proc_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')\"");
+					
+				td[1].align = 'center';
+				td[1].innerHTML = data[i]['tamanho'];	
+		
+				td[2].align = 'center';
+				td[2].innerHTML = data[i]['modificado'];	
+	
+				td[3].align = 'left';
+				td[3].innerHTML = get_link("javascript:void(0)", get_icon('phpedit.png','Editar Include','hspace=1'),"onclick=\"window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_phpeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+data[i]['proc_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')\"") + 
+							      get_link(_web_server_url+"/index.php?menuaction=workflow.bo_adminsource.export_file&file_name="+escape(data[i]['file_name'])+"&type="+data[i]['tipo_codigo']+"&proc_id="+proc_id,get_icon('phpexport.png','Exportar Include','hspace=1'),"");
+			
+				if (data[i]['file_name'] != 'shared.php') {
+					td[3].innerHTML += get_link("javascript:void(0)", get_icon('del_template.png','Excluir Include','hspace=1'),"onclick=\"delete_include('"+data[i]['file_name']+"')\""); 
+				}
+								 	
+				for (j = 0; j < td.length; j++) {
+					tr.appendChild(td[j]);
+				}
+	
+				body.appendChild(tr);
+			}
+		}
+	};
+
+    table.setAttribute("cellPadding", "2");
+    table.className = "table_elements";
+    table.id        = 'include_list';
+
+	tr.className = "table_elements_tr_header";
+
+	for (i = 0; i < td.length; i++) { 
+		td[i] = document.createElement('TD'); 
+		td[i].style.cursor = 'pointer';
+	}
+	
+	icon_order = (inc_sort_asc == 1) ? get_icon('arrow_descendant.gif','Crescente','hspace=1') : get_icon('arrow_ascendant.gif','Decrescente','hspace=1') ;
+
+	td[0].setAttribute('width', '63%');
+	td[0].align = 'left';
+	td[0].innerHTML = 'Nome do Arquivo';
+	td[0].onclick = function() { sort_include_list('file_name'); };
+	td[0].innerHTML = ( inc_sort_field == 'file_name' ) ? td[0].innerHTML = '<b>Nome do Arquivo</b>' + icon_order : td[0].innerHTML;
+		
+	td[1].setAttribute('width', '10%');
+	td[1].align = 'center';
+	td[1].innerHTML = 'Tamanho';	
+	td[1].onclick = function() { sort_include_list('tamanho'); };
+	td[1].innerHTML = ( inc_sort_field == 'tamanho' ) ? td[1].innerHTML = '<b>Tamanho</b>' + icon_order : td[1].innerHTML;
+	
+	td[2].setAttribute('width', '20%');
+	td[2].align = 'center';
+	td[2].innerHTML = 'Modificado';	
+	td[2].onclick = function() { sort_include_list('modificado'); };
+	td[2].innerHTML = ( inc_sort_field == 'modificado' ) ? td[2].innerHTML = '<b>Modificado</b>' + icon_order : td[2].innerHTML;
+
+	td[3].setAttribute('width', '7%');
+	td[3].align = 'center';
+	td[3].innerHTML = 'Ações';	
+
+	for (i = 0; i < td.length; i++) 
+		tr.appendChild(td[i]); 
+
+	body.appendChild(tr);
+	table.appendChild(body);
+	folder.appendChild(table);
+
+	cExecute ("$this.bo_adminsource.get_include_files", fillIncludeList, "proc_id="+proc_id+"&sort="+inc_sort_field+"&order_by="+inc_sort_asc);
+}
+
+function redraw_include_list()
+{
+	var include_folder = getFolder(ID_INCLUDES_FOLDER);
+	killElement('include_list');
+	createIncludeList(include_folder);
+}
+
+function delete_include(file_name)
+{
+	var deleteHnd = function(data) {
+		redraw_include_list();
+	};
+
+	if (confirm("Tem certeza que deseja excluir o include "+file_name+"?")) 
+	{
+		cExecute ("$this.bo_adminsource.delete_file", deleteHnd, "proc_id="+proc_id+"&type=include&file_name="+file_name);
+	}
+}
+
+var createHnd = function(data) {
+	var includes_folder = getFolder(ID_INCLUDES_FOLDER);
+		
+	switch(data) 
+	{
+		case 0: alert('Erro: Nome de arquivo inválido.');
+				break;
+		case 1: alert('Erro: ID de processo inválido.');
+				break;
+		case 2: alert('Arquivo já existe.');
+				break;
+		case 3: alert('Arquivo criado com sucesso.');
+				break;
+		case 4: alert('Não foi possível criar o arquivo.');
+				break;
+
+	}
+	killElement('include_list');
+	createIncludeList(includes_folder);
+};
+
+
+function create_new_include() 
+{
+
+	include_model = document.getElementById('win_include_model'); 
+	modelo = include_model.value;
+
+
+	text = document.getElementById('win_include_name'); 
+	file_name = text.value;
+	if (file_name) {
+		if (rewrite) {
+			rewrite_file = 1;
+		} else {
+			rewrite_file = 0;
+		}
+		cExecute ("$this.bo_adminsource.create_file", createHnd, "rewrite="+rewrite_file+"&modelo="+modelo+"&proc_id="+proc_id+"&type=include&file_name="+file_name);
+		win.close();
+	} else {
+		alert('É necessário informar o nome do arquivo a ser criado.');
+		text.focus();
+	}
+}
+
+function draw_include_toolbar(folder) {
+	var toolbar_cell = document.getElementById('td_main_toolbar_'+folder.id+'_1');
+
+    include_tool = new TMainMenu("include_tool",'horizontal');
+	include_tool.Add( new TPopMenu('Novo Include',_web_server_url+'/workflow/templateFile.php?file=images/new_template.png','f','show_include_window()', 'Insere Novo Include') );
+	
+	setToolBarStyle(include_tool);
+	//alert(toolbar_cell.innerHTML);
+	include_tool.Build(toolbar_cell.id);
+	document.getElementById(include_tool._id).style.visibility = 'visible';
+}
+
+function draw_includes_folder() {
+ 
+	var includes_folder = getFolder(ID_INCLUDES_FOLDER);
+	var toolbar;
+
+	toolbar = document.getElementById("wf_toolbar_"+includes_folder.id);
+	if (toolbar == null) 
+	{
+		createToolBar(ID_INCLUDES_FOLDER,false);
+		draw_include_toolbar(includes_folder);
+	}
+
+	createIncludeList(includes_folder);
+}
Index: /sandbox/workflow/branches/993/js/adminsource/php_folder.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminsource/php_folder.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminsource/php_folder.js	(revision 795)
@@ -0,0 +1,138 @@
+var php_sort_field = 'file_name';
+var php_sort_asc   = 1;
+var php_toolbar;
+
+function sort_file_list(field)
+{
+	php_sort_field = field;
+	php_sort_asc   = (php_sort_asc == 1) ? 0 : 1;
+
+	redraw_php_folder();
+}
+
+function createFileList(folder)
+{
+	var table = document.createElement("TABLE");
+    var body  = document.createElement("TBODY");
+	var tr    = document.createElement("TR");
+	var td    = new Array(5);
+
+	var fillFileList = function(data) {
+		var tr;
+		var td;		
+
+		if (data != null) {
+				for (i = 0; i < data.length; i++) {
+					tr = document.createElement("TR");
+					td = new Array(5);
+
+					for (j = 0; j < td.length; j++) {
+						td[j] = document.createElement('TD');
+					}
+		 
+					tr.className = 'table_elements_tr_line';
+
+					if (i % 2) {
+                    	tr.style.backgroundColor = '#FFFFFF';
+                	} else {
+                    	tr.style.backgroundColor = '#F5F5F5';
+                	}	
+
+					td[0].align = 'left';
+					td[0].innerHTML = get_link("javascript:void(0)", data[i]['file_name'],"onclick=window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_phpeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+data[i]['proc_id']+"&activity_id="+data[i]['activity_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')");
+						
+					td[1].align = 'center';
+					td[1].innerHTML = activity_icon(data[i]['tipo_atividade'], data[i]['interativa']);	
+					
+					td[2].align = 'center';
+					td[2].innerHTML = data[i]['tamanho'];	
+			
+					td[3].align = 'center';
+					td[3].innerHTML = data[i]['modificado'];	
+
+					td[4].align = 'center';
+					td[4].innerHTML = get_link("javascript:void(0)", get_icon('phpedit.png','Editar','hspace=1'),"onclick=window.open('"+_web_server_url+"/index.php?menuaction=workflow.ui_phpeditor.form&proc_name="+data[i]['proc_name']+"&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+data[i]['proc_id']+"&activity_id="+data[i]['activity_id']+"','','width=850,height=680,screenX=100,left=10,screenY=100,top=10,toolbar=no,scrollbars=yes,resizable=yes')") + 
+									  get_link(_web_server_url+"/index.php?menuaction=workflow.bo_adminsource.export_file&file_name="+data[i]['file_name']+"&type="+data[i]['tipo_codigo']+"&proc_id="+proc_id,get_icon('phpexport.png','Exportar','hspace=1'),""); 
+										
+
+					for (j = 0; j < td.length; j++) {
+						tr.appendChild(td[j]);
+					}
+
+					body.appendChild(tr);
+				}
+		}
+	};
+
+	table.id = 'php_files';
+    table.setAttribute("cellPadding", "2");
+    table.className = "table_elements";
+
+	tr.className = "table_elements_tr_header";
+
+
+	for (i = 0; i < td.length; i++) { 
+		td[i] = document.createElement('TD'); 
+		td[i].style.cursor = 'pointer';
+	}
+
+
+	icon_order = (php_sort_asc == 1) ? get_icon('arrow_descendant.gif','Crescente','hspace=1') : get_icon('arrow_ascendant.gif','Decrescente','hspace=1') ;
+
+	
+	td[0].setAttribute('width', '50%');
+	td[0].align = 'left';
+	td[0].innerHTML = 'Nome do Arquivo';
+	td[0].onclick = function() { sort_file_list('file_name'); };
+	td[0].innerHTML = ( php_sort_field == 'file_name' ) ? td[0].innerHTML = '<b>Nome do Arquivo</b>' + icon_order : td[0].innerHTML;
+		
+	td[1].setAttribute('width', '10%');
+	td[1].align = 'center';
+	td[1].innerHTML = 'Tipo';	
+	
+	td[2].setAttribute('width', '10%');
+	td[2].align = 'center';
+	td[2].innerHTML = 'Tamanho';
+	td[2].onclick = function() { sort_file_list('tamanho'); };
+	td[2].innerHTML = ( php_sort_field == 'tamanho' ) ? td[2].innerHTML = '<b>Tamanho</b>' + icon_order : td[2].innerHTML;
+
+	
+	td[3].setAttribute('width', '20%');
+	td[3].align = 'center';
+	td[3].innerHTML = 'Modificado';
+	td[3].onclick = function() { sort_file_list('modificado'); };
+	td[3].innerHTML = ( php_sort_field == 'modificado' ) ? td[3].innerHTML = '<b>Modificado</b>' + icon_order : td[3].innerHTML;
+
+	td[4].setAttribute('width', '10%');
+	td[4].align = 'center';
+	td[4].innerHTML = 'Ações';	
+
+	for (i = 0; i < td.length; i++) 
+		tr.appendChild(td[i]); 
+
+	body.appendChild(tr);
+	table.appendChild(body);
+	folder.appendChild(table);
+
+	cExecute ("$this.bo_adminsource.get_php_files", fillFileList, "proc_id="+proc_id+"&sort="+php_sort_field+"&order_by="+php_sort_asc);
+}
+
+function redraw_php_folder() {
+	var php_folder = getFolder(ID_PHP_FOLDER);
+	
+	killElement('php_files');
+	createFileList(php_folder);
+}
+
+function draw_php_folder() {
+ 
+	var php_folder = getFolder(ID_PHP_FOLDER);
+
+	php_toolbar = document.getElementById("wf_toolbar_"+php_folder.id);
+	if (php_toolbar == null) 
+	{
+		createToolBar(ID_PHP_FOLDER);
+	}
+
+	createFileList(php_folder);
+}
Index: /sandbox/workflow/branches/993/js/orgchart/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/orgchart/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/orgchart/main.js	(revision 795)
@@ -0,0 +1,26 @@
+var refreshAreas = new Array();
+var refreshEmployees = new Array();
+
+function init_orgchart(start_tab)
+{
+
+	if ((!is_gecko) && (!is_ie6up))
+	{
+		alert('OPSS !! Desculpe, mas seu navegador não suporta o Workflow.\nInstale o Mozilla FireFox 1.0+ ou Internet Explorer 6.0+.');
+	}
+	else
+	{
+		initBorders(1);
+		if (start_tab == null)
+			start_tab = 0;
+
+		var main_body = document.getElementById("main_body");
+		main_body.style.display = '';
+		if (alternate_border(start_tab) == 0)
+		{
+			createMenu();
+			lb_initialize();
+			listOrganizations();
+		}
+	}
+}
Index: /sandbox/workflow/branches/993/js/orgchart/organization.js
===================================================================
--- /sandbox/workflow/branches/993/js/orgchart/organization.js	(revision 2063)
+++ /sandbox/workflow/branches/993/js/orgchart/organization.js	(revision 2063)
@@ -0,0 +1,1007 @@
+String.prototype.repeat = function(l)
+{
+	return new Array(l+1).join(this);
+};
+
+var workflowOrgchartAdminEmployeeInfoTimer = null;
+var workflowOrgchartAdminAreaInfoTimer = null;
+
+var CadastroAjax = Class.create();
+
+CadastroAjax.prototype =
+{
+	initialize: function()
+	{
+		this.name = '';
+		this.required = new Array();
+		this.tableHeader = new Array();
+		this.combo = new Array();
+	},
+
+	add: function()
+	{
+		for (var i = 0; i < this.required.length; i++)
+		{
+			if ($F(this.required[i]) == '')
+			{
+				alert("Campo necessário ausente: " + $(this.required[i]).parentNode.parentNode.childNodes[0].childNodes[0].innerHTML);
+				$(this.required[i]).focus();
+				return;
+			}
+		}
+		var cb = function(data)
+		{
+			if (!handleError(data))
+				return;
+
+			/* update the screen info */
+			if (this.name.toLowerCase() == "organization")
+				listOrganizations();
+			else
+			{
+				if ($('organizacao_id'))
+				{
+					var index = $F('organizacao_id');
+					if (refreshAreas[index])
+						refreshAreas[index]();
+				}
+			}
+
+			valid.deactivate();
+		};
+
+		return this.ajaxAction('add', cb, Form.serialize($('orgchartForm')));
+	},
+
+	update: function()
+	{
+		for (var i = 0; i < this.required.length; i++)
+		{
+			if ($F(this.required[i]) == '')
+			{
+				alert("Campo necessário ausente: " + $(this.required[i]).parentNode.parentNode.childNodes[0].childNodes[0].innerHTML);
+				$(this.required[i]).focus();
+				return;
+			}
+		}
+		var cb = function(data)
+		{
+			if (!handleError(data))
+				return;
+
+			/* update the screen info */
+			if (this.name.toLowerCase() == "organization")
+				listOrganizations();
+			else
+			{
+				if ($('organizacao_id'))
+				{
+					var index = $F('organizacao_id');
+					if (refreshAreas[index])
+						refreshAreas[index]();
+				}
+			}
+
+			valid.deactivate();
+		};
+
+		return this.ajaxAction('update', cb, Form.serialize($('orgchartForm')));
+	},
+
+	remove: function(params, linkRemove)
+	{
+
+		if (linkRemove.addClassName)
+			linkRemove.addClassName('alerta');
+		if (confirm("Tem certeza que deseja excluir o registro selecionado?"))
+		{
+			var cb = function(data)
+			{
+				if (!handleError(data))
+					return;
+
+				/* update the screen info */
+				if (this.name.toLowerCase() == "organization")
+					listOrganizations();
+				else
+				{
+					var index = $('organizacao_id') ? $F('organizacao_id') : params['organizacao_id'];
+					if (refreshAreas[index])
+						refreshAreas[index]();
+				}
+
+				if ($('lbContent'))
+					valid.deactivate();
+			};
+			return this.ajaxAction('remove', cb, $H(params).toQueryString());
+		}
+		else
+			if (linkRemove.removeClassName)
+				linkRemove.removeClassName('alerta');
+	},
+
+	list: function(callback, params)
+	{
+		return this.ajaxAction('list', callback, $H(params).toQueryString());
+	},
+
+	generateTable: function(params, displayArea)
+	{
+		tableHeader = this.tableHeader;
+		var tableResult = function(data)
+		{
+			if (!handleError(data))
+				return;
+
+			if (data.length == 0)
+			{
+				displayArea.innerHTML += '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+				return true;
+			}
+
+			for (var i = 0; i < data.length; i++)
+			{
+				data[i]['tr_attributes'] = new Array();
+				data[i]['tr_attributes']['class'] = "linha" + i%2;;
+				data[i]['tr_attributes']['className'] = "linha" + i%2;;
+			}
+
+			var tableAtributes = new Array();
+			tableAtributes['id'] = this.name + 'List';
+			tableAtributes['class'] = 'organizationList';
+			tableAtributes['className'] = 'organizationList';
+			displayArea.appendChild(constructTable(tableHeader, data, tableAtributes));
+		};
+		this.list(tableResult, params);
+	},
+
+	generateUpdateTable: function(params, displayArea)
+	{
+		tableHeader = this.tableHeader;
+		if (!tableHeader['actions'])
+			tableHeader['actions'] = "Ações";
+		name = this.name.charAt(0).capitalize() + this.name.substr(1);
+		var tableResult = function(data)
+		{
+			if (!handleError(data))
+				return;
+
+			if (data.length == 0)
+			{
+				//displayArea.innerHTML += '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+				elem = document.createElement('div');
+				elem.id = this.name.capitalize() + 'List';
+				elem.innerHTML = '<br/><br/><center><strong>Nenhum registro encontrado</strong></center>';
+				displayArea.appendChild(elem);
+				return true;
+			}
+
+			for (var i = 0; i < data.length; i++)
+			{
+				var dataHash = new Hash();
+				for (j in data[i])
+					if (typeof data[i][j] != "function")
+					{
+						dataHash[j] = data[i][j];
+						if ( dataHash[j] == null )
+							dataHash[j] = '';
+					}
+
+				for (j in tableHeader)
+					if (typeof tableHeader[j] != "function")
+						if (j != 'actions')
+							data[i][j] = '<a href="#" onclick="obj' + name + '.fillForm(' + dataHash.customInspect() + '); return false;">' + data[i][j] + '</a>';
+
+				data[i]['tr_attributes'] = new Array();
+				data[i]['tr_attributes']['class'] = "linha" + i%2;
+				data[i]['tr_attributes']['className'] = "linha" + i%2;
+				data[i]['actions'] = '<a href="#" onclick="obj' + name + '.remove(' + dataHash.customInspect() + ' , this.parentNode.parentNode); return false;"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/button_cancel.png" /></a>';
+			}
+
+			var tableAtributes = new Array();
+			tableAtributes['id'] = this.name + 'List';
+			tableAtributes['class'] = 'orgchartUpdateTable';
+			tableAtributes['className'] = 'orgchartUpdateTable';
+			displayArea.appendChild(constructTable(tableHeader, data, tableAtributes));
+		};
+		this.list(tableResult, params);
+	},
+
+	fillForm: function(dataHash)
+	{
+		dataHash = $H(dataHash);
+		dataHash.each(function(pair)
+		{
+			var campo = $(pair.key);
+			if (campo)
+			{
+				if ((campo.nodeName == "SELECT") && (pair.value == null))
+					campo.value = campo.firstChild.value;
+				else
+					if (pair.value != null)
+						campo.value = pair.value;
+			}
+			else
+				new Insertion.Bottom($('orgchartForm'), '<input type="hidden" name="' + pair.key + '" id="' + pair.key + '" value="' + pair.value + '" />');
+		});
+		if (!$('updateOrgchart'))
+			new Insertion.Bottom($('orgchartForm'), '<input type="hidden" name="updateOrgchart" id="updateOrgchart" value="true" />');
+		var saveButton = $('inserir');
+		saveButton.innerHTML = "Salvar";
+		var name = this.name;
+		saveButton.onclick = function(){ eval('obj' + name.charAt(0).capitalize() + name.substr(1) + '.update();')};
+		var titleObject = $('modalTitle');
+		var title = titleObject.innerHTML.split(' ');
+		title[0] = "Atualizar";
+		titleObject.innerHTML = title.join(' ');
+		$('lightbox').scrollTop = 0;
+	},
+
+	generateComboBox: function(params, displayArea, includeNull, name, callback)
+	{
+		if (!name)
+			name = this.combo['id'];
+		combo = this.combo;
+		var comboResult = function(data)
+		{
+			if (!handleError(data))
+				return;
+
+			var newFormat = new Array();
+			if (includeNull)
+				newFormat['NULL'] = "Nenhum";
+			for (var i = 0; i < data.length; i++)
+				newFormat[data[i][combo['id']]] = data[i][combo['name']];
+			if ((newFormat.length > 0) || includeNull)
+				displayArea.innerHTML = constructSelectBox(name, newFormat);
+			else
+				displayArea.innerHTML = '<i>nenhum registro encontado</i><input type="hidden" id="' + name + '" value=""/>';
+			if (callback)
+				callback();
+		};
+		this.list(comboResult, params);
+	},
+
+	ajaxAction: function(action, callback, params)
+	{
+		if (params == "")
+			cExecute('$this.bo_orgchart.' + action + this.name.charAt(0).capitalize() + this.name.substr(1), callback);
+		else
+			cExecute('$this.bo_orgchart.' + action + this.name.charAt(0).capitalize() + this.name.substr(1), callback, params);
+	}
+
+};
+
+var CadastroOrganization =
+{
+	name: 'organization',
+	required: new Array('nome', 'descricao', 'ativa'),
+	tableHeader: {'nome': 'Organização'},
+	combo: {'id': 'organizacao_id', 'name': 'nome'}
+};
+var objOrganization = new CadastroAjax();
+Object.extend(objOrganization, CadastroOrganization);
+
+var CadastroEmployeeStatus =
+{
+	name: 'employeeStatus',
+	required: new Array('descricao', 'exibir'),
+	tableHeader: {'descricao': 'Status de Funcionário'},
+	combo: {'id': 'funcionario_status_id', 'name': 'descricao'}
+};
+var objEmployeeStatus = new CadastroAjax();
+Object.extend(objEmployeeStatus, CadastroEmployeeStatus);
+
+var CadastroEmployeeCategory =
+{
+	name: 'employeeCategory',
+	required: new Array('organizacao_id', 'descricao'),
+	tableHeader: {'descricao': 'Nome'},
+	combo: {'id': 'funcionario_categoria_id', 'name': 'descricao'}
+};
+var objEmployeeCategory = new CadastroAjax();
+Object.extend(objEmployeeCategory, CadastroEmployeeCategory);
+
+var CadastroJobTitle =
+{
+	name: 'jobTitle',
+	required: new Array('organizacao_id', 'descricao'),
+	tableHeader: {'descricao': 'Nome'},
+	combo: {'id': 'cargo_id', 'name': 'descricao'}
+};
+var objJobTitle = new CadastroAjax();
+Object.extend(objJobTitle, CadastroJobTitle);
+
+var CadastroAreaStatus =
+{
+	name: 'areaStatus',
+	required: new Array('organizacao_id', 'descricao', 'nivel'),
+	tableHeader: {'descricao': 'Nome', 'nivel': 'Nível'},
+	combo: {'id': 'area_status_id', 'name': 'descricao'}
+};
+var objAreaStatus = new CadastroAjax();
+Object.extend(objAreaStatus, CadastroAreaStatus);
+
+var CadastroCostCenter =
+{
+	name: 'costCenter',
+	required: new Array('organizacao_id', 'nm_centro_custo', 'descricao', 'grupo'),
+	tableHeader: {'nm_centro_custo': 'Número', 'descricao': 'Nome', 'grupo': 'Grupo'},
+	combo: {'id': 'centro_custo_id', 'name': 'descricao'}
+};
+var objCostCenter = new CadastroAjax();
+Object.extend(objCostCenter, CadastroCostCenter);
+
+var CadastroLocal =
+{
+	name: 'local',
+	required: new Array('organizacao_id', 'descricao'),
+	tableHeader: {'descricao': 'Localidade'},
+	combo: {'id': 'localidade_id', 'name': 'descricao'}
+};
+var objLocal = new CadastroAjax();
+Object.extend(objLocal, CadastroLocal);
+
+var CadastroEmployee =
+{
+	name: 'employee',
+	required: new Array('funcionario_id', 'organizacao_id', 'funcionario_status_id', 'centro_custo_id', 'localidade_id', 'area_id'),
+	tableHeader: {'funcionario_id': 'Funcionário'},
+	combo: {'id': 'funcionario_id', 'name': 'funcionario_id'}
+};
+var objEmployee = new CadastroAjax();
+Object.extend(objEmployee, CadastroEmployee);
+
+var CadastroArea =
+{
+	name: 'area',
+	required: new Array('organizacao_id', 'area_status_id', 'centro_custo_id', 'superior_area_id', 'sigla', 'descricao', 'ativa'),
+	tableHeader: {'sigla': 'Área'},
+	combo: {'id': 'area_id', 'name': 'sigla'}
+};
+var objArea = new CadastroAjax();
+Object.extend(objArea, CadastroArea);
+
+var CadastroTelefone =
+{
+	name: 'telephones',
+	required: new Array('organizacao_id', 'descricao', 'numero'),
+	tableHeader: {'descricao': 'Descrição', 'numero': 'Telefones'},
+	combo: {'id': 'telefone_id', 'name': 'descricao'}
+};
+var objTelephones = new CadastroAjax();
+Object.extend(objTelephones, CadastroTelefone);
+
+var CadastroSubstituto =
+{
+	name: 'substitution',
+	required: new Array('organizacao_id', 'area_id', 'descricao', 'titular_funcionario_id', 'substituto_funcionario_id', 'data_inicio', 'data_fim'),
+	tableHeader: {'substituto_funcionario_id_desc': 'Nome', 'data_inicio': 'Data de início', 'data_fim': 'Data de término'},
+	combo: {}
+};
+var objSubstitution = new CadastroAjax();
+Object.extend(objSubstitution, CadastroSubstituto);
+
+
+function createOrganizationLayout(organizationID, organizationDiv)
+{
+	organizationDiv.innerHTML = '<div id="orgchartMenu_' + organizationID + '"></div>';
+	organizationDiv.innerHTML += '<div class="orgchartAreas" id="orgchartAreas_' + organizationID + '"></div>';
+	organizationDiv.innerHTML += '<div class="orgchartEmployees" id="orgchartEmployees_' + organizationID + '"></div>';
+	organizationDiv.innerHTML += '<div class="orgchartFooter"></div>';
+	organizationDiv.innerHTML += '<div id="employeeInfo" class="employeeInfo" style="display: none;"></div>';
+	organizationDiv.innerHTML += '<div id="areaInfo" class="employeeInfo" style="display: none;"></div>';
+
+	createOrganizationMenu(organizationID, $('orgchartMenu_' + organizationID));
+	loadOrganizationAreas(organizationID, $('orgchartAreas_' + organizationID));
+	lb_initialize();
+}
+
+function createOrganizationMenu(organizationID, div)
+{
+	var content = '<ul class="horizontalMenu">';
+	content += '<li style="margin: 5px 5px 0 5px">Atualizar : <select>'
+	content += '<option></option>'
+	content += '<option onclick="loadAddEmployeeStatusUI(' + organizationID  + ');" class="lbOn">Status de Funcionário</option>'
+	content += '<option onclick="loadAddEmployeeCategoryUI(' + organizationID  + ');" class="lbOn">Categorias</option>'
+	content += '<option onclick="loadAddJobTitleUI(' + organizationID  + ');" class="lbOn">Cargos</option>'
+	content += '<option onclick="loadAddAreaStatusUI(' + organizationID  + ');" class="lbOn">Status de Área</option>'
+	content += '<option onclick="loadAddCostCenterUI(' + organizationID  + ');" class="lbOn">Centros de Custo</option>'
+	content += '<option onclick="loadAddLocalUI(' + organizationID  + ');" class="lbOn">Localidade</option>'
+	content += '<option onclick="loadAddAreaUI(' + organizationID  + ');" class="lbOn">Áreas</option>'
+	content += '<option onclick="loadAddEmployeeUI(' + organizationID  + ');" class="lbOn">Funcionários</option>'
+	content += '<option onclick="loadAddTelephoneUI(' + organizationID  + ');" class="lbOn">Telefones</option>'
+	content += '<option onclick="loadAddSubstitutionUI(' + organizationID  + ');" class="lbOn">Substituições</option>'
+	content += '</select></li>';
+	content += '<li><a><input type="text" name="search_term" id="search_term" onkeypress="if (((window.Event) ? event.which : event.keyCode) == 13) $(\'search_span_' + organizationID  + '\').onclick(); return true;" /> <span id="search_span_' + organizationID + '" onclick="tmp = $$(\'div#orgchartAreas_' + organizationID + ' a.destaque\'); if (tmp[0]) tmp[0].removeClassName(\'destaque\'); searchEmployee(' + organizationID + ', $(\'orgchartEmployees_' + organizationID + '\')); return false;">busca</span></a></li>';
+	content += '</ul>';
+	content += '<br/>';
+	content += '<br/>';
+	div.innerHTML = content;
+}
+
+function loadOrganizationAreas(organizationID, div)
+{
+	var loadOrganizationAreasResult = function(data)
+	{
+		function recursivePrint(subdata)
+		{
+			for (var i = 0; i < subdata.length; i++)
+			{
+				div.innerHTML += '<br />' + '&nbsp;&nbsp;&nbsp;&nbsp;'.repeat(subdata[i]['depth']) + '<a href="javascript:void(0)" id="area_' + subdata[i]['area_id'] + '" onmouseover="getAreaInfoTimer(event, ' + subdata[i]['area_id'] + ', ' + organizationID + '); return false;" onmouseout="hideAreaInfo(); return false;" onclick="tmp = $$(\'div#orgchartAreas_' + organizationID + ' a.destaque\'); if (tmp[0]) tmp[0].removeClassName(\'destaque\'); this.addClassName(\'destaque\'); loadAreaEmployees(' + organizationID + ', ' + subdata[i]['area_id'] + ', $(\'orgchartEmployees_' + organizationID + '\'))">' + subdata[i]['sigla'] + '</a>';
+				if (subdata[i]['children'].length > 0)
+					recursivePrint(subdata[i]['children']);
+			}
+		}
+
+		if (!handleError(data))
+			return;
+
+		if (data.length == 0)
+		{
+			div.innerHTML = "<br/><br/><center><strong>Nenhuma área cadastrada.</strong></center><br/><br/>";
+			return;
+		}
+
+		div.innerHTML = "<center><strong>ÁREAS</strong></center>";
+		recursivePrint(data);
+		if (refreshEmployees[organizationID])
+			refreshEmployees[organizationID]();
+	};
+
+	objArea.ajaxAction('listHierarchical', loadOrganizationAreasResult, $H({'organizacao_id': organizationID}).toQueryString());
+	refreshAreas[organizationID] = function(){objArea.ajaxAction('listHierarchical', loadOrganizationAreasResult, $H({'organizacao_id': organizationID}).toQueryString());};
+}
+
+function searchEmployee(organizationID, div)
+{
+	var searchEmployeeResult = function(data)
+	{
+		if (!handleError(data))
+			return;
+
+		div.innerHTML = "";
+		if (data.length == 0)
+		{
+			div.innerHTML = "<br/><br/><center><strong>Nenhum funcionário encontrado.</strong></center>";
+			return;
+		}
+
+		var tableHeader = new Array();
+		tableHeader['funcionario_id_desc'] = 'Funcionário';
+		tableHeader['area_sigla'] = 'Área';
+		tableHeader['uid'] = 'UID';
+		tableHeader['actions'] = 'Ações';
+		for (var i = 0; i < data.length; i++)
+		{
+			var dataHash = new Hash();
+			for (j in data[i])
+				if (typeof data[i][j] != "function")
+					dataHash[j] = data[i][j];
+
+			data[i]['tr_attributes'] = new Array();
+			data[i]['tr_attributes']['class'] = "linha" + i%2;
+			data[i]['tr_attributes']['className'] = "linha" + i%2;
+			data[i]['funcionario_id_desc'] = '<a href="javascript:void(0)" class="lbOn" onmouseover="getEmployeeInfoTimer(event, ' + data[i]['funcionario_id'] + ', ' + organizationID + '); return false;" onmouseout="hideEmployeeInfo(); return false;" onclick="loadAddEmployeeUI(' + organizationID + ', function(){objEmployee.fillForm(' + dataHash.customInspect() + ')}); $(\'addEmployeeLink\').parentNode.removeChild($(\'addEmployeeLink\')); return false;">' + data[i]['funcionario_id_desc'] + '</a>' + (data[i]['removed'] ? ' <font color="red">(excluído)</font>' : '');
+			data[i]['actions'] = '<a href="#" onclick="objEmployee.remove({\'funcionario_id\': ' + data[i]['funcionario_id'] + ', \'organizacao_id\': ' + organizationID + '} , this.parentNode.parentNode); return false;"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/button_cancel.png" /></a>';
+		}
+
+		var tableAtributes = new Array();
+		tableAtributes['class'] = 'employeeList';
+		tableAtributes['className'] = 'employeeList';
+		div.appendChild(constructTable(tableHeader, data, tableAtributes));
+		lb_initialize();
+	};
+
+	objEmployee.ajaxAction('search', searchEmployeeResult, $H({'organizacao_id': organizationID, 'search_term': $F('search_term')}).toQueryString());
+	refreshEmployees[organizationID] = function(){objEmployee.ajaxAction('search', searchEmployeeResult, $H({'organizacao_id': organizationID, 'search_term': $F('search_term')}).toQueryString());};
+}
+
+function loadAreaEmployees(organizationID, areaID, div)
+{
+	var loadAreaEmployeesResult = function(data)
+	{
+		if (!handleError(data))
+			return;
+
+		var areaLink = $('area_' + areaID);
+		if (!areaLink.hasClassName('destaque'))
+			areaLink.addClassName('destaque');
+
+		div.innerHTML = "";
+		if (data.length == 0)
+		{
+			div.innerHTML = "<br/><br/><center><strong>Nenhum funcionário alocado nesta área.</strong></center>";
+			return;
+		}
+
+		var tableHeader = new Array();
+		tableHeader['funcionario_id_desc'] = 'Funcionário';
+		tableHeader['uid'] = 'UID';
+		tableHeader['actions'] = 'Ações';
+
+		var complement;
+		for (var i = 0; i < data.length; i++)
+		{
+			var dataHash = new Hash();
+			for (j in data[i])
+				if (typeof data[i][j] != "function")
+					dataHash[j] = data[i][j];
+
+			// are you a chief ('titular' or 'substituto')?
+			complement = '';
+			if (data[i]['chief'])
+				complement = ' <strong>(' + ((data[i]['chief'] == 1) ? 'Titular' : 'Substituto') + ')</strong>';
+
+			data[i]['tr_attributes'] = new Array();
+			data[i]['tr_attributes']['class'] = "linha" + i%2;
+			data[i]['tr_attributes']['className'] = "linha" + i%2;
+			data[i]['funcionario_id_desc'] = '<a href="javascript:void(0)" class="lbOn" onmouseover="getEmployeeInfoTimer(event, ' + data[i]['funcionario_id'] + ', ' + organizationID + '); return false;" onmouseout="hideEmployeeInfo(); return false;" onclick="loadAddEmployeeUI(' + organizationID + ', function(){objEmployee.fillForm(' + dataHash.customInspect() + ')}); $(\'addEmployeeLink\').parentNode.removeChild($(\'addEmployeeLink\')); return false;">' + data[i]['funcionario_id_desc'] + ' ' + complement + '</a>' + (data[i]['removed'] ? ' <font color="red">(excluído)</font>' : '');
+			data[i]['actions'] = '<a href="#" onclick="objEmployee.remove({\'funcionario_id\': ' + data[i]['funcionario_id'] + ', \'organizacao_id\': ' + organizationID + '} , this.parentNode.parentNode); return false;"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/button_cancel.png" /></a>';
+			window.scrollTo(0,0);
+		}
+
+		var tableAtributes = new Array();
+		tableAtributes['class'] = 'employeeList';
+		tableAtributes['className'] = 'employeeList';
+		div.appendChild(constructTable(tableHeader, data, tableAtributes));
+
+		lb_initialize();
+	};
+
+	objEmployee.ajaxAction('listArea', loadAreaEmployeesResult, $H({'area_id': areaID, 'organizacao_id': organizationID}).toQueryString());
+	refreshEmployees[organizationID] = function(){objEmployee.ajaxAction('listArea', loadAreaEmployeesResult, $H({'area_id': areaID, 'organizacao_id': organizationID}).toQueryString());};
+}
+
+function loadAddEmployeeStatusUI(organizationID)
+{
+	var valoresSimNao = new Array();
+	valoresSimNao['S'] = 'Sim';
+	valoresSimNao['N'] = 'Não';
+
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Status de Funcionário</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += "<table>";
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+	content += '<tr><td><label for="exibir">Exibir para o usuário</label></td>' + constructSelectBox('exibir', valoresSimNao) + '</td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objEmployeeStatus.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('descricao').focus();
+	objEmployeeStatus.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+}
+
+function loadAddEmployeeCategoryUI(organizationID)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Categoria</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += '<table>';
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objEmployeeCategory.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('descricao').focus();
+	objEmployeeCategory.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+}
+
+function loadAddJobTitleUI(organizationID)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Cargos</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += '<table>';
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objJobTitle.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('descricao').focus();
+	objJobTitle.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+}
+
+function loadAddAreaStatusUI(organizationID)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Status de Área</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += '<table>';
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+	content += '<tr><td><label for="nivel">Nível</label></td><td><input type="text" name="nivel" id="nivel" size="3" /></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objAreaStatus.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('descricao').focus();
+	objAreaStatus.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+}
+
+function loadAddCostCenterUI(organizationID)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Centro de Custo</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += "<table>";
+	content += '<tr><td><label for="nm_centro_custo">Número</label></td><td><input type="text" name="nm_centro_custo" id="nm_centro_custo" size="4" /></td></tr>';
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+	content += '<tr><td><label for="grupo">Grupo</label></td><td><input type="text" name="grupo" id="grupo" size="10" /></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objCostCenter.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('nm_centro_custo').focus();
+	objCostCenter.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+}
+
+function loadAddLocalUI(organizationID)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Localidade</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += "<table>";
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+
+	content += '<tr><td><label for="empresa">Empresa</label></td><td><input type="text" name="empresa" id="empresa" size="80" /></td></tr>';
+	content += '<tr><td><label for="endereco">Endereço</label></td><td><input type="text" name="endereco" id="endereco" size="80" /></td></tr>';
+	content += '<tr><td><label for="complemento">Complemento</label></td><td><input type="text" name="complemento" id="complemento" size="50" /></td></tr>';
+	content += '<tr><td><label for="cep">Cep</label></td><td><input type="text" name="cep" id="cep" size="10" /></td></tr>';
+	content += '<tr><td><label for="bairro">Bairro</label></td><td><input type="text" name="bairro" id="bairro" size="30" /></td></tr>';
+	content += '<tr><td><label for="cidade">Cidade</label></td><td><input type="text" name="cidade" id="cidade" size="50" /></td></tr>';
+	content += '<tr><td><label for="uf">UF</label></td><td><input type="text" name="uf" id="uf" size="2" maxlength="2" /></td></tr>';
+
+	content += '<tr><td><label for="centro_custo_id">Centro de Custo</label></td><td id="comboCentroCusto"><i>carregando</i></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objLocal.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('descricao').focus();
+	objCostCenter.generateComboBox({'organizacao_id': organizationID}, $('comboCentroCusto'), true, null,
+		function()
+		{
+			objLocal.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+		}
+	);
+}
+
+function loadAddEmployeeUI(organizationID, callback)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Funcionário</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += "<table>";
+	content += '<tr><td><label for="funcionario_id_desc">Funcionário</label></td><td>';
+	content += '<input type="hidden" name="funcionario_id" id="funcionario_id" value="" />';
+	content += '<input type="input" name="funcionario_id_desc" id="funcionario_id_desc" value="" readonly="true" size="40" />';
+	content += '<a href="javascript:void(0)" onclick="openParticipants(\'funcionario_id\', \'uid=1&hidegroups=1\');" id="addEmployeeLink"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/add_user.png" /></a>';
+	content += '</td></tr>';
+	content += '<tr><td><label for="funcionario_status_id">Status</label></td><td id="comboStatus"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="funcionario_categoria_id">Categoria</label></td><td id="comboFuncionarioCategoria"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="cargo_id">Cargo</label></td><td id="comboCargo"><i>carregando</i></td></tr>';
+
+	content += '<tr><td><label for="titulo">T&iacute;tulo</label></td><td><input type="text" size="30" name="titulo" id="titulo"/></td></tr>';
+
+	content += '<tr><td><label for="nivel">Nível</label></td><td><input type="text" size="3" name="nivel" id="nivel"/></td></tr>';
+	content += '<tr><td><label for="area_id">Área</label></td><td id="comboArea"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="centro_custo_id">Centro de Custo</label></td><td id="comboCentroCusto"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="localidade_id">Localidade</label></td><td id="comboLocalidade"><i>carregando</i></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objEmployee.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+
+	objEmployeeStatus.generateComboBox({'organizacao_id': organizationID}, $('comboStatus'), false, null,
+		function()
+		{
+			objEmployeeCategory.generateComboBox({'organizacao_id': organizationID}, $('comboFuncionarioCategoria'), true, null,
+				function()
+				{
+					objJobTitle.generateComboBox({'organizacao_id': organizationID}, $('comboCargo'), true, null,
+						function()
+						{
+							objArea.generateComboBox({'organizacao_id': organizationID}, $('comboArea'), false, null,
+								function()
+								{
+									objCostCenter.generateComboBox({'organizacao_id': organizationID}, $('comboCentroCusto'), true, null,
+										function()
+										{
+											objLocal.generateComboBox({'organizacao_id': organizationID}, $('comboLocalidade'), false, null, callback);
+										}
+									)
+								}
+							)
+						}
+					)
+				}
+			)
+		}
+	);
+}
+
+function loadAddAreaUI(organizationID)
+{
+	var valoresSimNao = new Array();
+	valoresSimNao['S'] = 'Sim';
+	valoresSimNao['N'] = 'Não';
+
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Área</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += "<table>";
+	content += '<tr><td><label for="sigla">Sigla</label></td><td><input type="text" name="sigla" id="sigla" size="15" /></td></tr>';
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" size="30" /></td></tr>';
+	content += '<tr><td><label for="titular_funcionario_id">Titular</label></td><td>';
+	content += '<input type="hidden" name="titular_funcionario_id" id="titular_funcionario_id" value="" />';
+	content += '<input type="input" name="titular_funcionario_id_desc" id="titular_funcionario_id_desc" value="" readonly="true" size="40" />';
+	content += '<a href="javascript:void(0)" onclick="openParticipants(\'titular_funcionario_id\', \'uid=1&hidegroups=1\');"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/add_user.png" /></a>';
+	content += ' <a href="javascript:void(0)" onclick="$(\'titular_funcionario_id\').value=\'\'; $(\'titular_funcionario_id_desc\').value=\'\'; return false;"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/delete_user.png" /></a>';
+	content += '</td></tr>';
+	content += '<tr><td><label for="auxiliar_funcionario_id">Auxiliar Administrativo</label></td><td>';
+	content += '<input type="hidden" name="auxiliar_funcionario_id" id="auxiliar_funcionario_id" value="" />';
+	content += '<input type="input" name="auxiliar_funcionario_id_desc" id="auxiliar_funcionario_id_desc" value="" readonly="true" size="40" />';
+	content += '<a href="javascript:void(0)" onclick="openParticipants(\'auxiliar_funcionario_id\', \'uid=1&hidegroups=1\');"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/add_user.png" /></a>';
+	content += ' <a href="javascript:void(0)" onclick="$(\'auxiliar_funcionario_id\').value=\'\'; $(\'auxiliar_funcionario_id_desc\').value=\'\'; return false;"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/delete_user.png" /></a>';
+	content += '</td></tr>';
+	content += '<tr><td><label for="area_status_id">Status</label></td><td id="comboStatus"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="superior_area_id">Área Superior</label></td><td id="comboArea"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="centro_custo_id">Centro de Custo</label></td><td id="comboCentroCusto"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="ativa">Ativa</label></td><td>' + constructSelectBox('ativa', valoresSimNao) + '</td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objArea.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('sigla').focus();
+
+	objAreaStatus.generateComboBox({'organizacao_id': organizationID}, $('comboStatus'), false, null,
+		function()
+		{
+			objArea.generateComboBox({'organizacao_id': organizationID}, $('comboArea'), true, 'superior_area_id',
+				function()
+				{
+					objCostCenter.generateComboBox({'organizacao_id': organizationID}, $('comboCentroCusto'), false, null,
+						function()
+						{
+							objArea.generateUpdateTable({'organizacao_id': organizationID}, divLB);
+						}
+					)
+				}
+			)
+		}
+	);
+}
+
+function loadAddTelephoneUI(organizationID)
+{
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Telefones da Organização</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += '<table>';
+	content += '<tr><td><label for="descricao">Descrição</label></td><td><input type="text" name="descricao" id="descricao" size="50" /></td></tr>';
+	content += '<tr><td><label for="nivel">Telefones</label></td><td><input type="text" name="numero" id="numero" size="50" /></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objTelephones.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $( 'lbContent' );
+	divLB.innerHTML = content;
+	$( 'descricao' ).focus( );
+	objTelephones.generateUpdateTable( { 'organizacao_id' : organizationID }, divLB );
+}
+
+
+function loadAddSubstitutionUI(organizationID)
+{
+	var area_id = 'combo_area';
+	var content;
+
+	content  = '<h2 id="modalTitle">Adicionar Substituição</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += '<input type="hidden" name="organizacao_id" id="organizacao_id" value="' + organizationID + '" />';
+	content += "<table>";
+	content += '<tr><td><label for="area_id">Sigla</label>';
+	content += '<input type="hidden" name="area_id" id="area_id" value="" />';
+	content += '</td><td id="comboArea"><i>carregando</i></td></tr>';
+	content += '<tr><td><label for="descricao">Nome</label></td><td><input type="text" name="descricao" id="descricao" readonly="true" size="40" /></td></tr>';
+	content += '<tr><td><label for="titular_funcionario_id">Titular</label></td><td>';
+	content += '<input type="hidden" name="titular_funcionario_id" id="titular_funcionario_id" value="" readonly="true" />';
+	content += '<input type="input" name="titular_funcionario_id_desc" id="titular_funcionario_id_desc" value="" readonly="true" size="40" />';
+	content += '</td></tr>';
+	content += '<tr><td><label for="substituto_funcionario_id">Substituto</label></td><td>';
+	content += '<input type="hidden" name="substituto_funcionario_id" id="substituto_funcionario_id" value="" />';
+	content += '<input type="input" name="substituto_funcionario_id_desc" id="substituto_funcionario_id_desc" value="" readonly="true" size="40" />';
+	content += '<a href="javascript:void(0)" onclick="openParticipants(\'substituto_funcionario_id\', \'uid=1&hidegroups=1\');"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/add_user.png" /></a>';
+	content += ' <a href="javascript:void(0)" onclick="$(\'substituto_funcionario_id\').value=\'\'; $(\'substituto_funcionario_id_desc\').value=\'\'; return false;"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/delete_user.png" /></a>';
+	content += '</td></tr>';
+	content += '<tr><td><label for="data_inicio">Data de início</label></td><td><input type="text" name="data_inicio" id="data_inicio" size="15" onkeypress="return formatDateField(event, this);" /></td></tr>';
+	content += '<tr><td><label for="data_fim">Data de término</label></td><td><input type="text" name="data_fim" id="data_fim" size="15" onkeypress="return formatDateField(event, this);"/></td></tr>';
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objSubstitution.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+
+	// function that must be called after loading areas on the combobox
+	var areas_callback = function () {
+
+		// every change on the combo box must query for area information
+		$(area_id).onchange = function () {
+			if ($('SubstitutionList'))
+				$('SubstitutionList').remove();
+			
+			var info_callback = function (data) {
+
+				// just to be sure
+				if (!data[0]) {
+					alert("Não foi possível encontrar os dados.");
+				}
+
+				// we received an empty response. Let's reset the form.
+				if ((data[0]['area_id'] == '') || (data[0]['area_id'] == null)) {
+					alert('RESET');
+					$('area_id').value = '';
+					$('descricao').value = '';
+					$('titular_funcionario_id').value = '';
+					$('titular_funcionario_id_desc').value = '';
+				}
+				// fill the form
+				else {
+					$('area_id').value = data[0]['area_id'];
+					$('descricao').value = data[0]['descricao'];
+					$('titular_funcionario_id').value = data[0]['titular_funcionario_id'];
+					$('titular_funcionario_id_desc').value = data[0]['titular_funcionario_id_desc'];
+				}
+
+				// get the list of substitutions
+				objSubstitution.generateUpdateTable({'organizacao_id': organizationID, 'area_id': $(area_id).value}, divLB);
+			}
+			objArea.list(info_callback, {'organizacao_id': organizationID, 'area_id': $(area_id).value});
+
+		}
+	}
+	objArea.generateComboBox({'organizacao_id': organizationID}, $('comboArea'), true, area_id, areas_callback);
+}
+
+function getEmployeeInfoTimer(e, employeeID, organizationID)
+{
+	var div = $('employeeInfo');
+	div.style.left = (Event.pointerX(e) + 20) + 'px';
+	div.style.top = (Event.pointerY(e) + 14) + 'px';
+
+	if (workflowOrgchartAdminEmployeeInfoTimer != null)
+	{
+		workflowOrgchartAdminEmployeeInfoTimer = clearTimeout(workflowOrgchartAdminEmployeeInfoTimer);
+		workflowOrgchartAdminEmployeeInfoTimer = null;
+	}
+
+	workflowOrgchartAdminEmployeeInfoTimer = setTimeout('getEmployeeInfo(' + employeeID + ', ' + organizationID + ' )', 500);
+}
+
+function getEmployeeInfo(employeeID, organizationID)
+{
+	function resultGetEmployeeInfo(data)
+	{
+		if (workflowOrgchartAdminEmployeeInfoTimer == null)
+			return;
+
+		workflowOrgchartAdminEmployeeInfoTimer = clearTimeout(workflowOrgchartAdminEmployeeInfoTimer);
+		workflowOrgchartAdminEmployeeInfoTimer = null;
+
+		var content = '';
+		content += '<table><tr><td valign="top">';
+		content += '<img src="workflow/showUserPicture.php?userID=' + employeeID + '"/>';
+		content += '</td><td valign="top" style="padding-left: 12px;">';
+		for (var i = 0; i < data['info'].length; i++)
+			content += '<strong>' + data['info'][i]['name'] + '</strong>: ' + data['info'][i]['value'] + '<br/>';
+		content += '</td></tr></table>';
+		var pageYLimit = document.body.scrollTop + document.body.clientHeight;
+		var div = $('employeeInfo');
+		div.innerHTML = content;
+
+		if ((parseInt(div.style.top.replace(/px/g, '')) + div.getHeight()) > pageYLimit)
+			div.style.top = (parseInt(div.style.top.replace(/px/g, '')) - (div.getHeight())) + 'px';
+
+		div.show();
+	}
+	cExecute('$this.bo_orgchart.getEmployeeInfo', resultGetEmployeeInfo, 'funcionario_id=' + employeeID + '&organizacao_id=' + organizationID);
+}
+
+function hideEmployeeInfo()
+{
+	if (workflowOrgchartAdminEmployeeInfoTimer != null)
+	{
+		workflowOrgchartAdminEmployeeInfoTimer = clearTimeout(workflowOrgchartAdminEmployeeInfoTimer);
+		workflowOrgchartAdminEmployeeInfoTimer = null;
+	}
+	$('employeeInfo').hide();
+}
+
+function getAreaInfoTimer(e, areaID, organizationID)
+{
+	var div = $('areaInfo');
+	div.style.left = (Event.pointerX(e) + 20) + 'px';
+	div.style.top = (Event.pointerY(e) + 14) + 'px';
+
+	if (workflowOrgchartAdminAreaInfoTimer != null)
+	{
+		workflowOrgchartAdminAreaInfoTimer = clearTimeout(workflowOrgchartAdminAreaInfoTimer);
+		workflowOrgchartAdminAreaInfoTimer = null;
+	}
+
+	workflowOrgchartAdminAreaInfoTimer = setTimeout('getAreaInfo(' + areaID + ', ' + organizationID + ' )', 500);
+}
+
+function getAreaInfo(areaID, organizationID)
+{
+	function resultGetAreaInfo(data)
+	{
+		if (workflowOrgchartAdminAreaInfoTimer == null)
+			return;
+
+		workflowOrgchartAdminAreaInfoTimer = clearTimeout(workflowOrgchartAdminAreaInfoTimer);
+		workflowOrgchartAdminAreaInfoTimer = null;
+
+		var content = '';
+		content += '<table><tr>';
+		content += '<td valign="top" style="padding-left: 12px;">';
+		for (var i = 0; i < data['info'].length; i++)
+			content += '<strong>' + data['info'][i]['name'] + '</strong>: ' + data['info'][i]['value'] + '<br/>';
+		content += '</td></tr></table>';
+		var pageYLimit = document.body.scrollTop + document.body.clientHeight;
+		var div = $('areaInfo');
+		div.innerHTML = content;
+
+		if ((parseInt(div.style.top.replace(/px/g, '')) + div.getHeight()) > pageYLimit)
+			div.style.top = (parseInt(div.style.top.replace(/px/g, '')) - (div.getHeight())) + 'px';
+
+		div.show();
+	}
+	cExecute('$this.bo_orgchart.getAreaInfo', resultGetAreaInfo, 'area_id=' + areaID + '&organizacao_id=' + organizationID);
+}
+
+function hideAreaInfo()
+{
+	if (workflowOrgchartAdminAreaInfoTimer != null)
+	{
+		workflowOrgchartAdminAreaInfoTimer = clearTimeout(workflowOrgchartAdminAreaInfoTimer);
+		workflowOrgchartAdminAreaInfoTimer = null;
+	}
+	$('areaInfo').hide();
+}
Index: /sandbox/workflow/branches/993/js/orgchart/organizations.js
===================================================================
--- /sandbox/workflow/branches/993/js/orgchart/organizations.js	(revision 1245)
+++ /sandbox/workflow/branches/993/js/orgchart/organizations.js	(revision 1245)
@@ -0,0 +1,83 @@
+function createMenu()
+{
+	var content = '<ul class="horizontalMenu">';
+	content += '<li><a href="#" onclick="loadAddOrganizationUI(); return false;" class="lbOn">Organizações</a></li>';
+	content += '</ul>';
+	content += '<br/>';
+	content += '<br/>';
+	$('content_id_0').innerHTML = content;
+}
+
+function listOrganizations()
+{
+	var listOrganizationsResult = function(data)
+	{
+		var tmp = $('organizationList');
+		if (tmp)
+			tmp.parentNode.removeChild(tmp);
+
+		for (var i = 0; i < data.length; i++)
+		{
+			data[i]['nome'] = '<a href="#" onclick="clickLoadOrganization(this, ' + data[i]['organizacao_id'] + '); return false;">' + data[i]['nome'] + '</a>';
+			data[i]['tr_attributes'] = new Array();
+			data[i]['tr_attributes']['class'] = "linha" + i%2;;
+			data[i]['tr_attributes']['className'] = "linha" + i%2;;
+		}
+
+		var tableHeader = new Array();
+		tableHeader['nome'] = 'Organização';
+		tableHeader['descricao'] = 'Descrição';
+
+		var tableAtributes = new Array();
+		tableAtributes['id'] = "organizationList";
+		tableAtributes['class'] = 'organizationList';
+		tableAtributes['className'] = 'organizationList';
+
+		var table = $('organizationList');
+		if (table)
+			table.parentNode.removeChild(table);
+
+		$('content_id_0').appendChild(constructTable(tableHeader, data, tableAtributes));
+	};
+
+	objOrganization.list(listOrganizationsResult, {});
+}
+
+function loadAddOrganizationUI()
+{
+	var valoresSimNao = new Array();
+	valoresSimNao['S'] = 'Sim';
+	valoresSimNao['N'] = 'Não';
+
+	var content;
+	content = '<h2 id="modalTitle">Adicionar Organização</h2>';
+	content += '<form name="orgchartForm" id="orgchartForm">';
+	content += "<table>";
+	content += '<tr><td><label for="nome">Nome</label></td><td><input type="text" name="nome" id="nome" size="50" /></td></tr>';
+	content += '<tr><td><label for="descricao">Descrição</label></td><td><textarea name="descricao" id="descricao" cols="40" rows="5"></textarea></td></tr>';
+	content += '<tr><td><label for="ativa">Ativa</label></td><td>' + constructSelectBox('ativa', valoresSimNao) + '</td></tr>';
+	content += '<tr><td><label for="url_imagem">Imagem</label></td><td><input tyle="text" name="url_imagem" id="url_imagem" size="50" /></td></tr>';
+
+	content += '<tr><td><label for="sitio">S&iacute;tio</label></td><td><input tyle="text" name="sitio" id="sitio" size="80" /></td></tr>';
+
+	content += "</table>";
+	content += '</form>';
+	content += '<button id="inserir" onclick="objOrganization.add(); return false;">Inserir</button>';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	var divLB = $('lbContent');
+	divLB.innerHTML = content;
+	$('nome').focus();
+	objOrganization.generateUpdateTable({}, divLB);
+}
+
+function clickLoadOrganization(link, organizationID)
+{
+	if ($('orgchartMenu_' + organizationID))
+		return;
+	refreshAreas[organizationID] = null;
+	refreshEmployees[organizationID] = null;
+	var border_id = create_border(link.innerHTML);
+	var divNewOrganization = $('content_id_' + border_id);
+	createOrganizationLayout(organizationID, divNewOrganization);
+}
Index: /sandbox/workflow/branches/993/js/orgchart/utils.js
===================================================================
--- /sandbox/workflow/branches/993/js/orgchart/utils.js	(revision 2371)
+++ /sandbox/workflow/branches/993/js/orgchart/utils.js	(revision 2371)
@@ -0,0 +1,84 @@
+function constructTable(header, content, atributes)
+{
+	/*** constrói a tabela ***/
+	var table = document.createElement("TABLE");
+
+	table.style.marginTop = "10px";
+
+	/* configura a tabela */
+	if (atributes)
+		for (i in atributes)
+			if (typeof atributes[i] != "function")
+				table.setAttribute(i, atributes[i]);
+
+	var tbody = document.createElement("TBODY");
+	var tr;
+	var td;
+
+	/* cabeçalho */
+	tr = document.createElement("TR");
+	tr.className = 'message_header';
+	for (i in header)
+	{
+		if (typeof header[i] != "function")
+		{
+			td = document.createElement("TH");
+			td.innerHTML = header[i];
+			td.className = 'message_header';
+			tr.appendChild(td);
+		}
+	}
+	tbody.appendChild(tr);
+
+	/* elementos da tabela */
+	for (var i = 0; i < content.length; i++)
+	{
+		/* atributos da linha (TR) */
+		tr = document.createElement("TR");
+		if (content[i]['tr_attributes'])
+			for (j in content[i]['tr_attributes'])
+				if (typeof content[i]['tr_attributes'][j] != "function")
+					tr.setAttribute(j, content[i]['tr_attributes'][j]);
+
+		/* dados da tabela */
+		for (j in header)
+		{
+			if (typeof header[j] != "function")
+			{
+				td = document.createElement("TD");
+				td.innerHTML = content[i][j];
+				tr.appendChild(td);
+			}
+		}
+		tbody.appendChild(tr);
+	}
+	table.appendChild(tbody);
+
+	return table;
+}
+
+/* constrói select boxes */
+function constructSelectBox(name, items, selected)
+{
+	var output = '';
+
+	output = '<select name="' + name + '" id="' + name  + '">';
+	for (i in items)
+		if (typeof items[i] != "function")
+			output += '<option value="' + i + '"' +  ((i == selected) ? ' selected' : '') + '>' + items[i] + '</option>';
+	output += '</select>';
+
+	return output;
+}
+
+/* gerencia possíveis erros oriundos do método chamado via Ajax */
+function handleError(data)
+{
+	if (typeof(data) == "string")
+	{
+		write_errors(data);
+		return false;
+	}
+	else
+		return true;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/fckpackager.xml
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/fckpackager.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/fckpackager.xml	(revision 795)
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the configuration file to be used with FCKpackager to generate the
+ * compressed code files in the "js" folder.
+ *
+ * Please check http://www.fckeditor.net for more info.
+-->
+<Package>
+	<Header><![CDATA[/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * This file has been compressed for better performance. The original source
+ * can be found at "editor/_source".
+ */
+]]></Header>
+	<Constants removeDeclaration="false">
+		<Constant name="FCK_STATUS_NOTLOADED" value="0" />
+		<Constant name="FCK_STATUS_ACTIVE" value="1" />
+		<Constant name="FCK_STATUS_COMPLETE" value="2" />
+		<Constant name="FCK_TRISTATE_OFF" value="0" />
+		<Constant name="FCK_TRISTATE_ON" value="1" />
+		<Constant name="FCK_TRISTATE_DISABLED" value="-1" />
+		<Constant name="FCK_UNKNOWN" value="-9" />
+		<Constant name="FCK_TOOLBARITEM_ONLYICON" value="0" />
+		<Constant name="FCK_TOOLBARITEM_ONLYTEXT" value="1" />
+		<Constant name="FCK_TOOLBARITEM_ICONTEXT" value="2" />
+		<Constant name="FCK_EDITMODE_WYSIWYG" value="0" />
+		<Constant name="FCK_EDITMODE_SOURCE" value="1" />
+	</Constants>
+	<PackageFile path="editor/js/fckeditorcode_ie.js">
+		<File path="editor/_source/fckconstants.js" />
+		<File path="editor/_source/fckjscoreextensions.js" />
+		<File path="editor/_source/classes/fckiecleanup.js" />
+		<File path="editor/_source/internals/fckbrowserinfo.js" />
+		<File path="editor/_source/internals/fckurlparams.js" />
+		<File path="editor/_source/classes/fckevents.js" />
+		<File path="editor/_source/internals/fck.js" />
+		<File path="editor/_source/internals/fck_ie.js" />
+		<File path="editor/_source/internals/fckconfig.js" />
+		<File path="editor/_source/internals/fckdebug.js" />
+		<File path="editor/_source/internals/fckdomtools.js" />
+		<File path="editor/_source/internals/fcktools.js" />
+		<File path="editor/_source/internals/fcktools_ie.js" />
+		<File path="editor/_source/fckeditorapi.js" />
+		<File path="editor/_source/classes/fckimagepreloader.js" />
+
+		<File path="editor/_source/internals/fckregexlib.js" />
+		<File path="editor/_source/internals/fcklistslib.js" />
+		<File path="editor/_source/internals/fcklanguagemanager.js" />
+		<File path="editor/_source/internals/fckxhtmlentities.js" />
+		<File path="editor/_source/internals/fckxhtml.js" />
+		<File path="editor/_source/internals/fckxhtml_ie.js" />
+		<File path="editor/_source/internals/fckcodeformatter.js" />
+		<File path="editor/_source/internals/fckundo_ie.js" />
+		<File path="editor/_source/classes/fckeditingarea.js" />
+		<File path="editor/_source/classes/fckkeystrokehandler.js" />
+
+		<File path="editor/_source/internals/fcklisthandler.js" />
+		<File path="editor/_source/classes/fckelementpath.js" />
+		<File path="editor/_source/classes/fckdomrange.js" />
+		<File path="editor/_source/classes/fckdomrange_ie.js" />
+		<File path="editor/_source/classes/fckdocumentfragment_ie.js" />
+		<File path="editor/_source/classes/fckw3crange.js" />
+		<File path="editor/_source/classes/fckenterkey.js" />
+
+		<File path="editor/_source/internals/fckdocumentprocessor.js" />
+		<File path="editor/_source/internals/fckselection.js" />
+		<File path="editor/_source/internals/fckselection_ie.js" />
+
+		<File path="editor/_source/internals/fcktablehandler.js" />
+		<File path="editor/_source/internals/fcktablehandler_ie.js" />
+		<File path="editor/_source/classes/fckxml_ie.js" />
+		<File path="editor/_source/classes/fckstyledef.js" />
+		<File path="editor/_source/classes/fckstyledef_ie.js" />
+		<File path="editor/_source/classes/fckstylesloader.js" />
+
+		<File path="editor/_source/commandclasses/fcknamedcommand.js" />
+		<File path="editor/_source/commandclasses/fck_othercommands.js" />
+		<File path="editor/_source/commandclasses/fckspellcheckcommand_ie.js" />
+		<File path="editor/_source/commandclasses/fcktextcolorcommand.js" />
+		<File path="editor/_source/commandclasses/fckpasteplaintextcommand.js" />
+		<File path="editor/_source/commandclasses/fckpastewordcommand.js" />
+		<File path="editor/_source/commandclasses/fcktablecommand.js" />
+		<File path="editor/_source/commandclasses/fckstylecommand.js" />
+		<File path="editor/_source/commandclasses/fckfitwindow.js" />
+		<File path="editor/_source/internals/fckcommands.js" />
+
+		<File path="editor/_source/classes/fckpanel.js" />
+		<File path="editor/_source/classes/fckicon.js" />
+		<File path="editor/_source/classes/fcktoolbarbuttonui.js" />
+		<File path="editor/_source/classes/fcktoolbarbutton.js" />
+		<File path="editor/_source/classes/fckspecialcombo.js" />
+		<File path="editor/_source/classes/fcktoolbarspecialcombo.js" />
+		<File path="editor/_source/classes/fcktoolbarfontscombo.js" />
+		<File path="editor/_source/classes/fcktoolbarfontsizecombo.js" />
+		<File path="editor/_source/classes/fcktoolbarfontformatcombo.js" />
+		<File path="editor/_source/classes/fcktoolbarstylecombo.js" />
+		<File path="editor/_source/classes/fcktoolbarpanelbutton.js" />
+		<File path="editor/_source/internals/fcktoolbaritems.js" />
+		<File path="editor/_source/classes/fcktoolbar.js" />
+		<File path="editor/_source/classes/fcktoolbarbreak_ie.js" />
+		<File path="editor/_source/internals/fcktoolbarset.js" />
+		<File path="editor/_source/internals/fckdialog.js" />
+		<File path="editor/_source/internals/fckdialog_ie.js" />
+
+		<File path="editor/_source/classes/fckmenuitem.js" />
+		<File path="editor/_source/classes/fckmenublock.js" />
+		<File path="editor/_source/classes/fckmenublockpanel.js" />
+		<File path="editor/_source/classes/fckcontextmenu.js" />
+		<File path="editor/_source/internals/fck_contextmenu.js" />
+
+		<File path="editor/_source/classes/fckplugin.js" />
+		<File path="editor/_source/internals/fckplugins.js" />
+	</PackageFile>
+
+	<PackageFile path="editor/js/fckeditorcode_gecko.js">
+		<File path="editor/_source/fckconstants.js" />
+		<File path="editor/_source/fckjscoreextensions.js" />
+		<File path="editor/_source/internals/fckbrowserinfo.js" />
+		<File path="editor/_source/internals/fckurlparams.js" />
+		<File path="editor/_source/classes/fckevents.js" />
+		<File path="editor/_source/internals/fck.js" />
+		<File path="editor/_source/internals/fck_gecko.js" />
+		<File path="editor/_source/internals/fckconfig.js" />
+		<File path="editor/_source/internals/fckdebug.js" />
+		<File path="editor/_source/internals/fckdomtools.js" />
+		<File path="editor/_source/internals/fcktools.js" />
+		<File path="editor/_source/internals/fcktools_gecko.js" />
+		<File path="editor/_source/fckeditorapi.js" />
+		<File path="editor/_source/classes/fckimagepreloader.js" />
+
+		<File path="editor/_source/internals/fckregexlib.js" />
+		<File path="editor/_source/internals/fcklistslib.js" />
+		<File path="editor/_source/internals/fcklanguagemanager.js" />
+		<File path="editor/_source/internals/fckxhtmlentities.js" />
+		<File path="editor/_source/internals/fckxhtml.js" />
+		<File path="editor/_source/internals/fckxhtml_gecko.js" />
+		<File path="editor/_source/internals/fckcodeformatter.js" />
+		<File path="editor/_source/internals/fckundo_gecko.js" />
+		<File path="editor/_source/classes/fckeditingarea.js" />
+		<File path="editor/_source/classes/fckkeystrokehandler.js" />
+
+		<File path="editor/_source/internals/fcklisthandler.js" />
+		<File path="editor/_source/classes/fckelementpath.js" />
+		<File path="editor/_source/classes/fckdomrange.js" />
+		<File path="editor/_source/classes/fckdomrange_gecko.js" />
+		<File path="editor/_source/classes/fckdocumentfragment_gecko.js" />
+		<File path="editor/_source/classes/fckw3crange.js" />
+		<File path="editor/_source/classes/fckenterkey.js" />
+
+		<File path="editor/_source/internals/fckdocumentprocessor.js" />
+		<File path="editor/_source/internals/fckselection.js" />
+		<File path="editor/_source/internals/fckselection_gecko.js" />
+
+		<File path="editor/_source/internals/fcktablehandler.js" />
+		<File path="editor/_source/internals/fcktablehandler_gecko.js" />
+		<File path="editor/_source/classes/fckxml_gecko.js" />
+		<File path="editor/_source/classes/fckstyledef.js" />
+		<File path="editor/_source/classes/fckstyledef_gecko.js" />
+		<File path="editor/_source/classes/fckstylesloader.js" />
+
+		<File path="editor/_source/commandclasses/fcknamedcommand.js" />
+		<File path="editor/_source/commandclasses/fck_othercommands.js" />
+		<File path="editor/_source/commandclasses/fckspellcheckcommand_gecko.js" />
+		<File path="editor/_source/commandclasses/fcktextcolorcommand.js" />
+		<File path="editor/_source/commandclasses/fckpasteplaintextcommand.js" />
+		<File path="editor/_source/commandclasses/fckpastewordcommand.js" />
+		<File path="editor/_source/commandclasses/fcktablecommand.js" />
+		<File path="editor/_source/commandclasses/fckstylecommand.js" />
+		<File path="editor/_source/commandclasses/fckfitwindow.js" />
+		<File path="editor/_source/internals/fckcommands.js" />
+
+		<File path="editor/_source/classes/fckpanel.js" />
+		<File path="editor/_source/classes/fckicon.js" />
+		<File path="editor/_source/classes/fcktoolbarbuttonui.js" />
+		<File path="editor/_source/classes/fcktoolbarbutton.js" />
+		<File path="editor/_source/classes/fckspecialcombo.js" />
+		<File path="editor/_source/classes/fcktoolbarspecialcombo.js" />
+		<File path="editor/_source/classes/fcktoolbarfontscombo.js" />
+		<File path="editor/_source/classes/fcktoolbarfontsizecombo.js" />
+		<File path="editor/_source/classes/fcktoolbarfontformatcombo.js" />
+		<File path="editor/_source/classes/fcktoolbarstylecombo.js" />
+		<File path="editor/_source/classes/fcktoolbarpanelbutton.js" />
+		<File path="editor/_source/internals/fcktoolbaritems.js" />
+		<File path="editor/_source/classes/fcktoolbar.js" />
+		<File path="editor/_source/classes/fcktoolbarbreak_gecko.js" />
+		<File path="editor/_source/internals/fcktoolbarset.js" />
+		<File path="editor/_source/internals/fckdialog.js" />
+		<File path="editor/_source/internals/fckdialog_gecko.js" />
+
+		<File path="editor/_source/classes/fckmenuitem.js" />
+		<File path="editor/_source/classes/fckmenublock.js" />
+		<File path="editor/_source/classes/fckmenublockpanel.js" />
+		<File path="editor/_source/classes/fckcontextmenu.js" />
+		<File path="editor/_source/internals/fck_contextmenu.js" />
+
+		<File path="editor/_source/classes/fckplugin.js" />
+		<File path="editor/_source/internals/fckplugins.js" />
+	</PackageFile>
+
+</Package>
Index: /sandbox/workflow/branches/993/js/fckeditor/license.txt
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/license.txt	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/license.txt	(revision 795)
@@ -0,0 +1,1247 @@
+FCKeditor - The text editor for Internet - http://www.fckeditor.net
+Copyright (C) 2003-2007 Frederico Caldeira Knabben
+
+Licensed under the terms of any of the following licenses at your
+choice:
+
+ - GNU General Public License Version 2 or later (the "GPL")
+   http://www.gnu.org/licenses/gpl.html
+   (See Appendix A)
+
+ - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+   http://www.gnu.org/licenses/lgpl.html
+   (See Appendix B)
+
+ - Mozilla Public License Version 1.1 or later (the "MPL")
+   http://www.mozilla.org/MPL/MPL-1.1.html
+   (See Appendix C)
+
+You are not required to, but if you want to explicitly declare the
+license you have chosen to be bound to when using, reproducing,
+modifying and distributing this software, just include a text file
+titled "legal.txt" in your version of this software, indicating your
+license choice. In any case, your choice will not restrict any
+recipient of your version of this software to use, reproduce, modify
+and distribute this software under any of the above licenses.
+
+Appendix A: The GPL License
+===========================
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+Appendix B: The LGPL License
+============================
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+Appendix C: The MPL License
+===========================
+
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (the "License"); you may not use this file except in
+     compliance with the License. You may obtain a copy of the License at
+     http://www.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
Index: /sandbox/workflow/branches/993/js/fckeditor/fcktemplates.xml
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/fcktemplates.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/fcktemplates.xml	(revision 795)
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the sample templates definitions file. It makes the "templates"
+ * command completely customizable.
+ *
+ * See FCKConfig.TemplatesXmlPath in the configuration file.
+-->
+<Templates imagesBasePath="fck_template/images/">
+	<Template title="Image and Title" image="template1.gif">
+		<Description>One main image with a title and text that surround the image.</Description>
+		<Html>
+			<![CDATA[
+				<img style="MARGIN-RIGHT: 10px" height="100" alt="" width="100" align="left"/>
+				<h3>Type the title here</h3>
+				Type the text here
+			]]>
+		</Html>
+	</Template>
+	<Template title="Strange Template" image="template2.gif">
+		<Description>A template that defines two colums, each one with a title, and some text.</Description>
+		<Html>
+			<![CDATA[
+				<table cellspacing="0" cellpadding="0" width="100%" border="0">
+					<tbody>
+						<tr>
+							<td width="50%">
+							<h3>Title 1</h3>
+							</td>
+							<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </td>
+							<td width="50%">
+							<h3>Title 2</h3>
+							</td>
+						</tr>
+						<tr>
+							<td>Text 1</td>
+							<td>&nbsp;</td>
+							<td>Text 2</td>
+						</tr>
+					</tbody>
+				</table>
+				More text goes here.
+			]]>
+		</Html>
+	</Template>
+	<Template title="Text and Table" image="template3.gif">
+		<Description>A title with some text and a table.</Description>
+		<Html>
+			<![CDATA[
+				<table align="left" width="80%" border="0" cellspacing="0" cellpadding="0"><tr><td>
+					<h3>Title goes here</h3>
+					<p>
+					<table style="FLOAT: right" cellspacing="0" cellpadding="0" width="150" border="1">
+						<tbody>
+							<tr>
+								<td align="center" colspan="3"><strong>Table title</strong></td>
+							</tr>
+							<tr>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+							</tr>
+							<tr>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+							</tr>
+							<tr>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+							</tr>
+							<tr>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+								<td>&nbsp;</td>
+							</tr>
+						</tbody>
+					</table>
+					Type the text here</p>
+				</td></tr></table>
+			]]>
+		</Html>
+	</Template>
+</Templates>
Index: /sandbox/workflow/branches/993/js/fckeditor/_whatsnew.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/_whatsnew.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/_whatsnew.html	(revision 795)
@@ -0,0 +1,2675 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor - What's New?</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<style type="text/css">
+		body { font-family: arial, verdana, sans-serif }
+		p { margin-left: 20px }
+	</style>
+</head>
+<body>
+	<h3>
+		Version 2.4.2</h3>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/279">#279</a>] The UTF-8
+			BOM was being included in the wrong files, affecting mainly PHP installations.</li>
+	</ul>
+	<h3>
+		Version 2.4.1</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/118">#118</a>] The SelectAll
+			command now is available in Source Mode.</li>
+		<li>The new open source FCKpackager sub-project is now available. It replaces the FCKeditor.Packager
+			software to compact the editor source.</li>
+		<li>With Firefox, if a paste execution is blocked by the browser security settings,
+			the new "Paste" popup is shown to the user to complete the pasting operation. </li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>Various fixes to the ColdFusion File Browser connector.</li>
+		<li>We are now pointing the download of ieSpell to their pages, instead to a direct
+			file download from one of their mirrors. This disables the ability of "click and
+			go" (which can still be achieved by pointing the download to a file in your server),
+			but removes any troubles with mirrors link changes (and they change it frequently).</li>
+		<li>The Word cleanup has been changed to remove "display:none" tags that may come from
+			Word.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1659613&group_id=75348">SF
+			BUG-1659613</a>] The 2.4 version introduced a bug in the flash handling code that
+			generated out of memory errors in IE7.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1660456&group_id=75348">SF
+			BUG-1660456</a>] The icons in context menus were draggable.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1653009&group_id=75348">SF
+			BUG-1653009</a>] If the server is configured to process html files as asp then it
+			generated ASP error 0138.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1288609&group_id=75348">SF
+			BUG-1288609</a>] The content of iframes is now preserved.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1245504&group_id=75348">SF
+			BUG-1245504</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1652240&group_id=75348">SF
+				BUG-1652240</a>] Flash files without the .swf extension weren't recognized upon
+			reload.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1649753&group_id=75348&atid=543655">SF
+			PATCH-1649753</a>] Node selection for text didn't work in IE. Thanks to yurik dot
+			m.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1573191&group_id=75348&atid=543653">SF
+			BUG-1573191</a>] The Html code inserted with FCK.InsertHtml didn't have the same
+			protection for special tags.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/110">#110</a>] The OK
+			button in dialogs had its width set as an inline style.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/113">#113</a>] [<a
+			target="_blank" href="http://dev.fckeditor.net/ticket/94">#94</a>] [<a target="_blank"
+				href="https://sourceforge.net/tracker/?func=detail&aid=1659270&group_id=75348&atid=543653">SF
+				BUG-1659270</a>] ForcePasteAsPlainText didn't work in Firefox.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/114">#114</a>] The correct
+			entity is now used to fill empty blocks when ProcessHTMLEntities is disabled.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/90">#90</a>] The editor
+			was wrongly removing some &lt;br&gt; tags from the code.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/139">#139</a>] The CTRL+F
+			and CTRL+S keystroke default behaviors are now preserved.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/138">#138</a>] We are
+			not providing a CTRL + ALT combination in the default configuration file because
+			it may be incompatible with some keyboard layouts. So, the CTRL + ALT + S combination
+			has been changed to CTRL + SHIFT + S.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/129">#129</a>] In IE,
+			it was not possible to paste if "Allow paste operation via script" was disabled
+			in the browser security settings.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/112">#112</a>] The enter
+			key now behaves correctly on lists with Firefox, when the EnterMode is set to 'br'.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/152">#152</a>] Invalid
+			self-closing tags are now being fixed before loading. </li>
+		<li>A few tags were being ignored to the check for required contents (not getting stripped
+			out, as expected). Fixed.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/202">#202</a>] The HR
+			tag will not anymore break the contents loaded in the editor.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/211">#211</a>] Some invalid
+			inputs, like "&lt;p&gt;" where making the caret disappear in Firefox.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/99">#99</a>] The &lt;div&gt;
+			element is now considered a block container if EnterMode=p|br. It acts like a simple
+			block only if EnterMode=div.</li>
+		<li>Hidden fields will now show up as an icon in IE, instead of a normal text field.
+			They are also selectable and draggable, in all browsers.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/213">#213</a>] Styles
+			are now preserved when hitting enter at the end of a paragraph.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/77">#77</a>] If ShiftEnterMode
+			is set to a block tag (p or div), the desired block creation in now enforced, instead
+			of copying the current block (which is still the behavior of the simple enter).</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/209">#209</a>] Links and
+			images URLs will now be correctly preserved with Netscape 7.1.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/165">#165</a>] The enter
+			key now honors the EnterMode settings when outdenting a list item.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/190">#190</a>] Toolbars
+			may be wrongly positioned. Fixed.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/254">#254</a>] The IgnoreEmptyParagraphValue
+			setting is now correctly handled in Firefox.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/254">#248</a>] The behavior
+			of the backspace key has been fixed on some very specific cases.</li>
+	</ul>
+	<h3>
+		Version 2.4</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1329273&group_id=75348&atid=543656">SF
+			Feature-1329273</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1456005&group_id=75348&atid=543656">SF
+				Feature-1456005</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1315002&group_id=75348&atid=543653">SF
+					BUG-1315002</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1350180&group_id=75348&atid=543653">SF
+						BUG-1350180</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1450689&group_id=75348&atid=543653">SF
+							BUG-1450689</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1461033&group_id=75348&atid=543653">SF
+								BUG-1461033</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1510111&group_id=75348&atid=543653">SF
+									BUG-1510111</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1203560&group_id=75348&atid=543653">SF
+										BUG-1203560</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1564838&group_id=75348&atid=543653">SF
+											BUG-1564838</a>] The advance <strong>Enter Key Handler</strong>
+			is now being introduced. It gives you complete freedom to configure the editor to
+			generate <strong>&lt;p&gt;, &lt;div&gt; or &lt;br&gt;</strong> when the user uses
+			both the [Enter] and [Shift]+[Enter] keys. The new "EnterMode" and "ShiftEnterMode"
+			settings can be use to control its behavior. It also guarantees that all browsers
+			will generate the same output. </li>
+		<li>The new and powerful <strong>Keyboard Accelerator System</strong> is being introduced.
+			You can now precisely control the commands to execute when some key combinations
+			are activated by the user. It guarantees that all browsers will have the same behavior
+			regarding the shortcuts.<br />
+			It also makes it possible to remove buttons from the toolbar and still invoke their
+			features by using the keyboard instead.
+			<br />
+			It also blocks all default "CTRL based shortcuts" imposed by the browsers, so if
+			you don't want users to underline text, just remove the CTRL+U combination from
+			the keystrokes table. Take a look at the FCKConfig.Keystrokes setting in the fckconfig.js
+			file. </li>
+		<li>The new "<strong>ProtectedTags</strong>" configuration option is being introduced.
+			It will accept a list of tags (separated by a pipe "|"), which will have no effect
+			during editing, but will still be part of the document DOM. This can be used mainly
+			for non HTML standard, custom tags.</li>
+		<li>Dialog box commands can now open resizable dialogs (by setting oCommand.Resizable
+			= true).</li>
+		<li>Updated support for AFP. Thanks to Soenke Freitag.</li>
+		<li>New language file:<ul>
+			<li><strong>Afrikaans</strong> (by Willem Petrus Botha). </li>
+		</ul>
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1456343&group_id=75348&atid=543655">SF
+			Patch-1456343</a>] New sample file showing how to dynamically exchange a textarea
+			and an instance of FCKeditor. Thanks to Finn Hakansson</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1496115&group_id=75348&atid=543655">SF
+			Patch-1496115</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1588578&group_id=75348&atid=543653">SF
+				BUG-1588578</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1376534&group_id=75348&atid=543653">SF
+					BUG-1376534</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1343506&group_id=75348&atid=543653">SF
+						BUG-1343506</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1211065&group_id=75348&atid=543656">SF
+							Feature-1211065</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=949144&group_id=75348&atid=543656">SF
+								Feature-949144</a>] The content of anchors are shown and preserved
+			on creation. * </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1587175&group_id=75348&atid=543656">SF
+			Feature-1587175</a>] Local links to an anchor are readjusted if the anchor changes.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1500040&group_id=75348&atid=543655">SF
+			Patch-1500040</a>] New configuration values to specify the Id and Class for the
+			body element.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1577202&group_id=75348&atid=543655">SF
+			Patch-1577202</a>] The links created with the popup option now are accessible even
+			if the user has JavaScript disabled.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1443472&group_id=75348&atid=543655">SF
+			Patch-1443472</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1576488&group_id=75348&atid=543653">SF
+				BUG-1576488</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1334305&group_id=75348&atid=543653">SF
+					BUG-1334305</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1578312&group_id=75348&atid=543653">SF
+						BUG-1578312</a>] The Paste from Word clean up function can be configured
+			with FCKConfig.CleanWordKeepsStructure to preserve the markup as much as possible.
+			Thanks Jean-Charles ROGEZ. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1472654&group_id=75348&atid=543655">SF
+			Patch-1472654</a>] The server side script location for SpellerPages can now be set
+			in the configuration file, by using the SpellerPagesServerScript setting.</li>
+		<li><span style="color: #ff0000">Attention:</span> All connectors are now pointing by
+			default to the "/userfiles/" folder instead of "/UserFiles/" (case change). Also,
+			the inner folders for each type (file, image, flash and media) are all lower-cased
+			too.</li>
+		<li><span style="color: #ff0000">Attention:</span> The UseBROnCarriageReturn configuration
+			is not anymore valid. The EnterMode setting can now be used to precisely set the
+			enter key behavior.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1444937&group_id=75348">SF
+			BUG-1444937</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1274364&group_id=75348">SF
+				BUG-1274364</a>] Shortcut keys are now undoable correctly.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1015230&group_id=75348">SF
+			BUG-1015230</a>] Toolbar buttons now update their state on shortcut keys activation.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1485621&group_id=75348">SF
+			BUG-1485621</a>] It is now possible to precisely control which shortcut keys can
+			be used.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1573714&group_id=75348">SF
+			BUG-1573714</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1593323&group_id=75348">SF
+				BUG-1593323</a>] Paste was not working in IE if both AutoDetectPasteFromWord
+			and ForcePasteAsPlainText settings were set to "false". </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1578306&group_id=75348">SF
+			BUG-1578306</a>] The context menu was wrongly positioned if the editing document
+			was set to render in strict mode. Thanks to Alfonso Martinez.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1567060&group_id=75348">SF
+			BUG-1567060</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1565902&group_id=75348">SF
+				BUG-1565902</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1440631&group_id=75348">SF
+					BUG-1440631</a>] IE was getting locked on some specific cases. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1582859&group_id=75348">SF
+			BUG-1582859</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1579507&group_id=75348&atid=543655">SF
+				Patch-1579507</a>] Firefox' spellchecker is now disabled during editing mode.
+			Thanks to Alfonso Martinez.</li>
+		<li>Fixed Safari and Opera detection system (for development purposes only).</li>
+		<li>Paste from Notepad was including font information in IE. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1584092&group_id=75348">SF
+			BUG-1584092</a>] When replacing text area, names with spaces are now accepted.</li>
+		<li>Depending on the implementation of toolbar combos (mainly for custom plugins) the
+			editor area was loosing the focus when clicking in the combo label. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1596937&group_id=75348&atid=543653">SF
+			BUG-1596937</a>] InsertHtml() was inserting the HTML outside the editor area on
+			some very specific cases.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1585548&group_id=75348">SF
+			BUG-1585548</a>] On very specific, rare and strange cases, the XHTML processor was
+			not working properly in IE. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1584951&group_id=75348">SF
+			BUG-1584951</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1380598&group_id=75348">SF
+				BUG-1380598</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1198139&group_id=75348">SF
+					BUG-1198139</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1437318&group_id=75348">SF
+						BUG-1437318</a>] In Firefox, the style selector will not anymore delete
+			the contents when removing styles on specific cases.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1515441&group_id=75348">SF
+			BUG-1515441</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1451071&group_id=75348">SF
+				BUG-1451071</a>] The "Insert/Edit Link" and "Select All" buttons are now working
+			properly when the editor is running on a IE Modal dialog.</li>
+		<li>On some very rare cases, IE was throwing a memory error when hiding the context
+			menus. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1526154&group_id=75348">SF
+			BUG-1526154</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1509208&group_id=75348&atid=543653">SF
+				BUG-1509208</a>] With Firefox, &lt;style&gt; tags defined in the source are
+			now preserved.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1535946&group_id=75348">SF
+			BUG-1535946</a>] The IE dialog system has been changed to better work with custom
+			dialogs.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1599520&group_id=75348">SF
+			BUG-1599520</a>] The table dialog was producing empty tags when leaving some of
+			its fields empty.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1599545&group_id=75348">SF
+			BUG-1599545</a>] HTML entities are now processed on attribute values too.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1598517&group_id=75348">SF
+			BUG-1598517</a>] Meta tags are now protected from execution during editing (avoiding
+			the "redirect" meta to be activated).</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1415601&group_id=75348">SF
+			BUG-1415601</a>] Firefox internals: styleWithCSS is used instead of the deprecated
+			useCSS whenever possible.</li>
+		<li>All JavaScript Core extension function have been renamed to "PascalCase" (some were
+			in "camelCase"). This may have impact on plugins that use any of those functions.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1592311&group_id=75348">SF
+			BUG-1592311</a>] Operations in the caption of tables are now working correctly in
+			both browsers.</li>
+		<li>Small interface fixes to the about box.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1604576&group_id=75348&atid=543655">SF
+			PATCH-1604576</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1604301&group_id=75348">SF
+				BUG-1604301</a>] Link creation failed in Firefox 3 alpha. Thanks to Arpad Borsos</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1577247&group_id=75348&atid=543653">SF
+			BUG-1577247</a>] Unneeded call to captureEvents and releaseEvents.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1610790&group_id=75348">SF
+			BUG-1610790</a>] On some specific situations, the call to form.submit(), in form
+			were FCKeditor has been unloaded by code, was throwing the "Can't execute code from
+			a freed script" error.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1613167&group_id=75348&atid=543653">SF
+			BUG-1613167</a>] If the configuration was missing the FCKConfig.AdditionalNumericEntities
+			entry an error appeared.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1590848&group_id=75348&atid=543653">SF
+			BUG-1590848</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1626360&group_id=75348&atid=543653">SF
+				BUG-1626360</a>] Cleaning of JavaScript strict warnings in the source code.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1559466&group_id=75348&atid=543653">SF
+			BUG-1559466</a>] The ol/ul list property window always searched first for a UL element.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1516008&group_id=75348&atid=543653">SF
+			BUG-1516008</a>] Class attribute in IE wasn't loaded in the image dialog.</li>
+		<li>The "OnAfterSetHTML" event is now fired when being/switching to Source View.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1631807&group_id=75348&atid=543653">SF
+			BUG-1631807</a>] Elements' style properties are now forced to lowercase in IE.</li>
+		<li>The extensions "html", "htm" and "asis" have been added to the list of denied extensions
+			on upload.</li>
+		<li>Empty inline elements (like span and strong) will not be generated any more.</li>
+		<li>Some elements attributes (like hspace) where not being retrieved when set to "0".</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1508341&group_id=75348&atid=543653">SF
+			BUG-1508341</a>] Fix for the ColdFusion script file of SpellerPages.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a href="http://www.imedi.org/">Medical
+			Media Lab</a>.</p>
+	<h3>
+		Version 2.3.3</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>The project has been <strong>relicensed</strong> under the terms of the <strong>
+			GPL / LGPL / MPL</strong> licenses. This change will remove many licensing compatibility
+			issues with other open source licenses, making the editor even more "open" than
+			before. </li>
+		<li><font color="#ff0000">Attention:</font> The default directory in the distribution
+			package is now named "fckeditor" (in lowercase) instead of "FCKeditor".&nbsp; This
+			change may impact installations on case sensitive OSs, like Linux. </li>
+		<li><font color="#ff0000">Attention:</font> The "Universal Keyboard" has been removed
+			from the package. The license of those files was unclear so they can't be included
+			alongside the rest of FCKeditor.</li>
+	</ul>
+	<h3>
+		Version 2.3.2</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>Users can now decide if the template dialog will replace the entire contents of
+			the editor or simply place the template in the cursor position. This feature can
+			be controlled by the "TemplateReplaceAll" and "TemplateReplaceCheckbox" configuration
+			options.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1237693&group_id=75348&atid=543655">SF
+			Patch-1237693</a>] A new configuration option (<strong>ProcessNumericEntities</strong>)
+			is now available to tell the editor to convert non ASCII chars to their relative
+			numeric entity references. It is disabled by default.</li>
+		<li>The new "<strong>AdditionalNumericEntities</strong>" setting makes it possible to
+			define a set of characters to be transformed to their relative numeric entities.
+			This is useful when you don't want the code to have simple quotes ('), for example.</li>
+		<li>The Norwegian language file (no.js) has been duplicated to include the Norwegian
+			Bokmal (nb.js) in the supported interface languages. Thanks to Martin Kronstad.
+		</li>
+		<li>Two new patterns have been added to the Universal Keyboard:
+			<ul>
+				<li>Persian. Thanks to Pooyan Mahdavi</li>
+				<li>Portuguese. Thanks to Bo Brandt.</li>
+			</ul>
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1517322&group_id=75348&atid=543655">SF
+			Patch-1517322</a>] It is now possible to define the start number on numbered lists.
+			Thanks to Marcel Bennett.</li>
+		<li>The Font Format combo will now reflect the EditorAreaCSS styles.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1461539&group_id=75348&atid=543655">SF
+			Patch-1461539</a>] The File Browser connector can now optionally return a "url"
+			attribute for the files. Thanks to Pent.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1090851&group_id=75348">SF
+			BUG-1090851</a>] The new "ToolbarComboPreviewCSS" configuration option has been
+			created, so it is possible to point the Style and Format toolbar combos to a different
+			CSS, avoiding conflicts with the editor area CSS.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1421309&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1421309</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1489402&group_id=75348">SF
+				BUG-1489402</a>] It is now possible to configure the Quick Uploder target path
+			to consider the file type (ex: Image or File) in the target path for uploads.</li>
+		<li>The JavaScript integration file has two new things:
+			<ul>
+				<li>The "CreateHtml()" function in the FCKeditor object, used to retrieve the HTML of
+					an editor instance, instead of writing it directly to the page (as done by "Create()").</li>
+				<li>The global "FCKeditor_IsCompatibleBrowser()" function, which tells if the executing
+					browser is compatible with FCKeditor. This makes it possible to do any necessary
+					processing depending on the compatibility, without having to create and editor instance.</li>
+			</ul>
+		</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1525242&group_id=75348">SF
+			BUG-1525242</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1500050&group_id=75348">SF
+				BUG-1500050</a>] All event attributes (like onclick or onmouseover) are now
+			being protected before loading the editor. In this way, we avoid firing those events
+			during editing (IE issue) and they don't interfere in other specific processors
+			in the editor.</li>
+		<li>Small security fixes to the File Browser connectors. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1546226&group_id=75348">SF
+			BUG-1546226</a>] Small fix to the ColdFusion CFC integration file.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&atid=543655&aid=1547768&group_id=75348">SF
+			Patch-1407500</a>] The Word Cleanup function was breaking the HTML on pasting, on
+			very specific cases. Fixed, thanks to Frode E. Moe.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1551979&group_id=75348&atid=543655">SF
+			Patch-1551979</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1418066&group_id=75348">SF
+				BUG-1418066</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1439621&group_id=75348">SF
+					BUG-1439621</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1501698&group_id=75348&atid=543653">SF
+						BUG-1501698</a>] Make FCKeditor work with application/xhtml+xml. Thanks
+			to Arpad Borsos.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1547738&group_id=75348&atid=543655">SF
+			Patch-1547738</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1550595&group_id=75348&atid=543653">SF
+				BUG-1550595</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1540807&group_id=75348&atid=543653">SF
+					BUG-1540807</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1510685&group_id=75348&atid=543653">SF
+						BUG-1510685</a>] Fixed problem with panels wrongly positioned when the
+			editor is placed on absolute or relative positioned elements. Thanks to Filipe Martins.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1511294&group_id=75348&atid=543655">SF
+			Patch-1511294</a>] Small fix for the File Browser compatibility with IE 5.5.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1503178&group_id=75348&atid=543655">SF
+			Patch-1503178</a>] Small improvement to stop IE from loading smiley images when
+			one smiley is quickly selected from a huge list of smileys. Thanks to stuckhere.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1549112&group_id=75348&atid=543653">SF
+			BUG-1549112</a>] The Replace dialog window now escapes regular expression specific
+			characters in the find and replace fields.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1548788&group_id=75348&atid=543653">SF
+			BUG-1548788</a>] Updated the ieSpell download URL.</li>
+		<li>In FF, the editor was throwing an error when closing the window. Fixed.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1538509&group_id=75348&atid=543653">SF
+			BUG-1538509</a>] The "type" attribute for text fields will always be set now.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1551734&group_id=75348&atid=543653">SF
+			BUG-1551734</a>] The SetHTML function will now update the editing area height no
+			matter which editing mode is active.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1554141&group_id=75348&atid=543653">SF
+			BUG-1554141</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1565562&group_id=75348&atid=543653">SF
+				BUG-1565562</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1451056&group_id=75348&atid=543653">SF
+					BUG-1451056</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1478408&group_id=75348&atid=543653">SF
+						BUG-1478408</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1489322&group_id=75348&atid=543653">SF
+							BUG-1489322</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1513667&group_id=75348&atid=543653">SF
+								BUG-1513667</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1562134&group_id=75348&atid=543653">SF
+									BUG-1562134</a>] The protection of URLs has been enhanced
+			and now it will not break URLs on very specific cases.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1545732&group_id=75348&atid=543653">SF
+			BUG-1545732</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1490919&group_id=75348&atid=543653">SF
+				BUG-1490919</a>] No security errors will be thrown when loading FCKeditor in
+			page inside a FRAME defined in a different domain.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1512817&group_id=75348&atid=543653">SF
+			BUG-1512817</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1571345&group_id=75348&atid=543653">SF
+				BUG-1571345</a>] Fixed the "undefined" addition to the content when ShowBorders
+			= false and FullPage = true in Firefox. Thanks to Brett.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1512798&group_id=75348&atid=543653">SF
+			BUG-1512798</a>] BaseHref will now work well on FullPage, even if no &lt;head&gt;
+			is available.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1509923&group_id=75348&atid=543653">SF
+			BUG-1509923</a>] The DocumentProcessor is now called when using InserHtml().</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1505964&group_id=75348&atid=543653">SF
+			BUG-1505964</a>] The DOCTYPE declaration is now preserved when working in FullPage.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1553727&group_id=75348&atid=543653">SF
+			BUG-1553727</a>] The editor was throwing an error when inserting complex templates.
+			Fixed.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1564930&group_id=75348&atid=543655">SF
+			Patch-1564930</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1562828&group_id=75348">SF
+				BUG-1562828</a>] In IE, anchors where incorrectly copied when using the Paste
+			from Word button. Fixed, thanks to geirhelge.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1557709&group_id=75348&atid=543653">SF
+			BUG-1557709</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1421810&group_id=75348&atid=543653">SF
+				BUG-1421810</a>] The link dialog now validates Popup Window names.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1556878&group_id=75348&atid=543653">SF
+			BUG-1556878</a>] Firefox was creating empty tags when deleting the selection in
+			some special cases.</li>
+		<li>The context menu for links is now correctly shown when right-clicking on floating
+			divs.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1084404&group_id=75348&atid=543653">SF
+			BUG-1084404</a>] The XHTML processor now ignores empty span tags.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1221728&group_id=75348&atid=543653">SF
+			BUG-1221728</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1174503&group_id=75348&atid=543653">SF
+				BUG-1174503</a>] The &lt;abbr&gt; tag is not anymore getting broken by IE.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1182906&group_id=75348&atid=543653">SF
+			BUG-1182906</a>] IE is not anymore messing up mailto links.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1386094&group_id=75348&atid=543653">SF
+			BUG-1386094</a>] Fixed an issue when setting configuration options to empty ('')
+			by code.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1389435&group_id=75348&atid=543653">SF
+			BUG-1389435</a>] Fixed an issue in some dialog boxes when handling numeric inputs.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1398829&group_id=75348&atid=543653">SF
+			BUG-1398829</a>] Some links may got broken on very specific cases. Fixed.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1409969&group_id=75348&atid=543653">SF
+			BUG-1409969</a>] &lt;noscript&gt; tags now remain untouched by the editor.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1433457&group_id=75348&atid=543653">SF
+			BUG-1433457</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1513631&group_id=75348&atid=543653">SF
+				BUG-1513631</a>] Empty "href" attributes in &lt;a&gt; or empty "src" in &lt;img&gt;
+			will now be correctly preserved.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1435195&group_id=75348&atid=543653">SF
+			BUG-1435195</a>] Scrollbars are now visible in the File Browser (for custom implementations).</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1438296&group_id=75348&atid=543653">SF
+			BUG-1438296</a>] The "ForceSimpleAmpersand" setting is now being honored in all
+			tags.</li>
+		<li>If a popup blocker blocks context menu operations, the correct alert message is
+			displayed now, instead of a ugly JavaScript error.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1454116&group_id=75348&atid=543653">SF
+			BUG-1454116</a>] The GetXHTML() function will not change the IsDirty() value of
+			the editor.</li>
+		<li>The spell check may not work correctly when using SpellerPages with ColdFusion.
+			Fixed.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1481861&group_id=75348&atid=543653">SF
+			BUG-1481861</a>] HTML comments are now removed by the Word Cleanup System.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1489390&group_id=75348&atid=543653">SF
+			BUG-1489390</a>] A few missing hard coded combo options used in some dialogs are
+			now localizable.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1505448&group_id=75348&atid=543653">SF
+			BUG-1505448</a>] The Form dialog now retrieves the value of the "action" attribute
+			exactly as defined in the source.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1517322&group_id=75348&atid=543655">SF
+			Patch-1517322</a>] Solved an issue when the toolbar has buttons with simple icons
+			(usually used by plugins) mixed with icons coming from a strip (the default toolbar
+			buttons).</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1575261&group_id=75348&atid=543655">SF
+			Patch-1575261</a>] Some fields in the Table and Cell Properties dialogs were being
+			cut. Fixed.</li>
+		<li>Fixed a startup compatibility issue with Firefox 1.0.4.</li>
+	</ul>
+	<h3>
+		Version 2.3.1</h3>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/support/tracker.php?aid=1506126">SF
+			BUG-1506126</a>] Fixed the Catalan language file, which had been published with
+			problems in accented letters. </li>
+		<li>More performance improvements in the default File Browser.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1506701&group_id=75348&atid=543653">SF
+			BUG-1506701</a>] Fixed compatibility issues with IE 5.5.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1509073&group_id=75348&atid=543653">SF
+			BUG-1509073</a>] Fixed the "Image Properties" dialog window, which was making invalid
+			calls to the "editor/dialog/" directory, generating error 400 entries in the web
+			server log.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1507294&group_id=75348&atid=543653">SF
+			BUG-1507294</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1507953&group_id=75348&atid=543653">SF
+				BUG-1507953</a>] The editing area was getting a fixed size when using the "SetHTML"
+			API command or even when switching back from the source view. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1507755&group_id=75348">SF
+			BUG-1507755</a>] Fixed a conflict between the "DisableObjectResizing" and "ShowBorders"
+			configuration options over IE.</li>
+		<li>Opera 9 tries to "mimic" Gecko in the browser detection system of FCKeditor. As
+			this browser is not "yet" supported, the editor was broken on it. It has been fixed,
+			and now a textarea is displayed, as in any other unsupported browser. Support for
+			Opera is still experimental and can be activated by setting the property "EnableOpera"
+			to true when creating an instance of the editor with the JavaScript integration
+			files.</li>
+		<li>With Opera 9, the toolbar was jumping on buttons rollover. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1509479&group_id=75348&atid=543656">SF
+			BUG-1509479</a>] The iframes used in Firefox for all editor panels (dropdown combos,
+			context menu, etc...) are now being placed right before the main iframe that holds
+			the editor. In this way, if the editor container element is removed from the DOM
+			(by DHTML) they are removed together with it.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1271070&group_id=75348&atid=543653">SF
+			BUG-1271070</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1411430&group_id=75348&atid=543653">SF
+				BUG-1411430</a>] The editor API now works well on DHTML pages that create and
+			remove instances of FCKeditor dynamically. </li>
+		<li>A second call to a page with the editor was not working correctly with Firefox 1.0.x.
+			Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1511460&group_id=75348&atid=543653">SF
+			BUG-1511460</a>] Small correction to the &lt;script&gt; protected source regex.
+			Thanks to Randall Severy.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1521754&group_id=75348">SF
+			BUG-1521754</a>] Small fix to the paths of the internal CSS files used by FCKeditor.
+			Thanks to johnw_ceb.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1511442&group_id=75348&atid=543653">SF
+			BUG-1511442</a>] The &lt;base&gt; tag is now correctly handled in IE, no matter
+			its position in the source code.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1507773&group_id=75348&atid=543653">SF
+			BUG-1507773</a>] The "Lock" and "Reset" buttons in the Image Properties dialog window
+			are not anymore jumping with Firefox 1.5.</li>
+	</ul>
+	<h3>
+		Version 2.3</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>The <strong>Toolbar Sharing</strong> system has been completed. See sample10.html
+			and sample11.html.*</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1407500&group_id=75348&atid=543655">SF
+			Patch-1407500</a>] Small enhancement to the Find and Replace dialog windows.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>Small security fixes.</li>
+		<li>The context menu system has been optimized. Nested menus now open "onmouseover".
+		</li>
+		<li>An error in the image preloader system was making the toolbar strip being downloaded
+			once for each button on slow connections. Some enhancements have also been made
+			so now the smaple05.html is loading fast for all skins.</li>
+		<li>Fixed many memory leak issues with IE.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1489768&group_id=75348&atid=543653">SF
+			BUG-1489768</a>] The panels (context menus, toolbar combos and color selectors),
+			where being displayed in the wrong position if the contents of the editor, or its
+			containing window were scrolled down. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1493176&group_id=75348">SF
+			BUG-1493176</a>] Using ASP, the connector was not working on servers with buffer
+			disable by default.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1491784&group_id=75348&atid=543653">SF
+			BUG-1491784</a>] Language files have been updated to not include html entities.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1490259&group_id=75348&atid=543653">SF
+			BUG-1490259</a>] No more security warning on IE over HTTPS.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1493173&group_id=75348&atid=543653">SF
+			BUG-1493173</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1499708&group_id=75348">SF
+				BUG-1499708</a>] We now assume that, if a user is in source editing, he/she
+			wants to control the HTML, so the editor doesn't make changes to it when posting
+			the form being in source view or when calling the GetXHTML function in the API.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1490610&group_id=75348&atid=543653">SF
+			BUG-1490610</a>] The FitWindow is now working on elements set with relative position.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1493438&group_id=75348&atid=543653">SF
+			BUG-1493438</a>] The "Word Wrap" combo in the cell properties dialog now accepts
+			only Yes/No (no more &lt;Not Set&gt; value).</li>
+		<li>The context menu is now being hidden when a nested menu option is selected.</li>
+		<li>Table cell context menu operations are now working correctly.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1494549&group_id=75348&atid=543653">SF
+			BUG-1494549</a>] The code formatter was having problems with dollar signs inside
+			&lt;pre&gt; tags.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1459740&group_id=75348&atid=543655">SF
+			Patch-1459740</a>] The "src" element of images can now be set by styles definitions.
+			Thanks to joelwreed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1437052&group_id=75348&atid=543655">SF
+			Patch-1437052</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1436166&group_id=75348&atid=543655">SF
+				Patch-1436166</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1352385&group_id=75348&atid=543655">SF
+					Patch-1352385</a>] Small fix to the FCK.InsertHtml, FCKTools.AppendStyleSheet
+			and FCKSelection.SelectNode functions over IE. Thanks to Alfonso Martinez.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1349765&group_id=75348&atid=543655">SF
+			Patch-1349765</a>] Small fix to the FCKSelection.GetType over Firefox. Thanks to
+			Alfonso Martinez.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543655&aid=1495422&group_id=75348">SF
+			Patch-1495422</a>] The editor now creates link based on the URL when no selection
+			is available. Thanks to Dominik Pesch.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543655&aid=1478859&group_id=75348">SF
+			Patch-1478859</a>] On some circumstances, the Yahoo popup blocker was blocking the
+			File Browser window, giving no feedback to the user. Now an alert message is displayed.</li>
+		<li>When using the editor in a RTL localized interface, like Arabic, the toolbar combos
+			were not showing completely in the first click. Fixed.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1500212&group_id=75348">SF
+			BUG-1500212</a>] All "_samples/html" samples are now working when loading directly
+			from the Windows Explorer. Thanks to Alfonso Martinez.</li>
+		<li>The "FitWindow" feature was breaking the editor under Firefox 1.0.x.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1500032&group_id=75348&atid=543655">SF
+			Patch-1500032</a>] In Firefox, the caret position now follows the user clicks when
+			clicking in the white area bellow the editor contents. Thanks to Alfonso Martinez.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1499522&group_id=75348">SF
+			BUG-1499522</a>] In Firefox, the link dialog window was loosing the focus (and quickly
+			reacquiring it) when opening. This behavior was blocking the dialog in some Linux
+			installations. </li>
+		<li>Drastically improved the loading performance of the file list in the default File
+			Browser.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1503059&group_id=75348">SF
+			BUG-1503059</a>] The default "BasePath" for FCKeditor in all integration files has
+			been now unified to "/fckeditor/" (lower-case). This is the usual casing system
+			in case sensitive OSs like Linux.</li>
+		<li>The "DisableFFTableHandles" setting is now honored when switching the full screen
+			mode with FitWindow.</li>
+		<li>Some fixes has been applied to the cell merging in Firefox.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a href="http://www.footsteps.nl/">Footsteps</a>
+		and <a href="http://www.kentico.com/">Kentico</a>.</p>
+	<h3>
+		Version 2.3 Beta</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li><span><strong>Extremely Fast Loading!</strong> The editor now loads more than 3
+			times faster than before, with no impact on its advanced features.</span> </li>
+		<li><span><strong>New toolbar system</strong>:</span>
+			<ul>
+				<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1454850&amp;group_id=75348&amp;atid=543656">SF
+					Feature-1454850</a>] The toolbar will now <strong>load much faster</strong>. All
+					images have being merged in a single image file using a unique system available
+					only with FCKeditor. </li>
+				<li>The &quot;Text Color&quot; and &quot;Background Color&quot; commands buttons have
+					enhancements on the interface.</li>
+				<li><strong><span style="color: #ff0000">Attention</span></strong>: As a completely
+					new system has being developed. Skins created for versions prior this one will not
+					work. Skin styles definitions have being merged, added and removed. All skins have
+					been a little bit reviewed. </li>
+				<li>It is possible to <strong>detach the toolbar</strong> from an editor instance and
+					share it with other instances. In this way you may have only one toolbar (in the
+					top of the window, for example, that can be used by many editors (see <a href="_samples/html/sample10.html">
+						sample10.html</a>). This feature is still under development (issues with IE
+					focus still to be solved).* </li>
+			</ul>
+		</li>
+		<li><strong><span>New context menu system</span></strong>:
+			<ul>
+				<li>It uses the same (fast) loading system as the toolbar. </li>
+				<li>Sub-Menus are now available to group features (try the context menu over a table
+					cell). </li>
+				<li>It is now possible to create your own context menu entries by creating plugins.
+				</li>
+			</ul>
+		</li>
+		<li><strong>New "FitWindow" toolbar button</strong>, based on the <a href="https://sourceforge.net/tracker/index.php?func=detail&aid=1431638&group_id=75348&atid=737639">
+			plugin</a> published by Paul Moers. Thanks Paul!</li>
+		<li><strong>&quot;Auto Grow&quot; Plugin</strong>: automatically resizes the editor
+			until a maximum height, based on its contents size.** </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1444943&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1444943</a>] <strong>Multiple CSS files</strong> can now be used in the
+			editing area. Just define FCKConfig.EditorAreaCSS as an array of strings (each one
+			is a path to a different css file). It works also as a simple string, as on prior
+			versions. </li>
+		<li>New language files:<ul>
+			<li><strong>Bengali / Bangla</strong> (by Richard Walledge).</li>
+			<li><strong>English (Canadian)</strong> (by Kevin Bennett). </li>
+			<li><strong>Khmer</strong> (by Sengtha Chay).</li>
+		</ul>
+		</li>
+		<li>The source view is now available in the editing area on Gecko browsers. Previously
+			a popup was used for it (due to a Firefox bug). </li>
+		<li><span>As some people may prefer the popup way for source editing, a new configuration
+			option (SourcePopup) has being introduced.</span> </li>
+		<li>The IEForceVScroll configuration option has been removed. The editor now automatically
+			shows the vertical scrollbar when needed (for XHTML doctypes). </li>
+		<li>The configuration file doesn't define a default DOCTYPE to be used now. </li>
+		<li>It is now possible to easily change the toolbar using the JavaScript API by just
+			calling &lt;EditorInstance&gt;.ToolbarSet.Load( '&lt;ToolbarName&gt;' ). See _testcases/010.html
+			for a sample. </li>
+		<li>The &quot;OnBlur&quot; and &quot;OnFocus&quot; JavaScript API events are now compatible
+			with all supported browsers. </li>
+		<li>Some few updates in the Lasso connector and uploader. </li>
+		<li>The GeckoUseSPAN setting is now set to "false" by default. In this way, the code
+			produced by the bold, italic and underline commands are the same on all browsers.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li><strong>Important security fixes have been applied to the File Manager, Uploader
+			and Connectors. Upgrade is highly recommended.</strong> Thanks to Alberto Moro,
+			Baudouin Lamourere and James Bercegay.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1399966&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1399966</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1249853&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1249853</a>] The &quot;BaseHref&quot; configuration is now working with
+			Firefox in both normal and full page modes.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1405263&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1405263</a>] A typo in the configuration file was impacting the Quick Upload
+			feature. </li>
+		<li>Nested &lt;ul&gt; and &lt;ol&gt; tags are now generating valid html.</li>
+		<li>The &quot;wmode&quot; and &quot;quality&quot; attributes are now preserved for Flash
+			embed tags, in case they are entered manually in the source view. Also, empty attributes
+			are removed from that tag. </li>
+		<li>Tables where not being created correctly on Opera. </li>
+		<li>The XHTML processor will ignore invalid tags with names ending with &quot;:&quot;,
+			like http:. </li>
+		<li><span>On Firefox, the scrollbar is not anymore displayed on toolbar dropdown commands
+			when not needed.</span> </li>
+		<li><span>Some small fixes have being done to the dropdown commands rendering for FF</span>.
+		</li>
+		<li>The table dialog window has been a little bit enlarged to avoid contents being cropped
+			on some languages, like Russian. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1465203&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1465203</a>] The ieSpell download URL has been updated. The problem is that
+			they don't have a fixed URL for it, so let's hope the mirror will be up for it.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1456332&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1456332</a>] Small fix in the Spanish language file. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1457078&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1457078</a>] The File Manager was generating 404 calls in the server. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1459846&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1459846</a>] Fixed a problem with the config file if PHP is set to parse .js
+			files. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1432120&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1432120</a>] The &quot;UserFilesAbsolutePath&quot; setting is not correctly
+			used in the PHP uploader. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1432120&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1408869</a>] The collapse handler is now rendering correctly in Firefox 1.5.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1410082&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1410082</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1424240&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1424240</a>] The &quot;moz-bindings.xml&quot; file is now well formed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1413980&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1413980</a>] All frameborder &quot;yes/no&quot; values have been changes to
+			&quot;1/0&quot;. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1414101&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1414101</a>] The fake table borders are now showing correctly when running under
+			the &quot;file://&quot; protocol. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1414155&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1414155</a>] Small typo in the cell properties dialog window.</li>
+		<li>Fixed a problem in the File Manager. It was not working well with folder or file
+			names with apostrophes ('). Thanks to RenÃ© de Jong.</li>
+		<li>Small "lenght" type corrected in the select dialog window. Thanks to Bernd Nussbaumer.</li>
+		<li>The about box is now showing correctly in Firefox 1.5.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1464020&group_id=75348&atid=543655">SF
+			Patch-1464020</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1155793&group_id=75348&atid=543653">SF
+				BUG-1155793</a>] The "Unlink" command is now working correctly under Firefox
+			if you don't have a complete link selection. Thanks to Johnny Egeland.</li>
+		<li>In the File Manager, it was not possible to upload files to folders with ampersands
+			in the name. Thanks to Mike Pone.</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1178359&group_id=75348&atid=543653">SF
+			BUG-1178359</a>] Elements from the toolbar are not anymore draggable in the editing
+			area.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1487544&group_id=75348&atid=543653">SF
+			BUG-1487544</a>] Fixed a small issue in the code formatter for &lt;br /&gt; and
+			&lt;hr /&gt; tags.</li>
+		<li>The "Background Color" command now works correctly when the GeckoUseSPAN setting
+			is disabled (default).</li>
+		<li>Links are now rendered in blue with Firefox (they were black before). Actually,
+			an entry for it has been added to the editing area CSS, so you can customize with
+			the color you prefer. </li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a href="http://www.footsteps.nl/">Footsteps</a>
+		and <a href="http://www.kentico.com/">Kentico</a>.
+		<br />
+		** This version has been partially sponsored by <a href="http://www.nextide.ca/">Nextide</a>.</p>
+	<h3>
+		Version 2.2</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>Let's welcome Wim Lemmens (didgiman). He's our new responsible for the ColdFusion
+			integration. In this version we are introducing his new files with the following
+			changes:
+			<ul>
+				<li>The &quot;<strong>Uploader</strong>&quot;, used for quick uploads,&nbsp;is now available
+					<strong>natively for ColdFusion</strong>. </li>
+				<li>Small bugs have been corrected in the <strong>File Browser connector</strong>. </li>
+				<li>The samples now work as is, even if you don't install the editor in the &quot;/FCKeditor&quot;
+					directory.</li>
+			</ul>
+		</li>
+		<li>And a big welcome also to &quot;Andrew Liu&quot;, our responsible for the <strong>
+			Python</strong> integration. This version is bringing <strong>native support for Python</strong>
+			, including the File Browser connector and Quick Upload. </li>
+		<li>The &quot;<strong>IsDirty()</strong>&quot; and &quot;<strong>ResetIsDirty()</strong>&quot;
+			functions have been&nbsp;added to the&nbsp;JavaScript API&nbsp;to check if the editor
+			content has been changed.* </li>
+		<li>New language files:
+			<ul>
+				<li><strong>Hindi</strong> (by Utkarshraj Atmaram) </li>
+				<li><strong>Latvian </strong>(by Janis Klavin&scaron;)</li>
+			</ul>
+		</li>
+		<li>For&nbsp;the interface, now we have complete <strong>RTL support</strong> also for
+			the drop-down toolbar commands, color selectors and context menu. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1325113&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1325113</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1277661&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1277661</a>] The new &quot;Delete Table&quot; command is available in the
+			Context Menu when right-clicking inside a table. </li>
+		<li>The &quot;FCKConfig.DisableTableHandles&quot; configuration option is now working
+			on Firefox 1.5. </li>
+		<li>The new &quot;<strong>OnBlur</strong>&quot; and &quot;<strong>OnFocus</strong>&quot;
+			events have been added to the JavaScript API (IE only). See&nbsp;&quot;_samples/html/sample09.html&quot;&nbsp;*
+		</li>
+		<li><strong><font color="#ff0000">Attention</font></strong>: The &quot;<strong>GetHTML</strong>&quot;
+			function has been deprecated. It now returns the same value as &quot;<strong>GetXHTML</strong>&quot;.
+			The same is valid for the &quot;EnableXHTML&quot; and &quot;EnableSourceXHTML&quot;
+			that have no effects now. The editor now works with XHTML output only. </li>
+		<li><strong><font color="#ff0000">Attention</font></strong>: A new &quot;<strong>PreserveSessionOnFileBrowser</strong>&quot;
+			configuration option has been introduced. It makes it possible to set whenever is
+			needed to maintain the user session in the File Browser. It is disabled by default,
+			as it has very specific usage and may cause the File Browser to be blocked by popup
+			blockers. If you have custom File Browsers that depends on session information,
+			remember to activate it. </li>
+		<li><strong><font color="#ff0000">Attention</font></strong>: The &quot;<strong>fun</strong>&quot;
+			smileys set has been removed from the package. If you are using it, you must manually
+			copy it to newer installations and upgrades. </li>
+		<li><strong><font color="#ff0000">Attention</font></strong>: The &quot;<strong>mcpuk</strong>&quot;
+			file browser has been removed from the package. We have no ways to support it. There
+			were also some licensing issues with it. Its web site can still be found at <a href="http://mcpuk.net/fbxp/">
+				http://mcpuk.net/fbxp/</a>. </li>
+		<li>It is now possible to set different CSS styles for the chars in the Special Chars
+			dialog window by adding the &quot;SpecialCharsOut&quot; and &quot;SpecialCharsOver&quot;
+			in the &quot;fck_dialog.css&quot; skin file.* </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1268726&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1268726</a>] Added table &quot;summary&quot; support in the table dialog.
+			Thanks to Sebastien-Mahe. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1284380&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1284380</a>] It is now possible to define the icon of a FCKToolbarPanelButton
+			object without being tied to the skin path (just like FCKToolbarButton). Thanks
+			to Ian Sullivan. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1338610&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1338610</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1263009&amp;group_id=75348&amp;atid=543656">SF
+				Patch-1263009</a>] New characters have been added to the &quot;Special Characters&quot;
+			dialog window. Thanks to Deian. </li>
+		<li>You can set the QueryString value &quot;fckdebug=true&quot; to activate &quot;debug
+			mode&quot; in the editor (showing the debug window), overriding the configurations.
+			The &quot;AllowQueryStringDebug&quot; configuration option is also available so
+			you can disable this feature.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1363548&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1363548</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1364425&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1364425</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1335045&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1335045</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1289661&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1289661</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1225370&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1225370</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156291&amp;group_id=75348&amp;atid=543653">SF
+								BUG-1156291</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1165914&amp;group_id=75348&amp;atid=543653">SF
+									BUG-1165914</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1111877&amp;group_id=75348&amp;atid=543653">SF
+										BUG-1111877</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092373&amp;group_id=75348&amp;atid=543653">SF
+											BUG-1092373</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1101596&amp;group_id=75348&amp;atid=543653">SF
+												BUG-1101596</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1246952&amp;group_id=75348&amp;atid=543653">SF
+													BUG-1246952</a>] The URLs for links and
+			images are now correctly preserved as entered, no matter if you are using relative
+			or absolute paths. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1162809&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1162809</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205638&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1205638</a>] The &quot;Image&quot; and &quot;Flash&quot;&nbsp;dialog windows
+			now loads the preview correctly if the &quot;BaseHref&quot; configuration option
+			is set. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1329807&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1329807</a>] The alert boxes are now showing correctly when doing cut/copy/paste
+			operations on Firefox installations when it is not possible to execute that operations
+			due to security settings. </li>
+		<li>A new &quot;Panel&quot; system (used in the drop-dowm toolbar commands, color selectors
+			and context menu) has been developed. The following bugs have been fixed with it:
+			<ul>
+				<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1186927&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1186927</a>] On IE, sometimes the context menu was being partially hidden.*
+				</li>
+				<li>On Firefox, the context menu was flashing in the wrong position before showing.
+				</li>
+				<li>On Firefox 1.5, the Color Selector was not working. </li>
+				<li>On Firefox 1.5, the fonts in the panels were too big. </li>
+				<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1076435&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1076435</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1200631&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1200631</a>] On Firefox, sometimes the context menu was being shown in the
+					wrong position.</li>
+			</ul>
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1364094&amp;group_id=75348">SF
+			BUG-1364094</a>] Font families were <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=317572">
+				not being rendered correctly on Firefox</a> . </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1315954&amp;group_id=75348">SF
+			BUG-1315954</a>] No error is thrown when pasting some case specific code from editor
+			to editor. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1341553&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1341553</a>] A small fix for a security alert in the File&nbsp;Browser has been
+			applied. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1370953&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1370953</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1339898&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1339898</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1323319&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1323319</a>] A message will be shown to the user (instead of a JS error)&nbsp;if
+			a &quot;popup blocker&quot; blocks the &quot;Browser Server&quot; button. Thanks
+			to Erwin Verdonk. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1370355&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1370355</a>] Anchor links that points to a single character anchor, like &quot;#A&quot;,
+			are now correctly detected in the Link dialog window. Thanks to Ricky Casey. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1368998&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1368998</a>] Custom error processing has been added to the file upload on the
+			File Browser. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1367802&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1367802</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1207740&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1207740</a>] A message is shown to the user if a dialog box is blocked by
+			a popup blocker in Firefox. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1358891&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1358891</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1340960&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1340960</a>] The editor not works locally (without a web server) on directories
+			where the path contains spaces. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1357247&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1357247</a>] The editor now intercepts SHIFT + INS keystrokes when needed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1328488&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1328488</a>] <strong><font color="#ff0000">Attention</font></strong>: The Page
+			Break command now produces different tags&nbsp;to avoid&nbsp;XHTML compatibility
+			issues. Any Page Break previously applied to content produced with previous versions
+			of FCKeditor will not me rendered now, even if&nbsp;they will still be working correctly.
+		</li>
+		<li>It is now possible to allow cut/copy/past operations on Firefox using the <a
+			href="http://kb.mozillazine.org/Granting_JavaScript_access_to_the_clipboard"
+			target="_blank">user.js</a> file. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1336792&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1336792</a>] A fix has been applied to the XHTML processor to allow tag names
+			with the &quot;minus&quot; char (-). </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1339560&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1339560</a>] The editor now correctly removes the &quot;selected&quot; option
+			for checkboxes and radio buttons. </li>
+		<li>The Table dialog box now selects the table correctly when right-clicking on objects
+			(like images) placed inside the table. </li>
+		<li><strong><font color="#ff0000">Attention</font></strong>: A few changes have been
+			made in the skins. If you have a custom skin, it is recommended you to make a diff
+			of the fck_contextmenu.css file of the default skin with your implementation. </li>
+		<li>Mouse select (marking&nbsp;things in blue, like selecting text) has been disabled
+			on panels (drop-down menu commands, color selector and context menu) and toolbar,
+			for both IE and Firefox. </li>
+		<li>On Gecko, fake borders will not be applied to tables with the border attribute set
+			to more than 0, but placed inside tables with border set to 0. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1360717&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1360717</a>] A wrapping issue in the &quot;Silver&quot; skin has been corrected.
+			Thanks to Ricky Casey. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1251145&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1251145</a>] In IE, the focus is now maintained in the text when clicking in
+			the empty area&nbsp;following it. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181386&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1181386</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1237791&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1237791</a>] The &quot;Stylesheet Classes&quot; field in the Link dialog
+			window in now applied correctly on IE. Thanks to Andrew Crowe. </li>
+		<li>The &quot;Past from Word&quot; dialog windows is now showing correctly on Firefox
+			on some languages. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1315008&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1315008</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1241992&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1241992</a>] IE, when selecting objects (like images) and hitting the &quot;Backspace&quot;
+			button, the browser's &quot;back&quot; will not get executed anymore and the object
+			will be correctly deleted. </li>
+		<li>The &quot;AutoDetectPasteFromWord&quot; is now working correctly in IE. Thanks to
+			Juan Ant. G&oacute;mez. </li>
+		<li>A small enhancement has been made in the Word pasting detection. Thanks to Juan
+			Ant. G&oacute;mez. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090686&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1090686</a>] No more conflict with Firefox &quot;Type-Ahead Find&quot; feature.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=942653&amp;group_id=75348&amp;atid=543653">SF
+			BUG-942653</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155856&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1155856</a>] The &quot;width&quot; and &quot;height&quot; of images sized
+			using the inline handlers are now correctly loaded in the image dialog box. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1209093&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1209093</a>] When &quot;Full Page Editing&quot; is active, in the &quot;Document
+			Properties&quot; dialog, the &quot;Browse Server&quot; button for the page background
+			is now correctly hidden if &quot;ImageBrowser&quot; is set to &quot;false&quot;
+			in the configurations file. Thanks to Richard. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1120266&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1120266</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1186196&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1186196</a>] The editor now retains the focus when selecting commands in
+			the toolbar. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1244480&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1244480</a>] The editor now will look first to linked fields &quot;ids&quot;
+			and&nbsp;second to &quot;names&quot;. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1252905&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1252905</a>] The &quot;InsertHtml&quot; function now preserves URLs as entered.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1266317&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1266317</a>] Toolbar commands are not anymore executed outside the editor. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1365664&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1365664</a>] The &quot;wrap=virtual&quot; attribute has been removed from the
+			integration files for validation purposes. No big impact. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=972193&amp;group_id=75348&amp;atid=543653">SF
+			BUG-972193</a>] Now just one click is needed to active the cursor inside the editor.
+		</li>
+		<li>The hidden fields used by the editor are now protected from changes using the &quot;Web
+			Developer Add-On &gt; Forms &gt; Display Forms Details&quot; extension. Thanks to
+			Jean-Marie Griess. </li>
+		<li>On IE, the &quot;Format&quot; toolbar dropdown now reflects the current paragraph
+			type on IE. Because of a bug in the browser, it is quite dependent on the browser
+			language and the editor interface language (both must be the same). Also, as the
+			&quot;Normal (DIV)&quot; type is seen by IE as &quot;Normal&quot;, to avoid confusion,
+			both types are ignored by this fix. </li>
+		<li>On some very rare cases, IE was loosing the &quot;align&quot; attribute for DIV
+			tags. Fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1388799&amp;group_id=75348">SF
+			BUG-1388799</a>] The code formatter was removing spaces on the beginning of lines
+			inside PRE tags. Fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1387135&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1387135</a>] No more &quot;NaN&quot; values in the image dialog, when changing
+			the sizes in some situations. </li>
+		<li>Corrected a small type in the table handler. </li>
+		<li>You can now set the &quot;z-index&quot; for floating panels (toolbar dropdowns,
+			color selectors, context menu) in Firefox, avoiding having them hidden under another
+			objects. By default it is set to 10,000. Use the FloatingPanelsZIndex configuration
+			option to change this value.</li>
+	</ul>
+	<p>
+		<strong>Special thanks</strong> to <a target="_blank" href="https://sourceforge.net/users/alfonsoml/">
+			Alfonso Martinez</a>, who have provided many patches and suggestions for the
+		following features / fixes present in this version. I encourage all you to <a href="https://sourceforge.net/donate/index.php?user_id=1356422">
+			donate</a> to Alfonso, as a way to say thanks for his nice open source approach.
+		Thanks Alfonso!. Check out his contributions:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1364094&amp;group_id=75348">SF
+			BUG-1352539</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1208348&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1208348</a>] With Firefox, no more &quot;fake&quot; selections are appearing
+			when inserting images, tables, special chars or when using the &quot;insertHtml&quot;
+			function. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543655&amp;aid=1382588&amp;group_id=75348">SF
+			Patch-1382588</a>] The &quot;FCKConfig.DisableImageHandles&quot; configuration option
+			is not working on Firefox 1.5. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1368586&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1368586</a>] Some fixes have been applied to the Flash dialog box and the
+			Flash pre-processor. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1360253&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1360253</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1378782&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1378782</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1305899&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1305899</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1344738&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1344738</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1347808&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1347808</a>] On dialogs, some fields&nbsp;became impossible
+			to select or change when using Firefox. It has been fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1357445&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1357445</a>] Add support for DIV in the Format drop-down combo for Firefox.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1350465&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1350465</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1376175&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1376175</a>] The &quot;Cell Properties&quot; dialog now works correctly
+			when right-clicking in an object (image, for example) placed inside the cell itself.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1349166&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1349166</a>] On IE, there is now support for namespaces on tags names. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1350552&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1350552</a>] Fix the display issue when applying styles on tables. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1352320&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1352320</a> ] Fixed&nbsp;a wrong&nbsp;usage of the &quot;parentElement&quot;
+			property on Gecko. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1355007&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1355007</a>] The new &quot;FCKDebug.OutputObject&quot; function is available
+			to dump all object information in the debug window. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1329500&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1329500</a>] It is now possible to delete table columns when clicking on a
+			TH cell of the column. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1315351&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1315351</a>] It is now possible to pass the image width and height to the
+			&quot;SetUrl&quot; function of the Flash dialog box. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1327384&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1327384</a>] TH tags are now correctly handled by the source code formatter
+			and the &quot;FillEmptyBlocks&quot; configuration option. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1327406&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1327406</a>] Fake borders are now displayed for TH elements on tables with
+			border set to 0. Also, on Firefox, it will now work even if the border attribute
+			is not defined and the borders are not dotted. </li>
+		<li>Hidden fields now get rendered on Firefox. </li>
+		<li>The BasePath is now included in the debugger URL to avoid problems when calling
+			it from plugins.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a target="_blank" href="http://www.alkacon.com">
+			Alkacon Software</a>.</p>
+	<h3>
+		Version 2.1.1</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>The new &quot;<strong>Insert Page Break</strong>&quot;&nbsp;command (for printing)&nbsp;has
+			been introduced.* </li>
+		<li>The editor package now has a root directory called &quot;FCKeditor&quot;.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1326285&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1326285</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1316430&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1316430</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1323662&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1323662</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1326223&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1326223</a>] We are doing a little step back with this version.
+			The ENTER and BACKSPACE behavior changes for Firefox have been remove. It is a nice
+			feature, but we need much more testing&nbsp;on it. It introduced some bugs and so
+			its preferable to not have that feature, avoiding problems (even if that feature
+			was intended to solve some issues). </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1289372&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1275714</a>] Comments in the beginning of the source are now preserved when
+			using the &quot;undo&quot; and &quot;redo&quot; commands. </li>
+		<li>The &quot;undo&quot; and &quot;redo&quot; commands now work for the Style command.
+		</li>
+		<li>An error in the execution of the pasting commands on Firefox has been fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1326184&amp;group_id=75348">SF
+			BUG-1326184</a>] No strange (invalid) entities are created when using Firefox. Also,
+			the &amp;nbsp; used by the FillEmptyBlocks setting is maintained even if you disable
+			the ProcessHTMLEntities setting.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a target="_blank" href="http://www.acttive.com.br/">
+			Acctive Software&nbsp;S.A.</a>.</p>
+	<h3>
+		Version 2.1</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1200328&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1200328</a>] The editor now offers a way to &quot;protect&quot; part of the
+			source to remain untouched while editing or changing views.&nbsp;Just use the &quot;FCKConfig.ProtectedSource&quot;
+			object to configure it and customize to your needs. It is based on regular expressions.
+			See fckconfig.js for some samples. </li>
+		<li>The editor now offers native support for <strong>Lasso</strong>. Thanks and welcome&nbsp;to
+			our new developer Jason Huck. </li>
+		<li>New language files are available:
+			<ul>
+				<li><strong>Faraose</strong> (by S&iacute;min Lassaberg and&nbsp;Helgi Arnthorsson)
+				</li>
+				<li><strong>Malay</strong> (by Fairul Izham Mohd Mokhlas) </li>
+				<li><strong>Mongolian</strong> (by Lkamtseren Odonbaatar) </li>
+				<li><strong>Vietnamese</strong> (by Phan Binh Giang)</li>
+			</ul>
+		</li>
+		<li>A new configurable&nbsp;ColdFusion connector is available. Thanks to Mark Woods.
+			Many enhancements has been introduced with it. </li>
+		<li>The PHP connector for the default File Browser now sorts the folders and files names.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1289372&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1289372</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1282758&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1282758</a>] In the PHP connector it is now possible to set the absolute
+			(server) path to the User Files directory, avoiding problems with Virtual Directories,
+			Symbolic Links or Aliases. Take a look at the config.php file. </li>
+		<li>The ASP.Net uploader (for Quick Uploads) has been added to the package. </li>
+		<li>A new way to define <strong>simple &quot;combo&quot; toolbar items</strong> , like
+			Style and Font, has been introduced.&nbsp;Thanks&nbsp;to Steve Lineberry.&nbsp;See
+			sample06.html and the &quot;simplecommands&quot; plugin&nbsp;to fully understand
+			it. </li>
+		<li>A new test case has been added that shows how to set the editor background dynamically
+			without using a CSS. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155906&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1155906</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1110116&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1110116</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1216332&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1216332</a>] The &quot;AutoDetectPasteFromWord&quot; configuration option
+			is back (IE only feature). </li>
+		<li>The&nbsp;new &quot;OnAfterLinkedFieldUpdate&quot; event has been introduced. If
+			is fired when the editor updates its hidden associated field. </li>
+		<li>Attention: The color of the right border of the toolbar (left on RTL interfaces)
+			has been moved from code to the CSS (TB_SideBorder class). Update your custom skins.
+		</li>
+		<li>A&nbsp;sample &quot;htaccess.txt&quot; file has been added to the editor's package
+			to show how to configure some Linux sites that could present problems on Firefox
+			with &quot;Illegal characters&quot; errors. Respectively the &quot;&iuml;&raquo;&iquest;&quot;
+			chars. </li>
+		<li>With the JavaScript, ASP and PHP integration files, you can set the QueryString
+			value &quot;fcksource=true&quot; to load the editor using the source files (located
+			in the _source directory) instead of the compressed ones. Thanks to Kae Verens for
+			the suggestion. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1246623&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1246623</a>] The new configuration option &quot;ForceStrongEm&quot; has
+			been introduced so you can force the editor to convert all &lt;B&gt; and &lt;I&gt;
+			tags to &lt;STRONG&gt; and &lt;EM&gt; respectively. </li>
+		<li>A nice contribution has been done by Goss Interactive Ltd:
+			<ul>
+				<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1246949&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1246949</a>] Implemented ENTER key and BACKSPACE key handlers for Gecko so that
+					P tags (or an appropriate block element) get inserted instead of BR tags when not
+					in the UseBROnCarriageReturn config mode.
+					<br />
+					The ENTER key handling has been written to function much the same as the ENTER key
+					handling on IE : as soon as the ENTER key is pressed, existing content will be wrapped
+					with a suitable block element (P tag) as appropriate and a new block element (P
+					tag) will be started.
+					<br />
+					The ENTER key handler also caters for pressing ENTER within empty list items - ENTER
+					in an empty item at the top of a list will remove that list item and start a new
+					P tag above the list; ENTER in an empty item at the bottom of a list will remove
+					that list item and start a new P tag below the list; ENTER in an empty item in the
+					middle of a list will remove that list item, split the list into two, and start
+					a new P tag between the two lists. </li>
+				<li>Any tables that are found to be incorrectly nested within a block element (P tag)
+					will be moved out of the block element when loaded into the editor. This is required
+					for the new ENTER/BACKSPACE key handlers and it also avoids non-compliant HTML.&nbsp;
+				</li>
+				<li>The InsertOrderedList and InsertUnorderedList commands have been overridden on Gecko
+					to ensure that block elements (P tags) are placed around a list item's content when
+					it is moved out of the list due to clicking on the editor's list toolbar buttons
+					(when not in the UseBROnCarriageReturn config mode). </li>
+			</ul>
+		</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1253255&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1253255</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1253255&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1265520</a>] Due to changes on version 2.0, the anchor list was not anymore
+			visible in the link dialog window. It has been fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1242979&amp;group_id=75348">SF
+			BUG-1242979</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1251354&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1251354</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1256178&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1256178</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1274841&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1274841</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1303949&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1303949</a>] Due to a bug on Firefox, some keys stopped working
+			on startup over Firefox. It has been fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1251373&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1251373</a> ] The above fix also has&nbsp;corrected some strange behaviors on
+			Firefox. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1144258">SF
+			BUG-1144258</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1092081">SF
+				BUG-1092081</a>] The File Browsers now run on the&nbsp;same server session used
+			in the page where the editor is placed in (IE issue). Thanks to Simone Chiaretta.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1305619&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1305619</a> ] No more repeated login dialogs when running the editor with Windows
+			Integrated Security with IIS. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1245304&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1245304</a>] The Test Case 004 is now working correctly. It has been changed
+			to set the editor hidden at startup. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1290610&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1290610</a> ] Over HTTPS, there were some warnings when loading the Images,
+			Flash and Link dialogs. Fixed. </li>
+		<li>Due to Gecko bugs, two errors were thrown when loading the editor in a hidden div.
+			Workarounds have been introduced. In any case, the testcase 004 hack is needed when
+			showing the editor (as in a tabbed interface). </li>
+		<li>An invalid path in the dialogs CSS file has been corrected. </li>
+		<li>On IE, the Undo/Redo can now be controlled using the Ctrl+Z and Ctrl+Y shortcut
+			keys. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1295538&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1295538</a> ] A few Undo/Redo fixes for IE have been done. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1247070&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1247070</a>] On Gecko, it is now possible to use the shortcut keys for Bold
+			(CTRL+B), Italic (CTRL+I) and Underline (CTRL+U), like in IE. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1274303&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1274303</a>] The &quot;Insert Column&quot; command is now working correctly
+			on TH cells. It also copies any attribute applied to the source cells. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1287070&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1287070</a> ] In the Universal Keyboard, the Arabic keystrokes translator
+			is now working with Firefox. Thanks again to Abdul-Aziz Al-Oraij. </li>
+		<li>The editor now handles AJAX requests with HTTP status 304. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157780&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1157780</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1229077&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1229077</a>] Weird comments are now handled correctly (ignored on some cases).
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155774&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1155774</a>] A spelling error in the Bulleted List Properties dialog has been
+			corrected. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1272018&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1272018</a>] The ampersand character can now be added from the Special Chars
+			dialog. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1263161&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1263161</a>] A small fix has been applied to the sampleposteddata.php file.
+			Thanks to Mike Wallace. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1241504&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1241504</a>] The editor now looks also for the ID of the hidden linked field.
+		</li>
+		<li>The caption property on tables is now working on Gecko. Thanks to Helen Somers (Goss
+			Interactive Ltd). </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1297431&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1297431</a>] With IE, the editor now works locally when its files are placed
+			in a directory path that contains spaces. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1279551&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1279551</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1242105&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1242105</a>] On IE, some features are dependant of ActiveX components (secure...
+			distributed&nbsp;with IE itself). Some security setting could avoid the usage of
+			those components and the editor would stop working. Now a message is shown, indicating
+			the use the minimum necessary settings need&nbsp;by the editor to run. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1298880&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1298880</a>] Firefox can't handle the STRONG and EM tags. Those tags are now
+			converted to B and I so it works accordingly. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1271723&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1271723</a>] On IE, it is now possible to select the text and work correctly
+			in the contents of absolute positioned/dimensioned divs. </li>
+		<li>On IE, there is no need to click twice in the editor to&nbsp;activate the cursor
+			in the editing area. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1221621&amp;group_id=75348">SF
+			BUG-1221621</a>] Many &quot;warnings&quot; in the Firefox console are not thrown
+			anymore. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1295526&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1295526</a>] While&nbsp;editing on &quot;FullPage&quot; mode the basehref is
+			now active for CSS &quot;link&quot; tags. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1222584&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1222584</a>] A small fix to the PHP connector has been applied. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1281313&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1281313</a>] A few small changes to avoid problems with Plone. Thanks to Jean-mat.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1275911&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1275911</a>] A check for double dots sequences on directory names on creation
+			has been introduced to the PHP and ASP connectors.</li>
+	</ul>
+	<h3>
+		Version 2.0</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>The&nbsp;new &quot;<strong>Flash</strong>&quot; command is available. Now you can
+			easily handle Flash content, over IE and Gecko, including server browser integration
+			and context menu support. Due to limitations of the browsers, it is not possible
+			to see the preview of the movie while editing, so a nice &quot;placeholder&quot;
+			is used instead. * </li>
+		<li>A&nbsp;&quot;<strong>Quick Upload</strong> &quot; option is now available in the
+			link, image and flash dialog windows, so the user don't need to go (or have) the
+			File Browser for this operations. The ASP and PHP uploader&nbsp;are included.&nbsp;Take
+			a look at the configuration file.*** </li>
+		<li>Added support for <strong>Active FoxPro Pages</strong> . Thanks to our new developer,
+			S&ouml;nke Freitag. </li>
+		<li>It is now possible to <strong>disable the size handles</strong> for images and tables
+			(IE only feature). Take a look at the DisableImageHandles and DisableTableHandles
+			configuration options. </li>
+		<li>The handles on form fields&nbsp;(small squares around them) and the inline editing
+			of&nbsp;its contents&nbsp;have been disabled. This makes it easier to users to use
+			the controls. </li>
+		<li>A much better support for Word pasting operations has been introduced. Now it uses
+			a dialog box, in this way we have better results and more control.** </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1225372&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1225372</a>] A small change has been done to the PHP integration file. The
+			generic __construct constructor has been added for better PHP 5 sub-classing&nbsp;compatibility
+			(backward compatible). Thanks to Marcus Bointon.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>ATTENTION: Some security changes have been made to the connectors. Now you must
+			explicitly enable the connector you want to use. Please test your application before
+			deploying this update. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1211591">SF
+			BUG-1211591</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1204273&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1204273</a>] The connectors have been changed so it is not possible to use
+			&quot;..&quot; on directory names. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1219734&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1219734</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1219728&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1219728</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1208654&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1208654</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205442&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1205442</a>] There was an error in the page unload on some cases
+			that has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1209708">SF
+			BUG-1209708</a>] [<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1214125">SF
+				BUG-1214125</a>] The undo on IE is now working correctly when the user starts
+			typing. </li>
+		<li>The preview now loads &quot;Full Page&quot; editing correctly. It also uses the
+			same XHTML code produced by the final output. </li>
+		<li>The &quot;Templates&quot; dialog was not working on some very specific (and strange)
+			occasions over IE. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1199631&amp;group_id=75348">SF
+			BUG-1199631</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1171944&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1171944</a>] A new option is available to avoid a bad IE behavior that shows
+			the horizontal scrollbar even when not needed. You can now force the vertical scrollbar
+			to be always visible. Just set the &quot;IEForceVScroll&quot; configuration option
+			to &quot;true&quot;. Thanks to Grant Bartlett. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212026&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1212026</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1228860&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1228860</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1211775&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1211775</a>] [<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1199824">SF
+						BUG-1199824</a>] An error in the Packager has been corrected. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1163669">SF
+			BUG-1163669</a>] The XHTML processor now adds a space before the closing slash of
+			tags that don't have a closing tag, like &lt;br /&gt;. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1213733&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1213733</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1216866&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1216866</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1209673&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1209673</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155454&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1155454</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1187936&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1187936</a> ]&nbsp;Now, on Gecko, the source is opened in a
+			dialog window to avoid fatal errors (Gecko bugs). </li>
+		<li>Some pages have been changed to avoid importing errors on Plone. Thanks to Arthur
+			Kalmenson. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1171606&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1171606</a>] There&nbsp;is a bug on IE that makes the editor to not work if
+			the instance name matches a meta tag name. Fixed. </li>
+		<li>On Firefox, the source code is now opened in a dialog box, to avoid error on pages
+			with more than one editor. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1225703&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1225703</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1214941&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1214941</a>] The &quot;ForcePasteAsPlainText&quot; configuration option
+			is now working correctly on Gecko browsers. Thanks to Manuel Polo. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1228836&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1228836</a>] The &quot;Show Table Borders&quot; feature is now working on Gecko
+			browsers. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212529&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1212529</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212517&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1212517</a>] The default File Browser now accepts connectors with querystring
+			parameters (with &quot;?&quot;). Thanks to Tomas Jucius. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1233318&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1233318</a>] A JavaScript error thrown when using the Print command has been
+			fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1229696&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1229696</a>] A regular expression has been escaped to avoid problems when opening
+			the code in some editors. It has been moved to a&nbsp;dialog window. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1231978&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1231978</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1228939&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1228939</a>] The Preview window is now using the Content Type and Base href.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1232056&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1232056</a>] The&nbsp;anchor icon is now working correctly on IE. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1232056&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1202468</a>] The anchor icon is now available on Gecko too. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1236279&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1236279</a>] A security warning has been corrected when using the File Browser
+			over HTTPS. </li>
+		<li>The ASP implementation now avoid errors when setting the editor value to null values.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1237359&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1237359</a>] The trailing &lt;BR&gt; added by Gecko at the end of the source
+			is now removed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1170828">SF
+			BUG-1170828</a>] No more &amp;nbsp; is added to the source when using the &quot;New
+			Page&quot; button. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1165264&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1165264</a>] A&nbsp;new configuration option has been included to force the
+			editor to ignore empty paragraph values&nbsp;(&lt;p&gt;&amp;nbsp;&lt;/p&gt;), returning
+			empty (&quot;&quot;). </li>
+		<li>No more &amp;nbsp; is added when creating a table or adding columns, rows or cells.
+		</li>
+		<li>The &lt;TD&gt; tags are now included in the FillEmptyBlocks configuration handling.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1224829&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1224829</a>] A small bug in the &quot;Find&quot; dialog has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1221307&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1221307</a>] A small bug in the &quot;Image&quot; dialog has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1219981&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1219981</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155726&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1155726</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1178473&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1178473</a>] It is handling the &lt;FORM&gt;, &lt;TEXTAREA&gt; and &lt;SELECT&gt;
+			tags &quot;name&quot; attribute correctly. Thanks to thc33. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205403&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1205403</a>] The checkbox and radio button values are now handled correctly
+			in their dialog windows. Thanks to thc33. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1236626&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1236626</a>] The toolbar now doesn't need to collapse when unloading the page
+			(IE only). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212559&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1212559</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1017231&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1017231</a>] The &quot;Save&quot; button now calls the &quot;onsubmit&quot;
+			event before posting the form. The submit can be cancelled if the onsubmit returns
+			&quot;false&quot;. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1215823&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1215823</a>] The editor now works correctly on Firefox if it values is set to
+			&quot;&lt;p&gt;&lt;/p&gt;&quot;. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1217546&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1217546</a>] No error is thrown when &quot;pasting as plain text&quot; and no
+			text is available for pasting (as an image for example). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1207031&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1207031</a>] [<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1223978">SF
+				BUG-1223978</a>] The context menu is now available in the source view. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1213871">SF
+			BUG-1213871</a>] Undo has been added to table creation and table operation commands.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205211&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1205211</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1229941&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1229941</a>] Small bug in the mcpuk file browser&nbsp;have been corrected.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a target="_blank" href="http://www.infineon.com/">
+			Infineon Technologies AG</a>.<br />
+		** This version has been partially sponsored by <a href="http://www.visualsoft.co.uk">
+			Visualsoft</a> <a href="http://www.visualsoft.co.uk/websolutions.html">Web Solutions</a>.<br />
+		*** This version has been partially sponsored by <a target="_blank" href="http://www.webcrossing.com">
+			Web Crossing, Inc</a>.</p>
+	<h3>
+		Version 2.0&nbsp;FC (Final Candidate)</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>A new tab called &quot;<strong>Link</strong>&quot; is available in the<strong> Image
+			Dialog</strong> window. In this way you can insert or modify the image link directly
+			from that dialog.* </li>
+		<li>The new &quot;<strong>Templates</strong>&quot; command is now available. Now the
+			user can select from a list of pre-build HTML and fill the editor with it. Take
+			a look at the &quot;_docs&quot; for more info.** </li>
+		<li>The <a target="_blank" href="http://mcpuk.net/fbxp/">mcpuk's</a> File Browser for
+			PHP has been included in the package. He became the official developer of the File
+			Manager for FCKeditor, so we can expect good news in the future. </li>
+		<li>New configuration options are available to <strong>hide tabs</strong> from the <strong>
+			Image</strong> Dialog&nbsp;and <strong>Link</strong> Dialog windows: LinkDlgHideTarget,
+			LinkDlgHideAdvanced, ImageDlgHideLink and ImageDlgHideAdvanced. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1189442&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1189442</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1187164&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1187164</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1185905&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1185905</a>] It is now possible to configure the editor to <strong>not convert Greek</strong>
+			or special&nbsp;<strong>Latin </strong>letters to ther specific HTML entities. You
+			can also configure it to not convert any character at all. Take a look at the &quot;ProcessHTMLEntities&quot;,
+			&quot;IncludeLatinEntities&quot; and &quot;IncludeGreekEntities&quot; configuration
+			options. </li>
+		<li>New language files are available:
+			<ul>
+				<li><strong>Basque</strong> (by Ibon Igartua) </li>
+				<li><strong>English (Australia / United Kingdom)</strong> (by Christopher Dawes) </li>
+				<li><strong>Ukrainian</strong> (by Alexander Pervak)</li>
+			</ul>
+		</li>
+		<li>The version and date information have been removed from the files headers to avoid
+			unecessary diffs in source control systems when new versions are released (from
+			now on). </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1159854&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1159854</a>] Ther HTML output rendered by the server side integration files
+			are now XHTML compatible. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181823&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1181823</a>] It is now possible to set the desired DOCTYPE to use when edit
+			HTML fragments (not in Full Page mode). </li>
+		<li>There is now an optional way to implement different &quot;mouse over&quot; effects
+			to the buttons when they are &quot;on&quot; of &quot;off&quot;.</li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1162200&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1162200</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1161633&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1161633</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1050293&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1050293</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1058948&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1058948</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1109120&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1109120</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155408&amp;group_id=75348&amp;atid=543653">SF
+								BUG-1155408</a>] The IE memory leak bug has been solved. The
+			code has been completely reviewed and many memory usage improvements have been done.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1179645&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1179645</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1183252&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1183252</a> ] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1166779&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1181647</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155627&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1155627</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155782&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1155782</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155750&amp;group_id=75348&amp;atid=543653">SF
+								BUG-1155750</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157166&amp;group_id=75348&amp;atid=543653">SF
+									BUG-1157166</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157857&amp;group_id=75348&amp;atid=543653">SF
+										BUG-1157857</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1158121&amp;group_id=75348&amp;atid=543653">SF
+											BUG-1158121</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1177153&amp;group_id=75348&amp;atid=543653">SF
+												BUG-1177153</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1175847&amp;group_id=75348&amp;atid=543653">SF
+													BUG-1175847</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155747&amp;group_id=75348&amp;atid=543653">SF
+														BUG-1155747</a>] There was a loading
+			problem in Gecko browsers in some cases. It has been solved. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1161147&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1161147</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157635&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1157635</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1149805&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1149805</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1124600&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1124600</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1117535&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1117535</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1118145&amp;group_id=75348&amp;atid=543653">SF
+								BUG-1118145</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1098113&amp;group_id=75348&amp;atid=543653">SF
+									BUG-1098113</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092272&amp;group_id=75348&amp;atid=543653">SF
+										BUG-1092272</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1086416&amp;group_id=75348&amp;atid=543653">SF
+											BUG-1086416</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1027952&amp;group_id=75348&amp;atid=543653">SF
+												BUG-1027952</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=978441&amp;group_id=75348&amp;atid=543653">SF
+													BUG-978441</a> ] A custom Undo/Redo system
+			has been implemented for IE. </li>
+		<li>The editor startup execution is now made in the right order (so configurations override
+			works correctly). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1166779&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1166779</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1166651&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1166651</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1066198&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1066198</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090388&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1090388</a> ]&nbsp;No more &quot;illegible&quot; characters in the
+			toolbar when &quot;ClearType&quot; is active. </li>
+		<li>It is now possible to set the &quot;width&quot; style of the BODY tag in the EditorAreaCSS
+			to limit the editing area size. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1113620&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1113620</a>] In IE, the editor doesn't generate new entries in the browser history
+			anymore. </li>
+		<li>The editor now uses the same method used on version RC2 to load its contents on
+			Gecko. It is now possible to have more than one editor in the page. This change
+			has a negative impact: the BaseHref property is not working. </li>
+		<li>Changes have been made to make the editor work with PHP versions&nbsp;older than&nbsp;2.1.0.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1190835&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1190835</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1196547&amp;group_id=75348">SF
+				BUG-1196547</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156863&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1156863</a>] The &quot;Insert Horizontal Line&quot; command is now working
+			correctly. Thanks to Hector Raul Colonia Coral. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1101861&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1101861</a>] The editor now shows a normal textarea correctly (as expected)
+			on Safari browsers (and all &quot;like Gecko&quot; browsers). Thanks to Bob Paul.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1182224&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1182224</a>] The PHP connector can now handle file extensions in upper case,&nbsp;like
+			JPG or Gif, correctly. Thanks to Georg Ivancsic. </li>
+		<li>The &quot;sample06.html&quot; is now working correctly with Gecko browsers. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156660&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1156660</a>] Some fixes have been applied to the Universal Keyboard. Thanks
+			to Abdul-Aziz Al-Oraij. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1192881&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1192881</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1185006&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1185006</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156068&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1156068</a>] The &quot;Browse Server&quot; button is now working correctly
+			for the Background Image in the &quot;Document Properties&quot; dialog window (full
+			page editing). The active &quot;BaseHref&quot; is also set to the preview window.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1191704&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1191704</a>] Invalid HTML tags (according to the W3C naming standards for XHTML)
+			are ignored with no errors. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1185911&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1185911</a>] The Greek language file name has been corrected to &quot;el.js&quot;.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181572&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1181572</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1158421&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1158421</a>] The &quot;Print&quot; button is now active on startup. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181572&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1165219</a>] No error occours when the user defines just one color to the FontColors
+			on &quot;in page&quot; configurations. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1162957&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1162957</a>] The small problem with Zope (ZPT)&nbsp;has been solved. </li>
+		<li>Some small RTL / LTR corrections has been done in the interface and the Farsi language
+			has been added to the Universal Keyboard. Thanks to Silver Baghdasarian.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by the <a href="http://www.hamilton.edu">
+			Hamilton College</a>.<br />
+		** This version has been partially sponsored by <a target="_blank" href="http://www.infineon.com/">
+			Infineon Technologies AG</a>.</p>
+	<h3>
+		Version 2.0 RC3 (Release Candidate 3)</h3>
+	<p>
+		New Features and Improvements:</p>
+	<ul>
+		<li>The editor now offers native <strong>Perl integration</strong>! Thanks and welcome
+			to Takashi Yamaguchi, our official Perl developer. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1026584&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1026584</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1112692&amp;group_id=75348&amp;atid=543656">SF
+				Feature-1112692</a>] <strong>Formatting </strong>has been introduced to the
+			<strong>Source View</strong>. The output HTML can also be formatted. You can choose
+			to use spaces or tab for indentation. See the configuration file. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1031492&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1031492</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1004293&amp;group_id=75348&amp;atid=543656">SF
+				Feature-1004293</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=784281&amp;group_id=75348&amp;atid=543656">SF
+					Feature-784281</a>] It is now possible to edit <strong>full HTML pages</strong>
+			with the editor. Use the &quot;FullPage&quot; configuration setting to activate
+			it. </li>
+		<li>The&nbsp;new toolbar command, &quot;<strong>Document Properties</strong>&quot;&nbsp;is
+			available to edit document header info, title, colors, background, etc... Full page
+			editing must be enabled. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1151448&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1151448</a>] <strong>Spell Check</strong> is now available. You can use
+			<strong>ieSpell</strong> or <strong>Speller Pages</strong> right from FCKeditor.
+			More info about configuration can be found in the _docs folder. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1041686&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1041686</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1086386&amp;group_id=75348&amp;atid=543656">SF
+				Feature-1086386</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1124602&amp;group_id=75348&amp;atid=543656">SF
+					Feature-1124602</a>] New &quot;<strong>Insert Anchor</strong>&quot; command
+			has been introduced. (The anchor icon is visible only over&nbsp;IE for now). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1123816&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1123816</a>] It is now possible to configure the editor to <strong>show &quot;fake&quot;
+				table borders</strong> when the border size is set to zero. (It is working only
+			on IE for now). </li>
+		<li><strong>Numbered</strong> and <strong>Bulleted</strong> lists can now be <strong>
+			configured</strong> . Just right click on then. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088608&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1088608</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1144047&amp;group_id=75348&amp;atid=543656">SF
+				Feature-1144047</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1149808&amp;group_id=75348&amp;atid=543656">SF
+					Feature-1149808</a>] A new configuration setting is available, &quot;<strong>BaseHref</strong>
+			&quot;, to set the URL used to resolve relative links. </li>
+		<li>It is now possible to set&nbsp;the <strong>content language direction</strong> .
+			See the &quot;FCKConfig.ContentLangDirection&quot; configurations setting. </li>
+		<li>All <strong>Field Commands</strong> available on version 1.6 have been upgraded
+			and&nbsp;included in this version: <strong>form</strong>, <strong>checkbox</strong>,
+			<strong>radio button</strong>, <strong>text field</strong>, text <strong>area</strong>,
+			<strong>select field</strong>, <strong>button</strong>, <strong>image button</strong>
+			and <strong>hidden field</strong> . </li>
+		<li><strong>Context menu</strong> options (right-click) has been added for: <strong>
+			anchors</strong>, <strong>select field</strong>, <strong>textarea</strong>, <strong>
+				checkbox</strong>, <strong>radio button</strong>, <strong>text field</strong>,
+			<strong>hidden field</strong>, <strong>textarea</strong>, <strong>button</strong>,
+			<strong>image button</strong>, <strong>form</strong>, <strong>bulleted list</strong>
+			and <strong>numbered list</strong> . </li>
+		<li>The &quot;<strong>Universal Keyboard</strong>&quot; has been converted from version
+			1.6 to this one and it's now available. </li>
+		<li>It is now possible to <strong>configure</strong> the items to be shown in the <strong>
+			context menu</strong> . Just use the FCKConfig.ContextMenu option&nbsp;at fckconfig.js.
+		</li>
+		<li>A new configuration (FillEmptyBlocks)&nbsp;is available to force the editor to <strong>
+			automatically insert a &amp;nbsp;</strong> on empty block elements (p, div, pre,
+			h1, etc...) to avoid differences from the editing and the final result. (Actually,
+			the editor automatically &quot;grows&quot; empty elements to make the user able
+			to enter text on it). Attention: the extra &amp;nbsp; will be added when switching
+			from WYSIWYG to Source View, so the user may see an additional space on empty blocks.
+			(XHTML support must be enabled). </li>
+		<li>It is now possible to configure the <strong>toolbar</strong> to &quot;<strong>break</strong>
+			&quot; between two toolbar strips. Just insert a &quot;/&quot; between then. Take
+			a look at fckconfig.js for a sample. </li>
+		<li>New Language files are available:
+			<ul>
+				<li><strong>Brazilian Portuguese</strong> (by Carlos Alberto Tomatis Loth) </li>
+				<li><strong>Bulgarian</strong> (by Miroslav Ivanov) </li>
+				<li><strong>Esperanto</strong> (by Tim Morley) </li>
+				<li><strong>Galician</strong> (by Fernando Riveiro Lopez) </li>
+				<li><strong>Japanese</strong> ( by Takashi Yamaguchi) </li>
+				<li><strong>Persian</strong> (by Hamed Taj-Abadi) </li>
+				<li><strong>Romanian</strong> (by Adrian Nicoara) </li>
+				<li><strong>Slovak</strong> (by Gabriel Kiss) </li>
+				<li><strong>Thai </strong>(by Audy Charin Arsakit) </li>
+				<li><strong>Turkish</strong> (by Reha Bi&ccedil;er) </li>
+				<li>The Chinese Traditional has been set as the default (zn) instead of zn-tw.</li>
+			</ul>
+		</li>
+		<li>Warning: All toolbar image images have been changed. The &quot;button.&quot; prefix
+			has been removed. If you have your custom skin, please rename your files. </li>
+		<li>A new plugin is available in the package: &quot;<strong>Placeholders</strong>&quot;.
+			In this way you can insert non editable tags in your document to be processed on
+			server side (very specific usage). </li>
+		<li>The ASPX files are no longer available in this package. They have been moved to
+			the FCKeditor.Net package. In this way the ASP.Net integration is much better organized.
+		</li>
+		<li>The FCKeditor.Packager program is now part of the main package. It is not anymore&nbsp;distributed
+			separately. </li>
+		<li>The PHP connector now sets the uploaded file permissions (chmod)&nbsp;to 0777. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090215&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1090215</a>] It's now possible to give back more info from your custom image
+			browser calling the SetUrl( url [, width] [, height] [, alt] ). Thanks to Ben Noblet.
+		</li>
+		<li>The package files now maintain their original &quot;Last Modified&quot; date, so
+			incremental FTP uploads can be used to update to&nbsp;new versions of the editor
+			(from now on). </li>
+		<li>The &quot;Source&quot; view now forces its contents to be written in &quot;Left
+			to Right&quot; direction even when the editor interface language is running a RTL
+			language (like Arabic, Hebrew or Persian). </li>
+	</ul>
+	<p>
+		Fixed Bugs:</p>
+	<ul>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1124220&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1124220</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1119894&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1119894</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090986&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1090986</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1100408&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1100408</a>] The editor now works correctly when starting with an
+			empty value and switching to the Source mode. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1119380&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1119380</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1115750&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1115750</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1101808&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1101808</a>] The problem with the scrollbar and the toolbar combos (Style,
+			Font, etc...) over Mac has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1098460&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1098460</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1076544&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1076544</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077845&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1077845</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092395&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1092395</a>] A new upload class has been included for the ASP File
+			Manager Connector. It uses the &quot;ADODB.Stream&quot; object. Many thanks to &quot;NetRube&quot;.
+		</li>
+		<li>I small correction has been made to the ColdFusion integration files. Thanks to
+			Hendrik Kramer. </li>
+		<li>There was a very specific problem when the editor was running over a FRAME executed
+			on another domain. </li>
+		<li>The performance problem on Gecko while typing&nbsp;quickly has been solved. </li>
+		<li>The &lt;br type= &quot;_moz&quot;&gt;is not anymore shown on XHTML source. </li>
+		<li>It has been introduced a mechanism to avoid automatic contents duplication on very
+			specific occasions (bad formatted HTML). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1146407&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1146407</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1145800&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1145800</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1118803&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1118803</a> ] Other&nbsp;issues in the XHTML processor have been solved.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1143969&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1143969</a>] The editor now accepts the &quot;accept-charset&quot; attribute
+			in the FORM tag (IE specific bug). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1122742&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1122742</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1089548&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1089548</a> ] Now, the contents of the SCRIPT and STYLE tags remain untouched.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1114748&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1114748</a>] The PHP File Manager Connector now sets the new folders permissions
+			(chmod)&nbsp;to 0777 correctly. </li>
+		<li>The PHP File Manager Connector now has a configuration file (editor/filemanager/browser/default/connectors/php/config.php)
+			to set some security preferences. </li>
+		<li>The&nbsp;ASP File Manager Connector now has a configuration file (editor/filemanager/browser/default/connectors/asp/config.asp)
+			to set some security preferences. </li>
+		<li>A small bug in the toolbar rendering (strips auto position) has been corrected.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1093732&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1093732</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1091377&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1091377</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083044&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1083044</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1096307&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1096307</a>] The configurations are now encoded so a user can use
+			values that has special chars (&amp;=/). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1103688&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1103688</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092331&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1092331</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088220&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1088220</a>] PHP samples now use PHP_SELF to automatically discover
+			the editor's base path. </li>
+		<li>Some small wrapping problems with some labels in the Image and Table dialog windows
+			have been fixed. </li>
+		<li>All .js files are now encoded in UTF-8 format with the BOM (byte order mask) to
+			avoid some errors on specific Linux installations. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1114449&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1114449</a>] The editor packager program has been modified so now it is possible
+			to use the source files to run the editor as described in the documentation. The
+			new packager must be downloaded. </li>
+		<li>A small problem with the editor focus while in&nbsp;source&nbsp;mode has been corrected.
+			Thanks to Eric (ric1607). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1108167&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1108167</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085149&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1085149</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1151296&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1151296</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1082433&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1082433</a>] No more IFRAMEs without src attribute. Now it points
+			to a blank page located in the editor's package. In this way we avoid security warnings
+			when using the editor over HTTPS. Thanks to Guillermo Bozovich. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1117779&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1117779</a>] The editor now works well if you have more than one element named
+			&quot;submit&quot;&nbsp;on its form (even if it is not correct to have this situation).
+		</li>
+		<li>The XHTML processor was duplicating the text on some specific situation. It has
+			been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090213&amp;group_id=75348&amp;atid=543655">SF
+			Patch-1090213</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1098929&amp;group_id=75348&amp;atid=543653">SF
+				Patch-1098929</a>] With ASP, the editor now works correctly on pages using &quot;Option
+			Explicit&quot;. Thanks to Ben Noblet. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1100759&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1100759</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1029125&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1029125</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=966130&amp;group_id=75348&amp;atid=543653">SF
+					BUG-966130</a>] The editor was not working with old IE 5.5 browsers. There
+			was a problem with the XML parser. It has been fixed. </li>
+		<li>The localization engine is now working correctly over IE 5.5 browsers. </li>
+		<li>Some commands where not working well over IE 5.5 (emoticons, image,...). It has
+			been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1146441&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1146441</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1149777&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1149777</a>] The editor now uses the TEXTAREA id&nbsp;in the ReplaceTextarea
+			function. If the id is now found, it uses the &quot;name&quot;. The docs have been
+			updated. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1144297&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1144297</a>] Some corrections have been made to the Dutch language file. Thanks
+			to Erwin Dondorp. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1121365&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1121365</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090102&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1090102</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1152171&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1152171</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1102907&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1102907</a>] There is no problem now to start the editor with values
+			like &quot;&lt;div&gt;&lt;/div&gt;&quot; or &quot;&lt;p&gt;&lt;/p&gt;&quot;. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1114059&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1114059</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1041861&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1041861</a>] The click on the disabled options in the Context Menu has no
+			effects now. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1152617&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1152617</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1102441&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1102441</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1095312&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1095312</a>] Some problems when setting the editor source to very specific
+			values has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1093514&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1093514</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1089204&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1089204</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077609&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1077609</a>] The editor now runs correctly if called directly (locally)&nbsp;without
+			a server installation (just opening the HTML sample files). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088248&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1088248</a>] The editor now uses a different method to load its contents. In
+			this way the URLs remain untouched. </li>
+		<li>The PHP integration file now detects Internet Explorer 5.5 correctly.</li>
+	</ul>
+	<h3>
+		Version 2.0 RC2 (Release Candidate 2)</h3>
+	<ul>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1042034&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1042034</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1075961&amp;group_id=75348&amp;atid=543656">SF
+				Feature-1075961</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083200&amp;group_id=75348&amp;atid=543656">SF
+					Feature-1083200</a>] A new dialog window for the <strong>table cell properties</strong>
+			is now available (right-click). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1042034&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1042034</a>] The new &quot;<strong>Split Cell</strong> &quot;, to split
+			a table cell in two columns, has been introduced (right-click). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1042034&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1042034</a>] The new &quot;<strong>Merge Cells</strong>&quot;, to merge
+			table cells (in the same row), has been introduced (right-click). </li>
+		<li>The &quot;fake&quot; <strong>TAB key support</strong> (available by default over
+			Gecko browsers is now available over IE too. You can set the number of spaces to
+			add setting the FCKConfig.TabSpaces configuration setting. Set it to 0 (zero) to
+			disable this feature (IE). </li>
+		<li>It now possible to tell IE to send a <strong>&lt;BR&gt;</strong> when the user presses
+			the <strong>Enter key</strong>. Take a look at the FCKConfig.UseBROnCarriageReturn
+			configuration setting. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085422&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1085422</a>] <strong>ColdFusion</strong>: The <strong>File Manager connector</strong>
+			is now available! (Thanks to Hendrik Kramer). </li>
+		<li>The editor is now available in <strong>29 languages!</strong> The new language files
+			available are:&nbsp;
+			<ul>
+				<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1067775&amp;group_id=75348&amp;atid=543656">SF
+					Feature-1067775</a>] <strong>Chinese Simplified and Traditional</strong> (Taiwan
+					and Hong Kong) (by NetRube). </li>
+				<li><strong>Czech</strong> (by David Hor&aacute;k). </li>
+				<li><strong>Danish</strong> (by Jesper Michelsen). </li>
+				<li><strong>Dutch</strong> (by Bram Crins). </li>
+				<li><strong>German</strong> (by Maik Unruh). </li>
+				<li><strong>Portuguese</strong> (Portugal) (by Francisco Pereira). </li>
+				<li><strong>Russian</strong> (by Andrey Grebnev). </li>
+				<li><strong>Slovenian</strong> (by Boris Volaric).</li>
+			</ul>
+		</li>
+		<li>Updates to the <strong>French</strong> language files (by Hubert Garrido). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085816&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1085816</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083743&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1083743</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1078783&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1078783</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077861&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1077861</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077861&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1037404</a>] Many&nbsp;small bugs&nbsp;in the XHTML processor
+			has been corrected (workarounds to browser specific bugs). These are some things
+			to consider regarding the changes:
+			<ul>
+				<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083744&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1083744</a>] On Gecko browsers, any element attribute that the name starts with
+					&quot;_moz&quot; will be ignored. </li>
+				<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1060073&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1060073</a>] The &lt;STYLE&gt; and &lt;SCRIPT&gt; elements contents will be
+					handled as is, without CDATA tag surrounding. This may break XHTML validation. In
+					any case the use of external files for scripts and styles is recommended (W3C recommendation).</li>
+			</ul>
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088310&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1088310</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1078837&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1078837</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=999792&amp;group_id=75348&amp;atid=543653">SF
+					BUG-999792</a>] URLs now remain untouched when initializing the editor or
+			switching from WYSYWYG to Source and vice versa. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1082323&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1082323</a>] The&nbsp;problem in the ASP and PHP connectors when handling non
+			&quot;strange&quot; chars in file names has been corrected. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085034&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1085034</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1076796&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1076796</a>] Some bugs in the PHP connector have been corrected. </li>
+		<li>A&nbsp;problem with the &quot;Format&quot; command on IE browsers on languages different
+			of English has been solved. The negative side of this correction is that due to
+			a IE bad design it is not possible to update the &quot;Format&quot; combo while
+			moving throw the text (context sensitive). </li>
+		<li>On Gecko browsers, when selecting an image and executing the &quot;New Page&quot;
+			command, the image handles still appear, even if the image is not available anymore
+			(this is a Gecko bug). When clicking in&nbsp;a &quot;phanton&quot; randle, the browser
+			crashes. It doesn't&nbsp;happen (the crash)&nbsp;anymore. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1082197&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1082197</a>] On ASP, the bug in the browser detection system for Gecko browsers
+			has been corrected. Thanks to Alex Varga. </li>
+		<li>Again on ASP, the browser detection for IE had some problems on servers that use
+			comma for decimal separators on numbers. It has been corrected. Thanks to Agrotic.
+		</li>
+		<li>No error is thrown now when&nbsp;non existing&nbsp;language is configured in the
+			editor. The English language file is loaded in that case. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077747&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1077747</a>] The missing images on the Office2003 and Silver skins are now included
+			in the package. </li>
+		<li>On some Gecko browsers, the dialog window was not loading correctly. I couldn't
+			reproduce the problem, but a fix has been applied based on users tests. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1004078&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1004078</a>] ColdFusion: The &quot;config&quot; structure/hash table with keys
+			and values is in ColdFusion not(!) case sensitive. All keys returned by ColdFusion
+			are in upper case format. Because the FCKeditor configuration keys must be case
+			sensitive, we had to match all structure/hash keys with a list of the correct configuration
+			names in mixed case. This has been added to the fckeditor.cfc and fckeditor.cfm.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1075166&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1075166</a>] ColdFusion: The &quot;fallback&quot; variant of the texteditor
+			(&lt;textarea&gt;) has a bug in the fckeditor.cfm. This has been fixed. </li>
+		<li>A typo in the Polish language file has been corrected. Thanks to Pawel Tomicki.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1086370&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1086370</a>] A small coding type in the Link dialog window has been corrected.
+		</li>
+	</ul>
+	<h3>
+		Version 2.0 RC1 (Release Candidate 1)</h3>
+	<ul>
+		<li><strong>ASP</strong> support is now available (including the&nbsp;File Manager connector).
+		</li>
+		<li><strong>PHP</strong> support is now available (including the File Manager connector).
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1063217&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1063217</a>] The new advanced&nbsp;<strong>Style</strong> command is available
+			in the toolbar: full preview, context sensitive, style definitions are loaded from
+			a XML file (see documentation for more instructions). </li>
+		<li>The <strong>Font Format</strong>, <strong>Font Name</strong> and <strong>Font Size</strong>
+			toolbar command now show a <strong>preview</strong> of the available options. </li>
+		<li>The new <strong>Find</strong> and <strong>Replace</strong> features has been introduced.
+		</li>
+		<li>A new <strong>Plug-in</strong> system has been developed. Now it is quite easy to
+			customize the editor to your needs. (Take a look at the html/sample06.html file).
+		</li>
+		<li>The editor now handles <strong>HTML entities</strong> in the right way (XHTML support
+			must be set to &quot;true&quot;). It handles all entities defined in the W3C&nbsp;XHTML
+			DTD file. </li>
+		<li>A new &quot;_docs&quot; folder has been introduced for the <strong>documentation</strong>.
+			It is not yet complete, but I hope the community will help us to fill it better.
+		</li>
+		<li>It is now possible (even if it is not recommended by the W3C) to force the use of
+			simple ampersands (&amp;) on attributes (like the links href) instead of its entity
+			&amp;amp;. Just set FCKConfig.ForceSimpleAmpersand = true in the&nbsp;configuration
+			file. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1026866&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1026866</a>] The &quot;<strong>EditorAreaCSS</strong>&quot; configuration
+			option has been introduced. In this way you can set the CSS to use in the editor
+			(editable area). </li>
+		<li>The editing area is not anymore clipped if the toolbar is too large and exceeds
+			the window width. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1064902&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1064902</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1033933&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1033933</a>] The editor <strong>interface</strong> is now completely <strong>localizable</strong>.
+			The version ships with 19 languages including: <b>Arabic</b>, <b>Bosnian</b>, <b>Catalan</b>,
+			<b>English</b>, <b>Spanish</b>, <b>Estonian</b>, <b>Finnish</b>, <b>French</b>,
+			<b>Greek</b>, <b>Hebrew</b>, <b>Croatian</b>, <b>Italian</b>, <b>Korean</b>, <b>Lithuanian</b>,
+			<b>Norwegian</b>, <strong>Polish</strong>, <strong>Serbian (Cyrillic)</strong>,
+			<strong>Serbian (Latin)</strong> and <strong>Swedish</strong>.</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1027858&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1027858</a>] Firefox 1.0 PR&nbsp;introduced&nbsp;a bug that made the editor
+			stop working on it. A workaround has been developed to fix the problem. </li>
+		<li>There was a positioning problem over IE&nbsp;with the color panel. It has been corrected.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1049842&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1049842</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1033832&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1033832</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1028623&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1028623</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1026610&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1026610</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1064498&amp;group_id=75348&amp;atid=543653">SF
+							BUG-1064498</a>] The combo commands in the toolbar were not opening
+			in the right way. It has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1053399&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1053399</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=965318&amp;group_id=75348&amp;atid=543653">SF
+				BUG-965318</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1018296&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1018296</a>] The toolbar buttons icons were not showing on some IE and
+			Firefox/Mac installations. It has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1054621&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1054621</a>] Color pickers are now working with the &quot;office2003&quot; and
+			&quot;silver&quot; skins. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1054108&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1054108</a>] IE doesn&rsquo;t recognize the &quot;&amp;apos;&quot; entity for
+			apostrophes, so a workaround has been developed to replace it with &quot;&amp;#39;&quot;
+			(its numeric entity representation). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=983434&amp;group_id=75348&amp;atid=543653">SF
+			BUG-983434</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=983398&amp;group_id=75348&amp;atid=543653">SF
+				BUG-983398</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1028103&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1028103</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1072496&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1072496</a>] The problem with elements with name &quot;submit&quot;
+			inside the editor's form has been solved. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1018743&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1018743</a>] The problem with Gecko when collapsing the toolbar while in source
+			mode has been fixed. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1065268&amp;group_id=75348">SF
+			BUG-1065268</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1034354&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1034354</a>] The XHTML processor now doesn&rsquo;t use the minimized tag
+			syntax (like &lt;br/&gt;) for empty elements that are not marked as EMPTY in the
+			W3C XHTML DTD specifications. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1029654&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1029654</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1046500&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1046500</a>] Due to a bug on Gecko there was a problem when creating links.
+			It has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1065973&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1065973</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=999792&amp;group_id=75348&amp;atid=543653">SF
+				BUG-999792</a>] The editor now handles relative URLs in IE. In effect IE transform
+			all relative URLs to absolute links, pointing to the site the editor is running.
+			So now the editor removes the protocol and host part of the link if it matches the
+			running server. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1071824&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1071824</a>] The color dialog box bug has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1052856&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1052856</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1046493&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1046493</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1023530&amp;group_id=75348&amp;atid=543653">SF
+					BUG-1023530</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1025978&amp;group_id=75348&amp;atid=543653">SF
+						BUG-1025978</a>] The editor now doesn&rsquo;t throw an error if no selection
+			was made and the create link command is used. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1036756&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1036756</a>] The XHTML processor has been reviewed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1029101&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1029101</a>] The Paste from Word feature is working correctly. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1034623&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1034623</a>] There is an IE bug when setting the editor value to &quot;&lt;p&gt;&lt;hr&gt;&lt;/p&gt;&quot;.
+			A workaround has been developed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1052695&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1052695</a>] There are some rendering differences between Netscape and Mozilla.
+			(Actually that is a bug on both browsers). A workaround has been developed to solve
+			it. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1073053&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1073053</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1050394&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1050394</a>] The editor doesn&rsquo;t throw errors when hidden. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1066321&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1066321</a>] Scrollbars should not appear on dialog boxes (at least for the
+			Image and Link ones). </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1046490&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1046490</a>] Dialogs now are forced to show on foreground over Mac. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1073955&amp;group_id=75348">SF
+			BUG-1073955</a>] A small bug in the image dialog window has been corrected. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1049534&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1049534</a>] The Resources Browser window is now working well over Gecko browsers.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1036675&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1036675</a>] The Resources Browser window now displays the server error on bad
+			installations.</li>
+	</ul>
+	<h3>
+		Version 2.0 Beta 2</h3>
+	<ul>
+		<li>There is a new configuration - &quot;<strong>GeckoUseSPAN</strong>&quot; - that
+			can be used to tell Gecko browsers to use &lt;SPAN style...&gt; or &lt;B&gt;, &lt;I&gt;
+			and &lt;U&gt; for the bold, italic and underline commands. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1002622&amp;group_id=75348&amp;atid=543656">SF
+			Feature-1002622</a>] New <strong>Text Color</strong> and&nbsp;<strong>Background Color</strong>
+			&nbsp;commands have been added to the editor. </li>
+		<li>On Gecko browsers, a message is shown when,&nbsp;because of&nbsp;security settings,&nbsp;the
+			user&nbsp;is not able to&nbsp;cut, copy or paste data from the clipboard using the
+			toolbar buttons or the context menu. </li>
+		<li>The new &quot;<strong>Paste as Plain Text</strong> &quot; command has been introduced.
+		</li>
+		<li>The new &quot;<strong>Paste from Word</strong> &quot; command has been introduced.
+		</li>
+		<li>A new configuration named&nbsp;&quot;StartupFocus&quot; can be used to tell the
+			editor to get the focus when the page is loaded. </li>
+		<li>All <strong>Java </strong>integration files has been moved to a new separated package.
+		</li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1016781&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1016781</a>] <strong>Table operations</strong> are now working when right click
+			inside a table. The following commands has been introduced: <strong>Insert Row</strong>,
+			<strong>Delete Row</strong>, <strong>Insert Column</strong>, <strong>Delete Column</strong>,
+			<strong>Insert Cell</strong> and <strong>Delete Cells</strong> . </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=965067&amp;group_id=75348&amp;atid=543653">SF
+			BUG-965067</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1010379&amp;group_id=75348&amp;atid=543653">SF
+				BUG-1010379</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=977713&amp;group_id=75348&amp;atid=543653">SF
+					BUG-977713</a>] XHTML support was not working with FireFox, blocking the
+			editor when submitting data. It has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1007547&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1007547</a> ] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=974595&amp;group_id=75348&amp;atid=543653">SF
+				BUG-974595</a> ]&nbsp;The &quot;FCKLang not defined&quot; error when loading
+			has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1021028&amp;group_id=75348&amp;atid=543653">SF
+			BUG-1021028</a>] If the editor doesn't have the focus, some commands were been executed
+			outside the editor in the place where the focus is. It has been fixed. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=981191&amp;group_id=75348&amp;atid=543653">SF
+			BUG-981191</a>] We are now using &lt;!--- ---&gt; for ColdFusion comments.</li>
+	</ul>
+	<h3>
+		Version 2.0 Beta 1</h3>
+	<p>
+		This is the first beta of the 2.x series. It brings a lot of new and important things.
+		Beta versions will be released until all features available on version 1.x will
+		be introduced in the 2.0.<br />
+		<br />
+		<strong>Note:</strong> As it is a beta, it is not yet completely developed. Future
+		versions can bring new features that can break backward compatibility with this
+		version.
+	</p>
+	<ul>
+		<li>Gecko browsers (<strong>Mozilla</strong> and <strong>Netscape</strong>) support.
+		</li>
+		<li><strong>Quick startup</strong> response times. </li>
+		<li>Complete <strong>XHTML</strong> 1.0 support. </li>
+		<li><strong>Advanced link</strong> dialog box:
+			<ul>
+				<li>Target selection. </li>
+				<li>Popup configurator. </li>
+				<li>E-Mail link. </li>
+				<li>Anchor selector. </li>
+			</ul>
+		</li>
+		<li>New <strong>File Manager</strong>. </li>
+		<li>New dialog box system, with <strong>tabbed dialogs</strong> support. </li>
+		<li>New <strong>context menus</strong> with icons. </li>
+		<li>New toolbar with &quot;expand/collapse&quot; feature. </li>
+		<li><strong>Skins</strong> support. </li>
+		<li><strong>Right to left languages</strong> support. </li>
+	</ul>
+	<h3>
+		Version 1.6.1</h3>
+	<ul>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=862364&amp;group_id=75348&amp;atid=543653">SF
+			BUG-862364</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=812733&amp;group_id=75348&amp;atid=543653">SF
+				BUG-812733</a>] There was a problem when the user tried to delete the last row,
+			collumn or cell in a table. It has been corrected.* </li>
+		<li>New Estonian language file. Thanks to Kristjan Kivikangur </li>
+		<li>New Croatian language file. Thanks to Alex Varga. </li>
+		<li>Updated language file for Czech. Thanks to Plachow. </li>
+		<li>Updated language file for Chineze (zh-cn). Thanks to Yanglin. </li>
+		<li>Updated language file for Catalan. Thanks to Jordi Cerdan.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a href="http://www.genuitec.com/">Genuitec,
+			LLC</a>.</p>
+	<h3>
+		Version 1.6</h3>
+	<ul>
+		<li><strong>Context Menu</strong> support for <strong>form</strong> elements.* </li>
+		<li>New <strong>&quot;Selection Field&quot; command</strong> with advanced dialog box
+			for options definitions.* </li>
+		<li>New <strong>&quot;Image Button&quot; command</strong> is available.* </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=936196&amp;group_id=75348&amp;atid=543656">SF
+			Feature-936196</a>] Many form elements <strong>bugs has been fixed</strong> and
+			<strong>many improvements</strong> has been done.* </li>
+		<li>New <strong>Java Integration Module</strong>. There is a complete Java API and Tag
+			Library implementations. Take a look at the _jsp directory. Thanks to Simone Chiaretta
+			and Hao Jiang. </li>
+		<li>The <strong>Word Spell Checker</strong> can be used. To be able to run it, your
+			browser security configuration &quot;Initialize and script ActiveX controls not
+			marked as safe&quot; must be set to &quot;Enable&quot; or &quot;Prompt&quot;. And
+			easier and more secure way to do that is to add your site in the list of trusted
+			sites. IeSpell can still be used. Take a look at the fck_config.js file for some
+			configuration options. Thanks to EdwardRF. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=748807&amp;group_id=75348&amp;atid=543656">SF
+			Feature-748807</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=801030&amp;group_id=75348&amp;atid=543656">SF
+				Feature-801030</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=880684&amp;group_id=75348&amp;atid=543656">SF
+					Feature-880684</a>] New &quot;<strong>Anchor&quot; command</strong>, including
+			context menu support. Thanks to G.Meijer. </li>
+		<li>Special characters are replaced with their decimal HTML entities when the XHMTL
+			support is enabled (only over IE5.5+). </li>
+		<li>New <strong>Office 2003 Style</strong> toolbar icons are available. Just uncomment
+			the config.ToolbarImagesPath key in the fck_config.js file. Thanks to Abdul-Aziz
+			A. Al-Oraij. <strong>Attention</strong>: the default toolbar items have been moved
+			to the &quot;images/toolbar/default&quot; directory. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=934566&amp;group_id=75348&amp;atid=543655">SF
+			Patch-934566</a>] <strong>Double click support</strong> for Images, Tables, Links,
+			Anchors and all Form elements. Thanks to Top Man. </li>
+		<li>New <strong>&quot;New Page&quot; command</strong> to start a typing from scratch.
+			Thanks to Abdul-Aziz A. Al-Oraij. </li>
+		<li>New <strong>&quot;Replace&quot; command</strong>. Thanks to Abdul-Aziz A. Al-Oraij.
+		</li>
+		<li>New <strong>&quot;Advanced Font Style&quot; command</strong>. Thanks to Abdul-Aziz
+			A. Al-Oraij. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=738193&amp;group_id=75348&amp;atid=543656">SF
+			Feature-738193</a>] New <strong>&quot;Save&quot; command</strong>. It can be used
+			to simulate a save action, but in fact it just submits the form where the editor
+			is placed in. Thanks to Abdul-Aziz A. Al-Oraij. </li>
+		<li>New <strong>&quot;Universal Keyboard&quot; command</strong>. This 22 charsets are
+			available: Arabic, Belarusian, Bulgarian, Croatian, Czech, Danish, Finnish, French,
+			Greek, Hebrew, Hungarian, Diacritical, Macedonian, Norwegian, Polish, Russian, Serbian
+			(Cyrillic), Serbian (Latin), Slovak, Spanish, Ukrainian and Vietnamese. Includes
+			a keystroke listener to type Arabic on none Arabic OS or machine. Thanks to Abdul-Aziz
+			A. Al-Oraij. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=935358&amp;group_id=75348&amp;atid=543655">SF
+			Patch-935358</a>] New <strong>&quot;Preview&quot; command</strong>. Context menu
+			option is included and can be deactivated throw the config.ShowPreviewContextMenu
+			configuration. Thanks to Ben Ramsey. </li>
+		<li>New &quot;<strong>Table Auto Format</strong>&quot; context menu command. Hack a
+			little the fck_config.js and the fck_editorarea.css files. Thanks to Alexandros
+			Lezos. </li>
+		<li>New &quot;<strong>Bulleted List Properties</strong> &quot; context menu to define
+			its type and class. Thanks to Alexandros Lezos. </li>
+		<li>The <strong>image dialog</strong> box has been a <strong>redesigned</strong> . Thanks
+			to Mark Fierling. </li>
+		<li>Images now always have the <strong>&quot;alt&quot; attribute</strong> set, even
+			when it's value is empty. Thanks to Andreas Barnet. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=942250&amp;group_id=75348&amp;atid=543655">SF
+			Patch-942250</a>] You can set on fck_config.js to <strong>automatically clean Word</strong>
+			pasting operations without a user confirmation. </li>
+		<li>Forms element dialogs and other localization pending labels has been updated. </li>
+		<li>A new <strong>Lithuanian</strong> language file is available. Thanks to Tauras Paliulis.
+		</li>
+		<li>A new <strong>Hebrew</strong> language file is available. Thanks to Ophir Radnitz.
+		</li>
+		<li>A new <strong>Serbian</strong> language file is available. Thanks to Zoran Subic.
+		</li>
+		<li><strong>Danish</strong> language file updates. Thanks to Flemming Jensen. </li>
+		<li><strong>Catalan</strong> language file updates. Thanks to Jordi Cerdan. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=936514&amp;group_id=75348&amp;atid=543655">SF
+			Patch-936514</a>] [<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=918716&amp;group_id=75348">SF
+				BUG-918716</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=931037&amp;group_id=75348&amp;atid=543653">SF
+					BUG-931037</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=865864&amp;group_id=75348&amp;atid=543653">SF
+						BUG-865864</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=915410&amp;group_id=75348&amp;atid=543653">SF
+							BUG-915410</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=918716&amp;group_id=75348&amp;atid=543653">SF
+								BUG-918716</a>] Some <strong>languages files</strong> were not
+			saved on <strong>UTF-8</strong> format causing some javascript errors on loading
+			the editor or making &quot;undefined&quot; to show on editor labels. This problem
+			was solved. </li>
+		<li>Updates on the testsubmit.php file. Thanks to Geat and Gabriel Schillaci </li>
+		<li>[<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=924620&amp;group_id=75348">SF
+			BUG-924620</a>] There was a problem when setting a name to an editor instance when
+			the name is used by another tag. For example when using &quot;description&quot;
+			as the name in a page with the &lt;META name=&quot;description&quot;&gt; tag. </li>
+		<li>[<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=935018&amp;group_id=75348&amp;atid=543653">SF
+			BUG-935018</a>] The &quot;buletted&quot; typo has been corrected. </li>
+		<li>[<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=902122&amp;group_id=75348&amp;atid=543653">SF
+			BUG-902122</a>] Wrong css and js file references have been corrected. </li>
+		<li>[<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=918942&amp;group_id=75348&amp;atid=543653">SF
+			BUG-918942</a>] All dialog boxes now accept Enter and Escape keys as Ok and Cancel
+			buttons.</li>
+	</ul>
+	<p>
+		* This version has been partially sponsored by <a href="http://www.genuitec.com/">Genuitec,
+			LLC</a>.</p>
+	<h3>
+		Version 1.5</h3>
+	<ul>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543656&amp;aid=913777&amp;group_id=75348">SF
+			Feature-913777</a>] <strong>New Form Commands</strong> are now available! Special
+			thanks to G.Meijer. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=861149&amp;group_id=75348&amp;atid=543656">SF
+			Feature-861149</a>] <strong>Print Command</strong> is now available! </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=743546&amp;group_id=75348">SF
+			BUG-743546</a>] The <strong>XHTML content duplication problem </strong>has been
+			<strong>solved</strong> . Thanks to Paul Hutchison. </li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=875853&amp;group_id=75348">SF
+			BUG-875853</a>] The <strong>image dialog box</strong> now gives precedence for width
+			and height values set as styles. In this way a user can change the size of the image
+			directly inside the editor and the changes will be reflected in the dialog box.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543656&amp;aid=913777&amp;group_id=75348">SF
+			Feature-788368</a>] The sample <strong>file upload </strong>manager for ASPX now
+			uses <strong>guids</strong> for the file name generation. In this way a support
+			XML file is not needed anymore. </li>
+		<li>It's possible now to <strong>programmatically change the Base Path</strong> of the
+			editor if it's installed in a directory different of &quot;/FCKeditor/&quot;. Something
+			like this:<br />
+			oFCKeditor.BasePath = '/FCKeditor/' ;<br />
+			Take a look at the _test directory for samples. </li>
+		<li>There was a little bug in the TAB feature that moved the insertion point if there
+			were any object (images, tables) in the content. It has been fixed. </li>
+		<li>The problem with <strong>accented and international characters</strong> on the PHP
+			test page was solved. </li>
+		<li>A new <strong>Chinese (Taiwan)</strong> language file is available. Thanks to Nil.
+		</li>
+		<li>A new <strong>Slovenian</strong> language file is available. Thanks to Pavel Rotar.
+		</li>
+		<li>A new <strong>Catalan</strong> language file is available. Thanks to Jordi Cerdan.
+		</li>
+		<li>A new <strong>Arabic</strong> language file is available. Thanks to Abdul-Aziz A.
+			Al-Oraij. </li>
+		<li>Small corrections on the <strong>Norwegian</strong> language file. </li>
+		<li>A Java version for the test results (testsubmit.jsp) is now available. Thanks to
+			Pritpal Dhaliwal. </li>
+		<li>When using JavaScript to create a editor instance it's possible now to easily get
+			the editor's value calling oFCKeditor.GetValue() (eg.). Better JavaScript API interfaces
+			will be available on version 2.0. </li>
+		<li>If <strong>XHTML</strong> is enabled the editor cleans the HTML before showing it
+			on the Source View, so the exact result can be viewed by the user. This option can
+			be activated setting config.EnableSourceXHTML = true in the fck_config.js file.
+		</li>
+		<li>The <strong>JS integration object</strong> now escapes all configuration settings,
+			in this way a user can use <strong>reserved chars</strong> on it. For example:
+			<br />
+			oFCKeditor.Config[&quot;ImageBrowserURL&quot;] = '/imgs/browse.asp?filter=abc*.jpg&amp;userid=1';
+		</li>
+		<li>A minimal browse server sample is now available in ASP. Thanks to Andreas Barnet.
+		</li>
+	</ul>
+	<h3>
+		Version 1.4</h3>
+	<ul>
+		<li><strong>ATTENTION: For PHP users</strong>: The editor was changed and now uses <strong>
+			htmlspecialchars</strong> instead of <strong>htmlentities</strong> when handling
+			the initial value. It should works well, but please make some tests before upgrading
+			definitively. If there is any problem just uncomment the line in the fckeditor.php
+			file (and send me a message!). </li>
+		<li>The editor is now integrated with <strong>ieSpell</strong> (<a href="http://www.iespell.com">http://www.iespell.com</a>)
+			for <strong>Spell Checking</strong>. You can configure the download URL in then
+			fck_config.js file. Thanks to Sanjay Sharma. (ieSpell is free for personal use but
+			must be paid for commercial use) </li>
+		<li><strong>Table</strong> and <strong>table cell</strong> dialogs has been changed.
+			Now you can <strong>select the class</strong> you want to be applied. Thanks to
+			Alexander Lezos. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=865378&amp;group_id=75348&amp;atid=543656">SF
+			Feature-865378</a>]A new <strong>upload support is available for ASP</strong>. It
+			uses the /UserImages/ folder in the root of the web site as the files container
+			and a counter controlled by the upload.cnt file. Both must have write permissions
+			set to the IUSR_xxx user. Thanks to Trax and Juanjo. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=798128&amp;group_id=75348&amp;atid=543655">SF
+			Patch-798128</a>] The user (programmer) can now define a <strong>custom separator</strong>
+			for the list items of a combo in the toolbar. Thanks to Wulff D. Heiss. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=741963&amp;group_id=75348&amp;atid=543656">SF
+			Feature-741963</a>][<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=878941&amp;group_id=75348&amp;atid=543656">SF
+				Feature-878941</a>][<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=869389&amp;group_id=75348&amp;atid=543655">SF
+					Patch-869389</a>] A minimal support for a &ldquo;fake&rdquo; <strong>TAB is now available</strong>,
+			even if HTML has no support for TAB. Now when the user presses the TAB key a configurable
+			number of spaces (&amp;nbsp;) is added. Take a look at config.TabSpaces on the fck_config.js
+			file. No action is performed if it is set to zero. The default value is 4. Thanks
+			to Phil Hassey. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=782779&amp;group_id=75348&amp;atid=543653">SF
+			BUG-782779</a>][<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=790939&amp;group_id=75348&amp;atid=543653">SF
+				BUG-790939</a>] The problem with big images has been corrected. Thanks to Raver.
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=853374&amp;group_id=75348">SF
+			BUG-862975</a>] Now the editor does nothing if no image is selected in the image
+			dialog box and the OK button is hit. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=851609&amp;group_id=75348&amp;atid=543653">SF
+			BUG-851609</a>] The problem with ASP and null values has been solved. </li>
+		<li><strong>Norwegean</strong> language pack. Thanks to Martin Kronstad. </li>
+		<li><strong>Hungarian</strong> language pack. Thanks to Bal&aacute;zs Szab&oacute;.
+		</li>
+		<li><strong>Bosnian</strong> language pack. Thanks to Trax. </li>
+		<li><strong>Japanese</strong> language pack. Thanks to Kato Yuichiro. </li>
+		<li>Updates on the <strong>Polish</strong> language pack. Thanks to Norbert Neubauer.
+		</li>
+		<li>The <strong>Chinese (Taiwan)</strong> (zh-tw) has been removed from the package
+			because it's corrupt. I'm sorry. I hope someone could send me a good version soon.
+		</li>
+	</ul>
+	<h3>
+		Version 1.3.1</h3>
+	<ul>
+		<li>It's now possible to configure the editor the insert a <strong>&lt;BR&gt; tag instead
+			of &lt;P&gt;</strong> when the user presses the <strong>&lt;Enter&gt;</strong> key.
+			Take a look at the fck_config.js configuration file for the &quot;<strong>UseBROnCarriageReturn</strong>&quot;
+			key. This option is disabled by default. </li>
+		<li><strong>Icelandic</strong> language pack. Thanks to Andri &Oacute;skarsson. </li>
+		<li>[<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=853374&amp;group_id=75348">SF
+			BUG-853374</a>] On IE 5.0 there was a little error introduced with version 1.3 on
+			initialization. It was corrected. </li>
+		<li>[<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=853372&amp;group_id=75348">SF
+			BUG-853372</a>] On IE 5.0 there was a little error introduced with version 1.3 when
+			setting the focus in the editor. It was corrected. </li>
+		<li>Minor errors on the language file for <strong>english</strong> has been corrected.
+			Thanks to Anders Madsen. </li>
+		<li>Minor errors on the language file for <strong>danish</strong> has been corrected.
+			Thanks to Martin Johansen. </li>
+	</ul>
+	<h3>
+		Version 1.3</h3>
+	<ul>
+		<li>Language support for <strong>Danish, Polish, Simple Chinese, Slovak, Swedish and
+			Turkish</strong>. </li>
+		<li>Language updates for <strong>Romanian</strong>. </li>
+		<li>It's now possible to <strong>override</strong> any of the <strong>editor's configurations</strong>
+			(for now it's implemented just for JavaScript, ASPX and HTC modules). See _test/test.html
+			for a sample. I'm now waiting for the Community for the ASP, CFM and PHP versions.
+		</li>
+		<li>A new method is available for <strong>PHP</strong> users. It's called <strong>ReturnFCKeditor</strong>.
+			It works exactly like CreateFCKeditor, but it <strong>returns a string with the HTML</strong>
+			for the editor instead of output it (echo). This feature is useful for people who
+			are working with Smarty Templates or something like that. Thanks to Timothy J. Finucane.
+		</li>
+		<li>Many people have had problems with <strong>international characters</strong> over
+			<strong>PHP</strong>. I had also the same problem. PHP have strange problems with
+			character encoding. The code hasn't been changed but just saved again with Western
+			European encoding. <strong>Now it works well</strong> in my system.<br />
+			Take a look also at the &quot;default_charset&quot; configuration option at the
+			php.ini file. It doesn't seem to be an editor's problem but a PHP issue. </li>
+		<li>The &quot;<strong>testsubmit.php</strong>&quot; file now strips the &quot;<strong>Magic
+			Quotes</strong> &quot; that are automatically added by PHP on form posts. </li>
+		<li>A <strong>new language</strong> integration module is available for <strong>ASP/Jscript</strong>.
+			Thanks to Dimiter Naydenov. </li>
+		<li><strong>New configuration</strong> options are available to <strong>customize the
+			Target</strong> combo box in the <strong>Insert/Modify Link</strong> dialog box.
+			Now you can hide it, or set which options are available in the combo box. Take a
+			look at the fck_config.js file. </li>
+		<li>The <strong>Text as Plain Text</strong> toolbar <strong>icon</strong> has been changed
+			<strong>to avoid confusion</strong> with the Normal Paste or. Thanks to Kaupo Kalda.
+		</li>
+		<li>The file <strong>dhtmled.cab has been removed</strong> from the package. It's not
+			needed to the editor to work and caused some confusion for a few users. </li>
+		<li>The <strong>editor's content</strong> now <strong>doesn't loose the focus</strong>
+			when the user clicks with the mouse in a toolbar button. </li>
+		<li>On <strong>drag-and-drop</strong> operations the data to be inserted in the editor
+			is now <strong>converted to plain text</strong> when the &quot;<strong>ForcePasteAsPlainText</strong>&quot;
+			configuration is set to <strong>true</strong>. </li>
+		<li>The <strong>image browser</strong> sample in PHP now <strong>sorts the files</strong>
+			by name. Thanks to Sergey Lupashko. </li>
+		<li>Two <strong>new configuration</strong> options are available to <strong>turn on/off
+			by default</strong> the &quot;<strong>Show Borders</strong>&quot; and &quot;<strong>Show
+				Details</strong>&quot; commands. </li>
+		<li>Some <strong>characters have been removed</strong> from the &quot;<strong>Insert
+			Special Chars</strong>&quot; dialog box because they were causing encoding problems
+			in some languages. Thanks to Abomb Hua. </li>
+		<li><strong>JSP</strong> versions of the <strong>image and file upload and browsing</strong>
+			features. Thanks to Simone Chiaretta.</li>
+	</ul>
+	<h3>
+		Version 1.2.4</h3>
+	<ul>
+		<li>Language support for <strong>Spanish, Finnish, Romanian and Korean</strong>. </li>
+		<li>Language updates for <strong>German</strong>. </li>
+		<li>New <strong>Zoom</strong> toolbar option. (<a href="https://sourceforge.net/forum/forum.php?thread_id=904116&amp;forum_id=257180">Thanks
+			to &quot;mtn_roadie&quot;</a>)</li>
+	</ul>
+	<h3>
+		Version 1.2.2</h3>
+	<ul>
+		<li>Language support for <strong>French</strong>. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=782779&amp;group_id=75348&amp;atid=543653">SF
+			BUG-782779</a>] Version 1.2 introduced a bug on the image dialog window: when changing
+			the image, no update was done. This bug is now fixed. </li>
+	</ul>
+	<h3>
+		Version 1.2</h3>
+	<ul>
+		<li>Enhancements to the <strong>Word cleaning</strong> feature (Thanks to Karl von Randow).
+		</li>
+		<li>The <strong>Table dialog box</strong> now handles the Style width and height set
+			in the table (Thanks to Roberto Arruda). There where many problems on prior version
+			when people changed manually the table's size, dragging the size handles, and then
+			it was not possible to set a new size using the table dialog box. </li>
+		<li>For the <strong>Image dialog box:</strong>
+			<ul>
+				<li>No image is shown in the preview pane if no image has been set. </li>
+				<li>If no HSpace is set in the image a &quot;-1&quot; value was shown in the dialog
+					box. Now, nothing is shown if the value is negative. </li>
+			</ul>
+		</li>
+		<li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=739630&amp;group_id=75348&amp;atid=543653">SF
+			BUG-739630</a>] Image with link lost the link when changing its properties. The
+			problem is solved. </li>
+		<li>Due to some problems in the XHTML cleaning (content duplication when the source
+			HTML is dirty and malformed), the <strong>XHTML support is turned off by default</strong>
+			from this version. You can still change this behavior and turn it on in the configuration
+			file. </li>
+		<li>Some little updates on the <strong>English </strong>language file. </li>
+		<li>A few addition of missing entries on all languages files (translations for these
+			changes are pending). </li>
+		<li>Language files has been added for the following languages:
+			<ul>
+				<li><strong>Brazilian Portuguese</strong> (pt-br) </li>
+				<li><strong>Czech</strong> (cz) </li>
+				<li><strong>Dutch</strong> (nl) </li>
+				<li><strong>Russian</strong> (ru) </li>
+				<li><strong>Chinese (Taiwan)</strong> (zh-tw) </li>
+				<li><strong>Greek</strong> (gr) </li>
+				<li><strong>German</strong> (de)</li>
+			</ul>
+		</li>
+	</ul>
+	<h3>
+		Version 1.1</h3>
+	<ul>
+		<li>The &quot;<strong>Multi Language</strong>&quot; system is now available. This version
+			ships with English and Italian versions completed. Other languages will be available
+			soon. The editor automatically detects the client language and sets all labels,
+			tooltips and dialog boxes to it, if available. The auto detection and the default
+			language can be set in the <strong>fck_config.file</strong>. </li>
+		<li>Two files can now be created to isolate customizations code from the original source
+			code of the editor: <strong>fckeditor.config.js</strong> and <strong>fckeditor.custom.js</strong>.
+			Create these files in the root folder of your web site, if needed. The first one
+			can be used to add or override configurations set on fck_config.js. The second one
+			is used for custom actions and behaviors. </li>
+		<li>A problem with relative links and images like &quot;/test/test.doc&quot; has been
+			solved. In prior versions, only with XHTML support enabled, the URL was changed
+			to something like &quot;http://www.mysite.xxx/test/test.doc&quot; (The domain was
+			automatically added). Now the XHTML cleaning procedure gets the URLs exactly how
+			they are defined in the editor&rsquo;s HTML. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=742168&amp;group_id=75348&amp;atid=543653">SF
+			BUG-742168</a>] Mouse drag and drop from toolbar buttons has been disabled. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=768210&amp;group_id=75348&amp;atid=543653">SF
+			BUG-768210</a>] HTML entities, like <strong>&amp;lt;</strong>, were not load correctly.
+			The problem is solved. </li>
+		<li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=748812&amp;group_id=75348&amp;atid=543653">SF
+			BUG-748812</a>] The link dialog window doesn't open when the link button is grayed.
+		</li>
+	</ul>
+	<h3>
+		Version 1.0</h3>
+	<ul>
+		<li>Three new options are available in the configuration file to set what file types
+			are allowed / denied to be uploaded from the &quot;Insert Link&quot; and &quot;Insert
+			Image&quot; dialog boxes. </li>
+		<li>Upload options, for links and images, are automatically hidden on IE 5.0 browsers
+			(it's not compatible). </li>
+		<li>[SF BUG-734894] Fixed a problem on XHTML cleaning: the value on INPUT fields were
+			lost. </li>
+		<li>[SF BUG-713797] Fixed some image dialog errors when trying to set image properties
+			when no image is available. </li>
+		<li>[SF BUG-736414] Developed a workaround for a DHTML control bug when loading in the
+			editor some HTML started with &lt;p&gt;&lt;hr&gt;&lt;/p&gt;. </li>
+		<li>[SF BUG-737143] Paste from Word cleaning changed to solve some IE 5.0 errors. This
+			feature is still not available over IE 5.0. </li>
+		<li>[SF BUG-737233] CSS mappings are now OK on the PHP image browser module. </li>
+		<li>[SF BUG-737495] The image preview in the image dialog box is now working correctly.
+		</li>
+		<li>[SF BUG-737532] The editor automatically switches to WYSIWYG mode when the form
+			is posted. </li>
+		<li>[SF BUG-739571] The editor is now working well over Opera (as for Netscape, a TEXTAREA
+			is shown). </li>
+	</ul>
+	<h3>
+		Version 1.0 Final Candidate</h3>
+	<ul>
+		<li>A new dialog box for the &quot;Link&quot; command is available. Now you can upload
+			and browse the server exactly like the image dialog box. It's also possible to define
+			the link title and target window (_blank, _self, _parent and _top). As with the
+			image dialog box, a sample (and simple) file server browser is available. </li>
+		<li>A new configuration option is available to force every paste action to be handled
+			as plain text. See &quot;config.ForcePasteAsPlainText&quot; in fck_config.js. </li>
+		<li>A new Toolbar button is available: &quot;Paste from Word&quot;. It automatically
+			cleans the clipboard content before pasting (removesWord styles, classes, xml stuff,
+			etc...). This command is available for IE 5.5 and more. For IE 5.0 users, a message
+			is displayed advising that the text will not be cleaned before pasting. </li>
+		<li>The editor automatically detects Word clipboard data on pasting operations and asks
+			the user to clean it before pasting. This option is turned on by default but it
+			can be configured. See &quot;config.AutoDetectPasteFromWord&quot; in fck_config.js.
+		</li>
+		<li>Table properties are now available in cells' right click context menu. </li>
+		<li>It's now possible to edit cells advanced properties from it's right click context
+			menu. </li>
+	</ul>
+	<h3>
+		Version 1.0 Release Candidate 1 (RC1)</h3>
+	<ul>
+		<li>Some performance improvements. </li>
+		<li>The file dhtmled.cab has been added to the package for clients ho needs to install
+			the Microsoft DHTML Editor component. </li>
+		<li>[SF BUG-713952] The format command options are localized, so it depends on the IE
+			language to work. Until version 0.9.5 it was working only over English IE browsers.
+			Now the options are load dynamically on the client using the client's language.
+		</li>
+		<li>[SF BUG-712103] The style command is localized, so it depends on the IE language
+			to work. Until version 0.9.5 it was working only over English IE browsers. Now it
+			configures itself using the client's language. </li>
+		<li>[SF BUG-726137] On version 0.9.5, some commands (special chars, image, emoticons,
+			...) remove the next available character before inserting the required content even
+			if no selection was made in the editor. Now the editor replaces only the selected
+			content (if available). </li>
+	</ul>
+	<h3>
+		Version 0.9.5 beta</h3>
+	<ul>
+		<li>XHTML support is now available! It can be enabled/disabled in the fck_config.js
+			file. </li>
+		<li>&quot;Show Table Borders&quot; option: show borders for tables with borders size
+			set to zero. </li>
+		<li>&quot;Show Details&quot; option: show hidden elements (comments, scripts, paragraphs,
+			line breaks) </li>
+		<li>IE behavior integration module. Thanks to Daniel Shryock. </li>
+		<li>&quot;Find&quot; option: to find text in the document. </li>
+		<li>More performance enhancements. </li>
+		<li>New testsubmit.php file. Thansk to Jim Michaels. </li>
+		<li>Two initial PHP upload manager implementations (not working yet). Thanks to Frederic
+			Tyndiuk and Christian Liljedahl. </li>
+		<li>Initial PHP image browser implementation (not working yet). Thanks to Frederic Tyndiuk.
+		</li>
+		<li>Initial CFM upload manager implementation. Thanks to John Watson. </li>
+	</ul>
+	<h3>
+		Version 0.9.4 beta</h3>
+	<ul>
+		<li>ColdFusion module integration is now available! Thanks to John Watson. </li>
+		<li>&quot;Insert Smiley&quot; toolbar option! Thanks to Fredox. Take a look at fck_config.js
+			for configuration options. </li>
+		<li>&quot;Paste as plain text&quot; toolbar option! </li>
+		<li>Right click support for links (edit / remove). </li>
+		<li>Buttons now are shown in gray when disabled. </li>
+		<li>Buttons are shown just when the image is downloaded (no more &quot;red x&quot; while
+			waiting for it). </li>
+		<li>The toolbar background color can be set with a CSS style (see fck_editor.css). </li>
+		<li>Toolbar images have been reviewed:
+			<ul>
+				<li>Now they are transparent. </li>
+				<li>No more over...gif for every button (so the editor loads quicker). </li>
+				<li>Buttons states are controlled with CSS styles. (see fck_editor.css).</li>
+			</ul>
+		</li>
+		<li>Internet Explorer 5.0 compatibility, except for the image uploading popup. </li>
+		<li>Optimizations when loading the editor. </li>
+		<li>[SF BUG-709544] - Toolbar buttons wait for the images to be downloaded to start
+			watching and responding the user actions (turn buttons on/off when the user changes
+			position inside the editor). </li>
+		<li>JavaScript integration is now Object Oriented. CreateFCKeditor function is not available
+			anymore. Take a look in test.html. </li>
+		<li>Two new configuration options, ImageBrowser and ImageUpload, are available to turn
+			on and off the image upload and image browsing options in the Image dialog box.
+			This options can be hidden for a specific editor instance throw specific URL parameter
+			in the editor&rsquo;s IFRAME (upload=true/false&amp;browse=true/false). All specific
+			language integration modules handle this option. For sample see the _test directory.
+		</li>
+	</ul>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/fckconfig.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/fckconfig.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/fckconfig.js	(revision 795)
@@ -0,0 +1,240 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Editor configuration settings.
+ *
+ * Follow this link for more information:
+ * http://wiki.fckeditor.net/Developer%27s_Guide/Configuration/Configurations_Settings
+ */
+
+// Disable the custom Enter Key Handler. This option will be removed in version 2.5.
+FCKConfig.DisableEnterKeyHandler = false ;
+
+FCKConfig.CustomConfigurationsPath = '' ;
+
+FCKConfig.EditorAreaCSS = FCKConfig.BasePath + 'css/fck_editorarea.css' ;
+FCKConfig.ToolbarComboPreviewCSS = '' ;
+
+FCKConfig.DocType = '' ;
+
+FCKConfig.BaseHref = '' ;
+
+FCKConfig.FullPage = false ;
+
+FCKConfig.Debug = false ;
+FCKConfig.AllowQueryStringDebug = true ;
+
+FCKConfig.SkinPath = FCKConfig.BasePath + 'skins/default/' ;
+FCKConfig.PreloadImages = [ FCKConfig.SkinPath + 'images/toolbar.start.gif', FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif' ] ;
+
+FCKConfig.PluginsPath = FCKConfig.BasePath + 'plugins/' ;
+
+// FCKConfig.Plugins.Add( 'autogrow' ) ;
+FCKConfig.AutoGrowMax = 400 ;
+
+// FCKConfig.ProtectedSource.Add( /<%[\s\S]*?%>/g ) ;	// ASP style server side code <%...%>
+// FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ;	// PHP style server side code
+// FCKConfig.ProtectedSource.Add( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ) ;	// ASP.Net style tags <asp:control>
+
+FCKConfig.AutoDetectLanguage	= true ;
+FCKConfig.DefaultLanguage		= 'en' ;
+FCKConfig.ContentLangDirection	= 'ltr' ;
+
+FCKConfig.ProcessHTMLEntities	= true ;
+FCKConfig.IncludeLatinEntities	= true ;
+FCKConfig.IncludeGreekEntities	= true ;
+
+FCKConfig.ProcessNumericEntities = false ;
+
+FCKConfig.AdditionalNumericEntities = ''  ;		// Single Quote: "'"
+
+FCKConfig.FillEmptyBlocks	= true ;
+
+FCKConfig.FormatSource		= true ;
+FCKConfig.FormatOutput		= true ;
+FCKConfig.FormatIndentator	= '    ' ;
+
+FCKConfig.ForceStrongEm = true ;
+FCKConfig.GeckoUseSPAN	= false ;
+FCKConfig.StartupFocus	= false ;
+FCKConfig.ForcePasteAsPlainText	= false ;
+FCKConfig.AutoDetectPasteFromWord = true ;	// IE only.
+FCKConfig.ForceSimpleAmpersand	= false ;
+FCKConfig.TabSpaces		= 0 ;
+FCKConfig.ShowBorders	= true ;
+FCKConfig.SourcePopup	= false ;
+FCKConfig.ToolbarStartExpanded	= true ;
+FCKConfig.ToolbarCanCollapse	= true ;
+FCKConfig.IgnoreEmptyParagraphValue = true ;
+FCKConfig.PreserveSessionOnFileBrowser = false ;
+FCKConfig.FloatingPanelsZIndex = 10000 ;
+
+FCKConfig.TemplateReplaceAll = true ;
+FCKConfig.TemplateReplaceCheckbox = true ;
+
+FCKConfig.ToolbarLocation = 'In' ;
+
+FCKConfig.ToolbarSets["Default"] = [
+	['Source','DocProps','-','Save','NewPage','Preview','-','Templates'],
+	['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],
+	['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
+	['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField'],
+	'/',
+	['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
+	['OrderedList','UnorderedList','-','Outdent','Indent'],
+	['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
+	['Link','Unlink','Anchor'],
+	['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak'],
+	'/',
+	['Style','FontFormat','FontName','FontSize'],
+	['TextColor','BGColor'],
+	['FitWindow','-','About']
+] ;
+
+FCKConfig.ToolbarSets["TextFormatting"] = [
+	['DocProps','-','NewPage','Preview','-','Templates'],
+	['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],
+	['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
+	'/',
+	['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
+	['OrderedList','UnorderedList','-','Outdent','Indent'],
+	['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
+	['Link','Unlink','Anchor'],
+	['Image','Table','Rule','Smiley','SpecialChar','PageBreak'],
+	'/',
+	['Style','FontFormat','FontName','FontSize'],
+	['TextColor','BGColor'],
+	['FitWindow','-','About']
+] ;
+
+FCKConfig.ToolbarSets["Basic"] = [
+	['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','About']
+] ;
+
+FCKConfig.EnterMode = 'p' ;			// p | div | br
+FCKConfig.ShiftEnterMode = 'br' ;	// p | div | br
+
+FCKConfig.Keystrokes = [
+	[ CTRL + 65 /*A*/, true ],
+	[ CTRL + 67 /*C*/, true ],
+	[ CTRL + 70 /*F*/, true ],
+	[ CTRL + 83 /*S*/, true ],
+	[ CTRL + 88 /*X*/, true ],
+	[ CTRL + 86 /*V*/, 'Paste' ],
+	[ SHIFT + 45 /*INS*/, 'Paste' ],
+	[ CTRL + 90 /*Z*/, 'Undo' ],
+	[ CTRL + 89 /*Y*/, 'Redo' ],
+	[ CTRL + SHIFT + 90 /*Z*/, 'Redo' ],
+	[ CTRL + 76 /*L*/, 'Link' ],
+	[ CTRL + 66 /*B*/, 'Bold' ],
+	[ CTRL + 73 /*I*/, 'Italic' ],
+	[ CTRL + 85 /*U*/, 'Underline' ],
+	[ CTRL + SHIFT + 83 /*S*/, 'Save' ],
+	[ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ],
+	[ CTRL + 9 /*TAB*/, 'Source' ]
+] ;
+
+FCKConfig.ContextMenu = ['Generic','Link','Anchor','Image','Flash','Select','Textarea','Checkbox','Radio','TextField','HiddenField','ImageButton','Button','BulletedList','NumberedList','Table','Form'] ;
+
+FCKConfig.FontColors = '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,808080,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF' ;
+
+FCKConfig.FontNames		= 'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;
+FCKConfig.FontSizes		= '1/xx-small;2/x-small;3/small;4/medium;5/large;6/x-large;7/xx-large' ;
+FCKConfig.FontFormats	= 'p;div;pre;address;h1;h2;h3;h4;h5;h6' ;
+
+FCKConfig.StylesXmlPath		= FCKConfig.EditorPath + 'fckstyles.xml' ;
+FCKConfig.TemplatesXmlPath	= FCKConfig.EditorPath + 'fcktemplates.xml' ;
+
+FCKConfig.SpellChecker			= 'ieSpell' ;	// 'ieSpell' | 'SpellerPages'
+FCKConfig.IeSpellDownloadUrl	= 'http://www.iespell.com/download.php' ;
+FCKConfig.SpellerPagesServerScript = 'server-scripts/spellchecker.php' ;	// Available extension: .php .cfm .pl
+
+FCKConfig.MaxUndoLevels = 15 ;
+
+FCKConfig.DisableObjectResizing = false ;
+FCKConfig.DisableFFTableHandles = true ;
+
+FCKConfig.LinkDlgHideTarget		= false ;
+FCKConfig.LinkDlgHideAdvanced	= false ;
+
+FCKConfig.ImageDlgHideLink		= false ;
+FCKConfig.ImageDlgHideAdvanced	= false ;
+
+FCKConfig.FlashDlgHideAdvanced	= false ;
+
+FCKConfig.ProtectedTags = '' ;
+
+// This will be applied to the body element of the editor
+FCKConfig.BodyId = '' ;
+FCKConfig.BodyClass = '' ;
+
+// The option switches between trying to keep the html structure or do the changes so the content looks like it was in Word
+FCKConfig.CleanWordKeepsStructure = false ;
+
+// The following value defines which File Browser connector and Quick Upload
+// "uploader" to use. It is valid for the default implementaion and it is here
+// just to make this configuration file cleaner.
+// It is not possible to change this value using an external file or even
+// inline when creating the editor instance. In that cases you must set the
+// values of LinkBrowserURL, ImageBrowserURL and so on.
+// Custom implementations should just ignore it.
+var _FileBrowserLanguage	= 'asp' ;	// asp | aspx | cfm | lasso | perl | php | py
+var _QuickUploadLanguage	= 'asp' ;	// asp | aspx | cfm | lasso | php
+
+
+// Don't care about the following line. It just calculates the correct connector
+// extension to use for the default File Browser (Perl uses "cgi").
+var _FileBrowserExtension = _FileBrowserLanguage == 'perl' ? 'cgi' : _FileBrowserLanguage ;
+
+FCKConfig.LinkBrowser = true ;
+FCKConfig.LinkBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.LinkBrowserWindowWidth	= FCKConfig.ScreenWidth * 0.7 ;		// 70%
+FCKConfig.LinkBrowserWindowHeight	= FCKConfig.ScreenHeight * 0.7 ;	// 70%
+
+FCKConfig.ImageBrowser = true ;
+FCKConfig.ImageBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Image&Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.ImageBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;	// 70% ;
+FCKConfig.ImageBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;	// 70% ;
+
+FCKConfig.FlashBrowser = true ;
+FCKConfig.FlashBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.FlashBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;	//70% ;
+FCKConfig.FlashBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;	//70% ;
+
+FCKConfig.LinkUpload = true ;
+FCKConfig.LinkUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage ;
+FCKConfig.LinkUploadAllowedExtensions	= "" ;			// empty for all
+FCKConfig.LinkUploadDeniedExtensions	= ".(html|htm|php|php2|php3|php4|php5|phtml|pwml|inc|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|com|dll|vbs|js|reg|cgi|htaccess|asis)$" ;	// empty for no one
+
+FCKConfig.ImageUpload = true ;
+FCKConfig.ImageUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage + '?Type=Image' ;
+FCKConfig.ImageUploadAllowedExtensions	= ".(jpg|gif|jpeg|png|bmp)$" ;		// empty for all
+FCKConfig.ImageUploadDeniedExtensions	= "" ;							// empty for no one
+
+FCKConfig.FlashUpload = true ;
+FCKConfig.FlashUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage + '?Type=Flash' ;
+FCKConfig.FlashUploadAllowedExtensions	= ".(swf|fla)$" ;		// empty for all
+FCKConfig.FlashUploadDeniedExtensions	= "" ;					// empty for no one
+
+FCKConfig.SmileyPath	= FCKConfig.BasePath + 'images/smiley/msn/' ;
+FCKConfig.SmileyImages	= ['regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif','embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif','devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif','broken_heart.gif','kiss.gif','envelope.gif'] ;
+FCKConfig.SmileyColumns = 8 ;
+FCKConfig.SmileyWindowWidth		= 320 ;
+FCKConfig.SmileyWindowHeight	= 240 ;
Index: /sandbox/workflow/branches/993/js/fckeditor/fckeditor.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/fckeditor.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/fckeditor.js	(revision 795)
@@ -0,0 +1,214 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the integration file for JavaScript.
+ *
+ * It defines the FCKeditor class that can be used to create editor
+ * instances in a HTML page in the client side. For server side
+ * operations, use the specific integration system.
+ */
+
+// FCKeditor Class
+var FCKeditor = function( instanceName, width, height, toolbarSet, value )
+{
+	// Properties
+	this.InstanceName	= instanceName ;
+	this.Width			= width			|| '100%' ;
+	this.Height			= height		|| '200' ;
+	this.ToolbarSet		= toolbarSet	|| 'Default' ;
+	this.Value			= value			|| '' ;
+	this.BasePath		= '/fckeditor/' ;
+	this.CheckBrowser	= true ;
+	this.DisplayErrors	= true ;
+	this.EnableSafari	= false ;		// This is a temporary property, while Safari support is under development.
+	this.EnableOpera	= false ;		// This is a temporary property, while Opera support is under development.
+
+	this.Config			= new Object() ;
+
+	// Events
+	this.OnError		= null ;	// function( source, errorNumber, errorDescription )
+}
+
+FCKeditor.prototype.Version			= '2.4.2' ;
+FCKeditor.prototype.VersionBuild	= '14978' ;
+
+FCKeditor.prototype.Create = function()
+{
+	document.write( this.CreateHtml() ) ;
+}
+
+FCKeditor.prototype.CreateHtml = function()
+{
+	// Check for errors
+	if ( !this.InstanceName || this.InstanceName.length == 0 )
+	{
+		this._ThrowError( 701, 'You must specify an instance name.' ) ;
+		return '' ;
+	}
+
+	var sHtml = '<div>' ;
+
+	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
+	{
+		sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" />' ;
+		sHtml += this._GetConfigHtml() ;
+		sHtml += this._GetIFrameHtml() ;
+	}
+	else
+	{
+		var sWidth  = this.Width.toString().indexOf('%')  > 0 ? this.Width  : this.Width  + 'px' ;
+		var sHeight = this.Height.toString().indexOf('%') > 0 ? this.Height : this.Height + 'px' ;
+		sHtml += '<textarea name="' + this.InstanceName + '" rows="4" cols="40" style="width:' + sWidth + ';height:' + sHeight + '">' + this._HTMLEncode( this.Value ) + '<\/textarea>' ;
+	}
+
+	sHtml += '</div>' ;
+
+	return sHtml ;
+}
+
+FCKeditor.prototype.ReplaceTextarea = function()
+{
+	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
+	{
+		// We must check the elements firstly using the Id and then the name.
+		var oTextarea = document.getElementById( this.InstanceName ) ;
+		var colElementsByName = document.getElementsByName( this.InstanceName ) ;
+		var i = 0;
+		while ( oTextarea || i == 0 )
+		{
+			if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
+				break ;
+			oTextarea = colElementsByName[i++] ;
+		}
+
+		if ( !oTextarea )
+		{
+			alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
+			return ;
+		}
+
+		oTextarea.style.display = 'none' ;
+		this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
+		this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
+	}
+}
+
+FCKeditor.prototype._InsertHtmlBefore = function( html, element )
+{
+	if ( element.insertAdjacentHTML )	// IE
+		element.insertAdjacentHTML( 'beforeBegin', html ) ;
+	else								// Gecko
+	{
+		var oRange = document.createRange() ;
+		oRange.setStartBefore( element ) ;
+		var oFragment = oRange.createContextualFragment( html );
+		element.parentNode.insertBefore( oFragment, element ) ;
+	}
+}
+
+FCKeditor.prototype._GetConfigHtml = function()
+{
+	var sConfig = '' ;
+	for ( var o in this.Config )
+	{
+		if ( sConfig.length > 0 ) sConfig += '&amp;' ;
+		sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
+	}
+
+	return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" />' ;
+}
+
+FCKeditor.prototype._GetIFrameHtml = function()
+{
+	var sFile = 'fckeditor.html' ;
+
+	try
+	{
+		if ( (/fcksource=true/i).test( window.top.location.search ) )
+			sFile = 'fckeditor.original.html' ;
+	}
+	catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }
+
+	var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
+	if (this.ToolbarSet) sLink += '&amp;Toolbar=' + this.ToolbarSet ;
+
+	return '<iframe id="' + this.InstanceName + '___Frame" src="' + sLink + '" width="' + this.Width + '" height="' + this.Height + '" frameborder="0" scrolling="no"></iframe>' ;
+}
+
+FCKeditor.prototype._IsCompatibleBrowser = function()
+{
+	return FCKeditor_IsCompatibleBrowser( this.EnableSafari, this.EnableOpera ) ;
+}
+
+FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
+{
+	this.ErrorNumber		= errorNumber ;
+	this.ErrorDescription	= errorDescription ;
+
+	if ( this.DisplayErrors )
+	{
+		document.write( '<div style="COLOR: #ff0000">' ) ;
+		document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
+		document.write( '</div>' ) ;
+	}
+
+	if ( typeof( this.OnError ) == 'function' )
+		this.OnError( this, errorNumber, errorDescription ) ;
+}
+
+FCKeditor.prototype._HTMLEncode = function( text )
+{
+	if ( typeof( text ) != "string" )
+		text = text.toString() ;
+
+	text = text.replace(
+		/&/g, "&amp;").replace(
+		/"/g, "&quot;").replace(
+		/</g, "&lt;").replace(
+		/>/g, "&gt;") ;
+
+	return text ;
+}
+
+function FCKeditor_IsCompatibleBrowser( enableSafari, enableOpera )
+{
+	var sAgent = navigator.userAgent.toLowerCase() ;
+
+	// Internet Explorer
+	if ( sAgent.indexOf("msie") != -1 && sAgent.indexOf("mac") == -1 && sAgent.indexOf("opera") == -1 )
+	{
+		var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
+		return ( sBrowserVersion >= 5.5 ) ;
+	}
+
+	// Gecko (Opera 9 tries to behave like Gecko at this point).
+	if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
+		return true ;
+
+	// Opera
+	if ( enableOpera && navigator.appName == 'Opera' && parseInt( navigator.appVersion, 10 ) >= 9 )
+			return true ;
+
+	// Safari
+	if ( enableSafari && sAgent.indexOf( 'safari' ) != -1 )
+		return ( sAgent.match( /safari\/(\d+)/ )[1] >= 312 ) ;	// Build must be at least 312 (1.3)
+
+	return false ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckeditorapi.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckeditorapi.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckeditorapi.js	(revision 795)
@@ -0,0 +1,161 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Create the FCKeditorAPI object that is available as a global object in
+ * the page where the editor is placed in.
+ */
+
+var FCKeditorAPI ;
+
+function InitializeAPI()
+{
+	var oParentWindow = window.parent ;
+
+	if ( !( FCKeditorAPI = oParentWindow.FCKeditorAPI ) )
+	{
+		// Make the FCKeditorAPI object available in the parent window. Use
+		// eval so this core runs in the parent's scope and so it will still be
+		// available if the editor instance is removed ("Can't execute code
+		// from a freed script" error).
+
+		// Note: we check the existence of oEditor.GetParentForm because some external 
+		// code (like JSON) can extend the Object protype and we get then extra oEditor 
+		// objects that aren't really FCKeditor instances.
+		var sScript =
+			'var FCKeditorAPI = {' +
+				'Version : "2.4.2",' +
+				'VersionBuild : "14978",' +
+				'__Instances : new Object(),' +
+
+				'GetInstance : function( name )' +
+				'{' +
+					'return this.__Instances[ name ];' +
+				'},' +
+
+				'_FormSubmit : function()' +
+				'{' +
+					'for ( var name in FCKeditorAPI.__Instances )' +
+					'{' +
+						'var oEditor = FCKeditorAPI.__Instances[ name ] ;' +
+						'if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )' +
+							'oEditor.UpdateLinkedField() ;' +
+					'}' +
+					'this._FCKOriginalSubmit() ;' +
+				'},' +
+
+				'_FunctionQueue	: {' +
+					'Functions : new Array(),' +
+					'IsRunning : false,' +
+
+					'Add : function( f )' +
+					'{' +
+						'this.Functions.push( f );' +
+						'if ( !this.IsRunning )' +
+							'this.StartNext();' +
+					'},' +
+
+					'StartNext : function()' +
+					'{' +
+						'var aQueue = this.Functions ;' +
+						'if ( aQueue.length > 0 )' +
+						'{' +
+							'this.IsRunning = true;' +
+							'aQueue[0].call();' +
+						'}' +
+						'else ' +
+							'this.IsRunning = false;' +
+					'},' +
+
+					'Remove : function( f )' +
+					'{' +
+						'var aQueue = this.Functions;' +
+						'var i = 0, fFunc;' +
+						'while( (fFunc = aQueue[ i ]) )' +
+						'{' +
+							'if ( fFunc == f )' +
+								'aQueue.splice( i,1 );' +
+							'i++ ;' +
+						'}' +
+						'this.StartNext();' +
+					'}' +
+				'}' +
+			'}' ;
+
+		// In IE, the "eval" function is not always available (it works with
+		// the JavaScript samples, but not with the ASP ones, for example).
+		// So, let's use the execScript instead.
+		if ( oParentWindow.execScript )
+			oParentWindow.execScript( sScript, 'JavaScript' ) ;
+		else
+		{
+			if ( FCKBrowserInfo.IsGecko10 )
+			{
+				// FF 1.0.4 gives an error with the request bellow. The
+				// following seams to work well.
+				eval.call( oParentWindow, sScript ) ;
+			}
+			else if ( FCKBrowserInfo.IsSafari )
+			{
+				// oParentWindow.eval in Safari executes in the calling window
+				// environment, instead of the parent one. The following should make it work.
+				var oParentDocument = oParentWindow.document ;
+				var eScript = oParentDocument.createElement('script') ;
+				eScript.appendChild( oParentDocument.createTextNode( sScript ) ) ;
+				oParentDocument.documentElement.appendChild( eScript ) ;
+			}
+			else
+				oParentWindow.eval( sScript ) ;
+		}
+
+		FCKeditorAPI = oParentWindow.FCKeditorAPI ;
+	}
+
+	// Add the current instance to the FCKeditorAPI's instances collection.
+	FCKeditorAPI.__Instances[ FCK.Name ] = FCK ;
+}
+
+// Attach to the form onsubmit event and to the form.submit().
+function _AttachFormSubmitToAPI()
+{
+	// Get the linked field form.
+	var oForm = FCK.GetParentForm() ;
+
+	if ( oForm )
+	{
+		// Attach to the onsubmit event.
+		FCKTools.AddEventListener( oForm, 'submit', FCK.UpdateLinkedField ) ;
+
+		// IE sees oForm.submit function as an 'object'.
+		if ( !oForm._FCKOriginalSubmit && ( typeof( oForm.submit ) == 'function' || ( !oForm.submit.tagName && !oForm.submit.length ) ) )
+		{
+			// Save the original submit.
+			oForm._FCKOriginalSubmit = oForm.submit ;
+
+			// Create our replacement for the submit.
+			oForm.submit = FCKeditorAPI._FormSubmit ;
+		}
+	}
+}
+
+function FCKeditorAPI_Cleanup()
+{
+	delete FCKeditorAPI.__Instances[ FCK.Name ] ;
+}
+FCKTools.AddEventListener( window, 'unload', FCKeditorAPI_Cleanup ) ;	
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckplugins.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckplugins.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckplugins.js	(revision 795)
@@ -0,0 +1,46 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKPlugins object that is responsible for loading the Plugins.
+ */
+
+var FCKPlugins = FCK.Plugins = new Object() ;
+FCKPlugins.ItemsCount = 0 ;
+FCKPlugins.Items = new Object() ;
+
+FCKPlugins.Load = function()
+{
+	var oItems = FCKPlugins.Items ;
+
+	// build the plugins collection.
+	for ( var i = 0 ; i < FCKConfig.Plugins.Items.length ; i++ )
+	{
+		var oItem = FCKConfig.Plugins.Items[i] ;
+		var oPlugin = oItems[ oItem[0] ] = new FCKPlugin( oItem[0], oItem[1], oItem[2] ) ;
+		FCKPlugins.ItemsCount++ ;
+	}
+
+	// Load all items in the plugins collection.
+	for ( var s in oItems )
+		oItems[s].Load() ;
+
+	// This is a self destroyable function (must be called once).
+	FCKPlugins.Load = null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection.js	(revision 795)
@@ -0,0 +1,24 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Active selection functions.
+ */
+
+var FCKSelection = FCK.Selection = new Object() ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdebug.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdebug.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdebug.js	(revision 795)
@@ -0,0 +1,56 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Debug window control and operations.
+ */
+
+var FCKDebug = new Object() ;
+
+FCKDebug._GetWindow = function()
+{
+	if ( !this.DebugWindow || this.DebugWindow.closed )
+		this.DebugWindow = window.open( FCKConfig.BasePath + 'fckdebug.html', 'FCKeditorDebug', 'menubar=no,scrollbars=yes,resizable=yes,location=no,toolbar=no,width=600,height=500', true ) ;
+
+	return this.DebugWindow ;
+}
+
+FCKDebug.Output = function( message, color, noParse )
+{
+	if ( ! FCKConfig.Debug )
+		return ;
+
+	try
+	{
+		this._GetWindow().Output( message, color ) ;
+	}
+	catch ( e ) {}	 // Ignore errors
+}
+
+FCKDebug.OutputObject = function( anyObject, color )
+{
+	if ( ! FCKConfig.Debug )
+		return ;
+
+	try
+	{
+		this._GetWindow().OutputObject( anyObject, color ) ;
+	}
+	catch ( e ) {}	 // Ignore errors
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_ie.js	(revision 795)
@@ -0,0 +1,383 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Creation and initialization of the "FCK" object. This is the main
+ * object that represents an editor instance.
+ * (IE specific implementations)
+ */
+
+FCK.Description = "FCKeditor for Internet Explorer 5.5+" ;
+
+FCK._GetBehaviorsStyle = function()
+{
+	if ( !FCK._BehaviorsStyle )
+	{
+		var sBasePath = FCKConfig.FullBasePath ;
+		var sTableBehavior = '' ;
+		var sStyle ;
+
+		// The behaviors should be pointed using the FullBasePath to avoid security
+		// errors when using a differente BaseHref.
+		sStyle = '<style type="text/css" _fcktemp="true">' ;
+
+		if ( FCKConfig.ShowBorders )
+			sTableBehavior = 'url(' + sBasePath + 'css/behaviors/showtableborders.htc)' ;
+
+		// Disable resize handlers.
+		sStyle += 'INPUT,TEXTAREA,SELECT,.FCK__Anchor,.FCK__PageBreak,.FCK__InputHidden' ;
+
+		if ( FCKConfig.DisableObjectResizing )
+		{
+			sStyle += ',IMG' ;
+			sTableBehavior += ' url(' + sBasePath + 'css/behaviors/disablehandles.htc)' ;
+		}
+
+		sStyle += ' { behavior: url(' + sBasePath + 'css/behaviors/disablehandles.htc) ; }' ;
+
+		if ( sTableBehavior.length > 0 )
+			sStyle += 'TABLE { behavior: ' + sTableBehavior + ' ; }' ;
+
+		sStyle += '</style>' ;
+		FCK._BehaviorsStyle = sStyle ;
+	}
+
+	return FCK._BehaviorsStyle ;
+}
+
+function Doc_OnMouseUp()
+{
+	if ( FCK.EditorWindow.event.srcElement.tagName == 'HTML' )
+	{
+		FCK.Focus() ;
+		FCK.EditorWindow.event.cancelBubble	= true ;
+		FCK.EditorWindow.event.returnValue	= false ;
+	}
+}
+
+function Doc_OnPaste()
+{
+	return ( FCK.Status == FCK_STATUS_COMPLETE && FCK.Events.FireEvent( "OnPaste" ) ) ;
+}
+
+function Doc_OnKeyDown()
+{
+	if ( FCK.EditorWindow )
+	{
+		var e = FCK.EditorWindow.event ;
+
+		if ( !( e.keyCode >=16 && e.keyCode <= 18 ) )
+			Doc_OnKeyDownUndo() ;
+	}
+	return true ;
+}
+
+function Doc_OnKeyDownUndo()
+{
+	if ( !FCKUndo.Typing )
+	{
+		FCKUndo.SaveUndoStep() ;
+		FCKUndo.Typing = true ;
+		FCK.Events.FireEvent( "OnSelectionChange" ) ;
+	}
+
+	FCKUndo.TypesCount++ ;
+
+	if ( FCKUndo.TypesCount > FCKUndo.MaxTypes )
+	{
+		FCKUndo.TypesCount = 0 ;
+		FCKUndo.SaveUndoStep() ;
+	}
+}
+
+function Doc_OnDblClick()
+{
+	FCK.OnDoubleClick( FCK.EditorWindow.event.srcElement ) ;
+	FCK.EditorWindow.event.cancelBubble = true ;
+}
+
+function Doc_OnSelectionChange()
+{
+	FCK.Events.FireEvent( "OnSelectionChange" ) ;
+}
+
+FCK.InitializeBehaviors = function( dontReturn )
+{
+	// Set the focus to the editable area when clicking in the document area.
+	// TODO: The cursor must be positioned at the end.
+	this.EditorDocument.attachEvent( 'onmouseup', Doc_OnMouseUp ) ;
+
+	// Intercept pasting operations
+	this.EditorDocument.body.attachEvent( 'onpaste', Doc_OnPaste ) ;
+
+	// Reset the context menu.
+	FCK.ContextMenu._InnerContextMenu.AttachToElement( FCK.EditorDocument.body ) ;
+
+	// Build the "TAB" key replacement (if necessary).
+	if ( FCKConfig.TabSpaces > 0 )
+	{
+		window.FCKTabHTML = '' ;
+		for ( i = 0 ; i < FCKConfig.TabSpaces ; i++ )
+			window.FCKTabHTML += "&nbsp;" ;
+	}
+	this.EditorDocument.attachEvent("onkeydown", Doc_OnKeyDown ) ;
+
+	this.EditorDocument.attachEvent("ondblclick", Doc_OnDblClick ) ;
+
+	// Catch cursor selection changes.
+	this.EditorDocument.attachEvent("onselectionchange", Doc_OnSelectionChange ) ;
+}
+
+FCK.InsertHtml = function( html )
+{
+	html = FCKConfig.ProtectedSource.Protect( html ) ;
+	html = FCK.ProtectEvents( html ) ;
+	html = FCK.ProtectUrls( html ) ;
+	html = FCK.ProtectTags( html ) ;
+
+//	FCK.Focus() ;
+	FCK.EditorWindow.focus() ;
+
+	FCKUndo.SaveUndoStep() ;
+
+	// Gets the actual selection.
+	var oSel = FCK.EditorDocument.selection ;
+
+	// Deletes the actual selection contents.
+	if ( oSel.type.toLowerCase() == 'control' )
+		oSel.clear() ;
+
+	// Insert the HTML.
+	oSel.createRange().pasteHTML( html ) ;
+
+	FCKDocumentProcessor.Process( FCK.EditorDocument ) ;
+}
+
+FCK.SetInnerHtml = function( html )		// IE Only
+{
+	var oDoc = FCK.EditorDocument ;
+	// Using the following trick, any comment in the begining of the HTML will
+	// be preserved.
+	oDoc.body.innerHTML = '<div id="__fakeFCKRemove__">&nbsp;</div>' + html ;
+	oDoc.getElementById('__fakeFCKRemove__').removeNode( true ) ;
+}
+
+function FCK_PreloadImages()
+{
+	var oPreloader = new FCKImagePreloader() ;
+
+	// Add the configured images.
+	oPreloader.AddImages( FCKConfig.PreloadImages ) ;
+
+	// Add the skin icons strip.
+	oPreloader.AddImages( FCKConfig.SkinPath + 'fck_strip.gif' ) ;
+
+	oPreloader.OnComplete = LoadToolbarSetup ;
+	oPreloader.Start() ;
+}
+
+// Disable the context menu in the editor (outside the editing area).
+function Document_OnContextMenu()
+{
+	return ( event.srcElement._FCKShowContextMenu == true ) ;
+}
+document.oncontextmenu = Document_OnContextMenu ;
+
+function FCK_Cleanup()
+{
+	this.EditorWindow = null ;
+	this.EditorDocument = null ;
+}
+
+FCK.Paste = function()
+{
+	// As we call ExecuteNamedCommand('Paste'), it would enter in a loop. So, let's use a semaphore.
+	if ( FCK._PasteIsRunning )
+		return true ;
+
+	if ( FCKConfig.ForcePasteAsPlainText )
+	{
+		FCK.PasteAsPlainText() ;
+		return false ;
+	}
+	
+	var sHTML = FCK._CheckIsPastingEnabled( true ) ;
+
+	if ( sHTML === false )
+		FCKTools.RunFunction( FCKDialog.OpenDialog, FCKDialog, ['FCKDialog_Paste', FCKLang.Paste, 'dialog/fck_paste.html', 400, 330, 'Security'] ) ;
+	else
+	{
+		if ( FCKConfig.AutoDetectPasteFromWord && sHTML.length > 0 )
+		{
+			var re = /<\w[^>]*(( class="?MsoNormal"?)|(="mso-))/gi ;
+			if ( re.test( sHTML ) )
+			{
+				if ( confirm( FCKLang.PasteWordConfirm ) )
+				{
+					FCK.PasteFromWord() ;
+					return false ;
+				}
+			}
+		}
+
+		// Instead of inserting the retrieved HTML, let's leave the OS work for us,
+		// by calling FCK.ExecuteNamedCommand( 'Paste' ). It could give better results.
+
+		// Enable the semaphore to avoid a loop.
+		FCK._PasteIsRunning = true ;
+
+		FCK.ExecuteNamedCommand( 'Paste' ) ;
+
+		// Removes the semaphore.
+		delete FCK._PasteIsRunning ;
+	}
+
+	// Let's always make a custom implementation (return false), otherwise
+	// the new Keyboard Handler may conflict with this code, and the CTRL+V code
+	// could result in a simple "V" being pasted.
+	return false ;
+}
+
+FCK.PasteAsPlainText = function()
+{
+	if ( !FCK._CheckIsPastingEnabled() )
+	{
+		FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteAsText, 'dialog/fck_paste.html', 400, 330, 'PlainText' ) ;
+		return ;
+	}
+	
+	// Get the data available in the clipboard in text format.
+	var sText = clipboardData.getData("Text") ;
+
+	if ( sText && sText.length > 0 )
+	{
+		// Replace the carriage returns with <BR>
+		sText = FCKTools.HTMLEncode( sText ).replace( /\n/g, '<BR>' ) ;
+
+		// Insert the resulting data in the editor.
+		this.InsertHtml( sText ) ;
+	}
+}
+
+FCK._CheckIsPastingEnabled = function( returnContents )
+{
+	// The following seams to be the only reliable way to check is script
+	// pasting operations are enabled in the secutiry settings of IE6 and IE7.
+	// It adds a little bit of overhead to the check, but so far that's the
+	// only way, mainly because of IE7.
+	
+	FCK._PasteIsEnabled = false ;
+	
+	document.body.attachEvent( 'onpaste', FCK_CheckPasting_Listener ) ;
+	
+	// The execCommand in GetClipboardHTML will fire the "onpaste", only if the
+	// security settings are enabled.
+	var oReturn = FCK.GetClipboardHTML() ;
+
+	document.body.detachEvent( 'onpaste', FCK_CheckPasting_Listener ) ;
+	
+	if ( FCK._PasteIsEnabled )
+	{
+		if ( !returnContents )
+			oReturn = true ;
+	}
+	else
+		oReturn = false ;
+
+	delete FCK._PasteIsEnabled ;
+
+	return oReturn ;
+}
+
+function FCK_CheckPasting_Listener()
+{
+	FCK._PasteIsEnabled = true ;
+}
+
+FCK.InsertElement = function( element )
+{
+	FCK.InsertHtml( element.outerHTML ) ;
+}
+
+FCK.GetClipboardHTML = function()
+{
+	var oDiv = document.getElementById( '___FCKHiddenDiv' ) ;
+
+	if ( !oDiv )
+	{
+		oDiv = document.createElement( 'DIV' ) ;
+		oDiv.id = '___FCKHiddenDiv' ;
+
+		var oDivStyle = oDiv.style ;
+		oDivStyle.position		= 'absolute' ;
+		oDivStyle.visibility	= oDivStyle.overflow	= 'hidden' ;
+		oDivStyle.width			= oDivStyle.height		= 1 ;
+
+		document.body.appendChild( oDiv ) ;
+	}
+
+	oDiv.innerHTML = '' ;
+
+	var oTextRange = document.body.createTextRange() ;
+	oTextRange.moveToElementText( oDiv ) ;
+	oTextRange.execCommand( 'Paste' ) ;
+
+	var sData = oDiv.innerHTML ;
+	oDiv.innerHTML = '' ;
+
+	return sData ;
+}
+
+FCK.AttachToOnSelectionChange = function( functionPointer )
+{
+	this.Events.AttachEvent( 'OnSelectionChange', functionPointer ) ;
+}
+
+FCK.CreateLink = function( url )
+{
+	// Remove any existing link in the selection.
+	FCK.ExecuteNamedCommand( 'Unlink' ) ;
+
+	if ( url.length > 0 )
+	{
+		// Generate a temporary name for the link.
+		var sTempUrl = 'javascript:void(0);/*' + ( new Date().getTime() ) + '*/' ;
+
+		// Use the internal "CreateLink" command to create the link.
+		FCK.ExecuteNamedCommand( 'CreateLink', sTempUrl ) ;
+
+		// Look for the just create link.
+		var oLinks = this.EditorDocument.links ;
+
+		for ( i = 0 ; i < oLinks.length ; i++ )
+		{
+			var oLink = oLinks[i] ;
+
+			if ( oLink.href == sTempUrl )
+			{
+				var sInnerHtml = oLink.innerHTML ;	// Save the innerHTML (IE changes it if it is like an URL).
+				oLink.href = url ;
+				oLink.innerHTML = sInnerHtml ;		// Restore the innerHTML.
+				return oLink ;
+			}
+		}
+	}
+
+	return null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml.js	(revision 795)
@@ -0,0 +1,466 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKXHtml object, responsible for the XHTML operations.
+ */
+
+var FCKXHtml = new Object() ;
+
+FCKXHtml.CurrentJobNum = 0 ;
+
+FCKXHtml.GetXHTML = function( node, includeNode, format )
+{
+	FCKXHtmlEntities.Initialize() ;
+	
+	// Set the correct entity to use for empty blocks.
+	this._NbspEntity = ( FCKConfig.ProcessHTMLEntities? 'nbsp' : '#160' ) ;
+
+	// Save the current IsDirty state. The XHTML processor may change the
+	// original HTML, dirtying it.
+	var bIsDirty = FCK.IsDirty() ;
+
+	this._CreateNode = FCKConfig.ForceStrongEm ? FCKXHtml_CreateNode_StrongEm : FCKXHtml_CreateNode_Normal ;
+
+	// Special blocks are blocks of content that remain untouched during the
+	// process. It is used for SCRIPTs and STYLEs.
+	FCKXHtml.SpecialBlocks = new Array() ;
+
+	// Create the XML DOMDocument object.
+	this.XML = FCKTools.CreateXmlObject( 'DOMDocument' ) ;
+
+	// Add a root element that holds all child nodes.
+	this.MainNode = this.XML.appendChild( this.XML.createElement( 'xhtml' ) ) ;
+
+	FCKXHtml.CurrentJobNum++ ;
+
+	if ( includeNode )
+		this._AppendNode( this.MainNode, node ) ;
+	else
+		this._AppendChildNodes( this.MainNode, node, false ) ;
+
+	// Get the resulting XHTML as a string.
+	var sXHTML = this._GetMainXmlString() ;
+
+	this.XML = null ;
+
+	// Strip the "XHTML" root node.
+	sXHTML = sXHTML.substr( 7, sXHTML.length - 15 ).Trim() ;
+
+	// Remove the trailing <br> added by Gecko.
+	// REMOVE: Maybe the following is not anymore necessary because a similar
+	// check is made on _AppendNode
+	if ( FCKBrowserInfo.IsGecko )
+		sXHTML = sXHTML.replace( /<br\/>$/, '' ) ;
+
+	// Add a space in the tags with no closing tags, like <br/> -> <br />
+	sXHTML = sXHTML.replace( FCKRegexLib.SpaceNoClose, ' />');
+
+	if ( FCKConfig.ForceSimpleAmpersand )
+		sXHTML = sXHTML.replace( FCKRegexLib.ForceSimpleAmpersand, '&' ) ;
+
+	if ( format )
+		sXHTML = FCKCodeFormatter.Format( sXHTML ) ;
+
+	// Now we put back the SpecialBlocks contents.
+	for ( var i = 0 ; i < FCKXHtml.SpecialBlocks.length ; i++ )
+	{
+		var oRegex = new RegExp( '___FCKsi___' + i ) ;
+		sXHTML = sXHTML.replace( oRegex, FCKXHtml.SpecialBlocks[i] ) ;
+	}
+
+	// Replace entities marker with the ampersand.
+	sXHTML = sXHTML.replace( FCKRegexLib.GeckoEntitiesMarker, '&' ) ;
+
+	// Restore the IsDirty state if it was not dirty.
+	if ( !bIsDirty )
+		FCK.ResetIsDirty() ;
+
+	return sXHTML ;
+}
+
+FCKXHtml._AppendAttribute = function( xmlNode, attributeName, attributeValue )
+{
+	try
+	{
+		if ( attributeValue == undefined || attributeValue == null )
+			attributeValue = '' ;
+		else if ( attributeValue.replace )
+		{
+			if ( FCKConfig.ForceSimpleAmpersand )
+				attributeValue = attributeValue.replace( /&/g, '___FCKAmp___' ) ;
+
+			// Entities must be replaced in the attribute values.
+			attributeValue = attributeValue.replace( FCKXHtmlEntities.EntitiesRegex, FCKXHtml_GetEntity ) ;
+		}
+
+		// Create the attribute.
+		var oXmlAtt = this.XML.createAttribute( attributeName ) ;
+		oXmlAtt.value = attributeValue ;
+
+		// Set the attribute in the node.
+		xmlNode.attributes.setNamedItem( oXmlAtt ) ;
+	}
+	catch (e)
+	{}
+}
+
+FCKXHtml._AppendChildNodes = function( xmlNode, htmlNode, isBlockElement )
+{
+	// Trim block elements. This is also needed to avoid Firefox leaving extra
+	// BRs at the end of them.
+	if ( isBlockElement )
+		FCKDomTools.TrimNode( htmlNode, true ) ;
+
+	var iCount = 0 ;
+
+	var oNode = htmlNode.firstChild ;
+
+	while ( oNode )
+	{
+		if ( this._AppendNode( xmlNode, oNode ) )
+			iCount++ ;
+
+		oNode = oNode.nextSibling ;
+	}
+
+	if ( iCount == 0 )
+	{
+		if ( isBlockElement && FCKConfig.FillEmptyBlocks )
+		{
+			this._AppendEntity( xmlNode, this._NbspEntity ) ;
+			return xmlNode ;
+		}
+
+		var sNodeName = xmlNode.nodeName ;
+
+		// Some inline elements are required to have something inside (span, strong, etc...).
+		if ( FCKListsLib.InlineChildReqElements[ sNodeName ] )
+			return null ;
+
+		// We can't use short representation of empty elements that are not marked
+		// as empty in th XHTML DTD.
+		if ( !FCKListsLib.EmptyElements[ sNodeName ] )
+			xmlNode.appendChild( this.XML.createTextNode('') ) ;
+	}
+
+	return xmlNode ;
+}
+
+FCKXHtml._AppendNode = function( xmlNode, htmlNode )
+{
+	if ( !htmlNode )
+		return false ;
+
+	switch ( htmlNode.nodeType )
+	{
+		// Element Node.
+		case 1 :
+
+			// Here we found an element that is not the real element, but a
+			// fake one (like the Flash placeholder image), so we must get the real one.
+			if ( htmlNode.getAttribute('_fckfakelement') )
+				return FCKXHtml._AppendNode( xmlNode, FCK.GetRealElement( htmlNode ) ) ;
+
+			// Mozilla insert custom nodes in the DOM.
+			if ( FCKBrowserInfo.IsGecko && htmlNode.hasAttribute('_moz_editor_bogus_node') )
+				return false ;
+
+			// This is for elements that are instrumental to FCKeditor and
+			// must be removed from the final HTML.
+			if ( htmlNode.getAttribute('_fcktemp') )
+				return false ;
+
+			// Get the element name.
+			var sNodeName = htmlNode.tagName.toLowerCase()  ;
+
+			if ( FCKBrowserInfo.IsIE )
+			{
+				// IE doens't include the scope name in the nodeName. So, add the namespace.
+				if ( htmlNode.scopeName && htmlNode.scopeName != 'HTML' && htmlNode.scopeName != 'FCK' )
+					sNodeName = htmlNode.scopeName.toLowerCase() + ':' + sNodeName ;
+			}
+			else
+			{
+				if ( sNodeName.StartsWith( 'fck:' ) )
+					sNodeName = sNodeName.Remove( 0,4 ) ;
+			}
+
+			// Check if the node name is valid, otherwise ignore this tag.
+			// If the nodeName starts with a slash, it is a orphan closing tag.
+			// On some strange cases, the nodeName is empty, even if the node exists.
+			if ( !FCKRegexLib.ElementName.test( sNodeName ) )
+				return false ;
+
+			// Remove the <br> if it is a bogus node.
+			if ( sNodeName == 'br' && htmlNode.getAttribute( 'type', 2 ) == '_moz' )
+				return false ;
+
+			// The already processed nodes must be marked to avoid then to be duplicated (bad formatted HTML).
+			// So here, the "mark" is checked... if the element is Ok, then mark it.
+			if ( htmlNode._fckxhtmljob && htmlNode._fckxhtmljob == FCKXHtml.CurrentJobNum )
+				return false ;
+
+			var oNode = this._CreateNode( sNodeName ) ;
+
+			// Add all attributes.
+			FCKXHtml._AppendAttributes( xmlNode, htmlNode, oNode, sNodeName ) ;
+
+			htmlNode._fckxhtmljob = FCKXHtml.CurrentJobNum ;
+
+			// Tag specific processing.
+			var oTagProcessor = FCKXHtml.TagProcessors[ sNodeName ] ;
+
+			if ( oTagProcessor )
+				oNode = oTagProcessor( oNode, htmlNode, xmlNode ) ;
+			else
+				oNode = this._AppendChildNodes( oNode, htmlNode, Boolean( FCKListsLib.NonEmptyBlockElements[ sNodeName ] ) ) ;
+
+			if ( !oNode )
+				return false ;
+
+			xmlNode.appendChild( oNode ) ;
+
+			break ;
+
+		// Text Node.
+		case 3 :
+			return this._AppendTextNode( xmlNode, htmlNode.nodeValue.ReplaceNewLineChars(' ') ) ;
+
+		// Comment
+		case 8 :
+			// IE catches the <!DOTYPE ... > as a comment, but it has no
+			// innerHTML, so we can catch it, and ignore it.
+			if ( FCKBrowserInfo.IsIE && !htmlNode.innerHTML )
+				break ;
+
+			try { xmlNode.appendChild( this.XML.createComment( htmlNode.nodeValue ) ) ; }
+			catch (e) { /* Do nothing... probably this is a wrong format comment. */ }
+			break ;
+
+		// Unknown Node type.
+		default :
+			xmlNode.appendChild( this.XML.createComment( "Element not supported - Type: " + htmlNode.nodeType + " Name: " + htmlNode.nodeName ) ) ;
+			break ;
+	}
+	return true ;
+}
+
+function FCKXHtml_CreateNode_StrongEm( nodeName )
+{
+	switch ( nodeName )
+	{
+		case 'b' :
+			nodeName = 'strong' ;
+			break ;
+		case 'i' :
+			nodeName = 'em' ;
+			break ;
+	}
+	return this.XML.createElement( nodeName ) ;
+}
+
+function FCKXHtml_CreateNode_Normal( nodeName )
+{
+	return this.XML.createElement( nodeName ) ;
+}
+
+// Append an item to the SpecialBlocks array and returns the tag to be used.
+FCKXHtml._AppendSpecialItem = function( item )
+{
+	return '___FCKsi___' + FCKXHtml.SpecialBlocks.AddItem( item ) ;
+}
+
+FCKXHtml._AppendEntity = function( xmlNode, entity )
+{
+	xmlNode.appendChild( this.XML.createTextNode( '#?-:' + entity + ';' ) ) ;
+}
+
+FCKXHtml._AppendTextNode = function( targetNode, textValue )
+{
+	var bHadText = textValue.length > 0 ;
+	if ( bHadText )
+		targetNode.appendChild( this.XML.createTextNode( textValue.replace( FCKXHtmlEntities.EntitiesRegex, FCKXHtml_GetEntity ) ) ) ;
+	return bHadText ;
+}
+
+// Retrieves a entity (internal format) for a given character.
+function FCKXHtml_GetEntity( character )
+{
+	// We cannot simply place the entities in the text, because the XML parser
+	// will translate & to &amp;. So we use a temporary marker which is replaced
+	// in the end of the processing.
+	var sEntity = FCKXHtmlEntities.Entities[ character ] || ( '#' + character.charCodeAt(0) ) ;
+	return '#?-:' + sEntity + ';' ;
+}
+
+// Remove part of an attribute from a node according to a regExp
+FCKXHtml._RemoveAttribute = function( xmlNode, regX, sAttribute )
+{
+	var oAtt = xmlNode.attributes.getNamedItem( sAttribute ) ;
+
+	if ( oAtt && regX.test( oAtt.nodeValue ) )
+	{
+		var sValue = oAtt.nodeValue.replace( regX, '' ) ;
+
+		if ( sValue.length == 0 )
+			xmlNode.attributes.removeNamedItem( sAttribute ) ;
+		else
+			oAtt.nodeValue = sValue ;
+	}
+}
+
+// An object that hold tag specific operations.
+FCKXHtml.TagProcessors =
+{
+	img : function( node, htmlNode )
+	{
+		// The "ALT" attribute is required in XHTML.
+		if ( ! node.attributes.getNamedItem( 'alt' ) )
+			FCKXHtml._AppendAttribute( node, 'alt', '' ) ;
+
+		var sSavedUrl = htmlNode.getAttribute( '_fcksavedurl' ) ;
+		if ( sSavedUrl != null )
+			FCKXHtml._AppendAttribute( node, 'src', sSavedUrl ) ;
+
+		return node ;
+	},
+
+	a : function( node, htmlNode )
+	{
+		// Firefox may create empty tags when deleting the selection in some special cases (SF-BUG 1556878).
+		if ( htmlNode.innerHTML.Trim().length == 0 && !htmlNode.name )
+			return false ;
+
+		var sSavedUrl = htmlNode.getAttribute( '_fcksavedurl' ) ;
+		if ( sSavedUrl != null )
+			FCKXHtml._AppendAttribute( node, 'href', sSavedUrl ) ;
+
+
+		// Anchors with content has been marked with an additional class, now we must remove it.
+		if ( FCKBrowserInfo.IsIE )
+		{
+			FCKXHtml._RemoveAttribute( node, FCKRegexLib.FCK_Class, 'class' ) ;
+
+			// Buggy IE, doesn't copy the name of changed anchors.
+			if ( htmlNode.name )
+				FCKXHtml._AppendAttribute( node, 'name', htmlNode.name ) ;
+		}
+
+		node = FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
+
+		return node ;
+	},
+
+	script : function( node, htmlNode )
+	{
+		// The "TYPE" attribute is required in XHTML.
+		if ( ! node.attributes.getNamedItem( 'type' ) )
+			FCKXHtml._AppendAttribute( node, 'type', 'text/javascript' ) ;
+
+		node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( htmlNode.text ) ) ) ;
+
+		return node ;
+	},
+
+	style : function( node, htmlNode )
+	{
+		// The "TYPE" attribute is required in XHTML.
+		if ( ! node.attributes.getNamedItem( 'type' ) )
+			FCKXHtml._AppendAttribute( node, 'type', 'text/css' ) ;
+
+		node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( htmlNode.innerHTML ) ) ) ;
+
+		return node ;
+	},
+
+	title : function( node, htmlNode )
+	{
+		node.appendChild( FCKXHtml.XML.createTextNode( FCK.EditorDocument.title ) ) ;
+
+		return node ;
+	},
+
+	table : function( node, htmlNode )
+	{
+		// There is a trick to show table borders when border=0. We add to the
+		// table class the FCK__ShowTableBorders rule. So now we must remove it.
+
+		if ( FCKBrowserInfo.IsIE )
+			FCKXHtml._RemoveAttribute( node, FCKRegexLib.FCK_Class, 'class' ) ;
+
+		node = FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
+
+		return node ;
+	},
+
+	// Fix nested <ul> and <ol>.
+	ol : function( node, htmlNode, targetNode )
+	{
+		if ( htmlNode.innerHTML.Trim().length == 0 )
+			return false ;
+
+		var ePSibling = targetNode.lastChild ;
+
+		if ( ePSibling && ePSibling.nodeType == 3 )
+			ePSibling = ePSibling.previousSibling ;
+
+		if ( ePSibling && ePSibling.nodeName.toUpperCase() == 'LI' )
+		{
+			htmlNode._fckxhtmljob = null ;
+			FCKXHtml._AppendNode( ePSibling, htmlNode ) ;
+			return false ;
+		}
+
+		node = FCKXHtml._AppendChildNodes( node, htmlNode ) ;
+
+		return node ;
+	},
+
+	span : function( node, htmlNode )
+	{
+		// Firefox may create empty tags when deleting the selection in some special cases (SF-BUG 1084404).
+		if ( htmlNode.innerHTML.length == 0 )
+			return false ;
+
+		node = FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
+
+		return node ;
+	},
+
+	// IE loses contents of iframes, and Gecko does give it back HtmlEncoded
+	// Note: Opera does lose the content and doesn't provide it in the innerHTML string
+	iframe : function( node, htmlNode )
+	{
+		var sHtml = htmlNode.innerHTML ;
+
+		// Gecko does give back the encoded html
+		if ( FCKBrowserInfo.IsGecko )
+			sHtml = FCKTools.HTMLDecode( sHtml );
+		
+		// Remove the saved urls here as the data won't be processed as nodes
+		sHtml = sHtml.replace( /\s_fcksavedurl="[^"]*"/g, '' ) ;
+
+		node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( sHtml ) ) ) ;
+
+		return node ;
+	}
+} ;
+
+FCKXHtml.TagProcessors.ul = FCKXHtml.TagProcessors.ol ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection_gecko.js	(revision 795)
@@ -0,0 +1,151 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Active selection functions. (Gecko specific implementation)
+ */
+
+// Get the selection type (like document.select.type in IE).
+FCKSelection.GetType = function()
+{
+//	if ( ! this._Type )
+//	{
+		// By default set the type to "Text".
+		this._Type = 'Text' ;
+
+		// Check if the actual selection is a Control (IMG, TABLE, HR, etc...).
+		var oSel ;
+		try { oSel = FCK.EditorWindow.getSelection() ; }
+		catch (e) {}
+
+		if ( oSel && oSel.rangeCount == 1 )
+		{
+			var oRange = oSel.getRangeAt(0) ;
+			if ( oRange.startContainer == oRange.endContainer && (oRange.endOffset - oRange.startOffset) == 1 && oRange.startContainer.nodeType != Node.TEXT_NODE )
+				this._Type = 'Control' ;
+		}
+//	}
+	return this._Type ;
+}
+
+// Retrieves the selected element (if any), just in the case that a single
+// element (object like and image or a table) is selected.
+FCKSelection.GetSelectedElement = function()
+{
+	if ( this.GetType() == 'Control' )
+	{
+		var oSel = FCK.EditorWindow.getSelection() ;
+		return oSel.anchorNode.childNodes[ oSel.anchorOffset ] ;
+	}
+	return null ;
+}
+
+FCKSelection.GetParentElement = function()
+{
+	if ( this.GetType() == 'Control' )
+		return FCKSelection.GetSelectedElement().parentNode ;
+	else
+	{
+		var oSel = FCK.EditorWindow.getSelection() ;
+		if ( oSel )
+		{
+			var oNode = oSel.anchorNode ;
+
+			while ( oNode && oNode.nodeType != 1 )
+				oNode = oNode.parentNode ;
+
+			return oNode ;
+		}
+	}
+	return null ;
+}
+
+FCKSelection.SelectNode = function( element )
+{
+//	FCK.Focus() ;
+
+	var oRange = FCK.EditorDocument.createRange() ;
+	oRange.selectNode( element ) ;
+
+	var oSel = FCK.EditorWindow.getSelection() ;
+	oSel.removeAllRanges() ;
+	oSel.addRange( oRange ) ;
+}
+
+FCKSelection.Collapse = function( toStart )
+{
+	var oSel = FCK.EditorWindow.getSelection() ;
+
+	if ( toStart == null || toStart === true )
+		oSel.collapseToStart() ;
+	else
+		oSel.collapseToEnd() ;
+}
+
+// The "nodeTagName" parameter must be Upper Case.
+FCKSelection.HasAncestorNode = function( nodeTagName )
+{
+	var oContainer = this.GetSelectedElement() ;
+	if ( ! oContainer && FCK.EditorWindow )
+	{
+		try		{ oContainer = FCK.EditorWindow.getSelection().getRangeAt(0).startContainer ; }
+		catch(e){}
+	}
+
+	while ( oContainer )
+	{
+		if ( oContainer.nodeType == 1 && oContainer.tagName == nodeTagName ) return true ;
+		oContainer = oContainer.parentNode ;
+	}
+
+	return false ;
+}
+
+// The "nodeTagName" parameter must be Upper Case.
+FCKSelection.MoveToAncestorNode = function( nodeTagName )
+{
+	var oNode ;
+
+	var oContainer = this.GetSelectedElement() ;
+	if ( ! oContainer )
+		oContainer = FCK.EditorWindow.getSelection().getRangeAt(0).startContainer ;
+
+	while ( oContainer )
+	{
+		if ( oContainer.nodeName == nodeTagName )
+			return oContainer ;
+
+		oContainer = oContainer.parentNode ;
+	}
+	return null ;
+}
+
+FCKSelection.Delete = function()
+{
+	// Gets the actual selection.
+	var oSel = FCK.EditorWindow.getSelection() ;
+
+	// Deletes the actual selection contents.
+	for ( var i = 0 ; i < oSel.rangeCount ; i++ )
+	{
+		oSel.getRangeAt(i).deleteContents() ;
+	}
+
+	return oSel ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckcodeformatter.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckcodeformatter.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckcodeformatter.js	(revision 795)
@@ -0,0 +1,100 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Format the HTML.
+ */
+
+var FCKCodeFormatter = new Object() ;
+
+FCKCodeFormatter.Init = function()
+{
+	var oRegex = this.Regex = new Object() ;
+
+	// Regex for line breaks.
+	oRegex.BlocksOpener = /\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi ;
+	oRegex.BlocksCloser = /\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi ;
+
+	oRegex.NewLineTags	= /\<(BR|HR)[^\>]*\>/gi ;
+
+	oRegex.MainTags = /\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi ;
+
+	oRegex.LineSplitter = /\s*\n+\s*/g ;
+
+	// Regex for indentation.
+	oRegex.IncreaseIndent = /^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i ;
+	oRegex.DecreaseIndent = /^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i ;
+	oRegex.FormatIndentatorRemove = new RegExp( '^' + FCKConfig.FormatIndentator ) ;
+
+	oRegex.ProtectedTags = /(<PRE[^>]*>)([\s\S]*?)(<\/PRE>)/gi ;
+}
+
+FCKCodeFormatter._ProtectData = function( outer, opener, data, closer )
+{
+	return opener + '___FCKpd___' + FCKCodeFormatter.ProtectedData.AddItem( data ) + closer ;
+}
+
+FCKCodeFormatter.Format = function( html )
+{
+	if ( !this.Regex )
+		this.Init() ;
+
+	// Protected content that remain untouched during the
+	// process go in the following array.
+	FCKCodeFormatter.ProtectedData = new Array() ;
+
+	var sFormatted = html.replace( this.Regex.ProtectedTags, FCKCodeFormatter._ProtectData ) ;
+
+	// Line breaks.
+	sFormatted		= sFormatted.replace( this.Regex.BlocksOpener, '\n$&' ) ;
+	sFormatted		= sFormatted.replace( this.Regex.BlocksCloser, '$&\n' ) ;
+	sFormatted		= sFormatted.replace( this.Regex.NewLineTags, '$&\n' ) ;
+	sFormatted		= sFormatted.replace( this.Regex.MainTags, '\n$&\n' ) ;
+
+	// Indentation.
+	var sIndentation = '' ;
+
+	var asLines = sFormatted.split( this.Regex.LineSplitter ) ;
+	sFormatted = '' ;
+
+	for ( var i = 0 ; i < asLines.length ; i++ )
+	{
+		var sLine = asLines[i] ;
+
+		if ( sLine.length == 0 )
+			continue ;
+
+		if ( this.Regex.DecreaseIndent.test( sLine ) )
+			sIndentation = sIndentation.replace( this.Regex.FormatIndentatorRemove, '' ) ;
+
+		sFormatted += sIndentation + sLine + '\n' ;
+
+		if ( this.Regex.IncreaseIndent.test( sLine ) )
+			sIndentation += FCKConfig.FormatIndentator ;
+	}
+
+	// Now we put back the protected data.
+	for ( var j = 0 ; j < FCKCodeFormatter.ProtectedData.length ; j++ )
+	{
+		var oRegex = new RegExp( '___FCKpd___' + j ) ;
+		sFormatted = sFormatted.replace( oRegex, FCKCodeFormatter.ProtectedData[j].replace( /\$/g, '$$$$' ) ) ;
+	}
+
+	return sFormatted.Trim() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog.js	(revision 795)
@@ -0,0 +1,38 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Dialog windows operations.
+ */
+
+var FCKDialog = new Object() ;
+
+// This method opens a dialog window using the standard dialog template.
+FCKDialog.OpenDialog = function( dialogName, dialogTitle, dialogPage, width, height, customValue, parentWindow, resizable )
+{
+	// Setup the dialog info.
+	var oDialogInfo = new Object() ;
+	oDialogInfo.Title = dialogTitle ;
+	oDialogInfo.Page = dialogPage ;
+	oDialogInfo.Editor = window ;
+	oDialogInfo.CustomValue = customValue ;		// Optional
+
+	var sUrl = FCKConfig.BasePath + 'fckdialog.html' ;
+	this.Show( oDialogInfo, dialogName, sUrl, width, height, parentWindow, resizable ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools.js	(revision 795)
@@ -0,0 +1,225 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Utility functions.
+ */
+
+// Constant for the Gecko Bogus Node.
+//var GECKO_BOGUS = '<br _moz_editor_bogus_node="TRUE">' ;
+var GECKO_BOGUS = '<br type="_moz">' ;
+
+var FCKTools = new Object() ;
+
+FCKTools.CreateBogusBR = function( targetDocument )
+{
+	var eBR = targetDocument.createElement( 'br' ) ;
+//	eBR.setAttribute( '_moz_editor_bogus_node', 'TRUE' ) ;
+	eBR.setAttribute( 'type', '_moz' ) ;
+	return eBR ;
+}
+
+// Returns a reference to the appended style sheet or an array with all the appended references
+FCKTools.AppendStyleSheet = function( documentElement, cssFileUrlOrArray )
+{
+	if ( typeof( cssFileUrlOrArray ) == 'string' )
+		return this._AppendStyleSheet( documentElement, cssFileUrlOrArray ) ;
+	else
+	{
+		var aStyleSheeArray = new Array() ;
+
+		for ( var i = 0 ; i < cssFileUrlOrArray.length ; i++ )
+			aStyleSheeArray.push(this._AppendStyleSheet( documentElement, cssFileUrlOrArray[i] ) ) ;
+
+		return aStyleSheeArray ;
+	}
+}
+
+FCKTools.GetElementDocument = function ( element )
+{
+	return element.ownerDocument || element.document ;
+}
+
+// Get the window object where the element is placed in.
+FCKTools.GetElementWindow = function( element )
+{
+	return this.GetDocumentWindow( this.GetElementDocument( element ) ) ;
+}
+
+FCKTools.GetDocumentWindow = function( document )
+{
+	// With Safari, there is not way to retrieve the window from the document, so we must fix it.
+	if ( FCKBrowserInfo.IsSafari && !document.parentWindow )
+		this.FixDocumentParentWindow( window.top ) ;
+
+	return document.parentWindow || document.defaultView ;
+}
+
+/*
+	This is a Safari specific function that fix the reference to the parent
+	window from the document object.
+*/
+FCKTools.FixDocumentParentWindow = function( targetWindow )
+{
+	targetWindow.document.parentWindow = targetWindow ;
+
+	for ( var i = 0 ; i < targetWindow.frames.length ; i++ )
+		FCKTools.FixDocumentParentWindow( targetWindow.frames[i] ) ;
+}
+
+FCKTools.HTMLEncode = function( text )
+{
+	if ( !text )
+		return '' ;
+
+	text = text.replace( /&/g, '&amp;' ) ;
+	text = text.replace( /</g, '&lt;' ) ;
+	text = text.replace( />/g, '&gt;' ) ;
+
+	return text ;
+}
+
+FCKTools.HTMLDecode = function( text )
+{
+	if ( !text )
+		return '' ;
+
+	text = text.replace( /&gt;/g, '>' ) ;
+	text = text.replace( /&lt;/g, '<' ) ;
+	text = text.replace( /&amp;/g, '&' ) ;
+
+	return text ;
+}
+
+/**
+ * Adds an option to a SELECT element.
+ */
+FCKTools.AddSelectOption = function( selectElement, optionText, optionValue )
+{
+	var oOption = FCKTools.GetElementDocument( selectElement ).createElement( "OPTION" ) ;
+
+	oOption.text	= optionText ;
+	oOption.value	= optionValue ;
+
+	selectElement.options.add(oOption) ;
+
+	return oOption ;
+}
+
+FCKTools.RunFunction = function( func, thisObject, paramsArray, timerWindow )
+{
+	if ( func )
+		this.SetTimeout( func, 0, thisObject, paramsArray, timerWindow ) ;
+}
+
+FCKTools.SetTimeout = function( func, milliseconds, thisObject, paramsArray, timerWindow )
+{
+	return ( timerWindow || window ).setTimeout(
+		function()
+		{
+			if ( paramsArray )
+				func.apply( thisObject, [].concat( paramsArray ) ) ;
+			else
+				func.apply( thisObject ) ;
+		},
+		milliseconds ) ;
+}
+
+FCKTools.SetInterval = function( func, milliseconds, thisObject, paramsArray, timerWindow )
+{
+	return ( timerWindow || window ).setInterval(
+		function()
+		{
+			func.apply( thisObject, paramsArray || [] ) ;
+		},
+		milliseconds ) ;
+}
+
+FCKTools.ConvertStyleSizeToHtml = function( size )
+{
+	return size.EndsWith( '%' ) ? size : parseInt( size, 10 ) ;
+}
+
+FCKTools.ConvertHtmlSizeToStyle = function( size )
+{
+	return size.EndsWith( '%' ) ? size : ( size + 'px' ) ;
+}
+
+// START iCM MODIFICATIONS
+// Amended to accept a list of one or more ascensor tag names
+// Amended to check the element itself before working back up through the parent hierarchy
+FCKTools.GetElementAscensor = function( element, ascensorTagNames )
+{
+//	var e = element.parentNode ;
+	var e = element ;
+	var lstTags = "," + ascensorTagNames.toUpperCase() + "," ;
+
+	while ( e )
+	{
+		if ( lstTags.indexOf( "," + e.nodeName.toUpperCase() + "," ) != -1 )
+			return e ;
+
+		e = e.parentNode ;
+	}
+	return null ;
+}
+// END iCM MODIFICATIONS
+
+FCKTools.CreateEventListener = function( func, params )
+{
+	var f = function()
+	{
+		var aAllParams = [] ;
+
+		for ( var i = 0 ; i < arguments.length ; i++ )
+			aAllParams.push( arguments[i] ) ;
+
+		func.apply( this, aAllParams.concat( params ) ) ;
+	}
+
+	return f ;
+}
+
+FCKTools.IsStrictMode = function( document )
+{
+	// There is no compatMode in Safari, but it seams that it always behave as
+	// CSS1Compat, so let's assume it as the default.
+	return ( 'CSS1Compat' == ( document.compatMode || 'CSS1Compat' ) ) ;
+}
+
+// Transforms a "arguments" object to an array.
+FCKTools.ArgumentsToArray = function( args, startIndex, maxLength )
+{
+	startIndex = startIndex || 0 ;
+	maxLength = maxLength || args.length ;
+
+	var argsArray = new Array() ;
+
+	for ( var i = startIndex ; i < startIndex + maxLength && i < args.length ; i++ )
+		argsArray.push( args[i] ) ;
+
+	return argsArray ;
+}
+
+FCKTools.CloneObject = function( sourceObject )
+{
+	var fCloneCreator = function() {} ;
+	fCloneCreator.prototype = sourceObject ;
+	return new fCloneCreator ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckcommands.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckcommands.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckcommands.js	(revision 795)
@@ -0,0 +1,132 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Define all commands available in the editor.
+ */
+
+var FCKCommands = FCK.Commands = new Object() ;
+FCKCommands.LoadedCommands = new Object() ;
+
+FCKCommands.RegisterCommand = function( commandName, command )
+{
+	this.LoadedCommands[ commandName ] = command ;
+}
+
+FCKCommands.GetCommand = function( commandName )
+{
+	var oCommand = FCKCommands.LoadedCommands[ commandName ] ;
+
+	if ( oCommand )
+		return oCommand ;
+
+	switch ( commandName )
+	{
+		case 'DocProps'		: oCommand = new FCKDialogCommand( 'DocProps'	, FCKLang.DocProps				, 'dialog/fck_docprops.html'	, 400, 390, FCKCommands.GetFullPageState ) ; break ;
+		case 'Templates'	: oCommand = new FCKDialogCommand( 'Templates'	, FCKLang.DlgTemplatesTitle		, 'dialog/fck_template.html'	, 380, 450 ) ; break ;
+		case 'Link'			: oCommand = new FCKDialogCommand( 'Link'		, FCKLang.DlgLnkWindowTitle		, 'dialog/fck_link.html'		, 400, 330 ) ; break ;
+		case 'Unlink'		: oCommand = new FCKUnlinkCommand() ; break ;
+		case 'Anchor'		: oCommand = new FCKDialogCommand( 'Anchor'		, FCKLang.DlgAnchorTitle		, 'dialog/fck_anchor.html'		, 370, 170 ) ; break ;
+		case 'BulletedList'	: oCommand = new FCKDialogCommand( 'BulletedList', FCKLang.BulletedListProp		, 'dialog/fck_listprop.html?UL'	, 370, 170 ) ; break ;
+		case 'NumberedList'	: oCommand = new FCKDialogCommand( 'NumberedList', FCKLang.NumberedListProp		, 'dialog/fck_listprop.html?OL'	, 370, 170 ) ; break ;
+		case 'About'		: oCommand = new FCKDialogCommand( 'About'		, FCKLang.About					, 'dialog/fck_about.html'		, 400, 330 ) ; break ;
+
+		case 'Find'			: oCommand = new FCKDialogCommand( 'Find'		, FCKLang.DlgFindTitle			, 'dialog/fck_find.html'		, 340, 170 ) ; break ;
+		case 'Replace'		: oCommand = new FCKDialogCommand( 'Replace'	, FCKLang.DlgReplaceTitle		, 'dialog/fck_replace.html'		, 340, 200 ) ; break ;
+
+		case 'Image'		: oCommand = new FCKDialogCommand( 'Image'		, FCKLang.DlgImgTitle			, 'dialog/fck_image.html'		, 450, 400 ) ; break ;
+		case 'Flash'		: oCommand = new FCKDialogCommand( 'Flash'		, FCKLang.DlgFlashTitle			, 'dialog/fck_flash.html'		, 450, 400 ) ; break ;
+		case 'SpecialChar'	: oCommand = new FCKDialogCommand( 'SpecialChar', FCKLang.DlgSpecialCharTitle	, 'dialog/fck_specialchar.html'	, 400, 320 ) ; break ;
+		case 'Smiley'		: oCommand = new FCKDialogCommand( 'Smiley'		, FCKLang.DlgSmileyTitle		, 'dialog/fck_smiley.html'		, FCKConfig.SmileyWindowWidth, FCKConfig.SmileyWindowHeight ) ; break ;
+		case 'Table'		: oCommand = new FCKDialogCommand( 'Table'		, FCKLang.DlgTableTitle			, 'dialog/fck_table.html'		, 450, 250 ) ; break ;
+		case 'TableProp'	: oCommand = new FCKDialogCommand( 'Table'		, FCKLang.DlgTableTitle			, 'dialog/fck_table.html?Parent', 400, 250 ) ; break ;
+		case 'TableCellProp': oCommand = new FCKDialogCommand( 'TableCell'	, FCKLang.DlgCellTitle			, 'dialog/fck_tablecell.html'	, 550, 250 ) ; break ;
+
+		case 'Style'		: oCommand = new FCKStyleCommand() ; break ;
+
+		case 'FontName'		: oCommand = new FCKFontNameCommand() ; break ;
+		case 'FontSize'		: oCommand = new FCKFontSizeCommand() ; break ;
+		case 'FontFormat'	: oCommand = new FCKFormatBlockCommand() ; break ;
+
+		case 'Source'		: oCommand = new FCKSourceCommand() ; break ;
+		case 'Preview'		: oCommand = new FCKPreviewCommand() ; break ;
+		case 'Save'			: oCommand = new FCKSaveCommand() ; break ;
+		case 'NewPage'		: oCommand = new FCKNewPageCommand() ; break ;
+		case 'PageBreak'	: oCommand = new FCKPageBreakCommand() ; break ;
+
+		case 'TextColor'	: oCommand = new FCKTextColorCommand('ForeColor') ; break ;
+		case 'BGColor'		: oCommand = new FCKTextColorCommand('BackColor') ; break ;
+
+		case 'Paste'		: oCommand = new FCKPasteCommand() ; break ;
+		case 'PasteText'	: oCommand = new FCKPastePlainTextCommand() ; break ;
+		case 'PasteWord'	: oCommand = new FCKPasteWordCommand() ; break ;
+
+		case 'TableInsertRow'		: oCommand = new FCKTableCommand('TableInsertRow') ; break ;
+		case 'TableDeleteRows'		: oCommand = new FCKTableCommand('TableDeleteRows') ; break ;
+		case 'TableInsertColumn'	: oCommand = new FCKTableCommand('TableInsertColumn') ; break ;
+		case 'TableDeleteColumns'	: oCommand = new FCKTableCommand('TableDeleteColumns') ; break ;
+		case 'TableInsertCell'		: oCommand = new FCKTableCommand('TableInsertCell') ; break ;
+		case 'TableDeleteCells'		: oCommand = new FCKTableCommand('TableDeleteCells') ; break ;
+		case 'TableMergeCells'		: oCommand = new FCKTableCommand('TableMergeCells') ; break ;
+		case 'TableSplitCell'		: oCommand = new FCKTableCommand('TableSplitCell') ; break ;
+		case 'TableDelete'			: oCommand = new FCKTableCommand('TableDelete') ; break ;
+
+		case 'Form'			: oCommand = new FCKDialogCommand( 'Form'		, FCKLang.Form			, 'dialog/fck_form.html'		, 380, 230 ) ; break ;
+		case 'Checkbox'		: oCommand = new FCKDialogCommand( 'Checkbox'	, FCKLang.Checkbox		, 'dialog/fck_checkbox.html'	, 380, 230 ) ; break ;
+		case 'Radio'		: oCommand = new FCKDialogCommand( 'Radio'		, FCKLang.RadioButton	, 'dialog/fck_radiobutton.html'	, 380, 230 ) ; break ;
+		case 'TextField'	: oCommand = new FCKDialogCommand( 'TextField'	, FCKLang.TextField		, 'dialog/fck_textfield.html'	, 380, 230 ) ; break ;
+		case 'Textarea'		: oCommand = new FCKDialogCommand( 'Textarea'	, FCKLang.Textarea		, 'dialog/fck_textarea.html'	, 380, 230 ) ; break ;
+		case 'HiddenField'	: oCommand = new FCKDialogCommand( 'HiddenField', FCKLang.HiddenField	, 'dialog/fck_hiddenfield.html'	, 380, 230 ) ; break ;
+		case 'Button'		: oCommand = new FCKDialogCommand( 'Button'		, FCKLang.Button		, 'dialog/fck_button.html'		, 380, 230 ) ; break ;
+		case 'Select'		: oCommand = new FCKDialogCommand( 'Select'		, FCKLang.SelectionField, 'dialog/fck_select.html'		, 400, 380 ) ; break ;
+		case 'ImageButton'	: oCommand = new FCKDialogCommand( 'ImageButton', FCKLang.ImageButton	, 'dialog/fck_image.html?ImageButton', 450, 400 ) ; break ;
+
+		case 'SpellCheck'	: oCommand = new FCKSpellCheckCommand() ; break ;
+		case 'FitWindow'	: oCommand = new FCKFitWindow() ; break ;
+
+		case 'Undo'	: oCommand = new FCKUndoCommand() ; break ;
+		case 'Redo'	: oCommand = new FCKRedoCommand() ; break ;
+
+		case 'SelectAll' : oCommand = new FCKSelectAllCommand() ; break ;
+
+		// Generic Undefined command (usually used when a command is under development).
+		case 'Undefined'	: oCommand = new FCKUndefinedCommand() ; break ;
+
+		// By default we assume that it is a named command.
+		default:
+			if ( FCKRegexLib.NamedCommands.test( commandName ) )
+				oCommand = new FCKNamedCommand( commandName ) ;
+			else
+			{
+				alert( FCKLang.UnknownCommand.replace( /%1/g, commandName ) ) ;
+				return null ;
+			}
+	}
+
+	FCKCommands.LoadedCommands[ commandName ] = oCommand ;
+
+	return oCommand ;
+}
+
+// Gets the state of the "Document Properties" button. It must be enabled only
+// when "Full Page" editing is available.
+FCKCommands.GetFullPageState = function()
+{
+	return FCKConfig.FullPage ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtmlentities.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtmlentities.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtmlentities.js	(revision 795)
@@ -0,0 +1,345 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This file define the HTML entities handled by the editor.
+ */
+
+var FCKXHtmlEntities = new Object() ;
+
+FCKXHtmlEntities.Initialize = function()
+{
+	if ( FCKXHtmlEntities.Entities )
+		return ;
+
+	var sChars = '' ;
+	var oEntities, e ;
+
+	if ( FCKConfig.ProcessHTMLEntities )
+	{
+		FCKXHtmlEntities.Entities = {
+			// Latin-1 Entities
+			' ':'nbsp',
+			'¡':'iexcl',
+			'¢':'cent',
+			'£':'pound',
+			'¤':'curren',
+			'¥':'yen',
+			'¦':'brvbar',
+			'§':'sect',
+			'¨':'uml',
+			'©':'copy',
+			'ª':'ordf',
+			'«':'laquo',
+			'¬':'not',
+			'­':'shy',
+			'®':'reg',
+			'¯':'macr',
+			'°':'deg',
+			'±':'plusmn',
+			'²':'sup2',
+			'³':'sup3',
+			'´':'acute',
+			'µ':'micro',
+			'¶':'para',
+			'·':'middot',
+			'¸':'cedil',
+			'¹':'sup1',
+			'º':'ordm',
+			'»':'raquo',
+			'¼':'frac14',
+			'½':'frac12',
+			'¾':'frac34',
+			'¿':'iquest',
+			'×':'times',
+			'÷':'divide',
+
+			// Symbols
+
+			'ƒ':'fnof',
+			'•':'bull',
+			'…':'hellip',
+			'′':'prime',
+			'″':'Prime',
+			'‾':'oline',
+			'⁄':'frasl',
+			'℘':'weierp',
+			'ℑ':'image',
+			'ℜ':'real',
+			'™':'trade',
+			'ℵ':'alefsym',
+			'←':'larr',
+			'↑':'uarr',
+			'→':'rarr',
+			'↓':'darr',
+			'↔':'harr',
+			'↵':'crarr',
+			'⇐':'lArr',
+			'⇑':'uArr',
+			'⇒':'rArr',
+			'⇓':'dArr',
+			'⇔':'hArr',
+			'∀':'forall',
+			'∂':'part',
+			'∃':'exist',
+			'∅':'empty',
+			'∇':'nabla',
+			'∈':'isin',
+			'∉':'notin',
+			'∋':'ni',
+			'∏':'prod',
+			'∑':'sum',
+			'−':'minus',
+			'∗':'lowast',
+			'√':'radic',
+			'∝':'prop',
+			'∞':'infin',
+			'∠':'ang',
+			'∧':'and',
+			'∨':'or',
+			'∩':'cap',
+			'∪':'cup',
+			'∫':'int',
+			'∴':'there4',
+			'∼':'sim',
+			'≅':'cong',
+			'≈':'asymp',
+			'≠':'ne',
+			'≡':'equiv',
+			'≤':'le',
+			'≥':'ge',
+			'⊂':'sub',
+			'⊃':'sup',
+			'⊄':'nsub',
+			'⊆':'sube',
+			'⊇':'supe',
+			'⊕':'oplus',
+			'⊗':'otimes',
+			'⊥':'perp',
+			'⋅':'sdot',
+			'◊':'loz',
+			'♠':'spades',
+			'♣':'clubs',
+			'♥':'hearts',
+			'♦':'diams',
+
+			// Other Special Characters
+
+			'"':'quot',
+		//	'&':'amp',		// This entity is automatically handled by the XHTML parser.
+		//	'<':'lt',		// This entity is automatically handled by the XHTML parser.
+		//	'>':'gt',		// This entity is automatically handled by the XHTML parser.
+			'ˆ':'circ',
+			'˜':'tilde',
+			' ':'ensp',
+			' ':'emsp',
+			' ':'thinsp',
+			'‌':'zwnj',
+			'‍':'zwj',
+			'‎':'lrm',
+			'‏':'rlm',
+			'–':'ndash',
+			'—':'mdash',
+			'‘':'lsquo',
+			'’':'rsquo',
+			'‚':'sbquo',
+			'“':'ldquo',
+			'”':'rdquo',
+			'„':'bdquo',
+			'†':'dagger',
+			'‡':'Dagger',
+			'‰':'permil',
+			'‹':'lsaquo',
+			'›':'rsaquo',
+			'€':'euro'
+		} ;
+
+		// Process Base Entities.
+		for ( e in FCKXHtmlEntities.Entities )
+			sChars += e ;
+
+		// Include Latin Letters Entities.
+		if ( FCKConfig.IncludeLatinEntities )
+		{
+			oEntities = {
+				'À':'Agrave',
+				'Á':'Aacute',
+				'Â':'Acirc',
+				'Ã':'Atilde',
+				'Ä':'Auml',
+				'Å':'Aring',
+				'Æ':'AElig',
+				'Ç':'Ccedil',
+				'È':'Egrave',
+				'É':'Eacute',
+				'Ê':'Ecirc',
+				'Ë':'Euml',
+				'Ì':'Igrave',
+				'Í':'Iacute',
+				'Î':'Icirc',
+				'Ï':'Iuml',
+				'Ð':'ETH',
+				'Ñ':'Ntilde',
+				'Ò':'Ograve',
+				'Ó':'Oacute',
+				'Ô':'Ocirc',
+				'Õ':'Otilde',
+				'Ö':'Ouml',
+				'Ø':'Oslash',
+				'Ù':'Ugrave',
+				'Ú':'Uacute',
+				'Û':'Ucirc',
+				'Ü':'Uuml',
+				'Ý':'Yacute',
+				'Þ':'THORN',
+				'ß':'szlig',
+				'à':'agrave',
+				'á':'aacute',
+				'â':'acirc',
+				'ã':'atilde',
+				'ä':'auml',
+				'å':'aring',
+				'æ':'aelig',
+				'ç':'ccedil',
+				'è':'egrave',
+				'é':'eacute',
+				'ê':'ecirc',
+				'ë':'euml',
+				'ì':'igrave',
+				'í':'iacute',
+				'î':'icirc',
+				'ï':'iuml',
+				'ð':'eth',
+				'ñ':'ntilde',
+				'ò':'ograve',
+				'ó':'oacute',
+				'ô':'ocirc',
+				'õ':'otilde',
+				'ö':'ouml',
+				'ø':'oslash',
+				'ù':'ugrave',
+				'ú':'uacute',
+				'û':'ucirc',
+				'ü':'uuml',
+				'ý':'yacute',
+				'þ':'thorn',
+				'ÿ':'yuml',
+				'Œ':'OElig',
+				'œ':'oelig',
+				'Š':'Scaron',
+				'š':'scaron',
+				'Ÿ':'Yuml'
+			} ;
+
+			for ( e in oEntities )
+			{
+				FCKXHtmlEntities.Entities[ e ] = oEntities[ e ] ;
+				sChars += e ;
+			}
+
+			oEntities = null ;
+		}
+
+		// Include Greek Letters Entities.
+		if ( FCKConfig.IncludeGreekEntities )
+		{
+			oEntities = {
+				'Α':'Alpha',
+				'Β':'Beta',
+				'Γ':'Gamma',
+				'Δ':'Delta',
+				'Ε':'Epsilon',
+				'Ζ':'Zeta',
+				'Η':'Eta',
+				'Θ':'Theta',
+				'Ι':'Iota',
+				'Κ':'Kappa',
+				'Λ':'Lambda',
+				'Μ':'Mu',
+				'Ν':'Nu',
+				'Ξ':'Xi',
+				'Ο':'Omicron',
+				'Π':'Pi',
+				'Ρ':'Rho',
+				'Σ':'Sigma',
+				'Τ':'Tau',
+				'Υ':'Upsilon',
+				'Φ':'Phi',
+				'Χ':'Chi',
+				'Ψ':'Psi',
+				'Ω':'Omega',
+				'α':'alpha',
+				'β':'beta',
+				'γ':'gamma',
+				'δ':'delta',
+				'ε':'epsilon',
+				'ζ':'zeta',
+				'η':'eta',
+				'θ':'theta',
+				'ι':'iota',
+				'κ':'kappa',
+				'λ':'lambda',
+				'μ':'mu',
+				'ν':'nu',
+				'ξ':'xi',
+				'ο':'omicron',
+				'π':'pi',
+				'ρ':'rho',
+				'ς':'sigmaf',
+				'σ':'sigma',
+				'τ':'tau',
+				'υ':'upsilon',
+				'φ':'phi',
+				'χ':'chi',
+				'ψ':'psi',
+				'ω':'omega'
+			} ;
+
+			for ( e in oEntities )
+			{
+				FCKXHtmlEntities.Entities[ e ] = oEntities[ e ] ;
+				sChars += e ;
+			}
+
+			oEntities = null ;
+		}
+	}
+	else
+	{
+		FCKXHtmlEntities.Entities = {} ;
+
+		// Even if we are not processing the entities, we must render the &nbsp;
+		// correctly. As we don't want HTML entities, let's use its numeric
+		// representation (&#160).
+		sChars = ' ' ;
+	}
+
+	// Create the Regex used to find entities in the text.
+	var sRegexPattern = '[' + sChars + ']' ;
+
+	if ( FCKConfig.ProcessNumericEntities )
+		sRegexPattern = '[^ -~]|' + sRegexPattern ;
+
+	var sAdditional = FCKConfig.AdditionalNumericEntities ;
+
+	if ( sAdditional && sAdditional.length > 0 )
+		sRegexPattern += '|' + FCKConfig.AdditionalNumericEntities ;
+
+	FCKXHtmlEntities.EntitiesRegex = new RegExp( sRegexPattern, 'g' ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler_ie.js	(revision 795)
@@ -0,0 +1,58 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Manage table operations (IE specific).
+ */
+
+FCKTableHandler.GetSelectedCells = function()
+{
+	var aCells = new Array() ;
+
+	var oRange = FCK.EditorDocument.selection.createRange() ;
+//	var oParent = oRange.parentElement() ;
+	var oParent = FCKSelection.GetParentElement() ;
+
+	if ( oParent && oParent.tagName.Equals( 'TD', 'TH' ) )
+		aCells[0] = oParent ;
+	else
+	{
+		oParent = FCKSelection.MoveToAncestorNode( 'TABLE' ) ;
+
+		if ( oParent )
+		{
+			// Loops throw all cells checking if the cell is, or part of it, is inside the selection
+			// and then add it to the selected cells collection.
+			for ( var i = 0 ; i < oParent.cells.length ; i++ )
+			{
+				var oCellRange = FCK.EditorDocument.selection.createRange() ;
+				oCellRange.moveToElementText( oParent.cells[i] ) ;
+
+				if ( oRange.inRange( oCellRange )
+					|| ( oRange.compareEndPoints('StartToStart',oCellRange) >= 0 &&  oRange.compareEndPoints('StartToEnd',oCellRange) <= 0 )
+					|| ( oRange.compareEndPoints('EndToStart',oCellRange) >= 0 &&  oRange.compareEndPoints('EndToEnd',oCellRange) <= 0 ) )
+				{
+					aCells[aCells.length] = oParent.cells[i] ;
+				}
+			}
+		}
+	}
+
+	return aCells ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktoolbaritems.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktoolbaritems.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktoolbaritems.js	(revision 795)
@@ -0,0 +1,121 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Toolbar items definitions.
+ */
+
+var FCKToolbarItems = new Object() ;
+FCKToolbarItems.LoadedItems = new Object() ;
+
+FCKToolbarItems.RegisterItem = function( itemName, item )
+{
+	this.LoadedItems[ itemName ] = item ;
+}
+
+FCKToolbarItems.GetItem = function( itemName )
+{
+	var oItem = FCKToolbarItems.LoadedItems[ itemName ] ;
+
+	if ( oItem )
+		return oItem ;
+
+	switch ( itemName )
+	{
+		case 'Source'			: oItem = new FCKToolbarButton( 'Source'	, FCKLang.Source, null, FCK_TOOLBARITEM_ICONTEXT, true, true, 1 ) ; break ;
+		case 'DocProps'			: oItem = new FCKToolbarButton( 'DocProps'	, FCKLang.DocProps, null, null, null, null, 2 ) ; break ;
+		case 'Save'				: oItem = new FCKToolbarButton( 'Save'		, FCKLang.Save, null, null, true, null, 3 ) ; break ;
+		case 'NewPage'			: oItem = new FCKToolbarButton( 'NewPage'	, FCKLang.NewPage, null, null, true, null, 4  ) ; break ;
+		case 'Preview'			: oItem = new FCKToolbarButton( 'Preview'	, FCKLang.Preview, null, null, true, null, 5  ) ; break ;
+		case 'Templates'		: oItem = new FCKToolbarButton( 'Templates'	, FCKLang.Templates, null, null, null, null, 6 ) ; break ;
+		case 'About'			: oItem = new FCKToolbarButton( 'About'		, FCKLang.About, null, null, true, null, 47  ) ; break ;
+
+		case 'Cut'				: oItem = new FCKToolbarButton( 'Cut'		, FCKLang.Cut, null, null, false, true, 7 ) ; break ;
+		case 'Copy'				: oItem = new FCKToolbarButton( 'Copy'		, FCKLang.Copy, null, null, false, true, 8 ) ; break ;
+		case 'Paste'			: oItem = new FCKToolbarButton( 'Paste'		, FCKLang.Paste, null, null, false, true, 9 ) ; break ;
+		case 'PasteText'		: oItem = new FCKToolbarButton( 'PasteText'	, FCKLang.PasteText, null, null, false, true, 10 ) ; break ;
+		case 'PasteWord'		: oItem = new FCKToolbarButton( 'PasteWord'	, FCKLang.PasteWord, null, null, false, true, 11 ) ; break ;
+		case 'Print'			: oItem = new FCKToolbarButton( 'Print'		, FCKLang.Print, null, null, false, true, 12 ) ; break ;
+		case 'SpellCheck'		: oItem = new FCKToolbarButton( 'SpellCheck', FCKLang.SpellCheck, null, null, null, null, 13 ) ; break ;
+		case 'Undo'				: oItem = new FCKToolbarButton( 'Undo'		, FCKLang.Undo, null, null, false, true, 14 ) ; break ;
+		case 'Redo'				: oItem = new FCKToolbarButton( 'Redo'		, FCKLang.Redo, null, null, false, true, 15 ) ; break ;
+		case 'SelectAll'		: oItem = new FCKToolbarButton( 'SelectAll'	, FCKLang.SelectAll, null, null, true, null, 18 ) ; break ;
+		case 'RemoveFormat'		: oItem = new FCKToolbarButton( 'RemoveFormat', FCKLang.RemoveFormat, null, null, false, true, 19 ) ; break ;
+		case 'FitWindow'		: oItem = new FCKToolbarButton( 'FitWindow'	, FCKLang.FitWindow, null, null, true, true, 66 ) ; break ;
+
+		case 'Bold'				: oItem = new FCKToolbarButton( 'Bold'		, FCKLang.Bold, null, null, false, true, 20 ) ; break ;
+		case 'Italic'			: oItem = new FCKToolbarButton( 'Italic'	, FCKLang.Italic, null, null, false, true, 21 ) ; break ;
+		case 'Underline'		: oItem = new FCKToolbarButton( 'Underline'	, FCKLang.Underline, null, null, false, true, 22 ) ; break ;
+		case 'StrikeThrough'	: oItem = new FCKToolbarButton( 'StrikeThrough'	, FCKLang.StrikeThrough, null, null, false, true, 23 ) ; break ;
+		case 'Subscript'		: oItem = new FCKToolbarButton( 'Subscript'		, FCKLang.Subscript, null, null, false, true, 24 ) ; break ;
+		case 'Superscript'		: oItem = new FCKToolbarButton( 'Superscript'	, FCKLang.Superscript, null, null, false, true, 25 ) ; break ;
+
+		case 'OrderedList'		: oItem = new FCKToolbarButton( 'InsertOrderedList'		, FCKLang.NumberedListLbl, FCKLang.NumberedList, null, false, true, 26 ) ; break ;
+		case 'UnorderedList'	: oItem = new FCKToolbarButton( 'InsertUnorderedList'	, FCKLang.BulletedListLbl, FCKLang.BulletedList, null, false, true, 27 ) ; break ;
+		case 'Outdent'			: oItem = new FCKToolbarButton( 'Outdent'	, FCKLang.DecreaseIndent, null, null, false, true, 28 ) ; break ;
+		case 'Indent'			: oItem = new FCKToolbarButton( 'Indent'	, FCKLang.IncreaseIndent, null, null, false, true, 29 ) ; break ;
+
+		case 'Link'				: oItem = new FCKToolbarButton( 'Link'		, FCKLang.InsertLinkLbl, FCKLang.InsertLink, null, false, true, 34 ) ; break ;
+		case 'Unlink'			: oItem = new FCKToolbarButton( 'Unlink'	, FCKLang.RemoveLink, null, null, false, true, 35 ) ; break ;
+		case 'Anchor'			: oItem = new FCKToolbarButton( 'Anchor'	, FCKLang.Anchor, null, null, null, null, 36 ) ; break ;
+
+		case 'Image'			: oItem = new FCKToolbarButton( 'Image'			, FCKLang.InsertImageLbl, FCKLang.InsertImage, null, false, true, 37 ) ; break ;
+		case 'Flash'			: oItem = new FCKToolbarButton( 'Flash'			, FCKLang.InsertFlashLbl, FCKLang.InsertFlash, null, false, true, 38 ) ; break ;
+		case 'Table'			: oItem = new FCKToolbarButton( 'Table'			, FCKLang.InsertTableLbl, FCKLang.InsertTable, null, false, true, 39 ) ; break ;
+		case 'SpecialChar'		: oItem = new FCKToolbarButton( 'SpecialChar'	, FCKLang.InsertSpecialCharLbl, FCKLang.InsertSpecialChar, null, false, true, 42 ) ; break ;
+		case 'Smiley'			: oItem = new FCKToolbarButton( 'Smiley'		, FCKLang.InsertSmileyLbl, FCKLang.InsertSmiley, null, false, true, 41 ) ; break ;
+		case 'PageBreak'		: oItem = new FCKToolbarButton( 'PageBreak'		, FCKLang.PageBreakLbl, FCKLang.PageBreak, null, false, true, 43 ) ; break ;
+
+		case 'Rule'				: oItem = new FCKToolbarButton( 'InsertHorizontalRule', FCKLang.InsertLineLbl, FCKLang.InsertLine, null, false, true, 40 ) ; break ;
+
+		case 'JustifyLeft'		: oItem = new FCKToolbarButton( 'JustifyLeft'	, FCKLang.LeftJustify, null, null, false, true, 30 ) ; break ;
+		case 'JustifyCenter'	: oItem = new FCKToolbarButton( 'JustifyCenter'	, FCKLang.CenterJustify, null, null, false, true, 31 ) ; break ;
+		case 'JustifyRight'		: oItem = new FCKToolbarButton( 'JustifyRight'	, FCKLang.RightJustify, null, null, false, true, 32 ) ; break ;
+		case 'JustifyFull'		: oItem = new FCKToolbarButton( 'JustifyFull'	, FCKLang.BlockJustify, null, null, false, true, 33 ) ; break ;
+
+		case 'Style'			: oItem = new FCKToolbarStyleCombo() ; break ;
+		case 'FontName'			: oItem = new FCKToolbarFontsCombo() ; break ;
+		case 'FontSize'			: oItem = new FCKToolbarFontSizeCombo() ; break ;
+		case 'FontFormat'		: oItem = new FCKToolbarFontFormatCombo() ; break ;
+
+		case 'TextColor'		: oItem = new FCKToolbarPanelButton( 'TextColor', FCKLang.TextColor, null, null, 45 ) ; break ;
+		case 'BGColor'			: oItem = new FCKToolbarPanelButton( 'BGColor'	, FCKLang.BGColor, null, null, 46 ) ; break ;
+
+		case 'Find'				: oItem = new FCKToolbarButton( 'Find'		, FCKLang.Find, null, null, null, null, 16 ) ; break ;
+		case 'Replace'			: oItem = new FCKToolbarButton( 'Replace'	, FCKLang.Replace, null, null, null, null, 17 ) ; break ;
+
+		case 'Form'				: oItem = new FCKToolbarButton( 'Form'			, FCKLang.Form, null, null, null, null, 48 ) ; break ;
+		case 'Checkbox'			: oItem = new FCKToolbarButton( 'Checkbox'		, FCKLang.Checkbox, null, null, null, null, 49 ) ; break ;
+		case 'Radio'			: oItem = new FCKToolbarButton( 'Radio'			, FCKLang.RadioButton, null, null, null, null, 50 ) ; break ;
+		case 'TextField'		: oItem = new FCKToolbarButton( 'TextField'		, FCKLang.TextField, null, null, null, null, 51 ) ; break ;
+		case 'Textarea'			: oItem = new FCKToolbarButton( 'Textarea'		, FCKLang.Textarea, null, null, null, null, 52 ) ; break ;
+		case 'HiddenField'		: oItem = new FCKToolbarButton( 'HiddenField'	, FCKLang.HiddenField, null, null, null, null, 56 ) ; break ;
+		case 'Button'			: oItem = new FCKToolbarButton( 'Button'		, FCKLang.Button, null, null, null, null, 54 ) ; break ;
+		case 'Select'			: oItem = new FCKToolbarButton( 'Select'		, FCKLang.SelectionField, null, null, null, null, 53 ) ; break ;
+		case 'ImageButton'		: oItem = new FCKToolbarButton( 'ImageButton'	, FCKLang.ImageButton, null, null, null, null, 55 ) ; break ;
+
+		default:
+			alert( FCKLang.UnknownToolbarItem.replace( /%1/g, itemName ) ) ;
+			return null ;
+	}
+
+	FCKToolbarItems.LoadedItems[ itemName ] = oItem ;
+
+	return oItem ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml_gecko.js	(revision 795)
@@ -0,0 +1,66 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKXHtml object, responsible for the XHTML operations.
+ * Gecko specific.
+ */
+
+FCKXHtml._GetMainXmlString = function()
+{
+	// Create the XMLSerializer.
+	var oSerializer = new XMLSerializer() ;
+
+	// Return the serialized XML as a string.
+	return oSerializer.serializeToString( this.MainNode ) ;
+}
+
+FCKXHtml._AppendAttributes = function( xmlNode, htmlNode, node )
+{
+	var aAttributes = htmlNode.attributes ;
+
+	for ( var n = 0 ; n < aAttributes.length ; n++ )
+	{
+		var oAttribute = aAttributes[n] ;
+
+		if ( oAttribute.specified )
+		{
+			var sAttName = oAttribute.nodeName.toLowerCase() ;
+			var sAttValue ;
+
+			// Ignore any attribute starting with "_fck".
+			if ( sAttName.StartsWith( '_fck' ) )
+				continue ;
+			// There is a bug in Mozilla that returns '_moz_xxx' attributes as specified.
+			else if ( sAttName.indexOf( '_moz' ) == 0 )
+				continue ;
+			// There are one cases (on Gecko) when the oAttribute.nodeValue must be used:
+			//		- for the "class" attribute
+			else if ( sAttName == 'class' )
+				sAttValue = oAttribute.nodeValue ;
+			// XHTML doens't support attribute minimization like "CHECKED". It must be trasformed to cheched="checked".
+			else if ( oAttribute.nodeValue === true )
+				sAttValue = sAttName ;
+			else
+				sAttValue = htmlNode.getAttribute( sAttName, 2 ) ;	// We must use getAttribute to get it exactly as it is defined.
+
+			this._AppendAttribute( node, sAttName, sAttValue ) ;
+		}
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckconfig.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckconfig.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckconfig.js	(revision 795)
@@ -0,0 +1,199 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Creates and initializes the FCKConfig object.
+ */
+
+var FCKConfig = FCK.Config = new Object() ;
+
+/*
+	For the next major version (probably 3.0) we should move all this stuff to
+	another dedicated object and leave FCKConfig as a holder object for settings only).
+*/
+
+// Editor Base Path
+if ( document.location.protocol == 'file:' )
+{
+	FCKConfig.BasePath = decodeURIComponent( document.location.pathname.substr(1) ) ;
+	FCKConfig.BasePath = FCKConfig.BasePath.replace( /\\/gi, '/' ) ;
+	FCKConfig.BasePath = 'file://' + FCKConfig.BasePath.substring(0,FCKConfig.BasePath.lastIndexOf('/')+1) ;
+	FCKConfig.FullBasePath = FCKConfig.BasePath ;
+}
+else
+{
+	FCKConfig.BasePath = document.location.pathname.substring(0,document.location.pathname.lastIndexOf('/')+1) ;
+	FCKConfig.FullBasePath = document.location.protocol + '//' + document.location.host + FCKConfig.BasePath ;
+}
+
+FCKConfig.EditorPath = FCKConfig.BasePath.replace( /editor\/$/, '' ) ;
+
+// There is a bug in Gecko. If the editor is hidden on startup, an error is
+// thrown when trying to get the screen dimentions.
+try
+{
+	FCKConfig.ScreenWidth	= screen.width ;
+	FCKConfig.ScreenHeight	= screen.height ;
+}
+catch (e)
+{
+	FCKConfig.ScreenWidth	= 800 ;
+	FCKConfig.ScreenHeight	= 600 ;
+}
+
+// Override the actual configuration values with the values passed throw the
+// hidden field "<InstanceName>___Config".
+FCKConfig.ProcessHiddenField = function()
+{
+	this.PageConfig = new Object() ;
+
+	// Get the hidden field.
+	var oConfigField = window.parent.document.getElementById( FCK.Name + '___Config' ) ;
+
+	// Do nothing if the config field was not defined.
+	if ( ! oConfigField ) return ;
+
+	var aCouples = oConfigField.value.split('&') ;
+
+	for ( var i = 0 ; i < aCouples.length ; i++ )
+	{
+		if ( aCouples[i].length == 0 )
+			continue ;
+
+		var aConfig = aCouples[i].split( '=' ) ;
+		var sKey = decodeURIComponent( aConfig[0] ) ;
+		var sVal = decodeURIComponent( aConfig[1] ) ;
+
+		if ( sKey == 'CustomConfigurationsPath' )	// The Custom Config File path must be loaded immediately.
+			FCKConfig[ sKey ] = sVal ;
+
+		else if ( sVal.toLowerCase() == "true" )	// If it is a boolean TRUE.
+			this.PageConfig[ sKey ] = true ;
+
+		else if ( sVal.toLowerCase() == "false" )	// If it is a boolean FALSE.
+			this.PageConfig[ sKey ] = false ;
+
+		else if ( sVal.length > 0 && !isNaN( sVal ) )	// If it is a number.
+			this.PageConfig[ sKey ] = parseInt( sVal, 10 ) ;
+
+		else										// In any other case it is a string.
+			this.PageConfig[ sKey ] = sVal ;
+	}
+}
+
+function FCKConfig_LoadPageConfig()
+{
+	var oPageConfig = FCKConfig.PageConfig ;
+	for ( var sKey in oPageConfig )
+		FCKConfig[ sKey ] = oPageConfig[ sKey ] ;
+}
+
+function FCKConfig_PreProcess()
+{
+	var oConfig = FCKConfig ;
+
+	// Force debug mode if fckdebug=true in the QueryString (main page).
+	if ( oConfig.AllowQueryStringDebug )
+	{
+		try
+		{
+			if ( (/fckdebug=true/i).test( window.top.location.search ) )
+				oConfig.Debug = true ;
+		}
+		catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }
+	}
+
+	// Certifies that the "PluginsPath" configuration ends with a slash.
+	if ( !oConfig.PluginsPath.EndsWith('/') )
+		oConfig.PluginsPath += '/' ;
+
+	// EditorAreaCSS accepts an array of paths or a single path (as string).
+	// In the last case, transform it in an array.
+	if ( typeof( oConfig.EditorAreaCSS ) == 'string' )
+		oConfig.EditorAreaCSS = [ oConfig.EditorAreaCSS ] ;
+
+	var sComboPreviewCSS = oConfig.ToolbarComboPreviewCSS ;
+	if ( !sComboPreviewCSS || sComboPreviewCSS.length == 0 )
+		oConfig.ToolbarComboPreviewCSS = oConfig.EditorAreaCSS ;
+	else if ( typeof( sComboPreviewCSS ) == 'string' )
+		oConfig.ToolbarComboPreviewCSS = [ sComboPreviewCSS ] ;
+}
+
+// Define toolbar sets collection.
+FCKConfig.ToolbarSets = new Object() ;
+
+// Defines the plugins collection.
+FCKConfig.Plugins = new Object() ;
+FCKConfig.Plugins.Items = new Array() ;
+
+FCKConfig.Plugins.Add = function( name, langs, path )
+{
+	FCKConfig.Plugins.Items.AddItem( [name, langs, path] ) ;
+}
+
+// FCKConfig.ProtectedSource: object that holds a collection of Regular
+// Expressions that defined parts of the raw HTML that must remain untouched
+// like custom tags, scripts, server side code, etc...
+FCKConfig.ProtectedSource = new Object() ;
+
+// Initialize the regex array with the default ones.
+FCKConfig.ProtectedSource.RegexEntries = [
+	// First of any other protection, we must protect all comments to avoid
+	// loosing them (of course, IE related).
+	/<!--[\s\S]*?-->/g ,
+
+	// Script tags will also be forced to be protected, otherwise IE will execute them.
+	/<script[\s\S]*?<\/script>/gi,
+
+	// <noscript> tags (get lost in IE and messed up in FF).
+	/<noscript[\s\S]*?<\/noscript>/gi
+] ;
+
+FCKConfig.ProtectedSource.Add = function( regexPattern )
+{
+	this.RegexEntries.AddItem( regexPattern ) ;
+}
+
+FCKConfig.ProtectedSource.Protect = function( html )
+{
+	function _Replace( protectedSource )
+	{
+		var index = FCKTempBin.AddElement( protectedSource ) ;
+		return '<!--{PS..' + index + '}-->' ;
+	}
+
+	for ( var i = 0 ; i < this.RegexEntries.length ; i++ )
+	{
+		html = html.replace( this.RegexEntries[i], _Replace ) ;
+	}
+
+	return html ;
+}
+
+FCKConfig.ProtectedSource.Revert = function( html, clearBin )
+{
+	function _Replace( m, opener, index )
+	{
+		var protectedValue = clearBin ? FCKTempBin.RemoveElement( index ) : FCKTempBin.Elements[ index ] ;
+		// There could be protected source inside another one.
+		return FCKConfig.ProtectedSource.Revert( protectedValue, clearBin ) ;
+	}
+
+	return html.replace( /(<|&lt;)!--\{PS..(\d+)\}--(>|&gt;)/g, _Replace ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog_gecko.js	(revision 795)
@@ -0,0 +1,103 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Dialog windows operations. (Gecko specific implementations)
+ */
+
+FCKDialog.Show = function( dialogInfo, dialogName, pageUrl, dialogWidth, dialogHeight, parentWindow, resizable )
+{
+	var iTop  = (FCKConfig.ScreenHeight - dialogHeight) / 2 ;
+	var iLeft = (FCKConfig.ScreenWidth  - dialogWidth)  / 2 ;
+
+	var sOption  = "location=no,menubar=no,toolbar=no,dependent=yes,dialog=yes,minimizable=no,modal=yes,alwaysRaised=yes" +
+		",resizable="  + ( resizable ? 'yes' : 'no' ) +
+		",width="  + dialogWidth +
+		",height=" + dialogHeight +
+		",top="  + iTop +
+		",left=" + iLeft ;
+
+	if ( !parentWindow )
+		parentWindow = window ;
+
+	FCKFocusManager.Lock() ;
+
+	var oWindow = parentWindow.open( '', 'FCKeditorDialog_' + dialogName, sOption, true ) ;
+
+	if ( !oWindow )
+	{
+		alert( FCKLang.DialogBlocked ) ;
+		FCKFocusManager.Unlock() ;
+		return ;
+	}
+
+	oWindow.moveTo( iLeft, iTop ) ;
+	oWindow.resizeTo( dialogWidth, dialogHeight ) ;
+	oWindow.focus() ;
+	oWindow.location.href = pageUrl ;
+
+	oWindow.dialogArguments = dialogInfo ;
+
+	// On some Gecko browsers (probably over slow connections) the
+	// "dialogArguments" are not set to the target window so we must
+	// put it in the opener window so it can be used by the target one.
+	parentWindow.FCKLastDialogInfo = dialogInfo ;
+
+	this.Window = oWindow ;
+
+	// Try/Catch must be used to avoit an error when using a frameset
+	// on a different domain:
+	// "Permission denied to get property Window.releaseEvents".
+	try
+	{
+		window.top.parent.addEventListener( 'mousedown', this.CheckFocus, true ) ;
+		window.top.parent.addEventListener( 'mouseup', this.CheckFocus, true ) ;
+		window.top.parent.addEventListener( 'click', this.CheckFocus, true ) ;
+		window.top.parent.addEventListener( 'focus', this.CheckFocus, true ) ;
+	}
+	catch (e)
+	{}
+}
+
+FCKDialog.CheckFocus = function()
+{
+	// It is strange, but we have to check the FCKDialog existence to avoid a
+	// random error: "FCKDialog is not defined".
+	if ( typeof( FCKDialog ) != "object" )
+		return false ;
+
+	if ( FCKDialog.Window && !FCKDialog.Window.closed )
+		FCKDialog.Window.focus() ;
+	else
+	{
+		// Try/Catch must be used to avoit an error when using a frameset
+		// on a different domain:
+		// "Permission denied to get property Window.releaseEvents".
+		try
+		{
+			window.top.parent.removeEventListener( 'onmousedown', FCKDialog.CheckFocus, true ) ;
+			window.top.parent.removeEventListener( 'mouseup', FCKDialog.CheckFocus, true ) ;
+			window.top.parent.removeEventListener( 'click', FCKDialog.CheckFocus, true ) ;
+			window.top.parent.removeEventListener( 'onfocus', FCKDialog.CheckFocus, true ) ;
+		}
+		catch (e)
+		{}
+	}
+	return false ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools_gecko.js	(revision 795)
@@ -0,0 +1,235 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Utility functions. (Gecko version).
+ */
+
+FCKTools.CancelEvent = function( e )
+{
+	if ( e )
+		e.preventDefault() ;
+}
+
+FCKTools.DisableSelection = function( element )
+{
+	if ( FCKBrowserInfo.IsGecko )
+		element.style.MozUserSelect	= 'none' ;	// Gecko only.
+	else
+		element.style.userSelect	= 'none' ;	// CSS3 (not supported yet).
+}
+
+// Appends a CSS file to a document.
+FCKTools._AppendStyleSheet = function( documentElement, cssFileUrl )
+{
+	var e = documentElement.createElement( 'LINK' ) ;
+	e.rel	= 'stylesheet' ;
+	e.type	= 'text/css' ;
+	e.href	= cssFileUrl ;
+	documentElement.getElementsByTagName("HEAD")[0].appendChild( e ) ;
+	return e ;
+}
+
+// Removes all attributes and values from the element.
+FCKTools.ClearElementAttributes = function( element )
+{
+	// Loop throw all attributes in the element
+	for ( var i = 0 ; i < element.attributes.length ; i++ )
+	{
+		// Remove the element by name.
+		element.removeAttribute( element.attributes[i].name, 0 ) ;	// 0 : Case Insensitive
+	}
+}
+
+// Returns an Array of strings with all defined in the elements inside another element.
+FCKTools.GetAllChildrenIds = function( parentElement )
+{
+	// Create the array that will hold all Ids.
+	var aIds = new Array() ;
+
+	// Define a recursive function that search for the Ids.
+	var fGetIds = function( parent )
+	{
+		for ( var i = 0 ; i < parent.childNodes.length ; i++ )
+		{
+			var sId = parent.childNodes[i].id ;
+
+			// Check if the Id is defined for the element.
+			if ( sId && sId.length > 0 ) aIds[ aIds.length ] = sId ;
+
+			// Recursive call.
+			fGetIds( parent.childNodes[i] ) ;
+		}
+	}
+
+	// Start the recursive calls.
+	fGetIds( parentElement ) ;
+
+	return aIds ;
+}
+
+// Replaces a tag with its contents. For example "<span>My <b>tag</b></span>"
+// will be replaced with "My <b>tag</b>".
+FCKTools.RemoveOuterTags = function( e )
+{
+	var oFragment = e.ownerDocument.createDocumentFragment() ;
+
+	for ( var i = 0 ; i < e.childNodes.length ; i++ )
+		oFragment.appendChild( e.childNodes[i].cloneNode(true) ) ;
+
+	e.parentNode.replaceChild( oFragment, e ) ;
+}
+
+FCKTools.CreateXmlObject = function( object )
+{
+	switch ( object )
+	{
+		case 'XmlHttp' :
+			return new XMLHttpRequest() ;
+		case 'DOMDocument' :
+			return document.implementation.createDocument( '', '', null ) ;
+	}
+	return null ;
+}
+
+FCKTools.GetScrollPosition = function( relativeWindow )
+{
+	return { X : relativeWindow.pageXOffset, Y : relativeWindow.pageYOffset } ;
+}
+
+FCKTools.AddEventListener = function( sourceObject, eventName, listener )
+{
+	sourceObject.addEventListener( eventName, listener, false ) ;
+}
+
+FCKTools.RemoveEventListener = function( sourceObject, eventName, listener )
+{
+	sourceObject.removeEventListener( eventName, listener, false ) ;
+}
+
+// Listeners attached with this function cannot be detached.
+FCKTools.AddEventListenerEx = function( sourceObject, eventName, listener, paramsArray )
+{
+	sourceObject.addEventListener(
+		eventName,
+		function( e )
+		{
+			listener.apply( sourceObject, [ e ].concat( paramsArray || [] ) ) ;
+		},
+		false
+	) ;
+}
+
+// Returns and object with the "Width" and "Height" properties.
+FCKTools.GetViewPaneSize = function( win )
+{
+	return { Width : win.innerWidth, Height : win.innerHeight } ;
+}
+
+FCKTools.SaveStyles = function( element )
+{
+	var oSavedStyles = new Object() ;
+
+	if ( element.className.length > 0 )
+	{
+		oSavedStyles.Class = element.className ;
+		element.className = '' ;
+	}
+
+	var sInlineStyle = element.getAttribute( 'style' ) ;
+
+	if ( sInlineStyle && sInlineStyle.length > 0 )
+	{
+		oSavedStyles.Inline = sInlineStyle ;
+		element.setAttribute( 'style', '', 0 ) ;	// 0 : Case Insensitive
+	}
+
+	return oSavedStyles ;
+}
+
+FCKTools.RestoreStyles = function( element, savedStyles )
+{
+	element.className = savedStyles.Class || '' ;
+
+	if ( savedStyles.Inline )
+		element.setAttribute( 'style', savedStyles.Inline, 0 ) ;	// 0 : Case Insensitive
+	else
+		element.removeAttribute( 'style', 0 ) ;
+}
+
+FCKTools.RegisterDollarFunction = function( targetWindow )
+{
+	targetWindow.$ = function( id )
+	{
+		return this.document.getElementById( id ) ;
+	} ;
+}
+
+FCKTools.AppendElement = function( target, elementName )
+{
+	return target.appendChild( target.ownerDocument.createElement( elementName ) ) ;
+}
+
+// Get the coordinates of an element.
+//		@el : The element to get the position.
+//		@relativeWindow: The window to which we want the coordinates relative to.
+FCKTools.GetElementPosition = function( el, relativeWindow )
+{
+	// Initializes the Coordinates object that will be returned by the function.
+	var c = { X:0, Y:0 } ;
+
+	var oWindow = relativeWindow || window ;
+
+	var oOwnerWindow = FCKTools.GetElementWindow( el ) ;
+
+	// Loop throw the offset chain.
+	while ( el )
+	{
+		var sPosition = oOwnerWindow.getComputedStyle(el, '').position ;
+
+		// Check for non "static" elements.
+		// 'FCKConfig.FloatingPanelsZIndex' -- Submenus are under a positioned IFRAME.
+		if ( sPosition && sPosition != 'static' && el.style.zIndex != FCKConfig.FloatingPanelsZIndex )
+			break ;
+
+		c.X += el.offsetLeft - el.scrollLeft ;
+		c.Y += el.offsetTop - el.scrollTop  ;
+
+		if ( el.offsetParent )
+			el = el.offsetParent ;
+		else
+		{
+			if ( oOwnerWindow != oWindow )
+			{
+				el = oOwnerWindow.frameElement ;
+				if ( el )
+					oOwnerWindow = FCKTools.GetElementWindow( el ) ;
+			}
+			else
+			{
+				c.X += el.scrollLeft ;
+				c.Y += el.scrollTop  ;
+				break ;
+			}
+		}
+	}
+
+	// Return the Coordinates object
+	return c ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckxhtml_ie.js	(revision 795)
@@ -0,0 +1,194 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKXHtml object, responsible for the XHTML operations.
+ * IE specific.
+ */
+
+FCKXHtml._GetMainXmlString = function()
+{
+	return this.MainNode.xml ;
+}
+
+FCKXHtml._AppendAttributes = function( xmlNode, htmlNode, node, nodeName )
+{
+	var aAttributes = htmlNode.attributes ;
+
+	for ( var n = 0 ; n < aAttributes.length ; n++ )
+	{
+		var oAttribute = aAttributes[n] ;
+
+		if ( oAttribute.specified )
+		{
+			var sAttName = oAttribute.nodeName.toLowerCase() ;
+			var sAttValue ;
+
+			// Ignore any attribute starting with "_fck".
+			if ( sAttName.StartsWith( '_fck' ) )
+				continue ;
+			// The following must be done because of a bug on IE regarding the style
+			// attribute. It returns "null" for the nodeValue.
+			else if ( sAttName == 'style' )
+				sAttValue = htmlNode.style.cssText.replace( FCKRegexLib.StyleProperties, FCKTools.ToLowerCase ) ;
+			// There are two cases when the oAttribute.nodeValue must be used:
+			//		- for the "class" attribute
+			//		- for events attributes (on IE only).
+			else if ( sAttName == 'class' || sAttName.indexOf('on') == 0 )
+				sAttValue = oAttribute.nodeValue ;
+			else if ( nodeName == 'body' && sAttName == 'contenteditable' )
+				continue ;
+			// XHTML doens't support attribute minimization like "CHECKED". It must be trasformed to cheched="checked".
+			else if ( oAttribute.nodeValue === true )
+				sAttValue = sAttName ;
+			else
+			{
+				// We must use getAttribute to get it exactly as it is defined.
+				// There are some rare cases that IE throws an error here, so we must try/catch.
+				try
+				{
+					sAttValue = htmlNode.getAttribute( sAttName, 2 ) ;
+				}
+				catch (e) {}
+			}
+			this._AppendAttribute( node, sAttName, sAttValue || oAttribute.nodeValue ) ;
+		}
+	}
+}
+
+FCKXHtml.TagProcessors['meta'] = function( node, htmlNode )
+{
+	var oHttpEquiv = node.attributes.getNamedItem( 'http-equiv' ) ;
+
+	if ( oHttpEquiv == null || oHttpEquiv.value.length == 0 )
+	{
+		// Get the http-equiv value from the outerHTML.
+		var sHttpEquiv = htmlNode.outerHTML.match( FCKRegexLib.MetaHttpEquiv ) ;
+
+		if ( sHttpEquiv )
+		{
+			sHttpEquiv = sHttpEquiv[1] ;
+			FCKXHtml._AppendAttribute( node, 'http-equiv', sHttpEquiv ) ;
+		}
+	}
+
+	return node ;
+}
+
+// IE automaticaly changes <FONT> tags to <FONT size=+0>.
+FCKXHtml.TagProcessors['font'] = function( node, htmlNode )
+{
+	if ( node.attributes.length == 0 )
+		node = FCKXHtml.XML.createDocumentFragment() ;
+
+	node = FCKXHtml._AppendChildNodes( node, htmlNode ) ;
+
+	return node ;
+}
+
+// IE doens't see the value attribute as an attribute for the <INPUT> tag.
+FCKXHtml.TagProcessors['input'] = function( node, htmlNode )
+{
+	if ( htmlNode.name )
+		FCKXHtml._AppendAttribute( node, 'name', htmlNode.name ) ;
+
+	if ( htmlNode.value && !node.attributes.getNamedItem( 'value' ) )
+		FCKXHtml._AppendAttribute( node, 'value', htmlNode.value ) ;
+
+	if ( !node.attributes.getNamedItem( 'type' ) )
+		FCKXHtml._AppendAttribute( node, 'type', 'text' ) ;
+
+	return node ;
+}
+
+// IE ignores the "SELECTED" attribute so we must add it manually.
+FCKXHtml.TagProcessors['option'] = function( node, htmlNode )
+{
+	if ( htmlNode.selected && !node.attributes.getNamedItem( 'selected' ) )
+		FCKXHtml._AppendAttribute( node, 'selected', 'selected' ) ;
+
+	node = FCKXHtml._AppendChildNodes( node, htmlNode ) ;
+
+	return node ;
+}
+
+// IE ignores the "COORDS" and "SHAPE" attribute so we must add it manually.
+FCKXHtml.TagProcessors['area'] = function( node, htmlNode )
+{
+	if ( ! node.attributes.getNamedItem( 'coords' ) )
+	{
+		var sCoords = htmlNode.getAttribute( 'coords', 2 ) ;
+		if ( sCoords && sCoords != '0,0,0' )
+			FCKXHtml._AppendAttribute( node, 'coords', sCoords ) ;
+	}
+
+	if ( ! node.attributes.getNamedItem( 'shape' ) )
+	{
+		var sShape = htmlNode.getAttribute( 'shape', 2 ) ;
+		if ( sShape && sShape.length > 0 )
+			FCKXHtml._AppendAttribute( node, 'shape', sShape ) ;
+	}
+
+	return node ;
+}
+
+FCKXHtml.TagProcessors['label'] = function( node, htmlNode )
+{
+	if ( htmlNode.htmlFor.length > 0 )
+		FCKXHtml._AppendAttribute( node, 'for', htmlNode.htmlFor ) ;
+
+	node = FCKXHtml._AppendChildNodes( node, htmlNode ) ;
+
+	return node ;
+}
+
+FCKXHtml.TagProcessors['form'] = function( node, htmlNode )
+{
+	if ( htmlNode.acceptCharset && htmlNode.acceptCharset.length > 0 && htmlNode.acceptCharset != 'UNKNOWN' )
+		FCKXHtml._AppendAttribute( node, 'accept-charset', htmlNode.acceptCharset ) ;
+
+	if ( htmlNode.name )
+		FCKXHtml._AppendAttribute( node, 'name', htmlNode.name ) ;
+
+	node = FCKXHtml._AppendChildNodes( node, htmlNode ) ;
+
+	return node ;
+}
+
+// IE doens't hold the name attribute as an attribute for the <TEXTAREA> and <SELECT> tags.
+FCKXHtml.TagProcessors['textarea'] = FCKXHtml.TagProcessors['select'] = function( node, htmlNode )
+{
+	if ( htmlNode.name )
+		FCKXHtml._AppendAttribute( node, 'name', htmlNode.name ) ;
+
+	node = FCKXHtml._AppendChildNodes( node, htmlNode ) ;
+
+	return node ;
+}
+
+// On very rare cases, IE is loosing the "align" attribute for DIV. (right align and apply bulleted list)
+FCKXHtml.TagProcessors['div'] = function( node, htmlNode )
+{
+	if ( htmlNode.align.length > 0 )
+		FCKXHtml._AppendAttribute( node, 'align', htmlNode.align ) ;
+
+	node = FCKXHtml._AppendChildNodes( node, htmlNode, true ) ;
+
+	return node ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklisthandler.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklisthandler.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklisthandler.js	(revision 795)
@@ -0,0 +1,152 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Tool object to manage HTML lists items (UL, OL and LI).
+ */
+
+var FCKListHandler =
+{
+	OutdentListItem : function( listItem )
+	{
+		var eParent = listItem.parentNode ;
+
+		// It may happen that a LI is not in a UL or OL (Orphan).
+		if ( eParent.tagName.toUpperCase().Equals( 'UL','OL' ) )
+		{
+			var oDocument = FCKTools.GetElementDocument( listItem ) ;
+			var oDogFrag = new FCKDocumentFragment( oDocument ) ;
+
+			// All children and successive siblings will be moved to a a DocFrag.
+			var eNextSiblings = oDogFrag.RootNode ;
+			var eHasLiSibling = false ;
+
+			// If we have nested lists inside it, let's move it to the list of siblings.
+			var eChildList = FCKDomTools.GetFirstChild( listItem, ['UL','OL'] ) ;
+			if ( eChildList )
+			{
+				eHasLiSibling = true ;
+
+				var eChild ;
+				// The extra () is to avoid a warning with strict error checking. This is ok.
+				while ( (eChild = eChildList.firstChild) )
+					eNextSiblings.appendChild( eChildList.removeChild( eChild ) ) ;
+
+				FCKDomTools.RemoveNode( eChildList ) ;
+			}
+
+			// Move all successive siblings.
+			var eSibling ;
+			var eHasSuccessiveLiSibling = false ;
+			// The extra () is to avoid a warning with strict error checking. This is ok.
+			while ( (eSibling = listItem.nextSibling) )
+			{
+				if ( !eHasLiSibling && eSibling.nodeType == 1 && eSibling.nodeName.toUpperCase() == 'LI' )
+					eHasSuccessiveLiSibling = eHasLiSibling = true ;
+
+				eNextSiblings.appendChild( eSibling.parentNode.removeChild( eSibling ) ) ;
+
+				// If a sibling is a incorrectly nested UL or OL, consider only its children.
+				if ( !eHasSuccessiveLiSibling && eSibling.nodeType == 1 && eSibling.nodeName.toUpperCase().Equals( 'UL','OL' ) )
+					FCKDomTools.RemoveNode( eSibling, true ) ;
+			}
+
+			// If we are in a list chain.
+			var sParentParentTag = eParent.parentNode.tagName.toUpperCase() ;
+			var bWellNested = ( sParentParentTag == 'LI' ) ;
+			if ( bWellNested || sParentParentTag.Equals( 'UL','OL' ) )
+			{
+				if ( eHasLiSibling )
+				{
+					var eChildList = eParent.cloneNode( false ) ;
+					oDogFrag.AppendTo( eChildList ) ;
+					listItem.appendChild( eChildList ) ;
+				}
+				else if ( bWellNested )
+					oDogFrag.InsertAfterNode( eParent.parentNode ) ;
+				else
+					oDogFrag.InsertAfterNode( eParent ) ;
+
+				// Move the LI after its parent.parentNode (the upper LI in the hierarchy).
+				if ( bWellNested )
+					FCKDomTools.InsertAfterNode( eParent.parentNode, eParent.removeChild( listItem ) ) ;
+				else
+					FCKDomTools.InsertAfterNode( eParent, eParent.removeChild( listItem ) ) ;
+			}
+			else
+			{
+				if ( eHasLiSibling )
+				{
+					var eNextList = eParent.cloneNode( false ) ;
+					oDogFrag.AppendTo( eNextList ) ;
+					FCKDomTools.InsertAfterNode( eParent, eNextList ) ;
+				}
+
+				var eBlock = oDocument.createElement( FCKConfig.EnterMode == 'p' ? 'p' : 'div' ) ;
+				FCKDomTools.MoveChildren( eParent.removeChild( listItem ), eBlock ) ;
+				FCKDomTools.InsertAfterNode( eParent, eBlock ) ;
+
+				if ( FCKConfig.EnterMode == 'br' )
+				{
+					// We need the bogus to make it work properly. In Gecko, we
+					// need it before the new block, on IE, after it.
+					if ( FCKBrowserInfo.IsGecko )
+						eBlock.parentNode.insertBefore( FCKTools.CreateBogusBR( oDocument ), eBlock ) ;
+					else
+						FCKDomTools.InsertAfterNode( eBlock, FCKTools.CreateBogusBR( oDocument ) ) ;
+
+					FCKDomTools.RemoveNode( eBlock, true ) ;
+				}
+			}
+
+			if ( this.CheckEmptyList( eParent ) )
+				FCKDomTools.RemoveNode( eParent, true ) ;
+		}
+	},
+
+	CheckEmptyList : function( listElement )
+	{
+		return ( FCKDomTools.GetFirstChild( listElement, 'LI' ) == null ) ;
+	},
+
+	// Check if the list has contents (excluding nested lists).
+	CheckListHasContents : function( listElement )
+	{
+		var eChildNode = listElement.firstChild ;
+
+		while ( eChildNode )
+		{
+			switch ( eChildNode.nodeType )
+			{
+				case 1 :
+					if ( !eChildNode.nodeName.IEquals( 'UL','LI' ) )
+						return true ;
+					break ;
+
+				case 3 :
+					if ( eChildNode.nodeValue.Trim().length > 0 )
+						return true ;
+			}
+
+			eChildNode = eChildNode.nextSibling ;
+		}
+
+		return false ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktools_ie.js	(revision 795)
@@ -0,0 +1,214 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Utility functions. (IE version).
+ */
+
+FCKTools.CancelEvent = function( e )
+{
+	return false ;
+}
+
+// Appends one or more CSS files to a document.
+FCKTools._AppendStyleSheet = function( documentElement, cssFileUrl )
+{
+	return documentElement.createStyleSheet( cssFileUrl ).owningElement ;
+}
+
+// Removes all attributes and values from the element.
+FCKTools.ClearElementAttributes = function( element )
+{
+	element.clearAttributes() ;
+}
+
+FCKTools.GetAllChildrenIds = function( parentElement )
+{
+	var aIds = new Array() ;
+	for ( var i = 0 ; i < parentElement.all.length ; i++ )
+	{
+		var sId = parentElement.all[i].id ;
+		if ( sId && sId.length > 0 )
+			aIds[ aIds.length ] = sId ;
+	}
+	return aIds ;
+}
+
+FCKTools.RemoveOuterTags = function( e )
+{
+	e.insertAdjacentHTML( 'beforeBegin', e.innerHTML ) ;
+	e.parentNode.removeChild( e ) ;
+}
+
+FCKTools.CreateXmlObject = function( object )
+{
+	var aObjs ;
+
+	switch ( object )
+	{
+		case 'XmlHttp' :
+			aObjs = [ 'MSXML2.XmlHttp', 'Microsoft.XmlHttp' ] ;
+			break ;
+
+		case 'DOMDocument' :
+			aObjs = [ 'MSXML2.DOMDocument', 'Microsoft.XmlDom' ] ;
+			break ;
+	}
+
+	for ( var i = 0 ; i < 2 ; i++ )
+	{
+		try { return new ActiveXObject( aObjs[i] ) ; }
+		catch (e)
+		{}
+	}
+
+	if ( FCKLang.NoActiveX )
+	{
+		alert( FCKLang.NoActiveX ) ;
+		FCKLang.NoActiveX = null ;
+	}
+	return null ;
+}
+
+FCKTools.DisableSelection = function( element )
+{
+	element.unselectable = 'on' ;
+
+	var e, i = 0 ;
+	// The extra () is to avoid a warning with strict error checking. This is ok.
+	while ( (e = element.all[ i++ ]) )
+	{
+		switch ( e.tagName )
+		{
+			case 'IFRAME' :
+			case 'TEXTAREA' :
+			case 'INPUT' :
+			case 'SELECT' :
+				/* Ignore the above tags */
+				break ;
+			default :
+				e.unselectable = 'on' ;
+		}
+	}
+}
+
+FCKTools.GetScrollPosition = function( relativeWindow )
+{
+	var oDoc = relativeWindow.document ;
+
+	// Try with the doc element.
+	var oPos = { X : oDoc.documentElement.scrollLeft, Y : oDoc.documentElement.scrollTop } ;
+
+	if ( oPos.X > 0 || oPos.Y > 0 )
+		return oPos ;
+
+	// If no scroll, try with the body.
+	return { X : oDoc.body.scrollLeft, Y : oDoc.body.scrollTop } ;
+}
+
+FCKTools.AddEventListener = function( sourceObject, eventName, listener )
+{
+	sourceObject.attachEvent( 'on' + eventName, listener ) ;
+}
+
+FCKTools.RemoveEventListener = function( sourceObject, eventName, listener )
+{
+	sourceObject.detachEvent( 'on' + eventName, listener ) ;
+}
+
+// Listeners attached with this function cannot be detached.
+FCKTools.AddEventListenerEx = function( sourceObject, eventName, listener, paramsArray )
+{
+	// Ok... this is a closures party, but is the only way to make it clean of memory leaks.
+	var o = new Object() ;
+	o.Source = sourceObject ;
+	o.Params = paramsArray || [] ;	// Memory leak if we have DOM objects here.
+	o.Listener = function( ev )
+	{
+		return listener.apply( o.Source, [ ev ].concat( o.Params ) ) ;
+	}
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( null, function() { o.Source = null ; o.Params = null ; } ) ;
+
+	sourceObject.attachEvent( 'on' + eventName, o.Listener ) ;
+
+	sourceObject = null ;	// Memory leak cleaner (because of the above closure).
+	paramsArray = null ;	// Memory leak cleaner (because of the above closure).
+}
+
+// Returns and object with the "Width" and "Height" properties.
+FCKTools.GetViewPaneSize = function( win )
+{
+	var oSizeSource ;
+
+	var oDoc = win.document.documentElement ;
+	if ( oDoc && oDoc.clientWidth )				// IE6 Strict Mode
+		oSizeSource = oDoc ;
+	else
+		oSizeSource = top.document.body ;		// Other IEs
+
+	if ( oSizeSource )
+		return { Width : oSizeSource.clientWidth, Height : oSizeSource.clientHeight } ;
+	else
+		return { Width : 0, Height : 0 } ;
+}
+
+FCKTools.SaveStyles = function( element )
+{
+	var oSavedStyles = new Object() ;
+
+	if ( element.className.length > 0 )
+	{
+		oSavedStyles.Class = element.className ;
+		element.className = '' ;
+	}
+
+	var sInlineStyle = element.style.cssText ;
+
+	if ( sInlineStyle.length > 0 )
+	{
+		oSavedStyles.Inline = sInlineStyle ;
+		element.style.cssText = '' ;
+	}
+
+	return oSavedStyles ;
+}
+
+FCKTools.RestoreStyles = function( element, savedStyles )
+{
+	element.className		= savedStyles.Class || '' ;
+	element.style.cssText	= savedStyles.Inline || '' ;
+}
+
+FCKTools.RegisterDollarFunction = function( targetWindow )
+{
+	targetWindow.$ = targetWindow.document.getElementById ;
+}
+
+FCKTools.AppendElement = function( target, elementName )
+{
+	return target.appendChild( this.GetElementDocument( target ).createElement( elementName ) ) ;
+}
+
+// This function may be used by Regex replacements.
+FCKTools.ToLowerCase = function( strValue )
+{
+	return strValue.toLowerCase() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck.js	(revision 795)
@@ -0,0 +1,859 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Creation and initialization of the "FCK" object. This is the main object
+ * that represents an editor instance.
+ */
+
+// FCK represents the active editor instance.
+var FCK =
+{
+	Name		: FCKURLParams[ 'InstanceName' ],
+	Status		: FCK_STATUS_NOTLOADED,
+	EditMode	: FCK_EDITMODE_WYSIWYG,
+	Toolbar		: null,
+	HasFocus	: false,
+
+	GetLinkedFieldValue : function()
+	{
+		return this.LinkedField.value ;
+	},
+
+	GetParentForm : function()
+	{
+		return this.LinkedField.form ;
+	} ,
+
+	// # START : IsDirty implementation
+
+	StartupValue : '',
+
+	IsDirty : function()
+	{
+		if ( this.EditMode == FCK_EDITMODE_SOURCE )
+			return ( this.StartupValue != this.EditingArea.Textarea.value ) ;
+		else
+			return ( this.StartupValue != this.EditorDocument.body.innerHTML ) ;
+	},
+
+	ResetIsDirty : function()
+	{
+		if ( this.EditMode == FCK_EDITMODE_SOURCE )
+			this.StartupValue = this.EditingArea.Textarea.value ;
+		else if ( this.EditorDocument.body )
+			this.StartupValue = this.EditorDocument.body.innerHTML ;
+	},
+
+	// # END : IsDirty implementation
+
+	StartEditor : function()
+	{
+		this.TempBaseTag = FCKConfig.BaseHref.length > 0 ? '<base href="' + FCKConfig.BaseHref + '" _fcktemp="true"></base>' : '' ;
+
+		// Setup the keystroke handler.
+		var oKeystrokeHandler = FCK.KeystrokeHandler = new FCKKeystrokeHandler() ;
+		oKeystrokeHandler.OnKeystroke = _FCK_KeystrokeHandler_OnKeystroke ;
+
+		oKeystrokeHandler.SetKeystrokes( FCKConfig.Keystrokes ) ;
+
+		// In IE7, if the editor tries to access the clipboard by code, a dialog is
+		// shown to the user asking if the application is allowed to access or not.
+		// Due to the IE implementation of it, the KeystrokeHandler will not work
+		//well in this case, so we must leave the pasting keys to have their default behavior.
+		if ( FCKBrowserInfo.IsIE7 )
+		{
+			if ( ( CTRL + 86 /*V*/ ) in oKeystrokeHandler.Keystrokes )
+				oKeystrokeHandler.SetKeystrokes( [ CTRL + 86, true ] ) ;
+
+			if ( ( SHIFT + 45 /*INS*/ ) in oKeystrokeHandler.Keystrokes )
+				oKeystrokeHandler.SetKeystrokes( [ SHIFT + 45, true ] ) ;
+		}
+
+		this.EditingArea = new FCKEditingArea( document.getElementById( 'xEditingArea' ) ) ;
+		this.EditingArea.FFSpellChecker = false ;
+
+		// Final setup of the lists lib.
+		FCKListsLib.Setup() ;
+
+		// Set the editor's startup contents
+		this.SetHTML( this.GetLinkedFieldValue(), true ) ;
+	},
+
+	Focus : function()
+	{
+		FCK.EditingArea.Focus() ;
+	},
+
+	SetStatus : function( newStatus )
+	{
+		this.Status = newStatus ;
+
+		if ( newStatus == FCK_STATUS_ACTIVE )
+		{
+			FCKFocusManager.AddWindow( window, true ) ;
+
+			if ( FCKBrowserInfo.IsIE )
+				FCKFocusManager.AddWindow( window.frameElement, true ) ;
+
+			// Force the focus in the editor.
+			if ( FCKConfig.StartupFocus )
+				FCK.Focus() ;
+		}
+
+		this.Events.FireEvent( 'OnStatusChange', newStatus ) ;
+	},
+
+	// Fixes the body by moving all inline and text nodes to appropriate block
+	// elements.
+	FixBody : function()
+	{
+		var sBlockTag = FCKConfig.EnterMode ;
+
+		// In 'br' mode, no fix must be done.
+		if ( sBlockTag != 'p' && sBlockTag != 'div' )
+			return ;
+
+		var oDocument = this.EditorDocument ;
+
+		if ( !oDocument )
+			return ;
+
+		var oBody = oDocument.body ;
+
+		if ( !oBody )
+			return ;
+
+		FCKDomTools.TrimNode( oBody ) ;
+
+		var oNode = oBody.firstChild ;
+		var oNewBlock ;
+
+		while ( oNode )
+		{
+			var bMoveNode = false ;
+
+			switch ( oNode.nodeType )
+			{
+				// Element Node.
+				case 1 :
+					if ( !FCKListsLib.BlockElements[ oNode.nodeName.toLowerCase() ] )
+						bMoveNode = true ;
+					break ;
+
+				// Text Node.
+				case 3 :
+					// Ignore space only or empty text.
+					if ( oNewBlock || oNode.nodeValue.Trim().length > 0 )
+						bMoveNode = true ;
+			}
+
+			if ( bMoveNode )
+			{
+				var oParent = oNode.parentNode ;
+
+				if ( !oNewBlock )
+					oNewBlock = oParent.insertBefore( oDocument.createElement( sBlockTag ), oNode ) ;
+
+				oNewBlock.appendChild( oParent.removeChild( oNode ) ) ;
+
+				oNode = oNewBlock.nextSibling ;
+			}
+			else
+			{
+				if ( oNewBlock )
+				{
+					FCKDomTools.TrimNode( oNewBlock ) ;
+					oNewBlock = null ;
+				}
+				oNode = oNode.nextSibling ;
+			}
+		}
+
+		if ( oNewBlock )
+			FCKDomTools.TrimNode( oNewBlock ) ;
+	},
+
+	GetXHTML : function( format )
+	{
+		// We assume that if the user is in source editing, the editor value must
+		// represent the exact contents of the source, as the user wanted it to be.
+		if ( FCK.EditMode == FCK_EDITMODE_SOURCE )
+				return FCK.EditingArea.Textarea.value ;
+
+		this.FixBody() ;
+
+		var sXHTML ;
+		var oDoc = FCK.EditorDocument ;
+
+		if ( !oDoc )
+			return null ;
+
+		if ( FCKConfig.FullPage )
+		{
+			sXHTML = FCKXHtml.GetXHTML( oDoc.getElementsByTagName( 'html' )[0], true, format ) ;
+
+			if ( FCK.DocTypeDeclaration && FCK.DocTypeDeclaration.length > 0 )
+				sXHTML = FCK.DocTypeDeclaration + '\n' + sXHTML ;
+
+			if ( FCK.XmlDeclaration && FCK.XmlDeclaration.length > 0 )
+				sXHTML = FCK.XmlDeclaration + '\n' + sXHTML ;
+		}
+		else
+		{
+			sXHTML = FCKXHtml.GetXHTML( oDoc.body, false, format ) ;
+
+			if ( FCKConfig.IgnoreEmptyParagraphValue && FCKRegexLib.EmptyOutParagraph.test( sXHTML ) )
+				sXHTML = '' ;
+		}
+
+		// Restore protected attributes.
+		sXHTML = FCK.ProtectEventsRestore( sXHTML ) ;
+
+		if ( FCKBrowserInfo.IsIE )
+			sXHTML = sXHTML.replace( FCKRegexLib.ToReplace, '$1' ) ;
+
+		return FCKConfig.ProtectedSource.Revert( sXHTML ) ;
+	},
+
+	UpdateLinkedField : function()
+	{
+		FCK.LinkedField.value = FCK.GetXHTML( FCKConfig.FormatOutput ) ;
+		FCK.Events.FireEvent( 'OnAfterLinkedFieldUpdate' ) ;
+	},
+
+	RegisteredDoubleClickHandlers : new Object(),
+
+	OnDoubleClick : function( element )
+	{
+		var oHandler = FCK.RegisteredDoubleClickHandlers[ element.tagName ] ;
+		if ( oHandler )
+			oHandler( element ) ;
+	},
+
+	// Register objects that can handle double click operations.
+	RegisterDoubleClickHandler : function( handlerFunction, tag )
+	{
+		FCK.RegisteredDoubleClickHandlers[ tag.toUpperCase() ] = handlerFunction ;
+	},
+
+	OnAfterSetHTML : function()
+	{
+		FCKDocumentProcessor.Process( FCK.EditorDocument ) ;
+		FCKUndo.SaveUndoStep() ;
+
+		FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+		FCK.Events.FireEvent( 'OnAfterSetHTML' ) ;
+	},
+
+	// Saves URLs on links and images on special attributes, so they don't change when
+	// moving around.
+	ProtectUrls : function( html )
+	{
+		// <A> href
+		html = html.replace( FCKRegexLib.ProtectUrlsA	, '$& _fcksavedurl=$1' ) ;
+
+		// <IMG> src
+		html = html.replace( FCKRegexLib.ProtectUrlsImg	, '$& _fcksavedurl=$1' ) ;
+
+		return html ;
+	},
+
+	// Saves event attributes (like onclick) so they don't get executed while
+	// editing.
+	ProtectEvents : function( html )
+	{
+		return html.replace( FCKRegexLib.TagsWithEvent, _FCK_ProtectEvents_ReplaceTags ) ;
+	},
+
+	ProtectEventsRestore : function( html )
+	{
+		return html.replace( FCKRegexLib.ProtectedEvents, _FCK_ProtectEvents_RestoreEvents ) ;
+	},
+
+	ProtectTags : function( html )
+	{
+		var sTags = FCKConfig.ProtectedTags ;
+
+		// IE doesn't support <abbr> and it breaks it. Let's protect it.
+		if ( FCKBrowserInfo.IsIE )
+			sTags += sTags.length > 0 ? '|ABBR' : 'ABBR' ;
+		
+		var oRegex ;
+		if ( sTags.length > 0 )
+		{
+			oRegex = new RegExp( '<(' + sTags + ')(?!\w|:)', 'gi' ) ;
+			html = html.replace( oRegex, '<FCK:$1' ) ;
+
+			oRegex = new RegExp( '<\/(' + sTags + ')>', 'gi' ) ;
+			html = html.replace( oRegex, '<\/FCK:$1>' ) ;
+		}
+		
+		// Protect some empty elements. We must do it separately becase the
+		// original tag may not contain the closing slash, like <hr>:
+		//		- <meta> tags get executed, so if you have a redirect meta, the
+		//		  content will move to the target page.
+		//		- <hr> may destroy the document structure if not well
+		//		  positioned. The trick is protect it here and restore them in
+		//		  the FCKDocumentProcessor.
+		sTags = 'META' ;
+		if ( FCKBrowserInfo.IsIE )
+			sTags += '|HR' ;
+
+		oRegex = new RegExp( '<((' + sTags + ')(?=\s|>)[\s\S]*?)/?>', 'gi' ) ;
+		html = html.replace( oRegex, '<FCK:$1 />' ) ;
+
+		return html ;
+	},
+
+	SetHTML : function( html, resetIsDirty )
+	{
+		this.EditingArea.Mode = FCK.EditMode ;
+
+		if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+		{
+			html = FCKConfig.ProtectedSource.Protect( html ) ;
+
+			// Fix for invalid self-closing tags (see #152).
+			html = html.replace( FCKRegexLib.InvalidSelfCloseTags, '$1></$2>' ) ;
+
+			html = FCK.ProtectEvents( html ) ;
+			html = FCK.ProtectUrls( html ) ;
+			html = FCK.ProtectTags( html ) ;
+
+			// Firefox can't handle correctly the editing of the STRONG and EM tags.
+			// We must replace them with B and I.
+			if ( FCKBrowserInfo.IsGecko )
+			{
+				html = html.replace( FCKRegexLib.StrongOpener, '<b$1' ) ;
+				html = html.replace( FCKRegexLib.StrongCloser, '<\/b>' ) ;
+				html = html.replace( FCKRegexLib.EmOpener, '<i$1' ) ;
+				html = html.replace( FCKRegexLib.EmCloser, '<\/i>' ) ;
+			}
+
+			this._ForceResetIsDirty = ( resetIsDirty === true ) ;
+
+			var sHtml = '' ;
+
+			if ( FCKConfig.FullPage )
+			{
+				// The HTML must be fixed if the <head> is not available.
+				if ( !FCKRegexLib.HeadOpener.test( html ) )
+				{
+					// Check if the <html> is available.
+					if ( !FCKRegexLib.HtmlOpener.test( html ) )
+						html = '<html dir="' + FCKConfig.ContentLangDirection + '">' + html + '</html>' ;
+
+					// Add the <head>.
+					html = html.replace( FCKRegexLib.HtmlOpener, '$&<head></head>' ) ;
+				}
+
+				// Save the DOCTYPE.
+				FCK.DocTypeDeclaration = html.match( FCKRegexLib.DocTypeTag ) ;
+
+				if ( FCKBrowserInfo.IsIE )
+					sHtml = FCK._GetBehaviorsStyle() ;
+				else if ( FCKConfig.ShowBorders )
+					sHtml = '<link href="' + FCKConfig.FullBasePath + 'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />' ;
+
+				sHtml += '<link href="' + FCKConfig.FullBasePath + 'css/fck_internal.css' + '" rel="stylesheet" type="text/css" _fcktemp="true" />' ;
+
+				// Attention: do not change it before testing it well (sample07)!
+				// This is tricky... if the head ends with <meta ... content type>,
+				// Firefox will break. But, it works if we include the temporary
+				// links as the last elements in the HEAD.
+				sHtml = html.replace( FCKRegexLib.HeadCloser, sHtml + '$&' ) ;
+
+				// Insert the base tag (FCKConfig.BaseHref), if not exists in the source.
+				// The base must be the first tag in the HEAD, to get relative
+				// links on styles, for example.
+				if ( FCK.TempBaseTag.length > 0 && !FCKRegexLib.HasBaseTag.test( html ) )
+					sHtml = sHtml.replace( FCKRegexLib.HeadOpener, '$&' + FCK.TempBaseTag ) ;
+			}
+			else
+			{
+				sHtml =
+					FCKConfig.DocType +
+					'<html dir="' + FCKConfig.ContentLangDirection + '"' ;
+
+				// On IE, if you are use a DOCTYPE differenft of HTML 4 (like
+				// XHTML), you must force the vertical scroll to show, otherwise
+				// the horizontal one may appear when the page needs vertical scrolling.
+				if ( FCKBrowserInfo.IsIE && !FCKRegexLib.Html4DocType.test( FCKConfig.DocType ) )
+					sHtml += ' style="overflow-y: scroll"' ;
+
+				sHtml +=
+					'><head><title></title>' +
+					_FCK_GetEditorAreaStyleTags() +
+					'<link href="' + FCKConfig.FullBasePath + 'css/fck_internal.css' + '" rel="stylesheet" type="text/css" _fcktemp="true" />' ;
+
+				if ( FCKBrowserInfo.IsIE )
+					sHtml += FCK._GetBehaviorsStyle() ;
+				else if ( FCKConfig.ShowBorders )
+					sHtml += '<link href="' + FCKConfig.FullBasePath + 'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />' ;
+
+				sHtml += FCK.TempBaseTag ;
+
+				// Add ID and Class to the body
+				var sBodyTag = '<body' ;
+				if ( FCKConfig.BodyId && FCKConfig.BodyId.length > 0 )
+					sBodyTag += ' id="' + FCKConfig.BodyId + '"' ;
+				if ( FCKConfig.BodyClass && FCKConfig.BodyClass.length > 0 )
+					sBodyTag += ' class="' + FCKConfig.BodyClass + '"' ;
+				sHtml += '</head>' + sBodyTag + '>' ;
+
+				if ( FCKBrowserInfo.IsGecko && ( html.length == 0 || FCKRegexLib.EmptyParagraph.test( html ) ) )
+					sHtml += GECKO_BOGUS ;
+				else
+					sHtml += html ;
+
+				sHtml += '</body></html>' ;
+			}
+
+			this.EditingArea.OnLoad = _FCK_EditingArea_OnLoad ;
+			this.EditingArea.Start( sHtml ) ;
+		}
+		else
+		{
+			// Remove the references to the following elements, as the editing area
+			// IFRAME will be removed.
+			FCK.EditorWindow	= null ;
+			FCK.EditorDocument	= null ;
+
+			this.EditingArea.OnLoad = null ;
+			this.EditingArea.Start( html ) ;
+
+			// Enables the context menu in the textarea.
+			this.EditingArea.Textarea._FCKShowContextMenu = true ;
+
+			// Removes the enter key handler.
+			FCK.EnterKeyHandler = null ;
+
+			if ( resetIsDirty )
+				this.ResetIsDirty() ;
+
+			// Listen for keystroke events.
+			FCK.KeystrokeHandler.AttachToElement( this.EditingArea.Textarea ) ;
+
+			this.EditingArea.Textarea.focus() ;
+
+			FCK.Events.FireEvent( 'OnAfterSetHTML' ) ;
+		}
+
+		if ( FCKBrowserInfo.IsGecko )
+			window.onresize() ;
+	},
+
+	// For the FocusManager
+	HasFocus : false,
+
+
+	// This collection is used by the browser specific implementations to tell
+	// wich named commands must be handled separately.
+	RedirectNamedCommands : new Object(),
+
+	ExecuteNamedCommand : function( commandName, commandParameter, noRedirect )
+	{
+		FCKUndo.SaveUndoStep() ;
+
+		if ( !noRedirect && FCK.RedirectNamedCommands[ commandName ] != null )
+			FCK.ExecuteRedirectedNamedCommand( commandName, commandParameter ) ;
+		else
+		{
+			FCK.Focus() ;
+			FCK.EditorDocument.execCommand( commandName, false, commandParameter ) ;
+			FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+		}
+
+		FCKUndo.SaveUndoStep() ;
+	},
+
+	GetNamedCommandState : function( commandName )
+	{
+		try
+		{
+
+			if ( !FCK.EditorDocument.queryCommandEnabled( commandName ) )
+				return FCK_TRISTATE_DISABLED ;
+			else
+				return FCK.EditorDocument.queryCommandState( commandName ) ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF ;
+		}
+		catch ( e )
+		{
+			return FCK_TRISTATE_OFF ;
+		}
+	},
+
+	GetNamedCommandValue : function( commandName )
+	{
+		var sValue = '' ;
+		var eState = FCK.GetNamedCommandState( commandName ) ;
+
+		if ( eState == FCK_TRISTATE_DISABLED )
+			return null ;
+
+		try
+		{
+			sValue = this.EditorDocument.queryCommandValue( commandName ) ;
+		}
+		catch(e) {}
+
+		return sValue ? sValue : '' ;
+	},
+
+	PasteFromWord : function()
+	{
+		FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteFromWord, 'dialog/fck_paste.html', 400, 330, 'Word' ) ;
+	},
+
+	Preview : function()
+	{
+		var iWidth	= FCKConfig.ScreenWidth * 0.8 ;
+		var iHeight	= FCKConfig.ScreenHeight * 0.7 ;
+		var iLeft	= ( FCKConfig.ScreenWidth - iWidth ) / 2 ;
+		var oWindow = window.open( '', null, 'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width=' + iWidth + ',height=' + iHeight + ',left=' + iLeft ) ;
+
+		var sHTML ;
+
+		if ( FCKConfig.FullPage )
+		{
+			if ( FCK.TempBaseTag.length > 0 )
+				sHTML = FCK.TempBaseTag + FCK.GetXHTML() ;
+			else
+				sHTML = FCK.GetXHTML() ;
+		}
+		else
+		{
+			sHTML =
+				FCKConfig.DocType +
+				'<html dir="' + FCKConfig.ContentLangDirection + '">' +
+				'<head>' +
+				FCK.TempBaseTag +
+				'<title>' + FCKLang.Preview + '</title>' +
+				_FCK_GetEditorAreaStyleTags() +
+				'</head><body>' +
+				FCK.GetXHTML() +
+				'</body></html>' ;
+		}
+
+		oWindow.document.write( sHTML );
+		oWindow.document.close();
+	},
+
+	SwitchEditMode : function( noUndo )
+	{
+		var bIsWysiwyg = ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ) ;
+
+		// Save the current IsDirty state, so we may restore it after the switch.
+		var bIsDirty = FCK.IsDirty() ;
+
+		var sHtml ;
+
+		// Update the HTML in the view output to show.
+		if ( bIsWysiwyg )
+		{
+			if ( !noUndo && FCKBrowserInfo.IsIE )
+				FCKUndo.SaveUndoStep() ;
+
+			sHtml = FCK.GetXHTML( FCKConfig.FormatSource ) ;
+
+			if ( sHtml == null )
+				return false ;
+		}
+		else
+			sHtml = this.EditingArea.Textarea.value ;
+
+		FCK.EditMode = bIsWysiwyg ? FCK_EDITMODE_SOURCE : FCK_EDITMODE_WYSIWYG ;
+
+		FCK.SetHTML( sHtml, !bIsDirty ) ;
+
+		// Set the Focus.
+		FCK.Focus() ;
+
+		// Update the toolbar (Running it directly causes IE to fail).
+		FCKTools.RunFunction( FCK.ToolbarSet.RefreshModeState, FCK.ToolbarSet ) ;
+
+		return true ;
+	},
+
+	CreateElement : function( tag )
+	{
+		var e = FCK.EditorDocument.createElement( tag ) ;
+		return FCK.InsertElementAndGetIt( e ) ;
+	},
+
+	InsertElementAndGetIt : function( e )
+	{
+		e.setAttribute( 'FCKTempLabel', 'true' ) ;
+
+		this.InsertElement( e ) ;
+
+		var aEls = FCK.EditorDocument.getElementsByTagName( e.tagName ) ;
+
+		for ( var i = 0 ; i < aEls.length ; i++ )
+		{
+			if ( aEls[i].getAttribute( 'FCKTempLabel' ) )
+			{
+				aEls[i].removeAttribute( 'FCKTempLabel' ) ;
+				return aEls[i] ;
+			}
+		}
+		return null ;
+	}
+
+} ;
+
+FCK.Events	= new FCKEvents( FCK ) ;
+// GetHTML is Deprecated : returns the same value as GetXHTML.
+FCK.GetHTML	= FCK.GetXHTML ;
+
+// Replace all events attributes (like onclick).
+function _FCK_ProtectEvents_ReplaceTags( tagMatch )
+{
+	return tagMatch.replace( FCKRegexLib.EventAttributes, _FCK_ProtectEvents_ReplaceEvents ) ;
+}
+
+// Replace an event attribute with its respective __fckprotectedatt attribute.
+// The original event markup will be encoded and saved as the value of the new
+// attribute.
+function _FCK_ProtectEvents_ReplaceEvents( eventMatch, attName )
+{
+	return ' ' + attName + '_fckprotectedatt="' + eventMatch.ReplaceAll( [/&/g,/'/g,/"/g,/=/g,/</g,/>/g,/\r/g,/\n/g], ['&apos;','&#39;','&quot;','&#61;','&lt;','&gt;','&#10;','&#13;'] ) + '"' ;
+}
+
+function _FCK_ProtectEvents_RestoreEvents( match, encodedOriginal )
+{
+	return encodedOriginal.ReplaceAll( [/&#39;/g,/&quot;/g,/&#61;/g,/&lt;/g,/&gt;/g,/&#10;/g,/&#13;/g,/&apos;/g], ["'",'"','=','<','>','\r','\n','&'] ) ;
+}
+
+function _FCK_EditingArea_OnLoad()
+{
+	// Get the editor's window and document (DOM)
+	FCK.EditorWindow	= FCK.EditingArea.Window ;
+	FCK.EditorDocument	= FCK.EditingArea.Document ;
+
+	FCK.InitializeBehaviors() ;
+
+	// Create the enter key handler
+	if ( !FCKConfig.DisableEnterKeyHandler )
+		FCK.EnterKeyHandler = new FCKEnterKey( FCK.EditorWindow, FCKConfig.EnterMode, FCKConfig.ShiftEnterMode ) ;
+
+	// Listen for keystroke events.
+	FCK.KeystrokeHandler.AttachToElement( FCK.EditorDocument ) ;
+
+	if ( FCK._ForceResetIsDirty )
+		FCK.ResetIsDirty() ;
+
+	// This is a tricky thing for IE. In some cases, even if the cursor is
+	// blinking in the editing, the keystroke handler doesn't catch keyboard
+	// events. We must activate the editing area to make it work. (#142).
+	if ( FCKBrowserInfo.IsIE && FCK.HasFocus )
+		FCK.EditorDocument.body.setActive() ;
+
+	FCK.OnAfterSetHTML() ;
+
+	// Check if it is not a startup call, otherwise complete the startup.
+	if ( FCK.Status != FCK_STATUS_NOTLOADED )
+		return ;
+
+	FCK.SetStatus( FCK_STATUS_ACTIVE ) ;
+}
+
+function _FCK_GetEditorAreaStyleTags()
+{
+	var sTags = '' ;
+	var aCSSs = FCKConfig.EditorAreaCSS ;
+
+	for ( var i = 0 ; i < aCSSs.length ; i++ )
+		sTags += '<link href="' + aCSSs[i] + '" rel="stylesheet" type="text/css" />' ;
+
+	return sTags ;
+}
+
+function _FCK_KeystrokeHandler_OnKeystroke( keystroke, keystrokeValue )
+{
+	if ( FCK.Status != FCK_STATUS_COMPLETE )
+		return false ;
+
+	if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+	{
+		if ( keystrokeValue == 'Paste' )
+			return !FCK.Events.FireEvent( 'OnPaste' ) ;
+	}
+	else
+	{
+		// In source mode, some actions must have their default behavior.
+		if ( keystrokeValue.Equals( 'Paste', 'Undo', 'Redo', 'SelectAll' ) )
+			return false ;
+	}
+
+	// The return value indicates if the default behavior of the keystroke must
+	// be cancelled. Let's do that only if the Execute() call explicitelly returns "false".
+	var oCommand = FCK.Commands.GetCommand( keystrokeValue ) ;
+	return ( oCommand.Execute.apply( oCommand, FCKTools.ArgumentsToArray( arguments, 2 ) ) !== false ) ;
+}
+
+// Set the FCK.LinkedField reference to the field that will be used to post the
+// editor data.
+(function()
+{
+	// There is a bug on IE... getElementById returns any META tag that has the
+	// name set to the ID you are looking for. So the best way in to get the array
+	// by names and look for the correct one.
+	// As ASP.Net generates a ID that is different from the Name, we must also
+	// look for the field based on the ID (the first one is the ID).
+
+	var oDocument = window.parent.document ;
+
+	// Try to get the field using the ID.
+	var eLinkedField = oDocument.getElementById( FCK.Name ) ;
+
+	var i = 0;
+	while ( eLinkedField || i == 0 )
+	{
+		if ( eLinkedField && eLinkedField.tagName.toLowerCase().Equals( 'input', 'textarea' ) )
+		{
+			FCK.LinkedField = eLinkedField ;
+			break ;
+		}
+
+		eLinkedField = oDocument.getElementsByName( FCK.Name )[i++] ;
+	}
+})() ;
+
+var FCKTempBin =
+{
+	Elements : new Array(),
+
+	AddElement : function( element )
+	{
+		var iIndex = this.Elements.length ;
+		this.Elements[ iIndex ] = element ;
+		return iIndex ;
+	},
+
+	RemoveElement : function( index )
+	{
+		var e = this.Elements[ index ] ;
+		this.Elements[ index ] = null ;
+		return e ;
+	},
+
+	Reset : function()
+	{
+		var i = 0 ;
+		while ( i < this.Elements.length )
+			this.Elements[ i++ ] == null ;
+		this.Elements.length = 0 ;
+	}
+} ;
+
+
+
+// # Focus Manager: Manages the focus in the editor.
+var FCKFocusManager = FCK.FocusManager =
+{
+	IsLocked : false,
+
+	AddWindow : function( win, sendToEditingArea )
+	{
+		var oTarget ;
+
+		if ( FCKBrowserInfo.IsIE )
+			oTarget = win.nodeType == 1 ? win : win.frameElement ? win.frameElement : win.document ;
+		else
+			oTarget = win.document ;
+
+		FCKTools.AddEventListener( oTarget, 'blur', FCKFocusManager_Win_OnBlur ) ;
+		FCKTools.AddEventListener( oTarget, 'focus', sendToEditingArea ? FCKFocusManager_Win_OnFocus_Area : FCKFocusManager_Win_OnFocus ) ;
+	},
+
+	RemoveWindow : function( win )
+	{
+		if ( FCKBrowserInfo.IsIE )
+			oTarget = win.nodeType == 1 ? win : win.frameElement ? win.frameElement : win.document ;
+		else
+			oTarget = win.document ;
+
+		FCKTools.RemoveEventListener( oTarget, 'blur', FCKFocusManager_Win_OnBlur ) ;
+		FCKTools.RemoveEventListener( oTarget, 'focus', FCKFocusManager_Win_OnFocus_Area ) ;
+		FCKTools.RemoveEventListener( oTarget, 'focus', FCKFocusManager_Win_OnFocus ) ;
+	},
+
+	Lock : function()
+	{
+		this.IsLocked = true ;
+	},
+
+	Unlock : function()
+	{
+		if ( this._HasPendingBlur )
+			FCKFocusManager._Timer = window.setTimeout( FCKFocusManager_FireOnBlur, 100 ) ;
+
+		this.IsLocked = false ;
+	},
+
+	_ResetTimer : function()
+	{
+		this._HasPendingBlur = false ;
+
+		if ( this._Timer )
+		{
+			window.clearTimeout( this._Timer ) ;
+			delete this._Timer ;
+		}
+	}
+} ;
+
+function FCKFocusManager_Win_OnBlur()
+{
+	if ( typeof(FCK) != 'undefined' && FCK.HasFocus )
+	{
+		FCKFocusManager._ResetTimer() ;
+		FCKFocusManager._Timer = window.setTimeout( FCKFocusManager_FireOnBlur, 100 ) ;
+	}
+}
+
+function FCKFocusManager_FireOnBlur()
+{
+	if ( FCKFocusManager.IsLocked )
+		FCKFocusManager._HasPendingBlur = true ;
+	else
+	{
+		FCK.HasFocus = false ;
+		FCK.Events.FireEvent( "OnBlur" ) ;
+	}
+}
+
+function FCKFocusManager_Win_OnFocus_Area()
+{
+	FCK.Focus() ;
+	FCKFocusManager_Win_OnFocus() ;
+}
+
+function FCKFocusManager_Win_OnFocus()
+{
+	FCKFocusManager._ResetTimer() ;
+
+	if ( !FCK.HasFocus && !FCKFocusManager.IsLocked )
+	{
+		FCK.HasFocus = true ;
+		FCK.Events.FireEvent( "OnFocus" ) ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckundo_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckundo_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckundo_ie.js	(revision 795)
@@ -0,0 +1,123 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * IE specific implementation for the Undo/Redo system.
+ */
+
+var FCKUndo = new Object() ;
+
+FCKUndo.SavedData = new Array() ;
+FCKUndo.CurrentIndex = -1 ;
+FCKUndo.TypesCount = FCKUndo.MaxTypes = 25 ;
+FCKUndo.Typing = false ;
+
+FCKUndo.SaveUndoStep = function()
+{
+	if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+		return ;
+
+	// Shrink the array to the current level.
+	FCKUndo.SavedData = FCKUndo.SavedData.slice( 0, FCKUndo.CurrentIndex + 1 ) ;
+
+	// Get the Actual HTML.
+	var sHtml = FCK.EditorDocument.body.innerHTML ;
+
+	// Cancel operation if the new step is identical to the previous one.
+	if ( FCKUndo.CurrentIndex >= 0 && sHtml == FCKUndo.SavedData[ FCKUndo.CurrentIndex ][0] )
+		return ;
+
+	// If we reach the Maximun number of undo levels, we must remove the first
+	// entry of the list shifting all elements.
+	if ( FCKUndo.CurrentIndex + 1 >= FCKConfig.MaxUndoLevels )
+		FCKUndo.SavedData.shift() ;
+	else
+		FCKUndo.CurrentIndex++ ;
+
+	// Get the actual selection.
+	var sBookmark ;
+	if ( FCK.EditorDocument.selection.type == 'Text' )
+		sBookmark = FCK.EditorDocument.selection.createRange().getBookmark() ;
+
+	// Save the new level in front of the actual position.
+	FCKUndo.SavedData[ FCKUndo.CurrentIndex ] = [ sHtml, sBookmark ] ;
+
+	FCK.Events.FireEvent( "OnSelectionChange" ) ;
+}
+
+FCKUndo.CheckUndoState = function()
+{
+	return ( FCKUndo.Typing || FCKUndo.CurrentIndex > 0 ) ;
+}
+
+FCKUndo.CheckRedoState = function()
+{
+	return ( !FCKUndo.Typing && FCKUndo.CurrentIndex < ( FCKUndo.SavedData.length - 1 ) ) ;
+}
+
+FCKUndo.Undo = function()
+{
+	if ( FCKUndo.CheckUndoState() )
+	{
+		// If it is the first step.
+		if ( FCKUndo.CurrentIndex == ( FCKUndo.SavedData.length - 1 ) )
+		{
+			// Save the actual state for a possible "Redo" call.
+			FCKUndo.SaveUndoStep() ;
+		}
+
+		// Go a step back.
+		FCKUndo._ApplyUndoLevel( --FCKUndo.CurrentIndex ) ;
+
+		FCK.Events.FireEvent( "OnSelectionChange" ) ;
+	}
+}
+
+FCKUndo.Redo = function()
+{
+	if ( FCKUndo.CheckRedoState() )
+	{
+		// Go a step forward.
+		FCKUndo._ApplyUndoLevel( ++FCKUndo.CurrentIndex ) ;
+
+		FCK.Events.FireEvent( "OnSelectionChange" ) ;
+	}
+}
+
+FCKUndo._ApplyUndoLevel = function(level)
+{
+	var oData = FCKUndo.SavedData[ level ] ;
+
+	if ( !oData )
+		return ;
+
+	// Update the editor contents with that step data.
+	FCK.SetInnerHtml( oData[0] ) ;
+//	FCK.EditorDocument.body.innerHTML = oData[0] ;
+
+	if ( oData[1] )
+	{
+		var oRange = FCK.EditorDocument.selection.createRange() ;
+		oRange.moveToBookmark( oData[1] ) ;
+		oRange.select() ;
+	}
+
+	FCKUndo.TypesCount = 0 ;
+	FCKUndo.Typing = false ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklistslib.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklistslib.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklistslib.js	(revision 795)
@@ -0,0 +1,60 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Library of keys collections.
+ *
+ * Test have shown that check for the existence of a key in an object is the
+ * most efficient list entry check (10x faster that regex). Example:
+ *		if ( FCKListsLib.<ListName>[key] != null )
+ */
+
+var FCKListsLib =
+{
+	// We are not handling <ins> and <del> as block elements, for now.
+	BlockElements : { address:1,blockquote:1,center:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },
+
+	// Block elements that may be filled with &nbsp; if empty.
+	NonEmptyBlockElements : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,address:1,pre:1,ol:1,ul:1,li:1,td:1,th:1 },
+
+	// Inline elements which MUST have child nodes.
+	InlineChildReqElements : { abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1 },
+
+	// Elements marked as empty "Empty" in the XHTML DTD.
+	EmptyElements : { base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 },
+	
+	// Elements that may be considered the "Block boundary" in an element path.
+	PathBlockElements : { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },
+	
+	// Elements that may be considered the "Block limit" in an element path.
+	PathBlockLimitElements : { body:1,td:1,th:1,caption:1,form:1 },
+
+	// Final setup of FCKListsLib once the editor is loaded (at FCK.StartEditor). 
+	// TODO: For v3, there should be a generic way to register to the editor
+	// startup event, so this function would not be needed to be defined here, not
+	// even be called at FCK.StartEditor.
+	Setup : function()
+	{
+		// <div> is considered a block element only if EnterMode=div, otherwise it is a block limit.
+		if ( FCKConfig.EnterMode == 'div' )
+			this.PathBlockElements.div = 1 ;
+		else
+			this.PathBlockLimitElements.div = 1 ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler.js	(revision 795)
@@ -0,0 +1,385 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Manage table operations.
+ */
+
+var FCKTableHandler = new Object() ;
+
+FCKTableHandler.InsertRow = function()
+{
+	// Get the row where the selection is placed in.
+	var oRow = FCKSelection.MoveToAncestorNode( 'TR' ) ;
+	if ( !oRow ) return ;
+
+	// Create a clone of the row.
+	var oNewRow = oRow.cloneNode( true ) ;
+
+	// Insert the new row (copy) before of it.
+	oRow.parentNode.insertBefore( oNewRow, oRow ) ;
+
+	// Clean the row (it seems that the new row has been added after it).
+	FCKTableHandler.ClearRow( oRow ) ;
+}
+
+FCKTableHandler.DeleteRows = function( row )
+{
+	// If no row has been passed as a parameter,
+	// then get the row where the selection is placed in.
+	if ( !row )
+		row = FCKSelection.MoveToAncestorNode( 'TR' ) ;
+	if ( !row ) return ;
+
+	// Get the row's table.
+	var oTable = FCKTools.GetElementAscensor( row, 'TABLE' ) ;
+
+	// If just one row is available then delete the entire table.
+	if ( oTable.rows.length == 1 )
+	{
+		FCKTableHandler.DeleteTable( oTable ) ;
+		return ;
+	}
+
+	// Delete the row.
+	row.parentNode.removeChild( row ) ;
+}
+
+FCKTableHandler.DeleteTable = function( table )
+{
+	// If no table has been passed as a parameer,
+	// then get the table where the selection is placed in.
+	if ( !table )
+	{
+		table = FCKSelection.GetSelectedElement() ;
+		if ( !table || table.tagName != 'TABLE' )
+			table = FCKSelection.MoveToAncestorNode( 'TABLE' ) ;
+	}
+	if ( !table ) return ;
+
+	// Delete the table.
+	FCKSelection.SelectNode( table ) ;
+	FCKSelection.Collapse();
+	table.parentNode.removeChild( table ) ;
+}
+
+FCKTableHandler.InsertColumn = function()
+{
+	// Get the cell where the selection is placed in.
+	var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ;
+
+	if ( !oCell ) return ;
+
+	// Get the cell's table.
+	var oTable = FCKTools.GetElementAscensor( oCell, 'TABLE' ) ;
+
+	// Get the index of the column to be created (based on the cell).
+	var iIndex = oCell.cellIndex + 1 ;
+
+	// Loop throw all rows available in the table.
+	for ( var i = 0 ; i < oTable.rows.length ; i++ )
+	{
+		// Get the row.
+		var oRow = oTable.rows[i] ;
+
+		// If the row doens't have enought cells, ignore it.
+		if ( oRow.cells.length < iIndex )
+			continue ;
+
+		oCell = oRow.cells[iIndex-1].cloneNode(false) ;
+
+		if ( FCKBrowserInfo.IsGecko )
+			oCell.innerHTML = GECKO_BOGUS ;
+
+		// Get the cell that is placed in the new cell place.
+		var oBaseCell = oRow.cells[iIndex] ;
+
+		// If the cell is available (we are not in the last cell of the row).
+		if ( oBaseCell )
+			oRow.insertBefore( oCell, oBaseCell ) ;	// Insert the new cell just before of it.
+		else
+			oRow.appendChild( oCell ) ;				// Append the cell at the end of the row.
+	}
+}
+
+FCKTableHandler.DeleteColumns = function()
+{
+	// Get the cell where the selection is placed in.
+	var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ;
+
+	if ( !oCell ) return ;
+
+	// Get the cell's table.
+	var oTable = FCKTools.GetElementAscensor( oCell, 'TABLE' ) ;
+
+	// Get the cell index.
+	var iIndex = oCell.cellIndex ;
+
+	// Loop throw all rows (from down to up, because it's possible that some
+	// rows will be deleted).
+	for ( var i = oTable.rows.length - 1 ; i >= 0 ; i-- )
+	{
+		// Get the row.
+		var oRow = oTable.rows[i] ;
+
+		// If the cell to be removed is the first one and the row has just one cell.
+		if ( iIndex == 0 && oRow.cells.length == 1 )
+		{
+			// Remove the entire row.
+			FCKTableHandler.DeleteRows( oRow ) ;
+			continue ;
+		}
+
+		// If the cell to be removed exists the delete it.
+		if ( oRow.cells[iIndex] )
+			oRow.removeChild( oRow.cells[iIndex] ) ;
+	}
+}
+
+FCKTableHandler.InsertCell = function( cell )
+{
+	// Get the cell where the selection is placed in.
+	var oCell = cell ? cell : FCKSelection.MoveToAncestorNode( 'TD' ) ;
+	if ( !oCell ) return null ;
+
+	// Create the new cell element to be added.
+	var oNewCell = FCK.EditorDocument.createElement( 'TD' ) ;
+	if ( FCKBrowserInfo.IsGecko )
+		oNewCell.innerHTML = GECKO_BOGUS ;
+//	oNewCell.innerHTML = "&nbsp;" ;
+
+	// If it is the last cell in the row.
+	if ( oCell.cellIndex == oCell.parentNode.cells.length - 1 )
+	{
+		// Add the new cell at the end of the row.
+		oCell.parentNode.appendChild( oNewCell ) ;
+	}
+	else
+	{
+		// Add the new cell before the next cell (after the active one).
+		oCell.parentNode.insertBefore( oNewCell, oCell.nextSibling ) ;
+	}
+
+	return oNewCell ;
+}
+
+FCKTableHandler.DeleteCell = function( cell )
+{
+	// If this is the last cell in the row.
+	if ( cell.parentNode.cells.length == 1 )
+	{
+		// Delete the entire row.
+		FCKTableHandler.DeleteRows( FCKTools.GetElementAscensor( cell, 'TR' ) ) ;
+		return ;
+	}
+
+	// Delete the cell from the row.
+	cell.parentNode.removeChild( cell ) ;
+}
+
+FCKTableHandler.DeleteCells = function()
+{
+	var aCells = FCKTableHandler.GetSelectedCells() ;
+
+	for ( var i = aCells.length - 1 ; i >= 0  ; i-- )
+	{
+		FCKTableHandler.DeleteCell( aCells[i] ) ;
+	}
+}
+
+FCKTableHandler.MergeCells = function()
+{
+	// Get all selected cells.
+	var aCells = FCKTableHandler.GetSelectedCells() ;
+
+	// At least 2 cells must be selected.
+	if ( aCells.length < 2 )
+		return ;
+
+	// The merge can occour only if the selected cells are from the same row.
+	if ( aCells[0].parentNode != aCells[aCells.length-1].parentNode )
+		return ;
+
+	// Calculate the new colSpan for the first cell.
+	var iColSpan = isNaN( aCells[0].colSpan ) ? 1 : aCells[0].colSpan ;
+
+	var sHtml = '' ;
+	var oCellsContents = FCK.EditorDocument.createDocumentFragment() ;
+
+	for ( var i = aCells.length - 1 ; i >= 0 ; i-- )
+	{
+		var eCell = aCells[i] ;
+
+		// Move its contents to the document fragment.
+		for ( var c = eCell.childNodes.length - 1 ; c >= 0 ; c-- )
+		{
+			var eChild = eCell.removeChild( eCell.childNodes[c] ) ;
+
+			if ( ( eChild.hasAttribute && eChild.hasAttribute('_moz_editor_bogus_node') ) || ( eChild.getAttribute && eChild.getAttribute( 'type', 2 ) == '_moz' ) )
+				continue ;
+
+				oCellsContents.insertBefore( eChild, oCellsContents.firstChild ) ;
+		}
+
+		if ( i > 0 )
+		{
+			// Accumulate the colspan of the cell.
+			iColSpan += isNaN( eCell.colSpan ) ? 1 : eCell.colSpan ;
+
+			// Delete the cell.
+			FCKTableHandler.DeleteCell( eCell ) ;
+		}
+	}
+
+	// Set the innerHTML of the remaining cell (the first one).
+	aCells[0].colSpan = iColSpan ;
+
+	if ( FCKBrowserInfo.IsGecko && oCellsContents.childNodes.length == 0 )
+		aCells[0].innerHTML = GECKO_BOGUS ;
+	else
+		aCells[0].appendChild( oCellsContents ) ;
+}
+
+FCKTableHandler.SplitCell = function()
+{
+	// Check that just one cell is selected, otherwise return.
+	var aCells = FCKTableHandler.GetSelectedCells() ;
+	if ( aCells.length != 1 )
+		return ;
+
+	var aMap = this._CreateTableMap( aCells[0].parentNode.parentNode ) ;
+	var iCellIndex = FCKTableHandler._GetCellIndexSpan( aMap, aCells[0].parentNode.rowIndex , aCells[0] ) ;
+
+	var aCollCells = this._GetCollumnCells( aMap, iCellIndex ) ;
+
+	for ( var i = 0 ; i < aCollCells.length ; i++ )
+	{
+		if ( aCollCells[i] == aCells[0] )
+		{
+			var oNewCell = this.InsertCell( aCells[0] ) ;
+			if ( !isNaN( aCells[0].rowSpan ) && aCells[0].rowSpan > 1 )
+				oNewCell.rowSpan = aCells[0].rowSpan ;
+		}
+		else
+		{
+			if ( isNaN( aCollCells[i].colSpan ) )
+				aCollCells[i].colSpan = 2 ;
+			else
+				aCollCells[i].colSpan += 1 ;
+		}
+	}
+}
+
+// Get the cell index from a TableMap.
+FCKTableHandler._GetCellIndexSpan = function( tableMap, rowIndex, cell )
+{
+	if ( tableMap.length < rowIndex + 1 )
+		return null ;
+
+	var oRow = tableMap[ rowIndex ] ;
+
+	for ( var c = 0 ; c < oRow.length ; c++ )
+	{
+		if ( oRow[c] == cell )
+			return c ;
+	}
+
+	return null ;
+}
+
+// Get the cells available in a collumn of a TableMap.
+FCKTableHandler._GetCollumnCells = function( tableMap, collumnIndex )
+{
+	var aCollCells = new Array() ;
+
+	for ( var r = 0 ; r < tableMap.length ; r++ )
+	{
+		var oCell = tableMap[r][collumnIndex] ;
+		if ( oCell && ( aCollCells.length == 0 || aCollCells[ aCollCells.length - 1 ] != oCell ) )
+			aCollCells[ aCollCells.length ] = oCell ;
+	}
+
+	return aCollCells ;
+}
+
+// This function is quite hard to explain. It creates a matrix representing all cells in a table.
+// The difference here is that the "spanned" cells (colSpan and rowSpan) are duplicated on the matrix
+// cells that are "spanned". For example, a row with 3 cells where the second cell has colSpan=2 and rowSpan=3
+// will produce a bi-dimensional matrix with the following values (representing the cells):
+//		Cell1, Cell2, Cell2, Cell 3
+//		Cell4, Cell2, Cell2, Cell 5
+FCKTableHandler._CreateTableMap = function( table )
+{
+	var aRows = table.rows ;
+
+	// Row and Collumn counters.
+	var r = -1 ;
+
+	var aMap = new Array() ;
+
+	for ( var i = 0 ; i < aRows.length ; i++ )
+	{
+		r++ ;
+		if ( !aMap[r] )
+			aMap[r] = new Array() ;
+
+		var c = -1 ;
+
+		for ( var j = 0 ; j < aRows[i].cells.length ; j++ )
+		{
+			var oCell = aRows[i].cells[j] ;
+
+			c++ ;
+			while ( aMap[r][c] )
+				c++ ;
+
+			var iColSpan = isNaN( oCell.colSpan ) ? 1 : oCell.colSpan ;
+			var iRowSpan = isNaN( oCell.rowSpan ) ? 1 : oCell.rowSpan ;
+
+			for ( var rs = 0 ; rs < iRowSpan ; rs++ )
+			{
+				if ( !aMap[r + rs] )
+					aMap[r + rs] = new Array() ;
+
+				for ( var cs = 0 ; cs < iColSpan ; cs++ )
+				{
+					aMap[r + rs][c + cs] = aRows[i].cells[j] ;
+				}
+			}
+
+			c += iColSpan - 1 ;
+		}
+	}
+	return aMap ;
+}
+
+FCKTableHandler.ClearRow = function( tr )
+{
+	// Get the array of row's cells.
+	var aCells = tr.cells ;
+
+	// Replace the contents of each cell with "nothing".
+	for ( var i = 0 ; i < aCells.length ; i++ )
+	{
+		if ( FCKBrowserInfo.IsGecko )
+			aCells[i].innerHTML = GECKO_BOGUS ;
+		else
+			aCells[i].innerHTML = '' ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_gecko.js	(revision 795)
@@ -0,0 +1,254 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Creation and initialization of the "FCK" object. This is the main
+ * object that represents an editor instance.
+ * (Gecko specific implementations)
+ */
+
+FCK.Description = "FCKeditor for Gecko Browsers" ;
+
+FCK.InitializeBehaviors = function()
+{
+	// When calling "SetHTML", the editing area IFRAME gets a fixed height. So we must recaulculate it.
+	if ( FCKBrowserInfo.IsGecko )		// Not for Safari/Opera.
+		Window_OnResize() ;
+
+	FCKFocusManager.AddWindow( this.EditorWindow ) ;
+
+	this.ExecOnSelectionChange = function()
+	{
+		FCK.Events.FireEvent( "OnSelectionChange" ) ;
+	}
+
+	this.ExecOnSelectionChangeTimer = function()
+	{
+		if ( FCK.LastOnChangeTimer )
+			window.clearTimeout( FCK.LastOnChangeTimer ) ;
+
+		FCK.LastOnChangeTimer = window.setTimeout( FCK.ExecOnSelectionChange, 100 ) ;
+	}
+
+	this.EditorDocument.addEventListener( 'mouseup', this.ExecOnSelectionChange, false ) ;
+
+	// On Gecko, firing the "OnSelectionChange" event on every key press started to be too much
+	// slow. So, a timer has been implemented to solve performance issues when tipying to quickly.
+	this.EditorDocument.addEventListener( 'keyup', this.ExecOnSelectionChangeTimer, false ) ;
+
+	this._DblClickListener = function( e )
+	{
+		FCK.OnDoubleClick( e.target ) ;
+		e.stopPropagation() ;
+	}
+	this.EditorDocument.addEventListener( 'dblclick', this._DblClickListener, true ) ;
+
+	// Reset the context menu.
+	FCK.ContextMenu._InnerContextMenu.SetMouseClickWindow( FCK.EditorWindow ) ;
+	FCK.ContextMenu._InnerContextMenu.AttachToElement( FCK.EditorDocument ) ;
+}
+
+FCK.MakeEditable = function()
+{
+	this.EditingArea.MakeEditable() ;
+}
+
+// Disable the context menu in the editor (outside the editing area).
+function Document_OnContextMenu( e )
+{
+	if ( !e.target._FCKShowContextMenu )
+		e.preventDefault() ;
+}
+document.oncontextmenu = Document_OnContextMenu ;
+
+// GetNamedCommandState overload for Gecko.
+FCK._BaseGetNamedCommandState = FCK.GetNamedCommandState ;
+FCK.GetNamedCommandState = function( commandName )
+{
+	switch ( commandName )
+	{
+		case 'Unlink' :
+			return FCKSelection.HasAncestorNode('A') ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+		default :
+			return FCK._BaseGetNamedCommandState( commandName ) ;
+	}
+}
+
+// Named commands to be handled by this browsers specific implementation.
+FCK.RedirectNamedCommands =
+{
+	Print	: true,
+	Paste	: true,
+	Cut		: true,
+	Copy	: true
+} ;
+
+// ExecuteNamedCommand overload for Gecko.
+FCK.ExecuteRedirectedNamedCommand = function( commandName, commandParameter )
+{
+	switch ( commandName )
+	{
+		case 'Print' :
+			FCK.EditorWindow.print() ;
+			break ;
+		case 'Paste' :
+			try			{ if ( FCK.Paste() ) FCK.ExecuteNamedCommand( 'Paste', null, true ) ; }
+			catch (e)	{ FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.Paste, 'dialog/fck_paste.html', 400, 330, 'Security' ) ; }
+			break ;
+		case 'Cut' :
+			try			{ FCK.ExecuteNamedCommand( 'Cut', null, true ) ; }
+			catch (e)	{ alert(FCKLang.PasteErrorCut) ; }
+			break ;
+		case 'Copy' :
+			try			{ FCK.ExecuteNamedCommand( 'Copy', null, true ) ; }
+			catch (e)	{ alert(FCKLang.PasteErrorCopy) ; }
+			break ;
+		default :
+			FCK.ExecuteNamedCommand( commandName, commandParameter ) ;
+	}
+}
+
+FCK.AttachToOnSelectionChange = function( functionPointer )
+{
+	this.Events.AttachEvent( 'OnSelectionChange', functionPointer ) ;
+}
+
+FCK.Paste = function()
+{
+	if ( FCKConfig.ForcePasteAsPlainText )
+	{
+		FCK.PasteAsPlainText() ;
+		return false ;
+	}
+
+	/* For now, the AutoDetectPasteFromWord feature is IE only. */
+
+	return true ;
+}
+
+//**
+// FCK.InsertHtml: Inserts HTML at the current cursor location. Deletes the
+// selected content if any.
+FCK.InsertHtml = function( html )
+{
+	html = FCKConfig.ProtectedSource.Protect( html ) ;
+	html = FCK.ProtectEvents( html ) ;
+	html = FCK.ProtectUrls( html ) ;
+	html = FCK.ProtectTags( html ) ;
+
+	// Firefox can't handle correctly the editing of the STRONG and EM tags.
+	// We must replace them with B and I.
+		html = html.replace( FCKRegexLib.StrongOpener, '<b$1' ) ;
+		html = html.replace( FCKRegexLib.StrongCloser, '<\/b>' ) ;
+		html = html.replace( FCKRegexLib.EmOpener, '<i$1' ) ;
+		html = html.replace( FCKRegexLib.EmCloser, '<\/i>' ) ;
+
+	// Delete the actual selection.
+	var oSel = FCKSelection.Delete() ;
+
+	// Get the first available range.
+	var oRange = oSel.getRangeAt(0) ;
+
+	// Create a fragment with the input HTML.
+	var oFragment = oRange.createContextualFragment( html ) ;
+
+	// Get the last available node.
+	var oLastNode = oFragment.lastChild ;
+
+	// Insert the fragment in the range.
+	oRange.insertNode(oFragment) ;
+
+	// Set the cursor after the inserted fragment.
+	FCKSelection.SelectNode( oLastNode ) ;
+	FCKSelection.Collapse( false ) ;
+
+	this.Focus() ;
+}
+
+FCK.InsertElement = function( element )
+{
+	// Deletes the actual selection.
+	var oSel = FCKSelection.Delete() ;
+
+	// Gets the first available range.
+	var oRange = oSel.getRangeAt(0) ;
+
+	// Inserts the element in the range.
+	oRange.insertNode( element ) ;
+
+	// Set the cursor after the inserted fragment.
+	FCKSelection.SelectNode( element ) ;
+	FCKSelection.Collapse( false ) ;
+
+	this.Focus() ;
+}
+
+FCK.PasteAsPlainText = function()
+{
+	// TODO: Implement the "Paste as Plain Text" code.
+
+	// If the function is called inmediately Firefox 2 does automatically paste the contents as soon as the new dialog is created
+	// so we run it in a Timeout and the paste event can be cancelled
+	FCKTools.RunFunction( FCKDialog.OpenDialog, FCKDialog, ['FCKDialog_Paste', FCKLang.PasteAsText, 'dialog/fck_paste.html', 400, 330, 'PlainText'] ) ;
+
+/*
+	var sText = FCKTools.HTMLEncode( clipboardData.getData("Text") ) ;
+	sText = sText.replace( /\n/g, '<BR>' ) ;
+	this.InsertHtml( sText ) ;
+*/
+}
+/*
+FCK.PasteFromWord = function()
+{
+	// TODO: Implement the "Paste as Plain Text" code.
+
+	FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteFromWord, 'dialog/fck_paste.html', 400, 330, 'Word' ) ;
+
+//	FCK.CleanAndPaste( FCK.GetClipboardHTML() ) ;
+}
+*/
+FCK.GetClipboardHTML = function()
+{
+	return '' ;
+}
+
+FCK.CreateLink = function( url )
+{
+	FCK.ExecuteNamedCommand( 'Unlink' ) ;
+
+	if ( url.length > 0 )
+	{
+		// Generate a temporary name for the link.
+		var sTempUrl = 'javascript:void(0);/*' + ( new Date().getTime() ) + '*/' ;
+
+		// Use the internal "CreateLink" command to create the link.
+		FCK.ExecuteNamedCommand( 'CreateLink', sTempUrl ) ;
+
+		// Retrieve the just created link using XPath.
+		var oLink = this.EditorDocument.evaluate("//a[@href='" + sTempUrl + "']", this.EditorDocument.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue ;
+
+		if ( oLink )
+		{
+			oLink.href = url ;
+			return oLink ;
+		}
+	}
+
+	return null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktablehandler_gecko.js	(revision 795)
@@ -0,0 +1,57 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Manage table operations (IE specific).
+ */
+
+FCKTableHandler.GetSelectedCells = function()
+{
+	var aCells = new Array() ;
+
+	var oSelection = FCK.EditorWindow.getSelection() ;
+
+	// If the selection is a text.
+	if ( oSelection.rangeCount == 1 && oSelection.anchorNode.nodeType == 3 )
+	{
+		var oParent = FCKTools.GetElementAscensor( oSelection.anchorNode, 'TD,TH' ) ;
+
+		if ( oParent )
+		{
+			aCells[0] = oParent ;
+			return aCells ;
+		}
+	}
+
+	for ( var i = 0 ; i < oSelection.rangeCount ; i++ )
+	{
+		var oRange = oSelection.getRangeAt(i) ;
+		var oCell ;
+
+		if ( oRange.startContainer.tagName.Equals( 'TD', 'TH' ) )
+			oCell = oRange.startContainer ;
+		else
+			oCell = oRange.startContainer.childNodes[ oRange.startOffset ] ;
+
+		if ( oCell.tagName.Equals( 'TD', 'TH' ) )
+			aCells[aCells.length] = oCell ;
+	}
+
+	return aCells ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckbrowserinfo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckbrowserinfo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckbrowserinfo.js	(revision 795)
@@ -0,0 +1,48 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Contains browser detection information.
+ */
+
+var s = navigator.userAgent.toLowerCase() ;
+
+var FCKBrowserInfo =
+{
+	IsIE		: s.Contains('msie'),
+	IsIE7		: s.Contains('msie 7'),
+	IsGecko		: s.Contains('gecko/'),
+	IsSafari	: s.Contains('safari'),
+	IsOpera		: s.Contains('opera'),
+	IsMac		: s.Contains('macintosh')
+} ;
+
+// Completes the browser info with further Gecko information.
+(function( browserInfo )
+{
+	browserInfo.IsGeckoLike = ( browserInfo.IsGecko || browserInfo.IsSafari || browserInfo.IsOpera ) ;
+
+	if ( browserInfo.IsGecko )
+	{
+		var geckoVersion = s.match( /gecko\/(\d+)/ )[1] ;
+		browserInfo.IsGecko10 = geckoVersion < 20051111 ;	// Actually "10" refers to Gecko versions before Firefox 1.5, where Gecko 20051111 has been released.
+	}
+	else
+		browserInfo.IsGecko10 = false ;
+})(FCKBrowserInfo) ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdomtools.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdomtools.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdomtools.js	(revision 795)
@@ -0,0 +1,294 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Utility functions to work with the DOM.
+ */
+
+var FCKDomTools =
+{
+	MoveChildren : function( source, target )
+	{
+		if ( source == target )
+			return ;
+
+		var eChild ;
+		while ( (eChild = source.firstChild) )
+			target.appendChild( source.removeChild( eChild ) ) ;
+	},
+
+	// Remove blank spaces from the beginning and the end of the contents of a node.
+	TrimNode : function( node, ignoreEndBRs )
+	{
+		this.LTrimNode( node ) ;
+		this.RTrimNode( node, ignoreEndBRs ) ;
+	},
+
+	LTrimNode : function( node )
+	{
+		var eChildNode ;
+
+		while ( (eChildNode = node.firstChild) )
+		{
+			if ( eChildNode.nodeType == 3 )
+			{
+				var sTrimmed = eChildNode.nodeValue.LTrim() ;
+				var iOriginalLength = eChildNode.nodeValue.length ;
+
+				if ( sTrimmed.length == 0 )
+				{
+					node.removeChild( eChildNode ) ;
+					continue ;
+				}
+				else if ( sTrimmed.length < iOriginalLength )
+				{
+					eChildNode.splitText( iOriginalLength - sTrimmed.length ) ;
+					node.removeChild( node.firstChild ) ;
+				}
+			}
+			break ;
+		}
+	},
+
+	RTrimNode : function( node, ignoreEndBRs )
+	{
+		var eChildNode ;
+
+		while ( (eChildNode = node.lastChild) )
+		{
+			switch ( eChildNode.nodeType )
+			{
+				case 1 :
+					if ( eChildNode.nodeName.toUpperCase() == 'BR' && ( ignoreEndBRs || eChildNode.getAttribute( 'type', 2 ) == '_moz' ) )
+					{
+						node.removeChild( eChildNode ) ;
+						continue ;
+					}
+					break ;
+
+				case 3 :
+					var sTrimmed = eChildNode.nodeValue.RTrim() ;
+					var iOriginalLength = eChildNode.nodeValue.length ;
+
+					if ( sTrimmed.length == 0 )
+					{
+						// If the trimmed text node is empty, just remove it.
+						
+						// Use "eChildNode.parentNode" instead of "node" to avoid IE bug (#81).
+						eChildNode.parentNode.removeChild( eChildNode ) ;
+						continue ;
+					}
+					else if ( sTrimmed.length < iOriginalLength )
+					{
+						// If the trimmed text lenght is less than the original
+						// lenght, strip all spaces from the end by splitting
+						// the text and removing the resulting useless node.
+
+						eChildNode.splitText( sTrimmed.length ) ;
+						// Use "node.lastChild.parentNode" instead of "node" to avoid IE bug (#81).
+						node.lastChild.parentNode.removeChild( node.lastChild ) ;
+					}
+			}
+			break ;
+		}
+	},
+
+	RemoveNode : function( node, excludeChildren )
+	{
+		if ( excludeChildren )
+		{
+			// Move all children before the node.
+			var eChild ;
+			while ( (eChild = node.firstChild) )
+				node.parentNode.insertBefore( node.removeChild( eChild ), node ) ;
+		}
+
+		return node.parentNode.removeChild( node ) ;
+	},
+
+	GetFirstChild : function( node, childNames )
+	{
+		// If childNames is a string, transform it in a Array.
+		if ( typeof ( childNames ) == 'string' )
+			childNames = [ childNames ] ;
+
+		var eChild = node.firstChild ;
+		while( eChild )
+		{
+			if ( eChild.nodeType == 1 && eChild.tagName.Equals.apply( eChild.tagName, childNames ) )
+				return eChild ;
+
+			eChild = eChild.nextSibling ;
+		}
+
+		return null ;
+	},
+
+	GetLastChild : function( node, childNames )
+	{
+		// If childNames is a string, transform it in a Array.
+		if ( typeof ( childNames ) == 'string' )
+			childNames = [ childNames ] ;
+
+		var eChild = node.lastChild ;
+		while( eChild )
+		{
+			if ( eChild.nodeType == 1 && ( !childNames || eChild.tagName.Equals( childNames ) ) )
+				return eChild ;
+
+			eChild = eChild.previousSibling ;
+		}
+
+		return null ;
+	},
+
+	/*
+	 * Gets the previous element (nodeType=1) in the source order. Returns
+	 * "null" If no element is found.
+	 *		@param {Object} currentNode The node to start searching from.
+	 *		@param {Boolean} ignoreSpaceTextOnly Sets how text nodes will be
+	 *				handled. If set to "true", only white spaces text nodes
+	 *				will be ignored, while non white space text nodes will stop
+	 *				the search, returning null. If "false" or ommitted, all
+	 *				text nodes are ignored.
+	 *		@param {string[]} stopSearchElements An array of element names that
+	 *				will cause the search to stop when found, returning null.
+	 *				May be ommitted (or null).
+	 *		@param {string[]} ignoreElements An array of element names that
+	 *				must be ignored during the search.
+	 */
+	GetPreviousSourceElement : function( currentNode, ignoreSpaceTextOnly, stopSearchElements, ignoreElements )
+	{
+		if ( !currentNode )
+			return null ;
+
+		if ( stopSearchElements && currentNode.nodeType == 1 && currentNode.nodeName.IEquals( stopSearchElements ) )
+			return null ;
+
+		if ( currentNode.previousSibling )
+			currentNode = currentNode.previousSibling ;
+		else
+			return this.GetPreviousSourceElement( currentNode.parentNode, ignoreSpaceTextOnly, stopSearchElements, ignoreElements ) ;
+
+		while ( currentNode )
+		{
+			if ( currentNode.nodeType == 1 )
+			{
+				if ( stopSearchElements && currentNode.nodeName.IEquals( stopSearchElements ) )
+					break ;
+
+				if ( !ignoreElements || !currentNode.nodeName.IEquals( ignoreElements ) )
+					return currentNode ;
+			}
+			else if ( ignoreSpaceTextOnly && currentNode.nodeType == 3 && currentNode.nodeValue.RTrim().length > 0 )
+				break ;
+
+			if ( currentNode.lastChild )
+				currentNode = currentNode.lastChild ;
+			else
+				return this.GetPreviousSourceElement( currentNode, ignoreSpaceTextOnly, stopSearchElements, ignoreElements ) ;
+		}
+
+		return null ;
+	},
+
+	/*
+	 * Gets the next element (nodeType=1) in the source order. Returns
+	 * "null" If no element is found.
+	 *		@param {Object} currentNode The node to start searching from.
+	 *		@param {Boolean} ignoreSpaceTextOnly Sets how text nodes will be
+	 *				handled. If set to "true", only white spaces text nodes
+	 *				will be ignored, while non white space text nodes will stop
+	 *				the search, returning null. If "false" or ommitted, all
+	 *				text nodes are ignored.
+	 *		@param {string[]} stopSearchElements An array of element names that
+	 *				will cause the search to stop when found, returning null.
+	 *				May be ommitted (or null).
+	 *		@param {string[]} ignoreElements An array of element names that
+	 *				must be ignored during the search.
+	 */
+	GetNextSourceElement : function( currentNode, ignoreSpaceTextOnly, stopSearchElements, ignoreElements )
+	{
+		if ( !currentNode )
+			return null ;
+
+		if ( currentNode.nextSibling )
+			currentNode = currentNode.nextSibling ;
+		else
+			return this.GetNextSourceElement( currentNode.parentNode, ignoreSpaceTextOnly, stopSearchElements, ignoreElements ) ;
+
+		while ( currentNode )
+		{
+			if ( currentNode.nodeType == 1 )
+			{
+				if ( stopSearchElements && currentNode.nodeName.IEquals( stopSearchElements ) )
+					break ;
+
+				if ( !ignoreElements || !currentNode.nodeName.IEquals( ignoreElements ) )
+					return currentNode ;
+			}
+			else if ( ignoreSpaceTextOnly && currentNode.nodeType == 3 && currentNode.nodeValue.RTrim().length > 0 )
+				break ;
+
+			if ( currentNode.firstChild )
+				currentNode = currentNode.firstChild ;
+			else
+				return this.GetNextSourceElement( currentNode, ignoreSpaceTextOnly, stopSearchElements, ignoreElements ) ;
+		}
+
+		return null ;
+	},
+
+	// Inserts a element after a existing one.
+	InsertAfterNode : function( existingNode, newNode )
+	{
+		return existingNode.parentNode.insertBefore( newNode, existingNode.nextSibling ) ;
+	},
+
+	GetParents : function( node )
+	{
+		var parents = new Array() ;
+
+		while ( node )
+		{
+			parents.splice( 0, 0, node ) ;
+			node = node.parentNode ;
+		}
+
+		return parents ;
+	},
+
+	GetIndexOf : function( node )
+	{
+		var currentNode = node.parentNode ? node.parentNode.firstChild : null ;
+		var currentIndex = -1 ;
+
+		while ( currentNode )
+		{
+			currentIndex++ ;
+
+			if ( currentNode == node )
+				return currentIndex ;
+
+			currentNode = currentNode.nextSibling ;
+		}
+
+		return -1 ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckregexlib.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckregexlib.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckregexlib.js	(revision 795)
@@ -0,0 +1,95 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * These are some Regular Expresions used by the editor.
+ */
+
+var FCKRegexLib =
+{
+// This is the Regular expression used by the SetHTML method for the "&apos;" entity.
+AposEntity		: /&apos;/gi ,
+
+// Used by the Styles combo to identify styles that can't be applied to text.
+ObjectElements	: /^(?:IMG|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|HR|OBJECT|A|UL|OL|LI)$/i ,
+
+// List all named commands (commands that can be interpreted by the browser "execCommand" method.
+NamedCommands	: /^(?:Cut|Copy|Paste|Print|SelectAll|RemoveFormat|Unlink|Undo|Redo|Bold|Italic|Underline|StrikeThrough|Subscript|Superscript|JustifyLeft|JustifyCenter|JustifyRight|JustifyFull|Outdent|Indent|InsertOrderedList|InsertUnorderedList|InsertHorizontalRule)$/i ,
+
+BodyContents	: /([\s\S]*\<body[^\>]*\>)([\s\S]*)(\<\/body\>[\s\S]*)/i ,
+
+// Temporary text used to solve some browser specific limitations.
+ToReplace		: /___fcktoreplace:([\w]+)/ig ,
+
+// Get the META http-equiv attribute from the tag.
+MetaHttpEquiv	: /http-equiv\s*=\s*["']?([^"' ]+)/i ,
+
+HasBaseTag		: /<base /i ,
+
+HtmlOpener		: /<html\s?[^>]*>/i ,
+HeadOpener		: /<head\s?[^>]*>/i ,
+HeadCloser		: /<\/head\s*>/i ,
+
+// Temporary classes (Tables without border, Anchors with content) used in IE
+FCK_Class		: /(\s*FCK__[A-Za-z]*\s*)/ ,
+
+// Validate element names (it must be in lowercase).
+ElementName		: /(^[a-z_:][\w.\-:]*\w$)|(^[a-z_]$)/ ,
+
+// Used in conjuction with the FCKConfig.ForceSimpleAmpersand configuration option.
+ForceSimpleAmpersand : /___FCKAmp___/g ,
+
+// Get the closing parts of the tags with no closing tags, like <br/>... gets the "/>" part.
+SpaceNoClose	: /\/>/g ,
+
+// Empty elements may be <p></p> or even a simple opening <p> (see #211).
+EmptyParagraph	: /^<([^ >]+)[^>]*>\s*(<\/\1>)?$/ ,
+
+EmptyOutParagraph : /^<([^ >]+)[^>]*>(?:\s*|&nbsp;)(<\/\1>)?$/ ,
+
+TagBody			: /></ ,
+
+StrongOpener	: /<STRONG([ \>])/gi ,
+StrongCloser	: /<\/STRONG>/gi ,
+EmOpener		: /<EM([ \>])/gi ,
+EmCloser		: /<\/EM>/gi ,
+//AbbrOpener		: /<ABBR([ \>])/gi ,
+//AbbrCloser		: /<\/ABBR>/gi ,
+
+GeckoEntitiesMarker : /#\?-\:/g ,
+
+// We look for the "src" and href attribute with the " or ' or whithout one of
+// them. We have to do all in one, otherwhise we will have problems with URLs
+// like "thumbnail.php?src=someimage.jpg" (SF-BUG 1554141).
+ProtectUrlsImg	: /<img(?=\s).*?\ssrc=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi ,
+ProtectUrlsA	: /<a(?=\s).*?\shref=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi ,
+
+Html4DocType	: /HTML 4\.0 Transitional/i ,
+DocTypeTag		: /<!DOCTYPE[^>]*>/i ,
+
+// These regex are used to save the original event attributes in the HTML.
+TagsWithEvent	: /<[^\>]+ on\w+[\s\r\n]*=[\s\r\n]*?('|")[\s\S]+?\>/g ,
+EventAttributes	: /\s(on\w+)[\s\r\n]*=[\s\r\n]*?('|")([\s\S]*?)\2/g,
+ProtectedEvents : /\s\w+_fckprotectedatt="([^"]+)"/g,
+
+StyleProperties : /\S+\s*:/g,
+
+// [a-zA-Z0-9:]+ seams to be more efficient than [\w:]+
+InvalidSelfCloseTags : /(<(?!base|meta|link|hr|br|param|img|area|input)([a-zA-Z0-9:]+)[^>]*)\/>/gi
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckselection_ie.js	(revision 795)
@@ -0,0 +1,158 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Active selection functions. (IE specific implementation)
+ */
+
+// Get the selection type.
+FCKSelection.GetType = function()
+{
+	return FCK.EditorDocument.selection.type ;
+}
+
+// Retrieves the selected element (if any), just in the case that a single
+// element (object like and image or a table) is selected.
+FCKSelection.GetSelectedElement = function()
+{
+	if ( this.GetType() == 'Control' )
+	{
+		var oRange = FCK.EditorDocument.selection.createRange() ;
+
+		if ( oRange && oRange.item )
+			return FCK.EditorDocument.selection.createRange().item(0) ;
+	}
+}
+
+FCKSelection.GetParentElement = function()
+{
+	switch ( this.GetType() )
+	{
+		case 'Control' :
+			return FCKSelection.GetSelectedElement().parentElement ;
+		case 'None' :
+			return null ;
+		default :
+			return FCK.EditorDocument.selection.createRange().parentElement() ;
+	}
+}
+
+FCKSelection.SelectNode = function( node )
+{
+	FCK.Focus() ;
+	FCK.EditorDocument.selection.empty() ;
+	var oRange ;
+	try
+	{
+		// Try to select the node as a control.
+		oRange = FCK.EditorDocument.body.createControlRange() ;
+		oRange.addElement( node ) ;
+	}
+	catch(e)
+	{
+		// If failed, select it as a text range.
+		oRange = FCK.EditorDocument.body.createTextRange() ;
+		oRange.moveToElementText( node ) ;
+	}
+
+	oRange.select() ;
+}
+
+FCKSelection.Collapse = function( toStart )
+{
+	FCK.Focus() ;
+	if ( this.GetType() == 'Text' )
+	{
+		var oRange = FCK.EditorDocument.selection.createRange() ;
+		oRange.collapse( toStart == null || toStart === true ) ;
+		oRange.select() ;
+	}
+}
+
+// The "nodeTagName" parameter must be Upper Case.
+FCKSelection.HasAncestorNode = function( nodeTagName )
+{
+	var oContainer ;
+
+	if ( FCK.EditorDocument.selection.type == "Control" )
+	{
+		oContainer = this.GetSelectedElement() ;
+	}
+	else
+	{
+		var oRange  = FCK.EditorDocument.selection.createRange() ;
+		oContainer = oRange.parentElement() ;
+	}
+
+	while ( oContainer )
+	{
+		if ( oContainer.tagName == nodeTagName ) return true ;
+		oContainer = oContainer.parentNode ;
+	}
+
+	return false ;
+}
+
+// The "nodeTagName" parameter must be UPPER CASE.
+FCKSelection.MoveToAncestorNode = function( nodeTagName )
+{
+	var oNode, oRange ;
+
+	if ( ! FCK.EditorDocument )
+		return null ;
+
+	if ( FCK.EditorDocument.selection.type == "Control" )
+	{
+		oRange = FCK.EditorDocument.selection.createRange() ;
+		for ( i = 0 ; i < oRange.length ; i++ )
+		{
+			if (oRange(i).parentNode)
+			{
+				oNode = oRange(i).parentNode ;
+				break ;
+			}
+		}
+	}
+	else
+	{
+		oRange  = FCK.EditorDocument.selection.createRange() ;
+		oNode = oRange.parentElement() ;
+	}
+
+	while ( oNode && oNode.nodeName != nodeTagName )
+		oNode = oNode.parentNode ;
+
+	return oNode ;
+}
+
+FCKSelection.Delete = function()
+{
+	// Gets the actual selection.
+	var oSel = FCK.EditorDocument.selection ;
+
+	// Deletes the actual selection contents.
+	if ( oSel.type.toLowerCase() != "none" )
+	{
+		oSel.clear() ;
+	}
+
+	return oSel ;
+}
+
+
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckurlparams.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckurlparams.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckurlparams.js	(revision 795)
@@ -0,0 +1,39 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKURLParams object that is used to get all parameters
+ * passed by the URL QueryString (after the "?").
+ */
+
+// #### URLParams: holds all URL passed parameters (like ?Param1=Value1&Param2=Value2)
+var FCKURLParams = new Object() ;
+
+(function()
+{
+	var aParams = document.location.search.substr(1).split('&') ;
+	for ( var i = 0 ; i < aParams.length ; i++ )
+	{
+		var aParam = aParams[i].split('=') ;
+		var sParamName  = decodeURIComponent( aParam[0] ) ;
+		var sParamValue = decodeURIComponent( aParam[1] ) ;
+
+		FCKURLParams[ sParamName ] = sParamValue ;
+	}
+})();
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_contextmenu.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_contextmenu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fck_contextmenu.js	(revision 795)
@@ -0,0 +1,307 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCK.ContextMenu object that is responsible for all
+ * Context Menu operations in the editing area.
+ */
+
+FCK.ContextMenu = new Object() ;
+FCK.ContextMenu.Listeners = new Array() ;
+
+FCK.ContextMenu.RegisterListener = function( listener )
+{
+	if ( listener )
+		this.Listeners.push( listener ) ;
+}
+
+function FCK_ContextMenu_Init()
+{
+	var oInnerContextMenu = FCK.ContextMenu._InnerContextMenu = new FCKContextMenu( FCKBrowserInfo.IsIE ? window : window.parent, FCKLang.Dir ) ;
+	oInnerContextMenu.OnBeforeOpen	= FCK_ContextMenu_OnBeforeOpen ;
+	oInnerContextMenu.OnItemClick	= FCK_ContextMenu_OnItemClick ;
+
+	// Get the registering function.
+	var oMenu = FCK.ContextMenu ;
+
+	// Register all configured context menu listeners.
+	for ( var i = 0 ; i < FCKConfig.ContextMenu.length ; i++ )
+		oMenu.RegisterListener( FCK_ContextMenu_GetListener( FCKConfig.ContextMenu[i] ) ) ;
+}
+
+function FCK_ContextMenu_GetListener( listenerName )
+{
+	switch ( listenerName )
+	{
+		case 'Generic' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				menu.AddItem( 'Cut'		, FCKLang.Cut	, 7, FCKCommands.GetCommand( 'Cut' ).GetState() == FCK_TRISTATE_DISABLED ) ;
+				menu.AddItem( 'Copy'	, FCKLang.Copy	, 8, FCKCommands.GetCommand( 'Copy' ).GetState() == FCK_TRISTATE_DISABLED ) ;
+				menu.AddItem( 'Paste'	, FCKLang.Paste	, 9, FCKCommands.GetCommand( 'Paste' ).GetState() == FCK_TRISTATE_DISABLED ) ;
+			}} ;
+
+		case 'Table' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				var bIsTable	= ( tagName == 'TABLE' ) ;
+				var bIsCell		= ( !bIsTable && FCKSelection.HasAncestorNode( 'TABLE' ) ) ;
+
+				if ( bIsCell )
+				{
+					menu.AddSeparator() ;
+					var oItem = menu.AddItem( 'Cell'	, FCKLang.CellCM ) ;
+					oItem.AddItem( 'TableInsertCell'	, FCKLang.InsertCell, 58 ) ;
+					oItem.AddItem( 'TableDeleteCells'	, FCKLang.DeleteCells, 59 ) ;
+					oItem.AddItem( 'TableMergeCells'	, FCKLang.MergeCells, 60 ) ;
+					oItem.AddItem( 'TableSplitCell'		, FCKLang.SplitCell, 61 ) ;
+					oItem.AddSeparator() ;
+					oItem.AddItem( 'TableCellProp'		, FCKLang.CellProperties, 57 ) ;
+
+					menu.AddSeparator() ;
+					oItem = menu.AddItem( 'Row'			, FCKLang.RowCM ) ;
+					oItem.AddItem( 'TableInsertRow'		, FCKLang.InsertRow, 62 ) ;
+					oItem.AddItem( 'TableDeleteRows'	, FCKLang.DeleteRows, 63 ) ;
+
+					menu.AddSeparator() ;
+					oItem = menu.AddItem( 'Column'		, FCKLang.ColumnCM ) ;
+					oItem.AddItem( 'TableInsertColumn'	, FCKLang.InsertColumn, 64 ) ;
+					oItem.AddItem( 'TableDeleteColumns'	, FCKLang.DeleteColumns, 65 ) ;
+				}
+
+				if ( bIsTable || bIsCell )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'TableDelete'			, FCKLang.TableDelete ) ;
+					menu.AddItem( 'TableProp'			, FCKLang.TableProperties, 39 ) ;
+				}
+			}} ;
+
+		case 'Link' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				var bInsideLink = ( tagName == 'A' || FCKSelection.HasAncestorNode( 'A' ) ) ;
+
+				if ( bInsideLink || FCK.GetNamedCommandState( 'Unlink' ) != FCK_TRISTATE_DISABLED )
+				{
+					// Go up to the anchor to test its properties
+					var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ;
+					var bIsAnchor = ( oLink && oLink.name.length > 0 && oLink.href.length == 0 ) ;
+					// If it isn't a link then don't add the Link context menu
+					if ( bIsAnchor )
+						return ;
+
+					menu.AddSeparator() ;
+					if ( bInsideLink )
+						menu.AddItem( 'Link', FCKLang.EditLink		, 34 ) ;
+					menu.AddItem( 'Unlink'	, FCKLang.RemoveLink	, 35 ) ;
+				}
+			}} ;
+
+		case 'Image' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'IMG' && !tag.getAttribute( '_fckfakelement' ) )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Image', FCKLang.ImageProperties, 37 ) ;
+				}
+			}} ;
+
+		case 'Anchor' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				// Go up to the anchor to test its properties
+				var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ;
+				var bIsAnchor = ( oLink && oLink.name.length > 0 ) ;
+
+				if ( bIsAnchor || ( tagName == 'IMG' && tag.getAttribute( '_fckanchor' ) ) )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Anchor', FCKLang.AnchorProp, 36 ) ;
+				}
+			}} ;
+
+		case 'Flash' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'IMG' && tag.getAttribute( '_fckflash' ) )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Flash', FCKLang.FlashProperties, 38 ) ;
+				}
+			}} ;
+
+		case 'Form' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( FCKSelection.HasAncestorNode('FORM') )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Form', FCKLang.FormProp, 48 ) ;
+				}
+			}} ;
+
+		case 'Checkbox' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'INPUT' && tag.type == 'checkbox' )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Checkbox', FCKLang.CheckboxProp, 49 ) ;
+				}
+			}} ;
+
+		case 'Radio' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'INPUT' && tag.type == 'radio' )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Radio', FCKLang.RadioButtonProp, 50 ) ;
+				}
+			}} ;
+
+		case 'TextField' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'INPUT' && ( tag.type == 'text' || tag.type == 'password' ) )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'TextField', FCKLang.TextFieldProp, 51 ) ;
+				}
+			}} ;
+
+		case 'HiddenField' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'IMG' && tag.getAttribute( '_fckinputhidden' ) )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'HiddenField', FCKLang.HiddenFieldProp, 56 ) ;
+				}
+			}} ;
+
+		case 'ImageButton' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'INPUT' && tag.type == 'image' )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'ImageButton', FCKLang.ImageButtonProp, 55 ) ;
+				}
+			}} ;
+
+		case 'Button' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'INPUT' && ( tag.type == 'button' || tag.type == 'submit' || tag.type == 'reset' ) )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Button', FCKLang.ButtonProp, 54 ) ;
+				}
+			}} ;
+
+		case 'Select' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'SELECT' )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Select', FCKLang.SelectionFieldProp, 53 ) ;
+				}
+			}} ;
+
+		case 'Textarea' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( tagName == 'TEXTAREA' )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'Textarea', FCKLang.TextareaProp, 52 ) ;
+				}
+			}} ;
+
+		case 'BulletedList' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( FCKSelection.HasAncestorNode('UL') )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'BulletedList', FCKLang.BulletedListProp, 27 ) ;
+				}
+			}} ;
+
+		case 'NumberedList' :
+			return {
+			AddItems : function( menu, tag, tagName )
+			{
+				if ( FCKSelection.HasAncestorNode('OL') )
+				{
+					menu.AddSeparator() ;
+					menu.AddItem( 'NumberedList', FCKLang.NumberedListProp, 26 ) ;
+				}
+			}} ;
+	}
+	return null ;
+}
+
+function FCK_ContextMenu_OnBeforeOpen()
+{
+	// Update the UI.
+	FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+
+	// Get the actual selected tag (if any).
+	var oTag, sTagName ;
+
+	// The extra () is to avoid a warning with strict error checking. This is ok.
+	if ( (oTag = FCKSelection.GetSelectedElement()) )
+		sTagName = oTag.tagName ;
+
+	// Cleanup the current menu items.
+	var oMenu = FCK.ContextMenu._InnerContextMenu ;
+	oMenu.RemoveAllItems() ;
+
+	// Loop through the listeners.
+	var aListeners = FCK.ContextMenu.Listeners ;
+	for ( var i = 0 ; i < aListeners.length ; i++ )
+		aListeners[i].AddItems( oMenu, oTag, sTagName ) ;
+}
+
+function FCK_ContextMenu_OnItemClick( item )
+{
+	FCK.Focus() ;
+	FCKCommands.GetCommand( item.Name ).Execute() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdialog_ie.js	(revision 795)
@@ -0,0 +1,48 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Dialog windows operations. (IE specific implementations)
+ */
+
+FCKDialog.Show = function( dialogInfo, dialogName, pageUrl, dialogWidth, dialogHeight, parentWindow, resizable )
+{
+	if ( !parentWindow )
+		parentWindow = window ;
+
+	var sOptions = 'help:no;scroll:no;status:no' +
+		';resizable:'  + ( resizable ? 'yes' : 'no' ) +
+		';dialogWidth:' + dialogWidth + 'px' +
+		';dialogHeight:' + dialogHeight + 'px' ;
+
+	FCKFocusManager.Lock() ;
+
+	var oReturn = 'B' ;
+
+	try
+	{
+		oReturn = parentWindow.showModalDialog( pageUrl, dialogInfo, sOptions ) ;
+	}
+	catch( e ) {}
+
+	if ( 'B' === oReturn )
+		alert( FCKLang.DialogBlocked ) ;
+
+	FCKFocusManager.Unlock() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckundo_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckundo_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckundo_gecko.js	(revision 795)
@@ -0,0 +1,27 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Fake implementation to ignore calls on Gecko.
+ */
+
+var FCKUndo = new Object() ;
+
+FCKUndo.SaveUndoStep = function()
+{}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktoolbarset.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktoolbarset.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcktoolbarset.js	(revision 795)
@@ -0,0 +1,357 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKToolbarSet object that is used to load and draw the
+ * toolbar.
+ */
+
+function FCKToolbarSet_Create( overhideLocation )
+{
+	var oToolbarSet ;
+
+	var sLocation = overhideLocation || FCKConfig.ToolbarLocation ;
+	switch ( sLocation )
+	{
+		case 'In' :
+				document.getElementById( 'xToolbarRow' ).style.display = '' ;
+				oToolbarSet = new FCKToolbarSet( document ) ;
+			break ;
+
+//		case 'OutTop' :
+			// Not supported.
+
+		default :
+			FCK.Events.AttachEvent( 'OnBlur', FCK_OnBlur ) ;
+			FCK.Events.AttachEvent( 'OnFocus', FCK_OnFocus ) ;
+
+			var eToolbarTarget ;
+
+			// Out:[TargetWindow]([TargetId])
+			var oOutMatch = sLocation.match( /^Out:(.+)\((\w+)\)$/ ) ;
+			if ( oOutMatch )
+			{
+				eToolbarTarget = eval( 'parent.' + oOutMatch[1] ).document.getElementById( oOutMatch[2] ) ;
+			}
+			else
+			{
+				// Out:[TargetId]
+				oOutMatch = sLocation.match( /^Out:(\w+)$/ ) ;
+				if ( oOutMatch )
+					eToolbarTarget = parent.document.getElementById( oOutMatch[1] ) ;
+			}
+
+			if ( !eToolbarTarget )
+			{
+				alert( 'Invalid value for "ToolbarLocation"' ) ;
+				return this._Init( 'In' ) ;
+			}
+
+			// If it is a shared toolbar, it may be already available in the target element.
+			oToolbarSet = eToolbarTarget.__FCKToolbarSet ;
+			if ( oToolbarSet )
+				break ;
+
+			// Create the IFRAME that will hold the toolbar inside the target element.
+			var eToolbarIFrame = FCKTools.GetElementDocument( eToolbarTarget ).createElement( 'iframe' ) ;
+			eToolbarIFrame.frameBorder = 0 ;
+			eToolbarIFrame.width = '100%' ;
+			eToolbarIFrame.height = '10' ;
+			eToolbarTarget.appendChild( eToolbarIFrame ) ;
+			eToolbarIFrame.unselectable = 'on' ;
+
+			// Write the basic HTML for the toolbar (copy from the editor main page).
+			var eTargetDocument = eToolbarIFrame.contentWindow.document ;
+			eTargetDocument.open() ;
+			eTargetDocument.write( '<html><head><script type="text/javascript"> window.onload = window.onresize = function() { window.frameElement.height = document.body.scrollHeight ; } </script></head><body style="overflow: hidden">' + document.getElementById( 'xToolbarSpace' ).innerHTML + '</body></html>' ) ;
+			eTargetDocument.close() ;
+
+			eTargetDocument.oncontextmenu = FCKTools.CancelEvent ;
+
+			// Load external resources (must be done here, otherwise Firefox will not
+			// have the document DOM ready to be used right away.
+			FCKTools.AppendStyleSheet( eTargetDocument, FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+			oToolbarSet = eToolbarTarget.__FCKToolbarSet = new FCKToolbarSet( eTargetDocument ) ;
+			oToolbarSet._IFrame = eToolbarIFrame ;
+
+			if ( FCK.IECleanup )
+				FCK.IECleanup.AddItem( eToolbarTarget, FCKToolbarSet_Target_Cleanup ) ;
+	}
+
+	oToolbarSet.CurrentInstance = FCK ;
+
+	FCK.AttachToOnSelectionChange( oToolbarSet.RefreshItemsState ) ;
+
+	return oToolbarSet ;
+}
+
+function FCK_OnBlur( editorInstance )
+{
+	var eToolbarSet = editorInstance.ToolbarSet ;
+
+	if ( eToolbarSet.CurrentInstance == editorInstance )
+		eToolbarSet.Disable() ;
+}
+
+function FCK_OnFocus( editorInstance )
+{
+	var oToolbarset = editorInstance.ToolbarSet ;
+	var oInstance = editorInstance || FCK ;
+
+	// Unregister the toolbar window from the current instance.
+	oToolbarset.CurrentInstance.FocusManager.RemoveWindow( oToolbarset._IFrame.contentWindow ) ;
+
+	// Set the new current instance.
+	oToolbarset.CurrentInstance = oInstance ;
+
+	// Register the toolbar window in the current instance.
+	oInstance.FocusManager.AddWindow( oToolbarset._IFrame.contentWindow, true ) ;
+
+	oToolbarset.Enable() ;
+}
+
+function FCKToolbarSet_Cleanup()
+{
+	this._TargetElement = null ;
+	this._IFrame = null ;
+}
+
+function FCKToolbarSet_Target_Cleanup()
+{
+	this.__FCKToolbarSet = null ;
+}
+
+var FCKToolbarSet = function( targetDocument )
+{
+	this._Document = targetDocument ;
+
+	// Get the element that will hold the elements structure.
+	this._TargetElement	= targetDocument.getElementById( 'xToolbar' ) ;
+
+	// Setup the expand and collapse handlers.
+	var eExpandHandle	= targetDocument.getElementById( 'xExpandHandle' ) ;
+	var eCollapseHandle	= targetDocument.getElementById( 'xCollapseHandle' ) ;
+
+	eExpandHandle.title		= FCKLang.ToolbarExpand ;
+	eExpandHandle.onclick	= FCKToolbarSet_Expand_OnClick ;
+
+	eCollapseHandle.title	= FCKLang.ToolbarCollapse ;
+	eCollapseHandle.onclick	= FCKToolbarSet_Collapse_OnClick ;
+
+	// Set the toolbar state at startup.
+	if ( !FCKConfig.ToolbarCanCollapse || FCKConfig.ToolbarStartExpanded )
+		this.Expand() ;
+	else
+		this.Collapse() ;
+
+	// Enable/disable the collapse handler
+	eCollapseHandle.style.display = FCKConfig.ToolbarCanCollapse ? '' : 'none' ;
+
+	if ( FCKConfig.ToolbarCanCollapse )
+		eCollapseHandle.style.display = '' ;
+	else
+		targetDocument.getElementById( 'xTBLeftBorder' ).style.display = '' ;
+
+	// Set the default properties.
+	this.Toolbars = new Array() ;
+	this.IsLoaded = false ;
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( this, FCKToolbarSet_Cleanup ) ;
+}
+
+function FCKToolbarSet_Expand_OnClick()
+{
+	FCK.ToolbarSet.Expand() ;
+}
+
+function FCKToolbarSet_Collapse_OnClick()
+{
+	FCK.ToolbarSet.Collapse() ;
+}
+
+FCKToolbarSet.prototype.Expand = function()
+{
+	this._ChangeVisibility( false ) ;
+}
+
+FCKToolbarSet.prototype.Collapse = function()
+{
+	this._ChangeVisibility( true ) ;
+}
+
+FCKToolbarSet.prototype._ChangeVisibility = function( collapse )
+{
+	this._Document.getElementById( 'xCollapsed' ).style.display = collapse ? '' : 'none' ;
+	this._Document.getElementById( 'xExpanded' ).style.display = collapse ? 'none' : '' ;
+
+	if ( FCKBrowserInfo.IsGecko )
+	{
+		// I had to use "setTimeout" because Gecko was not responding in a right
+		// way when calling window.onresize() directly.
+		FCKTools.RunFunction( window.onresize ) ;
+	}
+}
+
+FCKToolbarSet.prototype.Load = function( toolbarSetName )
+{
+	this.Name = toolbarSetName ;
+
+	this.Items = new Array() ;
+
+	// Reset the array of toolbat items that are active only on WYSIWYG mode.
+	this.ItemsWysiwygOnly = new Array() ;
+
+	// Reset the array of toolbar items that are sensitive to the cursor position.
+	this.ItemsContextSensitive = new Array() ;
+
+	// Cleanup the target element.
+	this._TargetElement.innerHTML = '' ;
+
+	var ToolbarSet = FCKConfig.ToolbarSets[toolbarSetName] ;
+
+	if ( !ToolbarSet )
+	{
+		alert( FCKLang.UnknownToolbarSet.replace( /%1/g, toolbarSetName ) ) ;
+		return ;
+	}
+
+	this.Toolbars = new Array() ;
+
+	for ( var x = 0 ; x < ToolbarSet.length ; x++ )
+	{
+		var oToolbarItems = ToolbarSet[x] ;
+
+		var oToolbar ;
+
+		if ( typeof( oToolbarItems ) == 'string' )
+		{
+			if ( oToolbarItems == '/' )
+				oToolbar = new FCKToolbarBreak() ;
+		}
+		else
+		{
+			oToolbar = new FCKToolbar() ;
+
+			for ( var j = 0 ; j < oToolbarItems.length ; j++ )
+			{
+				var sItem = oToolbarItems[j] ;
+
+				if ( sItem == '-')
+					oToolbar.AddSeparator() ;
+				else
+				{
+					var oItem = FCKToolbarItems.GetItem( sItem ) ;
+					if ( oItem )
+					{
+						oToolbar.AddItem( oItem ) ;
+
+						this.Items.push( oItem ) ;
+
+						if ( !oItem.SourceView )
+							this.ItemsWysiwygOnly.push( oItem ) ;
+
+						if ( oItem.ContextSensitive )
+							this.ItemsContextSensitive.push( oItem ) ;
+					}
+				}
+			}
+
+			// oToolbar.AddTerminator() ;
+		}
+
+		oToolbar.Create( this._TargetElement ) ;
+
+		this.Toolbars[ this.Toolbars.length ] = oToolbar ;
+	}
+
+	FCKTools.DisableSelection( this._Document.getElementById( 'xCollapseHandle' ).parentNode ) ;
+
+	if ( FCK.Status != FCK_STATUS_COMPLETE )
+		FCK.Events.AttachEvent( 'OnStatusChange', this.RefreshModeState ) ;
+	else
+		this.RefreshModeState() ;
+
+	this.IsLoaded = true ;
+	this.IsEnabled = true ;
+
+	FCKTools.RunFunction( this.OnLoad ) ;
+}
+
+FCKToolbarSet.prototype.Enable = function()
+{
+	if ( this.IsEnabled )
+		return ;
+
+	this.IsEnabled = true ;
+
+	var aItems = this.Items ;
+	for ( var i = 0 ; i < aItems.length ; i++ )
+		aItems[i].RefreshState() ;
+}
+
+FCKToolbarSet.prototype.Disable = function()
+{
+	if ( !this.IsEnabled )
+		return ;
+
+	this.IsEnabled = false ;
+
+	var aItems = this.Items ;
+	for ( var i = 0 ; i < aItems.length ; i++ )
+		aItems[i].Disable() ;
+}
+
+FCKToolbarSet.prototype.RefreshModeState = function( editorInstance )
+{
+	if ( FCK.Status != FCK_STATUS_COMPLETE )
+		return ;
+
+	var oToolbarSet = editorInstance ? editorInstance.ToolbarSet : this ;
+	var aItems = oToolbarSet.ItemsWysiwygOnly ;
+
+	if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+	{
+		// Enable all buttons that are available on WYSIWYG mode only.
+		for ( var i = 0 ; i < aItems.length ; i++ )
+			aItems[i].Enable() ;
+
+		// Refresh the buttons state.
+		oToolbarSet.RefreshItemsState( editorInstance ) ;
+	}
+	else
+	{
+		// Refresh the buttons state.
+		oToolbarSet.RefreshItemsState( editorInstance ) ;
+
+		// Disable all buttons that are available on WYSIWYG mode only.
+		for ( var j = 0 ; j < aItems.length ; j++ )
+			aItems[j].Disable() ;
+	}
+}
+
+FCKToolbarSet.prototype.RefreshItemsState = function( editorInstance )
+{
+
+	var aItems = ( editorInstance ? editorInstance.ToolbarSet : this ).ItemsContextSensitive ;
+
+	for ( var i = 0 ; i < aItems.length ; i++ )
+		aItems[i].RefreshState() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdocumentprocessor.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdocumentprocessor.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fckdocumentprocessor.js	(revision 795)
@@ -0,0 +1,243 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Advanced document processors.
+ */
+
+var FCKDocumentProcessor = new Object() ;
+FCKDocumentProcessor._Items = new Array() ;
+
+FCKDocumentProcessor.AppendNew = function()
+{
+	var oNewItem = new Object() ;
+	this._Items.AddItem( oNewItem ) ;
+	return oNewItem ;
+}
+
+FCKDocumentProcessor.Process = function( document )
+{
+	var oProcessor, i = 0 ;
+	while( ( oProcessor = this._Items[i++] ) )
+		oProcessor.ProcessDocument( document ) ;
+}
+
+var FCKDocumentProcessor_CreateFakeImage = function( fakeClass, realElement )
+{
+	var oImg = FCK.EditorDocument.createElement( 'IMG' ) ;
+	oImg.className = fakeClass ;
+	oImg.src = FCKConfig.FullBasePath + 'images/spacer.gif' ;
+	oImg.setAttribute( '_fckfakelement', 'true', 0 ) ;
+	oImg.setAttribute( '_fckrealelement', FCKTempBin.AddElement( realElement ), 0 ) ;
+	return oImg ;
+}
+
+// Link Anchors
+if ( FCKBrowserInfo.IsIE || FCKBrowserInfo.IsOpera )
+{
+	var FCKAnchorsProcessor = FCKDocumentProcessor.AppendNew() ;
+	FCKAnchorsProcessor.ProcessDocument = function( document )
+	{
+		var aLinks = document.getElementsByTagName( 'A' ) ;
+
+		var oLink ;
+		var i = aLinks.length - 1 ;
+		while ( i >= 0 && ( oLink = aLinks[i--] ) )
+		{
+			// If it is anchor. Doesn't matter if it's also a link (even better: we show that it's both a link and an anchor)
+			if ( oLink.name.length > 0 )
+			{
+				//if the anchor has some content then we just add a temporary class
+				if ( oLink.innerHTML != '' )
+				{
+					if ( FCKBrowserInfo.IsIE )
+						oLink.className += ' FCK__AnchorC' ;
+				}
+				else
+				{
+					var oImg = FCKDocumentProcessor_CreateFakeImage( 'FCK__Anchor', oLink.cloneNode(true) ) ;
+					oImg.setAttribute( '_fckanchor', 'true', 0 ) ;
+
+					oLink.parentNode.insertBefore( oImg, oLink ) ;
+					oLink.parentNode.removeChild( oLink ) ;
+				}
+			}
+		}
+	}
+}
+
+// Page Breaks
+var FCKPageBreaksProcessor = FCKDocumentProcessor.AppendNew() ;
+FCKPageBreaksProcessor.ProcessDocument = function( document )
+{
+	var aDIVs = document.getElementsByTagName( 'DIV' ) ;
+
+	var eDIV ;
+	var i = aDIVs.length - 1 ;
+	while ( i >= 0 && ( eDIV = aDIVs[i--] ) )
+	{
+		if ( eDIV.style.pageBreakAfter == 'always' && eDIV.childNodes.length == 1 && eDIV.childNodes[0].style && eDIV.childNodes[0].style.display == 'none' )
+		{
+			var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', eDIV.cloneNode(true) ) ;
+
+			eDIV.parentNode.insertBefore( oFakeImage, eDIV ) ;
+			eDIV.parentNode.removeChild( eDIV ) ;
+		}
+	}
+/*
+	var aCenters = document.getElementsByTagName( 'CENTER' ) ;
+
+	var oCenter ;
+	var i = aCenters.length - 1 ;
+	while ( i >= 0 && ( oCenter = aCenters[i--] ) )
+	{
+		if ( oCenter.style.pageBreakAfter == 'always' && oCenter.innerHTML.Trim().length == 0 )
+		{
+			var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', oCenter.cloneNode(true) ) ;
+
+			oCenter.parentNode.insertBefore( oFakeImage, oCenter ) ;
+			oCenter.parentNode.removeChild( oCenter ) ;
+		}
+	}
+*/
+}
+
+// Flash Embeds.
+var FCKFlashProcessor = FCKDocumentProcessor.AppendNew() ;
+FCKFlashProcessor.ProcessDocument = function( document )
+{
+	/*
+	Sample code:
+	This is some <embed src="/UserFiles/Flash/Yellow_Runners.swf"></embed><strong>sample text</strong>. You are&nbsp;<a name="fred"></a> using <a href="http://www.fckeditor.net/">FCKeditor</a>.
+	*/
+
+	var aEmbeds = document.getElementsByTagName( 'EMBED' ) ;
+
+	var oEmbed ;
+	var i = aEmbeds.length - 1 ;
+	while ( i >= 0 && ( oEmbed = aEmbeds[i--] ) )
+	{
+		// IE doesn't return the type attribute with oEmbed.type or oEmbed.getAttribute("type") 
+		// But it turns out that after accessing it then it doesn't gets copied later
+		var oType = oEmbed.attributes[ 'type' ] ;
+
+		// Check the extension and the type. Now it should be enough with just the type
+		// Opera doesn't return oEmbed.src so oEmbed.src.EndsWith will fail
+		if ( (oEmbed.src && oEmbed.src.EndsWith( '.swf', true )) || ( oType && oType.nodeValue == 'application/x-shockwave-flash' ) )
+		{
+			var oCloned = oEmbed.cloneNode( true ) ;
+
+			// On IE, some properties are not getting clonned properly, so we
+			// must fix it. Thanks to Alfonso Martinez.
+			if ( FCKBrowserInfo.IsIE )
+			{
+				var aAttributes = [ 'scale', 'play', 'loop', 'menu', 'wmode', 'quality' ] ;
+				for ( var iAtt = 0 ; iAtt < aAttributes.length ; iAtt++ )
+				{
+					var oAtt = oEmbed.getAttribute( aAttributes[iAtt] ) ;
+					if ( oAtt ) oCloned.setAttribute( aAttributes[iAtt], oAtt ) ;
+				}
+				// It magically gets lost after reading it in oType
+				oCloned.setAttribute( 'type', oType.nodeValue ) ;
+			}
+
+			var oImg = FCKDocumentProcessor_CreateFakeImage( 'FCK__Flash', oCloned ) ;
+			oImg.setAttribute( '_fckflash', 'true', 0 ) ;
+
+			FCKFlashProcessor.RefreshView( oImg, oEmbed ) ;
+
+			oEmbed.parentNode.insertBefore( oImg, oEmbed ) ;
+			oEmbed.parentNode.removeChild( oEmbed ) ;
+
+//			oEmbed.setAttribute( '_fcktemp', 'true', 0) ;
+//			oEmbed.style.display = 'none' ;
+//			oEmbed.hidden = true ;
+		}
+	}
+}
+
+FCKFlashProcessor.RefreshView = function( placholderImage, originalEmbed )
+{
+	if ( originalEmbed.width > 0 )
+		placholderImage.style.width = FCKTools.ConvertHtmlSizeToStyle( originalEmbed.width ) ;
+
+	if ( originalEmbed.height > 0 )
+		placholderImage.style.height = FCKTools.ConvertHtmlSizeToStyle( originalEmbed.height ) ;
+}
+
+FCK.GetRealElement = function( fakeElement )
+{
+	var e = FCKTempBin.Elements[ fakeElement.getAttribute('_fckrealelement') ] ;
+
+	if ( fakeElement.getAttribute('_fckflash') )
+	{
+		if ( fakeElement.style.width.length > 0 )
+				e.width = FCKTools.ConvertStyleSizeToHtml( fakeElement.style.width ) ;
+
+		if ( fakeElement.style.height.length > 0 )
+				e.height = FCKTools.ConvertStyleSizeToHtml( fakeElement.style.height ) ;
+	}
+
+	return e ;
+}
+
+// HR Processor.
+// This is a IE only (tricky) thing. We protect all HR tags before loading them
+// (see FCK.ProtectTags). Here we put the HRs back.
+if ( FCKBrowserInfo.IsIE )
+{
+	FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )
+	{
+		var aHRs = document.getElementsByTagName( 'HR' ) ;
+
+		var eHR ;
+		var i = aHRs.length - 1 ;
+		while ( i >= 0 && ( eHR = aHRs[i--] ) )
+		{
+			// Create the replacement HR.
+			var newHR = document.createElement( 'hr' ) ;
+			newHR.mergeAttributes( eHR, true ) ;
+			
+			// We must insert the new one after it. insertBefore will not work in all cases.
+			FCKDomTools.InsertAfterNode( eHR, newHR ) ;
+
+			eHR.parentNode.removeChild( eHR ) ;
+		}
+	}
+}
+
+// INPUT:hidden Processor.
+FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )
+{
+	var aInputs = document.getElementsByTagName( 'INPUT' ) ;
+
+	var oInput ;
+	var i = aInputs.length - 1 ;
+	while ( i >= 0 && ( oInput = aInputs[i--] ) )
+	{
+		if ( oInput.type == 'hidden' )
+		{
+			var oImg = FCKDocumentProcessor_CreateFakeImage( 'FCK__InputHidden', oInput.cloneNode(true) ) ;
+			oImg.setAttribute( '_fckinputhidden', 'true', 0 ) ;
+
+			oInput.parentNode.insertBefore( oImg, oInput ) ;
+			oInput.parentNode.removeChild( oInput ) ;
+		}
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklanguagemanager.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklanguagemanager.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/internals/fcklanguagemanager.js	(revision 795)
@@ -0,0 +1,161 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKLanguageManager object that is used for language
+ * operations.
+ */
+
+var FCKLanguageManager = FCK.Language =
+{
+	AvailableLanguages :
+	{
+		af		: 'Afrikaans',
+		ar		: 'Arabic',
+		bg		: 'Bulgarian',
+		bn		: 'Bengali/Bangla',
+		bs		: 'Bosnian',
+		ca		: 'Catalan',
+		cs		: 'Czech',
+		da		: 'Danish',
+		de		: 'German',
+		el		: 'Greek',
+		en		: 'English',
+		'en-au'	: 'English (Australia)',
+		'en-ca'	: 'English (Canadian)',
+		'en-uk'	: 'English (United Kingdom)',
+		eo		: 'Esperanto',
+		es		: 'Spanish',
+		et		: 'Estonian',
+		eu		: 'Basque',
+		fa		: 'Persian',
+		fi		: 'Finnish',
+		fo		: 'Faroese',
+		fr		: 'French',
+		gl		: 'Galician',
+		he		: 'Hebrew',
+		hi		: 'Hindi',
+		hr		: 'Croatian',
+		hu		: 'Hungarian',
+		it		: 'Italian',
+		ja		: 'Japanese',
+		km		: 'Khmer',
+		ko		: 'Korean',
+		lt		: 'Lithuanian',
+		lv		: 'Latvian',
+		mn		: 'Mongolian',
+		ms		: 'Malay',
+		nb		: 'Norwegian Bokmal',
+		nl		: 'Dutch',
+		no		: 'Norwegian',
+		pl		: 'Polish',
+		pt		: 'Portuguese (Portugal)',
+		'pt-br'	: 'Portuguese (Brazil)',
+		ro		: 'Romanian',
+		ru		: 'Russian',
+		sk		: 'Slovak',
+		sl		: 'Slovenian',
+		sr		: 'Serbian (Cyrillic)',
+		'sr-latn'	: 'Serbian (Latin)',
+		sv		: 'Swedish',
+		th		: 'Thai',
+		tr		: 'Turkish',
+		uk		: 'Ukrainian',
+		vi		: 'Vietnamese',
+		zh		: 'Chinese Traditional',
+		'zh-cn'	: 'Chinese Simplified'
+	},
+
+	GetActiveLanguage : function()
+	{
+		if ( FCKConfig.AutoDetectLanguage )
+		{
+			var sUserLang ;
+
+			// IE accepts "navigator.userLanguage" while Gecko "navigator.language".
+			if ( navigator.userLanguage )
+				sUserLang = navigator.userLanguage.toLowerCase() ;
+			else if ( navigator.language )
+				sUserLang = navigator.language.toLowerCase() ;
+			else
+			{
+				// Firefox 1.0 PR has a bug: it doens't support the "language" property.
+				return FCKConfig.DefaultLanguage ;
+			}
+
+			// Some language codes are set in 5 characters,
+			// like "pt-br" for Brasilian Portuguese.
+			if ( sUserLang.length >= 5 )
+			{
+				sUserLang = sUserLang.substr(0,5) ;
+				if ( this.AvailableLanguages[sUserLang] ) return sUserLang ;
+			}
+
+			// If the user's browser is set to, for example, "pt-br" but only the
+			// "pt" language file is available then get that file.
+			if ( sUserLang.length >= 2 )
+			{
+				sUserLang = sUserLang.substr(0,2) ;
+				if ( this.AvailableLanguages[sUserLang] ) return sUserLang ;
+			}
+		}
+
+		return this.DefaultLanguage ;
+	},
+
+	TranslateElements : function( targetDocument, tag, propertyToSet, encode )
+	{
+		var e = targetDocument.getElementsByTagName(tag) ;
+		var sKey, s ;
+		for ( var i = 0 ; i < e.length ; i++ )
+		{
+			// The extra () is to avoid a warning with strict error checking. This is ok.
+			if ( (sKey = e[i].getAttribute( 'fckLang' )) )
+			{
+				// The extra () is to avoid a warning with strict error checking. This is ok.
+				if ( (s = FCKLang[ sKey ]) )
+				{
+					if ( encode )
+						s = FCKTools.HTMLEncode( s ) ;
+					eval( 'e[i].' + propertyToSet + ' = s' ) ;
+				}
+			}
+		}
+	},
+
+	TranslatePage : function( targetDocument )
+	{
+		this.TranslateElements( targetDocument, 'INPUT', 'value' ) ;
+		this.TranslateElements( targetDocument, 'SPAN', 'innerHTML' ) ;
+		this.TranslateElements( targetDocument, 'LABEL', 'innerHTML' ) ;
+		this.TranslateElements( targetDocument, 'OPTION', 'innerHTML', true ) ;
+	},
+
+	Initialize : function()
+	{
+		if ( this.AvailableLanguages[ FCKConfig.DefaultLanguage ] )
+			this.DefaultLanguage = FCKConfig.DefaultLanguage ;
+		else
+			this.DefaultLanguage = 'en' ;
+
+		this.ActiveLanguage = new Object() ;
+		this.ActiveLanguage.Code = this.GetActiveLanguage() ;
+		this.ActiveLanguage.Name = this.AvailableLanguages[ this.ActiveLanguage.Code ] ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckjscoreextensions.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckjscoreextensions.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckjscoreextensions.js	(revision 795)
@@ -0,0 +1,152 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Extensions to the JavaScript Core.
+ *
+ * All custom extentions functions are PascalCased to differ from the standard
+ * camelCased ones.
+ */
+
+String.prototype.Contains = function( textToCheck )
+{
+	return ( this.indexOf( textToCheck ) > -1 ) ;
+}
+
+String.prototype.Equals = function()
+{
+	var aArgs = arguments ;
+
+	// The arguments could also be a single array.
+	if ( aArgs.length == 1 && aArgs[0].pop )
+		aArgs = aArgs[0] ;
+
+	for ( var i = 0 ; i < aArgs.length ; i++ )
+	{
+		if ( this == aArgs[i] )
+			return true ;
+	}
+	return false ;
+}
+
+String.prototype.IEquals = function()
+{
+	var thisUpper = this.toUpperCase() ;
+
+	var aArgs = arguments ;
+
+	// The arguments could also be a single array.
+	if ( aArgs.length == 1 && aArgs[0].pop )
+		aArgs = aArgs[0] ;
+
+	for ( var i = 0 ; i < aArgs.length ; i++ )
+	{
+		if ( thisUpper == aArgs[i].toUpperCase() )
+			return true ;
+	}
+	return false ;
+}
+
+String.prototype.ReplaceAll = function( searchArray, replaceArray )
+{
+	var replaced = this ;
+
+	for ( var i = 0 ; i < searchArray.length ; i++ )
+	{
+		replaced = replaced.replace( searchArray[i], replaceArray[i] ) ;
+	}
+
+	return replaced ;
+}
+
+Array.prototype.AddItem = function( item )
+{
+	var i = this.length ;
+	this[ i ] = item ;
+	return i ;
+}
+
+Array.prototype.IndexOf = function( value )
+{
+	for ( var i = 0 ; i < this.length ; i++ )
+	{
+		if ( this[i] == value )
+			return i ;
+	}
+	return -1 ;
+}
+
+String.prototype.StartsWith = function( value )
+{
+	return ( this.substr( 0, value.length ) == value ) ;
+}
+
+// Extends the String object, creating a "EndsWith" method on it.
+String.prototype.EndsWith = function( value, ignoreCase )
+{
+	var L1 = this.length ;
+	var L2 = value.length ;
+
+	if ( L2 > L1 )
+		return false ;
+
+	if ( ignoreCase )
+	{
+		var oRegex = new RegExp( value + '$' , 'i' ) ;
+		return oRegex.test( this ) ;
+	}
+	else
+		return ( L2 == 0 || this.substr( L1 - L2, L2 ) == value ) ;
+}
+
+String.prototype.Remove = function( start, length )
+{
+	var s = '' ;
+
+	if ( start > 0 )
+		s = this.substring( 0, start ) ;
+
+	if ( start + length < this.length )
+		s += this.substring( start + length , this.length ) ;
+
+	return s ;
+}
+
+String.prototype.Trim = function()
+{
+	// We are not using \s because we don't want "non-breaking spaces to be caught".
+	return this.replace( /(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '' ) ;
+}
+
+String.prototype.LTrim = function()
+{
+	// We are not using \s because we don't want "non-breaking spaces to be caught".
+	return this.replace( /^[ \t\n\r]*/g, '' ) ;
+}
+
+String.prototype.RTrim = function()
+{
+	// We are not using \s because we don't want "non-breaking spaces to be caught".
+	return this.replace( /[ \t\n\r]*$/g, '' ) ;
+}
+
+String.prototype.ReplaceNewLineChars = function( replacement )
+{
+	return this.replace( /\n/g, replacement ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckscriptloader.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckscriptloader.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckscriptloader.js	(revision 795)
@@ -0,0 +1,108 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is a utility object which can be used to load specific components of
+ * FCKeditor, including all dependencies.
+ */
+
+var FCK_GENERIC = 1 ;
+var FCK_GENERIC_SPECIFIC = 2 ;
+var FCK_SPECIFIC = 3 ;
+
+var FCKScriptLoader = new Object() ;
+FCKScriptLoader.FCKeditorPath = '/fckeditor/' ;
+
+FCKScriptLoader._Scripts = new Object() ;
+FCKScriptLoader._LoadedScripts = new Object() ;
+
+FCKScriptLoader._IsIE = (/msie/).test( navigator.userAgent.toLowerCase() ) ;
+
+FCKScriptLoader.Load = function( scriptName )
+{
+	// Check if the script has already been loaded.
+	if ( scriptName in FCKScriptLoader._LoadedScripts )
+		return ;
+
+	var oScriptInfo = this._Scripts[ scriptName ] ;
+
+	if ( !oScriptInfo )
+	{
+		alert( 'FCKScriptLoader: The script "' + scriptName + '" could not be loaded' ) ;
+		return ;
+	}
+
+	for ( var i = 0 ; i < oScriptInfo.Dependency.length ; i++ )
+	{
+		this.Load( oScriptInfo.Dependency[i] ) ;
+	}
+
+	var sBaseScriptName = oScriptInfo.BasePath + scriptName.toLowerCase() ;
+
+	if ( oScriptInfo.Compatibility == FCK_GENERIC || oScriptInfo.Compatibility == FCK_GENERIC_SPECIFIC )
+		this._LoadScript( sBaseScriptName + '.js' ) ;
+
+	if ( oScriptInfo.Compatibility == FCK_SPECIFIC || oScriptInfo.Compatibility == FCK_GENERIC_SPECIFIC )
+	{
+		if ( this._IsIE )
+			this._LoadScript( sBaseScriptName + '_ie.js' ) ;
+		else
+			this._LoadScript( sBaseScriptName + '_gecko.js' ) ;
+	}
+
+	FCKScriptLoader._LoadedScripts[ scriptName ] = true ;
+}
+
+FCKScriptLoader._LoadScript = function( scriptPathFromSource )
+{
+	document.write( '<script type="text/javascript" src="' + this.FCKeditorPath + 'editor/_source/' + scriptPathFromSource + '" onerror="alert(\'Error loading \' + scriptPathFromSource);"><\/script>' ) ;
+}
+
+FCKScriptLoader.AddScript = function( scriptName, scriptBasePath, dependency, compatibility )
+{
+	this._Scripts[ scriptName ] =
+	{
+		BasePath : scriptBasePath || '',
+		Dependency : dependency || [],
+		Compatibility : compatibility || FCK_GENERIC
+	} ;
+}
+
+/*
+ * ####################################
+ * ### Scripts Definition List
+ */
+
+FCKScriptLoader.AddScript( 'FCKConstants' ) ;
+FCKScriptLoader.AddScript( 'FCKJSCoreExtensions' ) ;
+FCKScriptLoader.AddScript( 'FCKImagePreloader'	, 'classes/' ) ;
+FCKScriptLoader.AddScript( 'FCKBrowserInfo'		, 'internals/'	, ['FCKJSCoreExtensions'] ) ;
+FCKScriptLoader.AddScript( 'FCKConfig'			, 'internals/' ) ;
+FCKScriptLoader.AddScript( 'FCKListsLib'		, 'internals/' ) ;
+FCKScriptLoader.AddScript( 'FCKDebug'			, 'internals/'	, ['FCKConfig'] ) ;
+FCKScriptLoader.AddScript( 'FCKDomTools'		, 'internals/'	, ['FCKJSCoreExtensions'], FCK_GENERIC ) ;
+FCKScriptLoader.AddScript( 'FCKTools'			, 'internals/'	, ['FCKJSCoreExtensions','FCKBrowserInfo'], FCK_GENERIC_SPECIFIC ) ;
+FCKScriptLoader.AddScript( 'FCKElementPath'		, 'classes/'	, ['FCKListsLib'], FCK_GENERIC ) ;
+FCKScriptLoader.AddScript( 'FCKDocumentFragment', 'classes/'	, ['FCKDomTools'], FCK_SPECIFIC ) ;
+FCKScriptLoader.AddScript( 'FCKDomRange'		, 'classes/'	, ['FCKBrowserInfo','FCKJSCoreExtensions','FCKW3CRange','FCKElementPath','FCKDomTools','FCKTools','FCKDocumentFragment'], FCK_GENERIC_SPECIFIC ) ;
+FCKScriptLoader.AddScript( 'FCKEnterKey'		, 'classes/'	, ['FCKDomRange','FCKDomTools','FCKTools','FCKKeystrokeHandler','FCKListHandler'], FCK_GENERIC ) ;
+FCKScriptLoader.AddScript( 'FCKKeystrokeHandler', 'classes/'	, ['FCKConstants','FCKBrowserInfo','FCKTools'], FCK_GENERIC ) ;
+FCKScriptLoader.AddScript( 'FCKListHandler'		, 'internals/'	, ['FCKJSCoreExtensions','FCKDomTools','FCKTools'], FCK_GENERIC ) ;
+FCKScriptLoader.AddScript( 'FCKW3CRange'		, 'classes/'	, ['FCKDomTools','FCKTools','FCKDocumentFragment'], FCK_GENERIC ) ;
+// ####################################
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckconstants.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckconstants.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/fckconstants.js	(revision 795)
@@ -0,0 +1,52 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines some constants used by the editor. These constants are also
+ * globally available in the page where the editor is placed.
+ */
+
+// Editor Instance Status.
+var FCK_STATUS_NOTLOADED	= window.parent.FCK_STATUS_NOTLOADED	= 0 ;
+var FCK_STATUS_ACTIVE		= window.parent.FCK_STATUS_ACTIVE		= 1 ;
+var FCK_STATUS_COMPLETE		= window.parent.FCK_STATUS_COMPLETE		= 2 ;
+
+// Tristate Operations.
+var FCK_TRISTATE_OFF		= window.parent.FCK_TRISTATE_OFF		= 0 ;
+var FCK_TRISTATE_ON			= window.parent.FCK_TRISTATE_ON			= 1 ;
+var FCK_TRISTATE_DISABLED	= window.parent.FCK_TRISTATE_DISABLED	= -1 ;
+
+// For unknown values.
+var FCK_UNKNOWN				= window.parent.FCK_UNKNOWN				= -9 ;
+
+// Toolbar Items Style.
+var FCK_TOOLBARITEM_ONLYICON	= window.parent.FCK_TOOLBARITEM_ONLYICON	= 0 ;
+var FCK_TOOLBARITEM_ONLYTEXT	= window.parent.FCK_TOOLBARITEM_ONLYTEXT	= 1 ;
+var FCK_TOOLBARITEM_ICONTEXT	= window.parent.FCK_TOOLBARITEM_ICONTEXT	= 2 ;
+
+// Edit Mode
+var FCK_EDITMODE_WYSIWYG	= window.parent.FCK_EDITMODE_WYSIWYG	= 0 ;
+var FCK_EDITMODE_SOURCE		= window.parent.FCK_EDITMODE_SOURCE		= 1 ;
+
+var FCK_IMAGES_PATH = 'images/' ;		// Check usage.
+var FCK_SPACER_PATH = 'images/spacer.gif' ;
+
+var CTRL	= 1000 ;
+var SHIFT	= 2000 ;
+var ALT		= 4000 ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fck_othercommands.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fck_othercommands.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fck_othercommands.js	(revision 795)
@@ -0,0 +1,380 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Definition of other commands that are not available internaly in the
+ * browser (see FCKNamedCommand).
+ */
+
+// ### General Dialog Box Commands.
+var FCKDialogCommand = function( name, title, url, width, height, getStateFunction, getStateParam )
+{
+	this.Name	= name ;
+	this.Title	= title ;
+	this.Url	= url ;
+	this.Width	= width ;
+	this.Height	= height ;
+
+	this.GetStateFunction	= getStateFunction ;
+	this.GetStateParam		= getStateParam ;
+
+	this.Resizable = false ;
+}
+
+FCKDialogCommand.prototype.Execute = function()
+{
+	FCKDialog.OpenDialog( 'FCKDialog_' + this.Name , this.Title, this.Url, this.Width, this.Height, null, null, this.Resizable ) ;
+}
+
+FCKDialogCommand.prototype.GetState = function()
+{
+	if ( this.GetStateFunction )
+		return this.GetStateFunction( this.GetStateParam ) ;
+	else
+		return FCK_TRISTATE_OFF ;
+}
+
+// Generic Undefined command (usually used when a command is under development).
+var FCKUndefinedCommand = function()
+{
+	this.Name = 'Undefined' ;
+}
+
+FCKUndefinedCommand.prototype.Execute = function()
+{
+	alert( FCKLang.NotImplemented ) ;
+}
+
+FCKUndefinedCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
+
+// ### FontName
+var FCKFontNameCommand = function()
+{
+	this.Name = 'FontName' ;
+}
+
+FCKFontNameCommand.prototype.Execute = function( fontName )
+{
+	if (fontName == null || fontName == "")
+	{
+		// TODO: Remove font name attribute.
+	}
+	else
+		FCK.ExecuteNamedCommand( 'FontName', fontName ) ;
+}
+
+FCKFontNameCommand.prototype.GetState = function()
+{
+	return FCK.GetNamedCommandValue( 'FontName' ) ;
+}
+
+// ### FontSize
+var FCKFontSizeCommand = function()
+{
+	this.Name = 'FontSize' ;
+}
+
+FCKFontSizeCommand.prototype.Execute = function( fontSize )
+{
+	if ( typeof( fontSize ) == 'string' ) fontSize = parseInt(fontSize, 10) ;
+
+	if ( fontSize == null || fontSize == '' )
+	{
+		// TODO: Remove font size attribute (Now it works with size 3. Will it work forever?)
+		FCK.ExecuteNamedCommand( 'FontSize', 3 ) ;
+	}
+	else
+		FCK.ExecuteNamedCommand( 'FontSize', fontSize ) ;
+}
+
+FCKFontSizeCommand.prototype.GetState = function()
+{
+	return FCK.GetNamedCommandValue( 'FontSize' ) ;
+}
+
+// ### FormatBlock
+var FCKFormatBlockCommand = function()
+{
+	this.Name = 'FormatBlock' ;
+}
+
+FCKFormatBlockCommand.prototype.Execute = function( formatName )
+{
+	if ( formatName == null || formatName == '' )
+		FCK.ExecuteNamedCommand( 'FormatBlock', '<P>' ) ;
+	else if ( formatName == 'div' && FCKBrowserInfo.IsGecko )
+		FCK.ExecuteNamedCommand( 'FormatBlock', 'div' ) ;
+	else
+		FCK.ExecuteNamedCommand( 'FormatBlock', '<' + formatName + '>' ) ;
+}
+
+FCKFormatBlockCommand.prototype.GetState = function()
+{
+	return FCK.GetNamedCommandValue( 'FormatBlock' ) ;
+}
+
+// ### Preview
+var FCKPreviewCommand = function()
+{
+	this.Name = 'Preview' ;
+}
+
+FCKPreviewCommand.prototype.Execute = function()
+{
+     FCK.Preview() ;
+}
+
+FCKPreviewCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
+
+// ### Save
+var FCKSaveCommand = function()
+{
+	this.Name = 'Save' ;
+}
+
+FCKSaveCommand.prototype.Execute = function()
+{
+	// Get the linked field form.
+	var oForm = FCK.GetParentForm() ;
+
+	if ( typeof( oForm.onsubmit ) == 'function' )
+	{
+		var bRet = oForm.onsubmit() ;
+		if ( bRet != null && bRet === false )
+			return ;
+	}
+
+	// Submit the form.
+	oForm.submit() ;
+}
+
+FCKSaveCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
+
+// ### NewPage
+var FCKNewPageCommand = function()
+{
+	this.Name = 'NewPage' ;
+}
+
+FCKNewPageCommand.prototype.Execute = function()
+{
+	FCKUndo.SaveUndoStep() ;
+	FCK.SetHTML( '' ) ;
+	FCKUndo.Typing = true ;
+}
+
+FCKNewPageCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
+
+// ### Source button
+var FCKSourceCommand = function()
+{
+	this.Name = 'Source' ;
+}
+
+FCKSourceCommand.prototype.Execute = function()
+{
+	if ( FCKConfig.SourcePopup )	// Until v2.2, it was mandatory for FCKBrowserInfo.IsGecko.
+	{
+		var iWidth	= FCKConfig.ScreenWidth * 0.65 ;
+		var iHeight	= FCKConfig.ScreenHeight * 0.65 ;
+		FCKDialog.OpenDialog( 'FCKDialog_Source', FCKLang.Source, 'dialog/fck_source.html', iWidth, iHeight, null, null, true ) ;
+	}
+	else
+	    FCK.SwitchEditMode() ;
+}
+
+FCKSourceCommand.prototype.GetState = function()
+{
+	return ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_OFF : FCK_TRISTATE_ON ) ;
+}
+
+// ### Undo
+var FCKUndoCommand = function()
+{
+	this.Name = 'Undo' ;
+}
+
+FCKUndoCommand.prototype.Execute = function()
+{
+	if ( FCKBrowserInfo.IsIE )
+		FCKUndo.Undo() ;
+	else
+		FCK.ExecuteNamedCommand( 'Undo' ) ;
+}
+
+FCKUndoCommand.prototype.GetState = function()
+{
+	if ( FCKBrowserInfo.IsIE )
+		return ( FCKUndo.CheckUndoState() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
+	else
+		return FCK.GetNamedCommandState( 'Undo' ) ;
+}
+
+// ### Redo
+var FCKRedoCommand = function()
+{
+	this.Name = 'Redo' ;
+}
+
+FCKRedoCommand.prototype.Execute = function()
+{
+	if ( FCKBrowserInfo.IsIE )
+		FCKUndo.Redo() ;
+	else
+		FCK.ExecuteNamedCommand( 'Redo' ) ;
+}
+
+FCKRedoCommand.prototype.GetState = function()
+{
+	if ( FCKBrowserInfo.IsIE )
+		return ( FCKUndo.CheckRedoState() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
+	else
+		return FCK.GetNamedCommandState( 'Redo' ) ;
+}
+
+// ### Page Break
+var FCKPageBreakCommand = function()
+{
+	this.Name = 'PageBreak' ;
+}
+
+FCKPageBreakCommand.prototype.Execute = function()
+{
+//	var e = FCK.EditorDocument.createElement( 'CENTER' ) ;
+//	e.style.pageBreakAfter = 'always' ;
+
+	// Tidy was removing the empty CENTER tags, so the following solution has
+	// been found. It also validates correctly as XHTML 1.0 Strict.
+	var e = FCK.EditorDocument.createElement( 'DIV' ) ;
+	e.style.pageBreakAfter = 'always' ;
+	e.innerHTML = '<span style="DISPLAY:none">&nbsp;</span>' ;
+
+	var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', e ) ;
+	oFakeImage	= FCK.InsertElement( oFakeImage ) ;
+}
+
+FCKPageBreakCommand.prototype.GetState = function()
+{
+	return 0 ; // FCK_TRISTATE_OFF
+}
+
+// FCKUnlinkCommand - by Johnny Egeland (johnny@coretrek.com)
+var FCKUnlinkCommand = function()
+{
+	this.Name = 'Unlink' ;
+}
+
+FCKUnlinkCommand.prototype.Execute = function()
+{
+	if ( FCKBrowserInfo.IsGecko )
+	{
+		var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+		if ( oLink )
+			FCK.Selection.SelectNode( oLink ) ;
+	}
+
+	FCK.ExecuteNamedCommand( this.Name ) ;
+
+	if ( FCKBrowserInfo.IsGecko )
+		FCK.Selection.Collapse( true ) ;
+}
+
+FCKUnlinkCommand.prototype.GetState = function()
+{
+	var state = FCK.GetNamedCommandState( this.Name ) ;
+
+	// Check that it isn't an anchor
+	if ( state == FCK_TRISTATE_OFF && FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+	{
+		var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ;
+		var bIsAnchor = ( oLink && oLink.name.length > 0 && oLink.href.length == 0 ) ;
+		if ( bIsAnchor )
+			state = FCK_TRISTATE_DISABLED ;
+	}
+
+	return state ;
+}
+
+// FCKSelectAllCommand
+var FCKSelectAllCommand = function()
+{
+	this.Name = 'SelectAll' ;
+}
+
+FCKSelectAllCommand.prototype.Execute = function()
+{
+	if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+	{
+		FCK.ExecuteNamedCommand( 'SelectAll' ) ;
+	}
+	else
+	{
+		// Select the contents of the textarea
+		var textarea = FCK.EditingArea.Textarea ;
+		if ( FCKBrowserInfo.IsIE )
+		{
+			textarea.createTextRange().execCommand( 'SelectAll' ) ;
+		}
+		else
+		{
+			textarea.selectionStart = 0;
+			textarea.selectionEnd = textarea.value.length ;
+		}
+		textarea.focus() ;
+	}
+}
+
+FCKSelectAllCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
+
+// FCKPasteCommand
+var FCKPasteCommand = function()
+{
+	this.Name = 'Paste' ;
+}
+
+FCKPasteCommand.prototype =
+{
+	Execute : function()
+	{
+		if ( FCKBrowserInfo.IsIE )
+			FCK.Paste() ;
+		else
+			FCK.ExecuteNamedCommand( 'Paste' ) ;
+	},
+
+	GetState : function()
+	{
+		return FCK.GetNamedCommandState( 'Paste' ) ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcktextcolorcommand.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcktextcolorcommand.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcktextcolorcommand.js	(revision 795)
@@ -0,0 +1,175 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKTextColorCommand Class: represents the text color comand. It shows the
+ * color selection panel.
+ */
+
+// FCKTextColorCommand Contructor
+//		type: can be 'ForeColor' or 'BackColor'.
+var FCKTextColorCommand = function( type )
+{
+	this.Name = type == 'ForeColor' ? 'TextColor' : 'BGColor' ;
+	this.Type = type ;
+
+	var oWindow ;
+
+	if ( FCKBrowserInfo.IsIE )
+		oWindow = window ;
+	else if ( FCK.ToolbarSet._IFrame )
+		oWindow = FCKTools.GetElementWindow( FCK.ToolbarSet._IFrame ) ;
+	else
+		oWindow = window.parent ;
+
+	this._Panel = new FCKPanel( oWindow, true ) ;
+	this._Panel.AppendStyleSheet( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+	this._Panel.MainNode.className = 'FCK_Panel' ;
+	this._CreatePanelBody( this._Panel.Document, this._Panel.MainNode ) ;
+
+	FCKTools.DisableSelection( this._Panel.Document.body ) ;
+}
+
+FCKTextColorCommand.prototype.Execute = function( panelX, panelY, relElement )
+{
+	// We must "cache" the actual panel type to be used in the SetColor method.
+	FCK._ActiveColorPanelType = this.Type ;
+
+	// Show the Color Panel at the desired position.
+	this._Panel.Show( panelX, panelY, relElement ) ;
+}
+
+FCKTextColorCommand.prototype.SetColor = function( color )
+{
+	if ( FCK._ActiveColorPanelType == 'ForeColor' )
+		FCK.ExecuteNamedCommand( 'ForeColor', color ) ;
+	else if ( FCKBrowserInfo.IsGeckoLike )
+	{
+		if ( FCKBrowserInfo.IsGecko && !FCKConfig.GeckoUseSPAN )
+			FCK.EditorDocument.execCommand( 'useCSS', false, false ) ;
+
+		FCK.ExecuteNamedCommand( 'hilitecolor', color ) ;
+
+		if ( FCKBrowserInfo.IsGecko && !FCKConfig.GeckoUseSPAN )
+			FCK.EditorDocument.execCommand( 'useCSS', false, true ) ;
+	}
+	else
+		FCK.ExecuteNamedCommand( 'BackColor', color ) ;
+
+	// Delete the "cached" active panel type.
+	delete FCK._ActiveColorPanelType ;
+}
+
+FCKTextColorCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
+
+function FCKTextColorCommand_OnMouseOver()	{ this.className='ColorSelected' ; }
+
+function FCKTextColorCommand_OnMouseOut()	{ this.className='ColorDeselected' ; }
+
+function FCKTextColorCommand_OnClick()
+{
+	this.className = 'ColorDeselected' ;
+	this.Command.SetColor( '#' + this.Color ) ;
+	this.Command._Panel.Hide() ;
+}
+
+function FCKTextColorCommand_AutoOnClick()
+{
+	this.className = 'ColorDeselected' ;
+	this.Command.SetColor( '' ) ;
+	this.Command._Panel.Hide() ;
+}
+
+function FCKTextColorCommand_MoreOnClick()
+{
+	this.className = 'ColorDeselected' ;
+	this.Command._Panel.Hide() ;
+	FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, this.Command.SetColor ) ;
+}
+
+FCKTextColorCommand.prototype._CreatePanelBody = function( targetDocument, targetDiv )
+{
+	function CreateSelectionDiv()
+	{
+		var oDiv = targetDocument.createElement( "DIV" ) ;
+		oDiv.className		= 'ColorDeselected' ;
+		oDiv.onmouseover	= FCKTextColorCommand_OnMouseOver ;
+		oDiv.onmouseout		= FCKTextColorCommand_OnMouseOut ;
+
+		return oDiv ;
+	}
+
+	// Create the Table that will hold all colors.
+	var oTable = targetDiv.appendChild( targetDocument.createElement( "TABLE" ) ) ;
+	oTable.className = 'ForceBaseFont' ;		// Firefox 1.5 Bug.
+	oTable.style.tableLayout = 'fixed' ;
+	oTable.cellPadding = 0 ;
+	oTable.cellSpacing = 0 ;
+	oTable.border = 0 ;
+	oTable.width = 150 ;
+
+	var oCell = oTable.insertRow(-1).insertCell(-1) ;
+	oCell.colSpan = 8 ;
+
+	// Create the Button for the "Automatic" color selection.
+	var oDiv = oCell.appendChild( CreateSelectionDiv() ) ;
+	oDiv.innerHTML =
+		'<table cellspacing="0" cellpadding="0" width="100%" border="0">\
+			<tr>\
+				<td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\
+				<td nowrap width="100%" align="center">' + FCKLang.ColorAutomatic + '</td>\
+			</tr>\
+		</table>' ;
+
+	oDiv.Command = this ;
+	oDiv.onclick = FCKTextColorCommand_AutoOnClick ;
+
+	// Create an array of colors based on the configuration file.
+	var aColors = FCKConfig.FontColors.toString().split(',') ;
+
+	// Create the colors table based on the array.
+	var iCounter = 0 ;
+	while ( iCounter < aColors.length )
+	{
+		var oRow = oTable.insertRow(-1) ;
+
+		for ( var i = 0 ; i < 8 && iCounter < aColors.length ; i++, iCounter++ )
+		{
+			oDiv = oRow.insertCell(-1).appendChild( CreateSelectionDiv() ) ;
+			oDiv.Color = aColors[iCounter] ;
+			oDiv.innerHTML = '<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #' + aColors[iCounter] + '"></div></div>' ;
+
+			oDiv.Command = this ;
+			oDiv.onclick = FCKTextColorCommand_OnClick ;
+		}
+	}
+
+	// Create the Row and the Cell for the "More Colors..." button.
+	oCell = oTable.insertRow(-1).insertCell(-1) ;
+	oCell.colSpan = 8 ;
+
+	oDiv = oCell.appendChild( CreateSelectionDiv() ) ;
+	oDiv.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">' + FCKLang.ColorMoreColors + '</td></tr></table>' ;
+
+	oDiv.Command = this ;
+	oDiv.onclick = FCKTextColorCommand_MoreOnClick ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcknamedcommand.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcknamedcommand.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcknamedcommand.js	(revision 795)
@@ -0,0 +1,37 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKNamedCommand Class: represents an internal browser command.
+ */
+
+var FCKNamedCommand = function( commandName )
+{
+	this.Name = commandName ;
+}
+
+FCKNamedCommand.prototype.Execute = function()
+{
+	FCK.ExecuteNamedCommand( this.Name ) ;
+}
+
+FCKNamedCommand.prototype.GetState = function()
+{
+	return FCK.GetNamedCommandState( this.Name ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js	(revision 795)
@@ -0,0 +1,38 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPastePlainTextCommand Class: represents the
+ * "Paste as Plain Text" command.
+ */
+
+var FCKPastePlainTextCommand = function()
+{
+	this.Name = 'PasteText' ;
+}
+
+FCKPastePlainTextCommand.prototype.Execute = function()
+{
+	FCK.PasteAsPlainText() ;
+}
+
+FCKPastePlainTextCommand.prototype.GetState = function()
+{
+	return FCK.GetNamedCommandState( 'Paste' ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js	(revision 795)
@@ -0,0 +1,39 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleCommand Class: represents the "Spell Check" command.
+ * (Gecko specific implementation)
+ */
+
+var FCKSpellCheckCommand = function()
+{
+	this.Name = 'SpellCheck' ;
+	this.IsEnabled = ( FCKConfig.SpellChecker == 'SpellerPages' ) ;
+}
+
+FCKSpellCheckCommand.prototype.Execute = function()
+{
+	FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'dialog/fck_spellerpages.html', 440, 480 ) ;
+}
+
+FCKSpellCheckCommand.prototype.GetState = function()
+{
+	return this.IsEnabled ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcktablecommand.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcktablecommand.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fcktablecommand.js	(revision 795)
@@ -0,0 +1,71 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPastePlainTextCommand Class: represents the
+ * "Paste as Plain Text" command.
+ */
+
+var FCKTableCommand = function( command )
+{
+	this.Name = command ;
+}
+
+FCKTableCommand.prototype.Execute = function()
+{
+	FCKUndo.SaveUndoStep() ;
+
+	switch ( this.Name )
+	{
+		case 'TableInsertRow' :
+			FCKTableHandler.InsertRow() ;
+			break ;
+		case 'TableDeleteRows' :
+			FCKTableHandler.DeleteRows() ;
+			break ;
+		case 'TableInsertColumn' :
+			FCKTableHandler.InsertColumn() ;
+			break ;
+		case 'TableDeleteColumns' :
+			FCKTableHandler.DeleteColumns() ;
+			break ;
+		case 'TableInsertCell' :
+			FCKTableHandler.InsertCell() ;
+			break ;
+		case 'TableDeleteCells' :
+			FCKTableHandler.DeleteCells() ;
+			break ;
+		case 'TableMergeCells' :
+			FCKTableHandler.MergeCells() ;
+			break ;
+		case 'TableSplitCell' :
+			FCKTableHandler.SplitCell() ;
+			break ;
+		case 'TableDelete' :
+			FCKTableHandler.DeleteTable() ;
+			break ;
+		default :
+			alert( FCKLang.UnknownCommand.replace( /%1/g, this.Name ) ) ;
+	}
+}
+
+FCKTableCommand.prototype.GetState = function()
+{
+	return FCK_TRISTATE_OFF ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckpastewordcommand.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckpastewordcommand.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckpastewordcommand.js	(revision 795)
@@ -0,0 +1,40 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPasteWordCommand Class: represents the "Paste from Word" command.
+ */
+
+var FCKPasteWordCommand = function()
+{
+	this.Name = 'PasteWord' ;
+}
+
+FCKPasteWordCommand.prototype.Execute = function()
+{
+	FCK.PasteFromWord() ;
+}
+
+FCKPasteWordCommand.prototype.GetState = function()
+{
+	if ( FCKConfig.ForcePasteAsPlainText )
+		return FCK_TRISTATE_DISABLED ;
+	else
+		return FCK.GetNamedCommandState( 'Paste' ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js	(revision 795)
@@ -0,0 +1,67 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleCommand Class: represents the "Spell Check" command.
+ * (IE specific implementation)
+ */
+
+var FCKSpellCheckCommand = function()
+{
+	this.Name = 'SpellCheck' ;
+	this.IsEnabled = ( FCKConfig.SpellChecker == 'ieSpell' || FCKConfig.SpellChecker == 'SpellerPages' ) ;
+}
+
+FCKSpellCheckCommand.prototype.Execute = function()
+{
+	switch ( FCKConfig.SpellChecker )
+	{
+		case 'ieSpell' :
+			this._RunIeSpell() ;
+			break ;
+
+		case 'SpellerPages' :
+			FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'dialog/fck_spellerpages.html', 440, 480 ) ;
+			break ;
+	}
+}
+
+FCKSpellCheckCommand.prototype._RunIeSpell = function()
+{
+	try
+	{
+		var oIeSpell = new ActiveXObject( "ieSpell.ieSpellExtension" ) ;
+		oIeSpell.CheckAllLinkedDocuments( FCK.EditorDocument ) ;
+	}
+	catch( e )
+	{
+		if( e.number == -2146827859 )
+		{
+			if ( confirm( FCKLang.IeSpellDownload ) )
+				window.open( FCKConfig.IeSpellDownloadUrl , 'IeSpellDownload' ) ;
+		}
+		else
+			alert( 'Error Loading ieSpell: ' + e.message + ' (' + e.number + ')' ) ;
+	}
+}
+
+FCKSpellCheckCommand.prototype.GetState = function()
+{
+	return this.IsEnabled ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckfitwindow.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckfitwindow.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckfitwindow.js	(revision 795)
@@ -0,0 +1,169 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Stretch the editor to full window size and back.
+ */
+
+var FCKFitWindow = function()
+{
+	this.Name = 'FitWindow' ;
+}
+
+FCKFitWindow.prototype.Execute = function()
+{
+	var eEditorFrame		= window.frameElement ;
+	var eEditorFrameStyle	= eEditorFrame.style ;
+
+	var eMainWindow			= parent ;
+	var eDocEl				= eMainWindow.document.documentElement ;
+	var eBody				= eMainWindow.document.body ;
+	var eBodyStyle			= eBody.style ;
+	var eParent ;
+
+	// No original style properties known? Go fullscreen.
+	if ( !this.IsMaximized )
+	{
+		// Registering an event handler when the window gets resized.
+		if( FCKBrowserInfo.IsIE )
+			eMainWindow.attachEvent( 'onresize', FCKFitWindow_Resize ) ;
+		else
+			eMainWindow.addEventListener( 'resize', FCKFitWindow_Resize, true ) ;
+
+		// Save the scrollbars position.
+		this._ScrollPos = FCKTools.GetScrollPosition( eMainWindow ) ;
+
+		// Save and reset the styles for the entire node tree. They could interfere in the result.
+		eParent = eEditorFrame ;
+		// The extra () is to avoid a warning with strict error checking. This is ok.
+		while( (eParent = eParent.parentNode) )
+		{
+			if ( eParent.nodeType == 1 )
+				eParent._fckSavedStyles = FCKTools.SaveStyles( eParent ) ;
+		}
+
+		// Hide IE scrollbars (in strict mode).
+		if ( FCKBrowserInfo.IsIE )
+		{
+			this.documentElementOverflow = eDocEl.style.overflow ;
+			eDocEl.style.overflow	= 'hidden' ;
+			eBodyStyle.overflow		= 'hidden' ;
+		}
+		else
+		{
+			// Hide the scroolbars in Firefox.
+			eBodyStyle.overflow = 'hidden' ;
+			eBodyStyle.width = '0px' ;
+			eBodyStyle.height = '0px' ;
+		}
+
+		// Save the IFRAME styles.
+		this._EditorFrameStyles = FCKTools.SaveStyles( eEditorFrame ) ;
+
+		// Resize.
+		var oViewPaneSize = FCKTools.GetViewPaneSize( eMainWindow ) ;
+
+		eEditorFrameStyle.position	= "absolute";
+		eEditorFrameStyle.zIndex	= FCKConfig.FloatingPanelsZIndex - 1;
+		eEditorFrameStyle.left		= "0px";
+		eEditorFrameStyle.top		= "0px";
+		eEditorFrameStyle.width		= oViewPaneSize.Width + "px";
+		eEditorFrameStyle.height	= oViewPaneSize.Height + "px";
+
+		// Giving the frame some (huge) borders on his right and bottom
+		// side to hide the background that would otherwise show when the
+		// editor is in fullsize mode and the window is increased in size
+		// not for IE, because IE immediately adapts the editor on resize,
+		// without showing any of the background oddly in firefox, the
+		// editor seems not to fill the whole frame, so just setting the
+		// background of it to white to cover the page laying behind it anyway.
+		if ( !FCKBrowserInfo.IsIE )
+		{
+			eEditorFrameStyle.borderRight = eEditorFrameStyle.borderBottom = "9999px solid white" ;
+			eEditorFrameStyle.backgroundColor		= "white";
+		}
+
+		// Scroll to top left.
+		eMainWindow.scrollTo(0, 0);
+
+		this.IsMaximized = true ;
+	}
+	else	// Resize to original size.
+	{
+		// Remove the event handler of window resizing.
+		if( FCKBrowserInfo.IsIE )
+			eMainWindow.detachEvent( "onresize", FCKFitWindow_Resize ) ;
+		else
+			eMainWindow.removeEventListener( "resize", FCKFitWindow_Resize, true ) ;
+
+		// Restore the CSS position for the entire node tree.
+		eParent = eEditorFrame ;
+		// The extra () is to avoid a warning with strict error checking. This is ok.
+		while( (eParent = eParent.parentNode) )
+		{
+			if ( eParent._fckSavedStyles )
+			{
+				FCKTools.RestoreStyles( eParent, eParent._fckSavedStyles ) ;
+				eParent._fckSavedStyles = null ;
+			}
+		}
+
+		// Restore IE scrollbars
+		if ( FCKBrowserInfo.IsIE )
+			eDocEl.style.overflow = this.documentElementOverflow ;
+
+		// Restore original size
+		FCKTools.RestoreStyles( eEditorFrame, this._EditorFrameStyles ) ;
+
+		// Restore the window scroll position.
+		eMainWindow.scrollTo( this._ScrollPos.X, this._ScrollPos.Y ) ;
+
+		this.IsMaximized = false ;
+	}
+
+	FCKToolbarItems.GetItem('FitWindow').RefreshState() ;
+
+	// It seams that Firefox restarts the editing area when making this changes.
+	// On FF 1.0.x, the area is not anymore editable. On FF 1.5+, the special
+	//configuration, like DisableFFTableHandles and DisableObjectResizing get
+	//lost, so we must reset it. Also, the cursor position and selection are
+	//also lost, even if you comment the following line (MakeEditable).
+	// if ( FCKBrowserInfo.IsGecko10 )	// Initially I thought it was a FF 1.0 only problem.
+	FCK.EditingArea.MakeEditable() ;
+
+	FCK.Focus() ;
+}
+
+FCKFitWindow.prototype.GetState = function()
+{
+	if ( FCKConfig.ToolbarLocation != 'In' )
+		return FCK_TRISTATE_DISABLED ;
+	else
+		return ( this.IsMaximized ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF );
+}
+
+function FCKFitWindow_Resize()
+{
+	var oViewPaneSize = FCKTools.GetViewPaneSize( parent ) ;
+
+	var eEditorFrameStyle = window.frameElement.style ;
+
+	eEditorFrameStyle.width		= oViewPaneSize.Width + 'px' ;
+	eEditorFrameStyle.height	= oViewPaneSize.Height + 'px' ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckstylecommand.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckstylecommand.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/commandclasses/fckstylecommand.js	(revision 795)
@@ -0,0 +1,99 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleCommand Class: represents the "Style" command.
+ */
+
+var FCKStyleCommand = function()
+{
+	this.Name = 'Style' ;
+
+	// Load the Styles defined in the XML file.
+	this.StylesLoader = new FCKStylesLoader() ;
+	this.StylesLoader.Load( FCKConfig.StylesXmlPath ) ;
+	this.Styles = this.StylesLoader.Styles ;
+}
+
+FCKStyleCommand.prototype.Execute = function( styleName, styleComboItem )
+{
+	FCKUndo.SaveUndoStep() ;
+
+	if ( styleComboItem.Selected )
+		styleComboItem.Style.RemoveFromSelection() ;
+	else
+		styleComboItem.Style.ApplyToSelection() ;
+
+	FCKUndo.SaveUndoStep() ;
+
+	FCK.Focus() ;
+
+	FCK.Events.FireEvent( "OnSelectionChange" ) ;
+}
+
+FCKStyleCommand.prototype.GetState = function()
+{
+	if ( !FCK.EditorDocument )
+		return FCK_TRISTATE_DISABLED ;
+
+	var oSelection = FCK.EditorDocument.selection ;
+
+	if ( FCKSelection.GetType() == 'Control' )
+	{
+		var e = FCKSelection.GetSelectedElement() ;
+		if ( e )
+			return this.StylesLoader.StyleGroups[ e.tagName ] ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+	}
+
+	return FCK_TRISTATE_OFF ;
+}
+
+FCKStyleCommand.prototype.GetActiveStyles = function()
+{
+	var aActiveStyles = new Array() ;
+
+	if ( FCKSelection.GetType() == 'Control' )
+		this._CheckStyle( FCKSelection.GetSelectedElement(), aActiveStyles, false ) ;
+	else
+		this._CheckStyle( FCKSelection.GetParentElement(), aActiveStyles, true ) ;
+
+	return aActiveStyles ;
+}
+
+FCKStyleCommand.prototype._CheckStyle = function( element, targetArray, checkParent )
+{
+	if ( ! element )
+		return ;
+
+	if ( element.nodeType == 1 )
+	{
+		var aStyleGroup = this.StylesLoader.StyleGroups[ element.tagName ] ;
+		if ( aStyleGroup )
+		{
+			for ( var i = 0 ; i < aStyleGroup.length ; i++ )
+			{
+				if ( aStyleGroup[i].IsEqual( element ) )
+					targetArray[ targetArray.length ] = aStyleGroup[i] ;
+			}
+		}
+	}
+
+	if ( checkParent )
+		this._CheckStyle( element.parentNode, targetArray, checkParent ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarspecialcombo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarspecialcombo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarspecialcombo.js	(revision 795)
@@ -0,0 +1,134 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarSpecialCombo Class: This is a "abstract" base class to be used
+ * by the special combo toolbar elements like font name, font size, paragraph format, etc...
+ *
+ * The following properties and methods must be implemented when inheriting from
+ * this class:
+ * 	- Property:	CommandName							[ The command name to be executed ]
+ * 	- Method:	GetLabel()							[ Returns the label ]
+ * 	-			CreateItems( targetSpecialCombo )	[ Add all items in the special combo ]
+ */
+
+var FCKToolbarSpecialCombo = function()
+{
+	this.SourceView			= false ;
+	this.ContextSensitive	= true ;
+	this._LastValue			= null ;
+}
+
+
+function FCKToolbarSpecialCombo_OnSelect( itemId, item )
+{
+	FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).Execute( itemId, item ) ;
+}
+
+FCKToolbarSpecialCombo.prototype.Create = function( targetElement )
+{
+	this._Combo = new FCKSpecialCombo( this.GetLabel(), this.FieldWidth, this.PanelWidth, this.PanelMaxHeight, FCKBrowserInfo.IsIE ? window : FCKTools.GetElementWindow( targetElement ).parent ) ;
+
+	/*
+	this._Combo.FieldWidth		= this.FieldWidth		!= null ? this.FieldWidth		: 100 ;
+	this._Combo.PanelWidth		= this.PanelWidth		!= null ? this.PanelWidth		: 150 ;
+	this._Combo.PanelMaxHeight	= this.PanelMaxHeight	!= null ? this.PanelMaxHeight	: 150 ;
+	*/
+
+	//this._Combo.Command.Name = this.Command.Name;
+//	this._Combo.Label	= this.Label ;
+	this._Combo.Tooltip	= this.Tooltip ;
+	this._Combo.Style	= this.Style ;
+
+	this.CreateItems( this._Combo ) ;
+
+	this._Combo.Create( targetElement ) ;
+
+	this._Combo.CommandName = this.CommandName ;
+
+	this._Combo.OnSelect = FCKToolbarSpecialCombo_OnSelect ;
+}
+
+function FCKToolbarSpecialCombo_RefreshActiveItems( combo, value )
+{
+	combo.DeselectAll() ;
+	combo.SelectItem( value ) ;
+	combo.SetLabelById( value ) ;
+}
+
+FCKToolbarSpecialCombo.prototype.RefreshState = function()
+{
+	// Gets the actual state.
+	var eState ;
+
+//	if ( FCK.EditMode == FCK_EDITMODE_SOURCE && ! this.SourceView )
+//		eState = FCK_TRISTATE_DISABLED ;
+//	else
+//	{
+		var sValue = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).GetState() ;
+
+//		FCKDebug.Output( 'RefreshState of Special Combo "' + this.TypeOf + '" - State: ' + sValue ) ;
+
+		if ( sValue != FCK_TRISTATE_DISABLED )
+		{
+			eState = FCK_TRISTATE_ON ;
+
+			if ( this.RefreshActiveItems )
+				this.RefreshActiveItems( this._Combo, sValue ) ;
+			else
+			{
+				if ( this._LastValue != sValue )
+				{
+					this._LastValue = sValue ;
+					FCKToolbarSpecialCombo_RefreshActiveItems( this._Combo, sValue ) ;
+				}
+			}
+		}
+		else
+			eState = FCK_TRISTATE_DISABLED ;
+//	}
+
+	// If there are no state changes then do nothing and return.
+	if ( eState == this.State ) return ;
+
+	if ( eState == FCK_TRISTATE_DISABLED )
+	{
+		this._Combo.DeselectAll() ;
+		this._Combo.SetLabel( '' ) ;
+	}
+
+	// Sets the actual state.
+	this.State = eState ;
+
+	// Updates the graphical state.
+	this._Combo.SetEnabled( eState != FCK_TRISTATE_DISABLED ) ;
+}
+
+FCKToolbarSpecialCombo.prototype.Enable = function()
+{
+	this.RefreshState() ;
+}
+
+FCKToolbarSpecialCombo.prototype.Disable = function()
+{
+	this.State = FCK_TRISTATE_DISABLED ;
+	this._Combo.DeselectAll() ;
+	this._Combo.SetLabel( '' ) ;
+	this._Combo.SetEnabled( false ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbreak_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbreak_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbreak_ie.js	(revision 795)
@@ -0,0 +1,38 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarBreak Class: breaks the toolbars.
+ * It makes it possible to force the toolbar to brak to a new line.
+ * This is the IE specific implementation.
+ */
+
+var FCKToolbarBreak = function()
+{}
+
+FCKToolbarBreak.prototype.Create = function( targetElement )
+{
+	var oBreakDiv = FCKTools.GetElementDocument( targetElement ).createElement( 'div' ) ;
+
+	oBreakDiv.className = 'TB_Break' ;
+
+	oBreakDiv.style.clear = FCKLang.Dir == 'rtl' ? 'left' : 'right' ;
+
+	targetElement.appendChild( oBreakDiv ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef_gecko.js	(revision 795)
@@ -0,0 +1,119 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleDef Class: represents a single stylke definition. (Gecko specific)
+ */
+
+FCKStyleDef.prototype.ApplyToSelection = function()
+{
+	if ( FCKSelection.GetType() == 'Text' && !this.IsObjectElement )
+	{
+		var oSelection = FCK.ToolbarSet.CurrentInstance.EditorWindow.getSelection() ;
+
+		// Create the main element.
+		var e = FCK.ToolbarSet.CurrentInstance.EditorDocument.createElement( this.Element ) ;
+
+		for ( var i = 0 ; i < oSelection.rangeCount ; i++ )
+		{
+			e.appendChild( oSelection.getRangeAt(i).extractContents() ) ;
+		}
+
+		// Set the attributes.
+		this._AddAttributes( e ) ;
+
+		// Remove the duplicated elements.
+		this._RemoveDuplicates( e ) ;
+
+		var oRange = oSelection.getRangeAt(0) ;
+		oRange.insertNode( e ) ;
+	}
+	else
+	{
+		var oControl = FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement() ;
+		if ( oControl.tagName == this.Element )
+			this._AddAttributes( oControl ) ;
+	}
+}
+
+FCKStyleDef.prototype._AddAttributes = function( targetElement )
+{
+	for ( var a in this.Attributes )
+	{
+		switch ( a.toLowerCase() )
+		{
+			case 'src' :
+				targetElement.setAttribute( '_fcksavedurl', this.Attributes[a], 0 ) ;
+			default :
+				targetElement.setAttribute( a, this.Attributes[a], 0 ) ;
+		}
+	}
+}
+
+FCKStyleDef.prototype._RemoveDuplicates = function( parent )
+{
+	for ( var i = 0 ; i < parent.childNodes.length ; i++ )
+	{
+		var oChild = parent.childNodes[i] ;
+
+		if ( oChild.nodeType != 1 )
+			continue ;
+
+		this._RemoveDuplicates( oChild ) ;
+
+		if ( this.IsEqual( oChild ) )
+			FCKTools.RemoveOuterTags( oChild ) ;
+	}
+}
+
+FCKStyleDef.prototype.IsEqual = function( e )
+{
+	if ( e.tagName != this.Element )
+		return false ;
+
+	for ( var a in this.Attributes )
+	{
+		if ( e.getAttribute( a ) != this.Attributes[a] )
+			return false ;
+	}
+
+	return true ;
+}
+
+FCKStyleDef.prototype._RemoveMe = function( elementToCheck )
+{
+	if ( ! elementToCheck )
+		return ;
+
+	var oParent = elementToCheck.parentNode ;
+
+	if ( elementToCheck.nodeType == 1 && this.IsEqual( elementToCheck ) )
+	{
+		if ( this.IsObjectElement )
+		{
+			for ( var a in this.Attributes )
+				elementToCheck.removeAttribute( a, 0 ) ;
+			return ;
+		}
+		else
+			FCKTools.RemoveOuterTags( elementToCheck ) ;
+	}
+
+	this._RemoveMe( oParent ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckplugin.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckplugin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckplugin.js	(revision 795)
@@ -0,0 +1,56 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPlugin Class: Represents a single plugin.
+ */
+
+var FCKPlugin = function( name, availableLangs, basePath )
+{
+	this.Name = name ;
+	this.BasePath = basePath ? basePath : FCKConfig.PluginsPath ;
+	this.Path = this.BasePath + name + '/' ;
+
+	if ( !availableLangs || availableLangs.length == 0 )
+		this.AvailableLangs = new Array() ;
+	else
+		this.AvailableLangs = availableLangs.split(',') ;
+}
+
+FCKPlugin.prototype.Load = function()
+{
+	// Load the language file, if defined.
+	if ( this.AvailableLangs.length > 0 )
+	{
+		var sLang ;
+
+		// Check if the plugin has the language file for the active language.
+		if ( this.AvailableLangs.IndexOf( FCKLanguageManager.ActiveLanguage.Code ) >= 0 )
+			sLang = FCKLanguageManager.ActiveLanguage.Code ;
+		else
+			// Load the default language file (first one) if the current one is not available.
+			sLang = this.AvailableLangs[0] ;
+
+		// Add the main plugin script.
+		LoadScript( this.Path + 'lang/' + sLang + '.js' ) ;
+	}
+
+	// Add the main plugin script.
+	LoadScript( this.Path + 'fckplugin.js' ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenublockpanel.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenublockpanel.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenublockpanel.js	(revision 795)
@@ -0,0 +1,54 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This class is a menu block that behaves like a panel. It's a mix of the
+ * FCKMenuBlock and FCKPanel classes.
+ */
+
+var FCKMenuBlockPanel = function()
+{
+	// Call the "base" constructor.
+	FCKMenuBlock.call( this ) ;
+}
+
+FCKMenuBlockPanel.prototype = new FCKMenuBlock() ;
+
+
+// Override the create method.
+FCKMenuBlockPanel.prototype.Create = function()
+{
+	var oPanel = this.Panel = ( this.Parent && this.Parent.Panel ? this.Parent.Panel.CreateChildPanel() : new FCKPanel() ) ;
+	oPanel.AppendStyleSheet( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+	// Call the "base" implementation.
+	FCKMenuBlock.prototype.Create.call( this, oPanel.MainNode ) ;
+}
+
+FCKMenuBlockPanel.prototype.Show = function( x, y, relElement )
+{
+	if ( !this.Panel.CheckIsOpened() )
+		this.Panel.Show( x, y, relElement ) ;
+}
+
+FCKMenuBlockPanel.prototype.Hide = function()
+{
+	if ( this.Panel.CheckIsOpened() )
+		this.Panel.Hide() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarstylecombo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarstylecombo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarstylecombo.js	(revision 795)
@@ -0,0 +1,111 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarPanelButton Class: Handles the Fonts combo selector.
+ */
+
+var FCKToolbarStyleCombo = function( tooltip, style )
+{
+	this.CommandName = 'Style' ;
+	this.Label		= this.GetLabel() ;
+	this.Tooltip	= tooltip ? tooltip : this.Label ;
+	this.Style		= style ? style : FCK_TOOLBARITEM_ICONTEXT ;
+}
+
+// Inherit from FCKToolbarSpecialCombo.
+FCKToolbarStyleCombo.prototype = new FCKToolbarSpecialCombo ;
+
+
+FCKToolbarStyleCombo.prototype.GetLabel = function()
+{
+	return FCKLang.Style ;
+}
+
+FCKToolbarStyleCombo.prototype.CreateItems = function( targetSpecialCombo )
+{
+	var oTargetDoc = targetSpecialCombo._Panel.Document ;
+
+	// Add the Editor Area CSS to the panel so the style classes are previewed correctly.
+	FCKTools.AppendStyleSheet( oTargetDoc, FCKConfig.ToolbarComboPreviewCSS ) ;
+	oTargetDoc.body.className += ' ForceBaseFont' ;
+
+	// Add ID and Class to the body
+	if ( FCKConfig.BodyId && FCKConfig.BodyId.length > 0 )
+		oTargetDoc.body.id = FCKConfig.BodyId ;
+	if ( FCKConfig.BodyClass && FCKConfig.BodyClass.length > 0 )
+		oTargetDoc.body.className += ' ' + FCKConfig.BodyClass ;
+
+
+	// For some reason Gecko is blocking inside the "RefreshVisibleItems" function.
+	// The problem is present only in old versions
+	if ( !( FCKBrowserInfo.IsGecko && FCKBrowserInfo.IsGecko10 ) )
+		targetSpecialCombo.OnBeforeClick = this.RefreshVisibleItems ;
+
+	// Add the styles to the special combo.
+	var aCommandStyles = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).Styles ;
+	for ( var s in aCommandStyles )
+	{
+		var oStyle = aCommandStyles[s] ;
+		var oItem ;
+
+		if ( oStyle.IsObjectElement )
+			oItem = targetSpecialCombo.AddItem( s, s ) ;
+		else
+			oItem = targetSpecialCombo.AddItem( s, oStyle.GetOpenerTag() + s + oStyle.GetCloserTag() ) ;
+
+		oItem.Style = oStyle ;
+	}
+}
+
+FCKToolbarStyleCombo.prototype.RefreshActiveItems = function( targetSpecialCombo )
+{
+	// Clear the actual selection.
+	targetSpecialCombo.DeselectAll() ;
+
+	// Get the active styles.
+	var aStyles = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).GetActiveStyles() ;
+
+	if ( aStyles.length > 0 )
+	{
+		// Select the active styles in the combo.
+		for ( var i = 0 ; i < aStyles.length ; i++ )
+			targetSpecialCombo.SelectItem( aStyles[i].Name ) ;
+
+		// Set the combo label to the first style in the collection.
+		targetSpecialCombo.SetLabelById( aStyles[0].Name ) ;
+	}
+	else
+		targetSpecialCombo.SetLabel('') ;
+}
+
+FCKToolbarStyleCombo.prototype.RefreshVisibleItems = function( targetSpecialCombo )
+{
+	if ( FCKSelection.GetType() == 'Control' )
+		var sTagName = FCKSelection.GetSelectedElement().tagName ;
+
+	for ( var i in targetSpecialCombo.Items )
+	{
+		var oItem = targetSpecialCombo.Items[i] ;
+		if ( ( sTagName && oItem.Style.Element == sTagName ) || ( ! sTagName && ! oItem.Style.IsObjectElement ) )
+			oItem.style.display = '' ;
+		else
+			oItem.style.display = 'none' ;	// For some reason Gecko is blocking here.
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontsizecombo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontsizecombo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontsizecombo.js	(revision 795)
@@ -0,0 +1,52 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarPanelButton Class: Handles the Fonts combo selector.
+ */
+
+var FCKToolbarFontSizeCombo = function( tooltip, style )
+{
+	this.CommandName	= 'FontSize' ;
+	this.Label		= this.GetLabel() ;
+	this.Tooltip	= tooltip ? tooltip : this.Label ;
+	this.Style		= style ? style : FCK_TOOLBARITEM_ICONTEXT ;
+}
+
+// Inherit from FCKToolbarSpecialCombo.
+FCKToolbarFontSizeCombo.prototype = new FCKToolbarSpecialCombo ;
+
+
+FCKToolbarFontSizeCombo.prototype.GetLabel = function()
+{
+	return FCKLang.FontSize ;
+}
+
+FCKToolbarFontSizeCombo.prototype.CreateItems = function( targetSpecialCombo )
+{
+	targetSpecialCombo.FieldWidth = 70 ;
+
+	var aSizes = FCKConfig.FontSizes.split(';') ;
+
+	for ( var i = 0 ; i < aSizes.length ; i++ )
+	{
+		var aSizeParts = aSizes[i].split('/') ;
+		this._Combo.AddItem( aSizeParts[0], '<font size="' + aSizeParts[0] + '">' + aSizeParts[1] + '</font>', aSizeParts[1] ) ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckevents.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckevents.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckevents.js	(revision 795)
@@ -0,0 +1,53 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKEvents Class: used to handle events is a advanced way.
+ */
+
+var FCKEvents = function( eventsOwner )
+{
+	this.Owner = eventsOwner ;
+	this._RegisteredEvents = new Object() ;
+}
+
+FCKEvents.prototype.AttachEvent = function( eventName, functionPointer )
+{
+	var aTargets ;
+
+	if ( !( aTargets = this._RegisteredEvents[ eventName ] ) )
+		this._RegisteredEvents[ eventName ] = [ functionPointer ] ;
+	else
+		aTargets.push( functionPointer ) ;
+}
+
+FCKEvents.prototype.FireEvent = function( eventName, params )
+{
+	var bReturnValue = true ;
+
+	var oCalls = this._RegisteredEvents[ eventName ] ;
+
+	if ( oCalls )
+	{
+		for ( var i = 0 ; i < oCalls.length ; i++ )
+			bReturnValue = ( oCalls[ i ]( this.Owner, params ) && bReturnValue ) ;
+	}
+
+	return bReturnValue ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckcontextmenu.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckcontextmenu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckcontextmenu.js	(revision 795)
@@ -0,0 +1,134 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKContextMenu Class: renders an control a context menu.
+ */
+
+var FCKContextMenu = function( parentWindow, langDir )
+{
+	var oPanel = this._Panel = new FCKPanel( parentWindow, true ) ;
+	oPanel.AppendStyleSheet( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+	oPanel.IsContextMenu = true ;
+
+	// The FCKTools.DisableSelection doesn't seems to work to avoid dragging of the icons in Mozilla
+	// so we stop the start of the dragging
+	if ( FCKBrowserInfo.IsGecko )
+		oPanel.Document.addEventListener( 'draggesture', function(e) {e.preventDefault(); return false;}, true ) ;
+
+	var oMenuBlock = this._MenuBlock = new FCKMenuBlock() ;
+	oMenuBlock.Panel = oPanel ;
+	oMenuBlock.OnClick = FCKTools.CreateEventListener( FCKContextMenu_MenuBlock_OnClick, this ) ;
+
+	this._Redraw = true ;
+}
+
+
+FCKContextMenu.prototype.SetMouseClickWindow = function( mouseClickWindow )
+{
+	if ( !FCKBrowserInfo.IsIE )
+	{
+		this._Document = mouseClickWindow.document ;
+		this._Document.addEventListener( 'contextmenu', FCKContextMenu_Document_OnContextMenu, false ) ;
+	}
+}
+
+FCKContextMenu.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled )
+{
+	var oItem = this._MenuBlock.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled) ;
+	this._Redraw = true ;
+	return oItem ;
+}
+
+FCKContextMenu.prototype.AddSeparator = function()
+{
+	this._MenuBlock.AddSeparator() ;
+	this._Redraw = true ;
+}
+
+FCKContextMenu.prototype.RemoveAllItems = function()
+{
+	this._MenuBlock.RemoveAllItems() ;
+	this._Redraw = true ;
+}
+
+FCKContextMenu.prototype.AttachToElement = function( element )
+{
+	if ( FCKBrowserInfo.IsIE )
+		FCKTools.AddEventListenerEx( element, 'contextmenu', FCKContextMenu_AttachedElement_OnContextMenu, this ) ;
+	else
+		element._FCKContextMenu = this ;
+
+//	element.onmouseup		= FCKContextMenu_AttachedElement_OnMouseUp ;
+}
+
+function FCKContextMenu_Document_OnContextMenu( e )
+{
+	var el = e.target ;
+
+	while ( el )
+	{
+		if ( el._FCKContextMenu )
+		{
+			FCKTools.CancelEvent( e ) ;
+			FCKContextMenu_AttachedElement_OnContextMenu( e, el._FCKContextMenu, el ) ;
+		}
+		el = el.parentNode ;
+	}
+}
+
+function FCKContextMenu_AttachedElement_OnContextMenu( ev, fckContextMenu, el )
+{
+//	var iButton = e ? e.which - 1 : event.button ;
+
+//	if ( iButton != 2 )
+//		return ;
+
+	var eTarget = el || this ;
+
+	if ( fckContextMenu.OnBeforeOpen )
+		fckContextMenu.OnBeforeOpen.call( fckContextMenu, eTarget ) ;
+
+	if ( fckContextMenu._MenuBlock.Count() == 0 )
+		return false ;
+
+	if ( fckContextMenu._Redraw )
+	{
+		fckContextMenu._MenuBlock.Create( fckContextMenu._Panel.MainNode ) ;
+		fckContextMenu._Redraw = false ;
+	}
+	
+	// This will avoid that the content of the context menu can be dragged in IE
+	// as the content of the panel is recreated we need to do it every time
+	FCKTools.DisableSelection( fckContextMenu._Panel.Document.body ) ;
+
+	fckContextMenu._Panel.Show(
+		ev.pageX || ev.screenX,
+		ev.pageY || ev.screenY,
+		ev.currentTarget || null
+	) ;
+
+	return false ;
+}
+
+function FCKContextMenu_MenuBlock_OnClick( menuItem, contextMenu )
+{
+	contextMenu._Panel.Hide() ;
+	FCKTools.RunFunction( contextMenu.OnItemClick, contextMenu, menuItem ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarpanelbutton.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarpanelbutton.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarpanelbutton.js	(revision 795)
@@ -0,0 +1,91 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarPanelButton Class: represents a special button in the toolbar
+ * that shows a panel when pressed.
+ */
+
+var FCKToolbarPanelButton = function( commandName, label, tooltip, style, icon )
+{
+	this.CommandName = commandName ;
+
+	var oIcon ;
+
+	if ( icon == null )
+		oIcon = FCKConfig.SkinPath + 'toolbar/' + commandName.toLowerCase() + '.gif' ;
+	else if ( typeof( icon ) == 'number' )
+		oIcon = [ FCKConfig.SkinPath + 'fck_strip.gif', 16, icon ] ;
+
+	var oUIButton = this._UIButton = new FCKToolbarButtonUI( commandName, label, tooltip, oIcon, style ) ;
+	oUIButton._FCKToolbarPanelButton = this ;
+	oUIButton.ShowArrow = true ;
+	oUIButton.OnClick = FCKToolbarPanelButton_OnButtonClick ;
+}
+
+FCKToolbarPanelButton.prototype.TypeName = 'FCKToolbarPanelButton' ;
+
+FCKToolbarPanelButton.prototype.Create = function( parentElement )
+{
+	parentElement.className += 'Menu' ;
+
+	this._UIButton.Create( parentElement ) ;
+
+	var oPanel = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName )._Panel ;
+	oPanel._FCKToolbarPanelButton = this ;
+
+	var eLineDiv = oPanel.Document.body.appendChild( oPanel.Document.createElement( 'div' ) ) ;
+	eLineDiv.style.position = 'absolute' ;
+	eLineDiv.style.top = '0px' ;
+
+	var eLine = this.LineImg = eLineDiv.appendChild( oPanel.Document.createElement( 'IMG' ) ) ;
+	eLine.className = 'TB_ConnectionLine' ;
+//	eLine.style.backgroundColor = 'Red' ;
+	eLine.src = FCK_SPACER_PATH ;
+
+	oPanel.OnHide = FCKToolbarPanelButton_OnPanelHide ;
+}
+
+/*
+	Events
+*/
+
+function FCKToolbarPanelButton_OnButtonClick( toolbarButton )
+{
+	var oButton = this._FCKToolbarPanelButton ;
+	var e = oButton._UIButton.MainElement ;
+
+	oButton._UIButton.ChangeState( FCK_TRISTATE_ON ) ;
+
+	oButton.LineImg.style.width = ( e.offsetWidth - 2 ) + 'px' ;
+
+	FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( oButton.CommandName ).Execute( 0, e.offsetHeight - 1, e ) ; // -1 to be over the border
+}
+
+function FCKToolbarPanelButton_OnPanelHide()
+{
+	var oMenuButton = this._FCKToolbarPanelButton ;
+	oMenuButton._UIButton.ChangeState( FCK_TRISTATE_OFF ) ;
+}
+
+// The Panel Button works like a normal button so the refresh state functions
+// defined for the normal button can be reused here.
+FCKToolbarPanelButton.prototype.RefreshState	= FCKToolbarButton.prototype.RefreshState ;
+FCKToolbarPanelButton.prototype.Enable			= FCKToolbarButton.prototype.Enable ;
+FCKToolbarPanelButton.prototype.Disable			= FCKToolbarButton.prototype.Disable ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbreak_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbreak_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbreak_gecko.js	(revision 795)
@@ -0,0 +1,36 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarBreak Class: breaks the toolbars.
+ * It makes it possible to force the toolbar to break to a new line.
+ * This is the Gecko specific implementation.
+ */
+
+var FCKToolbarBreak = function()
+{}
+
+FCKToolbarBreak.prototype.Create = function( targetElement )
+{
+	var oBreakDiv = targetElement.ownerDocument.createElement( 'div' ) ;
+
+	oBreakDiv.style.clear = oBreakDiv.style.cssFloat = FCKLang.Dir == 'rtl' ? 'right' : 'left' ;
+
+	targetElement.appendChild( oBreakDiv ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckimagepreloader.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckimagepreloader.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckimagepreloader.js	(revision 795)
@@ -0,0 +1,68 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Preload a list of images, firing an event when complete.
+ */
+
+var FCKImagePreloader = function()
+{
+	this._Images = new Array() ;
+}
+
+FCKImagePreloader.prototype =
+{
+	AddImages : function( images )
+	{
+		if ( typeof( images ) == 'string' )
+			images = images.split( ';' ) ;
+
+		this._Images = this._Images.concat( images ) ;
+	},
+
+	Start : function()
+	{
+		var aImages = this._Images ;
+		this._PreloadCount = aImages.length ;
+
+		for ( var i = 0 ; i < aImages.length ; i++ )
+		{
+			var eImg = document.createElement( 'img' ) ;
+			eImg.onload = eImg.onerror = _FCKImagePreloader_OnImage ;
+			eImg._FCKImagePreloader = this ;
+			eImg.src = aImages[i] ;
+
+			_FCKImagePreloader_ImageCache.push( eImg ) ;
+		}
+	}
+};
+
+// All preloaded images must be placed in a global array, otherwise the preload
+// magic will not happen.
+var _FCKImagePreloader_ImageCache = new Array() ;
+
+function _FCKImagePreloader_OnImage()
+{
+	var oImagePreloader = this._FCKImagePreloader ;
+
+	if ( (--oImagePreloader._PreloadCount) == 0 && oImagePreloader.OnComplete )
+		oImagePreloader.OnComplete() ;
+
+	this._FCKImagePreloader = null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontformatcombo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontformatcombo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontformatcombo.js	(revision 795)
@@ -0,0 +1,114 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarPanelButton Class: Handles the Fonts combo selector.
+ */
+
+var FCKToolbarFontFormatCombo = function( tooltip, style )
+{
+	this.CommandName = 'FontFormat' ;
+	this.Label		= this.GetLabel() ;
+	this.Tooltip	= tooltip ? tooltip : this.Label ;
+	this.Style		= style ? style : FCK_TOOLBARITEM_ICONTEXT ;
+
+	this.NormalLabel = 'Normal' ;
+
+	this.PanelWidth = 190 ;
+}
+
+// Inherit from FCKToolbarSpecialCombo.
+FCKToolbarFontFormatCombo.prototype = new FCKToolbarSpecialCombo ;
+
+
+FCKToolbarFontFormatCombo.prototype.GetLabel = function()
+{
+	return FCKLang.FontFormat ;
+}
+
+FCKToolbarFontFormatCombo.prototype.CreateItems = function( targetSpecialCombo )
+{
+	var oTargetDoc = targetSpecialCombo._Panel.Document ;
+
+	// Add the Editor Area CSS to the panel to create a realistic preview.
+	FCKTools.AppendStyleSheet( oTargetDoc, FCKConfig.ToolbarComboPreviewCSS ) ;
+
+	// Add ID and Class to the body
+	if ( FCKConfig.BodyId && FCKConfig.BodyId.length > 0 )
+		oTargetDoc.body.id = FCKConfig.BodyId ;
+	if ( FCKConfig.BodyClass && FCKConfig.BodyClass.length > 0 )
+		oTargetDoc.body.className += ' ' + FCKConfig.BodyClass ;
+
+	// Get the format names from the language file.
+	var aNames = FCKLang['FontFormats'].split(';') ;
+	var oNames = {
+		p		: aNames[0],
+		pre		: aNames[1],
+		address	: aNames[2],
+		h1		: aNames[3],
+		h2		: aNames[4],
+		h3		: aNames[5],
+		h4		: aNames[6],
+		h5		: aNames[7],
+		h6		: aNames[8],
+		div		: aNames[9]
+	} ;
+
+	// Get the available formats from the configuration file.
+	var aTags = FCKConfig.FontFormats.split(';') ;
+
+	for ( var i = 0 ; i < aTags.length ; i++ )
+	{
+		// Support for DIV in Firefox has been reintroduced on version 2.2.
+//		if ( aTags[i] == 'div' && FCKBrowserInfo.IsGecko )
+//			continue ;
+
+		var sTag	= aTags[i] ;
+		var sLabel	= oNames[sTag] ;
+
+		if ( sTag == 'p' )
+			this.NormalLabel = sLabel ;
+
+		this._Combo.AddItem( sTag, '<div class="BaseFont"><' + sTag + '>' + sLabel + '</' + sTag + '></div>', sLabel ) ;
+	}
+}
+
+if ( FCKBrowserInfo.IsIE )
+{
+	FCKToolbarFontFormatCombo.prototype.RefreshActiveItems = function( combo, value )
+	{
+//		FCKDebug.Output( 'FCKToolbarFontFormatCombo Value: ' + value ) ;
+
+		// IE returns normal for DIV and P, so to avoid confusion, we will not show it if normal.
+		if ( value == this.NormalLabel )
+		{
+			if ( combo.Label != '&nbsp;' )
+				combo.DeselectAll(true) ;
+		}
+		else
+		{
+			if ( this._LastValue == value )
+				return ;
+
+			combo.SelectItemByLabel( value, true ) ;
+		}
+
+		this._LastValue = value ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenuitem.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenuitem.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenuitem.js	(revision 795)
@@ -0,0 +1,160 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines and renders a menu items in a menu block.
+ */
+
+var FCKMenuItem = function( parentMenuBlock, name, label, iconPathOrStripInfoArray, isDisabled )
+{
+	this.Name		= name ;
+	this.Label		= label || name ;
+	this.IsDisabled	= isDisabled ;
+
+	this.Icon = new FCKIcon( iconPathOrStripInfoArray ) ;
+
+	this.SubMenu			= new FCKMenuBlockPanel() ;
+	this.SubMenu.Parent		= parentMenuBlock ;
+	this.SubMenu.OnClick	= FCKTools.CreateEventListener( FCKMenuItem_SubMenu_OnClick, this ) ;
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( this, FCKMenuItem_Cleanup ) ;
+}
+
+
+FCKMenuItem.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled )
+{
+	this.HasSubMenu = true ;
+	return this.SubMenu.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled ) ;
+}
+
+FCKMenuItem.prototype.AddSeparator = function()
+{
+	this.SubMenu.AddSeparator() ;
+}
+
+FCKMenuItem.prototype.Create = function( parentTable )
+{
+	var bHasSubMenu = this.HasSubMenu ;
+
+	var oDoc = FCKTools.GetElementDocument( parentTable ) ;
+
+	// Add a row in the table to hold the menu item.
+	var r = this.MainElement = parentTable.insertRow(-1) ;
+	r.className = this.IsDisabled ? 'MN_Item_Disabled' : 'MN_Item' ;
+
+	// Set the row behavior.
+	if ( !this.IsDisabled )
+	{
+		FCKTools.AddEventListenerEx( r, 'mouseover', FCKMenuItem_OnMouseOver, [ this ] ) ;
+		FCKTools.AddEventListenerEx( r, 'click', FCKMenuItem_OnClick, [ this ] ) ;
+
+		if ( !bHasSubMenu )
+			FCKTools.AddEventListenerEx( r, 'mouseout', FCKMenuItem_OnMouseOut, [ this ] ) ;
+	}
+
+	// Create the icon cell.
+	var eCell = r.insertCell(-1) ;
+	eCell.className = 'MN_Icon' ;
+	eCell.appendChild( this.Icon.CreateIconElement( oDoc ) ) ;
+
+	// Create the label cell.
+	eCell = r.insertCell(-1) ;
+	eCell.className = 'MN_Label' ;
+	eCell.noWrap = true ;
+	eCell.appendChild( oDoc.createTextNode( this.Label ) ) ;
+
+	// Create the arrow cell and setup the sub menu panel (if needed).
+	eCell = r.insertCell(-1) ;
+	if ( bHasSubMenu )
+	{
+		eCell.className = 'MN_Arrow' ;
+
+		// The arrow is a fixed size image.
+		var eArrowImg = eCell.appendChild( oDoc.createElement( 'IMG' ) ) ;
+		eArrowImg.src = FCK_IMAGES_PATH + 'arrow_' + FCKLang.Dir + '.gif' ;
+		eArrowImg.width	 = 4 ;
+		eArrowImg.height = 7 ;
+
+		this.SubMenu.Create() ;
+		this.SubMenu.Panel.OnHide = FCKTools.CreateEventListener( FCKMenuItem_SubMenu_OnHide, this ) ;
+	}
+}
+
+FCKMenuItem.prototype.Activate = function()
+{
+	this.MainElement.className = 'MN_Item_Over' ;
+
+	if ( this.HasSubMenu )
+	{
+		// Show the child menu block. The ( +2, -2 ) correction is done because
+		// of the padding in the skin. It is not a good solution because one
+		// could change the skin and so the final result would not be accurate.
+		// For now it is ok because we are controlling the skin.
+		this.SubMenu.Show( this.MainElement.offsetWidth + 2, -2, this.MainElement ) ;
+	}
+
+	FCKTools.RunFunction( this.OnActivate, this ) ;
+}
+
+FCKMenuItem.prototype.Deactivate = function()
+{
+	this.MainElement.className = 'MN_Item' ;
+
+	if ( this.HasSubMenu )
+		this.SubMenu.Hide() ;
+}
+
+/* Events */
+
+function FCKMenuItem_SubMenu_OnClick( clickedItem, listeningItem )
+{
+	FCKTools.RunFunction( listeningItem.OnClick, listeningItem, [ clickedItem ] ) ;
+}
+
+function FCKMenuItem_SubMenu_OnHide( menuItem )
+{
+	menuItem.Deactivate() ;
+}
+
+function FCKMenuItem_OnClick( ev, menuItem )
+{
+	if ( menuItem.HasSubMenu )
+		menuItem.Activate() ;
+	else
+	{
+		menuItem.Deactivate() ;
+		FCKTools.RunFunction( menuItem.OnClick, menuItem, [ menuItem ] ) ;
+	}
+}
+
+function FCKMenuItem_OnMouseOver( ev, menuItem )
+{
+	menuItem.Activate() ;
+}
+
+function FCKMenuItem_OnMouseOut( ev, menuItem )
+{
+	menuItem.Deactivate() ;
+}
+
+function FCKMenuItem_Cleanup()
+{
+	this.MainElement = null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckenterkey.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckenterkey.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckenterkey.js	(revision 795)
@@ -0,0 +1,556 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Controls the [Enter] keystroke behavior in a document.
+ */
+
+/*
+ *	Constructor.
+ *		@targetDocument : the target document.
+ *		@enterMode : the behavior for the <Enter> keystroke.
+ *			May be "p", "div", "br". Default is "p".
+ *		@shiftEnterMode : the behavior for the <Shift>+<Enter> keystroke.
+ *			May be "p", "div", "br". Defaults to "br".
+ */
+var FCKEnterKey = function( targetWindow, enterMode, shiftEnterMode )
+{
+	this.Window			= targetWindow ;
+	this.EnterMode		= enterMode || 'p' ;
+	this.ShiftEnterMode	= shiftEnterMode || 'br' ;
+
+	// Setup the Keystroke Handler.
+	var oKeystrokeHandler = new FCKKeystrokeHandler( false ) ;
+	oKeystrokeHandler._EnterKey = this ;
+	oKeystrokeHandler.OnKeystroke = FCKEnterKey_OnKeystroke ;
+
+	oKeystrokeHandler.SetKeystrokes( [
+		[ 13		, 'Enter' ],
+		[ SHIFT + 13, 'ShiftEnter' ],
+		[ 8			, 'Backspace' ],
+		[ 46		, 'Delete' ]
+	] ) ;
+
+	oKeystrokeHandler.AttachToElement( targetWindow.document ) ;
+}
+
+
+function FCKEnterKey_OnKeystroke(  keyCombination, keystrokeValue )
+{
+	var oEnterKey = this._EnterKey ;
+
+	try
+	{
+		switch ( keystrokeValue )
+		{
+			case 'Enter' :
+				return oEnterKey.DoEnter() ;
+				break ;
+
+			case 'ShiftEnter' :
+				return oEnterKey.DoShiftEnter() ;
+				break ;
+
+			case 'Backspace' :
+				return oEnterKey.DoBackspace() ;
+				break ;
+
+			case 'Delete' :
+				return oEnterKey.DoDelete() ;
+		}
+	}
+	catch (e)
+	{
+		// If for any reason we are not able to handle it, go
+		// ahead with the browser default behavior.
+	}
+
+	return false ;
+}
+
+/*
+ * Executes the <Enter> key behavior.
+ */
+FCKEnterKey.prototype.DoEnter = function( mode, hasShift )
+{
+	this._HasShift = ( hasShift === true ) ;
+
+	var sMode = mode || this.EnterMode ;
+
+	if ( sMode == 'br' )
+		return this._ExecuteEnterBr() ;
+	else
+		return this._ExecuteEnterBlock( sMode ) ;
+}
+
+/*
+ * Executes the <Shift>+<Enter> key behavior.
+ */
+FCKEnterKey.prototype.DoShiftEnter = function()
+{
+	return this.DoEnter( this.ShiftEnterMode, true ) ;
+}
+
+/*
+ * Executes the <Backspace> key behavior.
+ */
+FCKEnterKey.prototype.DoBackspace = function()
+{
+	var bCustom = false ;
+
+	// Get the current selection.
+	var oRange = new FCKDomRange( this.Window ) ;
+	oRange.MoveToSelection() ;
+
+	if ( !oRange.CheckIsCollapsed() )
+		return false ;
+
+	var oStartBlock = oRange.StartBlock ;
+	var oEndBlock = oRange.EndBlock ;
+
+	// The selection boundaries must be in the same "block limit" element
+	if ( oRange.StartBlockLimit == oRange.EndBlockLimit && oStartBlock && oEndBlock )
+	{
+		if ( !oRange.CheckIsCollapsed() )
+		{
+			var bEndOfBlock = oRange.CheckEndOfBlock() ;
+
+			oRange.DeleteContents() ;
+
+			if ( oStartBlock != oEndBlock )
+			{
+				oRange.SetStart(oEndBlock,1) ;
+				oRange.SetEnd(oEndBlock,1) ;
+
+//				if ( bEndOfBlock )
+//					oEndBlock.parentNode.removeChild( oEndBlock ) ;
+			}
+
+			oRange.Select() ;
+
+			bCustom = ( oStartBlock == oEndBlock ) ;
+		}
+
+		if ( oRange.CheckStartOfBlock() )
+		{
+			var oCurrentBlock = oRange.StartBlock ;
+
+			var ePrevious = FCKDomTools.GetPreviousSourceElement( oCurrentBlock, true, [ 'BODY', oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ;
+
+			bCustom = this._ExecuteBackspace( oRange, ePrevious, oCurrentBlock ) ;
+		}
+		else if ( FCKBrowserInfo.IsGecko )
+		{
+			// Firefox looses the selection when executing CheckStartOfBlock, so we must reselect.
+			oRange.Select() ;
+		}
+	}
+
+	oRange.Release() ;
+	return bCustom ;
+}
+
+FCKEnterKey.prototype._ExecuteBackspace = function( range, previous, currentBlock )
+{
+	var bCustom = false ;
+
+	// We could be in a nested LI.
+	if ( !previous && currentBlock.nodeName.IEquals( 'LI' ) && currentBlock.parentNode.parentNode.nodeName.IEquals( 'LI' ) )
+	{
+		this._OutdentWithSelection( currentBlock, range ) ;
+		return true ;
+	}
+
+	if ( previous && previous.nodeName.IEquals( 'LI' ) )
+	{
+		var oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
+
+		while ( oNestedList )
+		{
+			previous = FCKDomTools.GetLastChild( oNestedList, 'LI' ) ;
+			oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
+		}
+	}
+
+	if ( previous && currentBlock )
+	{
+		// If we are in a LI, and the previous block is not an LI, we must outdent it.
+		if ( currentBlock.nodeName.IEquals( 'LI' ) && !previous.nodeName.IEquals( 'LI' ) )
+		{
+			this._OutdentWithSelection( currentBlock, range ) ;
+			return true ;
+		}
+
+		// Take a reference to the parent for post processing cleanup.
+		var oCurrentParent = currentBlock.parentNode ;
+
+		var sPreviousName = previous.nodeName.toLowerCase() ;
+		if ( FCKListsLib.EmptyElements[ sPreviousName ] != null || sPreviousName == 'table' )
+		{
+			FCKDomTools.RemoveNode( previous ) ;
+			bCustom = true ;
+		}
+		else
+		{
+			// Remove the current block.
+			FCKDomTools.RemoveNode( currentBlock ) ;
+
+			// Remove any empty tag left by the block removal.
+			while ( oCurrentParent.innerHTML.Trim().length == 0 )
+			{
+				var oParent = oCurrentParent.parentNode ;
+				oParent.removeChild( oCurrentParent ) ;
+				oCurrentParent = oParent ;
+			}
+
+			// Cleanup the previous and the current elements.
+			FCKDomTools.TrimNode( currentBlock ) ;
+			FCKDomTools.TrimNode( previous ) ;
+
+			// Append a space to the previous.
+			// Maybe it is not always desirable...
+			// previous.appendChild( this.Window.document.createTextNode( ' ' ) ) ;
+
+			// Set the range to the end of the previous element and bookmark it.
+			range.SetStart( previous, 2 ) ;
+			range.Collapse( true ) ;
+			var oBookmark = range.CreateBookmark() ;
+
+			// Move the contents of the block to the previous element and delete it.
+			FCKDomTools.MoveChildren( currentBlock, previous ) ;
+
+			// Place the selection at the bookmark.
+			range.MoveToBookmark( oBookmark ) ;
+			range.Select() ;
+
+			bCustom = true ;
+		}
+	}
+
+	return bCustom ;
+}
+
+/*
+ * Executes the <Delete> key behavior.
+ */
+FCKEnterKey.prototype.DoDelete = function()
+{
+	// The <Delete> has the same effect as the <Backspace>, so we have the same
+	// results if we just move to the next block and apply the same <Backspace> logic.
+
+	var bCustom = false ;
+
+	// Get the current selection.
+	var oRange = new FCKDomRange( this.Window ) ;
+	oRange.MoveToSelection() ;
+
+	// There is just one special case for collapsed selections at the end of a block.
+	if ( oRange.CheckIsCollapsed() && oRange.CheckEndOfBlock( FCKBrowserInfo.IsGecko ) )
+	{
+		var oCurrentBlock = oRange.StartBlock ;
+
+		var eNext = FCKDomTools.GetNextSourceElement( oCurrentBlock, true, [ oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ;
+
+		bCustom = this._ExecuteBackspace( oRange, oCurrentBlock, eNext ) ;
+	}
+
+	oRange.Release() ;
+	return bCustom ;
+}
+
+FCKEnterKey.prototype._ExecuteEnterBlock = function( blockTag, range )
+{
+	// Get the current selection.
+	var oRange = range || new FCKDomRange( this.Window ) ;
+
+	// If we don't have a range, move it to the selection.
+	if ( !range )
+		oRange.MoveToSelection() ;
+
+	// The selection boundaries must be in the same "block limit" element.
+	if ( oRange.StartBlockLimit == oRange.EndBlockLimit )
+	{
+		// If the StartBlock or EndBlock are not available (for text without a
+		// block tag), we must fix them, by moving the text to a block.
+		if ( !oRange.StartBlock )
+			this._FixBlock( oRange, true, blockTag ) ;
+
+		if ( !oRange.EndBlock )
+			this._FixBlock( oRange, false, blockTag ) ;
+
+		// Get the current blocks.
+		var eStartBlock	= oRange.StartBlock ;
+		var eEndBlock	= oRange.EndBlock ;
+
+		// Delete the current selection.
+		if ( !oRange.CheckIsEmpty() )
+			oRange.DeleteContents() ;
+
+		// If the selection boundaries are in the same block element
+		if ( eStartBlock == eEndBlock )
+		{
+			var eNewBlock ;
+
+			var bIsStartOfBlock	= oRange.CheckStartOfBlock() ;
+			var bIsEndOfBlock	= oRange.CheckEndOfBlock() ;
+
+			if ( bIsStartOfBlock && !bIsEndOfBlock )
+			{
+				eNewBlock = eStartBlock.cloneNode(false) ;
+
+				if ( FCKBrowserInfo.IsGeckoLike )
+					eNewBlock.innerHTML = GECKO_BOGUS ;
+
+				// Place the new block before the current block element.
+				eStartBlock.parentNode.insertBefore( eNewBlock, eStartBlock ) ;
+
+				// This is tricky, but to make the new block visible correctly
+				// we must select it.
+				if ( FCKBrowserInfo.IsIE )
+				{
+					// Move the selection to the new block.
+					oRange.MoveToNodeContents( eNewBlock ) ;
+
+					oRange.Select() ;
+				}
+
+				// Move the selection to the new block.
+				oRange.MoveToElementEditStart( eStartBlock ) ;
+			}
+			else
+			{
+				// Check if the selection is at the end of the block.
+				if ( bIsEndOfBlock )
+				{
+					var sStartBlockTag = eStartBlock.tagName.toUpperCase() ;
+
+					// If the entire block is selected, and we are in a LI, let's decrease its indentation.
+					if ( bIsStartOfBlock && sStartBlockTag == 'LI' )
+					{
+						this._OutdentWithSelection( eStartBlock, oRange ) ;
+						oRange.Release() ;
+						return true ;
+					}
+					else
+					{
+						// If is a header tag, or we are in a Shift+Enter (#77),
+						// create a new block element.
+						if ( (/^H[1-6]$/).test( sStartBlockTag ) || this._HasShift )
+							eNewBlock = this.Window.document.createElement( blockTag ) ;
+						// Otherwise, duplicate the current block.
+						else
+						{
+							eNewBlock = eStartBlock.cloneNode(false) ;
+							this._RecreateEndingTree( eStartBlock, eNewBlock ) ;
+						}
+
+						if ( FCKBrowserInfo.IsGeckoLike )
+						{
+							eNewBlock.innerHTML = GECKO_BOGUS ;
+
+							// If the entire block is selected, let's add a bogus in the start block.
+							if ( bIsStartOfBlock )
+								eStartBlock.innerHTML = GECKO_BOGUS ;
+						}
+					}
+				}
+				else
+				{
+					// Extract the contents of the block from the selection point to the end of its contents.
+					oRange.SetEnd( eStartBlock, 2 ) ;
+					var eDocFrag = oRange.ExtractContents() ;
+
+					// Duplicate the block element after it.
+					eNewBlock = eStartBlock.cloneNode(false) ;
+
+					// It could be that we are in a LI with a child UL/OL. Insert a bogus to give us space to type.
+					FCKDomTools.TrimNode( eDocFrag.RootNode ) ;
+					if ( eDocFrag.RootNode.firstChild.nodeType == 1 && eDocFrag.RootNode.firstChild.tagName.toUpperCase().Equals( 'UL', 'OL' ) )
+						eNewBlock.innerHTML = GECKO_BOGUS ;
+
+					// Place the extracted contents in the duplicated block.
+					eDocFrag.AppendTo( eNewBlock ) ;
+
+					if ( FCKBrowserInfo.IsGecko )
+					{
+						// In Gecko, the last child node must be a bogus <br>.
+						this._AppendBogusBr( eStartBlock ) ;
+						this._AppendBogusBr( eNewBlock ) ;
+					}
+				}
+
+				if ( eNewBlock )
+				{
+					FCKDomTools.InsertAfterNode( eStartBlock, eNewBlock ) ;
+
+					// Move the selection to the new block.
+					oRange.MoveToElementEditStart( eNewBlock ) ;
+
+					if ( FCKBrowserInfo.IsGecko )
+						eNewBlock.scrollIntoView( false ) ;
+				}
+			}
+		}
+		else
+		{
+			// Move the selection to the end block.
+			oRange.MoveToElementEditStart( eEndBlock ) ;
+		}
+
+		oRange.Select() ;
+	}
+
+	// Release the resources used by the range.
+	oRange.Release() ;
+
+	return true ;
+}
+
+FCKEnterKey.prototype._ExecuteEnterBr = function( blockTag )
+{
+	// Get the current selection.
+	var oRange = new FCKDomRange( this.Window ) ;
+	oRange.MoveToSelection() ;
+
+	// The selection boundaries must be in the same "block limit" element.
+	if ( oRange.StartBlockLimit == oRange.EndBlockLimit )
+	{
+		oRange.DeleteContents() ;
+
+		// Get the new selection (it is collapsed at this point).
+		oRange.MoveToSelection() ;
+
+		var bIsStartOfBlock	= oRange.CheckStartOfBlock() ;
+		var bIsEndOfBlock	= oRange.CheckEndOfBlock() ;
+
+		var sStartBlockTag = oRange.StartBlock ? oRange.StartBlock.tagName.toUpperCase() : '' ;
+
+		var bHasShift = this._HasShift ;
+
+		if ( !bHasShift && sStartBlockTag == 'LI' )
+			return this._ExecuteEnterBlock( null, oRange ) ;
+
+		// If we are at the end of a header block.
+		if ( !bHasShift && bIsEndOfBlock && (/^H[1-6]$/).test( sStartBlockTag ) )
+		{
+			FCKDebug.Output( 'BR - Header' ) ;
+
+			// Insert a BR after the current paragraph.
+			FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createElement( 'br' ) ) ;
+
+			// The space is required by Gecko only to make the cursor blink.
+			if ( FCKBrowserInfo.IsGecko )
+				FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createTextNode( '' ) ) ;
+
+			// IE and Gecko have different behaviors regarding the position.
+			oRange.SetStart( oRange.StartBlock.nextSibling, FCKBrowserInfo.IsIE ? 3 : 1 ) ;
+		}
+		else
+		{
+			FCKDebug.Output( 'BR - No Header' ) ;
+
+			var eBr = this.Window.document.createElement( 'br' ) ;
+
+			oRange.InsertNode( eBr ) ;
+
+			// The space is required by Gecko only to make the cursor blink.
+			if ( FCKBrowserInfo.IsGecko )
+				FCKDomTools.InsertAfterNode( eBr, this.Window.document.createTextNode( '' ) ) ;
+
+			// If we are at the end of a block, we must be sure the bogus node is available in that block.
+			if ( bIsEndOfBlock && FCKBrowserInfo.IsGecko )
+				this._AppendBogusBr( eBr.parentNode ) ;
+
+			if ( FCKBrowserInfo.IsIE )
+				oRange.SetStart( eBr, 4 ) ;
+			else
+				oRange.SetStart( eBr.nextSibling, 1 ) ;
+
+		}
+
+		// This collapse guarantees the cursor will be blinking.
+		oRange.Collapse( true ) ;
+
+		oRange.Select() ;
+	}
+
+	// Release the resources used by the range.
+	oRange.Release() ;
+
+	return true ;
+}
+
+// Transform a block without a block tag in a valid block (orphan text in the body or td, usually).
+FCKEnterKey.prototype._FixBlock = function( range, isStart, blockTag )
+{
+	// Bookmark the range so we can restore it later.
+	var oBookmark = range.CreateBookmark() ;
+
+	// Collapse the range to the requested ending boundary.
+	range.Collapse( isStart ) ;
+
+	// Expands it to the block contents.
+	range.Expand( 'block_contents' ) ;
+
+	// Create the fixed block.
+	var oFixedBlock = this.Window.document.createElement( blockTag ) ;
+
+	// Move the contents of the temporary range to the fixed block.
+	range.ExtractContents().AppendTo( oFixedBlock ) ;
+	FCKDomTools.TrimNode( oFixedBlock ) ;
+
+	// Insert the fixed block into the DOM.
+	range.InsertNode( oFixedBlock ) ;
+
+	// Move the range back to the bookmarked place.
+	range.MoveToBookmark( oBookmark ) ;
+}
+
+// Appends a bogus <br> at the end of the element, if not yet available.
+FCKEnterKey.prototype._AppendBogusBr = function( element )
+{
+	var eLastChild = element.getElementsByTagName('br') ;
+
+	if ( eLastChild )
+		eLastChild = eLastChild[ eLastChild.legth - 1 ] ;
+
+	if ( !eLastChild || eLastChild.getAttribute( 'type', 2 ) != '_moz' )
+		element.appendChild( FCKTools.CreateBogusBR( this.Window.document ) ) ;
+}
+
+// Recreate the elements tree at the end of the source block, at the beginning
+// of the target block. Eg.:
+//	If source = <p><u>Some</u> sample <b><i>text</i></b></p> then target = <p><b><i></i></b></p>
+//	If source = <p><u>Some</u> sample text</p> then target = <p></p>
+FCKEnterKey.prototype._RecreateEndingTree = function( source, target )
+{
+	while ( ( source = source.lastChild ) && source.nodeType == 1 && FCKListsLib.InlineChildReqElements[ source.nodeName.toLowerCase() ] != null )
+		target = target.insertBefore( source.cloneNode( false ), target.firstChild ) ;
+}
+
+// Outdents a LI, maintaining the seletion defined on a range.
+FCKEnterKey.prototype._OutdentWithSelection = function( li, range )
+{
+	var oBookmark = range.CreateBookmark() ;
+
+	FCKListHandler.OutdentListItem( li ) ;
+
+	range.MoveToBookmark( oBookmark ) ;
+	range.Select() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckicon.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckicon.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckicon.js	(revision 795)
@@ -0,0 +1,98 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKIcon Class: renders an icon from a single image, a strip or even a
+ * spacer.
+ */
+
+var FCKIcon = function( iconPathOrStripInfoArray )
+{
+	var sTypeOf = iconPathOrStripInfoArray ? typeof( iconPathOrStripInfoArray ) : 'undefined' ;
+	switch ( sTypeOf )
+	{
+		case 'number' :
+			this.Path = FCKConfig.SkinPath + 'fck_strip.gif' ;
+			this.Size = 16 ;
+			this.Position = iconPathOrStripInfoArray ;
+			break ;
+
+		case 'undefined' :
+			this.Path = FCK_SPACER_PATH ;
+			break ;
+
+		case 'string' :
+			this.Path = iconPathOrStripInfoArray ;
+			break ;
+
+		default :
+			// It is an array in the format [ StripFilePath, IconSize, IconPosition ]
+			this.Path		= iconPathOrStripInfoArray[0] ;
+			this.Size		= iconPathOrStripInfoArray[1] ;
+			this.Position	= iconPathOrStripInfoArray[2] ;
+	}
+}
+
+FCKIcon.prototype.CreateIconElement = function( document )
+{
+	var eIcon, eIconImage ;
+
+	if ( this.Position )		// It is using an icons strip image.
+	{
+		var sPos = '-' + ( ( this.Position - 1 ) * this.Size ) + 'px' ;
+
+		if ( FCKBrowserInfo.IsIE )
+		{
+			// <div class="TB_Button_Image"><img src="strip.gif" style="top:-16px"></div>
+
+			eIcon = document.createElement( 'DIV' ) ;
+
+			eIconImage = eIcon.appendChild( document.createElement( 'IMG' ) ) ;
+			eIconImage.src = this.Path ;
+			eIconImage.style.top = sPos ;
+		}
+		else
+		{
+			// <img class="TB_Button_Image" src="spacer.gif" style="background-position: 0px -16px;background-image: url(strip.gif);">
+
+			eIcon = document.createElement( 'IMG' ) ;
+			eIcon.src = FCK_SPACER_PATH ;
+			eIcon.style.backgroundPosition	= '0px ' + sPos ;
+			eIcon.style.backgroundImage		= 'url(' + this.Path + ')' ;
+		}
+	}
+	else					// It is using a single icon image.
+	{
+		// This is not working well with IE. See notes bellow.
+		// <img class="TB_Button_Image" src="smiley.gif">
+//		eIcon = document.createElement( 'IMG' ) ;
+//		eIcon.src = this.Path ? this.Path : FCK_SPACER_PATH ;
+
+		// IE makes the button 1px higher if using the <img> directly, so we
+		// are changing to the <div> system to clip the image correctly.
+		eIcon = document.createElement( 'DIV' ) ;
+
+		eIconImage = eIcon.appendChild( document.createElement( 'IMG' ) ) ;
+		eIconImage.src = this.Path ? this.Path : FCK_SPACER_PATH ;
+	}
+
+	eIcon.className = 'TB_Button_Image' ;
+
+	return eIcon ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange.js	(revision 795)
@@ -0,0 +1,452 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Class for working with a selection range, much like the W3C DOM Range, but
+ * it is not intented to be an implementation of the W3C interface.
+ */
+
+var FCKDomRange = function( sourceWindow )
+{
+	this.Window = sourceWindow ;
+}
+
+FCKDomRange.prototype =
+{
+
+	_UpdateElementInfo : function()
+	{
+		if ( !this._Range )
+			this.Release( true ) ;
+		else
+		{
+			var eStart	= this._Range.startContainer ;
+			var eEnd	= this._Range.endContainer ;
+
+			var oElementPath = new FCKElementPath( eStart ) ;
+			this.StartContainer		= oElementPath.LastElement ;
+			this.StartBlock			= oElementPath.Block ;
+			this.StartBlockLimit	= oElementPath.BlockLimit ;
+
+			if ( eStart != eEnd )
+				oElementPath = new FCKElementPath( eEnd ) ;
+			this.EndContainer		= oElementPath.LastElement ;
+			this.EndBlock			= oElementPath.Block ;
+			this.EndBlockLimit		= oElementPath.BlockLimit ;
+		}
+	},
+
+	CreateRange : function()
+	{
+		return new FCKW3CRange( this.Window.document ) ;
+	},
+
+	DeleteContents : function()
+	{
+		if ( this._Range )
+		{
+			this._Range.deleteContents() ;
+			this._UpdateElementInfo() ;
+		}
+	},
+
+	ExtractContents : function()
+	{
+		if ( this._Range )
+		{
+			var docFrag = this._Range.extractContents() ;
+			this._UpdateElementInfo() ;
+			return docFrag ;
+		}
+	},
+
+	CheckIsCollapsed : function()
+	{
+		if ( this._Range )
+			return this._Range.collapsed ;
+	},
+
+	Collapse : function( toStart )
+	{
+		if ( this._Range )
+			this._Range.collapse( toStart ) ;
+
+		this._UpdateElementInfo() ;
+	},
+
+	Clone : function()
+	{
+		var oClone = FCKTools.CloneObject( this ) ;
+
+		if ( this._Range )
+			oClone._Range = this._Range.cloneRange() ;
+
+		return oClone ;
+	},
+
+	MoveToNodeContents : function( targetNode )
+	{
+		if ( !this._Range )
+			this._Range = this.CreateRange() ;
+
+		this._Range.selectNodeContents( targetNode ) ;
+
+		this._UpdateElementInfo() ;
+	},
+
+	MoveToElementStart : function( targetElement )
+	{
+		this.SetStart(targetElement,1) ;
+		this.SetEnd(targetElement,1) ;
+	},
+
+	// Moves to the first editing point inside a element. For example, in a
+	// element tree like "<p><b><i></i></b> Text</p>", the start editing point
+	// is "<p><b><i>^</i></b> Text</p>" (inside <i>).
+	MoveToElementEditStart : function( targetElement )
+	{
+		var child ;
+
+		while ( ( child = targetElement.firstChild ) && child.nodeType == 1 && FCKListsLib.EmptyElements[ child.nodeName.toLowerCase() ] == null )
+			targetElement = child ;
+
+		this.MoveToElementStart( targetElement ) ;
+	},
+
+	InsertNode : function( node )
+	{
+		if ( this._Range )
+			this._Range.insertNode( node ) ;
+	},
+
+	CheckIsEmpty : function( ignoreEndBRs )
+	{
+		if ( this.CheckIsCollapsed() )
+			return true ;
+
+		// Inserts the contents of the range in a div tag.
+		var eToolDiv = this.Window.document.createElement( 'div' ) ;
+		this._Range.cloneContents().AppendTo( eToolDiv ) ;
+
+		FCKDomTools.TrimNode( eToolDiv, ignoreEndBRs ) ;
+
+		return ( eToolDiv.innerHTML.length == 0 ) ;
+	},
+
+	CheckStartOfBlock : function()
+	{
+		// Create a clone of the current range.
+		var oTestRange = this.Clone() ;
+
+		// Collapse it to its start point.
+		oTestRange.Collapse( true ) ;
+
+		// Move the start boundary to the start of the block.
+		oTestRange.SetStart( oTestRange.StartBlock || oTestRange.StartBlockLimit, 1 ) ;
+
+		var bIsStartOfBlock = oTestRange.CheckIsEmpty() ;
+
+		oTestRange.Release() ;
+
+		return bIsStartOfBlock ;
+	},
+
+	CheckEndOfBlock : function( refreshSelection )
+	{
+		// Create a clone of the current range.
+		var oTestRange = this.Clone() ;
+
+		// Collapse it to its end point.
+		oTestRange.Collapse( false ) ;
+
+		// Move the end boundary to the end of the block.
+		oTestRange.SetEnd( oTestRange.EndBlock || oTestRange.EndBlockLimit, 2 ) ;
+
+		var bIsEndOfBlock = oTestRange.CheckIsCollapsed() ;
+		
+		if ( !bIsEndOfBlock )
+		{
+			// Inserts the contents of the range in a div tag.
+			var eToolDiv = this.Window.document.createElement( 'div' ) ;
+			oTestRange._Range.cloneContents().AppendTo( eToolDiv ) ;
+			FCKDomTools.TrimNode( eToolDiv, true ) ;
+			
+			// Find out if we are in an empty tree of inline elements, like <b><i><span></span></i></b>
+			bIsEndOfBlock = true ;
+			var eLastChild = eToolDiv ;
+			while ( ( eLastChild = eLastChild.lastChild ) )
+			{
+				// Check the following:
+				//		1. Is there more than one node in the parents children?
+				//		2. Is the node not an element node?
+				//		3. Is it not a inline element.
+				if ( eLastChild.previousSibling || eLastChild.nodeType != 1 || FCKListsLib.InlineChildReqElements[ eLastChild.nodeName.toLowerCase() ] == null )
+				{
+					// So we are not in the end of the range.
+					bIsEndOfBlock = false ;
+					break ;
+				}
+			}
+		}
+		
+		oTestRange.Release() ;
+
+		if ( refreshSelection )
+			this.Select() ;
+
+		return bIsEndOfBlock ;
+	},
+
+	CreateBookmark : function()
+	{
+		// Create the bookmark info (random IDs).
+		var oBookmark =
+		{
+			StartId	: 'fck_dom_range_start_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000),
+			EndId	: 'fck_dom_range_end_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000)
+		} ;
+
+		var oDoc = this.Window.document ;
+		var eSpan ;
+		var oClone ;
+
+		// For collapsed ranges, add just the start marker.
+		if ( !this.CheckIsCollapsed() )
+		{
+			eSpan = oDoc.createElement( 'span' ) ;
+			eSpan.id = oBookmark.EndId ;
+			eSpan.innerHTML = '&nbsp;' ;	// For IE, it must have something inside, otherwise it may be removed during operations.
+
+			oClone = this.Clone() ;
+			oClone.Collapse( false ) ;
+			oClone.InsertNode( eSpan ) ;
+		}
+
+		eSpan = oDoc.createElement( 'span' ) ;
+		eSpan.id = oBookmark.StartId ;
+		eSpan.innerHTML = '&nbsp;' ;	// For IE, it must have something inside, otherwise it may be removed during operations.
+
+		oClone = this.Clone() ;
+		oClone.Collapse( true ) ;
+		oClone.InsertNode( eSpan ) ;
+
+		return oBookmark ;
+	},
+
+	MoveToBookmark : function( bookmark, preserveBookmark )
+	{
+		var oDoc = this.Window.document ;
+
+		var eStartSpan	=  oDoc.getElementById( bookmark.StartId ) ;
+		var eEndSpan	=  oDoc.getElementById( bookmark.EndId ) ;
+
+		this.SetStart( eStartSpan, 3 ) ;
+
+		if ( !preserveBookmark )
+			FCKDomTools.RemoveNode( eStartSpan ) ;
+
+		// If collapsed, the start span will not be available.
+		if ( eEndSpan )
+		{
+			this.SetEnd( eEndSpan, 3 ) ;
+
+			if ( !preserveBookmark )
+				FCKDomTools.RemoveNode( eEndSpan ) ;
+		}
+		else
+			this.Collapse( true ) ;
+	},
+
+	/*
+	 * Moves the position of the start boundary of the range to a specific position
+	 * relatively to a element.
+	 *		@position:
+	 *			1 = After Start		<target>^contents</target>
+	 *			2 = Before End		<target>contents^</target>
+	 *			3 = Before Start	^<target>contents</target>
+	 *			4 = After End		<target>contents</target>^
+	 */
+	SetStart : function( targetElement, position )
+	{
+		var oRange = this._Range ;
+		if ( !oRange )
+			oRange = this._Range = this.CreateRange() ;
+
+		switch( position )
+		{
+			case 1 :		// After Start		<target>^contents</target>
+				oRange.setStart( targetElement, 0 ) ;
+				break ;
+
+			case 2 :		// Before End		<target>contents^</target>
+				oRange.setStart( targetElement, targetElement.childNodes.length ) ;
+				break ;
+
+			case 3 :		// Before Start		^<target>contents</target>
+				oRange.setStartBefore( targetElement ) ;
+				break ;
+
+			case 4 :		// After End		<target>contents</target>^
+				oRange.setStartAfter( targetElement ) ;
+		}
+		this._UpdateElementInfo() ;
+	},
+
+	/*
+	 * Moves the position of the start boundary of the range to a specific position
+	 * relatively to a element.
+	 *		@position:
+	 *			1 = After Start		<target>^contents</target>
+	 *			2 = Before End		<target>contents^</target>
+	 *			3 = Before Start	^<target>contents</target>
+	 *			4 = After End		<target>contents</target>^
+	 */
+	SetEnd : function( targetElement, position )
+	{
+		var oRange = this._Range ;
+		if ( !oRange )
+			oRange = this._Range = this.CreateRange() ;
+
+		switch( position )
+		{
+			case 1 :		// After Start		<target>^contents</target>
+				oRange.setEnd( targetElement, 0 ) ;
+				break ;
+
+			case 2 :		// Before End		<target>contents^</target>
+				oRange.setEnd( targetElement, targetElement.childNodes.length ) ;
+				break ;
+
+			case 3 :		// Before Start		^<target>contents</target>
+				oRange.setEndBefore( targetElement ) ;
+				break ;
+
+			case 4 :		// After End		<target>contents</target>^
+				oRange.setEndAfter( targetElement ) ;
+		}
+		this._UpdateElementInfo() ;
+	},
+
+	Expand : function( unit )
+	{
+		var oNode, oSibling ;
+
+		switch ( unit )
+		{
+			case 'block_contents' :
+				if ( this.StartBlock )
+					this.SetStart( this.StartBlock, 1 ) ;
+				else
+				{
+					// Get the start node for the current range.
+					oNode = this._Range.startContainer ;
+
+					// If it is an element, get the current child node for the range (in the offset).
+					// If the offset node is not available, the the first one.
+					if ( oNode.nodeType == 1 )
+					{
+						if ( !( oNode = oNode.childNodes[ this._Range.startOffset ] ) )
+							oNode = oNode.firstChild ;
+					}
+
+					// Not able to defined the current position.
+					if ( !oNode )
+						return ;
+
+					// We must look for the left boundary, relative to the range
+					// start, which is limited by a block element.
+					while ( true )
+					{
+						oSibling = oNode.previousSibling ;
+
+						if ( !oSibling )
+						{
+							// Continue if we are not yet in the block limit (inside a <b>, for example).
+							if ( oNode.parentNode != this.StartBlockLimit )
+								oNode = oNode.parentNode ;
+							else
+								break ;
+						}
+						else if ( oSibling.nodeType != 1 || !(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test( oSibling.nodeName.toUpperCase() ) )
+						{
+							// Continue if the sibling is not a block tag.
+							oNode = oSibling ;
+						}
+						else
+							break ;
+					}
+
+					this._Range.setStartBefore( oNode ) ;
+				}
+
+				if ( this.EndBlock )
+					this.SetEnd( this.EndBlock, 2 ) ;
+				else
+				{
+					oNode = this._Range.endContainer ;
+					if ( oNode.nodeType == 1 )
+						oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ;
+
+					if ( !oNode )
+						return ;
+
+					// We must look for the right boundary, relative to the range
+					// end, which is limited by a block element.
+					while ( true )
+					{
+						oSibling = oNode.nextSibling ;
+
+						if ( !oSibling )
+						{
+							// Continue if we are not yet in the block limit (inide a <b>, for example).
+							if ( oNode.parentNode != this.EndBlockLimit )
+								oNode = oNode.parentNode ;
+							else
+								break ;
+						}
+						else if ( oSibling.nodeType != 1 || !(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test( oSibling.nodeName.toUpperCase() ) )
+						{
+							// Continue if the sibling is not a block tag.
+							oNode = oSibling ;
+						}
+						else
+							break ;
+					}
+
+					this._Range.setEndAfter( oNode ) ;
+				}
+
+				this._UpdateElementInfo() ;
+		}
+	},
+
+	Release : function( preserveWindow )
+	{
+		if ( !preserveWindow )
+			this.Window = null ;
+
+		this.StartContainer = null ;
+		this.StartBlock = null ;
+		this.StartBlockLimit = null ;
+		this.EndContainer = null ;
+		this.EndBlock = null ;
+		this.EndBlockLimit = null ;
+		this._Range = null ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef_ie.js	(revision 795)
@@ -0,0 +1,142 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleDef Class: represents a single stylke definition. (IE specific)
+ */
+
+FCKStyleDef.prototype.ApplyToSelection = function()
+{
+	var oSelection = FCK.ToolbarSet.CurrentInstance.EditorDocument.selection ;
+
+	if ( oSelection.type == 'Text' )
+	{
+		var oRange = oSelection.createRange() ;
+
+		// Create the main element.
+		var e = document.createElement( this.Element ) ;
+		e.innerHTML = oRange.htmlText ;
+
+		// Set the attributes.
+		this._AddAttributes( e ) ;
+
+		// Remove the duplicated elements.
+		this._RemoveDuplicates( e ) ;
+
+		// Replace the selection with the resulting HTML.
+		oRange.pasteHTML( e.outerHTML ) ;
+	}
+	else if ( oSelection.type == 'Control' )
+	{
+		var oControl = FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement() ;
+		if ( oControl.tagName == this.Element )
+			this._AddAttributes( oControl ) ;
+	}
+}
+
+FCKStyleDef.prototype._AddAttributes = function( targetElement )
+{
+	for ( var a in this.Attributes )
+	{
+		switch ( a.toLowerCase() )
+		{
+			case 'style' :
+				targetElement.style.cssText = this.Attributes[a] ;
+				break ;
+
+			case 'class' :
+				targetElement.setAttribute( 'className', this.Attributes[a], 0 ) ;
+				break ;
+
+			case 'src' :
+				targetElement.setAttribute( '_fcksavedurl', this.Attributes[a], 0 ) ;
+			default :
+				targetElement.setAttribute( a, this.Attributes[a], 0 ) ;
+		}
+	}
+}
+
+FCKStyleDef.prototype._RemoveDuplicates = function( parent )
+{
+	for ( var i = 0 ; i < parent.children.length ; i++ )
+	{
+		var oChild = parent.children[i] ;
+		this._RemoveDuplicates( oChild ) ;
+
+		if ( this.IsEqual( oChild ) )
+			FCKTools.RemoveOuterTags( oChild ) ;
+	}
+}
+
+FCKStyleDef.prototype.IsEqual = function( e )
+{
+	if ( e.tagName != this.Element )
+		return false ;
+
+	for ( var a in this.Attributes )
+	{
+		switch ( a.toLowerCase() )
+		{
+			case 'style' :
+				if ( e.style.cssText.toLowerCase() != this.Attributes[a].toLowerCase() )
+					return false ;
+				break ;
+			case 'class' :
+				if ( e.getAttribute( 'className', 0 ) != this.Attributes[a] )
+					return false ;
+				break ;
+			default :
+				if ( e.getAttribute( a, 0 ) != this.Attributes[a] )
+					return false ;
+		}
+	}
+
+	return true ;
+}
+
+FCKStyleDef.prototype._RemoveMe = function( elementToCheck )
+{
+	if ( ! elementToCheck )
+		return ;
+
+	var oParent = elementToCheck.parentElement ;
+
+	if ( this.IsEqual( elementToCheck ) )
+	{
+		if ( this.IsObjectElement )
+		{
+			for ( var a in this.Attributes )
+			{
+				switch ( a.toLowerCase() )
+				{
+					case 'class' :
+						elementToCheck.removeAttribute( 'className', 0 ) ;
+						break ;
+					default :
+						elementToCheck.removeAttribute( a, 0 ) ;
+				}
+			}
+			return ;
+		}
+		else
+			FCKTools.RemoveOuterTags( elementToCheck ) ;
+	}
+
+	this._RemoveMe( oParent ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbuttonui.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbuttonui.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbuttonui.js	(revision 795)
@@ -0,0 +1,222 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarButtonUI Class: interface representation of a toolbar button.
+ */
+
+var FCKToolbarButtonUI = function( name, label, tooltip, iconPathOrStripInfoArray, style, state )
+{
+	this.Name		= name ;
+	this.Label		= label || name ;
+	this.Tooltip	= tooltip || this.Label ;
+	this.Style		= style || FCK_TOOLBARITEM_ONLYICON ;
+	this.State		= state || FCK_TRISTATE_OFF ;
+
+	this.Icon = new FCKIcon( iconPathOrStripInfoArray ) ;
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( this, FCKToolbarButtonUI_Cleanup ) ;
+}
+
+
+FCKToolbarButtonUI.prototype._CreatePaddingElement = function( document )
+{
+	var oImg = document.createElement( 'IMG' ) ;
+	oImg.className = 'TB_Button_Padding' ;
+	oImg.src = FCK_SPACER_PATH ;
+	return oImg ;
+}
+
+FCKToolbarButtonUI.prototype.Create = function( parentElement )
+{
+	var oMainElement = this.MainElement ;
+
+	if ( oMainElement )
+	{
+		FCKToolbarButtonUI_Cleanup.call(this) ;
+
+		if ( oMainElement.parentNode )
+			oMainElement.parentNode.removeChild( oMainElement ) ;
+		oMainElement = this.MainElement = null ;
+	}
+
+	var oDoc = FCKTools.GetElementDocument( parentElement ) ;
+
+	// Create the Main Element.
+	oMainElement = this.MainElement = oDoc.createElement( 'DIV' ) ;
+	oMainElement._FCKButton = this ;		// IE Memory Leak (Circular reference).
+	oMainElement.title		= this.Tooltip ;
+
+	// The following will prevent the button from catching the focus.
+	if ( FCKBrowserInfo.IsGecko )
+		 oMainElement.onmousedown	= FCKTools.CancelEvent ;
+
+	this.ChangeState( this.State, true ) ;
+
+	if ( this.Style == FCK_TOOLBARITEM_ONLYICON && !this.ShowArrow )
+	{
+		// <td><div class="TB_Button_On" title="Smiley">{Image}</div></td>
+
+		oMainElement.appendChild( this.Icon.CreateIconElement( oDoc ) ) ;
+	}
+	else
+	{
+		// <td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td>{Image}</td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
+		// <td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td><img class="TB_Button_Padding"></td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
+
+		var oTable = oMainElement.appendChild( oDoc.createElement( 'TABLE' ) ) ;
+		oTable.cellPadding = 0 ;
+		oTable.cellSpacing = 0 ;
+
+		var oRow = oTable.insertRow(-1) ;
+
+		// The Image cell (icon or padding).
+		var oCell = oRow.insertCell(-1) ;
+
+		if ( this.Style == FCK_TOOLBARITEM_ONLYICON || this.Style == FCK_TOOLBARITEM_ICONTEXT )
+			oCell.appendChild( this.Icon.CreateIconElement( oDoc ) ) ;
+		else
+			oCell.appendChild( this._CreatePaddingElement( oDoc ) ) ;
+
+		if ( this.Style == FCK_TOOLBARITEM_ONLYTEXT || this.Style == FCK_TOOLBARITEM_ICONTEXT )
+		{
+			// The Text cell.
+			oCell = oRow.insertCell(-1) ;
+			oCell.className = 'TB_Button_Text' ;
+			oCell.noWrap = true ;
+			oCell.appendChild( oDoc.createTextNode( this.Label ) ) ;
+		}
+
+		if ( this.ShowArrow )
+		{
+			if ( this.Style != FCK_TOOLBARITEM_ONLYICON )
+			{
+				// A padding cell.
+				oRow.insertCell(-1).appendChild( this._CreatePaddingElement( oDoc ) ) ;
+			}
+
+			oCell = oRow.insertCell(-1) ;
+			var eImg = oCell.appendChild( oDoc.createElement( 'IMG' ) ) ;
+			eImg.src	= FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif' ;
+			eImg.width	= 5 ;
+			eImg.height	= 3 ;
+		}
+
+		// The last padding cell.
+		oCell = oRow.insertCell(-1) ;
+		oCell.appendChild( this._CreatePaddingElement( oDoc ) ) ;
+	}
+
+	parentElement.appendChild( oMainElement ) ;
+}
+
+FCKToolbarButtonUI.prototype.ChangeState = function( newState, force )
+{
+	if ( !force && this.State == newState )
+		return ;
+
+	var e = this.MainElement ;
+
+	switch ( parseInt( newState, 10 ) )
+	{
+		case FCK_TRISTATE_OFF :
+			e.className		= 'TB_Button_Off' ;
+			e.onmouseover	= FCKToolbarButton_OnMouseOverOff ;
+			e.onmouseout	= FCKToolbarButton_OnMouseOutOff ;
+			e.onclick		= FCKToolbarButton_OnClick ;
+
+			break ;
+
+		case FCK_TRISTATE_ON :
+			e.className		= 'TB_Button_On' ;
+			e.onmouseover	= FCKToolbarButton_OnMouseOverOn ;
+			e.onmouseout	= FCKToolbarButton_OnMouseOutOn ;
+			e.onclick		= FCKToolbarButton_OnClick ;
+
+			break ;
+
+		case FCK_TRISTATE_DISABLED :
+			e.className		= 'TB_Button_Disabled' ;
+			e.onmouseover	= null ;
+			e.onmouseout	= null ;
+			e.onclick		= null ;
+
+			break ;
+	}
+
+	this.State = newState ;
+}
+
+function FCKToolbarButtonUI_Cleanup()
+{
+	if ( this.MainElement )
+	{
+		this.MainElement._FCKButton = null ;
+		this.MainElement = null ;
+	}
+}
+
+// Event Handlers.
+
+function FCKToolbarButton_OnMouseOverOn()
+{
+	this.className = 'TB_Button_On_Over' ;
+}
+
+function FCKToolbarButton_OnMouseOutOn()
+{
+	this.className = 'TB_Button_On' ;
+}
+
+function FCKToolbarButton_OnMouseOverOff()
+{
+	this.className = 'TB_Button_Off_Over' ;
+}
+
+function FCKToolbarButton_OnMouseOutOff()
+{
+	this.className = 'TB_Button_Off' ;
+}
+
+function FCKToolbarButton_OnClick( e )
+{
+	if ( this._FCKButton.OnClick )
+		this._FCKButton.OnClick( this._FCKButton ) ;
+}
+
+/*
+	Sample outputs:
+
+	This is the base structure. The variation is the image that is marked as {Image}:
+		<td><div class="TB_Button_On" title="Smiley">{Image}</div></td>
+		<td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td>{Image}</td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
+		<td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td><img class="TB_Button_Padding"></td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
+
+	These are samples of possible {Image} values:
+
+		Strip - IE version:
+			<div class="TB_Button_Image"><img src="strip.gif" style="top:-16px"></div>
+
+		Strip : Firefox, Safari and Opera version
+			<img class="TB_Button_Image" style="background-position: 0px -16px;background-image: url(strip.gif);">
+
+		No-Strip : Browser independent:
+			<img class="TB_Button_Image" src="smiley.gif">
+*/
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontscombo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontscombo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarfontscombo.js	(revision 795)
@@ -0,0 +1,47 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarPanelButton Class: Handles the Fonts combo selector.
+ */
+
+var FCKToolbarFontsCombo = function( tooltip, style )
+{
+	this.CommandName	= 'FontName' ;
+	this.Label		= this.GetLabel() ;
+	this.Tooltip	= tooltip ? tooltip : this.Label ;
+	this.Style		= style ? style : FCK_TOOLBARITEM_ICONTEXT ;
+}
+
+// Inherit from FCKToolbarSpecialCombo.
+FCKToolbarFontsCombo.prototype = new FCKToolbarSpecialCombo ;
+
+
+FCKToolbarFontsCombo.prototype.GetLabel = function()
+{
+	return FCKLang.Font ;
+}
+
+FCKToolbarFontsCombo.prototype.CreateItems = function( targetSpecialCombo )
+{
+	var aFonts = FCKConfig.FontNames.split(';') ;
+
+	for ( var i = 0 ; i < aFonts.length ; i++ )
+		this._Combo.AddItem( aFonts[i], '<font face="' + aFonts[i] + '" style="font-size: 12px">' + aFonts[i] + '</font>' ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbutton.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbutton.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbarbutton.js	(revision 795)
@@ -0,0 +1,74 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbarButton Class: represents a button in the toolbar.
+ */
+
+var FCKToolbarButton = function( commandName, label, tooltip, style, sourceView, contextSensitive, icon )
+{
+	this.CommandName		= commandName ;
+	this.Label				= label ;
+	this.Tooltip			= tooltip ;
+	this.Style				= style ;
+	this.SourceView			= sourceView ? true : false ;
+	this.ContextSensitive	= contextSensitive ? true : false ;
+
+	if ( icon == null )
+		this.IconPath = FCKConfig.SkinPath + 'toolbar/' + commandName.toLowerCase() + '.gif' ;
+	else if ( typeof( icon ) == 'number' )
+		this.IconPath = [ FCKConfig.SkinPath + 'fck_strip.gif', 16, icon ] ;
+}
+
+FCKToolbarButton.prototype.Create = function( targetElement )
+{
+	this._UIButton = new FCKToolbarButtonUI( this.CommandName, this.Label, this.Tooltip, this.IconPath, this.Style ) ;
+	this._UIButton.OnClick = this.Click ;
+	this._UIButton._ToolbarButton = this ;
+	this._UIButton.Create( targetElement ) ;
+}
+
+FCKToolbarButton.prototype.RefreshState = function()
+{
+	// Gets the actual state.
+	var eState = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).GetState() ;
+
+	// If there are no state changes than do nothing and return.
+	if ( eState == this._UIButton.State ) return ;
+
+	// Sets the actual state.
+	this._UIButton.ChangeState( eState ) ;
+}
+
+FCKToolbarButton.prototype.Click = function()
+{
+	var oToolbarButton = this._ToolbarButton || this ;
+	FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( oToolbarButton.CommandName ).Execute() ;
+}
+
+FCKToolbarButton.prototype.Enable = function()
+{
+	this.RefreshState() ;
+}
+
+FCKToolbarButton.prototype.Disable = function()
+{
+	// Sets the actual state.
+	this._UIButton.ChangeState( FCK_TRISTATE_DISABLED ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckpanel.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckpanel.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckpanel.js	(revision 795)
@@ -0,0 +1,303 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Component that creates floating panels. It is used by many
+ * other components, like the toolbar items, context menu, etc...
+ */
+
+var FCKPanel = function( parentWindow )
+{
+	this.IsRTL			= ( FCKLang.Dir == 'rtl' ) ;
+	this.IsContextMenu	= false ;
+	this._LockCounter	= 0 ;
+
+	this._Window = parentWindow || window ;
+
+	var oDocument ;
+
+	if ( FCKBrowserInfo.IsIE )
+	{
+		// Create the Popup that will hold the panel.
+		this._Popup	= this._Window.createPopup() ;
+		oDocument = this.Document = this._Popup.document ;
+
+		FCK.IECleanup.AddItem( this, FCKPanel_Cleanup ) ;
+	}
+	else
+	{
+		var oIFrame = this._IFrame = this._Window.document.createElement('iframe') ;
+		oIFrame.src					= 'javascript:void(0)' ;
+		oIFrame.allowTransparency	= true ;
+		oIFrame.frameBorder			= '0' ;
+		oIFrame.scrolling			= 'no' ;
+		oIFrame.style.position		= 'absolute';
+		oIFrame.style.zIndex		= FCKConfig.FloatingPanelsZIndex ;
+		oIFrame.width = oIFrame.height = 0 ;
+
+		if ( this._Window == window.parent && window.frameElement )
+			window.frameElement.parentNode.insertBefore( oIFrame, window.frameElement ) ;
+		else
+			this._Window.document.body.appendChild( oIFrame ) ;
+
+		var oIFrameWindow = oIFrame.contentWindow ;
+
+		oDocument = this.Document = oIFrameWindow.document ;
+
+		// Initialize the IFRAME document body.
+		oDocument.open() ;
+		oDocument.write( '<html><head></head><body style="margin:0px;padding:0px;"><\/body><\/html>' ) ;
+		oDocument.close() ;
+
+		FCKTools.AddEventListenerEx( oIFrameWindow, 'focus', FCKPanel_Window_OnFocus, this ) ;
+		FCKTools.AddEventListenerEx( oIFrameWindow, 'blur', FCKPanel_Window_OnBlur, this ) ;
+	}
+
+	oDocument.dir = FCKLang.Dir ;
+
+	oDocument.oncontextmenu = FCKTools.CancelEvent ;
+
+
+	// Create the main DIV that is used as the panel base.
+	this.MainNode = oDocument.body.appendChild( oDocument.createElement('DIV') ) ;
+
+	// The "float" property must be set so Firefox calculates the size correcly.
+	this.MainNode.style.cssFloat = this.IsRTL ? 'right' : 'left' ;
+}
+
+
+FCKPanel.prototype.AppendStyleSheet = function( styleSheet )
+{
+	FCKTools.AppendStyleSheet( this.Document, styleSheet ) ;
+}
+
+FCKPanel.prototype.Preload = function( x, y, relElement )
+{
+	// The offsetWidth and offsetHeight properties are not available if the
+	// element is not visible. So we must "show" the popup with no size to
+	// be able to use that values in the second call (IE only).
+	if ( this._Popup )
+		this._Popup.show( x, y, 0, 0, relElement ) ;
+}
+
+FCKPanel.prototype.Show = function( x, y, relElement, width, height )
+{
+	var iMainWidth ;
+
+	if ( this._Popup )
+	{
+		// The offsetWidth and offsetHeight properties are not available if the
+		// element is not visible. So we must "show" the popup with no size to
+		// be able to use that values in the second call.
+		this._Popup.show( x, y, 0, 0, relElement ) ;
+
+		// The following lines must be place after the above "show", otherwise it
+		// doesn't has the desired effect.
+		this.MainNode.style.width	= width ? width + 'px' : '' ;
+		this.MainNode.style.height	= height ? height + 'px' : '' ;
+
+		iMainWidth = this.MainNode.offsetWidth ;
+
+		if ( this.IsRTL )
+		{
+			if ( this.IsContextMenu )
+				x  = x - iMainWidth + 1 ;
+			else if ( relElement )
+				x  = ( x * -1 ) + relElement.offsetWidth - iMainWidth ;
+		}
+
+		// Second call: Show the Popup at the specified location, with the correct size.
+		this._Popup.show( x, y, iMainWidth, this.MainNode.offsetHeight, relElement ) ;
+
+		if ( this.OnHide )
+		{
+			if ( this._Timer )
+				CheckPopupOnHide.call( this, true ) ;
+
+			this._Timer = FCKTools.SetInterval( CheckPopupOnHide, 100, this ) ;
+		}
+	}
+	else
+	{
+		// Do not fire OnBlur while the panel is opened.
+		if ( typeof( FCKFocusManager ) != 'undefined' )
+			FCKFocusManager.Lock() ;
+
+		if ( this.ParentPanel )
+			this.ParentPanel.Lock() ;
+
+		this.MainNode.style.width	= width ? width + 'px' : '' ;
+		this.MainNode.style.height	= height ? height + 'px' : '' ;
+
+		iMainWidth = this.MainNode.offsetWidth ;
+
+		if ( !width )	this._IFrame.width	= 1 ;
+		if ( !height )	this._IFrame.height	= 1 ;
+
+		// This is weird... but with Firefox, we must get the offsetWidth before
+		// setting the _IFrame size (which returns "0"), and then after that,
+		// to return the correct width. Remove the first step and it will not
+		// work when the editor is in RTL.
+		iMainWidth = this.MainNode.offsetWidth ;
+
+		var oPos = FCKTools.GetElementPosition(
+			relElement.nodeType == 9 ?
+				( FCKTools.IsStrictMode( relElement ) ? relElement.documentElement : relElement.body ) :
+				relElement,
+			this._Window ) ;
+
+		if ( this.IsRTL && !this.IsContextMenu )
+			x = ( x * -1 ) ;
+
+		x += oPos.X ;
+		y += oPos.Y ;
+
+		if ( this.IsRTL )
+		{
+			if ( this.IsContextMenu )
+				x  = x - iMainWidth + 1 ;
+			else if ( relElement )
+				x  = x + relElement.offsetWidth - iMainWidth ;
+		}
+		else
+		{
+			var oViewPaneSize = FCKTools.GetViewPaneSize( this._Window ) ;
+			var oScrollPosition = FCKTools.GetScrollPosition( this._Window ) ;
+
+			var iViewPaneHeight	= oViewPaneSize.Height + oScrollPosition.Y ;
+			var iViewPaneWidth	= oViewPaneSize.Width + oScrollPosition.X ;
+
+			if ( ( x + iMainWidth ) > iViewPaneWidth )
+				x -= x + iMainWidth - iViewPaneWidth ;
+
+			if ( ( y + this.MainNode.offsetHeight ) > iViewPaneHeight )
+				y -= y + this.MainNode.offsetHeight - iViewPaneHeight ;
+		}
+
+		if ( x < 0 )
+			 x = 0 ;
+
+		// Set the context menu DIV in the specified location.
+		this._IFrame.style.left	= x + 'px' ;
+		this._IFrame.style.top	= y + 'px' ;
+
+		var iWidth	= iMainWidth ;
+		var iHeight	= this.MainNode.offsetHeight ;
+
+		this._IFrame.width	= iWidth ;
+		this._IFrame.height = iHeight ;
+
+		// Move the focus to the IFRAME so we catch the "onblur".
+		this._IFrame.contentWindow.focus() ;
+	}
+
+	this._IsOpened = true ;
+
+	FCKTools.RunFunction( this.OnShow, this ) ;
+}
+
+FCKPanel.prototype.Hide = function( ignoreOnHide )
+{
+	if ( this._Popup )
+		this._Popup.hide() ;
+	else
+	{
+		if ( !this._IsOpened )
+			return ;
+
+		// Enable the editor to fire the "OnBlur".
+		if ( typeof( FCKFocusManager ) != 'undefined' )
+			FCKFocusManager.Unlock() ;
+
+		// It is better to set the sizes to 0, otherwise Firefox would have
+		// rendering problems.
+		this._IFrame.width = this._IFrame.height = 0 ;
+
+		this._IsOpened = false ;
+
+		if ( this.ParentPanel )
+			this.ParentPanel.Unlock() ;
+
+		if ( !ignoreOnHide )
+			FCKTools.RunFunction( this.OnHide, this ) ;
+	}
+}
+
+FCKPanel.prototype.CheckIsOpened = function()
+{
+	if ( this._Popup )
+		return this._Popup.isOpen ;
+	else
+		return this._IsOpened ;
+}
+
+FCKPanel.prototype.CreateChildPanel = function()
+{
+	var oWindow = this._Popup ? FCKTools.GetDocumentWindow( this.Document ) : this._Window ;
+
+	var oChildPanel = new FCKPanel( oWindow, true ) ;
+	oChildPanel.ParentPanel = this ;
+
+	return oChildPanel ;
+}
+
+FCKPanel.prototype.Lock = function()
+{
+	this._LockCounter++ ;
+}
+
+FCKPanel.prototype.Unlock = function()
+{
+	if ( --this._LockCounter == 0 && !this.HasFocus )
+		this.Hide() ;
+}
+
+/* Events */
+
+function FCKPanel_Window_OnFocus( e, panel )
+{
+	panel.HasFocus = true ;
+}
+
+function FCKPanel_Window_OnBlur( e, panel )
+{
+	panel.HasFocus = false ;
+
+	if ( panel._LockCounter == 0 )
+		FCKTools.RunFunction( panel.Hide, panel ) ;
+}
+
+function CheckPopupOnHide( forceHide )
+{
+	if ( forceHide || !this._Popup.isOpen )
+	{
+		window.clearInterval( this._Timer ) ;
+		this._Timer = null ;
+
+		FCKTools.RunFunction( this.OnHide, this ) ;
+	}
+}
+
+function FCKPanel_Cleanup()
+{
+	this._Popup = null ;
+	this._Window = null ;
+	this.Document = null ;
+	this.MainNode = null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckspecialcombo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckspecialcombo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckspecialcombo.js	(revision 795)
@@ -0,0 +1,363 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKSpecialCombo Class: represents a special combo.
+ */
+
+var FCKSpecialCombo = function( caption, fieldWidth, panelWidth, panelMaxHeight, parentWindow )
+{
+	// Default properties values.
+	this.FieldWidth		= fieldWidth || 100 ;
+	this.PanelWidth		= panelWidth || 150 ;
+	this.PanelMaxHeight	= panelMaxHeight || 150 ;
+	this.Label			= '&nbsp;' ;
+	this.Caption		= caption ;
+	this.Tooltip		= caption ;
+	this.Style			= FCK_TOOLBARITEM_ICONTEXT ;
+
+	this.Enabled = true ;
+
+	this.Items = new Object() ;
+
+	this._Panel = new FCKPanel( parentWindow || window, true ) ;
+	this._Panel.AppendStyleSheet( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+	this._PanelBox = this._Panel.MainNode.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ;
+	this._PanelBox.className = 'SC_Panel' ;
+	this._PanelBox.style.width = this.PanelWidth + 'px' ;
+
+	this._PanelBox.innerHTML = '<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>' ;
+
+	this._ItemsHolderEl = this._PanelBox.getElementsByTagName('TD')[0] ;
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( this, FCKSpecialCombo_Cleanup ) ;
+
+//	this._Panel.StyleSheet = FCKConfig.SkinPath + 'fck_contextmenu.css' ;
+//	this._Panel.Create() ;
+//	this._Panel.PanelDiv.className += ' SC_Panel' ;
+//	this._Panel.PanelDiv.innerHTML = '<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>' ;
+//	this._ItemsHolderEl = this._Panel.PanelDiv.getElementsByTagName('TD')[0] ;
+}
+
+function FCKSpecialCombo_ItemOnMouseOver()
+{
+	this.className += ' SC_ItemOver' ;
+}
+
+function FCKSpecialCombo_ItemOnMouseOut()
+{
+	this.className = this.originalClass ;
+}
+
+function FCKSpecialCombo_ItemOnClick()
+{
+	this.className = this.originalClass ;
+
+	this.FCKSpecialCombo._Panel.Hide() ;
+
+	this.FCKSpecialCombo.SetLabel( this.FCKItemLabel ) ;
+
+	if ( typeof( this.FCKSpecialCombo.OnSelect ) == 'function' )
+		this.FCKSpecialCombo.OnSelect( this.FCKItemID, this ) ;
+}
+
+FCKSpecialCombo.prototype.AddItem = function( id, html, label, bgColor )
+{
+	// <div class="SC_Item" onmouseover="this.className='SC_Item SC_ItemOver';" onmouseout="this.className='SC_Item';"><b>Bold 1</b></div>
+	var oDiv = this._ItemsHolderEl.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ;
+	oDiv.className = oDiv.originalClass = 'SC_Item' ;
+	oDiv.innerHTML = html ;
+	oDiv.FCKItemID = id ;
+	oDiv.FCKItemLabel = label || id ;
+	oDiv.FCKSpecialCombo = this ;
+	oDiv.Selected = false ;
+
+	// In IE, the width must be set so the borders are shown correctly when the content overflows.
+	if ( FCKBrowserInfo.IsIE )
+		oDiv.style.width = '100%' ;
+
+	if ( bgColor )
+		oDiv.style.backgroundColor = bgColor ;
+
+	oDiv.onmouseover	= FCKSpecialCombo_ItemOnMouseOver ;
+	oDiv.onmouseout		= FCKSpecialCombo_ItemOnMouseOut ;
+	oDiv.onclick		= FCKSpecialCombo_ItemOnClick ;
+
+	this.Items[ id.toString().toLowerCase() ] = oDiv ;
+
+	return oDiv ;
+}
+
+FCKSpecialCombo.prototype.SelectItem = function( itemId )
+{
+	itemId = itemId ? itemId.toString().toLowerCase() : '' ;
+
+	var oDiv = this.Items[ itemId ] ;
+	if ( oDiv )
+	{
+		oDiv.className = oDiv.originalClass = 'SC_ItemSelected' ;
+		oDiv.Selected = true ;
+	}
+}
+
+FCKSpecialCombo.prototype.SelectItemByLabel = function( itemLabel, setLabel )
+{
+	for ( var id in this.Items )
+	{
+		var oDiv = this.Items[id] ;
+
+		if ( oDiv.FCKItemLabel == itemLabel )
+		{
+			oDiv.className = oDiv.originalClass = 'SC_ItemSelected' ;
+			oDiv.Selected = true ;
+
+			if ( setLabel )
+				this.SetLabel( itemLabel ) ;
+		}
+	}
+}
+
+FCKSpecialCombo.prototype.DeselectAll = function( clearLabel )
+{
+	for ( var i in this.Items )
+	{
+		this.Items[i].className = this.Items[i].originalClass = 'SC_Item' ;
+		this.Items[i].Selected = false ;
+	}
+
+	if ( clearLabel )
+		this.SetLabel( '' ) ;
+}
+
+FCKSpecialCombo.prototype.SetLabelById = function( id )
+{
+	id = id ? id.toString().toLowerCase() : '' ;
+
+	var oDiv = this.Items[ id ] ;
+	this.SetLabel( oDiv ? oDiv.FCKItemLabel : '' ) ;
+}
+
+FCKSpecialCombo.prototype.SetLabel = function( text )
+{
+	this.Label = text.length == 0 ? '&nbsp;' : text ;
+
+	if ( this._LabelEl )
+	{
+		this._LabelEl.innerHTML = this.Label ;
+
+		// It may happen that the label is some HTML, including tags. This
+		// would be a problem because when the user click on those tags, the
+		// combo will get the selection from the editing area. So we must
+		// disable any kind of selection here.
+		FCKTools.DisableSelection( this._LabelEl ) ;
+	}
+}
+
+FCKSpecialCombo.prototype.SetEnabled = function( isEnabled )
+{
+	this.Enabled = isEnabled ;
+
+	this._OuterTable.className = isEnabled ? '' : 'SC_FieldDisabled' ;
+}
+
+FCKSpecialCombo.prototype.Create = function( targetElement )
+{
+	var oDoc = FCKTools.GetElementDocument( targetElement ) ;
+	var eOuterTable = this._OuterTable = targetElement.appendChild( oDoc.createElement( 'TABLE' ) ) ;
+	eOuterTable.cellPadding = 0 ;
+	eOuterTable.cellSpacing = 0 ;
+
+	eOuterTable.insertRow(-1) ;
+
+	var sClass ;
+	var bShowLabel ;
+
+	switch ( this.Style )
+	{
+		case FCK_TOOLBARITEM_ONLYICON :
+			sClass = 'TB_ButtonType_Icon' ;
+			bShowLabel = false;
+			break ;
+		case FCK_TOOLBARITEM_ONLYTEXT :
+			sClass = 'TB_ButtonType_Text' ;
+			bShowLabel = false;
+			break ;
+		case FCK_TOOLBARITEM_ICONTEXT :
+			bShowLabel = true;
+			break ;
+	}
+
+	if ( this.Caption && this.Caption.length > 0 && bShowLabel )
+	{
+		var oCaptionCell = eOuterTable.rows[0].insertCell(-1) ;
+		oCaptionCell.innerHTML = this.Caption ;
+		oCaptionCell.className = 'SC_FieldCaption' ;
+	}
+
+	// Create the main DIV element.
+	var oField = FCKTools.AppendElement( eOuterTable.rows[0].insertCell(-1), 'div' ) ;
+	if ( bShowLabel )
+	{
+		oField.className = 'SC_Field' ;
+		oField.style.width = this.FieldWidth + 'px' ;
+		oField.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label>&nbsp;</label></td><td class="SC_FieldButton">&nbsp;</td></tr></tbody></table>' ;
+
+		this._LabelEl = oField.getElementsByTagName('label')[0] ;		// Memory Leak
+		this._LabelEl.innerHTML = this.Label ;
+	}
+	else
+	{
+		oField.className = 'TB_Button_Off' ;
+		//oField.innerHTML = '<span className="SC_FieldCaption">' + this.Caption + '<table cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldButton" style="border-left: none;">&nbsp;</td></tr></tbody></table>' ;
+		//oField.innerHTML = '<table cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldButton" style="border-left: none;">&nbsp;</td></tr></tbody></table>' ;
+
+		// Gets the correct CSS class to use for the specified style (param).
+		oField.innerHTML = '<table title="' + this.Tooltip + '" class="' + sClass + '" cellspacing="0" cellpadding="0" border="0">' +
+				'<tr>' +
+					//'<td class="TB_Icon"><img src="' + FCKConfig.SkinPath + 'toolbar/' + this.Command.Name.toLowerCase() + '.gif" width="21" height="21"></td>' +
+					'<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
+					'<td class="TB_Text">' + this.Caption + '</td>' +
+					'<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
+					'<td class="TB_ButtonArrow"><img src="' + FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif" width="5" height="3"></td>' +
+					'<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
+				'</tr>' +
+			'</table>' ;
+	}
+
+
+	// Events Handlers
+
+	oField.SpecialCombo = this ;
+
+	oField.onmouseover	= FCKSpecialCombo_OnMouseOver ;
+	oField.onmouseout	= FCKSpecialCombo_OnMouseOut ;
+	oField.onclick		= FCKSpecialCombo_OnClick ;
+
+	FCKTools.DisableSelection( this._Panel.Document.body ) ;
+}
+
+function FCKSpecialCombo_Cleanup()
+{
+	this._LabelEl = null ;
+	this._OuterTable = null ;
+	this._ItemsHolderEl = null ;
+	this._PanelBox = null ;
+
+	if ( this.Items )
+	{
+		for ( var key in this.Items )
+			this.Items[key] = null ;
+	}
+}
+
+function FCKSpecialCombo_OnMouseOver()
+{
+	if ( this.SpecialCombo.Enabled )
+	{
+		switch ( this.SpecialCombo.Style )
+		{
+		case FCK_TOOLBARITEM_ONLYICON :
+			this.className = 'TB_Button_On_Over';
+			break ;
+		case FCK_TOOLBARITEM_ONLYTEXT :
+			this.className = 'TB_Button_On_Over';
+			break ;
+		case FCK_TOOLBARITEM_ICONTEXT :
+			this.className = 'SC_Field SC_FieldOver' ;
+			break ;
+		}
+	}
+}
+
+function FCKSpecialCombo_OnMouseOut()
+{
+	switch ( this.SpecialCombo.Style )
+	{
+		case FCK_TOOLBARITEM_ONLYICON :
+			this.className = 'TB_Button_Off';
+			break ;
+		case FCK_TOOLBARITEM_ONLYTEXT :
+			this.className = 'TB_Button_Off';
+			break ;
+		case FCK_TOOLBARITEM_ICONTEXT :
+			this.className='SC_Field' ;
+			break ;
+	}
+}
+
+function FCKSpecialCombo_OnClick( e )
+{
+	// For Mozilla we must stop the event propagation to avoid it hiding
+	// the panel because of a click outside of it.
+//	if ( e )
+//	{
+//		e.stopPropagation() ;
+//		FCKPanelEventHandlers.OnDocumentClick( e ) ;
+//	}
+
+	var oSpecialCombo = this.SpecialCombo ;
+
+	if ( oSpecialCombo.Enabled )
+	{
+		var oPanel			= oSpecialCombo._Panel ;
+		var oPanelBox		= oSpecialCombo._PanelBox ;
+		var oItemsHolder	= oSpecialCombo._ItemsHolderEl ;
+		var iMaxHeight		= oSpecialCombo.PanelMaxHeight ;
+
+		if ( oSpecialCombo.OnBeforeClick )
+			oSpecialCombo.OnBeforeClick( oSpecialCombo ) ;
+
+		// This is a tricky thing. We must call the "Load" function, otherwise
+		// it will not be possible to retrieve "oItemsHolder.offsetHeight" (IE only).
+		if ( FCKBrowserInfo.IsIE )
+			oPanel.Preload( 0, this.offsetHeight, this ) ;
+
+		if ( oItemsHolder.offsetHeight > iMaxHeight )
+//		{
+			oPanelBox.style.height = iMaxHeight + 'px' ;
+
+//			if ( FCKBrowserInfo.IsGecko )
+//				oPanelBox.style.overflow = '-moz-scrollbars-vertical' ;
+//		}
+		else
+			oPanelBox.style.height = '' ;
+
+//		oPanel.PanelDiv.style.width = oSpecialCombo.PanelWidth + 'px' ;
+
+		oPanel.Show( 0, this.offsetHeight, this ) ;
+	}
+
+//	return false ;
+}
+
+/*
+Sample Combo Field HTML output:
+
+<div class="SC_Field" style="width: 80px;">
+	<table width="100%" cellpadding="0" cellspacing="0" style="table-layout: fixed;">
+		<tbody>
+			<tr>
+				<td class="SC_FieldLabel"><label>&nbsp;</label></td>
+				<td class="SC_FieldButton">&nbsp;</td>
+			</tr>
+		</tbody>
+	</table>
+</div>
+*/
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbar.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbar.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fcktoolbar.js	(revision 795)
@@ -0,0 +1,120 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKToolbar Class: represents a toolbar in the toolbarset. It is a group of
+ * toolbar items.
+ */
+
+var FCKToolbar = function()
+{
+	this.Items = new Array() ;
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( this, FCKToolbar_Cleanup ) ;
+}
+
+FCKToolbar.prototype.AddItem = function( item )
+{
+	return this.Items[ this.Items.length ] = item ;
+}
+
+FCKToolbar.prototype.AddButton = function( name, label, tooltip, iconPathOrStripInfoArrayOrIndex, style, state )
+{
+	if ( typeof( iconPathOrStripInfoArrayOrIndex ) == 'number' )
+		 iconPathOrStripInfoArrayOrIndex = [ this.DefaultIconsStrip, this.DefaultIconSize, iconPathOrStripInfoArrayOrIndex ] ;
+
+	var oButton = new FCKToolbarButtonUI( name, label, tooltip, iconPathOrStripInfoArrayOrIndex, style, state ) ;
+	oButton._FCKToolbar = this ;
+	oButton.OnClick = FCKToolbar_OnItemClick ;
+
+	return this.AddItem( oButton ) ;
+}
+
+function FCKToolbar_OnItemClick( item )
+{
+	var oToolbar = item._FCKToolbar ;
+
+	if ( oToolbar.OnItemClick )
+		oToolbar.OnItemClick( oToolbar, item ) ;
+}
+
+FCKToolbar.prototype.AddSeparator = function()
+{
+	this.AddItem( new FCKToolbarSeparator() ) ;
+}
+
+FCKToolbar.prototype.Create = function( parentElement )
+{
+	if ( this.MainElement )
+	{
+//		this._Cleanup() ;
+		if ( this.MainElement.parentNode )
+			this.MainElement.parentNode.removeChild( this.MainElement ) ;
+		this.MainElement = null ;
+	}
+
+	var oDoc = FCKTools.GetElementDocument( parentElement ) ;
+
+	var e = this.MainElement = oDoc.createElement( 'table' ) ;
+	e.className = 'TB_Toolbar' ;
+	e.style.styleFloat = e.style.cssFloat = ( FCKLang.Dir == 'ltr' ? 'left' : 'right' ) ;
+	e.dir = FCKLang.Dir ;
+	e.cellPadding = 0 ;
+	e.cellSpacing = 0 ;
+
+	this.RowElement = e.insertRow(-1) ;
+
+	// Insert the start cell.
+	var eCell ;
+
+	if ( !this.HideStart )
+	{
+		eCell = this.RowElement.insertCell(-1) ;
+		eCell.appendChild( oDoc.createElement( 'div' ) ).className = 'TB_Start' ;
+	}
+
+	for ( var i = 0 ; i < this.Items.length ; i++ )
+	{
+		this.Items[i].Create( this.RowElement.insertCell(-1) ) ;
+	}
+
+	// Insert the ending cell.
+	if ( !this.HideEnd )
+	{
+		eCell = this.RowElement.insertCell(-1) ;
+		eCell.appendChild( oDoc.createElement( 'div' ) ).className = 'TB_End' ;
+	}
+
+	parentElement.appendChild( e ) ;
+}
+
+function FCKToolbar_Cleanup()
+{
+	this.MainElement = null ;
+	this.RowElement = null ;
+}
+
+var FCKToolbarSeparator = function()
+{}
+
+FCKToolbarSeparator.prototype.Create = function( parentElement )
+{
+	FCKTools.AppendElement( parentElement, 'div' ).className = 'TB_Separator' ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange_gecko.js	(revision 795)
@@ -0,0 +1,71 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Class for working with a selection range, much like the W3C DOM Range, but
+ * it is not intented to be an implementation of the W3C interface.
+ * (Gecko Implementation)
+ */
+
+FCKDomRange.prototype.MoveToSelection = function()
+{
+	this.Release( true ) ;
+
+	var oSel = this.Window.getSelection() ;
+
+	if ( oSel.rangeCount == 1 )
+	{
+		this._Range = FCKW3CRange.CreateFromRange( this.Window.document, oSel.getRangeAt(0) ) ;
+		this._UpdateElementInfo() ;
+	}
+}
+
+FCKDomRange.prototype.Select = function()
+{
+	var oRange = this._Range ;
+	if ( oRange )
+	{
+		var oDocRange = this.Window.document.createRange() ;
+		oDocRange.setStart( oRange.startContainer, oRange.startOffset ) ;
+
+		try
+		{
+			oDocRange.setEnd( oRange.endContainer, oRange.endOffset ) ;
+		}
+		catch ( e )
+		{
+			// There is a bug in Firefox implementation (it would be too easy
+			// otherwhise). The new start can't be after the end (W3C says it can).
+			// So, let's create a new range and collapse it to the desired point.
+			if ( e.toString().Contains( 'NS_ERROR_ILLEGAL_VALUE' ) )
+			{
+				oRange.collapse( true ) ;
+				oDocRange.setEnd( oRange.endContainer, oRange.endOffset ) ;
+			}
+			else
+				throw( e ) ;
+		}
+
+		var oSel = this.Window.getSelection() ;
+		oSel.removeAllRanges() ;
+
+		// We must add a clone otherwise Firefox will have rendering issues.
+		oSel.addRange( oDocRange ) ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckiecleanup.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckiecleanup.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckiecleanup.js	(revision 795)
@@ -0,0 +1,68 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKIECleanup Class: a generic class used as a tool to remove IE leaks.
+ */
+
+var	FCKIECleanup = function( attachWindow )
+{
+	// If the attachWindow already have a cleanup object, jusgt use that one.
+	if ( attachWindow._FCKCleanupObj )
+		this.Items = attachWindow._FCKCleanupObj.Items ;
+	else
+	{
+		this.Items = new Array() ;
+
+		attachWindow._FCKCleanupObj = this ;
+		FCKTools.AddEventListenerEx( attachWindow, 'unload', FCKIECleanup_Cleanup ) ;
+//		attachWindow.attachEvent( 'onunload', FCKIECleanup_Cleanup ) ;
+	}
+}
+
+FCKIECleanup.prototype.AddItem = function( dirtyItem, cleanupFunction )
+{
+	this.Items.push( [ dirtyItem, cleanupFunction ] ) ;
+}
+
+function FCKIECleanup_Cleanup()
+{
+	if ( !this._FCKCleanupObj )
+		return ;
+
+	var aItems = this._FCKCleanupObj.Items ;
+
+	while ( aItems.length > 0 )
+	{
+
+		// It is important to remove from the end to the beginning (pop()),
+		// because of the order things get created in the editor. In the code,
+		// elements in deeper position in the DOM are placed at the end of the
+		// cleanup function, so we must cleanup then first, otherwise IE could
+		// throw some crazy memory errors (IE bug).
+		var oItem = aItems.pop() ;
+		if ( oItem )
+			oItem[1].call( oItem[0] ) ;
+	}
+
+	this._FCKCleanupObj = null ;
+
+	if ( CollectGarbage )
+		CollectGarbage() ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckelementpath.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckelementpath.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckelementpath.js	(revision 795)
@@ -0,0 +1,66 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Manages the DOM anscensors element list of a specific DOM node
+ * (limited to body, inclusive).
+ */
+
+// TODO: Implement IE cleanup.
+
+var FCKElementPath = function( lastNode )
+{
+	var eBlock = null ;
+	var eBlockLimit = null ;
+
+	var aElements = new Array() ;
+
+	var e = lastNode ;
+	while ( e )
+	{
+		if ( e.nodeType == 1 )
+		{
+			if ( !this.LastElement )
+				this.LastElement = e ;
+
+			var sElementName = e.nodeName.toLowerCase() ;
+
+			if ( !eBlockLimit )
+			{
+				if ( !eBlock && FCKListsLib.PathBlockElements[ sElementName ] != null )
+					eBlock = e ;
+
+				if ( FCKListsLib.PathBlockLimitElements[ sElementName ] != null )
+					eBlockLimit = e ;
+			}
+
+			aElements.push( e ) ;
+
+			if ( sElementName == 'body' )
+				break ;
+		}
+		e = e.parentNode ;
+	}
+
+	this.Block = eBlock ;
+	this.BlockLimit = eBlockLimit ;
+	this.Elements = aElements ;
+}
+
+
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckxml_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckxml_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckxml_gecko.js	(revision 795)
@@ -0,0 +1,87 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKXml Class: class to load and manipulate XML files.
+ */
+
+var FCKXml = function()
+{}
+
+FCKXml.prototype.LoadUrl = function( urlToCall )
+{
+	this.Error = false ;
+	var oFCKXml = this ;
+
+	var oXmlHttp = FCKTools.CreateXmlObject( 'XmlHttp' ) ;
+	oXmlHttp.open( "GET", urlToCall, false ) ;
+	oXmlHttp.send( null ) ;
+
+	if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
+		this.DOMDocument = oXmlHttp.responseXML ;
+	else if ( oXmlHttp.status == 0 && oXmlHttp.readyState == 4 )
+		this.DOMDocument = oXmlHttp.responseXML ;
+	else
+		this.DOMDocument = null ;
+
+	if ( this.DOMDocument == null || this.DOMDocument.firstChild == null )
+	{
+		this.Error = true ;
+		if (window.confirm( 'Error loading "' + urlToCall + '"\r\nDo you want to see more info?' ) )
+			alert( 'URL requested: "' + urlToCall + '"\r\n' +
+						'Server response:\r\nStatus: ' + oXmlHttp.status + '\r\n' +
+						'Response text:\r\n' + oXmlHttp.responseText ) ;
+
+	}
+}
+
+FCKXml.prototype.SelectNodes = function( xpath, contextNode )
+{
+	if ( this.Error )
+		return new Array() ;
+
+	var aNodeArray = new Array();
+
+	var xPathResult = this.DOMDocument.evaluate( xpath, contextNode ? contextNode : this.DOMDocument,
+			this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
+	if ( xPathResult )
+	{
+		var oNode = xPathResult.iterateNext() ;
+		while( oNode )
+		{
+			aNodeArray[aNodeArray.length] = oNode ;
+			oNode = xPathResult.iterateNext();
+		}
+	}
+	return aNodeArray ;
+}
+
+FCKXml.prototype.SelectSingleNode = function( xpath, contextNode )
+{
+	if ( this.Error )
+		return null ;
+
+	var xPathResult = this.DOMDocument.evaluate( xpath, contextNode ? contextNode : this.DOMDocument,
+			this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), 9, null);
+
+	if ( xPathResult && xPathResult.singleNodeValue )
+		return xPathResult.singleNodeValue ;
+	else
+		return null ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckw3crange.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckw3crange.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckw3crange.js	(revision 795)
@@ -0,0 +1,448 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This class partially implements the W3C DOM Range for browser that don't
+ * support the standards (like IE):
+ * http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
+ */
+
+var FCKW3CRange = function( parentDocument )
+{
+	this._Document = parentDocument ;
+
+	this.startContainer	= null ;
+	this.startOffset	= null ;
+	this.endContainer	= null ;
+	this.endOffset		= null ;
+	this.collapsed		= true ;
+}
+
+FCKW3CRange.CreateRange = function( parentDocument )
+{
+	// We could opt to use the Range implentation of the browsers. The problem
+	// is that every browser have different bugs on their implementations,
+	// mostly related to different interpretations of the W3C specifications.
+	// So, for now, let's use our implementation and pray for browsers fixings
+	// soon. Otherwise will go crazy on trying to find out workarounds.
+	/*
+	// Get the browser implementation of the range, if available.
+	if ( parentDocument.createRange )
+	{
+		var range = parentDocument.createRange() ;
+		if ( typeof( range.startContainer ) != 'undefined' )
+			return range ;
+	}
+	*/
+	return new FCKW3CRange( parentDocument ) ;
+}
+
+FCKW3CRange.CreateFromRange = function( parentDocument, sourceRange )
+{
+	var range = FCKW3CRange.CreateRange( parentDocument ) ;
+	range.setStart( sourceRange.startContainer, sourceRange.startOffset ) ;
+	range.setEnd( sourceRange.endContainer, sourceRange.endOffset ) ;
+	return range ;
+}
+
+FCKW3CRange.prototype =
+{
+
+	_UpdateCollapsed : function()
+	{
+      this.collapsed = ( this.startContainer == this.endContainer && this.startOffset == this.endOffset ) ;
+	},
+
+	// W3C requires a check for the new position. If it is after the end
+	// boundary, the range should be collapsed to the new start. It seams we
+	// will not need this check for our use of this class so we can ignore it for now.
+	setStart : function( refNode, offset )
+	{
+		this.startContainer	= refNode ;
+		this.startOffset	= offset ;
+
+		if ( !this.endContainer )
+		{
+			this.endContainer	= refNode ;
+			this.endOffset		= offset ;
+		}
+
+		this._UpdateCollapsed() ;
+	},
+
+	// W3C requires a check for the new position. If it is before the start
+	// boundary, the range should be collapsed to the new end. It seams we
+	// will not need this check for our use of this class so we can ignore it for now.
+	setEnd : function( refNode, offset )
+	{
+		this.endContainer	= refNode ;
+		this.endOffset		= offset ;
+
+		if ( !this.startContainer )
+		{
+			this.startContainer	= refNode ;
+			this.startOffset	= offset ;
+		}
+
+		this._UpdateCollapsed() ;
+	},
+
+	setStartAfter : function( refNode )
+	{
+		this.setStart( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) + 1 ) ;
+	},
+
+	setStartBefore : function( refNode )
+	{
+		this.setStart( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) ) ;
+	},
+
+	setEndAfter : function( refNode )
+	{
+		this.setEnd( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) + 1 ) ;
+	},
+
+	setEndBefore : function( refNode )
+	{
+		this.setEnd( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) ) ;
+	},
+
+	collapse : function( toStart )
+	{
+		if ( toStart )
+		{
+			this.endContainer	= this.startContainer ;
+			this.endOffset		= this.startOffset ;
+		}
+		else
+		{
+			this.startContainer	= this.endContainer ;
+			this.startOffset	= this.endOffset ;
+		}
+
+		this.collapsed = true ;
+	},
+
+	selectNodeContents : function( refNode )
+	{
+		this.setStart( refNode, 0 ) ;
+		this.setEnd( refNode, refNode.nodeType == 3 ? refNode.data.length : refNode.childNodes.length ) ;
+	},
+
+	insertNode : function( newNode )
+	{
+		var startContainer = this.startContainer ;
+		var startOffset = this.startOffset ;
+
+		// If we are in a text node.
+		if ( startContainer.nodeType == 3 )
+		{
+			startContainer.splitText( startOffset ) ;
+
+			// Check if it is necessary to update the end boundary.
+			if ( startContainer == this.endContainer )
+				this.setEnd( startContainer.nextSibling, this.endOffset - this.startOffset ) ;
+
+			// Insert the new node it after the text node.
+			FCKDomTools.InsertAfterNode( startContainer, newNode ) ;
+
+			return ;
+		}
+		else
+		{
+			// Simply insert the new node before the current start node.
+			startContainer.insertBefore( newNode, startContainer.childNodes[ startOffset ] || null ) ;
+
+			// Check if it is necessary to update the end boundary.
+			if ( startContainer == this.endContainer )
+			{
+				this.endOffset++ ;
+				this.collapsed = false ;
+			}
+		}
+	},
+
+	deleteContents : function()
+	{
+		if ( this.collapsed )
+			return ;
+
+		this._ExecContentsAction( 0 ) ;
+	},
+
+	extractContents : function()
+	{
+		var docFrag = new FCKDocumentFragment( this._Document ) ;
+
+		if ( !this.collapsed )
+			this._ExecContentsAction( 1, docFrag ) ;
+
+		return docFrag ;
+	},
+
+	// The selection may be lost when clonning (due to the splitText() call).
+	cloneContents : function()
+	{
+		var docFrag = new FCKDocumentFragment( this._Document ) ;
+
+		if ( !this.collapsed )
+			this._ExecContentsAction( 2, docFrag ) ;
+
+		return docFrag ;
+	},
+
+	_ExecContentsAction : function( action, docFrag )
+	{
+		var startNode	= this.startContainer ;
+		var endNode		= this.endContainer ;
+
+		var startOffset	= this.startOffset ;
+		var endOffset	= this.endOffset ;
+
+		var removeStartNode	= false ;
+		var removeEndNode	= false ;
+
+		// Check the start and end nodes and make the necessary removals or changes.
+
+		// Start from the end, otherwise DOM mutations (splitText) made in the
+		// start boundary may interfere on the results here.
+
+		// For text containers, we must simply split the node and point to the
+		// second part. The removal will be handled by the rest of the code .
+		if ( endNode.nodeType == 3 )
+			endNode = endNode.splitText( endOffset ) ;
+		else
+		{
+			// If the end container has children and the offset is pointing
+			// to a child, then we should start from it.
+			if ( endNode.childNodes.length > 0 )
+			{
+				// If the offset points after the last node.
+				if ( endOffset > endNode.childNodes.length - 1 )
+				{
+					// Let's create a temporary node and mark it for removal.
+					endNode = FCKDomTools.InsertAfterNode( endNode.lastChild, this._Document.createTextNode('') ) ;
+					removeEndNode = true ;
+				}
+				else
+					endNode = endNode.childNodes[ endOffset ] ;
+			}
+		}
+
+		// For text containers, we must simply split the node. The removal will
+		// be handled by the rest of the code .
+		if ( startNode.nodeType == 3 )
+		{
+			startNode.splitText( startOffset ) ;
+
+			// In cases the end node is the same as the start node, the above
+			// splitting will also split the end, so me must move the end to
+			// the second part of the split.
+			if ( startNode == endNode )
+				endNode = startNode.nextSibling ;
+		}
+		else
+		{
+			// If the start container has children and the offset is pointing
+			// to a child, then we should start from its previous sibling.
+			if ( startNode.childNodes.length > 0 &&  startOffset <= startNode.childNodes.length - 1 )
+			{
+				// If the offset points to the first node, we don't have a
+				// sibling, so let's use the first one, but mark it for removal.
+				if ( startOffset == 0 )
+				{
+					// Let's create a temporary node and mark it for removal.
+					startNode = startNode.insertBefore( this._Document.createTextNode(''), startNode.firstChild ) ;
+					removeStartNode = true ;
+				}
+				else
+					startNode = startNode.childNodes[ startOffset ].previousSibling ;
+			}
+		}
+
+		// Get the parent nodes tree for the start and end boundaries.
+		var startParents	= FCKDomTools.GetParents( startNode ) ;
+		var endParents		= FCKDomTools.GetParents( endNode ) ;
+
+		// Compare them, to find the top most siblings.
+		var i, topStart, topEnd ;
+
+		for ( i = 0 ; i < startParents.length ; i++ )
+		{
+			topStart	= startParents[i] ;
+			topEnd		= endParents[i] ;
+
+			// The compared nodes will match until we find the top most
+			// siblings (different nodes that have the same parent).
+			// "i" will hold the index in the parants array for the top
+			// most element.
+			if ( topStart != topEnd )
+				break ;
+		}
+
+		var clone, levelStartNode, levelClone, currentNode, currentSibling ;
+
+		if ( docFrag )
+			clone = docFrag.RootNode ;
+
+		// Remove all successive sibling nodes for every node in the
+		// startParents tree.
+		for ( var j = i ; j < startParents.length ; j++ )
+		{
+			levelStartNode = startParents[j] ;
+
+			// For Extract and Clone, we must clone this level.
+			if ( clone && levelStartNode != startNode )		// action = 0 = Delete
+				levelClone = clone.appendChild( levelStartNode.cloneNode( levelStartNode == startNode ) ) ;
+
+			currentNode = levelStartNode.nextSibling ;
+
+			while( currentNode )
+			{
+				// Stop processing when the current node matches a node in the
+				// endParents tree or if it is the endNode.
+				if ( currentNode == endParents[j] || currentNode == endNode )
+					break ;
+
+				// Cache the next sibling.
+				currentSibling = currentNode.nextSibling ;
+
+				// If clonning, just clone it.
+				if ( action == 2 )	// 2 = Clone
+					clone.appendChild( currentNode.cloneNode( true ) ) ;
+				else
+				{
+					// Both Delete and Extract will remove the node.
+					currentNode.parentNode.removeChild( currentNode ) ;
+
+					// When Extracting, move the removed node to the docFrag.
+					if ( action == 1 )	// 1 = Extract
+						clone.appendChild( currentNode ) ;
+				}
+
+				currentNode = currentSibling ;
+			}
+
+			if ( clone )
+				clone = levelClone ;
+		}
+
+		if ( docFrag )
+			clone = docFrag.RootNode ;
+
+		// Remove all previous sibling nodes for every node in the
+		// endParents tree.
+		for ( var k = i ; k < endParents.length ; k++ )
+		{
+			levelStartNode = endParents[k] ;
+
+			// For Extract and Clone, we must clone this level.
+			if ( action > 0 && levelStartNode != endNode )		// action = 0 = Delete
+				levelClone = clone.appendChild( levelStartNode.cloneNode( levelStartNode == endNode ) ) ;
+
+			// The processing of siblings may have already been done by the parent.
+			if ( !startParents[k] || levelStartNode.parentNode != startParents[k].parentNode )
+			{
+				currentNode = levelStartNode.previousSibling ;
+
+				while( currentNode )
+				{
+					// Stop processing when the current node matches a node in the
+					// startParents tree or if it is the startNode.
+					if ( currentNode == startParents[k] || currentNode == startNode )
+						break ;
+
+					// Cache the next sibling.
+					currentSibling = currentNode.previousSibling ;
+
+					// If clonning, just clone it.
+					if ( action == 2 )	// 2 = Clone
+						clone.insertBefore( currentNode.cloneNode( true ), clone.firstChild ) ;
+					else
+					{
+						// Both Delete and Extract will remove the node.
+						currentNode.parentNode.removeChild( currentNode ) ;
+
+						// When Extracting, mode the removed node to the docFrag.
+						if ( action == 1 )	// 1 = Extract
+							clone.insertBefore( currentNode, clone.firstChild ) ;
+					}
+
+					currentNode = currentSibling ;
+				}
+			}
+
+			if ( clone )
+				clone = levelClone ;
+		}
+
+		if ( action == 2 )		// 2 = Clone.
+		{
+			// No changes in the DOM should be done, so fix the split text (if any).
+
+			var startTextNode = this.startContainer ;
+			if ( startTextNode.nodeType == 3 )
+			{
+				startTextNode.data += startTextNode.nextSibling.data ;
+				startTextNode.parentNode.removeChild( startTextNode.nextSibling ) ;
+			}
+
+			var endTextNode = this.endContainer ;
+			if ( endTextNode.nodeType == 3 && endTextNode.nextSibling )
+			{
+				endTextNode.data += endTextNode.nextSibling.data ;
+				endTextNode.parentNode.removeChild( endTextNode.nextSibling ) ;
+			}
+		}
+		else
+		{
+			// Collapse the range.
+
+			// If a node has been partially selected, collapse the range between
+			// topStart and topEnd. Otherwise, simply collapse it to the start. (W3C specs).
+			if ( topStart && topEnd && ( startNode.parentNode != topStart.parentNode || endNode.parentNode != topEnd.parentNode ) )
+				this.setStart( topEnd.parentNode, FCKDomTools.GetIndexOf( topEnd ) ) ;
+
+			// Collapse it to the start.
+			this.collapse( true ) ;
+		}
+
+		// Cleanup any marked node.
+		if( removeStartNode )
+			startNode.parentNode.removeChild( startNode ) ;
+
+		if( removeEndNode && endNode.parentNode )
+			endNode.parentNode.removeChild( endNode ) ;
+	},
+
+	cloneRange : function()
+	{
+		return FCKW3CRange.CreateFromRange( this._Document, this ) ;
+	},
+
+	toString : function()
+	{
+		var docFrag = this.cloneContents() ;
+
+		var tmpDiv = this._Document.createElement( 'div' ) ;
+		docFrag.AppendTo( tmpDiv ) ;
+
+		return tmpDiv.textContent || tmpDiv.innerText ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdomrange_ie.js	(revision 795)
@@ -0,0 +1,149 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Class for working with a selection range, much like the W3C DOM Range, but
+ * it is not intented to be an implementation of the W3C interface.
+ * (IE Implementation)
+ */
+
+FCKDomRange.prototype.MoveToSelection = function()
+{
+	this.Release( true ) ;
+
+	this._Range = new FCKW3CRange( this.Window.document ) ;
+
+	var oSel = this.Window.document.selection ;
+
+	if ( oSel.type != 'Control' )
+	{
+		// Set the start boundary.
+		eMarker = this._GetSelectionMarkerTag( true ) ;
+		this._Range.setStart( eMarker.parentNode, FCKDomTools.GetIndexOf( eMarker ) ) ;
+		eMarker.parentNode.removeChild( eMarker ) ;
+
+		// Set the end boundary.
+		var eMarker = this._GetSelectionMarkerTag( false ) ;
+		this._Range.setEnd( eMarker.parentNode, FCKDomTools.GetIndexOf( eMarker ) ) ;
+		eMarker.parentNode.removeChild( eMarker ) ;
+
+		this._UpdateElementInfo() ;
+	}
+	else
+	{
+		var oControl = oSel.createRange().item(0) ;
+
+		if ( oControl )
+		{
+			this._Range.setStartBefore( oControl ) ;
+			this._Range.setEndAfter( oControl ) ;
+			this._UpdateElementInfo() ;
+		}
+	}
+}
+
+FCKDomRange.prototype.Select = function()
+{
+	if ( this._Range )
+	{
+		var bIsCollapsed = this.CheckIsCollapsed() ;
+
+		// Create marker tags for the start and end boundaries.
+		var eStartMarker	= this._GetRangeMarkerTag( true ) ;
+
+		if ( !bIsCollapsed )
+			var eEndMarker	= this._GetRangeMarkerTag( false ) ;
+
+		// Create the main range which will be used for the selection.
+		var oIERange = this.Window.document.body.createTextRange() ;
+
+		// Position the range at the start boundary.
+		oIERange.moveToElementText( eStartMarker ) ;
+		oIERange.moveStart( 'character', 1 ) ;
+
+		if ( !bIsCollapsed )
+		{
+			// Create a tool range for the end.
+			var oIERangeEnd = this.Window.document.body.createTextRange() ;
+
+			// Position the tool range at the end.
+			oIERangeEnd.moveToElementText( eEndMarker ) ;
+
+			// Move the end boundary of the main range to match the tool range.
+			oIERange.setEndPoint( 'EndToEnd', oIERangeEnd ) ;
+			oIERange.moveEnd( 'character', -1 ) ;
+		}
+
+		// Remove the markers (reset the position, because of the changes in the DOM tree).
+		this._Range.setStartBefore( eStartMarker ) ;
+		eStartMarker.parentNode.removeChild( eStartMarker ) ;
+
+		if ( bIsCollapsed )
+		{
+			// The following trick is needed so IE makes collapsed selections
+			// inside empty blocks visible (expands the block).
+			try
+			{
+				oIERange.pasteHTML('&nbsp;') ;
+				oIERange.moveStart( 'character', -1 ) ;
+			}
+			catch (e){}
+			oIERange.select() ;
+			oIERange.pasteHTML('') ;
+		}
+		else
+		{
+			this._Range.setEndBefore( eEndMarker ) ;
+			eEndMarker.parentNode.removeChild( eEndMarker ) ;
+			oIERange.select() ;
+		}
+	}
+}
+
+FCKDomRange.prototype._GetSelectionMarkerTag = function( toStart )
+{
+	// Get a range for the start boundary.
+	var oRange = this.Window.document.selection.createRange() ;
+	oRange.collapse( toStart === true ) ;
+
+	// Paste a marker element at the collapsed range and get it from the DOM.
+	var sMarkerId = 'fck_dom_range_temp_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000) ;
+	oRange.pasteHTML( '<span id="' + sMarkerId + '"></span>' ) ;
+	return this.Window.document.getElementById( sMarkerId ) ;
+}
+
+FCKDomRange.prototype._GetRangeMarkerTag = function( toStart )
+{
+	// Get a range for the start boundary.
+	var oRange = this._Range ;
+
+	// insertNode() will add the node at the beginning of the Range, updating
+	// the endOffset if necessary. So, we can work with the current range in this case.
+	if ( !toStart )
+	{
+		oRange = oRange.cloneRange() ;
+		oRange.collapse( toStart === true ) ;
+	}
+
+	var eSpan = this.Window.document.createElement( 'span' ) ;
+	eSpan.innerHTML = '&nbsp;' ;
+	oRange.insertNode( eSpan ) ;
+
+	return eSpan ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdocumentfragment_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdocumentfragment_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdocumentfragment_gecko.js	(revision 795)
@@ -0,0 +1,46 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is a generic Document Fragment object. It is not intended to provide
+ * the W3C implementation, but is a way to fix the missing of a real Document
+ * Fragment in IE (where document.createDocumentFragment() returns a normal
+ * document instead), giving a standard interface for it.
+ * (IE Implementation)
+ */
+
+var FCKDocumentFragment = function( parentDocument, baseDocFrag )
+{
+	this.RootNode = baseDocFrag || parentDocument.createDocumentFragment() ;
+}
+
+FCKDocumentFragment.prototype =
+{
+
+	// Append the contents of this Document Fragment to another element.
+	AppendTo : function( targetNode )
+	{
+		targetNode.appendChild( this.RootNode ) ;
+	},
+
+	InsertAfterNode : function( existingNode )
+	{
+		FCKDomTools.InsertAfterNode( existingNode, this.RootNode ) ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstylesloader.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstylesloader.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstylesloader.js	(revision 795)
@@ -0,0 +1,88 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStylesLoader Class: this class define objects that are responsible
+ * for loading the styles defined in the XML file.
+ */
+
+var FCKStylesLoader = function()
+{
+	this.Styles = new Object() ;
+	this.StyleGroups = new Object() ;
+	this.Loaded = false ;
+	this.HasObjectElements = false ;
+}
+
+FCKStylesLoader.prototype.Load = function( stylesXmlUrl )
+{
+	// Load the XML file into a FCKXml object.
+	var oXml = new FCKXml() ;
+	oXml.LoadUrl( stylesXmlUrl ) ;
+
+	// Get the "Style" nodes defined in the XML file.
+	var aStyleNodes = oXml.SelectNodes( 'Styles/Style' ) ;
+
+	// Add each style to our "Styles" collection.
+	for ( var i = 0 ; i < aStyleNodes.length ; i++ )
+	{
+		var sElement = aStyleNodes[i].attributes.getNamedItem('element').value.toUpperCase() ;
+
+		// Create the style definition object.
+		var oStyleDef = new FCKStyleDef( aStyleNodes[i].attributes.getNamedItem('name').value, sElement ) ;
+
+		if ( oStyleDef.IsObjectElement )
+			this.HasObjectElements = true ;
+
+		// Get the attributes defined for the style (if any).
+		var aAttNodes = oXml.SelectNodes( 'Attribute', aStyleNodes[i] ) ;
+
+		// Add the attributes to the style definition object.
+		for ( var j = 0 ; j < aAttNodes.length ; j++ )
+		{
+			var sAttName	= aAttNodes[j].attributes.getNamedItem('name').value ;
+			var sAttValue	= aAttNodes[j].attributes.getNamedItem('value').value ;
+
+			// IE changes the "style" attribute value when applied to an element
+			// so we must get the final resulting value (for comparision issues).
+			if ( sAttName.toLowerCase() == 'style' )
+			{
+				var oTempE = document.createElement( 'SPAN' ) ;
+				oTempE.style.cssText = sAttValue ;
+				sAttValue = oTempE.style.cssText ;
+			}
+
+			oStyleDef.AddAttribute( sAttName, sAttValue ) ;
+		}
+
+		// Add the style to the "Styles" collection using it's name as the key.
+		this.Styles[ oStyleDef.Name ] = oStyleDef ;
+
+		// Add the style to the "StyleGroups" collection.
+		var aGroup = this.StyleGroups[sElement] ;
+		if ( aGroup == null )
+		{
+			this.StyleGroups[sElement] = new Array() ;
+			aGroup = this.StyleGroups[sElement] ;
+		}
+		aGroup[aGroup.length] = oStyleDef ;
+	}
+
+	this.Loaded = true ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckeditingarea.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckeditingarea.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckeditingarea.js	(revision 795)
@@ -0,0 +1,253 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKEditingArea Class: renders an editable area.
+ */
+
+/**
+ * @constructor
+ * @param {String} targetElement The element that will hold the editing area. Any child element present in the target will be deleted.
+ */
+var FCKEditingArea = function( targetElement )
+{
+	this.TargetElement = targetElement ;
+	this.Mode = FCK_EDITMODE_WYSIWYG ;
+
+	if ( FCK.IECleanup )
+		FCK.IECleanup.AddItem( this, FCKEditingArea_Cleanup ) ;
+}
+
+
+/**
+ * @param {String} html The complete HTML for the page, including DOCTYPE and the <html> tag.
+ */
+FCKEditingArea.prototype.Start = function( html, secondCall )
+{
+	var eTargetElement	= this.TargetElement ;
+	var oTargetDocument	= FCKTools.GetElementDocument( eTargetElement ) ;
+
+	// Remove all child nodes from the target.
+	while( eTargetElement.childNodes.length > 0 )
+		eTargetElement.removeChild( eTargetElement.childNodes[0] ) ;
+
+	if ( this.Mode == FCK_EDITMODE_WYSIWYG )
+	{
+		// Create the editing area IFRAME.
+		var oIFrame = this.IFrame = oTargetDocument.createElement( 'iframe' ) ;
+		oIFrame.src = 'javascript:void(0)' ;
+		oIFrame.frameBorder = 0 ;
+		oIFrame.width = oIFrame.height = '100%' ;
+
+		// Append the new IFRAME to the target.
+		eTargetElement.appendChild( oIFrame ) ;
+
+		// IE has a bug with the <base> tag... it must have a </base> closer,
+		// otherwise the all sucessive tags will be set as children nodes of the <base>.
+		if ( FCKBrowserInfo.IsIE )
+			html = html.replace( /(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi, '$1></base>' ) ;
+		else if ( !secondCall )
+		{
+			// If nothing in the body, place a BOGUS tag so the cursor will appear.
+			if ( FCKBrowserInfo.IsGecko )
+				html = html.replace( /(<body[^>]*>)\s*(<\/body>)/i, '$1' + GECKO_BOGUS + '$2' ) ;
+
+			// Gecko moves some tags out of the body to the head, so we must use
+			// innerHTML to set the body contents (SF BUG 1526154).
+
+			// Extract the BODY contents from the html.
+			var oMatch = html.match( FCKRegexLib.BodyContents ) ;
+
+			if ( oMatch )
+			{
+				html =
+					oMatch[1] +					// This is the HTML until the <body...> tag, inclusive.
+					'&nbsp;' +
+					oMatch[3] ;					// This is the HTML from the </body> tag, inclusive.
+
+				this._BodyHTML = oMatch[2] ;	// This is the BODY tag contents.
+			}
+			else
+				this._BodyHTML = html ;			// Invalid HTML input.
+		}
+
+		// Get the window and document objects used to interact with the newly created IFRAME.
+		this.Window = oIFrame.contentWindow ;
+
+		// IE: Avoid JavaScript errors thrown by the editing are source (like tags events).
+		// TODO: This error handler is not being fired.
+		// this.Window.onerror = function() { alert( 'Error!' ) ; return true ; }
+
+		var oDoc = this.Document = this.Window.document ;
+
+		oDoc.open() ;
+		oDoc.write( html ) ;
+		oDoc.close() ;
+
+		// Firefox 1.0.x is buggy... ohh yes... so let's do it two times and it
+		// will magicaly work.
+		if ( FCKBrowserInfo.IsGecko10 && !secondCall )
+		{
+			this.Start( html, true ) ;
+			return ;
+		}
+
+		this.Window._FCKEditingArea = this ;
+
+		// FF 1.0.x is buggy... we must wait a lot to enable editing because
+		// sometimes the content simply disappears, for example when pasting
+		// "bla1!<img src='some_url'>!bla2" in the source and then switching
+		// back to design.
+		if ( FCKBrowserInfo.IsGecko10 )
+			this.Window.setTimeout( FCKEditingArea_CompleteStart, 500 ) ;
+		else
+			FCKEditingArea_CompleteStart.call( this.Window ) ;
+	}
+	else
+	{
+		var eTextarea = this.Textarea = oTargetDocument.createElement( 'textarea' ) ;
+		eTextarea.className = 'SourceField' ;
+		eTextarea.dir = 'ltr' ;
+		eTextarea.style.width = eTextarea.style.height = '100%' ;
+		eTextarea.style.border = 'none' ;
+		eTargetElement.appendChild( eTextarea ) ;
+
+		eTextarea.value = html  ;
+
+		// Fire the "OnLoad" event.
+		FCKTools.RunFunction( this.OnLoad ) ;
+	}
+}
+
+// "this" here is FCKEditingArea.Window
+function FCKEditingArea_CompleteStart()
+{
+	// Of Firefox, the DOM takes a little to become available. So we must wait for it in a loop.
+	if ( !this.document.body )
+	{
+		this.setTimeout( FCKEditingArea_CompleteStart, 50 ) ;
+		return ;
+	}
+
+	var oEditorArea = this._FCKEditingArea ;
+	oEditorArea.MakeEditable() ;
+
+	// Fire the "OnLoad" event.
+	FCKTools.RunFunction( oEditorArea.OnLoad ) ;
+}
+
+FCKEditingArea.prototype.MakeEditable = function()
+{
+	var oDoc = this.Document ;
+
+	if ( FCKBrowserInfo.IsIE )
+	{
+		oDoc.body.contentEditable = true ;
+
+		/* The following commands don't throw errors, but have no effect.
+		oDoc.execCommand( 'AutoDetect', false, false ) ;
+		oDoc.execCommand( 'KeepSelection', false, true ) ;
+		*/
+	}
+	else
+	{
+		try
+		{
+			// Disable Firefox 2 Spell Checker.
+			oDoc.body.spellcheck = ( this.FFSpellChecker !== false ) ;
+
+			if ( this._BodyHTML )
+			{
+				oDoc.body.innerHTML = this._BodyHTML ;
+				this._BodyHTML = null ;
+			}
+
+			oDoc.designMode = 'on' ;
+
+			// Tell Gecko to use or not the <SPAN> tag for the bold, italic and underline.
+			try
+			{
+				oDoc.execCommand( 'styleWithCSS', false, FCKConfig.GeckoUseSPAN ) ;
+			}
+			catch (e)
+			{
+				// As evidenced here, useCSS is deprecated in favor of styleWithCSS:
+				// http://www.mozilla.org/editor/midas-spec.html
+				oDoc.execCommand( 'useCSS', false, !FCKConfig.GeckoUseSPAN ) ;
+			}
+
+			// Analysing Firefox 1.5 source code, it seams that there is support for a
+			// "insertBrOnReturn" command. Applying it gives no error, but it doesn't
+			// gives the same behavior that you have with IE. It works only if you are
+			// already inside a paragraph and it doesn't render correctly in the first enter.
+			// oDoc.execCommand( 'insertBrOnReturn', false, false ) ;
+
+			// Tell Gecko (Firefox 1.5+) to enable or not live resizing of objects (by Alfonso Martinez)
+			oDoc.execCommand( 'enableObjectResizing', false, !FCKConfig.DisableObjectResizing ) ;
+
+			// Disable the standard table editing features of Firefox.
+			oDoc.execCommand( 'enableInlineTableEditing', false, !FCKConfig.DisableFFTableHandles ) ;
+		}
+		catch (e) {}
+	}
+}
+
+FCKEditingArea.prototype.Focus = function()
+{
+	try
+	{
+		if ( this.Mode == FCK_EDITMODE_WYSIWYG )
+		{
+			// The following check is important to avoid IE entering in a focus loop. Ref:
+			// http://sourceforge.net/tracker/index.php?func=detail&aid=1567060&group_id=75348&atid=543653
+			if ( FCKBrowserInfo.IsIE && this.Document.hasFocus() )
+				return ;
+
+			if ( FCKBrowserInfo.IsSafari )
+				this.IFrame.focus() ;
+			else
+			{
+				this.Window.focus() ;
+			}
+		}
+		else
+		{
+			var oDoc = FCKTools.GetElementDocument( this.Textarea ) ;
+			if ( (!oDoc.hasFocus || oDoc.hasFocus() ) && oDoc.activeElement == this.Textarea )
+				return ;
+
+			this.Textarea.focus() ;
+		}
+	}
+	catch(e) {}
+}
+
+function FCKEditingArea_Cleanup()
+{
+	this.TargetElement = null ;
+	this.IFrame = null ;
+	this.Document = null ;
+	this.Textarea = null ;
+
+	if ( this.Window )
+	{
+		this.Window._FCKEditingArea = null ;
+		this.Window = null ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckxml_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckxml_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckxml_ie.js	(revision 795)
@@ -0,0 +1,90 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKXml Class: class to load and manipulate XML files.
+ * (IE specific implementation)
+ */
+
+var FCKXml = function()
+{
+	this.Error = false ;
+}
+
+FCKXml.prototype.LoadUrl = function( urlToCall )
+{
+	this.Error = false ;
+
+	var oXmlHttp = FCKTools.CreateXmlObject( 'XmlHttp' ) ;
+
+	if ( !oXmlHttp )
+	{
+		this.Error = true ;
+		return ;
+	}
+
+	oXmlHttp.open( "GET", urlToCall, false ) ;
+
+	oXmlHttp.send( null ) ;
+
+	if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
+		this.DOMDocument = oXmlHttp.responseXML ;
+	else if ( oXmlHttp.status == 0 && oXmlHttp.readyState == 4 )
+	{
+		this.DOMDocument = FCKTools.CreateXmlObject( 'DOMDocument' ) ;
+		this.DOMDocument.async = false ;
+		this.DOMDocument.resolveExternals = false ;
+		this.DOMDocument.loadXML( oXmlHttp.responseText ) ;
+	}
+	else
+	{
+		this.DOMDocument = null ;
+	}
+
+	if ( this.DOMDocument == null || this.DOMDocument.firstChild == null )
+	{
+		this.Error = true ;
+		if (window.confirm( 'Error loading "' + urlToCall + '"\r\nDo you want to see more info?' ) )
+			alert( 'URL requested: "' + urlToCall + '"\r\n' +
+						'Server response:\r\nStatus: ' + oXmlHttp.status + '\r\n' +
+						'Response text:\r\n' + oXmlHttp.responseText ) ;
+	}
+}
+
+FCKXml.prototype.SelectNodes = function( xpath, contextNode )
+{
+	if ( this.Error )
+		return new Array() ;
+
+	if ( contextNode )
+		return contextNode.selectNodes( xpath ) ;
+	else
+		return this.DOMDocument.selectNodes( xpath ) ;
+}
+
+FCKXml.prototype.SelectSingleNode = function( xpath, contextNode )
+{
+	if ( this.Error )
+		return null ;
+
+	if ( contextNode )
+		return contextNode.selectSingleNode( xpath ) ;
+	else
+		return this.DOMDocument.selectSingleNode( xpath ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckkeystrokehandler.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckkeystrokehandler.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckkeystrokehandler.js	(revision 795)
@@ -0,0 +1,136 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Control keyboard keystroke combinations.
+ */
+
+var FCKKeystrokeHandler = function( cancelCtrlDefaults )
+{
+	this.Keystrokes = new Object() ;
+	this.CancelCtrlDefaults = ( cancelCtrlDefaults !== false ) ;
+}
+
+/*
+ * Listen to keystroke events in an element or DOM document object.
+ *		@target: The element or document to listen to keystroke events.
+ */
+FCKKeystrokeHandler.prototype.AttachToElement = function( target )
+{
+	// For newer browsers, it is enough to listen to the keydown event only.
+	// Some browsers instead, don't cancel key events in the keydown, but in the
+	// keypress. So we must do a longer trip in those cases.
+	FCKTools.AddEventListenerEx( target, 'keydown', _FCKKeystrokeHandler_OnKeyDown, this ) ;
+	if ( FCKBrowserInfo.IsGecko10 || FCKBrowserInfo.IsOpera || ( FCKBrowserInfo.IsGecko && FCKBrowserInfo.IsMac ) )
+		FCKTools.AddEventListenerEx( target, 'keypress', _FCKKeystrokeHandler_OnKeyPress, this ) ;
+}
+
+/*
+ * Sets a list of keystrokes. It can receive either a single array or "n"
+ * arguments, each one being an array of 1 or 2 elemenst. The first element
+ * is the keystroke combination, and the second is the value to assign to it.
+ * If the second element is missing, the keystroke definition is removed.
+ */
+FCKKeystrokeHandler.prototype.SetKeystrokes = function()
+{
+	// Look through the arguments.
+	for ( var i = 0 ; i < arguments.length ; i++ )
+	{
+		var keyDef = arguments[i] ;
+
+		if ( typeof( keyDef[0] ) == 'object' )		// It is an array with arrays defining the keystrokes.
+			this.SetKeystrokes.apply( this, keyDef ) ;
+		else
+		{
+			if ( keyDef.length == 1 )		// If it has only one element, removed the keystroke.
+				delete this.Keystrokes[ keyDef[0] ] ;
+			else							// Otherwise add it.
+				this.Keystrokes[ keyDef[0] ] = keyDef[1] === true ? true : keyDef ;
+		}
+	}
+}
+
+function _FCKKeystrokeHandler_OnKeyDown( ev, keystrokeHandler )
+{
+	// Get the key code.
+	var keystroke = ev.keyCode || ev.which ;
+
+	// Combine it with the CTRL, SHIFT and ALT states.
+	var keyModifiers = 0 ;
+
+	if ( ev.ctrlKey || ev.metaKey )
+		keyModifiers += CTRL ;
+
+	if ( ev.shiftKey )
+		keyModifiers += SHIFT ;
+
+	if ( ev.altKey )
+		keyModifiers += ALT ;
+
+	var keyCombination = keystroke + keyModifiers ;
+
+	var cancelIt = keystrokeHandler._CancelIt = false ;
+
+	// Look for its definition availability.
+	var keystrokeValue = keystrokeHandler.Keystrokes[ keyCombination ] ;
+
+//	FCKDebug.Output( 'KeyDown: ' + keyCombination + ' - Value: ' + keystrokeValue ) ;
+
+	// If the keystroke is defined
+	if ( keystrokeValue )
+	{
+		// If the keystroke has been explicetly set to "true" OR calling the
+		// "OnKeystroke" event, it doesn't return "true", the default behavior
+		// must be preserved.
+		if ( keystrokeValue === true || !( keystrokeHandler.OnKeystroke && keystrokeHandler.OnKeystroke.apply( keystrokeHandler, keystrokeValue ) ) )
+			return true ;
+
+		cancelIt = true ;
+	}
+
+	// By default, it will cancel all combinations with the CTRL key only (except positioning keys).
+	if ( cancelIt || ( keystrokeHandler.CancelCtrlDefaults && keyModifiers == CTRL && ( keystroke < 33 || keystroke > 40 ) ) )
+	{
+		keystrokeHandler._CancelIt = true ;
+
+		if ( ev.preventDefault )
+			return ev.preventDefault() ;
+
+		ev.returnValue = false ;
+		ev.cancelBubble = true ;
+		return false ;
+	}
+
+	return true ;
+}
+
+function _FCKKeystrokeHandler_OnKeyPress( ev, keystrokeHandler )
+{
+	if ( keystrokeHandler._CancelIt )
+	{
+//		FCKDebug.Output( 'KeyPress Cancel', 'Red') ;
+
+		if ( ev.preventDefault )
+			return ev.preventDefault() ;
+
+		return false ;
+	}
+
+	return true ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckstyledef.js	(revision 795)
@@ -0,0 +1,59 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleDef Class: represents a single style definition.
+ */
+
+var FCKStyleDef = function( name, element )
+{
+	this.Name = name ;
+	this.Element = element.toUpperCase() ;
+	this.IsObjectElement = FCKRegexLib.ObjectElements.test( this.Element ) ;
+	this.Attributes = new Object() ;
+}
+
+FCKStyleDef.prototype.AddAttribute = function( name, value )
+{
+	this.Attributes[ name ] = value ;
+}
+
+FCKStyleDef.prototype.GetOpenerTag = function()
+{
+	var s = '<' + this.Element ;
+
+	for ( var a in this.Attributes )
+		s += ' ' + a + '="' + this.Attributes[a] + '"' ;
+
+	return s + '>' ;
+}
+
+FCKStyleDef.prototype.GetCloserTag = function()
+{
+	return '</' + this.Element + '>' ;
+}
+
+
+FCKStyleDef.prototype.RemoveFromSelection = function()
+{
+	if ( FCKSelection.GetType() == 'Control' )
+		this._RemoveMe( FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement() ) ;
+	else
+		this._RemoveMe( FCK.ToolbarSet.CurrentInstance.Selection.GetParentElement() ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdocumentfragment_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdocumentfragment_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckdocumentfragment_ie.js	(revision 795)
@@ -0,0 +1,58 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is a generic Document Fragment object. It is not intended to provide
+ * the W3C implementation, but is a way to fix the missing of a real Document
+ * Fragment in IE (where document.createDocumentFragment() returns a normal
+ * document instead), giving a standard interface for it.
+ * (IE Implementation)
+ */
+
+var FCKDocumentFragment = function( parentDocument )
+{
+	this._Document = parentDocument ;
+	this.RootNode = parentDocument.createElement( 'div' ) ;
+}
+
+// Append the contents of this Document Fragment to another node.
+FCKDocumentFragment.prototype =
+{
+
+	AppendTo : function( targetNode )
+	{
+		FCKDomTools.MoveChildren( this.RootNode, targetNode ) ;
+	},
+
+	AppendHtml : function( html )
+	{
+		var eTmpDiv = this._Document.createElement( 'div' ) ;
+		eTmpDiv.innerHTML = html ;
+		FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ;
+	},
+
+	InsertAfterNode : function( existingNode )
+	{
+		var eRoot = this.RootNode ;
+		var eLast ;
+
+		while( ( eLast = eRoot.lastChild ) )
+			FCKDomTools.InsertAfterNode( existingNode, eRoot.removeChild( eLast ) ) ;
+	}
+} ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenublock.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenublock.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/_source/classes/fckmenublock.js	(revision 795)
@@ -0,0 +1,143 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Renders a list of menu items.
+ */
+
+var FCKMenuBlock = function()
+{
+	this._Items	= new Array() ;
+}
+
+
+FCKMenuBlock.prototype.Count = function()
+{
+	return this._Items.length ;
+}
+
+FCKMenuBlock.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled )
+{
+	var oItem = new FCKMenuItem( this, name, label, iconPathOrStripInfoArrayOrIndex, isDisabled ) ;
+
+	oItem.OnClick		= FCKTools.CreateEventListener( FCKMenuBlock_Item_OnClick, this ) ;
+	oItem.OnActivate	= FCKTools.CreateEventListener( FCKMenuBlock_Item_OnActivate, this ) ;
+
+	this._Items.push( oItem ) ;
+
+	return oItem ;
+}
+
+FCKMenuBlock.prototype.AddSeparator = function()
+{
+	this._Items.push( new FCKMenuSeparator() ) ;
+}
+
+FCKMenuBlock.prototype.RemoveAllItems = function()
+{
+	this._Items = new Array() ;
+
+	var eItemsTable = this._ItemsTable ;
+	if ( eItemsTable )
+	{
+		while ( eItemsTable.rows.length > 0 )
+			eItemsTable.deleteRow( 0 ) ;
+	}
+}
+
+FCKMenuBlock.prototype.Create = function( parentElement )
+{
+	if ( !this._ItemsTable )
+	{
+		if ( FCK.IECleanup )
+			FCK.IECleanup.AddItem( this, FCKMenuBlock_Cleanup ) ;
+
+		this._Window = FCKTools.GetElementWindow( parentElement ) ;
+
+		var oDoc = FCKTools.GetElementDocument( parentElement ) ;
+
+		var eTable = parentElement.appendChild( oDoc.createElement( 'table' ) ) ;
+		eTable.cellPadding = 0 ;
+		eTable.cellSpacing = 0 ;
+
+		FCKTools.DisableSelection( eTable ) ;
+
+		var oMainElement = eTable.insertRow(-1).insertCell(-1) ;
+		oMainElement.className = 'MN_Menu' ;
+
+		var eItemsTable = this._ItemsTable = oMainElement.appendChild( oDoc.createElement( 'table' ) ) ;
+		eItemsTable.cellPadding = 0 ;
+		eItemsTable.cellSpacing = 0 ;
+	}
+
+	for ( var i = 0 ; i < this._Items.length ; i++ )
+		this._Items[i].Create( this._ItemsTable ) ;
+}
+
+/* Events */
+
+function FCKMenuBlock_Item_OnClick( clickedItem, menuBlock )
+{
+	FCKTools.RunFunction( menuBlock.OnClick, menuBlock, [ clickedItem ] ) ;
+}
+
+function FCKMenuBlock_Item_OnActivate( menuBlock )
+{
+	var oActiveItem = menuBlock._ActiveItem ;
+
+	if ( oActiveItem && oActiveItem != this )
+	{
+		// Set the focus to this menu block window (to fire OnBlur on opened panels).
+		if ( !FCKBrowserInfo.IsIE && oActiveItem.HasSubMenu && !this.HasSubMenu )
+			menuBlock._Window.focus() ;
+
+		oActiveItem.Deactivate() ;
+	}
+
+	menuBlock._ActiveItem = this ;
+}
+
+function FCKMenuBlock_Cleanup()
+{
+	this._Window = null ;
+	this._ItemsTable = null ;
+}
+
+// ################# //
+
+var FCKMenuSeparator = function()
+{}
+
+FCKMenuSeparator.prototype.Create = function( parentTable )
+{
+	var oDoc = FCKTools.GetElementDocument( parentTable ) ;
+
+	var r = parentTable.insertRow(-1) ;
+
+	var eCell = r.insertCell(-1) ;
+	eCell.className = 'MN_Separator MN_Icon' ;
+
+	eCell = r.insertCell(-1) ;
+	eCell.className = 'MN_Separator' ;
+	eCell.appendChild( oDoc.createElement( 'DIV' ) ).className = 'MN_Separator_Line' ;
+
+	eCell = r.insertCell(-1) ;
+	eCell.className = 'MN_Separator' ;
+	eCell.appendChild( oDoc.createElement( 'DIV' ) ).className = 'MN_Separator_Line' ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash/fck_flash_preview.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash/fck_flash_preview.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash/fck_flash_preview.html	(revision 795)
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Preview page for the Flash dialog window.
+-->
+<html>
+	<head>
+		<title></title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="robots" content="noindex, nofollow">
+		<link href="../common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+		<script language="javascript">
+
+// Sets the Skin CSS
+document.write( '<link href="' + window.parent.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+if ( window.parent.FCKConfig.BaseHref.length > 0 )
+	document.write( '<base href="' + window.parent.FCKConfig.BaseHref + '">' ) ;
+
+window.onload = function()
+{
+	window.parent.SetPreviewElement( document.body ) ;
+}
+
+		</script>
+	</head>
+	<body style="COLOR: #000000; BACKGROUND-COLOR: #ffffff"></body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash/fck_flash.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash/fck_flash.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash/fck_flash.js	(revision 795)
@@ -0,0 +1,288 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Scripts related to the Flash dialog window (see fck_flash.html).
+ */
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'Info', oEditor.FCKLang.DlgInfoTab ) ;
+
+if ( FCKConfig.FlashUpload )
+	window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload ) ;
+
+if ( !FCKConfig.FlashDlgHideAdvanced )
+	window.parent.AddTab( 'Advanced', oEditor.FCKLang.DlgAdvancedTag ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+	ShowE('divInfo'		, ( tabCode == 'Info' ) ) ;
+	ShowE('divUpload'	, ( tabCode == 'Upload' ) ) ;
+	ShowE('divAdvanced'	, ( tabCode == 'Advanced' ) ) ;
+}
+
+// Get the selected flash embed (if available).
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oEmbed ;
+
+if ( oFakeImage )
+{
+	if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckflash') )
+		oEmbed = FCK.GetRealElement( oFakeImage ) ;
+	else
+		oFakeImage = null ;
+}
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Load the selected element information (if any).
+	LoadSelection() ;
+
+	// Show/Hide the "Browse Server" button.
+	GetE('tdBrowse').style.display = FCKConfig.FlashBrowser	? '' : 'none' ;
+
+	// Set the actual uploader URL.
+	if ( FCKConfig.FlashUpload )
+		GetE('frmUpload').action = FCKConfig.FlashUploadURL ;
+
+	window.parent.SetAutoSize( true ) ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( ! oEmbed ) return ;
+
+	var sUrl = GetAttribute( oEmbed, 'src', '' ) ;
+
+	GetE('txtUrl').value    = GetAttribute( oEmbed, 'src', '' ) ;
+	GetE('txtWidth').value  = GetAttribute( oEmbed, 'width', '' ) ;
+	GetE('txtHeight').value = GetAttribute( oEmbed, 'height', '' ) ;
+
+	// Get Advances Attributes
+	GetE('txtAttId').value		= oEmbed.id ;
+	GetE('chkAutoPlay').checked	= GetAttribute( oEmbed, 'play', 'true' ) == 'true' ;
+	GetE('chkLoop').checked		= GetAttribute( oEmbed, 'loop', 'true' ) == 'true' ;
+	GetE('chkMenu').checked		= GetAttribute( oEmbed, 'menu', 'true' ) == 'true' ;
+	GetE('cmbScale').value		= GetAttribute( oEmbed, 'scale', '' ).toLowerCase() ;
+
+	GetE('txtAttTitle').value		= oEmbed.title ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+	{
+		GetE('txtAttClasses').value = oEmbed.getAttribute('className') || '' ;
+		GetE('txtAttStyle').value = oEmbed.style.cssText ;
+	}
+	else
+	{
+		GetE('txtAttClasses').value = oEmbed.getAttribute('class',2) || '' ;
+		GetE('txtAttStyle').value = oEmbed.getAttribute('style',2) ;
+	}
+
+	UpdatePreview() ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	if ( GetE('txtUrl').value.length == 0 )
+	{
+		window.parent.SetSelectedTab( 'Info' ) ;
+		GetE('txtUrl').focus() ;
+
+		alert( oEditor.FCKLang.DlgAlertUrl ) ;
+
+		return false ;
+	}
+
+	if ( !oEmbed )
+	{
+		oEmbed		= FCK.EditorDocument.createElement( 'EMBED' ) ;
+		oFakeImage  = null ;
+	}
+	UpdateEmbed( oEmbed ) ;
+
+	if ( !oFakeImage )
+	{
+		oFakeImage	= oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__Flash', oEmbed ) ;
+		oFakeImage.setAttribute( '_fckflash', 'true', 0 ) ;
+		oFakeImage	= FCK.InsertElementAndGetIt( oFakeImage ) ;
+	}
+	else
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+	oEditor.FCKFlashProcessor.RefreshView( oFakeImage, oEmbed ) ;
+
+	return true ;
+}
+
+function UpdateEmbed( e )
+{
+	SetAttribute( e, 'type'			, 'application/x-shockwave-flash' ) ;
+	SetAttribute( e, 'pluginspage'	, 'http://www.macromedia.com/go/getflashplayer' ) ;
+
+	e.src = GetE('txtUrl').value ;
+	SetAttribute( e, "width" , GetE('txtWidth').value ) ;
+	SetAttribute( e, "height", GetE('txtHeight').value ) ;
+
+	// Advances Attributes
+
+	SetAttribute( e, 'id'	, GetE('txtAttId').value ) ;
+	SetAttribute( e, 'scale', GetE('cmbScale').value ) ;
+
+	SetAttribute( e, 'play', GetE('chkAutoPlay').checked ? 'true' : 'false' ) ;
+	SetAttribute( e, 'loop', GetE('chkLoop').checked ? 'true' : 'false' ) ;
+	SetAttribute( e, 'menu', GetE('chkMenu').checked ? 'true' : 'false' ) ;
+
+	SetAttribute( e, 'title'	, GetE('txtAttTitle').value ) ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+	{
+		SetAttribute( e, 'className', GetE('txtAttClasses').value ) ;
+		e.style.cssText = GetE('txtAttStyle').value ;
+	}
+	else
+	{
+		SetAttribute( e, 'class', GetE('txtAttClasses').value ) ;
+		SetAttribute( e, 'style', GetE('txtAttStyle').value ) ;
+	}
+}
+
+var ePreview ;
+
+function SetPreviewElement( previewEl )
+{
+	ePreview = previewEl ;
+
+	if ( GetE('txtUrl').value.length > 0 )
+		UpdatePreview() ;
+}
+
+function UpdatePreview()
+{
+	if ( !ePreview )
+		return ;
+
+	while ( ePreview.firstChild )
+		ePreview.removeChild( ePreview.firstChild ) ;
+
+	if ( GetE('txtUrl').value.length == 0 )
+		ePreview.innerHTML = '&nbsp;' ;
+	else
+	{
+		var oDoc	= ePreview.ownerDocument || ePreview.document ;
+		var e		= oDoc.createElement( 'EMBED' ) ;
+
+		e.src		= GetE('txtUrl').value ;
+		e.type		= 'application/x-shockwave-flash' ;
+		e.width		= '100%' ;
+		e.height	= '100%' ;
+
+		ePreview.appendChild( e ) ;
+	}
+}
+
+// <embed id="ePreview" src="fck_flash/claims.swf" width="100%" height="100%" style="visibility:hidden" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
+
+function BrowseServer()
+{
+	OpenFileBrowser( FCKConfig.FlashBrowserURL, FCKConfig.FlashBrowserWindowWidth, FCKConfig.FlashBrowserWindowHeight ) ;
+}
+
+function SetUrl( url, width, height )
+{
+	GetE('txtUrl').value = url ;
+
+	if ( width )
+		GetE('txtWidth').value = width ;
+
+	if ( height )
+		GetE('txtHeight').value = height ;
+
+	UpdatePreview() ;
+
+	window.parent.SetSelectedTab( 'Info' ) ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+	switch ( errorNumber )
+	{
+		case 0 :	// No errors
+			alert( 'Your file has been successfully uploaded' ) ;
+			break ;
+		case 1 :	// Custom error
+			alert( customMsg ) ;
+			return ;
+		case 101 :	// Custom warning
+			alert( customMsg ) ;
+			break ;
+		case 201 :
+			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+			break ;
+		case 202 :
+			alert( 'Invalid file type' ) ;
+			return ;
+		case 203 :
+			alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+			return ;
+		default :
+			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+			return ;
+	}
+
+	SetUrl( fileUrl ) ;
+	GetE('frmUpload').reset() ;
+}
+
+var oUploadAllowedExtRegex	= new RegExp( FCKConfig.FlashUploadAllowedExtensions, 'i' ) ;
+var oUploadDeniedExtRegex	= new RegExp( FCKConfig.FlashUploadDeniedExtensions, 'i' ) ;
+
+function CheckUpload()
+{
+	var sFile = GetE('txtUploadFile').value ;
+
+	if ( sFile.length == 0 )
+	{
+		alert( 'Please select a file to upload' ) ;
+		return false ;
+	}
+
+	if ( ( FCKConfig.FlashUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
+		( FCKConfig.FlashUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
+	{
+		OnUploadCompleted( 202 ) ;
+		return false ;
+	}
+
+	return true ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_link.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_link.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_link.html	(revision 795)
@@ -0,0 +1,293 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Link dialog window.
+-->
+<html>
+	<head>
+		<title>Link Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script src="fck_link/fck_link.js" type="text/javascript"></script>
+	</head>
+	<body scroll="no" style="OVERFLOW: hidden">
+		<div id="divInfo" style="DISPLAY: none">
+			<span fckLang="DlgLnkType">Link Type</span><br />
+			<select id="cmbLinkType" onchange="SetLinkType(this.value);">
+				<option value="url" fckLang="DlgLnkTypeURL" selected="selected">URL</option>
+				<option value="anchor" fckLang="DlgLnkTypeAnchor">Anchor in this page</option>
+				<option value="email" fckLang="DlgLnkTypeEMail">E-Mail</option>
+			</select>
+			<br />
+			<br />
+			<div id="divLinkTypeUrl">
+				<table cellspacing="0" cellpadding="0" width="100%" border="0" dir="ltr">
+					<tr>
+						<td nowrap="nowrap">
+							<span fckLang="DlgLnkProto">Protocol</span><br />
+							<select id="cmbLinkProtocol">
+								<option value="http://" selected="selected">http://</option>
+								<option value="https://">https://</option>
+								<option value="ftp://">ftp://</option>
+								<option value="news://">news://</option>
+								<option value="" fckLang="DlgLnkProtoOther">&lt;other&gt;</option>
+							</select>
+						</td>
+						<td nowrap="nowrap">&nbsp;</td>
+						<td nowrap="nowrap" width="100%">
+							<span fckLang="DlgLnkURL">URL</span><br />
+							<input id="txtUrl" style="WIDTH: 100%" type="text" onkeyup="OnUrlChange();" onchange="OnUrlChange();" />
+						</td>
+					</tr>
+				</table>
+				<br />
+				<div id="divBrowseServer">
+				<input type="button" value="Browse Server" fckLang="DlgBtnBrowseServer" onclick="BrowseServer();" />
+				</div>
+			</div>
+			<div id="divLinkTypeAnchor" style="DISPLAY: none" align="center">
+				<div id="divSelAnchor" style="DISPLAY: none">
+					<table cellspacing="0" cellpadding="0" border="0" width="70%">
+						<tr>
+							<td colspan="3">
+								<span fckLang="DlgLnkAnchorSel">Select an Anchor</span>
+							</td>
+						</tr>
+						<tr>
+							<td width="50%">
+								<span fckLang="DlgLnkAnchorByName">By Anchor Name</span><br />
+								<select id="cmbAnchorName" onchange="GetE('cmbAnchorId').value='';" style="WIDTH: 100%">
+									<option value="" selected="selected"></option>
+								</select>
+							</td>
+							<td>&nbsp;&nbsp;&nbsp;</td>
+							<td width="50%">
+								<span fckLang="DlgLnkAnchorById">By Element Id</span><br />
+								<select id="cmbAnchorId" onchange="GetE('cmbAnchorName').value='';" style="WIDTH: 100%">
+									<option value="" selected="selected"></option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+				<div id="divNoAnchor" style="DISPLAY: none">
+					<span fckLang="DlgLnkNoAnchors">&lt;No anchors available in the document&gt;</span>
+				</div>
+			</div>
+			<div id="divLinkTypeEMail" style="DISPLAY: none">
+				<span fckLang="DlgLnkEMail">E-Mail Address</span><br />
+				<input id="txtEMailAddress" style="WIDTH: 100%" type="text" /><br />
+				<span fckLang="DlgLnkEMailSubject">Message Subject</span><br />
+				<input id="txtEMailSubject" style="WIDTH: 100%" type="text" /><br />
+				<span fckLang="DlgLnkEMailBody">Message Body</span><br />
+				<textarea id="txtEMailBody" style="WIDTH: 100%" rows="3" cols="20"></textarea>
+			</div>
+		</div>
+		<div id="divUpload" style="DISPLAY: none">
+			<form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data" action="" onsubmit="return CheckUpload();">
+				<span fckLang="DlgLnkUpload">Upload</span><br />
+				<input id="txtUploadFile" style="WIDTH: 100%" type="file" size="40" name="NewFile" /><br />
+				<br />
+				<input id="btnUpload" type="submit" value="Send it to the Server" fckLang="DlgLnkBtnUpload" />
+				<iframe name="UploadWindow" style="DISPLAY: none" src="javascript:void(0)"></iframe>
+			</form>
+		</div>
+		<div id="divTarget" style="DISPLAY: none">
+			<table cellspacing="0" cellpadding="0" width="100%" border="0">
+				<tr>
+					<td nowrap="nowrap">
+						<span fckLang="DlgLnkTarget">Target</span><br />
+						<select id="cmbTarget" onchange="SetTarget(this.value);">
+							<option value="" fckLang="DlgGenNotSet" selected="selected">&lt;not set&gt;</option>
+							<option value="frame" fckLang="DlgLnkTargetFrame">&lt;frame&gt;</option>
+							<option value="popup" fckLang="DlgLnkTargetPopup">&lt;popup window&gt;</option>
+							<option value="_blank" fckLang="DlgLnkTargetBlank">New Window (_blank)</option>
+							<option value="_top" fckLang="DlgLnkTargetTop">Topmost Window (_top)</option>
+							<option value="_self" fckLang="DlgLnkTargetSelf">Same Window (_self)</option>
+							<option value="_parent" fckLang="DlgLnkTargetParent">Parent Window (_parent)</option>
+						</select>
+					</td>
+					<td>&nbsp;</td>
+					<td id="tdTargetFrame" nowrap="nowrap" width="100%">
+						<span fckLang="DlgLnkTargetFrameName">Target Frame Name</span><br />
+						<input id="txtTargetFrame" style="WIDTH: 100%" type="text" onkeyup="OnTargetNameChange();"
+							onchange="OnTargetNameChange();" />
+					</td>
+					<td id="tdPopupName" style="DISPLAY: none" nowrap="nowrap" width="100%">
+						<span fckLang="DlgLnkPopWinName">Popup Window Name</span><br />
+						<input id="txtPopupName" style="WIDTH: 100%" type="text" />
+					</td>
+				</tr>
+			</table>
+			<br />
+			<table id="tablePopupFeatures" style="DISPLAY: none" cellspacing="0" cellpadding="0" align="center"
+				border="0">
+				<tr>
+					<td>
+						<span fckLang="DlgLnkPopWinFeat">Popup Window Features</span><br />
+						<table cellspacing="0" cellpadding="0" border="0">
+							<tr>
+								<td valign="top" nowrap="nowrap" width="50%">
+									<input id="chkPopupResizable" name="chkFeature" value="resizable" type="checkbox" /><label for="chkPopupResizable" fckLang="DlgLnkPopResize">Resizable</label><br />
+									<input id="chkPopupLocationBar" name="chkFeature" value="location" type="checkbox" /><label for="chkPopupLocationBar" fckLang="DlgLnkPopLocation">Location
+										Bar</label><br />
+									<input id="chkPopupManuBar" name="chkFeature" value="menubar" type="checkbox" /><label for="chkPopupManuBar" fckLang="DlgLnkPopMenu">Menu
+										Bar</label><br />
+									<input id="chkPopupScrollBars" name="chkFeature" value="scrollbars" type="checkbox" /><label for="chkPopupScrollBars" fckLang="DlgLnkPopScroll">Scroll
+										Bars</label>
+								</td>
+								<td></td>
+								<td valign="top" nowrap="nowrap" width="50%">
+									<input id="chkPopupStatusBar" name="chkFeature" value="status" type="checkbox" /><label for="chkPopupStatusBar" fckLang="DlgLnkPopStatus">Status
+										Bar</label><br />
+									<input id="chkPopupToolbar" name="chkFeature" value="toolbar" type="checkbox" /><label for="chkPopupToolbar" fckLang="DlgLnkPopToolbar">Toolbar</label><br />
+									<input id="chkPopupFullScreen" name="chkFeature" value="fullscreen" type="checkbox" /><label for="chkPopupFullScreen" fckLang="DlgLnkPopFullScrn">Full
+										Screen (IE)</label><br />
+									<input id="chkPopupDependent" name="chkFeature" value="dependent" type="checkbox" /><label for="chkPopupDependent" fckLang="DlgLnkPopDependent">Dependent
+										(Netscape)</label>
+								</td>
+							</tr>
+							<tr>
+								<td valign="top" nowrap="nowrap" width="50%">&nbsp;</td>
+								<td></td>
+								<td valign="top" nowrap="nowrap" width="50%"></td>
+							</tr>
+							<tr>
+								<td valign="top">
+									<table cellspacing="0" cellpadding="0" border="0">
+										<tr>
+											<td nowrap="nowrap"><span fckLang="DlgLnkPopWidth">Width</span></td>
+											<td>&nbsp;<input id="txtPopupWidth" type="text" maxlength="4" size="4" /></td>
+										</tr>
+										<tr>
+											<td nowrap="nowrap"><span fckLang="DlgLnkPopHeight">Height</span></td>
+											<td>&nbsp;<input id="txtPopupHeight" type="text" maxlength="4" size="4" /></td>
+										</tr>
+									</table>
+								</td>
+								<td>&nbsp;&nbsp;</td>
+								<td valign="top">
+									<table cellspacing="0" cellpadding="0" border="0">
+										<tr>
+											<td nowrap="nowrap"><span fckLang="DlgLnkPopLeft">Left Position</span></td>
+											<td>&nbsp;<input id="txtPopupLeft" type="text" maxlength="4" size="4" /></td>
+										</tr>
+										<tr>
+											<td nowrap="nowrap"><span fckLang="DlgLnkPopTop">Top Position</span></td>
+											<td>&nbsp;<input id="txtPopupTop" type="text" maxlength="4" size="4" /></td>
+										</tr>
+									</table>
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+			</table>
+		</div>
+		<div id="divAttribs" style="DISPLAY: none">
+			<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+				<tr>
+					<td valign="top" width="50%">
+						<span fckLang="DlgGenId">Id</span><br />
+						<input id="txtAttId" style="WIDTH: 100%" type="text" />
+					</td>
+					<td width="1"></td>
+					<td valign="top">
+						<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+							<tr>
+								<td width="60%">
+									<span fckLang="DlgGenLangDir">Language Direction</span><br />
+									<select id="cmbAttLangDir" style="WIDTH: 100%">
+										<option value="" fckLang="DlgGenNotSet" selected>&lt;not set&gt;</option>
+										<option value="ltr" fckLang="DlgGenLangDirLtr">Left to Right (LTR)</option>
+										<option value="rtl" fckLang="DlgGenLangDirRtl">Right to Left (RTL)</option>
+									</select>
+								</td>
+								<td width="1%">&nbsp;&nbsp;&nbsp;</td>
+								<td nowrap="nowrap"><span fckLang="DlgGenAccessKey">Access Key</span><br />
+									<input id="txtAttAccessKey" style="WIDTH: 100%" type="text" maxlength="1" size="1" />
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+				<tr>
+					<td valign="top" width="50%">
+						<span fckLang="DlgGenName">Name</span><br />
+						<input id="txtAttName" style="WIDTH: 100%" type="text" />
+					</td>
+					<td width="1"></td>
+					<td valign="top">
+						<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+							<tr>
+								<td width="60%">
+									<span fckLang="DlgGenLangCode">Language Code</span><br />
+									<input id="txtAttLangCode" style="WIDTH: 100%" type="text" />
+								</td>
+								<td width="1%">&nbsp;&nbsp;&nbsp;</td>
+								<td nowrap="nowrap">
+									<span fckLang="DlgGenTabIndex">Tab Index</span><br />
+									<input id="txtAttTabIndex" style="WIDTH: 100%" type="text" maxlength="5" size="5" />
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+				<tr>
+					<td valign="top" width="50%">&nbsp;</td>
+					<td width="1"></td>
+					<td valign="top"></td>
+				</tr>
+				<tr>
+					<td valign="top" width="50%">
+						<span fckLang="DlgGenTitle">Advisory Title</span><br />
+						<input id="txtAttTitle" style="WIDTH: 100%" type="text" />
+					</td>
+					<td width="1">&nbsp;&nbsp;&nbsp;</td>
+					<td valign="top">
+						<span fckLang="DlgGenContType">Advisory Content Type</span><br />
+						<input id="txtAttContentType" style="WIDTH: 100%" type="text" />
+					</td>
+				</tr>
+				<tr>
+					<td valign="top">
+						<span fckLang="DlgGenClass">Stylesheet Classes</span><br />
+						<input id="txtAttClasses" style="WIDTH: 100%" type="text" />
+					</td>
+					<td></td>
+					<td valign="top">
+						<span fckLang="DlgGenLinkCharset">Linked Resource Charset</span><br />
+						<input id="txtAttCharSet" style="WIDTH: 100%" type="text" />
+					</td>
+				</tr>
+			</table>
+			<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+				<tr>
+					<td>
+						<span fckLang="DlgGenStyle">Style</span><br />
+						<input id="txtAttStyle" style="WIDTH: 100%" type="text" />
+					</td>
+				</tr>
+			</table>
+		</div>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_form.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_form.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_form.html	(revision 795)
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Form dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.MoveToAncestorNode( 'FORM' ) ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl )
+	{
+		GetE('txtName').value	= oActiveEl.name ;
+		GetE('txtAction').value	= oActiveEl.getAttribute( 'action', 2 ) ;
+		GetE('txtMethod').value	= oActiveEl.method ;
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'FORM' ) ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+		oActiveEl.innerHTML = '&nbsp;' ;
+	}
+
+	oActiveEl.name = GetE('txtName').value ;
+	SetAttribute( oActiveEl, 'action'	, GetE('txtAction').value ) ;
+	oActiveEl.method = GetE('txtMethod').value ;
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table width="100%" style="height: 100%">
+		<tr>
+			<td align="center">
+				<table cellspacing="0" cellpadding="0" width="80%" border="0">
+					<tr>
+						<td>
+							<span fcklang="DlgFormName">Name</span><br />
+							<input style="width: 100%" type="text" id="txtName" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgFormAction">Action</span><br />
+							<input style="width: 100%" type="text" id="txtAction" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgFormMethod">Method</span><br />
+							<select id="txtMethod">
+								<option value="get" selected="selected">GET</option>
+								<option value="post">POST</option>
+							</select>
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_about.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_about.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_about.html	(revision 795)
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * "About" dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCKLang	= oEditor.FCKLang ;
+
+window.parent.AddTab( 'About', FCKLang.DlgAboutAboutTab ) ;
+window.parent.AddTab( 'License', FCKLang.DlgAboutLicenseTab ) ;
+window.parent.AddTab( 'BrowserInfo', FCKLang.DlgAboutBrowserInfoTab ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+	ShowE('divAbout', ( tabCode == 'About' ) ) ;
+	ShowE('divLicense', ( tabCode == 'License' ) ) ;
+	ShowE('divInfo'	, ( tabCode == 'BrowserInfo' ) ) ;
+}
+
+function SendEMail()
+{
+	var eMail = 'mailto:' ;
+	eMail += 'fredck' ;
+	eMail += '@' ;
+	eMail += 'fckeditor' ;
+	eMail += '.' ;
+	eMail += 'net' ;
+
+	window.location = eMail ;
+}
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	window.parent.SetAutoSize( true ) ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<div id="divAbout">
+		<table cellpadding="0" cellspacing="0" border="0" width="100%" style="height: 100%">
+			<tr>
+				<td>
+					<img alt="" src="fck_about/logo_fckeditor.gif" width="236" height="41" align="left" />
+					<table width="80" border="0" cellspacing="0" cellpadding="5" bgcolor="#ffffff" align="right">
+						<tr>
+							<td align="center" nowrap="nowrap" style="border-right: #000000 1px solid; border-top: #000000 1px solid;
+								border-left: #000000 1px solid; border-bottom: #000000 1px solid">
+								<span fcklang="DlgAboutVersion">version</span>
+								<br />
+								<b>2.4.2</b><br />
+								Build 14978</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+			<tr style="height: 100%">
+				<td align="center">
+					&nbsp;<br />
+					<span style="font-size: 14px" dir="ltr">
+						<br />
+						<b><a href="http://www.fckeditor.net/?about" target="_blank" title="Visit the FCKeditor web site">
+							Support <b>Open Source</b> Software</a></b> </span>
+					<br />
+					<br />
+					<br />
+					<span fcklang="DlgAboutInfo">For further information go to</span> <a href="http://www.fckeditor.net/?About"
+						target="_blank">http://www.fckeditor.net/</a>.
+					<br />
+					Copyright &copy; 2003-2007 <a href="#" onclick="SendEMail();">Frederico Caldeira Knabben</a>
+				</td>
+			</tr>
+			<tr>
+				<td align="center">
+					<img alt="" src="fck_about/logo_fredck.gif" width="87" height="36" />
+				</td>
+			</tr>
+		</table>
+	</div>
+	<div id="divLicense" style="display: none">
+			<p>
+				Licensed under the terms of any of the following licenses at your
+				choice:
+			</p>
+			<ul>
+				<li style="margin-bottom:15px">
+					<b>GNU General Public License</b> Version 2 or later (the "GPL")<br />
+					<a href="http://www.gnu.org/licenses/gpl.html" target="_blank">http://www.gnu.org/licenses/gpl.html</a>
+				</li>
+				<li style="margin-bottom:15px">
+					<b>GNU Lesser General Public License</b> Version 2.1 or later (the "LGPL")<br />
+					<a href="http://www.gnu.org/licenses/lgpl.html" target="_blank">http://www.gnu.org/licenses/lgpl.html</a>
+				</li>
+				<li>
+					<b>Mozilla Public License</b> Version 1.1 or later (the "MPL")<br />
+					<a href="http://www.mozilla.org/MPL/MPL-1.1.html" target="_blank">http://www.mozilla.org/MPL/MPL-1.1.html</a>
+			   </li>
+			</ul>
+	</div>
+	<div id="divInfo" style="display: none" dir="ltr">
+		<table align="center" width="80%" border="0">
+			<tr>
+				<td>
+					<script type="text/javascript">
+<!--
+document.write( '<b>User Agent<\/b><br />' + window.navigator.userAgent + '<br /><br />' ) ;
+document.write( '<b>Browser<\/b><br />' + window.navigator.appName + ' ' + window.navigator.appVersion + '<br /><br />' ) ;
+document.write( '<b>Platform<\/b><br />' + window.navigator.platform + '<br /><br />' ) ;
+
+var sUserLang = '?' ;
+
+if ( window.navigator.language )
+	sUserLang = window.navigator.language.toLowerCase() ;
+else if ( window.navigator.userLanguage )
+	sUserLang = window.navigator.userLanguage.toLowerCase() ;
+
+document.write( '<b>User Language<\/b><br />' + sUserLang ) ;
+//-->
+					</script>
+				</td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_anchor.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_anchor.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_anchor.html	(revision 795)
@@ -0,0 +1,227 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Anchor dialog window.
+-->
+<html>
+	<head>
+		<title>Anchor Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script type="text/javascript">
+
+var oEditor	= window.parent.InnerDialogLoaded() ;
+var FCK		= oEditor.FCK ;
+var FCKBrowserInfo = oEditor.FCKBrowserInfo ;
+var FCKTools = oEditor.FCKTools ;
+var FCKRegexLib = oEditor.FCKRegexLib ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oAnchor ;
+
+if ( oFakeImage )
+{
+	if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckanchor') )
+		oAnchor = FCK.GetRealElement( oFakeImage ) ;
+	else
+		oFakeImage = null ;
+}
+
+//Search for a real anchor
+if ( !oFakeImage )
+{
+	oAnchor = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+	if ( oAnchor )
+		FCK.Selection.SelectNode( oAnchor ) ;
+}
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oAnchor )
+		GetE('txtName').value = oAnchor.name ;
+	else
+		oAnchor = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	var sNewName = GetE('txtName').value ;
+
+	// Remove any illegal character in a name attribute:
+	// A name should start with a letter, but the validator passes anyway.
+	sNewName = sNewName.replace( /[^\w-_\.:]/g, '_' ) ;
+
+	if ( sNewName.length == 0 )
+	{
+		// Remove the anchor if the user leaves the name blank
+		if ( oAnchor )
+		{
+			RemoveAnchor() ;
+			return true ;
+		}
+
+		alert( oEditor.FCKLang.DlgAnchorErrorName ) ;
+		return false ;
+	}
+
+	oEditor.FCKUndo.SaveUndoStep() ;
+
+	if ( oAnchor )	// Modifying an existent anchor.
+	{
+		ReadjustLinksToAnchor( oAnchor.name, sNewName );
+
+		// Buggy explorer, bad bad browser. http://alt-tag.com/blog/archives/2006/02/ie-dom-bugs/
+		// Instead of just replacing the .name for the existing anchor (in order to preserve the content), we must remove the .name
+		// and assign .name, although it won't appear until it's specially processed in fckxhtml.js
+
+		// We remove the previous name
+		oAnchor.removeAttribute( 'name' ) ;
+		// Now we set it, but later we must process it specially
+		oAnchor.name = sNewName ;
+
+		return true ;
+	}
+
+	// Create a new anchor preserving the current selection
+	oAnchor = oEditor.FCK.CreateLink( '#' ) ;
+	if ( !oAnchor )
+	{
+		// Nothing was selected, so now just create a normal A
+		oAnchor = oEditor.FCK.CreateElement( 'a' ) ;
+	}
+	else
+	{
+		// Remove the fake href
+		oAnchor.removeAttribute( 'href' ) ;
+	}
+	// Set the name
+	oAnchor.name = sNewName ;
+
+	// IE does require special processing to show the Anchor's image
+	// Opera doesn't allow to select empty anchors
+	if ( FCKBrowserInfo.IsIE || FCKBrowserInfo.IsOpera )
+	{
+		if ( oAnchor.innerHTML != '' )
+		{
+			if ( FCKBrowserInfo.IsIE )
+				oAnchor.className += ' FCK__AnchorC' ;
+		}
+		else
+		{
+			// Create a fake image for both IE and Opera
+			var oImg = oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__Anchor', oAnchor.cloneNode(true) ) ;
+			oImg.setAttribute( '_fckanchor', 'true', 0 ) ;
+
+			oAnchor.parentNode.insertBefore( oImg, oAnchor ) ;
+			oAnchor.parentNode.removeChild( oAnchor ) ;
+		}
+
+	}
+
+	return true ;
+}
+
+// Removes the current anchor from the document
+function RemoveAnchor()
+{
+	// If it's also a link, then just remove the name and exit
+	if ( oAnchor.href.length != 0 )
+	{
+		oAnchor.removeAttribute( 'name' ) ;
+		// Remove temporary class for IE
+		if ( FCKBrowserInfo.IsIE )
+			oAnchor.className = oAnchor.className.replace( FCKRegexLib.FCK_Class, '' ) ;
+		return ;
+	}
+
+	// We need to remove the anchor
+	// If we got a fake image, then just remove it and we're done
+	if ( oFakeImage )
+	{
+		oFakeImage.parentNode.removeChild( oFakeImage ) ;
+		return ;
+	}
+	// Empty anchor, so just remove it
+	if ( oAnchor.innerHTML.length == 0 )
+	{
+		oAnchor.parentNode.removeChild( oAnchor ) ;
+		return ;
+	}
+	// Anchor with content, leave the content
+	FCKTools.RemoveOuterTags( oAnchor ) ;
+}
+
+// Checks all the links in the current page pointing to the current name and changes them to the new name
+function ReadjustLinksToAnchor( sCurrent, sNew )
+{
+	var oDoc = FCK.EditorDocument ;
+
+	var aLinks = oDoc.getElementsByTagName( 'A' ) ;
+
+	var sReference = '#' + sCurrent ;
+	// The url of the document, so we check absolute and partial references.
+	var sFullReference = oDoc.location.href.replace( /(#.*$)/, '') ;
+	sFullReference += sReference ;
+
+	var oLink ;
+	var i = aLinks.length - 1 ;
+	while ( i >= 0 && ( oLink = aLinks[i--] ) )
+	{
+		var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;
+		if ( sHRef == null )
+			sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;
+
+		if ( sHRef == sReference || sHRef == sFullReference )
+		{
+			oLink.href = '#' + sNew ;
+			SetAttribute( oLink, '_fcksavedurl', '#' + sNew ) ;
+		}
+	}
+}
+
+		</script>
+	</head>
+	<body style="OVERFLOW: hidden" scroll="no">
+		<table height="100%" width="100%">
+			<tr>
+				<td align="center">
+					<table border="0" cellpadding="0" cellspacing="0" width="80%">
+						<tr>
+							<td>
+								<span fckLang="DlgAnchorName">Anchor Name</span><BR>
+								<input id="txtName" style="WIDTH: 100%" type="text">
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_replace.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_replace.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_replace.html	(revision 795)
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * "Replace" dialog box window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+function OnLoad()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+	window.parent.SetAutoSize( true ) ;
+
+	oEditor.FCKUndo.SaveUndoStep() ;
+}
+
+function btnStat(frm)
+{
+	document.getElementById('btnReplace').disabled =
+		document.getElementById('btnReplaceAll').disabled =
+			( document.getElementById('txtFind').value.length == 0 ) ;
+}
+
+function ReplaceTextNodes( parentNode, regex, replaceValue, replaceAll, hasFound )
+{
+	for ( var i = 0 ; i < parentNode.childNodes.length ; i++ )
+	{
+		var oNode = parentNode.childNodes[i] ;
+		if ( oNode.nodeType == 3 )
+		{
+			var sReplaced = oNode.nodeValue.replace( regex, replaceValue ) ;
+			if ( oNode.nodeValue != sReplaced )
+			{
+				oNode.nodeValue = sReplaced ;
+				if ( ! replaceAll )
+					return true ;
+				hasFound = true ;
+			}
+		}
+
+		hasFound = ReplaceTextNodes( oNode, regex, replaceValue, replaceAll, hasFound ) ;
+		if ( ! replaceAll && hasFound )
+			return true ;
+	}
+
+	return hasFound ;
+}
+
+function GetRegexExpr()
+{
+	var sExpr = EscapeRegexString( document.getElementById('txtFind').value ) ;
+
+	if ( document.getElementById('chkWord').checked )
+		sExpr = '\\b' + sExpr + '\\b' ;
+
+	return sExpr ;
+}
+
+function GetCase()
+{
+	return ( document.getElementById('chkCase').checked ? '' : 'i' ) ;
+}
+
+function GetReplacement()
+{
+	return document.getElementById('txtReplace').value.replace( /\$/g, '$$$$' ) ;
+}
+
+function EscapeRegexString( str )
+{
+	return str.replace( /[\\\^\$\*\+\?\{\}\.\(\)\!\|\[\]\-]/g, '\\$&' ) ;
+}
+
+function Replace()
+{
+	var oRegex = new RegExp( GetRegexExpr(), GetCase() ) ;
+	if ( !ReplaceTextNodes( oEditor.FCK.EditorDocument.body, oRegex, GetReplacement(), false, false ) )
+		alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+}
+
+function ReplaceAll()
+{
+	var oRegex = new RegExp( GetRegexExpr(), GetCase() + 'g' ) ;
+	if ( !ReplaceTextNodes( oEditor.FCK.EditorDocument.body, oRegex, GetReplacement(), true, false ) )
+		alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+	window.parent.Cancel() ;
+}
+	</script>
+</head>
+<body onload="OnLoad()" style="overflow: hidden">
+	<table cellspacing="3" cellpadding="2" width="100%" border="0">
+		<tr>
+			<td nowrap="nowrap">
+				<label for="txtFind" fcklang="DlgReplaceFindLbl">
+					Find what:</label>
+			</td>
+			<td width="100%">
+				<input id="txtFind" onkeyup="btnStat(this.form)" style="width: 100%" tabindex="1"
+					type="text" />
+			</td>
+			<td>
+				<input id="btnReplace" style="width: 100%" disabled="disabled" onclick="Replace();"
+					type="button" value="Replace" fcklang="DlgReplaceReplaceBtn" />
+			</td>
+		</tr>
+		<tr>
+			<td valign="top" nowrap="nowrap">
+				<label for="txtReplace" fcklang="DlgReplaceReplaceLbl">
+					Replace with:</label>
+			</td>
+			<td valign="top">
+				<input id="txtReplace" style="width: 100%" tabindex="2" type="text" />
+			</td>
+			<td>
+				<input id="btnReplaceAll" disabled="disabled" onclick="ReplaceAll()" type="button"
+					value="Replace All" fcklang="DlgReplaceReplAllBtn" />
+			</td>
+		</tr>
+		<tr>
+			<td valign="bottom" colspan="3">
+				&nbsp;<input id="chkCase" tabindex="3" type="checkbox" /><label for="chkCase" fcklang="DlgReplaceCaseChk">Match
+					case</label>
+				<br />
+				&nbsp;<input id="chkWord" tabindex="4" type="checkbox" /><label for="chkWord" fcklang="DlgReplaceWordChk">Match
+					whole word</label>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_button.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_button.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_button.html	(revision 795)
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Button dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Button Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl && oActiveEl.tagName.toUpperCase() == "INPUT" && ( oActiveEl.type == "button" || oActiveEl.type == "submit" || oActiveEl.type == "reset" ) )
+	{
+		GetE('txtName').value	= oActiveEl.name ;
+		GetE('txtValue').value	= oActiveEl.value ;
+		GetE('txtType').value	= oActiveEl.type ;
+
+		GetE('txtType').disabled = true ;
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+		oActiveEl.type = GetE('txtType').value ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+	}
+
+	oActiveEl.name = GetE('txtName').value ;
+	SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table width="100%" style="height: 100%">
+		<tr>
+			<td align="center">
+				<table border="0" cellpadding="0" cellspacing="0" width="80%">
+					<tr>
+						<td colspan="">
+							<span fcklang="DlgCheckboxName">Name</span><br />
+							<input type="text" size="20" id="txtName" style="width: 100%" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgButtonText">Text (Value)</span><br />
+							<input type="text" id="txtValue" style="width: 100%" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgButtonType">Type</span><br />
+							<select id="txtType">
+								<option fcklang="DlgButtonTypeBtn" value="button" selected="selected">Button</option>
+								<option fcklang="DlgButtonTypeSbm" value="submit">Submit</option>
+								<option fcklang="DlgButtonTypeRst" value="reset">Reset</option>
+							</select>
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_template.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_template.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_template.html	(revision 795)
@@ -0,0 +1,242 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Template selection dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<style type="text/css">
+			.TplList
+			{
+				border: #dcdcdc 2px solid;
+				background-color: #ffffff;
+				overflow: auto;
+				width: 90%;
+			}
+
+			.TplItem
+			{
+				margin: 5px;
+				padding: 7px;
+				border: #eeeeee 1px solid;
+			}
+
+			.TplItem TABLE
+			{
+				display: inline;
+			}
+
+			.TplTitle
+			{
+				font-weight: bold;
+			}
+		</style>
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+
+window.onload = function()
+{
+	// Set the right box height (browser dependent).
+	GetE('eList').style.height = document.all ? '100%' : '295px' ;
+
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	GetE('xChkReplaceAll').checked = ( FCKConfig.TemplateReplaceAll !== false ) ;
+
+	if ( FCKConfig.TemplateReplaceCheckbox !== false )
+		GetE('xReplaceBlock').style.display = '' ;
+
+	window.parent.SetAutoSize( true ) ;
+
+	LoadTemplatesXml() ;
+}
+
+function LoadTemplatesXml()
+{
+	var oTemplate ;
+
+	if ( !FCK._Templates )
+	{
+		GetE('eLoading').style.display = '' ;
+
+		// Create the Templates array.
+		FCK._Templates = new Array() ;
+
+		// Load the XML file.
+		var oXml = new oEditor.FCKXml() ;
+		oXml.LoadUrl( FCKConfig.TemplatesXmlPath ) ;
+
+		// Get the Images Base Path.
+		var oAtt = oXml.SelectSingleNode( 'Templates/@imagesBasePath' ) ;
+		var sImagesBasePath = oAtt ? oAtt.value : '' ;
+
+		// Get the "Template" nodes defined in the XML file.
+		var aTplNodes = oXml.SelectNodes( 'Templates/Template' ) ;
+
+		for ( var i = 0 ; i < aTplNodes.length ; i++ )
+		{
+			var oNode = aTplNodes[i] ;
+
+			oTemplate = new Object() ;
+
+			var oPart ;
+
+			// Get the Template Title.
+			if ( (oPart = oNode.attributes.getNamedItem('title')) )
+				oTemplate.Title = oPart.value ;
+			else
+				oTemplate.Title = 'Template ' + ( i + 1 ) ;
+
+			// Get the Template Description.
+			if ( (oPart = oXml.SelectSingleNode( 'Description', oNode )) )
+				oTemplate.Description = oPart.text ? oPart.text : oPart.textContent ;
+
+			// Get the Template Image.
+			if ( (oPart = oNode.attributes.getNamedItem('image')) )
+				oTemplate.Image = sImagesBasePath + oPart.value ;
+
+			// Get the Template HTML.
+			if ( (oPart = oXml.SelectSingleNode( 'Html', oNode )) )
+				oTemplate.Html = oPart.text ? oPart.text : oPart.textContent ;
+			else
+			{
+				alert( 'No HTML defined for template index ' + i + '. Please review the "' + FCKConfig.TemplatesXmlPath + '" file.' ) ;
+				continue ;
+			}
+
+			FCK._Templates[ FCK._Templates.length ] = oTemplate ;
+		}
+
+		GetE('eLoading').style.display = 'none' ;
+	}
+
+	if ( FCK._Templates.length == 0 )
+		GetE('eEmpty').style.display = '' ;
+	else
+	{
+		for ( var j = 0 ; j < FCK._Templates.length ; j++ )
+		{
+			oTemplate = FCK._Templates[j] ;
+
+			var oItemDiv = GetE('eList').appendChild( document.createElement( 'DIV' ) ) ;
+			oItemDiv.TplIndex = j ;
+			oItemDiv.className = 'TplItem' ;
+
+			// Build the inner HTML of our new item DIV.
+			var sInner = '<table><tr>' ;
+
+			if ( oTemplate.Image )
+				sInner += '<td valign="top"><img src="' + oTemplate.Image + '"><\/td>' ;
+
+			sInner += '<td valign="top"><div class="TplTitle">' + oTemplate.Title + '<\/div>' ;
+
+			if ( oTemplate.Description )
+				sInner += '<div>' + oTemplate.Description + '<\/div>' ;
+
+			sInner += '<\/td><\/tr><\/table>' ;
+
+			oItemDiv.innerHTML = sInner ;
+
+			oItemDiv.onmouseover = ItemDiv_OnMouseOver ;
+			oItemDiv.onmouseout = ItemDiv_OnMouseOut ;
+			oItemDiv.onclick = ItemDiv_OnClick ;
+		}
+	}
+}
+
+function ItemDiv_OnMouseOver()
+{
+	this.className += ' PopupSelectionBox' ;
+}
+
+function ItemDiv_OnMouseOut()
+{
+	this.className = this.className.replace( /\s*PopupSelectionBox\s*/, '' ) ;
+}
+
+function ItemDiv_OnClick()
+{
+	SelectTemplate( this.TplIndex ) ;
+}
+
+function SelectTemplate( index )
+{
+	oEditor.FCKUndo.SaveUndoStep() ;
+
+	if ( GetE('xChkReplaceAll').checked )
+		FCK.SetHTML( FCK._Templates[index].Html ) ;
+	else
+		FCK.InsertHtml( FCK._Templates[index].Html ) ;
+
+	window.parent.Cancel( true ) ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table width="100%" style="height: 100%">
+		<tr>
+			<td align="center">
+				<span fcklang="DlgTemplatesSelMsg">Please select the template to open in the editor<br />
+					(the actual contents will be lost):</span>
+			</td>
+		</tr>
+		<tr>
+			<td height="100%" align="center">
+				<div id="eList" align="left" class="TplList">
+					<div id="eLoading" align="center" style="display: none">
+						<br />
+						<span fcklang="DlgTemplatesLoading">Loading templates list. Please wait...</span>
+					</div>
+					<div id="eEmpty" align="center" style="display: none">
+						<br />
+						<span fcklang="DlgTemplatesNoTpl">(No templates defined)</span>
+					</div>
+				</div>
+			</td>
+		</tr>
+		<tr id="xReplaceBlock" style="display: none">
+			<td>
+				<table cellpadding="0" cellspacing="0">
+					<tr>
+						<td>
+							<input id="xChkReplaceAll" type="checkbox" /></td>
+						<td>
+							&nbsp;</td>
+						<td>
+							<label for="xChkReplaceAll" fcklang="DlgTemplatesReplace">
+								Replace actual contents</label></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_paste.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_paste.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_paste.html	(revision 795)
@@ -0,0 +1,285 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This dialog is shown when, for some reason (usually security settings),
+ * the user is not able to paste data from the clipboard to the editor using
+ * the toolbar buttons or the context menu.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+
+	<script type="text/javascript">
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCK = oEditor.FCK;
+var FCKTools	= oEditor.FCKTools ;
+var FCKConfig	= oEditor.FCKConfig ;
+
+window.onload = function ()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+	
+	var sPastingType = window.parent.dialogArguments.CustomValue ;
+
+	if ( sPastingType == 'Word' || sPastingType == 'Security' )
+	{
+		if ( sPastingType == 'Security' )
+			document.getElementById( 'xSecurityMsg' ).style.display = '' ;
+
+		var oFrame = document.getElementById('frmData') ;
+		oFrame.style.display = '' ;
+
+		if ( oFrame.contentDocument )
+			oFrame.contentDocument.designMode = 'on' ;
+		else
+			oFrame.contentWindow.document.body.contentEditable = true ;
+	}
+	else
+	{
+		document.getElementById('txtData').style.display = '' ;
+	}
+
+	if ( sPastingType != 'Word' )
+		document.getElementById('oWordCommands').style.display = 'none' ;
+
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function Ok()
+{
+	var sHtml ;
+
+	var sPastingType = window.parent.dialogArguments.CustomValue ;
+
+	if ( sPastingType == 'Word' || sPastingType == 'Security' )
+	{
+		var oFrame = document.getElementById('frmData') ;
+		var oBody ;
+
+		if ( oFrame.contentDocument )
+			oBody = oFrame.contentDocument.body ;
+		else
+			oBody = oFrame.contentWindow.document.body ;
+
+		if ( sPastingType == 'Word' )
+		{
+			// If a plugin creates a FCK.CustomCleanWord function it will be called instead of the default one
+			if ( typeof( FCK.CustomCleanWord ) == 'function' )
+				sHtml = FCK.CustomCleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;
+			else
+				sHtml = CleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;
+		}
+		else
+			sHtml = oBody.innerHTML ;
+
+		// Fix relative anchor URLs (IE automatically adds the current page URL).
+		var re = new RegExp( window.location + "#", "g" ) ;
+		sHtml = sHtml.replace( re, '#') ;
+	}
+	else
+	{
+		sHtml = oEditor.FCKTools.HTMLEncode( document.getElementById('txtData').value )  ;
+		sHtml = sHtml.replace( /\n/g, '<BR>' ) ;
+	}
+
+	oEditor.FCK.InsertHtml( sHtml ) ;
+
+	return true ;
+}
+
+function CleanUpBox()
+{
+	var oFrame = document.getElementById('frmData') ;
+
+	if ( oFrame.contentDocument )
+		oFrame.contentDocument.body.innerHTML = '' ;
+	else
+		oFrame.contentWindow.document.body.innerHTML = '' ;
+}
+
+
+// This function will be called from the PasteFromWord dialog (fck_paste.html)
+// Input: oNode a DOM node that contains the raw paste from the clipboard
+// bIgnoreFont, bRemoveStyles booleans according to the values set in the dialog
+// Output: the cleaned string
+function CleanWord( oNode, bIgnoreFont, bRemoveStyles )
+{
+	var html = oNode.innerHTML ;
+
+	html = html.replace(/<o:p>\s*<\/o:p>/g, '') ;
+	html = html.replace(/<o:p>.*?<\/o:p>/g, '&nbsp;') ;
+
+	// Remove mso-xxx styles.
+	html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ;
+
+	// Remove margin styles.
+	html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '' ) ;
+	html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ;
+
+	html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ;
+	html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ;
+
+	html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ;
+
+	html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ;
+
+	html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ;
+
+	html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ;
+	html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ;
+
+	// Remove FONT face attributes.
+	if ( bIgnoreFont )
+	{
+		html = html.replace( /\s*face="[^"]*"/gi, '' ) ;
+		html = html.replace( /\s*face=[^ >]*/gi, '' ) ;
+
+		html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ;
+	}
+
+	// Remove Class attributes
+	html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ;
+
+	// Remove styles.
+	if ( bRemoveStyles )
+		html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ;
+
+	// Remove empty styles.
+	html =  html.replace( /\s*style="\s*"/gi, '' ) ;
+
+	html = html.replace( /<SPAN\s*[^>]*>\s*&nbsp;\s*<\/SPAN>/gi, '&nbsp;' ) ;
+
+	html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ;
+
+	// Remove Lang attributes
+	html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ;
+
+	html = html.replace( /<SPAN\s*>(.*?)<\/SPAN>/gi, '$1' ) ;
+
+	html = html.replace( /<FONT\s*>(.*?)<\/FONT>/gi, '$1' ) ;
+
+	// Remove XML elements and declarations
+	html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ;
+
+	// Remove Tags with XML namespace declarations: <o:p><\/o:p>
+	html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ;
+
+	// Remove comments [SF BUG-1481861].
+	html = html.replace(/<\!--.*-->/g, '' ) ;
+
+	html = html.replace( /<(U|I|STRIKE)>&nbsp;<\/\1>/g, '&nbsp;' ) ;
+
+	html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ;
+
+	// Remove "display:none" tags.
+	html = html.replace( /<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none(.*?)<\/\1>/ig, '' ) ;
+
+	if ( FCKConfig.CleanWordKeepsStructure )
+	{
+		// The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px">
+		html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ;
+
+		// Word likes to insert extra <font> tags, when using MSIE. (Wierd).
+		html = html.replace( /<(H\d)><FONT[^>]*>(.*?)<\/FONT><\/\1>/gi, '<$1>$2</$1>' );
+		html = html.replace( /<(H\d)><EM>(.*?)<\/EM><\/\1>/gi, '<$1>$2</$1>' );
+	}
+	else
+	{
+		html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ;
+		html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ;
+		html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ;
+		html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ;
+		html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ;
+		html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ;
+
+		html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ;
+
+		// Transform <P> to <DIV>
+		var re = new RegExp( '(<P)([^>]*>.*?)(<\/P>)', 'gi' ) ;	// Different because of a IE 5.0 error
+		html = html.replace( re, '<div$2<\/div>' ) ;
+
+		// Remove empty tags (three times, just to be sure).
+		// This also removes any empty anchor
+		html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;
+		html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;
+		html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;
+	}
+
+	return html ;
+}
+
+	</script>
+
+</head>
+<body style="overflow: hidden">
+	<table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 98%">
+		<tr>
+			<td>
+				<div id="xSecurityMsg" style="display: none">
+					<span fcklang="DlgPasteSec">Because of your browser security settings,
+						the editor is not able to access your clipboard data directly. You are required
+						to paste it again in this window.</span><br />
+					&nbsp;
+				</div>
+				<div>
+					<span fcklang="DlgPasteMsg2">Please paste inside the following box using the keyboard
+						(<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.</span><br />
+					&nbsp;
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td valign="top" height="100%" style="border-right: #000000 1px solid; border-top: #000000 1px solid;
+				border-left: #000000 1px solid; border-bottom: #000000 1px solid">
+				<textarea id="txtData" cols="80" rows="5" style="border: #000000 1px; display: none;
+					width: 99%; height: 98%"></textarea>
+				<iframe id="frmData" src="javascript:void(0)" height="98%" width="99%" frameborder="0"
+					style="border-right: #000000 1px; border-top: #000000 1px; display: none; border-left: #000000 1px;
+					border-bottom: #000000 1px; background-color: #ffffff"></iframe>
+			</td>
+		</tr>
+		<tr id="oWordCommands">
+			<td>
+				<table border="0" cellpadding="0" cellspacing="0" width="100%">
+					<tr>
+						<td nowrap="nowrap">
+							<input id="chkRemoveFont" type="checkbox" checked="checked" />
+							<label for="chkRemoveFont" fcklang="DlgPasteIgnoreFont">
+								Ignore Font Face definitions</label>
+							<br />
+							<input id="chkRemoveStyles" type="checkbox" />
+							<label for="chkRemoveStyles" fcklang="DlgPasteRemoveStyles">
+								Remove Styles definitions</label>
+						</td>
+						<td align="right" valign="top">
+							<input type="button" fcklang="DlgPasteCleanBox" value="Clean Up Box" onclick="CleanUpBox()" />
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_specialchar.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_specialchar.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_specialchar.html	(revision 795)
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Special Chars Selector dialog window.
+-->
+<html>
+	<head>
+		<meta name="robots" content="noindex, nofollow">
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<style type="text/css">
+				.Hand
+				{
+					cursor: pointer ;
+					cursor: hand ;
+				}
+				.Sample { font-size: 24px; }
+		</style>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+var oSample ;
+
+function insertChar(charValue)
+{
+	oEditor.FCK.InsertHtml( charValue || "" ) ;
+	window.parent.Cancel() ;
+}
+
+function over(td)
+{
+	oSample.innerHTML = td.innerHTML ;
+	td.className = 'LightBackground SpecialCharsOver Hand' ;
+}
+
+function out(td)
+{
+	oSample.innerHTML = "&nbsp;" ;
+	td.className = 'DarkBackground SpecialCharsOut Hand' ;
+}
+
+function setDefaults()
+{
+	// Gets the sample placeholder.
+	oSample = document.getElementById("SampleTD") ;
+
+	// First of all, translates the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+}
+
+		</script>
+	</HEAD>
+	<BODY onload="setDefaults()" scroll="no">
+		<table cellpadding="0" cellspacing="0" width="100%" height="100%">
+			<tr>
+				<td width="100%">
+					<table cellpadding="1" cellspacing="1" align="center" border="0" width="100%" height="100%">
+						<script type="text/javascript">
+var aChars = ["!","&quot;","#","$","%","&amp;","\\'","(",")","*","+","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","&lt;","=","&gt;","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~","&euro;","&lsquo;","&rsquo;","&rsquo;","&ldquo;","&rdquo;","&ndash;","&mdash;","&iexcl;","&cent;","&pound;","&curren;","&yen;","&brvbar;","&sect;","&uml;","&copy;","&ordf;","&laquo;","&not;","&reg;","&macr;","&deg;","&plusmn;","&sup2;","&sup3;","&acute;","&micro;","&para;","&middot;","&cedil;","&sup1;","&ordm;","&raquo;","&frac14;","&frac12;","&frac34;","&iquest;","&Agrave;","&Aacute;","&Acirc;","&Atilde;","&Auml;","&Aring;","&AElig;","&Ccedil;","&Egrave;","&Eacute;","&Ecirc;","&Euml;","&Igrave;","&Iacute;","&Icirc;","&Iuml;","&ETH;","&Ntilde;","&Ograve;","&Oacute;","&Ocirc;","&Otilde;","&Ouml;","&times;","&Oslash;","&Ugrave;","&Uacute;","&Ucirc;","&Uuml;","&Yacute;","&THORN;","&szlig;","&agrave;","&aacute;","&acirc;","&atilde;","&auml;","&aring;","&aelig;","&ccedil;","&egrave;","&eacute;","&ecirc;","&euml;","&igrave;","&iacute;","&icirc;","&iuml;","&eth;","&ntilde;","&ograve;","&oacute;","&ocirc;","&otilde;","&ouml;","&divide;","&oslash;","&ugrave;","&uacute;","&ucirc;","&uuml;","&uuml;","&yacute;","&thorn;","&yuml;","&OElig;","&oelig;","&sbquo;","&#8219;","&bdquo;","&hellip;","&trade;","&#9658;","&bull;","&rarr;","&rArr;","&hArr;","&diams;","&asymp;"] ;
+
+var cols = 20 ;
+
+var i = 0 ;
+while (i < aChars.length)
+{
+	document.write("<TR>") ;
+	for(var j = 0 ; j < cols ; j++)
+	{
+		if (aChars[i])
+		{
+			document.write('<TD width="1%" class="DarkBackground SpecialCharsOut Hand" align="center" onclick="insertChar(\'' + aChars[i].replace(/&/g, "&amp;") + '\')" onmouseover="over(this)" onmouseout="out(this)">') ;
+			document.write(aChars[i]) ;
+		}
+		else
+			document.write("<TD class='DarkBackground SpecialCharsOut'>&nbsp;") ;
+		document.write("<\/TD>") ;
+		i++ ;
+	}
+	document.write("<\/TR>") ;
+}
+						</script>
+					</table>
+				</td>
+				<td nowrap>&nbsp;&nbsp;&nbsp;&nbsp;</td>
+				<td valign="top">
+					<table width="40" cellpadding="0" cellspacing="0" border="0">
+						<tr>
+							<td id="SampleTD" width="40" height="40" align="center" class="DarkBackground SpecialCharsOut Sample">&nbsp;</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</BODY>
+</HTML>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_select.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_select.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_select.html	(revision 795)
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Select dialog window.
+-->
+<html>
+	<head>
+		<title>Select Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script type="text/javascript" src="fck_select/fck_select.js"></script>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+var oListText ;
+var oListValue ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	oListText	= document.getElementById( 'cmbText' ) ;
+	oListValue	= document.getElementById( 'cmbValue' ) ;
+
+	if ( oActiveEl && oActiveEl.tagName == 'SELECT' )
+	{
+		GetE('txtName').value		= oActiveEl.name ;
+		GetE('txtSelValue').value	= oActiveEl.value ;
+		GetE('txtLines').value		= GetAttribute( oActiveEl, 'size' ) ;
+		GetE('chkMultiple').checked	= oActiveEl.multiple ;
+
+		// Load the actual options
+		for ( var i = 0 ; i < oActiveEl.options.length ; i++ )
+		{
+			var sText	= oActiveEl.options[i].innerHTML ;
+			var sValue	= oActiveEl.options[i].value ;
+
+			AddComboOption( oListText, sText, sText ) ;
+			AddComboOption( oListValue, sValue, sValue ) ;
+		}
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	var sSize = GetE('txtLines').value ;
+	if ( sSize == null || isNaN( sSize ) || sSize <= 1 )
+		sSize = '' ;
+
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'SELECT' ) ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+	}
+
+	SetAttribute( oActiveEl, 'name'	, GetE('txtName').value ) ;
+	SetAttribute( oActiveEl, 'size'	, sSize ) ;
+	oActiveEl.multiple = ( sSize.length > 0 && GetE('chkMultiple').checked ) ;
+
+	// Remove all options.
+	while ( oActiveEl.options.length > 0 )
+		oActiveEl.remove(0) ;
+
+	// Add all available options.
+	for ( var i = 0 ; i < oListText.options.length ; i++ )
+	{
+		var sText	= oListText.options[i].value ;
+		var sValue	= oListValue.options[i].value ;
+		if ( sValue.length == 0 ) sValue = sText ;
+
+		var oOption = AddComboOption( oActiveEl, sText, sValue, oDOM ) ;
+
+		if ( sValue == GetE('txtSelValue').value )
+		{
+			SetAttribute( oOption, 'selected', 'selected' ) ;
+			oOption.selected = true ;
+		}
+	}
+
+	return true ;
+}
+
+		</script>
+	</head>
+	<body style='OVERFLOW: hidden' scroll='no'>
+		<table width="100%" height="100%">
+			<tr>
+				<td>
+					<table width="100%">
+						<tr>
+							<td nowrap><span fckLang="DlgSelectName">Name</span>&nbsp;</td>
+							<td width="100%" colSpan="2"><input id="txtName" style="WIDTH: 100%" type="text"></td>
+						</tr>
+						<tr>
+							<td nowrap><span fckLang="DlgSelectValue">Value</span>&nbsp;</td>
+							<td width="100%" colSpan="2"><input id="txtSelValue" style="WIDTH: 100%; BACKGROUND-COLOR: buttonface" type="text" readonly></td>
+						</tr>
+						<tr>
+							<td nowrap><span fckLang="DlgSelectSize">Size</span>&nbsp;</td>
+							<td nowrap><input id="txtLines" type="text" size="2" value="">&nbsp;<span fckLang="DlgSelectLines">lines</span></td>
+							<td nowrap align="right"><input id="chkMultiple" name="chkMultiple" type="checkbox"><label for="chkMultiple" fckLang="DlgSelectChkMulti">Allow
+									multiple selections</label></td>
+						</tr>
+					</table>
+					<br>
+					<hr style="POSITION: absolute">
+					<span style="LEFT: 10px; POSITION: relative; TOP: -7px" class="BackColor">&nbsp;<span fckLang="DlgSelectOpAvail">Available
+							Options</span>&nbsp;</span>
+					<table width="100%">
+						<tr>
+							<td width="50%"><span fckLang="DlgSelectOpText">Text</span><br>
+								<input id="txtText" style="WIDTH: 100%" type="text" name="txtText">
+							</td>
+							<td width="50%"><span fckLang="DlgSelectOpValue">Value</span><br>
+								<input id="txtValue" style="WIDTH: 100%" type="text" name="txtValue">
+							</td>
+							<td vAlign="bottom"><input onclick="Add();" type="button" fckLang="DlgSelectBtnAdd" value="Add"></td>
+							<td vAlign="bottom"><input onclick="Modify();" type="button" fckLang="DlgSelectBtnModify" value="Modify"></td>
+						</tr>
+						<tr>
+							<td rowSpan="2"><select id="cmbText" style="WIDTH: 100%" onchange="GetE('cmbValue').selectedIndex = this.selectedIndex;Select(this);"
+									size="5" name="cmbText"></select>
+							</td>
+							<td rowSpan="2"><select id="cmbValue" style="WIDTH: 100%" onchange="GetE('cmbText').selectedIndex = this.selectedIndex;Select(this);"
+									size="5" name="cmbValue"></select>
+							</td>
+							<td vAlign="top" colSpan="2">
+							</td>
+						</tr>
+						<tr>
+							<td vAlign="bottom" colSpan="2"><input style="WIDTH: 100%" onclick="Move(-1);" type="button" fckLang="DlgSelectBtnUp" value="Up">
+								<br>
+								<input style="WIDTH: 100%" onclick="Move(1);" type="button" fckLang="DlgSelectBtnDown"
+									value="Down">
+							</td>
+						</tr>
+						<TR>
+							<TD vAlign="bottom" colSpan="4"><INPUT onclick="SetSelectedValue();" type="button" fckLang="DlgSelectBtnSetValue" value="Set as selected value">&nbsp;&nbsp;
+								<input onclick="Delete();" type="button" fckLang="DlgSelectBtnDelete" value="Delete"></TD>
+						</TR>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_colorselector.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_colorselector.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_colorselector.html	(revision 795)
@@ -0,0 +1,171 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Color Selection dialog window.
+-->
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<style TYPE="text/css">
+			#ColorTable		{ cursor: pointer ; cursor: hand ; }
+			#hicolor		{ height: 74px ; width: 74px ; border-width: 1px ; border-style: solid ; }
+			#hicolortext	{ width: 75px ; text-align: right ; margin-bottom: 7px ; }
+			#selhicolor		{ height: 20px ; width: 74px ; border-width: 1px ; border-style: solid ; }
+			#selcolor		{ width: 75px ; height: 20px ; margin-top: 0px ; margin-bottom: 7px ; }
+			#btnClear		{ width: 75px ; height: 22px ; margin-bottom: 6px ; }
+			.ColorCell		{ height: 15px ; width: 15px ; }
+		</style>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+function OnLoad()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	CreateColorTable() ;
+
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function CreateColorTable()
+{
+	// Get the target table.
+	var oTable = document.getElementById('ColorTable') ;
+
+	// Create the base colors array.
+	var aColors = ['00','33','66','99','cc','ff'] ;
+
+	// This function combines two ranges of three values from the color array into a row.
+	function AppendColorRow( rangeA, rangeB )
+	{
+		for ( var i = rangeA ; i < rangeA + 3 ; i++ )
+		{
+			var oRow = oTable.insertRow(-1) ;
+
+			for ( var j = rangeB ; j < rangeB + 3 ; j++ )
+			{
+				for ( var n = 0 ; n < 6 ; n++ )
+				{
+					AppendColorCell( oRow, '#' + aColors[j] + aColors[n] + aColors[i] ) ;
+				}
+			}
+		}
+	}
+
+	// This function create a single color cell in the color table.
+	function AppendColorCell( targetRow, color )
+	{
+		var oCell = targetRow.insertCell(-1) ;
+		oCell.className = 'ColorCell' ;
+		oCell.bgColor = color ;
+
+		oCell.onmouseover = function()
+		{
+			document.getElementById('hicolor').style.backgroundColor = this.bgColor ;
+			document.getElementById('hicolortext').innerHTML = this.bgColor ;
+		}
+
+		oCell.onclick = function()
+		{
+			document.getElementById('selhicolor').style.backgroundColor = this.bgColor ;
+			document.getElementById('selcolor').value = this.bgColor ;
+		}
+	}
+
+	AppendColorRow( 0, 0 ) ;
+	AppendColorRow( 3, 0 ) ;
+	AppendColorRow( 0, 3 ) ;
+	AppendColorRow( 3, 3 ) ;
+
+	// Create the last row.
+	var oRow = oTable.insertRow(-1) ;
+
+	// Create the gray scale colors cells.
+	for ( var n = 0 ; n < 6 ; n++ )
+	{
+		AppendColorCell( oRow, '#' + aColors[n] + aColors[n] + aColors[n] ) ;
+	}
+
+	// Fill the row with black cells.
+	for ( var i = 0 ; i < 12 ; i++ )
+	{
+		AppendColorCell( oRow, '#000000' ) ;
+	}
+}
+
+function Clear()
+{
+	document.getElementById('selhicolor').style.backgroundColor = '' ;
+	document.getElementById('selcolor').value = '' ;
+}
+
+function ClearActual()
+{
+	document.getElementById('hicolor').style.backgroundColor = '' ;
+	document.getElementById('hicolortext').innerHTML = '&nbsp;' ;
+}
+
+function UpdateColor()
+{
+	try		  { document.getElementById('selhicolor').style.backgroundColor = document.getElementById('selcolor').value ; }
+	catch (e) { Clear() ; }
+}
+
+function Ok()
+{
+	if ( typeof(window.parent.dialogArguments.CustomValue) == 'function' )
+		window.parent.dialogArguments.CustomValue( document.getElementById('selcolor').value ) ;
+
+	return true ;
+}
+		</script>
+	</head>
+	<body onload="OnLoad()" scroll="no" style="OVERFLOW: hidden">
+		<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">
+			<tr>
+				<td align="center" valign="middle">
+					<table border="0" cellspacing="5" cellpadding="0" width="100%">
+						<tr>
+							<td valign="top" align="center" nowrap width="100%">
+								<table id="ColorTable" border="0" cellspacing="0" cellpadding="0" width="270" onmouseout="ClearActual();">
+								</table>
+							</td>
+							<td valign="top" align="left" nowrap>
+								<span fckLang="DlgColorHighlight">Highlight</span>
+								<div id="hicolor"></div>
+								<div id="hicolortext">&nbsp;</div>
+								<span fckLang="DlgColorSelected">Selected</span>
+								<div id="selhicolor"></div>
+								<input id="selcolor" type="text" maxlength="20" onchange="UpdateColor();">
+								<br>
+								<input id="btnClear" type="button" fckLang="DlgColorBtnClear" value="Clear" onclick="Clear();" />
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image/fck_image.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image/fck_image.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image/fck_image.js	(revision 795)
@@ -0,0 +1,486 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Scripts related to the Image dialog window (see fck_image.html).
+ */
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKDebug	= oEditor.FCKDebug ;
+
+var bImageButton = ( document.location.search.length > 0 && document.location.search.substr(1) == 'ImageButton' ) ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'Info', FCKLang.DlgImgInfoTab ) ;
+
+if ( !bImageButton && !FCKConfig.ImageDlgHideLink )
+	window.parent.AddTab( 'Link', FCKLang.DlgImgLinkTab ) ;
+
+if ( FCKConfig.ImageUpload )
+	window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload ) ;
+
+if ( !FCKConfig.ImageDlgHideAdvanced )
+	window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+	ShowE('divInfo'		, ( tabCode == 'Info' ) ) ;
+	ShowE('divLink'		, ( tabCode == 'Link' ) ) ;
+	ShowE('divUpload'	, ( tabCode == 'Upload' ) ) ;
+	ShowE('divAdvanced'	, ( tabCode == 'Advanced' ) ) ;
+}
+
+// Get the selected image (if available).
+var oImage = FCK.Selection.GetSelectedElement() ;
+
+if ( oImage && oImage.tagName != 'IMG' && !( oImage.tagName == 'INPUT' && oImage.type == 'image' ) )
+	oImage = null ;
+
+// Get the active link.
+var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+
+var oImageOriginal ;
+
+function UpdateOriginal( resetSize )
+{
+	if ( !eImgPreview )
+		return ;
+
+	if ( GetE('txtUrl').value.length == 0 )
+	{
+		oImageOriginal = null ;
+		return ;
+	}
+
+	oImageOriginal = document.createElement( 'IMG' ) ;	// new Image() ;
+
+	if ( resetSize )
+	{
+		oImageOriginal.onload = function()
+		{
+			this.onload = null ;
+			ResetSizes() ;
+		}
+	}
+
+	oImageOriginal.src = eImgPreview.src ;
+}
+
+var bPreviewInitialized ;
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	GetE('btnLockSizes').title = FCKLang.DlgImgLockRatio ;
+	GetE('btnResetSize').title = FCKLang.DlgBtnResetSize ;
+
+	// Load the selected element information (if any).
+	LoadSelection() ;
+
+	// Show/Hide the "Browse Server" button.
+	GetE('tdBrowse').style.display				= FCKConfig.ImageBrowser	? '' : 'none' ;
+	GetE('divLnkBrowseServer').style.display	= FCKConfig.LinkBrowser		? '' : 'none' ;
+
+	UpdateOriginal() ;
+
+	// Set the actual uploader URL.
+	if ( FCKConfig.ImageUpload )
+		GetE('frmUpload').action = FCKConfig.ImageUploadURL ;
+
+	window.parent.SetAutoSize( true ) ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( ! oImage ) return ;
+
+	var sUrl = oImage.getAttribute( '_fcksavedurl' ) ;
+	if ( sUrl == null )
+		sUrl = GetAttribute( oImage, 'src', '' ) ;
+
+	GetE('txtUrl').value    = sUrl ;
+	GetE('txtAlt').value    = GetAttribute( oImage, 'alt', '' ) ;
+	GetE('txtVSpace').value	= GetAttribute( oImage, 'vspace', '' ) ;
+	GetE('txtHSpace').value	= GetAttribute( oImage, 'hspace', '' ) ;
+	GetE('txtBorder').value	= GetAttribute( oImage, 'border', '' ) ;
+	GetE('cmbAlign').value	= GetAttribute( oImage, 'align', '' ) ;
+
+	var iWidth, iHeight ;
+
+	var regexSize = /^\s*(\d+)px\s*$/i ;
+
+	if ( oImage.style.width )
+	{
+		var aMatchW  = oImage.style.width.match( regexSize ) ;
+		if ( aMatchW )
+		{
+			iWidth = aMatchW[1] ;
+			oImage.style.width = '' ;
+		}
+	}
+
+	if ( oImage.style.height )
+	{
+		var aMatchH  = oImage.style.height.match( regexSize ) ;
+		if ( aMatchH )
+		{
+			iHeight = aMatchH[1] ;
+			oImage.style.height = '' ;
+		}
+	}
+
+	GetE('txtWidth').value	= iWidth ? iWidth : GetAttribute( oImage, "width", '' ) ;
+	GetE('txtHeight').value	= iHeight ? iHeight : GetAttribute( oImage, "height", '' ) ;
+
+	// Get Advances Attributes
+	GetE('txtAttId').value			= oImage.id ;
+	GetE('cmbAttLangDir').value		= oImage.dir ;
+	GetE('txtAttLangCode').value	= oImage.lang ;
+	GetE('txtAttTitle').value		= oImage.title ;
+	GetE('txtLongDesc').value		= oImage.longDesc ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+	{
+		GetE('txtAttClasses').value = oImage.getAttribute('className') || '' ;
+		GetE('txtAttStyle').value = oImage.style.cssText ;
+	}
+	else
+	{
+		GetE('txtAttClasses').value = oImage.getAttribute('class',2) || '' ;
+		GetE('txtAttStyle').value = oImage.getAttribute('style',2) ;
+	}
+
+	if ( oLink )
+	{
+		var sLinkUrl = oLink.getAttribute( '_fcksavedurl' ) ;
+		if ( sLinkUrl == null )
+			sLinkUrl = oLink.getAttribute('href',2) ;
+
+		GetE('txtLnkUrl').value		= sLinkUrl ;
+		GetE('cmbLnkTarget').value	= oLink.target ;
+	}
+
+	UpdatePreview() ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	if ( GetE('txtUrl').value.length == 0 )
+	{
+		window.parent.SetSelectedTab( 'Info' ) ;
+		GetE('txtUrl').focus() ;
+
+		alert( FCKLang.DlgImgAlertUrl ) ;
+
+		return false ;
+	}
+
+	var bHasImage = ( oImage != null ) ;
+
+	if ( bHasImage && bImageButton && oImage.tagName == 'IMG' )
+	{
+		if ( confirm( 'Do you want to transform the selected image on a image button?' ) )
+			oImage = null ;
+	}
+	else if ( bHasImage && !bImageButton && oImage.tagName == 'INPUT' )
+	{
+		if ( confirm( 'Do you want to transform the selected image button on a simple image?' ) )
+			oImage = null ;
+	}
+
+	if ( !bHasImage )
+	{
+		if ( bImageButton )
+		{
+			oImage = FCK.EditorDocument.createElement( 'INPUT' ) ;
+			oImage.type = 'image' ;
+			oImage = FCK.InsertElementAndGetIt( oImage ) ;
+		}
+		else
+			oImage = FCK.CreateElement( 'IMG' ) ;
+	}
+	else
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+	UpdateImage( oImage ) ;
+
+	var sLnkUrl = GetE('txtLnkUrl').value.Trim() ;
+
+	if ( sLnkUrl.length == 0 )
+	{
+		if ( oLink )
+			FCK.ExecuteNamedCommand( 'Unlink' ) ;
+	}
+	else
+	{
+		if ( oLink )	// Modifying an existent link.
+			oLink.href = sLnkUrl ;
+		else			// Creating a new link.
+		{
+			if ( !bHasImage )
+				oEditor.FCKSelection.SelectNode( oImage ) ;
+
+			oLink = oEditor.FCK.CreateLink( sLnkUrl ) ;
+
+			if ( !bHasImage )
+			{
+				oEditor.FCKSelection.SelectNode( oLink ) ;
+				oEditor.FCKSelection.Collapse( false ) ;
+			}
+		}
+
+		SetAttribute( oLink, '_fcksavedurl', sLnkUrl ) ;
+		SetAttribute( oLink, 'target', GetE('cmbLnkTarget').value ) ;
+	}
+
+	return true ;
+}
+
+function UpdateImage( e, skipId )
+{
+	e.src = GetE('txtUrl').value ;
+	SetAttribute( e, "_fcksavedurl", GetE('txtUrl').value ) ;
+	SetAttribute( e, "alt"   , GetE('txtAlt').value ) ;
+	SetAttribute( e, "width" , GetE('txtWidth').value ) ;
+	SetAttribute( e, "height", GetE('txtHeight').value ) ;
+	SetAttribute( e, "vspace", GetE('txtVSpace').value ) ;
+	SetAttribute( e, "hspace", GetE('txtHSpace').value ) ;
+	SetAttribute( e, "border", GetE('txtBorder').value ) ;
+	SetAttribute( e, "align" , GetE('cmbAlign').value ) ;
+
+	// Advances Attributes
+
+	if ( ! skipId )
+		SetAttribute( e, 'id', GetE('txtAttId').value ) ;
+
+	SetAttribute( e, 'dir'		, GetE('cmbAttLangDir').value ) ;
+	SetAttribute( e, 'lang'		, GetE('txtAttLangCode').value ) ;
+	SetAttribute( e, 'title'	, GetE('txtAttTitle').value ) ;
+	SetAttribute( e, 'class'	, GetE('txtAttClasses').value ) ;
+	SetAttribute( e, 'longDesc'	, GetE('txtLongDesc').value ) ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+		e.style.cssText = GetE('txtAttStyle').value ;
+	else
+		SetAttribute( e, 'style', GetE('txtAttStyle').value ) ;
+}
+
+var eImgPreview ;
+var eImgPreviewLink ;
+
+function SetPreviewElements( imageElement, linkElement )
+{
+	eImgPreview = imageElement ;
+	eImgPreviewLink = linkElement ;
+
+	UpdatePreview() ;
+	UpdateOriginal() ;
+
+	bPreviewInitialized = true ;
+}
+
+function UpdatePreview()
+{
+	if ( !eImgPreview || !eImgPreviewLink )
+		return ;
+
+	if ( GetE('txtUrl').value.length == 0 )
+		eImgPreviewLink.style.display = 'none' ;
+	else
+	{
+		UpdateImage( eImgPreview, true ) ;
+
+		if ( GetE('txtLnkUrl').value.Trim().length > 0 )
+			eImgPreviewLink.href = 'javascript:void(null);' ;
+		else
+			SetAttribute( eImgPreviewLink, 'href', '' ) ;
+
+		eImgPreviewLink.style.display = '' ;
+	}
+}
+
+var bLockRatio = true ;
+
+function SwitchLock( lockButton )
+{
+	bLockRatio = !bLockRatio ;
+	lockButton.className = bLockRatio ? 'BtnLocked' : 'BtnUnlocked' ;
+	lockButton.title = bLockRatio ? 'Lock sizes' : 'Unlock sizes' ;
+
+	if ( bLockRatio )
+	{
+		if ( GetE('txtWidth').value.length > 0 )
+			OnSizeChanged( 'Width', GetE('txtWidth').value ) ;
+		else
+			OnSizeChanged( 'Height', GetE('txtHeight').value ) ;
+	}
+}
+
+// Fired when the width or height input texts change
+function OnSizeChanged( dimension, value )
+{
+	// Verifies if the aspect ration has to be mantained
+	if ( oImageOriginal && bLockRatio )
+	{
+		var e = dimension == 'Width' ? GetE('txtHeight') : GetE('txtWidth') ;
+
+		if ( value.length == 0 || isNaN( value ) )
+		{
+			e.value = '' ;
+			return ;
+		}
+
+		if ( dimension == 'Width' )
+			value = value == 0 ? 0 : Math.round( oImageOriginal.height * ( value  / oImageOriginal.width ) ) ;
+		else
+			value = value == 0 ? 0 : Math.round( oImageOriginal.width  * ( value / oImageOriginal.height ) ) ;
+
+		if ( !isNaN( value ) )
+			e.value = value ;
+	}
+
+	UpdatePreview() ;
+}
+
+// Fired when the Reset Size button is clicked
+function ResetSizes()
+{
+	if ( ! oImageOriginal ) return ;
+
+	GetE('txtWidth').value  = oImageOriginal.width ;
+	GetE('txtHeight').value = oImageOriginal.height ;
+
+	UpdatePreview() ;
+}
+
+function BrowseServer()
+{
+	OpenServerBrowser(
+		'Image',
+		FCKConfig.ImageBrowserURL,
+		FCKConfig.ImageBrowserWindowWidth,
+		FCKConfig.ImageBrowserWindowHeight ) ;
+}
+
+function LnkBrowseServer()
+{
+	OpenServerBrowser(
+		'Link',
+		FCKConfig.LinkBrowserURL,
+		FCKConfig.LinkBrowserWindowWidth,
+		FCKConfig.LinkBrowserWindowHeight ) ;
+}
+
+function OpenServerBrowser( type, url, width, height )
+{
+	sActualBrowser = type ;
+	OpenFileBrowser( url, width, height ) ;
+}
+
+var sActualBrowser ;
+
+function SetUrl( url, width, height, alt )
+{
+	if ( sActualBrowser == 'Link' )
+	{
+		GetE('txtLnkUrl').value = url ;
+		UpdatePreview() ;
+	}
+	else
+	{
+		GetE('txtUrl').value = url ;
+		GetE('txtWidth').value = width ? width : '' ;
+		GetE('txtHeight').value = height ? height : '' ;
+
+		if ( alt )
+			GetE('txtAlt').value = alt;
+
+		UpdatePreview() ;
+		UpdateOriginal( true ) ;
+	}
+
+	window.parent.SetSelectedTab( 'Info' ) ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+	switch ( errorNumber )
+	{
+		case 0 :	// No errors
+			alert( 'Your file has been successfully uploaded' ) ;
+			break ;
+		case 1 :	// Custom error
+			alert( customMsg ) ;
+			return ;
+		case 101 :	// Custom warning
+			alert( customMsg ) ;
+			break ;
+		case 201 :
+			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+			break ;
+		case 202 :
+			alert( 'Invalid file type' ) ;
+			return ;
+		case 203 :
+			alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+			return ;
+		default :
+			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+			return ;
+	}
+
+	sActualBrowser = '' ;
+	SetUrl( fileUrl ) ;
+	GetE('frmUpload').reset() ;
+}
+
+var oUploadAllowedExtRegex	= new RegExp( FCKConfig.ImageUploadAllowedExtensions, 'i' ) ;
+var oUploadDeniedExtRegex	= new RegExp( FCKConfig.ImageUploadDeniedExtensions, 'i' ) ;
+
+function CheckUpload()
+{
+	var sFile = GetE('txtUploadFile').value ;
+
+	if ( sFile.length == 0 )
+	{
+		alert( 'Please select a file to upload' ) ;
+		return false ;
+	}
+
+	if ( ( FCKConfig.ImageUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
+		( FCKConfig.ImageUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
+	{
+		OnUploadCompleted( 202 ) ;
+		return false ;
+	}
+
+	return true ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image/fck_image_preview.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image/fck_image_preview.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image/fck_image_preview.html	(revision 795)
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Preview page for the Image dialog window.
+ *
+ * Curiosity: http://en.wikipedia.org/wiki/Lorem_ipsum
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<link href="../common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+	<script type="text/javascript">
+
+// Sets the Skin CSS
+document.write( '<link href="' + window.parent.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+if ( window.parent.FCKConfig.BaseHref.length > 0 )
+	document.write( '<base href="' + window.parent.FCKConfig.BaseHref + '">' ) ;
+
+window.onload = function()
+{
+	window.parent.SetPreviewElements(
+		document.getElementById( 'imgPreview' ),
+		document.getElementById( 'lnkPreview' ) ) ;
+}
+
+	</script>
+</head>
+<body style="color: #000000; background-color: #ffffff">
+	<a id="lnkPreview" onclick="return false;" style="cursor: default">
+		<img id="imgPreview" onload="window.parent.UpdateOriginal();" style="display: none" /></a>Lorem
+	ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas feugiat consequat diam.
+	Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, nulla.
+	Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis
+	euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce
+	mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie.
+	Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque
+	egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem,
+	in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut
+	placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy
+	metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices,
+	ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris
+	non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas
+	elementum. Nunc imperdiet gravida mauris.
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_find.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_find.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_find.html	(revision 795)
@@ -0,0 +1,173 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * "Find" dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+function OnLoad()
+{
+	// Whole word is available on IE only.
+	if ( oEditor.FCKBrowserInfo.IsIE )
+		document.getElementById('divWord').style.display = '' ;
+
+	// First of all, translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+	window.parent.SetAutoSize( true ) ;
+}
+
+function btnStat(frm)
+{
+	document.getElementById('btnFind').disabled =
+		( document.getElementById('txtFind').value.length == 0 ) ;
+}
+
+function ReplaceTextNodes( parentNode, regex, replaceValue, replaceAll )
+{
+	for ( var i = 0 ; i < parentNode.childNodes.length ; i++ )
+	{
+		var oNode = parentNode.childNodes[i] ;
+		if ( oNode.nodeType == 3 )
+		{
+			var sReplaced = oNode.nodeValue.replace( regex, replaceValue ) ;
+			if ( oNode.nodeValue != sReplaced )
+			{
+				oNode.nodeValue = sReplaced ;
+				if ( ! replaceAll )
+					return true ;
+			}
+		}
+		else
+		{
+			if ( ReplaceTextNodes( oNode, regex, replaceValue ) )
+				return true ;
+		}
+	}
+	return false ;
+}
+
+function GetRegexExpr()
+{
+	var sExpr ;
+
+	if ( document.getElementById('chkWord').checked )
+		sExpr = '\\b' + document.getElementById('txtFind').value + '\\b' ;
+	else
+		sExpr = document.getElementById('txtFind').value ;
+
+	return sExpr ;
+}
+
+function GetCase()
+{
+	return ( document.getElementById('chkCase').checked ? '' : 'i' ) ;
+}
+
+function Ok()
+{
+	if ( document.getElementById('txtFind').value.length == 0 )
+		return ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+		FindIE() ;
+	else
+		FindGecko() ;
+}
+
+var oRange ;
+
+if ( oEditor.FCKBrowserInfo.IsIE )
+	oRange = oEditor.FCK.EditorDocument.body.createTextRange() ;
+
+function FindIE()
+{
+	var iFlags = 0 ;
+
+	if ( chkCase.checked )
+		iFlags = iFlags | 4 ;
+
+	if ( chkWord.checked )
+		iFlags = iFlags | 2 ;
+
+	var bFound = oRange.findText( document.getElementById('txtFind').value, 1, iFlags ) ;
+
+	if ( bFound )
+	{
+		oRange.scrollIntoView() ;
+		oRange.select() ;
+		oRange.collapse(false) ;
+		oLastRangeFound = oRange ;
+	}
+	else
+	{
+		oRange = oEditor.FCK.EditorDocument.body.createTextRange() ;
+		alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+	}
+}
+
+function FindGecko()
+{
+	var bCase = document.getElementById('chkCase').checked ;
+	var bWord = document.getElementById('chkWord').checked ;
+
+	// window.find( searchString, caseSensitive, backwards, wrapAround, wholeWord, searchInFrames, showDialog ) ;
+	if ( !oEditor.FCK.EditorWindow.find( document.getElementById('txtFind').value, bCase, false, false, bWord, false, false ) )
+		alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+}
+	</script>
+</head>
+<body onload="OnLoad()" style="overflow: hidden">
+	<table cellspacing="3" cellpadding="2" width="100%" border="0">
+		<tr>
+			<td nowrap="nowrap">
+				<label for="txtFind" fcklang="DlgReplaceFindLbl">
+					Find what:</label>&nbsp;
+			</td>
+			<td width="100%">
+				<input id="txtFind" style="width: 100%" tabindex="1" type="text" />
+			</td>
+			<td>
+				<input id="btnFind" style="padding-right: 5px; padding-left: 5px" onclick="Ok();"
+					type="button" value="Find" fcklang="DlgFindFindBtn" />
+			</td>
+		</tr>
+		<tr>
+			<td valign="bottom" colspan="3">
+				&nbsp;<input id="chkCase" tabindex="3" type="checkbox" /><label for="chkCase" fcklang="DlgReplaceCaseChk">Match
+					case</label>
+				<br />
+				<div id="divWord" style="display: none">
+					&nbsp;<input id="chkWord" tabindex="4" type="checkbox" /><label for="chkWord" fcklang="DlgReplaceWordChk">Match
+						whole word</label>
+				</div>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_image.html	(revision 795)
@@ -0,0 +1,252 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Image Properties dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Image Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script src="fck_image/fck_image.js" type="text/javascript"></script>
+	<link href="common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+</head>
+<body scroll="no" style="overflow: hidden">
+	<div id="divInfo">
+		<table cellspacing="1" cellpadding="1" border="0" width="100%" height="100%">
+			<tr>
+				<td>
+					<table cellspacing="0" cellpadding="0" width="100%" border="0">
+						<tr>
+							<td width="100%">
+								<span fcklang="DlgImgURL">URL</span>
+							</td>
+							<td id="tdBrowse" style="display: none" nowrap="nowrap" rowspan="2">
+								&nbsp;
+								<input id="btnBrowse" onclick="BrowseServer();" type="button" value="Browse Server"
+									fcklang="DlgBtnBrowseServer" />
+							</td>
+						</tr>
+						<tr>
+							<td valign="top">
+								<input id="txtUrl" style="width: 100%" type="text" onblur="UpdatePreview();" />
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<span fcklang="DlgImgAlt">Short Description</span><br />
+					<input id="txtAlt" style="width: 100%" type="text" /><br />
+				</td>
+			</tr>
+			<tr height="100%">
+				<td valign="top">
+					<table cellspacing="0" cellpadding="0" width="100%" border="0" height="100%">
+						<tr>
+							<td valign="top">
+								<br />
+								<table cellspacing="0" cellpadding="0" border="0">
+									<tr>
+										<td nowrap="nowrap">
+											<span fcklang="DlgImgWidth">Width</span>&nbsp;</td>
+										<td>
+											<input type="text" size="3" id="txtWidth" onkeyup="OnSizeChanged('Width',this.value);" /></td>
+										<td rowspan="2">
+											<div id="btnLockSizes" class="BtnLocked" onmouseover="this.className = (bLockRatio ? 'BtnLocked' : 'BtnUnlocked' ) + ' BtnOver';"
+												onmouseout="this.className = (bLockRatio ? 'BtnLocked' : 'BtnUnlocked' );" title="Lock Sizes"
+												onclick="SwitchLock(this);">
+											</div>
+										</td>
+										<td rowspan="2">
+											<div id="btnResetSize" class="BtnReset" onmouseover="this.className='BtnReset BtnOver';"
+												onmouseout="this.className='BtnReset';" title="Reset Size" onclick="ResetSizes();">
+											</div>
+										</td>
+									</tr>
+									<tr>
+										<td nowrap="nowrap">
+											<span fcklang="DlgImgHeight">Height</span>&nbsp;</td>
+										<td>
+											<input type="text" size="3" id="txtHeight" onkeyup="OnSizeChanged('Height',this.value);" /></td>
+									</tr>
+								</table>
+								<br />
+								<table cellspacing="0" cellpadding="0" border="0">
+									<tr>
+										<td nowrap="nowrap">
+											<span fcklang="DlgImgBorder">Border</span>&nbsp;</td>
+										<td>
+											<input type="text" size="2" value="" id="txtBorder" onkeyup="UpdatePreview();" /></td>
+									</tr>
+									<tr>
+										<td nowrap="nowrap">
+											<span fcklang="DlgImgHSpace">HSpace</span>&nbsp;</td>
+										<td>
+											<input type="text" size="2" id="txtHSpace" onkeyup="UpdatePreview();" /></td>
+									</tr>
+									<tr>
+										<td nowrap="nowrap">
+											<span fcklang="DlgImgVSpace">VSpace</span>&nbsp;</td>
+										<td>
+											<input type="text" size="2" id="txtVSpace" onkeyup="UpdatePreview();" /></td>
+									</tr>
+									<tr>
+										<td nowrap="nowrap">
+											<span fcklang="DlgImgAlign">Align</span>&nbsp;</td>
+										<td>
+											<select id="cmbAlign" onchange="UpdatePreview();">
+												<option value="" selected="selected"></option>
+												<option fcklang="DlgImgAlignLeft" value="left">Left</option>
+												<option fcklang="DlgImgAlignAbsBottom" value="absBottom">Abs Bottom</option>
+												<option fcklang="DlgImgAlignAbsMiddle" value="absMiddle">Abs Middle</option>
+												<option fcklang="DlgImgAlignBaseline" value="baseline">Baseline</option>
+												<option fcklang="DlgImgAlignBottom" value="bottom">Bottom</option>
+												<option fcklang="DlgImgAlignMiddle" value="middle">Middle</option>
+												<option fcklang="DlgImgAlignRight" value="right">Right</option>
+												<option fcklang="DlgImgAlignTextTop" value="textTop">Text Top</option>
+												<option fcklang="DlgImgAlignTop" value="top">Top</option>
+											</select>
+										</td>
+									</tr>
+								</table>
+							</td>
+							<td>
+								&nbsp;&nbsp;&nbsp;</td>
+							<td width="100%" valign="top">
+								<table cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed">
+									<tr>
+										<td>
+											<span fcklang="DlgImgPreview">Preview</span></td>
+									</tr>
+									<tr>
+										<td valign="top">
+											<iframe class="ImagePreviewArea" src="fck_image/fck_image_preview.html" frameborder="0"
+												marginheight="0" marginwidth="0"></iframe>
+										</td>
+									</tr>
+								</table>
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</div>
+	<div id="divUpload" style="display: none">
+		<form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data"
+			action="" onsubmit="return CheckUpload();">
+			<span fcklang="DlgLnkUpload">Upload</span><br />
+			<input id="txtUploadFile" style="width: 100%" type="file" size="40" name="NewFile" /><br />
+			<br />
+			<input id="btnUpload" type="submit" value="Send it to the Server" fcklang="DlgLnkBtnUpload" />
+			<iframe name="UploadWindow" style="display: none" src="javascript:void(0)"></iframe>
+		</form>
+	</div>
+	<div id="divLink" style="display: none">
+		<table cellspacing="1" cellpadding="1" border="0" width="100%">
+			<tr>
+				<td>
+					<div>
+						<span fcklang="DlgLnkURL">URL</span><br />
+						<input id="txtLnkUrl" style="width: 100%" type="text" onblur="UpdatePreview();" />
+					</div>
+					<div id="divLnkBrowseServer" align="right">
+						<input type="button" value="Browse Server" fcklang="DlgBtnBrowseServer" onclick="LnkBrowseServer();" />
+					</div>
+					<div>
+						<span fcklang="DlgLnkTarget">Target</span><br />
+						<select id="cmbLnkTarget">
+							<option value="" fcklang="DlgGenNotSet" selected="selected">&lt;not set&gt;</option>
+							<option value="_blank" fcklang="DlgLnkTargetBlank">New Window (_blank)</option>
+							<option value="_top" fcklang="DlgLnkTargetTop">Topmost Window (_top)</option>
+							<option value="_self" fcklang="DlgLnkTargetSelf">Same Window (_self)</option>
+							<option value="_parent" fcklang="DlgLnkTargetParent">Parent Window (_parent)</option>
+						</select>
+					</div>
+				</td>
+			</tr>
+		</table>
+	</div>
+	<div id="divAdvanced" style="display: none">
+		<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+			<tr>
+				<td valign="top" width="50%">
+					<span fcklang="DlgGenId">Id</span><br />
+					<input id="txtAttId" style="width: 100%" type="text" />
+				</td>
+				<td width="1">
+					&nbsp;&nbsp;</td>
+				<td valign="top">
+					<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+						<tr>
+							<td width="60%">
+								<span fcklang="DlgGenLangDir">Language Direction</span><br />
+								<select id="cmbAttLangDir" style="width: 100%">
+									<option value="" fcklang="DlgGenNotSet" selected="selected">&lt;not set&gt;</option>
+									<option value="ltr" fcklang="DlgGenLangDirLtr">Left to Right (LTR)</option>
+									<option value="rtl" fcklang="DlgGenLangDirRtl">Right to Left (RTL)</option>
+								</select>
+							</td>
+							<td width="1%">
+								&nbsp;&nbsp;</td>
+							<td nowrap="nowrap">
+								<span fcklang="DlgGenLangCode">Language Code</span><br />
+								<input id="txtAttLangCode" style="width: 100%" type="text" />&nbsp;
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="3">
+					&nbsp;</td>
+			</tr>
+			<tr>
+				<td colspan="3">
+					<span fcklang="DlgGenLongDescr">Long Description URL</span><br />
+					<input id="txtLongDesc" style="width: 100%" type="text" />
+				</td>
+			</tr>
+			<tr>
+				<td colspan="3">
+					&nbsp;</td>
+			</tr>
+			<tr>
+				<td valign="top">
+					<span fcklang="DlgGenClass">Stylesheet Classes</span><br />
+					<input id="txtAttClasses" style="width: 100%" type="text" />
+				</td>
+				<td>
+				</td>
+				<td valign="top">
+					&nbsp;<span fcklang="DlgGenTitle">Advisory Title</span><br />
+					<input id="txtAttTitle" style="width: 100%" type="text" />
+				</td>
+			</tr>
+		</table>
+		<span fcklang="DlgGenStyle">Style</span><br />
+		<input id="txtAttStyle" style="width: 100%" type="text" />
+	</div>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_table.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_table.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_table.html	(revision 795)
@@ -0,0 +1,286 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Table dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Table Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+// Gets the table if there is one selected.
+var table ;
+var e = oEditor.FCKSelection.GetSelectedElement() ;
+
+if ( ( !e && document.location.search.substr(1) == 'Parent' ) || ( e && e.tagName != 'TABLE' ) )
+	e = oEditor.FCKSelection.MoveToAncestorNode( 'TABLE' ) ;
+
+if ( e && e.tagName == "TABLE" )
+	table = e ;
+
+// Fired when the window loading process is finished. It sets the fields with the
+// actual values if a table is selected in the editor.
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if (table)
+	{
+		document.getElementById('txtRows').value    = table.rows.length ;
+		document.getElementById('txtColumns').value = table.rows[0].cells.length ;
+
+		// Gets the value from the Width or the Style attribute
+		var iWidth  = (table.style.width  ? table.style.width  : table.width ) ;
+		var iHeight = (table.style.height ? table.style.height : table.height ) ;
+
+		if (iWidth.indexOf('%') >= 0)			// Percentual = %
+		{
+			iWidth = parseInt( iWidth.substr(0,iWidth.length - 1), 10 ) ;
+			document.getElementById('selWidthType').value = "percent" ;
+		}
+		else if (iWidth.indexOf('px') >= 0)		// Style Pixel = px
+		{																										  //
+			iWidth = iWidth.substr(0,iWidth.length - 2);
+			document.getElementById('selWidthType').value = "pixels" ;
+		}
+
+		if (iHeight && iHeight.indexOf('px') >= 0)		// Style Pixel = px
+			iHeight = iHeight.substr(0,iHeight.length - 2);
+
+		document.getElementById('txtWidth').value		= iWidth || '' ;
+		document.getElementById('txtHeight').value		= iHeight || '' ;
+		document.getElementById('txtBorder').value		= GetAttribute( table, 'border', '' ) ;
+		document.getElementById('selAlignment').value	= GetAttribute( table, 'align', '' ) ;
+		document.getElementById('txtCellPadding').value	= GetAttribute( table, 'cellPadding', '' ) ;
+		document.getElementById('txtCellSpacing').value	= GetAttribute( table, 'cellSpacing', '' ) ;
+		document.getElementById('txtSummary').value     = GetAttribute( table, 'summary', '' ) ;
+//		document.getElementById('cmbFontStyle').value	= table.className ;
+
+		if (table.caption) document.getElementById('txtCaption').value = table.caption.innerHTML ;
+
+		document.getElementById('txtRows').disabled    = true ;
+		document.getElementById('txtColumns').disabled = true ;
+	}
+
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+// Fired when the user press the OK button
+function Ok()
+{
+	var bExists = ( table != null ) ;
+
+	if ( ! bExists )
+		table = oEditor.FCK.EditorDocument.createElement( "TABLE" ) ;
+
+	// Removes the Width and Height styles
+	if ( bExists && table.style.width )		table.style.width = null ; //.removeAttribute("width") ;
+	if ( bExists && table.style.height )	table.style.height = null ; //.removeAttribute("height") ;
+
+	var sWidth = GetE('txtWidth').value ;
+	if ( sWidth.length > 0 && GetE('selWidthType').value == 'percent' )
+		sWidth += '%' ;
+
+	SetAttribute( table, 'width'		, sWidth ) ;
+	SetAttribute( table, 'height'		, GetE('txtHeight').value ) ;
+	SetAttribute( table, 'border'		, GetE('txtBorder').value ) ;
+	SetAttribute( table, 'align'		, GetE('selAlignment').value ) ;
+	SetAttribute( table, 'cellPadding'	, GetE('txtCellPadding').value ) ;
+	SetAttribute( table, 'cellSpacing'	, GetE('txtCellSpacing').value ) ;
+	SetAttribute( table, 'summary'		, GetE('txtSummary').value ) ;
+
+	var eCaption = oEditor.FCKDomTools.GetFirstChild( table, 'CAPTION' ) ;
+
+	if ( document.getElementById('txtCaption').value != '')
+	{
+		if ( !eCaption )
+		{
+			eCaption = oEditor.FCK.EditorDocument.createElement( 'CAPTION' ) ;
+			table.insertBefore( eCaption, table.firstChild ) ;
+		}
+
+		eCaption.innerHTML = document.getElementById('txtCaption').value ;
+	}
+	else if ( bExists && eCaption )
+		eCaption.parentNode.removeChild( eCaption ) ;
+
+	if (! bExists)
+	{
+		var iRows = document.getElementById('txtRows').value ;
+		var iCols = document.getElementById('txtColumns').value ;
+
+		for ( var r = 0 ; r < iRows ; r++ )
+		{
+			var oRow = table.insertRow(-1) ;
+			for ( var c = 0 ; c < iCols ; c++ )
+			{
+				var oCell = oRow.insertCell(-1) ;
+				if ( oEditor.FCKBrowserInfo.IsGeckoLike )
+					oCell.innerHTML = GECKO_BOGUS ;
+				//oCell.innerHTML = "&nbsp;" ;
+			}
+		}
+
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+		oEditor.FCK.InsertElement( table ) ;
+	}
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table id="otable" cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
+		<tr>
+			<td>
+				<table cellspacing="1" cellpadding="1" width="100%" border="0">
+					<tr>
+						<td valign="top">
+							<table cellspacing="0" cellpadding="0" border="0">
+								<tr>
+									<td>
+										<span fcklang="DlgTableRows">Rows</span>:</td>
+									<td>
+										&nbsp;<input id="txtRows" type="text" maxlength="3" size="2" value="3" name="txtRows"
+											onkeypress="return IsDigit(event);" /></td>
+								</tr>
+								<tr>
+									<td>
+										<span fcklang="DlgTableColumns">Columns</span>:</td>
+									<td>
+										&nbsp;<input id="txtColumns" type="text" maxlength="2" size="2" value="2" name="txtColumns"
+											onkeypress="return IsDigit(event);" /></td>
+								</tr>
+								<tr>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+								</tr>
+								<tr>
+									<td>
+										<span fcklang="DlgTableBorder">Border size</span>:</td>
+									<td>
+										&nbsp;<input id="txtBorder" type="text" maxlength="2" size="2" value="1" name="txtBorder"
+											onkeypress="return IsDigit(event);" /></td>
+								</tr>
+								<tr>
+									<td>
+										<span fcklang="DlgTableAlign">Alignment</span>:</td>
+									<td>
+										&nbsp;<select id="selAlignment" name="selAlignment">
+											<option fcklang="DlgTableAlignNotSet" value="" selected="selected">&lt;Not set&gt;</option>
+											<option fcklang="DlgTableAlignLeft" value="left">Left</option>
+											<option fcklang="DlgTableAlignCenter" value="center">Center</option>
+											<option fcklang="DlgTableAlignRight" value="right">Right</option>
+										</select></td>
+								</tr>
+							</table>
+						</td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td align="right" valign="top">
+							<table cellspacing="0" cellpadding="0" border="0">
+								<tr>
+									<td>
+										<span fcklang="DlgTableWidth">Width</span>:</td>
+									<td>
+										&nbsp;<input id="txtWidth" type="text" maxlength="4" size="3" value="200" name="txtWidth"
+											onkeypress="return IsDigit(event);" /></td>
+									<td>
+										&nbsp;<select id="selWidthType" name="selWidthType">
+											<option fcklang="DlgTableWidthPx" value="pixels" selected="selected">pixels</option>
+											<option fcklang="DlgTableWidthPc" value="percent">percent</option>
+										</select></td>
+								</tr>
+								<tr>
+									<td>
+										<span fcklang="DlgTableHeight">Height</span>:</td>
+									<td>
+										&nbsp;<input id="txtHeight" type="text" maxlength="4" size="3" name="txtHeight" onkeypress="return IsDigit(event);" /></td>
+									<td>
+										&nbsp;<span fcklang="DlgTableWidthPx">pixels</span></td>
+								</tr>
+								<tr>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgTableCellSpace">Cell spacing</span>:</td>
+									<td>
+										&nbsp;<input id="txtCellSpacing" type="text" maxlength="2" size="2" value="1" name="txtCellSpacing"
+											onkeypress="return IsDigit(event);" /></td>
+									<td>
+										&nbsp;</td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgTableCellPad">Cell padding</span>:</td>
+									<td>
+										&nbsp;<input id="txtCellPadding" type="text" maxlength="2" size="2" value="1" name="txtCellPadding"
+											onkeypress="return IsDigit(event);" /></td>
+									<td>
+										&nbsp;</td>
+								</tr>
+							</table>
+						</td>
+					</tr>
+				</table>
+				<table cellspacing="0" cellpadding="0" width="100%" border="0">
+					<tr>
+						<td nowrap="nowrap">
+							<span fcklang="DlgTableCaption">Caption</span>:&nbsp;</td>
+						<td>
+							&nbsp;</td>
+						<td width="100%" nowrap="nowrap">
+							<input id="txtCaption" type="text" style="width: 100%" /></td>
+					</tr>
+					<tr>
+						<td nowrap="nowrap">
+							<span fcklang="DlgTableSummary">Summary</span>:&nbsp;</td>
+						<td>
+							&nbsp;</td>
+						<td width="100%" nowrap="nowrap">
+							<input id="txtSummary" type="text" style="width: 100%" /></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_tablecell.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_tablecell.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_tablecell.html	(revision 795)
@@ -0,0 +1,255 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Cell properties dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Table Cell Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+// Array of selected Cells
+var aCells = oEditor.FCKTableHandler.GetSelectedCells() ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+	SetStartupValue() ;
+
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function SetStartupValue()
+{
+	if ( aCells.length > 0 )
+	{
+		var oCell = aCells[0] ;
+		var iWidth = GetAttribute( oCell, 'width' ) ;
+
+		if ( iWidth.indexOf && iWidth.indexOf( '%' ) >= 0 )
+		{
+			iWidth = iWidth.substr( 0, iWidth.length - 1 ) ;
+			GetE('selWidthType').value = 'percent' ;
+		}
+
+		if ( oCell.attributes['noWrap'] != null && oCell.attributes['noWrap'].specified )
+			GetE('selWordWrap').value = !oCell.noWrap ;
+
+		GetE('txtWidth').value			= iWidth ;
+		GetE('txtHeight').value			= GetAttribute( oCell, 'height' ) ;
+		GetE('selHAlign').value			= GetAttribute( oCell, 'align' ) ;
+		GetE('selVAlign').value			= GetAttribute( oCell, 'vAlign' ) ;
+		GetE('txtRowSpan').value		= GetAttribute( oCell, 'rowSpan' ) ;
+		GetE('txtCollSpan').value		= GetAttribute( oCell, 'colSpan' ) ;
+		GetE('txtBackColor').value		= GetAttribute( oCell, 'bgColor' ) ;
+		GetE('txtBorderColor').value	= GetAttribute( oCell, 'borderColor' ) ;
+//		GetE('cmbFontStyle').value		= oCell.className ;
+	}
+}
+
+// Fired when the user press the OK button
+function Ok()
+{
+	for( i = 0 ; i < aCells.length ; i++ )
+	{
+		if ( GetE('txtWidth').value.length > 0 )
+			aCells[i].width	= GetE('txtWidth').value + ( GetE('selWidthType').value == 'percent' ? '%' : '') ;
+		else
+			aCells[i].removeAttribute( 'width', 0 ) ;
+
+		if ( GetE('selWordWrap').value == 'false' )
+			aCells[i].noWrap = true ;
+		else
+			aCells[i].removeAttribute( 'noWrap' ) ;
+
+		SetAttribute( aCells[i], 'height'		, GetE('txtHeight').value ) ;
+		SetAttribute( aCells[i], 'align'		, GetE('selHAlign').value ) ;
+		SetAttribute( aCells[i], 'vAlign'		, GetE('selVAlign').value ) ;
+		SetAttribute( aCells[i], 'rowSpan'		, GetE('txtRowSpan').value ) ;
+		SetAttribute( aCells[i], 'colSpan'		, GetE('txtCollSpan').value ) ;
+		SetAttribute( aCells[i], 'bgColor'		, GetE('txtBackColor').value ) ;
+		SetAttribute( aCells[i], 'borderColor'	, GetE('txtBorderColor').value ) ;
+//		SetAttribute( aCells[i], 'className'	, GetE('cmbFontStyle').value ) ;
+	}
+
+	return true ;
+}
+
+function SelectBackColor( color )
+{
+	if ( color && color.length > 0 )
+		GetE('txtBackColor').value = color ;
+}
+
+function SelectBorderColor( color )
+{
+	if ( color && color.length > 0 )
+		GetE('txtBorderColor').value = color ;
+}
+
+function SelectColor( wich )
+{
+	oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', oEditor.FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, wich == 'Back' ? SelectBackColor : SelectBorderColor, window ) ;
+}
+
+	</script>
+</head>
+<body scroll="no" style="overflow: hidden">
+	<table cellspacing="0" cellpadding="0" width="100%" border="0" height="100%">
+		<tr>
+			<td>
+				<table cellspacing="1" cellpadding="1" width="100%" border="0">
+					<tr>
+						<td>
+							<table cellspacing="0" cellpadding="0" border="0">
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellWidth">Width</span>:</td>
+									<td>
+										&nbsp;<input onkeypress="return IsDigit(event);" id="txtWidth" type="text" maxlength="4"
+											size="3" name="txtWidth" />&nbsp;<select id="selWidthType" name="selWidthType">
+												<option fcklang="DlgCellWidthPx" value="pixels" selected="selected">pixels</option>
+												<option fcklang="DlgCellWidthPc" value="percent">percent</option>
+											</select></td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellHeight">Height</span>:</td>
+									<td>
+										&nbsp;<input id="txtHeight" type="text" maxlength="4" size="3" name="txtHeight" onkeypress="return IsDigit(event);" />&nbsp;<span
+											fcklang="DlgCellWidthPx">pixels</span></td>
+								</tr>
+								<tr>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellWordWrap">Word Wrap</span>:</td>
+									<td>
+										&nbsp;<select id="selWordWrap" name="selAlignment">
+											<option fcklang="DlgCellWordWrapYes" value="true" selected="selected">Yes</option>
+											<option fcklang="DlgCellWordWrapNo" value="false">No</option>
+										</select></td>
+								</tr>
+								<tr>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellHorAlign">Horizontal Alignment</span>:</td>
+									<td>
+										&nbsp;<select id="selHAlign" name="selAlignment">
+											<option fcklang="DlgCellHorAlignNotSet" value="" selected>&lt;Not set&gt;</option>
+											<option fcklang="DlgCellHorAlignLeft" value="left">Left</option>
+											<option fcklang="DlgCellHorAlignCenter" value="center">Center</option>
+											<option fcklang="DlgCellHorAlignRight" value="right">Right</option>
+										</select></td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellVerAlign">Vertical Alignment</span>:</td>
+									<td>
+										&nbsp;<select id="selVAlign" name="selAlignment">
+											<option fcklang="DlgCellVerAlignNotSet" value="" selected>&lt;Not set&gt;</option>
+											<option fcklang="DlgCellVerAlignTop" value="top">Top</option>
+											<option fcklang="DlgCellVerAlignMiddle" value="middle">Middle</option>
+											<option fcklang="DlgCellVerAlignBottom" value="bottom">Bottom</option>
+											<option fcklang="DlgCellVerAlignBaseline" value="baseline">Baseline</option>
+										</select></td>
+								</tr>
+							</table>
+						</td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td align="right">
+							<table cellspacing="0" cellpadding="0" border="0">
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellRowSpan">Rows Span</span>:</td>
+									<td>
+										&nbsp;
+										<input onkeypress="return IsDigit(event);" id="txtRowSpan" type="text" maxlength="3" size="2"
+											name="txtRows"></td>
+									<td>
+									</td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellCollSpan">Columns Span</span>:</td>
+									<td>
+										&nbsp;
+										<input onkeypress="return IsDigit(event);" id="txtCollSpan" type="text" maxlength="2"
+											size="2" name="txtColumns"></td>
+									<td>
+									</td>
+								</tr>
+								<tr>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+									<td>
+										&nbsp;</td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellBackColor">Background Color</span>:</td>
+									<td>
+										&nbsp;<input id="txtBackColor" type="text" size="8" name="txtCellSpacing"></td>
+									<td>
+										&nbsp;
+										<input type="button" fcklang="DlgCellBtnSelect" value="Select..." onclick="SelectColor( 'Back' )"></td>
+								</tr>
+								<tr>
+									<td nowrap="nowrap">
+										<span fcklang="DlgCellBorderColor">Border Color</span>:</td>
+									<td>
+										&nbsp;<input id="txtBorderColor" type="text" size="8" name="txtCellPadding" /></td>
+									<td>
+										&nbsp;
+										<input type="button" fcklang="DlgCellBtnSelect" value="Select..." onclick="SelectColor( 'Border' )" /></td>
+								</tr>
+							</table>
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_textfield.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_textfield.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_textfield.html	(revision 795)
@@ -0,0 +1,139 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Text field dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl && oActiveEl.tagName == 'INPUT' && ( oActiveEl.type == 'text' || oActiveEl.type == 'password' ) )
+	{
+		GetE('txtName').value	= oActiveEl.name ;
+		GetE('txtValue').value	= oActiveEl.value ;
+		GetE('txtSize').value	= GetAttribute( oActiveEl, 'size' ) ;
+		GetE('txtMax').value	= GetAttribute( oActiveEl, 'maxLength' ) ;
+		GetE('txtType').value	= oActiveEl.type ;
+
+		GetE('txtType').disabled = true ;
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( isNaN( GetE('txtMax').value ) || GetE('txtMax').value < 0 )
+	{
+		alert( "Maximum characters must be a positive number." ) ;
+		GetE('txtMax').focus() ;
+		return false ;
+	}
+	else if( isNaN( GetE('txtSize').value ) || GetE('txtSize').value < 0 )
+	{
+		alert( "Width must be a positive number." ) ;
+		GetE('txtSize').focus() ;
+		return false ;
+	}
+
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+		oActiveEl.type = GetE('txtType').value ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+	}
+
+	oActiveEl.name = GetE('txtName').value ;
+	SetAttribute( oActiveEl, 'value'	, GetE('txtValue').value ) ;
+	SetAttribute( oActiveEl, 'size'		, GetE('txtSize').value ) ;
+	SetAttribute( oActiveEl, 'maxlength', GetE('txtMax').value ) ;
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table width="100%" style="height: 100%">
+		<tr>
+			<td align="center">
+				<table cellspacing="0" cellpadding="0" border="0">
+					<tr>
+						<td>
+							<span fcklang="DlgTextName">Name</span><br />
+							<input id="txtName" type="text" size="20" />
+						</td>
+						<td>
+						</td>
+						<td>
+							<span fcklang="DlgTextValue">Value</span><br />
+							<input id="txtValue" type="text" size="25" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgTextCharWidth">Character Width</span><br />
+							<input id="txtSize" type="text" size="5" />
+						</td>
+						<td>
+						</td>
+						<td>
+							<span fcklang="DlgTextMaxChars">Maximum Characters</span><br />
+							<input id="txtMax" type="text" size="5" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgTextType">Type</span><br />
+							<select id="txtType">
+								<option value="text" selected="selected" fcklang="DlgTextTypeText">Text</option>
+								<option value="password" fcklang="DlgTextTypePass">Password</option>
+							</select>
+						</td>
+						<td>
+							&nbsp;</td>
+						<td>
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_docprops.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_docprops.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_docprops.html	(revision 795)
@@ -0,0 +1,600 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Link dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'General'		, FCKLang.DlgDocGeneralTab ) ;
+window.parent.AddTab( 'Background'	, FCKLang.DlgDocBackTab ) ;
+window.parent.AddTab( 'Colors'		, FCKLang.DlgDocColorsTab ) ;
+window.parent.AddTab( 'Meta'		, FCKLang.DlgDocMetaTab ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+	ShowE( 'divGeneral'		, ( tabCode == 'General' ) ) ;
+	ShowE( 'divBackground'	, ( tabCode == 'Background' ) ) ;
+	ShowE( 'divColors'		, ( tabCode == 'Colors' ) ) ;
+	ShowE( 'divMeta'		, ( tabCode == 'Meta' ) ) ;
+
+	ShowE( 'ePreview'		, ( tabCode == 'Background' || tabCode == 'Colors' ) ) ;
+}
+
+//#### Get Base elements from the document: BEGIN
+
+// The HTML element of the document.
+var oHTML = FCK.EditorDocument.getElementsByTagName('html')[0] ;
+
+// The HEAD element of the document.
+var oHead = oHTML.getElementsByTagName('head')[0] ;
+
+var oBody = FCK.EditorDocument.body ;
+
+// This object contains all META tags defined in the document.
+var oMetaTags = new Object() ;
+
+// Get all META tags defined in the document.
+AppendMetaCollection( oMetaTags, oHead.getElementsByTagName('meta') ) ;
+AppendMetaCollection( oMetaTags, oHead.getElementsByTagName('fck:meta') ) ;
+
+function AppendMetaCollection( targetObject, metaCollection )
+{
+	// Loop throw all METAs and put it in the HashTable.
+	for ( var i = 0 ; i < metaCollection.length ; i++ )
+	{
+		// Try to get the "name" attribute.
+		var sName = GetAttribute( metaCollection[i], 'name', GetAttribute( metaCollection[i], '___fcktoreplace:name', '' ) ) ;
+
+		// If no "name", try with the "http-equiv" attribute.
+		if ( sName.length == 0 )
+		{
+			if ( oEditor.FCKBrowserInfo.IsIE )
+			{
+				// Get the http-equiv value from the outerHTML.
+				var oHttpEquivMatch = metaCollection[i].outerHTML.match( oEditor.FCKRegexLib.MetaHttpEquiv ) ;
+				if ( oHttpEquivMatch )
+					sName = oHttpEquivMatch[1] ;
+			}
+			else
+				sName = GetAttribute( metaCollection[i], 'http-equiv', '' ) ;
+		}
+
+		if ( sName.length > 0 )
+			targetObject[ sName.toLowerCase() ] = metaCollection[i] ;
+	}
+}
+
+//#### END
+
+// Set a META tag in the document.
+function SetMetadata( name, content, isHttp )
+{
+	if ( content.length == 0 )
+	{
+		RemoveMetadata( name ) ;
+		return ;
+	}
+
+	var oMeta = oMetaTags[ name.toLowerCase() ] ;
+
+	if ( !oMeta )
+	{
+		oMeta = oHead.appendChild( FCK.EditorDocument.createElement('META') ) ;
+
+		if ( isHttp )
+			SetAttribute( oMeta, 'http-equiv', name ) ;
+		else
+		{
+			// On IE, it is not possible to set the "name" attribute of the META tag.
+			// So a temporary attribute is used and it is replaced when getting the
+			// editor's HTML/XHTML value. This is sad, I know :(
+			if ( oEditor.FCKBrowserInfo.IsIE )
+				SetAttribute( oMeta, '___fcktoreplace:name', name ) ;
+			else
+				SetAttribute( oMeta, 'name', name ) ;
+		}
+
+		oMetaTags[ name.toLowerCase() ] = oMeta ;
+	}
+
+	SetAttribute( oMeta, 'content', content ) ;
+//	oMeta.content = content ;
+}
+
+function RemoveMetadata( name )
+{
+	var oMeta = oMetaTags[ name.toLowerCase() ] ;
+
+	if ( oMeta && oMeta != null )
+	{
+		oMeta.parentNode.removeChild( oMeta ) ;
+		oMetaTags[ name.toLowerCase() ] = null ;
+	}
+}
+
+function GetMetadata( name )
+{
+	var oMeta = oMetaTags[ name.toLowerCase() ] ;
+
+	if ( oMeta && oMeta != null )
+		return oMeta.getAttribute( 'content', 2 ) ;
+	else
+		return '' ;
+}
+
+window.onload = function ()
+{
+	// Show/Hide the "Browse Server" button.
+	GetE('tdBrowse').style.display = oEditor.FCKConfig.ImageBrowser ? "" : "none";
+
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+	FillFields() ;
+
+	UpdatePreview() ;
+
+	// Show the "Ok" button.
+	window.parent.SetOkButton( true ) ;
+
+	window.parent.SetAutoSize( true ) ;
+}
+
+function FillFields()
+{
+	// ### General Info
+	GetE('txtPageTitle').value = FCK.EditorDocument.title ;
+
+	GetE('selDirection').value	= GetAttribute( oHTML, 'dir', '' ) ;
+	GetE('txtLang').value		= GetAttribute( oHTML, 'xml:lang', GetAttribute( oHTML, 'lang', '' ) ) ;	// "xml:lang" takes precedence to "lang".
+
+	// Character Set Encoding.
+//	if ( oEditor.FCKBrowserInfo.IsIE )
+//		var sCharSet = FCK.EditorDocument.charset ;
+//	else
+		var sCharSet = GetMetadata( 'Content-Type' ) ;
+
+	if ( sCharSet != null && sCharSet.length > 0 )
+	{
+//		if ( !oEditor.FCKBrowserInfo.IsIE )
+			sCharSet = sCharSet.match( /[^=]*$/ ) ;
+
+		GetE('selCharSet').value = sCharSet ;
+
+		if ( GetE('selCharSet').selectedIndex == -1 )
+		{
+			GetE('selCharSet').value = '...' ;
+			GetE('txtCustomCharSet').value = sCharSet ;
+
+			CheckOther( GetE('selCharSet'), 'txtCustomCharSet' ) ;
+		}
+	}
+
+	// Document Type.
+	if ( FCK.DocTypeDeclaration && FCK.DocTypeDeclaration.length > 0 )
+	{
+		GetE('selDocType').value = FCK.DocTypeDeclaration ;
+
+		if ( GetE('selDocType').selectedIndex == -1 )
+		{
+			GetE('selDocType').value = '...' ;
+			GetE('txtDocType').value = FCK.DocTypeDeclaration ;
+
+			CheckOther( GetE('selDocType'), 'txtDocType' ) ;
+		}
+	}
+
+	// Document Type.
+	GetE('chkIncXHTMLDecl').checked = ( FCK.XmlDeclaration && FCK.XmlDeclaration.length > 0 ) ;
+
+	// ### Background
+	GetE('txtBackColor').value = GetAttribute( oBody, 'bgColor'		, '' ) ;
+	GetE('txtBackImage').value = GetAttribute( oBody, 'background'	, '' ) ;
+	GetE('chkBackNoScroll').checked = ( GetAttribute( oBody, 'bgProperties', '' ).toLowerCase() == 'fixed' ) ;
+
+	// ### Colors
+	GetE('txtColorText').value		= GetAttribute( oBody, 'text'	, '' ) ;
+	GetE('txtColorLink').value		= GetAttribute( oBody, 'link'	, '' ) ;
+	GetE('txtColorVisited').value	= GetAttribute( oBody, 'vLink'	, '' ) ;
+	GetE('txtColorActive').value	= GetAttribute( oBody, 'aLink'	, '' ) ;
+
+	// ### Margins
+	GetE('txtMarginTop').value		= GetAttribute( oBody, 'topMargin'		, '' ) ;
+	GetE('txtMarginLeft').value		= GetAttribute( oBody, 'leftMargin'		, '' ) ;
+	GetE('txtMarginRight').value	= GetAttribute( oBody, 'rightMargin'	, '' ) ;
+	GetE('txtMarginBottom').value	= GetAttribute( oBody, 'bottomMargin'	, '' ) ;
+
+	// ### Meta Data
+	GetE('txtMetaKeywords').value		= GetMetadata( 'keywords' ) ;
+	GetE('txtMetaDescription').value	= GetMetadata( 'description' ) ;
+	GetE('txtMetaAuthor').value			= GetMetadata( 'author' ) ;
+	GetE('txtMetaCopyright').value		= GetMetadata( 'copyright' ) ;
+}
+
+// Called when the "Ok" button is clicked.
+function Ok()
+{
+	// ### General Info
+	FCK.EditorDocument.title = GetE('txtPageTitle').value ;
+
+	var oHTML = FCK.EditorDocument.getElementsByTagName('html')[0] ;
+
+	SetAttribute( oHTML, 'dir'		, GetE('selDirection').value ) ;
+	SetAttribute( oHTML, 'lang'		, GetE('txtLang').value ) ;
+	SetAttribute( oHTML, 'xml:lang'	, GetE('txtLang').value ) ;
+
+	// Character Set Enconding.
+	var sCharSet = GetE('selCharSet').value ;
+	if ( sCharSet == '...' )
+		sCharSet = GetE('txtCustomCharSet').value ;
+
+	if ( sCharSet.length > 0 )
+			sCharSet = 'text/html; charset=' + sCharSet ;
+
+//	if ( oEditor.FCKBrowserInfo.IsIE )
+//		FCK.EditorDocument.charset = sCharSet ;
+//	else
+		SetMetadata( 'Content-Type', sCharSet, true ) ;
+
+	// Document Type
+	var sDocType = GetE('selDocType').value ;
+	if ( sDocType == '...' )
+		sDocType = GetE('txtDocType').value ;
+
+	FCK.DocTypeDeclaration = sDocType ;
+
+	// XHTML Declarations.
+	if ( GetE('chkIncXHTMLDecl').checked )
+	{
+		if ( sCharSet.length == 0 )
+			sCharSet = 'utf-8' ;
+
+		FCK.XmlDeclaration = '<?xml version="1.0" encoding="' + sCharSet + '"?>' ;
+
+		SetAttribute( oHTML, 'xmlns', 'http://www.w3.org/1999/xhtml' ) ;
+	}
+	else
+	{
+		FCK.XmlDeclaration = null ;
+		oHTML.removeAttribute( 'xmlns', 0 ) ;
+	}
+
+	// ### Background
+	SetAttribute( oBody, 'bgcolor'		, GetE('txtBackColor').value ) ;
+	SetAttribute( oBody, 'background'	, GetE('txtBackImage').value ) ;
+	SetAttribute( oBody, 'bgproperties'	, GetE('chkBackNoScroll').checked ? 'fixed' : '' ) ;
+
+	// ### Colors
+	SetAttribute( oBody, 'text'	, GetE('txtColorText').value ) ;
+	SetAttribute( oBody, 'link'	, GetE('txtColorLink').value ) ;
+	SetAttribute( oBody, 'vlink', GetE('txtColorVisited').value ) ;
+	SetAttribute( oBody, 'alink', GetE('txtColorActive').value ) ;
+
+	// ### Margins
+	SetAttribute( oBody, 'topmargin'	, GetE('txtMarginTop').value ) ;
+	SetAttribute( oBody, 'leftmargin'	, GetE('txtMarginLeft').value ) ;
+	SetAttribute( oBody, 'rightmargin'	, GetE('txtMarginRight').value ) ;
+	SetAttribute( oBody, 'bottommargin'	, GetE('txtMarginBottom').value ) ;
+
+	// ### Meta data
+	SetMetadata( 'keywords'		, GetE('txtMetaKeywords').value ) ;
+	SetMetadata( 'description'	, GetE('txtMetaDescription').value ) ;
+	SetMetadata( 'author'		, GetE('txtMetaAuthor').value ) ;
+	SetMetadata( 'copyright'	, GetE('txtMetaCopyright').value ) ;
+
+	return true ;
+}
+
+var bPreviewIsLoaded = false ;
+var oPreviewWindow ;
+var oPreviewBody ;
+
+// Called by the Preview page when loaded.
+function OnPreviewLoad( previewWindow, previewBody )
+{
+	oPreviewWindow	= previewWindow ;
+	oPreviewBody	= previewBody ;
+
+	bPreviewIsLoaded = true ;
+	UpdatePreview() ;
+}
+
+function UpdatePreview()
+{
+	if ( !bPreviewIsLoaded )
+		return ;
+
+	// ### Background
+	SetAttribute( oPreviewBody, 'bgcolor'		, GetE('txtBackColor').value ) ;
+	SetAttribute( oPreviewBody, 'background'	, GetE('txtBackImage').value ) ;
+	SetAttribute( oPreviewBody, 'bgproperties'	, GetE('chkBackNoScroll').checked ? 'fixed' : '' ) ;
+
+	// ### Colors
+	SetAttribute( oPreviewBody, 'text', GetE('txtColorText').value ) ;
+
+	oPreviewWindow.SetLinkColor( GetE('txtColorLink').value ) ;
+	oPreviewWindow.SetVisitedColor( GetE('txtColorVisited').value ) ;
+	oPreviewWindow.SetActiveColor( GetE('txtColorActive').value ) ;
+}
+
+function CheckOther( combo, txtField )
+{
+	var bNotOther = ( combo.value != '...' ) ;
+
+	GetE(txtField).style.backgroundColor = ( bNotOther ? '#cccccc' : '' ) ;
+	GetE(txtField).disabled = bNotOther ;
+}
+
+function SetColor( inputId, color )
+{
+	GetE( inputId ).value = color + '' ;
+	UpdatePreview() ;
+}
+
+function SelectBackColor( color )		{ SetColor('txtBackColor', color ) ; }
+function SelectColorText( color )		{ SetColor('txtColorText', color ) ; }
+function SelectColorLink( color )		{ SetColor('txtColorLink', color ) ; }
+function SelectColorVisited( color )	{ SetColor('txtColorVisited', color ) ; }
+function SelectColorActive( color )		{ SetColor('txtColorActive', color ) ; }
+
+function SelectColor( wich )
+{
+	switch ( wich )
+	{
+		case 'Back'			: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectBackColor, window ) ; return ;
+		case 'ColorText'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorText, window ) ; return ;
+		case 'ColorLink'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorLink, window ) ; return ;
+		case 'ColorVisited'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorVisited, window ) ; return ;
+		case 'ColorActive'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorActive, window ) ; return ;
+	}
+}
+
+function BrowseServerBack()
+{
+	OpenFileBrowser( FCKConfig.ImageBrowserURL, FCKConfig.ImageBrowserWindowWidth, FCKConfig.ImageBrowserWindowHeight ) ;
+}
+
+function SetUrl( url )
+{
+	GetE('txtBackImage').value = url ;
+	UpdatePreview() ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
+		<tr>
+			<td valign="top" style="height: 100%">
+				<div id="divGeneral">
+					<span fcklang="DlgDocPageTitle">Page Title</span><br />
+					<input id="txtPageTitle" style="width: 100%" type="text" />
+					<br />
+					<table cellspacing="0" cellpadding="0" border="0">
+						<tr>
+							<td>
+								<span fcklang="DlgDocLangDir">Language Direction</span><br />
+								<select id="selDirection">
+									<option value="" selected="selected"></option>
+									<option value="ltr" fcklang="DlgDocLangDirLTR">Left to Right (LTR)</option>
+									<option value="rtl" fcklang="DlgDocLangDirRTL">Right to Left (RTL)</option>
+								</select>
+							</td>
+							<td>
+								&nbsp;&nbsp;&nbsp;</td>
+							<td>
+								<span fcklang="DlgDocLangCode">Language Code</span><br />
+								<input id="txtLang" type="text" />
+							</td>
+						</tr>
+					</table>
+					<br />
+					<table cellspacing="0" cellpadding="0" width="100%" border="0">
+						<tr>
+							<td style="white-space: nowrap">
+								<span fcklang="DlgDocCharSet">Character Set Encoding</span><br />
+								<select id="selCharSet" onchange="CheckOther( this, 'txtCustomCharSet' );">
+									<option value="" selected="selected"></option>
+									<option value="us-ascii">ASCII</option>
+									<option fcklang="DlgDocCharSetCE" value="iso-8859-2">Central European</option>
+									<option fcklang="DlgDocCharSetCT" value="big5">Chinese Traditional (Big5)</option>
+									<option fcklang="DlgDocCharSetCR" value="iso-8859-5">Cyrillic</option>
+									<option fcklang="DlgDocCharSetGR" value="iso-8859-7">Greek</option>
+									<option fcklang="DlgDocCharSetJP" value="iso-2022-jp">Japanese</option>
+									<option fcklang="DlgDocCharSetKR" value="iso-2022-kr">Korean</option>
+									<option fcklang="DlgDocCharSetTR" value="iso-8859-9">Turkish</option>
+									<option fcklang="DlgDocCharSetUN" value="utf-8">Unicode (UTF-8)</option>
+									<option fcklang="DlgDocCharSetWE" value="iso-8859-1">Western European</option>
+									<option fcklang="DlgOpOther" value="...">&lt;Other&gt;</option>
+								</select>
+							</td>
+							<td>
+								&nbsp;&nbsp;&nbsp;</td>
+							<td width="100%">
+								<span fcklang="DlgDocCharSetOther">Other Character Set Encoding</span><br />
+								<input id="txtCustomCharSet" style="width: 100%; background-color: #cccccc" disabled="disabled"
+									type="text" />
+							</td>
+						</tr>
+						<tr>
+							<td colspan="3">
+								&nbsp;</td>
+						</tr>
+						<tr>
+							<td nowrap="nowrap">
+								<span fcklang="DlgDocDocType">Document Type Heading</span><br />
+								<select id="selDocType" name="selDocType" onchange="CheckOther( this, 'txtDocType' );">
+									<option value="" selected="selected"></option>
+									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'>HTML
+										4.01 Transitional</option>
+									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'>
+										HTML 4.01 Strict</option>
+									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'>
+										HTML 4.01 Frameset</option>
+									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'>
+										XHTML 1.0 Transitional</option>
+									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'>
+										XHTML 1.0 Strict</option>
+									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'>
+										XHTML 1.0 Frameset</option>
+									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'>
+										XHTML 1.1</option>
+									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'>HTML 3.2</option>
+									<option value='<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">'>HTML 2.0</option>
+									<option value="..." fcklang="DlgOpOther">&lt;Other&gt;</option>
+								</select>
+							</td>
+							<td>
+							</td>
+							<td width="100%">
+								<span fcklang="DlgDocDocTypeOther">Other Document Type Heading</span><br />
+								<input id="txtDocType" style="width: 100%; background-color: #cccccc" disabled="disabled"
+									type="text" />
+							</td>
+						</tr>
+					</table>
+					<br />
+					<input id="chkIncXHTMLDecl" type="checkbox" />
+					<label for="chkIncXHTMLDecl" fcklang="DlgDocIncXHTML">
+						Include XHTML Declarations</label>
+				</div>
+				<div id="divBackground" style="display: none">
+					<span fcklang="DlgDocBgColor">Background Color</span><br />
+					<input id="txtBackColor" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" />&nbsp;<input
+						id="btnSelBackColor" onclick="SelectColor( 'Back' )" type="button" value="Select..."
+						fcklang="DlgCellBtnSelect" /><br />
+					<br />
+					<span fcklang="DlgDocBgImage">Background Image URL</span><br />
+					<table cellspacing="0" cellpadding="0" width="100%" border="0">
+						<tr>
+							<td width="100%">
+								<input id="txtBackImage" style="width: 100%" type="text" onchange="UpdatePreview();"
+									onkeyup="UpdatePreview();" /></td>
+							<td id="tdBrowse" nowrap="nowrap">
+								&nbsp;<input id="btnBrowse" onclick="BrowseServerBack();" type="button" fcklang="DlgBtnBrowseServer"
+									value="Browse Server" /></td>
+						</tr>
+					</table>
+					<input id="chkBackNoScroll" type="checkbox" onclick="UpdatePreview();" />
+					<label for="chkBackNoScroll" fcklang="DlgDocBgNoScroll">
+						Nonscrolling Background</label>
+				</div>
+				<div id="divColors" style="display: none">
+					<table cellspacing="0" cellpadding="0" width="100%" border="0">
+						<tr>
+							<td>
+								<span fcklang="DlgDocCText">Text</span><br />
+								<input id="txtColorText" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+									onclick="SelectColor( 'ColorText' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+								<br />
+								<span fcklang="DlgDocCLink">Link</span><br />
+								<input id="txtColorLink" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+									onclick="SelectColor( 'ColorLink' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+								<br />
+								<span fcklang="DlgDocCVisited">Visited Link</span><br />
+								<input id="txtColorVisited" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+									onclick="SelectColor( 'ColorVisited' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+								<br />
+								<span fcklang="DlgDocCActive">Active Link</span><br />
+								<input id="txtColorActive" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+									onclick="SelectColor( 'ColorActive' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+							</td>
+							<td valign="middle" align="center">
+								<table cellspacing="2" cellpadding="0" border="0">
+									<tr>
+										<td>
+											<span fcklang="DlgDocMargins">Page Margins</span></td>
+									</tr>
+									<tr>
+										<td style="border: #000000 1px solid; padding: 5px">
+											<table cellpadding="0" cellspacing="0" border="0" dir="ltr">
+												<tr>
+													<td align="center" colspan="3">
+														<span fcklang="DlgDocMaTop">Top</span><br />
+														<input id="txtMarginTop" type="text" size="3" />
+													</td>
+												</tr>
+												<tr>
+													<td align="left">
+														<span fcklang="DlgDocMaLeft">Left</span><br />
+														<input id="txtMarginLeft" type="text" size="3" />
+													</td>
+													<td>
+														&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+													<td align="right">
+														<span fcklang="DlgDocMaRight">Right</span><br />
+														<input id="txtMarginRight" type="text" size="3" />
+													</td>
+												</tr>
+												<tr>
+													<td align="center" colspan="3">
+														<span fcklang="DlgDocMaBottom">Bottom</span><br />
+														<input id="txtMarginBottom" type="text" size="3" />
+													</td>
+												</tr>
+											</table>
+										</td>
+									</tr>
+								</table>
+							</td>
+						</tr>
+					</table>
+				</div>
+				<div id="divMeta" style="display: none">
+					<span fcklang="DlgDocMeIndex">Document Indexing Keywords (comma separated)</span><br />
+					<textarea id="txtMetaKeywords" style="width: 100%" rows="2" cols="20"></textarea>
+					<br />
+					<span fcklang="DlgDocMeDescr">Document Description</span><br />
+					<textarea id="txtMetaDescription" style="width: 100%" rows="4" cols="20"></textarea>
+					<br />
+					<span fcklang="DlgDocMeAuthor">Author</span><br />
+					<input id="txtMetaAuthor" style="width: 100%" type="text" /><br />
+					<br />
+					<span fcklang="DlgDocMeCopy">Copyright</span><br />
+					<input id="txtMetaCopyright" type="text" style="width: 100%" />
+				</div>
+			</td>
+		</tr>
+		<tr id="ePreview" style="display: none">
+			<td>
+				<span fcklang="DlgDocPreview">Preview</span><br />
+				<iframe id="frmPreview" src="fck_docprops/fck_document_preview.html" width="100%"
+					height="100"></iframe>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_link/fck_link.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_link/fck_link.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_link/fck_link.js	(revision 795)
@@ -0,0 +1,664 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Scripts related to the Link dialog window (see fck_link.html).
+ */
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'Info', FCKLang.DlgLnkInfoTab ) ;
+
+if ( !FCKConfig.LinkDlgHideTarget )
+	window.parent.AddTab( 'Target', FCKLang.DlgLnkTargetTab, true ) ;
+
+if ( FCKConfig.LinkUpload )
+	window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload, true ) ;
+
+if ( !FCKConfig.LinkDlgHideAdvanced )
+	window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+	ShowE('divInfo'		, ( tabCode == 'Info' ) ) ;
+	ShowE('divTarget'	, ( tabCode == 'Target' ) ) ;
+	ShowE('divUpload'	, ( tabCode == 'Upload' ) ) ;
+	ShowE('divAttribs'	, ( tabCode == 'Advanced' ) ) ;
+
+	window.parent.SetAutoSize( true ) ;
+}
+
+//#### Regular Expressions library.
+var oRegex = new Object() ;
+
+oRegex.UriProtocol = /^(((http|https|ftp|news):\/\/)|mailto:)/gi ;
+
+oRegex.UrlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/gi ;
+
+oRegex.UrlOnChangeTestOther = /^((javascript:)|[#\/\.])/gi ;
+
+oRegex.ReserveTarget = /^_(blank|self|top|parent)$/i ;
+
+oRegex.PopupUri = /^javascript:void\(\s*window.open\(\s*'([^']+)'\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*\)\s*$/ ;
+
+// Accessible popups
+oRegex.OnClickPopup = /^\s*on[cC]lick="\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*"$/ ;
+
+oRegex.PopupFeatures = /(?:^|,)([^=]+)=(\d+|yes|no)/gi ;
+
+//#### Parser Functions
+
+var oParser = new Object() ;
+
+oParser.ParseEMailUrl = function( emailUrl )
+{
+	// Initializes the EMailInfo object.
+	var oEMailInfo = new Object() ;
+	oEMailInfo.Address	= '' ;
+	oEMailInfo.Subject	= '' ;
+	oEMailInfo.Body		= '' ;
+
+	var oParts = emailUrl.match( /^([^\?]+)\??(.+)?/ ) ;
+	if ( oParts )
+	{
+		// Set the e-mail address.
+		oEMailInfo.Address = oParts[1] ;
+
+		// Look for the optional e-mail parameters.
+		if ( oParts[2] )
+		{
+			var oMatch = oParts[2].match( /(^|&)subject=([^&]+)/i ) ;
+			if ( oMatch ) oEMailInfo.Subject = decodeURIComponent( oMatch[2] ) ;
+
+			oMatch = oParts[2].match( /(^|&)body=([^&]+)/i ) ;
+			if ( oMatch ) oEMailInfo.Body = decodeURIComponent( oMatch[2] ) ;
+		}
+	}
+
+	return oEMailInfo ;
+}
+
+oParser.CreateEMailUri = function( address, subject, body )
+{
+	var sBaseUri = 'mailto:' + address ;
+
+	var sParams = '' ;
+
+	if ( subject.length > 0 )
+		sParams = '?subject=' + encodeURIComponent( subject ) ;
+
+	if ( body.length > 0 )
+	{
+		sParams += ( sParams.length == 0 ? '?' : '&' ) ;
+		sParams += 'body=' + encodeURIComponent( body ) ;
+	}
+
+	return sBaseUri + sParams ;
+}
+
+//#### Initialization Code
+
+// oLink: The actual selected link in the editor.
+var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+if ( oLink )
+	FCK.Selection.SelectNode( oLink ) ;
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Fill the Anchor Names and Ids combos.
+	LoadAnchorNamesAndIds() ;
+
+	// Load the selected link information (if any).
+	LoadSelection() ;
+
+	// Update the dialog box.
+	SetLinkType( GetE('cmbLinkType').value ) ;
+
+	// Show/Hide the "Browse Server" button.
+	GetE('divBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ;
+
+	// Show the initial dialog content.
+	GetE('divInfo').style.display = '' ;
+
+	// Set the actual uploader URL.
+	if ( FCKConfig.LinkUpload )
+		GetE('frmUpload').action = FCKConfig.LinkUploadURL ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+}
+
+var bHasAnchors ;
+
+function LoadAnchorNamesAndIds()
+{
+	// Since version 2.0, the anchors are replaced in the DOM by IMGs so the user see the icon
+	// to edit them. So, we must look for that images now.
+	var aAnchors = new Array() ;
+	var i ;
+	var oImages = oEditor.FCK.EditorDocument.getElementsByTagName( 'IMG' ) ;
+	for( i = 0 ; i < oImages.length ; i++ )
+	{
+		if ( oImages[i].getAttribute('_fckanchor') )
+			aAnchors[ aAnchors.length ] = oEditor.FCK.GetRealElement( oImages[i] ) ;
+	}
+
+	// Add also real anchors
+	var oLinks = oEditor.FCK.EditorDocument.getElementsByTagName( 'A' ) ;
+	for( i = 0 ; i < oLinks.length ; i++ )
+	{
+		if ( oLinks[i].name && ( oLinks[i].name.length > 0 ) )
+			aAnchors[ aAnchors.length ] = oLinks[i] ;
+	}
+
+	var aIds = oEditor.FCKTools.GetAllChildrenIds( oEditor.FCK.EditorDocument.body ) ;
+
+	bHasAnchors = ( aAnchors.length > 0 || aIds.length > 0 ) ;
+
+	for ( i = 0 ; i < aAnchors.length ; i++ )
+	{
+		var sName = aAnchors[i].name ;
+		if ( sName && sName.length > 0 )
+			oEditor.FCKTools.AddSelectOption( GetE('cmbAnchorName'), sName, sName ) ;
+	}
+
+	for ( i = 0 ; i < aIds.length ; i++ )
+	{
+		oEditor.FCKTools.AddSelectOption( GetE('cmbAnchorId'), aIds[i], aIds[i] ) ;
+	}
+
+	ShowE( 'divSelAnchor'	, bHasAnchors ) ;
+	ShowE( 'divNoAnchor'	, !bHasAnchors ) ;
+}
+
+function LoadSelection()
+{
+	if ( !oLink ) return ;
+
+	var sType = 'url' ;
+
+	// Get the actual Link href.
+	var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;
+	if ( sHRef == null )
+		sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;
+
+	// Look for a popup javascript link.
+	var oPopupMatch = oRegex.PopupUri.exec( sHRef ) ;
+	if( oPopupMatch )
+	{
+		GetE('cmbTarget').value = 'popup' ;
+		sHRef = oPopupMatch[1] ;
+		FillPopupFields( oPopupMatch[2], oPopupMatch[3] ) ;
+		SetTarget( 'popup' ) ;
+	}
+
+	// Accesible popups, the popup data is in the onclick attribute
+	if ( !oPopupMatch ) {
+		var onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;
+		oPopupMatch = oRegex.OnClickPopup.exec( onclick ) ;
+		if( oPopupMatch )
+		{
+			GetE( 'cmbTarget' ).value = 'popup' ;
+			FillPopupFields( oPopupMatch[1], oPopupMatch[2] ) ;
+			SetTarget( 'popup' ) ;
+		}
+	}
+
+	// Search for the protocol.
+	var sProtocol = oRegex.UriProtocol.exec( sHRef ) ;
+
+	if ( sProtocol )
+	{
+		sProtocol = sProtocol[0].toLowerCase() ;
+		GetE('cmbLinkProtocol').value = sProtocol ;
+
+		// Remove the protocol and get the remainig URL.
+		var sUrl = sHRef.replace( oRegex.UriProtocol, '' ) ;
+
+		if ( sProtocol == 'mailto:' )	// It is an e-mail link.
+		{
+			sType = 'email' ;
+
+			var oEMailInfo = oParser.ParseEMailUrl( sUrl ) ;
+			GetE('txtEMailAddress').value	= oEMailInfo.Address ;
+			GetE('txtEMailSubject').value	= oEMailInfo.Subject ;
+			GetE('txtEMailBody').value		= oEMailInfo.Body ;
+		}
+		else				// It is a normal link.
+		{
+			sType = 'url' ;
+			GetE('txtUrl').value = sUrl ;
+		}
+	}
+	else if ( sHRef.substr(0,1) == '#' && sHRef.length > 1 )	// It is an anchor link.
+	{
+		sType = 'anchor' ;
+		GetE('cmbAnchorName').value = GetE('cmbAnchorId').value = sHRef.substr(1) ;
+	}
+	else					// It is another type of link.
+	{
+		sType = 'url' ;
+
+		GetE('cmbLinkProtocol').value = '' ;
+		GetE('txtUrl').value = sHRef ;
+	}
+
+	if ( !oPopupMatch )
+	{
+		// Get the target.
+		var sTarget = oLink.target ;
+
+		if ( sTarget && sTarget.length > 0 )
+		{
+			if ( oRegex.ReserveTarget.test( sTarget ) )
+			{
+				sTarget = sTarget.toLowerCase() ;
+				GetE('cmbTarget').value = sTarget ;
+			}
+			else
+				GetE('cmbTarget').value = 'frame' ;
+			GetE('txtTargetFrame').value = sTarget ;
+		}
+	}
+
+	// Get Advances Attributes
+	GetE('txtAttId').value			= oLink.id ;
+	GetE('txtAttName').value		= oLink.name ;
+	GetE('cmbAttLangDir').value		= oLink.dir ;
+	GetE('txtAttLangCode').value	= oLink.lang ;
+	GetE('txtAttAccessKey').value	= oLink.accessKey ;
+	GetE('txtAttTabIndex').value	= oLink.tabIndex <= 0 ? '' : oLink.tabIndex ;
+	GetE('txtAttTitle').value		= oLink.title ;
+	GetE('txtAttContentType').value	= oLink.type ;
+	GetE('txtAttCharSet').value		= oLink.charset ;
+
+	var sClass ;
+	if ( oEditor.FCKBrowserInfo.IsIE )
+	{
+		sClass	= oLink.getAttribute('className',2) || '' ;
+		// Clean up temporary classes for internal use:
+		sClass = sClass.replace( FCKRegexLib.FCK_Class, '' ) ;
+
+		GetE('txtAttStyle').value	= oLink.style.cssText ;
+	}
+	else
+	{
+		sClass	= oLink.getAttribute('class',2) || '' ;
+		GetE('txtAttStyle').value	= oLink.getAttribute('style',2) || '' ;
+	}
+	GetE('txtAttClasses').value	= sClass ;
+
+	// Update the Link type combo.
+	GetE('cmbLinkType').value = sType ;
+}
+
+//#### Link type selection.
+function SetLinkType( linkType )
+{
+	ShowE('divLinkTypeUrl'		, (linkType == 'url') ) ;
+	ShowE('divLinkTypeAnchor'	, (linkType == 'anchor') ) ;
+	ShowE('divLinkTypeEMail'	, (linkType == 'email') ) ;
+
+	if ( !FCKConfig.LinkDlgHideTarget )
+		window.parent.SetTabVisibility( 'Target'	, (linkType == 'url') ) ;
+
+	if ( FCKConfig.LinkUpload )
+		window.parent.SetTabVisibility( 'Upload'	, (linkType == 'url') ) ;
+
+	if ( !FCKConfig.LinkDlgHideAdvanced )
+		window.parent.SetTabVisibility( 'Advanced'	, (linkType != 'anchor' || bHasAnchors) ) ;
+
+	if ( linkType == 'email' )
+		window.parent.SetAutoSize( true ) ;
+}
+
+//#### Target type selection.
+function SetTarget( targetType )
+{
+	GetE('tdTargetFrame').style.display	= ( targetType == 'popup' ? 'none' : '' ) ;
+	GetE('tdPopupName').style.display	=
+		GetE('tablePopupFeatures').style.display = ( targetType == 'popup' ? '' : 'none' ) ;
+
+	switch ( targetType )
+	{
+		case "_blank" :
+		case "_self" :
+		case "_parent" :
+		case "_top" :
+			GetE('txtTargetFrame').value = targetType ;
+			break ;
+		case "" :
+			GetE('txtTargetFrame').value = '' ;
+			break ;
+	}
+
+	if ( targetType == 'popup' )
+		window.parent.SetAutoSize( true ) ;
+}
+
+//#### Called while the user types the URL.
+function OnUrlChange()
+{
+	var sUrl = GetE('txtUrl').value ;
+	var sProtocol = oRegex.UrlOnChangeProtocol.exec( sUrl ) ;
+
+	if ( sProtocol )
+	{
+		sUrl = sUrl.substr( sProtocol[0].length ) ;
+		GetE('txtUrl').value = sUrl ;
+		GetE('cmbLinkProtocol').value = sProtocol[0].toLowerCase() ;
+	}
+	else if ( oRegex.UrlOnChangeTestOther.test( sUrl ) )
+	{
+		GetE('cmbLinkProtocol').value = '' ;
+	}
+}
+
+//#### Called while the user types the target name.
+function OnTargetNameChange()
+{
+	var sFrame = GetE('txtTargetFrame').value ;
+
+	if ( sFrame.length == 0 )
+		GetE('cmbTarget').value = '' ;
+	else if ( oRegex.ReserveTarget.test( sFrame ) )
+		GetE('cmbTarget').value = sFrame.toLowerCase() ;
+	else
+		GetE('cmbTarget').value = 'frame' ;
+}
+
+// Accesible popups
+function BuildOnClickPopup()
+{
+	var sWindowName = "'" + GetE('txtPopupName').value.replace(/\W/gi, "") + "'" ;
+
+	var sFeatures = '' ;
+	var aChkFeatures = document.getElementsByName( 'chkFeature' ) ;
+	for ( var i = 0 ; i < aChkFeatures.length ; i++ )
+	{
+		if ( i > 0 ) sFeatures += ',' ;
+		sFeatures += aChkFeatures[i].value + '=' + ( aChkFeatures[i].checked ? 'yes' : 'no' ) ;
+	}
+
+	if ( GetE('txtPopupWidth').value.length > 0 )	sFeatures += ',width=' + GetE('txtPopupWidth').value ;
+	if ( GetE('txtPopupHeight').value.length > 0 )	sFeatures += ',height=' + GetE('txtPopupHeight').value ;
+	if ( GetE('txtPopupLeft').value.length > 0 )	sFeatures += ',left=' + GetE('txtPopupLeft').value ;
+	if ( GetE('txtPopupTop').value.length > 0 )		sFeatures += ',top=' + GetE('txtPopupTop').value ;
+
+	if ( sFeatures != '' )
+		sFeatures = sFeatures + ",status" ;
+
+	return ( "window.open(this.href," + sWindowName + ",'" + sFeatures + "'); return false" ) ;
+}
+
+//#### Fills all Popup related fields.
+function FillPopupFields( windowName, features )
+{
+	if ( windowName )
+		GetE('txtPopupName').value = windowName ;
+
+	var oFeatures = new Object() ;
+	var oFeaturesMatch ;
+	while( ( oFeaturesMatch = oRegex.PopupFeatures.exec( features ) ) != null )
+	{
+		var sValue = oFeaturesMatch[2] ;
+		if ( sValue == ( 'yes' || '1' ) )
+			oFeatures[ oFeaturesMatch[1] ] = true ;
+		else if ( ! isNaN( sValue ) && sValue != 0 )
+			oFeatures[ oFeaturesMatch[1] ] = sValue ;
+	}
+
+	// Update all features check boxes.
+	var aChkFeatures = document.getElementsByName('chkFeature') ;
+	for ( var i = 0 ; i < aChkFeatures.length ; i++ )
+	{
+		if ( oFeatures[ aChkFeatures[i].value ] )
+			aChkFeatures[i].checked = true ;
+	}
+
+	// Update position and size text boxes.
+	if ( oFeatures['width'] )	GetE('txtPopupWidth').value		= oFeatures['width'] ;
+	if ( oFeatures['height'] )	GetE('txtPopupHeight').value	= oFeatures['height'] ;
+	if ( oFeatures['left'] )	GetE('txtPopupLeft').value		= oFeatures['left'] ;
+	if ( oFeatures['top'] )		GetE('txtPopupTop').value		= oFeatures['top'] ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	var sUri, sInnerHtml ;
+
+	switch ( GetE('cmbLinkType').value )
+	{
+		case 'url' :
+			sUri = GetE('txtUrl').value ;
+
+			if ( sUri.length == 0 )
+			{
+				alert( FCKLang.DlnLnkMsgNoUrl ) ;
+				return false ;
+			}
+
+			sUri = GetE('cmbLinkProtocol').value + sUri ;
+
+			break ;
+
+		case 'email' :
+			sUri = GetE('txtEMailAddress').value ;
+
+			if ( sUri.length == 0 )
+			{
+				alert( FCKLang.DlnLnkMsgNoEMail ) ;
+				return false ;
+			}
+
+			sUri = oParser.CreateEMailUri(
+				sUri,
+				GetE('txtEMailSubject').value,
+				GetE('txtEMailBody').value ) ;
+			break ;
+
+		case 'anchor' :
+			var sAnchor = GetE('cmbAnchorName').value ;
+			if ( sAnchor.length == 0 ) sAnchor = GetE('cmbAnchorId').value ;
+
+			if ( sAnchor.length == 0 )
+			{
+				alert( FCKLang.DlnLnkMsgNoAnchor ) ;
+				return false ;
+			}
+
+			sUri = '#' + sAnchor ;
+			break ;
+	}
+
+	// No link selected, so try to create one.
+	if ( !oLink )
+		oLink = oEditor.FCK.CreateLink( sUri ) ;
+
+	if ( oLink )
+		sInnerHtml = oLink.innerHTML ;		// Save the innerHTML (IE changes it if it is like an URL).
+	else
+	{
+		// If no selection, use the uri as the link text (by dom, 2006-05-26)
+
+		sInnerHtml = sUri;
+
+		// Built a better text for empty links.
+		switch ( GetE('cmbLinkType').value )
+		{
+			// anchor: use old behavior --> return true
+			case 'anchor':
+				sInnerHtml = sInnerHtml.replace( /^#/, '' ) ;
+				break ;
+
+			// url: try to get path
+			case 'url':
+				var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$") ;
+				var asLinkPath = oLinkPathRegEx.exec( sUri ) ;
+				if (asLinkPath != null)
+					sInnerHtml = asLinkPath[1];  // use matched path
+				break ;
+
+			// mailto: try to get email address
+			case 'email':
+				sInnerHtml = GetE('txtEMailAddress').value ;
+				break ;
+		}
+
+		// Create a new (empty) anchor.
+		oLink = oEditor.FCK.CreateElement( 'a' ) ;
+	}
+
+	oEditor.FCKUndo.SaveUndoStep() ;
+
+	oLink.href = sUri ;
+	SetAttribute( oLink, '_fcksavedurl', sUri ) ;
+
+	// Accesible popups
+	if( GetE('cmbTarget').value == 'popup' )
+	{
+		SetAttribute( oLink, 'onclick_fckprotectedatt', " onclick=\"" + BuildOnClickPopup() + "\"") ;
+	}
+	else
+	{
+		// Check if the previous onclick was for a popup:
+		// In that case remove the onclick handler.
+		var onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;
+		if( oRegex.OnClickPopup.test( onclick ) )
+			SetAttribute( oLink, 'onclick_fckprotectedatt', '' ) ;
+	}
+
+	oLink.innerHTML = sInnerHtml ;		// Set (or restore) the innerHTML
+
+	// Target
+	if( GetE('cmbTarget').value != 'popup' )
+		SetAttribute( oLink, 'target', GetE('txtTargetFrame').value ) ;
+	else
+		SetAttribute( oLink, 'target', null ) ;
+
+	// Advances Attributes
+	SetAttribute( oLink, 'id'		, GetE('txtAttId').value ) ;
+	SetAttribute( oLink, 'name'		, GetE('txtAttName').value ) ;
+	SetAttribute( oLink, 'dir'		, GetE('cmbAttLangDir').value ) ;
+	SetAttribute( oLink, 'lang'		, GetE('txtAttLangCode').value ) ;
+	SetAttribute( oLink, 'accesskey', GetE('txtAttAccessKey').value ) ;
+	SetAttribute( oLink, 'tabindex'	, ( GetE('txtAttTabIndex').value > 0 ? GetE('txtAttTabIndex').value : null ) ) ;
+	SetAttribute( oLink, 'title'	, GetE('txtAttTitle').value ) ;
+	SetAttribute( oLink, 'type'		, GetE('txtAttContentType').value ) ;
+	SetAttribute( oLink, 'charset'	, GetE('txtAttCharSet').value ) ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+	{
+		var sClass = GetE('txtAttClasses').value ;
+		// If it's also an anchor add an internal class
+		if ( GetE('txtAttName').value.length != 0 )
+			sClass += ' FCK__AnchorC' ;
+		SetAttribute( oLink, 'className', sClass ) ;
+
+		oLink.style.cssText = GetE('txtAttStyle').value ;
+	}
+	else
+	{
+		SetAttribute( oLink, 'class', GetE('txtAttClasses').value ) ;
+		SetAttribute( oLink, 'style', GetE('txtAttStyle').value ) ;
+	}
+
+	// Select the link.
+	oEditor.FCKSelection.SelectNode(oLink);
+
+	return true ;
+}
+
+function BrowseServer()
+{
+	OpenFileBrowser( FCKConfig.LinkBrowserURL, FCKConfig.LinkBrowserWindowWidth, FCKConfig.LinkBrowserWindowHeight ) ;
+}
+
+function SetUrl( url )
+{
+	document.getElementById('txtUrl').value = url ;
+	OnUrlChange() ;
+	window.parent.SetSelectedTab( 'Info' ) ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+	switch ( errorNumber )
+	{
+		case 0 :	// No errors
+			alert( 'Your file has been successfully uploaded' ) ;
+			break ;
+		case 1 :	// Custom error
+			alert( customMsg ) ;
+			return ;
+		case 101 :	// Custom warning
+			alert( customMsg ) ;
+			break ;
+		case 201 :
+			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+			break ;
+		case 202 :
+			alert( 'Invalid file type' ) ;
+			return ;
+		case 203 :
+			alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+			return ;
+		default :
+			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+			return ;
+	}
+
+	SetUrl( fileUrl ) ;
+	GetE('frmUpload').reset() ;
+}
+
+var oUploadAllowedExtRegex	= new RegExp( FCKConfig.LinkUploadAllowedExtensions, 'i' ) ;
+var oUploadDeniedExtRegex	= new RegExp( FCKConfig.LinkUploadDeniedExtensions, 'i' ) ;
+
+function CheckUpload()
+{
+	var sFile = GetE('txtUploadFile').value ;
+
+	if ( sFile.length == 0 )
+	{
+		alert( 'Please select a file to upload' ) ;
+		return false ;
+	}
+
+	if ( ( FCKConfig.LinkUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
+		( FCKConfig.LinkUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
+	{
+		OnUploadCompleted( 202 ) ;
+		return false ;
+	}
+
+	return true ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_radiobutton.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_radiobutton.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_radiobutton.html	(revision 795)
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Radio Button dialog window.
+-->
+<html>
+	<head>
+		<title>Radio Button Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl && oActiveEl.tagName.toUpperCase() == 'INPUT' && oActiveEl.type == 'radio' )
+	{
+		GetE('txtName').value		= oActiveEl.name ;
+		GetE('txtValue').value		= oEditor.FCKBrowserInfo.IsIE ? oActiveEl.value : GetAttribute( oActiveEl, 'value' ) ;
+		GetE('txtSelected').checked	= oActiveEl.checked ;
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+		oActiveEl.type = 'radio' ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+	}
+
+	if ( GetE('txtName').value.length > 0 )
+		oActiveEl.name = GetE('txtName').value ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+		oActiveEl.value = GetE('txtValue').value ;
+	else
+		SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+	var bIsChecked = GetE('txtSelected').checked ;
+	SetAttribute( oActiveEl, 'checked', bIsChecked ? 'checked' : null ) ;	// For Firefox
+	oActiveEl.checked = bIsChecked ;
+
+	return true ;
+}
+
+		</script>
+	</head>
+	<body style="OVERFLOW: hidden" scroll="no">
+		<table height="100%" width="100%">
+			<tr>
+				<td align="center">
+					<table border="0" cellpadding="0" cellspacing="0" width="80%">
+						<tr>
+							<td>
+								<span fckLang="DlgCheckboxName">Name</span><br>
+								<input type="text" size="20" id="txtName" style="WIDTH: 100%">
+							</td>
+						</tr>
+						<tr>
+							<td>
+								<span fckLang="DlgCheckboxValue">Value</span><br>
+								<input type="text" size="20" id="txtValue" style="WIDTH: 100%">
+							</td>
+						</tr>
+						<tr>
+							<td><input type="checkbox" id="txtSelected"><label for="txtSelected" fckLang="DlgCheckboxSelected">Checked</label></td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_flash.html	(revision 795)
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Flash Properties dialog window.
+-->
+<html>
+	<head>
+		<title>Flash Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script src="fck_flash/fck_flash.js" type="text/javascript"></script>
+		<link href="common/fck_dialog_common.css" type="text/css" rel="stylesheet">
+	</head>
+	<body scroll="no" style="OVERFLOW: hidden">
+		<div id="divInfo">
+			<table cellSpacing="1" cellPadding="1" width="100%" border="0">
+				<tr>
+					<td>
+						<table cellSpacing="0" cellPadding="0" width="100%" border="0">
+							<tr>
+								<td width="100%"><span fckLang="DlgImgURL">URL</span>
+								</td>
+								<td id="tdBrowse" style="DISPLAY: none" noWrap rowSpan="2">&nbsp; <input id="btnBrowse" onclick="BrowseServer();" type="button" value="Browse Server" fckLang="DlgBtnBrowseServer">
+								</td>
+							</tr>
+							<tr>
+								<td vAlign="top"><input id="txtUrl" onblur="UpdatePreview();" style="WIDTH: 100%" type="text">
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+				<TR>
+					<TD>
+						<table cellSpacing="0" cellPadding="0" border="0">
+							<TR>
+								<TD nowrap>
+									<span fckLang="DlgImgWidth">Width</span><br>
+									<input id="txtWidth" class="FCK__FieldNumeric" type="text" size="3">
+								</TD>
+								<TD>&nbsp;</TD>
+								<TD>
+									<span fckLang="DlgImgHeight">Height</span><br>
+									<input id="txtHeight" class="FCK__FieldNumeric" type="text" size="3">
+								</TD>
+							</TR>
+						</table>
+					</TD>
+				</TR>
+				<tr>
+					<td vAlign="top">
+						<table cellSpacing="0" cellPadding="0" width="100%" border="0">
+							<tr>
+								<td valign="top" width="100%">
+									<table cellSpacing="0" cellPadding="0" width="100%">
+										<tr>
+											<td><span fckLang="DlgImgPreview">Preview</span></td>
+										</tr>
+										<tr>
+											<td id="ePreviewCell" valign="top" class="FlashPreviewArea"><iframe src="fck_flash/fck_flash_preview.html" frameborder="0" marginheight="0" marginwidth="0"></iframe></td>
+										</tr>
+									</table>
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+			</table>
+		</div>
+		<div id="divUpload" style="DISPLAY: none">
+			<form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data" action="" onsubmit="return CheckUpload();">
+				<span fckLang="DlgLnkUpload">Upload</span><br />
+				<input id="txtUploadFile" style="WIDTH: 100%" type="file" size="40" name="NewFile" /><br />
+				<br />
+				<input id="btnUpload" type="submit" value="Send it to the Server" fckLang="DlgLnkBtnUpload" />
+				<iframe name="UploadWindow" style="DISPLAY: none" src="javascript:void(0)"></iframe>
+			</form>
+		</div>
+		<div id="divAdvanced" style="DISPLAY: none">
+			<TABLE cellSpacing="0" cellPadding="0" border="0">
+				<TR>
+					<TD nowrap>
+						<span fckLang="DlgFlashScale">Scale</span><BR>
+						<select id="cmbScale">
+							<option value="" selected></option>
+							<option value="showall" fckLang="DlgFlashScaleAll">Show all</option>
+							<option value="noborder" fckLang="DlgFlashScaleNoBorder">No Border</option>
+							<option value="exactfit" fckLang="DlgFlashScaleFit">Exact Fit</option>
+						</select></TD>
+					<TD>&nbsp;&nbsp;&nbsp; &nbsp;
+					</TD>
+					<td valign="bottom">
+						<table>
+							<tr>
+								<td><input id="chkAutoPlay" type="checkbox" checked></td>
+								<td><label for="chkAutoPlay" nowrap fckLang="DlgFlashChkPlay">Auto Play</label>&nbsp;&nbsp;</td>
+								<td><input id="chkLoop" type="checkbox" checked></td>
+								<td><label for="chkLoop" nowrap fckLang="DlgFlashChkLoop">Loop</label>&nbsp;&nbsp;</td>
+								<td><input id="chkMenu" type="checkbox" checked></td>
+								<td><label for="chkMenu" nowrap fckLang="DlgFlashChkMenu">Enable Flash Menu</label></td>
+							</tr>
+						</table>
+					</td>
+				</TR>
+			</TABLE>
+			<br>
+			&nbsp;
+			<table cellSpacing="0" cellPadding="0" width="100%" align="center" border="0">
+				<tr>
+					<td vAlign="top" width="50%"><span fckLang="DlgGenId">Id</span><br>
+						<input id="txtAttId" style="WIDTH: 100%" type="text">
+					</td>
+					<td>&nbsp;&nbsp;</td>
+					<td vAlign="top" nowrap><span fckLang="DlgGenClass">Stylesheet Classes</span><br>
+						<input id="txtAttClasses" style="WIDTH: 100%" type="text">
+					</td>
+					<td>&nbsp;&nbsp;</td>
+					<td vAlign="top" nowrap width="50%">&nbsp;<span fckLang="DlgGenTitle">Advisory Title</span><br>
+						<input id="txtAttTitle" style="WIDTH: 100%" type="text">
+					</td>
+				</tr>
+			</table>
+			<span fckLang="DlgGenStyle">Style</span><br>
+			<input id="txtAttStyle" style="WIDTH: 100%" type="text">
+		</div>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_hiddenfield.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_hiddenfield.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_hiddenfield.html	(revision 795)
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Hidden Field dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Hidden Field Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCK = oEditor.FCK ;
+
+// Gets the document DOM
+var oDOM = FCK.EditorDocument ;
+
+// Get the selected flash embed (if available).
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oActiveEl ;
+
+if ( oFakeImage )
+{
+	if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckinputhidden') )
+		oActiveEl = FCK.GetRealElement( oFakeImage ) ;
+	else
+		oFakeImage = null ;
+}
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl )
+	{
+		GetE('txtName').value		= oActiveEl.name ;
+		GetE('txtValue').value		= oActiveEl.value ;
+	}
+
+	window.parent.SetOkButton( true ) ;
+}
+
+
+function Ok()
+{
+	if ( !oActiveEl )
+	{
+		oActiveEl = FCK.EditorDocument.createElement( 'INPUT' ) ;
+		oActiveEl.type = 'hidden' ;
+
+		oFakeImage = null ;
+	}
+
+	oActiveEl.name = GetE('txtName').value ;
+	SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+	if ( !oFakeImage )
+	{
+		oFakeImage	= oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__InputHidden', oActiveEl ) ;
+		oFakeImage.setAttribute( '_fckinputhidden', 'true', 0 ) ;
+		oFakeImage	= FCK.InsertElementAndGetIt( oFakeImage ) ;
+	}
+	else
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+	oEditor.FCKFlashProcessor.RefreshView( oFakeImage, oActiveEl ) ;
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden" scroll="no">
+	<table height="100%" width="100%">
+		<tr>
+			<td align="center">
+				<table border="0" class="inhoud" cellpadding="0" cellspacing="0" width="80%">
+					<tr>
+						<td>
+							<span fcklang="DlgHiddenName">Name</span><br />
+							<input type="text" size="20" id="txtName" style="width: 100%" />
+						</td>
+					</tr>
+					<tr>
+						<td>
+							<span fcklang="DlgHiddenValue">Value</span><br />
+							<input type="text" size="30" id="txtValue" style="width: 100%" />
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_source.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_source.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_source.html	(revision 795)
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Source editor dialog window.
+-->
+<html>
+	<head>
+		<title>Source</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="robots" content="noindex, nofollow">
+		<link href="common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+		<script language="javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKConfig	= oEditor.FCKConfig ;
+
+window.onload = function()
+{
+	// EnableXHTML and EnableSourceXHTML has been deprecated
+//	document.getElementById('txtSource').value = ( FCKConfig.EnableXHTML && FCKConfig.EnableSourceXHTML ? FCK.GetXHTML( FCKConfig.FormatSource ) : FCK.GetHTML( FCKConfig.FormatSource ) ) ;
+	document.getElementById('txtSource').value = FCK.GetXHTML( FCKConfig.FormatSource ) ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	if ( oEditor.FCKBrowserInfo.IsIE )
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+	FCK.SetHTML( document.getElementById('txtSource').value, false ) ;
+
+	return true ;
+}
+		</script>
+	</head>
+	<body scroll="no" style="OVERFLOW: hidden">
+		<table width="100%" height="100%">
+			<tr>
+				<td height="100%"><textarea id="txtSource" dir="ltr" style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-SIZE: 14px; PADDING-BOTTOM: 5px; WIDTH: 100%; PADDING-TOP: 5px; FONT-FAMILY: Monospace; HEIGHT: 100%">Loading. Please wait...</textarea></td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/moz-bindings.xml
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/moz-bindings.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/moz-bindings.xml	(revision 795)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<bindings xmlns="http://www.mozilla.org/xbl">
+	<binding id="numericfield">
+		<implementation>
+			<constructor>
+				this.keypress = CheckIsDigit ;
+			</constructor>
+			<method name="CheckIsDigit">
+				<body>
+					<![CDATA[
+					var iCode = keyCode ;
+
+					var bAccepted =
+						(
+							( iCode >= 48 && iCode <= 57 )		// Numbers
+							|| (iCode >= 37 && iCode <= 40)		// Arrows
+							|| iCode == 8						// Backspace
+							|| iCode == 46						// Delete
+						) ;
+
+					return bAccepted ;
+					]]>
+				</body>
+			</method>
+		</implementation>
+		<events>
+			<event type="keypress" value="CheckIsDigit()" />
+		</events>
+	</binding>
+</bindings>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fck_dialog_common.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fck_dialog_common.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fck_dialog_common.css	(revision 795)
@@ -0,0 +1,83 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the CSS file used for interface details in some dialog
+ * windows.
+ */
+
+.ImagePreviewArea
+{
+	border: #000000 1px solid;
+	overflow: auto;
+	width: 100%;
+	height: 170px;
+	background-color: #ffffff;
+}
+
+.FlashPreviewArea
+{
+	border: #000000 1px solid;
+	padding: 5px;
+	overflow: auto;
+	width: 100%;
+	height: 170px;
+	background-color: #ffffff;
+}
+
+.BtnReset
+{
+	float: left;
+	background-position: center center;
+	background-image: url(images/reset.gif);
+	width: 16px;
+	height: 16px;
+	background-repeat: no-repeat;
+	border: 1px none;
+	font-size: 1px ;
+}
+
+.BtnLocked, .BtnUnlocked
+{
+	float: left;
+	background-position: center center;
+	background-image: url(images/locked.gif);
+	width: 16px;
+	height: 16px;
+	background-repeat: no-repeat;
+	border: none 1px;
+	font-size: 1px ;
+}
+
+.BtnUnlocked
+{
+	background-image: url(images/unlocked.gif);
+}
+
+.BtnOver
+{
+	border: outset 1px;
+	cursor: pointer;
+	cursor: hand;
+}
+
+.FCK__FieldNumeric
+{
+	behavior: url(common/fcknumericfield.htc) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fck_dialog_common.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fck_dialog_common.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fck_dialog_common.js	(revision 795)
@@ -0,0 +1,154 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Useful functions used by almost all dialog window pages.
+ */
+
+var GECKO_BOGUS = '<br type="_moz">' ;
+
+// Gets a element by its Id. Used for shorter coding.
+function GetE( elementId )
+{
+	return document.getElementById( elementId )  ;
+}
+
+function ShowE( element, isVisible )
+{
+	if ( typeof( element ) == 'string' )
+		element = GetE( element ) ;
+	element.style.display = isVisible ? '' : 'none' ;
+}
+
+function SetAttribute( element, attName, attValue )
+{
+	if ( attValue == null || attValue.length == 0 )
+		element.removeAttribute( attName, 0 ) ;			// 0 : Case Insensitive
+	else
+		element.setAttribute( attName, attValue, 0 ) ;	// 0 : Case Insensitive
+}
+
+function GetAttribute( element, attName, valueIfNull )
+{
+	var oAtt = element.attributes[attName] ;
+
+	if ( oAtt == null || !oAtt.specified )
+		return valueIfNull ? valueIfNull : '' ;
+
+	var oValue = element.getAttribute( attName, 2 ) ;
+
+	if ( oValue == null )
+		oValue = oAtt.nodeValue ;
+
+	return ( oValue == null ? valueIfNull : oValue ) ;
+}
+
+// Functions used by text fiels to accept numbers only.
+function IsDigit( e )
+{
+	if ( !e )
+		e = event ;
+
+	var iCode = ( e.keyCode || e.charCode ) ;
+
+	return (
+			( iCode >= 48 && iCode <= 57 )		// Numbers
+			|| (iCode >= 37 && iCode <= 40)		// Arrows
+			|| iCode == 8						// Backspace
+			|| iCode == 46						// Delete
+	) ;
+}
+
+String.prototype.Trim = function()
+{
+	return this.replace( /(^\s*)|(\s*$)/g, '' ) ;
+}
+
+String.prototype.StartsWith = function( value )
+{
+	return ( this.substr( 0, value.length ) == value ) ;
+}
+
+String.prototype.Remove = function( start, length )
+{
+	var s = '' ;
+
+	if ( start > 0 )
+		s = this.substring( 0, start ) ;
+
+	if ( start + length < this.length )
+		s += this.substring( start + length , this.length ) ;
+
+	return s ;
+}
+
+String.prototype.ReplaceAll = function( searchArray, replaceArray )
+{
+	var replaced = this ;
+
+	for ( var i = 0 ; i < searchArray.length ; i++ )
+	{
+		replaced = replaced.replace( searchArray[i], replaceArray[i] ) ;
+	}
+
+	return replaced ;
+}
+
+function OpenFileBrowser( url, width, height )
+{
+	// oEditor must be defined.
+
+	var iLeft = ( oEditor.FCKConfig.ScreenWidth  - width ) / 2 ;
+	var iTop  = ( oEditor.FCKConfig.ScreenHeight - height ) / 2 ;
+
+	var sOptions = "toolbar=no,status=no,resizable=yes,dependent=yes,scrollbars=yes" ;
+	sOptions += ",width=" + width ;
+	sOptions += ",height=" + height ;
+	sOptions += ",left=" + iLeft ;
+	sOptions += ",top=" + iTop ;
+
+	// The "PreserveSessionOnFileBrowser" because the above code could be
+	// blocked by popup blockers.
+	if ( oEditor.FCKConfig.PreserveSessionOnFileBrowser && oEditor.FCKBrowserInfo.IsIE )
+	{
+		// The following change has been made otherwise IE will open the file
+		// browser on a different server session (on some cases):
+		// http://support.microsoft.com/default.aspx?scid=kb;en-us;831678
+		// by Simone Chiaretta.
+		var oWindow = oEditor.window.open( url, 'FCKBrowseWindow', sOptions ) ;
+
+		if ( oWindow )
+		{
+			// Detect Yahoo popup blocker.
+			try
+			{
+				var sTest = oWindow.name ; // Yahoo returns "something", but we can't access it, so detect that and avoid strange errors for the user.
+				oWindow.opener = window ;
+			}
+			catch(e)
+			{
+				alert( oEditor.FCKLang.BrowseServerBlocked ) ;
+			}
+		}
+		else
+			alert( oEditor.FCKLang.BrowseServerBlocked ) ;
+    }
+    else
+		window.open( url, 'FCKBrowseWindow', sOptions ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fcknumericfield.htc
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fcknumericfield.htc	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/common/fcknumericfield.htc	(revision 795)
@@ -0,0 +1,24 @@
+<public:component lightweight="true">
+
+<script language="javascript">
+
+function CheckIsDigit()
+{
+	var iCode = event.keyCode ;
+
+	event.returnValue =
+		(
+			( iCode >= 48 && iCode <= 57 )		// Numbers
+			|| (iCode >= 37 && iCode <= 40)		// Arrows
+			|| iCode == 8						// Backspace
+			|| iCode == 46						// Delete
+		) ;
+
+	return event.returnValue ;
+}
+
+this.onkeypress = CheckIsDigit ;
+
+</script>
+
+</public:component>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_smiley.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_smiley.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_smiley.html	(revision 795)
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Smileys (emoticons) dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<style type="text/css">
+		.Hand
+		{
+			cursor: pointer;
+			cursor: hand;
+		}
+	</style>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+window.onload = function ()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+}
+
+function InsertSmiley( url )
+{
+	var oImg = oEditor.FCK.CreateElement( 'IMG' ) ;
+	oImg.src = url ;
+	oImg.setAttribute( '_fcksavedurl', url ) ;
+
+	// For long smileys list, it seams that IE continues loading the images in
+	// the background when you quickly select one image. so, let's clear
+	// everything before closing.
+	document.body.innerHTML = '' ;
+
+	window.parent.Cancel() ;
+}
+
+function over(td)
+{
+	td.className = 'LightBackground Hand' ;
+}
+
+function out(td)
+{
+	td.className = 'DarkBackground Hand' ;
+}
+	</script>
+</head>
+<body scroll="no">
+	<table cellpadding="2" cellspacing="2" align="center" border="0" width="100%" height="100%">
+		<script type="text/javascript">
+
+var FCKConfig = oEditor.FCKConfig ;
+
+var sBasePath	= FCKConfig.SmileyPath ;
+var aImages		= FCKConfig.SmileyImages ;
+var iCols		= FCKConfig.SmileyColumns ;
+var iColWidth	= parseInt( 100 / iCols, 10 ) ;
+
+var i = 0 ;
+while (i < aImages.length)
+{
+	document.write( '<tr>' ) ;
+	for(var j = 0 ; j < iCols ; j++)
+	{
+		if (aImages[i])
+		{
+			var sUrl = sBasePath + aImages[i] ;
+			document.write( '<td width="' + iColWidth + '%" align="center" class="DarkBackground Hand" onclick="InsertSmiley(\'' + sUrl.replace(/'/g, "\\'" ) + '\')" onmouseover="over(this)" onmouseout="out(this)">' ) ;
+			document.write( '<img src="' + sUrl + '" border="0" />' ) ;
+		}
+		else
+			document.write( '<td width="' + iColWidth + '%" class="DarkBackground">&nbsp;' ) ;
+		document.write( '<\/td>' ) ;
+		i++ ;
+	}
+	document.write('<\/tr>') ;
+}
+
+		</script>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_listprop.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_listprop.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_listprop.html	(revision 795)
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Bulleted List dialog window.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta content="noindex, nofollow" name="robots" />
+	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+	<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+var sListType = ( location.search == '?OL' ? 'OL' : 'UL' ) ;
+
+var oActiveEl = oEditor.FCKSelection.MoveToAncestorNode( sListType ) ;
+var oActiveSel ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( sListType == 'UL' )
+		oActiveSel = GetE('selBulleted') ;
+	else
+	{
+		if ( oActiveEl )
+		{
+			oActiveSel = GetE('selNumbered') ;
+			GetE('eStart').style.display = '' ;
+			GetE('txtStartPosition').value	= GetAttribute( oActiveEl, 'start' ) ;
+		}
+	}
+
+	oActiveSel.style.display = '' ;
+
+	if ( oActiveEl )
+	{
+		if ( oActiveEl.getAttribute('type') )
+			oActiveSel.value = oActiveEl.getAttribute('type').toLowerCase() ;
+	}
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( oActiveEl ){
+		SetAttribute( oActiveEl, 'type'	, oActiveSel.value ) ;
+		if(oActiveEl.tagName == 'OL')
+			SetAttribute( oActiveEl, 'start', GetE('txtStartPosition').value ) ;
+	}
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<table width="100%" style="height: 100%">
+		<tr>
+			<td style="text-align:center">
+				<table cellspacing="0" cellpadding="0" border="0" style="margin-left: auto; margin-right: auto;">
+					<tr>
+						<td id="eStart" style="display: none; padding-right: 5px; padding-left: 5px">
+							<span fcklang="DlgLstStart">Start</span><br />
+							<input type="text" id="txtStartPosition" size="5" />
+						</td>
+						<td style="padding-right: 5px; padding-left: 5px">
+							<span fcklang="DlgLstType">List Type</span><br />
+							<select id="selBulleted" style="display: none">
+								<option value="" selected="selected"></option>
+								<option value="circle" fcklang="DlgLstTypeCircle">Circle</option>
+								<option value="disc" fcklang="DlgLstTypeDisc">Disc</option>
+								<option value="square" fcklang="DlgLstTypeSquare">Square</option>
+							</select>
+							<select id="selNumbered" style="display: none">
+								<option value="" selected="selected"></option>
+								<option value="1" fcklang="DlgLstTypeNumbers">Numbers (1, 2, 3)</option>
+								<option value="a" fcklang="DlgLstTypeLCase">Lowercase Letters (a, b, c)</option>
+								<option value="A" fcklang="DlgLstTypeUCase">Uppercase Letters (A, B, C)</option>
+								<option value="i" fcklang="DlgLstTypeSRoman">Small Roman Numerals (i, ii, iii)</option>
+								<option value="I" fcklang="DlgLstTypeLRoman">Large Roman Numerals (I, II, III)</option>
+							</select>
+							&nbsp;
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_select/fck_select.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_select/fck_select.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_select/fck_select.js	(revision 795)
@@ -0,0 +1,169 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Scripts for the fck_select.html page.
+ */
+
+function Select( combo )
+{
+	var iIndex = combo.selectedIndex ;
+
+	oListText.selectedIndex		= iIndex ;
+	oListValue.selectedIndex	= iIndex ;
+
+	var oTxtText	= document.getElementById( "txtText" ) ;
+	var oTxtValue	= document.getElementById( "txtValue" ) ;
+
+	oTxtText.value	= oListText.value ;
+	oTxtValue.value	= oListValue.value ;
+}
+
+function Add()
+{
+	var oTxtText	= document.getElementById( "txtText" ) ;
+	var oTxtValue	= document.getElementById( "txtValue" ) ;
+
+	AddComboOption( oListText, oTxtText.value, oTxtText.value ) ;
+	AddComboOption( oListValue, oTxtValue.value, oTxtValue.value ) ;
+
+	oListText.selectedIndex = oListText.options.length - 1 ;
+	oListValue.selectedIndex = oListValue.options.length - 1 ;
+
+	oTxtText.value	= '' ;
+	oTxtValue.value	= '' ;
+
+	oTxtText.focus() ;
+}
+
+function Modify()
+{
+	var iIndex = oListText.selectedIndex ;
+
+	if ( iIndex < 0 ) return ;
+
+	var oTxtText	= document.getElementById( "txtText" ) ;
+	var oTxtValue	= document.getElementById( "txtValue" ) ;
+
+	oListText.options[ iIndex ].innerHTML	= oTxtText.value ;
+	oListText.options[ iIndex ].value		= oTxtText.value ;
+
+	oListValue.options[ iIndex ].innerHTML	= oTxtValue.value ;
+	oListValue.options[ iIndex ].value		= oTxtValue.value ;
+
+	oTxtText.value	= '' ;
+	oTxtValue.value	= '' ;
+
+	oTxtText.focus() ;
+}
+
+function Move( steps )
+{
+	ChangeOptionPosition( oListText, steps ) ;
+	ChangeOptionPosition( oListValue, steps ) ;
+}
+
+function Delete()
+{
+	RemoveSelectedOptions( oListText ) ;
+	RemoveSelectedOptions( oListValue ) ;
+}
+
+function SetSelectedValue()
+{
+	var iIndex = oListValue.selectedIndex ;
+	if ( iIndex < 0 ) return ;
+
+	var oTxtValue = document.getElementById( "txtSelValue" ) ;
+
+	oTxtValue.value = oListValue.options[ iIndex ].value ;
+}
+
+// Moves the selected option by a number of steps (also negative)
+function ChangeOptionPosition( combo, steps )
+{
+	var iActualIndex = combo.selectedIndex ;
+
+	if ( iActualIndex < 0 )
+		return ;
+
+	var iFinalIndex = iActualIndex + steps ;
+
+	if ( iFinalIndex < 0 )
+		iFinalIndex = 0 ;
+
+	if ( iFinalIndex > ( combo.options.length - 1 ) )
+		iFinalIndex = combo.options.length - 1 ;
+
+	if ( iActualIndex == iFinalIndex )
+		return ;
+
+	var oOption = combo.options[ iActualIndex ] ;
+	var sText	= oOption.innerHTML ;
+	var sValue	= oOption.value ;
+
+	combo.remove( iActualIndex ) ;
+
+	oOption = AddComboOption( combo, sText, sValue, null, iFinalIndex ) ;
+
+	oOption.selected = true ;
+}
+
+// Remove all selected options from a SELECT object
+function RemoveSelectedOptions(combo)
+{
+	// Save the selected index
+	var iSelectedIndex = combo.selectedIndex ;
+
+	var oOptions = combo.options ;
+
+	// Remove all selected options
+	for ( var i = oOptions.length - 1 ; i >= 0 ; i-- )
+	{
+		if (oOptions[i].selected) combo.remove(i) ;
+	}
+
+	// Reset the selection based on the original selected index
+	if ( combo.options.length > 0 )
+	{
+		if ( iSelectedIndex >= combo.options.length ) iSelectedIndex = combo.options.length - 1 ;
+		combo.selectedIndex = iSelectedIndex ;
+	}
+}
+
+// Add a new option to a SELECT object (combo or list)
+function AddComboOption( combo, optionText, optionValue, documentObject, index )
+{
+	var oOption ;
+
+	if ( documentObject )
+		oOption = documentObject.createElement("OPTION") ;
+	else
+		oOption = document.createElement("OPTION") ;
+
+	if ( index != null )
+		combo.options.add( oOption, index ) ;
+	else
+		combo.options.add( oOption ) ;
+
+	oOption.innerHTML = optionText.length > 0 ? optionText : '&nbsp;' ;
+	oOption.value     = optionValue ;
+
+	return oOption ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_textarea.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_textarea.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_textarea.html	(revision 795)
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Text Area dialog window.
+-->
+<html>
+	<head>
+		<title>Text Area Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl && oActiveEl.tagName == 'TEXTAREA' )
+	{
+		GetE('txtName').value		= oActiveEl.name ;
+		GetE('txtCols').value		= GetAttribute( oActiveEl, 'cols' ) ;
+		GetE('txtRows').value		= GetAttribute( oActiveEl, 'rows' ) ;
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'TEXTAREA' ) ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+	}
+
+	oActiveEl.name = GetE('txtName').value ;
+	SetAttribute( oActiveEl, 'cols', GetE('txtCols').value ) ;
+	SetAttribute( oActiveEl, 'rows', GetE('txtRows').value ) ;
+
+	return true ;
+}
+
+		</script>
+	</head>
+	<body style='OVERFLOW: hidden' scroll='no'>
+		<table height="100%" width="100%">
+			<tr>
+				<td align="center">
+					<table border="0" cellpadding="0" cellspacing="0" width="80%">
+						<tr>
+							<td>
+								<span fckLang="DlgTextareaName">Name</span><br>
+								<input type="text" id="txtName" style="WIDTH: 100%">
+								<span fckLang="DlgTextareaCols">Collumns</span><br>
+								<input id="txtCols" type="text" size="5">
+								<br>
+								<span fckLang="DlgTextareaRows">Rows</span><br>
+								<input id="txtRows" type="text" size="5">
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js	(revision 795)
@@ -0,0 +1,462 @@
+﻿////////////////////////////////////////////////////
+// spellChecker.js
+//
+// spellChecker object
+//
+// This file is sourced on web pages that have a textarea object to evaluate
+// for spelling. It includes the implementation for the spellCheckObject.
+//
+////////////////////////////////////////////////////
+
+
+// constructor
+function spellChecker( textObject ) {
+
+	// public properties - configurable
+//	this.popUpUrl = '/speller/spellchecker.html';							// by FredCK
+	this.popUpUrl = 'fck_spellerpages/spellerpages/spellchecker.html';		// by FredCK
+	this.popUpName = 'spellchecker';
+//	this.popUpProps = "menu=no,width=440,height=350,top=70,left=120,resizable=yes,status=yes";	// by FredCK
+	this.popUpProps = null ;																	// by FredCK
+//	this.spellCheckScript = '/speller/server-scripts/spellchecker.php';		// by FredCK
+	//this.spellCheckScript = '/cgi-bin/spellchecker.pl';
+
+	// values used to keep track of what happened to a word
+	this.replWordFlag = "R";	// single replace
+	this.ignrWordFlag = "I";	// single ignore
+	this.replAllFlag = "RA";	// replace all occurances
+	this.ignrAllFlag = "IA";	// ignore all occurances
+	this.fromReplAll = "~RA";	// an occurance of a "replace all" word
+	this.fromIgnrAll = "~IA";	// an occurance of a "ignore all" word
+	// properties set at run time
+	this.wordFlags = new Array();
+	this.currentTextIndex = 0;
+	this.currentWordIndex = 0;
+	this.spellCheckerWin = null;
+	this.controlWin = null;
+	this.wordWin = null;
+	this.textArea = textObject;	// deprecated
+	this.textInputs = arguments;
+
+	// private methods
+	this._spellcheck = _spellcheck;
+	this._getSuggestions = _getSuggestions;
+	this._setAsIgnored = _setAsIgnored;
+	this._getTotalReplaced = _getTotalReplaced;
+	this._setWordText = _setWordText;
+	this._getFormInputs = _getFormInputs;
+
+	// public methods
+	this.openChecker = openChecker;
+	this.startCheck = startCheck;
+	this.checkTextBoxes = checkTextBoxes;
+	this.checkTextAreas = checkTextAreas;
+	this.spellCheckAll = spellCheckAll;
+	this.ignoreWord = ignoreWord;
+	this.ignoreAll = ignoreAll;
+	this.replaceWord = replaceWord;
+	this.replaceAll = replaceAll;
+	this.terminateSpell = terminateSpell;
+	this.undo = undo;
+
+	// set the current window's "speller" property to the instance of this class.
+	// this object can now be referenced by child windows/frames.
+	window.speller = this;
+}
+
+// call this method to check all text boxes (and only text boxes) in the HTML document
+function checkTextBoxes() {
+	this.textInputs = this._getFormInputs( "^text$" );
+	this.openChecker();
+}
+
+// call this method to check all textareas (and only textareas ) in the HTML document
+function checkTextAreas() {
+	this.textInputs = this._getFormInputs( "^textarea$" );
+	this.openChecker();
+}
+
+// call this method to check all text boxes and textareas in the HTML document
+function spellCheckAll() {
+	this.textInputs = this._getFormInputs( "^text(area)?$" );
+	this.openChecker();
+}
+
+// call this method to check text boxe(s) and/or textarea(s) that were passed in to the
+// object's constructor or to the textInputs property
+function openChecker() {
+	this.spellCheckerWin = window.open( this.popUpUrl, this.popUpName, this.popUpProps );
+	if( !this.spellCheckerWin.opener ) {
+		this.spellCheckerWin.opener = window;
+	}
+}
+
+function startCheck( wordWindowObj, controlWindowObj ) {
+
+	// set properties from args
+	this.wordWin = wordWindowObj;
+	this.controlWin = controlWindowObj;
+
+	// reset properties
+	this.wordWin.resetForm();
+	this.controlWin.resetForm();
+	this.currentTextIndex = 0;
+	this.currentWordIndex = 0;
+	// initialize the flags to an array - one element for each text input
+	this.wordFlags = new Array( this.wordWin.textInputs.length );
+	// each element will be an array that keeps track of each word in the text
+	for( var i=0; i<this.wordFlags.length; i++ ) {
+		this.wordFlags[i] = [];
+	}
+
+	// start
+	this._spellcheck();
+
+	return true;
+}
+
+function ignoreWord() {
+	var wi = this.currentWordIndex;
+	var ti = this.currentTextIndex;
+	if( !this.wordWin ) {
+		alert( 'Error: Word frame not available.' );
+		return false;
+	}
+	if( !this.wordWin.getTextVal( ti, wi )) {
+		alert( 'Error: "Not in dictionary" text is missing.' );
+		return false;
+	}
+	// set as ignored
+	if( this._setAsIgnored( ti, wi, this.ignrWordFlag )) {
+		this.currentWordIndex++;
+		this._spellcheck();
+	}
+	return true;
+}
+
+function ignoreAll() {
+	var wi = this.currentWordIndex;
+	var ti = this.currentTextIndex;
+	if( !this.wordWin ) {
+		alert( 'Error: Word frame not available.' );
+		return false;
+	}
+	// get the word that is currently being evaluated.
+	var s_word_to_repl = this.wordWin.getTextVal( ti, wi );
+	if( !s_word_to_repl ) {
+		alert( 'Error: "Not in dictionary" text is missing' );
+		return false;
+	}
+
+	// set this word as an "ignore all" word.
+	this._setAsIgnored( ti, wi, this.ignrAllFlag );
+
+	// loop through all the words after this word
+	for( var i = ti; i < this.wordWin.textInputs.length; i++ ) {
+		for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+			if(( i == ti && j > wi ) || i > ti ) {
+				// future word: set as "from ignore all" if
+				// 1) do not already have a flag and
+				// 2) have the same value as current word
+				if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl )
+				&& ( !this.wordFlags[i][j] )) {
+					this._setAsIgnored( i, j, this.fromIgnrAll );
+				}
+			}
+		}
+	}
+
+	// finally, move on
+	this.currentWordIndex++;
+	this._spellcheck();
+	return true;
+}
+
+function replaceWord() {
+	var wi = this.currentWordIndex;
+	var ti = this.currentTextIndex;
+	if( !this.wordWin ) {
+		alert( 'Error: Word frame not available.' );
+		return false;
+	}
+	if( !this.wordWin.getTextVal( ti, wi )) {
+		alert( 'Error: "Not in dictionary" text is missing' );
+		return false;
+	}
+	if( !this.controlWin.replacementText ) {
+		return false ;
+	}
+	var txt = this.controlWin.replacementText;
+	if( txt.value ) {
+		var newspell = new String( txt.value );
+		if( this._setWordText( ti, wi, newspell, this.replWordFlag )) {
+			this.currentWordIndex++;
+			this._spellcheck();
+		}
+	}
+	return true;
+}
+
+function replaceAll() {
+	var ti = this.currentTextIndex;
+	var wi = this.currentWordIndex;
+	if( !this.wordWin ) {
+		alert( 'Error: Word frame not available.' );
+		return false;
+	}
+	var s_word_to_repl = this.wordWin.getTextVal( ti, wi );
+	if( !s_word_to_repl ) {
+		alert( 'Error: "Not in dictionary" text is missing' );
+		return false;
+	}
+	var txt = this.controlWin.replacementText;
+	if( !txt.value ) return false;
+	var newspell = new String( txt.value );
+
+	// set this word as a "replace all" word.
+	this._setWordText( ti, wi, newspell, this.replAllFlag );
+
+	// loop through all the words after this word
+	for( var i = ti; i < this.wordWin.textInputs.length; i++ ) {
+		for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+			if(( i == ti && j > wi ) || i > ti ) {
+				// future word: set word text to s_word_to_repl if
+				// 1) do not already have a flag and
+				// 2) have the same value as s_word_to_repl
+				if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl )
+				&& ( !this.wordFlags[i][j] )) {
+					this._setWordText( i, j, newspell, this.fromReplAll );
+				}
+			}
+		}
+	}
+
+	// finally, move on
+	this.currentWordIndex++;
+	this._spellcheck();
+	return true;
+}
+
+function terminateSpell() {
+	// called when we have reached the end of the spell checking.
+	var msg = "";		// by FredCK
+	var numrepl = this._getTotalReplaced();
+	if( numrepl == 0 ) {
+		// see if there were no misspellings to begin with
+		if( !this.wordWin ) {
+			msg = "";
+		} else {
+			if( this.wordWin.totalMisspellings() ) {
+//				msg += "No words changed.";			// by FredCK
+				msg += FCKLang.DlgSpellNoChanges ;	// by FredCK
+			} else {
+//				msg += "No misspellings found.";	// by FredCK
+				msg += FCKLang.DlgSpellNoMispell ;	// by FredCK
+			}
+		}
+	} else if( numrepl == 1 ) {
+//		msg += "One word changed.";			// by FredCK
+		msg += FCKLang.DlgSpellOneChange ;	// by FredCK
+	} else {
+//		msg += numrepl + " words changed.";	// by FredCK
+		msg += FCKLang.DlgSpellManyChanges.replace( /%1/g, numrepl ) ;
+	}
+	if( msg ) {
+//		msg += "\n";	// by FredCK
+		alert( msg );
+	}
+
+	if( numrepl > 0 ) {
+		// update the text field(s) on the opener window
+		for( var i = 0; i < this.textInputs.length; i++ ) {
+			// this.textArea.value = this.wordWin.text;
+			if( this.wordWin ) {
+				if( this.wordWin.textInputs[i] ) {
+					this.textInputs[i].value = this.wordWin.textInputs[i];
+				}
+			}
+		}
+	}
+
+	// return back to the calling window
+//	this.spellCheckerWin.close();					// by FredCK
+	if ( typeof( this.OnFinished ) == 'function' )	// by FredCK
+		this.OnFinished(numrepl) ;					// by FredCK
+
+	return true;
+}
+
+function undo() {
+	// skip if this is the first word!
+	var ti = this.currentTextIndex;
+	var wi = this.currentWordIndex;
+
+	if( this.wordWin.totalPreviousWords( ti, wi ) > 0 ) {
+		this.wordWin.removeFocus( ti, wi );
+
+		// go back to the last word index that was acted upon
+		do {
+			// if the current word index is zero then reset the seed
+			if( this.currentWordIndex == 0 && this.currentTextIndex > 0 ) {
+				this.currentTextIndex--;
+				this.currentWordIndex = this.wordWin.totalWords( this.currentTextIndex )-1;
+				if( this.currentWordIndex < 0 ) this.currentWordIndex = 0;
+			} else {
+				if( this.currentWordIndex > 0 ) {
+					this.currentWordIndex--;
+				}
+			}
+		} while (
+			this.wordWin.totalWords( this.currentTextIndex ) == 0
+			|| this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromIgnrAll
+			|| this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromReplAll
+		);
+
+		var text_idx = this.currentTextIndex;
+		var idx = this.currentWordIndex;
+		var preReplSpell = this.wordWin.originalSpellings[text_idx][idx];
+
+		// if we got back to the first word then set the Undo button back to disabled
+		if( this.wordWin.totalPreviousWords( text_idx, idx ) == 0 ) {
+			this.controlWin.disableUndo();
+		}
+
+		var i, j, origSpell ;
+		// examine what happened to this current word.
+		switch( this.wordFlags[text_idx][idx] ) {
+			// replace all: go through this and all the future occurances of the word
+			// and revert them all to the original spelling and clear their flags
+			case this.replAllFlag :
+				for( i = text_idx; i < this.wordWin.textInputs.length; i++ ) {
+					for( j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+						if(( i == text_idx && j >= idx ) || i > text_idx ) {
+							origSpell = this.wordWin.originalSpellings[i][j];
+							if( origSpell == preReplSpell ) {
+								this._setWordText ( i, j, origSpell, undefined );
+							}
+						}
+					}
+				}
+				break;
+
+			// ignore all: go through all the future occurances of the word
+			// and clear their flags
+			case this.ignrAllFlag :
+				for( i = text_idx; i < this.wordWin.textInputs.length; i++ ) {
+					for( j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+						if(( i == text_idx && j >= idx ) || i > text_idx ) {
+							origSpell = this.wordWin.originalSpellings[i][j];
+							if( origSpell == preReplSpell ) {
+								this.wordFlags[i][j] = undefined;
+							}
+						}
+					}
+				}
+				break;
+
+			// replace: revert the word to its original spelling
+			case this.replWordFlag :
+				this._setWordText ( text_idx, idx, preReplSpell, undefined );
+				break;
+		}
+
+		// For all four cases, clear the wordFlag of this word. re-start the process
+		this.wordFlags[text_idx][idx] = undefined;
+		this._spellcheck();
+	}
+}
+
+function _spellcheck() {
+	var ww = this.wordWin;
+
+	// check if this is the last word in the current text element
+	if( this.currentWordIndex == ww.totalWords( this.currentTextIndex) ) {
+		this.currentTextIndex++;
+		this.currentWordIndex = 0;
+		// keep going if we're not yet past the last text element
+		if( this.currentTextIndex < this.wordWin.textInputs.length ) {
+			this._spellcheck();
+			return;
+		} else {
+			this.terminateSpell();
+			return;
+		}
+	}
+
+	// if this is after the first one make sure the Undo button is enabled
+	if( this.currentWordIndex > 0 ) {
+		this.controlWin.enableUndo();
+	}
+
+	// skip the current word if it has already been worked on
+	if( this.wordFlags[this.currentTextIndex][this.currentWordIndex] ) {
+		// increment the global current word index and move on.
+		this.currentWordIndex++;
+		this._spellcheck();
+	} else {
+		var evalText = ww.getTextVal( this.currentTextIndex, this.currentWordIndex );
+		if( evalText ) {
+			this.controlWin.evaluatedText.value = evalText;
+			ww.setFocus( this.currentTextIndex, this.currentWordIndex );
+			this._getSuggestions( this.currentTextIndex, this.currentWordIndex );
+		}
+	}
+}
+
+function _getSuggestions( text_num, word_num ) {
+	this.controlWin.clearSuggestions();
+	// add suggestion in list for each suggested word.
+	// get the array of suggested words out of the
+	// three-dimensional array containing all suggestions.
+	var a_suggests = this.wordWin.suggestions[text_num][word_num];
+	if( a_suggests ) {
+		// got an array of suggestions.
+		for( var ii = 0; ii < a_suggests.length; ii++ ) {
+			this.controlWin.addSuggestion( a_suggests[ii] );
+		}
+	}
+	this.controlWin.selectDefaultSuggestion();
+}
+
+function _setAsIgnored( text_num, word_num, flag ) {
+	// set the UI
+	this.wordWin.removeFocus( text_num, word_num );
+	// do the bookkeeping
+	this.wordFlags[text_num][word_num] = flag;
+	return true;
+}
+
+function _getTotalReplaced() {
+	var i_replaced = 0;
+	for( var i = 0; i < this.wordFlags.length; i++ ) {
+		for( var j = 0; j < this.wordFlags[i].length; j++ ) {
+			if(( this.wordFlags[i][j] == this.replWordFlag )
+			|| ( this.wordFlags[i][j] == this.replAllFlag )
+			|| ( this.wordFlags[i][j] == this.fromReplAll )) {
+				i_replaced++;
+			}
+		}
+	}
+	return i_replaced;
+}
+
+function _setWordText( text_num, word_num, newText, flag ) {
+	// set the UI and form inputs
+	this.wordWin.setText( text_num, word_num, newText );
+	// keep track of what happened to this word:
+	this.wordFlags[text_num][word_num] = flag;
+	return true;
+}
+
+function _getFormInputs( inputPattern ) {
+	var inputs = new Array();
+	for( var i = 0; i < document.forms.length; i++ ) {
+		for( var j = 0; j < document.forms[i].elements.length; j++ ) {
+			if( document.forms[i].elements[j].type.match( inputPattern )) {
+				inputs[inputs.length] = document.forms[i].elements[j];
+			}
+		}
+	}
+	return inputs;
+}
+
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js	(revision 795)
@@ -0,0 +1,87 @@
+﻿////////////////////////////////////////////////////
+// controlWindow object
+////////////////////////////////////////////////////
+function controlWindow( controlForm ) {
+	// private properties
+	this._form = controlForm;
+
+	// public properties
+	this.windowType = "controlWindow";
+//	this.noSuggestionSelection = "- No suggestions -";	// by FredCK
+	this.noSuggestionSelection = FCKLang.DlgSpellNoSuggestions ;
+	// set up the properties for elements of the given control form
+	this.suggestionList  = this._form.sugg;
+	this.evaluatedText   = this._form.misword;
+	this.replacementText = this._form.txtsugg;
+	this.undoButton      = this._form.btnUndo;
+
+	// public methods
+	this.addSuggestion = addSuggestion;
+	this.clearSuggestions = clearSuggestions;
+	this.selectDefaultSuggestion = selectDefaultSuggestion;
+	this.resetForm = resetForm;
+	this.setSuggestedText = setSuggestedText;
+	this.enableUndo = enableUndo;
+	this.disableUndo = disableUndo;
+}
+
+function resetForm() {
+	if( this._form ) {
+		this._form.reset();
+	}
+}
+
+function setSuggestedText() {
+	var slct = this.suggestionList;
+	var txt = this.replacementText;
+	var str = "";
+	if( (slct.options[0].text) && slct.options[0].text != this.noSuggestionSelection ) {
+		str = slct.options[slct.selectedIndex].text;
+	}
+	txt.value = str;
+}
+
+function selectDefaultSuggestion() {
+	var slct = this.suggestionList;
+	var txt = this.replacementText;
+	if( slct.options.length == 0 ) {
+		this.addSuggestion( this.noSuggestionSelection );
+	} else {
+		slct.options[0].selected = true;
+	}
+	this.setSuggestedText();
+}
+
+function addSuggestion( sugg_text ) {
+	var slct = this.suggestionList;
+	if( sugg_text ) {
+		var i = slct.options.length;
+		var newOption = new Option( sugg_text, 'sugg_text'+i );
+		slct.options[i] = newOption;
+	 }
+}
+
+function clearSuggestions() {
+	var slct = this.suggestionList;
+	for( var j = slct.length - 1; j > -1; j-- ) {
+		if( slct.options[j] ) {
+			slct.options[j] = null;
+		}
+	}
+}
+
+function enableUndo() {
+	if( this.undoButton ) {
+		if( this.undoButton.disabled == true ) {
+			this.undoButton.disabled = false;
+		}
+	}
+}
+
+function disableUndo() {
+	if( this.undoButton ) {
+		if( this.undoButton.disabled == false ) {
+			this.undoButton.disabled = true;
+		}
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html	(revision 795)
@@ -0,0 +1,153 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="spellerStyle.css" />
+		<script type="text/javascript" src="controlWindow.js"></script>
+		<script type="text/javascript">
+var spellerObject;
+var controlWindowObj;
+
+if( parent.opener ) {
+	spellerObject = parent.opener.speller;
+}
+
+function ignore_word() {
+	if( spellerObject ) {
+		spellerObject.ignoreWord();
+	}
+}
+
+function ignore_all() {
+	if( spellerObject ) {
+		spellerObject.ignoreAll();
+	}
+}
+
+function replace_word() {
+	if( spellerObject ) {
+		spellerObject.replaceWord();
+	}
+}
+
+function replace_all() {
+	if( spellerObject ) {
+		spellerObject.replaceAll();
+	}
+}
+
+function end_spell() {
+	if( spellerObject ) {
+		spellerObject.terminateSpell();
+	}
+}
+
+function undo() {
+	if( spellerObject ) {
+		spellerObject.undo();
+	}
+}
+
+function suggText() {
+	if( controlWindowObj ) {
+		controlWindowObj.setSuggestedText();
+	}
+}
+
+var FCKLang = window.parent.parent.FCKLang ;	// by FredCK
+
+function init_spell() {
+	// By FredCK (fckLang attributes have been added to the HTML source of this page)
+	window.parent.parent.OnSpellerControlsLoad( this ) ;
+
+	var controlForm = document.spellcheck;
+
+	// create a new controlWindow object
+ 	controlWindowObj = new controlWindow( controlForm );
+
+	// call the init_spell() function in the parent frameset
+	if( parent.frames.length ) {
+		parent.init_spell( controlWindowObj );
+	} else {
+		alert( 'This page was loaded outside of a frameset. It might not display properly' );
+	}
+}
+
+</script>
+	</head>
+	<body class="controlWindowBody" onLoad="init_spell();" style="OVERFLOW: hidden" scroll="no">	<!-- by FredCK -->
+		<form name="spellcheck">
+			<table border="0" cellpadding="0" cellspacing="0" border="0" align="center">
+				<tr>
+					<td colspan="3" class="normalLabel"><span fckLang="DlgSpellNotInDic">Not in dictionary:</span></td>
+				</tr>
+				<tr>
+					<td colspan="3"><input class="readonlyInput" type="text" name="misword" readonly /></td>
+				</tr>
+				<tr>
+					<td colspan="3" height="5"></td>
+				</tr>
+				<tr>
+					<td class="normalLabel"><span fckLang="DlgSpellChangeTo">Change to:</span></td>
+				</tr>
+				<tr valign="top">
+					<td>
+						<table border="0" cellpadding="0" cellspacing="0" border="0">
+							<tr>
+								<td class="normalLabel">
+									<input class="textDefault" type="text" name="txtsugg" />
+								</td>
+							</tr>
+							<tr>
+								<td>
+									<select class="suggSlct" name="sugg" size="7" onChange="suggText();" onDblClick="replace_word();">
+										<option></option>
+									</select>
+								</td>
+							</tr>
+						</table>
+					</td>
+					<td>&nbsp;&nbsp;</td>
+					<td>
+						<table border="0" cellpadding="0" cellspacing="0" border="0">
+							<tr>
+								<td>
+									<input class="buttonDefault" type="button" fckLang="DlgSpellBtnIgnore" value="Ignore" onClick="ignore_word();">
+								</td>
+								<td>&nbsp;&nbsp;</td>
+								<td>
+									<input class="buttonDefault" type="button" fckLang="DlgSpellBtnIgnoreAll" value="Ignore All" onClick="ignore_all();">
+								</td>
+							</tr>
+							<tr>
+								<td colspan="3" height="5"></td>
+							</tr>
+							<tr>
+								<td>
+									<input class="buttonDefault" type="button" fckLang="DlgSpellBtnReplace" value="Replace" onClick="replace_word();">
+								</td>
+								<td>&nbsp;&nbsp;</td>
+								<td>
+									<input class="buttonDefault" type="button" fckLang="DlgSpellBtnReplaceAll" value="Replace All" onClick="replace_all();">
+								</td>
+							</tr>
+							<tr>
+								<td colspan="3" height="5"></td>
+							</tr>
+							<tr>
+								<td>
+									<input class="buttonDefault" type="button" name="btnUndo" fckLang="DlgSpellBtnUndo" value="Undo" onClick="undo();"
+										disabled>
+								</td>
+								<td>&nbsp;&nbsp;</td>
+								<td>
+									<!-- by FredCK
+									<input class="buttonDefault" type="button" value="Close" onClick="end_spell();">
+									-->
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+			</table>
+		</form>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html	(revision 795)
@@ -0,0 +1,71 @@
+
+<script>
+
+var wordWindow = null;
+var controlWindow = null;
+
+function init_spell( spellerWindow ) {
+
+	if( spellerWindow ) {
+		if( spellerWindow.windowType == "wordWindow" ) {
+			wordWindow = spellerWindow;
+		} else if ( spellerWindow.windowType == "controlWindow" ) {
+			controlWindow = spellerWindow;
+		}
+	}
+
+	if( controlWindow && wordWindow ) {
+		// populate the speller object and start it off!
+		var speller = opener.speller;
+		wordWindow.speller = speller;
+		speller.startCheck( wordWindow, controlWindow );
+	}
+}
+
+// encodeForPost
+function encodeForPost( str ) {
+	var s = new String( str );
+	s = encodeURIComponent( s );
+	// additionally encode single quotes to evade any PHP
+	// magic_quotes_gpc setting (it inserts escape characters and
+	// therefore skews the btye positions of misspelled words)
+	return s.replace( /\'/g, '%27' );
+}
+
+// post the text area data to the script that populates the speller
+function postWords() {
+	var bodyDoc = window.frames[0].document;
+	bodyDoc.open();
+	bodyDoc.write('<html>');
+	bodyDoc.write('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
+	bodyDoc.write('<link rel="stylesheet" type="text/css" href="spellerStyle.css"/>');
+	if (opener) {
+		var speller = opener.speller;
+		bodyDoc.write('<body class="normalText" onLoad="document.forms[0].submit();">');
+		bodyDoc.write('<p>' + window.parent.FCKLang.DlgSpellProgress + '<\/p>');		// by FredCK
+		bodyDoc.write('<form action="'+speller.spellCheckScript+'" method="post">');
+		for( var i = 0; i < speller.textInputs.length; i++ ) {
+			bodyDoc.write('<input type="hidden" name="textinputs[]" value="'+encodeForPost(speller.textInputs[i].value)+'">');
+		}
+		bodyDoc.write('<\/form>');
+		bodyDoc.write('<\/body>');
+	} else {
+		bodyDoc.write('<body class="normalText">');
+		bodyDoc.write('<p><b>This page cannot be displayed<\/b><\/p><p>The window was not opened from another window.<\/p>');
+		bodyDoc.write('<\/body>');
+	}
+	bodyDoc.write('<\/html>');
+	bodyDoc.close();
+}
+</script>
+
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<head>
+<title>Speller Pages</title>
+</head>
+<frameset rows="*,201" onLoad="postWords();">
+<frame src="blank.html">
+<frame src="controls.html">
+</frameset>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php	(revision 795)
@@ -0,0 +1,196 @@
+<?php
+header('Content-type: text/html; charset=utf-8');
+
+// The following variables values must reflect your installation needs.
+
+$aspell_prog	= '"C:\Program Files\Aspell\bin\aspell.exe"';	// by FredCK (for Windows)
+//$aspell_prog	= 'aspell';										// by FredCK (for Linux)
+
+$lang			= 'en_US';
+$aspell_opts	= "-a --lang=$lang --encoding=utf-8 -H";		// by FredCK
+
+$tempfiledir	= "./";
+
+$spellercss		= '../spellerStyle.css';						// by FredCK
+$word_win_src	= '../wordWindow.js';							// by FredCK
+
+$textinputs		= $_POST['textinputs']; # array
+$input_separator = "A";
+
+# set the JavaScript variable to the submitted text.
+# textinputs is an array, each element corresponding to the (url-encoded)
+# value of the text control submitted for spell-checking
+function print_textinputs_var() {
+	global $textinputs;
+	foreach( $textinputs as $key=>$val ) {
+		# $val = str_replace( "'", "%27", $val );
+		echo "textinputs[$key] = decodeURIComponent(\"" . $val . "\");\n";
+	}
+}
+
+# make declarations for the text input index
+function print_textindex_decl( $text_input_idx ) {
+	echo "words[$text_input_idx] = [];\n";
+	echo "suggs[$text_input_idx] = [];\n";
+}
+
+# set an element of the JavaScript 'words' array to a misspelled word
+function print_words_elem( $word, $index, $text_input_idx ) {
+	echo "words[$text_input_idx][$index] = '" . escape_quote( $word ) . "';\n";
+}
+
+
+# set an element of the JavaScript 'suggs' array to a list of suggestions
+function print_suggs_elem( $suggs, $index, $text_input_idx ) {
+	echo "suggs[$text_input_idx][$index] = [";
+	foreach( $suggs as $key=>$val ) {
+		if( $val ) {
+			echo "'" . escape_quote( $val ) . "'";
+			if ( $key+1 < count( $suggs )) {
+				echo ", ";
+			}
+		}
+	}
+	echo "];\n";
+}
+
+# escape single quote
+function escape_quote( $str ) {
+	return preg_replace ( "/'/", "\\'", $str );
+}
+
+
+# handle a server-side error.
+function error_handler( $err ) {
+	echo "error = '" . escape_quote( $err ) . "';\n";
+}
+
+## get the list of misspelled words. Put the results in the javascript words array
+## for each misspelled word, get suggestions and put in the javascript suggs array
+function print_checker_results() {
+
+	global $aspell_prog;
+	global $aspell_opts;
+	global $tempfiledir;
+	global $textinputs;
+	global $input_separator;
+	$aspell_err = "";
+	# create temp file
+	$tempfile = tempnam( $tempfiledir, 'aspell_data_' );
+
+	# open temp file, add the submitted text.
+	if( $fh = fopen( $tempfile, 'w' )) {
+		for( $i = 0; $i < count( $textinputs ); $i++ ) {
+			$text = urldecode( $textinputs[$i] );
+			$lines = explode( "\n", $text );
+			fwrite ( $fh, "%\n" ); # exit terse mode
+			fwrite ( $fh, "^$input_separator\n" );
+			fwrite ( $fh, "!\n" ); # enter terse mode
+			foreach( $lines as $key=>$value ) {
+				# use carat on each line to escape possible aspell commands
+				fwrite( $fh, "^$value\n" );
+			}
+		}
+		fclose( $fh );
+
+		# exec aspell command - redirect STDERR to STDOUT
+		$cmd = "$aspell_prog $aspell_opts < $tempfile 2>&1";
+		if( $aspellret = shell_exec( $cmd )) {
+			$linesout = explode( "\n", $aspellret );
+			$index = 0;
+			$text_input_index = -1;
+			# parse each line of aspell return
+			foreach( $linesout as $key=>$val ) {
+				$chardesc = substr( $val, 0, 1 );
+				# if '&', then not in dictionary but has suggestions
+				# if '#', then not in dictionary and no suggestions
+				# if '*', then it is a delimiter between text inputs
+				# if '@' then version info
+				if( $chardesc == '&' || $chardesc == '#' ) {
+					$line = explode( " ", $val, 5 );
+					print_words_elem( $line[1], $index, $text_input_index );
+					if( isset( $line[4] )) {
+						$suggs = explode( ", ", $line[4] );
+					} else {
+						$suggs = array();
+					}
+					print_suggs_elem( $suggs, $index, $text_input_index );
+					$index++;
+				} elseif( $chardesc == '*' ) {
+					$text_input_index++;
+					print_textindex_decl( $text_input_index );
+					$index = 0;
+				} elseif( $chardesc != '@' && $chardesc != "" ) {
+					# assume this is error output
+					$aspell_err .= $val;
+				}
+			}
+			if( $aspell_err ) {
+				$aspell_err = "Error executing `$cmd`\\n$aspell_err";
+				error_handler( $aspell_err );
+			}
+		} else {
+			error_handler( "System error: Aspell program execution failed (`$cmd`)" );
+		}
+	} else {
+		error_handler( "System error: Could not open file '$tempfile' for writing" );
+	}
+
+	# close temp file, delete file
+	unlink( $tempfile );
+}
+
+
+?>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel="stylesheet" type="text/css" href="<?php echo $spellercss ?>" />
+<script language="javascript" src="<?php echo $word_win_src ?>"></script>
+<script language="javascript">
+var suggs = new Array();
+var words = new Array();
+var textinputs = new Array();
+var error;
+<?php
+
+print_textinputs_var();
+
+print_checker_results();
+
+?>
+
+var wordWindowObj = new wordWindow();
+wordWindowObj.originalSpellings = words;
+wordWindowObj.suggestions = suggs;
+wordWindowObj.textInputs = textinputs;
+
+function init_spell() {
+	// check if any error occured during server-side processing
+	if( error ) {
+		alert( error );
+	} else {
+		// call the init_spell() function in the parent frameset
+		if (parent.frames.length) {
+			parent.init_spell( wordWindowObj );
+		} else {
+			alert('This page was loaded outside of a frameset. It might not display properly');
+		}
+	}
+}
+
+
+
+</script>
+
+</head>
+<!-- <body onLoad="init_spell();">		by FredCK -->
+<body onLoad="init_spell();" bgcolor="#ffffff">
+
+<script type="text/javascript">
+wordWindowObj.writeBody();
+</script>
+
+</body>
+</html>
+
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css	(revision 795)
@@ -0,0 +1,49 @@
+.blend {
+	font-family: courier new;
+	font-size: 10pt;
+	border: 0;
+	margin-bottom:-1;
+}
+.normalLabel {
+	font-size:8pt;
+}
+.normalText {
+	font-family:arial, helvetica, sans-serif;
+	font-size:10pt;
+	color:000000;
+	background-color:FFFFFF;
+}
+.plainText {
+	font-family: courier new, courier, monospace;
+	font-size: 10pt;
+	color:000000;
+	background-color:FFFFFF;
+}
+.controlWindowBody {
+	font-family:arial, helvetica, sans-serif;
+	font-size:8pt;
+	padding: 7px ;		/* by FredCK */
+	margin: 0px ;		/* by FredCK */
+	/* color:000000;				by FredCK */
+	/* background-color:DADADA;		by FredCK */
+}
+.readonlyInput {
+	background-color:DADADA;
+	color:000000;
+	font-size:8pt;
+	width:392px;
+}
+.textDefault {
+	font-size:8pt;
+	width: 200px;
+}
+.buttonDefault {
+	width:90px;
+	height:22px;
+	font-size:8pt;
+}
+.suggSlct {
+	width:200px;
+	margin-top:2;
+	font-size:8pt;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js	(revision 795)
@@ -0,0 +1,272 @@
+﻿////////////////////////////////////////////////////
+// wordWindow object
+////////////////////////////////////////////////////
+function wordWindow() {
+	// private properties
+	this._forms = [];
+
+	// private methods
+	this._getWordObject = _getWordObject;
+	//this._getSpellerObject = _getSpellerObject;
+	this._wordInputStr = _wordInputStr;
+	this._adjustIndexes = _adjustIndexes;
+	this._isWordChar = _isWordChar;
+	this._lastPos = _lastPos;
+
+	// public properties
+	this.wordChar = /[a-zA-Z]/;
+	this.windowType = "wordWindow";
+	this.originalSpellings = new Array();
+	this.suggestions = new Array();
+	this.checkWordBgColor = "pink";
+	this.normWordBgColor = "white";
+	this.text = "";
+	this.textInputs = new Array();
+	this.indexes = new Array();
+	//this.speller = this._getSpellerObject();
+
+	// public methods
+	this.resetForm = resetForm;
+	this.totalMisspellings = totalMisspellings;
+	this.totalWords = totalWords;
+	this.totalPreviousWords = totalPreviousWords;
+	//this.getTextObjectArray = getTextObjectArray;
+	this.getTextVal = getTextVal;
+	this.setFocus = setFocus;
+	this.removeFocus = removeFocus;
+	this.setText = setText;
+	//this.getTotalWords = getTotalWords;
+	this.writeBody = writeBody;
+	this.printForHtml = printForHtml;
+}
+
+function resetForm() {
+	if( this._forms ) {
+		for( var i = 0; i < this._forms.length; i++ ) {
+			this._forms[i].reset();
+		}
+	}
+	return true;
+}
+
+function totalMisspellings() {
+	var total_words = 0;
+	for( var i = 0; i < this.textInputs.length; i++ ) {
+		total_words += this.totalWords( i );
+	}
+	return total_words;
+}
+
+function totalWords( textIndex ) {
+	return this.originalSpellings[textIndex].length;
+}
+
+function totalPreviousWords( textIndex, wordIndex ) {
+	var total_words = 0;
+	for( var i = 0; i <= textIndex; i++ ) {
+		for( var j = 0; j < this.totalWords( i ); j++ ) {
+			if( i == textIndex && j == wordIndex ) {
+				break;
+			} else {
+				total_words++;
+			}
+		}
+	}
+	return total_words;
+}
+
+//function getTextObjectArray() {
+//	return this._form.elements;
+//}
+
+function getTextVal( textIndex, wordIndex ) {
+	var word = this._getWordObject( textIndex, wordIndex );
+	if( word ) {
+		return word.value;
+	}
+}
+
+function setFocus( textIndex, wordIndex ) {
+	var word = this._getWordObject( textIndex, wordIndex );
+	if( word ) {
+		if( word.type == "text" ) {
+			word.focus();
+			word.style.backgroundColor = this.checkWordBgColor;
+		}
+	}
+}
+
+function removeFocus( textIndex, wordIndex ) {
+	var word = this._getWordObject( textIndex, wordIndex );
+	if( word ) {
+		if( word.type == "text" ) {
+			word.blur();
+			word.style.backgroundColor = this.normWordBgColor;
+		}
+	}
+}
+
+function setText( textIndex, wordIndex, newText ) {
+	var word = this._getWordObject( textIndex, wordIndex );
+	var beginStr;
+	var endStr;
+	if( word ) {
+		var pos = this.indexes[textIndex][wordIndex];
+		var oldText = word.value;
+		// update the text given the index of the string
+		beginStr = this.textInputs[textIndex].substring( 0, pos );
+		endStr = this.textInputs[textIndex].substring(
+			pos + oldText.length,
+			this.textInputs[textIndex].length
+		);
+		this.textInputs[textIndex] = beginStr + newText + endStr;
+
+		// adjust the indexes on the stack given the differences in
+		// length between the new word and old word.
+		var lengthDiff = newText.length - oldText.length;
+		this._adjustIndexes( textIndex, wordIndex, lengthDiff );
+
+		word.size = newText.length;
+		word.value = newText;
+		this.removeFocus( textIndex, wordIndex );
+	}
+}
+
+
+function writeBody() {
+	var d = window.document;
+	var is_html = false;
+
+	d.open();
+
+	// iterate through each text input.
+	for( var txtid = 0; txtid < this.textInputs.length; txtid++ ) {
+		var end_idx = 0;
+		var begin_idx = 0;
+		d.writeln( '<form name="textInput'+txtid+'">' );
+		var wordtxt = this.textInputs[txtid];
+		this.indexes[txtid] = [];
+
+		if( wordtxt ) {
+			var orig = this.originalSpellings[txtid];
+			if( !orig ) break;
+
+			//!!! plain text, or HTML mode?
+			d.writeln( '<div class="plainText">' );
+			// iterate through each occurrence of a misspelled word.
+			for( var i = 0; i < orig.length; i++ ) {
+				// find the position of the current misspelled word,
+				// starting at the last misspelled word.
+				// and keep looking if it's a substring of another word
+				do {
+					begin_idx = wordtxt.indexOf( orig[i], end_idx );
+					end_idx = begin_idx + orig[i].length;
+					// word not found? messed up!
+					if( begin_idx == -1 ) break;
+					// look at the characters immediately before and after
+					// the word. If they are word characters we'll keep looking.
+					var before_char = wordtxt.charAt( begin_idx - 1 );
+					var after_char = wordtxt.charAt( end_idx );
+				} while (
+					this._isWordChar( before_char )
+					|| this._isWordChar( after_char )
+				);
+
+				// keep track of its position in the original text.
+				this.indexes[txtid][i] = begin_idx;
+
+				// write out the characters before the current misspelled word
+				for( var j = this._lastPos( txtid, i ); j < begin_idx; j++ ) {
+					// !!! html mode? make it html compatible
+					d.write( this.printForHtml( wordtxt.charAt( j )));
+				}
+
+				// write out the misspelled word.
+				d.write( this._wordInputStr( orig[i] ));
+
+				// if it's the last word, write out the rest of the text
+				if( i == orig.length-1 ){
+					d.write( printForHtml( wordtxt.substr( end_idx )));
+				}
+			}
+
+			d.writeln( '</div>' );
+
+		}
+		d.writeln( '</form>' );
+	}
+	//for ( var j = 0; j < d.forms.length; j++ ) {
+	//	alert( d.forms[j].name );
+	//	for( var k = 0; k < d.forms[j].elements.length; k++ ) {
+	//		alert( d.forms[j].elements[k].name + ": " + d.forms[j].elements[k].value );
+	//	}
+	//}
+
+	// set the _forms property
+	this._forms = d.forms;
+	d.close();
+}
+
+// return the character index in the full text after the last word we evaluated
+function _lastPos( txtid, idx ) {
+	if( idx > 0 )
+		return this.indexes[txtid][idx-1] + this.originalSpellings[txtid][idx-1].length;
+	else
+		return 0;
+}
+
+function printForHtml( n ) {
+	return n ;		// by FredCK
+/*
+	var htmlstr = n;
+	if( htmlstr.length == 1 ) {
+		// do simple case statement if it's just one character
+		switch ( n ) {
+			case "\n":
+				htmlstr = '<br/>';
+				break;
+			case "<":
+				htmlstr = '&lt;';
+				break;
+			case ">":
+				htmlstr = '&gt;';
+				break;
+		}
+		return htmlstr;
+	} else {
+		htmlstr = htmlstr.replace( /</g, '&lt' );
+		htmlstr = htmlstr.replace( />/g, '&gt' );
+		htmlstr = htmlstr.replace( /\n/g, '<br/>' );
+		return htmlstr;
+	}
+*/
+}
+
+function _isWordChar( letter ) {
+	if( letter.search( this.wordChar ) == -1 ) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
+function _getWordObject( textIndex, wordIndex ) {
+	if( this._forms[textIndex] ) {
+		if( this._forms[textIndex].elements[wordIndex] ) {
+			return this._forms[textIndex].elements[wordIndex];
+		}
+	}
+	return null;
+}
+
+function _wordInputStr( word ) {
+	var str = '<input readonly ';
+	str += 'class="blend" type="text" value="' + word + '" size="' + word.length + '">';
+	return str;
+}
+
+function _adjustIndexes( textIndex, wordIndex, lengthDiff ) {
+	for( var i = wordIndex + 1; i < this.originalSpellings[textIndex].length; i++ ) {
+		this.indexes[textIndex][i] = this.indexes[textIndex][i] + lengthDiff;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_spellerpages.html	(revision 795)
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Spell Check dialog window.
+-->
+<html>
+	<head>
+		<title>Spell Check</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="fck_spellerpages/spellerpages/spellChecker.js"></script>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCKLang = oEditor.FCKLang ;
+
+window.onload = function()
+{
+	document.getElementById('txtHtml').value = oEditor.FCK.EditorDocument.body.innerHTML ;
+
+	var oSpeller = new spellChecker( document.getElementById('txtHtml') ) ;
+	oSpeller.spellCheckScript = oEditor.FCKConfig.SpellerPagesServerScript || 'server-scripts/spellchecker.php' ;
+	oSpeller.OnFinished = oSpeller_OnFinished ;
+	oSpeller.openChecker() ;
+}
+
+function OnSpellerControlsLoad( controlsWindow )
+{
+	// Translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage( controlsWindow.document ) ;
+}
+
+function oSpeller_OnFinished( numberOCorrections )
+{
+	if ( numberOCorrections > 0 )
+		oEditor.FCK.SetHTML( document.getElementById('txtHtml').value ) ;
+	window.parent.Cancel() ;
+}
+
+		</script>
+	</head>
+	<body style="OVERFLOW: hidden" scroll="no" style="padding:0px;">
+		<input type="hidden" id="txtHtml" value="">
+		<iframe id="frmSpell" src="javascript:void(0)" name="spellchecker" width="100%" height="100%" frameborder="0"></iframe>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_checkbox.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_checkbox.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_checkbox.html	(revision 795)
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Checkbox dialog window.
+-->
+<html>
+	<head>
+		<title>Checkbox Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
+		<script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	if ( oActiveEl && oActiveEl.tagName == 'INPUT' && oActiveEl.type == 'checkbox' )
+	{
+		GetE('txtName').value		= oActiveEl.name ;
+		GetE('txtValue').value		= oEditor.FCKBrowserInfo.IsIE ? oActiveEl.value : GetAttribute( oActiveEl, 'value' ) ;
+		GetE('txtSelected').checked	= oActiveEl.checked ;
+	}
+	else
+		oActiveEl = null ;
+
+	window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+	if ( !oActiveEl )
+	{
+		oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+		oActiveEl.type = 'checkbox' ;
+		oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+	}
+
+	if ( GetE('txtName').value.length > 0 )
+		oActiveEl.name = GetE('txtName').value ;
+
+	if ( oEditor.FCKBrowserInfo.IsIE )
+		oActiveEl.value = GetE('txtValue').value ;
+	else
+		SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+	var bIsChecked = GetE('txtSelected').checked ;
+	SetAttribute( oActiveEl, 'checked', bIsChecked ? 'checked' : null ) ;	// For Firefox
+	oActiveEl.checked = bIsChecked ;
+
+	return true ;
+}
+
+		</script>
+	</head>
+	<body style="OVERFLOW: hidden" scroll="no">
+		<table height="100%" width="100%">
+			<tr>
+				<td align="center">
+					<table border="0" cellpadding="0" cellspacing="0" width="80%">
+						<tr>
+							<td>
+								<span fckLang="DlgCheckboxName">Name</span><br>
+								<input type="text" size="20" id="txtName" style="WIDTH: 100%">
+							</td>
+						</tr>
+						<tr>
+							<td>
+								<span fckLang="DlgCheckboxValue">Value</span><br>
+								<input type="text" size="20" id="txtValue" style="WIDTH: 100%">
+							</td>
+						</tr>
+						<tr>
+							<td><input type="checkbox" id="txtSelected"><label for="txtSelected" fckLang="DlgCheckboxSelected">Checked</label></td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html	(revision 795)
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Preview shown in the "Document Properties" dialog window.
+-->
+<html>
+	<head>
+		<title>Document Properties - Preview</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="robots" content="noindex, nofollow">
+		<script language="javascript">
+
+var eBase = parent.FCK.EditorDocument.getElementsByTagName( 'BASE' ) ;
+if ( eBase.length > 0 && eBase[0].href.length > 0 )
+{
+	document.write( '<base href="' + eBase[0].href + '">' ) ;
+}
+
+window.onload = function()
+{
+	if ( typeof( parent.OnPreviewLoad ) == 'function' )
+		parent.OnPreviewLoad( window, document.body ) ;
+}
+
+function SetBaseHRef( baseHref )
+{
+	var eBase = document.createElement( 'BASE' ) ;
+	eBase.href = baseHref ;
+
+	var eHead = document.getElementsByTagName( 'HEAD' )[0] ;
+	eHead.appendChild( eBase ) ;
+}
+
+function SetLinkColor( color )
+{
+	if ( color && color.length > 0 )
+		document.getElementById('eLink').style.color = color ;
+	else
+		document.getElementById('eLink').style.color = window.document.linkColor ;
+}
+
+function SetVisitedColor( color )
+{
+	if ( color && color.length > 0 )
+		document.getElementById('eVisited').style.color = color ;
+	else
+		document.getElementById('eVisited').style.color = window.document.vlinkColor ;
+}
+
+function SetActiveColor( color )
+{
+	if ( color && color.length > 0 )
+		document.getElementById('eActive').style.color = color ;
+	else
+		document.getElementById('eActive').style.color = window.document.alinkColor ;
+}
+		</script>
+	</head>
+	<body>
+		<table width="100%" height="100%" cellpadding="0" cellspacing="0" border="0">
+			<tr>
+				<td align="center" valign="middle">
+					Normal Text
+				</td>
+				<td id="eLink" align="center" valign="middle">
+					<u>Link Text</u>
+				</td>
+			</tr>
+			<tr>
+				<td id="eVisited" valign="middle" align="center">
+					<u>Visited Link</u>
+				</td>
+				<td id="eActive" valign="middle" align="center">
+					<u>Active Link</u>
+				</td>
+			</tr>
+		</table>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+		<br>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/fckeditor.original.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/fckeditor.original.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/fckeditor.original.html	(revision 795)
@@ -0,0 +1,319 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Main page that holds the editor.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor</title>
+	<meta name="robots" content="noindex, nofollow" />
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<!-- @Packager.RemoveLine
+	<meta http-equiv="Cache-Control" content="public" />
+	@Packager.RemoveLine -->
+	<script type="text/javascript">
+
+// Instead of loading scripts and CSSs using inline tags, all scripts are
+// loaded by code. In this way we can guarantee the correct processing order,
+// otherwise external scripts and inline scripts could be executed in an
+// unwanted order (IE).
+
+function LoadScript( url )
+{
+	document.write( '<scr' + 'ipt type="text/javascript" src="' + url + '" onerror="alert(\'Error loading \' + this.src);"><\/scr' + 'ipt>' ) ;
+}
+
+function LoadCss( url )
+{
+	document.write( '<link href="' + url + '" type="text/css" rel="stylesheet" onerror="alert(\'Error loading \' + this.src);" />' ) ;
+}
+
+// Main editor scripts.
+var sSuffix = /msie/.test( navigator.userAgent.toLowerCase() ) ? 'ie' : 'gecko' ;
+
+/* @Packager.RemoveLine
+LoadScript( 'js/fckeditorcode_' + sSuffix + '.js' ) ;
+@Packager.RemoveLine */
+// @Packager.Remove.Start
+
+LoadScript( '_source/fckconstants.js' ) ;
+LoadScript( '_source/fckjscoreextensions.js' ) ;
+
+if ( sSuffix == 'ie' )
+	LoadScript( '_source/classes/fckiecleanup.js' ) ;
+
+LoadScript( '_source/internals/fckbrowserinfo.js' ) ;
+LoadScript( '_source/internals/fckurlparams.js' ) ;
+LoadScript( '_source/classes/fckevents.js' ) ;
+LoadScript( '_source/internals/fck.js' ) ;
+LoadScript( '_source/internals/fck_' + sSuffix + '.js' ) ;
+LoadScript( '_source/internals/fckconfig.js' ) ;
+
+LoadScript( '_source/internals/fckdebug.js' ) ;
+LoadScript( '_source/internals/fckdomtools.js' ) ;
+LoadScript( '_source/internals/fcktools.js' ) ;
+LoadScript( '_source/internals/fcktools_' + sSuffix + '.js' ) ;
+LoadScript( '_source/fckeditorapi.js' ) ;
+LoadScript( '_source/classes/fckimagepreloader.js' ) ;
+LoadScript( '_source/internals/fckregexlib.js' ) ;
+LoadScript( '_source/internals/fcklistslib.js' ) ;
+LoadScript( '_source/internals/fcklanguagemanager.js' ) ;
+LoadScript( '_source/internals/fckxhtmlentities.js' ) ;
+LoadScript( '_source/internals/fckxhtml.js' ) ;
+LoadScript( '_source/internals/fckxhtml_' + sSuffix + '.js' ) ;
+LoadScript( '_source/internals/fckcodeformatter.js' ) ;
+LoadScript( '_source/internals/fckundo_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckeditingarea.js' ) ;
+LoadScript( '_source/classes/fckkeystrokehandler.js' ) ;
+
+LoadScript( '_source/internals/fcklisthandler.js' ) ;
+LoadScript( '_source/classes/fckelementpath.js' ) ;
+LoadScript( '_source/classes/fckdomrange.js' ) ;
+LoadScript( '_source/classes/fckdocumentfragment_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckw3crange.js' ) ;
+LoadScript( '_source/classes/fckdomrange_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckenterkey.js' ) ;
+
+LoadScript( '_source/internals/fckdocumentprocessor.js' ) ;
+LoadScript( '_source/internals/fckselection.js' ) ;
+LoadScript( '_source/internals/fckselection_' + sSuffix + '.js' ) ;
+
+LoadScript( '_source/internals/fcktablehandler.js' ) ;
+LoadScript( '_source/internals/fcktablehandler_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckxml_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckstyledef.js' ) ;
+LoadScript( '_source/classes/fckstyledef_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckstylesloader.js' ) ;
+
+LoadScript( '_source/commandclasses/fcknamedcommand.js' ) ;
+LoadScript( '_source/commandclasses/fck_othercommands.js' ) ;
+LoadScript( '_source/commandclasses/fckspellcheckcommand_' + sSuffix + '.js' ) ;
+LoadScript( '_source/commandclasses/fcktextcolorcommand.js' ) ;
+LoadScript( '_source/commandclasses/fckpasteplaintextcommand.js' ) ;
+LoadScript( '_source/commandclasses/fckpastewordcommand.js' ) ;
+LoadScript( '_source/commandclasses/fcktablecommand.js' ) ;
+LoadScript( '_source/commandclasses/fckstylecommand.js' ) ;
+LoadScript( '_source/commandclasses/fckfitwindow.js' ) ;
+LoadScript( '_source/internals/fckcommands.js' ) ;
+
+LoadScript( '_source/classes/fckpanel.js' ) ;
+LoadScript( '_source/classes/fckicon.js' ) ;
+LoadScript( '_source/classes/fcktoolbarbuttonui.js' ) ;
+LoadScript( '_source/classes/fcktoolbarbutton.js' ) ;
+LoadScript( '_source/classes/fckspecialcombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarspecialcombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarfontscombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarfontsizecombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarfontformatcombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarstylecombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarpanelbutton.js' ) ;
+LoadScript( '_source/internals/fcktoolbaritems.js' ) ;
+LoadScript( '_source/classes/fcktoolbar.js' ) ;
+LoadScript( '_source/classes/fcktoolbarbreak_' + sSuffix + '.js' ) ;
+LoadScript( '_source/internals/fcktoolbarset.js' ) ;
+LoadScript( '_source/internals/fckdialog.js' ) ;
+LoadScript( '_source/internals/fckdialog_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckmenuitem.js' ) ;
+LoadScript( '_source/classes/fckmenublock.js' ) ;
+LoadScript( '_source/classes/fckmenublockpanel.js' ) ;
+LoadScript( '_source/classes/fckcontextmenu.js' ) ;
+LoadScript( '_source/internals/fck_contextmenu.js' ) ;
+LoadScript( '_source/classes/fckplugin.js' ) ;
+LoadScript( '_source/internals/fckplugins.js' ) ;
+
+// @Packager.Remove.End
+
+// Base configuration file.
+LoadScript( '../fckconfig.js' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+if ( FCKBrowserInfo.IsIE )
+{
+	// Remove IE mouse flickering.
+	try
+	{
+		document.execCommand( 'BackgroundImageCache', false, true ) ;
+	}
+	catch (e)
+	{
+		// We have been reported about loading problems caused by the above
+		// line. For safety, let's just ignore errors.
+	}
+
+	// Create the default cleanup object used by the editor.
+	FCK.IECleanup = new FCKIECleanup( window ) ;
+	FCK.IECleanup.AddItem( FCKTempBin, FCKTempBin.Reset ) ;
+	FCK.IECleanup.AddItem( FCK, FCK_Cleanup ) ;
+}
+
+// The config hidden field is processed immediately, because
+// CustomConfigurationsPath may be set in the page.
+FCKConfig.ProcessHiddenField() ;
+
+// Load the custom configurations file (if defined).
+if ( FCKConfig.CustomConfigurationsPath.length > 0 )
+	LoadScript( FCKConfig.CustomConfigurationsPath ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Load configurations defined at page level.
+FCKConfig_LoadPageConfig() ;
+
+FCKConfig_PreProcess() ;
+
+// Load the active skin CSS.
+LoadCss( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+// Load the language file.
+FCKLanguageManager.Initialize() ;
+LoadScript( 'lang/' + FCKLanguageManager.ActiveLanguage.Code + '.js' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Initialize the editing area context menu.
+FCK_ContextMenu_Init() ;
+
+FCKPlugins.Load() ;
+
+	</script>
+	<script type="text/javascript">
+
+// Set the editor interface direction.
+window.document.dir = FCKLang.Dir ;
+
+// Activate pasting operations.
+if ( FCKConfig.ForcePasteAsPlainText || FCKConfig.AutoDetectPasteFromWord )
+	FCK.Events.AttachEvent( 'OnPaste', FCK.Paste ) ;
+
+	</script>
+	<script type="text/javascript">
+
+window.onload = function()
+{
+	InitializeAPI() ;
+
+	if ( FCKBrowserInfo.IsIE )
+		FCK_PreloadImages() ;
+	else
+		LoadToolbarSetup() ;
+}
+
+function LoadToolbarSetup()
+{
+	FCKeditorAPI._FunctionQueue.Add( LoadToolbar ) ;
+}
+
+function LoadToolbar()
+{
+	var oToolbarSet = FCK.ToolbarSet = FCKToolbarSet_Create() ;
+
+	if ( oToolbarSet.IsLoaded )
+		StartEditor() ;
+	else
+	{
+		oToolbarSet.OnLoad = StartEditor ;
+		oToolbarSet.Load( FCKURLParams['Toolbar'] || 'Default' ) ;
+	}
+}
+
+function StartEditor()
+{
+	// Remove the onload listener.
+	FCK.ToolbarSet.OnLoad = null ;
+
+	FCKeditorAPI._FunctionQueue.Remove( LoadToolbar ) ;
+
+	FCK.Events.AttachEvent( 'OnStatusChange', WaitForActive ) ;
+
+	// Start the editor.
+	FCK.StartEditor() ;
+}
+
+function WaitForActive( editorInstance, newStatus )
+{
+	if ( newStatus == FCK_STATUS_ACTIVE )
+	{
+		if ( FCKBrowserInfo.IsGecko )
+			FCKTools.RunFunction( window.onresize ) ;
+
+		_AttachFormSubmitToAPI() ;
+
+		FCK.SetStatus( FCK_STATUS_COMPLETE ) ;
+
+		// Call the special "FCKeditor_OnComplete" function that should be present in
+		// the HTML page where the editor is located.
+		if ( typeof( window.parent.FCKeditor_OnComplete ) == 'function' )
+			window.parent.FCKeditor_OnComplete( FCK ) ;
+	}
+}
+
+// Gecko browsers doens't calculate well that IFRAME size so we must
+// recalculate it every time the window size changes.
+if ( FCKBrowserInfo.IsGecko )
+{
+	function Window_OnResize()
+	{
+		if ( FCKBrowserInfo.IsOpera )
+			return ;
+
+		var oCell = document.getElementById( 'xEditingArea' ) ;
+
+		var eInnerElement = oCell.firstChild ;
+		if ( eInnerElement )
+		{
+			eInnerElement.style.height = 0 ;
+			eInnerElement.style.height = oCell.scrollHeight - 2 ;
+		}
+	}
+	window.onresize = Window_OnResize ;
+}
+
+	</script>
+</head>
+<body>
+	<table width="100%" cellpadding="0" cellspacing="0" style="height: 100%; table-layout: fixed">
+		<tr id="xToolbarRow" style="display: none">
+			<td id="xToolbarSpace" style="overflow: hidden">
+				<table width="100%" cellpadding="0" cellspacing="0">
+					<tr id="xCollapsed" style="display: none">
+						<td id="xExpandHandle" class="TB_Expand" colspan="3">
+							<img class="TB_ExpandImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+					</tr>
+					<tr id="xExpanded" style="display: none">
+						<td id="xTBLeftBorder" class="TB_SideBorder" style="width: 1px; display: none;"></td>
+						<td id="xCollapseHandle" style="display: none" class="TB_Collapse" valign="bottom">
+							<img class="TB_CollapseImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+						<td id="xToolbar" class="TB_ToolbarSet"></td>
+						<td class="TB_SideBorder" style="width: 1px"></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+		<tr>
+			<td id="xEditingArea" valign="top" style="height: 100%"></td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fo.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Faroese language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Fjal amboðsbjálkan",
+ToolbarExpand		: "Vís amboðsbjálkan",
+
+// Toolbar Items and Context Menu
+Save				: "Goym",
+NewPage				: "Nýggj síða",
+Preview				: "Frumsýning",
+Cut					: "Kvett",
+Copy				: "Avrita",
+Paste				: "Innrita",
+PasteText			: "Innrita reinan tekst",
+PasteWord			: "Innrita frá Word",
+Print				: "Prenta",
+SelectAll			: "Markera alt",
+RemoveFormat		: "Strika sniðgeving",
+InsertLinkLbl		: "Tilknýti",
+InsertLink			: "Ger/broyt tilknýti",
+RemoveLink			: "Strika tilknýti",
+Anchor				: "Ger/broyt marknastein",
+InsertImageLbl		: "Myndir",
+InsertImage			: "Set inn/broyt mynd",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Set inn/broyt Flash",
+InsertTableLbl		: "Tabell",
+InsertTable			: "Set inn/broyt tabell",
+InsertLineLbl		: "Linja",
+InsertLine			: "Ger vatnrætta linju",
+InsertSpecialCharLbl: "Sertekn",
+InsertSpecialChar	: "Set inn sertekn",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Set inn Smiley",
+About				: "Um FCKeditor",
+Bold				: "Feit skrift",
+Italic				: "Skráskrift",
+Underline			: "Undirstrikað",
+StrikeThrough		: "Yvirstrikað",
+Subscript			: "Lækkað skrift",
+Superscript			: "Hækkað skrift",
+LeftJustify			: "Vinstrasett",
+CenterJustify		: "Miðsett",
+RightJustify		: "Høgrasett",
+BlockJustify		: "Javnir tekstkantar",
+DecreaseIndent		: "Minka reglubrotarinntriv",
+IncreaseIndent		: "Økja reglubrotarinntriv",
+Undo				: "Angra",
+Redo				: "Vend aftur",
+NumberedListLbl		: "Talmerktur listi",
+NumberedList		: "Ger/strika talmerktan lista",
+BulletedListLbl		: "Punktmerktur listi",
+BulletedList		: "Ger/strika punktmerktan lista",
+ShowTableBorders	: "Vís tabellbordar",
+ShowDetails			: "Vís í smálutum",
+Style				: "Typografi",
+FontFormat			: "Skriftsnið",
+Font				: "Skrift",
+FontSize			: "Skriftstødd",
+TextColor			: "Tekstlitur",
+BGColor				: "Bakgrundslitur",
+Source				: "Kelda",
+Find				: "Leita",
+Replace				: "Yvirskriva",
+SpellCheck			: "Kanna stavseting",
+UniversalKeyboard	: "Knappaborð",
+PageBreakLbl		: "Síðuskift",
+PageBreak			: "Ger síðuskift",
+
+Form			: "Formur",
+Checkbox		: "Flugubein",
+RadioButton		: "Radioknøttur",
+TextField		: "Tekstteigur",
+Textarea		: "Tekstumráði",
+HiddenField		: "Fjaldur teigur",
+Button			: "Knøttur",
+SelectionField	: "Valskrá",
+ImageButton		: "Myndaknøttur",
+
+FitWindow		: "Set tekstviðgera til fulla stødd",
+
+// Context Menu
+EditLink			: "Broyt tilknýti",
+CellCM				: "Meski",
+RowCM				: "Rað",
+ColumnCM			: "Kolonna",
+InsertRow			: "Nýtt rað",
+DeleteRows			: "Strika røðir",
+InsertColumn		: "Nýggj kolonna",
+DeleteColumns		: "Strika kolonnur",
+InsertCell			: "Nýggjur meski",
+DeleteCells			: "Strika meskar",
+MergeCells			: "Flætta meskar",
+SplitCell			: "Být sundur meskar",
+TableDelete			: "Strika tabell",
+CellProperties		: "Meskueginleikar",
+TableProperties		: "Tabelleginleikar",
+ImageProperties		: "Myndaeginleikar",
+FlashProperties		: "Flash eginleikar",
+
+AnchorProp			: "Eginleikar fyri marknastein",
+ButtonProp			: "Eginleikar fyri knøtt",
+CheckboxProp		: "Eginleikar fyri flugubein",
+HiddenFieldProp		: "Eginleikar fyri fjaldan teig",
+RadioButtonProp		: "Eginleikar fyri radioknøtt",
+ImageButtonProp		: "Eginleikar fyri myndaknøtt",
+TextFieldProp		: "Eginleikar fyri tekstteig",
+SelectionFieldProp	: "Eginleikar fyri valskrá",
+TextareaProp		: "Eginleikar fyri tekstumráði",
+FormProp			: "Eginleikar fyri Form",
+
+FontFormats			: "Vanligt;Sniðgivið;Adressa;Yvirskrift 1;Yvirskrift 2;Yvirskrift 3;Yvirskrift 4;Yvirskrift 5;Yvirskrift 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML verður viðgjørt. Bíða við...",
+Done				: "Liðugt",
+PasteWordConfirm	: "Teksturin, royndur verður at seta inn, tykist at stava frá Word. Vilt tú reinsa tekstin, áðrenn hann verður settur inn?",
+NotCompatiblePaste	: "Hetta er bert tøkt í Internet Explorer 5.5 og nýggjari. Vilt tú seta tekstin inn kortini - óreinsaðan?",
+UnknownToolbarItem	: "Ókendur lutur í amboðsbjálkanum \"%1\"",
+UnknownCommand		: "Ókend kommando \"%1\"",
+NotImplemented		: "Hetta er ikki tøkt í hesi útgávuni",
+UnknownToolbarSet	: "Amboðsbjálkin \"%1\" finst ikki",
+NoActiveX			: "Trygdaruppsetingin í alnótskaganum kann sum er avmarka onkrar hentleikar í tekstviðgeranum. Tú mást loyva møguleikanum \"Run/Kør ActiveX controls and plug-ins\". Tú kanst uppliva feilir og ávaringar um tvørrandi hentleikar.",
+BrowseServerBlocked : "Ambætarakagin kundi ikki opnast. Tryggja tær, at allar pop-up forðingar eru óvirknar.",
+DialogBlocked		: "Tað eyðnaðist ikki at opna samskiftisrútin. Tryggja tær, at allar pop-up forðingar eru óvirknar.",
+
+// Dialogs
+DlgBtnOK			: "Góðkent",
+DlgBtnCancel		: "Avlýst",
+DlgBtnClose			: "Lat aftur",
+DlgBtnBrowseServer	: "Ambætarakagi",
+DlgAdvancedTag		: "Fjølbroytt",
+DlgOpOther			: "<Annað>",
+DlgInfoTab			: "Upplýsingar",
+DlgAlertUrl			: "Vinarliga veit ein URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ikki sett>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Tekstkós",
+DlgGenLangDirLtr	: "Frá vinstru til høgru (LTR)",
+DlgGenLangDirRtl	: "Frá høgru til vinstru (RTL)",
+DlgGenLangCode		: "Málkoda",
+DlgGenAccessKey		: "Snarvegisknappur",
+DlgGenName			: "Navn",
+DlgGenTabIndex		: "Inntriv indeks",
+DlgGenLongDescr		: "Víðkað URL frágreiðing",
+DlgGenClass			: "Typografi klassar",
+DlgGenTitle			: "Vegleiðandi heiti",
+DlgGenContType		: "Vegleiðandi innihaldsslag",
+DlgGenLinkCharset	: "Atknýtt teknsett",
+DlgGenStyle			: "Typografi",
+
+// Image Dialog
+DlgImgTitle			: "Myndaeginleikar",
+DlgImgInfoTab		: "Myndaupplýsingar",
+DlgImgBtnUpload		: "Send til ambætaran",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Send",
+DlgImgAlt			: "Alternativur tekstur",
+DlgImgWidth			: "Breidd",
+DlgImgHeight		: "Hædd",
+DlgImgLockRatio		: "Læs lutfallið",
+DlgBtnResetSize		: "Upprunastødd",
+DlgImgBorder		: "Bordi",
+DlgImgHSpace		: "Høgri breddi",
+DlgImgVSpace		: "Vinstri breddi",
+DlgImgAlign			: "Justering",
+DlgImgAlignLeft		: "Vinstra",
+DlgImgAlignAbsBottom: "Abs botnur",
+DlgImgAlignAbsMiddle: "Abs miðja",
+DlgImgAlignBaseline	: "Basislinja",
+DlgImgAlignBottom	: "Botnur",
+DlgImgAlignMiddle	: "Miðja",
+DlgImgAlignRight	: "Høgra",
+DlgImgAlignTextTop	: "Tekst toppur",
+DlgImgAlignTop		: "Ovast",
+DlgImgPreview		: "Frumsýning",
+DlgImgAlertUrl		: "Rita slóðina til myndina",
+DlgImgLinkTab		: "Tilknýti",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash eginleikar",
+DlgFlashChkPlay		: "Avspælingin byrjar sjálv",
+DlgFlashChkLoop		: "Endurspæl",
+DlgFlashChkMenu		: "Ger Flash skrá virkna",
+DlgFlashScale		: "Skalering",
+DlgFlashScaleAll	: "Vís alt",
+DlgFlashScaleNoBorder	: "Eingin bordi",
+DlgFlashScaleFit	: "Neyv skalering",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Tilknýti",
+DlgLnkInfoTab		: "Tilknýtis upplýsingar",
+DlgLnkTargetTab		: "Mál",
+
+DlgLnkType			: "Tilknýtisslag",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Tilknýti til marknastein í tekstinum",
+DlgLnkTypeEMail		: "Teldupostur",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<Annað>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Vel ein marknastein",
+DlgLnkAnchorByName	: "Eftir navni á marknasteini",
+DlgLnkAnchorById	: "Eftir element Id",
+DlgLnkNoAnchors		: "(Eingir marknasteinar eru í hesum dokumentið)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Teldupost-adressa",
+DlgLnkEMailSubject	: "Evni",
+DlgLnkEMailBody		: "Breyðtekstur",
+DlgLnkUpload		: "Send til ambætaran",
+DlgLnkBtnUpload		: "Send til ambætaran",
+
+DlgLnkTarget		: "Mál",
+DlgLnkTargetFrame	: "<ramma>",
+DlgLnkTargetPopup	: "<popup vindeyga>",
+DlgLnkTargetBlank	: "Nýtt vindeyga (_blank)",
+DlgLnkTargetParent	: "Upphavliga vindeygað (_parent)",
+DlgLnkTargetSelf	: "Sama vindeygað (_self)",
+DlgLnkTargetTop		: "Alt vindeygað (_top)",
+DlgLnkTargetFrameName	: "Vís navn vindeygans",
+DlgLnkPopWinName	: "Popup vindeygans navn",
+DlgLnkPopWinFeat	: "Popup vindeygans víðkaðu eginleikar",
+DlgLnkPopResize		: "Kann broyta stødd",
+DlgLnkPopLocation	: "Adressulinja",
+DlgLnkPopMenu		: "Skrábjálki",
+DlgLnkPopScroll		: "Rullibjálki",
+DlgLnkPopStatus		: "Støðufrágreiðingarbjálki",
+DlgLnkPopToolbar	: "Amboðsbjálki",
+DlgLnkPopFullScrn	: "Fullur skermur (IE)",
+DlgLnkPopDependent	: "Bundið (Netscape)",
+DlgLnkPopWidth		: "Breidd",
+DlgLnkPopHeight		: "Hædd",
+DlgLnkPopLeft		: "Frástøða frá vinstru",
+DlgLnkPopTop		: "Frástøða frá íerva",
+
+DlnLnkMsgNoUrl		: "Vinarliga skriva tilknýti (URL)",
+DlnLnkMsgNoEMail	: "Vinarliga skriva teldupost-adressu",
+DlnLnkMsgNoAnchor	: "Vinarliga vel marknastein",
+DlnLnkMsgInvPopName	: "Popup navnið má byrja við bókstavi og má ikki hava millumrúm",
+
+// Color Dialog
+DlgColorTitle		: "Vel lit",
+DlgColorBtnClear	: "Strika alt",
+DlgColorHighlight	: "Framhevja",
+DlgColorSelected	: "Valt",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Vel Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Vel sertekn",
+
+// Table Dialog
+DlgTableTitle		: "Eginleikar fyri tabell",
+DlgTableRows		: "Røðir",
+DlgTableColumns		: "Kolonnur",
+DlgTableBorder		: "Bordabreidd",
+DlgTableAlign		: "Justering",
+DlgTableAlignNotSet	: "<Einki valt>",
+DlgTableAlignLeft	: "Vinstrasett",
+DlgTableAlignCenter	: "Miðsett",
+DlgTableAlignRight	: "Høgrasett",
+DlgTableWidth		: "Breidd",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "prosent",
+DlgTableHeight		: "Hædd",
+DlgTableCellSpace	: "Fjarstøða millum meskar",
+DlgTableCellPad		: "Meskubreddi",
+DlgTableCaption		: "Tabellfrágreiðing",
+DlgTableSummary		: "Samandráttur",
+
+// Table Cell Dialog
+DlgCellTitle		: "Mesku eginleikar",
+DlgCellWidth		: "Breidd",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "prosent",
+DlgCellHeight		: "Hædd",
+DlgCellWordWrap		: "Orðkloyving",
+DlgCellWordWrapNotSet	: "<Einki valt>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nei",
+DlgCellHorAlign		: "Vatnrøtt justering",
+DlgCellHorAlignNotSet	: "<Einki valt>",
+DlgCellHorAlignLeft	: "Vinstrasett",
+DlgCellHorAlignCenter	: "Miðsett",
+DlgCellHorAlignRight: "Høgrasett",
+DlgCellVerAlign		: "Lodrøtt justering",
+DlgCellVerAlignNotSet	: "<Ikki sett>",
+DlgCellVerAlignTop	: "Ovast",
+DlgCellVerAlignMiddle	: "Miðjan",
+DlgCellVerAlignBottom	: "Niðast",
+DlgCellVerAlignBaseline	: "Basislinja",
+DlgCellRowSpan		: "Røðir, meskin fevnir um",
+DlgCellCollSpan		: "Kolonnur, meskin fevnir um",
+DlgCellBackColor	: "Bakgrundslitur",
+DlgCellBorderColor	: "Litur á borda",
+DlgCellBtnSelect	: "Vel...",
+
+// Find Dialog
+DlgFindTitle		: "Finn",
+DlgFindFindBtn		: "Finn",
+DlgFindNotFoundMsg	: "Leititeksturin varð ikki funnin",
+
+// Replace Dialog
+DlgReplaceTitle			: "Yvirskriva",
+DlgReplaceFindLbl		: "Finn:",
+DlgReplaceReplaceLbl	: "Yvirskriva við:",
+DlgReplaceCaseChk		: "Munur á stórum og smáðum bókstavum",
+DlgReplaceReplaceBtn	: "Yvirskriva",
+DlgReplaceReplAllBtn	: "Yvirskriva alt",
+DlgReplaceWordChk		: "Bert heil orð",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Trygdaruppseting alnótskagans forðar tekstviðgeranum í at kvetta tekstin. vinarliga nýt knappaborðið til at kvetta tekstin (CTRL+X).",
+PasteErrorCopy	: "Trygdaruppseting alnótskagans forðar tekstviðgeranum í at avrita tekstin. Vinarliga nýt knappaborðið til at avrita tekstin (CTRL+C).",
+
+PasteAsText		: "Innrita som reinan tekst",
+PasteFromWord	: "Innrita fra Word",
+
+DlgPasteMsg2	: "Vinarliga koyr tekstin í hendan rútin við knappaborðinum (<strong>CTRL+V</strong>) og klikk á <strong>Góðtak</strong>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Forfjóna Font definitiónirnar",
+DlgPasteRemoveStyles	: "Strika Styles definitiónir",
+DlgPasteCleanBox		: "Reinskanarkassi",
+
+// Color Picker
+ColorAutomatic	: "Av sær sjálvum",
+ColorMoreColors	: "Fleiri litir...",
+
+// Document Properties
+DocProps		: "Eginleikar fyri dokument",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Eginleikar fyri marknastein",
+DlgAnchorName		: "Heiti marknasteinsins",
+DlgAnchorErrorName	: "Vinarliga rita marknasteinsins heiti",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Finst ikki í orðabókini",
+DlgSpellChangeTo		: "Broyt til",
+DlgSpellBtnIgnore		: "Forfjóna",
+DlgSpellBtnIgnoreAll	: "Forfjóna alt",
+DlgSpellBtnReplace		: "Yvirskriva",
+DlgSpellBtnReplaceAll	: "Yvirskriva alt",
+DlgSpellBtnUndo			: "Angra",
+DlgSpellNoSuggestions	: "- Einki uppskot -",
+DlgSpellProgress		: "Rættstavarin arbeiðir...",
+DlgSpellNoMispell		: "Rættstavarain liðugur: Eingin feilur funnin",
+DlgSpellNoChanges		: "Rættstavarain liðugur: Einki orð varð broytt",
+DlgSpellOneChange		: "Rættstavarain liðugur: Eitt orð er broytt",
+DlgSpellManyChanges		: "Rættstavarain liðugur: %1 orð broytt",
+
+IeSpellDownload			: "Rættstavarin er ikki tøkur í tekstviðgeranum. Vilt tú heinta hann nú?",
+
+// Button Dialog
+DlgButtonText		: "Tekstur",
+DlgButtonType		: "Slag",
+DlgButtonTypeBtn	: "Knøttur",
+DlgButtonTypeSbm	: "Send",
+DlgButtonTypeRst	: "Nullstilla",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Navn",
+DlgCheckboxValue	: "Virði",
+DlgCheckboxSelected	: "Valt",
+
+// Form Dialog
+DlgFormName		: "Navn",
+DlgFormAction	: "Hending",
+DlgFormMethod	: "Háttur",
+
+// Select Field Dialog
+DlgSelectName		: "Navn",
+DlgSelectValue		: "Virði",
+DlgSelectSize		: "Stødd",
+DlgSelectLines		: "Linjur",
+DlgSelectChkMulti	: "Loyv fleiri valmøguleikum samstundis",
+DlgSelectOpAvail	: "Tøkir møguleikar",
+DlgSelectOpText		: "Tekstur",
+DlgSelectOpValue	: "Virði",
+DlgSelectBtnAdd		: "Legg afturat",
+DlgSelectBtnModify	: "Broyt",
+DlgSelectBtnUp		: "Upp",
+DlgSelectBtnDown	: "Niður",
+DlgSelectBtnSetValue : "Set sum valt virði",
+DlgSelectBtnDelete	: "Strika",
+
+// Textarea Dialog
+DlgTextareaName	: "Navn",
+DlgTextareaCols	: "kolonnur",
+DlgTextareaRows	: "røðir",
+
+// Text Field Dialog
+DlgTextName			: "Navn",
+DlgTextValue		: "Virði",
+DlgTextCharWidth	: "Breidd (sjónlig tekn)",
+DlgTextMaxChars		: "Mest loyvdu tekn",
+DlgTextType			: "Slag",
+DlgTextTypeText		: "Tekstur",
+DlgTextTypePass		: "Loyniorð",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Navn",
+DlgHiddenValue	: "Virði",
+
+// Bulleted List Dialog
+BulletedListProp	: "Eginleikar fyri punktmerktan lista",
+NumberedListProp	: "Eginleikar fyri talmerktan lista",
+DlgLstStart			: "Byrjan",
+DlgLstType			: "Slag",
+DlgLstTypeCircle	: "Sirkul",
+DlgLstTypeDisc		: "Fyltur sirkul",
+DlgLstTypeSquare	: "Fjórhyrningur",
+DlgLstTypeNumbers	: "Talmerkt (1, 2, 3)",
+DlgLstTypeLCase		: "Smáir bókstavir (a, b, c)",
+DlgLstTypeUCase		: "Stórir bókstavir (A, B, C)",
+DlgLstTypeSRoman	: "Smá rómaratøl (i, ii, iii)",
+DlgLstTypeLRoman	: "Stór rómaratøl (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Generelt",
+DlgDocBackTab		: "Bakgrund",
+DlgDocColorsTab		: "Litir og breddar",
+DlgDocMetaTab		: "META-upplýsingar",
+
+DlgDocPageTitle		: "Síðuheiti",
+DlgDocLangDir		: "Tekstkós",
+DlgDocLangDirLTR	: "Frá vinstru móti høgru (LTR)",
+DlgDocLangDirRTL	: "Frá høgru móti vinstru (RTL)",
+DlgDocLangCode		: "Málkoda",
+DlgDocCharSet		: "Teknsett koda",
+DlgDocCharSetCE		: "Miðeuropa",
+DlgDocCharSetCT		: "Kinesiskt traditionelt (Big5)",
+DlgDocCharSetCR		: "Cyrilliskt",
+DlgDocCharSetGR		: "Grikst",
+DlgDocCharSetJP		: "Japanskt",
+DlgDocCharSetKR		: "Koreanskt",
+DlgDocCharSetTR		: "Turkiskt",
+DlgDocCharSetUN		: "UNICODE (UTF-8)",
+DlgDocCharSetWE		: "Vestureuropa",
+DlgDocCharSetOther	: "Onnur teknsett koda",
+
+DlgDocDocType		: "Dokumentslag yvirskrift",
+DlgDocDocTypeOther	: "Annað dokumentslag yvirskrift",
+DlgDocIncXHTML		: "Viðfest XHTML deklaratiónir",
+DlgDocBgColor		: "Bakgrundslitur",
+DlgDocBgImage		: "Leið til bakgrundsmynd (URL)",
+DlgDocBgNoScroll	: "Læst bakgrund (rullar ikki)",
+DlgDocCText			: "Tekstur",
+DlgDocCLink			: "Tilknýti",
+DlgDocCVisited		: "Vitjaði tilknýti",
+DlgDocCActive		: "Virkin tilknýti",
+DlgDocMargins		: "Síðubreddar",
+DlgDocMaTop			: "Ovast",
+DlgDocMaLeft		: "Vinstra",
+DlgDocMaRight		: "Høgra",
+DlgDocMaBottom		: "Niðast",
+DlgDocMeIndex		: "Dokument index lyklaorð (sundurbýtt við komma)",
+DlgDocMeDescr		: "Dokumentlýsing",
+DlgDocMeAuthor		: "Høvundur",
+DlgDocMeCopy		: "Upphavsrættindi",
+DlgDocPreview		: "Frumsýning",
+
+// Templates Dialog
+Templates			: "Skabelónir",
+DlgTemplatesTitle	: "Innihaldsskabelónir",
+DlgTemplatesSelMsg	: "Vinarliga vel ta skabelón, ið skal opnast í tekstviðgeranum<br>(Hetta yvirskrivar núverandi innihald):",
+DlgTemplatesLoading	: "Heinti yvirlit yvir skabelónir. Vinarliga bíða við...",
+DlgTemplatesNoTpl	: "(Ongar skabelónir tøkar)",
+DlgTemplatesReplace	: "Yvirskriva núverandi innihald",
+
+// About Dialog
+DlgAboutAboutTab	: "Um",
+DlgAboutBrowserInfoTab	: "Upplýsingar um alnótskagan",
+DlgAboutLicenseTab	: "License",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "Fyri fleiri upplýsingar, far til"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bs.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bs.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bs.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Bosnian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Skupi trake sa alatima",
+ToolbarExpand		: "Otvori trake sa alatima",
+
+// Toolbar Items and Context Menu
+Save				: "Snimi",
+NewPage				: "Novi dokument",
+Preview				: "Prikaži",
+Cut					: "Izreži",
+Copy				: "Kopiraj",
+Paste				: "Zalijepi",
+PasteText			: "Zalijepi kao obièan tekst",
+PasteWord			: "Zalijepi iz Word-a",
+Print				: "Štampaj",
+SelectAll			: "Selektuj sve",
+RemoveFormat		: "Poništi format",
+InsertLinkLbl		: "Link",
+InsertLink			: "Ubaci/Izmjeni link",
+RemoveLink			: "Izbriši link",
+Anchor				: "Insert/Edit Anchor",	//MISSING
+InsertImageLbl		: "Slika",
+InsertImage			: "Ubaci/Izmjeni sliku",
+InsertFlashLbl		: "Flash",	//MISSING
+InsertFlash			: "Insert/Edit Flash",	//MISSING
+InsertTableLbl		: "Tabela",
+InsertTable			: "Ubaci/Izmjeni tabelu",
+InsertLineLbl		: "Linija",
+InsertLine			: "Ubaci horizontalnu liniju",
+InsertSpecialCharLbl: "Specijalni karakter",
+InsertSpecialChar	: "Ubaci specijalni karater",
+InsertSmileyLbl		: "Smješko",
+InsertSmiley		: "Ubaci smješka",
+About				: "O FCKeditor-u",
+Bold				: "Boldiraj",
+Italic				: "Ukosi",
+Underline			: "Podvuci",
+StrikeThrough		: "Precrtaj",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Lijevo poravnanje",
+CenterJustify		: "Centralno poravnanje",
+RightJustify		: "Desno poravnanje",
+BlockJustify		: "Puno poravnanje",
+DecreaseIndent		: "Smanji uvod",
+IncreaseIndent		: "Poveæaj uvod",
+Undo				: "Vrati",
+Redo				: "Ponovi",
+NumberedListLbl		: "Numerisana lista",
+NumberedList		: "Ubaci/Izmjeni numerisanu listu",
+BulletedListLbl		: "Lista",
+BulletedList		: "Ubaci/Izmjeni listu",
+ShowTableBorders	: "Pokaži okvire tabela",
+ShowDetails			: "Pokaži detalje",
+Style				: "Stil",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Velièina",
+TextColor			: "Boja teksta",
+BGColor				: "Boja pozadine",
+Source				: "HTML kôd",
+Find				: "Naði",
+Replace				: "Zamjeni",
+SpellCheck			: "Check Spelling",	//MISSING
+UniversalKeyboard	: "Universal Keyboard",	//MISSING
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "Form",	//MISSING
+Checkbox		: "Checkbox",	//MISSING
+RadioButton		: "Radio Button",	//MISSING
+TextField		: "Text Field",	//MISSING
+Textarea		: "Textarea",	//MISSING
+HiddenField		: "Hidden Field",	//MISSING
+Button			: "Button",	//MISSING
+SelectionField	: "Selection Field",	//MISSING
+ImageButton		: "Image Button",	//MISSING
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Izmjeni link",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Ubaci red",
+DeleteRows			: "Briši redove",
+InsertColumn		: "Ubaci kolonu",
+DeleteColumns		: "Briši kolone",
+InsertCell			: "Ubaci æeliju",
+DeleteCells			: "Briši æelije",
+MergeCells			: "Spoji æelije",
+SplitCell			: "Razdvoji æeliju",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "Svojstva æelije",
+TableProperties		: "Svojstva tabele",
+ImageProperties		: "Svojstva slike",
+FlashProperties		: "Flash Properties",	//MISSING
+
+AnchorProp			: "Anchor Properties",	//MISSING
+ButtonProp			: "Button Properties",	//MISSING
+CheckboxProp		: "Checkbox Properties",	//MISSING
+HiddenFieldProp		: "Hidden Field Properties",	//MISSING
+RadioButtonProp		: "Radio Button Properties",	//MISSING
+ImageButtonProp		: "Image Button Properties",	//MISSING
+TextFieldProp		: "Text Field Properties",	//MISSING
+SelectionFieldProp	: "Selection Field Properties",	//MISSING
+TextareaProp		: "Textarea Properties",	//MISSING
+FormProp			: "Form Properties",	//MISSING
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Procesiram XHTML. Molim saèekajte...",
+Done				: "Gotovo",
+PasteWordConfirm	: "Tekst koji želite zalijepiti èini se da je kopiran iz Worda. Da li želite da se prvo oèisti?",
+NotCompatiblePaste	: "Ova komanda je podržana u Internet Explorer-u verzijama 5.5 ili novijim. Da li želite da izvršite lijepljenje teksta bez èišæenja?",
+UnknownToolbarItem	: "Nepoznata stavka sa trake sa alatima \"%1\"",
+UnknownCommand		: "Nepoznata komanda \"%1\"",
+NotImplemented		: "Komanda nije implementirana",
+UnknownToolbarSet	: "Traka sa alatima \"%1\" ne postoji",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Odustani",
+DlgBtnClose			: "Zatvori",
+DlgBtnBrowseServer	: "Browse Server",	//MISSING
+DlgAdvancedTag		: "Naprednije",
+DlgOpOther			: "<Other>",	//MISSING
+DlgInfoTab			: "Info",	//MISSING
+DlgAlertUrl			: "Please insert the URL",	//MISSING
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nije podešeno>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Smjer pisanja",
+DlgGenLangDirLtr	: "S lijeva na desno (LTR)",
+DlgGenLangDirRtl	: "S desna na lijevo (RTL)",
+DlgGenLangCode		: "Jezièni kôd",
+DlgGenAccessKey		: "Pristupna tipka",
+DlgGenName			: "Naziv",
+DlgGenTabIndex		: "Tab indeks",
+DlgGenLongDescr		: "Dugaèki opis URL-a",
+DlgGenClass			: "Klase CSS stilova",
+DlgGenTitle			: "Advisory title",
+DlgGenContType		: "Advisory vrsta sadržaja",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Stil",
+
+// Image Dialog
+DlgImgTitle			: "Svojstva slike",
+DlgImgInfoTab		: "Info slike",
+DlgImgBtnUpload		: "Šalji na server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Šalji",
+DlgImgAlt			: "Tekst na slici",
+DlgImgWidth			: "Širina",
+DlgImgHeight		: "Visina",
+DlgImgLockRatio		: "Zakljuèaj odnos",
+DlgBtnResetSize		: "Resetuj dimenzije",
+DlgImgBorder		: "Okvir",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Poravnanje",
+DlgImgAlignLeft		: "Lijevo",
+DlgImgAlignAbsBottom: "Abs dole",
+DlgImgAlignAbsMiddle: "Abs sredina",
+DlgImgAlignBaseline	: "Bazno",
+DlgImgAlignBottom	: "Dno",
+DlgImgAlignMiddle	: "Sredina",
+DlgImgAlignRight	: "Desno",
+DlgImgAlignTextTop	: "Vrh teksta",
+DlgImgAlignTop		: "Vrh",
+DlgImgPreview		: "Prikaz",
+DlgImgAlertUrl		: "Molimo ukucajte URL od slike.",
+DlgImgLinkTab		: "Link",	//MISSING
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",	//MISSING
+DlgFlashChkPlay		: "Auto Play",	//MISSING
+DlgFlashChkLoop		: "Loop",	//MISSING
+DlgFlashChkMenu		: "Enable Flash Menu",	//MISSING
+DlgFlashScale		: "Scale",	//MISSING
+DlgFlashScaleAll	: "Show all",	//MISSING
+DlgFlashScaleNoBorder	: "No Border",	//MISSING
+DlgFlashScaleFit	: "Exact Fit",	//MISSING
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link info",
+DlgLnkTargetTab		: "Prozor",
+
+DlgLnkType			: "Tip linka",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Sidro na ovoj stranici",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<drugi>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Izaberi sidro",
+DlgLnkAnchorByName	: "Po nazivu sidra",
+DlgLnkAnchorById	: "Po Id-u elementa",
+DlgLnkNoAnchors		: "<Nema dostupnih sidra na stranici>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Adresa",
+DlgLnkEMailSubject	: "Subjekt poruke",
+DlgLnkEMailBody		: "Poruka",
+DlgLnkUpload		: "Šalji",
+DlgLnkBtnUpload		: "Šalji na server",
+
+DlgLnkTarget		: "Prozor",
+DlgLnkTargetFrame	: "<frejm>",
+DlgLnkTargetPopup	: "<popup prozor>",
+DlgLnkTargetBlank	: "Novi prozor (_blank)",
+DlgLnkTargetParent	: "Glavni prozor (_parent)",
+DlgLnkTargetSelf	: "Isti prozor (_self)",
+DlgLnkTargetTop		: "Najgornji prozor (_top)",
+DlgLnkTargetFrameName	: "Target Frame Name",	//MISSING
+DlgLnkPopWinName	: "Naziv popup prozora",
+DlgLnkPopWinFeat	: "Moguænosti popup prozora",
+DlgLnkPopResize		: "Promjenljive velièine",
+DlgLnkPopLocation	: "Traka za lokaciju",
+DlgLnkPopMenu		: "Izborna traka",
+DlgLnkPopScroll		: "Scroll traka",
+DlgLnkPopStatus		: "Statusna traka",
+DlgLnkPopToolbar	: "Traka sa alatima",
+DlgLnkPopFullScrn	: "Cijeli ekran (IE)",
+DlgLnkPopDependent	: "Ovisno (Netscape)",
+DlgLnkPopWidth		: "Širina",
+DlgLnkPopHeight		: "Visina",
+DlgLnkPopLeft		: "Lijeva pozicija",
+DlgLnkPopTop		: "Gornja pozicija",
+
+DlnLnkMsgNoUrl		: "Molimo ukucajte URL link",
+DlnLnkMsgNoEMail	: "Molimo ukucajte e-mail adresu",
+DlnLnkMsgNoAnchor	: "Molimo izaberite sidro",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Izaberi boju",
+DlgColorBtnClear	: "Oèisti",
+DlgColorHighlight	: "Igled",
+DlgColorSelected	: "Selektovana",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Ubaci smješka",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Izaberi specijalni karakter",
+
+// Table Dialog
+DlgTableTitle		: "Svojstva tabele",
+DlgTableRows		: "Redova",
+DlgTableColumns		: "Kolona",
+DlgTableBorder		: "Okvir",
+DlgTableAlign		: "Poravnanje",
+DlgTableAlignNotSet	: "<Nije podešeno>",
+DlgTableAlignLeft	: "Lijevo",
+DlgTableAlignCenter	: "Centar",
+DlgTableAlignRight	: "Desno",
+DlgTableWidth		: "Širina",
+DlgTableWidthPx		: "piksela",
+DlgTableWidthPc		: "posto",
+DlgTableHeight		: "Visina",
+DlgTableCellSpace	: "Razmak æelija",
+DlgTableCellPad		: "Uvod æelija",
+DlgTableCaption		: "Naslov",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "Svojstva æelije",
+DlgCellWidth		: "Širina",
+DlgCellWidthPx		: "piksela",
+DlgCellWidthPc		: "posto",
+DlgCellHeight		: "Visina",
+DlgCellWordWrap		: "Vrapuj tekst",
+DlgCellWordWrapNotSet	: "<Nije podešeno>",
+DlgCellWordWrapYes	: "Da",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Horizontalno poravnanje",
+DlgCellHorAlignNotSet	: "<Nije podešeno>",
+DlgCellHorAlignLeft	: "Lijevo",
+DlgCellHorAlignCenter	: "Centar",
+DlgCellHorAlignRight: "Desno",
+DlgCellVerAlign		: "Vertikalno poravnanje",
+DlgCellVerAlignNotSet	: "<Nije podešeno>",
+DlgCellVerAlignTop	: "Gore",
+DlgCellVerAlignMiddle	: "Sredina",
+DlgCellVerAlignBottom	: "Dno",
+DlgCellVerAlignBaseline	: "Bazno",
+DlgCellRowSpan		: "Spajanje æelija",
+DlgCellCollSpan		: "Spajanje kolona",
+DlgCellBackColor	: "Boja pozadine",
+DlgCellBorderColor	: "Boja okvira",
+DlgCellBtnSelect	: "Selektuj...",
+
+// Find Dialog
+DlgFindTitle		: "Naði",
+DlgFindFindBtn		: "Naði",
+DlgFindNotFoundMsg	: "Traženi tekst nije pronaðen.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Zamjeni",
+DlgReplaceFindLbl		: "Naði šta:",
+DlgReplaceReplaceLbl	: "Zamjeni sa:",
+DlgReplaceCaseChk		: "Uporeðuj velika/mala slova",
+DlgReplaceReplaceBtn	: "Zamjeni",
+DlgReplaceReplAllBtn	: "Zamjeni sve",
+DlgReplaceWordChk		: "Uporeðuj samo cijelu rijeè",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Sigurnosne postavke vašeg pretraživaèa ne dozvoljavaju operacije automatskog rezanja. Molimo koristite kraticu na tastaturi (Ctrl+X).",
+PasteErrorCopy	: "Sigurnosne postavke Vašeg pretraživaèa ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tastaturi (Ctrl+C).",
+
+PasteAsText		: "Zalijepi kao obièan tekst",
+PasteFromWord	: "Zalijepi iz Word-a",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.",	//MISSING
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",	//MISSING
+DlgPasteRemoveStyles	: "Remove Styles definitions",	//MISSING
+DlgPasteCleanBox		: "Clean Up Box",	//MISSING
+
+// Color Picker
+ColorAutomatic	: "Automatska",
+ColorMoreColors	: "Više boja...",
+
+// Document Properties
+DocProps		: "Document Properties",	//MISSING
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anchor Properties",	//MISSING
+DlgAnchorName		: "Anchor Name",	//MISSING
+DlgAnchorErrorName	: "Please type the anchor name",	//MISSING
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Not in dictionary",	//MISSING
+DlgSpellChangeTo		: "Change to",	//MISSING
+DlgSpellBtnIgnore		: "Ignore",	//MISSING
+DlgSpellBtnIgnoreAll	: "Ignore All",	//MISSING
+DlgSpellBtnReplace		: "Replace",	//MISSING
+DlgSpellBtnReplaceAll	: "Replace All",	//MISSING
+DlgSpellBtnUndo			: "Undo",	//MISSING
+DlgSpellNoSuggestions	: "- No suggestions -",	//MISSING
+DlgSpellProgress		: "Spell check in progress...",	//MISSING
+DlgSpellNoMispell		: "Spell check complete: No misspellings found",	//MISSING
+DlgSpellNoChanges		: "Spell check complete: No words changed",	//MISSING
+DlgSpellOneChange		: "Spell check complete: One word changed",	//MISSING
+DlgSpellManyChanges		: "Spell check complete: %1 words changed",	//MISSING
+
+IeSpellDownload			: "Spell checker not installed. Do you want to download it now?",	//MISSING
+
+// Button Dialog
+DlgButtonText		: "Text (Value)",	//MISSING
+DlgButtonType		: "Type",	//MISSING
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",	//MISSING
+DlgCheckboxValue	: "Value",	//MISSING
+DlgCheckboxSelected	: "Selected",	//MISSING
+
+// Form Dialog
+DlgFormName		: "Name",	//MISSING
+DlgFormAction	: "Action",	//MISSING
+DlgFormMethod	: "Method",	//MISSING
+
+// Select Field Dialog
+DlgSelectName		: "Name",	//MISSING
+DlgSelectValue		: "Value",	//MISSING
+DlgSelectSize		: "Size",	//MISSING
+DlgSelectLines		: "lines",	//MISSING
+DlgSelectChkMulti	: "Allow multiple selections",	//MISSING
+DlgSelectOpAvail	: "Available Options",	//MISSING
+DlgSelectOpText		: "Text",	//MISSING
+DlgSelectOpValue	: "Value",	//MISSING
+DlgSelectBtnAdd		: "Add",	//MISSING
+DlgSelectBtnModify	: "Modify",	//MISSING
+DlgSelectBtnUp		: "Up",	//MISSING
+DlgSelectBtnDown	: "Down",	//MISSING
+DlgSelectBtnSetValue : "Set as selected value",	//MISSING
+DlgSelectBtnDelete	: "Delete",	//MISSING
+
+// Textarea Dialog
+DlgTextareaName	: "Name",	//MISSING
+DlgTextareaCols	: "Columns",	//MISSING
+DlgTextareaRows	: "Rows",	//MISSING
+
+// Text Field Dialog
+DlgTextName			: "Name",	//MISSING
+DlgTextValue		: "Value",	//MISSING
+DlgTextCharWidth	: "Character Width",	//MISSING
+DlgTextMaxChars		: "Maximum Characters",	//MISSING
+DlgTextType			: "Type",	//MISSING
+DlgTextTypeText		: "Text",	//MISSING
+DlgTextTypePass		: "Password",	//MISSING
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",	//MISSING
+DlgHiddenValue	: "Value",	//MISSING
+
+// Bulleted List Dialog
+BulletedListProp	: "Bulleted List Properties",	//MISSING
+NumberedListProp	: "Numbered List Properties",	//MISSING
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Type",	//MISSING
+DlgLstTypeCircle	: "Circle",	//MISSING
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "Square",	//MISSING
+DlgLstTypeNumbers	: "Numbers (1, 2, 3)",	//MISSING
+DlgLstTypeLCase		: "Lowercase Letters (a, b, c)",	//MISSING
+DlgLstTypeUCase		: "Uppercase Letters (A, B, C)",	//MISSING
+DlgLstTypeSRoman	: "Small Roman Numerals (i, ii, iii)",	//MISSING
+DlgLstTypeLRoman	: "Large Roman Numerals (I, II, III)",	//MISSING
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",	//MISSING
+DlgDocBackTab		: "Background",	//MISSING
+DlgDocColorsTab		: "Colors and Margins",	//MISSING
+DlgDocMetaTab		: "Meta Data",	//MISSING
+
+DlgDocPageTitle		: "Page Title",	//MISSING
+DlgDocLangDir		: "Language Direction",	//MISSING
+DlgDocLangDirLTR	: "Left to Right (LTR)",	//MISSING
+DlgDocLangDirRTL	: "Right to Left (RTL)",	//MISSING
+DlgDocLangCode		: "Language Code",	//MISSING
+DlgDocCharSet		: "Character Set Encoding",	//MISSING
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Other Character Set Encoding",	//MISSING
+
+DlgDocDocType		: "Document Type Heading",	//MISSING
+DlgDocDocTypeOther	: "Other Document Type Heading",	//MISSING
+DlgDocIncXHTML		: "Include XHTML Declarations",	//MISSING
+DlgDocBgColor		: "Background Color",	//MISSING
+DlgDocBgImage		: "Background Image URL",	//MISSING
+DlgDocBgNoScroll	: "Nonscrolling Background",	//MISSING
+DlgDocCText			: "Text",	//MISSING
+DlgDocCLink			: "Link",	//MISSING
+DlgDocCVisited		: "Visited Link",	//MISSING
+DlgDocCActive		: "Active Link",	//MISSING
+DlgDocMargins		: "Page Margins",	//MISSING
+DlgDocMaTop			: "Top",	//MISSING
+DlgDocMaLeft		: "Left",	//MISSING
+DlgDocMaRight		: "Right",	//MISSING
+DlgDocMaBottom		: "Bottom",	//MISSING
+DlgDocMeIndex		: "Document Indexing Keywords (comma separated)",	//MISSING
+DlgDocMeDescr		: "Document Description",	//MISSING
+DlgDocMeAuthor		: "Author",	//MISSING
+DlgDocMeCopy		: "Copyright",	//MISSING
+DlgDocPreview		: "Preview",	//MISSING
+
+// Templates Dialog
+Templates			: "Templates",	//MISSING
+DlgTemplatesTitle	: "Content Templates",	//MISSING
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br />(the actual contents will be lost):",	//MISSING
+DlgTemplatesLoading	: "Loading templates list. Please wait...",	//MISSING
+DlgTemplatesNoTpl	: "(No templates defined)",	//MISSING
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "About",	//MISSING
+DlgAboutBrowserInfoTab	: "Browser Info",	//MISSING
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "verzija",
+DlgAboutInfo		: "Za više informacija posjetite"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/cs.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/cs.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/cs.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Czech language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Skrýt panel nástrojů",
+ToolbarExpand		: "Zobrazit panel nástrojů",
+
+// Toolbar Items and Context Menu
+Save				: "Uložit",
+NewPage				: "Nová stránka",
+Preview				: "Náhled",
+Cut					: "Vyjmout",
+Copy				: "Kopírovat",
+Paste				: "Vložit",
+PasteText			: "Vložit jako čistý text",
+PasteWord			: "Vložit z Wordu",
+Print				: "Tisk",
+SelectAll			: "Vybrat vše",
+RemoveFormat		: "Odstranit formátování",
+InsertLinkLbl		: "Odkaz",
+InsertLink			: "Vložit/změnit odkaz",
+RemoveLink			: "Odstranit odkaz",
+Anchor				: "Vložít/změnit záložku",
+InsertImageLbl		: "Obrázek",
+InsertImage			: "Vložit/změnit obrázek",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Vložit/Upravit Flash",
+InsertTableLbl		: "Tabulka",
+InsertTable			: "Vložit/změnit tabulku",
+InsertLineLbl		: "Linka",
+InsertLine			: "Vložit vodorovnou linku",
+InsertSpecialCharLbl: "Speciální znaky",
+InsertSpecialChar	: "Vložit speciální znaky",
+InsertSmileyLbl		: "Smajlíky",
+InsertSmiley		: "Vložit smajlík",
+About				: "O aplikaci FCKeditor",
+Bold				: "Tučné",
+Italic				: "Kurzíva",
+Underline			: "Podtržené",
+StrikeThrough		: "Přeškrtnuté",
+Subscript			: "Dolní index",
+Superscript			: "Horní index",
+LeftJustify			: "Zarovnat vlevo",
+CenterJustify		: "Zarovnat na střed",
+RightJustify		: "Zarovnat vpravo",
+BlockJustify		: "Zarovnat do bloku",
+DecreaseIndent		: "Zmenšit odsazení",
+IncreaseIndent		: "Zvětšit odsazení",
+Undo				: "Zpět",
+Redo				: "Znovu",
+NumberedListLbl		: "Číslování",
+NumberedList		: "Vložit/odstranit číslovaný seznam",
+BulletedListLbl		: "Odrážky",
+BulletedList		: "Vložit/odstranit odrážky",
+ShowTableBorders	: "Zobrazit okraje tabulek",
+ShowDetails			: "Zobrazit podrobnosti",
+Style				: "Styl",
+FontFormat			: "Formát",
+Font				: "Písmo",
+FontSize			: "Velikost",
+TextColor			: "Barva textu",
+BGColor				: "Barva pozadí",
+Source				: "Zdroj",
+Find				: "Hledat",
+Replace				: "Nahradit",
+SpellCheck			: "Zkontrolovat pravopis",
+UniversalKeyboard	: "Univerzální klávesnice",
+PageBreakLbl		: "Konec stránky",
+PageBreak			: "Vložit konec stránky",
+
+Form			: "Formulář",
+Checkbox		: "Zaškrtávací políčko",
+RadioButton		: "Přepínač",
+TextField		: "Textové pole",
+Textarea		: "Textová oblast",
+HiddenField		: "Skryté pole",
+Button			: "Tlačítko",
+SelectionField	: "Seznam",
+ImageButton		: "Obrázkové tlačítko",
+
+FitWindow		: "Maximalizovat velikost editoru",
+
+// Context Menu
+EditLink			: "Změnit odkaz",
+CellCM				: "Buňka",
+RowCM				: "Řádek",
+ColumnCM			: "Sloupec",
+InsertRow			: "Vložit řádek",
+DeleteRows			: "Smazat řádek",
+InsertColumn		: "Vložit sloupec",
+DeleteColumns		: "Smazat sloupec",
+InsertCell			: "Vložit buňku",
+DeleteCells			: "Smazat buňky",
+MergeCells			: "Sloučit buňky",
+SplitCell			: "Rozdělit buňku",
+TableDelete			: "Smazat tabulku",
+CellProperties		: "Vlastnosti buňky",
+TableProperties		: "Vlastnosti tabulky",
+ImageProperties		: "Vlastnosti obrázku",
+FlashProperties		: "Vlastnosti Flashe",
+
+AnchorProp			: "Vlastnosti záložky",
+ButtonProp			: "Vlastnosti tlačítka",
+CheckboxProp		: "Vlastnosti zaškrtávacího políčka",
+HiddenFieldProp		: "Vlastnosti skrytého pole",
+RadioButtonProp		: "Vlastnosti přepínače",
+ImageButtonProp		: "Vlastností obrázkového tlačítka",
+TextFieldProp		: "Vlastnosti textového pole",
+SelectionFieldProp	: "Vlastnosti seznamu",
+TextareaProp		: "Vlastnosti textové oblasti",
+FormProp			: "Vlastnosti formuláře",
+
+FontFormats			: "Normální;Formátovaný;Adresa;Nadpis 1;Nadpis 2;Nadpis 3;Nadpis 4;Nadpis 5;Nadpis 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Probíhá zpracování XHTML. Prosím čekejte...",
+Done				: "Hotovo",
+PasteWordConfirm	: "Jak je vidět, vkládaný text je kopírován z Wordu. Chcete jej před vložením vyčistit?",
+NotCompatiblePaste	: "Tento příkaz je dostupný pouze v Internet Exploreru verze 5.5 nebo vyšší. Chcete vložit text bez vyčištění?",
+UnknownToolbarItem	: "Neznámá položka panelu nástrojů \"%1\"",
+UnknownCommand		: "Neznámý příkaz \"%1\"",
+NotImplemented		: "Příkaz není implementován",
+UnknownToolbarSet	: "Panel nástrojů \"%1\" neexistuje",
+NoActiveX			: "Nastavení bezpečnosti Vašeho prohlížeče omezuje funkčnost některých jeho možností. Je třeba zapnout volbu \"Spouštět ovládáací prvky ActiveX a moduly plug-in\", jinak nebude možné využívat všechny dosputné schopnosti editoru.",
+BrowseServerBlocked : "Průzkumník zdrojů nelze otevřít. Prověřte, zda nemáte aktivováno blokování popup oken.",
+DialogBlocked		: "Nelze otevřít dialogové okno. Prověřte, zda nemáte aktivováno blokování popup oken.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Storno",
+DlgBtnClose			: "Zavřít",
+DlgBtnBrowseServer	: "Vybrat na serveru",
+DlgAdvancedTag		: "Rozšířené",
+DlgOpOther			: "<Ostatní>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Prosím vložte URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nenastaveno>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Orientace jazyka",
+DlgGenLangDirLtr	: "Zleva do prava (LTR)",
+DlgGenLangDirRtl	: "Zprava do leva (RTL)",
+DlgGenLangCode		: "Kód jazyka",
+DlgGenAccessKey		: "Přístupový klíč",
+DlgGenName			: "Jméno",
+DlgGenTabIndex		: "Pořadí prvku",
+DlgGenLongDescr		: "Dlouhý popis URL",
+DlgGenClass			: "Třída stylu",
+DlgGenTitle			: "Pomocný titulek",
+DlgGenContType		: "Pomocný typ obsahu",
+DlgGenLinkCharset	: "Přiřazená znaková sada",
+DlgGenStyle			: "Styl",
+
+// Image Dialog
+DlgImgTitle			: "Vlastnosti obrázku",
+DlgImgInfoTab		: "Informace o obrázku",
+DlgImgBtnUpload		: "Odeslat na server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Odeslat",
+DlgImgAlt			: "Alternativní text",
+DlgImgWidth			: "Šířka",
+DlgImgHeight		: "Výška",
+DlgImgLockRatio		: "Zámek",
+DlgBtnResetSize		: "Původní velikost",
+DlgImgBorder		: "Okraje",
+DlgImgHSpace		: "H-mezera",
+DlgImgVSpace		: "V-mezera",
+DlgImgAlign			: "Zarovnání",
+DlgImgAlignLeft		: "Vlevo",
+DlgImgAlignAbsBottom: "Zcela dolů",
+DlgImgAlignAbsMiddle: "Doprostřed",
+DlgImgAlignBaseline	: "Na účaří",
+DlgImgAlignBottom	: "Dolů",
+DlgImgAlignMiddle	: "Na střed",
+DlgImgAlignRight	: "Vpravo",
+DlgImgAlignTextTop	: "Na horní okraj textu",
+DlgImgAlignTop		: "Nahoru",
+DlgImgPreview		: "Náhled",
+DlgImgAlertUrl		: "Zadejte prosím URL obrázku",
+DlgImgLinkTab		: "Odkaz",
+
+// Flash Dialog
+DlgFlashTitle		: "Vlastnosti Flashe",
+DlgFlashChkPlay		: "Automatické spuštění",
+DlgFlashChkLoop		: "Opakování",
+DlgFlashChkMenu		: "Nabídka Flash",
+DlgFlashScale		: "Zobrazit",
+DlgFlashScaleAll	: "Zobrazit vše",
+DlgFlashScaleNoBorder	: "Bez okraje",
+DlgFlashScaleFit	: "Přizpůsobit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Odkaz",
+DlgLnkInfoTab		: "Informace o odkazu",
+DlgLnkTargetTab		: "Cíl",
+
+DlgLnkType			: "Typ odkazu",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Kotva v této stránce",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<jiný>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Vybrat kotvu",
+DlgLnkAnchorByName	: "Podle jména kotvy",
+DlgLnkAnchorById	: "Podle Id objektu",
+DlgLnkNoAnchors		: "<Ve stránce žádná kotva není definována>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mailová adresa",
+DlgLnkEMailSubject	: "Předmět zprávy",
+DlgLnkEMailBody		: "Tělo zprávy",
+DlgLnkUpload		: "Odeslat",
+DlgLnkBtnUpload		: "Odeslat na Server",
+
+DlgLnkTarget		: "Cíl",
+DlgLnkTargetFrame	: "<rámec>",
+DlgLnkTargetPopup	: "<vyskakovací okno>",
+DlgLnkTargetBlank	: "Nové okno (_blank)",
+DlgLnkTargetParent	: "Rodičovské okno (_parent)",
+DlgLnkTargetSelf	: "Stejné okno (_self)",
+DlgLnkTargetTop		: "Hlavní okno (_top)",
+DlgLnkTargetFrameName	: "Název cílového rámu",
+DlgLnkPopWinName	: "Název vyskakovacího okna",
+DlgLnkPopWinFeat	: "Vlastnosti vyskakovacího okna",
+DlgLnkPopResize		: "Měnitelná velikost",
+DlgLnkPopLocation	: "Panel umístění",
+DlgLnkPopMenu		: "Panel nabídky",
+DlgLnkPopScroll		: "Posuvníky",
+DlgLnkPopStatus		: "Stavový řádek",
+DlgLnkPopToolbar	: "Panel nástrojů",
+DlgLnkPopFullScrn	: "Celá obrazovka (IE)",
+DlgLnkPopDependent	: "Závislost (Netscape)",
+DlgLnkPopWidth		: "Šířka",
+DlgLnkPopHeight		: "Výška",
+DlgLnkPopLeft		: "Levý okraj",
+DlgLnkPopTop		: "Horní okraj",
+
+DlnLnkMsgNoUrl		: "Zadejte prosím URL odkazu",
+DlnLnkMsgNoEMail	: "Zadejte prosím e-mailovou adresu",
+DlnLnkMsgNoAnchor	: "Vyberte prosím kotvu",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Výběr barvy",
+DlgColorBtnClear	: "Vymazat",
+DlgColorHighlight	: "Zvýrazněná",
+DlgColorSelected	: "Vybraná",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Vkládání smajlíků",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Výběr speciálního znaku",
+
+// Table Dialog
+DlgTableTitle		: "Vlastnosti tabulky",
+DlgTableRows		: "Řádky",
+DlgTableColumns		: "Sloupce",
+DlgTableBorder		: "Ohraničení",
+DlgTableAlign		: "Zarovnání",
+DlgTableAlignNotSet	: "<nenastaveno>",
+DlgTableAlignLeft	: "Vlevo",
+DlgTableAlignCenter	: "Na střed",
+DlgTableAlignRight	: "Vpravo",
+DlgTableWidth		: "Šířka",
+DlgTableWidthPx		: "bodů",
+DlgTableWidthPc		: "procent",
+DlgTableHeight		: "Výška",
+DlgTableCellSpace	: "Vzdálenost buněk",
+DlgTableCellPad		: "Odsazení obsahu",
+DlgTableCaption		: "Popis",
+DlgTableSummary		: "Souhrn",
+
+// Table Cell Dialog
+DlgCellTitle		: "Vlastnosti buňky",
+DlgCellWidth		: "Šířka",
+DlgCellWidthPx		: "bodů",
+DlgCellWidthPc		: "procent",
+DlgCellHeight		: "Výška",
+DlgCellWordWrap		: "Zalamování",
+DlgCellWordWrapNotSet	: "<nenanstaveno>",
+DlgCellWordWrapYes	: "Ano",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Vodorovné zarovnání",
+DlgCellHorAlignNotSet	: "<nenastaveno>",
+DlgCellHorAlignLeft	: "Vlevo",
+DlgCellHorAlignCenter	: "Na střed",
+DlgCellHorAlignRight: "Vpravo",
+DlgCellVerAlign		: "Svislé zarovnání",
+DlgCellVerAlignNotSet	: "<nenastaveno>",
+DlgCellVerAlignTop	: "Nahoru",
+DlgCellVerAlignMiddle	: "Doprostřed",
+DlgCellVerAlignBottom	: "Dolů",
+DlgCellVerAlignBaseline	: "Na účaří",
+DlgCellRowSpan		: "Sloučené řádky",
+DlgCellCollSpan		: "Sloučené sloupce",
+DlgCellBackColor	: "Barva pozadí",
+DlgCellBorderColor	: "Barva ohraničení",
+DlgCellBtnSelect	: "Výběr...",
+
+// Find Dialog
+DlgFindTitle		: "Hledat",
+DlgFindFindBtn		: "Hledat",
+DlgFindNotFoundMsg	: "Hledaný text nebyl nalezen.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Nahradit",
+DlgReplaceFindLbl		: "Co hledat:",
+DlgReplaceReplaceLbl	: "Čím nahradit:",
+DlgReplaceCaseChk		: "Rozlišovat velikost písma",
+DlgReplaceReplaceBtn	: "Nahradit",
+DlgReplaceReplAllBtn	: "Nahradit vše",
+DlgReplaceWordChk		: "Pouze celá slova",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Bezpečnostní nastavení Vašeho prohlížeče nedovolují editoru spustit funkci pro vyjmutí zvoleného textu do schránky. Prosím vyjměte zvolený text do schránky pomocí klávesnice (Ctrl+X).",
+PasteErrorCopy	: "Bezpečnostní nastavení Vašeho prohlížeče nedovolují editoru spustit funkci pro kopírování zvoleného textu do schránky. Prosím zkopírujte zvolený text do schránky pomocí klávesnice (Ctrl+C).",
+
+PasteAsText		: "Vložit jako čistý text",
+PasteFromWord	: "Vložit text z Wordu",
+
+DlgPasteMsg2	: "Do následujícího pole vložte požadovaný obsah pomocí klávesnice (<STRONG>Ctrl+V</STRONG>) a stiskněte <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorovat písmo",
+DlgPasteRemoveStyles	: "Odstranit styly",
+DlgPasteCleanBox		: "Vyčistit",
+
+// Color Picker
+ColorAutomatic	: "Automaticky",
+ColorMoreColors	: "Více barev...",
+
+// Document Properties
+DocProps		: "Vlastnosti dokumentu",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Vlastnosti záložky",
+DlgAnchorName		: "Název záložky",
+DlgAnchorErrorName	: "Zadejte prosím název záložky",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Není ve slovníku",
+DlgSpellChangeTo		: "Změnit na",
+DlgSpellBtnIgnore		: "Přeskočit",
+DlgSpellBtnIgnoreAll	: "Přeskakovat vše",
+DlgSpellBtnReplace		: "Zaměnit",
+DlgSpellBtnReplaceAll	: "Zaměňovat vše",
+DlgSpellBtnUndo			: "Zpět",
+DlgSpellNoSuggestions	: "- žádné návrhy -",
+DlgSpellProgress		: "Probíhá kontrola pravopisu...",
+DlgSpellNoMispell		: "Kontrola pravopisu dokončena: Žádné pravopisné chyby nenalezeny",
+DlgSpellNoChanges		: "Kontrola pravopisu dokončena: Beze změn",
+DlgSpellOneChange		: "Kontrola pravopisu dokončena: Jedno slovo změněno",
+DlgSpellManyChanges		: "Kontrola pravopisu dokončena: %1 slov změněno",
+
+IeSpellDownload			: "Kontrola pravopisu není nainstalována. Chcete ji nyní stáhnout?",
+
+// Button Dialog
+DlgButtonText		: "Popisek",
+DlgButtonType		: "Typ",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Název",
+DlgCheckboxValue	: "Hodnota",
+DlgCheckboxSelected	: "Zaškrtnuto",
+
+// Form Dialog
+DlgFormName		: "Název",
+DlgFormAction	: "Akce",
+DlgFormMethod	: "Metoda",
+
+// Select Field Dialog
+DlgSelectName		: "Název",
+DlgSelectValue		: "Hodnota",
+DlgSelectSize		: "Velikost",
+DlgSelectLines		: "Řádků",
+DlgSelectChkMulti	: "Povolit mnohonásobné výběry",
+DlgSelectOpAvail	: "Dostupná nastavení",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Hodnota",
+DlgSelectBtnAdd		: "Přidat",
+DlgSelectBtnModify	: "Změnit",
+DlgSelectBtnUp		: "Nahoru",
+DlgSelectBtnDown	: "Dolů",
+DlgSelectBtnSetValue : "Nastavit jako vybranou hodnotu",
+DlgSelectBtnDelete	: "Smazat",
+
+// Textarea Dialog
+DlgTextareaName	: "Název",
+DlgTextareaCols	: "Sloupců",
+DlgTextareaRows	: "Řádků",
+
+// Text Field Dialog
+DlgTextName			: "Název",
+DlgTextValue		: "Hodnota",
+DlgTextCharWidth	: "Šířka ve znacích",
+DlgTextMaxChars		: "Maximální počet znaků",
+DlgTextType			: "Typ",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Heslo",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Název",
+DlgHiddenValue	: "Hodnota",
+
+// Bulleted List Dialog
+BulletedListProp	: "Vlastnosti odrážek",
+NumberedListProp	: "Vlastnosti číslovaného seznamu",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Typ",
+DlgLstTypeCircle	: "Kružnice",
+DlgLstTypeDisc		: "Kruh",
+DlgLstTypeSquare	: "Čtverec",
+DlgLstTypeNumbers	: "Čísla (1, 2, 3)",
+DlgLstTypeLCase		: "Malá písmena (a, b, c)",
+DlgLstTypeUCase		: "Velká písmena (A, B, C)",
+DlgLstTypeSRoman	: "Malé římská číslice (i, ii, iii)",
+DlgLstTypeLRoman	: "Velké římské číslice (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Obecné",
+DlgDocBackTab		: "Pozadí",
+DlgDocColorsTab		: "Barvy a okraje",
+DlgDocMetaTab		: "Metadata",
+
+DlgDocPageTitle		: "Titulek stránky",
+DlgDocLangDir		: "Směr jazyku",
+DlgDocLangDirLTR	: "Zleva do prava ",
+DlgDocLangDirRTL	: "Zprava doleva",
+DlgDocLangCode		: "Kód jazyku",
+DlgDocCharSet		: "Znaková sada",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Další znaková sada",
+
+DlgDocDocType		: "Typ dokumentu",
+DlgDocDocTypeOther	: "Jiný typ dokumetu",
+DlgDocIncXHTML		: "Zahrnou deklarace XHTML",
+DlgDocBgColor		: "Barva pozadí",
+DlgDocBgImage		: "URL obrázku na pozadí",
+DlgDocBgNoScroll	: "Nerolovatelné pozadí",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Odkaz",
+DlgDocCVisited		: "Navštívený odkaz",
+DlgDocCActive		: "Vybraný odkaz",
+DlgDocMargins		: "Okraje stránky",
+DlgDocMaTop			: "Horní",
+DlgDocMaLeft		: "Levý",
+DlgDocMaRight		: "Pravý",
+DlgDocMaBottom		: "Dolní",
+DlgDocMeIndex		: "Klíčová slova (oddělená čárkou)",
+DlgDocMeDescr		: "Popis dokumentu",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Autorská práva",
+DlgDocPreview		: "Náhled",
+
+// Templates Dialog
+Templates			: "Šablony",
+DlgTemplatesTitle	: "Šablony obsahu",
+DlgTemplatesSelMsg	: "Prosím zvolte šablonu pro otevření v editoru<br>(aktuální obsah editoru bude ztracen):",
+DlgTemplatesLoading	: "Nahrávám přeheld šablon. Prosím čekejte...",
+DlgTemplatesNoTpl	: "(Není definována žádná šablona)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "O aplikaci",
+DlgAboutBrowserInfoTab	: "Informace o prohlížeči",
+DlgAboutLicenseTab	: "Licence",
+DlgAboutVersion		: "verze",
+DlgAboutInfo		: "Více informací získáte na"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-au.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-au.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-au.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * English (Australia) language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Collapse Toolbar",
+ToolbarExpand		: "Expand Toolbar",
+
+// Toolbar Items and Context Menu
+Save				: "Save",
+NewPage				: "New Page",
+Preview				: "Preview",
+Cut					: "Cut",
+Copy				: "Copy",
+Paste				: "Paste",
+PasteText			: "Paste as plain text",
+PasteWord			: "Paste from Word",
+Print				: "Print",
+SelectAll			: "Select All",
+RemoveFormat		: "Remove Format",
+InsertLinkLbl		: "Link",
+InsertLink			: "Insert/Edit Link",
+RemoveLink			: "Remove Link",
+Anchor				: "Insert/Edit Anchor",
+InsertImageLbl		: "Image",
+InsertImage			: "Insert/Edit Image",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insert/Edit Flash",
+InsertTableLbl		: "Table",
+InsertTable			: "Insert/Edit Table",
+InsertLineLbl		: "Line",
+InsertLine			: "Insert Horizontal Line",
+InsertSpecialCharLbl: "Special Character",
+InsertSpecialChar	: "Insert Special Character",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Insert Smiley",
+About				: "About FCKeditor",
+Bold				: "Bold",
+Italic				: "Italic",
+Underline			: "Underline",
+StrikeThrough		: "Strike Through",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Left Justify",
+CenterJustify		: "Centre Justify",
+RightJustify		: "Right Justify",
+BlockJustify		: "Block Justify",
+DecreaseIndent		: "Decrease Indent",
+IncreaseIndent		: "Increase Indent",
+Undo				: "Undo",
+Redo				: "Redo",
+NumberedListLbl		: "Numbered List",
+NumberedList		: "Insert/Remove Numbered List",
+BulletedListLbl		: "Bulleted List",
+BulletedList		: "Insert/Remove Bulleted List",
+ShowTableBorders	: "Show Table Borders",
+ShowDetails			: "Show Details",
+Style				: "Style",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Size",
+TextColor			: "Text Colour",
+BGColor				: "Background Colour",
+Source				: "Source",
+Find				: "Find",
+Replace				: "Replace",
+SpellCheck			: "Check Spelling",
+UniversalKeyboard	: "Universal Keyboard",
+PageBreakLbl		: "Page Break",
+PageBreak			: "Insert Page Break",
+
+Form			: "Form",
+Checkbox		: "Checkbox",
+RadioButton		: "Radio Button",
+TextField		: "Text Field",
+Textarea		: "Textarea",
+HiddenField		: "Hidden Field",
+Button			: "Button",
+SelectionField	: "Selection Field",
+ImageButton		: "Image Button",
+
+FitWindow		: "Maximize the editor size",
+
+// Context Menu
+EditLink			: "Edit Link",
+CellCM				: "Cell",
+RowCM				: "Row",
+ColumnCM			: "Column",
+InsertRow			: "Insert Row",
+DeleteRows			: "Delete Rows",
+InsertColumn		: "Insert Column",
+DeleteColumns		: "Delete Columns",
+InsertCell			: "Insert Cell",
+DeleteCells			: "Delete Cells",
+MergeCells			: "Merge Cells",
+SplitCell			: "Split Cell",
+TableDelete			: "Delete Table",
+CellProperties		: "Cell Properties",
+TableProperties		: "Table Properties",
+ImageProperties		: "Image Properties",
+FlashProperties		: "Flash Properties",
+
+AnchorProp			: "Anchor Properties",
+ButtonProp			: "Button Properties",
+CheckboxProp		: "Checkbox Properties",
+HiddenFieldProp		: "Hidden Field Properties",
+RadioButtonProp		: "Radio Button Properties",
+ImageButtonProp		: "Image Button Properties",
+TextFieldProp		: "Text Field Properties",
+SelectionFieldProp	: "Selection Field Properties",
+TextareaProp		: "Textarea Properties",
+FormProp			: "Form Properties",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Processing XHTML. Please wait...",
+Done				: "Done",
+PasteWordConfirm	: "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?",
+NotCompatiblePaste	: "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?",
+UnknownToolbarItem	: "Unknown toolbar item \"%1\"",
+UnknownCommand		: "Unknown command name \"%1\"",
+NotImplemented		: "Command not implemented",
+UnknownToolbarSet	: "Toolbar set \"%1\" doesn't exist",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancel",
+DlgBtnClose			: "Close",
+DlgBtnBrowseServer	: "Browse Server",
+DlgAdvancedTag		: "Advanced",
+DlgOpOther			: "<Other>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Please insert the URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<not set>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Language Direction",
+DlgGenLangDirLtr	: "Left to Right (LTR)",
+DlgGenLangDirRtl	: "Right to Left (RTL)",
+DlgGenLangCode		: "Language Code",
+DlgGenAccessKey		: "Access Key",
+DlgGenName			: "Name",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Long Description URL",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Image Properties",
+DlgImgInfoTab		: "Image Info",
+DlgImgBtnUpload		: "Send it to the Server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternative Text",
+DlgImgWidth			: "Width",
+DlgImgHeight		: "Height",
+DlgImgLockRatio		: "Lock Ratio",
+DlgBtnResetSize		: "Reset Size",
+DlgImgBorder		: "Border",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Align",
+DlgImgAlignLeft		: "Left",
+DlgImgAlignAbsBottom: "Abs Bottom",
+DlgImgAlignAbsMiddle: "Abs Middle",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Bottom",
+DlgImgAlignMiddle	: "Middle",
+DlgImgAlignRight	: "Right",
+DlgImgAlignTextTop	: "Text Top",
+DlgImgAlignTop		: "Top",
+DlgImgPreview		: "Preview",
+DlgImgAlertUrl		: "Please type the image URL",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",
+DlgFlashChkPlay		: "Auto Play",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Enable Flash Menu",
+DlgFlashScale		: "Scale",
+DlgFlashScaleAll	: "Show all",
+DlgFlashScaleNoBorder	: "No Border",
+DlgFlashScaleFit	: "Exact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Target",
+
+DlgLnkType			: "Link Type",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Link to anchor in the text",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<other>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Select an Anchor",
+DlgLnkAnchorByName	: "By Anchor Name",
+DlgLnkAnchorById	: "By Element Id",
+DlgLnkNoAnchors		: "(No anchors available in the document)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Address",
+DlgLnkEMailSubject	: "Message Subject",
+DlgLnkEMailBody		: "Message Body",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Send it to the Server",
+
+DlgLnkTarget		: "Target",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<popup window>",
+DlgLnkTargetBlank	: "New Window (_blank)",
+DlgLnkTargetParent	: "Parent Window (_parent)",
+DlgLnkTargetSelf	: "Same Window (_self)",
+DlgLnkTargetTop		: "Topmost Window (_top)",
+DlgLnkTargetFrameName	: "Target Frame Name",
+DlgLnkPopWinName	: "Popup Window Name",
+DlgLnkPopWinFeat	: "Popup Window Features",
+DlgLnkPopResize		: "Resizable",
+DlgLnkPopLocation	: "Location Bar",
+DlgLnkPopMenu		: "Menu Bar",
+DlgLnkPopScroll		: "Scroll Bars",
+DlgLnkPopStatus		: "Status Bar",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Full Screen (IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "Width",
+DlgLnkPopHeight		: "Height",
+DlgLnkPopLeft		: "Left Position",
+DlgLnkPopTop		: "Top Position",
+
+DlnLnkMsgNoUrl		: "Please type the link URL",
+DlnLnkMsgNoEMail	: "Please type the e-mail address",
+DlnLnkMsgNoAnchor	: "Please select an anchor",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",
+
+// Color Dialog
+DlgColorTitle		: "Select Colour",
+DlgColorBtnClear	: "Clear",
+DlgColorHighlight	: "Highlight",
+DlgColorSelected	: "Selected",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insert a Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Select Special Character",
+
+// Table Dialog
+DlgTableTitle		: "Table Properties",
+DlgTableRows		: "Rows",
+DlgTableColumns		: "Columns",
+DlgTableBorder		: "Border size",
+DlgTableAlign		: "Alignment",
+DlgTableAlignNotSet	: "<Not set>",
+DlgTableAlignLeft	: "Left",
+DlgTableAlignCenter	: "Centre",
+DlgTableAlignRight	: "Right",
+DlgTableWidth		: "Width",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Height",
+DlgTableCellSpace	: "Cell spacing",
+DlgTableCellPad		: "Cell padding",
+DlgTableCaption		: "Caption",
+DlgTableSummary		: "Summary",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cell Properties",
+DlgCellWidth		: "Width",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Height",
+DlgCellWordWrap		: "Word Wrap",
+DlgCellWordWrapNotSet	: "<Not set>",
+DlgCellWordWrapYes	: "Yes",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Horizontal Alignment",
+DlgCellHorAlignNotSet	: "<Not set>",
+DlgCellHorAlignLeft	: "Left",
+DlgCellHorAlignCenter	: "Centre",
+DlgCellHorAlignRight: "Right",
+DlgCellVerAlign		: "Vertical Alignment",
+DlgCellVerAlignNotSet	: "<Not set>",
+DlgCellVerAlignTop	: "Top",
+DlgCellVerAlignMiddle	: "Middle",
+DlgCellVerAlignBottom	: "Bottom",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Rows Span",
+DlgCellCollSpan		: "Columns Span",
+DlgCellBackColor	: "Background Colour",
+DlgCellBorderColor	: "Border Colour",
+DlgCellBtnSelect	: "Select...",
+
+// Find Dialog
+DlgFindTitle		: "Find",
+DlgFindFindBtn		: "Find",
+DlgFindNotFoundMsg	: "The specified text was not found.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Replace",
+DlgReplaceFindLbl		: "Find what:",
+DlgReplaceReplaceLbl	: "Replace with:",
+DlgReplaceCaseChk		: "Match case",
+DlgReplaceReplaceBtn	: "Replace",
+DlgReplaceReplAllBtn	: "Replace All",
+DlgReplaceWordChk		: "Match whole word",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).",
+PasteErrorCopy	: "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).",
+
+PasteAsText		: "Paste as Plain Text",
+PasteFromWord	: "Paste from Word",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<STRONG>Ctrl+V</STRONG>) and hit <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",
+DlgPasteRemoveStyles	: "Remove Styles definitions",
+DlgPasteCleanBox		: "Clean Up Box",
+
+// Color Picker
+ColorAutomatic	: "Automatic",
+ColorMoreColors	: "More Colours...",
+
+// Document Properties
+DocProps		: "Document Properties",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anchor Properties",
+DlgAnchorName		: "Anchor Name",
+DlgAnchorErrorName	: "Please type the anchor name",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Not in dictionary",
+DlgSpellChangeTo		: "Change to",
+DlgSpellBtnIgnore		: "Ignore",
+DlgSpellBtnIgnoreAll	: "Ignore All",
+DlgSpellBtnReplace		: "Replace",
+DlgSpellBtnReplaceAll	: "Replace All",
+DlgSpellBtnUndo			: "Undo",
+DlgSpellNoSuggestions	: "- No suggestions -",
+DlgSpellProgress		: "Spell check in progress...",
+DlgSpellNoMispell		: "Spell check complete: No misspellings found",
+DlgSpellNoChanges		: "Spell check complete: No words changed",
+DlgSpellOneChange		: "Spell check complete: One word changed",
+DlgSpellManyChanges		: "Spell check complete: %1 words changed",
+
+IeSpellDownload			: "Spell checker not installed. Do you want to download it now?",
+
+// Button Dialog
+DlgButtonText		: "Text (Value)",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",
+DlgCheckboxValue	: "Value",
+DlgCheckboxSelected	: "Selected",
+
+// Form Dialog
+DlgFormName		: "Name",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Method",
+
+// Select Field Dialog
+DlgSelectName		: "Name",
+DlgSelectValue		: "Value",
+DlgSelectSize		: "Size",
+DlgSelectLines		: "lines",
+DlgSelectChkMulti	: "Allow multiple selections",
+DlgSelectOpAvail	: "Available Options",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Value",
+DlgSelectBtnAdd		: "Add",
+DlgSelectBtnModify	: "Modify",
+DlgSelectBtnUp		: "Up",
+DlgSelectBtnDown	: "Down",
+DlgSelectBtnSetValue : "Set as selected value",
+DlgSelectBtnDelete	: "Delete",
+
+// Textarea Dialog
+DlgTextareaName	: "Name",
+DlgTextareaCols	: "Columns",
+DlgTextareaRows	: "Rows",
+
+// Text Field Dialog
+DlgTextName			: "Name",
+DlgTextValue		: "Value",
+DlgTextCharWidth	: "Character Width",
+DlgTextMaxChars		: "Maximum Characters",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Password",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",
+DlgHiddenValue	: "Value",
+
+// Bulleted List Dialog
+BulletedListProp	: "Bulleted List Properties",
+NumberedListProp	: "Numbered List Properties",
+DlgLstStart			: "Start",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Circle",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "Square",
+DlgLstTypeNumbers	: "Numbers (1, 2, 3)",
+DlgLstTypeLCase		: "Lowercase Letters (a, b, c)",
+DlgLstTypeUCase		: "Uppercase Letters (A, B, C)",
+DlgLstTypeSRoman	: "Small Roman Numerals (i, ii, iii)",
+DlgLstTypeLRoman	: "Large Roman Numerals (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Background",
+DlgDocColorsTab		: "Colours and Margins",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Page Title",
+DlgDocLangDir		: "Language Direction",
+DlgDocLangDirLTR	: "Left to Right (LTR)",
+DlgDocLangDirRTL	: "Right to Left (RTL)",
+DlgDocLangCode		: "Language Code",
+DlgDocCharSet		: "Character Set Encoding",
+DlgDocCharSetCE		: "Central European",
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Greek",
+DlgDocCharSetJP		: "Japanese",
+DlgDocCharSetKR		: "Korean",
+DlgDocCharSetTR		: "Turkish",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "Other Character Set Encoding",
+
+DlgDocDocType		: "Document Type Heading",
+DlgDocDocTypeOther	: "Other Document Type Heading",
+DlgDocIncXHTML		: "Include XHTML Declarations",
+DlgDocBgColor		: "Background Colour",
+DlgDocBgImage		: "Background Image URL",
+DlgDocBgNoScroll	: "Nonscrolling Background",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Visited Link",
+DlgDocCActive		: "Active Link",
+DlgDocMargins		: "Page Margins",
+DlgDocMaTop			: "Top",
+DlgDocMaLeft		: "Left",
+DlgDocMaRight		: "Right",
+DlgDocMaBottom		: "Bottom",
+DlgDocMeIndex		: "Document Indexing Keywords (comma separated)",
+DlgDocMeDescr		: "Document Description",
+DlgDocMeAuthor		: "Author",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Preview",
+
+// Templates Dialog
+Templates			: "Templates",
+DlgTemplatesTitle	: "Content Templates",
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br>(the actual contents will be lost):",
+DlgTemplatesLoading	: "Loading templates list. Please wait...",
+DlgTemplatesNoTpl	: "(No templates defined)",
+DlgTemplatesReplace	: "Replace actual contents",
+
+// About Dialog
+DlgAboutAboutTab	: "About",
+DlgAboutBrowserInfoTab	: "Browser Info",
+DlgAboutLicenseTab	: "License",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "For further information go to"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/km.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/km.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/km.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Khmer language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "បង្រួមរបាឧបរកណ៍",
+ToolbarExpand		: "ពង្រីករបាឧបរណ៍",
+
+// Toolbar Items and Context Menu
+Save				: "រក្សាទុក",
+NewPage				: "ទំព័រថ្មី",
+Preview				: "មើលសាកល្បង",
+Cut					: "កាត់យក",
+Copy				: "ចំលងយក",
+Paste				: "ចំលងដាក់",
+PasteText			: "ចំលងដាក់ជាអត្ថបទធម្មតា",
+PasteWord			: "ចំលងដាក់ពី Word",
+Print				: "បោះពុម្ភ",
+SelectAll			: "ជ្រើសរើសទាំងអស់",
+RemoveFormat		: "លប់ចោល ការរចនា",
+InsertLinkLbl		: "ឈ្នាប់",
+InsertLink			: "បន្ថែម/កែប្រែ ឈ្នាប់",
+RemoveLink			: "លប់ឈ្នាប់",
+Anchor				: "បន្ថែម/កែប្រែ យុថ្កា",
+InsertImageLbl		: "រូបភាព",
+InsertImage			: "បន្ថែម/កែប្រែ រូបភាព",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "បន្ថែម/កែប្រែ Flash",
+InsertTableLbl		: "តារាង",
+InsertTable			: "បន្ថែម/កែប្រែ តារាង",
+InsertLineLbl		: "បន្ទាត់",
+InsertLine			: "បន្ថែមបន្ទាត់ផ្តេក",
+InsertSpecialCharLbl: "អក្សរពិសេស",
+InsertSpecialChar	: "បន្ថែមអក្សរពិសេស",
+InsertSmileyLbl		: "រូបភាព",
+InsertSmiley		: "បន្ថែម រូបភាព",
+About				: "អំពី FCKeditor",
+Bold				: "អក្សរដិតធំ",
+Italic				: "អក្សរផ្តេក",
+Underline			: "ដិតបន្ទាត់ពីក្រោមអក្សរ",
+StrikeThrough		: "ដិតបន្ទាត់ពាក់កណ្តាលអក្សរ",
+Subscript			: "អក្សរតូចក្រោម",
+Superscript			: "អក្សរតូចលើ",
+LeftJustify			: "តំរឹមឆ្វេង",
+CenterJustify		: "តំរឹមកណ្តាល",
+RightJustify		: "តំរឹមស្តាំ",
+BlockJustify		: "តំរឹមសងខាង",
+DecreaseIndent		: "បន្ថយការចូលបន្ទាត់",
+IncreaseIndent		: "បន្ថែមការចូលបន្ទាត់",
+Undo				: "សារឡើងវិញ",
+Redo				: "ធ្វើឡើងវិញ",
+NumberedListLbl		: "បញ្ជីជាអក្សរ",
+NumberedList		: "បន្ថែម/លប់ បញ្ជីជាអក្សរ",
+BulletedListLbl		: "បញ្ជីជារង្វង់មូល",
+BulletedList		: "បន្ថែម/លប់ បញ្ជីជារង្វង់មូល",
+ShowTableBorders	: "បង្ហាញស៊ុមតារាង",
+ShowDetails			: "បង្ហាញពិស្តារ",
+Style				: "ម៉ូត",
+FontFormat			: "រចនា",
+Font				: "ហ្វុង",
+FontSize			: "ទំហំ",
+TextColor			: "ពណ៌អក្សរ",
+BGColor				: "ពណ៌ផ្ទៃខាងក្រោយ",
+Source				: "កូត",
+Find				: "ស្វែងរក",
+Replace				: "ជំនួស",
+SpellCheck			: "ពិនិត្យអក្ខរាវិរុទ្ធ",
+UniversalKeyboard	: "ក្តារពុម្ភអក្សរសកល",
+PageBreakLbl		: "ការផ្តាច់ទំព័រ",
+PageBreak			: "បន្ថែម ការផ្តាច់ទំព័រ",
+
+Form			: "បែបបទ",
+Checkbox		: "ប្រអប់ជ្រើសរើស",
+RadioButton		: "ប៉ូតុនរង្វង់មូល",
+TextField		: "ជួរសរសេរអត្ថបទ",
+Textarea		: "តំបន់សរសេរអត្ថបទ",
+HiddenField		: "ជួរលាក់",
+Button			: "ប៉ូតុន",
+SelectionField	: "ជួរជ្រើសរើស",
+ImageButton		: "ប៉ូតុនរូបភាព",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "កែប្រែឈ្នាប់",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "បន្ថែមជួរផ្តេក",
+DeleteRows			: "លប់ជួរផ្តេក",
+InsertColumn		: "បន្ថែមជួរឈរ",
+DeleteColumns		: "លប់ជួរឈរ",
+InsertCell			: "បន្ថែម សែល",
+DeleteCells			: "លប់សែល",
+MergeCells			: "បញ្ជូលសែល",
+SplitCell			: "ផ្តាច់សែល",
+TableDelete			: "លប់តារាង",
+CellProperties		: "ការកំណត់សែល",
+TableProperties		: "ការកំណត់តារាង",
+ImageProperties		: "ការកំណត់រូបភាព",
+FlashProperties		: "ការកំណត់ Flash",
+
+AnchorProp			: "ការកំណត់យុថ្កា",
+ButtonProp			: "ការកំណត់ ប៉ូតុន",
+CheckboxProp		: "ការកំណត់ប្រអប់ជ្រើសរើស",
+HiddenFieldProp		: "ការកំណត់ជួរលាក់",
+RadioButtonProp		: "ការកំណត់ប៉ូតុនរង្វង់",
+ImageButtonProp		: "ការកំណត់ប៉ូតុនរូបភាព",
+TextFieldProp		: "ការកំណត់ជួរអត្ថបទ",
+SelectionFieldProp	: "ការកំណត់ជួរជ្រើសរើស",
+TextareaProp		: "ការកំណត់កន្លែងសរសេរអត្ថបទ",
+FormProp			: "ការកំណត់បែបបទ",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "កំពុងដំណើរការ XHTML ។ សូមរងចាំ...",
+Done				: "ចប់រួចរាល់",
+PasteWordConfirm	: "អត្ថបទដែលលោកអ្នកបំរុងចំលងដាក់ ហាក់បីដូចជាត្រូវចំលងមកពីកម្មវិធី​Word​។ តើលោកអ្នកចង់សំអាតមុនចំលងអត្ថបទដាក់ទេ?",
+NotCompatiblePaste	: "ពាក្យបញ្ជានេះប្រើបានតែជាមួយ Internet Explorer កំរិត 5.5 រឺ លើសនេះ ។ តើលោកអ្នកចង់ចំលងដាក់ដោយមិនចាំបាច់សំអាតទេ?",
+UnknownToolbarItem	: "វត្ថុលើរបាឧបរកណ៍ មិនស្គាល់ \"%1\"",
+UnknownCommand		: "ឈ្មោះពាក្យបញ្ជា មិនស្គាល់ \"%1\"",
+NotImplemented		: "ពាក្យបញ្ជា មិនបានអនុវត្ត",
+UnknownToolbarSet	: "របាឧបរកណ៍ \"%1\" ពុំមាន ។",
+NoActiveX			: "ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​អាចធ្វើអោយលោកអ្នកមិនអាចប្រើមុខងារខ្លះរបស់កម្មវិធីតាក់តែងអត្ថបទនេះ ។ លោកអ្នកត្រូវកំណត់អោយ \"ActiveX និង​កម្មវិធីជំនួយក្នុង (plug-ins)\" អោយដំណើរការ ។ លោកអ្នកអាចជួបប្រទះនឹង បញ្ហា ព្រមជាមួយនឹងការបាត់បង់មុខងារណាមួយរបស់កម្មវិធីតាក់តែងអត្ថបទនេះ ។",
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "វីនដូវមិនអាចបើកបានទេ ។ សូមពិនិត្យចំពោះកម្មវិធីបិទ វីនដូវលោត (popup) ថាតើវាដំណើរការរឺទេ ។",
+
+// Dialogs
+DlgBtnOK			: "យល់ព្រម",
+DlgBtnCancel		: "មិនយល់ព្រម",
+DlgBtnClose			: "បិទ",
+DlgBtnBrowseServer	: "មើល",
+DlgAdvancedTag		: "កំរិតខ្ពស់",
+DlgOpOther			: "<ផ្សេងទៅត>",
+DlgInfoTab			: "ពត៌មាន",
+DlgAlertUrl			: "សូមសរសេរ URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<មិនមែន>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "ទិសដៅភាសា",
+DlgGenLangDirLtr	: "ពីឆ្វេងទៅស្តាំ(LTR)",
+DlgGenLangDirRtl	: "ពីស្តាំទៅឆ្វេង(RTL)",
+DlgGenLangCode		: "លេខកូតភាសា",
+DlgGenAccessKey		: "ឃី សំរាប់ចូល",
+DlgGenName			: "ឈ្មោះ",
+DlgGenTabIndex		: "លេខ Tab",
+DlgGenLongDescr		: "អធិប្បាយ URL វែង",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "ចំណងជើង ប្រឹក្សា",
+DlgGenContType		: "ប្រភេទអត្ថបទ ប្រឹក្សា",
+DlgGenLinkCharset	: "លេខកូតអក្សររបស់ឈ្នាប់",
+DlgGenStyle			: "ម៉ូត",
+
+// Image Dialog
+DlgImgTitle			: "ការកំណត់រូបភាព",
+DlgImgInfoTab		: "ពត៌មានអំពីរូបភាព",
+DlgImgBtnUpload		: "បញ្ជូនទៅកាន់ម៉ាស៊ីនផ្តល់សេវា",
+DlgImgURL			: "URL",
+DlgImgUpload		: "ទាញយក",
+DlgImgAlt			: "អត្ថបទជំនួស",
+DlgImgWidth			: "ទទឹង",
+DlgImgHeight		: "កំពស់",
+DlgImgLockRatio		: "អត្រាឡុក",
+DlgBtnResetSize		: "កំណត់ទំហំឡើងវិញ",
+DlgImgBorder		: "ស៊ុម",
+DlgImgHSpace		: "គំលាតទទឹង",
+DlgImgVSpace		: "គំលាតបណ្តោយ",
+DlgImgAlign			: "កំណត់ទីតាំង",
+DlgImgAlignLeft		: "ខាងឆ្វង",
+DlgImgAlignAbsBottom: "Abs Bottom",	//MISSING
+DlgImgAlignAbsMiddle: "Abs Middle",	//MISSING
+DlgImgAlignBaseline	: "បន្ទាត់ជាមូលដ្ឋាន",
+DlgImgAlignBottom	: "ខាងក្រោម",
+DlgImgAlignMiddle	: "កណ្តាល",
+DlgImgAlignRight	: "ខាងស្តាំ",
+DlgImgAlignTextTop	: "លើអត្ថបទ",
+DlgImgAlignTop		: "ខាងលើ",
+DlgImgPreview		: "មើលសាកល្បង",
+DlgImgAlertUrl		: "សូមសរសេរងាស័យដ្ឋានរបស់រូបភាព",
+DlgImgLinkTab		: "ឈ្នាប់",
+
+// Flash Dialog
+DlgFlashTitle		: "ការកំណត់ Flash",
+DlgFlashChkPlay		: "លេងដោយស្វ័យប្រវត្ត",
+DlgFlashChkLoop		: "ចំនួនដង",
+DlgFlashChkMenu		: "បង្ហាញ មឺនុយរបស់ Flash",
+DlgFlashScale		: "ទំហំ",
+DlgFlashScaleAll	: "បង្ហាញទាំងអស់",
+DlgFlashScaleNoBorder	: "មិនបង្ហាញស៊ុម",
+DlgFlashScaleFit	: "ត្រូវល្មម",
+
+// Link Dialog
+DlgLnkWindowTitle	: "ឈ្នាប់",
+DlgLnkInfoTab		: "ពត៌មានអំពីឈ្នាប់",
+DlgLnkTargetTab		: "គោលដៅ",
+
+DlgLnkType			: "ប្រភេទឈ្នាប់",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "យុថ្កានៅក្នុងទំព័រនេះ",
+DlgLnkTypeEMail		: "អ៊ីមែល",
+DlgLnkProto			: "ប្រូតូកូល",
+DlgLnkProtoOther	: "<ផ្សេងទៀត>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "ជ្រើសរើសយុថ្កា",
+DlgLnkAnchorByName	: "តាមឈ្មោះរបស់យុថ្កា",
+DlgLnkAnchorById	: "តាម Id",
+DlgLnkNoAnchors		: "<ពុំមានយុថ្កានៅក្នុងឯកសារនេះទេ>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "អ៊ីមែល",
+DlgLnkEMailSubject	: "ចំណងជើងអត្ថបទ",
+DlgLnkEMailBody		: "អត្ថបទ",
+DlgLnkUpload		: "ទាញយក",
+DlgLnkBtnUpload		: "ទាញយក",
+
+DlgLnkTarget		: "គោលដៅ",
+DlgLnkTargetFrame	: "<ហ្វ្រេម>",
+DlgLnkTargetPopup	: "<វីនដូវ លោត>",
+DlgLnkTargetBlank	: "វីនដូវថ្មី (_blank)",
+DlgLnkTargetParent	: "វីនដូវមេ (_parent)",
+DlgLnkTargetSelf	: "វីនដូវដដែល (_self)",
+DlgLnkTargetTop		: "វីនដូវនៅលើគេ(_top)",
+DlgLnkTargetFrameName	: "ឈ្មោះហ្រ្វេមដែលជាគោលដៅ",
+DlgLnkPopWinName	: "ឈ្មោះវីនដូវលោត",
+DlgLnkPopWinFeat	: "លក្ខណះរបស់វីនដូលលោត",
+DlgLnkPopResize		: "ទំហំអាចផ្លាស់ប្តូរ",
+DlgLnkPopLocation	: "របា ទីតាំង",
+DlgLnkPopMenu		: "របា មឺនុយ",
+DlgLnkPopScroll		: "របា ទាញ",
+DlgLnkPopStatus		: "របា ពត៌មាន",
+DlgLnkPopToolbar	: "របា ឩបករណ៍",
+DlgLnkPopFullScrn	: "អេក្រុងពេញ(IE)",
+DlgLnkPopDependent	: "អាស្រ័យលើ (Netscape)",
+DlgLnkPopWidth		: "ទទឹង",
+DlgLnkPopHeight		: "កំពស់",
+DlgLnkPopLeft		: "ទីតាំងខាងឆ្វេង",
+DlgLnkPopTop		: "ទីតាំងខាងលើ",
+
+DlnLnkMsgNoUrl		: "សូមសរសេរ អាស័យដ្ឋាន URL",
+DlnLnkMsgNoEMail	: "សូមសរសេរ អាស័យដ្ឋាន អ៊ីមែល",
+DlnLnkMsgNoAnchor	: "សូមជ្រើសរើស យុថ្កា",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "ជ្រើសរើស ពណ៌",
+DlgColorBtnClear	: "លប់",
+DlgColorHighlight	: "ផាត់ពណ៌",
+DlgColorSelected	: "បានជ្រើសរើស",
+
+// Smiley Dialog
+DlgSmileyTitle		: "បញ្ជូលរូបភាព",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "តូអក្សរពិសេស",
+
+// Table Dialog
+DlgTableTitle		: "ការកំណត់ តារាង",
+DlgTableRows		: "ជួរផ្តេក",
+DlgTableColumns		: "ជួរឈរ",
+DlgTableBorder		: "ទំហំស៊ុម",
+DlgTableAlign		: "ការកំណត់ទីតាំង",
+DlgTableAlignNotSet	: "<មិនកំណត់>",
+DlgTableAlignLeft	: "ខាងឆ្វេង",
+DlgTableAlignCenter	: "កណ្តាល",
+DlgTableAlignRight	: "ខាងស្តាំ",
+DlgTableWidth		: "ទទឹង",
+DlgTableWidthPx		: "ភីកសែល",
+DlgTableWidthPc		: "ភាគរយ",
+DlgTableHeight		: "កំពស់",
+DlgTableCellSpace	: "គំលាតសែល",
+DlgTableCellPad		: "គែមសែល",
+DlgTableCaption		: "ចំណងជើង",
+DlgTableSummary		: "សេចក្តីសង្ខេប",
+
+// Table Cell Dialog
+DlgCellTitle		: "ការកំណត់ សែល",
+DlgCellWidth		: "ទទឹង",
+DlgCellWidthPx		: "ភីកសែល",
+DlgCellWidthPc		: "ភាគរយ",
+DlgCellHeight		: "កំពស់",
+DlgCellWordWrap		: "បង្ហាញអត្ថបទទាំងអស់",
+DlgCellWordWrapNotSet	: "<មិនកំណត់>",
+DlgCellWordWrapYes	: "បាទ(ចា)",
+DlgCellWordWrapNo	: "ទេ",
+DlgCellHorAlign		: "តំរឹមផ្តេក",
+DlgCellHorAlignNotSet	: "<មិនកំណត់>",
+DlgCellHorAlignLeft	: "ខាងឆ្វេង",
+DlgCellHorAlignCenter	: "កណ្តាល",
+DlgCellHorAlignRight: "Right",	//MISSING
+DlgCellVerAlign		: "តំរឹមឈរ",
+DlgCellVerAlignNotSet	: "<មិនកណត់>",
+DlgCellVerAlignTop	: "ខាងលើ",
+DlgCellVerAlignMiddle	: "កណ្តាល",
+DlgCellVerAlignBottom	: "ខាងក្រោម",
+DlgCellVerAlignBaseline	: "បន្ទាត់ជាមូលដ្ឋាន",
+DlgCellRowSpan		: "បញ្ជូលជួរផ្តេក",
+DlgCellCollSpan		: "បញ្ជូលជួរឈរ",
+DlgCellBackColor	: "ពណ៌ផ្នែកខាងក្រោម",
+DlgCellBorderColor	: "ពណ៌ស៊ុម",
+DlgCellBtnSelect	: "ជ្រើសរើស...",
+
+// Find Dialog
+DlgFindTitle		: "ស្វែងរក",
+DlgFindFindBtn		: "ស្វែងរក",
+DlgFindNotFoundMsg	: "ពាក្យនេះ រកមិនឃើញទេ ។",
+
+// Replace Dialog
+DlgReplaceTitle			: "ជំនួស",
+DlgReplaceFindLbl		: "ស្វែងរកអ្វី:",
+DlgReplaceReplaceLbl	: "ជំនួសជាមួយ:",
+DlgReplaceCaseChk		: "ករណ៉ត្រូវរក",
+DlgReplaceReplaceBtn	: "ជំនួស",
+DlgReplaceReplAllBtn	: "ជំនួសទាំងអស់",
+DlgReplaceWordChk		: "ត្រូវពាក្យទាំងអស់",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​មិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ កាត់អត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ  (Ctrl+X) ។",
+PasteErrorCopy	: "ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​មិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ ចំលងអត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl+C)។",
+
+PasteAsText		: "ចំលងដាក់អត្ថបទធម្មតា",
+PasteFromWord	: "ចំលងពាក្យពីកម្មវិធី Word",
+
+DlgPasteMsg2	: "សូមចំលងអត្ថបទទៅដាក់ក្នុងប្រអប់ដូចខាងក្រោមដោយប្រើប្រាស់ ឃី ​(<STRONG>Ctrl+V</STRONG>) ហើយចុច <STRONG>OK</STRONG> ។",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "មិនគិតអំពីប្រភេទពុម្ភអក្សរ",
+DlgPasteRemoveStyles	: "លប់ម៉ូត",
+DlgPasteCleanBox		: "លប់អត្ថបទចេញពីប្រអប់",
+
+// Color Picker
+ColorAutomatic	: "ស្វ័យប្រវត្ត",
+ColorMoreColors	: "ពណ៌ផ្សេងទៀត..",
+
+// Document Properties
+DocProps		: "ការកំណត់ ឯកសារ",
+
+// Anchor Dialog
+DlgAnchorTitle		: "ការកំណត់ចំណងជើងយុទ្ធថ្កា",
+DlgAnchorName		: "ឈ្មោះយុទ្ធថ្កា",
+DlgAnchorErrorName	: "សូមសរសេរ ឈ្មោះយុទ្ធថ្កា",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "គ្មានក្នុងវចនានុក្រម",
+DlgSpellChangeTo		: "ផ្លាស់ប្តូរទៅ",
+DlgSpellBtnIgnore		: "មិនផ្លាស់ប្តូរ",
+DlgSpellBtnIgnoreAll	: "មិនផ្លាស់ប្តូរ ទាំងអស់",
+DlgSpellBtnReplace		: "ជំនួស",
+DlgSpellBtnReplaceAll	: "ជំនួសទាំងអស់",
+DlgSpellBtnUndo			: "សារឡើងវិញ",
+DlgSpellNoSuggestions	: "- គ្មានសំណើរ -",
+DlgSpellProgress		: "កំពុងពិនិត្យអក្ខរាវិរុទ្ធ...",
+DlgSpellNoMispell		: "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: គ្មានកំហុស",
+DlgSpellNoChanges		: "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: ពុំមានផ្លាស់ប្តូរ",
+DlgSpellOneChange		: "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: ពាក្យមួយត្រូចបានផ្លាស់ប្តូរ",
+DlgSpellManyChanges		: "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: %1 ពាក្យបានផ្លាស់ប្តូរ",
+
+IeSpellDownload			: "ពុំមានកម្មវិធីពិនិត្យអក្ខរាវិរុទ្ធ ។ តើចង់ទាញយកពីណា?",
+
+// Button Dialog
+DlgButtonText		: "អត្ថបទ(តំលៃ)",
+DlgButtonType		: "ប្រភេទ",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "ឈ្មោះ",
+DlgCheckboxValue	: "តំលៃ",
+DlgCheckboxSelected	: "បានជ្រើសរើស",
+
+// Form Dialog
+DlgFormName		: "ឈ្មោះ",
+DlgFormAction	: "សកម្មភាព",
+DlgFormMethod	: "វិធី",
+
+// Select Field Dialog
+DlgSelectName		: "ឈ្មោះ",
+DlgSelectValue		: "តំលៃ",
+DlgSelectSize		: "ទំហំ",
+DlgSelectLines		: "បន្ទាត់",
+DlgSelectChkMulti	: "អនុញ្ញាតអោយជ្រើសរើសច្រើន",
+DlgSelectOpAvail	: "ការកំណត់ជ្រើសរើស ដែលអាចកំណត់បាន",
+DlgSelectOpText		: "ពាក្យ",
+DlgSelectOpValue	: "តំលៃ",
+DlgSelectBtnAdd		: "បន្ថែម",
+DlgSelectBtnModify	: "ផ្លាស់ប្តូរ",
+DlgSelectBtnUp		: "លើ",
+DlgSelectBtnDown	: "ក្រោម",
+DlgSelectBtnSetValue : "Set as selected value",	//MISSING
+DlgSelectBtnDelete	: "លប់",
+
+// Textarea Dialog
+DlgTextareaName	: "ឈ្មោះ",
+DlgTextareaCols	: "ជូរឈរ",
+DlgTextareaRows	: "ជូរផ្តេក",
+
+// Text Field Dialog
+DlgTextName			: "ឈ្មោះ",
+DlgTextValue		: "តំលៃ",
+DlgTextCharWidth	: "ទទឹង អក្សរ",
+DlgTextMaxChars		: "អក្សរអតិបរិមា",
+DlgTextType			: "ប្រភេទ",
+DlgTextTypeText		: "ពាក្យ",
+DlgTextTypePass		: "ពាក្យសំងាត់",
+
+// Hidden Field Dialog
+DlgHiddenName	: "ឈ្មោះ",
+DlgHiddenValue	: "តំលៃ",
+
+// Bulleted List Dialog
+BulletedListProp	: "កំណត់បញ្ជីរង្វង់",
+NumberedListProp	: "កំណត់បញ្េជីលេខ",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "ប្រភេទ",
+DlgLstTypeCircle	: "រង្វង់",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "ការេ",
+DlgLstTypeNumbers	: "លេខ(1, 2, 3)",
+DlgLstTypeLCase		: "អក្សរតូច(a, b, c)",
+DlgLstTypeUCase		: "អក្សរធំ(A, B, C)",
+DlgLstTypeSRoman	: "អក្សរឡាតាំងតូច(i, ii, iii)",
+DlgLstTypeLRoman	: "អក្សរឡាតាំងធំ(I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "ទូទៅ",
+DlgDocBackTab		: "ផ្នែកខាងក្រោយ",
+DlgDocColorsTab		: "ទំព័រ​និង ស៊ុម",
+DlgDocMetaTab		: "ទិន្នន័យមេ",
+
+DlgDocPageTitle		: "ចំណងជើងទំព័រ",
+DlgDocLangDir		: "ទិសដៅសរសេរភាសា",
+DlgDocLangDirLTR	: "ពីឆ្វេងទៅស្ដាំ(LTR)",
+DlgDocLangDirRTL	: "ពីស្ដាំទៅឆ្វេង(RTL)",
+DlgDocLangCode		: "លេខកូតភាសា",
+DlgDocCharSet		: "កំណត់លេខកូតភាសា",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "កំណត់លេខកូតភាសាផ្សេងទៀត",
+
+DlgDocDocType		: "ប្រភេទក្បាលទំព័រ",
+DlgDocDocTypeOther	: "ប្រភេទក្បាលទំព័រផ្សេងទៀត",
+DlgDocIncXHTML		: "បញ្ជូល XHTML",
+DlgDocBgColor		: "ពណ៌ខាងក្រោម",
+DlgDocBgImage		: "URL របស់រូបភាពខាងក្រោម",
+DlgDocBgNoScroll	: "ទំព័រក្រោមមិនប្តូរ",
+DlgDocCText			: "អត្តបទ",
+DlgDocCLink			: "ឈ្នាប់",
+DlgDocCVisited		: "ឈ្នាប់មើលហើយ",
+DlgDocCActive		: "ឈ្នាប់កំពុងមើល",
+DlgDocMargins		: "ស៊ុមទំព័រ",
+DlgDocMaTop			: "លើ",
+DlgDocMaLeft		: "ឆ្វេង",
+DlgDocMaRight		: "ស្ដាំ",
+DlgDocMaBottom		: "ក្រោម",
+DlgDocMeIndex		: "ពាក្យនៅក្នុងឯកសារ (ផ្តាច់ពីគ្នាដោយក្បៀស)",
+DlgDocMeDescr		: "សេចក្តីអត្ថាធិប្បាយអំពីឯកសារ",
+DlgDocMeAuthor		: "អ្នកនិពន្ធ",
+DlgDocMeCopy		: "រក្សាសិទ្ធិ៏",
+DlgDocPreview		: "មើលសាកល្បង",
+
+// Templates Dialog
+Templates			: "ឯកសារគំរូ",
+DlgTemplatesTitle	: "ឯកសារគំរូ របស់អត្ថន័យ",
+DlgTemplatesSelMsg	: "សូមជ្រើសរើសឯកសារគំរូ ដើម្បីបើកនៅក្នុងកម្មវិធីតាក់តែងអត្ថបទ<br>(អត្ថបទនឹងបាត់បង់):",
+DlgTemplatesLoading	: "កំពុងអានបញ្ជីឯកសារគំរូ ។ សូមរងចាំ...",
+DlgTemplatesNoTpl	: "(ពុំមានឯកសារគំរូត្រូវបានកំណត់)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "អំពី",
+DlgAboutBrowserInfoTab	: "ព៌តមានកម្មវិធីរុករក",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "ជំនាន់",
+DlgAboutInfo		: "សំរាប់ព៌តមានផ្សេងទៀត សូមទាក់ទង"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/es.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/es.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/es.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Spanish language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Contraer Barra",
+ToolbarExpand		: "Expandir Barra",
+
+// Toolbar Items and Context Menu
+Save				: "Guardar",
+NewPage				: "Nueva Página",
+Preview				: "Vista Previa",
+Cut					: "Cortar",
+Copy				: "Copiar",
+Paste				: "Pegar",
+PasteText			: "Pegar como texto plano",
+PasteWord			: "Pegar desde Word",
+Print				: "Imprimir",
+SelectAll			: "Seleccionar Todo",
+RemoveFormat		: "Eliminar Formato",
+InsertLinkLbl		: "Vínculo",
+InsertLink			: "Insertar/Editar Vínculo",
+RemoveLink			: "Eliminar Vínculo",
+Anchor				: "Referencia",
+InsertImageLbl		: "Imagen",
+InsertImage			: "Insertar/Editar Imagen",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insertar/Editar Flash",
+InsertTableLbl		: "Tabla",
+InsertTable			: "Insertar/Editar Tabla",
+InsertLineLbl		: "Línea",
+InsertLine			: "Insertar Línea Horizontal",
+InsertSpecialCharLbl: "Caracter Especial",
+InsertSpecialChar	: "Insertar Caracter Especial",
+InsertSmileyLbl		: "Emoticons",
+InsertSmiley		: "Insertar Emoticons",
+About				: "Acerca de FCKeditor",
+Bold				: "Negrita",
+Italic				: "Cursiva",
+Underline			: "Subrayado",
+StrikeThrough		: "Tachado",
+Subscript			: "Subíndice",
+Superscript			: "Superíndice",
+LeftJustify			: "Alinear a Izquierda",
+CenterJustify		: "Centrar",
+RightJustify		: "Alinear a Derecha",
+BlockJustify		: "Justificado",
+DecreaseIndent		: "Disminuir Sangría",
+IncreaseIndent		: "Aumentar Sangría",
+Undo				: "Deshacer",
+Redo				: "Rehacer",
+NumberedListLbl		: "Numeración",
+NumberedList		: "Insertar/Eliminar Numeración",
+BulletedListLbl		: "Viñetas",
+BulletedList		: "Insertar/Eliminar Viñetas",
+ShowTableBorders	: "Mostrar Bordes de Tablas",
+ShowDetails			: "Mostrar saltos de Párrafo",
+Style				: "Estilo",
+FontFormat			: "Formato",
+Font				: "Fuente",
+FontSize			: "Tamaño",
+TextColor			: "Color de Texto",
+BGColor				: "Color de Fondo",
+Source				: "Fuente HTML",
+Find				: "Buscar",
+Replace				: "Reemplazar",
+SpellCheck			: "Ortografía",
+UniversalKeyboard	: "Teclado Universal",
+PageBreakLbl		: "Salto de Página",
+PageBreak			: "Insertar Salto de Página",
+
+Form			: "Formulario",
+Checkbox		: "Casilla de Verificación",
+RadioButton		: "Botones de Radio",
+TextField		: "Campo de Texto",
+Textarea		: "Area de Texto",
+HiddenField		: "Campo Oculto",
+Button			: "Botón",
+SelectionField	: "Campo de Selección",
+ImageButton		: "Botón Imagen",
+
+FitWindow		: "Maximizar el tamaño del editor",
+
+// Context Menu
+EditLink			: "Editar Vínculo",
+CellCM				: "Celda",
+RowCM				: "Fila",
+ColumnCM			: "Columna",
+InsertRow			: "Insertar Fila",
+DeleteRows			: "Eliminar Filas",
+InsertColumn		: "Insertar Columna",
+DeleteColumns		: "Eliminar Columnas",
+InsertCell			: "Insertar Celda",
+DeleteCells			: "Eliminar Celdas",
+MergeCells			: "Combinar Celdas",
+SplitCell			: "Dividir Celda",
+TableDelete			: "Eliminar Tabla",
+CellProperties		: "Propiedades de Celda",
+TableProperties		: "Propiedades de Tabla",
+ImageProperties		: "Propiedades de Imagen",
+FlashProperties		: "Propiedades de Flash",
+
+AnchorProp			: "Propiedades de Referencia",
+ButtonProp			: "Propiedades de Botón",
+CheckboxProp		: "Propiedades de Casilla",
+HiddenFieldProp		: "Propiedades de Campo Oculto",
+RadioButtonProp		: "Propiedades de Botón de Radio",
+ImageButtonProp		: "Propiedades de Botón de Imagen",
+TextFieldProp		: "Propiedades de Campo de Texto",
+SelectionFieldProp	: "Propiedades de Campo de Selección",
+TextareaProp		: "Propiedades de Area de Texto",
+FormProp			: "Propiedades de Formulario",
+
+FontFormats			: "Normal;Con formato;Dirección;Encabezado 1;Encabezado 2;Encabezado 3;Encabezado 4;Encabezado 5;Encabezado 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Procesando XHTML. Por favor, espere...",
+Done				: "Hecho",
+PasteWordConfirm	: "El texto que desea parece provenir de Word. Desea depurarlo antes de pegarlo?",
+NotCompatiblePaste	: "Este comando está disponible sólo para Internet Explorer version 5.5 or superior. Desea pegar sin depurar?",
+UnknownToolbarItem	: "Item de barra desconocido \"%1\"",
+UnknownCommand		: "Nombre de comando desconocido \"%1\"",
+NotImplemented		: "Comando no implementado",
+UnknownToolbarSet	: "Nombre de barra \"%1\" no definido",
+NoActiveX			: "La configuración de las opciones de seguridad de su navegador puede estar limitando algunas características del editor. Por favor active la opción \"Ejecutar controles y complementos de ActiveX \", de lo contrario puede experimentar errores o ausencia de funcionalidades.",
+BrowseServerBlocked : "La ventana de visualización del servidor no pudo ser abierta. Verifique que su navegador no esté bloqueando las ventanas emergentes (pop up).",
+DialogBlocked		: "No se ha podido abrir la ventana de diálogo. Verifique que su navegador no esté bloqueando las ventanas emergentes (pop up).",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancelar",
+DlgBtnClose			: "Cerrar",
+DlgBtnBrowseServer	: "Ver Servidor",
+DlgAdvancedTag		: "Avanzado",
+DlgOpOther			: "<Otro>",
+DlgInfoTab			: "Información",
+DlgAlertUrl			: "Inserte el URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<No definido>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Orientación de idioma",
+DlgGenLangDirLtr	: "Izquierda a Derecha (LTR)",
+DlgGenLangDirRtl	: "Derecha a Izquierda (RTL)",
+DlgGenLangCode		: "Código de idioma",
+DlgGenAccessKey		: "Clave de Acceso",
+DlgGenName			: "Nombre",
+DlgGenTabIndex		: "Indice de tabulación",
+DlgGenLongDescr		: "Descripción larga URL",
+DlgGenClass			: "Clases de hojas de estilo",
+DlgGenTitle			: "Título",
+DlgGenContType		: "Tipo de Contenido",
+DlgGenLinkCharset	: "Fuente de caracteres vinculado",
+DlgGenStyle			: "Estilo",
+
+// Image Dialog
+DlgImgTitle			: "Propiedades de Imagen",
+DlgImgInfoTab		: "Información de Imagen",
+DlgImgBtnUpload		: "Enviar al Servidor",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Cargar",
+DlgImgAlt			: "Texto Alternativo",
+DlgImgWidth			: "Anchura",
+DlgImgHeight		: "Altura",
+DlgImgLockRatio		: "Proporcional",
+DlgBtnResetSize		: "Tamaño Original",
+DlgImgBorder		: "Borde",
+DlgImgHSpace		: "Esp.Horiz",
+DlgImgVSpace		: "Esp.Vert",
+DlgImgAlign			: "Alineación",
+DlgImgAlignLeft		: "Izquierda",
+DlgImgAlignAbsBottom: "Abs inferior",
+DlgImgAlignAbsMiddle: "Abs centro",
+DlgImgAlignBaseline	: "Línea de base",
+DlgImgAlignBottom	: "Pie",
+DlgImgAlignMiddle	: "Centro",
+DlgImgAlignRight	: "Derecha",
+DlgImgAlignTextTop	: "Tope del texto",
+DlgImgAlignTop		: "Tope",
+DlgImgPreview		: "Vista Previa",
+DlgImgAlertUrl		: "Por favor tipee el URL de la imagen",
+DlgImgLinkTab		: "Vínculo",
+
+// Flash Dialog
+DlgFlashTitle		: "Propiedades de Flash",
+DlgFlashChkPlay		: "Autoejecución",
+DlgFlashChkLoop		: "Repetir",
+DlgFlashChkMenu		: "Activar Menú Flash",
+DlgFlashScale		: "Escala",
+DlgFlashScaleAll	: "Mostrar todo",
+DlgFlashScaleNoBorder	: "Sin Borde",
+DlgFlashScaleFit	: "Ajustado",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Vínculo",
+DlgLnkInfoTab		: "Información de Vínculo",
+DlgLnkTargetTab		: "Destino",
+
+DlgLnkType			: "Tipo de vínculo",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Referencia en esta página",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocolo",
+DlgLnkProtoOther	: "<otro>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Seleccionar una referencia",
+DlgLnkAnchorByName	: "Por Nombre de Referencia",
+DlgLnkAnchorById	: "Por ID de elemento",
+DlgLnkNoAnchors		: "<No hay referencias disponibles en el documento>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Dirección de E-Mail",
+DlgLnkEMailSubject	: "Título del Mensaje",
+DlgLnkEMailBody		: "Cuerpo del Mensaje",
+DlgLnkUpload		: "Cargar",
+DlgLnkBtnUpload		: "Enviar al Servidor",
+
+DlgLnkTarget		: "Destino",
+DlgLnkTargetFrame	: "<marco>",
+DlgLnkTargetPopup	: "<ventana emergente>",
+DlgLnkTargetBlank	: "Nueva Ventana(_blank)",
+DlgLnkTargetParent	: "Ventana Padre (_parent)",
+DlgLnkTargetSelf	: "Misma Ventana (_self)",
+DlgLnkTargetTop		: "Ventana primaria (_top)",
+DlgLnkTargetFrameName	: "Nombre del Marco Destino",
+DlgLnkPopWinName	: "Nombre de Ventana Emergente",
+DlgLnkPopWinFeat	: "Características de Ventana Emergente",
+DlgLnkPopResize		: "Ajustable",
+DlgLnkPopLocation	: "Barra de ubicación",
+DlgLnkPopMenu		: "Barra de Menú",
+DlgLnkPopScroll		: "Barras de desplazamiento",
+DlgLnkPopStatus		: "Barra de Estado",
+DlgLnkPopToolbar	: "Barra de Herramientas",
+DlgLnkPopFullScrn	: "Pantalla Completa (IE)",
+DlgLnkPopDependent	: "Dependiente (Netscape)",
+DlgLnkPopWidth		: "Anchura",
+DlgLnkPopHeight		: "Altura",
+DlgLnkPopLeft		: "Posición Izquierda",
+DlgLnkPopTop		: "Posición Derecha",
+
+DlnLnkMsgNoUrl		: "Por favor tipee el vínculo URL",
+DlnLnkMsgNoEMail	: "Por favor tipee la dirección de e-mail",
+DlnLnkMsgNoAnchor	: "Por favor seleccione una referencia",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Seleccionar Color",
+DlgColorBtnClear	: "Ninguno",
+DlgColorHighlight	: "Resaltado",
+DlgColorSelected	: "Seleccionado",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insertar un Emoticon",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Seleccione un caracter especial",
+
+// Table Dialog
+DlgTableTitle		: "Propiedades de Tabla",
+DlgTableRows		: "Filas",
+DlgTableColumns		: "Columnas",
+DlgTableBorder		: "Tamaño de Borde",
+DlgTableAlign		: "Alineación",
+DlgTableAlignNotSet	: "<No establecido>",
+DlgTableAlignLeft	: "Izquierda",
+DlgTableAlignCenter	: "Centrado",
+DlgTableAlignRight	: "Derecha",
+DlgTableWidth		: "Anchura",
+DlgTableWidthPx		: "pixeles",
+DlgTableWidthPc		: "porcentaje",
+DlgTableHeight		: "Altura",
+DlgTableCellSpace	: "Esp. e/celdas",
+DlgTableCellPad		: "Esp. interior",
+DlgTableCaption		: "Título",
+DlgTableSummary		: "Síntesis",
+
+// Table Cell Dialog
+DlgCellTitle		: "Propiedades de Celda",
+DlgCellWidth		: "Anchura",
+DlgCellWidthPx		: "pixeles",
+DlgCellWidthPc		: "porcentaje",
+DlgCellHeight		: "Altura",
+DlgCellWordWrap		: "Cortar Línea",
+DlgCellWordWrapNotSet	: "<No establecido>",
+DlgCellWordWrapYes	: "Si",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Alineación Horizontal",
+DlgCellHorAlignNotSet	: "<No establecido>",
+DlgCellHorAlignLeft	: "Izquierda",
+DlgCellHorAlignCenter	: "Centrado",
+DlgCellHorAlignRight: "Derecha",
+DlgCellVerAlign		: "Alineación Vertical",
+DlgCellVerAlignNotSet	: "<Not establecido>",
+DlgCellVerAlignTop	: "Tope",
+DlgCellVerAlignMiddle	: "Medio",
+DlgCellVerAlignBottom	: "ie",
+DlgCellVerAlignBaseline	: "Línea de Base",
+DlgCellRowSpan		: "Abarcar Filas",
+DlgCellCollSpan		: "Abarcar Columnas",
+DlgCellBackColor	: "Color de Fondo",
+DlgCellBorderColor	: "Color de Borde",
+DlgCellBtnSelect	: "Seleccione...",
+
+// Find Dialog
+DlgFindTitle		: "Buscar",
+DlgFindFindBtn		: "Buscar",
+DlgFindNotFoundMsg	: "El texto especificado no ha sido encontrado.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Reemplazar",
+DlgReplaceFindLbl		: "Texto a buscar:",
+DlgReplaceReplaceLbl	: "Reemplazar con:",
+DlgReplaceCaseChk		: "Coincidir may/min",
+DlgReplaceReplaceBtn	: "Reemplazar",
+DlgReplaceReplAllBtn	: "Reemplazar Todo",
+DlgReplaceWordChk		: "Coincidir toda la palabra",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de cortado. Por favor use el teclado (Ctrl+X).",
+PasteErrorCopy	: "La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de copiado. Por favor use el teclado (Ctrl+C).",
+
+PasteAsText		: "Pegar como Texto Plano",
+PasteFromWord	: "Pegar desde Word",
+
+DlgPasteMsg2	: "Por favor pegue dentro del cuadro utilizando el teclado (<STRONG>Ctrl+V</STRONG>); luego presione <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorar definiciones de fuentes",
+DlgPasteRemoveStyles	: "Remover definiciones de estilo",
+DlgPasteCleanBox		: "Borrar el contenido del cuadro",
+
+// Color Picker
+ColorAutomatic	: "Automático",
+ColorMoreColors	: "Más Colores...",
+
+// Document Properties
+DocProps		: "Propiedades del Documento",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Propiedades de la Referencia",
+DlgAnchorName		: "Nombre de la Referencia",
+DlgAnchorErrorName	: "Por favor, complete el nombre de la Referencia",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "No se encuentra en el Diccionario",
+DlgSpellChangeTo		: "Cambiar a",
+DlgSpellBtnIgnore		: "Ignorar",
+DlgSpellBtnIgnoreAll	: "Ignorar Todo",
+DlgSpellBtnReplace		: "Reemplazar",
+DlgSpellBtnReplaceAll	: "Reemplazar Todo",
+DlgSpellBtnUndo			: "Deshacer",
+DlgSpellNoSuggestions	: "- No hay sugerencias -",
+DlgSpellProgress		: "Control de Ortografía en progreso...",
+DlgSpellNoMispell		: "Control finalizado: no se encontraron errores",
+DlgSpellNoChanges		: "Control finalizado: no se ha cambiado ninguna palabra",
+DlgSpellOneChange		: "Control finalizado: se ha cambiado una palabra",
+DlgSpellManyChanges		: "Control finalizado: se ha cambiado %1 palabras",
+
+IeSpellDownload			: "Módulo de Control de Ortografía no instalado. ¿Desea descargarlo ahora?",
+
+// Button Dialog
+DlgButtonText		: "Texto (Valor)",
+DlgButtonType		: "Tipo",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nombre",
+DlgCheckboxValue	: "Valor",
+DlgCheckboxSelected	: "Seleccionado",
+
+// Form Dialog
+DlgFormName		: "Nombre",
+DlgFormAction	: "Acción",
+DlgFormMethod	: "Método",
+
+// Select Field Dialog
+DlgSelectName		: "Nombre",
+DlgSelectValue		: "Valor",
+DlgSelectSize		: "Tamaño",
+DlgSelectLines		: "Lineas",
+DlgSelectChkMulti	: "Permitir múltiple selección",
+DlgSelectOpAvail	: "Opciones disponibles",
+DlgSelectOpText		: "Texto",
+DlgSelectOpValue	: "Valor",
+DlgSelectBtnAdd		: "Agregar",
+DlgSelectBtnModify	: "Modificar",
+DlgSelectBtnUp		: "Subir",
+DlgSelectBtnDown	: "Bajar",
+DlgSelectBtnSetValue : "Establecer como predeterminado",
+DlgSelectBtnDelete	: "Eliminar",
+
+// Textarea Dialog
+DlgTextareaName	: "Nombre",
+DlgTextareaCols	: "Columnas",
+DlgTextareaRows	: "Filas",
+
+// Text Field Dialog
+DlgTextName			: "Nombre",
+DlgTextValue		: "Valor",
+DlgTextCharWidth	: "Caracteres de ancho",
+DlgTextMaxChars		: "Máximo caracteres",
+DlgTextType			: "Tipo",
+DlgTextTypeText		: "Texto",
+DlgTextTypePass		: "Contraseña",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nombre",
+DlgHiddenValue	: "Valor",
+
+// Bulleted List Dialog
+BulletedListProp	: "Propiedades de Viñetas",
+NumberedListProp	: "Propiedades de Numeraciones",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tipo",
+DlgLstTypeCircle	: "Círculo",
+DlgLstTypeDisc		: "Disco",
+DlgLstTypeSquare	: "Cuadrado",
+DlgLstTypeNumbers	: "Números (1, 2, 3)",
+DlgLstTypeLCase		: "letras en minúsculas (a, b, c)",
+DlgLstTypeUCase		: "letras en mayúsculas (A, B, C)",
+DlgLstTypeSRoman	: "Números Romanos (i, ii, iii)",
+DlgLstTypeLRoman	: "Números Romanos (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Fondo",
+DlgDocColorsTab		: "Colores y Márgenes",
+DlgDocMetaTab		: "Meta Información",
+
+DlgDocPageTitle		: "Título de Página",
+DlgDocLangDir		: "Orientación de idioma",
+DlgDocLangDirLTR	: "Izq. a Derecha (LTR)",
+DlgDocLangDirRTL	: "Der. a Izquierda (RTL)",
+DlgDocLangCode		: "Código de Idioma",
+DlgDocCharSet		: "Codif. de Conjunto de Caracteres",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Otra Codificación",
+
+DlgDocDocType		: "Encabezado de Tipo de Documento",
+DlgDocDocTypeOther	: "Otro Encabezado",
+DlgDocIncXHTML		: "Incluir Declaraciones XHTML",
+DlgDocBgColor		: "Color de Fondo",
+DlgDocBgImage		: "URL de Imagen de Fondo",
+DlgDocBgNoScroll	: "Fondo sin rolido",
+DlgDocCText			: "Texto",
+DlgDocCLink			: "Vínculo",
+DlgDocCVisited		: "Vínculo Visitado",
+DlgDocCActive		: "Vínculo Activo",
+DlgDocMargins		: "Márgenes de Página",
+DlgDocMaTop			: "Tope",
+DlgDocMaLeft		: "Izquierda",
+DlgDocMaRight		: "Derecha",
+DlgDocMaBottom		: "Pie",
+DlgDocMeIndex		: "Claves de indexación del Documento (separados por comas)",
+DlgDocMeDescr		: "Descripción del Documento",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Vista Previa",
+
+// Templates Dialog
+Templates			: "Plantillas",
+DlgTemplatesTitle	: "Contenido de Plantillas",
+DlgTemplatesSelMsg	: "Por favor selecciona la plantilla a abrir en el editor<br>(el contenido actual se perderá):",
+DlgTemplatesLoading	: "Cargando lista de Plantillas. Por favor, aguarde...",
+DlgTemplatesNoTpl	: "(No hay plantillas definidas)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Acerca de",
+DlgAboutBrowserInfoTab	: "Información de Navegador",
+DlgAboutLicenseTab	: "Licencia",
+DlgAboutVersion		: "versión",
+DlgAboutInfo		: "Para mayor información por favor dirigirse a"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/eu.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/eu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/eu.js	(revision 795)
@@ -0,0 +1,505 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Basque language file.
+ * Euskara hizkuntza fitxategia.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Estutu Tresna Barra",
+ToolbarExpand		: "Hedatu Tresna Barra",
+
+// Toolbar Items and Context Menu
+Save				: "Gorde",
+NewPage				: "Orrialde Berria",
+Preview				: "Aurrebista",
+Cut					: "Ebaki",
+Copy				: "Kopiatu",
+Paste				: "Itsatsi",
+PasteText			: "Itsatsi testu bezala",
+PasteWord			: "Itsatsi Word-etik",
+Print				: "Inprimatu",
+SelectAll			: "Hautatu dena",
+RemoveFormat		: "Kendu Formatoa",
+InsertLinkLbl		: "Esteka",
+InsertLink			: "Txertatu/Editatu Esteka",
+RemoveLink			: "Kendu Esteka",
+Anchor				: "Aingura",
+InsertImageLbl		: "Irudia",
+InsertImage			: "Txertatu/Editatu Irudia",
+InsertFlashLbl		: "Flasha",
+InsertFlash			: "Txertatu/Editatu Flasha",
+InsertTableLbl		: "Taula",
+InsertTable			: "Txertatu/Editatu Taula",
+InsertLineLbl		: "Lerroa",
+InsertLine			: "Txertatu Marra Horizontala",
+InsertSpecialCharLbl: "Karaktere Berezia",
+InsertSpecialChar	: "Txertatu Karaktere Berezia",
+InsertSmileyLbl		: "Aurpegierak",
+InsertSmiley		: "Txertatu Aurpegierak",
+About				: "FCKeditor-ri buruz",
+Bold				: "Lodia",
+Italic				: "Etzana",
+Underline			: "Azpimarratu",
+StrikeThrough		: "Marratua",
+Subscript			: "Azpi-indize",
+Superscript			: "Goi-indize",
+LeftJustify			: "Lerrokatu Ezkerrean",
+CenterJustify		: "Lerrokatu Erdian",
+RightJustify		: "Lerrokatu Eskuman",
+BlockJustify		: "Justifikatu",
+DecreaseIndent		: "Txikitu Koska",
+IncreaseIndent		: "Handitu Koska",
+Undo				: "Desegin",
+Redo				: "Berregin",
+NumberedListLbl		: "Zenbakidun Zerrenda",
+NumberedList		: "Txertatu/Kendu Zenbakidun zerrenda",
+BulletedListLbl		: "Buletdun Zerrenda",
+BulletedList		: "Txertatu/Kendu Buletdun zerrenda",
+ShowTableBorders	: "Erakutsi Taularen Ertzak",
+ShowDetails			: "Erakutsi Xehetasunak",
+Style				: "Estiloa",
+FontFormat			: "Formatoa",
+Font				: "Letra-tipoa",
+FontSize			: "Tamaina",
+TextColor			: "Testu Kolorea",
+BGColor				: "Atzeko kolorea",
+Source				: "HTML Iturburua",
+Find				: "Bilatu",
+Replace				: "Ordezkatu",
+SpellCheck			: "Ortografia",
+UniversalKeyboard	: "Teklatu Unibertsala",
+PageBreakLbl		: "Orrialde-jauzia",
+PageBreak			: "Txertatu Orrialde-jauzia",
+
+Form			: "Formularioa",
+Checkbox		: "Kontrol-laukia",
+RadioButton		: "Aukera-botoia",
+TextField		: "Testu Eremua",
+Textarea		: "Testu-area",
+HiddenField		: "Ezkutuko Eremua",
+Button			: "Botoia",
+SelectionField	: "Hautespen Eremua",
+ImageButton		: "Irudi Botoia",
+
+FitWindow		: "Maximizatu editorearen tamaina",
+
+// Context Menu
+EditLink			: "Aldatu Esteka",
+CellCM				: "Gelaxka",
+RowCM				: "Errenkada",
+ColumnCM			: "Zutabea",
+InsertRow			: "Txertatu Errenkada",
+DeleteRows			: "Ezabatu Errenkadak",
+InsertColumn		: "Txertatu Zutabea",
+DeleteColumns		: "Ezabatu Zutabeak",
+InsertCell			: "Txertatu Gelaxka",
+DeleteCells			: "Kendu Gelaxkak",
+MergeCells			: "Batu Gelaxkak",
+SplitCell			: "Zatitu Gelaxka",
+TableDelete			: "Ezabatu Taula",
+CellProperties		: "Gelaxkaren Ezaugarriak",
+TableProperties		: "Taularen Ezaugarriak",
+ImageProperties		: "Irudiaren Ezaugarriak",
+FlashProperties		: "Flasharen Ezaugarriak",
+
+AnchorProp			: "Ainguraren Ezaugarriak",
+ButtonProp			: "Botoiaren Ezaugarriak",
+CheckboxProp		: "Kontrol-laukiko Ezaugarriak",
+HiddenFieldProp		: "Ezkutuko Eremuaren Ezaugarriak",
+RadioButtonProp		: "Aukera-botoiaren Ezaugarriak",
+ImageButtonProp		: "Irudi Botoiaren Ezaugarriak",
+TextFieldProp		: "Testu Eremuaren Ezaugarriak",
+SelectionFieldProp	: "Hautespen Eremuaren Ezaugarriak",
+TextareaProp		: "Testu-arearen Ezaugarriak",
+FormProp			: "Formularioaren Ezaugarriak",
+
+FontFormats			: "Arrunta;Formateatua;Helbidea;Izenburua 1;Izenburua 2;Izenburua 3;Izenburua 4;Izenburua 5;Izenburua 6;Paragrafoa (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML Prozesatzen. Itxaron mesedez...",
+Done				: "Eginda",
+PasteWordConfirm	: "Itsatsi nahi duzun textua Wordetik hartua dela dirudi. Itsatsi baino lehen garbitu nahi duzu?",
+NotCompatiblePaste	: "Komando hau Internet Explorer 5.5 bertsiorako edo ondorengoentzako erabilgarria dago. Garbitu gabe itsatsi nahi duzu?",
+UnknownToolbarItem	: "Ataza barrako elementu ezezaguna \"%1\"",
+UnknownCommand		: "Komando izen ezezaguna \"%1\"",
+NotImplemented		: "Komando ez inplementatua",
+UnknownToolbarSet	: "Ataza barra \"%1\" taldea ez da existitzen",
+NoActiveX			: "Zure nabigatzailearen segustasun hobespenak editore honen zenbait ezaugarri mugatu ditzake. \"ActiveX kontrolak eta plug-inak\" aktibatu beharko zenituzke, bestela erroreak eta ezaugarrietan mugak egon daitezke.",
+BrowseServerBlocked : "Baliabideen arakatzailea ezin da ireki. Ziurtatu popup blokeatzaileak desgaituta dituzula.",
+DialogBlocked		: "Ezin da elkarrizketa-leihoa ireki. Ziurtatu popup blokeatzaileak desgaituta dituzula.",
+
+// Dialogs
+DlgBtnOK			: "Ados",
+DlgBtnCancel		: "Utzi",
+DlgBtnClose			: "Itxi",
+DlgBtnBrowseServer	: "Zerbitzaria arakatu",
+DlgAdvancedTag		: "Aurreratua",
+DlgOpOther			: "<Bestelakoak>",
+DlgInfoTab			: "Informazioa",
+DlgAlertUrl			: "Mesedez URLa idatzi ezazu",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<Ezarri gabe>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Hizkuntzaren Norabidea",
+DlgGenLangDirLtr	: "Ezkerretik Eskumara(LTR)",
+DlgGenLangDirRtl	: "Eskumatik Ezkerrera (RTL)",
+DlgGenLangCode		: "Hizkuntza Kodea",
+DlgGenAccessKey		: "Sarbide-gakoa",
+DlgGenName			: "Izena",
+DlgGenTabIndex		: "Tabulazio Indizea",
+DlgGenLongDescr		: "URL Deskribapen Luzea",
+DlgGenClass			: "Estilo-orriko Klaseak",
+DlgGenTitle			: "Izenburua",
+DlgGenContType		: "Eduki Mota (Content Type)",
+DlgGenLinkCharset	: "Estekatutako Karaktere Multzoa",
+DlgGenStyle			: "Estiloa",
+
+// Image Dialog
+DlgImgTitle			: "Irudi Ezaugarriak",
+DlgImgInfoTab		: "Irudi informazioa",
+DlgImgBtnUpload		: "Zerbitzarira bidalia",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Gora Kargatu",
+DlgImgAlt			: "Textu Alternatiboa",
+DlgImgWidth			: "Zabalera",
+DlgImgHeight		: "Altuera",
+DlgImgLockRatio		: "Erlazioa Blokeatu",
+DlgBtnResetSize		: "Tamaina Berrezarri",
+DlgImgBorder		: "Ertza",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Lerrokatu",
+DlgImgAlignLeft		: "Ezkerrera",
+DlgImgAlignAbsBottom: "Abs Behean",
+DlgImgAlignAbsMiddle: "Abs Erdian",
+DlgImgAlignBaseline	: "Oinan",
+DlgImgAlignBottom	: "Behean",
+DlgImgAlignMiddle	: "Erdian",
+DlgImgAlignRight	: "Eskuman",
+DlgImgAlignTextTop	: "Testua Goian",
+DlgImgAlignTop		: "Goian",
+DlgImgPreview		: "Aurrebista",
+DlgImgAlertUrl		: "Mesedez Irudiaren URLa idatzi",
+DlgImgLinkTab		: "Esteka",
+
+// Flash Dialog
+DlgFlashTitle		: "Flasharen Ezaugarriak",
+DlgFlashChkPlay		: "Automatikoki Erreproduzitu",
+DlgFlashChkLoop		: "Begizta",
+DlgFlashChkMenu		: "Flasharen Menua Gaitu",
+DlgFlashScale		: "Eskalatu",
+DlgFlashScaleAll	: "Dena erakutsi",
+DlgFlashScaleNoBorder	: "Ertzarik gabe",
+DlgFlashScaleFit	: "Doitu",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Esteka",
+DlgLnkInfoTab		: "Estekaren Informazioa",
+DlgLnkTargetTab		: "Helburua",
+
+DlgLnkType			: "Esteka Mota",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Aingura horrialde honentan",
+DlgLnkTypeEMail		: "ePosta",
+DlgLnkProto			: "Protokoloa",
+DlgLnkProtoOther	: "<Beste batzuk>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Aingura bat hautatu",
+DlgLnkAnchorByName	: "Aingura izenagatik",
+DlgLnkAnchorById	: "Elementuaren ID-gatik",
+DlgLnkNoAnchors		: "<Ez daude aingurak eskuragarri dokumentuan>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "ePosta Helbidea",
+DlgLnkEMailSubject	: "Mezuaren Gaia",
+DlgLnkEMailBody		: "Mezuaren Gorputza",
+DlgLnkUpload		: "Gora kargatu",
+DlgLnkBtnUpload		: "Zerbitzarira bidali",
+
+DlgLnkTarget		: "Target (Helburua)",
+DlgLnkTargetFrame	: "<marko>",
+DlgLnkTargetPopup	: "<popup lehioa>",
+DlgLnkTargetBlank	: "Lehio Berria (_blank)",
+DlgLnkTargetParent	: "Lehio Gurasoa (_parent)",
+DlgLnkTargetSelf	: "Lehio Berdina (_self)",
+DlgLnkTargetTop		: "Goiko Lehioa (_top)",
+DlgLnkTargetFrameName	: "Marko Helburuaren Izena",
+DlgLnkPopWinName	: "Popup Lehioaren Izena",
+DlgLnkPopWinFeat	: "Popup Lehioaren Ezaugarriak",
+DlgLnkPopResize		: "Tamaina Aldakorra",
+DlgLnkPopLocation	: "Kokaleku Barra",
+DlgLnkPopMenu		: "Menu Barra",
+DlgLnkPopScroll		: "Korritze Barrak",
+DlgLnkPopStatus		: "Egoera Barra",
+DlgLnkPopToolbar	: "Tresna Barra",
+DlgLnkPopFullScrn	: "Pantaila Osoa (IE)",
+DlgLnkPopDependent	: "Menpekoa (Netscape)",
+DlgLnkPopWidth		: "Zabalera",
+DlgLnkPopHeight		: "Altuera",
+DlgLnkPopLeft		: "Ezkerreko  Posizioa",
+DlgLnkPopTop		: "Goiko Posizioa",
+
+DlnLnkMsgNoUrl		: "Mesedez URL esteka idatzi",
+DlnLnkMsgNoEMail	: "Mesedez ePosta helbidea idatzi",
+DlnLnkMsgNoAnchor	: "Mesedez aingura bat aukeratu",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Kolore Aukeraketa",
+DlgColorBtnClear	: "Garbitu",
+DlgColorHighlight	: "Nabarmendu",
+DlgColorSelected	: "Aukeratuta",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Aurpegiera Sartu",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Karaktere Berezia Aukeratu",
+
+// Table Dialog
+DlgTableTitle		: "Taularen Ezaugarriak",
+DlgTableRows		: "Lerroak",
+DlgTableColumns		: "Zutabeak",
+DlgTableBorder		: "Ertzaren Zabalera",
+DlgTableAlign		: "Lerrokatu",
+DlgTableAlignNotSet	: "<Ezarri gabe>",
+DlgTableAlignLeft	: "Ezkerrean",
+DlgTableAlignCenter	: "Erdian",
+DlgTableAlignRight	: "Eskuman",
+DlgTableWidth		: "Zabalera",
+DlgTableWidthPx		: "pixel",
+DlgTableWidthPc		: "ehuneko",
+DlgTableHeight		: "Altuera",
+DlgTableCellSpace	: "Gelaxka arteko tartea",
+DlgTableCellPad		: "Gelaxken betegarria",
+DlgTableCaption		: "Epigrafea",
+DlgTableSummary		: "Laburpena",
+
+// Table Cell Dialog
+DlgCellTitle		: "Gelaxken Ezaugarriak",
+DlgCellWidth		: "Zabalera",
+DlgCellWidthPx		: "pixel",
+DlgCellWidthPc		: "ehuneko",
+DlgCellHeight		: "Altuera",
+DlgCellWordWrap		: "Itzulbira",
+DlgCellWordWrapNotSet	: "<Ezarri gabe>",
+DlgCellWordWrapYes	: "Bai",
+DlgCellWordWrapNo	: "Ez",
+DlgCellHorAlign		: "Horizontal Alignment",
+DlgCellHorAlignNotSet	: "<Ezarri gabe>",
+DlgCellHorAlignLeft	: "Ezkerrean",
+DlgCellHorAlignCenter	: "Erdian",
+DlgCellHorAlignRight: "Eskuman",
+DlgCellVerAlign		: "Lerrokatu Bertikalki",
+DlgCellVerAlignNotSet	: "<Ezarri gabe>",
+DlgCellVerAlignTop	: "Goian",
+DlgCellVerAlignMiddle	: "Erdian",
+DlgCellVerAlignBottom	: "Behean",
+DlgCellVerAlignBaseline	: "Oinan",
+DlgCellRowSpan		: "Lerroak Hedatu",
+DlgCellCollSpan		: "Zutabeak Hedatu",
+DlgCellBackColor	: "Atzeko Kolorea",
+DlgCellBorderColor	: "Ertzako Kolorea",
+DlgCellBtnSelect	: "Aukertau...",
+
+// Find Dialog
+DlgFindTitle		: "Bilaketa",
+DlgFindFindBtn		: "Bilatu",
+DlgFindNotFoundMsg	: "Idatzitako testua ez da topatu.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Ordeztu",
+DlgReplaceFindLbl		: "Zer bilatu:",
+DlgReplaceReplaceLbl	: "Zerekin ordeztu:",
+DlgReplaceCaseChk		: "Maiuskula/minuskula",
+DlgReplaceReplaceBtn	: "Ordeztu",
+DlgReplaceReplAllBtn	: "Ordeztu Guztiak",
+DlgReplaceWordChk		: "Esaldi osoa bilatu",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Zure web nabigatzailearen segurtasun ezarpenak testuak automatikoki moztea ez dute baimentzen. Mesedez teklatua erabili ezazu (Ctrl+X).",
+PasteErrorCopy	: "Zure web nabigatzailearen segurtasun ezarpenak testuak automatikoki kopiatzea ez dute baimentzen. Mesedez teklatua erabili ezazu (Ctrl+C).",
+
+PasteAsText		: "Testu Arrunta bezala Itsatsi",
+PasteFromWord	: "Word-etik itsatsi",
+
+DlgPasteMsg2	: "Mesedez teklatua erabilita (<STRONG>Ctrl+V</STRONG>) ondorego eremuan testua itsatsi eta <STRONG>OK</STRONG> sakatu.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Letra Motaren definizioa ezikusi",
+DlgPasteRemoveStyles	: "Estilo definizioak kendu",
+DlgPasteCleanBox		: "Testu-eremua Garbitu",
+
+// Color Picker
+ColorAutomatic	: "Automatikoa",
+ColorMoreColors	: "Kolore gehiago...",
+
+// Document Properties
+DocProps		: "Dokumentuaren Ezarpenak",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ainguraren Ezaugarriak",
+DlgAnchorName		: "Ainguraren Izena",
+DlgAnchorErrorName	: "Idatzi ainguraren izena",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ez dago hiztegian",
+DlgSpellChangeTo		: "Honekin ordezkatu",
+DlgSpellBtnIgnore		: "Ezikusi",
+DlgSpellBtnIgnoreAll	: "Denak Ezikusi",
+DlgSpellBtnReplace		: "Ordezkatu",
+DlgSpellBtnReplaceAll	: "Denak Ordezkatu",
+DlgSpellBtnUndo			: "Desegin",
+DlgSpellNoSuggestions	: "- Iradokizunik ez -",
+DlgSpellProgress		: "Zuzenketa ortografikoa martxan...",
+DlgSpellNoMispell		: "Zuzenketa ortografikoa bukatuta: Akatsik ez",
+DlgSpellNoChanges		: "Zuzenketa ortografikoa bukatuta: Ez da ezer aldatu",
+DlgSpellOneChange		: "Zuzenketa ortografikoa bukatuta: Hitz bat aldatu da",
+DlgSpellManyChanges		: "Zuzenketa ortografikoa bukatuta: %1 hitz aldatu dira",
+
+IeSpellDownload			: "Zuzentzaile ortografikoa ez dago instalatuta. Deskargatu nahi duzu?",
+
+// Button Dialog
+DlgButtonText		: "Testua (Balorea)",
+DlgButtonType		: "Mota",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Izena",
+DlgCheckboxValue	: "Balorea",
+DlgCheckboxSelected	: "Hautatuta",
+
+// Form Dialog
+DlgFormName		: "Izena",
+DlgFormAction	: "Ekintza",
+DlgFormMethod	: "Method",
+
+// Select Field Dialog
+DlgSelectName		: "Izena",
+DlgSelectValue		: "Balorea",
+DlgSelectSize		: "Tamaina",
+DlgSelectLines		: "lerro kopurura",
+DlgSelectChkMulti	: "Hautaketa anitzak baimendu",
+DlgSelectOpAvail	: "Aukera Eskuragarriak",
+DlgSelectOpText		: "Testua",
+DlgSelectOpValue	: "Balorea",
+DlgSelectBtnAdd		: "Gehitu",
+DlgSelectBtnModify	: "Aldatu",
+DlgSelectBtnUp		: "Gora",
+DlgSelectBtnDown	: "Behera",
+DlgSelectBtnSetValue : "Aukeratutako balorea ezarri",
+DlgSelectBtnDelete	: "Ezabatu",
+
+// Textarea Dialog
+DlgTextareaName	: "Izena",
+DlgTextareaCols	: "Zutabeak",
+DlgTextareaRows	: "Lerroak",
+
+// Text Field Dialog
+DlgTextName			: "Izena",
+DlgTextValue		: "Balorea",
+DlgTextCharWidth	: "Zabalera",
+DlgTextMaxChars		: "Zenbat karaktere gehienez",
+DlgTextType			: "Mota",
+DlgTextTypeText		: "Testua",
+DlgTextTypePass		: "Pasahitza",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Izena",
+DlgHiddenValue	: "Balorea",
+
+// Bulleted List Dialog
+BulletedListProp	: "Buletdun Zerrendaren Ezarpenak",
+NumberedListProp	: "Zenbakidun Zerrendaren Ezarpenak",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Mota",
+DlgLstTypeCircle	: "Zirkulua",
+DlgLstTypeDisc		: "Diskoa",
+DlgLstTypeSquare	: "Karratua",
+DlgLstTypeNumbers	: "Zenbakiak (1, 2, 3)",
+DlgLstTypeLCase		: "Letra xeheak (a, b, c)",
+DlgLstTypeUCase		: "Letra larriak (A, B, C)",
+DlgLstTypeSRoman	: "Erromatar zenbaki zeheak (i, ii, iii)",
+DlgLstTypeLRoman	: "Erromatar zenbaki larriak (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Orokorra",
+DlgDocBackTab		: "Atzekaldea",
+DlgDocColorsTab		: "Koloreak eta Marjinak",
+DlgDocMetaTab		: "Meta Informazioa",
+
+DlgDocPageTitle		: "Orriaren Izenburua",
+DlgDocLangDir		: "Hizkuntzaren Norabidea",
+DlgDocLangDirLTR	: "Ezkerretik eskumara (LTR)",
+DlgDocLangDirRTL	: "Eskumatik ezkerrera (RTL)",
+DlgDocLangCode		: "Hizkuntzaren Kodea",
+DlgDocCharSet		: "Karaktere Multzoaren Kodeketa",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Beste Karaktere Multzoaren Kodeketa",
+
+DlgDocDocType		: "Document Type Goiburua",
+DlgDocDocTypeOther	: "Beste Document Type Goiburua",
+DlgDocIncXHTML		: "XHTML Ezarpenak",
+DlgDocBgColor		: "Atzeko Kolorea",
+DlgDocBgImage		: "Atzeko Irudiaren URL-a",
+DlgDocBgNoScroll	: "Korritze gabeko Atzekaldea",
+DlgDocCText			: "Testua",
+DlgDocCLink			: "Estekak",
+DlgDocCVisited		: "Bisitatutako Estekak",
+DlgDocCActive		: "Esteka Aktiboa",
+DlgDocMargins		: "Orrialdearen marjinak",
+DlgDocMaTop			: "Goian",
+DlgDocMaLeft		: "Ezkerrean",
+DlgDocMaRight		: "Eskuman",
+DlgDocMaBottom		: "Behean",
+DlgDocMeIndex		: "Dokumentuaren Gako-hitzak (komarekin bananduta)",
+DlgDocMeDescr		: "Dokumentuaren Deskribapena",
+DlgDocMeAuthor		: "Egilea",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Aurrebista",
+
+// Templates Dialog
+Templates			: "Txantiloiak",
+DlgTemplatesTitle	: "Eduki Txantiloiak",
+DlgTemplatesSelMsg	: "Mesedez txantiloia aukeratu editorean kargatzeko<br>(orain dauden edukiak galduko dira):",
+DlgTemplatesLoading	: "Txantiloiak kargatzen. Itxaron mesedez...",
+DlgTemplatesNoTpl	: "(Ez dago definitutako txantiloirik)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Honi buruz",
+DlgAboutBrowserInfoTab	: "Nabigatzailearen Informazioa",
+DlgAboutLicenseTab	: "Lizentzia",
+DlgAboutVersion		: "bertsioa",
+DlgAboutInfo		: "Informazio gehiago eskuratzeko hona joan"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ko.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Korean language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "툴바 감추기",
+ToolbarExpand		: "툴바 보이기",
+
+// Toolbar Items and Context Menu
+Save				: "저장하기",
+NewPage				: "새 문서",
+Preview				: "미리보기",
+Cut					: "잘라내기",
+Copy				: "복사하기",
+Paste				: "붙여넣기",
+PasteText			: "텍스트로 붙여넣기",
+PasteWord			: "MS Word 형식에서 붙여넣기",
+Print				: "인쇄하기",
+SelectAll			: "전체선택",
+RemoveFormat		: "포맷 지우기",
+InsertLinkLbl		: "링크",
+InsertLink			: "링크 삽입/변경",
+RemoveLink			: "링크 삭제",
+Anchor				: "책갈피 삽입/변경",
+InsertImageLbl		: "이미지",
+InsertImage			: "이미지 삽입/변경",
+InsertFlashLbl		: "플래쉬",
+InsertFlash			: "플래쉬 삽입/변경",
+InsertTableLbl		: "표",
+InsertTable			: "표 삽입/변경",
+InsertLineLbl		: "수평선",
+InsertLine			: "수평선 삽입",
+InsertSpecialCharLbl: "특수문자 삽입",
+InsertSpecialChar	: "특수문자 삽입",
+InsertSmileyLbl		: "아이콘",
+InsertSmiley		: "아이콘 삽입",
+About				: "FCKeditor에 대하여",
+Bold				: "진하게",
+Italic				: "이텔릭",
+Underline			: "밑줄",
+StrikeThrough		: "취소선",
+Subscript			: "아래 첨자",
+Superscript			: "위 첨자",
+LeftJustify			: "왼쪽 정렬",
+CenterJustify		: "가운데 정렬",
+RightJustify		: "오른쪽 정렬",
+BlockJustify		: "양쪽 맞춤",
+DecreaseIndent		: "내어쓰기",
+IncreaseIndent		: "들여쓰기",
+Undo				: "취소",
+Redo				: "재실행",
+NumberedListLbl		: "순서있는 목록",
+NumberedList		: "순서있는 목록",
+BulletedListLbl		: "순서없는 목록",
+BulletedList		: "순서없는 목록",
+ShowTableBorders	: "표 테두리 보기",
+ShowDetails			: "문서기호 보기",
+Style				: "스타일",
+FontFormat			: "포맷",
+Font				: "폰트",
+FontSize			: "글자 크기",
+TextColor			: "글자 색상",
+BGColor				: "배경 색상",
+Source				: "소스",
+Find				: "찾기",
+Replace				: "바꾸기",
+SpellCheck			: "철자검사",
+UniversalKeyboard	: "다국어 입력기",
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "폼",
+Checkbox		: "체크박스",
+RadioButton		: "라디오버튼",
+TextField		: "입력필드",
+Textarea		: "입력영역",
+HiddenField		: "숨김필드",
+Button			: "버튼",
+SelectionField	: "펼침목록",
+ImageButton		: "이미지버튼",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "링크 수정",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "가로줄 삽입",
+DeleteRows			: "가로줄 삭제",
+InsertColumn		: "세로줄 삽입",
+DeleteColumns		: "세로줄 삭제",
+InsertCell			: "셀 삽입",
+DeleteCells			: "셀 삭제",
+MergeCells			: "셀 합치기",
+SplitCell			: "셀 나누기",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "셀 속성",
+TableProperties		: "표 속성",
+ImageProperties		: "이미지 속성",
+FlashProperties		: "플래쉬 속성",
+
+AnchorProp			: "책갈피 속성",
+ButtonProp			: "버튼 속성",
+CheckboxProp		: "체크박스 속성",
+HiddenFieldProp		: "숨김필드 속성",
+RadioButtonProp		: "라디오버튼 속성",
+ImageButtonProp		: "이미지버튼 속성",
+TextFieldProp		: "입력필드 속성",
+SelectionFieldProp	: "펼침목록 속성",
+TextareaProp		: "입력영역 속성",
+FormProp			: "폼 속성",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML 처리중. 잠시만 기다려주십시요.",
+Done				: "완료",
+PasteWordConfirm	: "붙여넣기 할 텍스트는 MS Word에서 복사한 것입니다. 붙여넣기 전에 MS Word 포멧을 삭제하시겠습니까?",
+NotCompatiblePaste	: "이 명령은 인터넷익스플로러 5.5 버전 이상에서만 작동합니다. 포멧을 삭제하지 않고 붙여넣기 하시겠습니까?",
+UnknownToolbarItem	: "알수없는 툴바입니다. : \"%1\"",
+UnknownCommand		: "알수없는 기능입니다. : \"%1\"",
+NotImplemented		: "기능이 실행되지 않았습니다.",
+UnknownToolbarSet	: "툴바 설정이 없습니다. : \"%1\"",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "예",
+DlgBtnCancel		: "아니오",
+DlgBtnClose			: "닫기",
+DlgBtnBrowseServer	: "서버 보기",
+DlgAdvancedTag		: "자세히",
+DlgOpOther			: "<기타>",
+DlgInfoTab			: "정보",
+DlgAlertUrl			: "URL을 입력하십시요",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<설정되지 않음>",
+DlgGenId			: "ID",
+DlgGenLangDir		: "쓰기 방향",
+DlgGenLangDirLtr	: "왼쪽에서 오른쪽 (LTR)",
+DlgGenLangDirRtl	: "오른쪽에서 왼쪽 (RTL)",
+DlgGenLangCode		: "언어 코드",
+DlgGenAccessKey		: "엑세스 키",
+DlgGenName			: "Name",
+DlgGenTabIndex		: "탭 순서",
+DlgGenLongDescr		: "URL 설명",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "이미지 설정",
+DlgImgInfoTab		: "이미지 정보",
+DlgImgBtnUpload		: "서버로 전송",
+DlgImgURL			: "URL",
+DlgImgUpload		: "업로드",
+DlgImgAlt			: "이미지 설명",
+DlgImgWidth			: "너비",
+DlgImgHeight		: "높이",
+DlgImgLockRatio		: "비율 유지",
+DlgBtnResetSize		: "원래 크기로",
+DlgImgBorder		: "테두리",
+DlgImgHSpace		: "수평여백",
+DlgImgVSpace		: "수직여백",
+DlgImgAlign			: "정렬",
+DlgImgAlignLeft		: "왼쪽",
+DlgImgAlignAbsBottom: "줄아래(Abs Bottom)",
+DlgImgAlignAbsMiddle: "줄중간(Abs Middle)",
+DlgImgAlignBaseline	: "기준선",
+DlgImgAlignBottom	: "아래",
+DlgImgAlignMiddle	: "중간",
+DlgImgAlignRight	: "오른쪽",
+DlgImgAlignTextTop	: "글자위(Text Top)",
+DlgImgAlignTop		: "위",
+DlgImgPreview		: "미리보기",
+DlgImgAlertUrl		: "이미지 URL을 입력하십시요",
+DlgImgLinkTab		: "링크",
+
+// Flash Dialog
+DlgFlashTitle		: "플래쉬 등록정보",
+DlgFlashChkPlay		: "자동재생",
+DlgFlashChkLoop		: "반복",
+DlgFlashChkMenu		: "플래쉬메뉴 가능",
+DlgFlashScale		: "영역",
+DlgFlashScaleAll	: "모두보기",
+DlgFlashScaleNoBorder	: "경계선없음",
+DlgFlashScaleFit	: "영역자동조절",
+
+// Link Dialog
+DlgLnkWindowTitle	: "링크",
+DlgLnkInfoTab		: "링크 정보",
+DlgLnkTargetTab		: "타겟",
+
+DlgLnkType			: "링크 종류",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "책갈피",
+DlgLnkTypeEMail		: "이메일",
+DlgLnkProto			: "프로토콜",
+DlgLnkProtoOther	: "<기타>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "책갈피 선택",
+DlgLnkAnchorByName	: "책갈피 이름",
+DlgLnkAnchorById	: "책갈피 ID",
+DlgLnkNoAnchors		: "<문서에 책갈피가 없습니다.>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "이메일 주소",
+DlgLnkEMailSubject	: "제목",
+DlgLnkEMailBody		: "내용",
+DlgLnkUpload		: "업로드",
+DlgLnkBtnUpload		: "서버로 전송",
+
+DlgLnkTarget		: "타겟",
+DlgLnkTargetFrame	: "<프레임>",
+DlgLnkTargetPopup	: "<팝업창>",
+DlgLnkTargetBlank	: "새 창 (_blank)",
+DlgLnkTargetParent	: "부모 창 (_parent)",
+DlgLnkTargetSelf	: "현재 창 (_self)",
+DlgLnkTargetTop		: "최 상위 창 (_top)",
+DlgLnkTargetFrameName	: "타겟 프레임 이름",
+DlgLnkPopWinName	: "팝업창 이름",
+DlgLnkPopWinFeat	: "팝업창 설정",
+DlgLnkPopResize		: "크기조정",
+DlgLnkPopLocation	: "주소표시줄",
+DlgLnkPopMenu		: "메뉴바",
+DlgLnkPopScroll		: "스크롤바",
+DlgLnkPopStatus		: "상태바",
+DlgLnkPopToolbar	: "툴바",
+DlgLnkPopFullScrn	: "전체화면 (IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "너비",
+DlgLnkPopHeight		: "높이",
+DlgLnkPopLeft		: "왼쪽 위치",
+DlgLnkPopTop		: "윗쪽 위치",
+
+DlnLnkMsgNoUrl		: "링크 URL을 입력하십시요.",
+DlnLnkMsgNoEMail	: "이메일주소를 입력하십시요.",
+DlnLnkMsgNoAnchor	: "책갈피명을 입력하십시요.",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "색상 선택",
+DlgColorBtnClear	: "지우기",
+DlgColorHighlight	: "현재",
+DlgColorSelected	: "선택됨",
+
+// Smiley Dialog
+DlgSmileyTitle		: "아이콘 삽입",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "특수문자 선택",
+
+// Table Dialog
+DlgTableTitle		: "표 설정",
+DlgTableRows		: "가로줄",
+DlgTableColumns		: "세로줄",
+DlgTableBorder		: "테두리 크기",
+DlgTableAlign		: "정렬",
+DlgTableAlignNotSet	: "<설정되지 않음>",
+DlgTableAlignLeft	: "왼쪽",
+DlgTableAlignCenter	: "가운데",
+DlgTableAlignRight	: "오른쪽",
+DlgTableWidth		: "너비",
+DlgTableWidthPx		: "픽셀",
+DlgTableWidthPc		: "퍼센트",
+DlgTableHeight		: "높이",
+DlgTableCellSpace	: "셀 간격",
+DlgTableCellPad		: "셀 여백",
+DlgTableCaption		: "캡션",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "셀 설정",
+DlgCellWidth		: "너비",
+DlgCellWidthPx		: "픽셀",
+DlgCellWidthPc		: "퍼센트",
+DlgCellHeight		: "높이",
+DlgCellWordWrap		: "워드랩",
+DlgCellWordWrapNotSet	: "<설정되지 않음>",
+DlgCellWordWrapYes	: "예",
+DlgCellWordWrapNo	: "아니오",
+DlgCellHorAlign		: "수평 정렬",
+DlgCellHorAlignNotSet	: "<설정되지 않음>",
+DlgCellHorAlignLeft	: "왼쪽",
+DlgCellHorAlignCenter	: "가운데",
+DlgCellHorAlignRight: "오른쪽",
+DlgCellVerAlign		: "수직 정렬",
+DlgCellVerAlignNotSet	: "<설정되지 않음>",
+DlgCellVerAlignTop	: "위",
+DlgCellVerAlignMiddle	: "중간",
+DlgCellVerAlignBottom	: "아래",
+DlgCellVerAlignBaseline	: "기준선",
+DlgCellRowSpan		: "세로 합치기",
+DlgCellCollSpan		: "가로 합치기",
+DlgCellBackColor	: "배경 색상",
+DlgCellBorderColor	: "테두리 색상",
+DlgCellBtnSelect	: "선택",
+
+// Find Dialog
+DlgFindTitle		: "찾기",
+DlgFindFindBtn		: "찾기",
+DlgFindNotFoundMsg	: "문자열을 찾을 수 없습니다.",
+
+// Replace Dialog
+DlgReplaceTitle			: "바꾸기",
+DlgReplaceFindLbl		: "찾을 문자열:",
+DlgReplaceReplaceLbl	: "바꿀 문자열:",
+DlgReplaceCaseChk		: "대소문자 구분",
+DlgReplaceReplaceBtn	: "바꾸기",
+DlgReplaceReplAllBtn	: "모두 바꾸기",
+DlgReplaceWordChk		: "온전한 단어",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "브라우저의 보안설정때문에 잘라내기 기능을 실행할 수 없습니다. 키보드 명령을 사용하십시요. (Ctrl+X).",
+PasteErrorCopy	: "브라우저의 보안설정때문에 복사하기 기능을 실행할 수 없습니다. 키보드 명령을 사용하십시요.  (Ctrl+C).",
+
+PasteAsText		: "텍스트로 붙여넣기",
+PasteFromWord	: "MS Word 형식에서 붙여넣기",
+
+DlgPasteMsg2	: "키보드의 (<STRONG>Ctrl+V</STRONG>) 를 이용해서 상자안에 붙여넣고 <STRONG>OK</STRONG> 를 누르세요.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "폰트 설정 무시",
+DlgPasteRemoveStyles	: "스타일 정의 제거",
+DlgPasteCleanBox		: "글상자 제거",
+
+// Color Picker
+ColorAutomatic	: "기본색상",
+ColorMoreColors	: "색상선택...",
+
+// Document Properties
+DocProps		: "문서 속성",
+
+// Anchor Dialog
+DlgAnchorTitle		: "책갈피 속성",
+DlgAnchorName		: "책갈피 이름",
+DlgAnchorErrorName	: "책갈피 이름을 입력하십시요.",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "사전에 없는 단어",
+DlgSpellChangeTo		: "변경할 단어",
+DlgSpellBtnIgnore		: "건너뜀",
+DlgSpellBtnIgnoreAll	: "모두 건너뜀",
+DlgSpellBtnReplace		: "변경",
+DlgSpellBtnReplaceAll	: "모두 변경",
+DlgSpellBtnUndo			: "취소",
+DlgSpellNoSuggestions	: "- 추천단어 없음 -",
+DlgSpellProgress		: "철자검사를 진행중입니다...",
+DlgSpellNoMispell		: "철자검사 완료: 잘못된 철자가 없습니다.",
+DlgSpellNoChanges		: "철자검사 완료: 변경된 단어가 없습니다.",
+DlgSpellOneChange		: "철자검사 완료: 단어가 변경되었습니다.",
+DlgSpellManyChanges		: "철자검사 완료: %1 단어가 변경되었습니다.",
+
+IeSpellDownload			: "철자 검사기가 철치되지 않았습니다. 지금 다운로드하시겠습니까?",
+
+// Button Dialog
+DlgButtonText		: "버튼글자(값)",
+DlgButtonType		: "버튼종류",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "이름",
+DlgCheckboxValue	: "값",
+DlgCheckboxSelected	: "선택됨",
+
+// Form Dialog
+DlgFormName		: "폼이름",
+DlgFormAction	: "실행경로(Action)",
+DlgFormMethod	: "방법(Method)",
+
+// Select Field Dialog
+DlgSelectName		: "이름",
+DlgSelectValue		: "값",
+DlgSelectSize		: "세로크기",
+DlgSelectLines		: "줄",
+DlgSelectChkMulti	: "여러항목 선택 허용",
+DlgSelectOpAvail	: "선택옵션",
+DlgSelectOpText		: "이름",
+DlgSelectOpValue	: "값",
+DlgSelectBtnAdd		: "추가",
+DlgSelectBtnModify	: "변경",
+DlgSelectBtnUp		: "위로",
+DlgSelectBtnDown	: "아래로",
+DlgSelectBtnSetValue : "선택된것으로 설정",
+DlgSelectBtnDelete	: "삭제",
+
+// Textarea Dialog
+DlgTextareaName	: "이름",
+DlgTextareaCols	: "칸수",
+DlgTextareaRows	: "줄수",
+
+// Text Field Dialog
+DlgTextName			: "이름",
+DlgTextValue		: "값",
+DlgTextCharWidth	: "글자 너비",
+DlgTextMaxChars		: "최대 글자수",
+DlgTextType			: "종류",
+DlgTextTypeText		: "문자열",
+DlgTextTypePass		: "비밀번호",
+
+// Hidden Field Dialog
+DlgHiddenName	: "이름",
+DlgHiddenValue	: "값",
+
+// Bulleted List Dialog
+BulletedListProp	: "순서없는 목록 속성",
+NumberedListProp	: "순서있는 목록 속성",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "종류",
+DlgLstTypeCircle	: "원(Circle)",
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "네모점(Square)",
+DlgLstTypeNumbers	: "번호 (1, 2, 3)",
+DlgLstTypeLCase		: "소문자 (a, b, c)",
+DlgLstTypeUCase		: "대문자 (A, B, C)",
+DlgLstTypeSRoman	: "로마자 수문자 (i, ii, iii)",
+DlgLstTypeLRoman	: "로마자 대문자 (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "일반",
+DlgDocBackTab		: "배경",
+DlgDocColorsTab		: "색상 및 여백",
+DlgDocMetaTab		: "메타데이터",
+
+DlgDocPageTitle		: "페이지명",
+DlgDocLangDir		: "문자 쓰기방향",
+DlgDocLangDirLTR	: "왼쪽에서 오른쪽 (LTR)",
+DlgDocLangDirRTL	: "오른쪽에서 왼쪽 (RTL)",
+DlgDocLangCode		: "언어코드",
+DlgDocCharSet		: "캐릭터셋 인코딩",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "다른 캐릭터셋 인코딩",
+
+DlgDocDocType		: "문서 헤드",
+DlgDocDocTypeOther	: "다른 문서헤드",
+DlgDocIncXHTML		: "XHTML 문서정의 포함",
+DlgDocBgColor		: "배경색상",
+DlgDocBgImage		: "배경이미지 URL",
+DlgDocBgNoScroll	: "스크롤되지않는 배경",
+DlgDocCText			: "텍스트",
+DlgDocCLink			: "링크",
+DlgDocCVisited		: "방문한 링크(Visited)",
+DlgDocCActive		: "활성화된 링크(Active)",
+DlgDocMargins		: "페이지 여백",
+DlgDocMaTop			: "위",
+DlgDocMaLeft		: "왼쪽",
+DlgDocMaRight		: "오른쪽",
+DlgDocMaBottom		: "아래",
+DlgDocMeIndex		: "문서 키워드 (콤마로 구분)",
+DlgDocMeDescr		: "문서 설명",
+DlgDocMeAuthor		: "작성자",
+DlgDocMeCopy		: "저작권",
+DlgDocPreview		: "미리보기",
+
+// Templates Dialog
+Templates			: "템플릿",
+DlgTemplatesTitle	: "내용 템플릿",
+DlgTemplatesSelMsg	: "에디터에서 사용할 템플릿을 선택하십시요.<br>(지금까지 작성된 내용은 사라집니다.):",
+DlgTemplatesLoading	: "템플릿 목록을 불러오는중입니다. 잠시만 기다려주십시요.",
+DlgTemplatesNoTpl	: "(템플릿이 없습니다.)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "About",
+DlgAboutBrowserInfoTab	: "브라우저 정보",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "버전",
+DlgAboutInfo		: "For further information go to"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hu.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hu.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hu.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Hungarian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Eszköztár elrejtése",
+ToolbarExpand		: "Eszköztár megjelenítése",
+
+// Toolbar Items and Context Menu
+Save				: "Mentés",
+NewPage				: "Új oldal",
+Preview				: "Előnézet",
+Cut					: "Kivágás",
+Copy				: "Másolás",
+Paste				: "Beillesztés",
+PasteText			: "Beillesztés formázás nélkül",
+PasteWord			: "Beillesztés Word-ből",
+Print				: "Nyomtatás",
+SelectAll			: "Mindent kijelöl",
+RemoveFormat		: "Formázás eltávolítása",
+InsertLinkLbl		: "Hivatkozás",
+InsertLink			: "Hivatkozás beillesztése/módosítása",
+RemoveLink			: "Hivatkozás törlése",
+Anchor				: "Horgony beillesztése/szerkesztése",
+InsertImageLbl		: "Kép",
+InsertImage			: "Kép beillesztése/módosítása",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Flash beillesztése, módosítása",
+InsertTableLbl		: "Táblázat",
+InsertTable			: "Táblázat beillesztése/módosítása",
+InsertLineLbl		: "Vonal",
+InsertLine			: "Elválasztóvonal beillesztése",
+InsertSpecialCharLbl: "Speciális karakter",
+InsertSpecialChar	: "Speciális karakter beillesztése",
+InsertSmileyLbl		: "Hangulatjelek",
+InsertSmiley		: "Hangulatjelek beillesztése",
+About				: "FCKeditor névjegy",
+Bold				: "Félkövér",
+Italic				: "Dőlt",
+Underline			: "Aláhúzott",
+StrikeThrough		: "Áthúzott",
+Subscript			: "Alsó index",
+Superscript			: "Felső index",
+LeftJustify			: "Balra",
+CenterJustify		: "Középre",
+RightJustify		: "Jobbra",
+BlockJustify		: "Sorkizárt",
+DecreaseIndent		: "Behúzás csökkentése",
+IncreaseIndent		: "Behúzás növelése",
+Undo				: "Visszavonás",
+Redo				: "Ismétlés",
+NumberedListLbl		: "Számozás",
+NumberedList		: "Számozás beillesztése/törlése",
+BulletedListLbl		: "Felsorolás",
+BulletedList		: "Felsorolás beillesztése/törlése",
+ShowTableBorders	: "Táblázat szegély mutatása",
+ShowDetails			: "Részletek mutatása",
+Style				: "Stílus",
+FontFormat			: "Formátum",
+Font				: "Betűtípus",
+FontSize			: "Méret",
+TextColor			: "Betűszín",
+BGColor				: "Háttérszín",
+Source				: "Forráskód",
+Find				: "Keresés",
+Replace				: "Csere",
+SpellCheck			: "Helyesírás-ellenőrzés",
+UniversalKeyboard	: "Univerzális billentyűzet",
+PageBreakLbl		: "Oldaltörés",
+PageBreak			: "Oldaltörés beillesztése",
+
+Form			: "Űrlap",
+Checkbox		: "Jelölőnégyzet",
+RadioButton		: "Választógomb",
+TextField		: "Szövegmező",
+Textarea		: "Szövegterület",
+HiddenField		: "Rejtettmező",
+Button			: "Gomb",
+SelectionField	: "Legördülő lista",
+ImageButton		: "Képgomb",
+
+FitWindow		: "Maximalizálás",
+
+// Context Menu
+EditLink			: "Hivatkozás módosítása",
+CellCM				: "Cella",
+RowCM				: "Sor",
+ColumnCM			: "Oszlop",
+InsertRow			: "Sor beszúrása",
+DeleteRows			: "Sorok törlése",
+InsertColumn		: "Oszlop beszúrása",
+DeleteColumns		: "Oszlopok törlése",
+InsertCell			: "Cella beszúrása",
+DeleteCells			: "Cellák törlése",
+MergeCells			: "Cellák egyesítése",
+SplitCell			: "Cella szétválasztása",
+TableDelete			: "Táblázat törlése",
+CellProperties		: "Cella tulajdonságai",
+TableProperties		: "Táblázat tulajdonságai",
+ImageProperties		: "Kép tulajdonságai",
+FlashProperties		: "Flash tulajdonságai",
+
+AnchorProp			: "Horgony tulajdonságai",
+ButtonProp			: "Gomb tulajdonságai",
+CheckboxProp		: "Jelölőnégyzet tulajdonságai",
+HiddenFieldProp		: "Rejtett mező tulajdonságai",
+RadioButtonProp		: "Választógomb tulajdonságai",
+ImageButtonProp		: "Képgomb tulajdonságai",
+TextFieldProp		: "Szövegmező tulajdonságai",
+SelectionFieldProp	: "Legördülő lista tulajdonságai",
+TextareaProp		: "Szövegterület tulajdonságai",
+FormProp			: "Űrlap tulajdonságai",
+
+FontFormats			: "Normál;Formázott;Címsor;Fejléc 1;Fejléc 2;Fejléc 3;Fejléc 4;Fejléc 5;Fejléc 6;Bekezdés (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML feldolgozása. Kérem várjon...",
+Done				: "Kész",
+PasteWordConfirm	: "A beilleszteni kívánt szöveg Word-ből van másolva. El kívánja távolítani a formázást a beillesztés előtt?",
+NotCompatiblePaste	: "Ez a parancs csak Internet Explorer 5.5 verziótól használható. Megpróbálja beilleszteni a szöveget az eredeti formázással?",
+UnknownToolbarItem	: "Ismeretlen eszköztár elem \"%1\"",
+UnknownCommand		: "Ismeretlen parancs \"%1\"",
+NotImplemented		: "A parancs nem hajtható végre",
+UnknownToolbarSet	: "Az eszközkészlet \"%1\" nem létezik",
+NoActiveX			: "A böngésző biztonsági beállításai korlátozzák a szerkesztő lehetőségeit. Engedélyezni kell ezt az opciót: \"Run ActiveX controls and plug-ins\". Ettől függetlenül előfordulhatnak hibaüzenetek ill. bizonyos funkciók hiányozhatnak.",
+BrowseServerBlocked : "Nem lehet megnyitni a fájlböngészőt. Bizonyosodjon meg róla, hogy a felbukkanó ablakok engedélyezve vannak.",
+DialogBlocked		: "Nem lehet megnyitni a párbeszédablakot. Bizonyosodjon meg róla, hogy a felbukkanó ablakok engedélyezve vannak.",
+
+// Dialogs
+DlgBtnOK			: "Rendben",
+DlgBtnCancel		: "Mégsem",
+DlgBtnClose			: "Bezárás",
+DlgBtnBrowseServer	: "Böngészés a szerveren",
+DlgAdvancedTag		: "További opciók",
+DlgOpOther			: "Egyéb",
+DlgInfoTab			: "Alaptulajdonságok",
+DlgAlertUrl			: "Illessze be a webcímet",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nincs beállítva>",
+DlgGenId			: "Azonosító",
+DlgGenLangDir		: "Írás iránya",
+DlgGenLangDirLtr	: "Balról jobbra",
+DlgGenLangDirRtl	: "Jobbról balra",
+DlgGenLangCode		: "Nyelv kódja",
+DlgGenAccessKey		: "Billentyűkombináció",
+DlgGenName			: "Név",
+DlgGenTabIndex		: "Tabulátor index",
+DlgGenLongDescr		: "Részletes leírás webcíme",
+DlgGenClass			: "Stíluskészlet",
+DlgGenTitle			: "Súgócimke",
+DlgGenContType		: "Súgó tartalomtípusa",
+DlgGenLinkCharset	: "Hivatkozott tartalom kódlapja",
+DlgGenStyle			: "Stílus",
+
+// Image Dialog
+DlgImgTitle			: "Kép tulajdonságai",
+DlgImgInfoTab		: "Alaptulajdonságok",
+DlgImgBtnUpload		: "Küldés a szerverre",
+DlgImgURL			: "Hivatkozás",
+DlgImgUpload		: "Feltöltés",
+DlgImgAlt			: "Buborék szöveg",
+DlgImgWidth			: "Szélesség",
+DlgImgHeight		: "Magasság",
+DlgImgLockRatio		: "Arány megtartása",
+DlgBtnResetSize		: "Eredeti méret",
+DlgImgBorder		: "Keret",
+DlgImgHSpace		: "Vízsz. táv",
+DlgImgVSpace		: "Függ. táv",
+DlgImgAlign			: "Igazítás",
+DlgImgAlignLeft		: "Bal",
+DlgImgAlignAbsBottom: "Legaljára",
+DlgImgAlignAbsMiddle: "Közepére",
+DlgImgAlignBaseline	: "Alapvonalhoz",
+DlgImgAlignBottom	: "Aljára",
+DlgImgAlignMiddle	: "Középre",
+DlgImgAlignRight	: "Jobbra",
+DlgImgAlignTextTop	: "Szöveg tetejére",
+DlgImgAlignTop		: "Tetejére",
+DlgImgPreview		: "Előnézet",
+DlgImgAlertUrl		: "Töltse ki a kép webcímét",
+DlgImgLinkTab		: "Hivatkozás",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash tulajdonságai",
+DlgFlashChkPlay		: "Automata lejátszás",
+DlgFlashChkLoop		: "Folyamatosan",
+DlgFlashChkMenu		: "Flash menü engedélyezése",
+DlgFlashScale		: "Méretezés",
+DlgFlashScaleAll	: "Mindent mutat",
+DlgFlashScaleNoBorder	: "Keret nélkül",
+DlgFlashScaleFit	: "Teljes kitöltés",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Hivatkozás tulajdonságai",
+DlgLnkInfoTab		: "Alaptulajdonságok",
+DlgLnkTargetTab		: "Megjelenítés",
+
+DlgLnkType			: "Hivatkozás típusa",
+DlgLnkTypeURL		: "Webcím",
+DlgLnkTypeAnchor	: "Horgony az oldalon",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<más>",
+DlgLnkURL			: "Webcím",
+DlgLnkAnchorSel		: "Horgony választása",
+DlgLnkAnchorByName	: "Horgony név szerint",
+DlgLnkAnchorById	: "Azonosító szerint",
+DlgLnkNoAnchors		: "<Nincs horgony a dokumentumban>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail cím",
+DlgLnkEMailSubject	: "Üzenet tárgya",
+DlgLnkEMailBody		: "Üzenet",
+DlgLnkUpload		: "Feltöltés",
+DlgLnkBtnUpload		: "Küldés a szerverre",
+
+DlgLnkTarget		: "Tartalom megjelenítése",
+DlgLnkTargetFrame	: "<keretben>",
+DlgLnkTargetPopup	: "<felugró ablakban>",
+DlgLnkTargetBlank	: "Új ablakban (_blank)",
+DlgLnkTargetParent	: "Szülő ablakban (_parent)",
+DlgLnkTargetSelf	: "Azonos ablakban (_self)",
+DlgLnkTargetTop		: "Legfelső ablakban (_top)",
+DlgLnkTargetFrameName	: "Keret neve",
+DlgLnkPopWinName	: "Felugró ablak neve",
+DlgLnkPopWinFeat	: "Felugró ablak jellemzői",
+DlgLnkPopResize		: "Méretezhető",
+DlgLnkPopLocation	: "Címsor",
+DlgLnkPopMenu		: "Menü sor",
+DlgLnkPopScroll		: "Gördítősáv",
+DlgLnkPopStatus		: "Állapotsor",
+DlgLnkPopToolbar	: "Eszköztár",
+DlgLnkPopFullScrn	: "Teljes képernyő (csak IE)",
+DlgLnkPopDependent	: "Szülőhöz kapcsolt (csak Netscape)",
+DlgLnkPopWidth		: "Szélesség",
+DlgLnkPopHeight		: "Magasság",
+DlgLnkPopLeft		: "Bal pozíció",
+DlgLnkPopTop		: "Felső pozíció",
+
+DlnLnkMsgNoUrl		: "Adja meg a hivatkozás webcímét",
+DlnLnkMsgNoEMail	: "Adja meg az E-Mail címet",
+DlnLnkMsgNoAnchor	: "Válasszon egy horgonyt",
+DlnLnkMsgInvPopName	: "A felbukkanó ablak neve alfanumerikus karakterrel kezdôdjön, valamint ne tartalmazzon szóközt",
+
+// Color Dialog
+DlgColorTitle		: "Színválasztás",
+DlgColorBtnClear	: "Törlés",
+DlgColorHighlight	: "Előnézet",
+DlgColorSelected	: "Kiválasztott",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Hangulatjel beszúrása",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Speciális karakter választása",
+
+// Table Dialog
+DlgTableTitle		: "Táblázat tulajdonságai",
+DlgTableRows		: "Sorok",
+DlgTableColumns		: "Oszlopok",
+DlgTableBorder		: "Szegélyméret",
+DlgTableAlign		: "Igazítás",
+DlgTableAlignNotSet	: "<Nincs beállítva>",
+DlgTableAlignLeft	: "Balra",
+DlgTableAlignCenter	: "Középre",
+DlgTableAlignRight	: "Jobbra",
+DlgTableWidth		: "Szélesség",
+DlgTableWidthPx		: "képpont",
+DlgTableWidthPc		: "százalék",
+DlgTableHeight		: "Magasság",
+DlgTableCellSpace	: "Cella térköz",
+DlgTableCellPad		: "Cella belső margó",
+DlgTableCaption		: "Felirat",
+DlgTableSummary		: "Leírás",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cella tulajdonságai",
+DlgCellWidth		: "Szélesség",
+DlgCellWidthPx		: "képpont",
+DlgCellWidthPc		: "százalék",
+DlgCellHeight		: "Magasság",
+DlgCellWordWrap		: "Sortörés",
+DlgCellWordWrapNotSet	: "<Nincs beállítva>",
+DlgCellWordWrapYes	: "Igen",
+DlgCellWordWrapNo	: "Nem",
+DlgCellHorAlign		: "Vízsz. igazítás",
+DlgCellHorAlignNotSet	: "<Nincs beállítva>",
+DlgCellHorAlignLeft	: "Balra",
+DlgCellHorAlignCenter	: "Középre",
+DlgCellHorAlignRight: "Jobbra",
+DlgCellVerAlign		: "Függ. igazítás",
+DlgCellVerAlignNotSet	: "<Nincs beállítva>",
+DlgCellVerAlignTop	: "Tetejére",
+DlgCellVerAlignMiddle	: "Középre",
+DlgCellVerAlignBottom	: "Aljára",
+DlgCellVerAlignBaseline	: "Egyvonalba",
+DlgCellRowSpan		: "Sorok egyesítése",
+DlgCellCollSpan		: "Oszlopok egyesítése",
+DlgCellBackColor	: "Háttérszín",
+DlgCellBorderColor	: "Szegélyszín",
+DlgCellBtnSelect	: "Kiválasztás...",
+
+// Find Dialog
+DlgFindTitle		: "Keresés",
+DlgFindFindBtn		: "Keresés",
+DlgFindNotFoundMsg	: "A keresett szöveg nem található.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Csere",
+DlgReplaceFindLbl		: "Keresett szöveg:",
+DlgReplaceReplaceLbl	: "Csere erre:",
+DlgReplaceCaseChk		: "kis- és nagybetű megkülönböztetése",
+DlgReplaceReplaceBtn	: "Csere",
+DlgReplaceReplAllBtn	: "Az összes cseréje",
+DlgReplaceWordChk		: "csak ha ez a teljes szó",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a kivágás műveletet. Használja az alábbi billentyűkombinációt (Ctrl+X).",
+PasteErrorCopy	: "A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a másolás műveletet. Használja az alábbi billentyűkombinációt (Ctrl+X).",
+
+PasteAsText		: "Beillesztés formázatlan szövegként",
+PasteFromWord	: "Beillesztés Word-ből",
+
+DlgPasteMsg2	: "Másolja be az alábbi mezőbe a <STRONG>Ctrl+V</STRONG> billentyűk lenyomásával, majd nyomjon <STRONG>Rendben</STRONG>-t.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Betű formázások megszüntetése",
+DlgPasteRemoveStyles	: "Stílusok eltávolítása",
+DlgPasteCleanBox		: "Törlés",
+
+// Color Picker
+ColorAutomatic	: "Automatikus",
+ColorMoreColors	: "További színek...",
+
+// Document Properties
+DocProps		: "Dokumentum tulajdonságai",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Horgony tulajdonságai",
+DlgAnchorName		: "Horgony neve",
+DlgAnchorErrorName	: "Kérem adja meg a horgony nevét",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nincs a szótárban",
+DlgSpellChangeTo		: "Módosítás",
+DlgSpellBtnIgnore		: "Kihagyja",
+DlgSpellBtnIgnoreAll	: "Mindet kihagyja",
+DlgSpellBtnReplace		: "Csere",
+DlgSpellBtnReplaceAll	: "Összes cseréje",
+DlgSpellBtnUndo			: "Visszavonás",
+DlgSpellNoSuggestions	: "Nincs javaslat",
+DlgSpellProgress		: "Helyesírás-ellenőrzés folyamatban...",
+DlgSpellNoMispell		: "Helyesírás-ellenőrzés kész: Nem találtam hibát",
+DlgSpellNoChanges		: "Helyesírás-ellenőrzés kész: Nincs változtatott szó",
+DlgSpellOneChange		: "Helyesírás-ellenőrzés kész: Egy szó cserélve",
+DlgSpellManyChanges		: "Helyesírás-ellenőrzés kész: %1 szó cserélve",
+
+IeSpellDownload			: "A helyesírás-ellenőrző nincs telepítve. Szeretné letölteni most?",
+
+// Button Dialog
+DlgButtonText		: "Szöveg (Érték)",
+DlgButtonType		: "Típus",
+DlgButtonTypeBtn	: "Gomb",
+DlgButtonTypeSbm	: "Küldés",
+DlgButtonTypeRst	: "Alaphelyzet",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Név",
+DlgCheckboxValue	: "Érték",
+DlgCheckboxSelected	: "Kiválasztott",
+
+// Form Dialog
+DlgFormName		: "Név",
+DlgFormAction	: "Adatfeldolgozást végző hivatkozás",
+DlgFormMethod	: "Adatküldés módja",
+
+// Select Field Dialog
+DlgSelectName		: "Név",
+DlgSelectValue		: "Érték",
+DlgSelectSize		: "Méret",
+DlgSelectLines		: "sor",
+DlgSelectChkMulti	: "több sor is kiválasztható",
+DlgSelectOpAvail	: "Elérhető opciók",
+DlgSelectOpText		: "Szöveg",
+DlgSelectOpValue	: "Érték",
+DlgSelectBtnAdd		: "Hozzáad",
+DlgSelectBtnModify	: "Módosít",
+DlgSelectBtnUp		: "Fel",
+DlgSelectBtnDown	: "Le",
+DlgSelectBtnSetValue : "Legyen az alapértelmezett érték",
+DlgSelectBtnDelete	: "Töröl",
+
+// Textarea Dialog
+DlgTextareaName	: "Név",
+DlgTextareaCols	: "Karakterek száma egy sorban",
+DlgTextareaRows	: "Sorok száma",
+
+// Text Field Dialog
+DlgTextName			: "Név",
+DlgTextValue		: "Érték",
+DlgTextCharWidth	: "Megjelenített karakterek száma",
+DlgTextMaxChars		: "Maximális karakterszám",
+DlgTextType			: "Típus",
+DlgTextTypeText		: "Szöveg",
+DlgTextTypePass		: "Jelszó",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Név",
+DlgHiddenValue	: "Érték",
+
+// Bulleted List Dialog
+BulletedListProp	: "Felsorolás tulajdonságai",
+NumberedListProp	: "Számozás tulajdonságai",
+DlgLstStart			: "Start",
+DlgLstType			: "Formátum",
+DlgLstTypeCircle	: "Kör",
+DlgLstTypeDisc		: "Lemez",
+DlgLstTypeSquare	: "Négyzet",
+DlgLstTypeNumbers	: "Számok (1, 2, 3)",
+DlgLstTypeLCase		: "Kisbetűk (a, b, c)",
+DlgLstTypeUCase		: "Nagybetűk (A, B, C)",
+DlgLstTypeSRoman	: "Kis római számok (i, ii, iii)",
+DlgLstTypeLRoman	: "Nagy római számok (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Általános",
+DlgDocBackTab		: "Háttér",
+DlgDocColorsTab		: "Színek és margók",
+DlgDocMetaTab		: "Meta adatok",
+
+DlgDocPageTitle		: "Oldalcím",
+DlgDocLangDir		: "Írás iránya",
+DlgDocLangDirLTR	: "Balról jobbra",
+DlgDocLangDirRTL	: "Jobbról balra",
+DlgDocLangCode		: "Nyelv kód",
+DlgDocCharSet		: "Karakterkódolás",
+DlgDocCharSetCE		: "Közép-Európai",
+DlgDocCharSetCT		: "Kínai Tradicionális (Big5)",
+DlgDocCharSetCR		: "Cyrill",
+DlgDocCharSetGR		: "Görög",
+DlgDocCharSetJP		: "Japán",
+DlgDocCharSetKR		: "Koreai",
+DlgDocCharSetTR		: "Török",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Nyugat-Európai",
+DlgDocCharSetOther	: "Más karakterkódolás",
+
+DlgDocDocType		: "Dokumentum típus fejléc",
+DlgDocDocTypeOther	: "Más dokumentum típus fejléc",
+DlgDocIncXHTML		: "XHTML deklarációk beillesztése",
+DlgDocBgColor		: "Háttérszín",
+DlgDocBgImage		: "Háttérkép cím",
+DlgDocBgNoScroll	: "Nem gördíthető háttér",
+DlgDocCText			: "Szöveg",
+DlgDocCLink			: "Cím",
+DlgDocCVisited		: "Látogatott cím",
+DlgDocCActive		: "Aktív cím",
+DlgDocMargins		: "Oldal margók",
+DlgDocMaTop			: "Felső",
+DlgDocMaLeft		: "Bal",
+DlgDocMaRight		: "Jobb",
+DlgDocMaBottom		: "Alsó",
+DlgDocMeIndex		: "Dokumentum keresőszavak (vesszővel elválasztva)",
+DlgDocMeDescr		: "Dokumentum leírás",
+DlgDocMeAuthor		: "Szerző",
+DlgDocMeCopy		: "Szerzői jog",
+DlgDocPreview		: "Előnézet",
+
+// Templates Dialog
+Templates			: "Sablonok",
+DlgTemplatesTitle	: "Elérhető sablonok",
+DlgTemplatesSelMsg	: "Válassza ki melyik sablon nyíljon meg a szerkesztőben<br>(a jelenlegi tartalom elveszik):",
+DlgTemplatesLoading	: "Sablon lista betöltése. Kis türelmet...",
+DlgTemplatesNoTpl	: "(Nincs sablon megadva)",
+DlgTemplatesReplace	: "Kicseréli a jelenlegi tartalmat",
+
+// About Dialog
+DlgAboutAboutTab	: "Névjegy",
+DlgAboutBrowserInfoTab	: "Böngésző információ",
+DlgAboutLicenseTab	: "Licensz",
+DlgAboutVersion		: "verzió",
+DlgAboutInfo		: "További információkért látogasson el ide:"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/no.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/no.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/no.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Norwegian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Skjul verktøylinje",
+ToolbarExpand		: "Vis verktøylinje",
+
+// Toolbar Items and Context Menu
+Save				: "Lagre",
+NewPage				: "Ny Side",
+Preview				: "Forhåndsvis",
+Cut					: "Klipp ut",
+Copy				: "Kopier",
+Paste				: "Lim inn",
+PasteText			: "Lim inn som ren tekst",
+PasteWord			: "Lim inn fra Word",
+Print				: "Skriv ut",
+SelectAll			: "Velg alle",
+RemoveFormat		: "Fjern format",
+InsertLinkLbl		: "Lenke",
+InsertLink			: "Sett inn/Rediger lenke",
+RemoveLink			: "Fjern lenke",
+Anchor				: "Sett inn/Rediger anker",
+InsertImageLbl		: "Bilde",
+InsertImage			: "Sett inn/Rediger bilde",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Sett inn/Rediger Flash",
+InsertTableLbl		: "Tabell",
+InsertTable			: "Sett inn/Rediger tabell",
+InsertLineLbl		: "Linje",
+InsertLine			: "Sett inn horisontal linje",
+InsertSpecialCharLbl: "Spesielt tegn",
+InsertSpecialChar	: "Sett inn spesielt tegn",
+InsertSmileyLbl		: "Smil",
+InsertSmiley		: "Sett inn smil",
+About				: "Om FCKeditor",
+Bold				: "Fet",
+Italic				: "Kursiv",
+Underline			: "Understrek",
+StrikeThrough		: "Gjennomstrek",
+Subscript			: "Senket skrift",
+Superscript			: "Hevet skrift",
+LeftJustify			: "Venstrejuster",
+CenterJustify		: "Midtjuster",
+RightJustify		: "Høyrejuster",
+BlockJustify		: "Blokkjuster",
+DecreaseIndent		: "Senk nivå",
+IncreaseIndent		: "Øk nivå",
+Undo				: "Angre",
+Redo				: "Gjør om",
+NumberedListLbl		: "Numrert liste",
+NumberedList		: "Sett inn/Fjern numrert liste",
+BulletedListLbl		: "Uordnet liste",
+BulletedList		: "Sett inn/Fjern uordnet liste",
+ShowTableBorders	: "Vis tabellrammer",
+ShowDetails			: "Vis detaljer",
+Style				: "Stil",
+FontFormat			: "Format",
+Font				: "Skrift",
+FontSize			: "Størrelse",
+TextColor			: "Tekstfarge",
+BGColor				: "Bakgrunnsfarge",
+Source				: "Kilde",
+Find				: "Finn",
+Replace				: "Erstatt",
+SpellCheck			: "Stavekontroll",
+UniversalKeyboard	: "Universelt tastatur",
+PageBreakLbl		: "Sideskift",
+PageBreak			: "Sett inn sideskift",
+
+Form			: "Skjema",
+Checkbox		: "Sjekkboks",
+RadioButton		: "Radioknapp",
+TextField		: "Tekstfelt",
+Textarea		: "Tekstområde",
+HiddenField		: "Skjult felt",
+Button			: "Knapp",
+SelectionField	: "Dropdown meny",
+ImageButton		: "Bildeknapp",
+
+FitWindow		: "Maksimer størrelsen på redigeringsverktøyet",
+
+// Context Menu
+EditLink			: "Rediger lenke",
+CellCM				: "Celle",
+RowCM				: "Rader",
+ColumnCM			: "Kolonne",
+InsertRow			: "Sett inn rad",
+DeleteRows			: "Slett rader",
+InsertColumn		: "Sett inn kolonne",
+DeleteColumns		: "Slett kolonner",
+InsertCell			: "Sett inn celle",
+DeleteCells			: "Slett celler",
+MergeCells			: "Slå sammen celler",
+SplitCell			: "Splitt celler",
+TableDelete			: "Slett tabell",
+CellProperties		: "Celleegenskaper",
+TableProperties		: "Tabellegenskaper",
+ImageProperties		: "Bildeegenskaper",
+FlashProperties		: "Flash Egenskaper",
+
+AnchorProp			: "Ankeregenskaper",
+ButtonProp			: "Knappegenskaper",
+CheckboxProp		: "Sjekkboksegenskaper",
+HiddenFieldProp		: "Skjult felt egenskaper",
+RadioButtonProp		: "Radioknappegenskaper",
+ImageButtonProp		: "Bildeknappegenskaper",
+TextFieldProp		: "Tekstfeltegenskaper",
+SelectionFieldProp	: "Dropdown menyegenskaper",
+TextareaProp		: "Tekstfeltegenskaper",
+FormProp			: "Skjemaegenskaper",
+
+FontFormats			: "Normal;Formatert;Adresse;Tittel 1;Tittel 2;Tittel 3;Tittel 4;Tittel 5;Tittel 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Lager XHTML. Vennligst vent...",
+Done				: "Ferdig",
+PasteWordConfirm	: "Teksten du prøver å lime inn ser ut som om den kommer fra word , du bør rense den før du limer inn , vil du gjøre dette?",
+NotCompatiblePaste	: "Denne kommandoen er tilgjenglig kun for Internet Explorer version 5.5 eller bedre. Vil du fortsette uten å rense?(Du kan lime inn som ren tekst)",
+UnknownToolbarItem	: "Ukjent menyvalg \"%1\"",
+UnknownCommand		: "Ukjent kommando \"%1\"",
+NotImplemented		: "Kommando ikke ennå implimentert",
+UnknownToolbarSet	: "Verktøylinjesett \"%1\" finnes ikke",
+NoActiveX			: "Din nettleser's sikkerhetsinstillinger kan begrense noen av funksjonene i redigeringsverktøyet. Du må aktivere \"Kjør ActiveXkontroller og plugins\". Du kan oppleve feil og advarsler om manglende funksjoner",
+BrowseServerBlocked : "Kunne ikke åpne dialogboksen for filarkiv. Pass på at du har slått av popupstoppere.",
+DialogBlocked		: "Kunne ikke åpne dialogboksen. Pass på at du har slått av popupstoppere.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Avbryt",
+DlgBtnClose			: "Lukk",
+DlgBtnBrowseServer	: "Bla igjennom server",
+DlgAdvancedTag		: "Avansert",
+DlgOpOther			: "<Annet>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Vennligst skriv inn URL'en",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ikke satt>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Språkretning",
+DlgGenLangDirLtr	: "Venstre til høyre (VTH)",
+DlgGenLangDirRtl	: "Høyre til venstre (HTV)",
+DlgGenLangCode		: "Språk kode",
+DlgGenAccessKey		: "Aksessknapp",
+DlgGenName			: "Navn",
+DlgGenTabIndex		: "Tab Indeks",
+DlgGenLongDescr		: "Utvidet beskrivelse",
+DlgGenClass			: "Stilarkklasser",
+DlgGenTitle			: "Tittel",
+DlgGenContType		: "Type",
+DlgGenLinkCharset	: "Lenket språkkart",
+DlgGenStyle			: "Stil",
+
+// Image Dialog
+DlgImgTitle			: "Bildeegenskaper",
+DlgImgInfoTab		: "Bildeinformasjon",
+DlgImgBtnUpload		: "Send det til serveren",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Last opp",
+DlgImgAlt			: "Alternativ tekst",
+DlgImgWidth			: "Bredde",
+DlgImgHeight		: "Høyde",
+DlgImgLockRatio		: "Lås forhold",
+DlgBtnResetSize		: "Tilbakestill størrelse",
+DlgImgBorder		: "Ramme",
+DlgImgHSpace		: "HMarg",
+DlgImgVSpace		: "VMarg",
+DlgImgAlign			: "Juster",
+DlgImgAlignLeft		: "Venstre",
+DlgImgAlignAbsBottom: "Abs bunn",
+DlgImgAlignAbsMiddle: "Abs midten",
+DlgImgAlignBaseline	: "Bunnlinje",
+DlgImgAlignBottom	: "Bunn",
+DlgImgAlignMiddle	: "Midten",
+DlgImgAlignRight	: "Høyre",
+DlgImgAlignTextTop	: "Tekst topp",
+DlgImgAlignTop		: "Topp",
+DlgImgPreview		: "Forhåndsvis",
+DlgImgAlertUrl		: "Vennligst skriv bildeurlen",
+DlgImgLinkTab		: "Lenke",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Egenskaper",
+DlgFlashChkPlay		: "Auto Spill",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Slå på Flash meny",
+DlgFlashScale		: "Skaler",
+DlgFlashScaleAll	: "Vis alt",
+DlgFlashScaleNoBorder	: "Ingen ramme",
+DlgFlashScaleFit	: "Skaler til å passeExact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Lenke",
+DlgLnkInfoTab		: "Lenkeinfo",
+DlgLnkTargetTab		: "Mål",
+
+DlgLnkType			: "Lenketype",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Lenke til bokmerke i teksten",
+DlgLnkTypeEMail		: "E-Post",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<annet>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Velg ett anker",
+DlgLnkAnchorByName	: "Anker etter navn",
+DlgLnkAnchorById	: "Element etter ID",
+DlgLnkNoAnchors		: "<Ingen anker i dokumentet>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Post Addresse",
+DlgLnkEMailSubject	: "Meldingsemne",
+DlgLnkEMailBody		: "Melding",
+DlgLnkUpload		: "Last opp",
+DlgLnkBtnUpload		: "Send til server",
+
+DlgLnkTarget		: "Mål",
+DlgLnkTargetFrame	: "<ramme>",
+DlgLnkTargetPopup	: "<popup vindu>",
+DlgLnkTargetBlank	: "Nytt vindu (_blank)",
+DlgLnkTargetParent	: "Foreldre vindu (_parent)",
+DlgLnkTargetSelf	: "Samme vindu (_self)",
+DlgLnkTargetTop		: "Hele vindu (_top)",
+DlgLnkTargetFrameName	: "Målramme",
+DlgLnkPopWinName	: "Popup vindus navn",
+DlgLnkPopWinFeat	: "Popup vindus egenskaper",
+DlgLnkPopResize		: "Endre størrelse",
+DlgLnkPopLocation	: "Adresselinje",
+DlgLnkPopMenu		: "Menylinje",
+DlgLnkPopScroll		: "Scrollbar",
+DlgLnkPopStatus		: "Statuslinje",
+DlgLnkPopToolbar	: "Verktøylinje",
+DlgLnkPopFullScrn	: "Full skjerm (IE)",
+DlgLnkPopDependent	: "Avhenging (Netscape)",
+DlgLnkPopWidth		: "Bredde",
+DlgLnkPopHeight		: "Høyde",
+DlgLnkPopLeft		: "Venstre posisjon",
+DlgLnkPopTop		: "Topp posisjon",
+
+DlnLnkMsgNoUrl		: "Vennligst skriv inn lenkens url",
+DlnLnkMsgNoEMail	: "Vennligst skriv inn e-postadressen",
+DlnLnkMsgNoAnchor	: "Vennligst velg ett anker",
+DlnLnkMsgInvPopName	: "Popup vinduets navn må begynne med en bokstav, og kan ikke inneholde mellomrom",
+
+// Color Dialog
+DlgColorTitle		: "Velg farge",
+DlgColorBtnClear	: "Tøm",
+DlgColorHighlight	: "Marker",
+DlgColorSelected	: "Velg",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Sett inn smil",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Velg spesielt tegn",
+
+// Table Dialog
+DlgTableTitle		: "Tabellegenskaper",
+DlgTableRows		: "Rader",
+DlgTableColumns		: "Kolonner",
+DlgTableBorder		: "Rammestørrelse",
+DlgTableAlign		: "Justering",
+DlgTableAlignNotSet	: "<Ikke satt>",
+DlgTableAlignLeft	: "Venstre",
+DlgTableAlignCenter	: "Midtjuster",
+DlgTableAlignRight	: "Høyre",
+DlgTableWidth		: "Bredde",
+DlgTableWidthPx		: "pixler",
+DlgTableWidthPc		: "prosent",
+DlgTableHeight		: "Høyde",
+DlgTableCellSpace	: "Celle marg",
+DlgTableCellPad		: "Celle polstring",
+DlgTableCaption		: "Tittel",
+DlgTableSummary		: "Sammendrag",
+
+// Table Cell Dialog
+DlgCellTitle		: "Celle egenskaper",
+DlgCellWidth		: "Bredde",
+DlgCellWidthPx		: "pixeler",
+DlgCellWidthPc		: "prosent",
+DlgCellHeight		: "Høyde",
+DlgCellWordWrap		: "Tekstbrytning",
+DlgCellWordWrapNotSet	: "<Ikke satt>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nei",
+DlgCellHorAlign		: "Horisontal justering",
+DlgCellHorAlignNotSet	: "<Ikke satt>",
+DlgCellHorAlignLeft	: "Venstre",
+DlgCellHorAlignCenter	: "Midtjuster",
+DlgCellHorAlignRight: "Høyre",
+DlgCellVerAlign		: "Vertikal justering",
+DlgCellVerAlignNotSet	: "<Ikke satt>",
+DlgCellVerAlignTop	: "Topp",
+DlgCellVerAlignMiddle	: "Midten",
+DlgCellVerAlignBottom	: "Bunn",
+DlgCellVerAlignBaseline	: "Bunnlinje",
+DlgCellRowSpan		: "Radspenn",
+DlgCellCollSpan		: "Kolonnespenn",
+DlgCellBackColor	: "Bakgrunnsfarge",
+DlgCellBorderColor	: "Rammefarge",
+DlgCellBtnSelect	: "Velg...",
+
+// Find Dialog
+DlgFindTitle		: "Finn",
+DlgFindFindBtn		: "Finn",
+DlgFindNotFoundMsg	: "Den spesifiserte teksten ble ikke funnet.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Erstatt",
+DlgReplaceFindLbl		: "Finn hva:",
+DlgReplaceReplaceLbl	: "Erstatt med:",
+DlgReplaceCaseChk		: "Riktig case",
+DlgReplaceReplaceBtn	: "Erstatt",
+DlgReplaceReplAllBtn	: "Erstatt alle",
+DlgReplaceWordChk		: "Finn hele ordet",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Din nettlesers sikkerhetsinstillinger tillater ikke automatisk klipping av tekst. Vennligst brukt snareveien (Ctrl+X).",
+PasteErrorCopy	: "Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst brukt snareveien (Ctrl+C).",
+
+PasteAsText		: "Lim inn som ren tekst",
+PasteFromWord	: "Lim inn fra word",
+
+DlgPasteMsg2	: "Vennligst lim inn i den følgende boksen med tastaturet (<STRONG>Ctrl+V</STRONG>) og trykk <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Fjern skrifttyper",
+DlgPasteRemoveStyles	: "Fjern stildefinisjoner",
+DlgPasteCleanBox		: "Tøm boksen",
+
+// Color Picker
+ColorAutomatic	: "Automatisk",
+ColorMoreColors	: "Flere farger...",
+
+// Document Properties
+DocProps		: "Dokumentegenskaper",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ankeregenskaper",
+DlgAnchorName		: "Ankernavn",
+DlgAnchorErrorName	: "Vennligst skriv inn ankernavnet",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ikke i ordboken",
+DlgSpellChangeTo		: "Endre til",
+DlgSpellBtnIgnore		: "Ignorer",
+DlgSpellBtnIgnoreAll	: "Ignorer alle",
+DlgSpellBtnReplace		: "Erstatt",
+DlgSpellBtnReplaceAll	: "Erstatt alle",
+DlgSpellBtnUndo			: "Angre",
+DlgSpellNoSuggestions	: "- ingen forslag -",
+DlgSpellProgress		: "Stavekontroll pågår...",
+DlgSpellNoMispell		: "Stavekontroll fullført: ingen feilstavinger funnet",
+DlgSpellNoChanges		: "Stavekontroll fullført: ingen ord endret",
+DlgSpellOneChange		: "Stavekontroll fullført: Ett ord endret",
+DlgSpellManyChanges		: "Stavekontroll fullført: %1 ord endret",
+
+IeSpellDownload			: "Stavekontroll ikke installert, vil du laste den ned nå?",
+
+// Button Dialog
+DlgButtonText		: "Tekst",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Knapp",
+DlgButtonTypeSbm	: "Send",
+DlgButtonTypeRst	: "Nullstill",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Navn",
+DlgCheckboxValue	: "Verdi",
+DlgCheckboxSelected	: "Valgt",
+
+// Form Dialog
+DlgFormName		: "Navn",
+DlgFormAction	: "Handling",
+DlgFormMethod	: "Metode",
+
+// Select Field Dialog
+DlgSelectName		: "Navn",
+DlgSelectValue		: "Verdi",
+DlgSelectSize		: "Størrelse",
+DlgSelectLines		: "Linjer",
+DlgSelectChkMulti	: "Tillat flervalg",
+DlgSelectOpAvail	: "Tilgjenglige alternativer",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Verdi",
+DlgSelectBtnAdd		: "Legg til",
+DlgSelectBtnModify	: "Endre",
+DlgSelectBtnUp		: "Opp",
+DlgSelectBtnDown	: "Ned",
+DlgSelectBtnSetValue : "Sett som valgt",
+DlgSelectBtnDelete	: "Slett",
+
+// Textarea Dialog
+DlgTextareaName	: "Navn",
+DlgTextareaCols	: "Kolonner",
+DlgTextareaRows	: "Rader",
+
+// Text Field Dialog
+DlgTextName			: "Navn",
+DlgTextValue		: "verdi",
+DlgTextCharWidth	: "Tegnbredde",
+DlgTextMaxChars		: "Maks antall tegn",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Passord",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Navn",
+DlgHiddenValue	: "Verdi",
+
+// Bulleted List Dialog
+BulletedListProp	: "Uordnet listeegenskaper",
+NumberedListProp	: "Ordnet listeegenskaper",
+DlgLstStart			: "Start",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Sirkel",
+DlgLstTypeDisc		: "Hel sirkel",
+DlgLstTypeSquare	: "Firkant",
+DlgLstTypeNumbers	: "Numre(1, 2, 3)",
+DlgLstTypeLCase		: "Små bokstaver (a, b, c)",
+DlgLstTypeUCase		: "Store bokstaver(A, B, C)",
+DlgLstTypeSRoman	: "Små romerske tall(i, ii, iii)",
+DlgLstTypeLRoman	: "Store romerske tall(I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Generalt",
+DlgDocBackTab		: "Bakgrunn",
+DlgDocColorsTab		: "Farger og marginer",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Sidetittel",
+DlgDocLangDir		: "Språkretning",
+DlgDocLangDirLTR	: "Venstre til høyre (LTR)",
+DlgDocLangDirRTL	: "Høyre til venstre (RTL)",
+DlgDocLangCode		: "Språkkode",
+DlgDocCharSet		: "Tegnsett",
+DlgDocCharSetCE		: "Sentraleuropeisk",
+DlgDocCharSetCT		: "Tradisonell kinesisk(Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Gresk",
+DlgDocCharSetJP		: "Japansk",
+DlgDocCharSetKR		: "Koreansk",
+DlgDocCharSetTR		: "Tyrkisk",
+DlgDocCharSetUN		: "Unikode (UTF-8)",
+DlgDocCharSetWE		: "Vesteuropeisk",
+DlgDocCharSetOther	: "Annet tegnsett",
+
+DlgDocDocType		: "Dokumenttype header",
+DlgDocDocTypeOther	: "Annet dokumenttype header",
+DlgDocIncXHTML		: "Inkulder XHTML deklarasjon",
+DlgDocBgColor		: "Bakgrunnsfarge",
+DlgDocBgImage		: "Bakgrunnsbilde url",
+DlgDocBgNoScroll	: "Ikke scroll bakgrunnsbilde",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Besøkt lenke",
+DlgDocCActive		: "Aktiv lenke",
+DlgDocMargins		: "Sidemargin",
+DlgDocMaTop			: "Topp",
+DlgDocMaLeft		: "Venstre",
+DlgDocMaRight		: "Høyre",
+DlgDocMaBottom		: "Bunn",
+DlgDocMeIndex		: "Dokument nøkkelord (kommaseparert)",
+DlgDocMeDescr		: "Dokumentbeskrivelse",
+DlgDocMeAuthor		: "Forfatter",
+DlgDocMeCopy		: "Kopirett",
+DlgDocPreview		: "Forhåndsvising",
+
+// Templates Dialog
+Templates			: "Maler",
+DlgTemplatesTitle	: "Innholdsmaler",
+DlgTemplatesSelMsg	: "Velg malen du vil åpne<br>(innholdet du har skrevet blir tapt!):",
+DlgTemplatesLoading	: "Laster malliste. Vennligst vent...",
+DlgTemplatesNoTpl	: "(Ingen maler definert)",
+DlgTemplatesReplace	: "Erstatt faktisk innold",
+
+// About Dialog
+DlgAboutAboutTab	: "Om",
+DlgAboutBrowserInfoTab	: "Nettleserinfo",
+DlgAboutLicenseTab	: "Lisens",
+DlgAboutVersion		: "versjon",
+DlgAboutInfo		: "For further information go to"	//MISSING
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sk.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sk.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sk.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Slovak language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Skryť panel nástrojov",
+ToolbarExpand		: "Zobraziť panel nástrojov",
+
+// Toolbar Items and Context Menu
+Save				: "Uložit",
+NewPage				: "Nová stránka",
+Preview				: "Náhľad",
+Cut					: "Vystrihnúť",
+Copy				: "Kopírovať",
+Paste				: "Vložiť",
+PasteText			: "Vložiť ako čistý text",
+PasteWord			: "Vložiť z Wordu",
+Print				: "Tlač",
+SelectAll			: "Vybrať všetko",
+RemoveFormat		: "Odstrániť formátovanie",
+InsertLinkLbl		: "Odkaz",
+InsertLink			: "Vložiť/zmeniť odkaz",
+RemoveLink			: "Odstrániť odkaz",
+Anchor				: "Vložiť/zmeniť kotvu",
+InsertImageLbl		: "Obrázok",
+InsertImage			: "Vložiť/zmeniť obrázok",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Vložiť/zmeniť Flash",
+InsertTableLbl		: "Tabuľka",
+InsertTable			: "Vložiť/zmeniť tabuľku",
+InsertLineLbl		: "Čiara",
+InsertLine			: "Vložiť vodorovnú čiaru",
+InsertSpecialCharLbl: "Špeciálne znaky",
+InsertSpecialChar	: "Vložiť špeciálne znaky",
+InsertSmileyLbl		: "Smajlíky",
+InsertSmiley		: "Vložiť smajlíka",
+About				: "O aplikáci FCKeditor",
+Bold				: "Tučné",
+Italic				: "Kurzíva",
+Underline			: "Podčiarknuté",
+StrikeThrough		: "Prečiarknuté",
+Subscript			: "Dolný index",
+Superscript			: "Horný index",
+LeftJustify			: "Zarovnať vľavo",
+CenterJustify		: "Zarovnať na stred",
+RightJustify		: "Zarovnať vpravo",
+BlockJustify		: "Zarovnať do bloku",
+DecreaseIndent		: "Zmenšiť odsadenie",
+IncreaseIndent		: "Zväčšiť odsadenie",
+Undo				: "Späť",
+Redo				: "Znovu",
+NumberedListLbl		: "Číslovanie",
+NumberedList		: "Vložiť/odstrániť číslovaný zoznam",
+BulletedListLbl		: "Odrážky",
+BulletedList		: "Vložiť/odstraniť odrážky",
+ShowTableBorders	: "Zobraziť okraje tabuliek",
+ShowDetails			: "Zobraziť podrobnosti",
+Style				: "Štýl",
+FontFormat			: "Formát",
+Font				: "Písmo",
+FontSize			: "Veľkosť",
+TextColor			: "Farba textu",
+BGColor				: "Farba pozadia",
+Source				: "Zdroj",
+Find				: "Hľadať",
+Replace				: "Nahradiť",
+SpellCheck			: "Kontrola pravopisu",
+UniversalKeyboard	: "Univerzálna klávesnica",
+PageBreakLbl		: "Oddeľovač stránky",
+PageBreak			: "Vložiť oddeľovač stránky",
+
+Form			: "Formulár",
+Checkbox		: "Zaškrtávacie políčko",
+RadioButton		: "Prepínač",
+TextField		: "Textové pole",
+Textarea		: "Textová oblasť",
+HiddenField		: "Skryté pole",
+Button			: "Tlačíidlo",
+SelectionField	: "Rozbaľovací zoznam",
+ImageButton		: "Obrázkové tlačidlo",
+
+FitWindow		: "Maximalizovať veľkosť okna editora",
+
+// Context Menu
+EditLink			: "Zmeniť odkaz",
+CellCM				: "Bunka",
+RowCM				: "Riadok",
+ColumnCM			: "Stĺpec",
+InsertRow			: "Vložiť riadok",
+DeleteRows			: "Vymazať riadok",
+InsertColumn		: "Vložiť stĺpec",
+DeleteColumns		: "Zmazať stĺpec",
+InsertCell			: "Vložiť bunku",
+DeleteCells			: "Vymazať bunky",
+MergeCells			: "Zlúčiť bunky",
+SplitCell			: "Rozdeliť bunku",
+TableDelete			: "Vymazať tabuľku",
+CellProperties		: "Vlastnosti bunky",
+TableProperties		: "Vlastnosti tabuľky",
+ImageProperties		: "Vlastnosti obrázku",
+FlashProperties		: "Vlastnosti Flashu",
+
+AnchorProp			: "Vlastnosti kotvy",
+ButtonProp			: "Vlastnosti tlačidla",
+CheckboxProp		: "Vlastnosti zaškrtávacieho políčka",
+HiddenFieldProp		: "Vlastnosti skrytého poľa",
+RadioButtonProp		: "Vlastnosti prepínača",
+ImageButtonProp		: "Vlastnosti obrázkového tlačidla",
+TextFieldProp		: "Vlastnosti textového poľa",
+SelectionFieldProp	: "Vlastnosti rozbaľovacieho zoznamu",
+TextareaProp		: "Vlastnosti textovej oblasti",
+FormProp			: "Vlastnosti formulára",
+
+FontFormats			: "Normálny;Formátovaný;Adresa;Nadpis 1;Nadpis 2;Nadpis 3;Nadpis 4;Nadpis 5;Nadpis 6;Odsek (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Prebieha spracovanie XHTML. Čakajte prosím...",
+Done				: "Dokončené.",
+PasteWordConfirm	: "Vyzerá to tak, že vkladaný text je kopírovaný z Wordu. Chcete ho pred vložením vyčistiť?",
+NotCompatiblePaste	: "Tento príkaz je dostupný len v prehliadači Internet Explorer verzie 5.5 alebo vyššej. Chcete vložiť text bez vyčistenia?",
+UnknownToolbarItem	: "Neznáma položka panela nástrojov \"%1\"",
+UnknownCommand		: "Neznámy príkaz \"%1\"",
+NotImplemented		: "Príkaz nie je implementovaný",
+UnknownToolbarSet	: "Panel nástrojov \"%1\" neexistuje",
+NoActiveX			: "Bezpečnostné nastavenia vášho prehliadača môžu obmedzovať niektoré funkcie editora. Pre ich plnú funkčnosť musíte zapnúť voľbu \"Spúšťať ActiveX moduly a zásuvné moduly\", inak sa môžete stretnúť s chybami a nefunkčnosťou niektorých funkcií.",
+BrowseServerBlocked : "Prehliadač zdrojových prvkov nebolo možné otvoriť. Uistite sa, že máte vypnuté všetky blokovače vyskakujúcich okien.",
+DialogBlocked		: "Dialógové okno nebolo možné otvoriť. Uistite sa, že máte vypnuté všetky blokovače vyskakujúcich okien.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Zrušiť",
+DlgBtnClose			: "Zavrieť",
+DlgBtnBrowseServer	: "Prechádzať server",
+DlgAdvancedTag		: "Rozšírené",
+DlgOpOther			: "<Ďalšie>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Prosím vložte URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nenastavené>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Orientácia jazyka",
+DlgGenLangDirLtr	: "Zľava doprava (LTR)",
+DlgGenLangDirRtl	: "Sprava doľava (RTL)",
+DlgGenLangCode		: "Kód jazyka",
+DlgGenAccessKey		: "Prístupový kľúč",
+DlgGenName			: "Meno",
+DlgGenTabIndex		: "Poradie prvku",
+DlgGenLongDescr		: "Dlhý popis URL",
+DlgGenClass			: "Trieda štýlu",
+DlgGenTitle			: "Pomocný titulok",
+DlgGenContType		: "Pomocný typ obsahu",
+DlgGenLinkCharset	: "Priradená znaková sada",
+DlgGenStyle			: "Štýl",
+
+// Image Dialog
+DlgImgTitle			: "Vlastnosti obrázku",
+DlgImgInfoTab		: "Informácie o obrázku",
+DlgImgBtnUpload		: "Odoslať na server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Odoslať",
+DlgImgAlt			: "Alternatívny text",
+DlgImgWidth			: "Šírka",
+DlgImgHeight		: "Výška",
+DlgImgLockRatio		: "Zámok",
+DlgBtnResetSize		: "Pôvodná veľkosť",
+DlgImgBorder		: "Okraje",
+DlgImgHSpace		: "H-medzera",
+DlgImgVSpace		: "V-medzera",
+DlgImgAlign			: "Zarovnanie",
+DlgImgAlignLeft		: "Vľavo",
+DlgImgAlignAbsBottom: "Úplne dole",
+DlgImgAlignAbsMiddle: "Do stredu",
+DlgImgAlignBaseline	: "Na základňu",
+DlgImgAlignBottom	: "Dole",
+DlgImgAlignMiddle	: "Na stred",
+DlgImgAlignRight	: "Vpravo",
+DlgImgAlignTextTop	: "Na horný okraj textu",
+DlgImgAlignTop		: "Nahor",
+DlgImgPreview		: "Náhľad",
+DlgImgAlertUrl		: "Zadajte prosím URL obrázku",
+DlgImgLinkTab		: "Odkaz",
+
+// Flash Dialog
+DlgFlashTitle		: "Vlastnosti Flashu",
+DlgFlashChkPlay		: "Automatické prehrávanie",
+DlgFlashChkLoop		: "Opakovanie",
+DlgFlashChkMenu		: "Povoliť Flash Menu",
+DlgFlashScale		: "Mierka",
+DlgFlashScaleAll	: "Zobraziť mierku",
+DlgFlashScaleNoBorder	: "Bez okrajov",
+DlgFlashScaleFit	: "Roztiahnuť na celé",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Odkaz",
+DlgLnkInfoTab		: "Informácie o odkaze",
+DlgLnkTargetTab		: "Cieľ",
+
+DlgLnkType			: "Typ odkazu",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Kotva v tejto stránke",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<iný>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Vybrať kotvu",
+DlgLnkAnchorByName	: "Podľa mena kotvy",
+DlgLnkAnchorById	: "Podľa Id objektu",
+DlgLnkNoAnchors		: "<V stránke nie je definovaná žiadna kotva>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mailová adresa",
+DlgLnkEMailSubject	: "Predmet správy",
+DlgLnkEMailBody		: "Telo správy",
+DlgLnkUpload		: "Odoslať",
+DlgLnkBtnUpload		: "Odoslať na server",
+
+DlgLnkTarget		: "Cieľ",
+DlgLnkTargetFrame	: "<rámec>",
+DlgLnkTargetPopup	: "<vyskakovacie okno>",
+DlgLnkTargetBlank	: "Nové okno (_blank)",
+DlgLnkTargetParent	: "Rodičovské okno (_parent)",
+DlgLnkTargetSelf	: "Rovnaké okno (_self)",
+DlgLnkTargetTop		: "Hlavné okno (_top)",
+DlgLnkTargetFrameName	: "Meno rámu cieľa",
+DlgLnkPopWinName	: "Názov vyskakovacieho okna",
+DlgLnkPopWinFeat	: "Vlastnosti vyskakovacieho okna",
+DlgLnkPopResize		: "Meniteľná veľkosť",
+DlgLnkPopLocation	: "Panel umiestnenia",
+DlgLnkPopMenu		: "Panel ponuky",
+DlgLnkPopScroll		: "Posuvníky",
+DlgLnkPopStatus		: "Stavový riadok",
+DlgLnkPopToolbar	: "Panel nástrojov",
+DlgLnkPopFullScrn	: "Celá obrazovka (IE)",
+DlgLnkPopDependent	: "Závislosť (Netscape)",
+DlgLnkPopWidth		: "Šírka",
+DlgLnkPopHeight		: "Výška",
+DlgLnkPopLeft		: "Ľavý okraj",
+DlgLnkPopTop		: "Horný okraj",
+
+DlnLnkMsgNoUrl		: "Zadajte prosím URL odkazu",
+DlnLnkMsgNoEMail	: "Zadajte prosím e-mailovú adresu",
+DlnLnkMsgNoAnchor	: "Vyberte prosím kotvu",
+DlnLnkMsgInvPopName	: "Názov vyskakovacieho okna sa musá začínať písmenom a nemôže obsahovať medzery",
+
+// Color Dialog
+DlgColorTitle		: "Výber farby",
+DlgColorBtnClear	: "Vymazať",
+DlgColorHighlight	: "Zvýraznená",
+DlgColorSelected	: "Vybraná",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Vkladanie smajlíkov",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Výber špeciálneho znaku",
+
+// Table Dialog
+DlgTableTitle		: "Vlastnosti tabuľky",
+DlgTableRows		: "Riadky",
+DlgTableColumns		: "Stĺpce",
+DlgTableBorder		: "Ohraničenie",
+DlgTableAlign		: "Zarovnanie",
+DlgTableAlignNotSet	: "<nenastavené>",
+DlgTableAlignLeft	: "Vľavo",
+DlgTableAlignCenter	: "Na stred",
+DlgTableAlignRight	: "Vpravo",
+DlgTableWidth		: "Šírka",
+DlgTableWidthPx		: "pixelov",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Výška",
+DlgTableCellSpace	: "Vzdialenosť buniek",
+DlgTableCellPad		: "Odsadenie obsahu",
+DlgTableCaption		: "Popis",
+DlgTableSummary		: "Prehľad",
+
+// Table Cell Dialog
+DlgCellTitle		: "Vlastnosti bunky",
+DlgCellWidth		: "Šírka",
+DlgCellWidthPx		: "bodov",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Výška",
+DlgCellWordWrap		: "Zalamovannie",
+DlgCellWordWrapNotSet	: "<nenastavené>",
+DlgCellWordWrapYes	: "Áno",
+DlgCellWordWrapNo	: "Nie",
+DlgCellHorAlign		: "Vodorovné zarovnanie",
+DlgCellHorAlignNotSet	: "<nenastavené>",
+DlgCellHorAlignLeft	: "Vľavo",
+DlgCellHorAlignCenter	: "Na stred",
+DlgCellHorAlignRight: "Vpravo",
+DlgCellVerAlign		: "Zvislé zarovnanie",
+DlgCellVerAlignNotSet	: "<nenastavené>",
+DlgCellVerAlignTop	: "Nahor",
+DlgCellVerAlignMiddle	: "Doprostred",
+DlgCellVerAlignBottom	: "Dole",
+DlgCellVerAlignBaseline	: "Na základňu",
+DlgCellRowSpan		: "Zlúčené riadky",
+DlgCellCollSpan		: "Zlúčené stĺpce",
+DlgCellBackColor	: "Farba pozadia",
+DlgCellBorderColor	: "Farba ohraničenia",
+DlgCellBtnSelect	: "Výber...",
+
+// Find Dialog
+DlgFindTitle		: "Hľadať",
+DlgFindFindBtn		: "Hľadať",
+DlgFindNotFoundMsg	: "Hľadaný text nebol nájdený.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Nahradiť",
+DlgReplaceFindLbl		: "Čo hľadať:",
+DlgReplaceReplaceLbl	: "Čím nahradiť:",
+DlgReplaceCaseChk		: "Rozlišovať malé/veľké písmená",
+DlgReplaceReplaceBtn	: "Nahradiť",
+DlgReplaceReplAllBtn	: "Nahradiť všetko",
+DlgReplaceWordChk		: "Len celé slová",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Bezpečnostné nastavenie Vášho prehliadača nedovoľujú editoru spustiť funkciu pre vystrihnutie zvoleného textu do schránky. Prosím vystrihnite zvolený text do schránky pomocou klávesnice (Ctrl+X).",
+PasteErrorCopy	: "Bezpečnostné nastavenie Vášho prehliadača nedovoľujú editoru spustiť funkciu pre kopírovanie zvoleného textu do schránky. Prosím skopírujte zvolený text do schránky pomocou klávesnice (Ctrl+C).",
+
+PasteAsText		: "Vložiť ako čistý text",
+PasteFromWord	: "Vložiť text z Wordu",
+
+DlgPasteMsg2	: "Prosím vložte nasledovný rámček použitím klávesnice (<STRONG>Ctrl+V</STRONG>) a stlačte <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorovať nastavenia typu písma",
+DlgPasteRemoveStyles	: "Odstrániť formátovanie",
+DlgPasteCleanBox		: "Vyčistiť schránku",
+
+// Color Picker
+ColorAutomatic	: "Automaticky",
+ColorMoreColors	: "Viac farieb...",
+
+// Document Properties
+DocProps		: "Vlastnosti dokumentu",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Vlastnosti kotvy",
+DlgAnchorName		: "Meno kotvy",
+DlgAnchorErrorName	: "Zadajte prosím meno kotvy",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nie je v slovníku",
+DlgSpellChangeTo		: "Zmeniť na",
+DlgSpellBtnIgnore		: "Ignorovať",
+DlgSpellBtnIgnoreAll	: "Ignorovať všetko",
+DlgSpellBtnReplace		: "Prepísat",
+DlgSpellBtnReplaceAll	: "Prepísat všetko",
+DlgSpellBtnUndo			: "Späť",
+DlgSpellNoSuggestions	: "- Žiadny návrh -",
+DlgSpellProgress		: "Prebieha kontrola pravopisu...",
+DlgSpellNoMispell		: "Kontrola pravopisu dokončená: bez chýb",
+DlgSpellNoChanges		: "Kontrola pravopisu dokončená: žiadne slová nezmenené",
+DlgSpellOneChange		: "Kontrola pravopisu dokončená: zmenené jedno slovo",
+DlgSpellManyChanges		: "Kontrola pravopisu dokončená: zmenených %1 slov",
+
+IeSpellDownload			: "Kontrola pravopisu nie je naištalovaná. Chcete ju hneď stiahnuť?",
+
+// Button Dialog
+DlgButtonText		: "Text",
+DlgButtonType		: "Typ",
+DlgButtonTypeBtn	: "Tlačidlo",
+DlgButtonTypeSbm	: "Odoslať",
+DlgButtonTypeRst	: "Vymazať",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Názov",
+DlgCheckboxValue	: "Hodnota",
+DlgCheckboxSelected	: "Vybrané",
+
+// Form Dialog
+DlgFormName		: "Názov",
+DlgFormAction	: "Akcie",
+DlgFormMethod	: "Metóda",
+
+// Select Field Dialog
+DlgSelectName		: "Názov",
+DlgSelectValue		: "Hodnota",
+DlgSelectSize		: "Veľkosť",
+DlgSelectLines		: "riadkov",
+DlgSelectChkMulti	: "Povoliť viacnásobný výber",
+DlgSelectOpAvail	: "Dostupné možnosti",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Hodnota",
+DlgSelectBtnAdd		: "Pridať",
+DlgSelectBtnModify	: "Zmeniť",
+DlgSelectBtnUp		: "Hore",
+DlgSelectBtnDown	: "Dole",
+DlgSelectBtnSetValue : "Nastaviť ako vybranú hodnotu",
+DlgSelectBtnDelete	: "Zmazať",
+
+// Textarea Dialog
+DlgTextareaName	: "Názov",
+DlgTextareaCols	: "Stĺpce",
+DlgTextareaRows	: "Riadky",
+
+// Text Field Dialog
+DlgTextName			: "Názov",
+DlgTextValue		: "Hodnota",
+DlgTextCharWidth	: "Šírka pola (znakov)",
+DlgTextMaxChars		: "Maximálny počet znakov",
+DlgTextType			: "Typ",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Heslo",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Názov",
+DlgHiddenValue	: "Hodnota",
+
+// Bulleted List Dialog
+BulletedListProp	: "Vlastnosti odrážok",
+NumberedListProp	: "Vlastnosti číslovania",
+DlgLstStart			: "Štart",
+DlgLstType			: "Typ",
+DlgLstTypeCircle	: "Krúžok",
+DlgLstTypeDisc		: "Disk",
+DlgLstTypeSquare	: "Štvorec",
+DlgLstTypeNumbers	: "Číslovanie (1, 2, 3)",
+DlgLstTypeLCase		: "Malé písmená (a, b, c)",
+DlgLstTypeUCase		: "Veľké písmená (A, B, C)",
+DlgLstTypeSRoman	: "Malé rímske číslice (i, ii, iii)",
+DlgLstTypeLRoman	: "Veľké rímske číslice (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Všeobecné",
+DlgDocBackTab		: "Pozadie",
+DlgDocColorsTab		: "Farby a okraje",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Titulok",
+DlgDocLangDir		: "Orientácie jazyka",
+DlgDocLangDirLTR	: "Zľava doprava (LTR)",
+DlgDocLangDirRTL	: "Sprava doľava (RTL)",
+DlgDocLangCode		: "Kód jazyka",
+DlgDocCharSet		: "Kódová stránka",
+DlgDocCharSetCE		: "Stredoeurópske",
+DlgDocCharSetCT		: "Čínština tradičná (Big5)",
+DlgDocCharSetCR		: "Cyrillika",
+DlgDocCharSetGR		: "Gréčtina",
+DlgDocCharSetJP		: "Japončina",
+DlgDocCharSetKR		: "Korejčina",
+DlgDocCharSetTR		: "Turečtina",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Západná európa",
+DlgDocCharSetOther	: "Iná kódová stránka",
+
+DlgDocDocType		: "Typ záhlavia dokumentu",
+DlgDocDocTypeOther	: "Iný typ záhlavia dokumentu",
+DlgDocIncXHTML		: "Obsahuje deklarácie XHTML",
+DlgDocBgColor		: "Farba pozadia",
+DlgDocBgImage		: "URL adresa obrázku na pozadí",
+DlgDocBgNoScroll	: "Fixné pozadie",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Odkaz",
+DlgDocCVisited		: "Navštívený odkaz",
+DlgDocCActive		: "Aktívny odkaz",
+DlgDocMargins		: "Okraje stránky",
+DlgDocMaTop			: "Horný",
+DlgDocMaLeft		: "Ľavý",
+DlgDocMaRight		: "Pravý",
+DlgDocMaBottom		: "Dolný",
+DlgDocMeIndex		: "Kľúčové slová pre indexovanie (oddelené čiarkou)",
+DlgDocMeDescr		: "Popis stránky",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Autorské práva",
+DlgDocPreview		: "Náhľad",
+
+// Templates Dialog
+Templates			: "Šablóny",
+DlgTemplatesTitle	: "Šablóny obsahu",
+DlgTemplatesSelMsg	: "Prosím vyberte šablóny na otvorenie v editore<br>(súšasný obsah bude stratený):",
+DlgTemplatesLoading	: "Nahrávam zoznam šablón. Čakajte prosím...",
+DlgTemplatesNoTpl	: "(žiadne šablóny nenájdené)",
+DlgTemplatesReplace	: "Nahradiť aktuálny obsah",
+
+// About Dialog
+DlgAboutAboutTab	: "O aplikáci",
+DlgAboutBrowserInfoTab	: "Informácie o prehliadači",
+DlgAboutLicenseTab	: "Licencia",
+DlgAboutVersion		: "verzia",
+DlgAboutInfo		: "Viac informácií získate na"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/vi.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/vi.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/vi.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Vietnamese language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Thu gọn Thanh công cụ",
+ToolbarExpand		: "Mở rộng Thanh công cụ",
+
+// Toolbar Items and Context Menu
+Save				: "Lưu",
+NewPage				: "Trang mới",
+Preview				: "Xem trước",
+Cut					: "Cắt",
+Copy				: "Sao chép",
+Paste				: "Dán",
+PasteText			: "Dán theo dạng văn bản thuần",
+PasteWord			: "Dán với định dạng Word",
+Print				: "In",
+SelectAll			: "Chọn Tất cả",
+RemoveFormat		: "Xoá Định dạng",
+InsertLinkLbl		: "Liên kết",
+InsertLink			: "Chèn/Sửa Liên kết",
+RemoveLink			: "Xoá Liên kết",
+Anchor				: "Chèn/Sửa Neo",
+InsertImageLbl		: "Hình ảnh",
+InsertImage			: "Chèn/Sửa Hình ảnh",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Chèn/Sửa Flash",
+InsertTableLbl		: "Bảng",
+InsertTable			: "Chèn/Sửa Bảng",
+InsertLineLbl		: "Đường phân cách ngang",
+InsertLine			: "Chèn Đường phân cách ngang",
+InsertSpecialCharLbl: "Ký tự đặc biệt",
+InsertSpecialChar	: "Chèn Ký tự đặc biệt",
+InsertSmileyLbl		: "Hình biểu lộ cảm xúc (mặt cười)",
+InsertSmiley		: "Chèn Hình biểu lộ cảm xúc (mặt cười)",
+About				: "Giới thiệu về FCKeditor",
+Bold				: "Đậm",
+Italic				: "Nghiêng",
+Underline			: "Gạch chân",
+StrikeThrough		: "Gạch xuyên ngang",
+Subscript			: "Chỉ số dưới",
+Superscript			: "Chỉ số trên",
+LeftJustify			: "Canh trái",
+CenterJustify		: "Canh giữa",
+RightJustify		: "Canh phải",
+BlockJustify		: "Canh đều",
+DecreaseIndent		: "Dịch ra ngoài",
+IncreaseIndent		: "Dịch vào trong",
+Undo				: "Khôi phục thao tác",
+Redo				: "Làm lại thao tác",
+NumberedListLbl		: "Danh sách có thứ tự",
+NumberedList		: "Chèn/Xoá Danh sách có thứ tự",
+BulletedListLbl		: "Danh sách không thứ tự",
+BulletedList		: "Chèn/Xoá Danh sách không thứ tự",
+ShowTableBorders	: "Hiển thị Đường viền bảng",
+ShowDetails			: "Hiển thị Chi tiết",
+Style				: "Mẫu",
+FontFormat			: "Định dạng",
+Font				: "Phông",
+FontSize			: "Cỡ chữ",
+TextColor			: "Màu chữ",
+BGColor				: "Màu nền",
+Source				: "Mã HTML",
+Find				: "Tìm kiếm",
+Replace				: "Thay thế",
+SpellCheck			: "Kiểm tra Chính tả",
+UniversalKeyboard	: "Bàn phím Quốc tế",
+PageBreakLbl		: "Ngắt trang",
+PageBreak			: "Chèn Ngắt trang",
+
+Form			: "Biểu mẫu",
+Checkbox		: "Nút kiểm",
+RadioButton		: "Nút chọn",
+TextField		: "Trường văn bản",
+Textarea		: "Vùng văn bản",
+HiddenField		: "Trường ẩn",
+Button			: "Nút",
+SelectionField	: "Ô chọn",
+ImageButton		: "Nút hình ảnh",
+
+FitWindow		: "Mở rộng tối đa kích thước trình biên tập",
+
+// Context Menu
+EditLink			: "Sửa Liên kết",
+CellCM				: "Ô",
+RowCM				: "Hàng",
+ColumnCM			: "Cột",
+InsertRow			: "Chèn Hàng",
+DeleteRows			: "Xoá Hàng",
+InsertColumn		: "Chèn Cột",
+DeleteColumns		: "Xoá Cột",
+InsertCell			: "Chèn Ô",
+DeleteCells			: "Xoá Ô",
+MergeCells			: "Trộn Ô",
+SplitCell			: "Chia Ô",
+TableDelete			: "Xóa Bảng",
+CellProperties		: "Thuộc tính Ô",
+TableProperties		: "Thuộc tính Bảng",
+ImageProperties		: "Thuộc tính Hình ảnh",
+FlashProperties		: "Thuộc tính Flash",
+
+AnchorProp			: "Thuộc tính Neo",
+ButtonProp			: "Thuộc tính Nút",
+CheckboxProp		: "Thuộc tính Nút kiểm",
+HiddenFieldProp		: "Thuộc tính Trường ẩn",
+RadioButtonProp		: "Thuộc tính Nút chọn",
+ImageButtonProp		: "Thuộc tính Nút hình ảnh",
+TextFieldProp		: "Thuộc tính Trường văn bản",
+SelectionFieldProp	: "Thuộc tính Ô chọn",
+TextareaProp		: "Thuộc tính Vùng văn bản",
+FormProp			: "Thuộc tính Biểu mẫu",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Đang xử lý XHTML. Vui lòng đợi trong giây lát...",
+Done				: "Đã hoàn thành",
+PasteWordConfirm	: "Văn bản bạn muốn dán có kèm định dạng của Word. Bạn có muốn loại bỏ định dạng Word trước khi dán?",
+NotCompatiblePaste	: "Lệnh này chỉ được hỗ trợ từ trình duyệt Internet Explorer phiên bản 5.5 hoặc mới hơn. Bạn có muốn dán nguyên mẫu?",
+UnknownToolbarItem	: "Không rõ mục trên thanh công cụ \"%1\"",
+UnknownCommand		: "Không rõ lệnh \"%1\"",
+NotImplemented		: "Lệnh không được thực hiện",
+UnknownToolbarSet	: "Thanh công cụ \"%1\" không tồn tại",
+NoActiveX			: "Các thiết lập bảo mật của trình duyệt có thể giới hạn một số chức năng của trình biên tập. Bạn phải bật tùy chọn \"Run ActiveX controls and plug-ins\". Bạn có thể gặp một số lỗi và thấy thiếu đi một số chức năng.",
+BrowseServerBlocked : "Không thể mở được bộ duyệt tài nguyên. Hãy đảm bảo chức năng chặn popup đã bị vô hiệu hóa.",
+DialogBlocked		: "Không thể mở được cửa sổ hộp thoại. Hãy đảm bảo chức năng chặn popup đã bị vô hiệu hóa.",
+
+// Dialogs
+DlgBtnOK			: "Đồng ý",
+DlgBtnCancel		: "Bỏ qua",
+DlgBtnClose			: "Đóng",
+DlgBtnBrowseServer	: "Duyệt trên máy chủ",
+DlgAdvancedTag		: "Mở rộng",
+DlgOpOther			: "<Khác>",
+DlgInfoTab			: "Thông tin",
+DlgAlertUrl			: "Hãy nhập vào một URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<không thiết lập>",
+DlgGenId			: "Định danh",
+DlgGenLangDir		: "Đường dẫn Ngôn ngữ",
+DlgGenLangDirLtr	: "Trái sang Phải (LTR)",
+DlgGenLangDirRtl	: "Phải sang Trái (RTL)",
+DlgGenLangCode		: "Mã Ngôn ngữ",
+DlgGenAccessKey		: "Phím Hỗ trợ truy cập",
+DlgGenName			: "Tên",
+DlgGenTabIndex		: "Chỉ số của Tab",
+DlgGenLongDescr		: "Mô tả URL",
+DlgGenClass			: "Lớp Stylesheet",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Bảng mã của tài nguyên được liên kết đến",
+DlgGenStyle			: "Mẫu",
+
+// Image Dialog
+DlgImgTitle			: "Thuộc tính Hình ảnh",
+DlgImgInfoTab		: "Thông tin Hình ảnh",
+DlgImgBtnUpload		: "Tải lên Máy chủ",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Tải lên",
+DlgImgAlt			: "Chú thích Hình ảnh",
+DlgImgWidth			: "Rộng",
+DlgImgHeight		: "Cao",
+DlgImgLockRatio		: "Giữ tỷ lệ",
+DlgBtnResetSize		: "Kích thước gốc",
+DlgImgBorder		: "Đường viền",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Vị trí",
+DlgImgAlignLeft		: "Trái",
+DlgImgAlignAbsBottom: "Dưới tuyệt đối",
+DlgImgAlignAbsMiddle: "Giữa tuyệt đối",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Dưới",
+DlgImgAlignMiddle	: "Giữa",
+DlgImgAlignRight	: "Phải",
+DlgImgAlignTextTop	: "Phía trên chữ",
+DlgImgAlignTop		: "Trên",
+DlgImgPreview		: "Xem trước",
+DlgImgAlertUrl		: "Hãy đưa vào URL của hình ảnh",
+DlgImgLinkTab		: "Liên kết",
+
+// Flash Dialog
+DlgFlashTitle		: "Thuộc tính Flash",
+DlgFlashChkPlay		: "Tự động chạy",
+DlgFlashChkLoop		: "Lặp",
+DlgFlashChkMenu		: "Cho phép bật Menu của Flash",
+DlgFlashScale		: "Tỷ lệ",
+DlgFlashScaleAll	: "Hiển thị tất cả",
+DlgFlashScaleNoBorder	: "Không đường viền",
+DlgFlashScaleFit	: "Vừa vặn",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Liên kết",
+DlgLnkInfoTab		: "Thông tin Liên kết",
+DlgLnkTargetTab		: "Đích",
+
+DlgLnkType			: "Kiểu Liên kết",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Neo trong trang này",
+DlgLnkTypeEMail		: "Thư điện tử",
+DlgLnkProto			: "Giao thức",
+DlgLnkProtoOther	: "<khác>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Chọn một Neo",
+DlgLnkAnchorByName	: "Theo Tên Neo",
+DlgLnkAnchorById	: "Theo Định danh Element",
+DlgLnkNoAnchors		: "<Không có Neo nào trong tài liệu>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Thư điện tử",
+DlgLnkEMailSubject	: "Tiêu đề Thông điệp",
+DlgLnkEMailBody		: "Nội dung Thông điệp",
+DlgLnkUpload		: "Tải lên",
+DlgLnkBtnUpload		: "Tải lên Máy chủ",
+
+DlgLnkTarget		: "Đích",
+DlgLnkTargetFrame	: "<khung>",
+DlgLnkTargetPopup	: "<cửa sổ popup>",
+DlgLnkTargetBlank	: "Cửa sổ mới (_blank)",
+DlgLnkTargetParent	: "Cửa sổ cha (_parent)",
+DlgLnkTargetSelf	: "Cùng cửa sổ (_self)",
+DlgLnkTargetTop		: "Cửa sổ trên cùng(_top)",
+DlgLnkTargetFrameName	: "Tên Khung đích",
+DlgLnkPopWinName	: "Tên Cửa sổ Popup",
+DlgLnkPopWinFeat	: "Đặc điểm của Cửa sổ Popup",
+DlgLnkPopResize		: "Kích thước thay đổi",
+DlgLnkPopLocation	: "Thanh vị trí",
+DlgLnkPopMenu		: "Thanh Menu",
+DlgLnkPopScroll		: "Thanh cuộn",
+DlgLnkPopStatus		: "Thanh trạng thái",
+DlgLnkPopToolbar	: "Thanh công cụ",
+DlgLnkPopFullScrn	: "Toàn màn hình (IE)",
+DlgLnkPopDependent	: "Phụ thuộc (Netscape)",
+DlgLnkPopWidth		: "Rộng",
+DlgLnkPopHeight		: "Cao",
+DlgLnkPopLeft		: "Vị trí Trái",
+DlgLnkPopTop		: "Vị trí Trên",
+
+DlnLnkMsgNoUrl		: "Hãy đưa vào Liên kết URL",
+DlnLnkMsgNoEMail	: "Hãy đưa vào địa chỉ thư điện tử",
+DlnLnkMsgNoAnchor	: "Hãy chọn một Neo",
+DlnLnkMsgInvPopName	: "Tên của cửa sổ Popup phải bắt đầu bằng một ký tự và không được chứa khoảng trắng",
+
+// Color Dialog
+DlgColorTitle		: "Chọn màu",
+DlgColorBtnClear	: "Xoá",
+DlgColorHighlight	: "Tô sáng",
+DlgColorSelected	: "Đã chọn",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Chèn Hình biểu lộ cảm xúc (mặt cười)",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Hãy chọn Ký tự đặc biệt",
+
+// Table Dialog
+DlgTableTitle		: "Thuộc tính bảng",
+DlgTableRows		: "Hàng",
+DlgTableColumns		: "Cột",
+DlgTableBorder		: "Cỡ Đường viền",
+DlgTableAlign		: "Canh lề",
+DlgTableAlignNotSet	: "<Chưa thiết lập>",
+DlgTableAlignLeft	: "Trái",
+DlgTableAlignCenter	: "Giữa",
+DlgTableAlignRight	: "Phải",
+DlgTableWidth		: "Rộng",
+DlgTableWidthPx		: "điểm (px)",
+DlgTableWidthPc		: "%",
+DlgTableHeight		: "Cao",
+DlgTableCellSpace	: "Khoảng cách Ô",
+DlgTableCellPad		: "Đệm Ô",
+DlgTableCaption		: "Đầu đề",
+DlgTableSummary		: "Tóm lược",
+
+// Table Cell Dialog
+DlgCellTitle		: "Thuộc tính Ô",
+DlgCellWidth		: "Rộng",
+DlgCellWidthPx		: "điểm (px)",
+DlgCellWidthPc		: "%",
+DlgCellHeight		: "Cao",
+DlgCellWordWrap		: "Bọc từ",
+DlgCellWordWrapNotSet	: "<Chưa thiết lập>",
+DlgCellWordWrapYes	: "Đồng ý",
+DlgCellWordWrapNo	: "Không",
+DlgCellHorAlign		: "Canh theo Chiều ngang",
+DlgCellHorAlignNotSet	: "<Chưa thiết lập>",
+DlgCellHorAlignLeft	: "Trái",
+DlgCellHorAlignCenter	: "Giữa",
+DlgCellHorAlignRight: "Phải",
+DlgCellVerAlign		: "Canh theo Chiều dọc",
+DlgCellVerAlignNotSet	: "<Chưa thiết lập>",
+DlgCellVerAlignTop	: "Trên",
+DlgCellVerAlignMiddle	: "Giữa",
+DlgCellVerAlignBottom	: "Dưới",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Nối Hàng",
+DlgCellCollSpan		: "Nối Cột",
+DlgCellBackColor	: "Màu nền",
+DlgCellBorderColor	: "Màu viền",
+DlgCellBtnSelect	: "Chọn...",
+
+// Find Dialog
+DlgFindTitle		: "Tìm kiếm",
+DlgFindFindBtn		: "Tìm kiếm",
+DlgFindNotFoundMsg	: "Không tìm thấy chuỗi cần tìm.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Thay thế",
+DlgReplaceFindLbl		: "Tìm chuỗi:",
+DlgReplaceReplaceLbl	: "Thay bằng:",
+DlgReplaceCaseChk		: "Phân biệt chữ hoa/thường",
+DlgReplaceReplaceBtn	: "Thay thế",
+DlgReplaceReplAllBtn	: "Thay thế Tất cả",
+DlgReplaceWordChk		: "Đúng toàn bộ từ",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh cắt. Hãy sử dụng bàn phím cho lệnh này (Ctrl+X).",
+PasteErrorCopy	: "Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh sao chép. Hãy sử dụng bàn phím cho lệnh này (Ctrl+C).",
+
+PasteAsText		: "Dán theo định dạng văn bản thuần",
+PasteFromWord	: "Dán với định dạng Word",
+
+DlgPasteMsg2	: "Hãy dán nội dung vào trong khung bên dưới, sử dụng tổ hợp phím (<STRONG>Ctrl+V</STRONG>) và nhấn vào nút <STRONG>Đồng ý</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Chấp nhận các định dạng phông",
+DlgPasteRemoveStyles	: "Gỡ bỏ các định dạng Styles",
+DlgPasteCleanBox		: "Xóa nội dung",
+
+// Color Picker
+ColorAutomatic	: "Tự động",
+ColorMoreColors	: "Màu khác...",
+
+// Document Properties
+DocProps		: "Thuộc tính Tài liệu",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Thuộc tính Neo",
+DlgAnchorName		: "Tên của Neo",
+DlgAnchorErrorName	: "Hãy đưa vào tên của Neo",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Không có trong từ điển",
+DlgSpellChangeTo		: "Chuyển thành",
+DlgSpellBtnIgnore		: "Bỏ qua",
+DlgSpellBtnIgnoreAll	: "Bỏ qua Tất cả",
+DlgSpellBtnReplace		: "Thay thế",
+DlgSpellBtnReplaceAll	: "Thay thế Tất cả",
+DlgSpellBtnUndo			: "Phục hồi lại",
+DlgSpellNoSuggestions	: "- Không đưa ra gợi ý về từ -",
+DlgSpellProgress		: "Đang tiến hành kiểm tra chính tả...",
+DlgSpellNoMispell		: "Hoàn tất kiểm tra chính tả: Không có lỗi chính tả",
+DlgSpellNoChanges		: "Hoàn tất kiểm tra chính tả: Không có từ nào được thay đổi",
+DlgSpellOneChange		: "Hoàn tất kiểm tra chính tả: Một từ đã được thay đổi",
+DlgSpellManyChanges		: "Hoàn tất kiểm tra chính tả: %1 từ đã được thay đổi",
+
+IeSpellDownload			: "Chức năng kiểm tra chính tả chưa được cài đặt. Bạn có muốn tải về ngay bây giờ?",
+
+// Button Dialog
+DlgButtonText		: "Chuỗi hiển thị (Giá trị)",
+DlgButtonType		: "Kiểu",
+DlgButtonTypeBtn	: "Nút Bấm",
+DlgButtonTypeSbm	: "Nút Gửi",
+DlgButtonTypeRst	: "Nút Nhập lại",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Tên",
+DlgCheckboxValue	: "Giá trị",
+DlgCheckboxSelected	: "Được chọn",
+
+// Form Dialog
+DlgFormName		: "Tên",
+DlgFormAction	: "Hành động",
+DlgFormMethod	: "Phương thức",
+
+// Select Field Dialog
+DlgSelectName		: "Tên",
+DlgSelectValue		: "Giá trị",
+DlgSelectSize		: "Kích cỡ",
+DlgSelectLines		: "dòng",
+DlgSelectChkMulti	: "Cho phép chọn nhiều",
+DlgSelectOpAvail	: "Các tùy chọn có thể sử dụng",
+DlgSelectOpText		: "Văn bản",
+DlgSelectOpValue	: "Giá trị",
+DlgSelectBtnAdd		: "Thêm",
+DlgSelectBtnModify	: "Thay đổi",
+DlgSelectBtnUp		: "Lên",
+DlgSelectBtnDown	: "Xuống",
+DlgSelectBtnSetValue : "Giá trị được chọn",
+DlgSelectBtnDelete	: "Xoá",
+
+// Textarea Dialog
+DlgTextareaName	: "Tên",
+DlgTextareaCols	: "Cột",
+DlgTextareaRows	: "Hàng",
+
+// Text Field Dialog
+DlgTextName			: "Tên",
+DlgTextValue		: "Giá trị",
+DlgTextCharWidth	: "Rộng",
+DlgTextMaxChars		: "Số Ký tự tối đa",
+DlgTextType			: "Kiểu",
+DlgTextTypeText		: "Ký tự",
+DlgTextTypePass		: "Mật khẩu",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Tên",
+DlgHiddenValue	: "Giá trị",
+
+// Bulleted List Dialog
+BulletedListProp	: "Thuộc tính Danh sách không thứ tự",
+NumberedListProp	: "Thuộc tính Danh sách có thứ tự",
+DlgLstStart			: "Bắt đầu",
+DlgLstType			: "Kiểu",
+DlgLstTypeCircle	: "Hình tròn",
+DlgLstTypeDisc		: "Hình đĩa",
+DlgLstTypeSquare	: "Hình vuông",
+DlgLstTypeNumbers	: "Số thứ tự (1, 2, 3)",
+DlgLstTypeLCase		: "Chữ cái thường (a, b, c)",
+DlgLstTypeUCase		: "Chữ cái hoa (A, B, C)",
+DlgLstTypeSRoman	: "Số La Mã thường (i, ii, iii)",
+DlgLstTypeLRoman	: "Số La Mã hoa (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Toàn thể",
+DlgDocBackTab		: "Nền",
+DlgDocColorsTab		: "Màu sắc và Đường biên",
+DlgDocMetaTab		: "Siêu dữ liệu",
+
+DlgDocPageTitle		: "Tiêu đề Trang",
+DlgDocLangDir		: "Đường dẫn Ngôn ngữ",
+DlgDocLangDirLTR	: "Trái sang Phải (LTR)",
+DlgDocLangDirRTL	: "Phải sang Trái (RTL)",
+DlgDocLangCode		: "Mã Ngôn ngữ",
+DlgDocCharSet		: "Bảng mã ký tự",
+DlgDocCharSetCE		: "Trung Âu",
+DlgDocCharSetCT		: "Tiếng Trung Quốc (Big5)",
+DlgDocCharSetCR		: "Tiếng Kirin",
+DlgDocCharSetGR		: "Tiếng Hy Lạp",
+DlgDocCharSetJP		: "Tiếng Nhật",
+DlgDocCharSetKR		: "Tiếng Hàn",
+DlgDocCharSetTR		: "Tiếng Thổ Nhĩ Kỳ",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Tây Âu",
+DlgDocCharSetOther	: "Bảng mã ký tự khác",
+
+DlgDocDocType		: "Kiểu Đề mục Tài liệu",
+DlgDocDocTypeOther	: "Kiểu Đề mục Tài liệu khác",
+DlgDocIncXHTML		: "Bao gồm cả định nghĩa XHTML",
+DlgDocBgColor		: "Màu nền",
+DlgDocBgImage		: "URL của Hình ảnh nền",
+DlgDocBgNoScroll	: "Không cuộn nền",
+DlgDocCText			: "Văn bản",
+DlgDocCLink			: "Liên kết",
+DlgDocCVisited		: "Liên kết Đã ghé thăm",
+DlgDocCActive		: "Liên kết Hiện hành",
+DlgDocMargins		: "Đường biên của Trang",
+DlgDocMaTop			: "Trên",
+DlgDocMaLeft		: "Trái",
+DlgDocMaRight		: "Phải",
+DlgDocMaBottom		: "Dưới",
+DlgDocMeIndex		: "Các từ khóa chỉ mục tài liệu (phân cách bởi dấu phẩy)",
+DlgDocMeDescr		: "Mô tả tài liệu",
+DlgDocMeAuthor		: "Tác giả",
+DlgDocMeCopy		: "Bản quyền",
+DlgDocPreview		: "Xem trước",
+
+// Templates Dialog
+Templates			: "Mẫu dựng sẵn",
+DlgTemplatesTitle	: "Nội dung Mẫu dựng sẵn",
+DlgTemplatesSelMsg	: "Hãy chọn Mẫu dựng sẵn để mở trong trình biên tập<br>(nội dung hiện tại sẽ bị mất):",
+DlgTemplatesLoading	: "Đang nạp Danh sách Mẫu dựng sẵn. Vui lòng đợi trong giây lát...",
+DlgTemplatesNoTpl	: "(Không có Mẫu dựng sẵn nào được định nghĩa)",
+DlgTemplatesReplace	: "Thay thế nội dung hiện tại",
+
+// About Dialog
+DlgAboutAboutTab	: "Giới thiệu",
+DlgAboutBrowserInfoTab	: "Thông tin trình duyệt",
+DlgAboutLicenseTab	: "Giấy phép",
+DlgAboutVersion		: "phiên bản",
+DlgAboutInfo		: "Để biết thêm thông tin, hãy truy cập"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-uk.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-uk.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-uk.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * English (United Kingdom) language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Collapse Toolbar",
+ToolbarExpand		: "Expand Toolbar",
+
+// Toolbar Items and Context Menu
+Save				: "Save",
+NewPage				: "New Page",
+Preview				: "Preview",
+Cut					: "Cut",
+Copy				: "Copy",
+Paste				: "Paste",
+PasteText			: "Paste as plain text",
+PasteWord			: "Paste from Word",
+Print				: "Print",
+SelectAll			: "Select All",
+RemoveFormat		: "Remove Format",
+InsertLinkLbl		: "Link",
+InsertLink			: "Insert/Edit Link",
+RemoveLink			: "Remove Link",
+Anchor				: "Insert/Edit Anchor",
+InsertImageLbl		: "Image",
+InsertImage			: "Insert/Edit Image",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insert/Edit Flash",
+InsertTableLbl		: "Table",
+InsertTable			: "Insert/Edit Table",
+InsertLineLbl		: "Line",
+InsertLine			: "Insert Horizontal Line",
+InsertSpecialCharLbl: "Special Character",
+InsertSpecialChar	: "Insert Special Character",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Insert Smiley",
+About				: "About FCKeditor",
+Bold				: "Bold",
+Italic				: "Italic",
+Underline			: "Underline",
+StrikeThrough		: "Strike Through",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Left Justify",
+CenterJustify		: "Centre Justify",
+RightJustify		: "Right Justify",
+BlockJustify		: "Block Justify",
+DecreaseIndent		: "Decrease Indent",
+IncreaseIndent		: "Increase Indent",
+Undo				: "Undo",
+Redo				: "Redo",
+NumberedListLbl		: "Numbered List",
+NumberedList		: "Insert/Remove Numbered List",
+BulletedListLbl		: "Bulleted List",
+BulletedList		: "Insert/Remove Bulleted List",
+ShowTableBorders	: "Show Table Borders",
+ShowDetails			: "Show Details",
+Style				: "Style",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Size",
+TextColor			: "Text Colour",
+BGColor				: "Background Colour",
+Source				: "Source",
+Find				: "Find",
+Replace				: "Replace",
+SpellCheck			: "Check Spelling",
+UniversalKeyboard	: "Universal Keyboard",
+PageBreakLbl		: "Page Break",
+PageBreak			: "Insert Page Break",
+
+Form			: "Form",
+Checkbox		: "Checkbox",
+RadioButton		: "Radio Button",
+TextField		: "Text Field",
+Textarea		: "Textarea",
+HiddenField		: "Hidden Field",
+Button			: "Button",
+SelectionField	: "Selection Field",
+ImageButton		: "Image Button",
+
+FitWindow		: "Maximize the editor size",
+
+// Context Menu
+EditLink			: "Edit Link",
+CellCM				: "Cell",
+RowCM				: "Row",
+ColumnCM			: "Column",
+InsertRow			: "Insert Row",
+DeleteRows			: "Delete Rows",
+InsertColumn		: "Insert Column",
+DeleteColumns		: "Delete Columns",
+InsertCell			: "Insert Cell",
+DeleteCells			: "Delete Cells",
+MergeCells			: "Merge Cells",
+SplitCell			: "Split Cell",
+TableDelete			: "Delete Table",
+CellProperties		: "Cell Properties",
+TableProperties		: "Table Properties",
+ImageProperties		: "Image Properties",
+FlashProperties		: "Flash Properties",
+
+AnchorProp			: "Anchor Properties",
+ButtonProp			: "Button Properties",
+CheckboxProp		: "Checkbox Properties",
+HiddenFieldProp		: "Hidden Field Properties",
+RadioButtonProp		: "Radio Button Properties",
+ImageButtonProp		: "Image Button Properties",
+TextFieldProp		: "Text Field Properties",
+SelectionFieldProp	: "Selection Field Properties",
+TextareaProp		: "Textarea Properties",
+FormProp			: "Form Properties",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Processing XHTML. Please wait...",
+Done				: "Done",
+PasteWordConfirm	: "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?",
+NotCompatiblePaste	: "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?",
+UnknownToolbarItem	: "Unknown toolbar item \"%1\"",
+UnknownCommand		: "Unknown command name \"%1\"",
+NotImplemented		: "Command not implemented",
+UnknownToolbarSet	: "Toolbar set \"%1\" doesn't exist",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancel",
+DlgBtnClose			: "Close",
+DlgBtnBrowseServer	: "Browse Server",
+DlgAdvancedTag		: "Advanced",
+DlgOpOther			: "<Other>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Please insert the URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<not set>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Language Direction",
+DlgGenLangDirLtr	: "Left to Right (LTR)",
+DlgGenLangDirRtl	: "Right to Left (RTL)",
+DlgGenLangCode		: "Language Code",
+DlgGenAccessKey		: "Access Key",
+DlgGenName			: "Name",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Long Description URL",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Image Properties",
+DlgImgInfoTab		: "Image Info",
+DlgImgBtnUpload		: "Send it to the Server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternative Text",
+DlgImgWidth			: "Width",
+DlgImgHeight		: "Height",
+DlgImgLockRatio		: "Lock Ratio",
+DlgBtnResetSize		: "Reset Size",
+DlgImgBorder		: "Border",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Align",
+DlgImgAlignLeft		: "Left",
+DlgImgAlignAbsBottom: "Abs Bottom",
+DlgImgAlignAbsMiddle: "Abs Middle",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Bottom",
+DlgImgAlignMiddle	: "Middle",
+DlgImgAlignRight	: "Right",
+DlgImgAlignTextTop	: "Text Top",
+DlgImgAlignTop		: "Top",
+DlgImgPreview		: "Preview",
+DlgImgAlertUrl		: "Please type the image URL",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",
+DlgFlashChkPlay		: "Auto Play",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Enable Flash Menu",
+DlgFlashScale		: "Scale",
+DlgFlashScaleAll	: "Show all",
+DlgFlashScaleNoBorder	: "No Border",
+DlgFlashScaleFit	: "Exact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Target",
+
+DlgLnkType			: "Link Type",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Link to anchor in the text",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<other>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Select an Anchor",
+DlgLnkAnchorByName	: "By Anchor Name",
+DlgLnkAnchorById	: "By Element Id",
+DlgLnkNoAnchors		: "(No anchors available in the document)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Address",
+DlgLnkEMailSubject	: "Message Subject",
+DlgLnkEMailBody		: "Message Body",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Send it to the Server",
+
+DlgLnkTarget		: "Target",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<popup window>",
+DlgLnkTargetBlank	: "New Window (_blank)",
+DlgLnkTargetParent	: "Parent Window (_parent)",
+DlgLnkTargetSelf	: "Same Window (_self)",
+DlgLnkTargetTop		: "Topmost Window (_top)",
+DlgLnkTargetFrameName	: "Target Frame Name",
+DlgLnkPopWinName	: "Popup Window Name",
+DlgLnkPopWinFeat	: "Popup Window Features",
+DlgLnkPopResize		: "Resizable",
+DlgLnkPopLocation	: "Location Bar",
+DlgLnkPopMenu		: "Menu Bar",
+DlgLnkPopScroll		: "Scroll Bars",
+DlgLnkPopStatus		: "Status Bar",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Full Screen (IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "Width",
+DlgLnkPopHeight		: "Height",
+DlgLnkPopLeft		: "Left Position",
+DlgLnkPopTop		: "Top Position",
+
+DlnLnkMsgNoUrl		: "Please type the link URL",
+DlnLnkMsgNoEMail	: "Please type the e-mail address",
+DlnLnkMsgNoAnchor	: "Please select an anchor",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",
+
+// Color Dialog
+DlgColorTitle		: "Select Colour",
+DlgColorBtnClear	: "Clear",
+DlgColorHighlight	: "Highlight",
+DlgColorSelected	: "Selected",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insert a Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Select Special Character",
+
+// Table Dialog
+DlgTableTitle		: "Table Properties",
+DlgTableRows		: "Rows",
+DlgTableColumns		: "Columns",
+DlgTableBorder		: "Border size",
+DlgTableAlign		: "Alignment",
+DlgTableAlignNotSet	: "<Not set>",
+DlgTableAlignLeft	: "Left",
+DlgTableAlignCenter	: "Centre",
+DlgTableAlignRight	: "Right",
+DlgTableWidth		: "Width",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Height",
+DlgTableCellSpace	: "Cell spacing",
+DlgTableCellPad		: "Cell padding",
+DlgTableCaption		: "Caption",
+DlgTableSummary		: "Summary",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cell Properties",
+DlgCellWidth		: "Width",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Height",
+DlgCellWordWrap		: "Word Wrap",
+DlgCellWordWrapNotSet	: "<Not set>",
+DlgCellWordWrapYes	: "Yes",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Horizontal Alignment",
+DlgCellHorAlignNotSet	: "<Not set>",
+DlgCellHorAlignLeft	: "Left",
+DlgCellHorAlignCenter	: "Centre",
+DlgCellHorAlignRight: "Right",
+DlgCellVerAlign		: "Vertical Alignment",
+DlgCellVerAlignNotSet	: "<Not set>",
+DlgCellVerAlignTop	: "Top",
+DlgCellVerAlignMiddle	: "Middle",
+DlgCellVerAlignBottom	: "Bottom",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Rows Span",
+DlgCellCollSpan		: "Columns Span",
+DlgCellBackColor	: "Background Colour",
+DlgCellBorderColor	: "Border Colour",
+DlgCellBtnSelect	: "Select...",
+
+// Find Dialog
+DlgFindTitle		: "Find",
+DlgFindFindBtn		: "Find",
+DlgFindNotFoundMsg	: "The specified text was not found.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Replace",
+DlgReplaceFindLbl		: "Find what:",
+DlgReplaceReplaceLbl	: "Replace with:",
+DlgReplaceCaseChk		: "Match case",
+DlgReplaceReplaceBtn	: "Replace",
+DlgReplaceReplAllBtn	: "Replace All",
+DlgReplaceWordChk		: "Match whole word",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).",
+PasteErrorCopy	: "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).",
+
+PasteAsText		: "Paste as Plain Text",
+PasteFromWord	: "Paste from Word",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<STRONG>Ctrl+V</STRONG>) and hit <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",
+DlgPasteRemoveStyles	: "Remove Styles definitions",
+DlgPasteCleanBox		: "Clean Up Box",
+
+// Color Picker
+ColorAutomatic	: "Automatic",
+ColorMoreColors	: "More Colours...",
+
+// Document Properties
+DocProps		: "Document Properties",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anchor Properties",
+DlgAnchorName		: "Anchor Name",
+DlgAnchorErrorName	: "Please type the anchor name",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Not in dictionary",
+DlgSpellChangeTo		: "Change to",
+DlgSpellBtnIgnore		: "Ignore",
+DlgSpellBtnIgnoreAll	: "Ignore All",
+DlgSpellBtnReplace		: "Replace",
+DlgSpellBtnReplaceAll	: "Replace All",
+DlgSpellBtnUndo			: "Undo",
+DlgSpellNoSuggestions	: "- No suggestions -",
+DlgSpellProgress		: "Spell check in progress...",
+DlgSpellNoMispell		: "Spell check complete: No misspellings found",
+DlgSpellNoChanges		: "Spell check complete: No words changed",
+DlgSpellOneChange		: "Spell check complete: One word changed",
+DlgSpellManyChanges		: "Spell check complete: %1 words changed",
+
+IeSpellDownload			: "Spell checker not installed. Do you want to download it now?",
+
+// Button Dialog
+DlgButtonText		: "Text (Value)",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",
+DlgCheckboxValue	: "Value",
+DlgCheckboxSelected	: "Selected",
+
+// Form Dialog
+DlgFormName		: "Name",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Method",
+
+// Select Field Dialog
+DlgSelectName		: "Name",
+DlgSelectValue		: "Value",
+DlgSelectSize		: "Size",
+DlgSelectLines		: "lines",
+DlgSelectChkMulti	: "Allow multiple selections",
+DlgSelectOpAvail	: "Available Options",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Value",
+DlgSelectBtnAdd		: "Add",
+DlgSelectBtnModify	: "Modify",
+DlgSelectBtnUp		: "Up",
+DlgSelectBtnDown	: "Down",
+DlgSelectBtnSetValue : "Set as selected value",
+DlgSelectBtnDelete	: "Delete",
+
+// Textarea Dialog
+DlgTextareaName	: "Name",
+DlgTextareaCols	: "Columns",
+DlgTextareaRows	: "Rows",
+
+// Text Field Dialog
+DlgTextName			: "Name",
+DlgTextValue		: "Value",
+DlgTextCharWidth	: "Character Width",
+DlgTextMaxChars		: "Maximum Characters",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Password",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",
+DlgHiddenValue	: "Value",
+
+// Bulleted List Dialog
+BulletedListProp	: "Bulleted List Properties",
+NumberedListProp	: "Numbered List Properties",
+DlgLstStart			: "Start",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Circle",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "Square",
+DlgLstTypeNumbers	: "Numbers (1, 2, 3)",
+DlgLstTypeLCase		: "Lowercase Letters (a, b, c)",
+DlgLstTypeUCase		: "Uppercase Letters (A, B, C)",
+DlgLstTypeSRoman	: "Small Roman Numerals (i, ii, iii)",
+DlgLstTypeLRoman	: "Large Roman Numerals (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Background",
+DlgDocColorsTab		: "Colours and Margins",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Page Title",
+DlgDocLangDir		: "Language Direction",
+DlgDocLangDirLTR	: "Left to Right (LTR)",
+DlgDocLangDirRTL	: "Right to Left (RTL)",
+DlgDocLangCode		: "Language Code",
+DlgDocCharSet		: "Character Set Encoding",
+DlgDocCharSetCE		: "Central European",
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Greek",
+DlgDocCharSetJP		: "Japanese",
+DlgDocCharSetKR		: "Korean",
+DlgDocCharSetTR		: "Turkish",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "Other Character Set Encoding",
+
+DlgDocDocType		: "Document Type Heading",
+DlgDocDocTypeOther	: "Other Document Type Heading",
+DlgDocIncXHTML		: "Include XHTML Declarations",
+DlgDocBgColor		: "Background Colour",
+DlgDocBgImage		: "Background Image URL",
+DlgDocBgNoScroll	: "Nonscrolling Background",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Visited Link",
+DlgDocCActive		: "Active Link",
+DlgDocMargins		: "Page Margins",
+DlgDocMaTop			: "Top",
+DlgDocMaLeft		: "Left",
+DlgDocMaRight		: "Right",
+DlgDocMaBottom		: "Bottom",
+DlgDocMeIndex		: "Document Indexing Keywords (comma separated)",
+DlgDocMeDescr		: "Document Description",
+DlgDocMeAuthor		: "Author",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Preview",
+
+// Templates Dialog
+Templates			: "Templates",
+DlgTemplatesTitle	: "Content Templates",
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br>(the actual contents will be lost):",
+DlgTemplatesLoading	: "Loading templates list. Please wait...",
+DlgTemplatesNoTpl	: "(No templates defined)",
+DlgTemplatesReplace	: "Replace actual contents",
+
+// About Dialog
+DlgAboutAboutTab	: "About",
+DlgAboutBrowserInfoTab	: "Browser Info",
+DlgAboutLicenseTab	: "License",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "For further information go to"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ms.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ms.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ms.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Malay language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Collapse Toolbar",
+ToolbarExpand		: "Expand Toolbar",
+
+// Toolbar Items and Context Menu
+Save				: "Simpan",
+NewPage				: "Helaian Baru",
+Preview				: "Prebiu",
+Cut					: "Potong",
+Copy				: "Salin",
+Paste				: "Tampal",
+PasteText			: "Tampal sebagai Text Biasa",
+PasteWord			: "Tampal dari Word",
+Print				: "Cetak",
+SelectAll			: "Pilih Semua",
+RemoveFormat		: "Buang Format",
+InsertLinkLbl		: "Sambungan",
+InsertLink			: "Masukkan/Sunting Sambungan",
+RemoveLink			: "Buang Sambungan",
+Anchor				: "Masukkan/Sunting Pautan",
+InsertImageLbl		: "Gambar",
+InsertImage			: "Masukkan/Sunting Gambar",
+InsertFlashLbl		: "Flash",	//MISSING
+InsertFlash			: "Insert/Edit Flash",	//MISSING
+InsertTableLbl		: "Jadual",
+InsertTable			: "Masukkan/Sunting Jadual",
+InsertLineLbl		: "Garisan",
+InsertLine			: "Masukkan Garisan Membujur",
+InsertSpecialCharLbl: "Huruf Istimewa",
+InsertSpecialChar	: "Masukkan Huruf Istimewa",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Masukkan Smiley",
+About				: "Tentang FCKeditor",
+Bold				: "Bold",
+Italic				: "Italic",
+Underline			: "Underline",
+StrikeThrough		: "Strike Through",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Jajaran Kiri",
+CenterJustify		: "Jajaran Tengah",
+RightJustify		: "Jajaran Kanan",
+BlockJustify		: "Jajaran Blok",
+DecreaseIndent		: "Kurangkan Inden",
+IncreaseIndent		: "Tambahkan Inden",
+Undo				: "Batalkan",
+Redo				: "Ulangkan",
+NumberedListLbl		: "Senarai bernombor",
+NumberedList		: "Masukkan/Sunting Senarai bernombor",
+BulletedListLbl		: "Senarai tidak bernombor",
+BulletedList		: "Masukkan/Sunting Senarai tidak bernombor",
+ShowTableBorders	: "Tunjukkan Border Jadual",
+ShowDetails			: "Tunjukkan Butiran",
+Style				: "Stail",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Saiz",
+TextColor			: "Warna Text",
+BGColor				: "Warna Latarbelakang",
+Source				: "Sumber",
+Find				: "Cari",
+Replace				: "Ganti",
+SpellCheck			: "Semak Ejaan",
+UniversalKeyboard	: "Papan Kekunci Universal",
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "Borang",
+Checkbox		: "Checkbox",
+RadioButton		: "Butang Radio",
+TextField		: "Text Field",
+Textarea		: "Textarea",
+HiddenField		: "Field Tersembunyi",
+Button			: "Butang",
+SelectionField	: "Field Pilihan",
+ImageButton		: "Butang Bergambar",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Sunting Sambungan",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Masukkan Baris",
+DeleteRows			: "Buangkan Baris",
+InsertColumn		: "Masukkan Lajur",
+DeleteColumns		: "Buangkan Lajur",
+InsertCell			: "Masukkan Sel",
+DeleteCells			: "Buangkan Sel-sel",
+MergeCells			: "Cantumkan Sel-sel",
+SplitCell			: "Bahagikan Sel",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "Ciri-ciri Sel",
+TableProperties		: "Ciri-ciri Jadual",
+ImageProperties		: "Ciri-ciri Gambar",
+FlashProperties		: "Flash Properties",	//MISSING
+
+AnchorProp			: "Ciri-ciri Pautan",
+ButtonProp			: "Ciri-ciri Butang",
+CheckboxProp		: "Ciri-ciri Checkbox",
+HiddenFieldProp		: "Ciri-ciri Field Tersembunyi",
+RadioButtonProp		: "Ciri-ciri Butang Radio",
+ImageButtonProp		: "Ciri-ciri Butang Bergambar",
+TextFieldProp		: "Ciri-ciri Text Field",
+SelectionFieldProp	: "Ciri-ciri Selection Field",
+TextareaProp		: "Ciri-ciri Textarea",
+FormProp			: "Ciri-ciri Borang",
+
+FontFormats			: "Normal;Telah Diformat;Alamat;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Perenggan (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Memproses XHTML. Sila tunggu...",
+Done				: "Siap",
+PasteWordConfirm	: "Text yang anda hendak tampal adalah berasal dari Word. Adakah anda mahu membuang semua format Word sebelum tampal ke dalam text?",
+NotCompatiblePaste	: "Arahan ini bole dilakukan jika anda mempuunyai Internet Explorer version 5.5 atau yang lebih tinggi. Adakah anda hendak tampal text tanpa membuang format Word?",
+UnknownToolbarItem	: "Toolbar item tidak diketahui\"%1\"",
+UnknownCommand		: "Arahan tidak diketahui \"%1\"",
+NotImplemented		: "Arahan tidak terdapat didalam sistem",
+UnknownToolbarSet	: "Set toolbar \"%1\" tidak wujud",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Batal",
+DlgBtnClose			: "Tutup",
+DlgBtnBrowseServer	: "Browse Server",
+DlgAdvancedTag		: "Advanced",
+DlgOpOther			: "<Lain-lain>",
+DlgInfoTab			: "Info",	//MISSING
+DlgAlertUrl			: "Please insert the URL",	//MISSING
+
+// General Dialogs Labels
+DlgGenNotSet		: "<tidak di set>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Arah Tulisan",
+DlgGenLangDirLtr	: "Kiri ke Kanan (LTR)",
+DlgGenLangDirRtl	: "Kanan ke Kiri (RTL)",
+DlgGenLangCode		: "Kod Bahasa",
+DlgGenAccessKey		: "Kunci Akses",
+DlgGenName			: "Nama",
+DlgGenTabIndex		: "Indeks Tab ",
+DlgGenLongDescr		: "Butiran Panjang URL",
+DlgGenClass			: "Kelas-kelas Stylesheet",
+DlgGenTitle			: "Tajuk Makluman",
+DlgGenContType		: "Jenis Kandungan Makluman",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Stail",
+
+// Image Dialog
+DlgImgTitle			: "Ciri-ciri Imej",
+DlgImgInfoTab		: "Info Imej",
+DlgImgBtnUpload		: "Hantar ke Server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Muat Naik",
+DlgImgAlt			: "Text Alternatif",
+DlgImgWidth			: "Lebar",
+DlgImgHeight		: "Tinggi",
+DlgImgLockRatio		: "Tetapkan Nisbah",
+DlgBtnResetSize		: "Saiz Set Semula",
+DlgImgBorder		: "Border",
+DlgImgHSpace		: "Ruang Melintang",
+DlgImgVSpace		: "Ruang Menegak",
+DlgImgAlign			: "Jajaran",
+DlgImgAlignLeft		: "Kiri",
+DlgImgAlignAbsBottom: "Bawah Mutlak",
+DlgImgAlignAbsMiddle: "Pertengahan Mutlak",
+DlgImgAlignBaseline	: "Garis Dasar",
+DlgImgAlignBottom	: "Bawah",
+DlgImgAlignMiddle	: "Pertengahan",
+DlgImgAlignRight	: "Kanan",
+DlgImgAlignTextTop	: "Atas Text",
+DlgImgAlignTop		: "Atas",
+DlgImgPreview		: "Prebiu",
+DlgImgAlertUrl		: "Sila taip URL untuk fail gambar",
+DlgImgLinkTab		: "Sambungan",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",	//MISSING
+DlgFlashChkPlay		: "Auto Play",	//MISSING
+DlgFlashChkLoop		: "Loop",	//MISSING
+DlgFlashChkMenu		: "Enable Flash Menu",	//MISSING
+DlgFlashScale		: "Scale",	//MISSING
+DlgFlashScaleAll	: "Show all",	//MISSING
+DlgFlashScaleNoBorder	: "No Border",	//MISSING
+DlgFlashScaleFit	: "Exact Fit",	//MISSING
+
+// Link Dialog
+DlgLnkWindowTitle	: "Sambungan",
+DlgLnkInfoTab		: "Butiran Sambungan",
+DlgLnkTargetTab		: "Sasaran",
+
+DlgLnkType			: "Jenis Sambungan",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Pautan dalam muka surat ini",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<lain-lain>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Sila pilih pautan",
+DlgLnkAnchorByName	: "dengan menggunakan nama pautan",
+DlgLnkAnchorById	: "dengan menggunakan ID elemen",
+DlgLnkNoAnchors		: "<Tiada pautan terdapat dalam dokumen ini>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Alamat E-Mail",
+DlgLnkEMailSubject	: "Subjek Mesej",
+DlgLnkEMailBody		: "Isi Kandungan Mesej",
+DlgLnkUpload		: "Muat Naik",
+DlgLnkBtnUpload		: "Hantar ke Server",
+
+DlgLnkTarget		: "Sasaran",
+DlgLnkTargetFrame	: "<bingkai>",
+DlgLnkTargetPopup	: "<tetingkap popup>",
+DlgLnkTargetBlank	: "Tetingkap Baru (_blank)",
+DlgLnkTargetParent	: "Tetingkap Parent (_parent)",
+DlgLnkTargetSelf	: "Tetingkap yang Sama (_self)",
+DlgLnkTargetTop		: "Tetingkap yang paling atas (_top)",
+DlgLnkTargetFrameName	: "Nama Bingkai Sasaran",
+DlgLnkPopWinName	: "Nama Tetingkap Popup",
+DlgLnkPopWinFeat	: "Ciri Tetingkap Popup",
+DlgLnkPopResize		: "Saiz bolehubah",
+DlgLnkPopLocation	: "Bar Lokasi",
+DlgLnkPopMenu		: "Bar Menu",
+DlgLnkPopScroll		: "Bar-bar skrol",
+DlgLnkPopStatus		: "Bar Status",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Skrin Penuh (IE)",
+DlgLnkPopDependent	: "Bergantungan (Netscape)",
+DlgLnkPopWidth		: "Lebar",
+DlgLnkPopHeight		: "Tinggi",
+DlgLnkPopLeft		: "Posisi Kiri",
+DlgLnkPopTop		: "Posisi Atas",
+
+DlnLnkMsgNoUrl		: "Sila taip sambungan URL",
+DlnLnkMsgNoEMail	: "Sila taip alamat e-mail",
+DlnLnkMsgNoAnchor	: "Sila pilih pautan berkenaaan",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Pilihan Warna",
+DlgColorBtnClear	: "Nyahwarna",
+DlgColorHighlight	: "Terang",
+DlgColorSelected	: "Dipilih",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Masukkan Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Sila pilih huruf istimewa",
+
+// Table Dialog
+DlgTableTitle		: "Ciri-ciri Jadual",
+DlgTableRows		: "Barisan",
+DlgTableColumns		: "Jaluran",
+DlgTableBorder		: "Saiz Border",
+DlgTableAlign		: "Penjajaran",
+DlgTableAlignNotSet	: "<Tidak diset>",
+DlgTableAlignLeft	: "Kiri",
+DlgTableAlignCenter	: "Tengah",
+DlgTableAlignRight	: "Kanan",
+DlgTableWidth		: "Lebar",
+DlgTableWidthPx		: "piksel-piksel",
+DlgTableWidthPc		: "peratus",
+DlgTableHeight		: "Tinggi",
+DlgTableCellSpace	: "Ruangan Antara Sel",
+DlgTableCellPad		: "Tambahan Ruang Sel",
+DlgTableCaption		: "Keterangan",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "Ciri-ciri Sel",
+DlgCellWidth		: "Lebar",
+DlgCellWidthPx		: "piksel-piksel",
+DlgCellWidthPc		: "peratus",
+DlgCellHeight		: "Tinggi",
+DlgCellWordWrap		: "Mengulung Perkataan",
+DlgCellWordWrapNotSet	: "<Tidak diset>",
+DlgCellWordWrapYes	: "Ya",
+DlgCellWordWrapNo	: "Tidak",
+DlgCellHorAlign		: "Jajaran Membujur",
+DlgCellHorAlignNotSet	: "<Tidak diset>",
+DlgCellHorAlignLeft	: "Kiri",
+DlgCellHorAlignCenter	: "Tengah",
+DlgCellHorAlignRight: "Kanan",
+DlgCellVerAlign		: "Jajaran Menegak",
+DlgCellVerAlignNotSet	: "<Tidak diset>",
+DlgCellVerAlignTop	: "Atas",
+DlgCellVerAlignMiddle	: "Tengah",
+DlgCellVerAlignBottom	: "Bawah",
+DlgCellVerAlignBaseline	: "Garis Dasar",
+DlgCellRowSpan		: "Penggunaan Baris",
+DlgCellCollSpan		: "Penggunaan Lajur",
+DlgCellBackColor	: "Warna Latarbelakang",
+DlgCellBorderColor	: "Warna Border",
+DlgCellBtnSelect	: "Pilih...",
+
+// Find Dialog
+DlgFindTitle		: "Carian",
+DlgFindFindBtn		: "Cari",
+DlgFindNotFoundMsg	: "Text yang dicari tidak dijumpai.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Gantian",
+DlgReplaceFindLbl		: "Perkataan yang dicari:",
+DlgReplaceReplaceLbl	: "Diganti dengan:",
+DlgReplaceCaseChk		: "Padanan case huruf",
+DlgReplaceReplaceBtn	: "Ganti",
+DlgReplaceReplAllBtn	: "Ganti semua",
+DlgReplaceWordChk		: "Padana Keseluruhan perkataan",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Keselamatan perisian browser anda tidak membenarkan operasi suntingan text/imej. Sila gunakan papan kekunci (Ctrl+X).",
+PasteErrorCopy	: "Keselamatan perisian browser anda tidak membenarkan operasi salinan text/imej. Sila gunakan papan kekunci (Ctrl+C).",
+
+PasteAsText		: "Tampal sebagai text biasa",
+PasteFromWord	: "Tampal dari perisian \"Word\"",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.",	//MISSING
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",	//MISSING
+DlgPasteRemoveStyles	: "Remove Styles definitions",	//MISSING
+DlgPasteCleanBox		: "Clean Up Box",	//MISSING
+
+// Color Picker
+ColorAutomatic	: "Otomatik",
+ColorMoreColors	: "Warna lain-lain...",
+
+// Document Properties
+DocProps		: "Ciri-ciri dokumen",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ciri-ciri Pautan",
+DlgAnchorName		: "Nama Pautan",
+DlgAnchorErrorName	: "Sila taip nama pautan",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Tidak terdapat didalam kamus",
+DlgSpellChangeTo		: "Tukarkan kepada",
+DlgSpellBtnIgnore		: "Biar",
+DlgSpellBtnIgnoreAll	: "Biarkan semua",
+DlgSpellBtnReplace		: "Ganti",
+DlgSpellBtnReplaceAll	: "Gantikan Semua",
+DlgSpellBtnUndo			: "Batalkan",
+DlgSpellNoSuggestions	: "- Tiada cadangan -",
+DlgSpellProgress		: "Pemeriksaan ejaan sedang diproses...",
+DlgSpellNoMispell		: "Pemeriksaan ejaan siap: Tiada salah ejaan",
+DlgSpellNoChanges		: "Pemeriksaan ejaan siap: Tiada perkataan diubah",
+DlgSpellOneChange		: "Pemeriksaan ejaan siap: Satu perkataan telah diubah",
+DlgSpellManyChanges		: "Pemeriksaan ejaan siap: %1 perkataan diubah",
+
+IeSpellDownload			: "Pemeriksa ejaan tidak dipasang. Adakah anda mahu muat turun sekarang?",
+
+// Button Dialog
+DlgButtonText		: "Teks (Nilai)",
+DlgButtonType		: "Jenis",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nama",
+DlgCheckboxValue	: "Nilai",
+DlgCheckboxSelected	: "Dipilih",
+
+// Form Dialog
+DlgFormName		: "Nama",
+DlgFormAction	: "Tindakan borang",
+DlgFormMethod	: "Cara borang dihantar",
+
+// Select Field Dialog
+DlgSelectName		: "Nama",
+DlgSelectValue		: "Nilai",
+DlgSelectSize		: "Saiz",
+DlgSelectLines		: "garisan",
+DlgSelectChkMulti	: "Benarkan pilihan pelbagai",
+DlgSelectOpAvail	: "Pilihan sediada",
+DlgSelectOpText		: "Teks",
+DlgSelectOpValue	: "Nilai",
+DlgSelectBtnAdd		: "Tambah Pilihan",
+DlgSelectBtnModify	: "Ubah Pilihan",
+DlgSelectBtnUp		: "Naik ke atas",
+DlgSelectBtnDown	: "Turun ke bawah",
+DlgSelectBtnSetValue : "Set sebagai nilai terpilih",
+DlgSelectBtnDelete	: "Padam",
+
+// Textarea Dialog
+DlgTextareaName	: "Nama",
+DlgTextareaCols	: "Lajur",
+DlgTextareaRows	: "Baris",
+
+// Text Field Dialog
+DlgTextName			: "Nama",
+DlgTextValue		: "Nilai",
+DlgTextCharWidth	: "Lebar isian",
+DlgTextMaxChars		: "Isian Maksimum",
+DlgTextType			: "Jenis",
+DlgTextTypeText		: "Teks",
+DlgTextTypePass		: "Kata Laluan",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nama",
+DlgHiddenValue	: "Nilai",
+
+// Bulleted List Dialog
+BulletedListProp	: "Ciri-ciri senarai berpeluru",
+NumberedListProp	: "Ciri-ciri senarai bernombor",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Jenis",
+DlgLstTypeCircle	: "Circle",
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "Square",
+DlgLstTypeNumbers	: "Nombor-nombor (1, 2, 3)",
+DlgLstTypeLCase		: "Huruf-huruf kecil (a, b, c)",
+DlgLstTypeUCase		: "Huruf-huruf besar (A, B, C)",
+DlgLstTypeSRoman	: "Nombor Roman Kecil (i, ii, iii)",
+DlgLstTypeLRoman	: "Nombor Roman Besar (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Umum",
+DlgDocBackTab		: "Latarbelakang",
+DlgDocColorsTab		: "Warna dan margin",
+DlgDocMetaTab		: "Data Meta",
+
+DlgDocPageTitle		: "Tajuk Muka Surat",
+DlgDocLangDir		: "Arah Tulisan",
+DlgDocLangDirLTR	: "Kiri ke Kanan (LTR)",
+DlgDocLangDirRTL	: "Kanan ke Kiri (RTL)",
+DlgDocLangCode		: "Kod Bahasa",
+DlgDocCharSet		: "Enkod Set Huruf",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Enkod Set Huruf yang Lain",
+
+DlgDocDocType		: "Jenis Kepala Dokumen",
+DlgDocDocTypeOther	: "Jenis Kepala Dokumen yang Lain",
+DlgDocIncXHTML		: "Masukkan pemula kod XHTML",
+DlgDocBgColor		: "Warna Latarbelakang",
+DlgDocBgImage		: "URL Gambar Latarbelakang",
+DlgDocBgNoScroll	: "Imej Latarbelakang tanpa Skrol",
+DlgDocCText			: "Teks",
+DlgDocCLink			: "Sambungan",
+DlgDocCVisited		: "Sambungan telah Dilawati",
+DlgDocCActive		: "Sambungan Aktif",
+DlgDocMargins		: "Margin Muka Surat",
+DlgDocMaTop			: "Atas",
+DlgDocMaLeft		: "Kiri",
+DlgDocMaRight		: "Kanan",
+DlgDocMaBottom		: "Bawah",
+DlgDocMeIndex		: "Kata Kunci Indeks Dokumen (dipisahkan oleh koma)",
+DlgDocMeDescr		: "Keterangan Dokumen",
+DlgDocMeAuthor		: "Penulis",
+DlgDocMeCopy		: "Hakcipta",
+DlgDocPreview		: "Prebiu",
+
+// Templates Dialog
+Templates			: "Templat",
+DlgTemplatesTitle	: "Templat Kandungan",
+DlgTemplatesSelMsg	: "Sila pilih templat untuk dibuka oleh editor<br>(kandungan sebenar akan hilang):",
+DlgTemplatesLoading	: "Senarai Templat sedang diproses. Sila Tunggu...",
+DlgTemplatesNoTpl	: "(Tiada Templat Disimpan)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Tentang",
+DlgAboutBrowserInfoTab	: "Maklumat Perisian Browser",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "versi",
+DlgAboutInfo		: "Untuk maklumat lanjut sila pergi ke"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/uk.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/uk.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/uk.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Ukrainian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Згорнути панель інструментів",
+ToolbarExpand		: "Розгорнути панель інструментів",
+
+// Toolbar Items and Context Menu
+Save				: "Зберегти",
+NewPage				: "Нова сторінка",
+Preview				: "Попередній перегляд",
+Cut					: "Вирізати",
+Copy				: "Копіювати",
+Paste				: "Вставити",
+PasteText			: "Вставити тільки текст",
+PasteWord			: "Вставити з Word",
+Print				: "Друк",
+SelectAll			: "Виділити все",
+RemoveFormat		: "Прибрати форматування",
+InsertLinkLbl		: "Посилання",
+InsertLink			: "Вставити/Редагувати посилання",
+RemoveLink			: "Знищити посилання",
+Anchor				: "Вставити/Редагувати якір",
+InsertImageLbl		: "Зображення",
+InsertImage			: "Вставити/Редагувати зображення",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Вставити/Редагувати Flash",
+InsertTableLbl		: "Таблиця",
+InsertTable			: "Вставити/Редагувати таблицю",
+InsertLineLbl		: "Лінія",
+InsertLine			: "Вставити горизонтальну лінію",
+InsertSpecialCharLbl: "Спеціальний символ",
+InsertSpecialChar	: "Вставити спеціальний символ",
+InsertSmileyLbl		: "Смайлик",
+InsertSmiley		: "Вставити смайлик",
+About				: "Про FCKeditor",
+Bold				: "Жирний",
+Italic				: "Курсив",
+Underline			: "Підкреслений",
+StrikeThrough		: "Закреслений",
+Subscript			: "Підрядковий індекс",
+Superscript			: "Надрядковий индекс",
+LeftJustify			: "По лівому краю",
+CenterJustify		: "По центру",
+RightJustify		: "По правому краю",
+BlockJustify		: "По ширині",
+DecreaseIndent		: "Зменшити відступ",
+IncreaseIndent		: "Збільшити відступ",
+Undo				: "Повернути",
+Redo				: "Повторити",
+NumberedListLbl		: "Нумерований список",
+NumberedList		: "Вставити/Видалити нумерований список",
+BulletedListLbl		: "Маркований список",
+BulletedList		: "Вставити/Видалити маркований список",
+ShowTableBorders	: "Показати бордюри таблиці",
+ShowDetails			: "Показати деталі",
+Style				: "Стиль",
+FontFormat			: "Форматування",
+Font				: "Шрифт",
+FontSize			: "Розмір",
+TextColor			: "Колір тексту",
+BGColor				: "Колір фону",
+Source				: "Джерело",
+Find				: "Пошук",
+Replace				: "Заміна",
+SpellCheck			: "Перевірити орфографію",
+UniversalKeyboard	: "Універсальна клавіатура",
+PageBreakLbl		: "Розривши сторінки",
+PageBreak			: "Вставити розривши сторінки",
+
+Form			: "Форма",
+Checkbox		: "Флагова кнопка",
+RadioButton		: "Кнопка вибору",
+TextField		: "Текстове поле",
+Textarea		: "Текстова область",
+HiddenField		: "Приховане поле",
+Button			: "Кнопка",
+SelectionField	: "Список",
+ImageButton		: "Кнопка із зображенням",
+
+FitWindow		: "Розвернути вікно редактора",
+
+// Context Menu
+EditLink			: "Вставити посилання",
+CellCM				: "Осередок",
+RowCM				: "Рядок",
+ColumnCM			: "Колонка",
+InsertRow			: "Вставити строку",
+DeleteRows			: "Видалити строки",
+InsertColumn		: "Вставити колонку",
+DeleteColumns		: "Видалити колонки",
+InsertCell			: "Вставити комірку",
+DeleteCells			: "Видалити комірки",
+MergeCells			: "Об'єднати комірки",
+SplitCell			: "Роз'єднати комірку",
+TableDelete			: "Видалити таблицю",
+CellProperties		: "Властивості комірки",
+TableProperties		: "Властивості таблиці",
+ImageProperties		: "Властивості зображення",
+FlashProperties		: "Властивості Flash",
+
+AnchorProp			: "Властивості якоря",
+ButtonProp			: "Властивості кнопки",
+CheckboxProp		: "Властивості флагової кнопки",
+HiddenFieldProp		: "Властивості прихованого поля",
+RadioButtonProp		: "Властивості кнопки вибору",
+ImageButtonProp		: "Властивості кнопки із зображенням",
+TextFieldProp		: "Властивості текстового поля",
+SelectionFieldProp	: "Властивості списку",
+TextareaProp		: "Властивості текстової області",
+FormProp			: "Властивості форми",
+
+FontFormats			: "Нормальний;Форматований;Адреса;Заголовок 1;Заголовок 2;Заголовок 3;Заголовок 4;Заголовок 5;Заголовок 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Обробка XHTML. Зачекайте, будь ласка...",
+Done				: "Зроблено",
+PasteWordConfirm	: "Текст, що ви хочете вставити, схожий на копійований з Word. Ви хочете очистити його перед вставкою?",
+NotCompatiblePaste	: "Ця команда доступна для Internet Explorer версії 5.5 або вище. Ви хочете вставити без очищення?",
+UnknownToolbarItem	: "Невідомий елемент панелі інструментів \"%1\"",
+UnknownCommand		: "Невідоме ім'я команди \"%1\"",
+NotImplemented		: "Команда не реалізована",
+UnknownToolbarSet	: "Панель інструментів \"%1\" не існує",
+NoActiveX			: "Настройки безпеки вашого браузера можуть обмежувати деякі властивості редактора. Ви повинні включити опцію \"Запускати елементи управління ACTIVEX і плугіни\". Ви можете бачити помилки і помічати відсутність можливостей.",
+BrowseServerBlocked : "Ресурси браузера не можуть бути відкриті. Перевірте що блокування спливаючих вікон вимкнені.",
+DialogBlocked		: "Не можливо відкрити вікно діалогу. Перевірте що блокування спливаючих вікон вимкнені.",
+
+// Dialogs
+DlgBtnOK			: "ОК",
+DlgBtnCancel		: "Скасувати",
+DlgBtnClose			: "Зачинити",
+DlgBtnBrowseServer	: "Передивитися на сервері",
+DlgAdvancedTag		: "Розширений",
+DlgOpOther			: "<Інше>",
+DlgInfoTab			: "Інфо",
+DlgAlertUrl			: "Вставте, будь-ласка, URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<не визначено>",
+DlgGenId			: "Ідентифікатор",
+DlgGenLangDir		: "Напрямок мови",
+DlgGenLangDirLtr	: "Зліва на право (LTR)",
+DlgGenLangDirRtl	: "Зправа на ліво (RTL)",
+DlgGenLangCode		: "Мова",
+DlgGenAccessKey		: "Гаряча клавіша",
+DlgGenName			: "Им'я",
+DlgGenTabIndex		: "Послідовність переходу",
+DlgGenLongDescr		: "Довгий опис URL",
+DlgGenClass			: "Клас CSS",
+DlgGenTitle			: "Заголовок",
+DlgGenContType		: "Тип вмісту",
+DlgGenLinkCharset	: "Кодировка",
+DlgGenStyle			: "Стиль CSS",
+
+// Image Dialog
+DlgImgTitle			: "Властивості зображення",
+DlgImgInfoTab		: "Інформація про изображении",
+DlgImgBtnUpload		: "Надіслати на сервер",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Закачати",
+DlgImgAlt			: "Альтернативний текст",
+DlgImgWidth			: "Ширина",
+DlgImgHeight		: "Висота",
+DlgImgLockRatio		: "Зберегти пропорції",
+DlgBtnResetSize		: "Скинути розмір",
+DlgImgBorder		: "Бордюр",
+DlgImgHSpace		: "Горизонтальний відступ",
+DlgImgVSpace		: "Вертикальний відступ",
+DlgImgAlign			: "Вирівнювання",
+DlgImgAlignLeft		: "По лівому краю",
+DlgImgAlignAbsBottom: "Абс по низу",
+DlgImgAlignAbsMiddle: "Абс по середині",
+DlgImgAlignBaseline	: "По базовій лінії",
+DlgImgAlignBottom	: "По низу",
+DlgImgAlignMiddle	: "По середині",
+DlgImgAlignRight	: "По правому краю",
+DlgImgAlignTextTop	: "Текст на верху",
+DlgImgAlignTop		: "По верху",
+DlgImgPreview		: "Попередній перегляд",
+DlgImgAlertUrl		: "Будь ласка, введіть URL зображення",
+DlgImgLinkTab		: "Посилання",
+
+// Flash Dialog
+DlgFlashTitle		: "Властивості Flash",
+DlgFlashChkPlay		: "Авто програвання",
+DlgFlashChkLoop		: "Зациклити",
+DlgFlashChkMenu		: "Дозволити меню Flash",
+DlgFlashScale		: "Масштаб",
+DlgFlashScaleAll	: "Показати всі",
+DlgFlashScaleNoBorder	: "Без рамки",
+DlgFlashScaleFit	: "Дійсний розмір",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Посилання",
+DlgLnkInfoTab		: "Інформація посилання",
+DlgLnkTargetTab		: "Ціль",
+
+DlgLnkType			: "Тип посилання",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Якір на цю сторінку",
+DlgLnkTypeEMail		: "Эл. пошта",
+DlgLnkProto			: "Протокол",
+DlgLnkProtoOther	: "<інше>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Оберіть якір",
+DlgLnkAnchorByName	: "За ім'ям якоря",
+DlgLnkAnchorById	: "За ідентифікатором елемента",
+DlgLnkNoAnchors		: "<Немає якорів доступних в цьому документі>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Адреса ел. пошти",
+DlgLnkEMailSubject	: "Тема листа",
+DlgLnkEMailBody		: "Тіло повідомлення",
+DlgLnkUpload		: "Закачати",
+DlgLnkBtnUpload		: "Переслати на сервер",
+
+DlgLnkTarget		: "Ціль",
+DlgLnkTargetFrame	: "<фрейм>",
+DlgLnkTargetPopup	: "<спливаюче вікно>",
+DlgLnkTargetBlank	: "Нове вікно (_blank)",
+DlgLnkTargetParent	: "Батьківське вікно (_parent)",
+DlgLnkTargetSelf	: "Теж вікно (_self)",
+DlgLnkTargetTop		: "Найвище вікно (_top)",
+DlgLnkTargetFrameName	: "Ім'я целевого фрейма",
+DlgLnkPopWinName	: "Ім'я спливаючого вікна",
+DlgLnkPopWinFeat	: "Властивості спливаючого вікна",
+DlgLnkPopResize		: "Змінюється в розмірах",
+DlgLnkPopLocation	: "Панель локації",
+DlgLnkPopMenu		: "Панель меню",
+DlgLnkPopScroll		: "Полоси прокрутки",
+DlgLnkPopStatus		: "Строка статусу",
+DlgLnkPopToolbar	: "Панель інструментів",
+DlgLnkPopFullScrn	: "Повний екран (IE)",
+DlgLnkPopDependent	: "Залежний (Netscape)",
+DlgLnkPopWidth		: "Ширина",
+DlgLnkPopHeight		: "Висота",
+DlgLnkPopLeft		: "Позиція зліва",
+DlgLnkPopTop		: "Позиція зверху",
+
+DlnLnkMsgNoUrl		: "Будь ласка, занесіть URL посилання",
+DlnLnkMsgNoEMail	: "Будь ласка, занесіть адрес эл. почты",
+DlnLnkMsgNoAnchor	: "Будь ласка, оберіть якір",
+DlnLnkMsgInvPopName	: "Назва спливаючого вікна повинна починатися букви і не може містити пропусків",
+
+// Color Dialog
+DlgColorTitle		: "Оберіть колір",
+DlgColorBtnClear	: "Очистити",
+DlgColorHighlight	: "Підсвічений",
+DlgColorSelected	: "Обраний",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Вставити смайлик",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Оберіть спеціальний символ",
+
+// Table Dialog
+DlgTableTitle		: "Властивості таблиці",
+DlgTableRows		: "Строки",
+DlgTableColumns		: "Колонки",
+DlgTableBorder		: "Розмір бордюра",
+DlgTableAlign		: "Вирівнювання",
+DlgTableAlignNotSet	: "<Не вст.>",
+DlgTableAlignLeft	: "Зліва",
+DlgTableAlignCenter	: "По центру",
+DlgTableAlignRight	: "Зправа",
+DlgTableWidth		: "Ширина",
+DlgTableWidthPx		: "пікселів",
+DlgTableWidthPc		: "відсотків",
+DlgTableHeight		: "Висота",
+DlgTableCellSpace	: "Проміжок (spacing)",
+DlgTableCellPad		: "Відступ (padding)",
+DlgTableCaption		: "Заголовок",
+DlgTableSummary		: "Резюме",
+
+// Table Cell Dialog
+DlgCellTitle		: "Властивості комірки",
+DlgCellWidth		: "Ширина",
+DlgCellWidthPx		: "пікселів",
+DlgCellWidthPc		: "відсотків",
+DlgCellHeight		: "Висота",
+DlgCellWordWrap		: "Згортання текста",
+DlgCellWordWrapNotSet	: "<Не вст.>",
+DlgCellWordWrapYes	: "Так",
+DlgCellWordWrapNo	: "Ні",
+DlgCellHorAlign		: "Горизонтальне вирівнювання",
+DlgCellHorAlignNotSet	: "<Не вст.>",
+DlgCellHorAlignLeft	: "Зліва",
+DlgCellHorAlignCenter	: "По центру",
+DlgCellHorAlignRight: "Зправа",
+DlgCellVerAlign		: "Вертикальное вирівнювання",
+DlgCellVerAlignNotSet	: "<Не вст.>",
+DlgCellVerAlignTop	: "Зверху",
+DlgCellVerAlignMiddle	: "Посередині",
+DlgCellVerAlignBottom	: "Знизу",
+DlgCellVerAlignBaseline	: "По базовій лінії",
+DlgCellRowSpan		: "Діапазон строк (span)",
+DlgCellCollSpan		: "Діапазон колонок (span)",
+DlgCellBackColor	: "Колір фона",
+DlgCellBorderColor	: "Колір бордюра",
+DlgCellBtnSelect	: "Оберіть...",
+
+// Find Dialog
+DlgFindTitle		: "Пошук",
+DlgFindFindBtn		: "Пошук",
+DlgFindNotFoundMsg	: "Вказаний текст не знайдений.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Замінити",
+DlgReplaceFindLbl		: "Шукати:",
+DlgReplaceReplaceLbl	: "Замінити на:",
+DlgReplaceCaseChk		: "Учитывать регистр",
+DlgReplaceReplaceBtn	: "Замінити",
+DlgReplaceReplAllBtn	: "Замінити все",
+DlgReplaceWordChk		: "Збіг цілих слів",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Настройки безпеки вашого браузера не дозволяють редактору автоматично виконувати операції вирізування. Будь ласка, використовуйте клавіатуру для цього (Ctrl+X).",
+PasteErrorCopy	: "Настройки безпеки вашого браузера не дозволяють редактору автоматично виконувати операції копіювання. Будь ласка, використовуйте клавіатуру для цього (Ctrl+C).",
+
+PasteAsText		: "Вставити тільки текст",
+PasteFromWord	: "Вставити з Word",
+
+DlgPasteMsg2	: "Будь-ласка, вставте з буфера обміну в цю область, користуючись комбінацією клавіш (<STRONG>Ctrl+V</STRONG>) та натисніть <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ігнорувати налаштування шрифтів",
+DlgPasteRemoveStyles	: "Видалити налаштування стилів",
+DlgPasteCleanBox		: "Очистити область",
+
+// Color Picker
+ColorAutomatic	: "Автоматичний",
+ColorMoreColors	: "Кольори...",
+
+// Document Properties
+DocProps		: "Властивості документа",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Властивості якоря",
+DlgAnchorName		: "Ім'я якоря",
+DlgAnchorErrorName	: "Будь ласка, занесіть ім'я якоря",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Не має в словнику",
+DlgSpellChangeTo		: "Замінити на",
+DlgSpellBtnIgnore		: "Ігнорувати",
+DlgSpellBtnIgnoreAll	: "Ігнорувати все",
+DlgSpellBtnReplace		: "Замінити",
+DlgSpellBtnReplaceAll	: "Замінити все",
+DlgSpellBtnUndo			: "Назад",
+DlgSpellNoSuggestions	: "- Немає припущень -",
+DlgSpellProgress		: "Виконується перевірка орфографії...",
+DlgSpellNoMispell		: "Перевірку орфографії завершено: помилок не знайдено",
+DlgSpellNoChanges		: "Перевірку орфографії завершено: жодне слово не змінено",
+DlgSpellOneChange		: "Перевірку орфографії завершено: змінено одно слово",
+DlgSpellManyChanges		: "Перевірку орфографії завершено: 1% слів змінено",
+
+IeSpellDownload			: "Модуль перевірки орфографії не встановлено. Бажаєтн завантажити його зараз?",
+
+// Button Dialog
+DlgButtonText		: "Текст (Значення)",
+DlgButtonType		: "Тип",
+DlgButtonTypeBtn	: "Кнопка",
+DlgButtonTypeSbm	: "Відправити",
+DlgButtonTypeRst	: "Скинути",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Ім'я",
+DlgCheckboxValue	: "Значення",
+DlgCheckboxSelected	: "Обрана",
+
+// Form Dialog
+DlgFormName		: "Ім'я",
+DlgFormAction	: "Дія",
+DlgFormMethod	: "Метод",
+
+// Select Field Dialog
+DlgSelectName		: "Ім'я",
+DlgSelectValue		: "Значення",
+DlgSelectSize		: "Розмір",
+DlgSelectLines		: "лінії",
+DlgSelectChkMulti	: "Дозволити обрання декількох позицій",
+DlgSelectOpAvail	: "Доступні варіанти",
+DlgSelectOpText		: "Текст",
+DlgSelectOpValue	: "Значення",
+DlgSelectBtnAdd		: "Добавити",
+DlgSelectBtnModify	: "Змінити",
+DlgSelectBtnUp		: "Вгору",
+DlgSelectBtnDown	: "Вниз",
+DlgSelectBtnSetValue : "Встановити як вибране значення",
+DlgSelectBtnDelete	: "Видалити",
+
+// Textarea Dialog
+DlgTextareaName	: "Ім'я",
+DlgTextareaCols	: "Колонки",
+DlgTextareaRows	: "Строки",
+
+// Text Field Dialog
+DlgTextName			: "Ім'я",
+DlgTextValue		: "Значення",
+DlgTextCharWidth	: "Ширина",
+DlgTextMaxChars		: "Макс. кіл-ть символів",
+DlgTextType			: "Тип",
+DlgTextTypeText		: "Текст",
+DlgTextTypePass		: "Пароль",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Ім'я",
+DlgHiddenValue	: "Значення",
+
+// Bulleted List Dialog
+BulletedListProp	: "Властивості маркованого списка",
+NumberedListProp	: "Властивості нумерованного списка",
+DlgLstStart			: "Початок",
+DlgLstType			: "Тип",
+DlgLstTypeCircle	: "Коло",
+DlgLstTypeDisc		: "Диск",
+DlgLstTypeSquare	: "Квадрат",
+DlgLstTypeNumbers	: "Номери (1, 2, 3)",
+DlgLstTypeLCase		: "Літери нижнього регістра(a, b, c)",
+DlgLstTypeUCase		: "Букви верхнього регістра (A, B, C)",
+DlgLstTypeSRoman	: "Малі римські літери (i, ii, iii)",
+DlgLstTypeLRoman	: "Великі римські літери (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Загальні",
+DlgDocBackTab		: "Заднє тло",
+DlgDocColorsTab		: "Кольори та відступи",
+DlgDocMetaTab		: "Мета дані",
+
+DlgDocPageTitle		: "Заголовок сторінки",
+DlgDocLangDir		: "Напрямок тексту",
+DlgDocLangDirLTR	: "Зліва на право (LTR)",
+DlgDocLangDirRTL	: "Зправа на лево (RTL)",
+DlgDocLangCode		: "Код мови",
+DlgDocCharSet		: "Кодування набору символів",
+DlgDocCharSetCE		: "Центрально-європейська",
+DlgDocCharSetCT		: "Китайська традиційна (Big5)",
+DlgDocCharSetCR		: "Кирилиця",
+DlgDocCharSetGR		: "Грецька",
+DlgDocCharSetJP		: "Японська",
+DlgDocCharSetKR		: "Корейська",
+DlgDocCharSetTR		: "Турецька",
+DlgDocCharSetUN		: "Юнікод (UTF-8)",
+DlgDocCharSetWE		: "Західно-европейская",
+DlgDocCharSetOther	: "Інше кодування набору символів",
+
+DlgDocDocType		: "Заголовок типу документу",
+DlgDocDocTypeOther	: "Інший заголовок типу документу",
+DlgDocIncXHTML		: "Ввімкнути XHTML оголошення",
+DlgDocBgColor		: "Колір тла",
+DlgDocBgImage		: "URL зображення тла",
+DlgDocBgNoScroll	: "Тло без прокрутки",
+DlgDocCText			: "Текст",
+DlgDocCLink			: "Посилання",
+DlgDocCVisited		: "Відвідане посилання",
+DlgDocCActive		: "Активне посилання",
+DlgDocMargins		: "Відступи сторінки",
+DlgDocMaTop			: "Верхній",
+DlgDocMaLeft		: "Лівий",
+DlgDocMaRight		: "Правий",
+DlgDocMaBottom		: "Нижній",
+DlgDocMeIndex		: "Ключові слова документа (розділені комами)",
+DlgDocMeDescr		: "Опис документа",
+DlgDocMeAuthor		: "Автор",
+DlgDocMeCopy		: "Авторські права",
+DlgDocPreview		: "Попередній перегляд",
+
+// Templates Dialog
+Templates			: "Шаблони",
+DlgTemplatesTitle	: "Шаблони змісту",
+DlgTemplatesSelMsg	: "Оберіть, будь ласка, шаблон для відкриття в редакторі<br>(поточний зміст буде втрачено):",
+DlgTemplatesLoading	: "Завантаження списку шаблонів. Зачекайте, будь ласка...",
+DlgTemplatesNoTpl	: "(Не визначено жодного шаблону)",
+DlgTemplatesReplace	: "Замінити поточний вміст",
+
+// About Dialog
+DlgAboutAboutTab	: "Про програму",
+DlgAboutBrowserInfoTab	: "Інформація браузера",
+DlgAboutLicenseTab	: "Ліцензія",
+DlgAboutVersion		: "Версія",
+DlgAboutInfo		: "Додаткову інформацію дивіться на "
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/zh-cn.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/zh-cn.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/zh-cn.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Chinese Simplified language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "折叠工具栏",
+ToolbarExpand		: "展开工具栏",
+
+// Toolbar Items and Context Menu
+Save				: "保存",
+NewPage				: "新建",
+Preview				: "预览",
+Cut					: "剪切",
+Copy				: "复制",
+Paste				: "粘贴",
+PasteText			: "粘贴为无格式文本",
+PasteWord			: "从 MS Word 粘贴",
+Print				: "打印",
+SelectAll			: "全选",
+RemoveFormat		: "清除格式",
+InsertLinkLbl		: "超链接",
+InsertLink			: "插入/编辑超链接",
+RemoveLink			: "取消超链接",
+Anchor				: "插入/编辑锚点链接",
+InsertImageLbl		: "图象",
+InsertImage			: "插入/编辑图象",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "插入/编辑 Flash",
+InsertTableLbl		: "表格",
+InsertTable			: "插入/编辑表格",
+InsertLineLbl		: "水平线",
+InsertLine			: "插入水平线",
+InsertSpecialCharLbl: "特殊符号",
+InsertSpecialChar	: "插入特殊符号",
+InsertSmileyLbl		: "表情符",
+InsertSmiley		: "插入表情图标",
+About				: "关于 FCKeditor",
+Bold				: "加粗",
+Italic				: "倾斜",
+Underline			: "下划线",
+StrikeThrough		: "删除线",
+Subscript			: "下标",
+Superscript			: "上标",
+LeftJustify			: "左对齐",
+CenterJustify		: "居中对齐",
+RightJustify		: "右对齐",
+BlockJustify		: "两端对齐",
+DecreaseIndent		: "减少缩进量",
+IncreaseIndent		: "增加缩进量",
+Undo				: "撤消",
+Redo				: "重做",
+NumberedListLbl		: "编号列表",
+NumberedList		: "插入/删除编号列表",
+BulletedListLbl		: "项目列表",
+BulletedList		: "插入/删除项目列表",
+ShowTableBorders	: "显示表格边框",
+ShowDetails			: "显示详细资料",
+Style				: "样式",
+FontFormat			: "格式",
+Font				: "字体",
+FontSize			: "大小",
+TextColor			: "文本颜色",
+BGColor				: "背景颜色",
+Source				: "源代码",
+Find				: "查找",
+Replace				: "替换",
+SpellCheck			: "拼写检查",
+UniversalKeyboard	: "软键盘",
+PageBreakLbl		: "分页符",
+PageBreak			: "插入分页符",
+
+Form			: "表单",
+Checkbox		: "复选框",
+RadioButton		: "单选按钮",
+TextField		: "单行文本",
+Textarea		: "多行文本",
+HiddenField		: "隐藏域",
+Button			: "按钮",
+SelectionField	: "列表/菜单",
+ImageButton		: "图像域",
+
+FitWindow		: "全屏编辑",
+
+// Context Menu
+EditLink			: "编辑超链接",
+CellCM				: "单元格",
+RowCM				: "行",
+ColumnCM			: "列",
+InsertRow			: "插入行",
+DeleteRows			: "删除行",
+InsertColumn		: "插入列",
+DeleteColumns		: "删除列",
+InsertCell			: "插入单元格",
+DeleteCells			: "删除单元格",
+MergeCells			: "合并单元格",
+SplitCell			: "拆分单元格",
+TableDelete			: "删除表格",
+CellProperties		: "单元格属性",
+TableProperties		: "表格属性",
+ImageProperties		: "图象属性",
+FlashProperties		: "Flash 属性",
+
+AnchorProp			: "锚点链接属性",
+ButtonProp			: "按钮属性",
+CheckboxProp		: "复选框属性",
+HiddenFieldProp		: "隐藏域属性",
+RadioButtonProp		: "单选按钮属性",
+ImageButtonProp		: "图像域属性",
+TextFieldProp		: "单行文本属性",
+SelectionFieldProp	: "菜单/列表属性",
+TextareaProp		: "多行文本属性",
+FormProp			: "表单属性",
+
+FontFormats			: "普通;已编排格式;地址;标题 1;标题 2;标题 3;标题 4;标题 5;标题 6;段落(DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "正在处理 XHTML，请稍等...",
+Done				: "完成",
+PasteWordConfirm	: "您要粘贴的内容好像是来自 MS Word，是否要清除 MS Word 格式后再粘贴？",
+NotCompatiblePaste	: "该命令需要 Internet Explorer 5.5 或更高版本的支持，是否按常规粘贴进行？",
+UnknownToolbarItem	: "未知工具栏项目 \"%1\"",
+UnknownCommand		: "未知命令名称 \"%1\"",
+NotImplemented		: "命令无法执行",
+UnknownToolbarSet	: "工具栏设置 \"%1\" 不存在",
+NoActiveX			: "浏览器安全设置限制了本编辑器的某些功能。您必须启用安全设置中的“运行 ActiveX 控件和插件”，否则将出现某些错误并缺少功能。",
+BrowseServerBlocked : "无法打开资源浏览器，请确认是否启用了禁止弹出窗口。",
+DialogBlocked		: "无法打开对话框窗口，请确认是否启用了禁止弹出窗口或网页对话框（IE）。",
+
+// Dialogs
+DlgBtnOK			: "确定",
+DlgBtnCancel		: "取消",
+DlgBtnClose			: "关闭",
+DlgBtnBrowseServer	: "浏览服务器",
+DlgAdvancedTag		: "高级",
+DlgOpOther			: "<其它>",
+DlgInfoTab			: "信息",
+DlgAlertUrl			: "请插入 URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<没有设置>",
+DlgGenId			: "ID",
+DlgGenLangDir		: "语言方向",
+DlgGenLangDirLtr	: "从左到右 (LTR)",
+DlgGenLangDirRtl	: "从右到左 (RTL)",
+DlgGenLangCode		: "语言代码",
+DlgGenAccessKey		: "访问键",
+DlgGenName			: "名称",
+DlgGenTabIndex		: "Tab 键次序",
+DlgGenLongDescr		: "详细说明地址",
+DlgGenClass			: "样式类名称",
+DlgGenTitle			: "标题",
+DlgGenContType		: "内容类型",
+DlgGenLinkCharset	: "字符编码",
+DlgGenStyle			: "行内样式",
+
+// Image Dialog
+DlgImgTitle			: "图象属性",
+DlgImgInfoTab		: "图象",
+DlgImgBtnUpload		: "发送到服务器上",
+DlgImgURL			: "源文件",
+DlgImgUpload		: "上传",
+DlgImgAlt			: "替换文本",
+DlgImgWidth			: "宽度",
+DlgImgHeight		: "高度",
+DlgImgLockRatio		: "锁定比例",
+DlgBtnResetSize		: "恢复尺寸",
+DlgImgBorder		: "边框大小",
+DlgImgHSpace		: "水平间距",
+DlgImgVSpace		: "垂直间距",
+DlgImgAlign			: "对齐方式",
+DlgImgAlignLeft		: "左对齐",
+DlgImgAlignAbsBottom: "绝对底边",
+DlgImgAlignAbsMiddle: "绝对居中",
+DlgImgAlignBaseline	: "基线",
+DlgImgAlignBottom	: "底边",
+DlgImgAlignMiddle	: "居中",
+DlgImgAlignRight	: "右对齐",
+DlgImgAlignTextTop	: "文本上方",
+DlgImgAlignTop		: "顶端",
+DlgImgPreview		: "预览",
+DlgImgAlertUrl		: "请输入图象地址",
+DlgImgLinkTab		: "链接",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash 属性",
+DlgFlashChkPlay		: "自动播放",
+DlgFlashChkLoop		: "循环",
+DlgFlashChkMenu		: "启用 Flash 菜单",
+DlgFlashScale		: "缩放",
+DlgFlashScaleAll	: "全部显示",
+DlgFlashScaleNoBorder	: "无边框",
+DlgFlashScaleFit	: "严格匹配",
+
+// Link Dialog
+DlgLnkWindowTitle	: "超链接",
+DlgLnkInfoTab		: "超链接信息",
+DlgLnkTargetTab		: "目标",
+
+DlgLnkType			: "超链接类型",
+DlgLnkTypeURL		: "超链接",
+DlgLnkTypeAnchor	: "页内锚点链接",
+DlgLnkTypeEMail		: "电子邮件",
+DlgLnkProto			: "协议",
+DlgLnkProtoOther	: "<其它>",
+DlgLnkURL			: "地址",
+DlgLnkAnchorSel		: "选择一个锚点",
+DlgLnkAnchorByName	: "按锚点名称",
+DlgLnkAnchorById	: "按锚点 ID",
+DlgLnkNoAnchors		: "<此文档没有可用的锚点>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "地址",
+DlgLnkEMailSubject	: "主题",
+DlgLnkEMailBody		: "内容",
+DlgLnkUpload		: "上传",
+DlgLnkBtnUpload		: "发送到服务器上",
+
+DlgLnkTarget		: "目标",
+DlgLnkTargetFrame	: "<框架>",
+DlgLnkTargetPopup	: "<弹出窗口>",
+DlgLnkTargetBlank	: "新窗口 (_blank)",
+DlgLnkTargetParent	: "父窗口 (_parent)",
+DlgLnkTargetSelf	: "本窗口 (_self)",
+DlgLnkTargetTop		: "整页 (_top)",
+DlgLnkTargetFrameName	: "目标框架名称",
+DlgLnkPopWinName	: "弹出窗口名称",
+DlgLnkPopWinFeat	: "弹出窗口属性",
+DlgLnkPopResize		: "调整大小",
+DlgLnkPopLocation	: "地址栏",
+DlgLnkPopMenu		: "菜单栏",
+DlgLnkPopScroll		: "滚动条",
+DlgLnkPopStatus		: "状态栏",
+DlgLnkPopToolbar	: "工具栏",
+DlgLnkPopFullScrn	: "全屏 (IE)",
+DlgLnkPopDependent	: "依附 (NS)",
+DlgLnkPopWidth		: "宽",
+DlgLnkPopHeight		: "高",
+DlgLnkPopLeft		: "左",
+DlgLnkPopTop		: "右",
+
+DlnLnkMsgNoUrl		: "请输入超链接地址",
+DlnLnkMsgNoEMail	: "请输入电子邮件地址",
+DlnLnkMsgNoAnchor	: "请选择一个锚点",
+DlnLnkMsgInvPopName	: "弹出窗口名称必须以字母开头，并且不能含有空格。",
+
+// Color Dialog
+DlgColorTitle		: "选择颜色",
+DlgColorBtnClear	: "清除",
+DlgColorHighlight	: "预览",
+DlgColorSelected	: "选择",
+
+// Smiley Dialog
+DlgSmileyTitle		: "插入表情图标",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "选择特殊符号",
+
+// Table Dialog
+DlgTableTitle		: "表格属性",
+DlgTableRows		: "行数",
+DlgTableColumns		: "列数",
+DlgTableBorder		: "边框",
+DlgTableAlign		: "对齐",
+DlgTableAlignNotSet	: "<没有设置>",
+DlgTableAlignLeft	: "左对齐",
+DlgTableAlignCenter	: "居中",
+DlgTableAlignRight	: "右对齐",
+DlgTableWidth		: "宽度",
+DlgTableWidthPx		: "像素",
+DlgTableWidthPc		: "百分比",
+DlgTableHeight		: "高度",
+DlgTableCellSpace	: "间距",
+DlgTableCellPad		: "边距",
+DlgTableCaption		: "标题",
+DlgTableSummary		: "摘要",
+
+// Table Cell Dialog
+DlgCellTitle		: "单元格属性",
+DlgCellWidth		: "宽度",
+DlgCellWidthPx		: "像素",
+DlgCellWidthPc		: "百分比",
+DlgCellHeight		: "高度",
+DlgCellWordWrap		: "自动换行",
+DlgCellWordWrapNotSet	: "<没有设置>",
+DlgCellWordWrapYes	: "是",
+DlgCellWordWrapNo	: "否",
+DlgCellHorAlign		: "水平对齐",
+DlgCellHorAlignNotSet	: "<没有设置>",
+DlgCellHorAlignLeft	: "左对齐",
+DlgCellHorAlignCenter	: "居中",
+DlgCellHorAlignRight: "右对齐",
+DlgCellVerAlign		: "垂直对齐",
+DlgCellVerAlignNotSet	: "<没有设置>",
+DlgCellVerAlignTop	: "顶端",
+DlgCellVerAlignMiddle	: "居中",
+DlgCellVerAlignBottom	: "底部",
+DlgCellVerAlignBaseline	: "基线",
+DlgCellRowSpan		: "纵跨行数",
+DlgCellCollSpan		: "横跨列数",
+DlgCellBackColor	: "背景颜色",
+DlgCellBorderColor	: "边框颜色",
+DlgCellBtnSelect	: "选择...",
+
+// Find Dialog
+DlgFindTitle		: "查找",
+DlgFindFindBtn		: "查找",
+DlgFindNotFoundMsg	: "指定文本没有找到。",
+
+// Replace Dialog
+DlgReplaceTitle			: "替换",
+DlgReplaceFindLbl		: "查找:",
+DlgReplaceReplaceLbl	: "替换:",
+DlgReplaceCaseChk		: "区分大小写",
+DlgReplaceReplaceBtn	: "替换",
+DlgReplaceReplAllBtn	: "全部替换",
+DlgReplaceWordChk		: "全字匹配",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "您的浏览器安全设置不允许编辑器自动执行剪切操作，请使用键盘快捷键(Ctrl+X)来完成。",
+PasteErrorCopy	: "您的浏览器安全设置不允许编辑器自动执行复制操作，请使用键盘快捷键(Ctrl+C)来完成。",
+
+PasteAsText		: "粘贴为无格式文本",
+PasteFromWord	: "从 MS Word 粘贴",
+
+DlgPasteMsg2	: "请使用键盘快捷键(<STRONG>Ctrl+V</STRONG>)把内容粘贴到下面的方框里，再按 <STRONG>确定</STRONG>。",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "忽略 Font 标签",
+DlgPasteRemoveStyles	: "清理 CSS 样式",
+DlgPasteCleanBox		: "清空上面内容",
+
+// Color Picker
+ColorAutomatic	: "自动",
+ColorMoreColors	: "其它颜色...",
+
+// Document Properties
+DocProps		: "页面属性",
+
+// Anchor Dialog
+DlgAnchorTitle		: "命名锚点",
+DlgAnchorName		: "锚点名称",
+DlgAnchorErrorName	: "请输入锚点名称",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "没有在字典里",
+DlgSpellChangeTo		: "更改为",
+DlgSpellBtnIgnore		: "忽略",
+DlgSpellBtnIgnoreAll	: "全部忽略",
+DlgSpellBtnReplace		: "替换",
+DlgSpellBtnReplaceAll	: "全部替换",
+DlgSpellBtnUndo			: "撤消",
+DlgSpellNoSuggestions	: "- 没有建议 -",
+DlgSpellProgress		: "正在进行拼写检查...",
+DlgSpellNoMispell		: "拼写检查完成：没有发现拼写错误",
+DlgSpellNoChanges		: "拼写检查完成：没有更改任何单词",
+DlgSpellOneChange		: "拼写检查完成：更改了一个单词",
+DlgSpellManyChanges		: "拼写检查完成：更改了 %1 个单词",
+
+IeSpellDownload			: "拼写检查插件还没安装，你是否想现在就下载？",
+
+// Button Dialog
+DlgButtonText		: "标签(值)",
+DlgButtonType		: "类型",
+DlgButtonTypeBtn	: "按钮",
+DlgButtonTypeSbm	: "提交",
+DlgButtonTypeRst	: "重设",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "名称",
+DlgCheckboxValue	: "选定值",
+DlgCheckboxSelected	: "已勾选",
+
+// Form Dialog
+DlgFormName		: "名称",
+DlgFormAction	: "动作",
+DlgFormMethod	: "方法",
+
+// Select Field Dialog
+DlgSelectName		: "名称",
+DlgSelectValue		: "选定",
+DlgSelectSize		: "高度",
+DlgSelectLines		: "行",
+DlgSelectChkMulti	: "允许多选",
+DlgSelectOpAvail	: "列表值",
+DlgSelectOpText		: "标签",
+DlgSelectOpValue	: "值",
+DlgSelectBtnAdd		: "新增",
+DlgSelectBtnModify	: "修改",
+DlgSelectBtnUp		: "上移",
+DlgSelectBtnDown	: "下移",
+DlgSelectBtnSetValue : "设为初始化时选定",
+DlgSelectBtnDelete	: "删除",
+
+// Textarea Dialog
+DlgTextareaName	: "名称",
+DlgTextareaCols	: "字符宽度",
+DlgTextareaRows	: "行数",
+
+// Text Field Dialog
+DlgTextName			: "名称",
+DlgTextValue		: "初始值",
+DlgTextCharWidth	: "字符宽度",
+DlgTextMaxChars		: "最多字符数",
+DlgTextType			: "类型",
+DlgTextTypeText		: "文本",
+DlgTextTypePass		: "密码",
+
+// Hidden Field Dialog
+DlgHiddenName	: "名称",
+DlgHiddenValue	: "初始值",
+
+// Bulleted List Dialog
+BulletedListProp	: "项目列表属性",
+NumberedListProp	: "编号列表属性",
+DlgLstStart			: "开始序号",
+DlgLstType			: "列表类型",
+DlgLstTypeCircle	: "圆圈",
+DlgLstTypeDisc		: "圆点",
+DlgLstTypeSquare	: "方块",
+DlgLstTypeNumbers	: "数字 (1, 2, 3)",
+DlgLstTypeLCase		: "小写字母 (a, b, c)",
+DlgLstTypeUCase		: "大写字母 (A, B, C)",
+DlgLstTypeSRoman	: "小写罗马数字 (i, ii, iii)",
+DlgLstTypeLRoman	: "大写罗马数字 (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "常规",
+DlgDocBackTab		: "背景",
+DlgDocColorsTab		: "颜色和边距",
+DlgDocMetaTab		: "Meta 数据",
+
+DlgDocPageTitle		: "页面标题",
+DlgDocLangDir		: "语言方向",
+DlgDocLangDirLTR	: "从左到右 (LTR)",
+DlgDocLangDirRTL	: "从右到左 (RTL)",
+DlgDocLangCode		: "语言代码",
+DlgDocCharSet		: "字符编码",
+DlgDocCharSetCE		: "中欧",
+DlgDocCharSetCT		: "繁体中文 (Big5)",
+DlgDocCharSetCR		: "西里尔文",
+DlgDocCharSetGR		: "希腊文",
+DlgDocCharSetJP		: "日文",
+DlgDocCharSetKR		: "韩文",
+DlgDocCharSetTR		: "土耳其文",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "西欧",
+DlgDocCharSetOther	: "其它字符编码",
+
+DlgDocDocType		: "文档类型",
+DlgDocDocTypeOther	: "其它文档类型",
+DlgDocIncXHTML		: "包含 XHTML 声明",
+DlgDocBgColor		: "背景颜色",
+DlgDocBgImage		: "背景图像",
+DlgDocBgNoScroll	: "不滚动背景图像",
+DlgDocCText			: "文本",
+DlgDocCLink			: "超链接",
+DlgDocCVisited		: "已访问的超链接",
+DlgDocCActive		: "活动超链接",
+DlgDocMargins		: "页面边距",
+DlgDocMaTop			: "上",
+DlgDocMaLeft		: "左",
+DlgDocMaRight		: "右",
+DlgDocMaBottom		: "下",
+DlgDocMeIndex		: "页面索引关键字 (用半角逗号[,]分隔)",
+DlgDocMeDescr		: "页面说明",
+DlgDocMeAuthor		: "作者",
+DlgDocMeCopy		: "版权",
+DlgDocPreview		: "预览",
+
+// Templates Dialog
+Templates			: "模板",
+DlgTemplatesTitle	: "内容模板",
+DlgTemplatesSelMsg	: "请选择编辑器内容模板<br>(当前内容将会被清除替换):",
+DlgTemplatesLoading	: "正在加载模板列表，请稍等...",
+DlgTemplatesNoTpl	: "(没有模板)",
+DlgTemplatesReplace	: "替换当前内容",
+
+// About Dialog
+DlgAboutAboutTab	: "关于",
+DlgAboutBrowserInfoTab	: "浏览器信息",
+DlgAboutLicenseTab	: "许可证",
+DlgAboutVersion		: "版本",
+DlgAboutInfo		: "要获得更多信息请访问 "
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ro.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ro.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ro.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Romanian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Ascunde bara cu opţiuni",
+ToolbarExpand		: "Expandează bara cu opţiuni",
+
+// Toolbar Items and Context Menu
+Save				: "Salvează",
+NewPage				: "Pagină nouă",
+Preview				: "Previzualizare",
+Cut					: "Taie",
+Copy				: "Copiază",
+Paste				: "Adaugă",
+PasteText			: "Adaugă ca text simplu",
+PasteWord			: "Adaugă din Word",
+Print				: "Printează",
+SelectAll			: "Selectează tot",
+RemoveFormat		: "Înlătură formatarea",
+InsertLinkLbl		: "Link (Legătură web)",
+InsertLink			: "Inserează/Editează link (legătură web)",
+RemoveLink			: "Înlătură link (legătură web)",
+Anchor				: "Inserează/Editează ancoră",
+InsertImageLbl		: "Imagine",
+InsertImage			: "Inserează/Editează imagine",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Inserează/Editează flash",
+InsertTableLbl		: "Tabel",
+InsertTable			: "Inserează/Editează tabel",
+InsertLineLbl		: "Linie",
+InsertLine			: "Inserează linie orizontă",
+InsertSpecialCharLbl: "Caracter special",
+InsertSpecialChar	: "Inserează caracter special",
+InsertSmileyLbl		: "Figură expresivă (Emoticon)",
+InsertSmiley		: "Inserează Figură expresivă (Emoticon)",
+About				: "Despre FCKeditor",
+Bold				: "Îngroşat (bold)",
+Italic				: "Înclinat (italic)",
+Underline			: "Subliniat (underline)",
+StrikeThrough		: "Tăiat (strike through)",
+Subscript			: "Indice (subscript)",
+Superscript			: "Putere (superscript)",
+LeftJustify			: "Aliniere la stânga",
+CenterJustify		: "Aliniere centrală",
+RightJustify		: "Aliniere la dreapta",
+BlockJustify		: "Aliniere în bloc (Block Justify)",
+DecreaseIndent		: "Scade indentarea",
+IncreaseIndent		: "Creşte indentarea",
+Undo				: "Starea anterioară (undo)",
+Redo				: "Starea ulterioară (redo)",
+NumberedListLbl		: "Listă numerotată",
+NumberedList		: "Inserează/Şterge listă numerotată",
+BulletedListLbl		: "Listă cu puncte",
+BulletedList		: "Inserează/Şterge listă cu puncte",
+ShowTableBorders	: "Arată marginile tabelului",
+ShowDetails			: "Arată detalii",
+Style				: "Stil",
+FontFormat			: "Formatare",
+Font				: "Font",
+FontSize			: "Mărime",
+TextColor			: "Culoarea textului",
+BGColor				: "Coloarea fundalului",
+Source				: "Sursa",
+Find				: "Găseşte",
+Replace				: "Înlocuieşte",
+SpellCheck			: "Verifică text",
+UniversalKeyboard	: "Tastatură universală",
+PageBreakLbl		: "Separator de pagină (Page Break)",
+PageBreak			: "Inserează separator de pagină (Page Break)",
+
+Form			: "Formular (Form)",
+Checkbox		: "Bifă (Checkbox)",
+RadioButton		: "Buton radio (RadioButton)",
+TextField		: "Câmp text (TextField)",
+Textarea		: "Suprafaţă text (Textarea)",
+HiddenField		: "Câmp ascuns (HiddenField)",
+Button			: "Buton",
+SelectionField	: "Câmp selecţie (SelectionField)",
+ImageButton		: "Buton imagine (ImageButton)",
+
+FitWindow		: "Maximizează mărimea editorului",
+
+// Context Menu
+EditLink			: "Editează Link",
+CellCM				: "Celulă",
+RowCM				: "Linie",
+ColumnCM			: "Coloană",
+InsertRow			: "Inserează linie",
+DeleteRows			: "Şterge linii",
+InsertColumn		: "Inserează coloană",
+DeleteColumns		: "Şterge celule",
+InsertCell			: "Inserează celulă",
+DeleteCells			: "Şterge celule",
+MergeCells			: "Uneşte celule",
+SplitCell			: "Împarte celulă",
+TableDelete			: "Şterge tabel",
+CellProperties		: "Proprietăţile celulei",
+TableProperties		: "Proprietăţile tabelului",
+ImageProperties		: "Proprietăţile imaginii",
+FlashProperties		: "Proprietăţile flash-ului",
+
+AnchorProp			: "Proprietăţi ancoră",
+ButtonProp			: "Proprietăţi buton",
+CheckboxProp		: "Proprietăţi bifă (Checkbox)",
+HiddenFieldProp		: "Proprietăţi câmp ascuns (Hidden Field)",
+RadioButtonProp		: "Proprietăţi buton radio (Radio Button)",
+ImageButtonProp		: "Proprietăţi buton imagine (Image Button)",
+TextFieldProp		: "Proprietăţi câmp text (Text Field)",
+SelectionFieldProp	: "Proprietăţi câmp selecţie (Selection Field)",
+TextareaProp		: "Proprietăţi suprafaţă text (Textarea)",
+FormProp			: "Proprietăţi formular (Form)",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html	//MISSING
+
+// Alerts and Messages
+ProcessingXHTML		: "Procesăm XHTML. Vă rugăm aşteptaţi...",
+Done				: "Am terminat",
+PasteWordConfirm	: "Textul pe care doriţi să-l adăugaţi pare a fi formatat pentru Word. Doriţi să-l curăţaţi de această formatare înainte de a-l adăuga?",
+NotCompatiblePaste	: "Această facilitate e disponibilă doar pentru Microsoft Internet Explorer, versiunea 5.5 sau ulterioară. Vreţi să-l adăugaţi fără a-i fi înlăturat formatarea?",
+UnknownToolbarItem	: "Obiectul \"%1\" din bara cu opţiuni necunoscut",
+UnknownCommand		: "Comanda \"%1\" necunoscută",
+NotImplemented		: "Comandă neimplementată",
+UnknownToolbarSet	: "Grupul din bara cu opţiuni \"%1\" nu există",
+NoActiveX			: "Setările de securitate ale programului dvs. cu care navigaţi pe internet (browser) pot limita anumite funcţionalităţi ale editorului. Pentru a evita asta, trebuie să activaţi opţiunea \"Run ActiveX controls and plug-ins\". Poate veţi întâlni erori sau veţi observa funcţionalităţi lipsă.",
+BrowseServerBlocked : "The resources browser could not be opened. Asiguraţi-vă că nu e activ niciun \"popup blocker\" (funcţionalitate a programului de navigat (browser) sau a unui plug-in al acestuia de a bloca deschiderea unui noi ferestre).",
+DialogBlocked		: "Nu a fost posibilă deschiderea unei ferestre de dialog. Asiguraţi-vă că nu e activ niciun \"popup blocker\" (funcţionalitate a programului de navigat (browser) sau a unui plug-in al acestuia de a bloca deschiderea unui noi ferestre).",
+
+// Dialogs
+DlgBtnOK			: "Bine",
+DlgBtnCancel		: "Anulare",
+DlgBtnClose			: "Închidere",
+DlgBtnBrowseServer	: "Răsfoieşte server",
+DlgAdvancedTag		: "Avansat",
+DlgOpOther			: "<Altul>",
+DlgInfoTab			: "Informaţii",
+DlgAlertUrl			: "Vă rugăm să scrieţi URL-ul",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nesetat>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Direcţia cuvintelor",
+DlgGenLangDirLtr	: "stânga-dreapta (LTR)",
+DlgGenLangDirRtl	: "dreapta-stânga (RTL)",
+DlgGenLangCode		: "Codul limbii",
+DlgGenAccessKey		: "Tasta de acces",
+DlgGenName			: "Nume",
+DlgGenTabIndex		: "Indexul tabului",
+DlgGenLongDescr		: "Descrierea lungă URL",
+DlgGenClass			: "Clasele cu stilul paginii (CSS)",
+DlgGenTitle			: "Titlul consultativ",
+DlgGenContType		: "Tipul consultativ al titlului",
+DlgGenLinkCharset	: "Setul de caractere al resursei legate",
+DlgGenStyle			: "Stil",
+
+// Image Dialog
+DlgImgTitle			: "Proprietăţile imaginii",
+DlgImgInfoTab		: "Informaţii despre imagine",
+DlgImgBtnUpload		: "Trimite la server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Încarcă",
+DlgImgAlt			: "Text alternativ",
+DlgImgWidth			: "Lăţime",
+DlgImgHeight		: "Înălţime",
+DlgImgLockRatio		: "Păstrează proporţiile",
+DlgBtnResetSize		: "Resetează mărimea",
+DlgImgBorder		: "Margine",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Aliniere",
+DlgImgAlignLeft		: "Stânga",
+DlgImgAlignAbsBottom: "Jos absolut (Abs Bottom)",
+DlgImgAlignAbsMiddle: "Mijloc absolut (Abs Middle)",
+DlgImgAlignBaseline	: "Linia de jos (Baseline)",
+DlgImgAlignBottom	: "Jos",
+DlgImgAlignMiddle	: "Mijloc",
+DlgImgAlignRight	: "Dreapta",
+DlgImgAlignTextTop	: "Text sus",
+DlgImgAlignTop		: "Sus",
+DlgImgPreview		: "Previzualizare",
+DlgImgAlertUrl		: "Vă rugăm să scrieţi URL-ul imaginii",
+DlgImgLinkTab		: "Link (Legătură web)",
+
+// Flash Dialog
+DlgFlashTitle		: "Proprietăţile flash-ului",
+DlgFlashChkPlay		: "Rulează automat",
+DlgFlashChkLoop		: "Repetă (Loop)",
+DlgFlashChkMenu		: "Activează meniul flash",
+DlgFlashScale		: "Scală",
+DlgFlashScaleAll	: "Arată tot",
+DlgFlashScaleNoBorder	: "Fără margini (No border)",
+DlgFlashScaleFit	: "Potriveşte",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link (Legătură web)",
+DlgLnkInfoTab		: "Informaţii despre link (Legătură web)",
+DlgLnkTargetTab		: "Ţintă (Target)",
+
+DlgLnkType			: "Tipul link-ului (al legăturii web)",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Ancoră în această pagină",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<altul>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Selectaţi o ancoră",
+DlgLnkAnchorByName	: "după numele ancorei",
+DlgLnkAnchorById	: "după Id-ul elementului",
+DlgLnkNoAnchors		: "<Nicio ancoră disponibilă în document>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Adresă de e-mail",
+DlgLnkEMailSubject	: "Subiectul mesajului",
+DlgLnkEMailBody		: "Conţinutul mesajului",
+DlgLnkUpload		: "Încarcă",
+DlgLnkBtnUpload		: "Trimite la server",
+
+DlgLnkTarget		: "Ţintă (Target)",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<fereastra popup>",
+DlgLnkTargetBlank	: "Fereastră nouă (_blank)",
+DlgLnkTargetParent	: "Fereastra părinte (_parent)",
+DlgLnkTargetSelf	: "Aceeaşi fereastră (_self)",
+DlgLnkTargetTop		: "Fereastra din topul ierarhiei (_top)",
+DlgLnkTargetFrameName	: "Numele frame-ului ţintă",
+DlgLnkPopWinName	: "Numele ferestrei popup",
+DlgLnkPopWinFeat	: "Proprietăţile ferestrei popup",
+DlgLnkPopResize		: "Scalabilă",
+DlgLnkPopLocation	: "Bara de locaţie",
+DlgLnkPopMenu		: "Bara de meniu",
+DlgLnkPopScroll		: "Scroll Bars",
+DlgLnkPopStatus		: "Bara de status",
+DlgLnkPopToolbar	: "Bara de opţiuni",
+DlgLnkPopFullScrn	: "Tot ecranul (Full Screen)(IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "Lăţime",
+DlgLnkPopHeight		: "Înălţime",
+DlgLnkPopLeft		: "Poziţia la stânga",
+DlgLnkPopTop		: "Poziţia la dreapta",
+
+DlnLnkMsgNoUrl		: "Vă rugăm să scrieţi URL-ul",
+DlnLnkMsgNoEMail	: "Vă rugăm să scrieţi adresa de e-mail",
+DlnLnkMsgNoAnchor	: "Vă rugăm să selectaţi o ancoră",
+DlnLnkMsgInvPopName	: "Numele 'popup'-ului trebuie să înceapă cu un caracter alfabetic şi trebuie să nu conţină spaţii",
+
+// Color Dialog
+DlgColorTitle		: "Selectează culoare",
+DlgColorBtnClear	: "Curăţă",
+DlgColorHighlight	: "Subliniază (Highlight)",
+DlgColorSelected	: "Selectat",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Inserează o figură expresivă (Emoticon)",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Selectează caracter special",
+
+// Table Dialog
+DlgTableTitle		: "Proprietăţile tabelului",
+DlgTableRows		: "Linii",
+DlgTableColumns		: "Coloane",
+DlgTableBorder		: "Mărimea marginii",
+DlgTableAlign		: "Aliniament",
+DlgTableAlignNotSet	: "<Nesetat>",
+DlgTableAlignLeft	: "Stânga",
+DlgTableAlignCenter	: "Centru",
+DlgTableAlignRight	: "Dreapta",
+DlgTableWidth		: "Lăţime",
+DlgTableWidthPx		: "pixeli",
+DlgTableWidthPc		: "procente",
+DlgTableHeight		: "Înălţime",
+DlgTableCellSpace	: "Spaţiu între celule",
+DlgTableCellPad		: "Spaţiu în cadrul celulei",
+DlgTableCaption		: "Titlu (Caption)",
+DlgTableSummary		: "Rezumat",
+
+// Table Cell Dialog
+DlgCellTitle		: "Proprietăţile celulei",
+DlgCellWidth		: "Lăţime",
+DlgCellWidthPx		: "pixeli",
+DlgCellWidthPc		: "procente",
+DlgCellHeight		: "Înălţime",
+DlgCellWordWrap		: "Desparte cuvintele (Wrap)",
+DlgCellWordWrapNotSet	: "<Nesetat>",
+DlgCellWordWrapYes	: "Da",
+DlgCellWordWrapNo	: "Nu",
+DlgCellHorAlign		: "Aliniament orizontal",
+DlgCellHorAlignNotSet	: "<Nesetat>",
+DlgCellHorAlignLeft	: "Stânga",
+DlgCellHorAlignCenter	: "Centru",
+DlgCellHorAlignRight: "Dreapta",
+DlgCellVerAlign		: "Aliniament vertical",
+DlgCellVerAlignNotSet	: "<Nesetat>",
+DlgCellVerAlignTop	: "Sus",
+DlgCellVerAlignMiddle	: "Mijloc",
+DlgCellVerAlignBottom	: "Jos",
+DlgCellVerAlignBaseline	: "Linia de jos (Baseline)",
+DlgCellRowSpan		: "Lungimea în linii (Span)",
+DlgCellCollSpan		: "Lungimea în coloane (Span)",
+DlgCellBackColor	: "Culoarea fundalului",
+DlgCellBorderColor	: "Culoarea marginii",
+DlgCellBtnSelect	: "Selectaţi...",
+
+// Find Dialog
+DlgFindTitle		: "Găseşte",
+DlgFindFindBtn		: "Găseşte",
+DlgFindNotFoundMsg	: "Textul specificat nu a fost găsit.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Replace",
+DlgReplaceFindLbl		: "Găseşte:",
+DlgReplaceReplaceLbl	: "Înlocuieşte cu:",
+DlgReplaceCaseChk		: "Deosebeşte majuscule de minuscule (Match case)",
+DlgReplaceReplaceBtn	: "Înlocuieşte",
+DlgReplaceReplAllBtn	: "Înlocuieşte tot",
+DlgReplaceWordChk		: "Doar cuvintele întregi",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de tăiere. Vă rugăm folosiţi tastatura (Ctrl+X).",
+PasteErrorCopy	: "Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de copiere. Vă rugăm folosiţi tastatura (Ctrl+C).",
+
+PasteAsText		: "Adaugă ca text simplu (Plain Text)",
+PasteFromWord	: "Adaugă din Word",
+
+DlgPasteMsg2	: "Vă rugăm adăugaţi în căsuţa următoare folosind tastatura (<STRONG>Ctrl+V</STRONG>) şi apăsaţi <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoră definiţiile Font Face",
+DlgPasteRemoveStyles	: "Şterge definiţiile stilurilor",
+DlgPasteCleanBox		: "Şterge căsuţa",
+
+// Color Picker
+ColorAutomatic	: "Automatic",
+ColorMoreColors	: "Mai multe culori...",
+
+// Document Properties
+DocProps		: "Proprietăţile documentului",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Proprietăţile ancorei",
+DlgAnchorName		: "Numele ancorei",
+DlgAnchorErrorName	: "Vă rugăm scrieţi numele ancorei",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nu e în dicţionar",
+DlgSpellChangeTo		: "Schimbă în",
+DlgSpellBtnIgnore		: "Ignoră",
+DlgSpellBtnIgnoreAll	: "Ignoră toate",
+DlgSpellBtnReplace		: "Înlocuieşte",
+DlgSpellBtnReplaceAll	: "Înlocuieşte tot",
+DlgSpellBtnUndo			: "Starea anterioară (undo)",
+DlgSpellNoSuggestions	: "- Fără sugestii -",
+DlgSpellProgress		: "Verificarea textului în desfăşurare...",
+DlgSpellNoMispell		: "Verificarea textului terminată: Nicio greşeală găsită",
+DlgSpellNoChanges		: "Verificarea textului terminată: Niciun cuvânt modificat",
+DlgSpellOneChange		: "Verificarea textului terminată: Un cuvânt modificat",
+DlgSpellManyChanges		: "Verificarea textului terminată: 1% cuvinte modificate",
+
+IeSpellDownload			: "Unealta pentru verificat textul (Spell checker) neinstalată. Doriţi să o descărcaţi acum?",
+
+// Button Dialog
+DlgButtonText		: "Text (Valoare)",
+DlgButtonType		: "Tip",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nume",
+DlgCheckboxValue	: "Valoare",
+DlgCheckboxSelected	: "Selectat",
+
+// Form Dialog
+DlgFormName		: "Nume",
+DlgFormAction	: "Acţiune",
+DlgFormMethod	: "Metodă",
+
+// Select Field Dialog
+DlgSelectName		: "Nume",
+DlgSelectValue		: "Valoare",
+DlgSelectSize		: "Mărime",
+DlgSelectLines		: "linii",
+DlgSelectChkMulti	: "Permite selecţii multiple",
+DlgSelectOpAvail	: "Opţiuni disponibile",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Valoare",
+DlgSelectBtnAdd		: "Adaugă",
+DlgSelectBtnModify	: "Modifică",
+DlgSelectBtnUp		: "Sus",
+DlgSelectBtnDown	: "Jos",
+DlgSelectBtnSetValue : "Setează ca valoare selectată",
+DlgSelectBtnDelete	: "Şterge",
+
+// Textarea Dialog
+DlgTextareaName	: "Nume",
+DlgTextareaCols	: "Coloane",
+DlgTextareaRows	: "Linii",
+
+// Text Field Dialog
+DlgTextName			: "Nume",
+DlgTextValue		: "Valoare",
+DlgTextCharWidth	: "Lărgimea caracterului",
+DlgTextMaxChars		: "Caractere maxime",
+DlgTextType			: "Tip",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Parolă",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nume",
+DlgHiddenValue	: "Valoare",
+
+// Bulleted List Dialog
+BulletedListProp	: "Proprietăţile listei punctate (Bulleted List)",
+NumberedListProp	: "Proprietăţile listei numerotate (Numbered List)",
+DlgLstStart			: "Start",
+DlgLstType			: "Tip",
+DlgLstTypeCircle	: "Cerc",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "Pătrat",
+DlgLstTypeNumbers	: "Numere (1, 2, 3)",
+DlgLstTypeLCase		: "Minuscule-litere mici (a, b, c)",
+DlgLstTypeUCase		: "Majuscule (A, B, C)",
+DlgLstTypeSRoman	: "Cifre romane mici (i, ii, iii)",
+DlgLstTypeLRoman	: "Cifre romane mari (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Fundal",
+DlgDocColorsTab		: "Culori si margini",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Titlul paginii",
+DlgDocLangDir		: "Descrierea limbii",
+DlgDocLangDirLTR	: "stânga-dreapta (LTR)",
+DlgDocLangDirRTL	: "dreapta-stânga (RTL)",
+DlgDocLangCode		: "Codul limbii",
+DlgDocCharSet		: "Encoding setului de caractere",
+DlgDocCharSetCE		: "Central european",
+DlgDocCharSetCT		: "Chinezesc tradiţional (Big5)",
+DlgDocCharSetCR		: "Chirilic",
+DlgDocCharSetGR		: "Grecesc",
+DlgDocCharSetJP		: "Japonez",
+DlgDocCharSetKR		: "Corean",
+DlgDocCharSetTR		: "Turcesc",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Vest european",
+DlgDocCharSetOther	: "Alt encoding al setului de caractere",
+
+DlgDocDocType		: "Document Type Heading",
+DlgDocDocTypeOther	: "Alt Document Type Heading",
+DlgDocIncXHTML		: "Include declaraţii XHTML",
+DlgDocBgColor		: "Culoarea fundalului (Background Color)",
+DlgDocBgImage		: "URL-ul imaginii din fundal (Background Image URL)",
+DlgDocBgNoScroll	: "Fundal neflotant, fix (Nonscrolling Background)",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Link (Legătură web)",
+DlgDocCVisited		: "Link (Legătură web) vizitat",
+DlgDocCActive		: "Link (Legătură web) activ",
+DlgDocMargins		: "Marginile paginii",
+DlgDocMaTop			: "Sus",
+DlgDocMaLeft		: "Stânga",
+DlgDocMaRight		: "Dreapta",
+DlgDocMaBottom		: "Jos",
+DlgDocMeIndex		: "Cuvinte cheie după care se va indexa documentul (separate prin virgulă)",
+DlgDocMeDescr		: "Descrierea documentului",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Drepturi de autor",
+DlgDocPreview		: "Previzualizare",
+
+// Templates Dialog
+Templates			: "Template-uri (şabloane)",
+DlgTemplatesTitle	: "Template-uri (şabloane) de conţinut",
+DlgTemplatesSelMsg	: "Vă rugăm selectaţi template-ul (şablonul) ce se va deschide în editor<br>(conţinutul actual va fi pierdut):",
+DlgTemplatesLoading	: "Se încarcă lista cu template-uri (şabloane). Vă rugăm aşteptaţi...",
+DlgTemplatesNoTpl	: "(Niciun template (şablon) definit)",
+DlgTemplatesReplace	: "Înlocuieşte cuprinsul actual",
+
+// About Dialog
+DlgAboutAboutTab	: "Despre",
+DlgAboutBrowserInfoTab	: "Informaţii browser",
+DlgAboutLicenseTab	: "Licenţă",
+DlgAboutVersion		: "versiune",
+DlgAboutInfo		: "Pentru informaţii amănunţite, vizitaţi"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pt-br.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pt-br.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pt-br.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Brazilian Portuguese language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Ocultar Barra de Ferramentas",
+ToolbarExpand		: "Exibir Barra de Ferramentas",
+
+// Toolbar Items and Context Menu
+Save				: "Salvar",
+NewPage				: "Novo",
+Preview				: "Visualizar",
+Cut					: "Recortar",
+Copy				: "Copiar",
+Paste				: "Colar",
+PasteText			: "Colar como Texto sem Formatação",
+PasteWord			: "Colar do Word",
+Print				: "Imprimir",
+SelectAll			: "Selecionar Tudo",
+RemoveFormat		: "Remover Formatação",
+InsertLinkLbl		: "Hiperlink",
+InsertLink			: "Inserir/Editar Hiperlink",
+RemoveLink			: "Remover Hiperlink",
+Anchor				: "Inserir/Editar Âncora",
+InsertImageLbl		: "Figura",
+InsertImage			: "Inserir/Editar Figura",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insere/Edita Flash",
+InsertTableLbl		: "Tabela",
+InsertTable			: "Inserir/Editar Tabela",
+InsertLineLbl		: "Linha",
+InsertLine			: "Inserir Linha Horizontal",
+InsertSpecialCharLbl: "Caracteres Especiais",
+InsertSpecialChar	: "Inserir Caractere Especial",
+InsertSmileyLbl		: "Emoticon",
+InsertSmiley		: "Inserir Emoticon",
+About				: "Sobre FCKeditor",
+Bold				: "Negrito",
+Italic				: "Itálico",
+Underline			: "Sublinhado",
+StrikeThrough		: "Tachado",
+Subscript			: "Subscrito",
+Superscript			: "Sobrescrito",
+LeftJustify			: "Alinhar Esquerda",
+CenterJustify		: "Centralizar",
+RightJustify		: "Alinhar Direita",
+BlockJustify		: "Justificado",
+DecreaseIndent		: "Diminuir Recuo",
+IncreaseIndent		: "Aumentar Recuo",
+Undo				: "Desfazer",
+Redo				: "Refazer",
+NumberedListLbl		: "Numeração",
+NumberedList		: "Inserir/Remover Numeração",
+BulletedListLbl		: "Marcadores",
+BulletedList		: "Inserir/Remover Marcadores",
+ShowTableBorders	: "Exibir Bordas da Tabela",
+ShowDetails			: "Exibir Detalhes",
+Style				: "Estilo",
+FontFormat			: "Formatação",
+Font				: "Fonte",
+FontSize			: "Tamanho",
+TextColor			: "Cor do Texto",
+BGColor				: "Cor do Plano de Fundo",
+Source				: "Código-Fonte",
+Find				: "Localizar",
+Replace				: "Substituir",
+SpellCheck			: "Verificar Ortografia",
+UniversalKeyboard	: "Teclado Universal",
+PageBreakLbl		: "Quebra de Página",
+PageBreak			: "Inserir Quebra de Página",
+
+Form			: "Formulário",
+Checkbox		: "Caixa de Seleção",
+RadioButton		: "Botão de Opção",
+TextField		: "Caixa de Texto",
+Textarea		: "Área de Texto",
+HiddenField		: "Campo Oculto",
+Button			: "Botão",
+SelectionField	: "Caixa de Listagem",
+ImageButton		: "Botão de Imagem",
+
+FitWindow		: "Maximizar o tamanho do editor",
+
+// Context Menu
+EditLink			: "Editar Hiperlink",
+CellCM				: "Célula",
+RowCM				: "Linha",
+ColumnCM			: "Coluna",
+InsertRow			: "Inserir Linha",
+DeleteRows			: "Remover Linhas",
+InsertColumn		: "Inserir Coluna",
+DeleteColumns		: "Remover Colunas",
+InsertCell			: "Inserir Células",
+DeleteCells			: "Remover Células",
+MergeCells			: "Mesclar Células",
+SplitCell			: "Dividir Célular",
+TableDelete			: "Apagar Tabela",
+CellProperties		: "Formatar Célula",
+TableProperties		: "Formatar Tabela",
+ImageProperties		: "Formatar Figura",
+FlashProperties		: "Propriedades Flash",
+
+AnchorProp			: "Formatar Âncora",
+ButtonProp			: "Formatar Botão",
+CheckboxProp		: "Formatar Caixa de Seleção",
+HiddenFieldProp		: "Formatar Campo Oculto",
+RadioButtonProp		: "Formatar Botão de Opção",
+ImageButtonProp		: "Formatar Botão de Imagem",
+TextFieldProp		: "Formatar Caixa de Texto",
+SelectionFieldProp	: "Formatar Caixa de Listagem",
+TextareaProp		: "Formatar Área de Texto",
+FormProp			: "Formatar Formulário",
+
+FontFormats			: "Normal;Formatado;Endereço;Título 1;Título 2;Título 3;Título 4;Título 5;Título 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Processando XHTML. Por favor, aguarde...",
+Done				: "Pronto",
+PasteWordConfirm	: "O texto que você deseja colar parece ter sido copiado do Word. Você gostaria de remover a formatação antes de colar?",
+NotCompatiblePaste	: "Este comando está disponível para o navegador Internet Explorer 5.5 ou superior. Você gostaria de colar sem remover a formatação?",
+UnknownToolbarItem	: "O item da barra de ferramentas \"%1\" não é reconhecido",
+UnknownCommand		: "O comando \"%1\" não é reconhecido",
+NotImplemented		: "O comando não foi implementado",
+UnknownToolbarSet	: "A barra de ferramentas \"%1\" não existe",
+NoActiveX			: "As configurações de segurança do seu browser podem limitar algumas características do editor. Você precisa habilitar a opção \"Executar controles e plug-ins ActiveX\". Você pode experimentar erros e alertas de características faltantes.",
+BrowseServerBlocked : "Os recursos do browser não puderam ser abertos. Tenha certeza que todos os bloqueadores de popup estão desabilitados.",
+DialogBlocked		: "Não foi possível abrir a janela de diálogo. Tenha certeza que todos os bloqueadores de popup estão desabilitados.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancelar",
+DlgBtnClose			: "Fechar",
+DlgBtnBrowseServer	: "Localizar no Servidor",
+DlgAdvancedTag		: "Avançado",
+DlgOpOther			: "<Outros>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Inserir a URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<não ajustado>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Direção do idioma",
+DlgGenLangDirLtr	: "Esquerda para Direita (LTR)",
+DlgGenLangDirRtl	: "Direita para Esquerda (RTL)",
+DlgGenLangCode		: "Idioma",
+DlgGenAccessKey		: "Chave de Acesso",
+DlgGenName			: "Nome",
+DlgGenTabIndex		: "Índice de Tabulação",
+DlgGenLongDescr		: "Descrição da URL",
+DlgGenClass			: "Classe de Folhas de Estilo",
+DlgGenTitle			: "Título",
+DlgGenContType		: "Tipo de Conteúdo",
+DlgGenLinkCharset	: "Conjunto de Caracteres do Hiperlink",
+DlgGenStyle			: "Estilos",
+
+// Image Dialog
+DlgImgTitle			: "Formatar Figura",
+DlgImgInfoTab		: "Informações da Figura",
+DlgImgBtnUpload		: "Enviar para o Servidor",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Submeter",
+DlgImgAlt			: "Texto Alternativo",
+DlgImgWidth			: "Largura",
+DlgImgHeight		: "Altura",
+DlgImgLockRatio		: "Manter proporções",
+DlgBtnResetSize		: "Redefinir para o Tamanho Original",
+DlgImgBorder		: "Borda",
+DlgImgHSpace		: "Horizontal",
+DlgImgVSpace		: "Vertical",
+DlgImgAlign			: "Alinhamento",
+DlgImgAlignLeft		: "Esquerda",
+DlgImgAlignAbsBottom: "Inferior Absoluto",
+DlgImgAlignAbsMiddle: "Centralizado Absoluto",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Inferior",
+DlgImgAlignMiddle	: "Centralizado",
+DlgImgAlignRight	: "Direita",
+DlgImgAlignTextTop	: "Superior Absoluto",
+DlgImgAlignTop		: "Superior",
+DlgImgPreview		: "Visualização",
+DlgImgAlertUrl		: "Por favor, digite o URL da figura.",
+DlgImgLinkTab		: "Hiperlink",
+
+// Flash Dialog
+DlgFlashTitle		: "Propriedades Flash",
+DlgFlashChkPlay		: "Tocar Automaticamente",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Habilita Menu Flash",
+DlgFlashScale		: "Escala",
+DlgFlashScaleAll	: "Mostrar tudo",
+DlgFlashScaleNoBorder	: "Sem Borda",
+DlgFlashScaleFit	: "Escala Exata",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Hiperlink",
+DlgLnkInfoTab		: "Informações",
+DlgLnkTargetTab		: "Destino",
+
+DlgLnkType			: "Tipo de hiperlink",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Âncora nesta página",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocolo",
+DlgLnkProtoOther	: "<outro>",
+DlgLnkURL			: "URL do hiperlink",
+DlgLnkAnchorSel		: "Selecione uma âncora",
+DlgLnkAnchorByName	: "Pelo Nome da âncora",
+DlgLnkAnchorById	: "Pelo Id do Elemento",
+DlgLnkNoAnchors		: "(Não há âncoras disponíveis neste documento)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Endereço E-Mail",
+DlgLnkEMailSubject	: "Assunto da Mensagem",
+DlgLnkEMailBody		: "Corpo da Mensagem",
+DlgLnkUpload		: "Enviar ao Servidor",
+DlgLnkBtnUpload		: "Enviar ao Servidor",
+
+DlgLnkTarget		: "Destino",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<janela popup>",
+DlgLnkTargetBlank	: "Nova Janela (_blank)",
+DlgLnkTargetParent	: "Janela Pai (_parent)",
+DlgLnkTargetSelf	: "Mesma Janela (_self)",
+DlgLnkTargetTop		: "Janela Superior (_top)",
+DlgLnkTargetFrameName	: "Nome do Frame de Destino",
+DlgLnkPopWinName	: "Nome da Janela Pop-up",
+DlgLnkPopWinFeat	: "Atributos da Janela Pop-up",
+DlgLnkPopResize		: "Redimensionável",
+DlgLnkPopLocation	: "Barra de Endereços",
+DlgLnkPopMenu		: "Barra de Menus",
+DlgLnkPopScroll		: "Barras de Rolagem",
+DlgLnkPopStatus		: "Barra de Status",
+DlgLnkPopToolbar	: "Barra de Ferramentas",
+DlgLnkPopFullScrn	: "Modo Tela Cheia (IE)",
+DlgLnkPopDependent	: "Dependente (Netscape)",
+DlgLnkPopWidth		: "Largura",
+DlgLnkPopHeight		: "Altura",
+DlgLnkPopLeft		: "Esquerda",
+DlgLnkPopTop		: "Superior",
+
+DlnLnkMsgNoUrl		: "Por favor, digite o endereço do Hiperlink",
+DlnLnkMsgNoEMail	: "Por favor, digite o endereço de e-mail",
+DlnLnkMsgNoAnchor	: "Por favor, selecione uma âncora",
+DlnLnkMsgInvPopName	: "O nome da janela popup deve começar com uma letra ou sublinhado (_) e não pode conter espaços",
+
+// Color Dialog
+DlgColorTitle		: "Selecione uma Cor",
+DlgColorBtnClear	: "Limpar",
+DlgColorHighlight	: "Visualização",
+DlgColorSelected	: "Selecionada",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Inserir Emoticon",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Selecione um Caractere Especial",
+
+// Table Dialog
+DlgTableTitle		: "Formatar Tabela",
+DlgTableRows		: "Linhas",
+DlgTableColumns		: "Colunas",
+DlgTableBorder		: "Borda",
+DlgTableAlign		: "Alinhamento",
+DlgTableAlignNotSet	: "<Não ajustado>",
+DlgTableAlignLeft	: "Esquerda",
+DlgTableAlignCenter	: "Centralizado",
+DlgTableAlignRight	: "Direita",
+DlgTableWidth		: "Largura",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "%",
+DlgTableHeight		: "Altura",
+DlgTableCellSpace	: "Espaçamento",
+DlgTableCellPad		: "Enchimento",
+DlgTableCaption		: "Legenda",
+DlgTableSummary		: "Resumo",
+
+// Table Cell Dialog
+DlgCellTitle		: "Formatar célula",
+DlgCellWidth		: "Largura",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "%",
+DlgCellHeight		: "Altura",
+DlgCellWordWrap		: "Quebra de Linha",
+DlgCellWordWrapNotSet	: "<Não ajustado>",
+DlgCellWordWrapYes	: "Sim",
+DlgCellWordWrapNo	: "Não",
+DlgCellHorAlign		: "Alinhamento Horizontal",
+DlgCellHorAlignNotSet	: "<Não ajustado>",
+DlgCellHorAlignLeft	: "Esquerda",
+DlgCellHorAlignCenter	: "Centralizado",
+DlgCellHorAlignRight: "Direita",
+DlgCellVerAlign		: "Alinhamento Vertical",
+DlgCellVerAlignNotSet	: "<Não ajustado>",
+DlgCellVerAlignTop	: "Superior",
+DlgCellVerAlignMiddle	: "Centralizado",
+DlgCellVerAlignBottom	: "Inferior",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Transpor Linhas",
+DlgCellCollSpan		: "Transpor Colunas",
+DlgCellBackColor	: "Cor do Plano de Fundo",
+DlgCellBorderColor	: "Cor da Borda",
+DlgCellBtnSelect	: "Selecionar...",
+
+// Find Dialog
+DlgFindTitle		: "Localizar...",
+DlgFindFindBtn		: "Localizar",
+DlgFindNotFoundMsg	: "O texto especificado não foi encontrado.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Substituir",
+DlgReplaceFindLbl		: "Procurar por:",
+DlgReplaceReplaceLbl	: "Substituir por:",
+DlgReplaceCaseChk		: "Coincidir Maiúsculas/Minúsculas",
+DlgReplaceReplaceBtn	: "Substituir",
+DlgReplaceReplAllBtn	: "Substituir Tudo",
+DlgReplaceWordChk		: "Coincidir a palavra inteira",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "As configurações de segurança do seu navegador não permitem que o editor execute operações de recortar automaticamente. Por favor, utilize o teclado para recortar (Ctrl+X).",
+PasteErrorCopy	: "As configurações de segurança do seu navegador não permitem que o editor execute operações de copiar automaticamente. Por favor, utilize o teclado para copiar (Ctrl+C).",
+
+PasteAsText		: "Colar como Texto sem Formatação",
+PasteFromWord	: "Colar do Word",
+
+DlgPasteMsg2	: "Transfira o link usado no box usando o teclado com (<STRONG>Ctrl+V</STRONG>) e <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorar definições de fonte",
+DlgPasteRemoveStyles	: "Remove definições de estilo",
+DlgPasteCleanBox		: "Limpar Box",
+
+// Color Picker
+ColorAutomatic	: "Automático",
+ColorMoreColors	: "Mais Cores...",
+
+// Document Properties
+DocProps		: "Propriedades Documento",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Formatar Âncora",
+DlgAnchorName		: "Nome da Âncora",
+DlgAnchorErrorName	: "Por favor, digite o nome da âncora",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Não encontrada",
+DlgSpellChangeTo		: "Alterar para",
+DlgSpellBtnIgnore		: "Ignorar uma vez",
+DlgSpellBtnIgnoreAll	: "Ignorar Todas",
+DlgSpellBtnReplace		: "Alterar",
+DlgSpellBtnReplaceAll	: "Alterar Todas",
+DlgSpellBtnUndo			: "Desfazer",
+DlgSpellNoSuggestions	: "-sem sugestões de ortografia-",
+DlgSpellProgress		: "Verificação ortográfica em andamento...",
+DlgSpellNoMispell		: "Verificação encerrada: Não foram encontrados erros de ortografia",
+DlgSpellNoChanges		: "Verificação ortográfica encerrada: Não houve alterações",
+DlgSpellOneChange		: "Verificação ortográfica encerrada: Uma palavra foi alterada",
+DlgSpellManyChanges		: "Verificação ortográfica encerrada: %1 foram alteradas",
+
+IeSpellDownload			: "A verificação ortográfica não foi instalada. Você gostaria de realizar o download agora?",
+
+// Button Dialog
+DlgButtonText		: "Texto (Valor)",
+DlgButtonType		: "Tipo",
+DlgButtonTypeBtn	: "Botão",
+DlgButtonTypeSbm	: "Enviar",
+DlgButtonTypeRst	: "Limpar",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nome",
+DlgCheckboxValue	: "Valor",
+DlgCheckboxSelected	: "Selecionado",
+
+// Form Dialog
+DlgFormName		: "Nome",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Método",
+
+// Select Field Dialog
+DlgSelectName		: "Nome",
+DlgSelectValue		: "Valor",
+DlgSelectSize		: "Tamanho",
+DlgSelectLines		: "linhas",
+DlgSelectChkMulti	: "Permitir múltiplas seleções",
+DlgSelectOpAvail	: "Opções disponíveis",
+DlgSelectOpText		: "Texto",
+DlgSelectOpValue	: "Valor",
+DlgSelectBtnAdd		: "Adicionar",
+DlgSelectBtnModify	: "Modificar",
+DlgSelectBtnUp		: "Para cima",
+DlgSelectBtnDown	: "Para baixo",
+DlgSelectBtnSetValue : "Definir como selecionado",
+DlgSelectBtnDelete	: "Remover",
+
+// Textarea Dialog
+DlgTextareaName	: "Nome",
+DlgTextareaCols	: "Colunas",
+DlgTextareaRows	: "Linhas",
+
+// Text Field Dialog
+DlgTextName			: "Nome",
+DlgTextValue		: "Valor",
+DlgTextCharWidth	: "Comprimento (em caracteres)",
+DlgTextMaxChars		: "Número Máximo de Caracteres",
+DlgTextType			: "Tipo",
+DlgTextTypeText		: "Texto",
+DlgTextTypePass		: "Senha",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nome",
+DlgHiddenValue	: "Valor",
+
+// Bulleted List Dialog
+BulletedListProp	: "Formatar Marcadores",
+NumberedListProp	: "Formatar Numeração",
+DlgLstStart			: "Iniciar",
+DlgLstType			: "Tipo",
+DlgLstTypeCircle	: "Círculo",
+DlgLstTypeDisc		: "Disco",
+DlgLstTypeSquare	: "Quadrado",
+DlgLstTypeNumbers	: "Números (1, 2, 3)",
+DlgLstTypeLCase		: "Letras Minúsculas (a, b, c)",
+DlgLstTypeUCase		: "Letras Maiúsculas (A, B, C)",
+DlgLstTypeSRoman	: "Números Romanos Minúsculos (i, ii, iii)",
+DlgLstTypeLRoman	: "Números Romanos Maiúsculos (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Geral",
+DlgDocBackTab		: "Plano de Fundo",
+DlgDocColorsTab		: "Cores e Margens",
+DlgDocMetaTab		: "Meta Dados",
+
+DlgDocPageTitle		: "Título da Página",
+DlgDocLangDir		: "Direção do Idioma",
+DlgDocLangDirLTR	: "Esquerda para Direita (LTR)",
+DlgDocLangDirRTL	: "Direita para Esquerda (RTL)",
+DlgDocLangCode		: "Código do Idioma",
+DlgDocCharSet		: "Codificação de Caracteres",
+DlgDocCharSetCE		: "Europa Central",
+DlgDocCharSetCT		: "Chinês Tradicional (Big5)",
+DlgDocCharSetCR		: "Cirílico",
+DlgDocCharSetGR		: "Grego",
+DlgDocCharSetJP		: "Japonês",
+DlgDocCharSetKR		: "Coreano",
+DlgDocCharSetTR		: "Turco",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Europa Ocidental",
+DlgDocCharSetOther	: "Outra Codificação de Caracteres",
+
+DlgDocDocType		: "Cabeçalho Tipo de Documento",
+DlgDocDocTypeOther	: "Other Document Type Heading",
+DlgDocIncXHTML		: "Incluir Declarações XHTML",
+DlgDocBgColor		: "Cor do Plano de Fundo",
+DlgDocBgImage		: "URL da Imagem de Plano de Fundo",
+DlgDocBgNoScroll	: "Plano de Fundo Fixo",
+DlgDocCText			: "Texto",
+DlgDocCLink			: "Hiperlink",
+DlgDocCVisited		: "Hiperlink Visitado",
+DlgDocCActive		: "Hiperlink Ativo",
+DlgDocMargins		: "Margens da Página",
+DlgDocMaTop			: "Superior",
+DlgDocMaLeft		: "Inferior",
+DlgDocMaRight		: "Direita",
+DlgDocMaBottom		: "Inferior",
+DlgDocMeIndex		: "Palavras-chave de Indexação do Documento (separadas por vírgula)",
+DlgDocMeDescr		: "Descrição do Documento",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Direitos Autorais",
+DlgDocPreview		: "Visualizar",
+
+// Templates Dialog
+Templates			: "Modelos de layout",
+DlgTemplatesTitle	: "Modelo de layout do conteúdo",
+DlgTemplatesSelMsg	: "Selecione um modelo de layout para ser aberto no editor<br>(o conteúdo atual será perdido):",
+DlgTemplatesLoading	: "Carregando a lista de modelos de layout. Aguarde...",
+DlgTemplatesNoTpl	: "(Não foram definidos modelos de layout)",
+DlgTemplatesReplace	: "Substituir o conteúdo atual",
+
+// About Dialog
+DlgAboutAboutTab	: "Sobre",
+DlgAboutBrowserInfoTab	: "Informações do Navegador",
+DlgAboutLicenseTab	: "Licença",
+DlgAboutVersion		: "versão",
+DlgAboutInfo		: "Para maiores informações visite"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ru.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ru.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ru.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Russian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Свернуть панель инструментов",
+ToolbarExpand		: "Развернуть панель инструментов",
+
+// Toolbar Items and Context Menu
+Save				: "Сохранить",
+NewPage				: "Новая страница",
+Preview				: "Предварительный просмотр",
+Cut					: "Вырезать",
+Copy				: "Копировать",
+Paste				: "Вставить",
+PasteText			: "Вставить только текст",
+PasteWord			: "Вставить из Word",
+Print				: "Печать",
+SelectAll			: "Выделить все",
+RemoveFormat		: "Убрать форматирование",
+InsertLinkLbl		: "Ссылка",
+InsertLink			: "Вставить/Редактировать ссылку",
+RemoveLink			: "Убрать ссылку",
+Anchor				: "Вставить/Редактировать якорь",
+InsertImageLbl		: "Изображение",
+InsertImage			: "Вставить/Редактировать изображение",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Вставить/Редактировать Flash",
+InsertTableLbl		: "Таблица",
+InsertTable			: "Вставить/Редактировать таблицу",
+InsertLineLbl		: "Линия",
+InsertLine			: "Вставить горизонтальную линию",
+InsertSpecialCharLbl: "Специальный символ",
+InsertSpecialChar	: "Вставить специальный символ",
+InsertSmileyLbl		: "Смайлик",
+InsertSmiley		: "Вставить смайлик",
+About				: "О FCKeditor",
+Bold				: "Жирный",
+Italic				: "Курсив",
+Underline			: "Подчеркнутый",
+StrikeThrough		: "Зачеркнутый",
+Subscript			: "Подстрочный индекс",
+Superscript			: "Надстрочный индекс",
+LeftJustify			: "По левому краю",
+CenterJustify		: "По центру",
+RightJustify		: "По правому краю",
+BlockJustify		: "По ширине",
+DecreaseIndent		: "Уменьшить отступ",
+IncreaseIndent		: "Увеличить отступ",
+Undo				: "Отменить",
+Redo				: "Повторить",
+NumberedListLbl		: "Нумерованный список",
+NumberedList		: "Вставить/Удалить нумерованный список",
+BulletedListLbl		: "Маркированный список",
+BulletedList		: "Вставить/Удалить маркированный список",
+ShowTableBorders	: "Показать бордюры таблицы",
+ShowDetails			: "Показать детали",
+Style				: "Стиль",
+FontFormat			: "Форматирование",
+Font				: "Шрифт",
+FontSize			: "Размер",
+TextColor			: "Цвет текста",
+BGColor				: "Цвет фона",
+Source				: "Источник",
+Find				: "Найти",
+Replace				: "Заменить",
+SpellCheck			: "Проверить орфографию",
+UniversalKeyboard	: "Универсальная клавиатура",
+PageBreakLbl		: "Разрыв страницы",
+PageBreak			: "Вставить разрыв страницы",
+
+Form			: "Форма",
+Checkbox		: "Флаговая кнопка",
+RadioButton		: "Кнопка выбора",
+TextField		: "Текстовое поле",
+Textarea		: "Текстовая область",
+HiddenField		: "Скрытое поле",
+Button			: "Кнопка",
+SelectionField	: "Список",
+ImageButton		: "Кнопка с изображением",
+
+FitWindow		: "Развернуть окно редактора",
+
+// Context Menu
+EditLink			: "Вставить ссылку",
+CellCM				: "Ячейка",
+RowCM				: "Строка",
+ColumnCM			: "Колонка",
+InsertRow			: "Вставить строку",
+DeleteRows			: "Удалить строки",
+InsertColumn		: "Вставить колонку",
+DeleteColumns		: "Удалить колонки",
+InsertCell			: "Вставить ячейку",
+DeleteCells			: "Удалить ячейки",
+MergeCells			: "Соединить ячейки",
+SplitCell			: "Разбить ячейку",
+TableDelete			: "Удалить таблицу",
+CellProperties		: "Свойства ячейки",
+TableProperties		: "Свойства таблицы",
+ImageProperties		: "Свойства изображения",
+FlashProperties		: "Свойства Flash",
+
+AnchorProp			: "Свойства якоря",
+ButtonProp			: "Свойства кнопки",
+CheckboxProp		: "Свойства флаговой кнопки",
+HiddenFieldProp		: "Свойства скрытого поля",
+RadioButtonProp		: "Свойства кнопки выбора",
+ImageButtonProp		: "Свойства кнопки с изображением",
+TextFieldProp		: "Свойства текстового поля",
+SelectionFieldProp	: "Свойства списка",
+TextareaProp		: "Свойства текстовой области",
+FormProp			: "Свойства формы",
+
+FontFormats			: "Нормальный;Форматированный;Адрес;Заголовок 1;Заголовок 2;Заголовок 3;Заголовок 4;Заголовок 5;Заголовок 6;Нормальный (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Обработка XHTML. Пожалуйста подождите...",
+Done				: "Сделано",
+PasteWordConfirm	: "Текст, который вы хотите вставить, похож на копируемый из Word. Вы хотите очистить его перед вставкой?",
+NotCompatiblePaste	: "Эта команда доступна для Internet Explorer версии 5.5 или выше. Вы хотите вставить без очистки?",
+UnknownToolbarItem	: "Не известный элемент панели инструментов \"%1\"",
+UnknownCommand		: "Не известное имя команды \"%1\"",
+NotImplemented		: "Команда не реализована",
+UnknownToolbarSet	: "Панель инструментов \"%1\" не существует",
+NoActiveX			: "Настройки безопасности вашего браузера могут ограничивать некоторые свойства редактора. Вы должны включить опцию \"Запускать элементы управления ActiveX и плугины\". Вы можете видеть ошибки и замечать отсутствие возможностей.",
+BrowseServerBlocked : "Ресурсы браузера не могут быть открыты. Проверьте что блокировки всплывающих окон выключены.",
+DialogBlocked		: "Не возможно открыть окно диалога. Проверьте что блокировки всплывающих окон выключены.",
+
+// Dialogs
+DlgBtnOK			: "ОК",
+DlgBtnCancel		: "Отмена",
+DlgBtnClose			: "Закрыть",
+DlgBtnBrowseServer	: "Просмотреть на сервере",
+DlgAdvancedTag		: "Расширенный",
+DlgOpOther			: "<Другое>",
+DlgInfoTab			: "Информация",
+DlgAlertUrl			: "Пожалуйста вставьте URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<не определено>",
+DlgGenId			: "Идентификатор",
+DlgGenLangDir		: "Направление языка",
+DlgGenLangDirLtr	: "Слева на право (LTR)",
+DlgGenLangDirRtl	: "Справа на лево (RTL)",
+DlgGenLangCode		: "Язык",
+DlgGenAccessKey		: "Горячая клавиша",
+DlgGenName			: "Имя",
+DlgGenTabIndex		: "Последовательность перехода",
+DlgGenLongDescr		: "Длинное описание URL",
+DlgGenClass			: "Класс CSS",
+DlgGenTitle			: "Заголовок",
+DlgGenContType		: "Тип содержимого",
+DlgGenLinkCharset	: "Кодировка",
+DlgGenStyle			: "Стиль CSS",
+
+// Image Dialog
+DlgImgTitle			: "Свойства изображения",
+DlgImgInfoTab		: "Информация о изображении",
+DlgImgBtnUpload		: "Послать на сервер",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Закачать",
+DlgImgAlt			: "Альтернативный текст",
+DlgImgWidth			: "Ширина",
+DlgImgHeight		: "Высота",
+DlgImgLockRatio		: "Сохранять пропорции",
+DlgBtnResetSize		: "Сбросить размер",
+DlgImgBorder		: "Бордюр",
+DlgImgHSpace		: "Горизонтальный отступ",
+DlgImgVSpace		: "Вертикальный отступ",
+DlgImgAlign			: "Выравнивание",
+DlgImgAlignLeft		: "По левому краю",
+DlgImgAlignAbsBottom: "Абс понизу",
+DlgImgAlignAbsMiddle: "Абс посередине",
+DlgImgAlignBaseline	: "По базовой линии",
+DlgImgAlignBottom	: "Понизу",
+DlgImgAlignMiddle	: "Посередине",
+DlgImgAlignRight	: "По правому краю",
+DlgImgAlignTextTop	: "Текст наверху",
+DlgImgAlignTop		: "По верху",
+DlgImgPreview		: "Предварительный просмотр",
+DlgImgAlertUrl		: "Пожалуйста введите URL изображения",
+DlgImgLinkTab		: "Ссылка",
+
+// Flash Dialog
+DlgFlashTitle		: "Свойства Flash",
+DlgFlashChkPlay		: "Авто проигрывание",
+DlgFlashChkLoop		: "Повтор",
+DlgFlashChkMenu		: "Включить меню Flash",
+DlgFlashScale		: "Масштабировать",
+DlgFlashScaleAll	: "Показывать все",
+DlgFlashScaleNoBorder	: "Без бордюра",
+DlgFlashScaleFit	: "Точное совпадение",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Ссылка",
+DlgLnkInfoTab		: "Информация ссылки",
+DlgLnkTargetTab		: "Цель",
+
+DlgLnkType			: "Тип ссылки",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Якорь на эту страницу",
+DlgLnkTypeEMail		: "Эл. почта",
+DlgLnkProto			: "Протокол",
+DlgLnkProtoOther	: "<другое>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Выберите якорь",
+DlgLnkAnchorByName	: "По имени якоря",
+DlgLnkAnchorById	: "По идентификатору элемента",
+DlgLnkNoAnchors		: "<Нет якорей доступных в этом документе>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Адрес эл. почты",
+DlgLnkEMailSubject	: "Заголовок сообщения",
+DlgLnkEMailBody		: "Тело сообщения",
+DlgLnkUpload		: "Закачать",
+DlgLnkBtnUpload		: "Послать на сервер",
+
+DlgLnkTarget		: "Цель",
+DlgLnkTargetFrame	: "<фрейм>",
+DlgLnkTargetPopup	: "<всплывающее окно>",
+DlgLnkTargetBlank	: "Новое окно (_blank)",
+DlgLnkTargetParent	: "Родительское окно (_parent)",
+DlgLnkTargetSelf	: "Тоже окно (_self)",
+DlgLnkTargetTop		: "Самое верхнее окно (_top)",
+DlgLnkTargetFrameName	: "Имя целевого фрейма",
+DlgLnkPopWinName	: "Имя всплывающего окна",
+DlgLnkPopWinFeat	: "Свойства всплывающего окна",
+DlgLnkPopResize		: "Изменяющееся в размерах",
+DlgLnkPopLocation	: "Панель локации",
+DlgLnkPopMenu		: "Панель меню",
+DlgLnkPopScroll		: "Полосы прокрутки",
+DlgLnkPopStatus		: "Строка состояния",
+DlgLnkPopToolbar	: "Панель инструментов",
+DlgLnkPopFullScrn	: "Полный экран (IE)",
+DlgLnkPopDependent	: "Зависимый (Netscape)",
+DlgLnkPopWidth		: "Ширина",
+DlgLnkPopHeight		: "Высота",
+DlgLnkPopLeft		: "Позиция слева",
+DlgLnkPopTop		: "Позиция сверху",
+
+DlnLnkMsgNoUrl		: "Пожалуйста введите URL ссылки",
+DlnLnkMsgNoEMail	: "Пожалуйста введите адрес эл. почты",
+DlnLnkMsgNoAnchor	: "Пожалуйста выберете якорь",
+DlnLnkMsgInvPopName	: "Название вспывающего окна должно начинаться буквы и не может содержать пробелов",
+
+// Color Dialog
+DlgColorTitle		: "Выберите цвет",
+DlgColorBtnClear	: "Очистить",
+DlgColorHighlight	: "Подсвеченный",
+DlgColorSelected	: "Выбранный",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Вставить смайлик",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Выберите специальный символ",
+
+// Table Dialog
+DlgTableTitle		: "Свойства таблицы",
+DlgTableRows		: "Строки",
+DlgTableColumns		: "Колонки",
+DlgTableBorder		: "Размер бордюра",
+DlgTableAlign		: "Выравнивание",
+DlgTableAlignNotSet	: "<Не уст.>",
+DlgTableAlignLeft	: "Слева",
+DlgTableAlignCenter	: "По центру",
+DlgTableAlignRight	: "Справа",
+DlgTableWidth		: "Ширина",
+DlgTableWidthPx		: "пикселей",
+DlgTableWidthPc		: "процентов",
+DlgTableHeight		: "Высота",
+DlgTableCellSpace	: "Промежуток (spacing)",
+DlgTableCellPad		: "Отступ (padding)",
+DlgTableCaption		: "Заголовок",
+DlgTableSummary		: "Резюме",
+
+// Table Cell Dialog
+DlgCellTitle		: "Свойства ячейки",
+DlgCellWidth		: "Ширина",
+DlgCellWidthPx		: "пикселей",
+DlgCellWidthPc		: "процентов",
+DlgCellHeight		: "Высота",
+DlgCellWordWrap		: "Заворачивание текста",
+DlgCellWordWrapNotSet	: "<Не уст.>",
+DlgCellWordWrapYes	: "Да",
+DlgCellWordWrapNo	: "Нет",
+DlgCellHorAlign		: "Гор. выравнивание",
+DlgCellHorAlignNotSet	: "<Не уст.>",
+DlgCellHorAlignLeft	: "Слева",
+DlgCellHorAlignCenter	: "По центру",
+DlgCellHorAlignRight: "Справа",
+DlgCellVerAlign		: "Верт. выравнивание",
+DlgCellVerAlignNotSet	: "<Не уст.>",
+DlgCellVerAlignTop	: "Сверху",
+DlgCellVerAlignMiddle	: "Посередине",
+DlgCellVerAlignBottom	: "Снизу",
+DlgCellVerAlignBaseline	: "По базовой линии",
+DlgCellRowSpan		: "Диапазон строк (span)",
+DlgCellCollSpan		: "Диапазон колонок (span)",
+DlgCellBackColor	: "Цвет фона",
+DlgCellBorderColor	: "Цвет бордюра",
+DlgCellBtnSelect	: "Выберите...",
+
+// Find Dialog
+DlgFindTitle		: "Найти",
+DlgFindFindBtn		: "Найти",
+DlgFindNotFoundMsg	: "Указанный текст не найден.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Заменить",
+DlgReplaceFindLbl		: "Найти:",
+DlgReplaceReplaceLbl	: "Заменить на:",
+DlgReplaceCaseChk		: "Учитывать регистр",
+DlgReplaceReplaceBtn	: "Заменить",
+DlgReplaceReplAllBtn	: "Заменить все",
+DlgReplaceWordChk		: "Совпадение целых слов",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Настройки безопасности вашего браузера не позволяют редактору автоматически выполнять операции вырезания. Пожалуйста используйте клавиатуру для этого (Ctrl+X).",
+PasteErrorCopy	: "Настройки безопасности вашего браузера не позволяют редактору автоматически выполнять операции копирования. Пожалуйста используйте клавиатуру для этого (Ctrl+C).",
+
+PasteAsText		: "Вставить только текст",
+PasteFromWord	: "Вставить из Word",
+
+DlgPasteMsg2	: "Пожалуйста вставьте текст в прямоугольник используя сочетание клавиш (<STRONG>Ctrl+V</STRONG>) и нажмите <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Игнорировать определения гарнитуры",
+DlgPasteRemoveStyles	: "Убрать определения стилей",
+DlgPasteCleanBox		: "Очистить",
+
+// Color Picker
+ColorAutomatic	: "Автоматический",
+ColorMoreColors	: "Цвета...",
+
+// Document Properties
+DocProps		: "Свойства документа",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Свойства якоря",
+DlgAnchorName		: "Имя якоря",
+DlgAnchorErrorName	: "Пожалуйста введите имя якоря",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Нет в словаре",
+DlgSpellChangeTo		: "Заменить на",
+DlgSpellBtnIgnore		: "Игнорировать",
+DlgSpellBtnIgnoreAll	: "Игнорировать все",
+DlgSpellBtnReplace		: "Заменить",
+DlgSpellBtnReplaceAll	: "Заменить все",
+DlgSpellBtnUndo			: "Отменить",
+DlgSpellNoSuggestions	: "- Нет предположений -",
+DlgSpellProgress		: "Идет проверка орфографии...",
+DlgSpellNoMispell		: "Проверка орфографии закончена: ошибок не найдено",
+DlgSpellNoChanges		: "Проверка орфографии закончена: ни одного слова не изменено",
+DlgSpellOneChange		: "Проверка орфографии закончена: одно слово изменено",
+DlgSpellManyChanges		: "Проверка орфографии закончена: 1% слов изменен",
+
+IeSpellDownload			: "Модуль проверки орфографии не установлен. Хотите скачать его сейчас?",
+
+// Button Dialog
+DlgButtonText		: "Текст (Значение)",
+DlgButtonType		: "Тип",
+DlgButtonTypeBtn	: "Кнопка",
+DlgButtonTypeSbm	: "Отправить",
+DlgButtonTypeRst	: "Сбросить",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Имя",
+DlgCheckboxValue	: "Значение",
+DlgCheckboxSelected	: "Выбранная",
+
+// Form Dialog
+DlgFormName		: "Имя",
+DlgFormAction	: "Действие",
+DlgFormMethod	: "Метод",
+
+// Select Field Dialog
+DlgSelectName		: "Имя",
+DlgSelectValue		: "Значение",
+DlgSelectSize		: "Размер",
+DlgSelectLines		: "линии",
+DlgSelectChkMulti	: "Разрешить множественный выбор",
+DlgSelectOpAvail	: "Доступные варианты",
+DlgSelectOpText		: "Текст",
+DlgSelectOpValue	: "Значение",
+DlgSelectBtnAdd		: "Добавить",
+DlgSelectBtnModify	: "Модифицировать",
+DlgSelectBtnUp		: "Вверх",
+DlgSelectBtnDown	: "Вниз",
+DlgSelectBtnSetValue : "Установить как выбранное значение",
+DlgSelectBtnDelete	: "Удалить",
+
+// Textarea Dialog
+DlgTextareaName	: "Имя",
+DlgTextareaCols	: "Колонки",
+DlgTextareaRows	: "Строки",
+
+// Text Field Dialog
+DlgTextName			: "Имя",
+DlgTextValue		: "Значение",
+DlgTextCharWidth	: "Ширина",
+DlgTextMaxChars		: "Макс. кол-во символов",
+DlgTextType			: "Тип",
+DlgTextTypeText		: "Текст",
+DlgTextTypePass		: "Пароль",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Имя",
+DlgHiddenValue	: "Значение",
+
+// Bulleted List Dialog
+BulletedListProp	: "Свойства маркированного списка",
+NumberedListProp	: "Свойства нумерованного списка",
+DlgLstStart			: "Начало",
+DlgLstType			: "Тип",
+DlgLstTypeCircle	: "Круг",
+DlgLstTypeDisc		: "Диск",
+DlgLstTypeSquare	: "Квадрат",
+DlgLstTypeNumbers	: "Номера (1, 2, 3)",
+DlgLstTypeLCase		: "Буквы нижнего регистра (a, b, c)",
+DlgLstTypeUCase		: "Буквы верхнего регистра (A, B, C)",
+DlgLstTypeSRoman	: "Малые римские буквы (i, ii, iii)",
+DlgLstTypeLRoman	: "Большие римские буквы (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Общие",
+DlgDocBackTab		: "Задний фон",
+DlgDocColorsTab		: "Цвета и отступы",
+DlgDocMetaTab		: "Мета данные",
+
+DlgDocPageTitle		: "Заголовок страницы",
+DlgDocLangDir		: "Направление текста",
+DlgDocLangDirLTR	: "Слева на право (LTR)",
+DlgDocLangDirRTL	: "Справа на лево (RTL)",
+DlgDocLangCode		: "Код языка",
+DlgDocCharSet		: "Кодировка набора символов",
+DlgDocCharSetCE		: "Центрально-европейская",
+DlgDocCharSetCT		: "Китайская традиционная (Big5)",
+DlgDocCharSetCR		: "Кириллица",
+DlgDocCharSetGR		: "Греческая",
+DlgDocCharSetJP		: "Японская",
+DlgDocCharSetKR		: "Корейская",
+DlgDocCharSetTR		: "Турецкая",
+DlgDocCharSetUN		: "Юникод (UTF-8)",
+DlgDocCharSetWE		: "Западно-европейская",
+DlgDocCharSetOther	: "Другая кодировка набора символов",
+
+DlgDocDocType		: "Заголовок типа документа",
+DlgDocDocTypeOther	: "Другой заголовок типа документа",
+DlgDocIncXHTML		: "Включить XHTML объявления",
+DlgDocBgColor		: "Цвет фона",
+DlgDocBgImage		: "URL изображения фона",
+DlgDocBgNoScroll	: "Нескроллируемый фон",
+DlgDocCText			: "Текст",
+DlgDocCLink			: "Ссылка",
+DlgDocCVisited		: "Посещенная ссылка",
+DlgDocCActive		: "Активная ссылка",
+DlgDocMargins		: "Отступы страницы",
+DlgDocMaTop			: "Верхний",
+DlgDocMaLeft		: "Левый",
+DlgDocMaRight		: "Правый",
+DlgDocMaBottom		: "Нижний",
+DlgDocMeIndex		: "Ключевые слова документа (разделенные запятой)",
+DlgDocMeDescr		: "Описание документа",
+DlgDocMeAuthor		: "Автор",
+DlgDocMeCopy		: "Авторские права",
+DlgDocPreview		: "Предварительный просмотр",
+
+// Templates Dialog
+Templates			: "Шаблоны",
+DlgTemplatesTitle	: "Шаблоны содержимого",
+DlgTemplatesSelMsg	: "Пожалуйста выберете шаблон для открытия в редакторе<br>(текущее содержимое будет потеряно):",
+DlgTemplatesLoading	: "Загрузка списка шаблонов. Пожалуйста подождите...",
+DlgTemplatesNoTpl	: "(Ни одного шаблона не определено)",
+DlgTemplatesReplace	: "Заменить текущее содержание",
+
+// About Dialog
+DlgAboutAboutTab	: "О программе",
+DlgAboutBrowserInfoTab	: "Информация браузера",
+DlgAboutLicenseTab	: "Лицензия",
+DlgAboutVersion		: "Версия",
+DlgAboutInfo		: "Для большей информации, посетите"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/af.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/af.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/af.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Afrikaans language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Vou Gereedskaps balk toe",
+ToolbarExpand		: "Vou Gereedskaps balk oop",
+
+// Toolbar Items and Context Menu
+Save				: "Bewaar",
+NewPage				: "Nuwe Bladsy",
+Preview				: "Voorskou",
+Cut					: "Uitsny ",
+Copy				: "Kopieer",
+Paste				: "Byvoeg",
+PasteText			: "Slegs inhoud byvoeg",
+PasteWord			: "Van Word af byvoeg",
+Print				: "Druk",
+SelectAll			: "Selekteer alles",
+RemoveFormat		: "Formaat verweider",
+InsertLinkLbl		: "Skakel",
+InsertLink			: "Skakel byvoeg/verander",
+RemoveLink			: "Skakel verweider",
+Anchor				: "Plekhouer byvoeg/verander",
+InsertImageLbl		: "Beeld",
+InsertImage			: "Beeld byvoeg/verander",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Flash byvoeg/verander",
+InsertTableLbl		: "Tabel",
+InsertTable			: "Tabel byvoeg/verander",
+InsertLineLbl		: "Lyn",
+InsertLine			: "Horisontale lyn byvoeg",
+InsertSpecialCharLbl: "Spesiaale karakter",
+InsertSpecialChar	: "Spesiaale Karakter byvoeg",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Smiley byvoeg",
+About				: "Meer oor FCKeditor",
+Bold				: "Vet",
+Italic				: "Skuins",
+Underline			: "Onderstreep",
+StrikeThrough		: "Gestreik",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Links rig",
+CenterJustify		: "Rig Middel",
+RightJustify		: "Regs rig",
+BlockJustify		: "Blok paradeer",
+DecreaseIndent		: "Paradeering verkort",
+IncreaseIndent		: "Paradeering verleng",
+Undo				: "Ont-skep",
+Redo				: "Her-skep",
+NumberedListLbl		: "Genommerde lys",
+NumberedList		: "Genommerde lys byvoeg/verweider",
+BulletedListLbl		: "Gepunkte lys",
+BulletedList		: "Gepunkte lys byvoeg/verweider",
+ShowTableBorders	: "Wys tabel kante",
+ShowDetails			: "Wys informasie",
+Style				: "Styl",
+FontFormat			: "Karakter formaat",
+Font				: "Karakters",
+FontSize			: "Karakter grote",
+TextColor			: "Karakter kleur",
+BGColor				: "Agtergrond kleur",
+Source				: "Source",
+Find				: "Vind",
+Replace				: "Vervang",
+SpellCheck			: "Spelling nagaan",
+UniversalKeyboard	: "Universeele Sleutelbord",
+PageBreakLbl		: "Bladsy breek",
+PageBreak			: "Bladsy breek byvoeg",
+
+Form			: "Form",
+Checkbox		: "HakBox",
+RadioButton		: "PuntBox",
+TextField		: "Byvoegbare karakter strook",
+Textarea		: "Byvoegbare karakter area",
+HiddenField		: "Blinde strook",
+Button			: "Knop",
+SelectionField	: "Opklapbare keuse strook",
+ImageButton		: "Beeld knop",
+
+FitWindow		: "Maksimaliseer venster grote",
+
+// Context Menu
+EditLink			: "Verander skakel",
+CellCM				: "Cell",
+RowCM				: "Ry",
+ColumnCM			: "Kolom",
+InsertRow			: "Ry byvoeg",
+DeleteRows			: "Ry verweider",
+InsertColumn		: "Kolom byvoeg",
+DeleteColumns		: "Kolom verweider",
+InsertCell			: "Cell byvoeg",
+DeleteCells			: "Cell verweider",
+MergeCells			: "Cell verenig",
+SplitCell			: "Cell verdeel",
+TableDelete			: "Tabel verweider",
+CellProperties		: "Cell eienskappe",
+TableProperties		: "Tabel eienskappe",
+ImageProperties		: "Beeld eienskappe",
+FlashProperties		: "Flash eienskappe",
+
+AnchorProp			: "Plekhouer eienskappe",
+ButtonProp			: "Knop eienskappe",
+CheckboxProp		: "HakBox eienskappe",
+HiddenFieldProp		: "Blinde strook eienskappe",
+RadioButtonProp		: "PuntBox eienskappe",
+ImageButtonProp		: "Beeld knop eienskappe",
+TextFieldProp		: "Karakter strook eienskappe",
+SelectionFieldProp	: "Opklapbare keuse strook eienskappe",
+TextareaProp		: "Karakter area eienskappe",
+FormProp			: "Form eienskappe",
+
+FontFormats			: "Normaal;Geformateerd;Adres;Opskrif 1;Opskrif 2;Opskrif 3;Opskrif 4;Opskrif 5;Opskrif 6;Normaal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML word verarbeit. U geduld asseblief...",
+Done				: "Kompleet",
+PasteWordConfirm	: "Die informasie wat U probeer byvoeg is warskynlik van Word. Wil U dit reinig voor die byvoeging?",
+NotCompatiblePaste	: "Die instruksie is beskikbaar vir Internet Explorer weergawe 5.5 of hor. Wil U dir byvoeg sonder reiniging?",
+UnknownToolbarItem	: "Unbekende gereedskaps balk item \"%1\"",
+UnknownCommand		: "Unbekende instruksie naam \"%1\"",
+NotImplemented		: "Instruksie is nie geimplementeer nie.",
+UnknownToolbarSet	: "Gereedskaps balk \"%1\" bestaan nie",
+NoActiveX			: "U browser sekuriteit instellings kan die funksies van die editor behinder. U moet die opsie \"Run ActiveX controls and plug-ins\" aktiveer. U ondervinding mag problematies geskiet of sekere funksionaliteit mag verhinder word.",
+BrowseServerBlocked : "Die vorraad venster word geblok! Verseker asseblief dat U die \"popup blocker\" instelling verander.",
+DialogBlocked		: "Die dialoog venster vir verdere informasie word geblok. De-aktiveer asseblief die \"popup blocker\" instellings wat dit behinder.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Kanseleer",
+DlgBtnClose			: "Sluit",
+DlgBtnBrowseServer	: "Server deurblaai",
+DlgAdvancedTag		: "Ingewikkeld",
+DlgOpOther			: "<Ander>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Voeg asseblief die URL in",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<geen instelling>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Taal rigting",
+DlgGenLangDirLtr	: "Links na regs (LTR)",
+DlgGenLangDirRtl	: "Regs na links (RTL)",
+DlgGenLangCode		: "Taal kode",
+DlgGenAccessKey		: "Toegang sleutel",
+DlgGenName			: "Naam",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Lang beskreiwing URL",
+DlgGenClass			: "Skakel Tiepe",
+DlgGenTitle			: "Voorbeveelings Titel",
+DlgGenContType		: "Voorbeveelings inhoud soort",
+DlgGenLinkCharset	: "Geskakelde voorbeeld karakterstel",
+DlgGenStyle			: "Styl",
+
+// Image Dialog
+DlgImgTitle			: "Beeld eienskappe",
+DlgImgInfoTab		: "Beeld informasie",
+DlgImgBtnUpload		: "Stuur dit na die Server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Uplaai",
+DlgImgAlt			: "Alternatiewe beskrywing",
+DlgImgWidth			: "Weidte",
+DlgImgHeight		: "Hoogde",
+DlgImgLockRatio		: "Behou preporsie",
+DlgBtnResetSize		: "Herstel groote",
+DlgImgBorder		: "Kant",
+DlgImgHSpace		: "HSpasie",
+DlgImgVSpace		: "VSpasie",
+DlgImgAlign			: "Paradeer",
+DlgImgAlignLeft		: "Links",
+DlgImgAlignAbsBottom: "Abs Onder",
+DlgImgAlignAbsMiddle: "Abs Middel",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Onder",
+DlgImgAlignMiddle	: "Middel",
+DlgImgAlignRight	: "Regs",
+DlgImgAlignTextTop	: "Text Bo",
+DlgImgAlignTop		: "Bo",
+DlgImgPreview		: "Voorskou",
+DlgImgAlertUrl		: "Voeg asseblief Beeld URL in.",
+DlgImgLinkTab		: "Skakel",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash eienskappe",
+DlgFlashChkPlay		: "Automaties Speel",
+DlgFlashChkLoop		: "Herhaling",
+DlgFlashChkMenu		: "Laat Flash Menu toe",
+DlgFlashScale		: "Scale",
+DlgFlashScaleAll	: "Wys alles",
+DlgFlashScaleNoBorder	: "Geen kante",
+DlgFlashScaleFit	: "Presiese pas",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Skakel",
+DlgLnkInfoTab		: "Skakel informasie",
+DlgLnkTargetTab		: "Mikpunt",
+
+DlgLnkType			: "Skakel soort",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Skakel na plekhouers in text",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<ander>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Kies 'n plekhouer",
+DlgLnkAnchorByName	: "Volgens plekhouer naam",
+DlgLnkAnchorById	: "Volgens element Id",
+DlgLnkNoAnchors		: "<Geen plekhouers beskikbaar in dokument>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Adres",
+DlgLnkEMailSubject	: "Boodskap Opskrif",
+DlgLnkEMailBody		: "Boodskap Inhoud",
+DlgLnkUpload		: "Oplaai",
+DlgLnkBtnUpload		: "Stuur na Server",
+
+DlgLnkTarget		: "Mikpunt",
+DlgLnkTargetFrame	: "<raam>",
+DlgLnkTargetPopup	: "<popup venster>",
+DlgLnkTargetBlank	: "Nuwe Venster (_blank)",
+DlgLnkTargetParent	: "Vorige Venster (_parent)",
+DlgLnkTargetSelf	: "Selfde Venster (_self)",
+DlgLnkTargetTop		: "Boonste Venster (_top)",
+DlgLnkTargetFrameName	: "Mikpunt Venster Naam",
+DlgLnkPopWinName	: "Popup Venster Naam",
+DlgLnkPopWinFeat	: "Popup Venster Geaartheid",
+DlgLnkPopResize		: "Verstelbare Groote",
+DlgLnkPopLocation	: "Adres Balk",
+DlgLnkPopMenu		: "Menu Balk",
+DlgLnkPopScroll		: "Gleibalkstuk",
+DlgLnkPopStatus		: "Status Balk",
+DlgLnkPopToolbar	: "Gereedskap Balk",
+DlgLnkPopFullScrn	: "Voll Skerm (IE)",
+DlgLnkPopDependent	: "Afhanklik (Netscape)",
+DlgLnkPopWidth		: "Weite",
+DlgLnkPopHeight		: "Hoogde",
+DlgLnkPopLeft		: "Links Posisie",
+DlgLnkPopTop		: "Bo Posisie",
+
+DlnLnkMsgNoUrl		: "Voeg asseblief die URL in",
+DlnLnkMsgNoEMail	: "Voeg asseblief die e-mail adres in",
+DlnLnkMsgNoAnchor	: "Kies asseblief 'n plekhouer",
+DlnLnkMsgInvPopName	: "Die popup naam moet begin met alphabetiese karakters sonder spasies.",
+
+// Color Dialog
+DlgColorTitle		: "Kies Kleur",
+DlgColorBtnClear	: "Maak skoon",
+DlgColorHighlight	: "Highlight",
+DlgColorSelected	: "Geselekteer",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Voeg Smiley by",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Kies spesiale karakter",
+
+// Table Dialog
+DlgTableTitle		: "Tabel eienskappe",
+DlgTableRows		: "Reie",
+DlgTableColumns		: "Kolome",
+DlgTableBorder		: "Kant groote",
+DlgTableAlign		: "Parideering",
+DlgTableAlignNotSet	: "<geen instelling>",
+DlgTableAlignLeft	: "Links",
+DlgTableAlignCenter	: "Middel",
+DlgTableAlignRight	: "Regs",
+DlgTableWidth		: "Weite",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Hoogde",
+DlgTableCellSpace	: "Cell spasieering",
+DlgTableCellPad		: "Cell buffer",
+DlgTableCaption		: "Beskreiwing",
+DlgTableSummary		: "Opsomming",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cell eienskappe",
+DlgCellWidth		: "Weite",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Hoogde",
+DlgCellWordWrap		: "Woord Wrap",
+DlgCellWordWrapNotSet	: "<geen instelling>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nee",
+DlgCellHorAlign		: "Horisontale rigting",
+DlgCellHorAlignNotSet	: "<geen instelling>",
+DlgCellHorAlignLeft	: "Links",
+DlgCellHorAlignCenter	: "Middel",
+DlgCellHorAlignRight: "Regs",
+DlgCellVerAlign		: "Vertikale rigting",
+DlgCellVerAlignNotSet	: "<geen instelling>",
+DlgCellVerAlignTop	: "Bo",
+DlgCellVerAlignMiddle	: "Middel",
+DlgCellVerAlignBottom	: "Onder",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Rei strekking",
+DlgCellCollSpan		: "Kolom strekking",
+DlgCellBackColor	: "Agtergrond Kleur",
+DlgCellBorderColor	: "Kant Kleur",
+DlgCellBtnSelect	: "Keuse...",
+
+// Find Dialog
+DlgFindTitle		: "Vind",
+DlgFindFindBtn		: "Vind",
+DlgFindNotFoundMsg	: "Die gespesifiseerde karakters word nie gevind nie.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Vervang",
+DlgReplaceFindLbl		: "Soek wat:",
+DlgReplaceReplaceLbl	: "Vervang met:",
+DlgReplaceCaseChk		: "Vergelyk karakter skryfweise",
+DlgReplaceReplaceBtn	: "Vervang",
+DlgReplaceReplAllBtn	: "Vervang alles",
+DlgReplaceWordChk		: "Vergelyk komplete woord",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "U browser se sekuriteit instelling behinder die uitsny aksie. Gebruik asseblief die sleutel kombenasie(Ctrl+X).",
+PasteErrorCopy	: "U browser se sekuriteit instelling behinder die kopieerings aksie. Gebruik asseblief die sleutel kombenasie(Ctrl+C).",
+
+PasteAsText		: "Voeg slegs karakters by",
+PasteFromWord	: "Byvoeging uit Word",
+
+DlgPasteMsg2	: "Voeg asseblief die inhoud in die gegewe box by met sleutel kombenasie(<STRONG>Ctrl+V</STRONG>) en druk <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoreer karakter soort defenisies",
+DlgPasteRemoveStyles	: "Verweider Styl defenisies",
+DlgPasteCleanBox		: "Maak Box Skoon",
+
+// Color Picker
+ColorAutomatic	: "Automaties",
+ColorMoreColors	: "Meer Kleure...",
+
+// Document Properties
+DocProps		: "Dokument Eienskappe",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Plekhouer Eienskappe",
+DlgAnchorName		: "Plekhouer Naam",
+DlgAnchorErrorName	: "Voltooi die plekhouer naam asseblief",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nie in woordeboek nie",
+DlgSpellChangeTo		: "Verander na",
+DlgSpellBtnIgnore		: "Ignoreer",
+DlgSpellBtnIgnoreAll	: "Ignoreer na-volgende",
+DlgSpellBtnReplace		: "Vervang",
+DlgSpellBtnReplaceAll	: "vervang na-volgende",
+DlgSpellBtnUndo			: "Ont-skep",
+DlgSpellNoSuggestions	: "- Geen voorstel -",
+DlgSpellProgress		: "Spelling word beproef...",
+DlgSpellNoMispell		: "Spellproef kompleet: Geen foute",
+DlgSpellNoChanges		: "Spellproef kompleet: Geen woord veranderings",
+DlgSpellOneChange		: "Spellproef kompleet: Een woord verander",
+DlgSpellManyChanges		: "Spellproef kompleet: %1 woorde verander",
+
+IeSpellDownload			: "Geen Spellproefer geinstaleer nie. Wil U dit aflaai?",
+
+// Button Dialog
+DlgButtonText		: "Karakters (Waarde)",
+DlgButtonType		: "Soort",
+DlgButtonTypeBtn	: "Knop",
+DlgButtonTypeSbm	: "Indien",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Naam",
+DlgCheckboxValue	: "Waarde",
+DlgCheckboxSelected	: "Uitgekies",
+
+// Form Dialog
+DlgFormName		: "Naam",
+DlgFormAction	: "Aksie",
+DlgFormMethod	: "Metode",
+
+// Select Field Dialog
+DlgSelectName		: "Naam",
+DlgSelectValue		: "Waarde",
+DlgSelectSize		: "Grote",
+DlgSelectLines		: "lyne",
+DlgSelectChkMulti	: "Laat meerere keuses toe",
+DlgSelectOpAvail	: "Beskikbare Opsies",
+DlgSelectOpText		: "Karakters",
+DlgSelectOpValue	: "Waarde",
+DlgSelectBtnAdd		: "Byvoeg",
+DlgSelectBtnModify	: "Verander",
+DlgSelectBtnUp		: "Op",
+DlgSelectBtnDown	: "Af",
+DlgSelectBtnSetValue : "Stel as uitgekiesde waarde",
+DlgSelectBtnDelete	: "Verweider",
+
+// Textarea Dialog
+DlgTextareaName	: "Naam",
+DlgTextareaCols	: "Kolom",
+DlgTextareaRows	: "Reie",
+
+// Text Field Dialog
+DlgTextName			: "Naam",
+DlgTextValue		: "Waarde",
+DlgTextCharWidth	: "Karakter weite",
+DlgTextMaxChars		: "Maximale karakters",
+DlgTextType			: "Soort",
+DlgTextTypeText		: "Karakters",
+DlgTextTypePass		: "Wagwoord",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Naam",
+DlgHiddenValue	: "Waarde",
+
+// Bulleted List Dialog
+BulletedListProp	: "Gepunkte lys eienskappe",
+NumberedListProp	: "Genommerde lys eienskappe",
+DlgLstStart			: "Begin",
+DlgLstType			: "Soort",
+DlgLstTypeCircle	: "Sirkel",
+DlgLstTypeDisc		: "Skyf",
+DlgLstTypeSquare	: "Vierkant",
+DlgLstTypeNumbers	: "Nommer (1, 2, 3)",
+DlgLstTypeLCase		: "Klein Letters (a, b, c)",
+DlgLstTypeUCase		: "Hoof Letters (A, B, C)",
+DlgLstTypeSRoman	: "Klein Romeinse nommers (i, ii, iii)",
+DlgLstTypeLRoman	: "Groot Romeinse nommers (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Algemeen",
+DlgDocBackTab		: "Agtergrond",
+DlgDocColorsTab		: "Kleure en Rante",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Bladsy Opskrif",
+DlgDocLangDir		: "Taal rigting",
+DlgDocLangDirLTR	: "Link na Regs (LTR)",
+DlgDocLangDirRTL	: "Regs na Links (RTL)",
+DlgDocLangCode		: "Taal Kode",
+DlgDocCharSet		: "Karakterstel Kodeering",
+DlgDocCharSetCE		: "Sentraal Europa",
+DlgDocCharSetCT		: "Chinees Traditioneel (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Grieks",
+DlgDocCharSetJP		: "Japanees",
+DlgDocCharSetKR		: "Koreans",
+DlgDocCharSetTR		: "Turks",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "Ander Karakterstel Kodeering",
+
+DlgDocDocType		: "Dokument Opskrif Soort",
+DlgDocDocTypeOther	: "Ander Dokument Opskrif Soort",
+DlgDocIncXHTML		: "Voeg XHTML verklaring by",
+DlgDocBgColor		: "Agtergrond kleur",
+DlgDocBgImage		: "Agtergrond Beeld URL",
+DlgDocBgNoScroll	: "Vasgeklemde Agtergrond",
+DlgDocCText			: "Karakters",
+DlgDocCLink			: "Skakel",
+DlgDocCVisited		: "Besoekte Skakel",
+DlgDocCActive		: "Aktiewe Skakel",
+DlgDocMargins		: "Bladsy Rante",
+DlgDocMaTop			: "Bo",
+DlgDocMaLeft		: "Links",
+DlgDocMaRight		: "Regs",
+DlgDocMaBottom		: "Onder",
+DlgDocMeIndex		: "Dokument Index Sleutelwoorde(comma verdeelt)",
+DlgDocMeDescr		: "Dokument Beskrywing",
+DlgDocMeAuthor		: "Skrywer",
+DlgDocMeCopy		: "Kopiereg",
+DlgDocPreview		: "Voorskou",
+
+// Templates Dialog
+Templates			: "Templates",
+DlgTemplatesTitle	: "Inhoud Templates",
+DlgTemplatesSelMsg	: "Kies die template om te gebruik in die editor<br>(Inhoud word vervang!):",
+DlgTemplatesLoading	: "Templates word gelaai. U geduld asseblief...",
+DlgTemplatesNoTpl	: "(Geen templates gedefinieerd)",
+DlgTemplatesReplace	: "Vervang bestaande inhoud",
+
+// About Dialog
+DlgAboutAboutTab	: "Meer oor",
+DlgAboutBrowserInfoTab	: "Blaai Informasie deur",
+DlgAboutLicenseTab	: "Lesensie",
+DlgAboutVersion		: "weergawe",
+DlgAboutInfo		: "Vir meer informasie gaan na "
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/nb.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/nb.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/nb.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Norwegian Bokmål language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Skjul verktøylinje",
+ToolbarExpand		: "Vis verktøylinje",
+
+// Toolbar Items and Context Menu
+Save				: "Lagre",
+NewPage				: "Ny Side",
+Preview				: "Forhåndsvis",
+Cut					: "Klipp ut",
+Copy				: "Kopier",
+Paste				: "Lim inn",
+PasteText			: "Lim inn som ren tekst",
+PasteWord			: "Lim inn fra Word",
+Print				: "Skriv ut",
+SelectAll			: "Velg alle",
+RemoveFormat		: "Fjern format",
+InsertLinkLbl		: "Lenke",
+InsertLink			: "Sett inn/Rediger lenke",
+RemoveLink			: "Fjern lenke",
+Anchor				: "Sett inn/Rediger anker",
+InsertImageLbl		: "Bilde",
+InsertImage			: "Sett inn/Rediger bilde",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Sett inn/Rediger Flash",
+InsertTableLbl		: "Tabell",
+InsertTable			: "Sett inn/Rediger tabell",
+InsertLineLbl		: "Linje",
+InsertLine			: "Sett inn horisontal linje",
+InsertSpecialCharLbl: "Spesielt tegn",
+InsertSpecialChar	: "Sett inn spesielt tegn",
+InsertSmileyLbl		: "Smil",
+InsertSmiley		: "Sett inn smil",
+About				: "Om FCKeditor",
+Bold				: "Fet",
+Italic				: "Kursiv",
+Underline			: "Understrek",
+StrikeThrough		: "Gjennomstrek",
+Subscript			: "Senket skrift",
+Superscript			: "Hevet skrift",
+LeftJustify			: "Venstrejuster",
+CenterJustify		: "Midtjuster",
+RightJustify		: "Høyrejuster",
+BlockJustify		: "Blokkjuster",
+DecreaseIndent		: "Senk nivå",
+IncreaseIndent		: "Øk nivå",
+Undo				: "Angre",
+Redo				: "Gjør om",
+NumberedListLbl		: "Numrert liste",
+NumberedList		: "Sett inn/Fjern numrert liste",
+BulletedListLbl		: "Uordnet liste",
+BulletedList		: "Sett inn/Fjern uordnet liste",
+ShowTableBorders	: "Vis tabellrammer",
+ShowDetails			: "Vis detaljer",
+Style				: "Stil",
+FontFormat			: "Format",
+Font				: "Skrift",
+FontSize			: "Størrelse",
+TextColor			: "Tekstfarge",
+BGColor				: "Bakgrunnsfarge",
+Source				: "Kilde",
+Find				: "Finn",
+Replace				: "Erstatt",
+SpellCheck			: "Stavekontroll",
+UniversalKeyboard	: "Universelt tastatur",
+PageBreakLbl		: "Sideskift",
+PageBreak			: "Sett inn sideskift",
+
+Form			: "Skjema",
+Checkbox		: "Sjekkboks",
+RadioButton		: "Radioknapp",
+TextField		: "Tekstfelt",
+Textarea		: "Tekstområde",
+HiddenField		: "Skjult felt",
+Button			: "Knapp",
+SelectionField	: "Dropdown meny",
+ImageButton		: "Bildeknapp",
+
+FitWindow		: "Maksimer størrelsen på redigeringsverktøyet",
+
+// Context Menu
+EditLink			: "Rediger lenke",
+CellCM				: "Celle",
+RowCM				: "Rader",
+ColumnCM			: "Kolonne",
+InsertRow			: "Sett inn rad",
+DeleteRows			: "Slett rader",
+InsertColumn		: "Sett inn kolonne",
+DeleteColumns		: "Slett kolonner",
+InsertCell			: "Sett inn celle",
+DeleteCells			: "Slett celler",
+MergeCells			: "Slå sammen celler",
+SplitCell			: "Splitt celler",
+TableDelete			: "Slett tabell",
+CellProperties		: "Celleegenskaper",
+TableProperties		: "Tabellegenskaper",
+ImageProperties		: "Bildeegenskaper",
+FlashProperties		: "Flash Egenskaper",
+
+AnchorProp			: "Ankeregenskaper",
+ButtonProp			: "Knappegenskaper",
+CheckboxProp		: "Sjekkboksegenskaper",
+HiddenFieldProp		: "Skjult felt egenskaper",
+RadioButtonProp		: "Radioknappegenskaper",
+ImageButtonProp		: "Bildeknappegenskaper",
+TextFieldProp		: "Tekstfeltegenskaper",
+SelectionFieldProp	: "Dropdown menyegenskaper",
+TextareaProp		: "Tekstfeltegenskaper",
+FormProp			: "Skjemaegenskaper",
+
+FontFormats			: "Normal;Formatert;Adresse;Tittel 1;Tittel 2;Tittel 3;Tittel 4;Tittel 5;Tittel 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Lager XHTML. Vennligst vent...",
+Done				: "Ferdig",
+PasteWordConfirm	: "Teksten du prøver å lime inn ser ut som om den kommer fra word , du bør rense den før du limer inn , vil du gjøre dette?",
+NotCompatiblePaste	: "Denne kommandoen er tilgjenglig kun for Internet Explorer version 5.5 eller bedre. Vil du fortsette uten å rense?(Du kan lime inn som ren tekst)",
+UnknownToolbarItem	: "Ukjent menyvalg \"%1\"",
+UnknownCommand		: "Ukjent kommando \"%1\"",
+NotImplemented		: "Kommando ikke ennå implimentert",
+UnknownToolbarSet	: "Verktøylinjesett \"%1\" finnes ikke",
+NoActiveX			: "Din nettleser's sikkerhetsinstillinger kan begrense noen av funksjonene i redigeringsverktøyet. Du må aktivere \"Kjør ActiveXkontroller og plugins\". Du kan oppleve feil og advarsler om manglende funksjoner",
+BrowseServerBlocked : "Kunne ikke åpne dialogboksen for filarkiv. Pass på at du har slått av popupstoppere.",
+DialogBlocked		: "Kunne ikke åpne dialogboksen. Pass på at du har slått av popupstoppere.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Avbryt",
+DlgBtnClose			: "Lukk",
+DlgBtnBrowseServer	: "Bla igjennom server",
+DlgAdvancedTag		: "Avansert",
+DlgOpOther			: "<Annet>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Vennligst skriv inn URL'en",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ikke satt>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Språkretning",
+DlgGenLangDirLtr	: "Venstre til høyre (VTH)",
+DlgGenLangDirRtl	: "Høyre til venstre (HTV)",
+DlgGenLangCode		: "Språk kode",
+DlgGenAccessKey		: "Aksessknapp",
+DlgGenName			: "Navn",
+DlgGenTabIndex		: "Tab Indeks",
+DlgGenLongDescr		: "Utvidet beskrivelse",
+DlgGenClass			: "Stilarkklasser",
+DlgGenTitle			: "Tittel",
+DlgGenContType		: "Type",
+DlgGenLinkCharset	: "Lenket språkkart",
+DlgGenStyle			: "Stil",
+
+// Image Dialog
+DlgImgTitle			: "Bildeegenskaper",
+DlgImgInfoTab		: "Bildeinformasjon",
+DlgImgBtnUpload		: "Send det til serveren",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Last opp",
+DlgImgAlt			: "Alternativ tekst",
+DlgImgWidth			: "Bredde",
+DlgImgHeight		: "Høyde",
+DlgImgLockRatio		: "Lås forhold",
+DlgBtnResetSize		: "Tilbakestill størrelse",
+DlgImgBorder		: "Ramme",
+DlgImgHSpace		: "HMarg",
+DlgImgVSpace		: "VMarg",
+DlgImgAlign			: "Juster",
+DlgImgAlignLeft		: "Venstre",
+DlgImgAlignAbsBottom: "Abs bunn",
+DlgImgAlignAbsMiddle: "Abs midten",
+DlgImgAlignBaseline	: "Bunnlinje",
+DlgImgAlignBottom	: "Bunn",
+DlgImgAlignMiddle	: "Midten",
+DlgImgAlignRight	: "Høyre",
+DlgImgAlignTextTop	: "Tekst topp",
+DlgImgAlignTop		: "Topp",
+DlgImgPreview		: "Forhåndsvis",
+DlgImgAlertUrl		: "Vennligst skriv bildeurlen",
+DlgImgLinkTab		: "Lenke",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Egenskaper",
+DlgFlashChkPlay		: "Auto Spill",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Slå på Flash meny",
+DlgFlashScale		: "Skaler",
+DlgFlashScaleAll	: "Vis alt",
+DlgFlashScaleNoBorder	: "Ingen ramme",
+DlgFlashScaleFit	: "Skaler til å passeExact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Lenke",
+DlgLnkInfoTab		: "Lenkeinfo",
+DlgLnkTargetTab		: "Mål",
+
+DlgLnkType			: "Lenketype",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Lenke til bokmerke i teksten",
+DlgLnkTypeEMail		: "E-Post",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<annet>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Velg ett anker",
+DlgLnkAnchorByName	: "Anker etter navn",
+DlgLnkAnchorById	: "Element etter ID",
+DlgLnkNoAnchors		: "<Ingen anker i dokumentet>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Post Addresse",
+DlgLnkEMailSubject	: "Meldingsemne",
+DlgLnkEMailBody		: "Melding",
+DlgLnkUpload		: "Last opp",
+DlgLnkBtnUpload		: "Send til server",
+
+DlgLnkTarget		: "Mål",
+DlgLnkTargetFrame	: "<ramme>",
+DlgLnkTargetPopup	: "<popup vindu>",
+DlgLnkTargetBlank	: "Nytt vindu (_blank)",
+DlgLnkTargetParent	: "Foreldre vindu (_parent)",
+DlgLnkTargetSelf	: "Samme vindu (_self)",
+DlgLnkTargetTop		: "Hele vindu (_top)",
+DlgLnkTargetFrameName	: "Målramme",
+DlgLnkPopWinName	: "Popup vindus navn",
+DlgLnkPopWinFeat	: "Popup vindus egenskaper",
+DlgLnkPopResize		: "Endre størrelse",
+DlgLnkPopLocation	: "Adresselinje",
+DlgLnkPopMenu		: "Menylinje",
+DlgLnkPopScroll		: "Scrollbar",
+DlgLnkPopStatus		: "Statuslinje",
+DlgLnkPopToolbar	: "Verktøylinje",
+DlgLnkPopFullScrn	: "Full skjerm (IE)",
+DlgLnkPopDependent	: "Avhenging (Netscape)",
+DlgLnkPopWidth		: "Bredde",
+DlgLnkPopHeight		: "Høyde",
+DlgLnkPopLeft		: "Venstre posisjon",
+DlgLnkPopTop		: "Topp posisjon",
+
+DlnLnkMsgNoUrl		: "Vennligst skriv inn lenkens url",
+DlnLnkMsgNoEMail	: "Vennligst skriv inn e-postadressen",
+DlnLnkMsgNoAnchor	: "Vennligst velg ett anker",
+DlnLnkMsgInvPopName	: "Popup vinduets navn må begynne med en bokstav, og kan ikke inneholde mellomrom",
+
+// Color Dialog
+DlgColorTitle		: "Velg farge",
+DlgColorBtnClear	: "Tøm",
+DlgColorHighlight	: "Marker",
+DlgColorSelected	: "Velg",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Sett inn smil",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Velg spesielt tegn",
+
+// Table Dialog
+DlgTableTitle		: "Tabellegenskaper",
+DlgTableRows		: "Rader",
+DlgTableColumns		: "Kolonner",
+DlgTableBorder		: "Rammestørrelse",
+DlgTableAlign		: "Justering",
+DlgTableAlignNotSet	: "<Ikke satt>",
+DlgTableAlignLeft	: "Venstre",
+DlgTableAlignCenter	: "Midtjuster",
+DlgTableAlignRight	: "Høyre",
+DlgTableWidth		: "Bredde",
+DlgTableWidthPx		: "pixler",
+DlgTableWidthPc		: "prosent",
+DlgTableHeight		: "Høyde",
+DlgTableCellSpace	: "Celle marg",
+DlgTableCellPad		: "Celle polstring",
+DlgTableCaption		: "Tittel",
+DlgTableSummary		: "Sammendrag",
+
+// Table Cell Dialog
+DlgCellTitle		: "Celle egenskaper",
+DlgCellWidth		: "Bredde",
+DlgCellWidthPx		: "pixeler",
+DlgCellWidthPc		: "prosent",
+DlgCellHeight		: "Høyde",
+DlgCellWordWrap		: "Tekstbrytning",
+DlgCellWordWrapNotSet	: "<Ikke satt>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nei",
+DlgCellHorAlign		: "Horisontal justering",
+DlgCellHorAlignNotSet	: "<Ikke satt>",
+DlgCellHorAlignLeft	: "Venstre",
+DlgCellHorAlignCenter	: "Midtjuster",
+DlgCellHorAlignRight: "Høyre",
+DlgCellVerAlign		: "Vertikal justering",
+DlgCellVerAlignNotSet	: "<Ikke satt>",
+DlgCellVerAlignTop	: "Topp",
+DlgCellVerAlignMiddle	: "Midten",
+DlgCellVerAlignBottom	: "Bunn",
+DlgCellVerAlignBaseline	: "Bunnlinje",
+DlgCellRowSpan		: "Radspenn",
+DlgCellCollSpan		: "Kolonnespenn",
+DlgCellBackColor	: "Bakgrunnsfarge",
+DlgCellBorderColor	: "Rammefarge",
+DlgCellBtnSelect	: "Velg...",
+
+// Find Dialog
+DlgFindTitle		: "Finn",
+DlgFindFindBtn		: "Finn",
+DlgFindNotFoundMsg	: "Den spesifiserte teksten ble ikke funnet.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Erstatt",
+DlgReplaceFindLbl		: "Finn hva:",
+DlgReplaceReplaceLbl	: "Erstatt med:",
+DlgReplaceCaseChk		: "Riktig case",
+DlgReplaceReplaceBtn	: "Erstatt",
+DlgReplaceReplAllBtn	: "Erstatt alle",
+DlgReplaceWordChk		: "Finn hele ordet",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Din nettlesers sikkerhetsinstillinger tillater ikke automatisk klipping av tekst. Vennligst brukt snareveien (Ctrl+X).",
+PasteErrorCopy	: "Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst brukt snareveien (Ctrl+C).",
+
+PasteAsText		: "Lim inn som ren tekst",
+PasteFromWord	: "Lim inn fra word",
+
+DlgPasteMsg2	: "Vennligst lim inn i den følgende boksen med tastaturet (<STRONG>Ctrl+V</STRONG>) og trykk <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Fjern skrifttyper",
+DlgPasteRemoveStyles	: "Fjern stildefinisjoner",
+DlgPasteCleanBox		: "Tøm boksen",
+
+// Color Picker
+ColorAutomatic	: "Automatisk",
+ColorMoreColors	: "Flere farger...",
+
+// Document Properties
+DocProps		: "Dokumentegenskaper",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ankeregenskaper",
+DlgAnchorName		: "Ankernavn",
+DlgAnchorErrorName	: "Vennligst skriv inn ankernavnet",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ikke i ordboken",
+DlgSpellChangeTo		: "Endre til",
+DlgSpellBtnIgnore		: "Ignorer",
+DlgSpellBtnIgnoreAll	: "Ignorer alle",
+DlgSpellBtnReplace		: "Erstatt",
+DlgSpellBtnReplaceAll	: "Erstatt alle",
+DlgSpellBtnUndo			: "Angre",
+DlgSpellNoSuggestions	: "- ingen forslag -",
+DlgSpellProgress		: "Stavekontroll pågår...",
+DlgSpellNoMispell		: "Stavekontroll fullført: ingen feilstavinger funnet",
+DlgSpellNoChanges		: "Stavekontroll fullført: ingen ord endret",
+DlgSpellOneChange		: "Stavekontroll fullført: Ett ord endret",
+DlgSpellManyChanges		: "Stavekontroll fullført: %1 ord endret",
+
+IeSpellDownload			: "Stavekontroll ikke installert, vil du laste den ned nå?",
+
+// Button Dialog
+DlgButtonText		: "Tekst",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Knapp",
+DlgButtonTypeSbm	: "Send",
+DlgButtonTypeRst	: "Nullstill",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Navn",
+DlgCheckboxValue	: "Verdi",
+DlgCheckboxSelected	: "Valgt",
+
+// Form Dialog
+DlgFormName		: "Navn",
+DlgFormAction	: "Handling",
+DlgFormMethod	: "Metode",
+
+// Select Field Dialog
+DlgSelectName		: "Navn",
+DlgSelectValue		: "Verdi",
+DlgSelectSize		: "Størrelse",
+DlgSelectLines		: "Linjer",
+DlgSelectChkMulti	: "Tillat flervalg",
+DlgSelectOpAvail	: "Tilgjenglige alternativer",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Verdi",
+DlgSelectBtnAdd		: "Legg til",
+DlgSelectBtnModify	: "Endre",
+DlgSelectBtnUp		: "Opp",
+DlgSelectBtnDown	: "Ned",
+DlgSelectBtnSetValue : "Sett som valgt",
+DlgSelectBtnDelete	: "Slett",
+
+// Textarea Dialog
+DlgTextareaName	: "Navn",
+DlgTextareaCols	: "Kolonner",
+DlgTextareaRows	: "Rader",
+
+// Text Field Dialog
+DlgTextName			: "Navn",
+DlgTextValue		: "verdi",
+DlgTextCharWidth	: "Tegnbredde",
+DlgTextMaxChars		: "Maks antall tegn",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Passord",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Navn",
+DlgHiddenValue	: "Verdi",
+
+// Bulleted List Dialog
+BulletedListProp	: "Uordnet listeegenskaper",
+NumberedListProp	: "Ordnet listeegenskaper",
+DlgLstStart			: "Start",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Sirkel",
+DlgLstTypeDisc		: "Hel sirkel",
+DlgLstTypeSquare	: "Firkant",
+DlgLstTypeNumbers	: "Numre(1, 2, 3)",
+DlgLstTypeLCase		: "Små bokstaver (a, b, c)",
+DlgLstTypeUCase		: "Store bokstaver(A, B, C)",
+DlgLstTypeSRoman	: "Små romerske tall(i, ii, iii)",
+DlgLstTypeLRoman	: "Store romerske tall(I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Generalt",
+DlgDocBackTab		: "Bakgrunn",
+DlgDocColorsTab		: "Farger og marginer",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Sidetittel",
+DlgDocLangDir		: "Språkretning",
+DlgDocLangDirLTR	: "Venstre til høyre (LTR)",
+DlgDocLangDirRTL	: "Høyre til venstre (RTL)",
+DlgDocLangCode		: "Språkkode",
+DlgDocCharSet		: "Tegnsett",
+DlgDocCharSetCE		: "Sentraleuropeisk",
+DlgDocCharSetCT		: "Tradisonell kinesisk(Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Gresk",
+DlgDocCharSetJP		: "Japansk",
+DlgDocCharSetKR		: "Koreansk",
+DlgDocCharSetTR		: "Tyrkisk",
+DlgDocCharSetUN		: "Unikode (UTF-8)",
+DlgDocCharSetWE		: "Vesteuropeisk",
+DlgDocCharSetOther	: "Annet tegnsett",
+
+DlgDocDocType		: "Dokumenttype header",
+DlgDocDocTypeOther	: "Annet dokumenttype header",
+DlgDocIncXHTML		: "Inkulder XHTML deklarasjon",
+DlgDocBgColor		: "Bakgrunnsfarge",
+DlgDocBgImage		: "Bakgrunnsbilde url",
+DlgDocBgNoScroll	: "Ikke scroll bakgrunnsbilde",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Besøkt lenke",
+DlgDocCActive		: "Aktiv lenke",
+DlgDocMargins		: "Sidemargin",
+DlgDocMaTop			: "Topp",
+DlgDocMaLeft		: "Venstre",
+DlgDocMaRight		: "Høyre",
+DlgDocMaBottom		: "Bunn",
+DlgDocMeIndex		: "Dokument nøkkelord (kommaseparert)",
+DlgDocMeDescr		: "Dokumentbeskrivelse",
+DlgDocMeAuthor		: "Forfatter",
+DlgDocMeCopy		: "Kopirett",
+DlgDocPreview		: "Forhåndsvising",
+
+// Templates Dialog
+Templates			: "Maler",
+DlgTemplatesTitle	: "Innholdsmaler",
+DlgTemplatesSelMsg	: "Velg malen du vil åpne<br>(innholdet du har skrevet blir tapt!):",
+DlgTemplatesLoading	: "Laster malliste. Vennligst vent...",
+DlgTemplatesNoTpl	: "(Ingen maler definert)",
+DlgTemplatesReplace	: "Erstatt faktisk innold",
+
+// About Dialog
+DlgAboutAboutTab	: "Om",
+DlgAboutBrowserInfoTab	: "Nettleserinfo",
+DlgAboutLicenseTab	: "Lisens",
+DlgAboutVersion		: "versjon",
+DlgAboutInfo		: "For further information go to"	//MISSING
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bn.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bn.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bn.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Bengali/Bangla language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "টূলবার গুটিয়ে দাও",
+ToolbarExpand		: "টূলবার ছড়িয়ে দাও",
+
+// Toolbar Items and Context Menu
+Save				: "সংরক্ষন কর",
+NewPage				: "নতুন পেজ",
+Preview				: "প্রিভিউ",
+Cut					: "কাট",
+Copy				: "কপি",
+Paste				: "পেস্ট",
+PasteText			: "পেস্ট (সাদা টেক্সট)",
+PasteWord			: "পেস্ট (শব্দ)",
+Print				: "প্রিন্ট",
+SelectAll			: "সব সিলেক্ট কর",
+RemoveFormat		: "ফরমেট সরাও",
+InsertLinkLbl		: "লিংকের যুক্ত করার লেবেল",
+InsertLink			: "লিংক যুক্ত কর",
+RemoveLink			: "লিংক সরাও",
+Anchor				: "নোঙ্গর",
+InsertImageLbl		: "ছবির লেবেল যুক্ত কর",
+InsertImage			: "ছবি যুক্ত কর",
+InsertFlashLbl		: "ফ্লাশ লেবেল যুক্ত কর",
+InsertFlash			: "ফ্লাশ যুক্ত কর",
+InsertTableLbl		: "টেবিলের লেবেল যুক্ত কর",
+InsertTable			: "টেবিল যুক্ত কর",
+InsertLineLbl		: "রেখা যুক্ত কর",
+InsertLine			: "রেখা যুক্ত কর",
+InsertSpecialCharLbl: "বিশেষ অক্ষরের লেবেল যুক্ত কর",
+InsertSpecialChar	: "বিশেষ অক্ষর যুক্ত কর",
+InsertSmileyLbl		: "স্মাইলী",
+InsertSmiley		: "স্মাইলী যুক্ত কর",
+About				: "FCKeditor কে বানিয়েছে",
+Bold				: "বোল্ড",
+Italic				: "ইটালিক",
+Underline			: "আন্ডারলাইন",
+StrikeThrough		: "স্ট্রাইক থ্রু",
+Subscript			: "অধোলেখ",
+Superscript			: "অভিলেখ",
+LeftJustify			: "বা দিকে ঘেঁষা",
+CenterJustify		: "মাঝ বরাবর ঘেষা",
+RightJustify		: "ডান দিকে ঘেঁষা",
+BlockJustify		: "ব্লক জাস্টিফাই",
+DecreaseIndent		: "ইনডেন্ট কমাও",
+IncreaseIndent		: "ইনডেন্ট বাড়াও",
+Undo				: "আনডু",
+Redo				: "রি-ডু",
+NumberedListLbl		: "সাংখ্যিক লিস্টের লেবেল",
+NumberedList		: "সাংখ্যিক লিস্ট",
+BulletedListLbl		: "বুলেট লিস্ট লেবেল",
+BulletedList		: "বুলেটেড লিস্ট",
+ShowTableBorders	: "টেবিল বর্ডার",
+ShowDetails			: "সবটুকু দেখাও",
+Style				: "স্টাইল",
+FontFormat			: "ফন্ট ফরমেট",
+Font				: "ফন্ট",
+FontSize			: "সাইজ",
+TextColor			: "টেক্স্ট রং",
+BGColor				: "বেকগ্রাউন্ড রং",
+Source				: "সোর্স",
+Find				: "খোজো",
+Replace				: "রিপ্লেস",
+SpellCheck			: "বানান চেক",
+UniversalKeyboard	: "সার্বজনীন কিবোর্ড",
+PageBreakLbl		: "পেজ ব্রেক লেবেল",
+PageBreak			: "পেজ ব্রেক",
+
+Form			: "ফর্ম",
+Checkbox		: "চেক বাক্স",
+RadioButton		: "রেডিও বাটন",
+TextField		: "টেক্সট ফীল্ড",
+Textarea		: "টেক্সট এরিয়া",
+HiddenField		: "গুপ্ত ফীল্ড",
+Button			: "বাটন",
+SelectionField	: "বাছাই ফীল্ড",
+ImageButton		: "ছবির বাটন",
+
+FitWindow		: "উইন্ডো ফিট কর",
+
+// Context Menu
+EditLink			: "লিংক সম্পাদন",
+CellCM				: "সেল",
+RowCM				: "রো",
+ColumnCM			: "কলাম",
+InsertRow			: "রো যুক্ত কর",
+DeleteRows			: "রো মুছে দাও",
+InsertColumn		: "কলাম যুক্ত কর",
+DeleteColumns		: "কলাম মুছে দাও",
+InsertCell			: "সেল যুক্ত কর",
+DeleteCells			: "সেল মুছে দাও",
+MergeCells			: "সেল জোড়া দাও",
+SplitCell			: "সেল আলাদা কর",
+TableDelete			: "টেবিল ডিলীট কর",
+CellProperties		: "সেলের প্রোপার্টিজ",
+TableProperties		: "টেবিল প্রোপার্টি",
+ImageProperties		: "ছবি প্রোপার্টি",
+FlashProperties		: "ফ্লাশ প্রোপার্টি",
+
+AnchorProp			: "নোঙর প্রোপার্টি",
+ButtonProp			: "বাটন প্রোপার্টি",
+CheckboxProp		: "চেক বক্স প্রোপার্টি",
+HiddenFieldProp		: "গুপ্ত ফীল্ড প্রোপার্টি",
+RadioButtonProp		: "রেডিও বাটন প্রোপার্টি",
+ImageButtonProp		: "ছবি বাটন প্রোপার্টি",
+TextFieldProp		: "টেক্সট ফীল্ড প্রোপার্টি",
+SelectionFieldProp	: "বাছাই ফীল্ড প্রোপার্টি",
+TextareaProp		: "টেক্সট এরিয়া প্রোপার্টি",
+FormProp			: "ফর্ম প্রোপার্টি",
+
+FontFormats			: "সাধারণ;ফর্মেটেড;ঠিকানা;শীর্ষক ১;শীর্ষক ২;শীর্ষক ৩;শীর্ষক ৪;শীর্ষক ৫;শীর্ষক ৬;শীর্ষক (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML প্রসেস করা হচ্ছে",
+Done				: "শেষ হয়েছে",
+PasteWordConfirm	: "যে টেকস্টটি আপনি পেস্ট করতে চাচ্ছেন মনে হচ্ছে সেটি ওয়ার্ড থেকে কপি করা। আপনি কি পেস্ট করার আগে একে পরিষ্কার করতে চান?",
+NotCompatiblePaste	: "এই কমান্ডটি শুধুমাত্র ইন্টারনেট এক্সপ্লোরার ৫.০ বা তার পরের ভার্সনে পাওয়া সম্ভব। আপনি কি পরিষ্কার না করেই পেস্ট করতে চান?",
+UnknownToolbarItem	: "অজানা টুলবার আইটেম \"%1\"",
+UnknownCommand		: "অজানা কমান্ড \"%1\"",
+NotImplemented		: "কমান্ড ইমপ্লিমেন্ট করা হয়নি",
+UnknownToolbarSet	: "টুলবার সেট \"%1\" এর অস্তিত্ব নেই",
+NoActiveX			: "আপনার ব্রাউজারের সুরক্ষা সেটিংস কারনে এডিটরের কিছু ফিচার পাওয়া নাও যেতে পারে। আপনাকে অবশ্যই \"Run ActiveX controls and plug-ins\" এনাবেল করে নিতে হবে। আপনি ভুলভ্রান্তি কিছু কিছু ফিচারের অনুপস্থিতি উপলব্ধি করতে পারেন।",
+BrowseServerBlocked : "রিসোর্স ব্রাউজার খোলা গেল না। নিশ্চিত করুন যে সব পপআপ ব্লকার বন্ধ করা আছে।",
+DialogBlocked		: "ডায়ালগ ইউন্ডো খোলা গেল না। নিশ্চিত করুন যে সব পপআপ ব্লকার বন্ধ করা আছে।",
+
+// Dialogs
+DlgBtnOK			: "ওকে",
+DlgBtnCancel		: "বাতিল",
+DlgBtnClose			: "বন্ধ কর",
+DlgBtnBrowseServer	: "ব্রাউজ সার্ভার",
+DlgAdvancedTag		: "এডভান্সড",
+DlgOpOther			: "<অন্য>",
+DlgInfoTab			: "তথ্য",
+DlgAlertUrl			: "দয়া করে URL যুক্ত করুন",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<সেট নেই>",
+DlgGenId			: "আইডি",
+DlgGenLangDir		: "ভাষা লেখার দিক",
+DlgGenLangDirLtr	: "বাম থেকে ডান (LTR)",
+DlgGenLangDirRtl	: "ডান থেকে বাম (RTL)",
+DlgGenLangCode		: "ভাষা কোড",
+DlgGenAccessKey		: "এক্সেস কী",
+DlgGenName			: "নাম",
+DlgGenTabIndex		: "ট্যাব ইন্ডেক্স",
+DlgGenLongDescr		: "URL এর লম্বা বর্ণনা",
+DlgGenClass			: "স্টাইল-শীট ক্লাস",
+DlgGenTitle			: "পরামর্শ শীর্ষক",
+DlgGenContType		: "পরামর্শ কন্টেন্টের প্রকার",
+DlgGenLinkCharset	: "লিংক রিসোর্স ক্যারেক্টর সেট",
+DlgGenStyle			: "স্টাইল",
+
+// Image Dialog
+DlgImgTitle			: "ছবির প্রোপার্টি",
+DlgImgInfoTab		: "ছবির তথ্য",
+DlgImgBtnUpload		: "ইহাকে সার্ভারে প্রেরন কর",
+DlgImgURL			: "URL",
+DlgImgUpload		: "আপলোড",
+DlgImgAlt			: "বিকল্প টেক্সট",
+DlgImgWidth			: "প্রস্থ",
+DlgImgHeight		: "দৈর্ঘ্য",
+DlgImgLockRatio		: "অনুপাত লক কর",
+DlgBtnResetSize		: "সাইজ পূর্বাবস্থায় ফিরিয়ে দাও",
+DlgImgBorder		: "বর্ডার",
+DlgImgHSpace		: "হরাইজন্টাল স্পেস",
+DlgImgVSpace		: "ভার্টিকেল স্পেস",
+DlgImgAlign			: "এলাইন",
+DlgImgAlignLeft		: "বামে",
+DlgImgAlignAbsBottom: "Abs নীচে",
+DlgImgAlignAbsMiddle: "Abs উপর",
+DlgImgAlignBaseline	: "মূল রেখা",
+DlgImgAlignBottom	: "নীচে",
+DlgImgAlignMiddle	: "মধ্য",
+DlgImgAlignRight	: "ডানে",
+DlgImgAlignTextTop	: "টেক্সট উপর",
+DlgImgAlignTop		: "উপর",
+DlgImgPreview		: "প্রীভিউ",
+DlgImgAlertUrl		: "অনুগ্রহক করে ছবির URL টাইপ করুন",
+DlgImgLinkTab		: "লিংক",
+
+// Flash Dialog
+DlgFlashTitle		: "ফ্ল্যাশ প্রোপার্টি",
+DlgFlashChkPlay		: "অটো প্লে",
+DlgFlashChkLoop		: "লূপ",
+DlgFlashChkMenu		: "ফ্ল্যাশ মেনু এনাবল কর",
+DlgFlashScale		: "স্কেল",
+DlgFlashScaleAll	: "সব দেখাও",
+DlgFlashScaleNoBorder	: "কোনো বর্ডার নেই",
+DlgFlashScaleFit	: "নিখুঁত ফিট",
+
+// Link Dialog
+DlgLnkWindowTitle	: "লিংক",
+DlgLnkInfoTab		: "লিংক তথ্য",
+DlgLnkTargetTab		: "টার্গেট",
+
+DlgLnkType			: "লিংক প্রকার",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "এই পেজে নোঙর কর",
+DlgLnkTypeEMail		: "ইমেইল",
+DlgLnkProto			: "প্রোটোকল",
+DlgLnkProtoOther	: "<অন্য>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "নোঙর বাছাই",
+DlgLnkAnchorByName	: "নোঙরের নাম দিয়ে",
+DlgLnkAnchorById	: "নোঙরের আইডি দিয়ে",
+DlgLnkNoAnchors		: "<ডকুমেন্টে আর কোন নোঙর নেই>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "ইমেইল ঠিকানা",
+DlgLnkEMailSubject	: "মেসেজের বিষয়",
+DlgLnkEMailBody		: "মেসেজের দেহ",
+DlgLnkUpload		: "আপলোড",
+DlgLnkBtnUpload		: "একে সার্ভারে পাঠাও",
+
+DlgLnkTarget		: "টার্গেট",
+DlgLnkTargetFrame	: "<ফ্রেম>",
+DlgLnkTargetPopup	: "<পপআপ উইন্ডো>",
+DlgLnkTargetBlank	: "নতুন উইন্ডো (_blank)",
+DlgLnkTargetParent	: "মূল উইন্ডো (_parent)",
+DlgLnkTargetSelf	: "এই উইন্ডো (_self)",
+DlgLnkTargetTop		: "শীর্ষ উইন্ডো (_top)",
+DlgLnkTargetFrameName	: "টার্গেট ফ্রেমের নাম",
+DlgLnkPopWinName	: "পপআপ উইন্ডোর নাম",
+DlgLnkPopWinFeat	: "পপআপ উইন্ডো ফীচার সমূহ",
+DlgLnkPopResize		: "রিসাইজ করা সম্ভব",
+DlgLnkPopLocation	: "লোকেশন বার",
+DlgLnkPopMenu		: "মেন্যু বার",
+DlgLnkPopScroll		: "স্ক্রল বার",
+DlgLnkPopStatus		: "স্ট্যাটাস বার",
+DlgLnkPopToolbar	: "টুল বার",
+DlgLnkPopFullScrn	: "পূর্ণ পর্দা জুড়ে (IE)",
+DlgLnkPopDependent	: "ডিপেন্ডেন্ট (Netscape)",
+DlgLnkPopWidth		: "প্রস্থ",
+DlgLnkPopHeight		: "দৈর্ঘ্য",
+DlgLnkPopLeft		: "বামের পজিশন",
+DlgLnkPopTop		: "ডানের পজিশন",
+
+DlnLnkMsgNoUrl		: "অনুগ্রহ করে URL লিংক টাইপ করুন",
+DlnLnkMsgNoEMail	: "অনুগ্রহ করে ইমেইল এড্রেস টাইপ করুন",
+DlnLnkMsgNoAnchor	: "অনুগ্রহ করে নোঙর বাছাই করুন",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "রং বাছাই কর",
+DlgColorBtnClear	: "পরিষ্কার কর",
+DlgColorHighlight	: "হাইলাইট",
+DlgColorSelected	: "সিলেক্টেড",
+
+// Smiley Dialog
+DlgSmileyTitle		: "স্মাইলী যুক্ত কর",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "বিশেষ ক্যারেক্টার বাছাই কর",
+
+// Table Dialog
+DlgTableTitle		: "টেবিল প্রোপার্টি",
+DlgTableRows		: "রো",
+DlgTableColumns		: "কলাম",
+DlgTableBorder		: "বর্ডার সাইজ",
+DlgTableAlign		: "এলাইনমেন্ট",
+DlgTableAlignNotSet	: "<সেট নেই>",
+DlgTableAlignLeft	: "বামে",
+DlgTableAlignCenter	: "মাঝখানে",
+DlgTableAlignRight	: "ডানে",
+DlgTableWidth		: "প্রস্থ",
+DlgTableWidthPx		: "পিক্সেল",
+DlgTableWidthPc		: "শতকরা",
+DlgTableHeight		: "দৈর্ঘ্য",
+DlgTableCellSpace	: "সেল স্পেস",
+DlgTableCellPad		: "সেল প্যাডিং",
+DlgTableCaption		: "শীর্ষক",
+DlgTableSummary		: "সারাংশ",
+
+// Table Cell Dialog
+DlgCellTitle		: "সেল প্রোপার্টি",
+DlgCellWidth		: "প্রস্থ",
+DlgCellWidthPx		: "পিক্সেল",
+DlgCellWidthPc		: "শতকরা",
+DlgCellHeight		: "দৈর্ঘ্য",
+DlgCellWordWrap		: "ওয়ার্ড রেপ",
+DlgCellWordWrapNotSet	: "<সেট নেই>",
+DlgCellWordWrapYes	: "হাঁ",
+DlgCellWordWrapNo	: "না",
+DlgCellHorAlign		: "হরাইজন্টাল এলাইনমেন্ট",
+DlgCellHorAlignNotSet	: "<সেট নেই>",
+DlgCellHorAlignLeft	: "বামে",
+DlgCellHorAlignCenter	: "মাঝখানে",
+DlgCellHorAlignRight: "ডানে",
+DlgCellVerAlign		: "ভার্টিক্যাল এলাইনমেন্ট",
+DlgCellVerAlignNotSet	: "<সেট নেই>",
+DlgCellVerAlignTop	: "উপর",
+DlgCellVerAlignMiddle	: "মধ্য",
+DlgCellVerAlignBottom	: "নীচে",
+DlgCellVerAlignBaseline	: "মূলরেখা",
+DlgCellRowSpan		: "রো স্প্যান",
+DlgCellCollSpan		: "কলাম স্প্যান",
+DlgCellBackColor	: "ব্যাকগ্রাউন্ড রং",
+DlgCellBorderColor	: "বর্ডারের রং",
+DlgCellBtnSelect	: "বাছাই কর",
+
+// Find Dialog
+DlgFindTitle		: "খোঁজো",
+DlgFindFindBtn		: "খোঁজো",
+DlgFindNotFoundMsg	: "আপনার উল্লেখিত টেকস্ট পাওয়া যায়নি",
+
+// Replace Dialog
+DlgReplaceTitle			: "বদলে দাও",
+DlgReplaceFindLbl		: "যা খুঁজতে হবে:",
+DlgReplaceReplaceLbl	: "যার সাথে বদলাতে হবে:",
+DlgReplaceCaseChk		: "কেস মিলাও",
+DlgReplaceReplaceBtn	: "বদলে দাও",
+DlgReplaceReplAllBtn	: "সব বদলে দাও",
+DlgReplaceWordChk		: "পুরা শব্দ মেলাও",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কাট করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl+X)।",
+PasteErrorCopy	: "আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কপি করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl+C)।",
+
+PasteAsText		: "সাদা টেক্সট হিসেবে পেস্ট কর",
+PasteFromWord	: "ওয়ার্ড থেকে পেস্ট কর",
+
+DlgPasteMsg2	: "অনুগ্রহ করে নীচের বাক্সে কিবোর্ড ব্যবহার করে (<STRONG>Ctrl+V</STRONG>) পেস্ট করুন এবং <STRONG>OK</STRONG> চাপ দিন",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "ফন্ট ফেস ডেফিনেশন ইগনোর করুন",
+DlgPasteRemoveStyles	: "স্টাইল ডেফিনেশন সরিয়ে দিন",
+DlgPasteCleanBox		: "বাক্স পরিষ্কার করুন",
+
+// Color Picker
+ColorAutomatic	: "অটোমেটিক",
+ColorMoreColors	: "আরও রং...",
+
+// Document Properties
+DocProps		: "ডক্যুমেন্ট প্রোপার্টি",
+
+// Anchor Dialog
+DlgAnchorTitle		: "নোঙরের প্রোপার্টি",
+DlgAnchorName		: "নোঙরের নাম",
+DlgAnchorErrorName	: "নোঙরের নাম টাইপ করুন",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "শব্দকোষে নেই",
+DlgSpellChangeTo		: "এতে বদলাও",
+DlgSpellBtnIgnore		: "ইগনোর কর",
+DlgSpellBtnIgnoreAll	: "সব ইগনোর কর",
+DlgSpellBtnReplace		: "বদলে দাও",
+DlgSpellBtnReplaceAll	: "সব বদলে দাও",
+DlgSpellBtnUndo			: "আন্ডু",
+DlgSpellNoSuggestions	: "- কোন সাজেশন নেই -",
+DlgSpellProgress		: "বানান পরীক্ষা চলছে...",
+DlgSpellNoMispell		: "বানান পরীক্ষা শেষ: কোন ভুল বানান পাওয়া যায়নি",
+DlgSpellNoChanges		: "বানান পরীক্ষা শেষ: কোন শব্দ পরিবর্তন করা হয়নি",
+DlgSpellOneChange		: "বানান পরীক্ষা শেষ: একটি মাত্র শব্দ পরিবর্তন করা হয়েছে",
+DlgSpellManyChanges		: "বানান পরীক্ষা শেষ: %1 গুলো শব্দ বদলে গ্যাছে",
+
+IeSpellDownload			: "বানান পরীক্ষক ইনস্টল করা নেই। আপনি কি এখনই এটা ডাউনলোড করতে চান?",
+
+// Button Dialog
+DlgButtonText		: "টেক্সট (ভ্যালু)",
+DlgButtonType		: "প্রকার",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "নাম",
+DlgCheckboxValue	: "ভ্যালু",
+DlgCheckboxSelected	: "সিলেক্টেড",
+
+// Form Dialog
+DlgFormName		: "নাম",
+DlgFormAction	: "একশ্যন",
+DlgFormMethod	: "পদ্ধতি",
+
+// Select Field Dialog
+DlgSelectName		: "নাম",
+DlgSelectValue		: "ভ্যালু",
+DlgSelectSize		: "সাইজ",
+DlgSelectLines		: "লাইন সমূহ",
+DlgSelectChkMulti	: "একাধিক সিলেকশন এলাউ কর",
+DlgSelectOpAvail	: "অন্যান্য বিকল্প",
+DlgSelectOpText		: "টেক্সট",
+DlgSelectOpValue	: "ভ্যালু",
+DlgSelectBtnAdd		: "যুক্ত",
+DlgSelectBtnModify	: "বদলে দাও",
+DlgSelectBtnUp		: "উপর",
+DlgSelectBtnDown	: "নীচে",
+DlgSelectBtnSetValue : "বাছাই করা ভ্যালু হিসেবে সেট কর",
+DlgSelectBtnDelete	: "ডিলীট",
+
+// Textarea Dialog
+DlgTextareaName	: "নাম",
+DlgTextareaCols	: "কলাম",
+DlgTextareaRows	: "রো",
+
+// Text Field Dialog
+DlgTextName			: "নাম",
+DlgTextValue		: "ভ্যালু",
+DlgTextCharWidth	: "ক্যারেক্টার প্রশস্ততা",
+DlgTextMaxChars		: "সর্বাধিক ক্যারেক্টার",
+DlgTextType			: "টাইপ",
+DlgTextTypeText		: "টেক্সট",
+DlgTextTypePass		: "পাসওয়ার্ড",
+
+// Hidden Field Dialog
+DlgHiddenName	: "নাম",
+DlgHiddenValue	: "ভ্যালু",
+
+// Bulleted List Dialog
+BulletedListProp	: "বুলেটেড সূচী প্রোপার্টি",
+NumberedListProp	: "সাংখ্যিক সূচী প্রোপার্টি",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "প্রকার",
+DlgLstTypeCircle	: "গোল",
+DlgLstTypeDisc		: "ডিস্ক",
+DlgLstTypeSquare	: "চৌকোণা",
+DlgLstTypeNumbers	: "সংখ্যা (1, 2, 3)",
+DlgLstTypeLCase		: "ছোট অক্ষর (a, b, c)",
+DlgLstTypeUCase		: "বড় অক্ষর (A, B, C)",
+DlgLstTypeSRoman	: "ছোট রোমান সংখ্যা (i, ii, iii)",
+DlgLstTypeLRoman	: "বড় রোমান সংখ্যা (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "সাধারন",
+DlgDocBackTab		: "ব্যাকগ্রাউন্ড",
+DlgDocColorsTab		: "রং এবং মার্জিন",
+DlgDocMetaTab		: "মেটাডেটা",
+
+DlgDocPageTitle		: "পেজ শীর্ষক",
+DlgDocLangDir		: "ভাষা লিখার দিক",
+DlgDocLangDirLTR	: "বাম থেকে ডানে (LTR)",
+DlgDocLangDirRTL	: "ডান থেকে বামে (RTL)",
+DlgDocLangCode		: "ভাষা কোড",
+DlgDocCharSet		: "ক্যারেক্টার সেট এনকোডিং",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "অন্য ক্যারেক্টার সেট এনকোডিং",
+
+DlgDocDocType		: "ডক্যুমেন্ট টাইপ হেডিং",
+DlgDocDocTypeOther	: "অন্য ডক্যুমেন্ট টাইপ হেডিং",
+DlgDocIncXHTML		: "XHTML ডেক্লারেশন যুক্ত কর",
+DlgDocBgColor		: "ব্যাকগ্রাউন্ড রং",
+DlgDocBgImage		: "ব্যাকগ্রাউন্ড ছবির URL",
+DlgDocBgNoScroll	: "স্ক্রলহীন ব্যাকগ্রাউন্ড",
+DlgDocCText			: "টেক্সট",
+DlgDocCLink			: "লিংক",
+DlgDocCVisited		: "ভিজিট করা লিংক",
+DlgDocCActive		: "সক্রিয় লিংক",
+DlgDocMargins		: "পেজ মার্জিন",
+DlgDocMaTop			: "উপর",
+DlgDocMaLeft		: "বামে",
+DlgDocMaRight		: "ডানে",
+DlgDocMaBottom		: "নীচে",
+DlgDocMeIndex		: "ডক্যুমেন্ট ইন্ডেক্স কিওয়ার্ড (কমা দ্বারা বিচ্ছিন্ন)",
+DlgDocMeDescr		: "ডক্যূমেন্ট বর্ণনা",
+DlgDocMeAuthor		: "লেখক",
+DlgDocMeCopy		: "কপীরাইট",
+DlgDocPreview		: "প্রীভিউ",
+
+// Templates Dialog
+Templates			: "টেমপ্লেট",
+DlgTemplatesTitle	: "কনটেন্ট টেমপ্লেট",
+DlgTemplatesSelMsg	: "অনুগ্রহ করে এডিটরে ওপেন করার জন্য টেমপ্লেট বাছাই করুন<br>(আসল কনটেন্ট হারিয়ে যাবে):",
+DlgTemplatesLoading	: "টেমপ্লেট লিস্ট হারিয়ে যাবে। অনুগ্রহ করে অপেক্ষা করুন...",
+DlgTemplatesNoTpl	: "(কোন টেমপ্লেট ডিফাইন করা নেই)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "কে বানিয়েছে",
+DlgAboutBrowserInfoTab	: "ব্রাউজারের ব্যাপারে তথ্য",
+DlgAboutLicenseTab	: "লাইসেন্স",
+DlgAboutVersion		: "ভার্সন",
+DlgAboutInfo		: "আরও তথ্যের জন্য যান"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/el.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/el.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/el.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Greek language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Απόκρυψη Μπάρας Εργαλείων",
+ToolbarExpand		: "Εμφάνιση Μπάρας Εργαλείων",
+
+// Toolbar Items and Context Menu
+Save				: "Αποθήκευση",
+NewPage				: "Νέα Σελίδα",
+Preview				: "Προεπισκόπιση",
+Cut					: "Αποκοπή",
+Copy				: "Αντιγραφή",
+Paste				: "Επικόλληση",
+PasteText			: "Επικόλληση (απλό κείμενο)",
+PasteWord			: "Επικόλληση από το Word",
+Print				: "Εκτύπωση",
+SelectAll			: "Επιλογή όλων",
+RemoveFormat		: "Αφαίρεση Μορφοποίησης",
+InsertLinkLbl		: "Σύνδεσμος (Link)",
+InsertLink			: "Εισαγωγή/Μεταβολή Συνδέσμου (Link)",
+RemoveLink			: "Αφαίρεση Συνδέσμου (Link)",
+Anchor				: "Εισαγωγή/επεξεργασία Anchor",
+InsertImageLbl		: "Εικόνα",
+InsertImage			: "Εισαγωγή/Μεταβολή Εικόνας",
+InsertFlashLbl		: "Εισαγωγή Flash",
+InsertFlash			: "Εισαγωγή/επεξεργασία Flash",
+InsertTableLbl		: "Πίνακας",
+InsertTable			: "Εισαγωγή/Μεταβολή Πίνακα",
+InsertLineLbl		: "Γραμμή",
+InsertLine			: "Εισαγωγή Οριζόντιας Γραμμής",
+InsertSpecialCharLbl: "Ειδικό Σύμβολο",
+InsertSpecialChar	: "Εισαγωγή Ειδικού Συμβόλου",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Εισαγωγή Smiley",
+About				: "Περί του FCKeditor",
+Bold				: "Έντονα",
+Italic				: "Πλάγια",
+Underline			: "Υπογράμμιση",
+StrikeThrough		: "Διαγράμμιση",
+Subscript			: "Δείκτης",
+Superscript			: "Εκθέτης",
+LeftJustify			: "Στοίχιση Αριστερά",
+CenterJustify		: "Στοίχιση στο Κέντρο",
+RightJustify		: "Στοίχιση Δεξιά",
+BlockJustify		: "Πλήρης Στοίχιση (Block)",
+DecreaseIndent		: "Μείωση Εσοχής",
+IncreaseIndent		: "Αύξηση Εσοχής",
+Undo				: "Αναίρεση",
+Redo				: "Επαναφορά",
+NumberedListLbl		: "Λίστα με Αριθμούς",
+NumberedList		: "Εισαγωγή/Διαγραφή Λίστας με Αριθμούς",
+BulletedListLbl		: "Λίστα με Bullets",
+BulletedList		: "Εισαγωγή/Διαγραφή Λίστας με Bullets",
+ShowTableBorders	: "Προβολή Ορίων Πίνακα",
+ShowDetails			: "Προβολή Λεπτομερειών",
+Style				: "Στυλ",
+FontFormat			: "Μορφή Γραμματοσειράς",
+Font				: "Γραμματοσειρά",
+FontSize			: "Μέγεθος",
+TextColor			: "Χρώμα Γραμμάτων",
+BGColor				: "Χρώμα Υποβάθρου",
+Source				: "HTML κώδικας",
+Find				: "Αναζήτηση",
+Replace				: "Αντικατάσταση",
+SpellCheck			: "Ορθογραφικός έλεγχος",
+UniversalKeyboard	: "Διεθνής πληκτρολόγιο",
+PageBreakLbl		: "Τέλος σελίδας",
+PageBreak			: "Εισαγωγή τέλους σελίδας",
+
+Form			: "Φόρμα",
+Checkbox		: "Κουτί επιλογής",
+RadioButton		: "Κουμπί Radio",
+TextField		: "Πεδίο κειμένου",
+Textarea		: "Περιοχή κειμένου",
+HiddenField		: "Κρυφό πεδίο",
+Button			: "Κουμπί",
+SelectionField	: "Πεδίο επιλογής",
+ImageButton		: "Κουμπί εικόνας",
+
+FitWindow		: "Μεγιστοποίηση προγράμματος",
+
+// Context Menu
+EditLink			: "Μεταβολή Συνδέσμου (Link)",
+CellCM				: "Κελί",
+RowCM				: "Σειρά",
+ColumnCM			: "Στήλη",
+InsertRow			: "Εισαγωγή Γραμμής",
+DeleteRows			: "Διαγραφή Γραμμών",
+InsertColumn		: "Εισαγωγή Κολώνας",
+DeleteColumns		: "Διαγραφή Κολωνών",
+InsertCell			: "Εισαγωγή Κελιού",
+DeleteCells			: "Διαγραφή Κελιών",
+MergeCells			: "Ενοποίηση Κελιών",
+SplitCell			: "Διαχωρισμός Κελιού",
+TableDelete			: "Διαγραφή πίνακα",
+CellProperties		: "Ιδιότητες Κελιού",
+TableProperties		: "Ιδιότητες Πίνακα",
+ImageProperties		: "Ιδιότητες Εικόνας",
+FlashProperties		: "Ιδιότητες Flash",
+
+AnchorProp			: "Ιδιότητες άγκυρας",
+ButtonProp			: "Ιδιότητες κουμπιού",
+CheckboxProp		: "Ιδιότητες κουμπιού επιλογής",
+HiddenFieldProp		: "Ιδιότητες κρυφού πεδίου",
+RadioButtonProp		: "Ιδιότητες κουμπιού radio",
+ImageButtonProp		: "Ιδιότητες κουμπιού εικόνας",
+TextFieldProp		: "Ιδιότητες πεδίου κειμένου",
+SelectionFieldProp	: "Ιδιότητες πεδίου επιλογής",
+TextareaProp		: "Ιδιότητες περιοχής κειμένου",
+FormProp			: "Ιδιότητες φόρμας",
+
+FontFormats			: "Κανονικό;Μορφοποιημένο;Διεύθυνση;Επικεφαλίδα 1;Επικεφαλίδα 2;Επικεφαλίδα 3;Επικεφαλίδα 4;Επικεφαλίδα 5;Επικεφαλίδα 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Επεξεργασία XHTML. Παρακαλώ περιμένετε...",
+Done				: "Έτοιμο",
+PasteWordConfirm	: "Το κείμενο που θέλετε να επικολήσετε, φαίνεται πως προέρχεται από το Word. Θέλετε να καθαριστεί πριν επικοληθεί;",
+NotCompatiblePaste	: "Αυτή η επιλογή είναι διαθέσιμη στον Internet Explorer έκδοση 5.5+. Θέλετε να γίνει η επικόλληση χωρίς καθαρισμό;",
+UnknownToolbarItem	: "Άγνωστο αντικείμενο της μπάρας εργαλείων \"%1\"",
+UnknownCommand		: "Άγνωστή εντολή \"%1\"",
+NotImplemented		: "Η εντολή δεν έχει ενεργοποιηθεί",
+UnknownToolbarSet	: "Η μπάρα εργαλείων \"%1\" δεν υπάρχει",
+NoActiveX			: "Οι ρυθμίσεις ασφαλείας του browser σας μπορεί να περιορίσουν κάποιες ρυθμίσεις του προγράμματος. Χρειάζεται να ενεργοποιήσετε την επιλογή \"Run ActiveX controls and plug-ins\". Ίσως παρουσιαστούν λάθη και παρατηρήσετε ελειπείς λειτουργίες.",
+BrowseServerBlocked : "Οι πόροι του browser σας δεν είναι προσπελάσιμοι. Σιγουρευτείτε ότι δεν υπάρχουν ενεργοί popup blockers.",
+DialogBlocked		: "Δεν ήταν δυνατό να ανοίξει το παράθυρο διαλόγου. Σιγουρευτείτε ότι δεν υπάρχουν ενεργοί popup blockers.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Ακύρωση",
+DlgBtnClose			: "Κλείσιμο",
+DlgBtnBrowseServer	: "Εξερεύνηση διακομιστή",
+DlgAdvancedTag		: "Για προχωρημένους",
+DlgOpOther			: "<Άλλα>",
+DlgInfoTab			: "Πληροφορίες",
+DlgAlertUrl			: "Παρακαλώ εισάγετε URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<χωρίς>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Κατεύθυνση κειμένου",
+DlgGenLangDirLtr	: "Αριστερά προς Δεξιά (LTR)",
+DlgGenLangDirRtl	: "Δεξιά προς Αριστερά (RTL)",
+DlgGenLangCode		: "Κωδικός Γλώσσας",
+DlgGenAccessKey		: "Συντόμευση (Access Key)",
+DlgGenName			: "Όνομα",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Αναλυτική περιγραφή URL",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Συμβουλευτικός τίτλος",
+DlgGenContType		: "Συμβουλευτικός τίτλος περιεχομένου",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Στύλ",
+
+// Image Dialog
+DlgImgTitle			: "Ιδιότητες Εικόνας",
+DlgImgInfoTab		: "Πληροφορίες Εικόνας",
+DlgImgBtnUpload		: "Αποστολή στον Διακομιστή",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Αποστολή",
+DlgImgAlt			: "Εναλλακτικό Κείμενο (ALT)",
+DlgImgWidth			: "Πλάτος",
+DlgImgHeight		: "Ύψος",
+DlgImgLockRatio		: "Κλείδωμα Αναλογίας",
+DlgBtnResetSize		: "Επαναφορά Αρχικού Μεγέθους",
+DlgImgBorder		: "Περιθώριο",
+DlgImgHSpace		: "Οριζόντιος Χώρος (HSpace)",
+DlgImgVSpace		: "Κάθετος Χώρος (VSpace)",
+DlgImgAlign			: "Ευθυγράμμιση (Align)",
+DlgImgAlignLeft		: "Αριστερά",
+DlgImgAlignAbsBottom: "Απόλυτα Κάτω (Abs Bottom)",
+DlgImgAlignAbsMiddle: "Απόλυτα στη Μέση (Abs Middle)",
+DlgImgAlignBaseline	: "Γραμμή Βάσης (Baseline)",
+DlgImgAlignBottom	: "Κάτω (Bottom)",
+DlgImgAlignMiddle	: "Μέση (Middle)",
+DlgImgAlignRight	: "Δεξιά (Right)",
+DlgImgAlignTextTop	: "Κορυφή Κειμένου (Text Top)",
+DlgImgAlignTop		: "Πάνω (Top)",
+DlgImgPreview		: "Προεπισκόπιση",
+DlgImgAlertUrl		: "Εισάγετε την τοποθεσία (URL) της εικόνας",
+DlgImgLinkTab		: "Σύνδεσμος",
+
+// Flash Dialog
+DlgFlashTitle		: "Ιδιότητες flash",
+DlgFlashChkPlay		: "Αυτόματη έναρξη",
+DlgFlashChkLoop		: "Επανάληψη",
+DlgFlashChkMenu		: "Ενεργοποίηση Flash Menu",
+DlgFlashScale		: "Κλίμακα",
+DlgFlashScaleAll	: "Εμφάνιση όλων",
+DlgFlashScaleNoBorder	: "Χωρίς όρια",
+DlgFlashScaleFit	: "Ακριβής εφαρμογή",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Σύνδεσμος (Link)",
+DlgLnkInfoTab		: "Link",
+DlgLnkTargetTab		: "Παράθυρο Στόχος (Target)",
+
+DlgLnkType			: "Τύπος συνδέσμου (Link)",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Άγκυρα σε αυτή τη σελίδα",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Προτόκολο",
+DlgLnkProtoOther	: "<άλλο>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Επιλέξτε μια άγκυρα",
+DlgLnkAnchorByName	: "Βάσει του Ονόματος (Name) της άγκυρας",
+DlgLnkAnchorById	: "Βάσει του Element Id",
+DlgLnkNoAnchors		: "<Δεν υπάρχουν άγκυρες στο κείμενο>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Διεύθυνση Ηλεκτρονικού Ταχυδρομείου",
+DlgLnkEMailSubject	: "Θέμα Μηνύματος",
+DlgLnkEMailBody		: "Κείμενο Μηνύματος",
+DlgLnkUpload		: "Αποστολή",
+DlgLnkBtnUpload		: "Αποστολή στον Διακομιστή",
+
+DlgLnkTarget		: "Παράθυρο Στόχος (Target)",
+DlgLnkTargetFrame	: "<πλαίσιο>",
+DlgLnkTargetPopup	: "<παράθυρο popup>",
+DlgLnkTargetBlank	: "Νέο Παράθυρο (_blank)",
+DlgLnkTargetParent	: "Γονικό Παράθυρο (_parent)",
+DlgLnkTargetSelf	: "Ίδιο Παράθυρο (_self)",
+DlgLnkTargetTop		: "Ανώτατο Παράθυρο (_top)",
+DlgLnkTargetFrameName	: "Όνομα πλαισίου στόχου",
+DlgLnkPopWinName	: "Όνομα Popup Window",
+DlgLnkPopWinFeat	: "Επιλογές Popup Window",
+DlgLnkPopResize		: "Με αλλαγή Μεγέθους",
+DlgLnkPopLocation	: "Μπάρα Τοποθεσίας",
+DlgLnkPopMenu		: "Μπάρα Menu",
+DlgLnkPopScroll		: "Μπάρες Κύλισης",
+DlgLnkPopStatus		: "Μπάρα Status",
+DlgLnkPopToolbar	: "Μπάρα Εργαλείων",
+DlgLnkPopFullScrn	: "Ολόκληρη η Οθόνη (IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "Πλάτος",
+DlgLnkPopHeight		: "Ύψος",
+DlgLnkPopLeft		: "Τοποθεσία Αριστερής Άκρης",
+DlgLnkPopTop		: "Τοποθεσία Πάνω Άκρης",
+
+DlnLnkMsgNoUrl		: "Εισάγετε την τοποθεσία (URL) του υπερσυνδέσμου (Link)",
+DlnLnkMsgNoEMail	: "Εισάγετε την διεύθυνση ηλεκτρονικού ταχυδρομείου",
+DlnLnkMsgNoAnchor	: "Επιλέξτε ένα Anchor",
+DlnLnkMsgInvPopName	: "Το όνομα του popup πρέπει να αρχίζει με χαρακτήρα της αλφαβήτου και να μην περιέχει κενά",
+
+// Color Dialog
+DlgColorTitle		: "Επιλογή χρώματος",
+DlgColorBtnClear	: "Καθαρισμός",
+DlgColorHighlight	: "Προεπισκόπιση",
+DlgColorSelected	: "Επιλεγμένο",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Επιλέξτε ένα Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Επιλέξτε ένα Ειδικό Σύμβολο",
+
+// Table Dialog
+DlgTableTitle		: "Ιδιότητες Πίνακα",
+DlgTableRows		: "Γραμμές",
+DlgTableColumns		: "Κολώνες",
+DlgTableBorder		: "Μέγεθος Περιθωρίου",
+DlgTableAlign		: "Στοίχιση",
+DlgTableAlignNotSet	: "<χωρίς>",
+DlgTableAlignLeft	: "Αριστερά",
+DlgTableAlignCenter	: "Κέντρο",
+DlgTableAlignRight	: "Δεξιά",
+DlgTableWidth		: "Πλάτος",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "\%",
+DlgTableHeight		: "Ύψος",
+DlgTableCellSpace	: "Απόσταση κελιών",
+DlgTableCellPad		: "Γέμισμα κελιών",
+DlgTableCaption		: "Υπέρτιτλος",
+DlgTableSummary		: "Περίληψη",
+
+// Table Cell Dialog
+DlgCellTitle		: "Ιδιότητες Κελιού",
+DlgCellWidth		: "Πλάτος",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "\%",
+DlgCellHeight		: "Ύψος",
+DlgCellWordWrap		: "Με αλλαγή γραμμής",
+DlgCellWordWrapNotSet	: "<χωρίς>",
+DlgCellWordWrapYes	: "Ναι",
+DlgCellWordWrapNo	: "Όχι",
+DlgCellHorAlign		: "Οριζόντια Στοίχιση",
+DlgCellHorAlignNotSet	: "<χωρίς>",
+DlgCellHorAlignLeft	: "Αριστερά",
+DlgCellHorAlignCenter	: "Κέντρο",
+DlgCellHorAlignRight: "Δεξιά",
+DlgCellVerAlign		: "Κάθετη Στοίχιση",
+DlgCellVerAlignNotSet	: "<χωρίς>",
+DlgCellVerAlignTop	: "Πάνω (Top)",
+DlgCellVerAlignMiddle	: "Μέση (Middle)",
+DlgCellVerAlignBottom	: "Κάτω (Bottom)",
+DlgCellVerAlignBaseline	: "Γραμμή Βάσης (Baseline)",
+DlgCellRowSpan		: "Αριθμός Γραμμών (Rows Span)",
+DlgCellCollSpan		: "Αριθμός Κολωνών (Columns Span)",
+DlgCellBackColor	: "Χρώμα Υποβάθρου",
+DlgCellBorderColor	: "Χρώμα Περιθωρίου",
+DlgCellBtnSelect	: "Επιλογή...",
+
+// Find Dialog
+DlgFindTitle		: "Αναζήτηση",
+DlgFindFindBtn		: "Αναζήτηση",
+DlgFindNotFoundMsg	: "Το κείμενο δεν βρέθηκε.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Αντικατάσταση",
+DlgReplaceFindLbl		: "Αναζήτηση:",
+DlgReplaceReplaceLbl	: "Αντικατάσταση με:",
+DlgReplaceCaseChk		: "Έλεγχος πεζών/κεφαλαίων",
+DlgReplaceReplaceBtn	: "Αντικατάσταση",
+DlgReplaceReplAllBtn	: "Αντικατάσταση Όλων",
+DlgReplaceWordChk		: "Εύρεση πλήρους λέξης",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Οι ρυθμίσεις ασφαλείας του φυλλομετρητή σας δεν επιτρέπουν την επιλεγμένη εργασία αποκοπής. Χρησιμοποιείστε το πληκτρολόγιο (Ctrl+X).",
+PasteErrorCopy	: "Οι ρυθμίσεις ασφαλείας του φυλλομετρητή σας δεν επιτρέπουν την επιλεγμένη εργασία αντιγραφής. Χρησιμοποιείστε το πληκτρολόγιο (Ctrl+C).",
+
+PasteAsText		: "Επικόλληση ως Απλό Κείμενο",
+PasteFromWord	: "Επικόλληση από το Word",
+
+DlgPasteMsg2	: "Παρακαλώ επικολήστε στο ακόλουθο κουτί χρησιμοποιόντας το πληκτρολόγιο (<STRONG>Ctrl+V</STRONG>) και πατήστε <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Αγνόηση προδιαγραφών γραμματοσειράς",
+DlgPasteRemoveStyles	: "Αφαίρεση προδιαγραφών στύλ",
+DlgPasteCleanBox		: "Κουτί εκαθάρισης",
+
+// Color Picker
+ColorAutomatic	: "Αυτόματο",
+ColorMoreColors	: "Περισσότερα χρώματα...",
+
+// Document Properties
+DocProps		: "Ιδιότητες εγγράφου",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ιδιότητες άγκυρας",
+DlgAnchorName		: "Όνομα άγκυρας",
+DlgAnchorErrorName	: "Παρακαλούμε εισάγετε όνομα άγκυρας",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Δεν υπάρχει στο λεξικό",
+DlgSpellChangeTo		: "Αλλαγή σε",
+DlgSpellBtnIgnore		: "Αγνόηση",
+DlgSpellBtnIgnoreAll	: "Αγνόηση όλων",
+DlgSpellBtnReplace		: "Αντικατάσταση",
+DlgSpellBtnReplaceAll	: "Αντικατάσταση όλων",
+DlgSpellBtnUndo			: "Αναίρεση",
+DlgSpellNoSuggestions	: "- Δεν υπάρχουν προτάσεις -",
+DlgSpellProgress		: "Ορθογραφικός έλεγχος σε εξέλιξη...",
+DlgSpellNoMispell		: "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Δεν βρέθηκαν λάθη",
+DlgSpellNoChanges		: "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Δεν άλλαξαν λέξεις",
+DlgSpellOneChange		: "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Μια λέξη άλλαξε",
+DlgSpellManyChanges		: "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: %1 λέξεις άλλαξαν",
+
+IeSpellDownload			: "Δεν υπάρχει εγκατεστημένος ορθογράφος. Θέλετε να τον κατεβάσετε τώρα;",
+
+// Button Dialog
+DlgButtonText		: "Κείμενο (Τιμή)",
+DlgButtonType		: "Τύπος",
+DlgButtonTypeBtn	: "Κουμπί",
+DlgButtonTypeSbm	: "Καταχώρηση",
+DlgButtonTypeRst	: "Επαναφορά",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Όνομα",
+DlgCheckboxValue	: "Τιμή",
+DlgCheckboxSelected	: "Επιλεγμένο",
+
+// Form Dialog
+DlgFormName		: "Όνομα",
+DlgFormAction	: "Δράση",
+DlgFormMethod	: "Μάθοδος",
+
+// Select Field Dialog
+DlgSelectName		: "Όνομα",
+DlgSelectValue		: "Τιμή",
+DlgSelectSize		: "Μέγεθος",
+DlgSelectLines		: "γραμμές",
+DlgSelectChkMulti	: "Πολλαπλές επιλογές",
+DlgSelectOpAvail	: "Διαθέσιμες επιλογές",
+DlgSelectOpText		: "Κείμενο",
+DlgSelectOpValue	: "Τιμή",
+DlgSelectBtnAdd		: "Προσθήκη",
+DlgSelectBtnModify	: "Αλλαγή",
+DlgSelectBtnUp		: "Πάνω",
+DlgSelectBtnDown	: "Κάτω",
+DlgSelectBtnSetValue : "Προεπιλεγμένη επιλογή",
+DlgSelectBtnDelete	: "Διαγραφή",
+
+// Textarea Dialog
+DlgTextareaName	: "Όνομα",
+DlgTextareaCols	: "Στήλες",
+DlgTextareaRows	: "Σειρές",
+
+// Text Field Dialog
+DlgTextName			: "Όνομα",
+DlgTextValue		: "Τιμή",
+DlgTextCharWidth	: "Μήκος χαρακτήρων",
+DlgTextMaxChars		: "Μέγιστοι χαρακτήρες",
+DlgTextType			: "Τύπος",
+DlgTextTypeText		: "Κείμενο",
+DlgTextTypePass		: "Κωδικός",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Όνομα",
+DlgHiddenValue	: "Τιμή",
+
+// Bulleted List Dialog
+BulletedListProp	: "Ιδιότητες λίστας Bulleted",
+NumberedListProp	: "Ιδιότητες αριθμημένης λίστας ",
+DlgLstStart			: "Αρχή",
+DlgLstType			: "Τύπος",
+DlgLstTypeCircle	: "Κύκλος",
+DlgLstTypeDisc		: "Δίσκος",
+DlgLstTypeSquare	: "Τετράγωνο",
+DlgLstTypeNumbers	: "Αριθμοί (1, 2, 3)",
+DlgLstTypeLCase		: "Πεζά γράμματα (a, b, c)",
+DlgLstTypeUCase		: "Κεφαλαία γράμματα (A, B, C)",
+DlgLstTypeSRoman	: "Μικρά λατινικά αριθμητικά (i, ii, iii)",
+DlgLstTypeLRoman	: "Μεγάλα λατινικά αριθμητικά (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Γενικά",
+DlgDocBackTab		: "Φόντο",
+DlgDocColorsTab		: "Χρώματα και περιθώρια",
+DlgDocMetaTab		: "Δεδομένα Meta",
+
+DlgDocPageTitle		: "Τίτλος σελίδας",
+DlgDocLangDir		: "Κατεύθυνση γραφής",
+DlgDocLangDirLTR	: "αριστερά προς δεξιά (LTR)",
+DlgDocLangDirRTL	: "δεξιά προς αριστερά (RTL)",
+DlgDocLangCode		: "Κωδικός γλώσσας",
+DlgDocCharSet		: "Κωδικοποίηση χαρακτήρων",
+DlgDocCharSetCE		: "Κεντρικής Ευρώπης",
+DlgDocCharSetCT		: "Παραδοσιακά κινέζικα (Big5)",
+DlgDocCharSetCR		: "Κυριλλική",
+DlgDocCharSetGR		: "Ελληνική",
+DlgDocCharSetJP		: "Ιαπωνική",
+DlgDocCharSetKR		: "Κορεάτικη",
+DlgDocCharSetTR		: "Τουρκική",
+DlgDocCharSetUN		: "Διεθνής (UTF-8)",
+DlgDocCharSetWE		: "Δυτικής Ευρώπης",
+DlgDocCharSetOther	: "Άλλη κωδικοποίηση χαρακτήρων",
+
+DlgDocDocType		: "Επικεφαλίδα τύπου εγγράφου",
+DlgDocDocTypeOther	: "Άλλη επικεφαλίδα τύπου εγγράφου",
+DlgDocIncXHTML		: "Να συμπεριληφθούν οι δηλώσεις XHTML",
+DlgDocBgColor		: "Χρώμα φόντου",
+DlgDocBgImage		: "Διεύθυνση εικόνας φόντου",
+DlgDocBgNoScroll	: "Φόντο χωρίς κύλιση",
+DlgDocCText			: "Κείμενο",
+DlgDocCLink			: "Σύνδεσμος",
+DlgDocCVisited		: "Σύνδεσμος που έχει επισκευθεί",
+DlgDocCActive		: "Ενεργός σύνδεσμος",
+DlgDocMargins		: "Περιθώρια σελίδας",
+DlgDocMaTop			: "Κορυφή",
+DlgDocMaLeft		: "Αριστερά",
+DlgDocMaRight		: "Δεξιά",
+DlgDocMaBottom		: "Κάτω",
+DlgDocMeIndex		: "Λέξεις κλειδιά δείκτες εγγράφου (διαχωρισμός με κόμμα)",
+DlgDocMeDescr		: "Περιγραφή εγγράφου",
+DlgDocMeAuthor		: "Συγγραφέας",
+DlgDocMeCopy		: "Πνευματικά δικαιώματα",
+DlgDocPreview		: "Προεπισκόπηση",
+
+// Templates Dialog
+Templates			: "Πρότυπα",
+DlgTemplatesTitle	: "Πρότυπα περιεχομένου",
+DlgTemplatesSelMsg	: "Παρακαλώ επιλέξτε πρότυπο για εισαγωγή στο πρόγραμμα<br>(τα υπάρχοντα περιεχόμενα θα χαθούν):",
+DlgTemplatesLoading	: "Φόρτωση καταλόγου προτύπων. Παρακαλώ περιμένετε...",
+DlgTemplatesNoTpl	: "(Δεν έχουν καθοριστεί πρότυπα)",
+DlgTemplatesReplace	: "Αντικατάσταση υπάρχοντων περιεχομένων",
+
+// About Dialog
+DlgAboutAboutTab	: "Σχετικά",
+DlgAboutBrowserInfoTab	: "Πληροφορίες Browser",
+DlgAboutLicenseTab	: "Άδεια",
+DlgAboutVersion		: "έκδοση",
+DlgAboutInfo		: "Για περισσότερες πληροφορίες"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * English language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Collapse Toolbar",
+ToolbarExpand		: "Expand Toolbar",
+
+// Toolbar Items and Context Menu
+Save				: "Save",
+NewPage				: "New Page",
+Preview				: "Preview",
+Cut					: "Cut",
+Copy				: "Copy",
+Paste				: "Paste",
+PasteText			: "Paste as plain text",
+PasteWord			: "Paste from Word",
+Print				: "Print",
+SelectAll			: "Select All",
+RemoveFormat		: "Remove Format",
+InsertLinkLbl		: "Link",
+InsertLink			: "Insert/Edit Link",
+RemoveLink			: "Remove Link",
+Anchor				: "Insert/Edit Anchor",
+InsertImageLbl		: "Image",
+InsertImage			: "Insert/Edit Image",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insert/Edit Flash",
+InsertTableLbl		: "Table",
+InsertTable			: "Insert/Edit Table",
+InsertLineLbl		: "Line",
+InsertLine			: "Insert Horizontal Line",
+InsertSpecialCharLbl: "Special Character",
+InsertSpecialChar	: "Insert Special Character",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Insert Smiley",
+About				: "About FCKeditor",
+Bold				: "Bold",
+Italic				: "Italic",
+Underline			: "Underline",
+StrikeThrough		: "Strike Through",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Left Justify",
+CenterJustify		: "Center Justify",
+RightJustify		: "Right Justify",
+BlockJustify		: "Block Justify",
+DecreaseIndent		: "Decrease Indent",
+IncreaseIndent		: "Increase Indent",
+Undo				: "Undo",
+Redo				: "Redo",
+NumberedListLbl		: "Numbered List",
+NumberedList		: "Insert/Remove Numbered List",
+BulletedListLbl		: "Bulleted List",
+BulletedList		: "Insert/Remove Bulleted List",
+ShowTableBorders	: "Show Table Borders",
+ShowDetails			: "Show Details",
+Style				: "Style",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Size",
+TextColor			: "Text Color",
+BGColor				: "Background Color",
+Source				: "Source",
+Find				: "Find",
+Replace				: "Replace",
+SpellCheck			: "Check Spelling",
+UniversalKeyboard	: "Universal Keyboard",
+PageBreakLbl		: "Page Break",
+PageBreak			: "Insert Page Break",
+
+Form			: "Form",
+Checkbox		: "Checkbox",
+RadioButton		: "Radio Button",
+TextField		: "Text Field",
+Textarea		: "Textarea",
+HiddenField		: "Hidden Field",
+Button			: "Button",
+SelectionField	: "Selection Field",
+ImageButton		: "Image Button",
+
+FitWindow		: "Maximize the editor size",
+
+// Context Menu
+EditLink			: "Edit Link",
+CellCM				: "Cell",
+RowCM				: "Row",
+ColumnCM			: "Column",
+InsertRow			: "Insert Row",
+DeleteRows			: "Delete Rows",
+InsertColumn		: "Insert Column",
+DeleteColumns		: "Delete Columns",
+InsertCell			: "Insert Cell",
+DeleteCells			: "Delete Cells",
+MergeCells			: "Merge Cells",
+SplitCell			: "Split Cell",
+TableDelete			: "Delete Table",
+CellProperties		: "Cell Properties",
+TableProperties		: "Table Properties",
+ImageProperties		: "Image Properties",
+FlashProperties		: "Flash Properties",
+
+AnchorProp			: "Anchor Properties",
+ButtonProp			: "Button Properties",
+CheckboxProp		: "Checkbox Properties",
+HiddenFieldProp		: "Hidden Field Properties",
+RadioButtonProp		: "Radio Button Properties",
+ImageButtonProp		: "Image Button Properties",
+TextFieldProp		: "Text Field Properties",
+SelectionFieldProp	: "Selection Field Properties",
+TextareaProp		: "Textarea Properties",
+FormProp			: "Form Properties",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Processing XHTML. Please wait...",
+Done				: "Done",
+PasteWordConfirm	: "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?",
+NotCompatiblePaste	: "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?",
+UnknownToolbarItem	: "Unknown toolbar item \"%1\"",
+UnknownCommand		: "Unknown command name \"%1\"",
+NotImplemented		: "Command not implemented",
+UnknownToolbarSet	: "Toolbar set \"%1\" doesn't exist",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancel",
+DlgBtnClose			: "Close",
+DlgBtnBrowseServer	: "Browse Server",
+DlgAdvancedTag		: "Advanced",
+DlgOpOther			: "<Other>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Please insert the URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<not set>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Language Direction",
+DlgGenLangDirLtr	: "Left to Right (LTR)",
+DlgGenLangDirRtl	: "Right to Left (RTL)",
+DlgGenLangCode		: "Language Code",
+DlgGenAccessKey		: "Access Key",
+DlgGenName			: "Name",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Long Description URL",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Image Properties",
+DlgImgInfoTab		: "Image Info",
+DlgImgBtnUpload		: "Send it to the Server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternative Text",
+DlgImgWidth			: "Width",
+DlgImgHeight		: "Height",
+DlgImgLockRatio		: "Lock Ratio",
+DlgBtnResetSize		: "Reset Size",
+DlgImgBorder		: "Border",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Align",
+DlgImgAlignLeft		: "Left",
+DlgImgAlignAbsBottom: "Abs Bottom",
+DlgImgAlignAbsMiddle: "Abs Middle",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Bottom",
+DlgImgAlignMiddle	: "Middle",
+DlgImgAlignRight	: "Right",
+DlgImgAlignTextTop	: "Text Top",
+DlgImgAlignTop		: "Top",
+DlgImgPreview		: "Preview",
+DlgImgAlertUrl		: "Please type the image URL",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",
+DlgFlashChkPlay		: "Auto Play",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Enable Flash Menu",
+DlgFlashScale		: "Scale",
+DlgFlashScaleAll	: "Show all",
+DlgFlashScaleNoBorder	: "No Border",
+DlgFlashScaleFit	: "Exact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Target",
+
+DlgLnkType			: "Link Type",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Link to anchor in the text",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<other>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Select an Anchor",
+DlgLnkAnchorByName	: "By Anchor Name",
+DlgLnkAnchorById	: "By Element Id",
+DlgLnkNoAnchors		: "(No anchors available in the document)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Address",
+DlgLnkEMailSubject	: "Message Subject",
+DlgLnkEMailBody		: "Message Body",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Send it to the Server",
+
+DlgLnkTarget		: "Target",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<popup window>",
+DlgLnkTargetBlank	: "New Window (_blank)",
+DlgLnkTargetParent	: "Parent Window (_parent)",
+DlgLnkTargetSelf	: "Same Window (_self)",
+DlgLnkTargetTop		: "Topmost Window (_top)",
+DlgLnkTargetFrameName	: "Target Frame Name",
+DlgLnkPopWinName	: "Popup Window Name",
+DlgLnkPopWinFeat	: "Popup Window Features",
+DlgLnkPopResize		: "Resizable",
+DlgLnkPopLocation	: "Location Bar",
+DlgLnkPopMenu		: "Menu Bar",
+DlgLnkPopScroll		: "Scroll Bars",
+DlgLnkPopStatus		: "Status Bar",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Full Screen (IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "Width",
+DlgLnkPopHeight		: "Height",
+DlgLnkPopLeft		: "Left Position",
+DlgLnkPopTop		: "Top Position",
+
+DlnLnkMsgNoUrl		: "Please type the link URL",
+DlnLnkMsgNoEMail	: "Please type the e-mail address",
+DlnLnkMsgNoAnchor	: "Please select an anchor",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",
+
+// Color Dialog
+DlgColorTitle		: "Select Color",
+DlgColorBtnClear	: "Clear",
+DlgColorHighlight	: "Highlight",
+DlgColorSelected	: "Selected",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insert a Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Select Special Character",
+
+// Table Dialog
+DlgTableTitle		: "Table Properties",
+DlgTableRows		: "Rows",
+DlgTableColumns		: "Columns",
+DlgTableBorder		: "Border size",
+DlgTableAlign		: "Alignment",
+DlgTableAlignNotSet	: "<Not set>",
+DlgTableAlignLeft	: "Left",
+DlgTableAlignCenter	: "Center",
+DlgTableAlignRight	: "Right",
+DlgTableWidth		: "Width",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Height",
+DlgTableCellSpace	: "Cell spacing",
+DlgTableCellPad		: "Cell padding",
+DlgTableCaption		: "Caption",
+DlgTableSummary		: "Summary",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cell Properties",
+DlgCellWidth		: "Width",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Height",
+DlgCellWordWrap		: "Word Wrap",
+DlgCellWordWrapNotSet	: "<Not set>",
+DlgCellWordWrapYes	: "Yes",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Horizontal Alignment",
+DlgCellHorAlignNotSet	: "<Not set>",
+DlgCellHorAlignLeft	: "Left",
+DlgCellHorAlignCenter	: "Center",
+DlgCellHorAlignRight: "Right",
+DlgCellVerAlign		: "Vertical Alignment",
+DlgCellVerAlignNotSet	: "<Not set>",
+DlgCellVerAlignTop	: "Top",
+DlgCellVerAlignMiddle	: "Middle",
+DlgCellVerAlignBottom	: "Bottom",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Rows Span",
+DlgCellCollSpan		: "Columns Span",
+DlgCellBackColor	: "Background Color",
+DlgCellBorderColor	: "Border Color",
+DlgCellBtnSelect	: "Select...",
+
+// Find Dialog
+DlgFindTitle		: "Find",
+DlgFindFindBtn		: "Find",
+DlgFindNotFoundMsg	: "The specified text was not found.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Replace",
+DlgReplaceFindLbl		: "Find what:",
+DlgReplaceReplaceLbl	: "Replace with:",
+DlgReplaceCaseChk		: "Match case",
+DlgReplaceReplaceBtn	: "Replace",
+DlgReplaceReplAllBtn	: "Replace All",
+DlgReplaceWordChk		: "Match whole word",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).",
+PasteErrorCopy	: "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).",
+
+PasteAsText		: "Paste as Plain Text",
+PasteFromWord	: "Paste from Word",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",
+DlgPasteRemoveStyles	: "Remove Styles definitions",
+DlgPasteCleanBox		: "Clean Up Box",
+
+// Color Picker
+ColorAutomatic	: "Automatic",
+ColorMoreColors	: "More Colors...",
+
+// Document Properties
+DocProps		: "Document Properties",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anchor Properties",
+DlgAnchorName		: "Anchor Name",
+DlgAnchorErrorName	: "Please type the anchor name",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Not in dictionary",
+DlgSpellChangeTo		: "Change to",
+DlgSpellBtnIgnore		: "Ignore",
+DlgSpellBtnIgnoreAll	: "Ignore All",
+DlgSpellBtnReplace		: "Replace",
+DlgSpellBtnReplaceAll	: "Replace All",
+DlgSpellBtnUndo			: "Undo",
+DlgSpellNoSuggestions	: "- No suggestions -",
+DlgSpellProgress		: "Spell check in progress...",
+DlgSpellNoMispell		: "Spell check complete: No misspellings found",
+DlgSpellNoChanges		: "Spell check complete: No words changed",
+DlgSpellOneChange		: "Spell check complete: One word changed",
+DlgSpellManyChanges		: "Spell check complete: %1 words changed",
+
+IeSpellDownload			: "Spell checker not installed. Do you want to download it now?",
+
+// Button Dialog
+DlgButtonText		: "Text (Value)",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",
+DlgCheckboxValue	: "Value",
+DlgCheckboxSelected	: "Selected",
+
+// Form Dialog
+DlgFormName		: "Name",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Method",
+
+// Select Field Dialog
+DlgSelectName		: "Name",
+DlgSelectValue		: "Value",
+DlgSelectSize		: "Size",
+DlgSelectLines		: "lines",
+DlgSelectChkMulti	: "Allow multiple selections",
+DlgSelectOpAvail	: "Available Options",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Value",
+DlgSelectBtnAdd		: "Add",
+DlgSelectBtnModify	: "Modify",
+DlgSelectBtnUp		: "Up",
+DlgSelectBtnDown	: "Down",
+DlgSelectBtnSetValue : "Set as selected value",
+DlgSelectBtnDelete	: "Delete",
+
+// Textarea Dialog
+DlgTextareaName	: "Name",
+DlgTextareaCols	: "Columns",
+DlgTextareaRows	: "Rows",
+
+// Text Field Dialog
+DlgTextName			: "Name",
+DlgTextValue		: "Value",
+DlgTextCharWidth	: "Character Width",
+DlgTextMaxChars		: "Maximum Characters",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Password",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",
+DlgHiddenValue	: "Value",
+
+// Bulleted List Dialog
+BulletedListProp	: "Bulleted List Properties",
+NumberedListProp	: "Numbered List Properties",
+DlgLstStart			: "Start",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Circle",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "Square",
+DlgLstTypeNumbers	: "Numbers (1, 2, 3)",
+DlgLstTypeLCase		: "Lowercase Letters (a, b, c)",
+DlgLstTypeUCase		: "Uppercase Letters (A, B, C)",
+DlgLstTypeSRoman	: "Small Roman Numerals (i, ii, iii)",
+DlgLstTypeLRoman	: "Large Roman Numerals (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Background",
+DlgDocColorsTab		: "Colors and Margins",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Page Title",
+DlgDocLangDir		: "Language Direction",
+DlgDocLangDirLTR	: "Left to Right (LTR)",
+DlgDocLangDirRTL	: "Right to Left (RTL)",
+DlgDocLangCode		: "Language Code",
+DlgDocCharSet		: "Character Set Encoding",
+DlgDocCharSetCE		: "Central European",
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Greek",
+DlgDocCharSetJP		: "Japanese",
+DlgDocCharSetKR		: "Korean",
+DlgDocCharSetTR		: "Turkish",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "Other Character Set Encoding",
+
+DlgDocDocType		: "Document Type Heading",
+DlgDocDocTypeOther	: "Other Document Type Heading",
+DlgDocIncXHTML		: "Include XHTML Declarations",
+DlgDocBgColor		: "Background Color",
+DlgDocBgImage		: "Background Image URL",
+DlgDocBgNoScroll	: "Nonscrolling Background",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Visited Link",
+DlgDocCActive		: "Active Link",
+DlgDocMargins		: "Page Margins",
+DlgDocMaTop			: "Top",
+DlgDocMaLeft		: "Left",
+DlgDocMaRight		: "Right",
+DlgDocMaBottom		: "Bottom",
+DlgDocMeIndex		: "Document Indexing Keywords (comma separated)",
+DlgDocMeDescr		: "Document Description",
+DlgDocMeAuthor		: "Author",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Preview",
+
+// Templates Dialog
+Templates			: "Templates",
+DlgTemplatesTitle	: "Content Templates",
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br />(the actual contents will be lost):",
+DlgTemplatesLoading	: "Loading templates list. Please wait...",
+DlgTemplatesNoTpl	: "(No templates defined)",
+DlgTemplatesReplace	: "Replace actual contents",
+
+// About Dialog
+DlgAboutAboutTab	: "About",
+DlgAboutBrowserInfoTab	: "Browser Info",
+DlgAboutLicenseTab	: "License",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "For further information go to"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ar.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ar.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ar.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Arabic language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "rtl",
+
+ToolbarCollapse		: "ضم شريط الأدوات",
+ToolbarExpand		: "تمدد شريط الأدوات",
+
+// Toolbar Items and Context Menu
+Save				: "حفظ",
+NewPage				: "صفحة جديدة",
+Preview				: "معاينة الصفحة",
+Cut					: "قص",
+Copy				: "نسخ",
+Paste				: "لصق",
+PasteText			: "لصق كنص بسيط",
+PasteWord			: "لصق من وورد",
+Print				: "طباعة",
+SelectAll			: "تحديد الكل",
+RemoveFormat		: "إزالة التنسيقات",
+InsertLinkLbl		: "رابط",
+InsertLink			: "إدراج/تحرير رابط",
+RemoveLink			: "إزالة رابط",
+Anchor				: "إدراج/تحرير إشارة مرجعية",
+InsertImageLbl		: "صورة",
+InsertImage			: "إدراج/تحرير صورة",
+InsertFlashLbl		: "فلاش",
+InsertFlash			: "إدراج/تحرير فيلم فلاش",
+InsertTableLbl		: "جدول",
+InsertTable			: "إدراج/تحرير جدول",
+InsertLineLbl		: "خط فاصل",
+InsertLine			: "إدراج خط فاصل",
+InsertSpecialCharLbl: "رموز",
+InsertSpecialChar	: "إدراج  رموز..ِ",
+InsertSmileyLbl		: "ابتسامات",
+InsertSmiley		: "إدراج ابتسامات",
+About				: "حول FCKeditor",
+Bold				: "غامق",
+Italic				: "مائل",
+Underline			: "تسطير",
+StrikeThrough		: "يتوسطه خط",
+Subscript			: "منخفض",
+Superscript			: "مرتفع",
+LeftJustify			: "محاذاة إلى اليسار",
+CenterJustify		: "توسيط",
+RightJustify		: "محاذاة إلى اليمين",
+BlockJustify		: "ضبط",
+DecreaseIndent		: "إنقاص المسافة البادئة",
+IncreaseIndent		: "زيادة المسافة البادئة",
+Undo				: "تراجع",
+Redo				: "إعادة",
+NumberedListLbl		: "تعداد رقمي",
+NumberedList		: "إدراج/إلغاء تعداد رقمي",
+BulletedListLbl		: "تعداد نقطي",
+BulletedList		: "إدراج/إلغاء تعداد نقطي",
+ShowTableBorders	: "معاينة حدود الجداول",
+ShowDetails			: "معاينة التفاصيل",
+Style				: "نمط",
+FontFormat			: "تنسيق",
+Font				: "خط",
+FontSize			: "حجم الخط",
+TextColor			: "لون النص",
+BGColor				: "لون الخلفية",
+Source				: "شفرة المصدر",
+Find				: "بحث",
+Replace				: "إستبدال",
+SpellCheck			: "تدقيق إملائي",
+UniversalKeyboard	: "لوحة المفاتيح العالمية",
+PageBreakLbl		: "فصل الصفحة",
+PageBreak			: "إدخال صفحة جديدة",
+
+Form			: "نموذج",
+Checkbox		: "خانة إختيار",
+RadioButton		: "زر خيار",
+TextField		: "مربع نص",
+Textarea		: "ناحية نص",
+HiddenField		: "إدراج حقل خفي",
+Button			: "زر ضغط",
+SelectionField	: "قائمة منسدلة",
+ImageButton		: "زر صورة",
+
+FitWindow		: "تكبير حجم المحرر",
+
+// Context Menu
+EditLink			: "تحرير رابط",
+CellCM				: "خلية",
+RowCM				: "صف",
+ColumnCM			: "عمود",
+InsertRow			: "إدراج صف",
+DeleteRows			: "حذف صفوف",
+InsertColumn		: "إدراج عمود",
+DeleteColumns		: "حذف أعمدة",
+InsertCell			: "إدراج خلية",
+DeleteCells			: "حذف خلايا",
+MergeCells			: "دمج خلايا",
+SplitCell			: "تقسيم خلية",
+TableDelete			: "حذف الجدول",
+CellProperties		: "خصائص الخلية",
+TableProperties		: "خصائص الجدول",
+ImageProperties		: "خصائص الصورة",
+FlashProperties		: "خصائص فيلم الفلاش",
+
+AnchorProp			: "خصائص الإشارة المرجعية",
+ButtonProp			: "خصائص زر الضغط",
+CheckboxProp		: "خصائص خانة الإختيار",
+HiddenFieldProp		: "خصائص الحقل الخفي",
+RadioButtonProp		: "خصائص زر الخيار",
+ImageButtonProp		: "خصائص زر الصورة",
+TextFieldProp		: "خصائص مربع النص",
+SelectionFieldProp	: "خصائص القائمة المنسدلة",
+TextareaProp		: "خصائص ناحية النص",
+FormProp			: "خصائص النموذج",
+
+FontFormats			: "عادي;منسّق;دوس;العنوان 1;العنوان  2;العنوان  3;العنوان  4;العنوان  5;العنوان  6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "إنتظر قليلاً ريثما تتم   معالَجة‏ XHTML. لن يستغرق طويلاً...",
+Done				: "تم",
+PasteWordConfirm	: "يبدو أن النص المراد لصقه منسوخ من برنامج وورد. هل تود تنظيفه قبل الشروع في عملية اللصق؟",
+NotCompatiblePaste	: "هذه الميزة تحتاج لمتصفح من النوعInternet Explorer إصدار 5.5 فما فوق. هل تود اللصق دون تنظيف الكود؟",
+UnknownToolbarItem	: "عنصر شريط أدوات غير معروف \"%1\"",
+UnknownCommand		: "أمر غير معروف \"%1\"",
+NotImplemented		: "لم يتم دعم هذا الأمر",
+UnknownToolbarSet	: "لم أتمكن من العثور على طقم الأدوات \"%1\" ",
+NoActiveX			: "لتأمين متصفحك يجب أن تحدد بعض مميزات المحرر. يتوجب عليك تمكين الخيار \"Run ActiveX controls and plug-ins\". قد تواجة أخطاء وتلاحظ مميزات مفقودة",
+BrowseServerBlocked : "لايمكن فتح مصدر المتصفح. فضلا يجب التأكد بأن جميع موانع النوافذ المنبثقة معطلة",
+DialogBlocked		: "لايمكن فتح نافذة الحوار . فضلا تأكد من أن  مانع النوافذ المنبثة معطل .",
+
+// Dialogs
+DlgBtnOK			: "موافق",
+DlgBtnCancel		: "إلغاء الأمر",
+DlgBtnClose			: "إغلاق",
+DlgBtnBrowseServer	: "تصفح الخادم",
+DlgAdvancedTag		: "متقدم",
+DlgOpOther			: "<أخرى>",
+DlgInfoTab			: "معلومات",
+DlgAlertUrl			: "الرجاء كتابة عنوان الإنترنت",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<بدون تحديد>",
+DlgGenId			: "الرقم",
+DlgGenLangDir		: "إتجاه النص",
+DlgGenLangDirLtr	: "اليسار لليمين (LTR)",
+DlgGenLangDirRtl	: "اليمين لليسار (RTL)",
+DlgGenLangCode		: "رمز اللغة",
+DlgGenAccessKey		: "مفاتيح الإختصار",
+DlgGenName			: "الاسم",
+DlgGenTabIndex		: "الترتيب",
+DlgGenLongDescr		: "عنوان الوصف المفصّل",
+DlgGenClass			: "فئات التنسيق",
+DlgGenTitle			: "تلميح الشاشة",
+DlgGenContType		: "نوع التلميح",
+DlgGenLinkCharset	: "ترميز المادة المطلوبة",
+DlgGenStyle			: "نمط",
+
+// Image Dialog
+DlgImgTitle			: "خصائص الصورة",
+DlgImgInfoTab		: "معلومات الصورة",
+DlgImgBtnUpload		: "أرسلها للخادم",
+DlgImgURL			: "موقع الصورة",
+DlgImgUpload		: "رفع",
+DlgImgAlt			: "الوصف",
+DlgImgWidth			: "العرض",
+DlgImgHeight		: "الإرتفاع",
+DlgImgLockRatio		: "تناسق الحجم",
+DlgBtnResetSize		: "إستعادة الحجم الأصلي",
+DlgImgBorder		: "سمك الحدود",
+DlgImgHSpace		: "تباعد أفقي",
+DlgImgVSpace		: "تباعد عمودي",
+DlgImgAlign			: "محاذاة",
+DlgImgAlignLeft		: "يسار",
+DlgImgAlignAbsBottom: "أسفل النص",
+DlgImgAlignAbsMiddle: "وسط السطر",
+DlgImgAlignBaseline	: "على السطر",
+DlgImgAlignBottom	: "أسفل",
+DlgImgAlignMiddle	: "وسط",
+DlgImgAlignRight	: "يمين",
+DlgImgAlignTextTop	: "أعلى النص",
+DlgImgAlignTop		: "أعلى",
+DlgImgPreview		: "معاينة",
+DlgImgAlertUrl		: "فضلاً أكتب الموقع الذي توجد عليه هذه الصورة.",
+DlgImgLinkTab		: "الرابط",
+
+// Flash Dialog
+DlgFlashTitle		: "خصائص فيلم الفلاش",
+DlgFlashChkPlay		: "تشغيل تلقائي",
+DlgFlashChkLoop		: "تكرار",
+DlgFlashChkMenu		: "تمكين قائمة فيلم الفلاش",
+DlgFlashScale		: "الحجم",
+DlgFlashScaleAll	: "إظهار الكل",
+DlgFlashScaleNoBorder	: "بلا حدود",
+DlgFlashScaleFit	: "ضبط تام",
+
+// Link Dialog
+DlgLnkWindowTitle	: "إرتباط تشعبي",
+DlgLnkInfoTab		: "معلومات الرابط",
+DlgLnkTargetTab		: "الهدف",
+
+DlgLnkType			: "نوع الربط",
+DlgLnkTypeURL		: "العنوان",
+DlgLnkTypeAnchor	: "مكان في هذا المستند",
+DlgLnkTypeEMail		: "بريد إلكتروني",
+DlgLnkProto			: "البروتوكول",
+DlgLnkProtoOther	: "<أخرى>",
+DlgLnkURL			: "الموقع",
+DlgLnkAnchorSel		: "اختر علامة مرجعية",
+DlgLnkAnchorByName	: "حسب اسم العلامة",
+DlgLnkAnchorById	: "حسب تعريف العنصر",
+DlgLnkNoAnchors		: "<لا يوجد علامات مرجعية في هذا المستند>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "عنوان بريد إلكتروني",
+DlgLnkEMailSubject	: "موضوع الرسالة",
+DlgLnkEMailBody		: "محتوى الرسالة",
+DlgLnkUpload		: "رفع",
+DlgLnkBtnUpload		: "أرسلها للخادم",
+
+DlgLnkTarget		: "الهدف",
+DlgLnkTargetFrame	: "<إطار>",
+DlgLnkTargetPopup	: "<نافذة منبثقة>",
+DlgLnkTargetBlank	: "إطار جديد (_blank)",
+DlgLnkTargetParent	: "الإطار الأصل (_parent)",
+DlgLnkTargetSelf	: "نفس الإطار (_self)",
+DlgLnkTargetTop		: "صفحة كاملة (_top)",
+DlgLnkTargetFrameName	: "اسم الإطار الهدف",
+DlgLnkPopWinName	: "تسمية النافذة المنبثقة",
+DlgLnkPopWinFeat	: "خصائص النافذة المنبثقة",
+DlgLnkPopResize		: "قابلة للتحجيم",
+DlgLnkPopLocation	: "شريط العنوان",
+DlgLnkPopMenu		: "القوائم الرئيسية",
+DlgLnkPopScroll		: "أشرطة التمرير",
+DlgLnkPopStatus		: "شريط الحالة السفلي",
+DlgLnkPopToolbar	: "شريط الأدوات",
+DlgLnkPopFullScrn	: "ملئ الشاشة (IE)",
+DlgLnkPopDependent	: "تابع (Netscape)",
+DlgLnkPopWidth		: "العرض",
+DlgLnkPopHeight		: "الإرتفاع",
+DlgLnkPopLeft		: "التمركز لليسار",
+DlgLnkPopTop		: "التمركز للأعلى",
+
+DlnLnkMsgNoUrl		: "فضلاً أدخل عنوان الموقع الذي يشير إليه الرابط",
+DlnLnkMsgNoEMail	: "فضلاً أدخل عنوان البريد الإلكتروني",
+DlnLnkMsgNoAnchor	: "فضلاً حدد العلامة المرجعية المرغوبة",
+DlnLnkMsgInvPopName	: "اسم النافذة المنبثقة يجب أن يبدأ بحرف أبجدي دون مسافات",
+
+// Color Dialog
+DlgColorTitle		: "اختر لوناً",
+DlgColorBtnClear	: "مسح",
+DlgColorHighlight	: "تحديد",
+DlgColorSelected	: "إختيار",
+
+// Smiley Dialog
+DlgSmileyTitle		: "إدراج إبتسامات ",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "إدراج رمز",
+
+// Table Dialog
+DlgTableTitle		: "إدراج جدول",
+DlgTableRows		: "صفوف",
+DlgTableColumns		: "أعمدة",
+DlgTableBorder		: "سمك الحدود",
+DlgTableAlign		: "المحاذاة",
+DlgTableAlignNotSet	: "<بدون تحديد>",
+DlgTableAlignLeft	: "يسار",
+DlgTableAlignCenter	: "وسط",
+DlgTableAlignRight	: "يمين",
+DlgTableWidth		: "العرض",
+DlgTableWidthPx		: "بكسل",
+DlgTableWidthPc		: "بالمئة",
+DlgTableHeight		: "الإرتفاع",
+DlgTableCellSpace	: "تباعد الخلايا",
+DlgTableCellPad		: "المسافة البادئة",
+DlgTableCaption		: "الوصف",
+DlgTableSummary		: "الخلاصة",
+
+// Table Cell Dialog
+DlgCellTitle		: "خصائص الخلية",
+DlgCellWidth		: "العرض",
+DlgCellWidthPx		: "بكسل",
+DlgCellWidthPc		: "بالمئة",
+DlgCellHeight		: "الإرتفاع",
+DlgCellWordWrap		: "التفاف النص",
+DlgCellWordWrapNotSet	: "<بدون تحديد>",
+DlgCellWordWrapYes	: "نعم",
+DlgCellWordWrapNo	: "لا",
+DlgCellHorAlign		: "المحاذاة الأفقية",
+DlgCellHorAlignNotSet	: "<بدون تحديد>",
+DlgCellHorAlignLeft	: "يسار",
+DlgCellHorAlignCenter	: "وسط",
+DlgCellHorAlignRight: "يمين",
+DlgCellVerAlign		: "المحاذاة العمودية",
+DlgCellVerAlignNotSet	: "<بدون تحديد>",
+DlgCellVerAlignTop	: "أعلى",
+DlgCellVerAlignMiddle	: "وسط",
+DlgCellVerAlignBottom	: "أسفل",
+DlgCellVerAlignBaseline	: "على السطر",
+DlgCellRowSpan		: "إمتداد الصفوف",
+DlgCellCollSpan		: "إمتداد الأعمدة",
+DlgCellBackColor	: "لون الخلفية",
+DlgCellBorderColor	: "لون الحدود",
+DlgCellBtnSelect	: "حدّد...",
+
+// Find Dialog
+DlgFindTitle		: "بحث",
+DlgFindFindBtn		: "ابحث",
+DlgFindNotFoundMsg	: "لم يتم العثور على النص المحدد.",
+
+// Replace Dialog
+DlgReplaceTitle			: "إستبدال",
+DlgReplaceFindLbl		: "البحث عن:",
+DlgReplaceReplaceLbl	: "إستبدال بـ:",
+DlgReplaceCaseChk		: "مطابقة حالة الأحرف",
+DlgReplaceReplaceBtn	: "إستبدال",
+DlgReplaceReplAllBtn	: "إستبدال الكل",
+DlgReplaceWordChk		: "الكلمة بالكامل فقط",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع القص التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl+X).",
+PasteErrorCopy	: "الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع النسخ التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl+C).",
+
+PasteAsText		: "لصق كنص بسيط",
+PasteFromWord	: "لصق من وورد",
+
+DlgPasteMsg2	: "الصق داخل الصندوق بإستخدام زرّي (<STRONG>Ctrl+V</STRONG>) في لوحة المفاتيح، ثم اضغط زر  <STRONG>موافق</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "تجاهل تعريفات أسماء الخطوط",
+DlgPasteRemoveStyles	: "إزالة تعريفات الأنماط",
+DlgPasteCleanBox		: "نظّف محتوى الصندوق",
+
+// Color Picker
+ColorAutomatic	: "تلقائي",
+ColorMoreColors	: "ألوان إضافية...",
+
+// Document Properties
+DocProps		: "خصائص الصفحة",
+
+// Anchor Dialog
+DlgAnchorTitle		: "خصائص إشارة مرجعية",
+DlgAnchorName		: "اسم الإشارة المرجعية",
+DlgAnchorErrorName	: "الرجاء كتابة اسم الإشارة المرجعية",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "ليست في القاموس",
+DlgSpellChangeTo		: "التغيير إلى",
+DlgSpellBtnIgnore		: "تجاهل",
+DlgSpellBtnIgnoreAll	: "تجاهل الكل",
+DlgSpellBtnReplace		: "تغيير",
+DlgSpellBtnReplaceAll	: "تغيير الكل",
+DlgSpellBtnUndo			: "تراجع",
+DlgSpellNoSuggestions	: "- لا توجد إقتراحات -",
+DlgSpellProgress		: "جاري التدقيق إملائياً",
+DlgSpellNoMispell		: "تم إكمال التدقيق الإملائي: لم يتم العثور على أي أخطاء إملائية",
+DlgSpellNoChanges		: "تم إكمال التدقيق الإملائي: لم يتم تغيير أي كلمة",
+DlgSpellOneChange		: "تم إكمال التدقيق الإملائي: تم تغيير كلمة واحدة فقط",
+DlgSpellManyChanges		: "تم إكمال التدقيق الإملائي: تم تغيير %1 كلمات\كلمة",
+
+IeSpellDownload			: "المدقق الإملائي (الإنجليزي) غير مثبّت. هل تود تحميله الآن؟",
+
+// Button Dialog
+DlgButtonText		: "القيمة/التسمية",
+DlgButtonType		: "نوع الزر",
+DlgButtonTypeBtn	: "زر",
+DlgButtonTypeSbm	: "إرسال",
+DlgButtonTypeRst	: "إعادة تعيين",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "الاسم",
+DlgCheckboxValue	: "القيمة",
+DlgCheckboxSelected	: "محدد",
+
+// Form Dialog
+DlgFormName		: "الاسم",
+DlgFormAction	: "اسم الملف",
+DlgFormMethod	: "الأسلوب",
+
+// Select Field Dialog
+DlgSelectName		: "الاسم",
+DlgSelectValue		: "القيمة",
+DlgSelectSize		: "الحجم",
+DlgSelectLines		: "الأسطر",
+DlgSelectChkMulti	: "السماح بتحديدات متعددة",
+DlgSelectOpAvail	: "الخيارات المتاحة",
+DlgSelectOpText		: "النص",
+DlgSelectOpValue	: "القيمة",
+DlgSelectBtnAdd		: "إضافة",
+DlgSelectBtnModify	: "تعديل",
+DlgSelectBtnUp		: "تحريك لأعلى",
+DlgSelectBtnDown	: "تحريك لأسفل",
+DlgSelectBtnSetValue : "إجعلها محددة",
+DlgSelectBtnDelete	: "إزالة",
+
+// Textarea Dialog
+DlgTextareaName	: "الاسم",
+DlgTextareaCols	: "الأعمدة",
+DlgTextareaRows	: "الصفوف",
+
+// Text Field Dialog
+DlgTextName			: "الاسم",
+DlgTextValue		: "القيمة",
+DlgTextCharWidth	: "العرض بالأحرف",
+DlgTextMaxChars		: "عدد الحروف الأقصى",
+DlgTextType			: "نوع المحتوى",
+DlgTextTypeText		: "نص",
+DlgTextTypePass		: "كلمة مرور",
+
+// Hidden Field Dialog
+DlgHiddenName	: "الاسم",
+DlgHiddenValue	: "القيمة",
+
+// Bulleted List Dialog
+BulletedListProp	: "خصائص التعداد النقطي",
+NumberedListProp	: "خصائص التعداد الرقمي",
+DlgLstStart			: "البدء عند",
+DlgLstType			: "النوع",
+DlgLstTypeCircle	: "دائرة",
+DlgLstTypeDisc		: "قرص",
+DlgLstTypeSquare	: "مربع",
+DlgLstTypeNumbers	: "أرقام (1، 2، 3)َ",
+DlgLstTypeLCase		: "حروف صغيرة (a, b, c)َ",
+DlgLstTypeUCase		: "حروف كبيرة (A, B, C)َ",
+DlgLstTypeSRoman	: "ترقيم روماني صغير (i, ii, iii)َ",
+DlgLstTypeLRoman	: "ترقيم روماني كبير (I, II, III)َ",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "عام",
+DlgDocBackTab		: "الخلفية",
+DlgDocColorsTab		: "الألوان والهوامش",
+DlgDocMetaTab		: "المعرّفات الرأسية",
+
+DlgDocPageTitle		: "عنوان الصفحة",
+DlgDocLangDir		: "إتجاه اللغة",
+DlgDocLangDirLTR	: "اليسار لليمين (LTR)",
+DlgDocLangDirRTL	: "اليمين لليسار (RTL)",
+DlgDocLangCode		: "رمز اللغة",
+DlgDocCharSet		: "ترميز الحروف",
+DlgDocCharSetCE		: "أوروبا الوسطى",
+DlgDocCharSetCT		: "الصينية التقليدية (Big5)",
+DlgDocCharSetCR		: "السيريلية",
+DlgDocCharSetGR		: "اليونانية",
+DlgDocCharSetJP		: "اليابانية",
+DlgDocCharSetKR		: "الكورية",
+DlgDocCharSetTR		: "التركية",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "أوروبا الغربية",
+DlgDocCharSetOther	: "ترميز آخر",
+
+DlgDocDocType		: "ترويسة نوع  الصفحة",
+DlgDocDocTypeOther	: "ترويسة نوع  صفحة أخرى",
+DlgDocIncXHTML		: "تضمين   إعلانات‏ لغة XHTMLَ",
+DlgDocBgColor		: "لون الخلفية",
+DlgDocBgImage		: "رابط الصورة الخلفية",
+DlgDocBgNoScroll	: "جعلها علامة مائية",
+DlgDocCText			: "النص",
+DlgDocCLink			: "الروابط",
+DlgDocCVisited		: "المزارة",
+DlgDocCActive		: "النشطة",
+DlgDocMargins		: "هوامش الصفحة",
+DlgDocMaTop			: "علوي",
+DlgDocMaLeft		: "أيسر",
+DlgDocMaRight		: "أيمن",
+DlgDocMaBottom		: "سفلي",
+DlgDocMeIndex		: "الكلمات الأساسية (مفصولة بفواصل)َ",
+DlgDocMeDescr		: "وصف الصفحة",
+DlgDocMeAuthor		: "الكاتب",
+DlgDocMeCopy		: "المالك",
+DlgDocPreview		: "معاينة",
+
+// Templates Dialog
+Templates			: "القوالب",
+DlgTemplatesTitle	: "قوالب المحتوى",
+DlgTemplatesSelMsg	: "اختر القالب الذي تود وضعه في المحرر <br>(سيتم فقدان المحتوى الحالي):",
+DlgTemplatesLoading	: "جاري تحميل قائمة القوالب، الرجاء الإنتظار...",
+DlgTemplatesNoTpl	: "(لم يتم تعريف أي قالب)",
+DlgTemplatesReplace	: "استبدال المحتوى",
+
+// About Dialog
+DlgAboutAboutTab	: "نبذة",
+DlgAboutBrowserInfoTab	: "معلومات متصفحك",
+DlgAboutLicenseTab	: "الترخيص",
+DlgAboutVersion		: "الإصدار",
+DlgAboutInfo		: "لمزيد من المعلومات تفضل بزيارة"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/gl.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/gl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/gl.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Galician language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Ocultar Ferramentas",
+ToolbarExpand		: "Mostrar Ferramentas",
+
+// Toolbar Items and Context Menu
+Save				: "Gardar",
+NewPage				: "Nova Páxina",
+Preview				: "Vista Previa",
+Cut					: "Cortar",
+Copy				: "Copiar",
+Paste				: "Pegar",
+PasteText			: "Pegar como texto plano",
+PasteWord			: "Pegar dende Word",
+Print				: "Imprimir",
+SelectAll			: "Seleccionar todo",
+RemoveFormat		: "Eliminar Formato",
+InsertLinkLbl		: "Ligazón",
+InsertLink			: "Inserir/Editar Ligazón",
+RemoveLink			: "Eliminar Ligazón",
+Anchor				: "Inserir/Editar Referencia",
+InsertImageLbl		: "Imaxe",
+InsertImage			: "Inserir/Editar Imaxe",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Inserir/Editar Flash",
+InsertTableLbl		: "Tabla",
+InsertTable			: "Inserir/Editar Tabla",
+InsertLineLbl		: "Liña",
+InsertLine			: "Inserir Liña Horizontal",
+InsertSpecialCharLbl: "Carácter Special",
+InsertSpecialChar	: "Inserir Carácter Especial",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Inserir Smiley",
+About				: "Acerca de FCKeditor",
+Bold				: "Negrita",
+Italic				: "Cursiva",
+Underline			: "Sub-raiado",
+StrikeThrough		: "Tachado",
+Subscript			: "Subíndice",
+Superscript			: "Superíndice",
+LeftJustify			: "Aliñar á Esquerda",
+CenterJustify		: "Centrado",
+RightJustify		: "Aliñar á Dereita",
+BlockJustify		: "Xustificado",
+DecreaseIndent		: "Disminuir Sangría",
+IncreaseIndent		: "Aumentar Sangría",
+Undo				: "Desfacer",
+Redo				: "Refacer",
+NumberedListLbl		: "Lista Numerada",
+NumberedList		: "Inserir/Eliminar Lista Numerada",
+BulletedListLbl		: "Marcas",
+BulletedList		: "Inserir/Eliminar Marcas",
+ShowTableBorders	: "Mostrar Bordes das Táboas",
+ShowDetails			: "Mostrar Marcas Parágrafo",
+Style				: "Estilo",
+FontFormat			: "Formato",
+Font				: "Tipo",
+FontSize			: "Tamaño",
+TextColor			: "Cor do Texto",
+BGColor				: "Cor do Fondo",
+Source				: "Código Fonte",
+Find				: "Procurar",
+Replace				: "Substituir",
+SpellCheck			: "Corrección Ortográfica",
+UniversalKeyboard	: "Teclado Universal",
+PageBreakLbl		: "Salto de Páxina",
+PageBreak			: "Inserir Salto de Páxina",
+
+Form			: "Formulario",
+Checkbox		: "Cadro de Verificación",
+RadioButton		: "Botón de Radio",
+TextField		: "Campo de Texto",
+Textarea		: "Área de Texto",
+HiddenField		: "Campo Oculto",
+Button			: "Botón",
+SelectionField	: "Campo de Selección",
+ImageButton		: "Botón de Imaxe",
+
+FitWindow		: "Maximizar o tamaño do editor",
+
+// Context Menu
+EditLink			: "Editar Ligazón",
+CellCM				: "Cela",
+RowCM				: "Fila",
+ColumnCM			: "Columna",
+InsertRow			: "Inserir Fila",
+DeleteRows			: "Borrar Filas",
+InsertColumn		: "Inserir Columna",
+DeleteColumns		: "Borrar Columnas",
+InsertCell			: "Inserir Cela",
+DeleteCells			: "Borrar Cela",
+MergeCells			: "Unir Celas",
+SplitCell			: "Partir Celas",
+TableDelete			: "Borrar Táboa",
+CellProperties		: "Propriedades da Cela",
+TableProperties		: "Propriedades da Táboa",
+ImageProperties		: "Propriedades Imaxe",
+FlashProperties		: "Propriedades Flash",
+
+AnchorProp			: "Propriedades da Referencia",
+ButtonProp			: "Propriedades do Botón",
+CheckboxProp		: "Propriedades do Cadro de Verificación",
+HiddenFieldProp		: "Propriedades do Campo Oculto",
+RadioButtonProp		: "Propriedades do Botón de Radio",
+ImageButtonProp		: "Propriedades do Botón de Imaxe",
+TextFieldProp		: "Propriedades do Campo de Texto",
+SelectionFieldProp	: "Propriedades do Campo de Selección",
+TextareaProp		: "Propriedades da Área de Texto",
+FormProp			: "Propriedades do Formulario",
+
+FontFormats			: "Normal;Formateado;Enderezo;Enacabezado 1;Encabezado 2;Encabezado 3;Encabezado 4;Encabezado 5;Encabezado 6;Paragraph (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Procesando XHTML. Por facor, agarde...",
+Done				: "Feiro",
+PasteWordConfirm	: "Parece que o texto que quere pegar está copiado do Word.¿Quere limpar o formato antes de pegalo?",
+NotCompatiblePaste	: "Este comando está disponible para Internet Explorer versión 5.5 ou superior. ¿Quere pegalo sen limpar o formato?",
+UnknownToolbarItem	: "Ítem de ferramentas descoñecido \"%1\"",
+UnknownCommand		: "Nome de comando descoñecido \"%1\"",
+NotImplemented		: "Comando non implementado",
+UnknownToolbarSet	: "O conxunto de ferramentas \"%1\" non existe",
+NoActiveX			: "As opcións de seguridade do seu navegador poderían limitar algunha das características de editor. Debe activar a opción \"Executar controis ActiveX e plug-ins\". Pode notar que faltan características e experimentar erros",
+BrowseServerBlocked : "Non se poido abrir o navegador de recursos. Asegúrese de que están desactivados os bloqueadores de xanelas emerxentes",
+DialogBlocked		: "Non foi posible abrir a xanela de diálogo. Asegúrese de que están desactivados os bloqueadores de xanelas emerxentes",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancelar",
+DlgBtnClose			: "Pechar",
+DlgBtnBrowseServer	: "Navegar no Servidor",
+DlgAdvancedTag		: "Advanzado",
+DlgOpOther			: "<Outro>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Por favor, insira a URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<non definido>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Orientación do Idioma",
+DlgGenLangDirLtr	: "Esquerda a Dereita (LTR)",
+DlgGenLangDirRtl	: "Dereita a Esquerda (RTL)",
+DlgGenLangCode		: "Código do Idioma",
+DlgGenAccessKey		: "Chave de Acceso",
+DlgGenName			: "Nome",
+DlgGenTabIndex		: "Índice de Tabulación",
+DlgGenLongDescr		: "Descrición Completa da URL",
+DlgGenClass			: "Clases da Folla de Estilos",
+DlgGenTitle			: "Título",
+DlgGenContType		: "Tipo de Contido",
+DlgGenLinkCharset	: "Fonte de Caracteres Vinculado",
+DlgGenStyle			: "Estilo",
+
+// Image Dialog
+DlgImgTitle			: "Propriedades da Imaxe",
+DlgImgInfoTab		: "Información da Imaxe",
+DlgImgBtnUpload		: "Enviar ó Servidor",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Carregar",
+DlgImgAlt			: "Texto Alternativo",
+DlgImgWidth			: "Largura",
+DlgImgHeight		: "Altura",
+DlgImgLockRatio		: "Proporcional",
+DlgBtnResetSize		: "Tamaño Orixinal",
+DlgImgBorder		: "Límite",
+DlgImgHSpace		: "Esp. Horiz.",
+DlgImgVSpace		: "Esp. Vert.",
+DlgImgAlign			: "Aliñamento",
+DlgImgAlignLeft		: "Esquerda",
+DlgImgAlignAbsBottom: "Abs Inferior",
+DlgImgAlignAbsMiddle: "Abs Centro",
+DlgImgAlignBaseline	: "Liña Base",
+DlgImgAlignBottom	: "Pé",
+DlgImgAlignMiddle	: "Centro",
+DlgImgAlignRight	: "Dereita",
+DlgImgAlignTextTop	: "Tope do Texto",
+DlgImgAlignTop		: "Tope",
+DlgImgPreview		: "Vista Previa",
+DlgImgAlertUrl		: "Por favor, escriba a URL da imaxe",
+DlgImgLinkTab		: "Ligazón",
+
+// Flash Dialog
+DlgFlashTitle		: "Propriedades Flash",
+DlgFlashChkPlay		: "Auto Execución",
+DlgFlashChkLoop		: "Bucle",
+DlgFlashChkMenu		: "Activar Menú Flash",
+DlgFlashScale		: "Escalar",
+DlgFlashScaleAll	: "Amosar Todo",
+DlgFlashScaleNoBorder	: "Sen Borde",
+DlgFlashScaleFit	: "Encaixar axustando",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Ligazón",
+DlgLnkInfoTab		: "Información da Ligazón",
+DlgLnkTargetTab		: "Referencia a esta páxina",
+
+DlgLnkType			: "Tipo de Ligazón",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Referencia nesta páxina",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocolo",
+DlgLnkProtoOther	: "<outro>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Seleccionar unha Referencia",
+DlgLnkAnchorByName	: "Por Nome de Referencia",
+DlgLnkAnchorById	: "Por Element Id",
+DlgLnkNoAnchors		: "<Non hai referencias disponibles no documento>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Enderezo de E-Mail",
+DlgLnkEMailSubject	: "Asunto do Mensaxe",
+DlgLnkEMailBody		: "Corpo do Mensaxe",
+DlgLnkUpload		: "Carregar",
+DlgLnkBtnUpload		: "Enviar ó servidor",
+
+DlgLnkTarget		: "Destino",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<Xanela Emerxente>",
+DlgLnkTargetBlank	: "Nova Xanela (_blank)",
+DlgLnkTargetParent	: "Xanela Pai (_parent)",
+DlgLnkTargetSelf	: "Mesma Xanela (_self)",
+DlgLnkTargetTop		: "Xanela Primaria (_top)",
+DlgLnkTargetFrameName	: "Nome do Marco Destino",
+DlgLnkPopWinName	: "Nome da Xanela Emerxente",
+DlgLnkPopWinFeat	: "Características da Xanela Emerxente",
+DlgLnkPopResize		: "Axustable",
+DlgLnkPopLocation	: "Barra de Localización",
+DlgLnkPopMenu		: "Barra de Menú",
+DlgLnkPopScroll		: "Barras de Desplazamento",
+DlgLnkPopStatus		: "Barra de Estado",
+DlgLnkPopToolbar	: "Barra de Ferramentas",
+DlgLnkPopFullScrn	: "A Toda Pantalla (IE)",
+DlgLnkPopDependent	: "Dependente (Netscape)",
+DlgLnkPopWidth		: "Largura",
+DlgLnkPopHeight		: "Altura",
+DlgLnkPopLeft		: "Posición Esquerda",
+DlgLnkPopTop		: "Posición dende Arriba",
+
+DlnLnkMsgNoUrl		: "Por favor, escriba a ligazón URL",
+DlnLnkMsgNoEMail	: "Por favor, escriba o enderezo de e-mail",
+DlnLnkMsgNoAnchor	: "Por favor, seleccione un destino",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Seleccionar Color",
+DlgColorBtnClear	: "Nengunha",
+DlgColorHighlight	: "Destacado",
+DlgColorSelected	: "Seleccionado",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Inserte un Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Seleccione Caracter Especial",
+
+// Table Dialog
+DlgTableTitle		: "Propiedades da Táboa",
+DlgTableRows		: "Filas",
+DlgTableColumns		: "Columnas",
+DlgTableBorder		: "Tamaño do Borde",
+DlgTableAlign		: "Aliñamento",
+DlgTableAlignNotSet	: "<Non Definido>",
+DlgTableAlignLeft	: "Esquerda",
+DlgTableAlignCenter	: "Centro",
+DlgTableAlignRight	: "Ereita",
+DlgTableWidth		: "Largura",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Altura",
+DlgTableCellSpace	: "Marxe entre Celas",
+DlgTableCellPad		: "Marxe interior",
+DlgTableCaption		: "Título",
+DlgTableSummary		: "Sumario",
+
+// Table Cell Dialog
+DlgCellTitle		: "Propriedades da Cela",
+DlgCellWidth		: "Largura",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Altura",
+DlgCellWordWrap		: "Axustar Liñas",
+DlgCellWordWrapNotSet	: "<Non Definido>",
+DlgCellWordWrapYes	: "Si",
+DlgCellWordWrapNo	: "Non",
+DlgCellHorAlign		: "Aliñamento Horizontal",
+DlgCellHorAlignNotSet	: "<Non definido>",
+DlgCellHorAlignLeft	: "Esquerda",
+DlgCellHorAlignCenter	: "Centro",
+DlgCellHorAlignRight: "Dereita",
+DlgCellVerAlign		: "Aliñamento Vertical",
+DlgCellVerAlignNotSet	: "<Non definido>",
+DlgCellVerAlignTop	: "Arriba",
+DlgCellVerAlignMiddle	: "Medio",
+DlgCellVerAlignBottom	: "Abaixo",
+DlgCellVerAlignBaseline	: "Liña de Base",
+DlgCellRowSpan		: "Ocupar Filas",
+DlgCellCollSpan		: "Ocupar Columnas",
+DlgCellBackColor	: "Color de Fondo",
+DlgCellBorderColor	: "Color de Borde",
+DlgCellBtnSelect	: "Seleccionar...",
+
+// Find Dialog
+DlgFindTitle		: "Procurar",
+DlgFindFindBtn		: "Procurar",
+DlgFindNotFoundMsg	: "Non te atopou o texto indicado.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Substituir",
+DlgReplaceFindLbl		: "Texto a procurar:",
+DlgReplaceReplaceLbl	: "Substituir con:",
+DlgReplaceCaseChk		: "Coincidir Mai./min.",
+DlgReplaceReplaceBtn	: "Substituir",
+DlgReplaceReplAllBtn	: "Substitiur Todo",
+DlgReplaceWordChk		: "Coincidir con toda a palabra",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Os axustes de seguridade do seu navegador non permiten que o editor realice automáticamente as tarefas de corte. Por favor, use o teclado para iso (Ctrl+X).",
+PasteErrorCopy	: "Os axustes de seguridade do seu navegador non permiten que o editor realice automáticamente as tarefas de copia. Por favor, use o teclado para iso (Ctrl+C).",
+
+PasteAsText		: "Pegar como texto plano",
+PasteFromWord	: "Pegar dende Word",
+
+DlgPasteMsg2	: "Por favor, pegue dentro do seguinte cadro usando o teclado (<STRONG>Ctrl+V</STRONG>) e pulse <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorar as definicións de Tipografía",
+DlgPasteRemoveStyles	: "Eliminar as definicións de Estilos",
+DlgPasteCleanBox		: "Limpar o Cadro",
+
+// Color Picker
+ColorAutomatic	: "Automático",
+ColorMoreColors	: "Máis Cores...",
+
+// Document Properties
+DocProps		: "Propriedades do Documento",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Propriedades da Referencia",
+DlgAnchorName		: "Nome da Referencia",
+DlgAnchorErrorName	: "Por favor, escriba o nome da referencia",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Non está no diccionario",
+DlgSpellChangeTo		: "Cambiar a",
+DlgSpellBtnIgnore		: "Ignorar",
+DlgSpellBtnIgnoreAll	: "Ignorar Todas",
+DlgSpellBtnReplace		: "Substituir",
+DlgSpellBtnReplaceAll	: "Substituir Todas",
+DlgSpellBtnUndo			: "Desfacer",
+DlgSpellNoSuggestions	: "- Sen candidatos -",
+DlgSpellProgress		: "Corrección ortográfica en progreso...",
+DlgSpellNoMispell		: "Corrección ortográfica rematada: Non se atoparon erros",
+DlgSpellNoChanges		: "Corrección ortográfica rematada: Non se substituiu nengunha verba",
+DlgSpellOneChange		: "Corrección ortográfica rematada: Unha verba substituida",
+DlgSpellManyChanges		: "Corrección ortográfica rematada: %1 verbas substituidas",
+
+IeSpellDownload			: "O corrector ortográfico non está instalado. ¿Quere descargalo agora?",
+
+// Button Dialog
+DlgButtonText		: "Texto (Valor)",
+DlgButtonType		: "Tipo",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nome",
+DlgCheckboxValue	: "Valor",
+DlgCheckboxSelected	: "Seleccionado",
+
+// Form Dialog
+DlgFormName		: "Nome",
+DlgFormAction	: "Acción",
+DlgFormMethod	: "Método",
+
+// Select Field Dialog
+DlgSelectName		: "Nome",
+DlgSelectValue		: "Valor",
+DlgSelectSize		: "Tamaño",
+DlgSelectLines		: "liñas",
+DlgSelectChkMulti	: "Permitir múltiples seleccións",
+DlgSelectOpAvail	: "Opcións Disponibles",
+DlgSelectOpText		: "Texto",
+DlgSelectOpValue	: "Valor",
+DlgSelectBtnAdd		: "Engadir",
+DlgSelectBtnModify	: "Modificar",
+DlgSelectBtnUp		: "Subir",
+DlgSelectBtnDown	: "Baixar",
+DlgSelectBtnSetValue : "Definir como valor por defecto",
+DlgSelectBtnDelete	: "Borrar",
+
+// Textarea Dialog
+DlgTextareaName	: "Nome",
+DlgTextareaCols	: "Columnas",
+DlgTextareaRows	: "Filas",
+
+// Text Field Dialog
+DlgTextName			: "Nome",
+DlgTextValue		: "Valor",
+DlgTextCharWidth	: "Tamaño do Caracter",
+DlgTextMaxChars		: "Máximo de Caracteres",
+DlgTextType			: "Tipo",
+DlgTextTypeText		: "Texto",
+DlgTextTypePass		: "Chave",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nome",
+DlgHiddenValue	: "Valor",
+
+// Bulleted List Dialog
+BulletedListProp	: "Propriedades das Marcas",
+NumberedListProp	: "Propriedades da Lista de Numeración",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tipo",
+DlgLstTypeCircle	: "Círculo",
+DlgLstTypeDisc		: "Disco",
+DlgLstTypeSquare	: "Cuadrado",
+DlgLstTypeNumbers	: "Números (1, 2, 3)",
+DlgLstTypeLCase		: "Letras Minúsculas (a, b, c)",
+DlgLstTypeUCase		: "Letras Maiúsculas (A, B, C)",
+DlgLstTypeSRoman	: "Números Romanos en minúscula (i, ii, iii)",
+DlgLstTypeLRoman	: "Números Romanos en Maiúscula (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Xeral",
+DlgDocBackTab		: "Fondo",
+DlgDocColorsTab		: "Cores e Marxes",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Título da Páxina",
+DlgDocLangDir		: "Orientación do Idioma",
+DlgDocLangDirLTR	: "Esquerda a Dereita (LTR)",
+DlgDocLangDirRTL	: "Dereita a Esquerda (RTL)",
+DlgDocLangCode		: "Código de Idioma",
+DlgDocCharSet		: "Codificación do Xogo de Caracteres",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Outra Codificación do Xogo de Caracteres",
+
+DlgDocDocType		: "Encabezado do Tipo de Documento",
+DlgDocDocTypeOther	: "Outro Encabezado do Tipo de Documento",
+DlgDocIncXHTML		: "Incluir Declaracións XHTML",
+DlgDocBgColor		: "Cor de Fondo",
+DlgDocBgImage		: "URL da Imaxe de Fondo",
+DlgDocBgNoScroll	: "Fondo Fixo",
+DlgDocCText			: "Texto",
+DlgDocCLink			: "Ligazóns",
+DlgDocCVisited		: "Ligazón Visitada",
+DlgDocCActive		: "Ligazón Activa",
+DlgDocMargins		: "Marxes da Páxina",
+DlgDocMaTop			: "Arriba",
+DlgDocMaLeft		: "Esquerda",
+DlgDocMaRight		: "Dereita",
+DlgDocMaBottom		: "Abaixo",
+DlgDocMeIndex		: "Palabras Chave de Indexación do Documento (separadas por comas)",
+DlgDocMeDescr		: "Descripción do Documento",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Vista Previa",
+
+// Templates Dialog
+Templates			: "Plantillas",
+DlgTemplatesTitle	: "Plantillas de Contido",
+DlgTemplatesSelMsg	: "Por favor, seleccione a plantilla a abrir no editor<br>(o contido actual perderase):",
+DlgTemplatesLoading	: "Cargando listado de plantillas. Por favor, espere...",
+DlgTemplatesNoTpl	: "(Non hai plantillas definidas)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Acerca de",
+DlgAboutBrowserInfoTab	: "Información do Navegador",
+DlgAboutLicenseTab	: "Licencia",
+DlgAboutVersion		: "versión",
+DlgAboutInfo		: "Para máis información visitar:"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/_translationstatus.txt
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/_translationstatus.txt	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/_translationstatus.txt	(revision 795)
@@ -0,0 +1,76 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Translations Status.
+ */
+
+af.js      Found: 401   Missing: 1
+ar.js      Found: 401   Missing: 1
+bg.js      Found: 378   Missing: 24
+bn.js      Found: 386   Missing: 16
+bs.js      Found: 230   Missing: 172
+ca.js      Found: 401   Missing: 1
+cs.js      Found: 386   Missing: 16
+da.js      Found: 386   Missing: 16
+de.js      Found: 401   Missing: 1
+el.js      Found: 401   Missing: 1
+en-au.js   Found: 402   Missing: 0
+en-ca.js   Found: 402   Missing: 0
+en-uk.js   Found: 402   Missing: 0
+eo.js      Found: 350   Missing: 52
+es.js      Found: 386   Missing: 16
+et.js      Found: 386   Missing: 16
+eu.js      Found: 386   Missing: 16
+fa.js      Found: 401   Missing: 1
+fi.js      Found: 386   Missing: 16
+fo.js      Found: 401   Missing: 1
+fr.js      Found: 401   Missing: 1
+gl.js      Found: 386   Missing: 16
+he.js      Found: 401   Missing: 1
+hi.js      Found: 401   Missing: 1
+hr.js      Found: 401   Missing: 1
+hu.js      Found: 401   Missing: 1
+it.js      Found: 401   Missing: 1
+ja.js      Found: 401   Missing: 1
+km.js      Found: 376   Missing: 26
+ko.js      Found: 373   Missing: 29
+lt.js      Found: 381   Missing: 21
+lv.js      Found: 386   Missing: 16
+mn.js      Found: 230   Missing: 172
+ms.js      Found: 356   Missing: 46
+nb.js      Found: 400   Missing: 2
+nl.js      Found: 401   Missing: 1
+no.js      Found: 400   Missing: 2
+pl.js      Found: 386   Missing: 16
+pt-br.js   Found: 401   Missing: 1
+pt.js      Found: 386   Missing: 16
+ro.js      Found: 400   Missing: 2
+ru.js      Found: 401   Missing: 1
+sk.js      Found: 401   Missing: 1
+sl.js      Found: 378   Missing: 24
+sr-latn.js Found: 373   Missing: 29
+sr.js      Found: 373   Missing: 29
+sv.js      Found: 381   Missing: 21
+th.js      Found: 398   Missing: 4
+tr.js      Found: 401   Missing: 1
+uk.js      Found: 401   Missing: 1
+vi.js      Found: 401   Missing: 1
+zh-cn.js   Found: 401   Missing: 1
+zh.js      Found: 401   Missing: 1
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/_getfontformat.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/_getfontformat.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/_getfontformat.html	(revision 795)
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<html>
+	<head>
+		<title></title>
+	</head>
+	<script language="javascript">
+
+window.onload = function()
+{
+	var oRange = document.selection.createRange() ;
+
+	var sNormal ;
+	var sFormats = '' ;
+	for ( var i = 1 ; i <= 9 ; i++ )
+	{
+		oRange.moveToElementText( document.getElementById( 'x' + i ) ) ;
+		sFormats += oRange.queryCommandValue( 'FormatBlock' ) ;
+		if ( i == 1 )
+			sNormal = sFormats ;
+		sFormats += ';' ;
+	}
+
+	document.getElementById('xFontFormats').innerHTML = sFormats + sNormal + ' (DIV)' ;
+}
+	</script>
+	<body>
+		<table width="70%" align="center">
+			<tr>
+				<td>
+					<h3>FontFormats Localization</h3>
+					<p>
+						IE has some limits when handling the "Font Format". It actually uses localized
+						strings to retrieve the current format value. This makes it very difficult to
+						make a system that works on every single computer in the world.
+					</p>
+					<p>
+						With FCKeditor, this problem impacts in the "Format" toolbar command that
+						doesn't reflects the format of the current cursor position.
+					</p>
+					<p>
+						There is only one way to make it work. We must localize FCKeditor using the
+						strings used by IE. In this way, we will have the expected behavior at least
+						when using FCKeditor in the same language as the browser. So, when localizing
+						FCKeditor, go to a computer with IE in the target language, open this page and
+						use the following string to the "FontFormats" value:
+					</p>
+					<div style="white-space: nowrap">
+						FontFormats : "<span id="xFontFormats" style="COLOR: #000099"></span>",
+					</div>
+				</td>
+			</tr>
+		</table>
+		<div style="DISPLAY: none">
+			<p id="x1">&nbsp;</p>
+			<pre id="x2">&nbsp;</pre>
+			<address id="x3">&nbsp;</address>
+			<h1 id="x4">&nbsp;</h1>
+			<h2 id="x5">&nbsp;</h2>
+			<h3 id="x6">&nbsp;</h3>
+			<h4 id="x7">&nbsp;</h4>
+			<h5 id="x8">&nbsp;</h5>
+			<h6 id="x9">&nbsp;</h6>
+		</div>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fr.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fr.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fr.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * French language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Masquer Outils",
+ToolbarExpand		: "Afficher Outils",
+
+// Toolbar Items and Context Menu
+Save				: "Enregistrer",
+NewPage				: "Nouvelle page",
+Preview				: "Prévisualisation",
+Cut					: "Couper",
+Copy				: "Copier",
+Paste				: "Coller",
+PasteText			: "Coller comme texte",
+PasteWord			: "Coller de Word",
+Print				: "Imprimer",
+SelectAll			: "Tout sélectionner",
+RemoveFormat		: "Supprimer le format",
+InsertLinkLbl		: "Lien",
+InsertLink			: "Insérer/modifier le lien",
+RemoveLink			: "Supprimer le lien",
+Anchor				: "Insérer/modifier l'ancre",
+InsertImageLbl		: "Image",
+InsertImage			: "Insérer/modifier l'image",
+InsertFlashLbl		: "Animation Flash",
+InsertFlash			: "Insérer/modifier l'animation Flash",
+InsertTableLbl		: "Tableau",
+InsertTable			: "Insérer/modifier le tableau",
+InsertLineLbl		: "Séparateur",
+InsertLine			: "Insérer un séparateur",
+InsertSpecialCharLbl: "Caractères spéciaux",
+InsertSpecialChar	: "Insérer un caractère spécial",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Insérer un Smiley",
+About				: "A propos de FCKeditor",
+Bold				: "Gras",
+Italic				: "Italique",
+Underline			: "Souligné",
+StrikeThrough		: "Barré",
+Subscript			: "Indice",
+Superscript			: "Exposant",
+LeftJustify			: "Aligné à gauche",
+CenterJustify		: "Centré",
+RightJustify		: "Aligné à Droite",
+BlockJustify		: "Texte justifié",
+DecreaseIndent		: "Diminuer le retrait",
+IncreaseIndent		: "Augmenter le retrait",
+Undo				: "Annuler",
+Redo				: "Refaire",
+NumberedListLbl		: "Liste numérotée",
+NumberedList		: "Insérer/supprimer la liste numérotée",
+BulletedListLbl		: "Liste à puces",
+BulletedList		: "Insérer/supprimer la liste à puces",
+ShowTableBorders	: "Afficher les bordures du tableau",
+ShowDetails			: "Afficher les caractères invisibles",
+Style				: "Style",
+FontFormat			: "Format",
+Font				: "Police",
+FontSize			: "Taille",
+TextColor			: "Couleur de caractère",
+BGColor				: "Couleur de fond",
+Source				: "Source",
+Find				: "Chercher",
+Replace				: "Remplacer",
+SpellCheck			: "Orthographe",
+UniversalKeyboard	: "Clavier universel",
+PageBreakLbl		: "Saut de page",
+PageBreak			: "Insérer un saut de page",
+
+Form			: "Formulaire",
+Checkbox		: "Case à cocher",
+RadioButton		: "Bouton radio",
+TextField		: "Champ texte",
+Textarea		: "Zone de texte",
+HiddenField		: "Champ caché",
+Button			: "Bouton",
+SelectionField	: "Liste/menu",
+ImageButton		: "Bouton image",
+
+FitWindow		: "Edition pleine page",
+
+// Context Menu
+EditLink			: "Modifier le lien",
+CellCM				: "Cellule",
+RowCM				: "Ligne",
+ColumnCM			: "Colonne",
+InsertRow			: "Insérer une ligne",
+DeleteRows			: "Supprimer des lignes",
+InsertColumn		: "Insérer une colonne",
+DeleteColumns		: "Supprimer des colonnes",
+InsertCell			: "Insérer une cellule",
+DeleteCells			: "Supprimer des cellules",
+MergeCells			: "Fusionner les cellules",
+SplitCell			: "Scinder les cellules",
+TableDelete			: "Supprimer le tableau",
+CellProperties		: "Propriétés de cellule",
+TableProperties		: "Propriétés du tableau",
+ImageProperties		: "Propriétés de l'image",
+FlashProperties		: "Propriétés de l'animation Flash",
+
+AnchorProp			: "Propriétés de l'ancre",
+ButtonProp			: "Propriétés du bouton",
+CheckboxProp		: "Propriétés de la case à cocher",
+HiddenFieldProp		: "Propriétés du champ caché",
+RadioButtonProp		: "Propriétés du bouton radio",
+ImageButtonProp		: "Propriétés du bouton image",
+TextFieldProp		: "Propriétés du champ texte",
+SelectionFieldProp	: "Propriétés de la liste/du menu",
+TextareaProp		: "Propriétés de la zone de texte",
+FormProp			: "Propriétés du formulaire",
+
+FontFormats			: "Normal;Formaté;Adresse;En-tête 1;En-tête 2;En-tête 3;En-tête 4;En-tête 5;En-tête 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Calcul XHTML. Veuillez patienter...",
+Done				: "Terminé",
+PasteWordConfirm	: "Le texte à coller semble provenir de Word. Désirez-vous le nettoyer avant de coller?",
+NotCompatiblePaste	: "Cette commande nécessite Internet Explorer version 5.5 minimum. Souhaitez-vous coller sans nettoyage?",
+UnknownToolbarItem	: "Elément de barre d'outil inconnu \"%1\"",
+UnknownCommand		: "Nom de commande inconnu \"%1\"",
+NotImplemented		: "Commande non encore écrite",
+UnknownToolbarSet	: "La barre d'outils \"%1\" n'existe pas",
+NoActiveX			: "Les paramètres de sécurité de votre navigateur peuvent limiter quelques fonctionnalités de l'éditeur. Veuillez activer l'option \"Exécuter les contrôles ActiveX et les plug-ins\". Il se peut que vous rencontriez des erreurs et remarquiez quelques limitations.",
+BrowseServerBlocked : "Le navigateur n'a pas pu être ouvert. Assurez-vous que les bloqueurs de popups soient désactivés.",
+DialogBlocked		: "La fenêtre de dialogue n'a pas pu s'ouvrir. Assurez-vous que les bloqueurs de popups soient désactivés.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Annuler",
+DlgBtnClose			: "Fermer",
+DlgBtnBrowseServer	: "Parcourir le serveur",
+DlgAdvancedTag		: "Avancé",
+DlgOpOther			: "<Autre>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Veuillez saisir l'URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<Par défaut>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Sens d'écriture",
+DlgGenLangDirLtr	: "De gauche à droite (LTR)",
+DlgGenLangDirRtl	: "De droite à gauche (RTL)",
+DlgGenLangCode		: "Code langue",
+DlgGenAccessKey		: "Equivalent clavier",
+DlgGenName			: "Nom",
+DlgGenTabIndex		: "Ordre de tabulation",
+DlgGenLongDescr		: "URL de description longue",
+DlgGenClass			: "Classes de feuilles de style",
+DlgGenTitle			: "Titre",
+DlgGenContType		: "Type de contenu",
+DlgGenLinkCharset	: "Encodage de caractère",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Propriétés de l'image",
+DlgImgInfoTab		: "Informations sur l'image",
+DlgImgBtnUpload		: "Envoyer sur le serveur",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Télécharger",
+DlgImgAlt			: "Texte de remplacement",
+DlgImgWidth			: "Largeur",
+DlgImgHeight		: "Hauteur",
+DlgImgLockRatio		: "Garder les proportions",
+DlgBtnResetSize		: "Taille originale",
+DlgImgBorder		: "Bordure",
+DlgImgHSpace		: "Espacement horizontal",
+DlgImgVSpace		: "Espacement vertical",
+DlgImgAlign			: "Alignement",
+DlgImgAlignLeft		: "Gauche",
+DlgImgAlignAbsBottom: "Abs Bas",
+DlgImgAlignAbsMiddle: "Abs Milieu",
+DlgImgAlignBaseline	: "Bas du texte",
+DlgImgAlignBottom	: "Bas",
+DlgImgAlignMiddle	: "Milieu",
+DlgImgAlignRight	: "Droite",
+DlgImgAlignTextTop	: "Haut du texte",
+DlgImgAlignTop		: "Haut",
+DlgImgPreview		: "Prévisualisation",
+DlgImgAlertUrl		: "Veuillez saisir l'URL de l'image",
+DlgImgLinkTab		: "Lien",
+
+// Flash Dialog
+DlgFlashTitle		: "Propriétés de l'animation Flash",
+DlgFlashChkPlay		: "Lecture automatique",
+DlgFlashChkLoop		: "Boucle",
+DlgFlashChkMenu		: "Activer le menu Flash",
+DlgFlashScale		: "Affichage",
+DlgFlashScaleAll	: "Par défaut (tout montrer)",
+DlgFlashScaleNoBorder	: "Sans bordure",
+DlgFlashScaleFit	: "Ajuster aux dimensions",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Propriétés du lien",
+DlgLnkInfoTab		: "Informations sur le lien",
+DlgLnkTargetTab		: "Destination",
+
+DlgLnkType			: "Type de lien",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Ancre dans cette page",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocole",
+DlgLnkProtoOther	: "<autre>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Sélectionner une ancre",
+DlgLnkAnchorByName	: "Par nom",
+DlgLnkAnchorById	: "Par id",
+DlgLnkNoAnchors		: "<Pas d'ancre disponible dans le document>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Adresse E-Mail",
+DlgLnkEMailSubject	: "Sujet du message",
+DlgLnkEMailBody		: "Corps du message",
+DlgLnkUpload		: "Télécharger",
+DlgLnkBtnUpload		: "Envoyer sur le serveur",
+
+DlgLnkTarget		: "Destination",
+DlgLnkTargetFrame	: "<cadre>",
+DlgLnkTargetPopup	: "<fenêtre popup>",
+DlgLnkTargetBlank	: "Nouvelle fenêtre (_blank)",
+DlgLnkTargetParent	: "Fenêtre mère (_parent)",
+DlgLnkTargetSelf	: "Même fenêtre (_self)",
+DlgLnkTargetTop		: "Fenêtre supérieure (_top)",
+DlgLnkTargetFrameName	: "Nom du cadre de destination",
+DlgLnkPopWinName	: "Nom de la fenêtre popup",
+DlgLnkPopWinFeat	: "Caractéristiques de la fenêtre popup",
+DlgLnkPopResize		: "Taille modifiable",
+DlgLnkPopLocation	: "Barre d'adresses",
+DlgLnkPopMenu		: "Barre de menu",
+DlgLnkPopScroll		: "Barres de défilement",
+DlgLnkPopStatus		: "Barre d'état",
+DlgLnkPopToolbar	: "Barre d'outils",
+DlgLnkPopFullScrn	: "Plein écran (IE)",
+DlgLnkPopDependent	: "Dépendante (Netscape)",
+DlgLnkPopWidth		: "Largeur",
+DlgLnkPopHeight		: "Hauteur",
+DlgLnkPopLeft		: "Position à partir de la gauche",
+DlgLnkPopTop		: "Position à partir du haut",
+
+DlnLnkMsgNoUrl		: "Veuillez saisir l'URL",
+DlnLnkMsgNoEMail	: "Veuillez saisir l'adresse e-mail",
+DlnLnkMsgNoAnchor	: "Veuillez sélectionner une ancre",
+DlnLnkMsgInvPopName	: "Le nom de la fenêtre popup doit commencer par une lettre et ne doit pas contenir d'espace",
+
+// Color Dialog
+DlgColorTitle		: "Sélectionner",
+DlgColorBtnClear	: "Effacer",
+DlgColorHighlight	: "Prévisualisation",
+DlgColorSelected	: "Sélectionné",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insérer un Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Insérer un caractère spécial",
+
+// Table Dialog
+DlgTableTitle		: "Propriétés du tableau",
+DlgTableRows		: "Lignes",
+DlgTableColumns		: "Colonnes",
+DlgTableBorder		: "Bordure",
+DlgTableAlign		: "Alignement",
+DlgTableAlignNotSet	: "<Par défaut>",
+DlgTableAlignLeft	: "Gauche",
+DlgTableAlignCenter	: "Centré",
+DlgTableAlignRight	: "Droite",
+DlgTableWidth		: "Largeur",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "pourcentage",
+DlgTableHeight		: "Hauteur",
+DlgTableCellSpace	: "Espacement",
+DlgTableCellPad		: "Contour",
+DlgTableCaption		: "Titre",
+DlgTableSummary		: "Résumé",
+
+// Table Cell Dialog
+DlgCellTitle		: "Propriétés de la cellule",
+DlgCellWidth		: "Largeur",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "pourcentage",
+DlgCellHeight		: "Hauteur",
+DlgCellWordWrap		: "Retour à la ligne",
+DlgCellWordWrapNotSet	: "<Par défaut>",
+DlgCellWordWrapYes	: "Oui",
+DlgCellWordWrapNo	: "Non",
+DlgCellHorAlign		: "Alignement horizontal",
+DlgCellHorAlignNotSet	: "<Par défaut>",
+DlgCellHorAlignLeft	: "Gauche",
+DlgCellHorAlignCenter	: "Centré",
+DlgCellHorAlignRight: "Droite",
+DlgCellVerAlign		: "Alignement vertical",
+DlgCellVerAlignNotSet	: "<Par défaut>",
+DlgCellVerAlignTop	: "Haut",
+DlgCellVerAlignMiddle	: "Milieu",
+DlgCellVerAlignBottom	: "Bas",
+DlgCellVerAlignBaseline	: "Bas du texte",
+DlgCellRowSpan		: "Lignes fusionnées",
+DlgCellCollSpan		: "Colonnes fusionnées",
+DlgCellBackColor	: "Fond",
+DlgCellBorderColor	: "Bordure",
+DlgCellBtnSelect	: "Choisir...",
+
+// Find Dialog
+DlgFindTitle		: "Chercher",
+DlgFindFindBtn		: "Chercher",
+DlgFindNotFoundMsg	: "Le texte indiqué est introuvable.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Remplacer",
+DlgReplaceFindLbl		: "Rechercher:",
+DlgReplaceReplaceLbl	: "Remplacer par:",
+DlgReplaceCaseChk		: "Respecter la casse",
+DlgReplaceReplaceBtn	: "Remplacer",
+DlgReplaceReplAllBtn	: "Tout remplacer",
+DlgReplaceWordChk		: "Mot entier",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Les paramètres de sécurité de votre navigateur empêchent l'éditeur de couper automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl+X).",
+PasteErrorCopy	: "Les paramètres de sécurité de votre navigateur empêchent l'éditeur de copier automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl+C).",
+
+PasteAsText		: "Coller comme texte",
+PasteFromWord	: "Coller à partir de Word",
+
+DlgPasteMsg2	: "Veuillez coller dans la zone ci-dessous en utilisant le clavier (<STRONG>Ctrl+V</STRONG>) et cliquez sur <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorer les polices de caractères",
+DlgPasteRemoveStyles	: "Supprimer les styles",
+DlgPasteCleanBox		: "Effacer le contenu",
+
+// Color Picker
+ColorAutomatic	: "Automatique",
+ColorMoreColors	: "Plus de couleurs...",
+
+// Document Properties
+DocProps		: "Propriétés du document",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Propriétés de l'ancre",
+DlgAnchorName		: "Nom de l'ancre",
+DlgAnchorErrorName	: "Veuillez saisir le nom de l'ancre",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Pas dans le dictionnaire",
+DlgSpellChangeTo		: "Changer en",
+DlgSpellBtnIgnore		: "Ignorer",
+DlgSpellBtnIgnoreAll	: "Ignorer tout",
+DlgSpellBtnReplace		: "Remplacer",
+DlgSpellBtnReplaceAll	: "Remplacer tout",
+DlgSpellBtnUndo			: "Annuler",
+DlgSpellNoSuggestions	: "- Aucune suggestion -",
+DlgSpellProgress		: "Vérification d'orthographe en cours...",
+DlgSpellNoMispell		: "Vérification d'orthographe terminée: Aucune erreur trouvée",
+DlgSpellNoChanges		: "Vérification d'orthographe terminée: Pas de modifications",
+DlgSpellOneChange		: "Vérification d'orthographe terminée: Un mot modifié",
+DlgSpellManyChanges		: "Vérification d'orthographe terminée: %1 mots modifiés",
+
+IeSpellDownload			: "Le Correcteur n'est pas installé. Souhaitez-vous le télécharger maintenant?",
+
+// Button Dialog
+DlgButtonText		: "Texte (valeur)",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Bouton",
+DlgButtonTypeSbm	: "Envoyer",
+DlgButtonTypeRst	: "Réinitialiser",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nom",
+DlgCheckboxValue	: "Valeur",
+DlgCheckboxSelected	: "Sélectionné",
+
+// Form Dialog
+DlgFormName		: "Nom",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Méthode",
+
+// Select Field Dialog
+DlgSelectName		: "Nom",
+DlgSelectValue		: "Valeur",
+DlgSelectSize		: "Taille",
+DlgSelectLines		: "lignes",
+DlgSelectChkMulti	: "Sélection multiple",
+DlgSelectOpAvail	: "Options disponibles",
+DlgSelectOpText		: "Texte",
+DlgSelectOpValue	: "Valeur",
+DlgSelectBtnAdd		: "Ajouter",
+DlgSelectBtnModify	: "Modifier",
+DlgSelectBtnUp		: "Monter",
+DlgSelectBtnDown	: "Descendre",
+DlgSelectBtnSetValue : "Valeur sélectionnée",
+DlgSelectBtnDelete	: "Supprimer",
+
+// Textarea Dialog
+DlgTextareaName	: "Nom",
+DlgTextareaCols	: "Colonnes",
+DlgTextareaRows	: "Lignes",
+
+// Text Field Dialog
+DlgTextName			: "Nom",
+DlgTextValue		: "Valeur",
+DlgTextCharWidth	: "Largeur en caractères",
+DlgTextMaxChars		: "Nombre maximum de caractères",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Texte",
+DlgTextTypePass		: "Mot de passe",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nom",
+DlgHiddenValue	: "Valeur",
+
+// Bulleted List Dialog
+BulletedListProp	: "Propriétés de liste à puces",
+NumberedListProp	: "Propriétés de liste numérotée",
+DlgLstStart			: "Début",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Cercle",
+DlgLstTypeDisc		: "Disque",
+DlgLstTypeSquare	: "Carré",
+DlgLstTypeNumbers	: "Nombres (1, 2, 3)",
+DlgLstTypeLCase		: "Lettres minuscules (a, b, c)",
+DlgLstTypeUCase		: "Lettres majuscules (A, B, C)",
+DlgLstTypeSRoman	: "Chiffres romains minuscules (i, ii, iii)",
+DlgLstTypeLRoman	: "Chiffres romains majuscules (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Général",
+DlgDocBackTab		: "Fond",
+DlgDocColorsTab		: "Couleurs et marges",
+DlgDocMetaTab		: "Métadonnées",
+
+DlgDocPageTitle		: "Titre de la page",
+DlgDocLangDir		: "Sens d'écriture",
+DlgDocLangDirLTR	: "De la gauche vers la droite (LTR)",
+DlgDocLangDirRTL	: "De la droite vers la gauche (RTL)",
+DlgDocLangCode		: "Code langue",
+DlgDocCharSet		: "Encodage de caractère",
+DlgDocCharSetCE		: "Europe Centrale",
+DlgDocCharSetCT		: "Chinois Traditionnel (Big5)",
+DlgDocCharSetCR		: "Cyrillique",
+DlgDocCharSetGR		: "Grec",
+DlgDocCharSetJP		: "Japanais",
+DlgDocCharSetKR		: "Coréen",
+DlgDocCharSetTR		: "Turc",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Occidental",
+DlgDocCharSetOther	: "Autre encodage de caractère",
+
+DlgDocDocType		: "Type de document",
+DlgDocDocTypeOther	: "Autre type de document",
+DlgDocIncXHTML		: "Inclure les déclarations XHTML",
+DlgDocBgColor		: "Couleur de fond",
+DlgDocBgImage		: "Image de fond",
+DlgDocBgNoScroll	: "Image fixe sans défilement",
+DlgDocCText			: "Texte",
+DlgDocCLink			: "Lien",
+DlgDocCVisited		: "Lien visité",
+DlgDocCActive		: "Lien activé",
+DlgDocMargins		: "Marges",
+DlgDocMaTop			: "Haut",
+DlgDocMaLeft		: "Gauche",
+DlgDocMaRight		: "Droite",
+DlgDocMaBottom		: "Bas",
+DlgDocMeIndex		: "Mots-clés (séparés par des virgules)",
+DlgDocMeDescr		: "Description",
+DlgDocMeAuthor		: "Auteur",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Prévisualisation",
+
+// Templates Dialog
+Templates			: "Modèles",
+DlgTemplatesTitle	: "Modèles de contenu",
+DlgTemplatesSelMsg	: "Veuillez sélectionner le modèle à ouvrir dans l'éditeur<br>(le contenu actuel sera remplacé):",
+DlgTemplatesLoading	: "Chargement de la liste des modèles. Veuillez patienter...",
+DlgTemplatesNoTpl	: "(Aucun modèle disponible)",
+DlgTemplatesReplace	: "Remplacer tout le contenu",
+
+// About Dialog
+DlgAboutAboutTab	: "A propos de",
+DlgAboutBrowserInfoTab	: "Navigateur",
+DlgAboutLicenseTab	: "License",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "Pour plus d'informations, aller à"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/et.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/et.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/et.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Estonian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Voldi tööriistariba",
+ToolbarExpand		: "Laienda tööriistariba",
+
+// Toolbar Items and Context Menu
+Save				: "Salvesta",
+NewPage				: "Uus leht",
+Preview				: "Eelvaade",
+Cut					: "Lõika",
+Copy				: "Kopeeri",
+Paste				: "Kleebi",
+PasteText			: "Kleebi tavalise tekstina",
+PasteWord			: "Kleebi Wordist",
+Print				: "Prindi",
+SelectAll			: "Vali kõik",
+RemoveFormat		: "Eemalda vorming",
+InsertLinkLbl		: "Link",
+InsertLink			: "Sisesta/Muuda link",
+RemoveLink			: "Eemalda link",
+Anchor				: "Sisesta/Muuda ankur",
+InsertImageLbl		: "Pilt",
+InsertImage			: "Sisesta/Muuda pilt",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Sisesta/Muuda flash",
+InsertTableLbl		: "Tabel",
+InsertTable			: "Sisesta/Muuda tabel",
+InsertLineLbl		: "Joon",
+InsertLine			: "Sisesta horisontaaljoon",
+InsertSpecialCharLbl: "Erimärgid",
+InsertSpecialChar	: "Sisesta erimärk",
+InsertSmileyLbl		: "Emotikon",
+InsertSmiley		: "Sisesta emotikon",
+About				: "FCKeditor teave",
+Bold				: "Rasvane kiri",
+Italic				: "Kursiiv kiri",
+Underline			: "Allajoonitud kiri",
+StrikeThrough		: "Läbijoonitud kiri",
+Subscript			: "Allindeks",
+Superscript			: "Ülaindeks",
+LeftJustify			: "Vasakjoondus",
+CenterJustify		: "Keskjoondus",
+RightJustify		: "Paremjoondus",
+BlockJustify		: "Rööpjoondus",
+DecreaseIndent		: "Vähenda taanet",
+IncreaseIndent		: "Suurenda taanet",
+Undo				: "Võta tagasi",
+Redo				: "Korda toimingut",
+NumberedListLbl		: "Nummerdatud loetelu",
+NumberedList		: "Sisesta/Eemalda nummerdatud loetelu",
+BulletedListLbl		: "Punktiseeritud loetelu",
+BulletedList		: "Sisesta/Eemalda punktiseeritud loetelu",
+ShowTableBorders	: "Näita tabeli jooni",
+ShowDetails			: "Näita üksikasju",
+Style				: "Laad",
+FontFormat			: "Vorming",
+Font				: "Kiri",
+FontSize			: "Suurus",
+TextColor			: "Teksti värv",
+BGColor				: "Tausta värv",
+Source				: "Lähtekood",
+Find				: "Otsi",
+Replace				: "Asenda",
+SpellCheck			: "Kontrolli õigekirja",
+UniversalKeyboard	: "Universaalne klaviatuur",
+PageBreakLbl		: "Lehepiir",
+PageBreak			: "Sisesta lehevahetus koht",
+
+Form			: "Vorm",
+Checkbox		: "Märkeruut",
+RadioButton		: "Raadionupp",
+TextField		: "Tekstilahter",
+Textarea		: "Tekstiala",
+HiddenField		: "Varjatud lahter",
+Button			: "Nupp",
+SelectionField	: "Valiklahter",
+ImageButton		: "Piltnupp",
+
+FitWindow		: "Maksimeeri redaktori mõõtmed",
+
+// Context Menu
+EditLink			: "Muuda linki",
+CellCM				: "Lahter",
+RowCM				: "Rida",
+ColumnCM			: "Veerg",
+InsertRow			: "Lisa rida",
+DeleteRows			: "Eemalda ridu",
+InsertColumn		: "Lisa veerg",
+DeleteColumns		: "Eemalda veerud",
+InsertCell			: "Lisa lahter",
+DeleteCells			: "Eemalda lahtrid",
+MergeCells			: "Ühenda lahtrid",
+SplitCell			: "Lahuta lahtrid",
+TableDelete			: "Kustuta tabel",
+CellProperties		: "Lahtri atribuudid",
+TableProperties		: "Tabeli atribuudid",
+ImageProperties		: "Pildi  atribuudid",
+FlashProperties		: "Flash omadused",
+
+AnchorProp			: "Ankru omadused",
+ButtonProp			: "Nupu omadused",
+CheckboxProp		: "Märkeruudu omadused",
+HiddenFieldProp		: "Varjatud lahtri omadused",
+RadioButtonProp		: "Raadionupu omadused",
+ImageButtonProp		: "Piltnupu omadused",
+TextFieldProp		: "Tekstilahtri omadused",
+SelectionFieldProp	: "Valiklahtri omadused",
+TextareaProp		: "Tekstiala omadused",
+FormProp			: "Vormi omadused",
+
+FontFormats			: "Tavaline;Vormindatud;Aadress;Pealkiri 1;Pealkiri 2;Pealkiri 3;Pealkiri 4;Pealkiri 5;Pealkiri 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Töötlen XHTML. Palun oota...",
+Done				: "Tehtud",
+PasteWordConfirm	: "Tekst, mida soovid lisada paistab pärinevat Wordist. Kas soovid seda enne kleepimist puhastada?",
+NotCompatiblePaste	: "See käsk on saadaval ainult Internet Explorer versioon 5.5 või uuema puhul. Kas soovid kleepida ilma puhastamata?",
+UnknownToolbarItem	: "Tundmatu tööriistariba üksus \"%1\"",
+UnknownCommand		: "Tundmatu käsunimi \"%1\"",
+NotImplemented		: "Käsku ei täidetud",
+UnknownToolbarSet	: "Tööriistariba \"%1\" ei eksisteeri",
+NoActiveX			: "Sinu interneti sirvija turvalisuse seaded võivad limiteerida mõningaid tekstirdaktori kasutus võimalusi. Sa peaksid võimaldama valiku \"Run ActiveX controls and plug-ins\" oma sirvija seadetes. Muidu võid sa täheldada vigu tekstiredaktori töös ja märgata puuduvaid funktsioone.",
+BrowseServerBlocked : "Ressursside sirvija avamine ebaõnnestus. Võimalda pop-up akende avanemine.",
+DialogBlocked		: "Ei olenud võimalik avada dialoogi akent. Võimalda pop-up akende avanemine.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Loobu",
+DlgBtnClose			: "Sulge",
+DlgBtnBrowseServer	: "Sirvi serverit",
+DlgAdvancedTag		: "Täpsemalt",
+DlgOpOther			: "<Teine>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Palun sisesta URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<määramata>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Keele suund",
+DlgGenLangDirLtr	: "Vasakult paremale (LTR)",
+DlgGenLangDirRtl	: "Paremalt vasakule (RTL)",
+DlgGenLangCode		: "Keele kood",
+DlgGenAccessKey		: "Juurdepääsu võti",
+DlgGenName			: "Nimi",
+DlgGenTabIndex		: "Tab indeks",
+DlgGenLongDescr		: "Pikk kirjeldus URL",
+DlgGenClass			: "Stiilistiku klassid",
+DlgGenTitle			: "Juhendav tiitel",
+DlgGenContType		: "Juhendava sisu tüüp",
+DlgGenLinkCharset	: "Lingitud ressurssi märgistik",
+DlgGenStyle			: "Laad",
+
+// Image Dialog
+DlgImgTitle			: "Pildi atribuudid",
+DlgImgInfoTab		: "Pildi info",
+DlgImgBtnUpload		: "Saada serverissee",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Lae üles",
+DlgImgAlt			: "Alternatiivne tekst",
+DlgImgWidth			: "Laius",
+DlgImgHeight		: "Kõrgus",
+DlgImgLockRatio		: "Lukusta kuvasuhe",
+DlgBtnResetSize		: "Lähtesta suurus",
+DlgImgBorder		: "Joon",
+DlgImgHSpace		: "H. vaheruum",
+DlgImgVSpace		: "V. vaheruum",
+DlgImgAlign			: "Joondus",
+DlgImgAlignLeft		: "Vasak",
+DlgImgAlignAbsBottom: "Abs alla",
+DlgImgAlignAbsMiddle: "Abs keskele",
+DlgImgAlignBaseline	: "Baasjoonele",
+DlgImgAlignBottom	: "Alla",
+DlgImgAlignMiddle	: "Keskele",
+DlgImgAlignRight	: "Paremale",
+DlgImgAlignTextTop	: "Tekstit üles",
+DlgImgAlignTop		: "Üles",
+DlgImgPreview		: "Eelvaade",
+DlgImgAlertUrl		: "Palun kirjuta pildi URL",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash omadused",
+DlgFlashChkPlay		: "Automaatne start ",
+DlgFlashChkLoop		: "Korduv",
+DlgFlashChkMenu		: "Võimalda flash menüü",
+DlgFlashScale		: "Mastaap",
+DlgFlashScaleAll	: "Näita kõike",
+DlgFlashScaleNoBorder	: "Äärist ei ole",
+DlgFlashScaleFit	: "Täpne sobivus",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Lingi info",
+DlgLnkTargetTab		: "Sihtkoht",
+
+DlgLnkType			: "Lingi tüüp",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Ankur sellel lehel",
+DlgLnkTypeEMail		: "E-post",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<muu>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Vali ankur",
+DlgLnkAnchorByName	: "Ankru nime järgi",
+DlgLnkAnchorById	: "Elemendi id järgi",
+DlgLnkNoAnchors		: "<Selles dokumendis ei ole ankruid>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-posti aadress",
+DlgLnkEMailSubject	: "Sõnumi teema",
+DlgLnkEMailBody		: "Sõnumi tekst",
+DlgLnkUpload		: "Lae üles",
+DlgLnkBtnUpload		: "Saada serverisse",
+
+DlgLnkTarget		: "Sihtkoht",
+DlgLnkTargetFrame	: "<raam>",
+DlgLnkTargetPopup	: "<hüpikaken>",
+DlgLnkTargetBlank	: "Uus aken (_blank)",
+DlgLnkTargetParent	: "Vanem aken (_parent)",
+DlgLnkTargetSelf	: "Sama aken (_self)",
+DlgLnkTargetTop		: "Pealmine aken (_top)",
+DlgLnkTargetFrameName	: "Sihtmärk raami nimi",
+DlgLnkPopWinName	: "Hüpikakna nimi",
+DlgLnkPopWinFeat	: "Hüpikakna omadused",
+DlgLnkPopResize		: "Suurendatav",
+DlgLnkPopLocation	: "Aadressiriba",
+DlgLnkPopMenu		: "Menüüriba",
+DlgLnkPopScroll		: "Kerimisribad",
+DlgLnkPopStatus		: "Olekuriba",
+DlgLnkPopToolbar	: "Tööriistariba",
+DlgLnkPopFullScrn	: "Täisekraan (IE)",
+DlgLnkPopDependent	: "Sõltuv (Netscape)",
+DlgLnkPopWidth		: "Laius",
+DlgLnkPopHeight		: "Kõrgus",
+DlgLnkPopLeft		: "Vasak asukoht",
+DlgLnkPopTop		: "Ülemine asukoht",
+
+DlnLnkMsgNoUrl		: "Palun kirjuta lingi URL",
+DlnLnkMsgNoEMail	: "Palun kirjuta E-Posti aadress",
+DlnLnkMsgNoAnchor	: "Palun vali ankur",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Vali värv",
+DlgColorBtnClear	: "Tühjenda",
+DlgColorHighlight	: "Märgi",
+DlgColorSelected	: "Valitud",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Sisesta emotikon",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Vali erimärk",
+
+// Table Dialog
+DlgTableTitle		: "Tabeli atribuudid",
+DlgTableRows		: "Read",
+DlgTableColumns		: "Veerud",
+DlgTableBorder		: "Joone suurus",
+DlgTableAlign		: "Joondus",
+DlgTableAlignNotSet	: "<Määramata>",
+DlgTableAlignLeft	: "Vasak",
+DlgTableAlignCenter	: "Kesk",
+DlgTableAlignRight	: "Parem",
+DlgTableWidth		: "Laius",
+DlgTableWidthPx		: "pikslit",
+DlgTableWidthPc		: "protsenti",
+DlgTableHeight		: "Kõrgus",
+DlgTableCellSpace	: "Lahtri vahe",
+DlgTableCellPad		: "Lahtri täidis",
+DlgTableCaption		: "Tabeli tiitel",
+DlgTableSummary		: "Kokkuvõte",
+
+// Table Cell Dialog
+DlgCellTitle		: "Lahtri atribuudid",
+DlgCellWidth		: "Laius",
+DlgCellWidthPx		: "pikslit",
+DlgCellWidthPc		: "protsenti",
+DlgCellHeight		: "Kõrgus",
+DlgCellWordWrap		: "Sõna ülekanne",
+DlgCellWordWrapNotSet	: "<Määramata>",
+DlgCellWordWrapYes	: "Jah",
+DlgCellWordWrapNo	: "Ei",
+DlgCellHorAlign		: "Horisontaaljoondus",
+DlgCellHorAlignNotSet	: "<Määramata>",
+DlgCellHorAlignLeft	: "Vasak",
+DlgCellHorAlignCenter	: "Kesk",
+DlgCellHorAlignRight: "Parem",
+DlgCellVerAlign		: "Vertikaaljoondus",
+DlgCellVerAlignNotSet	: "<Määramata>",
+DlgCellVerAlignTop	: "Üles",
+DlgCellVerAlignMiddle	: "Keskele",
+DlgCellVerAlignBottom	: "Alla",
+DlgCellVerAlignBaseline	: "Baasjoonele",
+DlgCellRowSpan		: "Reaulatus",
+DlgCellCollSpan		: "Veeruulatus",
+DlgCellBackColor	: "Tausta värv",
+DlgCellBorderColor	: "Joone värv",
+DlgCellBtnSelect	: "Vali...",
+
+// Find Dialog
+DlgFindTitle		: "Otsi",
+DlgFindFindBtn		: "Otsi",
+DlgFindNotFoundMsg	: "Valitud teksti ei leitud.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Asenda",
+DlgReplaceFindLbl		: "Leia mida:",
+DlgReplaceReplaceLbl	: "Asenda millega:",
+DlgReplaceCaseChk		: "Erista suur- ja väiketähti",
+DlgReplaceReplaceBtn	: "Asenda",
+DlgReplaceReplAllBtn	: "Asenda kõik",
+DlgReplaceWordChk		: "Otsi terviklike sõnu",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Sinu interneti sirvija turvaseaded ei luba redaktoril automaatselt lõigata. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl+X).",
+PasteErrorCopy	: "Sinu interneti sirvija turvaseaded ei luba redaktoril automaatselt kopeerida. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl+C).",
+
+PasteAsText		: "Kleebi tavalise tekstina",
+PasteFromWord	: "Kleebi Wordist",
+
+DlgPasteMsg2	: "Palun kleebi järgnevasse kasti kasutades klaviatuuri klahvikombinatsiooni (<STRONG>Ctrl+V</STRONG>) ja vajuta seejärel <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoreeri kirja definitsioone",
+DlgPasteRemoveStyles	: "Eemalda stiilide definitsioonid",
+DlgPasteCleanBox		: "Puhasta ära kast",
+
+// Color Picker
+ColorAutomatic	: "Automaatne",
+ColorMoreColors	: "Rohkem värve...",
+
+// Document Properties
+DocProps		: "Dokumendi omadused",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ankru omadused",
+DlgAnchorName		: "Ankru nimi",
+DlgAnchorErrorName	: "Palun sisest ankru nimi",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Puudub sõnastikust",
+DlgSpellChangeTo		: "Muuda",
+DlgSpellBtnIgnore		: "Ignoreeri",
+DlgSpellBtnIgnoreAll	: "Ignoreeri kõiki",
+DlgSpellBtnReplace		: "Asenda",
+DlgSpellBtnReplaceAll	: "Asenda kõik",
+DlgSpellBtnUndo			: "Võta tagasi",
+DlgSpellNoSuggestions	: "- Soovitused puuduvad -",
+DlgSpellProgress		: "Toimub õigekirja kontroll...",
+DlgSpellNoMispell		: "Õigekirja kontroll sooritatud: õigekirjuvigu ei leitud",
+DlgSpellNoChanges		: "Õigekirja kontroll sooritatud: ühtegi sõna ei muudetud",
+DlgSpellOneChange		: "Õigekirja kontroll sooritatud: üks sõna muudeti",
+DlgSpellManyChanges		: "Õigekirja kontroll sooritatud: %1 sõna muudetud",
+
+IeSpellDownload			: "Õigekirja kontrollija ei ole installeeritud. Soovid sa selle alla laadida?",
+
+// Button Dialog
+DlgButtonText		: "Tekst (väärtus)",
+DlgButtonType		: "Tüüp",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nimi",
+DlgCheckboxValue	: "Väärtus",
+DlgCheckboxSelected	: "Valitud",
+
+// Form Dialog
+DlgFormName		: "Nimi",
+DlgFormAction	: "Toiming",
+DlgFormMethod	: "Meetod",
+
+// Select Field Dialog
+DlgSelectName		: "Nimi",
+DlgSelectValue		: "Väärtus",
+DlgSelectSize		: "Suurus",
+DlgSelectLines		: "ridu",
+DlgSelectChkMulti	: "Võimalda mitu valikut",
+DlgSelectOpAvail	: "Võimalikud valikud",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Väärtus",
+DlgSelectBtnAdd		: "Lisa",
+DlgSelectBtnModify	: "Muuda",
+DlgSelectBtnUp		: "Üles",
+DlgSelectBtnDown	: "Alla",
+DlgSelectBtnSetValue : "Sea valitud olekuna",
+DlgSelectBtnDelete	: "Kustuta",
+
+// Textarea Dialog
+DlgTextareaName	: "Nimi",
+DlgTextareaCols	: "Veerge",
+DlgTextareaRows	: "Ridu",
+
+// Text Field Dialog
+DlgTextName			: "Nimi",
+DlgTextValue		: "Väärtus",
+DlgTextCharWidth	: "Laius (tähemärkides)",
+DlgTextMaxChars		: "Maksimaalselt tähemärke",
+DlgTextType			: "Tüüp",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Parool",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nimi",
+DlgHiddenValue	: "Väärtus",
+
+// Bulleted List Dialog
+BulletedListProp	: "Täpitud loetelu omadused",
+NumberedListProp	: "Nummerdatud loetelu omadused",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tüüp",
+DlgLstTypeCircle	: "Ring",
+DlgLstTypeDisc		: "Ketas",
+DlgLstTypeSquare	: "Ruut",
+DlgLstTypeNumbers	: "Numbrid (1, 2, 3)",
+DlgLstTypeLCase		: "Väiketähed (a, b, c)",
+DlgLstTypeUCase		: "Suurtähed (A, B, C)",
+DlgLstTypeSRoman	: "Väiksed Rooma numbrid (i, ii, iii)",
+DlgLstTypeLRoman	: "Suured Rooma numbrid (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Üldine",
+DlgDocBackTab		: "Taust",
+DlgDocColorsTab		: "Värvid ja veerised",
+DlgDocMetaTab		: "Meta andmed",
+
+DlgDocPageTitle		: "Lehekülje tiitel",
+DlgDocLangDir		: "Kirja suund",
+DlgDocLangDirLTR	: "Vasakult paremale (LTR)",
+DlgDocLangDirRTL	: "Paremalt vasakule (RTL)",
+DlgDocLangCode		: "Keele kood",
+DlgDocCharSet		: "Märgistiku kodeering",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Ülejäänud märgistike kodeeringud",
+
+DlgDocDocType		: "Dokumendi tüüppäis",
+DlgDocDocTypeOther	: "Teised dokumendi tüüppäised",
+DlgDocIncXHTML		: "Arva kaasa XHTML deklaratsioonid",
+DlgDocBgColor		: "Taustavärv",
+DlgDocBgImage		: "Taustapildi URL",
+DlgDocBgNoScroll	: "Mittekeritav tagataust",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Külastatud link",
+DlgDocCActive		: "Aktiivne link",
+DlgDocMargins		: "Lehekülje äärised",
+DlgDocMaTop			: "Ülaserv",
+DlgDocMaLeft		: "Vasakserv",
+DlgDocMaRight		: "Paremserv",
+DlgDocMaBottom		: "Alaserv",
+DlgDocMeIndex		: "Dokumendi võtmesõnad (eraldatud komadega)",
+DlgDocMeDescr		: "Dokumendi kirjeldus",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Autoriõigus",
+DlgDocPreview		: "Eelvaade",
+
+// Templates Dialog
+Templates			: "Šabloon",
+DlgTemplatesTitle	: "Sisu šabloonid",
+DlgTemplatesSelMsg	: "Palun vali šabloon, et avada see redaktoris<br />(praegune sisu läheb kaotsi):",
+DlgTemplatesLoading	: "Laen šabloonide nimekirja. Palun oota...",
+DlgTemplatesNoTpl	: "(Ühtegi šablooni ei ole defineeritud)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Teave",
+DlgAboutBrowserInfoTab	: "Interneti sirvija info",
+DlgAboutLicenseTab	: "Litsents",
+DlgAboutVersion		: "versioon",
+DlgAboutInfo		: "Täpsema info saamiseks mine"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/nl.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/nl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/nl.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Dutch language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Menubalk inklappen",
+ToolbarExpand		: "Menubalk uitklappen",
+
+// Toolbar Items and Context Menu
+Save				: "Opslaan",
+NewPage				: "Nieuwe pagina",
+Preview				: "Voorbeeld",
+Cut					: "Knippen",
+Copy				: "Kopiëren",
+Paste				: "Plakken",
+PasteText			: "Plakken als platte tekst",
+PasteWord			: "Plakken als Word-gegevens",
+Print				: "Printen",
+SelectAll			: "Alles selecteren",
+RemoveFormat		: "Opmaak verwijderen",
+InsertLinkLbl		: "Link",
+InsertLink			: "Link invoegen/wijzigen",
+RemoveLink			: "Link verwijderen",
+Anchor				: "Interne link",
+InsertImageLbl		: "Afbeelding",
+InsertImage			: "Afbeelding invoegen/wijzigen",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Flash invoegen/wijzigen",
+InsertTableLbl		: "Tabel",
+InsertTable			: "Tabel invoegen/wijzigen",
+InsertLineLbl		: "Lijn",
+InsertLine			: "Invoegen horizontale lijn",
+InsertSpecialCharLbl: "Speciale tekens",
+InsertSpecialChar	: "Speciaal teken invoegen",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Smiley invoegen",
+About				: "Over FCKeditor",
+Bold				: "Vet",
+Italic				: "Schuingedrukt",
+Underline			: "Onderstreept",
+StrikeThrough		: "Doorhalen",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Links uitlijnen",
+CenterJustify		: "Centreren",
+RightJustify		: "Rechts uitlijnen",
+BlockJustify		: "Uitvullen",
+DecreaseIndent		: "Inspringen verkleinen",
+IncreaseIndent		: "Inspringen vergroten",
+Undo				: "Ongedaan maken",
+Redo				: "Opnieuw uitvoeren",
+NumberedListLbl		: "Genummerde lijst",
+NumberedList		: "Genummerde lijst invoegen/verwijderen",
+BulletedListLbl		: "Opsomming",
+BulletedList		: "Opsomming invoegen/verwijderen",
+ShowTableBorders	: "Randen tabel weergeven",
+ShowDetails			: "Details weergeven",
+Style				: "Stijl",
+FontFormat			: "Opmaak",
+Font				: "Lettertype",
+FontSize			: "Grootte",
+TextColor			: "Tekstkleur",
+BGColor				: "Achtergrondkleur",
+Source				: "Code",
+Find				: "Zoeken",
+Replace				: "Vervangen",
+SpellCheck			: "Spellingscontrole",
+UniversalKeyboard	: "Universeel toetsenbord",
+PageBreakLbl		: "Pagina-einde",
+PageBreak			: "Pagina-einde invoegen",
+
+Form			: "Formulier",
+Checkbox		: "Aanvinkvakje",
+RadioButton		: "Selectievakje",
+TextField		: "Tekstveld",
+Textarea		: "Tekstvak",
+HiddenField		: "Verborgen veld",
+Button			: "Knop",
+SelectionField	: "Selectieveld",
+ImageButton		: "Afbeeldingsknop",
+
+FitWindow		: "De editor maximaliseren",
+
+// Context Menu
+EditLink			: "Link wijzigen",
+CellCM				: "Cel",
+RowCM				: "Rij",
+ColumnCM			: "Kolom",
+InsertRow			: "Rij invoegen",
+DeleteRows			: "Rijen verwijderen",
+InsertColumn		: "Kolom invoegen",
+DeleteColumns		: "Kolommen verwijderen",
+InsertCell			: "Cel",
+DeleteCells			: "Cellen verwijderen",
+MergeCells			: "Cellen samenvoegen",
+SplitCell			: "Cellen splitsen",
+TableDelete			: "Tabel verwijderen",
+CellProperties		: "Eigenschappen cel",
+TableProperties		: "Eigenschappen tabel",
+ImageProperties		: "Eigenschappen afbeelding",
+FlashProperties		: "Eigenschappen Flash",
+
+AnchorProp			: "Eigenschappen interne link",
+ButtonProp			: "Eigenschappen knop",
+CheckboxProp		: "Eigenschappen aanvinkvakje",
+HiddenFieldProp		: "Eigenschappen verborgen veld",
+RadioButtonProp		: "Eigenschappen selectievakje",
+ImageButtonProp		: "Eigenschappen afbeeldingsknop",
+TextFieldProp		: "Eigenschappen tekstveld",
+SelectionFieldProp	: "Eigenschappen selectieveld",
+TextareaProp		: "Eigenschappen tekstvak",
+FormProp			: "Eigenschappen formulier",
+
+FontFormats			: "Normaal;Met opmaak;Adres;Kop 1;Kop 2;Kop 3;Kop 4;Kop 5;Kop 6;Normaal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Bezig met verwerken XHTML. Even geduld aub...",
+Done				: "Klaar",
+PasteWordConfirm	: "De tekst die je plakte lijkt gekopieerd uit te zijn Word. Wil je de tekst opschonen voordat deze geplakt wordt?",
+NotCompatiblePaste	: "Deze opdracht is beschikbaar voor Internet Explorer versie 5.5 of hoger. Wil je plakken zonder op te schonen?",
+UnknownToolbarItem	: "Onbekend item op menubalk \"%1\"",
+UnknownCommand		: "Onbekende opdrachtnaam: \"%1\"",
+NotImplemented		: "Opdracht niet geïmplementeerd.",
+UnknownToolbarSet	: "Menubalk \"%1\" bestaat niet.",
+NoActiveX			: "De beveilingsinstellingen van je browser zouden sommige functies van de editor kunnen beperken. De optie \"Activeer ActiveX-elementen en plug-ins\" dient ingeschakeld te worden. Het kan zijn dat er nu functies ontbreken of niet werken.",
+BrowseServerBlocked : "De bestandsbrowser kon niet geopend worden. Zorg ervoor dat pop-up-blokkeerders uit staan.",
+DialogBlocked		: "Kan het dialoogvenster niet weergeven. Zorg ervoor dat pop-up-blokkeerders uit staan.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Annuleren",
+DlgBtnClose			: "Afsluiten",
+DlgBtnBrowseServer	: "Bladeren op server",
+DlgAdvancedTag		: "Geavanceerd",
+DlgOpOther			: "<Anders>",
+DlgInfoTab			: "Informatie",
+DlgAlertUrl			: "Geef URL op",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<niet ingevuld>",
+DlgGenId			: "Kenmerk",
+DlgGenLangDir		: "Schrijfrichting",
+DlgGenLangDirLtr	: "Links naar rechts (LTR)",
+DlgGenLangDirRtl	: "Rechts naar links (RTL)",
+DlgGenLangCode		: "Taalcode",
+DlgGenAccessKey		: "Toegangstoets",
+DlgGenName			: "Naam",
+DlgGenTabIndex		: "Tabvolgorde",
+DlgGenLongDescr		: "Lange URL-omschrijving",
+DlgGenClass			: "Stylesheet-klassen",
+DlgGenTitle			: "Aanbevolen titel",
+DlgGenContType		: "Aanbevolen content-type",
+DlgGenLinkCharset	: "Karakterset van gelinkte bron",
+DlgGenStyle			: "Stijl",
+
+// Image Dialog
+DlgImgTitle			: "Eigenschappen afbeelding",
+DlgImgInfoTab		: "Informatie afbeelding",
+DlgImgBtnUpload		: "Naar server verzenden",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternatieve tekst",
+DlgImgWidth			: "Breedte",
+DlgImgHeight		: "Hoogte",
+DlgImgLockRatio		: "Afmetingen vergrendelen",
+DlgBtnResetSize		: "Afmetingen resetten",
+DlgImgBorder		: "Rand",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Uitlijning",
+DlgImgAlignLeft		: "Links",
+DlgImgAlignAbsBottom: "Absoluut-onder",
+DlgImgAlignAbsMiddle: "Absoluut-midden",
+DlgImgAlignBaseline	: "Basislijn",
+DlgImgAlignBottom	: "Beneden",
+DlgImgAlignMiddle	: "Midden",
+DlgImgAlignRight	: "Rechts",
+DlgImgAlignTextTop	: "Boven tekst",
+DlgImgAlignTop		: "Boven",
+DlgImgPreview		: "Voorbeeld",
+DlgImgAlertUrl		: "Geef de URL van de afbeelding",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Eigenschappen Flash",
+DlgFlashChkPlay		: "Automatisch afspelen",
+DlgFlashChkLoop		: "Herhalen",
+DlgFlashChkMenu		: "Flashmenu\'s inschakelen",
+DlgFlashScale		: "Schaal",
+DlgFlashScaleAll	: "Alles tonen",
+DlgFlashScaleNoBorder	: "Geen rand",
+DlgFlashScaleFit	: "Precies passend",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Linkomschrijving",
+DlgLnkTargetTab		: "Doel",
+
+DlgLnkType			: "Linktype",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Interne link in pagina",
+DlgLnkTypeEMail		: "E-mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<anders>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Kies een interne link",
+DlgLnkAnchorByName	: "Op naam interne link",
+DlgLnkAnchorById	: "Op kenmerk interne link",
+DlgLnkNoAnchors		: "(Geen interne links in document gevonden)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-mailadres",
+DlgLnkEMailSubject	: "Onderwerp bericht",
+DlgLnkEMailBody		: "Inhoud bericht",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Naar de server versturen",
+
+DlgLnkTarget		: "Doel",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<popup window>",
+DlgLnkTargetBlank	: "Nieuw venster (_blank)",
+DlgLnkTargetParent	: "Origineel venster (_parent)",
+DlgLnkTargetSelf	: "Zelfde venster (_self)",
+DlgLnkTargetTop		: "Hele venster (_top)",
+DlgLnkTargetFrameName	: "Naam doelframe",
+DlgLnkPopWinName	: "Naam popupvenster",
+DlgLnkPopWinFeat	: "Instellingen popupvenster",
+DlgLnkPopResize		: "Grootte wijzigen",
+DlgLnkPopLocation	: "Locatiemenu",
+DlgLnkPopMenu		: "Menubalk",
+DlgLnkPopScroll		: "Schuifbalken",
+DlgLnkPopStatus		: "Statusbalk",
+DlgLnkPopToolbar	: "Menubalk",
+DlgLnkPopFullScrn	: "Volledig scherm (IE)",
+DlgLnkPopDependent	: "Afhankelijk (Netscape)",
+DlgLnkPopWidth		: "Breedte",
+DlgLnkPopHeight		: "Hoogte",
+DlgLnkPopLeft		: "Positie links",
+DlgLnkPopTop		: "Positie boven",
+
+DlnLnkMsgNoUrl		: "Geef de link van de URL",
+DlnLnkMsgNoEMail	: "Geef een e-mailadres",
+DlnLnkMsgNoAnchor	: "Selecteer een interne link",
+DlnLnkMsgInvPopName	: "De naam van de popup moet met een alfa-numerieke waarde beginnen, en mag geen spaties bevatten.",
+
+// Color Dialog
+DlgColorTitle		: "Selecteer kleur",
+DlgColorBtnClear	: "Opschonen",
+DlgColorHighlight	: "Accentueren",
+DlgColorSelected	: "Geselecteerd",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Smiley invoegen",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Selecteer speciaal teken",
+
+// Table Dialog
+DlgTableTitle		: "Eigenschappen tabel",
+DlgTableRows		: "Rijen",
+DlgTableColumns		: "Kolommen",
+DlgTableBorder		: "Breedte rand",
+DlgTableAlign		: "Uitlijning",
+DlgTableAlignNotSet	: "<Niet ingevoerd>",
+DlgTableAlignLeft	: "Links",
+DlgTableAlignCenter	: "Centreren",
+DlgTableAlignRight	: "Rechts",
+DlgTableWidth		: "Breedte",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "procent",
+DlgTableHeight		: "Hoogte",
+DlgTableCellSpace	: "Afstand tussen cellen",
+DlgTableCellPad		: "Afstand vanaf rand cel",
+DlgTableCaption		: "Naam",
+DlgTableSummary		: "Samenvatting",
+
+// Table Cell Dialog
+DlgCellTitle		: "Eigenschappen cel",
+DlgCellWidth		: "Breedte",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "procent",
+DlgCellHeight		: "Hoogte",
+DlgCellWordWrap		: "Afbreken woorden",
+DlgCellWordWrapNotSet	: "<Niet ingevoerd>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nee",
+DlgCellHorAlign		: "Horizontale uitlijning",
+DlgCellHorAlignNotSet	: "<Niet ingevoerd>",
+DlgCellHorAlignLeft	: "Links",
+DlgCellHorAlignCenter	: "Centreren",
+DlgCellHorAlignRight: "Rechts",
+DlgCellVerAlign		: "Verticale uitlijning",
+DlgCellVerAlignNotSet	: "<Niet ingevoerd>",
+DlgCellVerAlignTop	: "Boven",
+DlgCellVerAlignMiddle	: "Midden",
+DlgCellVerAlignBottom	: "Beneden",
+DlgCellVerAlignBaseline	: "Basislijn",
+DlgCellRowSpan		: "Overkoepeling rijen",
+DlgCellCollSpan		: "Overkoepeling kolommen",
+DlgCellBackColor	: "Achtergrondkleur",
+DlgCellBorderColor	: "Randkleur",
+DlgCellBtnSelect	: "Selecteren...",
+
+// Find Dialog
+DlgFindTitle		: "Zoeken",
+DlgFindFindBtn		: "Zoeken",
+DlgFindNotFoundMsg	: "De opgegeven tekst is niet gevonden.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Vervangen",
+DlgReplaceFindLbl		: "Zoeken naar:",
+DlgReplaceReplaceLbl	: "Vervangen met:",
+DlgReplaceCaseChk		: "Hoofdlettergevoelig",
+DlgReplaceReplaceBtn	: "Vervangen",
+DlgReplaceReplAllBtn	: "Alles vervangen",
+DlgReplaceWordChk		: "Hele woord moet voorkomen",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "De beveiligingsinstelling van de browser verhinderen het automatisch knippen. Gebruik de sneltoets Ctrl+X van het toetsenbord.",
+PasteErrorCopy	: "De beveiligingsinstelling van de browser verhinderen het automatisch kopiëren. Gebruik de sneltoets Ctrl+C van het toetsenbord.",
+
+PasteAsText		: "Plakken als platte tekst",
+PasteFromWord	: "Plakken als Word-gegevens",
+
+DlgPasteMsg2	: "Plak de tekst in het volgende vak gebruik makend van je toetstenbord (<STRONG>Ctrl+V</STRONG>) en klik op <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Negeer \"Font Face\"-definities",
+DlgPasteRemoveStyles	: "Verwijder \"Style\"-definities",
+DlgPasteCleanBox		: "Vak opschonen",
+
+// Color Picker
+ColorAutomatic	: "Automatisch",
+ColorMoreColors	: "Meer kleuren...",
+
+// Document Properties
+DocProps		: "Eigenschappen document",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Eigenschappen interne link",
+DlgAnchorName		: "Naam interne link",
+DlgAnchorErrorName	: "Geef de naam van de interne link op",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Niet in het woordenboek",
+DlgSpellChangeTo		: "Wijzig in",
+DlgSpellBtnIgnore		: "Negeren",
+DlgSpellBtnIgnoreAll	: "Alles negeren",
+DlgSpellBtnReplace		: "Vervangen",
+DlgSpellBtnReplaceAll	: "Alles vervangen",
+DlgSpellBtnUndo			: "Ongedaan maken",
+DlgSpellNoSuggestions	: "-Geen suggesties-",
+DlgSpellProgress		: "Bezig met spellingscontrole...",
+DlgSpellNoMispell		: "Klaar met spellingscontrole: geen fouten gevonden",
+DlgSpellNoChanges		: "Klaar met spellingscontrole: geen woorden aangepast",
+DlgSpellOneChange		: "Klaar met spellingscontrole: één woord aangepast",
+DlgSpellManyChanges		: "Klaar met spellingscontrole: %1 woorden aangepast",
+
+IeSpellDownload			: "De spellingscontrole niet geïnstalleerd. Wil je deze nu downloaden?",
+
+// Button Dialog
+DlgButtonText		: "Tekst (waarde)",
+DlgButtonType		: "Soort",
+DlgButtonTypeBtn	: "Knop",
+DlgButtonTypeSbm	: "Versturen",
+DlgButtonTypeRst	: "Leegmaken",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Naam",
+DlgCheckboxValue	: "Waarde",
+DlgCheckboxSelected	: "Geselecteerd",
+
+// Form Dialog
+DlgFormName		: "Naam",
+DlgFormAction	: "Actie",
+DlgFormMethod	: "Methode",
+
+// Select Field Dialog
+DlgSelectName		: "Naam",
+DlgSelectValue		: "Waarde",
+DlgSelectSize		: "Grootte",
+DlgSelectLines		: "Regels",
+DlgSelectChkMulti	: "Gecombineerde selecties toestaan",
+DlgSelectOpAvail	: "Beschikbare opties",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Waarde",
+DlgSelectBtnAdd		: "Toevoegen",
+DlgSelectBtnModify	: "Wijzigen",
+DlgSelectBtnUp		: "Omhoog",
+DlgSelectBtnDown	: "Omlaag",
+DlgSelectBtnSetValue : "Als geselecteerde waarde instellen",
+DlgSelectBtnDelete	: "Verwijderen",
+
+// Textarea Dialog
+DlgTextareaName	: "Naam",
+DlgTextareaCols	: "Kolommen",
+DlgTextareaRows	: "Rijen",
+
+// Text Field Dialog
+DlgTextName			: "Naam",
+DlgTextValue		: "Waarde",
+DlgTextCharWidth	: "Breedte (tekens)",
+DlgTextMaxChars		: "Maximum aantal tekens",
+DlgTextType			: "Soort",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Wachtwoord",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Naam",
+DlgHiddenValue	: "Waarde",
+
+// Bulleted List Dialog
+BulletedListProp	: "Eigenschappen opsommingslijst",
+NumberedListProp	: "Eigenschappen genummerde opsommingslijst",
+DlgLstStart			: "Start",
+DlgLstType			: "Soort",
+DlgLstTypeCircle	: "Cirkel",
+DlgLstTypeDisc		: "Schijf",
+DlgLstTypeSquare	: "Vierkant",
+DlgLstTypeNumbers	: "Nummers (1, 2, 3)",
+DlgLstTypeLCase		: "Kleine letters (a, b, c)",
+DlgLstTypeUCase		: "Hoofdletters (A, B, C)",
+DlgLstTypeSRoman	: "Klein Romeins (i, ii, iii)",
+DlgLstTypeLRoman	: "Groot Romeins (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Algemeen",
+DlgDocBackTab		: "Achtergrond",
+DlgDocColorsTab		: "Kleuring en marges",
+DlgDocMetaTab		: "META-data",
+
+DlgDocPageTitle		: "Paginatitel",
+DlgDocLangDir		: "Schrijfrichting",
+DlgDocLangDirLTR	: "Links naar rechts",
+DlgDocLangDirRTL	: "Rechts naar links",
+DlgDocLangCode		: "Taalcode",
+DlgDocCharSet		: "Karakterset-encoding",
+DlgDocCharSetCE		: "Centraal Europees",
+DlgDocCharSetCT		: "Traditioneel Chinees (Big5)",
+DlgDocCharSetCR		: "Cyriliaans",
+DlgDocCharSetGR		: "Grieks",
+DlgDocCharSetJP		: "Japans",
+DlgDocCharSetKR		: "Koreaans",
+DlgDocCharSetTR		: "Turks",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "West europees",
+DlgDocCharSetOther	: "Andere karakterset-encoding",
+
+DlgDocDocType		: "Opschrift documentsoort",
+DlgDocDocTypeOther	: "Ander opschrift documentsoort",
+DlgDocIncXHTML		: "XHTML-declaraties meenemen",
+DlgDocBgColor		: "Achtergrondkleur",
+DlgDocBgImage		: "URL achtergrondplaatje",
+DlgDocBgNoScroll	: "Vaste achtergrond",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Bezochte link",
+DlgDocCActive		: "Active link",
+DlgDocMargins		: "Afstandsinstellingen document",
+DlgDocMaTop			: "Boven",
+DlgDocMaLeft		: "Links",
+DlgDocMaRight		: "Rechts",
+DlgDocMaBottom		: "Onder",
+DlgDocMeIndex		: "Trefwoorden betreffende document (kommagescheiden)",
+DlgDocMeDescr		: "Beschrijving document",
+DlgDocMeAuthor		: "Auteur",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Voorbeeld",
+
+// Templates Dialog
+Templates			: "Sjablonen",
+DlgTemplatesTitle	: "Inhoud sjabonen",
+DlgTemplatesSelMsg	: "Selecteer het sjabloon dat in de editor geopend moet worden (de actuele inhoud gaat verloren):",
+DlgTemplatesLoading	: "Bezig met laden sjabonen. Even geduld alstublieft...",
+DlgTemplatesNoTpl	: "(Geen sjablonen gedefinieerd)",
+DlgTemplatesReplace	: "Vervang de huidige inhoud",
+
+// About Dialog
+DlgAboutAboutTab	: "Over",
+DlgAboutBrowserInfoTab	: "Browserinformatie",
+DlgAboutLicenseTab	: "Licentie",
+DlgAboutVersion		: "Versie",
+DlgAboutInfo		: "Voor meer informatie ga naar "
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hr.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hr.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hr.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Croatian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Smanji trake s alatima",
+ToolbarExpand		: "Proširi trake s alatima",
+
+// Toolbar Items and Context Menu
+Save				: "Snimi",
+NewPage				: "Nova stranica",
+Preview				: "Pregledaj",
+Cut					: "Izreži",
+Copy				: "Kopiraj",
+Paste				: "Zalijepi",
+PasteText			: "Zalijepi kao čisti tekst",
+PasteWord			: "Zalijepi iz Worda",
+Print				: "Ispiši",
+SelectAll			: "Odaberi sve",
+RemoveFormat		: "Ukloni formatiranje",
+InsertLinkLbl		: "Link",
+InsertLink			: "Ubaci/promijeni link",
+RemoveLink			: "Ukloni link",
+Anchor				: "Ubaci/promijeni sidro",
+InsertImageLbl		: "Slika",
+InsertImage			: "Ubaci/promijeni sliku",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Ubaci/promijeni Flash",
+InsertTableLbl		: "Tablica",
+InsertTable			: "Ubaci/promijeni tablicu",
+InsertLineLbl		: "Linija",
+InsertLine			: "Ubaci vodoravnu liniju",
+InsertSpecialCharLbl: "Posebni karakteri",
+InsertSpecialChar	: "Ubaci posebne znakove",
+InsertSmileyLbl		: "Smješko",
+InsertSmiley		: "Ubaci smješka",
+About				: "O FCKeditoru",
+Bold				: "Podebljaj",
+Italic				: "Ukosi",
+Underline			: "Potcrtano",
+StrikeThrough		: "Precrtano",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Lijevo poravnanje",
+CenterJustify		: "Središnje poravnanje",
+RightJustify		: "Desno poravnanje",
+BlockJustify		: "Blok poravnanje",
+DecreaseIndent		: "Pomakni ulijevo",
+IncreaseIndent		: "Pomakni udesno",
+Undo				: "Poništi",
+Redo				: "Ponovi",
+NumberedListLbl		: "Brojčana lista",
+NumberedList		: "Ubaci/ukloni brojčanu listu",
+BulletedListLbl		: "Obična lista",
+BulletedList		: "Ubaci/ukloni običnu listu",
+ShowTableBorders	: "Prikaži okvir tablice",
+ShowDetails			: "Prikaži detalje",
+Style				: "Stil",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Veličina",
+TextColor			: "Boja teksta",
+BGColor				: "Boja pozadine",
+Source				: "Kôd",
+Find				: "Pronađi",
+Replace				: "Zamijeni",
+SpellCheck			: "Provjeri pravopis",
+UniversalKeyboard	: "Univerzalna tipkovnica",
+PageBreakLbl		: "Prijelom stranice",
+PageBreak			: "Ubaci prijelom stranice",
+
+Form			: "Form",
+Checkbox		: "Checkbox",
+RadioButton		: "Radio Button",
+TextField		: "Text Field",
+Textarea		: "Textarea",
+HiddenField		: "Hidden Field",
+Button			: "Button",
+SelectionField	: "Selection Field",
+ImageButton		: "Image Button",
+
+FitWindow		: "Povećaj veličinu editora",
+
+// Context Menu
+EditLink			: "Promijeni link",
+CellCM				: "Ćelija",
+RowCM				: "Red",
+ColumnCM			: "Kolona",
+InsertRow			: "Ubaci red",
+DeleteRows			: "Izbriši redove",
+InsertColumn		: "Ubaci kolonu",
+DeleteColumns		: "Izbriši kolone",
+InsertCell			: "Ubaci ćelije",
+DeleteCells			: "Izbriši ćelije",
+MergeCells			: "Spoji ćelije",
+SplitCell			: "Razdvoji ćelije",
+TableDelete			: "Izbriši tablicu",
+CellProperties		: "Svojstva ćelije",
+TableProperties		: "Svojstva tablice",
+ImageProperties		: "Svojstva slike",
+FlashProperties		: "Flash svojstva",
+
+AnchorProp			: "Svojstva sidra",
+ButtonProp			: "Image Button svojstva",
+CheckboxProp		: "Checkbox svojstva",
+HiddenFieldProp		: "Hidden Field svojstva",
+RadioButtonProp		: "Radio Button svojstva",
+ImageButtonProp		: "Image Button svojstva",
+TextFieldProp		: "Text Field svojstva",
+SelectionFieldProp	: "Selection svojstva",
+TextareaProp		: "Textarea svojstva",
+FormProp			: "Form svojstva",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Obrađujem XHTML. Molimo pričekajte...",
+Done				: "Završio",
+PasteWordConfirm	: "Tekst koji želite zalijepiti čini se da je kopiran iz Worda. Želite li prije očistiti tekst?",
+NotCompatiblePaste	: "Ova naredba je dostupna samo u Internet Exploreru 5.5 ili novijem. Želite li nastaviti bez čišćenja?",
+UnknownToolbarItem	: "Nepoznati član trake s alatima \"%1\"",
+UnknownCommand		: "Nepoznata naredba \"%1\"",
+NotImplemented		: "Naredba nije implementirana",
+UnknownToolbarSet	: "Traka s alatima \"%1\" ne postoji",
+NoActiveX			: "Vaše postavke pretraživača mogle bi ograničiti neke od mogućnosti editora. Morate uključiti opciju \"Run ActiveX controls and plug-ins\" u postavkama. Ukoliko to ne učinite, moguće su razliite greške tijekom rada.",
+BrowseServerBlocked : "Pretraivač nije moguće otvoriti. Provjerite da li je uključeno blokiranje pop-up prozora.",
+DialogBlocked		: "Nije moguće otvoriti novi prozor. Provjerite da li je uključeno blokiranje pop-up prozora.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Poništi",
+DlgBtnClose			: "Zatvori",
+DlgBtnBrowseServer	: "Pretraži server",
+DlgAdvancedTag		: "Napredno",
+DlgOpOther			: "<Drugo>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Molimo unesite URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nije postavljeno>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Smjer jezika",
+DlgGenLangDirLtr	: "S lijeva na desno (LTR)",
+DlgGenLangDirRtl	: "S desna na lijevo (RTL)",
+DlgGenLangCode		: "Kôd jezika",
+DlgGenAccessKey		: "Pristupna tipka",
+DlgGenName			: "Naziv",
+DlgGenTabIndex		: "Tab Indeks",
+DlgGenLongDescr		: "Dugački opis URL",
+DlgGenClass			: "Stylesheet klase",
+DlgGenTitle			: "Advisory naslov",
+DlgGenContType		: "Advisory vrsta sadržaja",
+DlgGenLinkCharset	: "Kodna stranica povezanih resursa",
+DlgGenStyle			: "Stil",
+
+// Image Dialog
+DlgImgTitle			: "Svojstva slika",
+DlgImgInfoTab		: "Info slike",
+DlgImgBtnUpload		: "Pošalji na server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Pošalji",
+DlgImgAlt			: "Alternativni tekst",
+DlgImgWidth			: "Širina",
+DlgImgHeight		: "Visina",
+DlgImgLockRatio		: "Zaključaj odnos",
+DlgBtnResetSize		: "Obriši veličinu",
+DlgImgBorder		: "Okvir",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Poravnaj",
+DlgImgAlignLeft		: "Lijevo",
+DlgImgAlignAbsBottom: "Abs dolje",
+DlgImgAlignAbsMiddle: "Abs sredina",
+DlgImgAlignBaseline	: "Bazno",
+DlgImgAlignBottom	: "Dolje",
+DlgImgAlignMiddle	: "Sredina",
+DlgImgAlignRight	: "Desno",
+DlgImgAlignTextTop	: "Vrh teksta",
+DlgImgAlignTop		: "Vrh",
+DlgImgPreview		: "Pregledaj",
+DlgImgAlertUrl		: "Unesite URL slike",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash svojstva",
+DlgFlashChkPlay		: "Auto Play",
+DlgFlashChkLoop		: "Ponavljaj",
+DlgFlashChkMenu		: "Omogući Flash izbornik",
+DlgFlashScale		: "Omjer",
+DlgFlashScaleAll	: "Prikaži sve",
+DlgFlashScaleNoBorder	: "Bez okvira",
+DlgFlashScaleFit	: "Točna veličina",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Meta",
+
+DlgLnkType			: "Link vrsta",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Sidro na ovoj stranici",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<drugo>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Odaberi sidro",
+DlgLnkAnchorByName	: "Po nazivu sidra",
+DlgLnkAnchorById	: "Po Id elementa",
+DlgLnkNoAnchors		: "<Nema dostupnih sidra>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail adresa",
+DlgLnkEMailSubject	: "Naslov",
+DlgLnkEMailBody		: "Sadržaj poruke",
+DlgLnkUpload		: "Pošalji",
+DlgLnkBtnUpload		: "Pošalji na server",
+
+DlgLnkTarget		: "Meta",
+DlgLnkTargetFrame	: "<okvir>",
+DlgLnkTargetPopup	: "<popup prozor>",
+DlgLnkTargetBlank	: "Novi prozor (_blank)",
+DlgLnkTargetParent	: "Roditeljski prozor (_parent)",
+DlgLnkTargetSelf	: "Isti prozor (_self)",
+DlgLnkTargetTop		: "Vršni prozor (_top)",
+DlgLnkTargetFrameName	: "Ime ciljnog okvira",
+DlgLnkPopWinName	: "Naziv popup prozora",
+DlgLnkPopWinFeat	: "Mogućnosti popup prozora",
+DlgLnkPopResize		: "Promjenljive veličine",
+DlgLnkPopLocation	: "Traka za lokaciju",
+DlgLnkPopMenu		: "Izborna traka",
+DlgLnkPopScroll		: "Scroll traka",
+DlgLnkPopStatus		: "Statusna traka",
+DlgLnkPopToolbar	: "Traka s alatima",
+DlgLnkPopFullScrn	: "Cijeli ekran (IE)",
+DlgLnkPopDependent	: "Ovisno (Netscape)",
+DlgLnkPopWidth		: "Širina",
+DlgLnkPopHeight		: "Visina",
+DlgLnkPopLeft		: "Lijeva pozicija",
+DlgLnkPopTop		: "Gornja pozicija",
+
+DlnLnkMsgNoUrl		: "Molimo upišite URL link",
+DlnLnkMsgNoEMail	: "Molimo upišite e-mail adresu",
+DlnLnkMsgNoAnchor	: "Molimo odaberite sidro",
+DlnLnkMsgInvPopName	: "Ime popup prozora mora početi sa slovom i ne smije sadržavati razmake",
+
+// Color Dialog
+DlgColorTitle		: "Odaberite boju",
+DlgColorBtnClear	: "Obriši",
+DlgColorHighlight	: "Osvijetli",
+DlgColorSelected	: "Odaberi",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Ubaci smješka",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Odaberite posebni karakter",
+
+// Table Dialog
+DlgTableTitle		: "Svojstva tablice",
+DlgTableRows		: "Redova",
+DlgTableColumns		: "Kolona",
+DlgTableBorder		: "Veličina okvira",
+DlgTableAlign		: "Poravnanje",
+DlgTableAlignNotSet	: "<nije postavljeno>",
+DlgTableAlignLeft	: "Lijevo",
+DlgTableAlignCenter	: "Središnje",
+DlgTableAlignRight	: "Desno",
+DlgTableWidth		: "Širina",
+DlgTableWidthPx		: "piksela",
+DlgTableWidthPc		: "postotaka",
+DlgTableHeight		: "Visina",
+DlgTableCellSpace	: "Prostornost ćelija",
+DlgTableCellPad		: "Razmak ćelija",
+DlgTableCaption		: "Naslov",
+DlgTableSummary		: "Sažetak",
+
+// Table Cell Dialog
+DlgCellTitle		: "Svojstva ćelije",
+DlgCellWidth		: "Širina",
+DlgCellWidthPx		: "piksela",
+DlgCellWidthPc		: "postotaka",
+DlgCellHeight		: "Visina",
+DlgCellWordWrap		: "Word Wrap",
+DlgCellWordWrapNotSet	: "<nije postavljeno>",
+DlgCellWordWrapYes	: "Da",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Vodoravno poravnanje",
+DlgCellHorAlignNotSet	: "<nije postavljeno>",
+DlgCellHorAlignLeft	: "Lijevo",
+DlgCellHorAlignCenter	: "Središnje",
+DlgCellHorAlignRight: "Desno",
+DlgCellVerAlign		: "Okomito poravnanje",
+DlgCellVerAlignNotSet	: "<nije postavljeno>",
+DlgCellVerAlignTop	: "Gornje",
+DlgCellVerAlignMiddle	: "Srednišnje",
+DlgCellVerAlignBottom	: "Donje",
+DlgCellVerAlignBaseline	: "Bazno",
+DlgCellRowSpan		: "Spajanje redova",
+DlgCellCollSpan		: "Spajanje kolona",
+DlgCellBackColor	: "Boja pozadine",
+DlgCellBorderColor	: "Boja okvira",
+DlgCellBtnSelect	: "Odaberi...",
+
+// Find Dialog
+DlgFindTitle		: "Pronađi",
+DlgFindFindBtn		: "Pronađi",
+DlgFindNotFoundMsg	: "Traženi tekst nije pronađen.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Zamijeni",
+DlgReplaceFindLbl		: "Pronađi:",
+DlgReplaceReplaceLbl	: "Zamijeni s:",
+DlgReplaceCaseChk		: "Usporedi mala/velika slova",
+DlgReplaceReplaceBtn	: "Zamijeni",
+DlgReplaceReplAllBtn	: "Zamijeni sve",
+DlgReplaceWordChk		: "Usporedi cijele riječi",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog izrezivanja. Molimo koristite kraticu na tipkovnici (Ctrl+X).",
+PasteErrorCopy	: "Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tipkovnici (Ctrl+C).",
+
+PasteAsText		: "Zalijepi kao čisti tekst",
+PasteFromWord	: "Zalijepi iz Worda",
+
+DlgPasteMsg2	: "Molimo zaljepite unutar doljnjeg okvira koristeći tipkovnicu (<STRONG>Ctrl+V</STRONG>) i kliknite <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Zanemari definiciju vrste fonta",
+DlgPasteRemoveStyles	: "Ukloni definicije stilova",
+DlgPasteCleanBox		: "Očisti okvir",
+
+// Color Picker
+ColorAutomatic	: "Automatski",
+ColorMoreColors	: "Više boja...",
+
+// Document Properties
+DocProps		: "Svojstva dokumenta",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Svojstva sidra",
+DlgAnchorName		: "Ime sidra",
+DlgAnchorErrorName	: "Molimo unesite ime sidra",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nije u rječniku",
+DlgSpellChangeTo		: "Promijeni u",
+DlgSpellBtnIgnore		: "Zanemari",
+DlgSpellBtnIgnoreAll	: "Zanemari sve",
+DlgSpellBtnReplace		: "Zamijeni",
+DlgSpellBtnReplaceAll	: "Zamijeni sve",
+DlgSpellBtnUndo			: "Vrati",
+DlgSpellNoSuggestions	: "-Nema preporuke-",
+DlgSpellProgress		: "Provjera u tijeku...",
+DlgSpellNoMispell		: "Provjera završena: Nema grešaka",
+DlgSpellNoChanges		: "Provjera završena: Nije napravljena promjena",
+DlgSpellOneChange		: "Provjera završena: Jedna riječ promjenjena",
+DlgSpellManyChanges		: "Provjera završena: Promijenjeno %1 riječi",
+
+IeSpellDownload			: "Provjera pravopisa nije instalirana. Želite li skinuti provjeru pravopisa?",
+
+// Button Dialog
+DlgButtonText		: "Tekst (vrijednost)",
+DlgButtonType		: "Vrsta",
+DlgButtonTypeBtn	: "Gumb",
+DlgButtonTypeSbm	: "Pošalji",
+DlgButtonTypeRst	: "Poništi",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Ime",
+DlgCheckboxValue	: "Vrijednost",
+DlgCheckboxSelected	: "Odabrano",
+
+// Form Dialog
+DlgFormName		: "Ime",
+DlgFormAction	: "Akcija",
+DlgFormMethod	: "Metoda",
+
+// Select Field Dialog
+DlgSelectName		: "Ime",
+DlgSelectValue		: "Vrijednost",
+DlgSelectSize		: "Veličina",
+DlgSelectLines		: "linija",
+DlgSelectChkMulti	: "Dozvoli višestruki odabir",
+DlgSelectOpAvail	: "Dostupne opcije",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Vrijednost",
+DlgSelectBtnAdd		: "Dodaj",
+DlgSelectBtnModify	: "Promijeni",
+DlgSelectBtnUp		: "Gore",
+DlgSelectBtnDown	: "Dolje",
+DlgSelectBtnSetValue : "Postavi kao odabranu vrijednost",
+DlgSelectBtnDelete	: "Obriši",
+
+// Textarea Dialog
+DlgTextareaName	: "Ime",
+DlgTextareaCols	: "Kolona",
+DlgTextareaRows	: "Redova",
+
+// Text Field Dialog
+DlgTextName			: "Ime",
+DlgTextValue		: "Vrijednost",
+DlgTextCharWidth	: "Širina",
+DlgTextMaxChars		: "Najviše karaktera",
+DlgTextType			: "Vrsta",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Šifra",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Ime",
+DlgHiddenValue	: "Vrijednost",
+
+// Bulleted List Dialog
+BulletedListProp	: "Svojstva liste",
+NumberedListProp	: "Svojstva brojčane liste",
+DlgLstStart			: "Početak",
+DlgLstType			: "Vrsta",
+DlgLstTypeCircle	: "Krug",
+DlgLstTypeDisc		: "Disk",
+DlgLstTypeSquare	: "Kvadrat",
+DlgLstTypeNumbers	: "Brojevi (1, 2, 3)",
+DlgLstTypeLCase		: "Mala slova (a, b, c)",
+DlgLstTypeUCase		: "Velika slova (A, B, C)",
+DlgLstTypeSRoman	: "Male rimske brojke (i, ii, iii)",
+DlgLstTypeLRoman	: "Velike rimske brojke (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Općenito",
+DlgDocBackTab		: "Pozadina",
+DlgDocColorsTab		: "Boje i margine",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Naslov stranice",
+DlgDocLangDir		: "Smjer jezika",
+DlgDocLangDirLTR	: "S lijeva na desno",
+DlgDocLangDirRTL	: "S desna na lijevo",
+DlgDocLangCode		: "Kôd jezika",
+DlgDocCharSet		: "Enkodiranje znakova",
+DlgDocCharSetCE		: "Središnja Europa",
+DlgDocCharSetCT		: "Tradicionalna kineska (Big5)",
+DlgDocCharSetCR		: "Ćirilica",
+DlgDocCharSetGR		: "Grčka",
+DlgDocCharSetJP		: "Japanska",
+DlgDocCharSetKR		: "Koreanska",
+DlgDocCharSetTR		: "Turska",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Zapadna Europa",
+DlgDocCharSetOther	: "Ostalo enkodiranje znakova",
+
+DlgDocDocType		: "Zaglavlje vrste dokumenta",
+DlgDocDocTypeOther	: "Ostalo zaglavlje vrste dokumenta",
+DlgDocIncXHTML		: "Ubaci XHTML deklaracije",
+DlgDocBgColor		: "Boja pozadine",
+DlgDocBgImage		: "URL slike pozadine",
+DlgDocBgNoScroll	: "Pozadine se ne pomiče",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Posjećeni link",
+DlgDocCActive		: "Aktivni link",
+DlgDocMargins		: "Margine stranice",
+DlgDocMaTop			: "Vrh",
+DlgDocMaLeft		: "Lijevo",
+DlgDocMaRight		: "Desno",
+DlgDocMaBottom		: "Dolje",
+DlgDocMeIndex		: "Ključne riječi dokumenta (odvojene zarezom)",
+DlgDocMeDescr		: "Opis dokumenta",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Autorska prava",
+DlgDocPreview		: "Pregledaj",
+
+// Templates Dialog
+Templates			: "Predlošci",
+DlgTemplatesTitle	: "Predlošci sadržaja",
+DlgTemplatesSelMsg	: "Molimo odaberite predložak koji želite otvoriti<br>(stvarni sadržaj će biti izgubljen):",
+DlgTemplatesLoading	: "Učitavam listu predložaka. Molimo pričekajte...",
+DlgTemplatesNoTpl	: "(Nema definiranih predložaka)",
+DlgTemplatesReplace	: "Zamijeni trenutne sadržaje",
+
+// About Dialog
+DlgAboutAboutTab	: "O FCKEditoru",
+DlgAboutBrowserInfoTab	: "Podaci o pretraživaču",
+DlgAboutLicenseTab	: "Licenca",
+DlgAboutVersion		: "inačica",
+DlgAboutInfo		: "Za više informacija posjetite"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/mn.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/mn.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/mn.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Mongolian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Багажны хэсэг эвдэх",
+ToolbarExpand		: "Багажны хэсэг өргөтгөх",
+
+// Toolbar Items and Context Menu
+Save				: "Хадгалах",
+NewPage				: "Шинэ хуудас",
+Preview				: "Уридчлан харах",
+Cut					: "Хайчлах",
+Copy				: "Хуулах",
+Paste				: "Буулгах",
+PasteText			: "plain text-ээс буулгах",
+PasteWord			: "Word-оос буулгах",
+Print				: "Хэвлэх",
+SelectAll			: "Бүгдийг нь сонгох",
+RemoveFormat		: "Формат авч хаях",
+InsertLinkLbl		: "Линк",
+InsertLink			: "Линк Оруулах/Засварлах",
+RemoveLink			: "Линк авч хаях",
+Anchor				: "Insert/Edit Anchor",	//MISSING
+InsertImageLbl		: "Зураг",
+InsertImage			: "Зураг Оруулах/Засварлах",
+InsertFlashLbl		: "Flash",	//MISSING
+InsertFlash			: "Insert/Edit Flash",	//MISSING
+InsertTableLbl		: "Хүснэгт",
+InsertTable			: "Хүснэгт Оруулах/Засварлах",
+InsertLineLbl		: "Зураас",
+InsertLine			: "Хөндлөн зураас оруулах",
+InsertSpecialCharLbl: "Онцгой тэмдэгт",
+InsertSpecialChar	: "Онцгой тэмдэгт оруулах",
+InsertSmileyLbl		: "Тодорхойлолт",
+InsertSmiley		: "Тодорхойлолт оруулах",
+About				: "FCKeditor-н тухай",
+Bold				: "Тод бүдүүн",
+Italic				: "Налуу",
+Underline			: "Доогуур нь зураастай болгох",
+StrikeThrough		: "Дундуур нь зураастай болгох",
+Subscript			: "Суурь болгох",
+Superscript			: "Зэрэг болгох",
+LeftJustify			: "Зүүн талд байрлуулах",
+CenterJustify		: "Төвд байрлуулах",
+RightJustify		: "Баруун талд байрлуулах",
+BlockJustify		: "Блок хэлбэрээр байрлуулах",
+DecreaseIndent		: "Догол мөр нэмэх",
+IncreaseIndent		: "Догол мөр хасах",
+Undo				: "Хүчингүй болгох",
+Redo				: "Өмнөх үйлдлээ сэргээх",
+NumberedListLbl		: "Дугаарлагдсан жагсаалт",
+NumberedList		: "Дугаарлагдсан жагсаалт Оруулах/Авах",
+BulletedListLbl		: "Цэгтэй жагсаалт",
+BulletedList		: "Цэгтэй жагсаалт Оруулах/Авах",
+ShowTableBorders	: "Хүснэгтийн хүрээг үзүүлэх",
+ShowDetails			: "Деталчлан үзүүлэх",
+Style				: "Загвар",
+FontFormat			: "Формат",
+Font				: "Фонт",
+FontSize			: "Хэмжээ",
+TextColor			: "Фонтны өнгө",
+BGColor				: "Фонны өнгө",
+Source				: "Код",
+Find				: "Хайх",
+Replace				: "Солих",
+SpellCheck			: "Check Spelling",	//MISSING
+UniversalKeyboard	: "Universal Keyboard",	//MISSING
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "Form",	//MISSING
+Checkbox		: "Checkbox",	//MISSING
+RadioButton		: "Radio Button",	//MISSING
+TextField		: "Text Field",	//MISSING
+Textarea		: "Textarea",	//MISSING
+HiddenField		: "Hidden Field",	//MISSING
+Button			: "Button",	//MISSING
+SelectionField	: "Selection Field",	//MISSING
+ImageButton		: "Image Button",	//MISSING
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Холбоос засварлах",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Мөр оруулах",
+DeleteRows			: "Мөр устгах",
+InsertColumn		: "Багана оруулах",
+DeleteColumns		: "Багана устгах",
+InsertCell			: "Нүх оруулах",
+DeleteCells			: "Нүх устгах",
+MergeCells			: "Нүх нэгтэх",
+SplitCell			: "Нүх тусгайрлах",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "Хоосон зайн шинж чанар",
+TableProperties		: "Хүснэгт",
+ImageProperties		: "Зураг",
+FlashProperties		: "Flash Properties",	//MISSING
+
+AnchorProp			: "Anchor Properties",	//MISSING
+ButtonProp			: "Button Properties",	//MISSING
+CheckboxProp		: "Checkbox Properties",	//MISSING
+HiddenFieldProp		: "Hidden Field Properties",	//MISSING
+RadioButtonProp		: "Radio Button Properties",	//MISSING
+ImageButtonProp		: "Image Button Properties",	//MISSING
+TextFieldProp		: "Text Field Properties",	//MISSING
+SelectionFieldProp	: "Selection Field Properties",	//MISSING
+TextareaProp		: "Textarea Properties",	//MISSING
+FormProp			: "Form Properties",	//MISSING
+
+FontFormats			: "Хэвийн;Formatted;Хаяг;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Paragraph (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML үйл явц явагдаж байна. Хүлээнэ үү...",
+Done				: "Хийх",
+PasteWordConfirm	: "Word-оос хуулсан текстээ санаж байгааг нь буулгахыг та хүсч байна уу. Та текст-ээ буулгахын өмнө цэвэрлэх үү?",
+NotCompatiblePaste	: "Энэ комманд Internet Explorer-ын 5.5 буюу түүнээс дээш хувилбарт идвэхшинэ. Та цэвэрлэхгүйгээр буулгахыг хүсч байна?",
+UnknownToolbarItem	: "Багажны хэсгийн \"%1\" item мэдэгдэхгүй байна",
+UnknownCommand		: "\"%1\" комманд нэр мэдагдэхгүй байна",
+NotImplemented		: "Зөвшөөрөгдөхгүй комманд",
+UnknownToolbarSet	: "Багажны хэсэгт \"%1\" оноох, үүсээгүй байна",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Болих",
+DlgBtnClose			: "Хаах",
+DlgBtnBrowseServer	: "Browse Server",	//MISSING
+DlgAdvancedTag		: "Нэмэлт",
+DlgOpOther			: "<Other>",	//MISSING
+DlgInfoTab			: "Info",	//MISSING
+DlgAlertUrl			: "Please insert the URL",	//MISSING
+
+// General Dialogs Labels
+DlgGenNotSet		: "<Оноохгүй>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Хэлний чиглэл",
+DlgGenLangDirLtr	: "Зүүнээс баруун (LTR)",
+DlgGenLangDirRtl	: "Баруунаас зүүн (RTL)",
+DlgGenLangCode		: "Хэлний код",
+DlgGenAccessKey		: "Холбох түлхүүр",
+DlgGenName			: "Нэр",
+DlgGenTabIndex		: "Tab индекс",
+DlgGenLongDescr		: "URL-ын тайлбар",
+DlgGenClass			: "Stylesheet классууд",
+DlgGenTitle			: "Зөвлөлдөх гарчиг",
+DlgGenContType		: "Зөвлөлдөх төрлийн агуулга",
+DlgGenLinkCharset	: "Тэмдэгт оноох нөөцөд холбогдсон",
+DlgGenStyle			: "Загвар",
+
+// Image Dialog
+DlgImgTitle			: "Зураг",
+DlgImgInfoTab		: "Зурагны мэдээлэл",
+DlgImgBtnUpload		: "Үүнийг сервэррүү илгээ",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Хуулах",
+DlgImgAlt			: "Тайлбар текст",
+DlgImgWidth			: "Өргөн",
+DlgImgHeight		: "Өндөр",
+DlgImgLockRatio		: "Lock Ratio",
+DlgBtnResetSize		: "хэмжээ дахин оноох",
+DlgImgBorder		: "Хүрээ",
+DlgImgHSpace		: "Хөндлөн зай",
+DlgImgVSpace		: "Босоо зай",
+DlgImgAlign			: "Эгнээ",
+DlgImgAlignLeft		: "Зүүн",
+DlgImgAlignAbsBottom: "Abs доод талд",
+DlgImgAlignAbsMiddle: "Abs Дунд талд",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Доод талд",
+DlgImgAlignMiddle	: "Дунд талд",
+DlgImgAlignRight	: "Баруун",
+DlgImgAlignTextTop	: "Текст дээр",
+DlgImgAlignTop		: "Дээд талд",
+DlgImgPreview		: "Уридчлан харах",
+DlgImgAlertUrl		: "Зурагны URL-ын төрлийн сонгоно уу",
+DlgImgLinkTab		: "Link",	//MISSING
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",	//MISSING
+DlgFlashChkPlay		: "Auto Play",	//MISSING
+DlgFlashChkLoop		: "Loop",	//MISSING
+DlgFlashChkMenu		: "Enable Flash Menu",	//MISSING
+DlgFlashScale		: "Scale",	//MISSING
+DlgFlashScaleAll	: "Show all",	//MISSING
+DlgFlashScaleNoBorder	: "No Border",	//MISSING
+DlgFlashScaleFit	: "Exact Fit",	//MISSING
+
+// Link Dialog
+DlgLnkWindowTitle	: "Линк",
+DlgLnkInfoTab		: "Линкийн мэдээлэл",
+DlgLnkTargetTab		: "Байрлал",
+
+DlgLnkType			: "Линкийн төрөл",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Энэ хуудасандах холбоос",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Протокол",
+DlgLnkProtoOther	: "<бусад>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Холбоос сонгох",
+DlgLnkAnchorByName	: "Холбоосын нэрээр",
+DlgLnkAnchorById	: "Элемэнт Id-гаар",
+DlgLnkNoAnchors		: "<Баримт бичиг холбоосгүй байна>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Хаяг",
+DlgLnkEMailSubject	: "Message Subject",
+DlgLnkEMailBody		: "Message-ийн агуулга",
+DlgLnkUpload		: "Хуулах",
+DlgLnkBtnUpload		: "Үүнийг серверрүү илгээ",
+
+DlgLnkTarget		: "Байрлал",
+DlgLnkTargetFrame	: "<Агуулах хүрээ>",
+DlgLnkTargetPopup	: "<popup цонх>",
+DlgLnkTargetBlank	: "Шинэ цонх (_blank)",
+DlgLnkTargetParent	: "Эцэг цонх (_parent)",
+DlgLnkTargetSelf	: "Төстэй цонх (_self)",
+DlgLnkTargetTop		: "Хамгийн түрүүн байх цонх (_top)",
+DlgLnkTargetFrameName	: "Target Frame Name",	//MISSING
+DlgLnkPopWinName	: "Popup цонхны нэр",
+DlgLnkPopWinFeat	: "Popup цонхны онцлог",
+DlgLnkPopResize		: "Хэмжээ өөрчлөх",
+DlgLnkPopLocation	: "Location хэсэг",
+DlgLnkPopMenu		: "Meню хэсэг",
+DlgLnkPopScroll		: "Скрол хэсэгүүд",
+DlgLnkPopStatus		: "Статус хэсэг",
+DlgLnkPopToolbar	: "Багажны хэсэг",
+DlgLnkPopFullScrn	: "Цонх дүүргэх (IE)",
+DlgLnkPopDependent	: "Хамаатай (Netscape)",
+DlgLnkPopWidth		: "Өргөн",
+DlgLnkPopHeight		: "Өндөр",
+DlgLnkPopLeft		: "Зүүн байрлал",
+DlgLnkPopTop		: "Дээд байрлал",
+
+DlnLnkMsgNoUrl		: "Линк URL-ээ төрөлжүүлнэ үү",
+DlnLnkMsgNoEMail	: "Е-mail хаягаа төрөлжүүлнэ үү",
+DlnLnkMsgNoAnchor	: "Холбоосоо сонгоно уу",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Өнгө сонгох",
+DlgColorBtnClear	: "Цэвэрлэх",
+DlgColorHighlight	: "Өнгө",
+DlgColorSelected	: "Сонгогдсон",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Тодорхойлолт оруулах",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Онцгой тэмдэгт сонгох",
+
+// Table Dialog
+DlgTableTitle		: "Хүснэгт",
+DlgTableRows		: "Мөр",
+DlgTableColumns		: "Багана",
+DlgTableBorder		: "Хүрээний хэмжээ",
+DlgTableAlign		: "Эгнээ",
+DlgTableAlignNotSet	: "<Оноохгүй>",
+DlgTableAlignLeft	: "Зүүн талд",
+DlgTableAlignCenter	: "Төвд",
+DlgTableAlignRight	: "Баруун талд",
+DlgTableWidth		: "Өргөн",
+DlgTableWidthPx		: "цэг",
+DlgTableWidthPc		: "хувь",
+DlgTableHeight		: "Өндөр",
+DlgTableCellSpace	: "Нүх хоорондын зай",
+DlgTableCellPad		: "Нүх доторлох",
+DlgTableCaption		: "Тайлбар",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "Хоосон зайн шинж чанар",
+DlgCellWidth		: "Өргөн",
+DlgCellWidthPx		: "цэг",
+DlgCellWidthPc		: "хувь",
+DlgCellHeight		: "Өндөр",
+DlgCellWordWrap		: "Үг таслах",
+DlgCellWordWrapNotSet	: "<Оноохгүй>",
+DlgCellWordWrapYes	: "Тийм",
+DlgCellWordWrapNo	: "Үгүй",
+DlgCellHorAlign		: "Босоо эгнээ",
+DlgCellHorAlignNotSet	: "<Оноохгүй>",
+DlgCellHorAlignLeft	: "Зүүн",
+DlgCellHorAlignCenter	: "Төв",
+DlgCellHorAlignRight: "Баруун",
+DlgCellVerAlign		: "Хөндлөн эгнээ",
+DlgCellVerAlignNotSet	: "<Оноохгүй>",
+DlgCellVerAlignTop	: "Дээд тал",
+DlgCellVerAlignMiddle	: "Дунд",
+DlgCellVerAlignBottom	: "Доод тал",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Нийт мөр",
+DlgCellCollSpan		: "Нийт багана",
+DlgCellBackColor	: "Фонны өнгө",
+DlgCellBorderColor	: "Хүрээний өнгө",
+DlgCellBtnSelect	: "Сонго...",
+
+// Find Dialog
+DlgFindTitle		: "Хайх",
+DlgFindFindBtn		: "Хайх",
+DlgFindNotFoundMsg	: "Хайсан текст олсонгүй.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Солих",
+DlgReplaceFindLbl		: "Хайх үг/үсэг:",
+DlgReplaceReplaceLbl	: "Солих үг:",
+DlgReplaceCaseChk		: "Тэнцэх төлөв",
+DlgReplaceReplaceBtn	: "Солих",
+DlgReplaceReplAllBtn	: "Бүгдийг нь Солих",
+DlgReplaceWordChk		: "Тэнцэх бүтэн үг",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хайчлах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl+X) товчны хослолыг ашиглана уу.",
+PasteErrorCopy	: "Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хуулах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl+C) товчны хослолыг ашиглана уу.",
+
+PasteAsText		: "Plain Text-ээс буулгах",
+PasteFromWord	: "Word-оос буулгах",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.",	//MISSING
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",	//MISSING
+DlgPasteRemoveStyles	: "Remove Styles definitions",	//MISSING
+DlgPasteCleanBox		: "Clean Up Box",	//MISSING
+
+// Color Picker
+ColorAutomatic	: "Автоматаар",
+ColorMoreColors	: "Нэмэлт өнгөнүүд...",
+
+// Document Properties
+DocProps		: "Document Properties",	//MISSING
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anchor Properties",	//MISSING
+DlgAnchorName		: "Anchor Name",	//MISSING
+DlgAnchorErrorName	: "Please type the anchor name",	//MISSING
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Not in dictionary",	//MISSING
+DlgSpellChangeTo		: "Change to",	//MISSING
+DlgSpellBtnIgnore		: "Ignore",	//MISSING
+DlgSpellBtnIgnoreAll	: "Ignore All",	//MISSING
+DlgSpellBtnReplace		: "Replace",	//MISSING
+DlgSpellBtnReplaceAll	: "Replace All",	//MISSING
+DlgSpellBtnUndo			: "Undo",	//MISSING
+DlgSpellNoSuggestions	: "- No suggestions -",	//MISSING
+DlgSpellProgress		: "Spell check in progress...",	//MISSING
+DlgSpellNoMispell		: "Spell check complete: No misspellings found",	//MISSING
+DlgSpellNoChanges		: "Spell check complete: No words changed",	//MISSING
+DlgSpellOneChange		: "Spell check complete: One word changed",	//MISSING
+DlgSpellManyChanges		: "Spell check complete: %1 words changed",	//MISSING
+
+IeSpellDownload			: "Spell checker not installed. Do you want to download it now?",	//MISSING
+
+// Button Dialog
+DlgButtonText		: "Text (Value)",	//MISSING
+DlgButtonType		: "Type",	//MISSING
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",	//MISSING
+DlgCheckboxValue	: "Value",	//MISSING
+DlgCheckboxSelected	: "Selected",	//MISSING
+
+// Form Dialog
+DlgFormName		: "Name",	//MISSING
+DlgFormAction	: "Action",	//MISSING
+DlgFormMethod	: "Method",	//MISSING
+
+// Select Field Dialog
+DlgSelectName		: "Name",	//MISSING
+DlgSelectValue		: "Value",	//MISSING
+DlgSelectSize		: "Size",	//MISSING
+DlgSelectLines		: "lines",	//MISSING
+DlgSelectChkMulti	: "Allow multiple selections",	//MISSING
+DlgSelectOpAvail	: "Available Options",	//MISSING
+DlgSelectOpText		: "Text",	//MISSING
+DlgSelectOpValue	: "Value",	//MISSING
+DlgSelectBtnAdd		: "Add",	//MISSING
+DlgSelectBtnModify	: "Modify",	//MISSING
+DlgSelectBtnUp		: "Up",	//MISSING
+DlgSelectBtnDown	: "Down",	//MISSING
+DlgSelectBtnSetValue : "Set as selected value",	//MISSING
+DlgSelectBtnDelete	: "Delete",	//MISSING
+
+// Textarea Dialog
+DlgTextareaName	: "Name",	//MISSING
+DlgTextareaCols	: "Columns",	//MISSING
+DlgTextareaRows	: "Rows",	//MISSING
+
+// Text Field Dialog
+DlgTextName			: "Name",	//MISSING
+DlgTextValue		: "Value",	//MISSING
+DlgTextCharWidth	: "Character Width",	//MISSING
+DlgTextMaxChars		: "Maximum Characters",	//MISSING
+DlgTextType			: "Type",	//MISSING
+DlgTextTypeText		: "Text",	//MISSING
+DlgTextTypePass		: "Password",	//MISSING
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",	//MISSING
+DlgHiddenValue	: "Value",	//MISSING
+
+// Bulleted List Dialog
+BulletedListProp	: "Bulleted List Properties",	//MISSING
+NumberedListProp	: "Numbered List Properties",	//MISSING
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Type",	//MISSING
+DlgLstTypeCircle	: "Circle",	//MISSING
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "Square",	//MISSING
+DlgLstTypeNumbers	: "Numbers (1, 2, 3)",	//MISSING
+DlgLstTypeLCase		: "Lowercase Letters (a, b, c)",	//MISSING
+DlgLstTypeUCase		: "Uppercase Letters (A, B, C)",	//MISSING
+DlgLstTypeSRoman	: "Small Roman Numerals (i, ii, iii)",	//MISSING
+DlgLstTypeLRoman	: "Large Roman Numerals (I, II, III)",	//MISSING
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",	//MISSING
+DlgDocBackTab		: "Background",	//MISSING
+DlgDocColorsTab		: "Colors and Margins",	//MISSING
+DlgDocMetaTab		: "Meta Data",	//MISSING
+
+DlgDocPageTitle		: "Page Title",	//MISSING
+DlgDocLangDir		: "Language Direction",	//MISSING
+DlgDocLangDirLTR	: "Left to Right (LTR)",	//MISSING
+DlgDocLangDirRTL	: "Right to Left (RTL)",	//MISSING
+DlgDocLangCode		: "Language Code",	//MISSING
+DlgDocCharSet		: "Character Set Encoding",	//MISSING
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Other Character Set Encoding",	//MISSING
+
+DlgDocDocType		: "Document Type Heading",	//MISSING
+DlgDocDocTypeOther	: "Other Document Type Heading",	//MISSING
+DlgDocIncXHTML		: "Include XHTML Declarations",	//MISSING
+DlgDocBgColor		: "Background Color",	//MISSING
+DlgDocBgImage		: "Background Image URL",	//MISSING
+DlgDocBgNoScroll	: "Nonscrolling Background",	//MISSING
+DlgDocCText			: "Text",	//MISSING
+DlgDocCLink			: "Link",	//MISSING
+DlgDocCVisited		: "Visited Link",	//MISSING
+DlgDocCActive		: "Active Link",	//MISSING
+DlgDocMargins		: "Page Margins",	//MISSING
+DlgDocMaTop			: "Top",	//MISSING
+DlgDocMaLeft		: "Left",	//MISSING
+DlgDocMaRight		: "Right",	//MISSING
+DlgDocMaBottom		: "Bottom",	//MISSING
+DlgDocMeIndex		: "Document Indexing Keywords (comma separated)",	//MISSING
+DlgDocMeDescr		: "Document Description",	//MISSING
+DlgDocMeAuthor		: "Author",	//MISSING
+DlgDocMeCopy		: "Copyright",	//MISSING
+DlgDocPreview		: "Preview",	//MISSING
+
+// Templates Dialog
+Templates			: "Templates",	//MISSING
+DlgTemplatesTitle	: "Content Templates",	//MISSING
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br />(the actual contents will be lost):",	//MISSING
+DlgTemplatesLoading	: "Loading templates list. Please wait...",	//MISSING
+DlgTemplatesNoTpl	: "(No templates defined)",	//MISSING
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "About",	//MISSING
+DlgAboutBrowserInfoTab	: "Browser Info",	//MISSING
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "Хувилбар",
+DlgAboutInfo		: "Мэдээллээр туслах"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pl.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pl.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Polish language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Zwiń pasek narzędzi",
+ToolbarExpand		: "Rozwiń pasek narzędzi",
+
+// Toolbar Items and Context Menu
+Save				: "Zapisz",
+NewPage				: "Nowa strona",
+Preview				: "Podgląd",
+Cut					: "Wytnij",
+Copy				: "Kopiuj",
+Paste				: "Wklej",
+PasteText			: "Wklej jako czysty tekst",
+PasteWord			: "Wklej z Worda",
+Print				: "Drukuj",
+SelectAll			: "Zaznacz wszystko",
+RemoveFormat		: "Usuń formatowanie",
+InsertLinkLbl		: "Hiperłącze",
+InsertLink			: "Wstaw/edytuj hiperłącze",
+RemoveLink			: "Usuń hiperłącze",
+Anchor				: "Wstaw/edytuj kotwicę",
+InsertImageLbl		: "Obrazek",
+InsertImage			: "Wstaw/edytuj obrazek",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Dodaj/Edytuj element Flash",
+InsertTableLbl		: "Tabela",
+InsertTable			: "Wstaw/edytuj tabelę",
+InsertLineLbl		: "Linia pozioma",
+InsertLine			: "Wstaw poziomą linię",
+InsertSpecialCharLbl: "Znak specjalny",
+InsertSpecialChar	: "Wstaw znak specjalny",
+InsertSmileyLbl		: "Emotikona",
+InsertSmiley		: "Wstaw emotikonę",
+About				: "O programie FCKeditor",
+Bold				: "Pogrubienie",
+Italic				: "Kursywa",
+Underline			: "Podkreślenie",
+StrikeThrough		: "Przekreślenie",
+Subscript			: "Indeks dolny",
+Superscript			: "Indeks górny",
+LeftJustify			: "Wyrównaj do lewej",
+CenterJustify		: "Wyrównaj do środka",
+RightJustify		: "Wyrównaj do prawej",
+BlockJustify		: "Wyrównaj do lewej i prawej",
+DecreaseIndent		: "Zmniejsz wcięcie",
+IncreaseIndent		: "Zwiększ wcięcie",
+Undo				: "Cofnij",
+Redo				: "Ponów",
+NumberedListLbl		: "Lista numerowana",
+NumberedList		: "Wstaw/usuń numerowanie listy",
+BulletedListLbl		: "Lista wypunktowana",
+BulletedList		: "Wstaw/usuń wypunktowanie listy",
+ShowTableBorders	: "Pokazuj ramkę tabeli",
+ShowDetails			: "Pokaż szczegóły",
+Style				: "Styl",
+FontFormat			: "Format",
+Font				: "Czcionka",
+FontSize			: "Rozmiar",
+TextColor			: "Kolor tekstu",
+BGColor				: "Kolor tła",
+Source				: "Źródło dokumentu",
+Find				: "Znajdź",
+Replace				: "Zamień",
+SpellCheck			: "Sprawdź pisownię",
+UniversalKeyboard	: "Klawiatura Uniwersalna",
+PageBreakLbl		: "Odstęp",
+PageBreak			: "Wstaw odstęp",
+
+Form			: "Formularz",
+Checkbox		: "Checkbox",
+RadioButton		: "Pole wyboru",
+TextField		: "Pole tekstowe",
+Textarea		: "Obszar tekstowy",
+HiddenField		: "Pole ukryte",
+Button			: "Przycisk",
+SelectionField	: "Lista wyboru",
+ImageButton		: "Przycisk obrazek",
+
+FitWindow		: "Maksymalizuj rozmiar edytora",
+
+// Context Menu
+EditLink			: "Edytuj hiperłącze",
+CellCM				: "Komórka",
+RowCM				: "Wiersz",
+ColumnCM			: "Kolumna",
+InsertRow			: "Wstaw wiersz",
+DeleteRows			: "Usuń wiersze",
+InsertColumn		: "Wstaw kolumnę",
+DeleteColumns		: "Usuń kolumny",
+InsertCell			: "Wstaw komórkę",
+DeleteCells			: "Usuń komórki",
+MergeCells			: "Połącz komórki",
+SplitCell			: "Podziel komórkę",
+TableDelete			: "Usuń tabelę",
+CellProperties		: "Właściwości komórki",
+TableProperties		: "Właściwości tabeli",
+ImageProperties		: "Właściwości obrazka",
+FlashProperties		: "Właściwości elementu Flash",
+
+AnchorProp			: "Właściwości kotwicy",
+ButtonProp			: "Właściwości przycisku",
+CheckboxProp		: "Checkbox - właściwości",
+HiddenFieldProp		: "Właściwości pola ukrytego",
+RadioButtonProp		: "Właściwości pola wyboru",
+ImageButtonProp		: "Właściwości przycisku obrazka",
+TextFieldProp		: "Właściwości pola tekstowego",
+SelectionFieldProp	: "Właściwości listy wyboru",
+TextareaProp		: "Właściwości obszaru tekstowego",
+FormProp			: "Właściwości formularza",
+
+FontFormats			: "Normalny;Tekst sformatowany;Adres;Nagłówek 1;Nagłówek 2;Nagłówek 3;Nagłówek 4;Nagłówek 5;Nagłówek 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Przetwarzanie XHTML. Proszę czekać...",
+Done				: "Gotowe",
+PasteWordConfirm	: "Tekst, który chcesz wkleić, prawdopodobnie pochodzi z programu Word. Czy chcesz go wyczyścic przed wklejeniem?",
+NotCompatiblePaste	: "Ta funkcja jest dostępna w programie Internet Explorer w wersji 5.5 lub wyższej. Czy chcesz wkleić tekst bez czyszczenia?",
+UnknownToolbarItem	: "Nieznany element paska narzędzi \"%1\"",
+UnknownCommand		: "Nieznana komenda \"%1\"",
+NotImplemented		: "Komenda niezaimplementowana",
+UnknownToolbarSet	: "Pasek narzędzi \"%1\" nie istnieje",
+NoActiveX			: "Ustawienia zabezpieczeń twojej przeglądarki mogą ograniczyć niektóre funkcje edytora. Musisz włączyć opcję \"Uruchamianie formantów Activex i dodatków plugin\". W przeciwnym wypadku mogą pojawiać się błędy.",
+BrowseServerBlocked : "Okno menadżera plików nie może zostać otwarte. Upewnij się, że wszystkie blokady popup są wyłączone.",
+DialogBlocked		: "Nie można otworzyć okna dialogowego. Upewnij się, że wszystkie blokady popup są wyłączone.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Anuluj",
+DlgBtnClose			: "Zamknij",
+DlgBtnBrowseServer	: "Przeglądaj",
+DlgAdvancedTag		: "Zaawansowane",
+DlgOpOther			: "<Inny>",
+DlgInfoTab			: "Informacje",
+DlgAlertUrl			: "Proszę podać URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nieustawione>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Kierunek tekstu",
+DlgGenLangDirLtr	: "Od lewej do prawej (LTR)",
+DlgGenLangDirRtl	: "Od prawej do lewej (RTL)",
+DlgGenLangCode		: "Kod języka",
+DlgGenAccessKey		: "Klawisz dostępu",
+DlgGenName			: "Nazwa",
+DlgGenTabIndex		: "Indeks tabeli",
+DlgGenLongDescr		: "Long Description URL",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Styl",
+
+// Image Dialog
+DlgImgTitle			: "Właściwości obrazka",
+DlgImgInfoTab		: "Informacje o obrazku",
+DlgImgBtnUpload		: "Syślij",
+DlgImgURL			: "Adres URL",
+DlgImgUpload		: "Wyślij",
+DlgImgAlt			: "Tekst zastępczy",
+DlgImgWidth			: "Szerokość",
+DlgImgHeight		: "Wysokość",
+DlgImgLockRatio		: "Zablokuj proporcje",
+DlgBtnResetSize		: "Przywróć rozmiar",
+DlgImgBorder		: "Ramka",
+DlgImgHSpace		: "Odstęp poziomy",
+DlgImgVSpace		: "Odstęp pionowy",
+DlgImgAlign			: "Wyrównaj",
+DlgImgAlignLeft		: "Do lewej",
+DlgImgAlignAbsBottom: "Do dołu",
+DlgImgAlignAbsMiddle: "Do środka w pionie",
+DlgImgAlignBaseline	: "Do linii bazowej",
+DlgImgAlignBottom	: "Do dołu",
+DlgImgAlignMiddle	: "Do środka",
+DlgImgAlignRight	: "Do prawej",
+DlgImgAlignTextTop	: "Do góry tekstu",
+DlgImgAlignTop		: "Do góry",
+DlgImgPreview		: "Podgląd",
+DlgImgAlertUrl		: "Podaj adres obrazka.",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Właściwości elementu Flash",
+DlgFlashChkPlay		: "Auto Odtwarzanie",
+DlgFlashChkLoop		: "Pętla",
+DlgFlashChkMenu		: "Włącz menu",
+DlgFlashScale		: "Skaluj",
+DlgFlashScaleAll	: "Pokaż wszystko",
+DlgFlashScaleNoBorder	: "Bez Ramki",
+DlgFlashScaleFit	: "Dokładne dopasowanie",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Hiperłącze",
+DlgLnkInfoTab		: "Informacje ",
+DlgLnkTargetTab		: "Cel",
+
+DlgLnkType			: "Typ hiperłącza",
+DlgLnkTypeURL		: "Adres URL",
+DlgLnkTypeAnchor	: "Odnośnik wewnątrz strony",
+DlgLnkTypeEMail		: "Adres e-mail",
+DlgLnkProto			: "Protokół",
+DlgLnkProtoOther	: "<inny>",
+DlgLnkURL			: "Adres URL",
+DlgLnkAnchorSel		: "Wybierz etykietę",
+DlgLnkAnchorByName	: "Wg etykiety",
+DlgLnkAnchorById	: "Wg identyfikatora elementu",
+DlgLnkNoAnchors		: "<W dokumencie nie zdefiniowano żadnych etykiet>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Adres e-mail",
+DlgLnkEMailSubject	: "Temat",
+DlgLnkEMailBody		: "Treść",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Wyślij",
+
+DlgLnkTarget		: "Cel",
+DlgLnkTargetFrame	: "<ramka>",
+DlgLnkTargetPopup	: "<wyskakujące okno>",
+DlgLnkTargetBlank	: "Nowe okno (_blank)",
+DlgLnkTargetParent	: "Okno nadrzędne (_parent)",
+DlgLnkTargetSelf	: "To samo okno (_self)",
+DlgLnkTargetTop		: "Okno najwyższe w hierarchii (_top)",
+DlgLnkTargetFrameName	: "Nazwa Ramki Docelowej",
+DlgLnkPopWinName	: "Nazwa wyskakującego okna",
+DlgLnkPopWinFeat	: "Właściwości wyskakującego okna",
+DlgLnkPopResize		: "Możliwa zmiana rozmiaru",
+DlgLnkPopLocation	: "Pasek adresu",
+DlgLnkPopMenu		: "Pasek menu",
+DlgLnkPopScroll		: "Paski przewijania",
+DlgLnkPopStatus		: "Pasek statusu",
+DlgLnkPopToolbar	: "Pasek narzędzi",
+DlgLnkPopFullScrn	: "Pełny ekran (IE)",
+DlgLnkPopDependent	: "Okno zależne (Netscape)",
+DlgLnkPopWidth		: "Szerokość",
+DlgLnkPopHeight		: "Wysokość",
+DlgLnkPopLeft		: "Pozycja w poziomie",
+DlgLnkPopTop		: "Pozycja w pionie",
+
+DlnLnkMsgNoUrl		: "Podaj adres URL",
+DlnLnkMsgNoEMail	: "Podaj adres e-mail",
+DlnLnkMsgNoAnchor	: "Wybierz etykietę",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Wybierz kolor",
+DlgColorBtnClear	: "Wyczyść",
+DlgColorHighlight	: "Podgląd",
+DlgColorSelected	: "Wybrane",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Wstaw emotikonę",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Wybierz znak specjalny",
+
+// Table Dialog
+DlgTableTitle		: "Właściwości tabeli",
+DlgTableRows		: "Liczba wierszy",
+DlgTableColumns		: "Liczba kolumn",
+DlgTableBorder		: "Grubość ramki",
+DlgTableAlign		: "Wyrównanie",
+DlgTableAlignNotSet	: "<brak ustawień>",
+DlgTableAlignLeft	: "Do lewej",
+DlgTableAlignCenter	: "Do środka",
+DlgTableAlignRight	: "Do prawej",
+DlgTableWidth		: "Szerokość",
+DlgTableWidthPx		: "piksele",
+DlgTableWidthPc		: "%",
+DlgTableHeight		: "Wysokość",
+DlgTableCellSpace	: "Odstęp pomiędzy komórkami",
+DlgTableCellPad		: "Margines wewnętrzny komórek",
+DlgTableCaption		: "Tytuł",
+DlgTableSummary		: "Podsumowanie",
+
+// Table Cell Dialog
+DlgCellTitle		: "Właściwości komórki",
+DlgCellWidth		: "Szerokość",
+DlgCellWidthPx		: "piksele",
+DlgCellWidthPc		: "%",
+DlgCellHeight		: "Wysokość",
+DlgCellWordWrap		: "Zawijanie tekstu",
+DlgCellWordWrapNotSet	: "<brak ustawień>",
+DlgCellWordWrapYes	: "Tak",
+DlgCellWordWrapNo	: "Nie",
+DlgCellHorAlign		: "Wyrównanie poziome",
+DlgCellHorAlignNotSet	: "<brak ustawień>",
+DlgCellHorAlignLeft	: "Do lewej",
+DlgCellHorAlignCenter	: "Do środka",
+DlgCellHorAlignRight: "Do prawej",
+DlgCellVerAlign		: "Wyrównanie pionowe",
+DlgCellVerAlignNotSet	: "<brak ustawień>",
+DlgCellVerAlignTop	: "Do góry",
+DlgCellVerAlignMiddle	: "Do środka",
+DlgCellVerAlignBottom	: "Do dołu",
+DlgCellVerAlignBaseline	: "Do linii bazowej",
+DlgCellRowSpan		: "Zajętość wierszy",
+DlgCellCollSpan		: "Zajętość kolumn",
+DlgCellBackColor	: "Kolor tła",
+DlgCellBorderColor	: "Kolor ramki",
+DlgCellBtnSelect	: "Wybierz...",
+
+// Find Dialog
+DlgFindTitle		: "Znajdź",
+DlgFindFindBtn		: "Znajdź",
+DlgFindNotFoundMsg	: "Nie znaleziono szukanego hasła.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Zamień",
+DlgReplaceFindLbl		: "Znajdź:",
+DlgReplaceReplaceLbl	: "Zastąp przez:",
+DlgReplaceCaseChk		: "Uwzględnij wielkość liter",
+DlgReplaceReplaceBtn	: "Zastąp",
+DlgReplaceReplAllBtn	: "Zastąp wszystko",
+DlgReplaceWordChk		: "Całe słowa",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne wycinanie tekstu. Użyj skrótu klawiszowego Ctrl+X.",
+PasteErrorCopy	: "Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne kopiowanie tekstu. Użyj skrótu klawiszowego Ctrl+C.",
+
+PasteAsText		: "Wklej jako czysty tekst",
+PasteFromWord	: "Wklej z Worda",
+
+DlgPasteMsg2	: "Proszę wkleić w poniższym polu używając klawiaturowego skrótu (<STRONG>Ctrl+V</STRONG>) i kliknąć <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoruj definicje 'Font Face'",
+DlgPasteRemoveStyles	: "Usuń definicje Stylów",
+DlgPasteCleanBox		: "Wyczyść",
+
+// Color Picker
+ColorAutomatic	: "Automatycznie",
+ColorMoreColors	: "Więcej kolorów...",
+
+// Document Properties
+DocProps		: "Właściwości dokumentu",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Właściwości kotwicy",
+DlgAnchorName		: "Nazwa kotwicy",
+DlgAnchorErrorName	: "Wpisz nazwę kotwicy",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Słowa nie ma w słowniku",
+DlgSpellChangeTo		: "Zmień na",
+DlgSpellBtnIgnore		: "Ignoruj",
+DlgSpellBtnIgnoreAll	: "Ignoruj wszystkie",
+DlgSpellBtnReplace		: "Zmień",
+DlgSpellBtnReplaceAll	: "Zmień wszystkie",
+DlgSpellBtnUndo			: "Undo",
+DlgSpellNoSuggestions	: "- Brak sugestii -",
+DlgSpellProgress		: "Trwa sprawdzanie ...",
+DlgSpellNoMispell		: "Sprawdzanie zakończone: nie znaleziono błędów",
+DlgSpellNoChanges		: "Sprawdzanie zakończone: nie zmieniono żadnego słowa",
+DlgSpellOneChange		: "Sprawdzanie zakończone: zmieniono jedno słowo",
+DlgSpellManyChanges		: "Sprawdzanie zakończone: zmieniono %l słów",
+
+IeSpellDownload			: "Słownik nie jest zainstalowany. Chcesz go ściągnąć?",
+
+// Button Dialog
+DlgButtonText		: "Tekst (Wartość)",
+DlgButtonType		: "Typ",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nazwa",
+DlgCheckboxValue	: "Wartość",
+DlgCheckboxSelected	: "Zaznaczony",
+
+// Form Dialog
+DlgFormName		: "Nazwa",
+DlgFormAction	: "Akcja",
+DlgFormMethod	: "Metoda",
+
+// Select Field Dialog
+DlgSelectName		: "Nazwa",
+DlgSelectValue		: "Wartość",
+DlgSelectSize		: "Rozmiar",
+DlgSelectLines		: "linii",
+DlgSelectChkMulti	: "Wielokrotny wybór",
+DlgSelectOpAvail	: "Dostępne opcje",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Wartość",
+DlgSelectBtnAdd		: "Dodaj",
+DlgSelectBtnModify	: "Zmień",
+DlgSelectBtnUp		: "Do góry",
+DlgSelectBtnDown	: "Do dołu",
+DlgSelectBtnSetValue : "Ustaw wartość zaznaczoną",
+DlgSelectBtnDelete	: "Usuń",
+
+// Textarea Dialog
+DlgTextareaName	: "Nazwa",
+DlgTextareaCols	: "Kolumnu",
+DlgTextareaRows	: "Wiersze",
+
+// Text Field Dialog
+DlgTextName			: "Nazwa",
+DlgTextValue		: "Wartość",
+DlgTextCharWidth	: "Szerokość w znakach",
+DlgTextMaxChars		: "Max. szerokość",
+DlgTextType			: "Typ",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Hasło",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nazwa",
+DlgHiddenValue	: "Wartość",
+
+// Bulleted List Dialog
+BulletedListProp	: "Właściwości listy punktowanej",
+NumberedListProp	: "Właściwości listy numerowanej",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Typ",
+DlgLstTypeCircle	: "Koło",
+DlgLstTypeDisc		: "Dysk",
+DlgLstTypeSquare	: "Kwadrat",
+DlgLstTypeNumbers	: "Cyfry (1, 2, 3)",
+DlgLstTypeLCase		: "Małe litery (a, b, c)",
+DlgLstTypeUCase		: "Duże litery (A, B, C)",
+DlgLstTypeSRoman	: "Numeracja rzymska (i, ii, iii)",
+DlgLstTypeLRoman	: "Numeracja rzymska (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Ogólne",
+DlgDocBackTab		: "Tło",
+DlgDocColorsTab		: "Kolory i marginesy",
+DlgDocMetaTab		: "Meta Dane",
+
+DlgDocPageTitle		: "Tytuł strony",
+DlgDocLangDir		: "Kierunek pisania",
+DlgDocLangDirLTR	: "Od lewej do prawej (LTR)",
+DlgDocLangDirRTL	: "Od prawej do lewej (RTL)",
+DlgDocLangCode		: "Kod języka",
+DlgDocCharSet		: "Kodowanie znaków",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Inne kodowanie znaków",
+
+DlgDocDocType		: "Nagłowek typu dokumentu",
+DlgDocDocTypeOther	: "Inny typ dokumentu",
+DlgDocIncXHTML		: "Dołącz deklarację XHTML",
+DlgDocBgColor		: "Kolor tła",
+DlgDocBgImage		: "Obrazek tła",
+DlgDocBgNoScroll	: "Tło nieruchome",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Hiperłącze",
+DlgDocCVisited		: "Odwiedzane hiperłącze",
+DlgDocCActive		: "Aktywne hiperłącze",
+DlgDocMargins		: "Marginesy strony",
+DlgDocMaTop			: "Górny",
+DlgDocMaLeft		: "Lewy",
+DlgDocMaRight		: "Prawy",
+DlgDocMaBottom		: "Dolny",
+DlgDocMeIndex		: "Słowa kluczowe (oddzielone przecinkami)",
+DlgDocMeDescr		: "Opis dokumentu",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Podgląd",
+
+// Templates Dialog
+Templates			: "Sablony",
+DlgTemplatesTitle	: "Szablony zawartości",
+DlgTemplatesSelMsg	: "Wybierz szablon do otwarcia w edytorze<br>(obecna zawartość okna edytora zostanie utracona):",
+DlgTemplatesLoading	: "Ładowanie listy szablonów. Proszę czekać...",
+DlgTemplatesNoTpl	: "(Brak zdefiniowanych szablonów)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "O ...",
+DlgAboutBrowserInfoTab	: "O przeglądarce",
+DlgAboutLicenseTab	: "Licencja",
+DlgAboutVersion		: "wersja",
+DlgAboutInfo		: "Więcej informacji uzyskasz pod adresem"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/th.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/th.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/th.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Thai language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "ซ่อนแถบเครื่องมือ",
+ToolbarExpand		: "แสดงแถบเครื่องมือ",
+
+// Toolbar Items and Context Menu
+Save				: "บันทึก",
+NewPage				: "สร้างหน้าเอกสารใหม่",
+Preview				: "ดูหน้าเอกสารตัวอย่าง",
+Cut					: "ตัด",
+Copy				: "สำเนา",
+Paste				: "วาง",
+PasteText			: "วางสำเนาจากตัวอักษรธรรมดา",
+PasteWord			: "วางสำเนาจากตัวอักษรเวิร์ด",
+Print				: "สั่งพิมพ์",
+SelectAll			: "เลือกทั้งหมด",
+RemoveFormat		: "ล้างรูปแบบ",
+InsertLinkLbl		: "ลิงค์เชื่อมโยงเว็บ อีเมล์ รูปภาพ หรือไฟล์อื่นๆ",
+InsertLink			: "แทรก/แก้ไข ลิงค์",
+RemoveLink			: "ลบ ลิงค์",
+Anchor				: "แทรก/แก้ไข Anchor",
+InsertImageLbl		: "รูปภาพ",
+InsertImage			: "แทรก/แก้ไข รูปภาพ",
+InsertFlashLbl		: "ไฟล์ Flash",
+InsertFlash			: "แทรก/แก้ไข ไฟล์ Flash",
+InsertTableLbl		: "ตาราง",
+InsertTable			: "แทรก/แก้ไข ตาราง",
+InsertLineLbl		: "เส้นคั่นบรรทัด",
+InsertLine			: "แทรกเส้นคั่นบรรทัด",
+InsertSpecialCharLbl: "ตัวอักษรพิเศษ",
+InsertSpecialChar	: "แทรกตัวอักษรพิเศษ",
+InsertSmileyLbl		: "รูปสื่ออารมณ์",
+InsertSmiley		: "แทรกรูปสื่ออารมณ์",
+About				: "เกี่ยวกับโปรแกรม FCKeditor",
+Bold				: "ตัวหนา",
+Italic				: "ตัวเอียง",
+Underline			: "ตัวขีดเส้นใต้",
+StrikeThrough		: "ตัวขีดเส้นทับ",
+Subscript			: "ตัวห้อย",
+Superscript			: "ตัวยก",
+LeftJustify			: "จัดชิดซ้าย",
+CenterJustify		: "จัดกึ่งกลาง",
+RightJustify		: "จัดชิดขวา",
+BlockJustify		: "จัดพอดีหน้ากระดาษ",
+DecreaseIndent		: "ลดระยะย่อหน้า",
+IncreaseIndent		: "เพิ่มระยะย่อหน้า",
+Undo				: "ยกเลิกคำสั่ง",
+Redo				: "ทำซ้ำคำสั่ง",
+NumberedListLbl		: "ลำดับรายการแบบตัวเลข",
+NumberedList		: "แทรก/แก้ไข ลำดับรายการแบบตัวเลข",
+BulletedListLbl		: "ลำดับรายการแบบสัญลักษณ์",
+BulletedList		: "แทรก/แก้ไข ลำดับรายการแบบสัญลักษณ์",
+ShowTableBorders	: "แสดงขอบของตาราง",
+ShowDetails			: "แสดงรายละเอียด",
+Style				: "ลักษณะ",
+FontFormat			: "รูปแบบ",
+Font				: "แบบอักษร",
+FontSize			: "ขนาด",
+TextColor			: "สีตัวอักษร",
+BGColor				: "สีพื้นหลัง",
+Source				: "ดูรหัส HTML",
+Find				: "ค้นหา",
+Replace				: "ค้นหาและแทนที่",
+SpellCheck			: "ตรวจการสะกดคำ",
+UniversalKeyboard	: "คีย์บอร์ดหลากภาษา",
+PageBreakLbl		: "ใส่ตัวแบ่งหน้า Page Break",
+PageBreak			: "แทรกตัวแบ่งหน้า Page Break",
+
+Form			: "แบบฟอร์ม",
+Checkbox		: "เช็คบ๊อก",
+RadioButton		: "เรดิโอบัตตอน",
+TextField		: "เท็กซ์ฟิลด์",
+Textarea		: "เท็กซ์แอเรีย",
+HiddenField		: "ฮิดเดนฟิลด์",
+Button			: "ปุ่ม",
+SelectionField	: "แถบตัวเลือก",
+ImageButton		: "ปุ่มแบบรูปภาพ",
+
+FitWindow		: "ขยายขนาดตัวอีดิตเตอร์",
+
+// Context Menu
+EditLink			: "แก้ไข ลิงค์",
+CellCM				: "ช่องตาราง",
+RowCM				: "แถว",
+ColumnCM			: "คอลัมน์",
+InsertRow			: "แทรกแถว",
+DeleteRows			: "ลบแถว",
+InsertColumn		: "แทรกสดมน์",
+DeleteColumns		: "ลบสดมน์",
+InsertCell			: "แทรกช่อง",
+DeleteCells			: "ลบช่อง",
+MergeCells			: "ผสานช่อง",
+SplitCell			: "แยกช่อง",
+TableDelete			: "ลบตาราง",
+CellProperties		: "คุณสมบัติของช่อง",
+TableProperties		: "คุณสมบัติของตาราง",
+ImageProperties		: "คุณสมบัติของรูปภาพ",
+FlashProperties		: "คุณสมบัติของไฟล์ Flash",
+
+AnchorProp			: "รายละเอียด Anchor",
+ButtonProp			: "รายละเอียดของ ปุ่ม",
+CheckboxProp		: "คุณสมบัติของ เช็คบ๊อก",
+HiddenFieldProp		: "คุณสมบัติของ ฮิดเดนฟิลด์",
+RadioButtonProp		: "คุณสมบัติของ เรดิโอบัตตอน",
+ImageButtonProp		: "คุณสมบัติของ ปุ่มแบบรูปภาพ",
+TextFieldProp		: "คุณสมบัติของ เท็กซ์ฟิลด์",
+SelectionFieldProp	: "คุณสมบัติของ แถบตัวเลือก",
+TextareaProp		: "คุณสมบัติของ เท็กแอเรีย",
+FormProp			: "คุณสมบัติของ แบบฟอร์ม",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Paragraph (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "โปรแกรมกำลังทำงานด้วยเทคโนโลยี XHTML กรุณารอสักครู่...",
+Done				: "โปรแกรมทำงานเสร็จสมบูรณ์",
+PasteWordConfirm	: "ข้อมูลที่ท่านต้องการวางลงในแผ่นงาน ถูกจัดรูปแบบจากโปรแกรมเวิร์ด. ท่านต้องการล้างรูปแบบที่มาจากโปรแกรมเวิร์ดหรือไม่?",
+NotCompatiblePaste	: "คำสั่งนี้ทำงานในโปรแกรมท่องเว็บ Internet Explorer version รุ่น 5.5 หรือใหม่กว่าเท่านั้น. ท่านต้องการวางตัวอักษรโดยไม่ล้างรูปแบบที่มาจากโปรแกรมเวิร์ดหรือไม่?",
+UnknownToolbarItem	: "ไม่สามารถระบุปุ่มเครื่องมือได้ \"%1\"",
+UnknownCommand		: "ไม่สามารถระบุชื่อคำสั่งได้ \"%1\"",
+NotImplemented		: "ไม่สามารถใช้งานคำสั่งได้",
+UnknownToolbarSet	: "ไม่มีการติดตั้งชุดคำสั่งในแถบเครื่องมือ \"%1\" กรุณาติดต่อผู้ดูแลระบบ",
+NoActiveX			: "โปรแกรมท่องอินเตอร์เน็ตของท่านไม่อนุญาติให้อีดิตเตอร์ทำงาน \"Run ActiveX controls and plug-ins\". หากไม่อนุญาติให้ใช้งาน ActiveX controls ท่านจะไม่สามารถใช้งานได้อย่างเต็มประสิทธิภาพ.",
+BrowseServerBlocked : "เปิดหน้าต่างป๊อบอัพเพื่อทำงานต่อไม่ได้ กรุณาปิดเครื่องมือป้องกันป๊อบอัพในโปรแกรมท่องอินเตอร์เน็ตของท่านด้วย",
+DialogBlocked		: "เปิดหน้าต่างป๊อบอัพเพื่อทำงานต่อไม่ได้ กรุณาปิดเครื่องมือป้องกันป๊อบอัพในโปรแกรมท่องอินเตอร์เน็ตของท่านด้วย",
+
+// Dialogs
+DlgBtnOK			: "ตกลง",
+DlgBtnCancel		: "ยกเลิก",
+DlgBtnClose			: "ปิด",
+DlgBtnBrowseServer	: "เปิดหน้าต่างจัดการไฟล์อัพโหลด",
+DlgAdvancedTag		: "ขั้นสูง",
+DlgOpOther			: "<อื่นๆ>",
+DlgInfoTab			: "อินโฟ",
+DlgAlertUrl			: "กรุณาระบุ URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ไม่ระบุ>",
+DlgGenId			: "ไอดี",
+DlgGenLangDir		: "การเขียน-อ่านภาษา",
+DlgGenLangDirLtr	: "จากซ้ายไปขวา (LTR)",
+DlgGenLangDirRtl	: "จากขวามาซ้าย (RTL)",
+DlgGenLangCode		: "รหัสภาษา",
+DlgGenAccessKey		: "แอคเซส คีย์",
+DlgGenName			: "ชื่อ",
+DlgGenTabIndex		: "ลำดับของ แท็บ",
+DlgGenLongDescr		: "คำอธิบายประกอบ URL",
+DlgGenClass			: "คลาสของไฟล์กำหนดลักษณะการแสดงผล",
+DlgGenTitle			: "คำเกริ่นนำ",
+DlgGenContType		: "ชนิดของคำเกริ่นนำ",
+DlgGenLinkCharset	: "ลิงค์เชื่อมโยงไปยังชุดตัวอักษร",
+DlgGenStyle			: "ลักษณะการแสดงผล",
+
+// Image Dialog
+DlgImgTitle			: "คุณสมบัติของ รูปภาพ",
+DlgImgInfoTab		: "ข้อมูลของรูปภาพ",
+DlgImgBtnUpload		: "อัพโหลดไฟล์ไปเก็บไว้ที่เครื่องแม่ข่าย (เซิร์ฟเวอร์)",
+DlgImgURL			: "ที่อยู่อ้างอิง URL",
+DlgImgUpload		: "อัพโหลดไฟล์",
+DlgImgAlt			: "คำประกอบรูปภาพ",
+DlgImgWidth			: "ความกว้าง",
+DlgImgHeight		: "ความสูง",
+DlgImgLockRatio		: "กำหนดอัตราส่วน กว้าง-สูง แบบคงที่",
+DlgBtnResetSize		: "กำหนดรูปเท่าขนาดจริง",
+DlgImgBorder		: "ขนาดขอบรูป",
+DlgImgHSpace		: "ระยะแนวนอน",
+DlgImgVSpace		: "ระยะแนวตั้ง",
+DlgImgAlign			: "การจัดวาง",
+DlgImgAlignLeft		: "ชิดซ้าย",
+DlgImgAlignAbsBottom: "ชิดด้านล่างสุด",
+DlgImgAlignAbsMiddle: "กึ่งกลาง",
+DlgImgAlignBaseline	: "ชิดบรรทัด",
+DlgImgAlignBottom	: "ชิดด้านล่าง",
+DlgImgAlignMiddle	: "กึ่งกลางแนวตั้ง",
+DlgImgAlignRight	: "ชิดขวา",
+DlgImgAlignTextTop	: "ใต้ตัวอักษร",
+DlgImgAlignTop		: "บนสุด",
+DlgImgPreview		: "หน้าเอกสารตัวอย่าง",
+DlgImgAlertUrl		: "กรุณาระบุที่อยู่อ้างอิงออนไลน์ของไฟล์รูปภาพ (URL)",
+DlgImgLinkTab		: "ลิ้งค์",
+
+// Flash Dialog
+DlgFlashTitle		: "คุณสมบัติของไฟล์ Flash",
+DlgFlashChkPlay		: "เล่นอัตโนมัติ Auto Play",
+DlgFlashChkLoop		: "เล่นวนรอบ Loop",
+DlgFlashChkMenu		: "ให้ใช้งานเมนูของ Flash",
+DlgFlashScale		: "อัตราส่วน Scale",
+DlgFlashScaleAll	: "แสดงให้เห็นทั้งหมด Show all",
+DlgFlashScaleNoBorder	: "ไม่แสดงเส้นขอบ No Border",
+DlgFlashScaleFit	: "แสดงให้พอดีกับพื้นที่ Exact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "ลิงค์เชื่อมโยงเว็บ อีเมล์ รูปภาพ หรือไฟล์อื่นๆ",
+DlgLnkInfoTab		: "รายละเอียด",
+DlgLnkTargetTab		: "การเปิดหน้าจอ",
+
+DlgLnkType			: "ประเภทของลิงค์",
+DlgLnkTypeURL		: "ที่อยู่อ้างอิงออนไลน์ (URL)",
+DlgLnkTypeAnchor	: "จุดเชื่อมโยง (Anchor)",
+DlgLnkTypeEMail		: "ส่งอีเมล์ (E-Mail)",
+DlgLnkProto			: "โปรโตคอล",
+DlgLnkProtoOther	: "<อื่นๆ>",
+DlgLnkURL			: "ที่อยู่อ้างอิงออนไลน์ (URL)",
+DlgLnkAnchorSel		: "ระบุข้อมูลของจุดเชื่อมโยง (Anchor)",
+DlgLnkAnchorByName	: "ชื่อ",
+DlgLnkAnchorById	: "ไอดี",
+DlgLnkNoAnchors		: "(ยังไม่มีจุดเชื่อมโยงภายในหน้าเอกสารนี้)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "อีเมล์ (E-Mail)",
+DlgLnkEMailSubject	: "หัวเรื่อง",
+DlgLnkEMailBody		: "ข้อความ",
+DlgLnkUpload		: "อัพโหลดไฟล์",
+DlgLnkBtnUpload		: "บันทึกไฟล์ไว้บนเซิร์ฟเวอร์",
+
+DlgLnkTarget		: "การเปิดหน้าลิงค์",
+DlgLnkTargetFrame	: "<เปิดในเฟรม>",
+DlgLnkTargetPopup	: "<เปิดหน้าจอเล็ก (Pop-up)>",
+DlgLnkTargetBlank	: "เปิดหน้าจอใหม่ (_blank)",
+DlgLnkTargetParent	: "เปิดในหน้าหลัก (_parent)",
+DlgLnkTargetSelf	: "เปิดในหน้าปัจจุบัน (_self)",
+DlgLnkTargetTop		: "เปิดในหน้าบนสุด (_top)",
+DlgLnkTargetFrameName	: "ชื่อทาร์เก็ตเฟรม",
+DlgLnkPopWinName	: "ระบุชื่อหน้าจอเล็ก (Pop-up)",
+DlgLnkPopWinFeat	: "คุณสมบัติของหน้าจอเล็ก (Pop-up)",
+DlgLnkPopResize		: "ปรับขนาดหน้าจอ",
+DlgLnkPopLocation	: "แสดงที่อยู่ของไฟล์",
+DlgLnkPopMenu		: "แสดงแถบเมนู",
+DlgLnkPopScroll		: "แสดงแถบเลื่อน",
+DlgLnkPopStatus		: "แสดงแถบสถานะ",
+DlgLnkPopToolbar	: "แสดงแถบเครื่องมือ",
+DlgLnkPopFullScrn	: "แสดงเต็มหน้าจอ (IE5.5++ เท่านั้น)",
+DlgLnkPopDependent	: "แสดงเต็มหน้าจอ (Netscape)",
+DlgLnkPopWidth		: "กว้าง",
+DlgLnkPopHeight		: "สูง",
+DlgLnkPopLeft		: "พิกัดซ้าย (Left Position)",
+DlgLnkPopTop		: "พิกัดบน (Top Position)",
+
+DlnLnkMsgNoUrl		: "กรุณาระบุที่อยู่อ้างอิงออนไลน์ (URL)",
+DlnLnkMsgNoEMail	: "กรุณาระบุอีเมล์ (E-mail)",
+DlnLnkMsgNoAnchor	: "กรุณาระบุจุดเชื่อมโยง (Anchor)",
+DlnLnkMsgInvPopName	: "ชื่อของหน้าต่างป๊อบอัพ จะต้องขึ้นต้นด้วยตัวอักษรเท่านั้น และต้องไม่มีช่องว่างในชื่อ",
+
+// Color Dialog
+DlgColorTitle		: "เลือกสี",
+DlgColorBtnClear	: "ล้างค่ารหัสสี",
+DlgColorHighlight	: "ตัวอย่างสี",
+DlgColorSelected	: "สีที่เลือก",
+
+// Smiley Dialog
+DlgSmileyTitle		: "แทรกสัญลักษณ์สื่ออารมณ์",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "แทรกตัวอักษรพิเศษ",
+
+// Table Dialog
+DlgTableTitle		: "คุณสมบัติของ ตาราง",
+DlgTableRows		: "แถว",
+DlgTableColumns		: "สดมน์",
+DlgTableBorder		: "ขนาดเส้นขอบ",
+DlgTableAlign		: "การจัดตำแหน่ง",
+DlgTableAlignNotSet	: "<ไม่ระบุ>",
+DlgTableAlignLeft	: "ชิดซ้าย",
+DlgTableAlignCenter	: "กึ่งกลาง",
+DlgTableAlignRight	: "ชิดขวา",
+DlgTableWidth		: "กว้าง",
+DlgTableWidthPx		: "จุดสี",
+DlgTableWidthPc		: "เปอร์เซ็น",
+DlgTableHeight		: "สูง",
+DlgTableCellSpace	: "ระยะแนวนอนน",
+DlgTableCellPad		: "ระยะแนวตั้ง",
+DlgTableCaption		: "หัวเรื่องของตาราง",
+DlgTableSummary		: "สรุปความ",
+
+// Table Cell Dialog
+DlgCellTitle		: "คุณสมบัติของ ช่อง",
+DlgCellWidth		: "กว้าง",
+DlgCellWidthPx		: "จุดสี",
+DlgCellWidthPc		: "เปอร์เซ็น",
+DlgCellHeight		: "สูง",
+DlgCellWordWrap		: "ตัดบรรทัดอัตโนมัติ",
+DlgCellWordWrapNotSet	: "<ไม่ระบุ>",
+DlgCellWordWrapYes	: "ใ่ช่",
+DlgCellWordWrapNo	: "ไม่",
+DlgCellHorAlign		: "การจัดวางแนวนอน",
+DlgCellHorAlignNotSet	: "<ไม่ระบุ>",
+DlgCellHorAlignLeft	: "ชิดซ้าย",
+DlgCellHorAlignCenter	: "กึ่งกลาง",
+DlgCellHorAlignRight: "ชิดขวา",
+DlgCellVerAlign		: "การจัดวางแนวตั้ง",
+DlgCellVerAlignNotSet	: "<ไม่ระบุ>",
+DlgCellVerAlignTop	: "บนสุด",
+DlgCellVerAlignMiddle	: "กึ่งกลาง",
+DlgCellVerAlignBottom	: "ล่างสุด",
+DlgCellVerAlignBaseline	: "อิงบรรทัด",
+DlgCellRowSpan		: "จำนวนแถวที่คร่อมกัน",
+DlgCellCollSpan		: "จำนวนสดมน์ที่คร่อมกัน",
+DlgCellBackColor	: "สีพื้นหลัง",
+DlgCellBorderColor	: "สีเส้นขอบ",
+DlgCellBtnSelect	: "เลือก..",
+
+// Find Dialog
+DlgFindTitle		: "ค้นหา",
+DlgFindFindBtn		: "ค้นหา",
+DlgFindNotFoundMsg	: "ไม่พบคำที่ค้นหา.",
+
+// Replace Dialog
+DlgReplaceTitle			: "ค้นหาและแทนที่",
+DlgReplaceFindLbl		: "ค้นหาคำว่า:",
+DlgReplaceReplaceLbl	: "แทนที่ด้วย:",
+DlgReplaceCaseChk		: "ตัวโหญ่-เล็ก ต้องตรงกัน",
+DlgReplaceReplaceBtn	: "แทนที่",
+DlgReplaceReplAllBtn	: "แทนที่ทั้งหมดที่พบ",
+DlgReplaceWordChk		: "ต้องตรงกันทุกคำ",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "ไม่สามารถตัดข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl และตัว X พร้อมกัน).",
+PasteErrorCopy	: "ไม่สามารถสำเนาข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl และตัว C พร้อมกัน).",
+
+PasteAsText		: "วางแบบตัวอักษรธรรมดา",
+PasteFromWord	: "วางแบบตัวอักษรจากโปรแกรมเวิร์ด",
+
+DlgPasteMsg2	: "กรุณาใช้คีย์บอร์ดเท่านั้น โดยกดปุ๋ม (<strong>Ctrl และ V</strong>)พร้อมๆกัน และกด <strong>OK</strong>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "ไม่สนใจ Font Face definitions",
+DlgPasteRemoveStyles	: "ลบ Styles definitions",
+DlgPasteCleanBox		: "ล้างข้อมูลใน Box",
+
+// Color Picker
+ColorAutomatic	: "สีอัตโนมัติ",
+ColorMoreColors	: "เลือกสีอื่นๆ...",
+
+// Document Properties
+DocProps		: "คุณสมบัติของเอกสาร",
+
+// Anchor Dialog
+DlgAnchorTitle		: "คุณสมบัติของ Anchor",
+DlgAnchorName		: "ชื่อ Anchor",
+DlgAnchorErrorName	: "กรุณาระบุชื่อของ Anchor",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "ไม่พบในดิกชันนารี",
+DlgSpellChangeTo		: "แก้ไขเป็น",
+DlgSpellBtnIgnore		: "ยกเว้น",
+DlgSpellBtnIgnoreAll	: "ยกเว้นทั้งหมด",
+DlgSpellBtnReplace		: "แทนที่",
+DlgSpellBtnReplaceAll	: "แทนที่ทั้งหมด",
+DlgSpellBtnUndo			: "ยกเลิก",
+DlgSpellNoSuggestions	: "- ไม่มีคำแนะนำใดๆ -",
+DlgSpellProgress		: "กำลังตรวจสอบคำสะกด...",
+DlgSpellNoMispell		: "ตรวจสอบคำสะกดเสร็จสิ้น: ไม่พบคำสะกดผิด",
+DlgSpellNoChanges		: "ตรวจสอบคำสะกดเสร็จสิ้น: ไม่มีการแก้คำใดๆ",
+DlgSpellOneChange		: "ตรวจสอบคำสะกดเสร็จสิ้น: แก้ไข1คำ",
+DlgSpellManyChanges		: "ตรวจสอบคำสะกดเสร็จสิ้น:: แก้ไข %1 คำ",
+
+IeSpellDownload			: "ไม่ได้ติดตั้งระบบตรวจสอบคำสะกด. ต้องการติดตั้งไหมครับ?",
+
+// Button Dialog
+DlgButtonText		: "ข้อความ (ค่าตัวแปร)",
+DlgButtonType		: "ข้อความ",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "ชื่อ",
+DlgCheckboxValue	: "ค่าตัวแปร",
+DlgCheckboxSelected	: "เลือกเป็นค่าเริ่มต้น",
+
+// Form Dialog
+DlgFormName		: "ชื่อ",
+DlgFormAction	: "แอคชั่น",
+DlgFormMethod	: "เมธอด",
+
+// Select Field Dialog
+DlgSelectName		: "ชื่อ",
+DlgSelectValue		: "ค่าตัวแปร",
+DlgSelectSize		: "ขนาด",
+DlgSelectLines		: "บรรทัด",
+DlgSelectChkMulti	: "เลือกหลายค่าได้",
+DlgSelectOpAvail	: "รายการตัวเลือก",
+DlgSelectOpText		: "ข้อความ",
+DlgSelectOpValue	: "ค่าตัวแปร",
+DlgSelectBtnAdd		: "เพิ่ม",
+DlgSelectBtnModify	: "แก้ไข",
+DlgSelectBtnUp		: "บน",
+DlgSelectBtnDown	: "ล่าง",
+DlgSelectBtnSetValue : "เลือกเป็นค่าเริ่มต้น",
+DlgSelectBtnDelete	: "ลบ",
+
+// Textarea Dialog
+DlgTextareaName	: "ชื่อ",
+DlgTextareaCols	: "สดมภ์",
+DlgTextareaRows	: "แถว",
+
+// Text Field Dialog
+DlgTextName			: "ชื่อ",
+DlgTextValue		: "ค่าตัวแปร",
+DlgTextCharWidth	: "ความกว้าง",
+DlgTextMaxChars		: "จำนวนตัวอักษรสูงสุด",
+DlgTextType			: "ชนิด",
+DlgTextTypeText		: "ข้อความ",
+DlgTextTypePass		: "รหัสผ่าน",
+
+// Hidden Field Dialog
+DlgHiddenName	: "ชื่อ",
+DlgHiddenValue	: "ค่าตัวแปร",
+
+// Bulleted List Dialog
+BulletedListProp	: "คุณสมบัติของ บูลเล็ตลิสต์",
+NumberedListProp	: "คุณสมบัติของ นัมเบอร์ลิสต์",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "ชนิด",
+DlgLstTypeCircle	: "รูปวงกลม",
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "รูปสี่เหลี่ยม",
+DlgLstTypeNumbers	: "หมายเลข (1, 2, 3)",
+DlgLstTypeLCase		: "ตัวพิมพ์เล็ก (a, b, c)",
+DlgLstTypeUCase		: "ตัวพิมพ์ใหญ่ (A, B, C)",
+DlgLstTypeSRoman	: "เลขโรมันพิมพ์เล็ก (i, ii, iii)",
+DlgLstTypeLRoman	: "เลขโรมันพิมพ์ใหญ่ (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "ลักษณะทั่วไปของเอกสาร",
+DlgDocBackTab		: "พื้นหลัง",
+DlgDocColorsTab		: "สีและระยะขอบ",
+DlgDocMetaTab		: "ข้อมูลสำหรับเสิร์ชเอนจิ้น",
+
+DlgDocPageTitle		: "ชื่อไตเติ้ล",
+DlgDocLangDir		: "การอ่านภาษา",
+DlgDocLangDirLTR	: "จากซ้ายไปขวา (LTR)",
+DlgDocLangDirRTL	: "จากขวาไปซ้าย (RTL)",
+DlgDocLangCode		: "รหัสภาษา",
+DlgDocCharSet		: "ชุดตัวอักษร",
+DlgDocCharSetCE		: "Central European",
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Greek",
+DlgDocCharSetJP		: "Japanese",
+DlgDocCharSetKR		: "Korean",
+DlgDocCharSetTR		: "Turkish",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "ชุดตัวอักษรอื่นๆ",
+
+DlgDocDocType		: "ประเภทของเอกสาร",
+DlgDocDocTypeOther	: "ประเภทเอกสารอื่นๆ",
+DlgDocIncXHTML		: "รวมเอา  XHTML Declarations ไว้ด้วย",
+DlgDocBgColor		: "สีพื้นหลัง",
+DlgDocBgImage		: "ที่อยู่อ้างอิงออนไลน์ของรูปพื้นหลัง (Image URL)",
+DlgDocBgNoScroll	: "พื้นหลังแบบไม่มีแถบเลื่อน",
+DlgDocCText			: "ข้อความ",
+DlgDocCLink			: "ลิงค์",
+DlgDocCVisited		: "ลิงค์ที่เคยคลิ้กแล้ว Visited Link",
+DlgDocCActive		: "ลิงค์ที่กำลังคลิ้ก Active Link",
+DlgDocMargins		: "ระยะขอบของหน้าเอกสาร",
+DlgDocMaTop			: "ด้านบน",
+DlgDocMaLeft		: "ด้านซ้าย",
+DlgDocMaRight		: "ด้านขวา",
+DlgDocMaBottom		: "ด้านล่าง",
+DlgDocMeIndex		: "คำสำคัญอธิบายเอกสาร (คั่นคำด้วย คอมม่า)",
+DlgDocMeDescr		: "ประโยคอธิบายเกี่ยวกับเอกสาร",
+DlgDocMeAuthor		: "ผู้สร้างเอกสาร",
+DlgDocMeCopy		: "สงวนลิขสิทธิ์",
+DlgDocPreview		: "ตัวอย่างหน้าเอกสาร",
+
+// Templates Dialog
+Templates			: "เทมเพลต",
+DlgTemplatesTitle	: "เทมเพลตของส่วนเนื้อหาเว็บไซต์",
+DlgTemplatesSelMsg	: "กรุณาเลือก เทมเพลต เพื่อนำไปแก้ไขในอีดิตเตอร์<br />(เนื้อหาส่วนนี้จะหายไป):",
+DlgTemplatesLoading	: "กำลังโหลดรายการเทมเพลตทั้งหมด...",
+DlgTemplatesNoTpl	: "(ยังไม่มีการกำหนดเทมเพลต)",
+DlgTemplatesReplace	: "แทนที่เนื้อหาเว็บไซต์ที่เลือก",
+
+// About Dialog
+DlgAboutAboutTab	: "เกี่ยวกับโปรแกรม",
+DlgAboutBrowserInfoTab	: "โปรแกรมท่องเว็บที่ท่านใช้",
+DlgAboutLicenseTab	: "ลิขสิทธิ์",
+DlgAboutVersion		: "รุ่น",
+DlgAboutInfo		: "For further information go to"	//MISSING
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/it.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/it.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/it.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Italian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Nascondi la barra degli strumenti",
+ToolbarExpand		: "Mostra la barra degli strumenti",
+
+// Toolbar Items and Context Menu
+Save				: "Salva",
+NewPage				: "Nuova pagina vuota",
+Preview				: "Anteprima",
+Cut					: "Taglia",
+Copy				: "Copia",
+Paste				: "Incolla",
+PasteText			: "Incolla come testo semplice",
+PasteWord			: "Incolla da Word",
+Print				: "Stampa",
+SelectAll			: "Seleziona tutto",
+RemoveFormat		: "Elimina formattazione",
+InsertLinkLbl		: "Collegamento",
+InsertLink			: "Inserisci/Modifica collegamento",
+RemoveLink			: "Elimina collegamento",
+Anchor				: "Inserisci/Modifica Ancora",
+InsertImageLbl		: "Immagine",
+InsertImage			: "Inserisci/Modifica immagine",
+InsertFlashLbl		: "Oggetto Flash",
+InsertFlash			: "Inserisci/Modifica Oggetto Flash",
+InsertTableLbl		: "Tabella",
+InsertTable			: "Inserisci/Modifica tabella",
+InsertLineLbl		: "Riga orizzontale",
+InsertLine			: "Inserisci riga orizzontale",
+InsertSpecialCharLbl: "Caratteri speciali",
+InsertSpecialChar	: "Inserisci carattere speciale",
+InsertSmileyLbl		: "Emoticon",
+InsertSmiley		: "Inserisci emoticon",
+About				: "Informazioni su FCKeditor",
+Bold				: "Grassetto",
+Italic				: "Corsivo",
+Underline			: "Sottolineato",
+StrikeThrough		: "Barrato",
+Subscript			: "Pedice",
+Superscript			: "Apice",
+LeftJustify			: "Allinea a sinistra",
+CenterJustify		: "Centra",
+RightJustify		: "Allinea a destra",
+BlockJustify		: "Giustifica",
+DecreaseIndent		: "Riduci rientro",
+IncreaseIndent		: "Aumenta rientro",
+Undo				: "Annulla",
+Redo				: "Ripristina",
+NumberedListLbl		: "Elenco numerato",
+NumberedList		: "Inserisci/Modifica elenco numerato",
+BulletedListLbl		: "Elenco puntato",
+BulletedList		: "Inserisci/Modifica elenco puntato",
+ShowTableBorders	: "Mostra bordi tabelle",
+ShowDetails			: "Mostra dettagli",
+Style				: "Stile",
+FontFormat			: "Formato",
+Font				: "Font",
+FontSize			: "Dimensione",
+TextColor			: "Colore testo",
+BGColor				: "Colore sfondo",
+Source				: "Codice Sorgente",
+Find				: "Trova",
+Replace				: "Sostituisci",
+SpellCheck			: "Correttore ortografico",
+UniversalKeyboard	: "Tastiera universale",
+PageBreakLbl		: "Interruzione di pagina",
+PageBreak			: "Inserisci interruzione di pagina",
+
+Form			: "Modulo",
+Checkbox		: "Checkbox",
+RadioButton		: "Radio Button",
+TextField		: "Campo di testo",
+Textarea		: "Area di testo",
+HiddenField		: "Campo nascosto",
+Button			: "Bottone",
+SelectionField	: "Menu di selezione",
+ImageButton		: "Bottone immagine",
+
+FitWindow		: "Massimizza l'area dell'editor",
+
+// Context Menu
+EditLink			: "Modifica collegamento",
+CellCM				: "Cella",
+RowCM				: "Riga",
+ColumnCM			: "Colonna",
+InsertRow			: "Inserisci riga",
+DeleteRows			: "Elimina righe",
+InsertColumn		: "Inserisci colonna",
+DeleteColumns		: "Elimina colonne",
+InsertCell			: "Inserisci cella",
+DeleteCells			: "Elimina celle",
+MergeCells			: "Unisce celle",
+SplitCell			: "Dividi celle",
+TableDelete			: "Cancella Tabella",
+CellProperties		: "Proprietà cella",
+TableProperties		: "Proprietà tabella",
+ImageProperties		: "Proprietà immagine",
+FlashProperties		: "Proprietà Oggetto Flash",
+
+AnchorProp			: "Proprietà ancora",
+ButtonProp			: "Proprietà bottone",
+CheckboxProp		: "Proprietà checkbox",
+HiddenFieldProp		: "Proprietà campo nascosto",
+RadioButtonProp		: "Proprietà radio button",
+ImageButtonProp		: "Proprietà bottone immagine",
+TextFieldProp		: "Proprietà campo di testo",
+SelectionFieldProp	: "Proprietà menu di selezione",
+TextareaProp		: "Proprietà area di testo",
+FormProp			: "Proprietà modulo",
+
+FontFormats			: "Normale;Formattato;Indirizzo;Titolo 1;Titolo 2;Titolo 3;Titolo 4;Titolo 5;Titolo 6;Paragrafo (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Elaborazione XHTML in corso. Attendere prego...",
+Done				: "Completato",
+PasteWordConfirm	: "Il testo da incollare sembra provenire da Word. Desideri pulirlo prima di incollare?",
+NotCompatiblePaste	: "Questa funzione è disponibile solo per Internet Explorer 5.5 o superiore. Desideri incollare il testo senza pulirlo?",
+UnknownToolbarItem	: "Elemento della barra strumenti sconosciuto \"%1\"",
+UnknownCommand		: "Comando sconosciuto \"%1\"",
+NotImplemented		: "Comando non implementato",
+UnknownToolbarSet	: "La barra di strumenti \"%1\" non esiste",
+NoActiveX			: "Le impostazioni di sicurezza del tuo browser potrebbero limitare alcune funzionalità dell'editor. Devi abilitare l'opzione \"Esegui controlli e plug-in ActiveX\". Potresti avere errori e notare funzionalità mancanti.",
+BrowseServerBlocked : "Non è possibile aprire la finestra di espolorazione risorse. Verifica che tutti i blocca popup siano bloccati.",
+DialogBlocked		: "Non è possibile aprire la finestra di dialogo. Verifica che tutti i blocca popup siano bloccati.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Annulla",
+DlgBtnClose			: "Chiudi",
+DlgBtnBrowseServer	: "Cerca sul server",
+DlgAdvancedTag		: "Avanzate",
+DlgOpOther			: "<Altro>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Devi inserire l'URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<non impostato>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Direzione scrittura",
+DlgGenLangDirLtr	: "Da Sinistra a Destra (LTR)",
+DlgGenLangDirRtl	: "Da Destra a Sinistra (RTL)",
+DlgGenLangCode		: "Codice Lingua",
+DlgGenAccessKey		: "Scorciatoia<br />da tastiera",
+DlgGenName			: "Nome",
+DlgGenTabIndex		: "Ordine di tabulazione",
+DlgGenLongDescr		: "URL descrizione estesa",
+DlgGenClass			: "Nome classe CSS",
+DlgGenTitle			: "Titolo",
+DlgGenContType		: "Tipo della risorsa collegata",
+DlgGenLinkCharset	: "Set di caretteri della risorsa collegata",
+DlgGenStyle			: "Stile",
+
+// Image Dialog
+DlgImgTitle			: "Proprietà immagine",
+DlgImgInfoTab		: "Informazioni immagine",
+DlgImgBtnUpload		: "Invia al server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Carica",
+DlgImgAlt			: "Testo alternativo",
+DlgImgWidth			: "Larghezza",
+DlgImgHeight		: "Altezza",
+DlgImgLockRatio		: "Blocca rapporto",
+DlgBtnResetSize		: "Reimposta dimensione",
+DlgImgBorder		: "Bordo",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Allineamento",
+DlgImgAlignLeft		: "Sinistra",
+DlgImgAlignAbsBottom: "In basso assoluto",
+DlgImgAlignAbsMiddle: "Centrato assoluto",
+DlgImgAlignBaseline	: "Linea base",
+DlgImgAlignBottom	: "In Basso",
+DlgImgAlignMiddle	: "Centrato",
+DlgImgAlignRight	: "Destra",
+DlgImgAlignTextTop	: "In alto al testo",
+DlgImgAlignTop		: "In Alto",
+DlgImgPreview		: "Anteprima",
+DlgImgAlertUrl		: "Devi inserire l'URL per l'immagine",
+DlgImgLinkTab		: "Collegamento",
+
+// Flash Dialog
+DlgFlashTitle		: "Proprietà Oggetto Flash",
+DlgFlashChkPlay		: "Avvio Automatico",
+DlgFlashChkLoop		: "Cicla",
+DlgFlashChkMenu		: "Abilita Menu di Flash",
+DlgFlashScale		: "Ridimensiona",
+DlgFlashScaleAll	: "Mostra Tutto",
+DlgFlashScaleNoBorder	: "Senza Bordo",
+DlgFlashScaleFit	: "Dimensione Esatta",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Collegamento",
+DlgLnkInfoTab		: "Informazioni collegamento",
+DlgLnkTargetTab		: "Destinazione",
+
+DlgLnkType			: "Tipo di Collegamento",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Ancora nella pagina",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocollo",
+DlgLnkProtoOther	: "<altro>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Scegli Ancora",
+DlgLnkAnchorByName	: "Per Nome",
+DlgLnkAnchorById	: "Per id elemento",
+DlgLnkNoAnchors		: "<Nessuna ancora disponibile nel documento>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Indirizzo E-Mail",
+DlgLnkEMailSubject	: "Oggetto del messaggio",
+DlgLnkEMailBody		: "Corpo del messaggio",
+DlgLnkUpload		: "Carica",
+DlgLnkBtnUpload		: "Invia al Server",
+
+DlgLnkTarget		: "Destinazione",
+DlgLnkTargetFrame	: "<riquadro>",
+DlgLnkTargetPopup	: "<finestra popup>",
+DlgLnkTargetBlank	: "Nuova finestra (_blank)",
+DlgLnkTargetParent	: "Finestra padre (_parent)",
+DlgLnkTargetSelf	: "Stessa finestra (_self)",
+DlgLnkTargetTop		: "Finestra superiore (_top)",
+DlgLnkTargetFrameName	: "Nome del riquadro di destinazione",
+DlgLnkPopWinName	: "Nome finestra popup",
+DlgLnkPopWinFeat	: "Caratteristiche finestra popup",
+DlgLnkPopResize		: "Ridimensionabile",
+DlgLnkPopLocation	: "Barra degli indirizzi",
+DlgLnkPopMenu		: "Barra del menu",
+DlgLnkPopScroll		: "Barre di scorrimento",
+DlgLnkPopStatus		: "Barra di stato",
+DlgLnkPopToolbar	: "Barra degli strumenti",
+DlgLnkPopFullScrn	: "A tutto schermo (IE)",
+DlgLnkPopDependent	: "Dipendente (Netscape)",
+DlgLnkPopWidth		: "Larghezza",
+DlgLnkPopHeight		: "Altezza",
+DlgLnkPopLeft		: "Posizione da sinistra",
+DlgLnkPopTop		: "Posizione dall'alto",
+
+DlnLnkMsgNoUrl		: "Devi inserire l'URL del collegamento",
+DlnLnkMsgNoEMail	: "Devi inserire un'indirizzo e-mail",
+DlnLnkMsgNoAnchor	: "Devi selezionare un'ancora",
+DlnLnkMsgInvPopName	: "Il nome del popup deve iniziare con una lettera, e non può contenere spazi",
+
+// Color Dialog
+DlgColorTitle		: "Seleziona colore",
+DlgColorBtnClear	: "Vuota",
+DlgColorHighlight	: "Evidenziato",
+DlgColorSelected	: "Selezionato",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Inserisci emoticon",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Seleziona carattere speciale",
+
+// Table Dialog
+DlgTableTitle		: "Proprietà tabella",
+DlgTableRows		: "Righe",
+DlgTableColumns		: "Colonne",
+DlgTableBorder		: "Dimensione bordo",
+DlgTableAlign		: "Allineamento",
+DlgTableAlignNotSet	: "<non impostato>",
+DlgTableAlignLeft	: "Sinistra",
+DlgTableAlignCenter	: "Centrato",
+DlgTableAlignRight	: "Destra",
+DlgTableWidth		: "Larghezza",
+DlgTableWidthPx		: "pixel",
+DlgTableWidthPc		: "percento",
+DlgTableHeight		: "Altezza",
+DlgTableCellSpace	: "Spaziatura celle",
+DlgTableCellPad		: "Padding celle",
+DlgTableCaption		: "Intestazione",
+DlgTableSummary		: "Indice",
+
+// Table Cell Dialog
+DlgCellTitle		: "Proprietà cella",
+DlgCellWidth		: "Larghezza",
+DlgCellWidthPx		: "pixel",
+DlgCellWidthPc		: "percento",
+DlgCellHeight		: "Altezza",
+DlgCellWordWrap		: "A capo automatico",
+DlgCellWordWrapNotSet	: "<non impostato>",
+DlgCellWordWrapYes	: "Si",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Allineamento orizzontale",
+DlgCellHorAlignNotSet	: "<non impostato>",
+DlgCellHorAlignLeft	: "Sinistra",
+DlgCellHorAlignCenter	: "Centrato",
+DlgCellHorAlignRight: "Destra",
+DlgCellVerAlign		: "Allineamento verticale",
+DlgCellVerAlignNotSet	: "<non impostato>",
+DlgCellVerAlignTop	: "In Alto",
+DlgCellVerAlignMiddle	: "Centrato",
+DlgCellVerAlignBottom	: "In Basso",
+DlgCellVerAlignBaseline	: "Linea base",
+DlgCellRowSpan		: "Righe occupate",
+DlgCellCollSpan		: "Colonne occupate",
+DlgCellBackColor	: "Colore sfondo",
+DlgCellBorderColor	: "Colore bordo",
+DlgCellBtnSelect	: "Scegli...",
+
+// Find Dialog
+DlgFindTitle		: "Trova",
+DlgFindFindBtn		: "Trova",
+DlgFindNotFoundMsg	: "L'elemento cercato non è stato trovato.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Sostituisci",
+DlgReplaceFindLbl		: "Trova:",
+DlgReplaceReplaceLbl	: "Sostituisci con:",
+DlgReplaceCaseChk		: "Maiuscole/minuscole",
+DlgReplaceReplaceBtn	: "Sostituisci",
+DlgReplaceReplAllBtn	: "Sostituisci tutto",
+DlgReplaceWordChk		: "Solo parole intere",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Le impostazioni di sicurezza del browser non permettono di tagliare automaticamente il testo. Usa la tastiera (Ctrl+X).",
+PasteErrorCopy	: "Le impostazioni di sicurezza del browser non permettono di copiare automaticamente il testo. Usa la tastiera (Ctrl+C).",
+
+PasteAsText		: "Incolla come testo semplice",
+PasteFromWord	: "Incolla da Word",
+
+DlgPasteMsg2	: "Incolla il testo all'interno dell'area sottostante usando la scorciatoia di tastiere (<STRONG>Ctrl+V</STRONG>) e premi <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignora le definizioni di Font",
+DlgPasteRemoveStyles	: "Rimuovi le definizioni di Stile",
+DlgPasteCleanBox		: "Svuota area di testo",
+
+// Color Picker
+ColorAutomatic	: "Automatico",
+ColorMoreColors	: "Altri colori...",
+
+// Document Properties
+DocProps		: "Proprietà del Documento",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Proprietà ancora",
+DlgAnchorName		: "Nome ancora",
+DlgAnchorErrorName	: "Inserici il nome dell'ancora",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Non nel dizionario",
+DlgSpellChangeTo		: "Cambia in",
+DlgSpellBtnIgnore		: "Ignora",
+DlgSpellBtnIgnoreAll	: "Ignora tutto",
+DlgSpellBtnReplace		: "Cambia",
+DlgSpellBtnReplaceAll	: "Cambia tutto",
+DlgSpellBtnUndo			: "Annulla",
+DlgSpellNoSuggestions	: "- Nessun suggerimento -",
+DlgSpellProgress		: "Controllo ortografico in corso",
+DlgSpellNoMispell		: "Controllo ortografico completato: nessun errore trovato",
+DlgSpellNoChanges		: "Controllo ortografico completato: nessuna parola cambiata",
+DlgSpellOneChange		: "Controllo ortografico completato: 1 parola cambiata",
+DlgSpellManyChanges		: "Controllo ortografico completato: %1 parole cambiate",
+
+IeSpellDownload			: "Contollo ortografico non installato. Lo vuoi scaricare ora?",
+
+// Button Dialog
+DlgButtonText		: "Testo (Value)",
+DlgButtonType		: "Tipo",
+DlgButtonTypeBtn	: "Bottone",
+DlgButtonTypeSbm	: "Invio",
+DlgButtonTypeRst	: "Annulla",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nome",
+DlgCheckboxValue	: "Valore",
+DlgCheckboxSelected	: "Selezionato",
+
+// Form Dialog
+DlgFormName		: "Nome",
+DlgFormAction	: "Azione",
+DlgFormMethod	: "Metodo",
+
+// Select Field Dialog
+DlgSelectName		: "Nome",
+DlgSelectValue		: "Valore",
+DlgSelectSize		: "Dimensione",
+DlgSelectLines		: "righe",
+DlgSelectChkMulti	: "Permetti selezione multipla",
+DlgSelectOpAvail	: "Opzioni disponibili",
+DlgSelectOpText		: "Testo",
+DlgSelectOpValue	: "Valore",
+DlgSelectBtnAdd		: "Aggiungi",
+DlgSelectBtnModify	: "Modifica",
+DlgSelectBtnUp		: "Su",
+DlgSelectBtnDown	: "Gi",
+DlgSelectBtnSetValue : "Imposta come predefinito",
+DlgSelectBtnDelete	: "Rimuovi",
+
+// Textarea Dialog
+DlgTextareaName	: "Nome",
+DlgTextareaCols	: "Colonne",
+DlgTextareaRows	: "Righe",
+
+// Text Field Dialog
+DlgTextName			: "Nome",
+DlgTextValue		: "Valore",
+DlgTextCharWidth	: "Larghezza",
+DlgTextMaxChars		: "Numero massimo di caratteri",
+DlgTextType			: "Tipo",
+DlgTextTypeText		: "Testo",
+DlgTextTypePass		: "Password",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nome",
+DlgHiddenValue	: "Valore",
+
+// Bulleted List Dialog
+BulletedListProp	: "Proprietà lista puntata",
+NumberedListProp	: "Proprietà lista numerata",
+DlgLstStart			: "Inizio",
+DlgLstType			: "Tipo",
+DlgLstTypeCircle	: "Tondo",
+DlgLstTypeDisc		: "Disco",
+DlgLstTypeSquare	: "Quadrato",
+DlgLstTypeNumbers	: "Numeri (1, 2, 3)",
+DlgLstTypeLCase		: "Caratteri minuscoli (a, b, c)",
+DlgLstTypeUCase		: "Caratteri maiuscoli (A, B, C)",
+DlgLstTypeSRoman	: "Numeri Romani minuscoli (i, ii, iii)",
+DlgLstTypeLRoman	: "Numeri Romani maiuscoli (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Genarale",
+DlgDocBackTab		: "Sfondo",
+DlgDocColorsTab		: "Colori e margini",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Titolo pagina",
+DlgDocLangDir		: "Direzione scrittura",
+DlgDocLangDirLTR	: "Da Sinistra a Destra (LTR)",
+DlgDocLangDirRTL	: "Da Destra a Sinistra (RTL)",
+DlgDocLangCode		: "Codice Lingua",
+DlgDocCharSet		: "Set di caretteri",
+DlgDocCharSetCE		: "Europa Centrale",
+DlgDocCharSetCT		: "Cinese Tradizionale (Big5)",
+DlgDocCharSetCR		: "Cirillico",
+DlgDocCharSetGR		: "Greco",
+DlgDocCharSetJP		: "Giapponese",
+DlgDocCharSetKR		: "Coreano",
+DlgDocCharSetTR		: "Turco",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Europa Occidentale",
+DlgDocCharSetOther	: "Altro set di caretteri",
+
+DlgDocDocType		: "Intestazione DocType",
+DlgDocDocTypeOther	: "Altra intestazione DocType",
+DlgDocIncXHTML		: "Includi dichiarazione XHTML",
+DlgDocBgColor		: "Colore di sfondo",
+DlgDocBgImage		: "Immagine di sfondo",
+DlgDocBgNoScroll	: "Sfondo fissato",
+DlgDocCText			: "Testo",
+DlgDocCLink			: "Collegamento",
+DlgDocCVisited		: "Collegamento visitato",
+DlgDocCActive		: "Collegamento attivo",
+DlgDocMargins		: "Margini",
+DlgDocMaTop			: "In Alto",
+DlgDocMaLeft		: "A Sinistra",
+DlgDocMaRight		: "A Destra",
+DlgDocMaBottom		: "In Basso",
+DlgDocMeIndex		: "Chiavi di indicizzazione documento (separate da virgola)",
+DlgDocMeDescr		: "Descrizione documento",
+DlgDocMeAuthor		: "Autore",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Anteprima",
+
+// Templates Dialog
+Templates			: "Modelli",
+DlgTemplatesTitle	: "Contenuto dei modelli",
+DlgTemplatesSelMsg	: "Seleziona il modello da aprire nell'editor<br />(il contenuto attuale verrà eliminato):",
+DlgTemplatesLoading	: "Caricamento modelli in corso. Attendere prego...",
+DlgTemplatesNoTpl	: "(Nessun modello definito)",
+DlgTemplatesReplace	: "Cancella il contenuto corrente",
+
+// About Dialog
+DlgAboutAboutTab	: "Informazioni",
+DlgAboutBrowserInfoTab	: "Informazioni Browser",
+DlgAboutLicenseTab	: "Licenza",
+DlgAboutVersion		: "versione",
+DlgAboutInfo		: "Per maggiori informazioni visitare"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sl.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sl.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Slovenian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Zloži orodno vrstico",
+ToolbarExpand		: "Razširi orodno vrstico",
+
+// Toolbar Items and Context Menu
+Save				: "Shrani",
+NewPage				: "Nova stran",
+Preview				: "Predogled",
+Cut					: "Izreži",
+Copy				: "Kopiraj",
+Paste				: "Prilepi",
+PasteText			: "Prilepi kot golo besedilo",
+PasteWord			: "Prilepi iz Worda",
+Print				: "Natisni",
+SelectAll			: "Izberi vse",
+RemoveFormat		: "Odstrani oblikovanje",
+InsertLinkLbl		: "Povezava",
+InsertLink			: "Vstavi/uredi povezavo",
+RemoveLink			: "Odstrani povezavo",
+Anchor				: "Vstavi/uredi zaznamek",
+InsertImageLbl		: "Slika",
+InsertImage			: "Vstavi/uredi sliko",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Vstavi/Uredi Flash",
+InsertTableLbl		: "Tabela",
+InsertTable			: "Vstavi/uredi tabelo",
+InsertLineLbl		: "Črta",
+InsertLine			: "Vstavi vodoravno črto",
+InsertSpecialCharLbl: "Posebni znak",
+InsertSpecialChar	: "Vstavi posebni znak",
+InsertSmileyLbl		: "Smeško",
+InsertSmiley		: "Vstavi smeška",
+About				: "O FCKeditorju",
+Bold				: "Krepko",
+Italic				: "Ležeče",
+Underline			: "Podčrtano",
+StrikeThrough		: "Prečrtano",
+Subscript			: "Podpisano",
+Superscript			: "Nadpisano",
+LeftJustify			: "Leva poravnava",
+CenterJustify		: "Sredinska poravnava",
+RightJustify		: "Desna poravnava",
+BlockJustify		: "Obojestranska poravnava",
+DecreaseIndent		: "Zmanjšaj zamik",
+IncreaseIndent		: "Povečaj zamik",
+Undo				: "Razveljavi",
+Redo				: "Ponovi",
+NumberedListLbl		: "Oštevilčen seznam",
+NumberedList		: "Vstavi/odstrani oštevilčevanje",
+BulletedListLbl		: "Označen seznam",
+BulletedList		: "Vstavi/odstrani označevanje",
+ShowTableBorders	: "Pokaži meje tabele",
+ShowDetails			: "Pokaži podrobnosti",
+Style				: "Slog",
+FontFormat			: "Oblika",
+Font				: "Pisava",
+FontSize			: "Velikost",
+TextColor			: "Barva besedila",
+BGColor				: "Barva ozadja",
+Source				: "Izvorna koda",
+Find				: "Najdi",
+Replace				: "Zamenjaj",
+SpellCheck			: "Preveri črkovanje",
+UniversalKeyboard	: "Večjezična tipkovnica",
+PageBreakLbl		: "Prelom strani",
+PageBreak			: "Vstavi prelom strani",
+
+Form			: "Obrazec",
+Checkbox		: "Potrditveno polje",
+RadioButton		: "Izbirno polje",
+TextField		: "Vnosno polje",
+Textarea		: "Vnosno območje",
+HiddenField		: "Skrito polje",
+Button			: "Gumb",
+SelectionField	: "Spustni seznam",
+ImageButton		: "Gumb s sliko",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Uredi povezavo",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Vstavi vrstico",
+DeleteRows			: "Izbriši vrstice",
+InsertColumn		: "Vstavi stolpec",
+DeleteColumns		: "Izbriši stolpce",
+InsertCell			: "Vstavi celico",
+DeleteCells			: "Izbriši celice",
+MergeCells			: "Združi celice",
+SplitCell			: "Razdeli celico",
+TableDelete			: "Izbriši tabelo",
+CellProperties		: "Lastnosti celice",
+TableProperties		: "Lastnosti tabele",
+ImageProperties		: "Lastnosti slike",
+FlashProperties		: "Lastnosti Flash",
+
+AnchorProp			: "Lastnosti zaznamka",
+ButtonProp			: "Lastnosti gumba",
+CheckboxProp		: "Lastnosti potrditvenega polja",
+HiddenFieldProp		: "Lastnosti skritega polja",
+RadioButtonProp		: "Lastnosti izbirnega polja",
+ImageButtonProp		: "Lastnosti gumba s sliko",
+TextFieldProp		: "Lastnosti vnosnega polja",
+SelectionFieldProp	: "Lastnosti spustnega seznama",
+TextareaProp		: "Lastnosti vnosnega območja",
+FormProp			: "Lastnosti obrazca",
+
+FontFormats			: "Navaden;Oblikovan;Napis;Naslov 1;Naslov 2;Naslov 3;Naslov 4;Naslov 5;Naslov 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Obdelujem XHTML. Prosim počakajte...",
+Done				: "Narejeno",
+PasteWordConfirm	: "Izgleda, da želite prilepiti besedilo iz Worda. Ali ga želite očistiti, preden ga prilepite?",
+NotCompatiblePaste	: "Ta ukaz deluje le v Internet Explorerje različice 5.5 ali višje. Ali želite prilepiti brez čiščenja?",
+UnknownToolbarItem	: "Neznan element orodne vrstice \"%1\"",
+UnknownCommand		: "Neznano ime ukaza \"%1\"",
+NotImplemented		: "Ukaz ni izdelan",
+UnknownToolbarSet	: "Skupina orodnih vrstic \"%1\" ne obstoja",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "V redu",
+DlgBtnCancel		: "Prekliči",
+DlgBtnClose			: "Zapri",
+DlgBtnBrowseServer	: "Prebrskaj na strežniku",
+DlgAdvancedTag		: "Napredno",
+DlgOpOther			: "<Ostalo>",
+DlgInfoTab			: "Podatki",
+DlgAlertUrl			: "Prosim vpiši spletni naslov",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ni postavljen>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Smer jezika",
+DlgGenLangDirLtr	: "Od leve proti desni (LTR)",
+DlgGenLangDirRtl	: "Od desne proti levi (RTL)",
+DlgGenLangCode		: "Oznaka jezika",
+DlgGenAccessKey		: "Vstopno geslo",
+DlgGenName			: "Ime",
+DlgGenTabIndex		: "Številka tabulatorja",
+DlgGenLongDescr		: "Dolg opis URL-ja",
+DlgGenClass			: "Razred stilne predloge",
+DlgGenTitle			: "Predlagani naslov",
+DlgGenContType		: "Predlagani tip vsebine (content-type)",
+DlgGenLinkCharset	: "Kodna tabela povezanega vira",
+DlgGenStyle			: "Slog",
+
+// Image Dialog
+DlgImgTitle			: "Lastnosti slike",
+DlgImgInfoTab		: "Podatki o sliki",
+DlgImgBtnUpload		: "Pošlji na strežnik",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Pošlji",
+DlgImgAlt			: "Nadomestno besedilo",
+DlgImgWidth			: "Širina",
+DlgImgHeight		: "Višina",
+DlgImgLockRatio		: "Zakleni razmerje",
+DlgBtnResetSize		: "Ponastavi velikost",
+DlgImgBorder		: "Obroba",
+DlgImgHSpace		: "Vodoravni razmik",
+DlgImgVSpace		: "Navpični razmik",
+DlgImgAlign			: "Poravnava",
+DlgImgAlignLeft		: "Levo",
+DlgImgAlignAbsBottom: "Popolnoma na dno",
+DlgImgAlignAbsMiddle: "Popolnoma v sredino",
+DlgImgAlignBaseline	: "Na osnovno črto",
+DlgImgAlignBottom	: "Na dno",
+DlgImgAlignMiddle	: "V sredino",
+DlgImgAlignRight	: "Desno",
+DlgImgAlignTextTop	: "Besedilo na vrh",
+DlgImgAlignTop		: "Na vrh",
+DlgImgPreview		: "Predogled",
+DlgImgAlertUrl		: "Vnesite URL slike",
+DlgImgLinkTab		: "Povezava",
+
+// Flash Dialog
+DlgFlashTitle		: "Lastnosti Flash",
+DlgFlashChkPlay		: "Samodejno predvajaj",
+DlgFlashChkLoop		: "Ponavljanje",
+DlgFlashChkMenu		: "Omogoči Flash Meni",
+DlgFlashScale		: "Povečava",
+DlgFlashScaleAll	: "Pokaži vse",
+DlgFlashScaleNoBorder	: "Brez obrobe",
+DlgFlashScaleFit	: "Natančno prileganje",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Povezava",
+DlgLnkInfoTab		: "Podatki o povezavi",
+DlgLnkTargetTab		: "Cilj",
+
+DlgLnkType			: "Vrsta povezave",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Zaznamek na tej strani",
+DlgLnkTypeEMail		: "Elektronski naslov",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<drugo>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Izberi zaznamek",
+DlgLnkAnchorByName	: "Po imenu zaznamka",
+DlgLnkAnchorById	: "Po ID-ju elementa",
+DlgLnkNoAnchors		: "<V tem dokumentu ni zaznamkov>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Elektronski naslov",
+DlgLnkEMailSubject	: "Predmet sporočila",
+DlgLnkEMailBody		: "Vsebina sporočila",
+DlgLnkUpload		: "Prenesi",
+DlgLnkBtnUpload		: "Pošlji na strežnik",
+
+DlgLnkTarget		: "Cilj",
+DlgLnkTargetFrame	: "<okvir>",
+DlgLnkTargetPopup	: "<pojavno okno>",
+DlgLnkTargetBlank	: "Novo okno (_blank)",
+DlgLnkTargetParent	: "Starševsko okno (_parent)",
+DlgLnkTargetSelf	: "Isto okno (_self)",
+DlgLnkTargetTop		: "Najvišje okno (_top)",
+DlgLnkTargetFrameName	: "Ime ciljnega okvirja",
+DlgLnkPopWinName	: "Ime pojavnega okna",
+DlgLnkPopWinFeat	: "Značilnosti pojavnega okna",
+DlgLnkPopResize		: "Spremenljive velikosti",
+DlgLnkPopLocation	: "Naslovna vrstica",
+DlgLnkPopMenu		: "Menijska vrstica",
+DlgLnkPopScroll		: "Drsniki",
+DlgLnkPopStatus		: "Vrstica stanja",
+DlgLnkPopToolbar	: "Orodna vrstica",
+DlgLnkPopFullScrn	: "Celozaslonska slika (IE)",
+DlgLnkPopDependent	: "Podokno (Netscape)",
+DlgLnkPopWidth		: "Širina",
+DlgLnkPopHeight		: "Višina",
+DlgLnkPopLeft		: "Lega levo",
+DlgLnkPopTop		: "Lega na vrhu",
+
+DlnLnkMsgNoUrl		: "Vnesite URL povezave",
+DlnLnkMsgNoEMail	: "Vnesite elektronski naslov",
+DlnLnkMsgNoAnchor	: "Izberite zaznamek",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Izberite barvo",
+DlgColorBtnClear	: "Počisti",
+DlgColorHighlight	: "Označi",
+DlgColorSelected	: "Izbrano",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Vstavi smeška",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Izberi posebni znak",
+
+// Table Dialog
+DlgTableTitle		: "Lastnosti tabele",
+DlgTableRows		: "Vrstice",
+DlgTableColumns		: "Stolpci",
+DlgTableBorder		: "Velikost obrobe",
+DlgTableAlign		: "Poravnava",
+DlgTableAlignNotSet	: "<Ni nastavljeno>",
+DlgTableAlignLeft	: "Levo",
+DlgTableAlignCenter	: "Sredinsko",
+DlgTableAlignRight	: "Desno",
+DlgTableWidth		: "Širina",
+DlgTableWidthPx		: "pik",
+DlgTableWidthPc		: "procentov",
+DlgTableHeight		: "Višina",
+DlgTableCellSpace	: "Razmik med celicami",
+DlgTableCellPad		: "Polnilo med celicami",
+DlgTableCaption		: "Naslov",
+DlgTableSummary		: "Povzetek",
+
+// Table Cell Dialog
+DlgCellTitle		: "Lastnosti celice",
+DlgCellWidth		: "Širina",
+DlgCellWidthPx		: "pik",
+DlgCellWidthPc		: "procentov",
+DlgCellHeight		: "Višina",
+DlgCellWordWrap		: "Pomikanje besedila",
+DlgCellWordWrapNotSet	: "<Ni nastavljeno>",
+DlgCellWordWrapYes	: "Da",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Vodoravna poravnava",
+DlgCellHorAlignNotSet	: "<Ni nastavljeno>",
+DlgCellHorAlignLeft	: "Levo",
+DlgCellHorAlignCenter	: "Sredinsko",
+DlgCellHorAlignRight: "Desno",
+DlgCellVerAlign		: "Navpična poravnava",
+DlgCellVerAlignNotSet	: "<Ni nastavljeno>",
+DlgCellVerAlignTop	: "Na vrh",
+DlgCellVerAlignMiddle	: "V sredino",
+DlgCellVerAlignBottom	: "Na dno",
+DlgCellVerAlignBaseline	: "Na osnovno črto",
+DlgCellRowSpan		: "Spojenih vrstic (row-span)",
+DlgCellCollSpan		: "Spojenih stolpcev (col-span)",
+DlgCellBackColor	: "Barva ozadja",
+DlgCellBorderColor	: "Barva obrobe",
+DlgCellBtnSelect	: "Izberi...",
+
+// Find Dialog
+DlgFindTitle		: "Najdi",
+DlgFindFindBtn		: "Najdi",
+DlgFindNotFoundMsg	: "Navedeno besedilo ni bilo najdeno.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Zamenjaj",
+DlgReplaceFindLbl		: "Najdi:",
+DlgReplaceReplaceLbl	: "Zamenjaj z:",
+DlgReplaceCaseChk		: "Razlikuj velike in male črke",
+DlgReplaceReplaceBtn	: "Zamenjaj",
+DlgReplaceReplAllBtn	: "Zamenjaj vse",
+DlgReplaceWordChk		: "Samo cele besede",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Varnostne nastavitve brskalnika ne dopuščajo samodejnega izrezovanja. Uporabite kombinacijo tipk na tipkovnici (Ctrl+X).",
+PasteErrorCopy	: "Varnostne nastavitve brskalnika ne dopuščajo samodejnega kopiranja. Uporabite kombinacijo tipk na tipkovnici (Ctrl+C).",
+
+PasteAsText		: "Prilepi kot golo besedilo",
+PasteFromWord	: "Prilepi iz Worda",
+
+DlgPasteMsg2	: "Prosim prilepite v sleči okvir s pomočjo tipkovnice (<STRONG>Ctrl+V</STRONG>) in pritisnite <STRONG>V redu</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Prezri obliko pisave",
+DlgPasteRemoveStyles	: "Odstrani nastavitve stila",
+DlgPasteCleanBox		: "Počisti okvir",
+
+// Color Picker
+ColorAutomatic	: "Samodejno",
+ColorMoreColors	: "Več barv...",
+
+// Document Properties
+DocProps		: "Lastnosti dokumenta",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Lastnosti zaznamka",
+DlgAnchorName		: "Ime zaznamka",
+DlgAnchorErrorName	: "Prosim vnesite ime zaznamka",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ni v slovarju",
+DlgSpellChangeTo		: "Spremeni v",
+DlgSpellBtnIgnore		: "Prezri",
+DlgSpellBtnIgnoreAll	: "Prezri vse",
+DlgSpellBtnReplace		: "Zamenjaj",
+DlgSpellBtnReplaceAll	: "Zamenjaj vse",
+DlgSpellBtnUndo			: "Razveljavi",
+DlgSpellNoSuggestions	: "- Ni predlogov -",
+DlgSpellProgress		: "Preverjanje črkovanja se izvaja...",
+DlgSpellNoMispell		: "Črkovanje je končano: Brez napak",
+DlgSpellNoChanges		: "Črkovanje je končano: Nobena beseda ni bila spremenjena",
+DlgSpellOneChange		: "Črkovanje je končano: Spremenjena je bila ena beseda",
+DlgSpellManyChanges		: "Črkovanje je končano: Spremenjenih je bilo %1 besed",
+
+IeSpellDownload			: "Črkovalnik ni nameščen. Ali ga želite prenesti sedaj?",
+
+// Button Dialog
+DlgButtonText		: "Besedilo (Vrednost)",
+DlgButtonType		: "Tip",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Ime",
+DlgCheckboxValue	: "Vrednost",
+DlgCheckboxSelected	: "Izbrano",
+
+// Form Dialog
+DlgFormName		: "Ime",
+DlgFormAction	: "Akcija",
+DlgFormMethod	: "Metoda",
+
+// Select Field Dialog
+DlgSelectName		: "Ime",
+DlgSelectValue		: "Vrednost",
+DlgSelectSize		: "Velikost",
+DlgSelectLines		: "vrstic",
+DlgSelectChkMulti	: "Dovoli izbor večih vrstic",
+DlgSelectOpAvail	: "Razpoložljive izbire",
+DlgSelectOpText		: "Besedilo",
+DlgSelectOpValue	: "Vrednost",
+DlgSelectBtnAdd		: "Dodaj",
+DlgSelectBtnModify	: "Spremeni",
+DlgSelectBtnUp		: "Gor",
+DlgSelectBtnDown	: "Dol",
+DlgSelectBtnSetValue : "Postavi kot privzeto izbiro",
+DlgSelectBtnDelete	: "Izbriši",
+
+// Textarea Dialog
+DlgTextareaName	: "Ime",
+DlgTextareaCols	: "Stolpcev",
+DlgTextareaRows	: "Vrstic",
+
+// Text Field Dialog
+DlgTextName			: "Ime",
+DlgTextValue		: "Vrednost",
+DlgTextCharWidth	: "Dolžina",
+DlgTextMaxChars		: "Največje število znakov",
+DlgTextType			: "Tip",
+DlgTextTypeText		: "Besedilo",
+DlgTextTypePass		: "Geslo",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Ime",
+DlgHiddenValue	: "Vrednost",
+
+// Bulleted List Dialog
+BulletedListProp	: "Lastnosti označenega seznama",
+NumberedListProp	: "Lastnosti oštevilčenega seznama",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tip",
+DlgLstTypeCircle	: "Pikica",
+DlgLstTypeDisc		: "Kroglica",
+DlgLstTypeSquare	: "Kvadratek",
+DlgLstTypeNumbers	: "Številke (1, 2, 3)",
+DlgLstTypeLCase		: "Male črke (a, b, c)",
+DlgLstTypeUCase		: "Velike črke (A, B, C)",
+DlgLstTypeSRoman	: "Male rimske številke (i, ii, iii)",
+DlgLstTypeLRoman	: "Velike rimske številke (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Splošno",
+DlgDocBackTab		: "Ozadje",
+DlgDocColorsTab		: "Barve in zamiki",
+DlgDocMetaTab		: "Meta podatki",
+
+DlgDocPageTitle		: "Naslov strani",
+DlgDocLangDir		: "Smer jezika",
+DlgDocLangDirLTR	: "Od leve proti desni (LTR)",
+DlgDocLangDirRTL	: "Od desne proti levi (RTL)",
+DlgDocLangCode		: "Oznaka jezika",
+DlgDocCharSet		: "Kodna tabela",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Druga kodna tabela",
+
+DlgDocDocType		: "Glava tipa dokumenta",
+DlgDocDocTypeOther	: "Druga glava tipa dokumenta",
+DlgDocIncXHTML		: "Vstavi XHTML deklaracije",
+DlgDocBgColor		: "Barva ozadja",
+DlgDocBgImage		: "URL slike za ozadje",
+DlgDocBgNoScroll	: "Nepremično ozadje",
+DlgDocCText			: "Besedilo",
+DlgDocCLink			: "Povezava",
+DlgDocCVisited		: "Obiskana povezava",
+DlgDocCActive		: "Aktivna povezava",
+DlgDocMargins		: "Zamiki strani",
+DlgDocMaTop			: "Na vrhu",
+DlgDocMaLeft		: "Levo",
+DlgDocMaRight		: "Desno",
+DlgDocMaBottom		: "Spodaj",
+DlgDocMeIndex		: "Ključne besede (ločene z vejicami)",
+DlgDocMeDescr		: "Opis strani",
+DlgDocMeAuthor		: "Avtor",
+DlgDocMeCopy		: "Avtorske pravice",
+DlgDocPreview		: "Predogled",
+
+// Templates Dialog
+Templates			: "Predloge",
+DlgTemplatesTitle	: "Vsebinske predloge",
+DlgTemplatesSelMsg	: "Izberite predlogo, ki jo želite odpreti v urejevalniku<br>(trenutna vsebina bo izgubljena):",
+DlgTemplatesLoading	: "Nalagam seznam predlog. Prosim počakajte...",
+DlgTemplatesNoTpl	: "(Ni pripravljenih predlog)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Vizitka",
+DlgAboutBrowserInfoTab	: "Informacije o brskalniku",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "različica",
+DlgAboutInfo		: "Za več informacij obiščite"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/lt.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/lt.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/lt.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Lithuanian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Sutraukti mygtukų juostą",
+ToolbarExpand		: "Išplėsti mygtukų juostą",
+
+// Toolbar Items and Context Menu
+Save				: "Išsaugoti",
+NewPage				: "Naujas puslapis",
+Preview				: "Peržiūra",
+Cut					: "Iškirpti",
+Copy				: "Kopijuoti",
+Paste				: "Įdėti",
+PasteText			: "Įdėti kaip gryną tekstą",
+PasteWord			: "Įdėti iš Word",
+Print				: "Spausdinti",
+SelectAll			: "Pažymėti viską",
+RemoveFormat		: "Panaikinti formatą",
+InsertLinkLbl		: "Nuoroda",
+InsertLink			: "Įterpti/taisyti nuorodą",
+RemoveLink			: "Panaikinti nuorodą",
+Anchor				: "Įterpti/modifikuoti žymę",
+InsertImageLbl		: "Vaizdas",
+InsertImage			: "Įterpti/taisyti vaizdą",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Įterpti/taisyti Flash",
+InsertTableLbl		: "Lentelė",
+InsertTable			: "Įterpti/taisyti lentelę",
+InsertLineLbl		: "Linija",
+InsertLine			: "Įterpti horizontalią liniją",
+InsertSpecialCharLbl: "Spec. simbolis",
+InsertSpecialChar	: "Įterpti specialų simbolį",
+InsertSmileyLbl		: "Veideliai",
+InsertSmiley		: "Įterpti veidelį",
+About				: "Apie FCKeditor",
+Bold				: "Pusjuodis",
+Italic				: "Kursyvas",
+Underline			: "Pabrauktas",
+StrikeThrough		: "Perbrauktas",
+Subscript			: "Apatinis indeksas",
+Superscript			: "Viršutinis indeksas",
+LeftJustify			: "Lygiuoti kairę",
+CenterJustify		: "Centruoti",
+RightJustify		: "Lygiuoti dešinę",
+BlockJustify		: "Lygiuoti abi puses",
+DecreaseIndent		: "Sumažinti įtrauką",
+IncreaseIndent		: "Padidinti įtrauką",
+Undo				: "Atšaukti",
+Redo				: "Atstatyti",
+NumberedListLbl		: "Numeruotas sąrašas",
+NumberedList		: "Įterpti/Panaikinti numeruotą sąrašą",
+BulletedListLbl		: "Suženklintas sąrašas",
+BulletedList		: "Įterpti/Panaikinti suženklintą sąrašą",
+ShowTableBorders	: "Rodyti lentelės rėmus",
+ShowDetails			: "Rodyti detales",
+Style				: "Stilius",
+FontFormat			: "Šrifto formatas",
+Font				: "Šriftas",
+FontSize			: "Šrifto dydis",
+TextColor			: "Teksto spalva",
+BGColor				: "Fono spalva",
+Source				: "Šaltinis",
+Find				: "Rasti",
+Replace				: "Pakeisti",
+SpellCheck			: "Rašybos tikrinimas",
+UniversalKeyboard	: "Universali klaviatūra",
+PageBreakLbl		: "Puslapių skirtukas",
+PageBreak			: "Įterpti puslapių skirtuką",
+
+Form			: "Forma",
+Checkbox		: "Žymimasis langelis",
+RadioButton		: "Žymimoji akutė",
+TextField		: "Teksto laukas",
+Textarea		: "Teksto sritis",
+HiddenField		: "Nerodomas laukas",
+Button			: "Mygtukas",
+SelectionField	: "Atrankos laukas",
+ImageButton		: "Vaizdinis mygtukas",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Taisyti nuorodą",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Įterpti eilutę",
+DeleteRows			: "Šalinti eilutes",
+InsertColumn		: "Įterpti stulpelį",
+DeleteColumns		: "Šalinti stulpelius",
+InsertCell			: "Įterpti langelį",
+DeleteCells			: "Šalinti langelius",
+MergeCells			: "Sujungti langelius",
+SplitCell			: "Skaidyti langelius",
+TableDelete			: "Šalinti lentelę",
+CellProperties		: "Langelio savybės",
+TableProperties		: "Lentelės savybės",
+ImageProperties		: "Vaizdo savybės",
+FlashProperties		: "Flash savybės",
+
+AnchorProp			: "Žymės savybės",
+ButtonProp			: "Mygtuko savybės",
+CheckboxProp		: "Žymimojo langelio savybės",
+HiddenFieldProp		: "Nerodomo lauko savybės",
+RadioButtonProp		: "Žymimosios akutės savybės",
+ImageButtonProp		: "Vaizdinio mygtuko savybės",
+TextFieldProp		: "Teksto lauko savybės",
+SelectionFieldProp	: "Atrankos lauko savybės",
+TextareaProp		: "Teksto srities savybės",
+FormProp			: "Formos savybės",
+
+FontFormats			: "Normalus;Formuotas;Kreipinio;Antraštinis 1;Antraštinis 2;Antraštinis 3;Antraštinis 4;Antraštinis 5;Antraštinis 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Apdorojamas XHTML. Prašome palaukti...",
+Done				: "Baigta",
+PasteWordConfirm	: "Įdedamas tekstas yra panašus į kopiją iš Word. Ar Jūs norite prieš įdėjimą išvalyti jį?",
+NotCompatiblePaste	: "Ši komanda yra prieinama tik per Internet Explorer 5.5 ar aukštesnę versiją. Ar Jūs norite įterpti be valymo?",
+UnknownToolbarItem	: "Nežinomas mygtukų juosta elementas \"%1\"",
+UnknownCommand		: "Nežinomas komandos vardas \"%1\"",
+NotImplemented		: "Komanda nėra įgyvendinta",
+UnknownToolbarSet	: "Mygtukų juostos rinkinys \"%1\" neegzistuoja",
+NoActiveX			: "Jūsų naršyklės saugumo nuostatos gali riboti kai kurias redaktoriaus savybes. Jūs turite aktyvuoti opciją \"Run ActiveX controls and plug-ins\". Kitu atveju Jums bus pranešama apie klaidas ir trūkstamas savybes.",
+BrowseServerBlocked : "Neįmanoma atidaryti naujo naršyklės lango. Įsitikinkite, kad iškylančių langų blokavimo programos neveiksnios.",
+DialogBlocked		: "Neįmanoma atidaryti dialogo lango. Įsitikinkite, kad iškylančių langų blokavimo programos neveiksnios.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Nutraukti",
+DlgBtnClose			: "Uždaryti",
+DlgBtnBrowseServer	: "Naršyti po serverį",
+DlgAdvancedTag		: "Papildomas",
+DlgOpOther			: "<Kita>",
+DlgInfoTab			: "Informacija",
+DlgAlertUrl			: "Prašome įrašyti URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nėra nustatyta>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Teksto kryptis",
+DlgGenLangDirLtr	: "Iš kairės į dešinę (LTR)",
+DlgGenLangDirRtl	: "Iš dešinės į kairę (RTL)",
+DlgGenLangCode		: "Kalbos kodas",
+DlgGenAccessKey		: "Prieigos raktas",
+DlgGenName			: "Vardas",
+DlgGenTabIndex		: "Tabuliavimo indeksas",
+DlgGenLongDescr		: "Ilgas aprašymas URL",
+DlgGenClass			: "Stilių lentelės klasės",
+DlgGenTitle			: "Konsultacinė antraštė",
+DlgGenContType		: "Konsultacinio turinio tipas",
+DlgGenLinkCharset	: "Susietų išteklių simbolių lentelė",
+DlgGenStyle			: "Stilius",
+
+// Image Dialog
+DlgImgTitle			: "Vaizdo savybės",
+DlgImgInfoTab		: "Vaizdo informacija",
+DlgImgBtnUpload		: "Siųsti į serverį",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Nusiųsti",
+DlgImgAlt			: "Alternatyvus Tekstas",
+DlgImgWidth			: "Plotis",
+DlgImgHeight		: "Aukštis",
+DlgImgLockRatio		: "Išlaikyti proporciją",
+DlgBtnResetSize		: "Atstatyti dydį",
+DlgImgBorder		: "Rėmelis",
+DlgImgHSpace		: "Hor.Erdvė",
+DlgImgVSpace		: "Vert.Erdvė",
+DlgImgAlign			: "Lygiuoti",
+DlgImgAlignLeft		: "Kairę",
+DlgImgAlignAbsBottom: "Absoliučią apačią",
+DlgImgAlignAbsMiddle: "Absoliutų vidurį",
+DlgImgAlignBaseline	: "Apatinę liniją",
+DlgImgAlignBottom	: "Apačią",
+DlgImgAlignMiddle	: "Vidurį",
+DlgImgAlignRight	: "Dešinę",
+DlgImgAlignTextTop	: "Teksto viršūnę",
+DlgImgAlignTop		: "Viršūnę",
+DlgImgPreview		: "Peržiūra",
+DlgImgAlertUrl		: "Prašome įvesti vaizdo URL",
+DlgImgLinkTab		: "Nuoroda",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash savybės",
+DlgFlashChkPlay		: "Automatinis paleidimas",
+DlgFlashChkLoop		: "Ciklas",
+DlgFlashChkMenu		: "Leisti Flash meniu",
+DlgFlashScale		: "Mastelis",
+DlgFlashScaleAll	: "Rodyti visą",
+DlgFlashScaleNoBorder	: "Be rėmelio",
+DlgFlashScaleFit	: "Tikslus atitikimas",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Nuoroda",
+DlgLnkInfoTab		: "Nuorodos informacija",
+DlgLnkTargetTab		: "Paskirtis",
+
+DlgLnkType			: "Nuorodos tipas",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Žymė šiame puslapyje",
+DlgLnkTypeEMail		: "El.paštas",
+DlgLnkProto			: "Protokolas",
+DlgLnkProtoOther	: "<kitas>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Pasirinkite žymę",
+DlgLnkAnchorByName	: "Pagal žymės vardą",
+DlgLnkAnchorById	: "Pagal žymės Id",
+DlgLnkNoAnchors		: "<Šiame dokumente žymių nėra>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "El.pašto adresas",
+DlgLnkEMailSubject	: "Žinutės tema",
+DlgLnkEMailBody		: "Žinutės turinys",
+DlgLnkUpload		: "Siųsti",
+DlgLnkBtnUpload		: "Siųsti į serverį",
+
+DlgLnkTarget		: "Paskirties vieta",
+DlgLnkTargetFrame	: "<kadras>",
+DlgLnkTargetPopup	: "<išskleidžiamas langas>",
+DlgLnkTargetBlank	: "Naujas langas (_blank)",
+DlgLnkTargetParent	: "Pirminis langas (_parent)",
+DlgLnkTargetSelf	: "Tas pats langas (_self)",
+DlgLnkTargetTop		: "Svarbiausias langas (_top)",
+DlgLnkTargetFrameName	: "Paskirties kadro vardas",
+DlgLnkPopWinName	: "Paskirties lango vardas",
+DlgLnkPopWinFeat	: "Išskleidžiamo lango savybės",
+DlgLnkPopResize		: "Keičiamas dydis",
+DlgLnkPopLocation	: "Adreso juosta",
+DlgLnkPopMenu		: "Meniu juosta",
+DlgLnkPopScroll		: "Slinkties juostos",
+DlgLnkPopStatus		: "Būsenos juosta",
+DlgLnkPopToolbar	: "Mygtukų juosta",
+DlgLnkPopFullScrn	: "Visas ekranas (IE)",
+DlgLnkPopDependent	: "Priklausomas (Netscape)",
+DlgLnkPopWidth		: "Plotis",
+DlgLnkPopHeight		: "Aukštis",
+DlgLnkPopLeft		: "Kairė pozicija",
+DlgLnkPopTop		: "Viršutinė pozicija",
+
+DlnLnkMsgNoUrl		: "Prašome įvesti nuorodos URL",
+DlnLnkMsgNoEMail	: "Prašome įvesti el.pašto adresą",
+DlnLnkMsgNoAnchor	: "Prašome pasirinkti žymę",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Pasirinkite spalvą",
+DlgColorBtnClear	: "Trinti",
+DlgColorHighlight	: "Paryškinta",
+DlgColorSelected	: "Pažymėta",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Įterpti veidelį",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Pasirinkite specialų simbolį",
+
+// Table Dialog
+DlgTableTitle		: "Lentelės savybės",
+DlgTableRows		: "Eilutės",
+DlgTableColumns		: "Stulpeliai",
+DlgTableBorder		: "Rėmelio dydis",
+DlgTableAlign		: "Lygiuoti",
+DlgTableAlignNotSet	: "<Nenustatyta>",
+DlgTableAlignLeft	: "Kairę",
+DlgTableAlignCenter	: "Centrą",
+DlgTableAlignRight	: "Dešinę",
+DlgTableWidth		: "Plotis",
+DlgTableWidthPx		: "taškais",
+DlgTableWidthPc		: "procentais",
+DlgTableHeight		: "Aukštis",
+DlgTableCellSpace	: "Tarpas tarp langelių",
+DlgTableCellPad		: "Trapas nuo langelio rėmo iki teksto",
+DlgTableCaption		: "Antraštė",
+DlgTableSummary		: "Santrauka",
+
+// Table Cell Dialog
+DlgCellTitle		: "Langelio savybės",
+DlgCellWidth		: "Plotis",
+DlgCellWidthPx		: "taškais",
+DlgCellWidthPc		: "procentais",
+DlgCellHeight		: "Aukštis",
+DlgCellWordWrap		: "Teksto laužymas",
+DlgCellWordWrapNotSet	: "<Nenustatyta>",
+DlgCellWordWrapYes	: "Taip",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Horizontaliai lygiuoti",
+DlgCellHorAlignNotSet	: "<Nenustatyta>",
+DlgCellHorAlignLeft	: "Kairę",
+DlgCellHorAlignCenter	: "Centrą",
+DlgCellHorAlignRight: "Dešinę",
+DlgCellVerAlign		: "Vertikaliai lygiuoti",
+DlgCellVerAlignNotSet	: "<Nenustatyta>",
+DlgCellVerAlignTop	: "Viršų",
+DlgCellVerAlignMiddle	: "Vidurį",
+DlgCellVerAlignBottom	: "Apačią",
+DlgCellVerAlignBaseline	: "Apatinę liniją",
+DlgCellRowSpan		: "Eilučių apjungimas",
+DlgCellCollSpan		: "Stulpelių apjungimas",
+DlgCellBackColor	: "Fono spalva",
+DlgCellBorderColor	: "Rėmelio spalva",
+DlgCellBtnSelect	: "Pažymėti...",
+
+// Find Dialog
+DlgFindTitle		: "Paieška",
+DlgFindFindBtn		: "Surasti",
+DlgFindNotFoundMsg	: "Nurodytas tekstas nerastas.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Pakeisti",
+DlgReplaceFindLbl		: "Surasti tekstą:",
+DlgReplaceReplaceLbl	: "Pakeisti tekstu:",
+DlgReplaceCaseChk		: "Skirti didžiąsias ir mažąsias raides",
+DlgReplaceReplaceBtn	: "Pakeisti",
+DlgReplaceReplAllBtn	: "Pakeisti viską",
+DlgReplaceWordChk		: "Atitikti pilną žodį",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti iškirpimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl+X).",
+PasteErrorCopy	: "Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti kopijavimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl+C).",
+
+PasteAsText		: "Įdėti kaip gryną tekstą",
+PasteFromWord	: "Įdėti iš Word",
+
+DlgPasteMsg2	: "Žemiau esančiame įvedimo lauke įdėkite tekstą, naudodami klaviatūrą (<STRONG>Ctrl+V</STRONG>) ir spūstelkite mygtuką <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoruoti šriftų nustatymus",
+DlgPasteRemoveStyles	: "Pašalinti stilių nustatymus",
+DlgPasteCleanBox		: "Trinti įvedimo lauką",
+
+// Color Picker
+ColorAutomatic	: "Automatinis",
+ColorMoreColors	: "Daugiau spalvų...",
+
+// Document Properties
+DocProps		: "Dokumento savybės",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Žymės savybės",
+DlgAnchorName		: "Žymės vardas",
+DlgAnchorErrorName	: "Prašome įvesti žymės vardą",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Žodyne nerastas",
+DlgSpellChangeTo		: "Pakeisti į",
+DlgSpellBtnIgnore		: "Ignoruoti",
+DlgSpellBtnIgnoreAll	: "Ignoruoti visus",
+DlgSpellBtnReplace		: "Pakeisti",
+DlgSpellBtnReplaceAll	: "Pakeisti visus",
+DlgSpellBtnUndo			: "Atšaukti",
+DlgSpellNoSuggestions	: "- Nėra pasiūlymų -",
+DlgSpellProgress		: "Vyksta rašybos tikrinimas...",
+DlgSpellNoMispell		: "Rašybos tikrinimas baigtas: Nerasta rašybos klaidų",
+DlgSpellNoChanges		: "Rašybos tikrinimas baigtas: Nėra pakeistų žodžių",
+DlgSpellOneChange		: "Rašybos tikrinimas baigtas: Vienas žodis pakeistas",
+DlgSpellManyChanges		: "Rašybos tikrinimas baigtas: Pakeista %1 žodžių",
+
+IeSpellDownload			: "Rašybos tikrinimas neinstaliuotas. Ar Jūs norite jį dabar atsisiųsti?",
+
+// Button Dialog
+DlgButtonText		: "Tekstas (Reikšmė)",
+DlgButtonType		: "Tipas",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Vardas",
+DlgCheckboxValue	: "Reikšmė",
+DlgCheckboxSelected	: "Pažymėtas",
+
+// Form Dialog
+DlgFormName		: "Vardas",
+DlgFormAction	: "Veiksmas",
+DlgFormMethod	: "Metodas",
+
+// Select Field Dialog
+DlgSelectName		: "Vardas",
+DlgSelectValue		: "Reikšmė",
+DlgSelectSize		: "Dydis",
+DlgSelectLines		: "eilučių",
+DlgSelectChkMulti	: "Leisti daugeriopą atranką",
+DlgSelectOpAvail	: "Galimos parinktys",
+DlgSelectOpText		: "Tekstas",
+DlgSelectOpValue	: "Reikšmė",
+DlgSelectBtnAdd		: "Įtraukti",
+DlgSelectBtnModify	: "Modifikuoti",
+DlgSelectBtnUp		: "Aukštyn",
+DlgSelectBtnDown	: "Žemyn",
+DlgSelectBtnSetValue : "Laikyti pažymėta reikšme",
+DlgSelectBtnDelete	: "Trinti",
+
+// Textarea Dialog
+DlgTextareaName	: "Vardas",
+DlgTextareaCols	: "Ilgis",
+DlgTextareaRows	: "Plotis",
+
+// Text Field Dialog
+DlgTextName			: "Vardas",
+DlgTextValue		: "Reikšmė",
+DlgTextCharWidth	: "Ilgis simboliais",
+DlgTextMaxChars		: "Maksimalus simbolių skaičius",
+DlgTextType			: "Tipas",
+DlgTextTypeText		: "Tekstas",
+DlgTextTypePass		: "Slaptažodis",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Vardas",
+DlgHiddenValue	: "Reikšmė",
+
+// Bulleted List Dialog
+BulletedListProp	: "Suženklinto sąrašo savybės",
+NumberedListProp	: "Numeruoto sąrašo savybės",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tipas",
+DlgLstTypeCircle	: "Apskritimas",
+DlgLstTypeDisc		: "Diskas",
+DlgLstTypeSquare	: "Kvadratas",
+DlgLstTypeNumbers	: "Skaičiai (1, 2, 3)",
+DlgLstTypeLCase		: "Mažosios raidės (a, b, c)",
+DlgLstTypeUCase		: "Didžiosios raidės (A, B, C)",
+DlgLstTypeSRoman	: "Romėnų mažieji skaičiai (i, ii, iii)",
+DlgLstTypeLRoman	: "Romėnų didieji skaičiai (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Bendros savybės",
+DlgDocBackTab		: "Fonas",
+DlgDocColorsTab		: "Spalvos ir kraštinės",
+DlgDocMetaTab		: "Meta duomenys",
+
+DlgDocPageTitle		: "Puslapio antraštė",
+DlgDocLangDir		: "Kalbos kryptis",
+DlgDocLangDirLTR	: "Iš kairės į dešinę (LTR)",
+DlgDocLangDirRTL	: "Iš dešinės į kairę (RTL)",
+DlgDocLangCode		: "Kalbos kodas",
+DlgDocCharSet		: "Simbolių kodavimo lentelė",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Kita simbolių kodavimo lentelė",
+
+DlgDocDocType		: "Dokumento tipo antraštė",
+DlgDocDocTypeOther	: "Kita dokumento tipo antraštė",
+DlgDocIncXHTML		: "Įtraukti XHTML deklaracijas",
+DlgDocBgColor		: "Fono spalva",
+DlgDocBgImage		: "Fono paveikslėlio nuoroda (URL)",
+DlgDocBgNoScroll	: "Neslenkantis fonas",
+DlgDocCText			: "Tekstas",
+DlgDocCLink			: "Nuoroda",
+DlgDocCVisited		: "Aplankyta nuoroda",
+DlgDocCActive		: "Aktyvi nuoroda",
+DlgDocMargins		: "Puslapio kraštinės",
+DlgDocMaTop			: "Viršuje",
+DlgDocMaLeft		: "Kairėje",
+DlgDocMaRight		: "Dešinėje",
+DlgDocMaBottom		: "Apačioje",
+DlgDocMeIndex		: "Dokumento indeksavimo raktiniai žodžiai (atskirti kableliais)",
+DlgDocMeDescr		: "Dokumento apibūdinimas",
+DlgDocMeAuthor		: "Autorius",
+DlgDocMeCopy		: "Autorinės teisės",
+DlgDocPreview		: "Peržiūra",
+
+// Templates Dialog
+Templates			: "Šablonai",
+DlgTemplatesTitle	: "Turinio šablonai",
+DlgTemplatesSelMsg	: "Pasirinkite norimą šabloną<br>(<b>Dėmesio!</b> esamas turinys bus prarastas):",
+DlgTemplatesLoading	: "Įkeliamas šablonų sąrašas. Prašome palaukti...",
+DlgTemplatesNoTpl	: "(Šablonų sąrašas tuščias)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Apie",
+DlgAboutBrowserInfoTab	: "Naršyklės informacija",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "versija",
+DlgAboutInfo		: "Papildomą informaciją galima gauti"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sr-latn.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sr-latn.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sr-latn.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Serbian (Latin) language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Smanji liniju sa alatkama",
+ToolbarExpand		: "Proiri liniju sa alatkama",
+
+// Toolbar Items and Context Menu
+Save				: "Sačuvaj",
+NewPage				: "Nova stranica",
+Preview				: "Izgled stranice",
+Cut					: "Iseci",
+Copy				: "Kopiraj",
+Paste				: "Zalepi",
+PasteText			: "Zalepi kao neformatiran tekst",
+PasteWord			: "Zalepi iz Worda",
+Print				: "Štampa",
+SelectAll			: "Označi sve",
+RemoveFormat		: "Ukloni formatiranje",
+InsertLinkLbl		: "Link",
+InsertLink			: "Unesi/izmeni link",
+RemoveLink			: "Ukloni link",
+Anchor				: "Unesi/izmeni sidro",
+InsertImageLbl		: "Slika",
+InsertImage			: "Unesi/izmeni sliku",
+InsertFlashLbl		: "Fleš",
+InsertFlash			: "Unesi/izmeni fleš",
+InsertTableLbl		: "Tabela",
+InsertTable			: "Unesi/izmeni tabelu",
+InsertLineLbl		: "Linija",
+InsertLine			: "Unesi horizontalnu liniju",
+InsertSpecialCharLbl: "Specijalni karakteri",
+InsertSpecialChar	: "Unesi specijalni karakter",
+InsertSmileyLbl		: "Smajli",
+InsertSmiley		: "Unesi smajlija",
+About				: "O FCKeditoru",
+Bold				: "Podebljano",
+Italic				: "Kurziv",
+Underline			: "Podvučeno",
+StrikeThrough		: "Precrtano",
+Subscript			: "Indeks",
+Superscript			: "Stepen",
+LeftJustify			: "Levo ravnanje",
+CenterJustify		: "Centriran tekst",
+RightJustify		: "Desno ravnanje",
+BlockJustify		: "Obostrano ravnanje",
+DecreaseIndent		: "Smanji levu marginu",
+IncreaseIndent		: "Uvećaj levu marginu",
+Undo				: "Poni�ti akciju",
+Redo				: "Ponovi akciju",
+NumberedListLbl		: "Nabrojiva lista",
+NumberedList		: "Unesi/ukloni nabrojivu listu",
+BulletedListLbl		: "Nenabrojiva lista",
+BulletedList		: "Unesi/ukloni nenabrojivu listu",
+ShowTableBorders	: "Prikaži okvir tabele",
+ShowDetails			: "Prikaži detalje",
+Style				: "Stil",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Veličina fonta",
+TextColor			: "Boja teksta",
+BGColor				: "Boja pozadine",
+Source				: "Kôd",
+Find				: "Pretraga",
+Replace				: "Zamena",
+SpellCheck			: "Proveri spelovanje",
+UniversalKeyboard	: "Univerzalna tastatura",
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "Forma",
+Checkbox		: "Polje za potvrdu",
+RadioButton		: "Radio-dugme",
+TextField		: "Tekstualno polje",
+Textarea		: "Zona teksta",
+HiddenField		: "Skriveno polje",
+Button			: "Dugme",
+SelectionField	: "Izborno polje",
+ImageButton		: "Dugme sa slikom",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Izmeni link",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Unesi red",
+DeleteRows			: "Obriši redove",
+InsertColumn		: "Unesi kolonu",
+DeleteColumns		: "Obriši kolone",
+InsertCell			: "Unesi ćelije",
+DeleteCells			: "Obriši ćelije",
+MergeCells			: "Spoj celije",
+SplitCell			: "Razdvoji celije",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "Osobine celije",
+TableProperties		: "Osobine tabele",
+ImageProperties		: "Osobine slike",
+FlashProperties		: "Osobine fleša",
+
+AnchorProp			: "Osobine sidra",
+ButtonProp			: "Osobine dugmeta",
+CheckboxProp		: "Osobine polja za potvrdu",
+HiddenFieldProp		: "Osobine skrivenog polja",
+RadioButtonProp		: "Osobine radio-dugmeta",
+ImageButtonProp		: "Osobine dugmeta sa slikom",
+TextFieldProp		: "Osobine tekstualnog polja",
+SelectionFieldProp	: "Osobine izbornog polja",
+TextareaProp		: "Osobine zone teksta",
+FormProp			: "Osobine forme",
+
+FontFormats			: "Normal;Formatirano;Adresa;Naslov 1;Naslov 2;Naslov 3;Naslov 4;Naslov 5;Naslov 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Obradujem XHTML. Malo strpljenja...",
+Done				: "Završio",
+PasteWordConfirm	: "Tekst koji želite da nalepite kopiran je iz Worda. Da li želite da bude očišćen od formata pre lepljenja?",
+NotCompatiblePaste	: "Ova komanda je dostupna samo za Internet Explorer od verzije 5.5. Da li želite da nalepim tekst bez čišćenja?",
+UnknownToolbarItem	: "Nepoznata stavka toolbara \"%1\"",
+UnknownCommand		: "Nepoznata naredba \"%1\"",
+NotImplemented		: "Naredba nije implementirana",
+UnknownToolbarSet	: "Toolbar \"%1\" ne postoji",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Otkaži",
+DlgBtnClose			: "Zatvori",
+DlgBtnBrowseServer	: "Pretraži server",
+DlgAdvancedTag		: "Napredni tagovi",
+DlgOpOther			: "<Ostali>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Molimo Vas, unesite URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nije postavljeno>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Smer jezika",
+DlgGenLangDirLtr	: "S leva na desno (LTR)",
+DlgGenLangDirRtl	: "S desna na levo (RTL)",
+DlgGenLangCode		: "Kôd jezika",
+DlgGenAccessKey		: "Pristupni taster",
+DlgGenName			: "Naziv",
+DlgGenTabIndex		: "Tab indeks",
+DlgGenLongDescr		: "Pun opis URL",
+DlgGenClass			: "Stylesheet klase",
+DlgGenTitle			: "Advisory naslov",
+DlgGenContType		: "Advisory vrsta sadržaja",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Stil",
+
+// Image Dialog
+DlgImgTitle			: "Osobine slika",
+DlgImgInfoTab		: "Info slike",
+DlgImgBtnUpload		: "Pošalji na server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Pošalji",
+DlgImgAlt			: "Alternativni tekst",
+DlgImgWidth			: "Širina",
+DlgImgHeight		: "Visina",
+DlgImgLockRatio		: "Zaključaj odnos",
+DlgBtnResetSize		: "Resetuj veličinu",
+DlgImgBorder		: "Okvir",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Ravnanje",
+DlgImgAlignLeft		: "Levo",
+DlgImgAlignAbsBottom: "Abs dole",
+DlgImgAlignAbsMiddle: "Abs sredina",
+DlgImgAlignBaseline	: "Bazno",
+DlgImgAlignBottom	: "Dole",
+DlgImgAlignMiddle	: "Sredina",
+DlgImgAlignRight	: "Desno",
+DlgImgAlignTextTop	: "Vrh teksta",
+DlgImgAlignTop		: "Vrh",
+DlgImgPreview		: "Izgled",
+DlgImgAlertUrl		: "Unesite URL slike",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Osobine fleša",
+DlgFlashChkPlay		: "Automatski start",
+DlgFlashChkLoop		: "Ponavljaj",
+DlgFlashChkMenu		: "Uključi fleš meni",
+DlgFlashScale		: "Skaliraj",
+DlgFlashScaleAll	: "Prikaži sve",
+DlgFlashScaleNoBorder	: "Bez ivice",
+DlgFlashScaleFit	: "Popuni površinu",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Meta",
+
+DlgLnkType			: "Vrsta linka",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Sidro na ovoj stranici",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<drugo>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Odaberi sidro",
+DlgLnkAnchorByName	: "Po nazivu sidra",
+DlgLnkAnchorById	: "Po Id-ju elementa",
+DlgLnkNoAnchors		: "<Nema dostupnih sidra>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail adresa",
+DlgLnkEMailSubject	: "Naslov",
+DlgLnkEMailBody		: "Sadržaj poruke",
+DlgLnkUpload		: "Pošalji",
+DlgLnkBtnUpload		: "Pošalji na server",
+
+DlgLnkTarget		: "Meta",
+DlgLnkTargetFrame	: "<okvir>",
+DlgLnkTargetPopup	: "<popup prozor>",
+DlgLnkTargetBlank	: "Novi prozor (_blank)",
+DlgLnkTargetParent	: "Roditeljski prozor (_parent)",
+DlgLnkTargetSelf	: "Isti prozor (_self)",
+DlgLnkTargetTop		: "Prozor na vrhu (_top)",
+DlgLnkTargetFrameName	: "Naziv odredišnog frejma",
+DlgLnkPopWinName	: "Naziv popup prozora",
+DlgLnkPopWinFeat	: "Mogućnosti popup prozora",
+DlgLnkPopResize		: "Promenljiva velicina",
+DlgLnkPopLocation	: "Lokacija",
+DlgLnkPopMenu		: "Kontekstni meni",
+DlgLnkPopScroll		: "Scroll bar",
+DlgLnkPopStatus		: "Statusna linija",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Prikaz preko celog ekrana (IE)",
+DlgLnkPopDependent	: "Zavisno (Netscape)",
+DlgLnkPopWidth		: "Širina",
+DlgLnkPopHeight		: "Visina",
+DlgLnkPopLeft		: "Od leve ivice ekrana (px)",
+DlgLnkPopTop		: "Od vrha ekrana (px)",
+
+DlnLnkMsgNoUrl		: "Unesite URL linka",
+DlnLnkMsgNoEMail	: "Otkucajte adresu elektronske pote",
+DlnLnkMsgNoAnchor	: "Odaberite sidro",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Odaberite boju",
+DlgColorBtnClear	: "Obriši",
+DlgColorHighlight	: "Posvetli",
+DlgColorSelected	: "Odaberi",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Unesi smajlija",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Odaberite specijalni karakter",
+
+// Table Dialog
+DlgTableTitle		: "Osobine tabele",
+DlgTableRows		: "Redova",
+DlgTableColumns		: "Kolona",
+DlgTableBorder		: "Veličina okvira",
+DlgTableAlign		: "Ravnanje",
+DlgTableAlignNotSet	: "<nije postavljeno>",
+DlgTableAlignLeft	: "Levo",
+DlgTableAlignCenter	: "Sredina",
+DlgTableAlignRight	: "Desno",
+DlgTableWidth		: "Širina",
+DlgTableWidthPx		: "piksela",
+DlgTableWidthPc		: "procenata",
+DlgTableHeight		: "Visina",
+DlgTableCellSpace	: "Ćelijski prostor",
+DlgTableCellPad		: "Razmak ćelija",
+DlgTableCaption		: "Naslov tabele",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "Osobine ćelije",
+DlgCellWidth		: "Širina",
+DlgCellWidthPx		: "piksela",
+DlgCellWidthPc		: "procenata",
+DlgCellHeight		: "Visina",
+DlgCellWordWrap		: "Deljenje reči",
+DlgCellWordWrapNotSet	: "<nije postavljeno>",
+DlgCellWordWrapYes	: "Da",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Vodoravno ravnanje",
+DlgCellHorAlignNotSet	: "<nije postavljeno>",
+DlgCellHorAlignLeft	: "Levo",
+DlgCellHorAlignCenter	: "Sredina",
+DlgCellHorAlignRight: "Desno",
+DlgCellVerAlign		: "Vertikalno ravnanje",
+DlgCellVerAlignNotSet	: "<nije postavljeno>",
+DlgCellVerAlignTop	: "Gornje",
+DlgCellVerAlignMiddle	: "Sredina",
+DlgCellVerAlignBottom	: "Donje",
+DlgCellVerAlignBaseline	: "Bazno",
+DlgCellRowSpan		: "Spajanje redova",
+DlgCellCollSpan		: "Spajanje kolona",
+DlgCellBackColor	: "Boja pozadine",
+DlgCellBorderColor	: "Boja okvira",
+DlgCellBtnSelect	: "Odaberi...",
+
+// Find Dialog
+DlgFindTitle		: "Pronađi",
+DlgFindFindBtn		: "Pronađi",
+DlgFindNotFoundMsg	: "Traženi tekst nije pronađen.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Zameni",
+DlgReplaceFindLbl		: "Pronadi:",
+DlgReplaceReplaceLbl	: "Zameni sa:",
+DlgReplaceCaseChk		: "Razlikuj mala i velika slova",
+DlgReplaceReplaceBtn	: "Zameni",
+DlgReplaceReplAllBtn	: "Zameni sve",
+DlgReplaceWordChk		: "Uporedi cele reci",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog isecanja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl+X).",
+PasteErrorCopy	: "Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl+C).",
+
+PasteAsText		: "Zalepi kao čist tekst",
+PasteFromWord	: "Zalepi iz Worda",
+
+DlgPasteMsg2	: "Molimo Vas da zalepite unutar donje povrine koristeći tastaturnu prečicu (<STRONG>Ctrl+V</STRONG>) i da pritisnete <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoriši definicije fontova",
+DlgPasteRemoveStyles	: "Ukloni definicije stilova",
+DlgPasteCleanBox		: "Obriši sve",
+
+// Color Picker
+ColorAutomatic	: "Automatski",
+ColorMoreColors	: "Više boja...",
+
+// Document Properties
+DocProps		: "Osobine dokumenta",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Osobine sidra",
+DlgAnchorName		: "Ime sidra",
+DlgAnchorErrorName	: "Unesite ime sidra",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nije u rečniku",
+DlgSpellChangeTo		: "Izmeni",
+DlgSpellBtnIgnore		: "Ignoriši",
+DlgSpellBtnIgnoreAll	: "Ignoriši sve",
+DlgSpellBtnReplace		: "Zameni",
+DlgSpellBtnReplaceAll	: "Zameni sve",
+DlgSpellBtnUndo			: "Vrati akciju",
+DlgSpellNoSuggestions	: "- Bez sugestija -",
+DlgSpellProgress		: "Provera spelovanja u toku...",
+DlgSpellNoMispell		: "Provera spelovanja završena: greške nisu pronadene",
+DlgSpellNoChanges		: "Provera spelovanja završena: Nije izmenjena nijedna rec",
+DlgSpellOneChange		: "Provera spelovanja završena: Izmenjena je jedna reč",
+DlgSpellManyChanges		: "Provera spelovanja završena: %1 reč(i) je izmenjeno",
+
+IeSpellDownload			: "Provera spelovanja nije instalirana. Da li želite da je skinete sa Interneta?",
+
+// Button Dialog
+DlgButtonText		: "Tekst (vrednost)",
+DlgButtonType		: "Tip",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Naziv",
+DlgCheckboxValue	: "Vrednost",
+DlgCheckboxSelected	: "Označeno",
+
+// Form Dialog
+DlgFormName		: "Naziv",
+DlgFormAction	: "Akcija",
+DlgFormMethod	: "Metoda",
+
+// Select Field Dialog
+DlgSelectName		: "Naziv",
+DlgSelectValue		: "Vrednost",
+DlgSelectSize		: "Veličina",
+DlgSelectLines		: "linija",
+DlgSelectChkMulti	: "Dozvoli višestruku selekciju",
+DlgSelectOpAvail	: "Dostupne opcije",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Vrednost",
+DlgSelectBtnAdd		: "Dodaj",
+DlgSelectBtnModify	: "Izmeni",
+DlgSelectBtnUp		: "Gore",
+DlgSelectBtnDown	: "Dole",
+DlgSelectBtnSetValue : "Podesi kao označenu vrednost",
+DlgSelectBtnDelete	: "Obriši",
+
+// Textarea Dialog
+DlgTextareaName	: "Naziv",
+DlgTextareaCols	: "Broj kolona",
+DlgTextareaRows	: "Broj redova",
+
+// Text Field Dialog
+DlgTextName			: "Naziv",
+DlgTextValue		: "Vrednost",
+DlgTextCharWidth	: "Širina (karaktera)",
+DlgTextMaxChars		: "Maksimalno karaktera",
+DlgTextType			: "Tip",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Lozinka",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Naziv",
+DlgHiddenValue	: "Vrednost",
+
+// Bulleted List Dialog
+BulletedListProp	: "Osobine nenabrojive liste",
+NumberedListProp	: "Osobine nabrojive liste",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tip",
+DlgLstTypeCircle	: "Krug",
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "Kvadrat",
+DlgLstTypeNumbers	: "Brojevi (1, 2, 3)",
+DlgLstTypeLCase		: "mala slova (a, b, c)",
+DlgLstTypeUCase		: "VELIKA slova (A, B, C)",
+DlgLstTypeSRoman	: "Male rimske cifre (i, ii, iii)",
+DlgLstTypeLRoman	: "Velike rimske cifre (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Opšte osobine",
+DlgDocBackTab		: "Pozadina",
+DlgDocColorsTab		: "Boje i margine",
+DlgDocMetaTab		: "Metapodaci",
+
+DlgDocPageTitle		: "Naslov stranice",
+DlgDocLangDir		: "Smer jezika",
+DlgDocLangDirLTR	: "Sleva nadesno (LTR)",
+DlgDocLangDirRTL	: "Zdesna nalevo (RTL)",
+DlgDocLangCode		: "Šifra jezika",
+DlgDocCharSet		: "Kodiranje skupa karaktera",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Ostala kodiranja skupa karaktera",
+
+DlgDocDocType		: "Zaglavlje tipa dokumenta",
+DlgDocDocTypeOther	: "Ostala zaglavlja tipa dokumenta",
+DlgDocIncXHTML		: "Ukljuci XHTML deklaracije",
+DlgDocBgColor		: "Boja pozadine",
+DlgDocBgImage		: "URL pozadinske slike",
+DlgDocBgNoScroll	: "Fiksirana pozadina",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Posećeni link",
+DlgDocCActive		: "Aktivni link",
+DlgDocMargins		: "Margine stranice",
+DlgDocMaTop			: "Gornja",
+DlgDocMaLeft		: "Leva",
+DlgDocMaRight		: "Desna",
+DlgDocMaBottom		: "Donja",
+DlgDocMeIndex		: "Ključne reci za indeksiranje dokumenta (razdvojene zarezima)",
+DlgDocMeDescr		: "Opis dokumenta",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Autorska prava",
+DlgDocPreview		: "Izgled stranice",
+
+// Templates Dialog
+Templates			: "Obrasci",
+DlgTemplatesTitle	: "Obrasci za sadržaj",
+DlgTemplatesSelMsg	: "Molimo Vas da odaberete obrazac koji ce biti primenjen na stranicu (trenutni sadržaj ce biti obrisan):",
+DlgTemplatesLoading	: "Učitavam listu obrazaca. Malo strpljenja...",
+DlgTemplatesNoTpl	: "(Nema definisanih obrazaca)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "O editoru",
+DlgAboutBrowserInfoTab	: "Informacije o pretraživacu",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "verzija",
+DlgAboutInfo		: "Za više informacija posetite"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/lv.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/lv.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/lv.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Latvian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Samazināt rīku joslu",
+ToolbarExpand		: "Paplašināt rīku joslu",
+
+// Toolbar Items and Context Menu
+Save				: "Saglabāt",
+NewPage				: "Jauna lapa",
+Preview				: "Pārskatīt",
+Cut					: "Izgriezt",
+Copy				: "Kopēt",
+Paste				: "Ievietot",
+PasteText			: "Ievietot kā vienkāršu tekstu",
+PasteWord			: "Ievietot no Worda",
+Print				: "Drukāt",
+SelectAll			: "Iezīmēt visu",
+RemoveFormat		: "Noņemt stilus",
+InsertLinkLbl		: "Hipersaite",
+InsertLink			: "Ievietot/Labot hipersaiti",
+RemoveLink			: "Noņemt hipersaiti",
+Anchor				: "Ievietot/Labot iezīmi",
+InsertImageLbl		: "Attēls",
+InsertImage			: "Ievietot/Labot Attēlu",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Ievietot/Labot Flash",
+InsertTableLbl		: "Tabula",
+InsertTable			: "Ievietot/Labot Tabulu",
+InsertLineLbl		: "Atdalītājsvītra",
+InsertLine			: "Ievietot horizontālu Atdalītājsvītru",
+InsertSpecialCharLbl: "Īpašs simbols",
+InsertSpecialChar	: "Ievietot speciālo simbolu",
+InsertSmileyLbl		: "Smaidiņi",
+InsertSmiley		: "Ievietot smaidiņu",
+About				: "Īsumā par FCKeditor",
+Bold				: "Treknu šriftu",
+Italic				: "Slīprakstā",
+Underline			: "Apakšsvītra",
+StrikeThrough		: "Pārsvītrots",
+Subscript			: "Zemrakstā",
+Superscript			: "Augšrakstā",
+LeftJustify			: "Izlīdzināt pa kreisi",
+CenterJustify		: "Izlīdzināt pret centru",
+RightJustify		: "Izlīdzināt pa labi",
+BlockJustify		: "Izlīdzināt malas",
+DecreaseIndent		: "Samazināt atkāpi",
+IncreaseIndent		: "Palielināt atkāpi",
+Undo				: "Atcelt",
+Redo				: "Atkārtot",
+NumberedListLbl		: "Numurēts saraksts",
+NumberedList		: "Ievietot/Noņemt numerēto sarakstu",
+BulletedListLbl		: "Izcelts saraksts",
+BulletedList		: "Ievietot/Noņemt izceltu sarakstu",
+ShowTableBorders	: "Parādīt tabulas robežas",
+ShowDetails			: "Parādīt sīkāku informāciju",
+Style				: "Stils",
+FontFormat			: "Formāts",
+Font				: "Šrifts",
+FontSize			: "Izmērs",
+TextColor			: "Teksta krāsa",
+BGColor				: "Fona krāsa",
+Source				: "HTML kods",
+Find				: "Meklēt",
+Replace				: "Nomainīt",
+SpellCheck			: "Pareizrakstības pārbaude",
+UniversalKeyboard	: "Universāla klaviatūra",
+PageBreakLbl		: "Lapas pārtraukums",
+PageBreak			: "Ievietot lapas pārtraukumu",
+
+Form			: "Forma",
+Checkbox		: "Atzīmēšanas kastīte",
+RadioButton		: "Izvēles poga",
+TextField		: "Teksta rinda",
+Textarea		: "Teksta laukums",
+HiddenField		: "Paslēpta teksta rinda",
+Button			: "Poga",
+SelectionField	: "Iezīmēšanas lauks",
+ImageButton		: "Attēlpoga",
+
+FitWindow		: "Maksimizēt redaktora izmēru",
+
+// Context Menu
+EditLink			: "Labot hipersaiti",
+CellCM				: "Šūna",
+RowCM				: "Rinda",
+ColumnCM			: "Kolonna",
+InsertRow			: "Ievietot rindu",
+DeleteRows			: "Dzēst rindas",
+InsertColumn		: "Ievietot kolonnu",
+DeleteColumns		: "Dzēst kolonnas",
+InsertCell			: "Ievietot rūtiņu",
+DeleteCells			: "Dzēst rūtiņas",
+MergeCells			: "Apvienot rūtiņas",
+SplitCell			: "Sadalīt rūtiņu",
+TableDelete			: "Dzēst tabulu",
+CellProperties		: "Rūtiņas īpašības",
+TableProperties		: "Tabulas īpašības",
+ImageProperties		: "Attēla īpašības",
+FlashProperties		: "Flash īpašības",
+
+AnchorProp			: "Iezīmes īpašības",
+ButtonProp			: "Pogas īpašības",
+CheckboxProp		: "Atzīmēšanas kastītes īpašības",
+HiddenFieldProp		: "Paslēptās teksta rindas īpašības",
+RadioButtonProp		: "Izvēles poga īpašības",
+ImageButtonProp		: "Attēlpogas īpašības",
+TextFieldProp		: "Teksta rindas  īpašības",
+SelectionFieldProp	: "Iezīmēšanas lauka īpašības",
+TextareaProp		: "Teksta laukuma īpašības",
+FormProp			: "Formas īpašības",
+
+FontFormats			: "Normāls teksts;Formatēts teksts;Adrese;Virsraksts 1;Virsraksts 2;Virsraksts 3;Virsraksts 4;Virsraksts 5;Virsraksts 6;Rindkopa (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Tiek apstrādāts XHTML. Lūdzu uzgaidiet...",
+Done				: "Darīts",
+PasteWordConfirm	: "Teksta fragments, kas tiek ievietots, izskatās, ka būtu sagatavots Word'ā. Vai vēlaties to apstrādāt pirms ievietošanas?",
+NotCompatiblePaste	: "Šī darbība ir pieejama Internet Explorer'ī, kas jaunāks par 5.5 versiju. Vai vēlaties ievietot bez apstrādes?",
+UnknownToolbarItem	: "Nezināms rīku joslas objekts \"%1\"",
+UnknownCommand		: "Nezināmas darbības nosaukums \"%1\"",
+NotImplemented		: "Darbība netika paveikta",
+UnknownToolbarSet	: "Rīku joslas komplekts \"%1\" neeksistē",
+NoActiveX			: "Interneta pārlūkprogrammas drošības uzstādījumi varētu ietekmēt dažas no redaktora īpašībām. Jābūt aktivizētai sadaļai \"Run ActiveX controls and plug-ins\". Savādāk ir iespējamas kļūdas darbībā un kļūdu paziņojumu parādīšanās.",
+BrowseServerBlocked : "Resursu pārlūks nevar tikt atvērts. Pārliecinieties, ka uznirstošo logu bloķētāji ir atslēgti.",
+DialogBlocked		: "Nav iespējams atvērt dialoglogu. Pārliecinieties, ka uznirstošo logu bloķētāji ir atslēgti.",
+
+// Dialogs
+DlgBtnOK			: "Darīts!",
+DlgBtnCancel		: "Atcelt",
+DlgBtnClose			: "Aizvērt",
+DlgBtnBrowseServer	: "Skatīt servera saturu",
+DlgAdvancedTag		: "Izvērstais",
+DlgOpOther			: "<Cits>",
+DlgInfoTab			: "Informācija",
+DlgAlertUrl			: "Lūdzu, ievietojiet hipersaiti",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<nav iestatīts>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Valodas lasīšanas virziens",
+DlgGenLangDirLtr	: "No kreisās uz labo (LTR)",
+DlgGenLangDirRtl	: "No labās uz kreiso (RTL)",
+DlgGenLangCode		: "Valodas kods",
+DlgGenAccessKey		: "Pieejas kods",
+DlgGenName			: "Nosaukums",
+DlgGenTabIndex		: "Ciļņu indekss",
+DlgGenLongDescr		: "Gara apraksta Hipersaite",
+DlgGenClass			: "Stilu saraksta klases",
+DlgGenTitle			: "Konsultatīvs virsraksts",
+DlgGenContType		: "Konsultatīvs satura tips",
+DlgGenLinkCharset	: "Pievienotā resursa kodu tabula",
+DlgGenStyle			: "Stils",
+
+// Image Dialog
+DlgImgTitle			: "Attēla īpašības",
+DlgImgInfoTab		: "Informācija par attēlu",
+DlgImgBtnUpload		: "Nosūtīt serverim",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Augšupielādēt",
+DlgImgAlt			: "Alternatīvais teksts",
+DlgImgWidth			: "Platums",
+DlgImgHeight		: "Augstums",
+DlgImgLockRatio		: "Nemainīga Augstuma/Platuma attiecība",
+DlgBtnResetSize		: "Atjaunot sākotnējo izmēru",
+DlgImgBorder		: "Rāmis",
+DlgImgHSpace		: "Horizontālā telpa",
+DlgImgVSpace		: "Vertikālā telpa",
+DlgImgAlign			: "Nolīdzināt",
+DlgImgAlignLeft		: "Pa kreisi",
+DlgImgAlignAbsBottom: "Absolūti apakšā",
+DlgImgAlignAbsMiddle: "Absolūti vertikāli centrēts",
+DlgImgAlignBaseline	: "Pamatrindā",
+DlgImgAlignBottom	: "Apakšā",
+DlgImgAlignMiddle	: "Vertikāli centrēts",
+DlgImgAlignRight	: "Pa labi",
+DlgImgAlignTextTop	: "Teksta augšā",
+DlgImgAlignTop		: "Augšā",
+DlgImgPreview		: "Pārskats",
+DlgImgAlertUrl		: "Lūdzu norādīt attēla hipersaiti",
+DlgImgLinkTab		: "Hipersaite",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash īpašības",
+DlgFlashChkPlay		: "Automātiska atskaņošana",
+DlgFlashChkLoop		: "Nepārtraukti",
+DlgFlashChkMenu		: "Atļaut Flash izvēlni",
+DlgFlashScale		: "Mainīt izmēru",
+DlgFlashScaleAll	: "Rādīt visu",
+DlgFlashScaleNoBorder	: "Bez rāmja",
+DlgFlashScaleFit	: "Precīzs izmērs",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Hipersaite",
+DlgLnkInfoTab		: "Hipersaites informācija",
+DlgLnkTargetTab		: "Mērķis",
+
+DlgLnkType			: "Hipersaites tips",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Iezīme šajā lapā",
+DlgLnkTypeEMail		: "E-pasts",
+DlgLnkProto			: "Protokols",
+DlgLnkProtoOther	: "<cits>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Izvēlēties iezīmi",
+DlgLnkAnchorByName	: "Pēc iezīmes nosaukuma",
+DlgLnkAnchorById	: "Pēc elementa ID",
+DlgLnkNoAnchors		: "<Šajā dokumentā nav iezīmju>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-pasta adrese",
+DlgLnkEMailSubject	: "Ziņas tēma",
+DlgLnkEMailBody		: "Ziņas saturs",
+DlgLnkUpload		: "Augšupielādēt",
+DlgLnkBtnUpload		: "Nosūtīt serverim",
+
+DlgLnkTarget		: "Mērķis",
+DlgLnkTargetFrame	: "<ietvars>",
+DlgLnkTargetPopup	: "<uznirstošā logā>",
+DlgLnkTargetBlank	: "Jaunā logā (_blank)",
+DlgLnkTargetParent	: "Esošajā logā (_parent)",
+DlgLnkTargetSelf	: "Tajā pašā logā (_self)",
+DlgLnkTargetTop		: "Visredzamākajā logā (_top)",
+DlgLnkTargetFrameName	: "Mērķa ietvara nosaukums",
+DlgLnkPopWinName	: "Uznirstošā loga nosaukums",
+DlgLnkPopWinFeat	: "Uznirstošā loga nosaukums īpašības",
+DlgLnkPopResize		: "Ar maināmu izmēru",
+DlgLnkPopLocation	: "Atrašanās vietas josla",
+DlgLnkPopMenu		: "Izvēlnes josla",
+DlgLnkPopScroll		: "Ritjoslas",
+DlgLnkPopStatus		: "Statusa josla",
+DlgLnkPopToolbar	: "Rīku josla",
+DlgLnkPopFullScrn	: "Pilnā ekrānā (IE)",
+DlgLnkPopDependent	: "Atkarīgs (Netscape)",
+DlgLnkPopWidth		: "Platums",
+DlgLnkPopHeight		: "Augstums",
+DlgLnkPopLeft		: "Kreisā koordināte",
+DlgLnkPopTop		: "Augšējā koordināte",
+
+DlnLnkMsgNoUrl		: "Lūdzu norādi hipersaiti",
+DlnLnkMsgNoEMail	: "Lūdzu norādi e-pasta adresi",
+DlnLnkMsgNoAnchor	: "Lūdzu norādi iezīmi",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Izvēlies krāsu",
+DlgColorBtnClear	: "Dzēst",
+DlgColorHighlight	: "Izcelt",
+DlgColorSelected	: "Iezīmētais",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Ievietot smaidiņu",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Ievietot īpašu simbolu",
+
+// Table Dialog
+DlgTableTitle		: "Tabulas īpašības",
+DlgTableRows		: "Rindas",
+DlgTableColumns		: "Kolonnas",
+DlgTableBorder		: "Rāmja izmērs",
+DlgTableAlign		: "Novietojums",
+DlgTableAlignNotSet	: "<nav norādīts>",
+DlgTableAlignLeft	: "Pa kreisi",
+DlgTableAlignCenter	: "Centrēti",
+DlgTableAlignRight	: "Pa labi",
+DlgTableWidth		: "Platums",
+DlgTableWidthPx		: "pikseļos",
+DlgTableWidthPc		: "procentuāli",
+DlgTableHeight		: "Augstums",
+DlgTableCellSpace	: "Rūtiņu atstatums",
+DlgTableCellPad		: "Rūtiņu nobīde",
+DlgTableCaption		: "Leģenda",
+DlgTableSummary		: "Anotācija",
+
+// Table Cell Dialog
+DlgCellTitle		: "Rūtiņas īpašības",
+DlgCellWidth		: "Platums",
+DlgCellWidthPx		: "pikseļi",
+DlgCellWidthPc		: "procentos",
+DlgCellHeight		: "Augstums",
+DlgCellWordWrap		: "Teksta pārnese",
+DlgCellWordWrapNotSet	: "<nav norādīta>",
+DlgCellWordWrapYes	: "Jā",
+DlgCellWordWrapNo	: "Nē",
+DlgCellHorAlign		: "Horizontāla novietojums",
+DlgCellHorAlignNotSet	: "<Nav norādīts>",
+DlgCellHorAlignLeft	: "Pa kreisi",
+DlgCellHorAlignCenter	: "Centrēti",
+DlgCellHorAlignRight: "Pa labi",
+DlgCellVerAlign		: "Vertikālais novietojums",
+DlgCellVerAlignNotSet	: "<nav norādīts>",
+DlgCellVerAlignTop	: "Augša",
+DlgCellVerAlignMiddle	: "Vidus",
+DlgCellVerAlignBottom	: "Apakša",
+DlgCellVerAlignBaseline	: "Pamatrindā",
+DlgCellRowSpan		: "Rindu pārnese",
+DlgCellCollSpan		: "Kolonnu pārnese",
+DlgCellBackColor	: "Fona krāsa",
+DlgCellBorderColor	: "Rāmja krāsa",
+DlgCellBtnSelect	: "Iezīmē...",
+
+// Find Dialog
+DlgFindTitle		: "Meklētājs",
+DlgFindFindBtn		: "Meklēt",
+DlgFindNotFoundMsg	: "Norādītā frāze netika atrasta.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Aizvietošana",
+DlgReplaceFindLbl		: "Meklēt:",
+DlgReplaceReplaceLbl	: "Nomainīt uz:",
+DlgReplaceCaseChk		: "Reģistrjūtīgs",
+DlgReplaceReplaceBtn	: "Aizvietot",
+DlgReplaceReplAllBtn	: "Aizvietot visu",
+DlgReplaceWordChk		: "Jāsakrīt pilnībā",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj editoram automātiski veikt izgriešanas darbību.  Lūdzu, izmantojiet (Ctrl+X, lai veiktu šo darbību.",
+PasteErrorCopy	: "Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj editoram automātiski veikt kopēšanas darbību.  Lūdzu, izmantojiet (Ctrl+C), lai veiktu šo darbību.",
+
+PasteAsText		: "Ievietot kā vienkāršu tekstu",
+PasteFromWord	: "Ievietot no Worda",
+
+DlgPasteMsg2	: "Lūdzu, ievietojiet tekstu šajā laukumā, izmantojot klaviatūru (<STRONG>Ctrl+V</STRONG>) un apstipriniet ar <STRONG>Darīts!</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorēt iepriekš norādītos fontus",
+DlgPasteRemoveStyles	: "Noņemt norādītos stilus",
+DlgPasteCleanBox		: "Apstrādāt laukuma saturu",
+
+// Color Picker
+ColorAutomatic	: "Automātiska",
+ColorMoreColors	: "Plašāka palete...",
+
+// Document Properties
+DocProps		: "Dokumenta īpašības",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Iezīmes īpašības",
+DlgAnchorName		: "Iezīmes nosaukums",
+DlgAnchorErrorName	: "Lūdzu norādiet iezīmes nosaukumu",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Netika atrasts vārdnīcā",
+DlgSpellChangeTo		: "Nomainīt uz",
+DlgSpellBtnIgnore		: "Ignorēt",
+DlgSpellBtnIgnoreAll	: "Ignorēt visu",
+DlgSpellBtnReplace		: "Aizvietot",
+DlgSpellBtnReplaceAll	: "Aizvietot visu",
+DlgSpellBtnUndo			: "Atcelt",
+DlgSpellNoSuggestions	: "- Nav ieteikumu -",
+DlgSpellProgress		: "Notiek pareizrakstības pārbaude...",
+DlgSpellNoMispell		: "Pareizrakstības pārbaude pabeigta: kļūdas netika atrastas",
+DlgSpellNoChanges		: "Pareizrakstības pārbaude pabeigta: nekas netika labots",
+DlgSpellOneChange		: "Pareizrakstības pārbaude pabeigta: 1 vārds izmainīts",
+DlgSpellManyChanges		: "Pareizrakstības pārbaude pabeigta: %1 vārdi tika mainīti",
+
+IeSpellDownload			: "Pareizrakstības pārbaudītājs nav pievienots. Vai vēlaties to lejupielādēt tagad?",
+
+// Button Dialog
+DlgButtonText		: "Teksts (vērtība)",
+DlgButtonType		: "Tips",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nosaukums",
+DlgCheckboxValue	: "Vērtība",
+DlgCheckboxSelected	: "Iezīmēts",
+
+// Form Dialog
+DlgFormName		: "Nosaukums",
+DlgFormAction	: "Darbība",
+DlgFormMethod	: "Metode",
+
+// Select Field Dialog
+DlgSelectName		: "Nosaukums",
+DlgSelectValue		: "Vērtība",
+DlgSelectSize		: "Izmērs",
+DlgSelectLines		: "rindas",
+DlgSelectChkMulti	: "Atļaut vairākus iezīmējumus",
+DlgSelectOpAvail	: "Pieejamās iespējas",
+DlgSelectOpText		: "Teksts",
+DlgSelectOpValue	: "Vērtība",
+DlgSelectBtnAdd		: "Pievienot",
+DlgSelectBtnModify	: "Veikt izmaiņas",
+DlgSelectBtnUp		: "Augšup",
+DlgSelectBtnDown	: "Lejup",
+DlgSelectBtnSetValue : "Noteikt kā iezīmēto vērtību",
+DlgSelectBtnDelete	: "Dzēst",
+
+// Textarea Dialog
+DlgTextareaName	: "Nosaukums",
+DlgTextareaCols	: "Kolonnas",
+DlgTextareaRows	: "Rindas",
+
+// Text Field Dialog
+DlgTextName			: "Nosaukums",
+DlgTextValue		: "Vērtība",
+DlgTextCharWidth	: "Simbolu platums",
+DlgTextMaxChars		: "Simbolu maksimālais daudzums",
+DlgTextType			: "Tips",
+DlgTextTypeText		: "Teksts",
+DlgTextTypePass		: "Parole",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nosaukums",
+DlgHiddenValue	: "Vērtība",
+
+// Bulleted List Dialog
+BulletedListProp	: "Aizzīmju saraksta īpašības",
+NumberedListProp	: "Numerētā saraksta īpašības",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tips",
+DlgLstTypeCircle	: "Aplis",
+DlgLstTypeDisc		: "Disks",
+DlgLstTypeSquare	: "Kvadrāts",
+DlgLstTypeNumbers	: "Skaitļi (1, 2, 3)",
+DlgLstTypeLCase		: "Maziem burtiem (a, b, c)",
+DlgLstTypeUCase		: "Lieliem burtiem (A, B, C)",
+DlgLstTypeSRoman	: "Maziem romiešu cipariem (i, ii, iii)",
+DlgLstTypeLRoman	: "Lieliem romiešu cipariem (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Vispārīga informācija",
+DlgDocBackTab		: "Fons",
+DlgDocColorsTab		: "Krāsas un robežu nobīdes",
+DlgDocMetaTab		: "META dati",
+
+DlgDocPageTitle		: "Dokumenta virsraksts <Title>",
+DlgDocLangDir		: "Valodas lasīšanas virziens",
+DlgDocLangDirLTR	: "No kreisās uz labo (LTR)",
+DlgDocLangDirRTL	: "No labās uz kreiso (RTL)",
+DlgDocLangCode		: "Valodas kods",
+DlgDocCharSet		: "Simbolu kodējums",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Cits simbolu kodējums",
+
+DlgDocDocType		: "Dokumenta tips",
+DlgDocDocTypeOther	: "Cits dokumenta tips",
+DlgDocIncXHTML		: "Ietvert XHTML deklarācijas",
+DlgDocBgColor		: "Fona krāsa",
+DlgDocBgImage		: "Fona attēla hipersaite",
+DlgDocBgNoScroll	: "Fona attēls ir fiksēts",
+DlgDocCText			: "Teksts",
+DlgDocCLink			: "Hipersaite",
+DlgDocCVisited		: "Apmeklēta hipersaite",
+DlgDocCActive		: "Aktīva hipersaite",
+DlgDocMargins		: "Lapas robežas",
+DlgDocMaTop			: "Augšā",
+DlgDocMaLeft		: "Pa kreisi",
+DlgDocMaRight		: "Pa labi",
+DlgDocMaBottom		: "Apakšā",
+DlgDocMeIndex		: "Dokumentu aprakstoši atslēgvārdi (atdalīti ar komatu)",
+DlgDocMeDescr		: "Dokumenta apraksts",
+DlgDocMeAuthor		: "Autors",
+DlgDocMeCopy		: "Autortiesības",
+DlgDocPreview		: "Priekšskats",
+
+// Templates Dialog
+Templates			: "Sagataves",
+DlgTemplatesTitle	: "Satura sagataves",
+DlgTemplatesSelMsg	: "Lūdzu, norādiet sagatavi, ko atvērt editorā<br>(patreizējie dati tiks zaudēti):",
+DlgTemplatesLoading	: "Notiek sagatavju saraksta ielāde. Lūdzu, uzgaidiet...",
+DlgTemplatesNoTpl	: "(Nav norādītas sagataves)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Par",
+DlgAboutBrowserInfoTab	: "Informācija par pārlūkprogrammu",
+DlgAboutLicenseTab	: "Licence",
+DlgAboutVersion		: "versija",
+DlgAboutInfo		: "Papildus informācija ir pieejama"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/zh.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/zh.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/zh.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Chinese Traditional language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "隱藏面板",
+ToolbarExpand		: "顯示面板",
+
+// Toolbar Items and Context Menu
+Save				: "儲存",
+NewPage				: "開新檔案",
+Preview				: "預覽",
+Cut					: "剪下",
+Copy				: "複製",
+Paste				: "貼上",
+PasteText			: "貼為純文字格式",
+PasteWord			: "自 Word 貼上",
+Print				: "列印",
+SelectAll			: "全選",
+RemoveFormat		: "清除格式",
+InsertLinkLbl		: "超連結",
+InsertLink			: "插入/編輯超連結",
+RemoveLink			: "移除超連結",
+Anchor				: "插入/編輯錨點",
+InsertImageLbl		: "影像",
+InsertImage			: "插入/編輯影像",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "插入/編輯 Flash",
+InsertTableLbl		: "表格",
+InsertTable			: "插入/編輯表格",
+InsertLineLbl		: "水平線",
+InsertLine			: "插入水平線",
+InsertSpecialCharLbl: "特殊符號",
+InsertSpecialChar	: "插入特殊符號",
+InsertSmileyLbl		: "表情符號",
+InsertSmiley		: "插入表情符號",
+About				: "關於 FCKeditor",
+Bold				: "粗體",
+Italic				: "斜體",
+Underline			: "底線",
+StrikeThrough		: "刪除線",
+Subscript			: "下標",
+Superscript			: "上標",
+LeftJustify			: "靠左對齊",
+CenterJustify		: "置中",
+RightJustify		: "靠右對齊",
+BlockJustify		: "左右對齊",
+DecreaseIndent		: "減少縮排",
+IncreaseIndent		: "增加縮排",
+Undo				: "復原",
+Redo				: "重複",
+NumberedListLbl		: "編號清單",
+NumberedList		: "插入/移除編號清單",
+BulletedListLbl		: "項目清單",
+BulletedList		: "插入/移除項目清單",
+ShowTableBorders	: "顯示表格邊框",
+ShowDetails			: "顯示詳細資料",
+Style				: "樣式",
+FontFormat			: "格式",
+Font				: "字體",
+FontSize			: "大小",
+TextColor			: "文字顏色",
+BGColor				: "背景顏色",
+Source				: "原始碼",
+Find				: "尋找",
+Replace				: "取代",
+SpellCheck			: "拼字檢查",
+UniversalKeyboard	: "萬國鍵盤",
+PageBreakLbl		: "分頁符號",
+PageBreak			: "插入分頁符號",
+
+Form			: "表單",
+Checkbox		: "核取方塊",
+RadioButton		: "選項按鈕",
+TextField		: "文字方塊",
+Textarea		: "文字區域",
+HiddenField		: "隱藏欄位",
+Button			: "按鈕",
+SelectionField	: "清單/選單",
+ImageButton		: "影像按鈕",
+
+FitWindow		: "編輯器最大化",
+
+// Context Menu
+EditLink			: "編輯超連結",
+CellCM				: "儲存格",
+RowCM				: "列",
+ColumnCM			: "欄",
+InsertRow			: "插入列",
+DeleteRows			: "刪除列",
+InsertColumn		: "插入欄",
+DeleteColumns		: "刪除欄",
+InsertCell			: "插入儲存格",
+DeleteCells			: "刪除儲存格",
+MergeCells			: "合併儲存格",
+SplitCell			: "分割儲存格",
+TableDelete			: "刪除表格",
+CellProperties		: "儲存格屬性",
+TableProperties		: "表格屬性",
+ImageProperties		: "影像屬性",
+FlashProperties		: "Flash 屬性",
+
+AnchorProp			: "錨點屬性",
+ButtonProp			: "按鈕屬性",
+CheckboxProp		: "核取方塊屬性",
+HiddenFieldProp		: "隱藏欄位屬性",
+RadioButtonProp		: "選項按鈕屬性",
+ImageButtonProp		: "影像按鈕屬性",
+TextFieldProp		: "文字方塊屬性",
+SelectionFieldProp	: "清單/選單屬性",
+TextareaProp		: "文字區域屬性",
+FormProp			: "表單屬性",
+
+FontFormats			: "本文;已格式化;位址;標題 1;標題 2;標題 3;標題 4;標題 5;標題 6;本文 (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "處理 XHTML 中，請稍候…",
+Done				: "完成",
+PasteWordConfirm	: "您想貼上的文字似乎是自 Word 複製而來，請問您是否要先清除 Word 的格式後再行貼上？",
+NotCompatiblePaste	: "此指令僅在 Internet Explorer 5.5 或以上的版本有效。請問您是否同意不清除格式即貼上？",
+UnknownToolbarItem	: "未知工具列項目 \"%1\"",
+UnknownCommand		: "未知指令名稱 \"%1\"",
+NotImplemented		: "尚未安裝此指令",
+UnknownToolbarSet	: "工具列設定 \"%1\" 不存在",
+NoActiveX			: "瀏覽器的安全性設定限制了本編輯器的某些功能。您必須啟用安全性設定中的「執行ActiveX控制項與外掛程式」項目，否則本編輯器將會出現錯誤並缺少某些功能",
+BrowseServerBlocked : "無法開啟資源瀏覽器，請確定所有快顯視窗封鎖程式是否關閉",
+DialogBlocked		: "無法開啟對話視窗，請確定所有快顯視窗封鎖程式是否關閉",
+
+// Dialogs
+DlgBtnOK			: "確定",
+DlgBtnCancel		: "取消",
+DlgBtnClose			: "關閉",
+DlgBtnBrowseServer	: "瀏覽伺服器端",
+DlgAdvancedTag		: "進階",
+DlgOpOther			: "<其他>",
+DlgInfoTab			: "資訊",
+DlgAlertUrl			: "請插入 URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<尚未設定>",
+DlgGenId			: "ID",
+DlgGenLangDir		: "語言方向",
+DlgGenLangDirLtr	: "由左而右 (LTR)",
+DlgGenLangDirRtl	: "由右而左 (RTL)",
+DlgGenLangCode		: "語言代碼",
+DlgGenAccessKey		: "存取鍵",
+DlgGenName			: "名稱",
+DlgGenTabIndex		: "定位順序",
+DlgGenLongDescr		: "詳細 URL",
+DlgGenClass			: "樣式表類別",
+DlgGenTitle			: "標題",
+DlgGenContType		: "內容類型",
+DlgGenLinkCharset	: "連結資源之編碼",
+DlgGenStyle			: "樣式",
+
+// Image Dialog
+DlgImgTitle			: "影像屬性",
+DlgImgInfoTab		: "影像資訊",
+DlgImgBtnUpload		: "上傳至伺服器",
+DlgImgURL			: "URL",
+DlgImgUpload		: "上傳",
+DlgImgAlt			: "替代文字",
+DlgImgWidth			: "寬度",
+DlgImgHeight		: "高度",
+DlgImgLockRatio		: "等比例",
+DlgBtnResetSize		: "重設為原大小",
+DlgImgBorder		: "邊框",
+DlgImgHSpace		: "水平距離",
+DlgImgVSpace		: "垂直距離",
+DlgImgAlign			: "對齊",
+DlgImgAlignLeft		: "靠左對齊",
+DlgImgAlignAbsBottom: "絕對下方",
+DlgImgAlignAbsMiddle: "絕對中間",
+DlgImgAlignBaseline	: "基準線",
+DlgImgAlignBottom	: "靠下對齊",
+DlgImgAlignMiddle	: "置中對齊",
+DlgImgAlignRight	: "靠右對齊",
+DlgImgAlignTextTop	: "文字上方",
+DlgImgAlignTop		: "靠上對齊",
+DlgImgPreview		: "預覽",
+DlgImgAlertUrl		: "請輸入影像 URL",
+DlgImgLinkTab		: "超連結",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash 屬性",
+DlgFlashChkPlay		: "自動播放",
+DlgFlashChkLoop		: "重複",
+DlgFlashChkMenu		: "開啟選單",
+DlgFlashScale		: "縮放",
+DlgFlashScaleAll	: "全部顯示",
+DlgFlashScaleNoBorder	: "無邊框",
+DlgFlashScaleFit	: "精確符合",
+
+// Link Dialog
+DlgLnkWindowTitle	: "超連結",
+DlgLnkInfoTab		: "超連結資訊",
+DlgLnkTargetTab		: "目標",
+
+DlgLnkType			: "超連接類型",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "本頁錨點",
+DlgLnkTypeEMail		: "電子郵件",
+DlgLnkProto			: "通訊協定",
+DlgLnkProtoOther	: "<其他>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "請選擇錨點",
+DlgLnkAnchorByName	: "依錨點名稱",
+DlgLnkAnchorById	: "依元件 ID",
+DlgLnkNoAnchors		: "<本文件尚無可用之錨點>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "電子郵件",
+DlgLnkEMailSubject	: "郵件主旨",
+DlgLnkEMailBody		: "郵件內容",
+DlgLnkUpload		: "上傳",
+DlgLnkBtnUpload		: "傳送至伺服器",
+
+DlgLnkTarget		: "目標",
+DlgLnkTargetFrame	: "<框架>",
+DlgLnkTargetPopup	: "<快顯視窗>",
+DlgLnkTargetBlank	: "新視窗 (_blank)",
+DlgLnkTargetParent	: "父視窗 (_parent)",
+DlgLnkTargetSelf	: "本視窗 (_self)",
+DlgLnkTargetTop		: "最上層視窗 (_top)",
+DlgLnkTargetFrameName	: "目標框架名稱",
+DlgLnkPopWinName	: "快顯視窗名稱",
+DlgLnkPopWinFeat	: "快顯視窗屬性",
+DlgLnkPopResize		: "可調整大小",
+DlgLnkPopLocation	: "網址列",
+DlgLnkPopMenu		: "選單列",
+DlgLnkPopScroll		: "捲軸",
+DlgLnkPopStatus		: "狀態列",
+DlgLnkPopToolbar	: "工具列",
+DlgLnkPopFullScrn	: "全螢幕 (IE)",
+DlgLnkPopDependent	: "從屬 (NS)",
+DlgLnkPopWidth		: "寬",
+DlgLnkPopHeight		: "高",
+DlgLnkPopLeft		: "左",
+DlgLnkPopTop		: "右",
+
+DlnLnkMsgNoUrl		: "請輸入欲連結的 URL",
+DlnLnkMsgNoEMail	: "請輸入電子郵件位址",
+DlnLnkMsgNoAnchor	: "請選擇錨點",
+DlnLnkMsgInvPopName	: "快顯名稱必須以「英文字母」為開頭，且不得含有空白",
+
+// Color Dialog
+DlgColorTitle		: "請選擇顏色",
+DlgColorBtnClear	: "清除",
+DlgColorHighlight	: "預覽",
+DlgColorSelected	: "選擇",
+
+// Smiley Dialog
+DlgSmileyTitle		: "插入表情符號",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "請選擇特殊符號",
+
+// Table Dialog
+DlgTableTitle		: "表格屬性",
+DlgTableRows		: "列數",
+DlgTableColumns		: "欄數",
+DlgTableBorder		: "邊框",
+DlgTableAlign		: "對齊",
+DlgTableAlignNotSet	: "<未設定>",
+DlgTableAlignLeft	: "靠左對齊",
+DlgTableAlignCenter	: "置中",
+DlgTableAlignRight	: "靠右對齊",
+DlgTableWidth		: "寬度",
+DlgTableWidthPx		: "像素",
+DlgTableWidthPc		: "百分比",
+DlgTableHeight		: "高度",
+DlgTableCellSpace	: "間距",
+DlgTableCellPad		: "內距",
+DlgTableCaption		: "標題",
+DlgTableSummary		: "摘要",
+
+// Table Cell Dialog
+DlgCellTitle		: "儲存格屬性",
+DlgCellWidth		: "寬度",
+DlgCellWidthPx		: "像素",
+DlgCellWidthPc		: "百分比",
+DlgCellHeight		: "高度",
+DlgCellWordWrap		: "自動換行",
+DlgCellWordWrapNotSet	: "<尚未設定>",
+DlgCellWordWrapYes	: "是",
+DlgCellWordWrapNo	: "否",
+DlgCellHorAlign		: "水平對齊",
+DlgCellHorAlignNotSet	: "<尚未設定>",
+DlgCellHorAlignLeft	: "靠左對齊",
+DlgCellHorAlignCenter	: "置中",
+DlgCellHorAlignRight: "靠右對齊",
+DlgCellVerAlign		: "垂直對齊",
+DlgCellVerAlignNotSet	: "<尚未設定>",
+DlgCellVerAlignTop	: "靠上對齊",
+DlgCellVerAlignMiddle	: "置中",
+DlgCellVerAlignBottom	: "靠下對齊",
+DlgCellVerAlignBaseline	: "基準線",
+DlgCellRowSpan		: "合併列數",
+DlgCellCollSpan		: "合併欄数",
+DlgCellBackColor	: "背景顏色",
+DlgCellBorderColor	: "邊框顏色",
+DlgCellBtnSelect	: "請選擇…",
+
+// Find Dialog
+DlgFindTitle		: "尋找",
+DlgFindFindBtn		: "尋找",
+DlgFindNotFoundMsg	: "未找到指定的文字。",
+
+// Replace Dialog
+DlgReplaceTitle			: "取代",
+DlgReplaceFindLbl		: "尋找:",
+DlgReplaceReplaceLbl	: "取代:",
+DlgReplaceCaseChk		: "大小寫須相符",
+DlgReplaceReplaceBtn	: "取代",
+DlgReplaceReplAllBtn	: "全部取代",
+DlgReplaceWordChk		: "全字相符",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "瀏覽器的安全性設定不允許編輯器自動執行剪下動作。請使用快捷鍵 (Ctrl+X) 剪下。",
+PasteErrorCopy	: "瀏覽器的安全性設定不允許編輯器自動執行複製動作。請使用快捷鍵 (Ctrl+C) 複製。",
+
+PasteAsText		: "貼為純文字格式",
+PasteFromWord	: "自 Word 貼上",
+
+DlgPasteMsg2	: "請使用快捷鍵 (<strong>Ctrl+V</strong>) 貼到下方區域中並按下 <strong>確定</strong>",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "移除字型設定",
+DlgPasteRemoveStyles	: "移除樣式設定",
+DlgPasteCleanBox		: "清除文字區域",
+
+// Color Picker
+ColorAutomatic	: "自動",
+ColorMoreColors	: "更多顏色…",
+
+// Document Properties
+DocProps		: "文件屬性",
+
+// Anchor Dialog
+DlgAnchorTitle		: "命名錨點",
+DlgAnchorName		: "錨點名稱",
+DlgAnchorErrorName	: "請輸入錨點名稱",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "不在字典中",
+DlgSpellChangeTo		: "更改為",
+DlgSpellBtnIgnore		: "忽略",
+DlgSpellBtnIgnoreAll	: "全部忽略",
+DlgSpellBtnReplace		: "取代",
+DlgSpellBtnReplaceAll	: "全部取代",
+DlgSpellBtnUndo			: "復原",
+DlgSpellNoSuggestions	: "- 無建議值 -",
+DlgSpellProgress		: "進行拼字檢查中…",
+DlgSpellNoMispell		: "拼字檢查完成：未發現拼字錯誤",
+DlgSpellNoChanges		: "拼字檢查完成：未更改任何單字",
+DlgSpellOneChange		: "拼字檢查完成：更改了 1 個單字",
+DlgSpellManyChanges		: "拼字檢查完成：更改了 %1 個單字",
+
+IeSpellDownload			: "尚未安裝拼字檢查元件。您是否想要現在下載？",
+
+// Button Dialog
+DlgButtonText		: "顯示文字 (值)",
+DlgButtonType		: "類型",
+DlgButtonTypeBtn	: "按鈕 (Button)",
+DlgButtonTypeSbm	: "送出 (Submit)",
+DlgButtonTypeRst	: "重設 (Reset)",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "名稱",
+DlgCheckboxValue	: "選取值",
+DlgCheckboxSelected	: "已選取",
+
+// Form Dialog
+DlgFormName		: "名稱",
+DlgFormAction	: "動作",
+DlgFormMethod	: "方法",
+
+// Select Field Dialog
+DlgSelectName		: "名稱",
+DlgSelectValue		: "選取值",
+DlgSelectSize		: "大小",
+DlgSelectLines		: "行",
+DlgSelectChkMulti	: "可多選",
+DlgSelectOpAvail	: "可用選項",
+DlgSelectOpText		: "顯示文字",
+DlgSelectOpValue	: "值",
+DlgSelectBtnAdd		: "新增",
+DlgSelectBtnModify	: "修改",
+DlgSelectBtnUp		: "上移",
+DlgSelectBtnDown	: "下移",
+DlgSelectBtnSetValue : "設為預設值",
+DlgSelectBtnDelete	: "刪除",
+
+// Textarea Dialog
+DlgTextareaName	: "名稱",
+DlgTextareaCols	: "字元寬度",
+DlgTextareaRows	: "列數",
+
+// Text Field Dialog
+DlgTextName			: "名稱",
+DlgTextValue		: "值",
+DlgTextCharWidth	: "字元寬度",
+DlgTextMaxChars		: "最多字元數",
+DlgTextType			: "類型",
+DlgTextTypeText		: "文字",
+DlgTextTypePass		: "密碼",
+
+// Hidden Field Dialog
+DlgHiddenName	: "名稱",
+DlgHiddenValue	: "值",
+
+// Bulleted List Dialog
+BulletedListProp	: "項目清單屬性",
+NumberedListProp	: "編號清單屬性",
+DlgLstStart			: "起始編號",
+DlgLstType			: "清單類型",
+DlgLstTypeCircle	: "圓圈",
+DlgLstTypeDisc		: "圓點",
+DlgLstTypeSquare	: "方塊",
+DlgLstTypeNumbers	: "數字 (1, 2, 3)",
+DlgLstTypeLCase		: "小寫字母 (a, b, c)",
+DlgLstTypeUCase		: "大寫字母 (A, B, C)",
+DlgLstTypeSRoman	: "小寫羅馬數字 (i, ii, iii)",
+DlgLstTypeLRoman	: "大寫羅馬數字 (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "一般",
+DlgDocBackTab		: "背景",
+DlgDocColorsTab		: "顯色與邊界",
+DlgDocMetaTab		: "Meta 資料",
+
+DlgDocPageTitle		: "頁面標題",
+DlgDocLangDir		: "語言方向",
+DlgDocLangDirLTR	: "由左而右 (LTR)",
+DlgDocLangDirRTL	: "由右而左 (RTL)",
+DlgDocLangCode		: "語言代碼",
+DlgDocCharSet		: "字元編碼",
+DlgDocCharSetCE		: "中歐語系",
+DlgDocCharSetCT		: "正體中文 (Big5)",
+DlgDocCharSetCR		: "斯拉夫文",
+DlgDocCharSetGR		: "希臘文",
+DlgDocCharSetJP		: "日文",
+DlgDocCharSetKR		: "韓文",
+DlgDocCharSetTR		: "土耳其文",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "西歐語系",
+DlgDocCharSetOther	: "其他字元編碼",
+
+DlgDocDocType		: "文件類型",
+DlgDocDocTypeOther	: "其他文件類型",
+DlgDocIncXHTML		: "包含 XHTML 定義",
+DlgDocBgColor		: "背景顏色",
+DlgDocBgImage		: "背景影像",
+DlgDocBgNoScroll	: "浮水印",
+DlgDocCText			: "文字",
+DlgDocCLink			: "超連結",
+DlgDocCVisited		: "已瀏覽過的超連結",
+DlgDocCActive		: "作用中的超連結",
+DlgDocMargins		: "頁面邊界",
+DlgDocMaTop			: "上",
+DlgDocMaLeft		: "左",
+DlgDocMaRight		: "右",
+DlgDocMaBottom		: "下",
+DlgDocMeIndex		: "文件索引關鍵字 (用半形逗號[,]分隔)",
+DlgDocMeDescr		: "文件說明",
+DlgDocMeAuthor		: "作者",
+DlgDocMeCopy		: "版權所有",
+DlgDocPreview		: "預覽",
+
+// Templates Dialog
+Templates			: "樣版",
+DlgTemplatesTitle	: "內容樣版",
+DlgTemplatesSelMsg	: "請選擇欲開啟的樣版<br> (原有的內容將會被清除):",
+DlgTemplatesLoading	: "讀取樣版清單中，請稍候…",
+DlgTemplatesNoTpl	: "(無樣版)",
+DlgTemplatesReplace	: "取代原有內容",
+
+// About Dialog
+DlgAboutAboutTab	: "關於",
+DlgAboutBrowserInfoTab	: "瀏覽器資訊",
+DlgAboutLicenseTab	: "許可證",
+DlgAboutVersion		: "版本",
+DlgAboutInfo		: "想獲得更多資訊請至 "
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ca.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ca.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ca.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Catalan language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Col·lapsa la barra",
+ToolbarExpand		: "Amplia la barra",
+
+// Toolbar Items and Context Menu
+Save				: "Desa",
+NewPage				: "Nova Pàgina",
+Preview				: "Vista Prèvia",
+Cut					: "Retalla",
+Copy				: "Copia",
+Paste				: "Enganxa",
+PasteText			: "Enganxa com a text no formatat",
+PasteWord			: "Enganxa des del Word",
+Print				: "Imprimeix",
+SelectAll			: "Selecciona-ho tot",
+RemoveFormat		: "Elimina Format",
+InsertLinkLbl		: "Enllaç",
+InsertLink			: "Insereix/Edita enllaç",
+RemoveLink			: "Elimina enllaç",
+Anchor				: "Insereix/Edita àncora",
+InsertImageLbl		: "Imatge",
+InsertImage			: "Insereix/Edita imatge",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insereix/Edita Flash",
+InsertTableLbl		: "Taula",
+InsertTable			: "Insereix/Edita taula",
+InsertLineLbl		: "Línia",
+InsertLine			: "Insereix línia horitzontal",
+InsertSpecialCharLbl: "Caràcter Especial",
+InsertSpecialChar	: "Insereix caràcter especial",
+InsertSmileyLbl		: "Icona",
+InsertSmiley		: "Insereix icona",
+About				: "Quant a FCKeditor",
+Bold				: "Negreta",
+Italic				: "Cursiva",
+Underline			: "Subratllat",
+StrikeThrough		: "Barrat",
+Subscript			: "Subíndex",
+Superscript			: "Superíndex",
+LeftJustify			: "Aliniament esquerra",
+CenterJustify		: "Aliniament centrat",
+RightJustify		: "Aliniament dreta",
+BlockJustify		: "Justifica",
+DecreaseIndent		: "Sagna el text",
+IncreaseIndent		: "Treu el sagnat del text",
+Undo				: "Desfés",
+Redo				: "Refés",
+NumberedListLbl		: "Llista numerada",
+NumberedList		: "Aplica o elimina la llista numerada",
+BulletedListLbl		: "Llista de pics",
+BulletedList		: "Aplica o elimina la llista de pics",
+ShowTableBorders	: "Mostra les vores de les taules",
+ShowDetails			: "Mostra detalls",
+Style				: "Estil",
+FontFormat			: "Format",
+Font				: "Tipus de lletra",
+FontSize			: "Mida",
+TextColor			: "Color de Text",
+BGColor				: "Color de Fons",
+Source				: "Codi font",
+Find				: "Cerca",
+Replace				: "Reemplaça",
+SpellCheck			: "Revisa l'ortografia",
+UniversalKeyboard	: "Teclat universal",
+PageBreakLbl		: "Salt de pàgina",
+PageBreak			: "Insereix salt de pàgina",
+
+Form			: "Formulari",
+Checkbox		: "Casella de verificació",
+RadioButton		: "Botó d'opció",
+TextField		: "Camp de text",
+Textarea		: "Àrea de text",
+HiddenField		: "Camp ocult",
+Button			: "Botó",
+SelectionField	: "Camp de selecció",
+ImageButton		: "Botó d'imatge",
+
+FitWindow		: "Maximiza la mida de l'editor",
+
+// Context Menu
+EditLink			: "Edita l'enllaç",
+CellCM				: "Cel·la",
+RowCM				: "Fila",
+ColumnCM			: "Columna",
+InsertRow			: "Insereix una fila",
+DeleteRows			: "Suprimeix una fila",
+InsertColumn		: "Afegeix una columna",
+DeleteColumns		: "Suprimeix una columna",
+InsertCell			: "Insereix una cel·la",
+DeleteCells			: "Suprimeix les cel·les",
+MergeCells			: "Fusiona les cel·les",
+SplitCell			: "Separa les cel·les",
+TableDelete			: "Suprimeix la taula",
+CellProperties		: "Propietats de la cel·la",
+TableProperties		: "Propietats de la taula",
+ImageProperties		: "Propietats de la imatge",
+FlashProperties		: "Propietats del Flash",
+
+AnchorProp			: "Propietats de l'àncora",
+ButtonProp			: "Propietats del botó",
+CheckboxProp		: "Propietats de la casella de verificació",
+HiddenFieldProp		: "Propietats del camp ocult",
+RadioButtonProp		: "Propietats del botó d'opció",
+ImageButtonProp		: "Propietats del botó d'imatge",
+TextFieldProp		: "Propietats del camp de text",
+SelectionFieldProp	: "Propietats del camp de selecció",
+TextareaProp		: "Propietats de l'àrea de text",
+FormProp			: "Propietats del formulari",
+
+FontFormats			: "Normal;Formatejat;Adreça;Encapçalament 1;Encapçalament 2;Encapçalament 3;Encapçalament 4;Encapçalament 5;Encapçalament 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Processant XHTML. Si us plau esperi...",
+Done				: "Fet",
+PasteWordConfirm	: "El text que voleu enganxar sembla provenir de Word. Voleu netejar aquest text abans que sigui enganxat?",
+NotCompatiblePaste	: "Aquesta funció és disponible per a Internet Explorer versió 5.5 o superior. Voleu enganxar sense netejar?",
+UnknownToolbarItem	: "Element de la barra d'eines desconegut \"%1\"",
+UnknownCommand		: "Nom de comanda desconegut \"%1\"",
+NotImplemented		: "Mètode no implementat",
+UnknownToolbarSet	: "Conjunt de barra d'eines \"%1\" inexistent",
+NoActiveX			: "Les preferències del navegador poden limitar algunes funcions d'aquest editor. Cal habilitar l'opció \"Executa controls ActiveX i plug-ins\". Poden sorgir errors i poden faltar algunes funcions.",
+BrowseServerBlocked : "El visualitzador de recursos no s'ha pogut obrir. Assegura't de que els bloquejos de finestres emergents estan desactivats.",
+DialogBlocked		: "No ha estat possible obrir una finestra de diàleg. Assegura't de que els bloquejos de finestres emergents estan desactivats.",
+
+// Dialogs
+DlgBtnOK			: "D'acord",
+DlgBtnCancel		: "Cancel·la",
+DlgBtnClose			: "Tanca",
+DlgBtnBrowseServer	: "Veure servidor",
+DlgAdvancedTag		: "Avançat",
+DlgOpOther			: "Altres",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Si us plau, afegiu la URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<no definit>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Direcció de l'idioma",
+DlgGenLangDirLtr	: "D'esquerra a dreta (LTR)",
+DlgGenLangDirRtl	: "De dreta a esquerra (RTL)",
+DlgGenLangCode		: "Codi d'idioma",
+DlgGenAccessKey		: "Clau d'accés",
+DlgGenName			: "Nom",
+DlgGenTabIndex		: "Index de Tab",
+DlgGenLongDescr		: "Descripció llarga de la URL",
+DlgGenClass			: "Classes del full d'estil",
+DlgGenTitle			: "Títol consultiu",
+DlgGenContType		: "Tipus de contingut consultiu",
+DlgGenLinkCharset	: "Conjunt de caràcters font enllaçat",
+DlgGenStyle			: "Estil",
+
+// Image Dialog
+DlgImgTitle			: "Propietats de la imatge",
+DlgImgInfoTab		: "Informació de la imatge",
+DlgImgBtnUpload		: "Envia-la al servidor",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Puja",
+DlgImgAlt			: "Text alternatiu",
+DlgImgWidth			: "Amplada",
+DlgImgHeight		: "Alçada",
+DlgImgLockRatio		: "Bloqueja les proporcions",
+DlgBtnResetSize		: "Restaura la mida",
+DlgImgBorder		: "Vora",
+DlgImgHSpace		: "Espaiat horit.",
+DlgImgVSpace		: "Espaiat vert.",
+DlgImgAlign			: "Alineació",
+DlgImgAlignLeft		: "Ajusta a l'esquerra",
+DlgImgAlignAbsBottom: "Abs Bottom",
+DlgImgAlignAbsMiddle: "Abs Middle",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Bottom",
+DlgImgAlignMiddle	: "Middle",
+DlgImgAlignRight	: "Ajusta a la dreta",
+DlgImgAlignTextTop	: "Text Top",
+DlgImgAlignTop		: "Top",
+DlgImgPreview		: "Vista prèvia",
+DlgImgAlertUrl		: "Si us plau, escriviu la URL de la imatge",
+DlgImgLinkTab		: "Enllaç",
+
+// Flash Dialog
+DlgFlashTitle		: "Propietats del Flash",
+DlgFlashChkPlay		: "Reprodució automàtica",
+DlgFlashChkLoop		: "Bucle",
+DlgFlashChkMenu		: "Habilita menú Flash",
+DlgFlashScale		: "Escala",
+DlgFlashScaleAll	: "Mostra-ho tot",
+DlgFlashScaleNoBorder	: "Sense vores",
+DlgFlashScaleFit	: "Mida exacta",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Enllaç",
+DlgLnkInfoTab		: "Informació de l'enllaç",
+DlgLnkTargetTab		: "Destí",
+
+DlgLnkType			: "Tipus d'enllaç",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Àncora en aquesta pàgina",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<altra>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Selecciona una àncora",
+DlgLnkAnchorByName	: "Per nom d'àncora",
+DlgLnkAnchorById	: "Per Id d'element",
+DlgLnkNoAnchors		: "<No hi ha àncores disponibles en aquest document>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Adreça d'E-Mail",
+DlgLnkEMailSubject	: "Assumpte del missatge",
+DlgLnkEMailBody		: "Cos del missatge",
+DlgLnkUpload		: "Puja",
+DlgLnkBtnUpload		: "Envia al servidor",
+
+DlgLnkTarget		: "Destí",
+DlgLnkTargetFrame	: "<marc>",
+DlgLnkTargetPopup	: "<finestra emergent>",
+DlgLnkTargetBlank	: "Nova finestra (_blank)",
+DlgLnkTargetParent	: "Finestra pare (_parent)",
+DlgLnkTargetSelf	: "Mateixa finestra (_self)",
+DlgLnkTargetTop		: "Finestra Major (_top)",
+DlgLnkTargetFrameName	: "Nom del marc de destí",
+DlgLnkPopWinName	: "Nom finestra popup",
+DlgLnkPopWinFeat	: "Característiques finestra popup",
+DlgLnkPopResize		: "Redimensionable",
+DlgLnkPopLocation	: "Barra d'adreça",
+DlgLnkPopMenu		: "Barra de menú",
+DlgLnkPopScroll		: "Barres d'scroll",
+DlgLnkPopStatus		: "Barra d'estat",
+DlgLnkPopToolbar	: "Barra d'eines",
+DlgLnkPopFullScrn	: "Pantalla completa (IE)",
+DlgLnkPopDependent	: "Depenent (Netscape)",
+DlgLnkPopWidth		: "Amplada",
+DlgLnkPopHeight		: "Alçada",
+DlgLnkPopLeft		: "Posició esquerra",
+DlgLnkPopTop		: "Posició dalt",
+
+DlnLnkMsgNoUrl		: "Si us plau, escrigui l'enllaç URL",
+DlnLnkMsgNoEMail	: "Si us plau, escrigui l'adreça e-mail",
+DlnLnkMsgNoAnchor	: "Si us plau, escrigui l'àncora",
+DlnLnkMsgInvPopName	: "El nom de la finestra emergent ha de començar amb una lletra i no pot tenir espais",
+
+// Color Dialog
+DlgColorTitle		: "Selecciona el color",
+DlgColorBtnClear	: "Neteja",
+DlgColorHighlight	: "Realça",
+DlgColorSelected	: "Selecciona",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insereix una icona",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Selecciona el caràcter especial",
+
+// Table Dialog
+DlgTableTitle		: "Propietats de la taula",
+DlgTableRows		: "Files",
+DlgTableColumns		: "Columnes",
+DlgTableBorder		: "Tamany vora",
+DlgTableAlign		: "Alineació",
+DlgTableAlignNotSet	: "<No Definit>",
+DlgTableAlignLeft	: "Esquerra",
+DlgTableAlignCenter	: "Centre",
+DlgTableAlignRight	: "Dreta",
+DlgTableWidth		: "Amplada",
+DlgTableWidthPx		: "píxels",
+DlgTableWidthPc		: "percentatge",
+DlgTableHeight		: "Alçada",
+DlgTableCellSpace	: "Espaiat de cel·les",
+DlgTableCellPad		: "Encoixinament de cel·les",
+DlgTableCaption		: "Títol",
+DlgTableSummary		: "Resum",
+
+// Table Cell Dialog
+DlgCellTitle		: "Propietats de la cel·la",
+DlgCellWidth		: "Amplada",
+DlgCellWidthPx		: "píxels",
+DlgCellWidthPc		: "percentatge",
+DlgCellHeight		: "Alçada",
+DlgCellWordWrap		: "Ajust de paraula",
+DlgCellWordWrapNotSet	: "<No Definit>",
+DlgCellWordWrapYes	: "Si",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Alineació horitzontal",
+DlgCellHorAlignNotSet	: "<No Definit>",
+DlgCellHorAlignLeft	: "Esquerra",
+DlgCellHorAlignCenter	: "Centre",
+DlgCellHorAlignRight: "Dreta",
+DlgCellVerAlign		: "Alineació vertical",
+DlgCellVerAlignNotSet	: "<No definit>",
+DlgCellVerAlignTop	: "Top",
+DlgCellVerAlignMiddle	: "Middle",
+DlgCellVerAlignBottom	: "Bottom",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Rows Span",
+DlgCellCollSpan		: "Columns Span",
+DlgCellBackColor	: "Color de fons",
+DlgCellBorderColor	: "Color de la vora",
+DlgCellBtnSelect	: "Seleccioneu...",
+
+// Find Dialog
+DlgFindTitle		: "Cerca",
+DlgFindFindBtn		: "Cerca",
+DlgFindNotFoundMsg	: "El text especificat no s'ha trobat.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Reemplaça",
+DlgReplaceFindLbl		: "Cerca:",
+DlgReplaceReplaceLbl	: "Remplaça amb:",
+DlgReplaceCaseChk		: "Sensible a majúscules",
+DlgReplaceReplaceBtn	: "Reemplaça",
+DlgReplaceReplAllBtn	: "Reemplaça'ls tots",
+DlgReplaceWordChk		: "Cerca paraula completa",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "La seguretat del vostre navegador no permet executar automàticament les operacions de retallar. Si us plau, utilitzeu el teclat (Ctrl+X).",
+PasteErrorCopy	: "La seguretat del vostre navegador no permet executar automàticament les operacions de copiar. Si us plau, utilitzeu el teclat (Ctrl+C).",
+
+PasteAsText		: "Enganxa com a text sense format",
+PasteFromWord	: "Enganxa com a Word",
+
+DlgPasteMsg2	: "Si us plau, enganxeu dins del següent camp utilitzant el teclat (<STRONG>Ctrl+V</STRONG>) i premeu <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignora definicions de font",
+DlgPasteRemoveStyles	: "Elimina definicions d'estil",
+DlgPasteCleanBox		: "Neteja camp",
+
+// Color Picker
+ColorAutomatic	: "Automàtic",
+ColorMoreColors	: "Més colors...",
+
+// Document Properties
+DocProps		: "Propietats del document",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Propietats de l'àncora",
+DlgAnchorName		: "Nom de l'àncora",
+DlgAnchorErrorName	: "Si us plau, escriviu el nom de l'ancora",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "No és al diccionari",
+DlgSpellChangeTo		: "Canvia a",
+DlgSpellBtnIgnore		: "Ignora",
+DlgSpellBtnIgnoreAll	: "Ignora-les totes",
+DlgSpellBtnReplace		: "Canvia",
+DlgSpellBtnReplaceAll	: "Canvia-les totes",
+DlgSpellBtnUndo			: "Desfés",
+DlgSpellNoSuggestions	: "Cap sugerència",
+DlgSpellProgress		: "Comprovació ortogràfica en progrés",
+DlgSpellNoMispell		: "Comprovació ortogràfica completada",
+DlgSpellNoChanges		: "Comprovació ortogràfica: cap paraulada canviada",
+DlgSpellOneChange		: "Comprovació ortogràfica: una paraula canviada",
+DlgSpellManyChanges		: "Comprovació ortogràfica %1 paraules canviades",
+
+IeSpellDownload			: "Comprovació ortogràfica no instal·lada. Voleu descarregar-ho ara?",
+
+// Button Dialog
+DlgButtonText		: "Text (Valor)",
+DlgButtonType		: "Tipus",
+DlgButtonTypeBtn	: "Botó",
+DlgButtonTypeSbm	: "Transmet formulari",
+DlgButtonTypeRst	: "Reinicia formulari",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nom",
+DlgCheckboxValue	: "Valor",
+DlgCheckboxSelected	: "Seleccionat",
+
+// Form Dialog
+DlgFormName		: "Nom",
+DlgFormAction	: "Acció",
+DlgFormMethod	: "Mètode",
+
+// Select Field Dialog
+DlgSelectName		: "Nom",
+DlgSelectValue		: "Valor",
+DlgSelectSize		: "Tamany",
+DlgSelectLines		: "Línies",
+DlgSelectChkMulti	: "Permet múltiples seleccions",
+DlgSelectOpAvail	: "Opcions disponibles",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Valor",
+DlgSelectBtnAdd		: "Afegeix",
+DlgSelectBtnModify	: "Modifica",
+DlgSelectBtnUp		: "Amunt",
+DlgSelectBtnDown	: "Avall",
+DlgSelectBtnSetValue : "Selecciona per defecte",
+DlgSelectBtnDelete	: "Elimina",
+
+// Textarea Dialog
+DlgTextareaName	: "Nom",
+DlgTextareaCols	: "Columnes",
+DlgTextareaRows	: "Files",
+
+// Text Field Dialog
+DlgTextName			: "Nom",
+DlgTextValue		: "Valor",
+DlgTextCharWidth	: "Amplada de caràcter",
+DlgTextMaxChars		: "Màxim de caràcters",
+DlgTextType			: "Tipus",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Contrasenya",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nom",
+DlgHiddenValue	: "Valor",
+
+// Bulleted List Dialog
+BulletedListProp	: "Propietats de la llista de pics",
+NumberedListProp	: "Propietats de llista numerada",
+DlgLstStart			: "Inici",
+DlgLstType			: "Tipus",
+DlgLstTypeCircle	: "Cercle",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "Quadrat",
+DlgLstTypeNumbers	: "Números (1, 2, 3)",
+DlgLstTypeLCase		: "Lletres minúscules (a, b, c)",
+DlgLstTypeUCase		: "Lletres majúscules (A, B, C)",
+DlgLstTypeSRoman	: "Números romans minúscules (i, ii, iii)",
+DlgLstTypeLRoman	: "Números romans majúscules (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Fons",
+DlgDocColorsTab		: "Colors i marges",
+DlgDocMetaTab		: "Dades Meta",
+
+DlgDocPageTitle		: "Títol de la pàgina",
+DlgDocLangDir		: "Direcció llenguatge",
+DlgDocLangDirLTR	: "Esquerra a dreta (LTR)",
+DlgDocLangDirRTL	: "Dreta a esquerra (RTL)",
+DlgDocLangCode		: "Codi de llenguatge",
+DlgDocCharSet		: "Codificació de conjunt de caràcters",
+DlgDocCharSetCE		: "Centreeuropeu",
+DlgDocCharSetCT		: "Xinès tradicional (Big5)",
+DlgDocCharSetCR		: "Ciríl·lic",
+DlgDocCharSetGR		: "Grec",
+DlgDocCharSetJP		: "Japonès",
+DlgDocCharSetKR		: "Coreà",
+DlgDocCharSetTR		: "Turc",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Europeu occidental",
+DlgDocCharSetOther	: "Una altra codificació de caràcters",
+
+DlgDocDocType		: "Capçalera de tipus de document",
+DlgDocDocTypeOther	: "Altra Capçalera de tipus de document",
+DlgDocIncXHTML		: "Incloure declaracions XHTML",
+DlgDocBgColor		: "Color de fons",
+DlgDocBgImage		: "URL de la imatge de fons",
+DlgDocBgNoScroll	: "Fons fixe",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Enllaç",
+DlgDocCVisited		: "Enllaç visitat",
+DlgDocCActive		: "Enllaç actiu",
+DlgDocMargins		: "Marges de pàgina",
+DlgDocMaTop			: "Cap",
+DlgDocMaLeft		: "Esquerra",
+DlgDocMaRight		: "Dreta",
+DlgDocMaBottom		: "Peu",
+DlgDocMeIndex		: "Mots clau per a indexació (separats per coma)",
+DlgDocMeDescr		: "Descripció del document",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Vista prèvia",
+
+// Templates Dialog
+Templates			: "Plantilles",
+DlgTemplatesTitle	: "Contingut plantilles",
+DlgTemplatesSelMsg	: "Si us plau, seleccioneu la plantilla per obrir en l'editor<br>(el contingut actual no serà enregistrat):",
+DlgTemplatesLoading	: "Carregant la llista de plantilles. Si us plau, espereu...",
+DlgTemplatesNoTpl	: "(No hi ha plantilles definides)",
+DlgTemplatesReplace	: "Reemplaça el contingut actual",
+
+// About Dialog
+DlgAboutAboutTab	: "Quant a",
+DlgAboutBrowserInfoTab	: "Informació del navegador",
+DlgAboutLicenseTab	: "Llicència",
+DlgAboutVersion		: "versió",
+DlgAboutInfo		: "Per a més informació aneu a"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-ca.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-ca.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/en-ca.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * English (Canadian) language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Collapse Toolbar",
+ToolbarExpand		: "Expand Toolbar",
+
+// Toolbar Items and Context Menu
+Save				: "Save",
+NewPage				: "New Page",
+Preview				: "Preview",
+Cut					: "Cut",
+Copy				: "Copy",
+Paste				: "Paste",
+PasteText			: "Paste as plain text",
+PasteWord			: "Paste from Word",
+Print				: "Print",
+SelectAll			: "Select All",
+RemoveFormat		: "Remove Format",
+InsertLinkLbl		: "Link",
+InsertLink			: "Insert/Edit Link",
+RemoveLink			: "Remove Link",
+Anchor				: "Insert/Edit Anchor",
+InsertImageLbl		: "Image",
+InsertImage			: "Insert/Edit Image",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Insert/Edit Flash",
+InsertTableLbl		: "Table",
+InsertTable			: "Insert/Edit Table",
+InsertLineLbl		: "Line",
+InsertLine			: "Insert Horizontal Line",
+InsertSpecialCharLbl: "Special Character",
+InsertSpecialChar	: "Insert Special Character",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Insert Smiley",
+About				: "About FCKeditor",
+Bold				: "Bold",
+Italic				: "Italic",
+Underline			: "Underline",
+StrikeThrough		: "Strike Through",
+Subscript			: "Subscript",
+Superscript			: "Superscript",
+LeftJustify			: "Left Justify",
+CenterJustify		: "Centre Justify",
+RightJustify		: "Right Justify",
+BlockJustify		: "Block Justify",
+DecreaseIndent		: "Decrease Indent",
+IncreaseIndent		: "Increase Indent",
+Undo				: "Undo",
+Redo				: "Redo",
+NumberedListLbl		: "Numbered List",
+NumberedList		: "Insert/Remove Numbered List",
+BulletedListLbl		: "Bulleted List",
+BulletedList		: "Insert/Remove Bulleted List",
+ShowTableBorders	: "Show Table Borders",
+ShowDetails			: "Show Details",
+Style				: "Style",
+FontFormat			: "Format",
+Font				: "Font",
+FontSize			: "Size",
+TextColor			: "Text Colour",
+BGColor				: "Background Colour",
+Source				: "Source",
+Find				: "Find",
+Replace				: "Replace",
+SpellCheck			: "Check Spelling",
+UniversalKeyboard	: "Universal Keyboard",
+PageBreakLbl		: "Page Break",
+PageBreak			: "Insert Page Break",
+
+Form			: "Form",
+Checkbox		: "Checkbox",
+RadioButton		: "Radio Button",
+TextField		: "Text Field",
+Textarea		: "Textarea",
+HiddenField		: "Hidden Field",
+Button			: "Button",
+SelectionField	: "Selection Field",
+ImageButton		: "Image Button",
+
+FitWindow		: "Maximize the editor size",
+
+// Context Menu
+EditLink			: "Edit Link",
+CellCM				: "Cell",
+RowCM				: "Row",
+ColumnCM			: "Column",
+InsertRow			: "Insert Row",
+DeleteRows			: "Delete Rows",
+InsertColumn		: "Insert Column",
+DeleteColumns		: "Delete Columns",
+InsertCell			: "Insert Cell",
+DeleteCells			: "Delete Cells",
+MergeCells			: "Merge Cells",
+SplitCell			: "Split Cell",
+TableDelete			: "Delete Table",
+CellProperties		: "Cell Properties",
+TableProperties		: "Table Properties",
+ImageProperties		: "Image Properties",
+FlashProperties		: "Flash Properties",
+
+AnchorProp			: "Anchor Properties",
+ButtonProp			: "Button Properties",
+CheckboxProp		: "Checkbox Properties",
+HiddenFieldProp		: "Hidden Field Properties",
+RadioButtonProp		: "Radio Button Properties",
+ImageButtonProp		: "Image Button Properties",
+TextFieldProp		: "Text Field Properties",
+SelectionFieldProp	: "Selection Field Properties",
+TextareaProp		: "Textarea Properties",
+FormProp			: "Form Properties",
+
+FontFormats			: "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Processing XHTML. Please wait...",
+Done				: "Done",
+PasteWordConfirm	: "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?",
+NotCompatiblePaste	: "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?",
+UnknownToolbarItem	: "Unknown toolbar item \"%1\"",
+UnknownCommand		: "Unknown command name \"%1\"",
+NotImplemented		: "Command not implemented",
+UnknownToolbarSet	: "Toolbar set \"%1\" doesn't exist",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancel",
+DlgBtnClose			: "Close",
+DlgBtnBrowseServer	: "Browse Server",
+DlgAdvancedTag		: "Advanced",
+DlgOpOther			: "<Other>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Please insert the URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<not set>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Language Direction",
+DlgGenLangDirLtr	: "Left to Right (LTR)",
+DlgGenLangDirRtl	: "Right to Left (RTL)",
+DlgGenLangCode		: "Language Code",
+DlgGenAccessKey		: "Access Key",
+DlgGenName			: "Name",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Long Description URL",
+DlgGenClass			: "Stylesheet Classes",
+DlgGenTitle			: "Advisory Title",
+DlgGenContType		: "Advisory Content Type",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Image Properties",
+DlgImgInfoTab		: "Image Info",
+DlgImgBtnUpload		: "Send it to the Server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternative Text",
+DlgImgWidth			: "Width",
+DlgImgHeight		: "Height",
+DlgImgLockRatio		: "Lock Ratio",
+DlgBtnResetSize		: "Reset Size",
+DlgImgBorder		: "Border",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Align",
+DlgImgAlignLeft		: "Left",
+DlgImgAlignAbsBottom: "Abs Bottom",
+DlgImgAlignAbsMiddle: "Abs Middle",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Bottom",
+DlgImgAlignMiddle	: "Middle",
+DlgImgAlignRight	: "Right",
+DlgImgAlignTextTop	: "Text Top",
+DlgImgAlignTop		: "Top",
+DlgImgPreview		: "Preview",
+DlgImgAlertUrl		: "Please type the image URL",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",
+DlgFlashChkPlay		: "Auto Play",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Enable Flash Menu",
+DlgFlashScale		: "Scale",
+DlgFlashScaleAll	: "Show all",
+DlgFlashScaleNoBorder	: "No Border",
+DlgFlashScaleFit	: "Exact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Target",
+
+DlgLnkType			: "Link Type",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Link to anchor in the text",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocol",
+DlgLnkProtoOther	: "<other>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Select an Anchor",
+DlgLnkAnchorByName	: "By Anchor Name",
+DlgLnkAnchorById	: "By Element Id",
+DlgLnkNoAnchors		: "(No anchors available in the document)",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Address",
+DlgLnkEMailSubject	: "Message Subject",
+DlgLnkEMailBody		: "Message Body",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Send it to the Server",
+
+DlgLnkTarget		: "Target",
+DlgLnkTargetFrame	: "<frame>",
+DlgLnkTargetPopup	: "<popup window>",
+DlgLnkTargetBlank	: "New Window (_blank)",
+DlgLnkTargetParent	: "Parent Window (_parent)",
+DlgLnkTargetSelf	: "Same Window (_self)",
+DlgLnkTargetTop		: "Topmost Window (_top)",
+DlgLnkTargetFrameName	: "Target Frame Name",
+DlgLnkPopWinName	: "Popup Window Name",
+DlgLnkPopWinFeat	: "Popup Window Features",
+DlgLnkPopResize		: "Resizable",
+DlgLnkPopLocation	: "Location Bar",
+DlgLnkPopMenu		: "Menu Bar",
+DlgLnkPopScroll		: "Scroll Bars",
+DlgLnkPopStatus		: "Status Bar",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Full Screen (IE)",
+DlgLnkPopDependent	: "Dependent (Netscape)",
+DlgLnkPopWidth		: "Width",
+DlgLnkPopHeight		: "Height",
+DlgLnkPopLeft		: "Left Position",
+DlgLnkPopTop		: "Top Position",
+
+DlnLnkMsgNoUrl		: "Please type the link URL",
+DlnLnkMsgNoEMail	: "Please type the e-mail address",
+DlnLnkMsgNoAnchor	: "Please select an anchor",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",
+
+// Color Dialog
+DlgColorTitle		: "Select Colour",
+DlgColorBtnClear	: "Clear",
+DlgColorHighlight	: "Highlight",
+DlgColorSelected	: "Selected",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Insert a Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Select Special Character",
+
+// Table Dialog
+DlgTableTitle		: "Table Properties",
+DlgTableRows		: "Rows",
+DlgTableColumns		: "Columns",
+DlgTableBorder		: "Border size",
+DlgTableAlign		: "Alignment",
+DlgTableAlignNotSet	: "<Not set>",
+DlgTableAlignLeft	: "Left",
+DlgTableAlignCenter	: "Centre",
+DlgTableAlignRight	: "Right",
+DlgTableWidth		: "Width",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "percent",
+DlgTableHeight		: "Height",
+DlgTableCellSpace	: "Cell spacing",
+DlgTableCellPad		: "Cell padding",
+DlgTableCaption		: "Caption",
+DlgTableSummary		: "Summary",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cell Properties",
+DlgCellWidth		: "Width",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "percent",
+DlgCellHeight		: "Height",
+DlgCellWordWrap		: "Word Wrap",
+DlgCellWordWrapNotSet	: "<Not set>",
+DlgCellWordWrapYes	: "Yes",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "Horizontal Alignment",
+DlgCellHorAlignNotSet	: "<Not set>",
+DlgCellHorAlignLeft	: "Left",
+DlgCellHorAlignCenter	: "Centre",
+DlgCellHorAlignRight: "Right",
+DlgCellVerAlign		: "Vertical Alignment",
+DlgCellVerAlignNotSet	: "<Not set>",
+DlgCellVerAlignTop	: "Top",
+DlgCellVerAlignMiddle	: "Middle",
+DlgCellVerAlignBottom	: "Bottom",
+DlgCellVerAlignBaseline	: "Baseline",
+DlgCellRowSpan		: "Rows Span",
+DlgCellCollSpan		: "Columns Span",
+DlgCellBackColor	: "Background Colour",
+DlgCellBorderColor	: "Border Colour",
+DlgCellBtnSelect	: "Select...",
+
+// Find Dialog
+DlgFindTitle		: "Find",
+DlgFindFindBtn		: "Find",
+DlgFindNotFoundMsg	: "The specified text was not found.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Replace",
+DlgReplaceFindLbl		: "Find what:",
+DlgReplaceReplaceLbl	: "Replace with:",
+DlgReplaceCaseChk		: "Match case",
+DlgReplaceReplaceBtn	: "Replace",
+DlgReplaceReplAllBtn	: "Replace All",
+DlgReplaceWordChk		: "Match whole word",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).",
+PasteErrorCopy	: "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).",
+
+PasteAsText		: "Paste as Plain Text",
+PasteFromWord	: "Paste from Word",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<STRONG>Ctrl+V</STRONG>) and hit <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",
+DlgPasteRemoveStyles	: "Remove Styles definitions",
+DlgPasteCleanBox		: "Clean Up Box",
+
+// Color Picker
+ColorAutomatic	: "Automatic",
+ColorMoreColors	: "More Colours...",
+
+// Document Properties
+DocProps		: "Document Properties",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anchor Properties",
+DlgAnchorName		: "Anchor Name",
+DlgAnchorErrorName	: "Please type the anchor name",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Not in dictionary",
+DlgSpellChangeTo		: "Change to",
+DlgSpellBtnIgnore		: "Ignore",
+DlgSpellBtnIgnoreAll	: "Ignore All",
+DlgSpellBtnReplace		: "Replace",
+DlgSpellBtnReplaceAll	: "Replace All",
+DlgSpellBtnUndo			: "Undo",
+DlgSpellNoSuggestions	: "- No suggestions -",
+DlgSpellProgress		: "Spell check in progress...",
+DlgSpellNoMispell		: "Spell check complete: No misspellings found",
+DlgSpellNoChanges		: "Spell check complete: No words changed",
+DlgSpellOneChange		: "Spell check complete: One word changed",
+DlgSpellManyChanges		: "Spell check complete: %1 words changed",
+
+IeSpellDownload			: "Spell checker not installed. Do you want to download it now?",
+
+// Button Dialog
+DlgButtonText		: "Text (Value)",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",
+DlgCheckboxValue	: "Value",
+DlgCheckboxSelected	: "Selected",
+
+// Form Dialog
+DlgFormName		: "Name",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Method",
+
+// Select Field Dialog
+DlgSelectName		: "Name",
+DlgSelectValue		: "Value",
+DlgSelectSize		: "Size",
+DlgSelectLines		: "lines",
+DlgSelectChkMulti	: "Allow multiple selections",
+DlgSelectOpAvail	: "Available Options",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Value",
+DlgSelectBtnAdd		: "Add",
+DlgSelectBtnModify	: "Modify",
+DlgSelectBtnUp		: "Up",
+DlgSelectBtnDown	: "Down",
+DlgSelectBtnSetValue : "Set as selected value",
+DlgSelectBtnDelete	: "Delete",
+
+// Textarea Dialog
+DlgTextareaName	: "Name",
+DlgTextareaCols	: "Columns",
+DlgTextareaRows	: "Rows",
+
+// Text Field Dialog
+DlgTextName			: "Name",
+DlgTextValue		: "Value",
+DlgTextCharWidth	: "Character Width",
+DlgTextMaxChars		: "Maximum Characters",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Password",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",
+DlgHiddenValue	: "Value",
+
+// Bulleted List Dialog
+BulletedListProp	: "Bulleted List Properties",
+NumberedListProp	: "Numbered List Properties",
+DlgLstStart			: "Start",
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Circle",
+DlgLstTypeDisc		: "Disc",
+DlgLstTypeSquare	: "Square",
+DlgLstTypeNumbers	: "Numbers (1, 2, 3)",
+DlgLstTypeLCase		: "Lowercase Letters (a, b, c)",
+DlgLstTypeUCase		: "Uppercase Letters (A, B, C)",
+DlgLstTypeSRoman	: "Small Roman Numerals (i, ii, iii)",
+DlgLstTypeLRoman	: "Large Roman Numerals (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "General",
+DlgDocBackTab		: "Background",
+DlgDocColorsTab		: "Colours and Margins",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Page Title",
+DlgDocLangDir		: "Language Direction",
+DlgDocLangDirLTR	: "Left to Right (LTR)",
+DlgDocLangDirRTL	: "Right to Left (RTL)",
+DlgDocLangCode		: "Language Code",
+DlgDocCharSet		: "Character Set Encoding",
+DlgDocCharSetCE		: "Central European",
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Greek",
+DlgDocCharSetJP		: "Japanese",
+DlgDocCharSetKR		: "Korean",
+DlgDocCharSetTR		: "Turkish",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "Other Character Set Encoding",
+
+DlgDocDocType		: "Document Type Heading",
+DlgDocDocTypeOther	: "Other Document Type Heading",
+DlgDocIncXHTML		: "Include XHTML Declarations",
+DlgDocBgColor		: "Background Colour",
+DlgDocBgImage		: "Background Image URL",
+DlgDocBgNoScroll	: "Nonscrolling Background",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Visited Link",
+DlgDocCActive		: "Active Link",
+DlgDocMargins		: "Page Margins",
+DlgDocMaTop			: "Top",
+DlgDocMaLeft		: "Left",
+DlgDocMaRight		: "Right",
+DlgDocMaBottom		: "Bottom",
+DlgDocMeIndex		: "Document Indexing Keywords (comma separated)",
+DlgDocMeDescr		: "Document Description",
+DlgDocMeAuthor		: "Author",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Preview",
+
+// Templates Dialog
+Templates			: "Templates",
+DlgTemplatesTitle	: "Content Templates",
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br>(the actual contents will be lost):",
+DlgTemplatesLoading	: "Loading templates list. Please wait...",
+DlgTemplatesNoTpl	: "(No templates defined)",
+DlgTemplatesReplace	: "Replace actual contents",
+
+// About Dialog
+DlgAboutAboutTab	: "About",
+DlgAboutBrowserInfoTab	: "Browser Info",
+DlgAboutLicenseTab	: "License",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "For further information go to"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pt.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pt.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/pt.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Portuguese language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Fechar Barra",
+ToolbarExpand		: "Expandir Barra",
+
+// Toolbar Items and Context Menu
+Save				: "Guardar",
+NewPage				: "Nova Página",
+Preview				: "Pré-visualizar",
+Cut					: "Cortar",
+Copy				: "Copiar",
+Paste				: "Colar",
+PasteText			: "Colar como texto não formatado",
+PasteWord			: "Colar do Word",
+Print				: "Imprimir",
+SelectAll			: "Seleccionar Tudo",
+RemoveFormat		: "Eliminar Formato",
+InsertLinkLbl		: "Hiperligação",
+InsertLink			: "Inserir/Editar Hiperligação",
+RemoveLink			: "Eliminar Hiperligação",
+Anchor				: " Inserir/Editar Âncora",
+InsertImageLbl		: "Imagem",
+InsertImage			: "Inserir/Editar Imagem",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Inserir/Editar Flash",
+InsertTableLbl		: "Tabela",
+InsertTable			: "Inserir/Editar Tabela",
+InsertLineLbl		: "Linha",
+InsertLine			: "Inserir Linha Horizontal",
+InsertSpecialCharLbl: "Caracter Especial",
+InsertSpecialChar	: "Inserir Caracter Especial",
+InsertSmileyLbl		: "Emoticons",
+InsertSmiley		: "Inserir Emoticons",
+About				: "Acerca do FCKeditor",
+Bold				: "Negrito",
+Italic				: "Itálico",
+Underline			: "Sublinhado",
+StrikeThrough		: "Rasurado",
+Subscript			: "Superior à Linha",
+Superscript			: "Inferior à Linha",
+LeftJustify			: "Alinhar à Esquerda",
+CenterJustify		: "Alinhar ao Centro",
+RightJustify		: "Alinhar à Direita",
+BlockJustify		: "Justificado",
+DecreaseIndent		: "Diminuir Avanço",
+IncreaseIndent		: "Aumentar Avanço",
+Undo				: "Anular",
+Redo				: "Repetir",
+NumberedListLbl		: "Numeração",
+NumberedList		: "Inserir/Eliminar Numeração",
+BulletedListLbl		: "Marcas",
+BulletedList		: "Inserir/Eliminar Marcas",
+ShowTableBorders	: "Mostrar Limites da Tabelas",
+ShowDetails			: "Mostrar Parágrafo",
+Style				: "Estilo",
+FontFormat			: "Formato",
+Font				: "Tipo de Letra",
+FontSize			: "Tamanho",
+TextColor			: "Cor do Texto",
+BGColor				: "Cor de Fundo",
+Source				: "Fonte",
+Find				: "Procurar",
+Replace				: "Substituir",
+SpellCheck			: "Verificação Ortográfica",
+UniversalKeyboard	: "Teclado Universal",
+PageBreakLbl		: "Quebra de Página",
+PageBreak			: "Inserir Quebra de Página",
+
+Form			: "Formulário",
+Checkbox		: "Caixa de Verificação",
+RadioButton		: "Botão de Opção",
+TextField		: "Campo de Texto",
+Textarea		: "Área de Texto",
+HiddenField		: "Campo Escondido",
+Button			: "Botão",
+SelectionField	: "Caixa de Combinação",
+ImageButton		: "Botão de Imagem",
+
+FitWindow		: "Maximizar o tamanho do editor",
+
+// Context Menu
+EditLink			: "Editar Hiperligação",
+CellCM				: "Célula",
+RowCM				: "Linha",
+ColumnCM			: "Coluna",
+InsertRow			: "Inserir Linha",
+DeleteRows			: "Eliminar Linhas",
+InsertColumn		: "Inserir Coluna",
+DeleteColumns		: "Eliminar Coluna",
+InsertCell			: "Inserir Célula",
+DeleteCells			: "Eliminar Célula",
+MergeCells			: "Unir Células",
+SplitCell			: "Dividir Célula",
+TableDelete			: "Eliminar Tabela",
+CellProperties		: "Propriedades da Célula",
+TableProperties		: "Propriedades da Tabela",
+ImageProperties		: "Propriedades da Imagem",
+FlashProperties		: "Propriedades do Flash",
+
+AnchorProp			: "Propriedades da Âncora",
+ButtonProp			: "Propriedades do Botão",
+CheckboxProp		: "Propriedades da Caixa de Verificação",
+HiddenFieldProp		: "Propriedades do Campo Escondido",
+RadioButtonProp		: "Propriedades do Botão de Opção",
+ImageButtonProp		: "Propriedades do Botão de imagens",
+TextFieldProp		: "Propriedades do Campo de Texto",
+SelectionFieldProp	: "Propriedades da Caixa de Combinação",
+TextareaProp		: "Propriedades da Área de Texto",
+FormProp			: "Propriedades do Formulário",
+
+FontFormats			: "Normal;Formatado;Endereço;Título 1;Título 2;Título 3;Título 4;Título 5;Título 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "A Processar XHTML. Por favor, espere...",
+Done				: "Concluído",
+PasteWordConfirm	: "O texto que deseja parece ter sido copiado do Word. Deseja limpar a formatação antes de colar?",
+NotCompatiblePaste	: "Este comando só está disponível para Internet Explorer versão 5.5 ou superior. Deseja colar sem limpar a formatação?",
+UnknownToolbarItem	: "Item de barra desconhecido \"%1\"",
+UnknownCommand		: "Nome de comando desconhecido \"%1\"",
+NotImplemented		: "Comando não implementado",
+UnknownToolbarSet	: "Nome de barra \"%1\" não definido",
+NoActiveX			: "As definições de segurança do navegador podem limitar algumas potencalidades do editr. Deve activar a opção \"Executar controlos e extensões ActiveX\". Pode ocorrer erros ou verificar que faltam potencialidades.",
+BrowseServerBlocked : "Não foi possível abrir o navegador de recursos. Certifique-se que todos os bloqueadores de popup estão desactivados.",
+DialogBlocked		: "Não foi possível abrir a janela de diálogo. Certifique-se que todos os bloqueadores de popup estão desactivados.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Cancelar",
+DlgBtnClose			: "Fechar",
+DlgBtnBrowseServer	: "Navegar no Servidor",
+DlgAdvancedTag		: "Avançado",
+DlgOpOther			: "<Outro>",
+DlgInfoTab			: "Informação",
+DlgAlertUrl			: "Por favor introduza o URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<Não definido>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Orientação de idioma",
+DlgGenLangDirLtr	: "Esquerda à Direita (LTR)",
+DlgGenLangDirRtl	: "Direita a Esquerda (RTL)",
+DlgGenLangCode		: "Código de Idioma",
+DlgGenAccessKey		: "Chave de Acesso",
+DlgGenName			: "Nome",
+DlgGenTabIndex		: "Índice de Tubulação",
+DlgGenLongDescr		: "Descrição Completa do URL",
+DlgGenClass			: "Classes de Estilo de Folhas Classes",
+DlgGenTitle			: "Título",
+DlgGenContType		: "Tipo de Conteúdo",
+DlgGenLinkCharset	: "Fonte de caracteres vinculado",
+DlgGenStyle			: "Estilo",
+
+// Image Dialog
+DlgImgTitle			: "Propriedades da Imagem",
+DlgImgInfoTab		: "Informação da Imagem",
+DlgImgBtnUpload		: "Enviar para o Servidor",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Carregar",
+DlgImgAlt			: "Texto Alternativo",
+DlgImgWidth			: "Largura",
+DlgImgHeight		: "Altura",
+DlgImgLockRatio		: "Proporcional",
+DlgBtnResetSize		: "Tamanho Original",
+DlgImgBorder		: "Limite",
+DlgImgHSpace		: "Esp.Horiz",
+DlgImgVSpace		: "Esp.Vert",
+DlgImgAlign			: "Alinhamento",
+DlgImgAlignLeft		: "Esquerda",
+DlgImgAlignAbsBottom: "Abs inferior",
+DlgImgAlignAbsMiddle: "Abs centro",
+DlgImgAlignBaseline	: "Linha de base",
+DlgImgAlignBottom	: "Fundo",
+DlgImgAlignMiddle	: "Centro",
+DlgImgAlignRight	: "Direita",
+DlgImgAlignTextTop	: "Topo do texto",
+DlgImgAlignTop		: "Topo",
+DlgImgPreview		: "Pré-visualizar",
+DlgImgAlertUrl		: "Por favor introduza o URL da imagem",
+DlgImgLinkTab		: "Hiperligação",
+
+// Flash Dialog
+DlgFlashTitle		: "Propriedades do Flash",
+DlgFlashChkPlay		: "Reproduzir automaticamente",
+DlgFlashChkLoop		: "Loop",
+DlgFlashChkMenu		: "Permitir Menu do Flash",
+DlgFlashScale		: "Escala",
+DlgFlashScaleAll	: "Mostrar tudo",
+DlgFlashScaleNoBorder	: "Sem Limites",
+DlgFlashScaleFit	: "Tamanho Exacto",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Hiperligação",
+DlgLnkInfoTab		: "Informação de Hiperligação",
+DlgLnkTargetTab		: "Destino",
+
+DlgLnkType			: "Tipo de Hiperligação",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Referência a esta página",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protocolo",
+DlgLnkProtoOther	: "<outro>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Seleccionar una referência",
+DlgLnkAnchorByName	: "Por Nome de Referência",
+DlgLnkAnchorById	: "Por ID de elemento",
+DlgLnkNoAnchors		: "<Não há referências disponíveis no documento>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Endereço de E-Mail",
+DlgLnkEMailSubject	: "Título de Mensagem",
+DlgLnkEMailBody		: "Corpo da Mensagem",
+DlgLnkUpload		: "Carregar",
+DlgLnkBtnUpload		: "Enviar ao Servidor",
+
+DlgLnkTarget		: "Destino",
+DlgLnkTargetFrame	: "<Frame>",
+DlgLnkTargetPopup	: "<Janela de popup>",
+DlgLnkTargetBlank	: "Nova Janela(_blank)",
+DlgLnkTargetParent	: "Janela Pai (_parent)",
+DlgLnkTargetSelf	: "Mesma janela (_self)",
+DlgLnkTargetTop		: "Janela primaria (_top)",
+DlgLnkTargetFrameName	: "Nome do Frame Destino",
+DlgLnkPopWinName	: "Nome da Janela de Popup",
+DlgLnkPopWinFeat	: "Características de Janela de Popup",
+DlgLnkPopResize		: "Ajustável",
+DlgLnkPopLocation	: "Barra de localização",
+DlgLnkPopMenu		: "Barra de Menu",
+DlgLnkPopScroll		: "Barras de deslocamento",
+DlgLnkPopStatus		: "Barra de Estado",
+DlgLnkPopToolbar	: "Barra de Ferramentas",
+DlgLnkPopFullScrn	: "Janela Completa (IE)",
+DlgLnkPopDependent	: "Dependente (Netscape)",
+DlgLnkPopWidth		: "Largura",
+DlgLnkPopHeight		: "Altura",
+DlgLnkPopLeft		: "Posição Esquerda",
+DlgLnkPopTop		: "Posição Direita",
+
+DlnLnkMsgNoUrl		: "Por favor introduza a hiperligação URL",
+DlnLnkMsgNoEMail	: "Por favor introduza o endereço de e-mail",
+DlnLnkMsgNoAnchor	: "Por favor seleccione uma referência",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Seleccionar Cor",
+DlgColorBtnClear	: "Nenhuma",
+DlgColorHighlight	: "Destacado",
+DlgColorSelected	: "Seleccionado",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Inserir um Emoticon",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Seleccione um caracter especial",
+
+// Table Dialog
+DlgTableTitle		: "Propriedades da Tabela",
+DlgTableRows		: "Linhas",
+DlgTableColumns		: "Colunas",
+DlgTableBorder		: "Tamanho do Limite",
+DlgTableAlign		: "Alinhamento",
+DlgTableAlignNotSet	: "<Não definido>",
+DlgTableAlignLeft	: "Esquerda",
+DlgTableAlignCenter	: "Centrado",
+DlgTableAlignRight	: "Direita",
+DlgTableWidth		: "Largura",
+DlgTableWidthPx		: "pixeis",
+DlgTableWidthPc		: "percentagem",
+DlgTableHeight		: "Altura",
+DlgTableCellSpace	: "Esp. e/células",
+DlgTableCellPad		: "Esp. interior",
+DlgTableCaption		: "Título",
+DlgTableSummary		: "Sumário",
+
+// Table Cell Dialog
+DlgCellTitle		: "Propriedades da Célula",
+DlgCellWidth		: "Largura",
+DlgCellWidthPx		: "pixeis",
+DlgCellWidthPc		: "percentagem",
+DlgCellHeight		: "Altura",
+DlgCellWordWrap		: "Moldar Texto",
+DlgCellWordWrapNotSet	: "<Não definido>",
+DlgCellWordWrapYes	: "Sim",
+DlgCellWordWrapNo	: "Não",
+DlgCellHorAlign		: "Alinhamento Horizontal",
+DlgCellHorAlignNotSet	: "<Não definido>",
+DlgCellHorAlignLeft	: "Esquerda",
+DlgCellHorAlignCenter	: "Centrado",
+DlgCellHorAlignRight: "Direita",
+DlgCellVerAlign		: "Alinhamento Vertical",
+DlgCellVerAlignNotSet	: "<Não definido>",
+DlgCellVerAlignTop	: "Topo",
+DlgCellVerAlignMiddle	: "Médio",
+DlgCellVerAlignBottom	: "Fundi",
+DlgCellVerAlignBaseline	: "Linha de Base",
+DlgCellRowSpan		: "Unir Linhas",
+DlgCellCollSpan		: "Unir Colunas",
+DlgCellBackColor	: "Cor do Fundo",
+DlgCellBorderColor	: "Cor do Limite",
+DlgCellBtnSelect	: "Seleccione...",
+
+// Find Dialog
+DlgFindTitle		: "Procurar",
+DlgFindFindBtn		: "Procurar",
+DlgFindNotFoundMsg	: "O texto especificado não foi encontrado.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Substituir",
+DlgReplaceFindLbl		: "Texto a Procurar:",
+DlgReplaceReplaceLbl	: "Substituir por:",
+DlgReplaceCaseChk		: "Maiúsculas/Minúsculas",
+DlgReplaceReplaceBtn	: "Substituir",
+DlgReplaceReplAllBtn	: "Substituir Tudo",
+DlgReplaceWordChk		: "Coincidir com toda a palavra",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "A configuração de segurança do navegador não permite a execução automática de operações de cortar. Por favor use o teclado (Ctrl+X).",
+PasteErrorCopy	: "A configuração de segurança do navegador não permite a execução automática de operações de copiar. Por favor use o teclado (Ctrl+C).",
+
+PasteAsText		: "Colar como Texto Simples",
+PasteFromWord	: "Colar do Word",
+
+DlgPasteMsg2	: "Por favor, cole dentro da seguinte caixa usando o teclado (<STRONG>Ctrl+V</STRONG>) e prima <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorar da definições do Tipo de Letra ",
+DlgPasteRemoveStyles	: "Remover as definições de Estilos",
+DlgPasteCleanBox		: "Caixa de Limpeza",
+
+// Color Picker
+ColorAutomatic	: "Automático",
+ColorMoreColors	: "Mais Cores...",
+
+// Document Properties
+DocProps		: "Propriedades do Documento",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Propriedades da Âncora",
+DlgAnchorName		: "Nome da Âncora",
+DlgAnchorErrorName	: "Por favor, introduza o nome da âncora",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Não está num directório",
+DlgSpellChangeTo		: "Mudar para",
+DlgSpellBtnIgnore		: "Ignorar",
+DlgSpellBtnIgnoreAll	: "Ignorar Tudo",
+DlgSpellBtnReplace		: "Substituir",
+DlgSpellBtnReplaceAll	: "Substituir Tudo",
+DlgSpellBtnUndo			: "Anular",
+DlgSpellNoSuggestions	: "- Sem sugestões -",
+DlgSpellProgress		: "Verificação ortográfica em progresso…",
+DlgSpellNoMispell		: "Verificação ortográfica completa: não foram encontrados erros",
+DlgSpellNoChanges		: "Verificação ortográfica completa: não houve alteração de palavras",
+DlgSpellOneChange		: "Verificação ortográfica completa: uma palavra alterada",
+DlgSpellManyChanges		: "Verificação ortográfica completa: %1 palavras alteradas",
+
+IeSpellDownload			: " Verificação ortográfica não instalada. Quer descarregar agora?",
+
+// Button Dialog
+DlgButtonText		: "Texto (Valor)",
+DlgButtonType		: "Tipo",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nome",
+DlgCheckboxValue	: "Valor",
+DlgCheckboxSelected	: "Seleccionado",
+
+// Form Dialog
+DlgFormName		: "Nome",
+DlgFormAction	: "Acção",
+DlgFormMethod	: "Método",
+
+// Select Field Dialog
+DlgSelectName		: "Nome",
+DlgSelectValue		: "Valor",
+DlgSelectSize		: "Tamanho",
+DlgSelectLines		: "linhas",
+DlgSelectChkMulti	: "Permitir selecções múltiplas",
+DlgSelectOpAvail	: "Opções Possíveis",
+DlgSelectOpText		: "Texto",
+DlgSelectOpValue	: "Valor",
+DlgSelectBtnAdd		: "Adicionar",
+DlgSelectBtnModify	: "Modificar",
+DlgSelectBtnUp		: "Para cima",
+DlgSelectBtnDown	: "Para baixo",
+DlgSelectBtnSetValue : "Definir um valor por defeito",
+DlgSelectBtnDelete	: "Apagar",
+
+// Textarea Dialog
+DlgTextareaName	: "Nome",
+DlgTextareaCols	: "Colunas",
+DlgTextareaRows	: "Linhas",
+
+// Text Field Dialog
+DlgTextName			: "Nome",
+DlgTextValue		: "Valor",
+DlgTextCharWidth	: "Tamanho do caracter",
+DlgTextMaxChars		: "Nr. Máximo de Caracteres",
+DlgTextType			: "Tipo",
+DlgTextTypeText		: "Texto",
+DlgTextTypePass		: "Palavra-chave",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nome",
+DlgHiddenValue	: "Valor",
+
+// Bulleted List Dialog
+BulletedListProp	: "Propriedades da Marca",
+NumberedListProp	: "Propriedades da Numeração",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tipo",
+DlgLstTypeCircle	: "Circulo",
+DlgLstTypeDisc		: "Disco",
+DlgLstTypeSquare	: "Quadrado",
+DlgLstTypeNumbers	: "Números (1, 2, 3)",
+DlgLstTypeLCase		: "Letras Minúsculas (a, b, c)",
+DlgLstTypeUCase		: "Letras Maiúsculas (A, B, C)",
+DlgLstTypeSRoman	: "Numeração Romana em Minúsculas (i, ii, iii)",
+DlgLstTypeLRoman	: "Numeração Romana em Maiúsculas (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Geral",
+DlgDocBackTab		: "Fundo",
+DlgDocColorsTab		: "Cores e Margens",
+DlgDocMetaTab		: "Meta Data",
+
+DlgDocPageTitle		: "Título da Página",
+DlgDocLangDir		: "Orientação de idioma",
+DlgDocLangDirLTR	: "Esquerda à Direita (LTR)",
+DlgDocLangDirRTL	: "Direita à Esquerda (RTL)",
+DlgDocLangCode		: "Código de Idioma",
+DlgDocCharSet		: "Codificação de Caracteres",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Outra Codificação de Caracteres",
+
+DlgDocDocType		: "Tipo de Cabeçalho do Documento",
+DlgDocDocTypeOther	: "Outro Tipo de Cabeçalho do Documento",
+DlgDocIncXHTML		: "Incluir Declarações XHTML",
+DlgDocBgColor		: "Cor de Fundo",
+DlgDocBgImage		: "Caminho para a Imagem de Fundo",
+DlgDocBgNoScroll	: "Fundo Fixo",
+DlgDocCText			: "Texto",
+DlgDocCLink			: "Hiperligação",
+DlgDocCVisited		: "Hiperligação Visitada",
+DlgDocCActive		: "Hiperligação Activa",
+DlgDocMargins		: "Margem das Páginas",
+DlgDocMaTop			: "Topo",
+DlgDocMaLeft		: "Esquerda",
+DlgDocMaRight		: "Direita",
+DlgDocMaBottom		: "Fundo",
+DlgDocMeIndex		: "Palavras de Indexação do Documento (separadas por virgula)",
+DlgDocMeDescr		: "Descrição do Documento",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Direitos de Autor",
+DlgDocPreview		: "Pré-visualizar",
+
+// Templates Dialog
+Templates			: "Modelos",
+DlgTemplatesTitle	: "Modelo de Conteúdo",
+DlgTemplatesSelMsg	: "Por favor, seleccione o modelo a abrir no editor<br>(o conteúdo actual será perdido):",
+DlgTemplatesLoading	: "A carregar a lista de modelos. Aguarde por favor...",
+DlgTemplatesNoTpl	: "(Sem modelos definidos)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Acerca",
+DlgAboutBrowserInfoTab	: "Informação do Nevegador",
+DlgAboutLicenseTab	: "Licença",
+DlgAboutVersion		: "versão",
+DlgAboutInfo		: "Para mais informações por favor dirija-se a"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/da.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/da.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/da.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Danish language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Skjul værktøjslinier",
+ToolbarExpand		: "Vis værktøjslinier",
+
+// Toolbar Items and Context Menu
+Save				: "Gem",
+NewPage				: "Ny side",
+Preview				: "Vis eksempel",
+Cut					: "Klip",
+Copy				: "Kopier",
+Paste				: "Indsæt",
+PasteText			: "Indsæt som ikke-formateret tekst",
+PasteWord			: "Indsæt fra Word",
+Print				: "Udskriv",
+SelectAll			: "Vælg alt",
+RemoveFormat		: "Fjern formatering",
+InsertLinkLbl		: "Hyperlink",
+InsertLink			: "Indsæt/rediger hyperlink",
+RemoveLink			: "Fjern hyperlink",
+Anchor				: "Indsæt/rediger bogmærke",
+InsertImageLbl		: "Indsæt billede",
+InsertImage			: "Indsæt/rediger billede",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Indsæt/rediger Flash",
+InsertTableLbl		: "Table",
+InsertTable			: "Indsæt/rediger tabel",
+InsertLineLbl		: "Linie",
+InsertLine			: "Indsæt vandret linie",
+InsertSpecialCharLbl: "Symbol",
+InsertSpecialChar	: "Indsæt symbol",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Indsæt smiley",
+About				: "Om FCKeditor",
+Bold				: "Fed",
+Italic				: "Kursiv",
+Underline			: "Understreget",
+StrikeThrough		: "Overstreget",
+Subscript			: "Sænket skrift",
+Superscript			: "Hævet skrift",
+LeftJustify			: "Venstrestillet",
+CenterJustify		: "Centreret",
+RightJustify		: "Højrestillet",
+BlockJustify		: "Lige margener",
+DecreaseIndent		: "Formindsk indrykning",
+IncreaseIndent		: "Forøg indrykning",
+Undo				: "Fortryd",
+Redo				: "Annuller fortryd",
+NumberedListLbl		: "Talopstilling",
+NumberedList		: "Indsæt/fjern talopstilling",
+BulletedListLbl		: "Punktopstilling",
+BulletedList		: "Indsæt/fjern punktopstilling",
+ShowTableBorders	: "Vis tabelkanter",
+ShowDetails			: "Vis detaljer",
+Style				: "Typografi",
+FontFormat			: "Formatering",
+Font				: "Skrifttype",
+FontSize			: "Skriftstørrelse",
+TextColor			: "Tekstfarve",
+BGColor				: "Baggrundsfarve",
+Source				: "Kilde",
+Find				: "Søg",
+Replace				: "Erstat",
+SpellCheck			: "Stavekontrol",
+UniversalKeyboard	: "Universaltastatur",
+PageBreakLbl		: "Sidskift",
+PageBreak			: "Indsæt sideskift",
+
+Form			: "Indsæt formular",
+Checkbox		: "Indsæt afkrydsningsfelt",
+RadioButton		: "Indsæt alternativknap",
+TextField		: "Indsæt tekstfelt",
+Textarea		: "Indsæt tekstboks",
+HiddenField		: "Indsæt skjult felt",
+Button			: "Indsæt knap",
+SelectionField	: "Indsæt liste",
+ImageButton		: "Indsæt billedknap",
+
+FitWindow		: "Maksimer editor vinduet",
+
+// Context Menu
+EditLink			: "Rediger hyperlink",
+CellCM				: "Celle",
+RowCM				: "Række",
+ColumnCM			: "Kolonne",
+InsertRow			: "Indsæt række",
+DeleteRows			: "Slet række",
+InsertColumn		: "Indsæt kolonne",
+DeleteColumns		: "Slet kolonne",
+InsertCell			: "Indsæt celle",
+DeleteCells			: "Slet celle",
+MergeCells			: "Flet celler",
+SplitCell			: "Opdel celle",
+TableDelete			: "Slet tabel",
+CellProperties		: "Egenskaber for celle",
+TableProperties		: "Egenskaber for tabel",
+ImageProperties		: "Egenskaber for billede",
+FlashProperties		: "Egenskaber for Flash",
+
+AnchorProp			: "Egenskaber for bogmærke",
+ButtonProp			: "Egenskaber for knap",
+CheckboxProp		: "Egenskaber for afkrydsningsfelt",
+HiddenFieldProp		: "Egenskaber for skjult felt",
+RadioButtonProp		: "Egenskaber for alternativknap",
+ImageButtonProp		: "Egenskaber for billedknap",
+TextFieldProp		: "Egenskaber for tekstfelt",
+SelectionFieldProp	: "Egenskaber for liste",
+TextareaProp		: "Egenskaber for tekstboks",
+FormProp			: "Egenskaber for formular",
+
+FontFormats			: "Normal;Formateret;Adresse;Overskrift 1;Overskrift 2;Overskrift 3;Overskrift 4;Overskrift 5;Overskrift 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Behandler XHTML...",
+Done				: "Færdig",
+PasteWordConfirm	: "Den tekst du forsøger at indsætte ser ud til at komme fra Word.<br>Vil du rense teksten før den indsættes?",
+NotCompatiblePaste	: "Denne kommando er tilgændelig i Internet Explorer 5.5 eller senere.<br>Vil du indsætte teksten uden at rense den ?",
+UnknownToolbarItem	: "Ukendt værktøjslinjeobjekt \"%1\"!",
+UnknownCommand		: "Ukendt kommandonavn \"%1\"!",
+NotImplemented		: "Kommandoen er ikke implementeret!",
+UnknownToolbarSet	: "Værktøjslinjen \"%1\" eksisterer ikke!",
+NoActiveX			: "Din browsers sikkerhedsindstillinger begrænser nogle af editorens muligheder.<br>Slå \"Kør ActiveX-objekter og plug-ins\" til, ellers vil du opleve fejl og manglende muligheder.",
+BrowseServerBlocked : "Browseren kunne ikke åbne de nødvendige ressourcer!<br>Slå pop-up blokering fra.",
+DialogBlocked		: "Dialogvinduet kunne ikke åbnes!<br>Slå pop-up blokering fra.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Annuller",
+DlgBtnClose			: "Luk",
+DlgBtnBrowseServer	: "Gennemse...",
+DlgAdvancedTag		: "Avanceret",
+DlgOpOther			: "<Andet>",
+DlgInfoTab			: "Generelt",
+DlgAlertUrl			: "Indtast URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<intet valgt>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Tekstretning",
+DlgGenLangDirLtr	: "Fra venstre mod højre (LTR)",
+DlgGenLangDirRtl	: "Fra højre mod venstre (RTL)",
+DlgGenLangCode		: "Sprogkode",
+DlgGenAccessKey		: "Genvejstast",
+DlgGenName			: "Navn",
+DlgGenTabIndex		: "Tabulator indeks",
+DlgGenLongDescr		: "Udvidet beskrivelse",
+DlgGenClass			: "Typografiark",
+DlgGenTitle			: "Titel",
+DlgGenContType		: "Indholdstype",
+DlgGenLinkCharset	: "Tegnsæt",
+DlgGenStyle			: "Typografi",
+
+// Image Dialog
+DlgImgTitle			: "Egenskaber for billede",
+DlgImgInfoTab		: "Generelt",
+DlgImgBtnUpload		: "Upload",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternativ tekst",
+DlgImgWidth			: "Bredde",
+DlgImgHeight		: "Højde",
+DlgImgLockRatio		: "Lås størrelsesforhold",
+DlgBtnResetSize		: "Nulstil størrelse",
+DlgImgBorder		: "Ramme",
+DlgImgHSpace		: "HMargen",
+DlgImgVSpace		: "VMargen",
+DlgImgAlign			: "Justering",
+DlgImgAlignLeft		: "Venstre",
+DlgImgAlignAbsBottom: "Absolut nederst",
+DlgImgAlignAbsMiddle: "Absolut centreret",
+DlgImgAlignBaseline	: "Grundlinje",
+DlgImgAlignBottom	: "Nederst",
+DlgImgAlignMiddle	: "Centreret",
+DlgImgAlignRight	: "Højre",
+DlgImgAlignTextTop	: "Toppen af teksten",
+DlgImgAlignTop		: "Øverst",
+DlgImgPreview		: "Vis eksempel",
+DlgImgAlertUrl		: "Indtast stien til billedet",
+DlgImgLinkTab		: "Hyperlink",
+
+// Flash Dialog
+DlgFlashTitle		: "Egenskaber for Flash",
+DlgFlashChkPlay		: "Automatisk afspilning",
+DlgFlashChkLoop		: "Gentagelse",
+DlgFlashChkMenu		: "Vis Flash menu",
+DlgFlashScale		: "Skalér",
+DlgFlashScaleAll	: "Vis alt",
+DlgFlashScaleNoBorder	: "Ingen ramme",
+DlgFlashScaleFit	: "Tilpas størrelse",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Egenskaber for hyperlink",
+DlgLnkInfoTab		: "Generelt",
+DlgLnkTargetTab		: "Mål",
+
+DlgLnkType			: "Hyperlink type",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Bogmærke på denne side",
+DlgLnkTypeEMail		: "E-mail",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<anden>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Vælg et anker",
+DlgLnkAnchorByName	: "Efter anker navn",
+DlgLnkAnchorById	: "Efter element Id",
+DlgLnkNoAnchors		: "<Ingen bogmærker dokumentet>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-mailadresse",
+DlgLnkEMailSubject	: "Emne",
+DlgLnkEMailBody		: "Brødtekst",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Upload",
+
+DlgLnkTarget		: "Mål",
+DlgLnkTargetFrame	: "<ramme>",
+DlgLnkTargetPopup	: "<popup vindue>",
+DlgLnkTargetBlank	: "Nyt vindue (_blank)",
+DlgLnkTargetParent	: "Overordnet ramme (_parent)",
+DlgLnkTargetSelf	: "Samme vindue (_self)",
+DlgLnkTargetTop		: "Hele vinduet (_top)",
+DlgLnkTargetFrameName	: "Destinationsvinduets navn",
+DlgLnkPopWinName	: "Pop-up vinduets navn",
+DlgLnkPopWinFeat	: "Egenskaber for pop-up",
+DlgLnkPopResize		: "Skalering",
+DlgLnkPopLocation	: "Adresselinje",
+DlgLnkPopMenu		: "Menulinje",
+DlgLnkPopScroll		: "Scrollbars",
+DlgLnkPopStatus		: "Statuslinje",
+DlgLnkPopToolbar	: "Værktøjslinje",
+DlgLnkPopFullScrn	: "Fuld skærm (IE)",
+DlgLnkPopDependent	: "Koblet/dependent (Netscape)",
+DlgLnkPopWidth		: "Bredde",
+DlgLnkPopHeight		: "Højde",
+DlgLnkPopLeft		: "Position fra venstre",
+DlgLnkPopTop		: "Position fra toppen",
+
+DlnLnkMsgNoUrl		: "Indtast hyperlink URL!",
+DlnLnkMsgNoEMail	: "Indtast e-mailaddresse!",
+DlnLnkMsgNoAnchor	: "Vælg bogmærke!",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Vælg farve",
+DlgColorBtnClear	: "Nulstil",
+DlgColorHighlight	: "Markeret",
+DlgColorSelected	: "Valgt",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Vælg smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Vælg symbol",
+
+// Table Dialog
+DlgTableTitle		: "Egenskaber for tabel",
+DlgTableRows		: "Rækker",
+DlgTableColumns		: "Kolonner",
+DlgTableBorder		: "Rammebredde",
+DlgTableAlign		: "Justering",
+DlgTableAlignNotSet	: "<intet valgt>",
+DlgTableAlignLeft	: "Venstrestillet",
+DlgTableAlignCenter	: "Centreret",
+DlgTableAlignRight	: "Højrestillet",
+DlgTableWidth		: "Bredde",
+DlgTableWidthPx		: "pixels",
+DlgTableWidthPc		: "procent",
+DlgTableHeight		: "Højde",
+DlgTableCellSpace	: "Celleafstand",
+DlgTableCellPad		: "Cellemargen",
+DlgTableCaption		: "Titel",
+DlgTableSummary		: "Resume",
+
+// Table Cell Dialog
+DlgCellTitle		: "Egenskaber for celle",
+DlgCellWidth		: "Bredde",
+DlgCellWidthPx		: "pixels",
+DlgCellWidthPc		: "procent",
+DlgCellHeight		: "Højde",
+DlgCellWordWrap		: "Orddeling",
+DlgCellWordWrapNotSet	: "<intet valgt>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nej",
+DlgCellHorAlign		: "Vandret justering",
+DlgCellHorAlignNotSet	: "<intet valgt>",
+DlgCellHorAlignLeft	: "Venstrestillet",
+DlgCellHorAlignCenter	: "Centreret",
+DlgCellHorAlignRight: "Højrestillet",
+DlgCellVerAlign		: "Lodret justering",
+DlgCellVerAlignNotSet	: "<intet valgt>",
+DlgCellVerAlignTop	: "Øverst",
+DlgCellVerAlignMiddle	: "Centreret",
+DlgCellVerAlignBottom	: "Nederst",
+DlgCellVerAlignBaseline	: "Grundlinje",
+DlgCellRowSpan		: "Højde i antal rækker",
+DlgCellCollSpan		: "Bredde i antal kolonner",
+DlgCellBackColor	: "Baggrundsfarve",
+DlgCellBorderColor	: "Rammefarve",
+DlgCellBtnSelect	: "Vælg...",
+
+// Find Dialog
+DlgFindTitle		: "Find",
+DlgFindFindBtn		: "Find",
+DlgFindNotFoundMsg	: "Søgeteksten blev ikke fundet!",
+
+// Replace Dialog
+DlgReplaceTitle			: "Erstat",
+DlgReplaceFindLbl		: "Søg efter:",
+DlgReplaceReplaceLbl	: "Erstat med:",
+DlgReplaceCaseChk		: "Forskel på store og små bogstaver",
+DlgReplaceReplaceBtn	: "Erstat",
+DlgReplaceReplAllBtn	: "Erstat alle",
+DlgReplaceWordChk		: "Kun hele ord",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Din browsers sikkerhedsindstillinger tillader ikke editoren at klippe tekst automatisk!<br>Brug i stedet tastaturet til at klippe teksten (Ctrl+X).",
+PasteErrorCopy	: "Din browsers sikkerhedsindstillinger tillader ikke editoren at kopiere tekst automatisk!<br>Brug i stedet tastaturet til at kopiere teksten (Ctrl+C).",
+
+PasteAsText		: "Indsæt som ikke-formateret tekst",
+PasteFromWord	: "Indsæt fra Word",
+
+DlgPasteMsg2	: "Indsæt i feltet herunder (<STRONG>Ctrl+V</STRONG>) og klik <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorer font definitioner",
+DlgPasteRemoveStyles	: "Ignorer typografi",
+DlgPasteCleanBox		: "Slet indhold",
+
+// Color Picker
+ColorAutomatic	: "Automatisk",
+ColorMoreColors	: "Flere farver...",
+
+// Document Properties
+DocProps		: "Egenskaber for dokument",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Egenskaber for bogmærke",
+DlgAnchorName		: "Bogmærke navn",
+DlgAnchorErrorName	: "Indtast bogmærke navn!",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ikke i ordbogen",
+DlgSpellChangeTo		: "Forslag",
+DlgSpellBtnIgnore		: "Ignorer",
+DlgSpellBtnIgnoreAll	: "Ignorer alle",
+DlgSpellBtnReplace		: "Erstat",
+DlgSpellBtnReplaceAll	: "Erstat alle",
+DlgSpellBtnUndo			: "Tilbage",
+DlgSpellNoSuggestions	: "- ingen forslag -",
+DlgSpellProgress		: "Stavekontrolen arbejder...",
+DlgSpellNoMispell		: "Stavekontrol færdig: Ingen fejl fundet",
+DlgSpellNoChanges		: "Stavekontrol færdig: Ingen ord ændret",
+DlgSpellOneChange		: "Stavekontrol færdig: Et ord ændret",
+DlgSpellManyChanges		: "Stavekontrol færdig: %1 ord ændret",
+
+IeSpellDownload			: "Stavekontrol ikke installeret.<br>Vil du hente den nu?",
+
+// Button Dialog
+DlgButtonText		: "Tekst",
+DlgButtonType		: "Type",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Navn",
+DlgCheckboxValue	: "Værdi",
+DlgCheckboxSelected	: "Valgt",
+
+// Form Dialog
+DlgFormName		: "Navn",
+DlgFormAction	: "Handling",
+DlgFormMethod	: "Metod",
+
+// Select Field Dialog
+DlgSelectName		: "Navn",
+DlgSelectValue		: "Værdi",
+DlgSelectSize		: "Størrelse",
+DlgSelectLines		: "linier",
+DlgSelectChkMulti	: "Tillad flere valg",
+DlgSelectOpAvail	: "Valgmuligheder",
+DlgSelectOpText		: "Tekst",
+DlgSelectOpValue	: "Værdi",
+DlgSelectBtnAdd		: "Tilføj",
+DlgSelectBtnModify	: "Rediger",
+DlgSelectBtnUp		: "Op",
+DlgSelectBtnDown	: "Ned",
+DlgSelectBtnSetValue : "Sæt som valgt",
+DlgSelectBtnDelete	: "Slet",
+
+// Textarea Dialog
+DlgTextareaName	: "Navn",
+DlgTextareaCols	: "Kolonner",
+DlgTextareaRows	: "Rækker",
+
+// Text Field Dialog
+DlgTextName			: "Navn",
+DlgTextValue		: "Værdi",
+DlgTextCharWidth	: "Bredde (tegn)",
+DlgTextMaxChars		: "Max antal tegn",
+DlgTextType			: "Type",
+DlgTextTypeText		: "Tekst",
+DlgTextTypePass		: "Adgangskode",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Navn",
+DlgHiddenValue	: "Værdi",
+
+// Bulleted List Dialog
+BulletedListProp	: "Egenskaber for punktopstilling",
+NumberedListProp	: "Egenskaber for talopstilling",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Type",
+DlgLstTypeCircle	: "Cirkel",
+DlgLstTypeDisc		: "Udfyldt cirkel",
+DlgLstTypeSquare	: "Firkant",
+DlgLstTypeNumbers	: "Nummereret (1, 2, 3)",
+DlgLstTypeLCase		: "Små bogstaver (a, b, c)",
+DlgLstTypeUCase		: "Store bogstaver (A, B, C)",
+DlgLstTypeSRoman	: "Små romertal (i, ii, iii)",
+DlgLstTypeLRoman	: "Store romertal (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Generelt",
+DlgDocBackTab		: "Baggrund",
+DlgDocColorsTab		: "Farver og margen",
+DlgDocMetaTab		: "Metadata",
+
+DlgDocPageTitle		: "Sidetitel",
+DlgDocLangDir		: "Sprog",
+DlgDocLangDirLTR	: "Fra venstre mod højre (LTR)",
+DlgDocLangDirRTL	: "Fra højre mod venstre (RTL)",
+DlgDocLangCode		: "Landekode",
+DlgDocCharSet		: "Tegnsæt kode",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Anden tegnsæt kode",
+
+DlgDocDocType		: "Dokumenttype kategori",
+DlgDocDocTypeOther	: "Anden dokumenttype kategori",
+DlgDocIncXHTML		: "Inkludere XHTML deklartion",
+DlgDocBgColor		: "Baggrundsfarve",
+DlgDocBgImage		: "Baggrundsbillede URL",
+DlgDocBgNoScroll	: "Fastlåst baggrund",
+DlgDocCText			: "Tekst",
+DlgDocCLink			: "Hyperlink",
+DlgDocCVisited		: "Besøgt hyperlink",
+DlgDocCActive		: "Aktivt hyperlink",
+DlgDocMargins		: "Sidemargen",
+DlgDocMaTop			: "Øverst",
+DlgDocMaLeft		: "Venstre",
+DlgDocMaRight		: "Højre",
+DlgDocMaBottom		: "Nederst",
+DlgDocMeIndex		: "Dokument index nøgleord (kommasepareret)",
+DlgDocMeDescr		: "Dokument beskrivelse",
+DlgDocMeAuthor		: "Forfatter",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Vis",
+
+// Templates Dialog
+Templates			: "Skabeloner",
+DlgTemplatesTitle	: "Indholdsskabeloner",
+DlgTemplatesSelMsg	: "Vælg den skabelon, som skal åbnes i editoren.<br>(Nuværende indhold vil blive overskrevet!):",
+DlgTemplatesLoading	: "Henter liste over skabeloner...",
+DlgTemplatesNoTpl	: "(Der er ikke defineret nogen skabelon!)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Om",
+DlgAboutBrowserInfoTab	: "Generelt",
+DlgAboutLicenseTab	: "Licens",
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "For yderlig information gå til"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sr.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sr.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sr.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Serbian (Cyrillic) language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Смањи линију са алаткама",
+ToolbarExpand		: "Прошири линију са алаткама",
+
+// Toolbar Items and Context Menu
+Save				: "Сачувај",
+NewPage				: "Нова страница",
+Preview				: "Изглед странице",
+Cut					: "Исеци",
+Copy				: "Копирај",
+Paste				: "Залепи",
+PasteText			: "Залепи као неформатиран текст",
+PasteWord			: "Залепи из Worda",
+Print				: "Штампа",
+SelectAll			: "Означи све",
+RemoveFormat		: "Уклони форматирање",
+InsertLinkLbl		: "Линк",
+InsertLink			: "Унеси/измени линк",
+RemoveLink			: "Уклони линк",
+Anchor				: "Унеси/измени сидро",
+InsertImageLbl		: "Слика",
+InsertImage			: "Унеси/измени слику",
+InsertFlashLbl		: "Флеш елемент",
+InsertFlash			: "Унеси/измени флеш",
+InsertTableLbl		: "Табела",
+InsertTable			: "Унеси/измени табелу",
+InsertLineLbl		: "Линија",
+InsertLine			: "Унеси хоризонталну линију",
+InsertSpecialCharLbl: "Специјални карактери",
+InsertSpecialChar	: "Унеси специјални карактер",
+InsertSmileyLbl		: "Смајли",
+InsertSmiley		: "Унеси смајлија",
+About				: "О ФЦКедитору",
+Bold				: "Подебљано",
+Italic				: "Курзив",
+Underline			: "Подвучено",
+StrikeThrough		: "Прецртано",
+Subscript			: "Индекс",
+Superscript			: "Степен",
+LeftJustify			: "Лево равнање",
+CenterJustify		: "Центриран текст",
+RightJustify		: "Десно равнање",
+BlockJustify		: "Обострано равнање",
+DecreaseIndent		: "Смањи леву маргину",
+IncreaseIndent		: "Увећај леву маргину",
+Undo				: "Поништи акцију",
+Redo				: "Понови акцију",
+NumberedListLbl		: "Набројиву листу",
+NumberedList		: "Унеси/уклони набројиву листу",
+BulletedListLbl		: "Ненабројива листа",
+BulletedList		: "Унеси/уклони ненабројиву листу",
+ShowTableBorders	: "Прикажи оквир табеле",
+ShowDetails			: "Прикажи детаље",
+Style				: "Стил",
+FontFormat			: "Формат",
+Font				: "Фонт",
+FontSize			: "Величина фонта",
+TextColor			: "Боја текста",
+BGColor				: "Боја позадине",
+Source				: "Kôд",
+Find				: "Претрага",
+Replace				: "Замена",
+SpellCheck			: "Провери спеловање",
+UniversalKeyboard	: "Универзална тастатура",
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "Форма",
+Checkbox		: "Поље за потврду",
+RadioButton		: "Радио-дугме",
+TextField		: "Текстуално поље",
+Textarea		: "Зона текста",
+HiddenField		: "Скривено поље",
+Button			: "Дугме",
+SelectionField	: "Изборно поље",
+ImageButton		: "Дугме са сликом",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Промени линк",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Унеси ред",
+DeleteRows			: "Обриши редове",
+InsertColumn		: "Унеси колону",
+DeleteColumns		: "Обриши колоне",
+InsertCell			: "Унеси ћелије",
+DeleteCells			: "Обриши ћелије",
+MergeCells			: "Спој ћелије",
+SplitCell			: "Раздвоји ћелије",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "Особине ћелије",
+TableProperties		: "Особине табеле",
+ImageProperties		: "Особине слике",
+FlashProperties		: "Особине Флеша",
+
+AnchorProp			: "Особине сидра",
+ButtonProp			: "Особине дугмета",
+CheckboxProp		: "Особине поља за потврду",
+HiddenFieldProp		: "Особине скривеног поља",
+RadioButtonProp		: "Особине радио-дугмета",
+ImageButtonProp		: "Особине дугмета са сликом",
+TextFieldProp		: "Особине текстуалног поља",
+SelectionFieldProp	: "Особине изборног поља",
+TextareaProp		: "Особине зоне текста",
+FormProp			: "Особине форме",
+
+FontFormats			: "Normal;Formatirano;Adresa;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Обрађујем XHTML. Maлo стрпљења...",
+Done				: "Завршио",
+PasteWordConfirm	: "Текст који желите да налепите копиран је из Worda. Да ли желите да буде очишћен од формата пре лепљења?",
+NotCompatiblePaste	: "Ова команда је доступна само за Интернет Екплорер од верзије 5.5. Да ли желите да налепим текст без чишћења?",
+UnknownToolbarItem	: "Непозната ставка toolbara \"%1\"",
+UnknownCommand		: "Непозната наредба \"%1\"",
+NotImplemented		: "Наредба није имплементирана",
+UnknownToolbarSet	: "Toolbar \"%1\" не постоји",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Oткажи",
+DlgBtnClose			: "Затвори",
+DlgBtnBrowseServer	: "Претражи сервер",
+DlgAdvancedTag		: "Напредни тагови",
+DlgOpOther			: "<Остали>",
+DlgInfoTab			: "Инфо",
+DlgAlertUrl			: "Молимо Вас, унесите УРЛ",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<није постављено>",
+DlgGenId			: "Ид",
+DlgGenLangDir		: "Смер језика",
+DlgGenLangDirLtr	: "С лева на десно (LTR)",
+DlgGenLangDirRtl	: "С десна на лево (RTL)",
+DlgGenLangCode		: "Kôд језика",
+DlgGenAccessKey		: "Приступни тастер",
+DlgGenName			: "Назив",
+DlgGenTabIndex		: "Таб индекс",
+DlgGenLongDescr		: "Пун опис УРЛ",
+DlgGenClass			: "Stylesheet класе",
+DlgGenTitle			: "Advisory наслов",
+DlgGenContType		: "Advisory врста садржаја",
+DlgGenLinkCharset	: "Linked Resource Charset",
+DlgGenStyle			: "Стил",
+
+// Image Dialog
+DlgImgTitle			: "Особине слика",
+DlgImgInfoTab		: "Инфо слике",
+DlgImgBtnUpload		: "Пошаљи на сервер",
+DlgImgURL			: "УРЛ",
+DlgImgUpload		: "Пошаљи",
+DlgImgAlt			: "Алтернативни текст",
+DlgImgWidth			: "Ширина",
+DlgImgHeight		: "Висина",
+DlgImgLockRatio		: "Закључај однос",
+DlgBtnResetSize		: "Ресетуј величину",
+DlgImgBorder		: "Оквир",
+DlgImgHSpace		: "HSpace",
+DlgImgVSpace		: "VSpace",
+DlgImgAlign			: "Равнање",
+DlgImgAlignLeft		: "Лево",
+DlgImgAlignAbsBottom: "Abs доле",
+DlgImgAlignAbsMiddle: "Abs средина",
+DlgImgAlignBaseline	: "Базно",
+DlgImgAlignBottom	: "Доле",
+DlgImgAlignMiddle	: "Средина",
+DlgImgAlignRight	: "Десно",
+DlgImgAlignTextTop	: "Врх текста",
+DlgImgAlignTop		: "Врх",
+DlgImgPreview		: "Изглед",
+DlgImgAlertUrl		: "Унесите УРЛ слике",
+DlgImgLinkTab		: "Линк",
+
+// Flash Dialog
+DlgFlashTitle		: "Особине флеша",
+DlgFlashChkPlay		: "Аутоматски старт",
+DlgFlashChkLoop		: "Понављај",
+DlgFlashChkMenu		: "Укључи флеш мени",
+DlgFlashScale		: "Скалирај",
+DlgFlashScaleAll	: "Прикажи све",
+DlgFlashScaleNoBorder	: "Без ивице",
+DlgFlashScaleFit	: "Попуни површину",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Линк",
+DlgLnkInfoTab		: "Линк инфо",
+DlgLnkTargetTab		: "Мета",
+
+DlgLnkType			: "Врста линка",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Сидро на овој страници",
+DlgLnkTypeEMail		: "Eлектронска пошта",
+DlgLnkProto			: "Протокол",
+DlgLnkProtoOther	: "<друго>",
+DlgLnkURL			: "УРЛ",
+DlgLnkAnchorSel		: "Одабери сидро",
+DlgLnkAnchorByName	: "По називу сидра",
+DlgLnkAnchorById	: "Пo Ид-jу елемента",
+DlgLnkNoAnchors		: "<Нема доступних сидра>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Адреса електронске поште",
+DlgLnkEMailSubject	: "Наслов",
+DlgLnkEMailBody		: "Садржај поруке",
+DlgLnkUpload		: "Пошаљи",
+DlgLnkBtnUpload		: "Пошаљи на сервер",
+
+DlgLnkTarget		: "Meтa",
+DlgLnkTargetFrame	: "<оквир>",
+DlgLnkTargetPopup	: "<искачући прозор>",
+DlgLnkTargetBlank	: "Нови прозор (_blank)",
+DlgLnkTargetParent	: "Родитељски прозор (_parent)",
+DlgLnkTargetSelf	: "Исти прозор (_self)",
+DlgLnkTargetTop		: "Прозор на врху (_top)",
+DlgLnkTargetFrameName	: "Назив одредишног фрејма",
+DlgLnkPopWinName	: "Назив искачућег прозора",
+DlgLnkPopWinFeat	: "Могућности искачућег прозора",
+DlgLnkPopResize		: "Променљива величина",
+DlgLnkPopLocation	: "Локација",
+DlgLnkPopMenu		: "Контекстни мени",
+DlgLnkPopScroll		: "Скрол бар",
+DlgLnkPopStatus		: "Статусна линија",
+DlgLnkPopToolbar	: "Toolbar",
+DlgLnkPopFullScrn	: "Приказ преко целог екрана (ИE)",
+DlgLnkPopDependent	: "Зависно (Netscape)",
+DlgLnkPopWidth		: "Ширина",
+DlgLnkPopHeight		: "Висина",
+DlgLnkPopLeft		: "Од леве ивице екрана (пиксела)",
+DlgLnkPopTop		: "Од врха екрана (пиксела)",
+
+DlnLnkMsgNoUrl		: "Унесите УРЛ линка",
+DlnLnkMsgNoEMail	: "Откуцајте адресу електронске поште",
+DlnLnkMsgNoAnchor	: "Одаберите сидро",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Одаберите боју",
+DlgColorBtnClear	: "Обриши",
+DlgColorHighlight	: "Посветли",
+DlgColorSelected	: "Одабери",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Унеси смајлија",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Одаберите специјални карактер",
+
+// Table Dialog
+DlgTableTitle		: "Особине табеле",
+DlgTableRows		: "Редова",
+DlgTableColumns		: "Kолона",
+DlgTableBorder		: "Величина оквира",
+DlgTableAlign		: "Равнање",
+DlgTableAlignNotSet	: "<није постављено>",
+DlgTableAlignLeft	: "Лево",
+DlgTableAlignCenter	: "Средина",
+DlgTableAlignRight	: "Десно",
+DlgTableWidth		: "Ширина",
+DlgTableWidthPx		: "пиксела",
+DlgTableWidthPc		: "процената",
+DlgTableHeight		: "Висина",
+DlgTableCellSpace	: "Ћелијски простор",
+DlgTableCellPad		: "Размак ћелија",
+DlgTableCaption		: "Наслов табеле",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "Особине ћелије",
+DlgCellWidth		: "Ширина",
+DlgCellWidthPx		: "пиксела",
+DlgCellWidthPc		: "процената",
+DlgCellHeight		: "Висина",
+DlgCellWordWrap		: "Дељење речи",
+DlgCellWordWrapNotSet	: "<није постављено>",
+DlgCellWordWrapYes	: "Да",
+DlgCellWordWrapNo	: "Не",
+DlgCellHorAlign		: "Водоравно равнање",
+DlgCellHorAlignNotSet	: "<није постављено>",
+DlgCellHorAlignLeft	: "Лево",
+DlgCellHorAlignCenter	: "Средина",
+DlgCellHorAlignRight: "Десно",
+DlgCellVerAlign		: "Вертикално равнање",
+DlgCellVerAlignNotSet	: "<није постављено>",
+DlgCellVerAlignTop	: "Горње",
+DlgCellVerAlignMiddle	: "Средина",
+DlgCellVerAlignBottom	: "Доње",
+DlgCellVerAlignBaseline	: "Базно",
+DlgCellRowSpan		: "Спајање редова",
+DlgCellCollSpan		: "Спајање колона",
+DlgCellBackColor	: "Боја позадине",
+DlgCellBorderColor	: "Боја оквира",
+DlgCellBtnSelect	: "Oдабери...",
+
+// Find Dialog
+DlgFindTitle		: "Пронађи",
+DlgFindFindBtn		: "Пронађи",
+DlgFindNotFoundMsg	: "Тражени текст није пронађен.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Замени",
+DlgReplaceFindLbl		: "Пронађи:",
+DlgReplaceReplaceLbl	: "Замени са:",
+DlgReplaceCaseChk		: "Разликуј велика и мала слова",
+DlgReplaceReplaceBtn	: "Замени",
+DlgReplaceReplAllBtn	: "Замени све",
+DlgReplaceWordChk		: "Упореди целе речи",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског исецања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl+X).",
+PasteErrorCopy	: "Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског копирања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl+C).",
+
+PasteAsText		: "Залепи као чист текст",
+PasteFromWord	: "Залепи из Worda",
+
+DlgPasteMsg2	: "Молимо Вас да залепите унутар доње површине користећи тастатурну пречицу (<STRONG>Ctrl+V</STRONG>) и да притиснете <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Игнориши Font Face дефиниције",
+DlgPasteRemoveStyles	: "Уклони дефиниције стилова",
+DlgPasteCleanBox		: "Обриши све",
+
+// Color Picker
+ColorAutomatic	: "Аутоматски",
+ColorMoreColors	: "Више боја...",
+
+// Document Properties
+DocProps		: "Особине документа",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Особине сидра",
+DlgAnchorName		: "Име сидра",
+DlgAnchorErrorName	: "Молимо Вас да унесете име сидра",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Није у речнику",
+DlgSpellChangeTo		: "Измени",
+DlgSpellBtnIgnore		: "Игнориши",
+DlgSpellBtnIgnoreAll	: "Игнориши све",
+DlgSpellBtnReplace		: "Замени",
+DlgSpellBtnReplaceAll	: "Замени све",
+DlgSpellBtnUndo			: "Врати акцију",
+DlgSpellNoSuggestions	: "- Без сугестија -",
+DlgSpellProgress		: "Провера спеловања у току...",
+DlgSpellNoMispell		: "Провера спеловања завршена: грешке нису пронађене",
+DlgSpellNoChanges		: "Провера спеловања завршена: Није измењена ниједна реч",
+DlgSpellOneChange		: "Провера спеловања завршена: Измењена је једна реч",
+DlgSpellManyChanges		: "Провера спеловања завршена:  %1 реч(и) је измењено",
+
+IeSpellDownload			: "Провера спеловања није инсталирана. Да ли желите да је скинете са Интернета?",
+
+// Button Dialog
+DlgButtonText		: "Текст (вредност)",
+DlgButtonType		: "Tип",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Назив",
+DlgCheckboxValue	: "Вредност",
+DlgCheckboxSelected	: "Означено",
+
+// Form Dialog
+DlgFormName		: "Назив",
+DlgFormAction	: "Aкција",
+DlgFormMethod	: "Mетода",
+
+// Select Field Dialog
+DlgSelectName		: "Назив",
+DlgSelectValue		: "Вредност",
+DlgSelectSize		: "Величина",
+DlgSelectLines		: "линија",
+DlgSelectChkMulti	: "Дозволи вишеструку селекцију",
+DlgSelectOpAvail	: "Доступне опције",
+DlgSelectOpText		: "Текст",
+DlgSelectOpValue	: "Вредност",
+DlgSelectBtnAdd		: "Додај",
+DlgSelectBtnModify	: "Измени",
+DlgSelectBtnUp		: "Горе",
+DlgSelectBtnDown	: "Доле",
+DlgSelectBtnSetValue : "Подеси као означену вредност",
+DlgSelectBtnDelete	: "Обриши",
+
+// Textarea Dialog
+DlgTextareaName	: "Назив",
+DlgTextareaCols	: "Број колона",
+DlgTextareaRows	: "Број редова",
+
+// Text Field Dialog
+DlgTextName			: "Назив",
+DlgTextValue		: "Вредност",
+DlgTextCharWidth	: "Ширина (карактера)",
+DlgTextMaxChars		: "Максимално карактера",
+DlgTextType			: "Тип",
+DlgTextTypeText		: "Текст",
+DlgTextTypePass		: "Лозинка",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Назив",
+DlgHiddenValue	: "Вредност",
+
+// Bulleted List Dialog
+BulletedListProp	: "Особине Bulleted листе",
+NumberedListProp	: "Особине набројиве листе",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Тип",
+DlgLstTypeCircle	: "Круг",
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "Квадрат",
+DlgLstTypeNumbers	: "Бројеви (1, 2, 3)",
+DlgLstTypeLCase		: "мала слова (a, b, c)",
+DlgLstTypeUCase		: "ВЕЛИКА СЛОВА (A, B, C)",
+DlgLstTypeSRoman	: "Мале римске цифре (i, ii, iii)",
+DlgLstTypeLRoman	: "Велике римске цифре (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Опште особине",
+DlgDocBackTab		: "Позадина",
+DlgDocColorsTab		: "Боје и маргине",
+DlgDocMetaTab		: "Метаподаци",
+
+DlgDocPageTitle		: "Наслов странице",
+DlgDocLangDir		: "Смер језика",
+DlgDocLangDirLTR	: "Слева надесно (LTR)",
+DlgDocLangDirRTL	: "Здесна налево (RTL)",
+DlgDocLangCode		: "Шифра језика",
+DlgDocCharSet		: "Кодирање скупа карактера",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Остала кодирања скупа карактера",
+
+DlgDocDocType		: "Заглавље типа документа",
+DlgDocDocTypeOther	: "Остала заглавља типа документа",
+DlgDocIncXHTML		: "Улључи XHTML декларације",
+DlgDocBgColor		: "Боја позадине",
+DlgDocBgImage		: "УРЛ позадинске слике",
+DlgDocBgNoScroll	: "Фиксирана позадина",
+DlgDocCText			: "Текст",
+DlgDocCLink			: "Линк",
+DlgDocCVisited		: "Посећени линк",
+DlgDocCActive		: "Активни линк",
+DlgDocMargins		: "Маргине странице",
+DlgDocMaTop			: "Горња",
+DlgDocMaLeft		: "Лева",
+DlgDocMaRight		: "Десна",
+DlgDocMaBottom		: "Доња",
+DlgDocMeIndex		: "Кључне речи за индексирање документа (раздвојене зарезом)",
+DlgDocMeDescr		: "Опис документа",
+DlgDocMeAuthor		: "Аутор",
+DlgDocMeCopy		: "Ауторска права",
+DlgDocPreview		: "Изглед странице",
+
+// Templates Dialog
+Templates			: "Обрасци",
+DlgTemplatesTitle	: "Обрасци за садржај",
+DlgTemplatesSelMsg	: "Молимо Вас да одаберете образац који ће бити примењен на страницу (тренутни садржај ће бити обрисан):",
+DlgTemplatesLoading	: "Учитавам листу образаца. Мало стрпљења...",
+DlgTemplatesNoTpl	: "(Нема дефинисаних образаца)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "О едитору",
+DlgAboutBrowserInfoTab	: "Информације о претраживачу",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "верзија",
+DlgAboutInfo		: "За више информација посетите"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/tr.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/tr.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/tr.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Turkish language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Araç Çubuğunu Kapat",
+ToolbarExpand		: "Araç Çubuğunu Aç",
+
+// Toolbar Items and Context Menu
+Save				: "Kaydet",
+NewPage				: "Yeni Sayfa",
+Preview				: "Ön İzleme",
+Cut					: "Kes",
+Copy				: "Kopyala",
+Paste				: "Yapıştır",
+PasteText			: "Düzyazı Olarak Yapıştır",
+PasteWord			: "Word'den Yapıştır",
+Print				: "Yazdır",
+SelectAll			: "Tümünü Seç",
+RemoveFormat		: "Biçimi Kaldır",
+InsertLinkLbl		: "Köprü",
+InsertLink			: "Köprü Ekle/Düzenle",
+RemoveLink			: "Köprü Kaldır",
+Anchor				: "Çapa Ekle/Düzenle",
+InsertImageLbl		: "Resim",
+InsertImage			: "Resim Ekle/Düzenle",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Flash Ekle/Düzenle",
+InsertTableLbl		: "Tablo",
+InsertTable			: "Tablo Ekle/Düzenle",
+InsertLineLbl		: "Satır",
+InsertLine			: "Yatay Satır Ekle",
+InsertSpecialCharLbl: "Özel Karakter",
+InsertSpecialChar	: "Özel Karakter Ekle",
+InsertSmileyLbl		: "İfade",
+InsertSmiley		: "İfade Ekle",
+About				: "FCKeditor Hakkında",
+Bold				: "Kalın",
+Italic				: "İtalik",
+Underline			: "Altı Çizgili",
+StrikeThrough		: "Üstü Çizgili",
+Subscript			: "Alt Simge",
+Superscript			: "Üst Simge",
+LeftJustify			: "Sola Dayalı",
+CenterJustify		: "Ortalanmış",
+RightJustify		: "Sağa Dayalı",
+BlockJustify		: "İki Kenara Yaslanmış",
+DecreaseIndent		: "Sekme Azalt",
+IncreaseIndent		: "Sekme Arttır",
+Undo				: "Geri Al",
+Redo				: "Tekrarla",
+NumberedListLbl		: "Numaralı Liste",
+NumberedList		: "Numaralı Liste Ekle/Kaldır",
+BulletedListLbl		: "Simgeli Liste",
+BulletedList		: "Simgeli Liste Ekle/Kaldır",
+ShowTableBorders	: "Tablo Kenarlarını Göster",
+ShowDetails			: "Detayları Göster",
+Style				: "Biçem",
+FontFormat			: "Biçim",
+Font				: "Yazı Türü",
+FontSize			: "Boyut",
+TextColor			: "Yazı Rengi",
+BGColor				: "Arka Renk",
+Source				: "Kaynak",
+Find				: "Bul",
+Replace				: "Değiştir",
+SpellCheck			: "Yazım Denetimi",
+UniversalKeyboard	: "Evrensel Klavye",
+PageBreakLbl		: "Sayfa sonu",
+PageBreak			: "Sayfa Sonu Ekle",
+
+Form			: "Form",
+Checkbox		: "Onay Kutusu",
+RadioButton		: "Seçenek Düğmesi",
+TextField		: "Metin Girişi",
+Textarea		: "Çok Satırlı Metin",
+HiddenField		: "Gizli Veri",
+Button			: "Düğme",
+SelectionField	: "Seçim Menüsü",
+ImageButton		: "Resimli Düğme",
+
+FitWindow		: "Düzenleyici boyutunu büyüt",
+
+// Context Menu
+EditLink			: "Köprü Düzenle",
+CellCM				: "Hücre",
+RowCM				: "Satır",
+ColumnCM			: "Sütun",
+InsertRow			: "Satır Ekle",
+DeleteRows			: "Satır Sil",
+InsertColumn		: "Sütun Ekle",
+DeleteColumns		: "Sütun Sil",
+InsertCell			: "Hücre Ekle",
+DeleteCells			: "Hücre Sil",
+MergeCells			: "Hücreleri Birleştir",
+SplitCell			: "Hücre Böl",
+TableDelete			: "Tabloyu Sil",
+CellProperties		: "Hücre Özellikleri",
+TableProperties		: "Tablo Özellikleri",
+ImageProperties		: "Resim Özellikleri",
+FlashProperties		: "Flash Özellikleri",
+
+AnchorProp			: "Çapa Özellikleri",
+ButtonProp			: "Düğme Özellikleri",
+CheckboxProp		: "Onay Kutusu Özellikleri",
+HiddenFieldProp		: "Gizli Veri Özellikleri",
+RadioButtonProp		: "Seçenek Düğmesi Özellikleri",
+ImageButtonProp		: "Resimli Düğme Özellikleri",
+TextFieldProp		: "Metin Girişi Özellikleri",
+SelectionFieldProp	: "Seçim Menüsü Özellikleri",
+TextareaProp		: "Çok Satırlı Metin Özellikleri",
+FormProp			: "Form Özellikleri",
+
+FontFormats			: "Normal;Biçimli;Adres;Başlık 1;Başlık 2;Başlık 3;Başlık 4;Başlık 5;Başlık 6;Paragraf (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML işleniyor. Lütfen bekleyin...",
+Done				: "Bitti",
+PasteWordConfirm	: "Yapıştırdığınız yazı Word'den gelmişe benziyor. Yapıştırmadan önce gereksiz eklentileri silmek ister misiniz?",
+NotCompatiblePaste	: "Bu komut Internet Explorer 5.5 ve ileriki sürümleri için mevcuttur. Temizlenmeden yapıştırılmasını ister misiniz ?",
+UnknownToolbarItem	: "Bilinmeyen araç çubugu öğesi \"%1\"",
+UnknownCommand		: "Bilinmeyen komut \"%1\"",
+NotImplemented		: "Komut uyarlanamadı",
+UnknownToolbarSet	: "\"%1\" araç çubuğu öğesi mevcut değil",
+NoActiveX			: "Kullandığınız tarayıcının güvenlik ayarları bazı özelliklerin kullanılmasını engelliyor. Bu özelliklerin çalışması için \"Run ActiveX controls and plug-ins (Activex ve eklentileri çalıştır)\" seçeneğinin aktif yapılması gerekiyor. Kullanılamayan eklentiler ve hatalar konusunda daha fazla bilgi sahibi olun.",
+BrowseServerBlocked : "Kaynak tarayıcısı açılamadı. Tüm \"popup blocker\" programlarının devre dışı olduğundan emin olun. (Yahoo toolbar, Msn toolbar, Google toolbar gibi)",
+DialogBlocked		: "Diyalog açmak mümkün olmadı. Tüm \"Popup Blocker\" programlarının devre dışı olduğundan emin olun.",
+
+// Dialogs
+DlgBtnOK			: "Tamam",
+DlgBtnCancel		: "İptal",
+DlgBtnClose			: "Kapat",
+DlgBtnBrowseServer	: "Sunucuyu Gez",
+DlgAdvancedTag		: "Gelişmiş",
+DlgOpOther			: "<Diğer>",
+DlgInfoTab			: "Bilgi",
+DlgAlertUrl			: "Lütfen URL girin",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<tanımlanmamış>",
+DlgGenId			: "Kimlik",
+DlgGenLangDir		: "Dil Yönü",
+DlgGenLangDirLtr	: "Soldan Sağa (LTR)",
+DlgGenLangDirRtl	: "Sağdan Sola (RTL)",
+DlgGenLangCode		: "Dil Kodlaması",
+DlgGenAccessKey		: "Erişim Tuşu",
+DlgGenName			: "Ad",
+DlgGenTabIndex		: "Sekme İndeksi",
+DlgGenLongDescr		: "Uzun Tanımlı URL",
+DlgGenClass			: "Biçem Sayfası Sınıfları",
+DlgGenTitle			: "Danışma Başlığı",
+DlgGenContType		: "Danışma İçerik Türü",
+DlgGenLinkCharset	: "Bağlı Kaynak Karakter Gurubu",
+DlgGenStyle			: "Biçem",
+
+// Image Dialog
+DlgImgTitle			: "Resim Özellikleri",
+DlgImgInfoTab		: "Resim Bilgisi",
+DlgImgBtnUpload		: "Sunucuya Yolla",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Karşıya Yükle",
+DlgImgAlt			: "Alternatif Yazı",
+DlgImgWidth			: "Genişlik",
+DlgImgHeight		: "Yükseklik",
+DlgImgLockRatio		: "Oranı Kilitle",
+DlgBtnResetSize		: "Boyutu Başa Döndür",
+DlgImgBorder		: "Kenar",
+DlgImgHSpace		: "Yatay Boşluk",
+DlgImgVSpace		: "Dikey Boşluk",
+DlgImgAlign			: "Hizalama",
+DlgImgAlignLeft		: "Sol",
+DlgImgAlignAbsBottom: "Tam Altı",
+DlgImgAlignAbsMiddle: "Tam Ortası",
+DlgImgAlignBaseline	: "Taban Çizgisi",
+DlgImgAlignBottom	: "Alt",
+DlgImgAlignMiddle	: "Orta",
+DlgImgAlignRight	: "Sağ",
+DlgImgAlignTextTop	: "Yazı Tepeye",
+DlgImgAlignTop		: "Tepe",
+DlgImgPreview		: "Ön İzleme",
+DlgImgAlertUrl		: "Lütfen resmin URL'sini yazınız",
+DlgImgLinkTab		: "Köprü",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Özellikleri",
+DlgFlashChkPlay		: "Otomatik Oynat",
+DlgFlashChkLoop		: "Döngü",
+DlgFlashChkMenu		: "Flash Menüsünü Kullan",
+DlgFlashScale		: "Boyutlandır",
+DlgFlashScaleAll	: "Hepsini Göster",
+DlgFlashScaleNoBorder	: "Kenar Yok",
+DlgFlashScaleFit	: "Tam Sığdır",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Köprü",
+DlgLnkInfoTab		: "Köprü Bilgisi",
+DlgLnkTargetTab		: "Hedef",
+
+DlgLnkType			: "Köprü Türü",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Bu sayfada çapa",
+DlgLnkTypeEMail		: "E-Posta",
+DlgLnkProto			: "Protokol",
+DlgLnkProtoOther	: "<diğer>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Çapa Seç",
+DlgLnkAnchorByName	: "Çapa Adı ile",
+DlgLnkAnchorById	: "Eleman Kimlik Numarası ile",
+DlgLnkNoAnchors		: "<Bu belgede hiç çapa yok>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Posta Adresi",
+DlgLnkEMailSubject	: "İleti Konusu",
+DlgLnkEMailBody		: "İleti Gövdesi",
+DlgLnkUpload		: "Karşıya Yükle",
+DlgLnkBtnUpload		: "Sunucuya Gönder",
+
+DlgLnkTarget		: "Hedef",
+DlgLnkTargetFrame	: "<çerçeve>",
+DlgLnkTargetPopup	: "<yeni açılan pencere>",
+DlgLnkTargetBlank	: "Yeni Pencere(_blank)",
+DlgLnkTargetParent	: "Anne Pencere (_parent)",
+DlgLnkTargetSelf	: "Kendi Penceresi (_self)",
+DlgLnkTargetTop		: "En Üst Pencere (_top)",
+DlgLnkTargetFrameName	: "Hedef Çerçeve Adı",
+DlgLnkPopWinName	: "Yeni Açılan Pencere Adı",
+DlgLnkPopWinFeat	: "Yeni Açılan Pencere Özellikleri",
+DlgLnkPopResize		: "Boyutlandırılabilir",
+DlgLnkPopLocation	: "Yer Çubuğu",
+DlgLnkPopMenu		: "Menü Çubuğu",
+DlgLnkPopScroll		: "Kaydırma Çubukları",
+DlgLnkPopStatus		: "Durum Çubuğu",
+DlgLnkPopToolbar	: "Araç Çubuğu",
+DlgLnkPopFullScrn	: "Tam Ekran (IE)",
+DlgLnkPopDependent	: "Bağımlı (Netscape)",
+DlgLnkPopWidth		: "Genişlik",
+DlgLnkPopHeight		: "Yükseklik",
+DlgLnkPopLeft		: "Sola Göre Konum",
+DlgLnkPopTop		: "Yukarıya Göre Konum",
+
+DlnLnkMsgNoUrl		: "Lütfen köprü URL'sini yazın",
+DlnLnkMsgNoEMail	: "Lütfen E-posta adresini yazın",
+DlnLnkMsgNoAnchor	: "Lütfen bir çapa seçin",
+DlnLnkMsgInvPopName	: "Açılır pencere adı abecesel bir karakterle başlamalı ve boşluk içermemelidir",
+
+// Color Dialog
+DlgColorTitle		: "Renk Seç",
+DlgColorBtnClear	: "Temizle",
+DlgColorHighlight	: "Vurgula",
+DlgColorSelected	: "Seçilmiş",
+
+// Smiley Dialog
+DlgSmileyTitle		: "İfade Ekle",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Özel Karakter Seç",
+
+// Table Dialog
+DlgTableTitle		: "Tablo Özellikleri",
+DlgTableRows		: "Satırlar",
+DlgTableColumns		: "Sütunlar",
+DlgTableBorder		: "Kenar Kalınlığı",
+DlgTableAlign		: "Hizalama",
+DlgTableAlignNotSet	: "<Tanımlanmamış>",
+DlgTableAlignLeft	: "Sol",
+DlgTableAlignCenter	: "Merkez",
+DlgTableAlignRight	: "Sağ",
+DlgTableWidth		: "Genişlik",
+DlgTableWidthPx		: "piksel",
+DlgTableWidthPc		: "yüzde",
+DlgTableHeight		: "Yükseklik",
+DlgTableCellSpace	: "Izgara kalınlığı",
+DlgTableCellPad		: "Izgara yazı arası",
+DlgTableCaption		: "Başlık",
+DlgTableSummary		: "Özet",
+
+// Table Cell Dialog
+DlgCellTitle		: "Hücre Özellikleri",
+DlgCellWidth		: "Genişlik",
+DlgCellWidthPx		: "piksel",
+DlgCellWidthPc		: "yüzde",
+DlgCellHeight		: "Yükseklik",
+DlgCellWordWrap		: "Sözcük Kaydır",
+DlgCellWordWrapNotSet	: "<Tanımlanmamış>",
+DlgCellWordWrapYes	: "Evet",
+DlgCellWordWrapNo	: "Hayır",
+DlgCellHorAlign		: "Yatay Hizalama",
+DlgCellHorAlignNotSet	: "<Tanımlanmamış>",
+DlgCellHorAlignLeft	: "Sol",
+DlgCellHorAlignCenter	: "Merkez",
+DlgCellHorAlignRight: "Sağ",
+DlgCellVerAlign		: "Dikey Hizalama",
+DlgCellVerAlignNotSet	: "<Tanımlanmamış>",
+DlgCellVerAlignTop	: "Tepe",
+DlgCellVerAlignMiddle	: "Orta",
+DlgCellVerAlignBottom	: "Alt",
+DlgCellVerAlignBaseline	: "Taban Çizgisi",
+DlgCellRowSpan		: "Satır Kapla",
+DlgCellCollSpan		: "Sütun Kapla",
+DlgCellBackColor	: "Arka Plan Rengi",
+DlgCellBorderColor	: "Kenar Rengi",
+DlgCellBtnSelect	: "Seç...",
+
+// Find Dialog
+DlgFindTitle		: "Bul",
+DlgFindFindBtn		: "Bul",
+DlgFindNotFoundMsg	: "Belirtilen yazı bulunamadı.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Değiştir",
+DlgReplaceFindLbl		: "Aranan:",
+DlgReplaceReplaceLbl	: "Bununla değiştir:",
+DlgReplaceCaseChk		: "Büyük/küçük harf duyarlı",
+DlgReplaceReplaceBtn	: "Değiştir",
+DlgReplaceReplAllBtn	: "Tümünü Değiştir",
+DlgReplaceWordChk		: "Kelimenin tamamı uysun",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kesme işlemine izin vermiyor. İşlem için (Ctrl+X) tuşlarını kullanın.",
+PasteErrorCopy	: "Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kopyalama işlemine izin vermiyor. İşlem için (Ctrl+C) tuşlarını kullanın.",
+
+PasteAsText		: "Düz Metin Olarak Yapıştır",
+PasteFromWord	: "Word'den yapıştır",
+
+DlgPasteMsg2	: "Lütfen aşağıdaki kutunun içine yapıştırın. (<STRONG>Ctrl+V</STRONG>) ve <STRONG>Tamam</STRONG> butonunu tıklayın.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Yazı Tipi tanımlarını yoksay",
+DlgPasteRemoveStyles	: "Biçem Tanımlarını çıkar",
+DlgPasteCleanBox		: "Temizlik Kutusu",
+
+// Color Picker
+ColorAutomatic	: "Otomatik",
+ColorMoreColors	: "Diğer renkler...",
+
+// Document Properties
+DocProps		: "Belge Özellikleri",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Çapa Özellikleri",
+DlgAnchorName		: "Çapa Adı",
+DlgAnchorErrorName	: "Lütfen çapa için ad giriniz",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Sözlükte Yok",
+DlgSpellChangeTo		: "Şuna değiştir:",
+DlgSpellBtnIgnore		: "Yoksay",
+DlgSpellBtnIgnoreAll	: "Tümünü Yoksay",
+DlgSpellBtnReplace		: "Değiştir",
+DlgSpellBtnReplaceAll	: "Tümünü Değiştir",
+DlgSpellBtnUndo			: "Geri Al",
+DlgSpellNoSuggestions	: "- Öneri Yok -",
+DlgSpellProgress		: "Yazım denetimi işlemde...",
+DlgSpellNoMispell		: "Yazım denetimi tamamlandı: Yanlış yazıma rastlanmadı",
+DlgSpellNoChanges		: "Yazım denetimi tamamlandı: Hiçbir kelime değiştirilmedi",
+DlgSpellOneChange		: "Yazım denetimi tamamlandı: Bir kelime değiştirildi",
+DlgSpellManyChanges		: "Yazım denetimi tamamlandı: %1 kelime değiştirildi",
+
+IeSpellDownload			: "Yazım denetimi yüklenmemiş. Şimdi yüklemek ister misiniz?",
+
+// Button Dialog
+DlgButtonText		: "Metin (Değer)",
+DlgButtonType		: "Tip",
+DlgButtonTypeBtn	: "Düğme",
+DlgButtonTypeSbm	: "Gönder",
+DlgButtonTypeRst	: "Sıfırla",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Ad",
+DlgCheckboxValue	: "Değer",
+DlgCheckboxSelected	: "Seçili",
+
+// Form Dialog
+DlgFormName		: "Ad",
+DlgFormAction	: "İşlem",
+DlgFormMethod	: "Yöntem",
+
+// Select Field Dialog
+DlgSelectName		: "Ad",
+DlgSelectValue		: "Değer",
+DlgSelectSize		: "Boyut",
+DlgSelectLines		: "satır",
+DlgSelectChkMulti	: "Çoklu seçime izin ver",
+DlgSelectOpAvail	: "Mevcut Seçenekler",
+DlgSelectOpText		: "Metin",
+DlgSelectOpValue	: "Değer",
+DlgSelectBtnAdd		: "Ekle",
+DlgSelectBtnModify	: "Düzenle",
+DlgSelectBtnUp		: "Yukarı",
+DlgSelectBtnDown	: "Aşağı",
+DlgSelectBtnSetValue : "Seçili değer olarak ata",
+DlgSelectBtnDelete	: "Sil",
+
+// Textarea Dialog
+DlgTextareaName	: "Ad",
+DlgTextareaCols	: "Sütunlar",
+DlgTextareaRows	: "Satırlar",
+
+// Text Field Dialog
+DlgTextName			: "Ad",
+DlgTextValue		: "Değer",
+DlgTextCharWidth	: "Karakter Genişliği",
+DlgTextMaxChars		: "En Fazla Karakter",
+DlgTextType			: "Tür",
+DlgTextTypeText		: "Metin",
+DlgTextTypePass		: "Parola",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Ad",
+DlgHiddenValue	: "Değer",
+
+// Bulleted List Dialog
+BulletedListProp	: "Simgeli Liste Özellikleri",
+NumberedListProp	: "Numaralı Liste Özellikleri",
+DlgLstStart			: "Başlangıç",
+DlgLstType			: "Tip",
+DlgLstTypeCircle	: "Çember",
+DlgLstTypeDisc		: "Disk",
+DlgLstTypeSquare	: "Kare",
+DlgLstTypeNumbers	: "Sayılar (1, 2, 3)",
+DlgLstTypeLCase		: "Küçük Harfler (a, b, c)",
+DlgLstTypeUCase		: "Büyük Harfler (A, B, C)",
+DlgLstTypeSRoman	: "Küçük Romen Rakamları (i, ii, iii)",
+DlgLstTypeLRoman	: "Büyük Romen Rakamları (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Genel",
+DlgDocBackTab		: "Arka Plan",
+DlgDocColorsTab		: "Renkler ve Kenar Boşlukları",
+DlgDocMetaTab		: "Tanım Bilgisi (Meta)",
+
+DlgDocPageTitle		: "Sayfa Başlığı",
+DlgDocLangDir		: "Dil Yönü",
+DlgDocLangDirLTR	: "Soldan Sağa (LTR)",
+DlgDocLangDirRTL	: "Sağdan Sola (RTL)",
+DlgDocLangCode		: "Dil Kodu",
+DlgDocCharSet		: "Karakter Kümesi Kodlaması",
+DlgDocCharSetCE		: "Orta Avrupa",
+DlgDocCharSetCT		: "Geleneksel Çince (Big5)",
+DlgDocCharSetCR		: "Kiril",
+DlgDocCharSetGR		: "Yunanca",
+DlgDocCharSetJP		: "Japonca",
+DlgDocCharSetKR		: "Korece",
+DlgDocCharSetTR		: "Türkçe",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Batı Avrupa",
+DlgDocCharSetOther	: "Diğer Karakter Kümesi Kodlaması",
+
+DlgDocDocType		: "Belge Türü Başlığı",
+DlgDocDocTypeOther	: "Diğer Belge Türü Başlığı",
+DlgDocIncXHTML		: "XHTML Bildirimlerini Dahil Et",
+DlgDocBgColor		: "Arka Plan Rengi",
+DlgDocBgImage		: "Arka Plan Resim URLsi",
+DlgDocBgNoScroll	: "Sabit Arka Plan",
+DlgDocCText			: "Metin",
+DlgDocCLink			: "Köprü",
+DlgDocCVisited		: "Ziyaret Edilmiş Köprü",
+DlgDocCActive		: "Etkin Köprü",
+DlgDocMargins		: "Kenar Boşlukları",
+DlgDocMaTop			: "Tepe",
+DlgDocMaLeft		: "Sol",
+DlgDocMaRight		: "Sağ",
+DlgDocMaBottom		: "Alt",
+DlgDocMeIndex		: "Belge Dizinleme Anahtar Kelimeleri (virgülle ayrılmış)",
+DlgDocMeDescr		: "Belge Tanımı",
+DlgDocMeAuthor		: "Yazar",
+DlgDocMeCopy		: "Telif",
+DlgDocPreview		: "Ön İzleme",
+
+// Templates Dialog
+Templates			: "Şablonlar",
+DlgTemplatesTitle	: "İçerik Şablonları",
+DlgTemplatesSelMsg	: "Düzenleyicide açmak için lütfen bir şablon seçin.<br>(hali hazırdaki içerik kaybolacaktır.):",
+DlgTemplatesLoading	: "Şablon listesi yüklenmekte. Lütfen bekleyiniz...",
+DlgTemplatesNoTpl	: "(Belirli bir şablon seçilmedi)",
+DlgTemplatesReplace	: "Mevcut içerik ile değiştir",
+
+// About Dialog
+DlgAboutAboutTab	: "Hakkında",
+DlgAboutBrowserInfoTab	: "Gezgin Bilgisi",
+DlgAboutLicenseTab	: "Lisans",
+DlgAboutVersion		: "sürüm",
+DlgAboutInfo		: "Daha fazla bilgi için:"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fa.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fa.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fa.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Persian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "rtl",
+
+ToolbarCollapse		: "برچیدن نوارابزار",
+ToolbarExpand		: "گستردن نوارابزار",
+
+// Toolbar Items and Context Menu
+Save				: "ذخیره",
+NewPage				: "برگهٴ تازه",
+Preview				: "پیش‌نمایش",
+Cut					: "برش",
+Copy				: "کپی",
+Paste				: "چسباندن",
+PasteText			: "چسباندن به عنوان متن ِساده",
+PasteWord			: "چسباندن از Word",
+Print				: "چاپ",
+SelectAll			: "گزینش همه",
+RemoveFormat		: "برداشتن فرمت",
+InsertLinkLbl		: "پیوند",
+InsertLink			: "گنجاندن/ویرایش ِپیوند",
+RemoveLink			: "برداشتن پیوند",
+Anchor				: "گنجاندن/ویرایش ِلنگر",
+InsertImageLbl		: "تصویر",
+InsertImage			: "گنجاندن/ویرایش ِتصویر",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "گنجاندن/ویرایش ِFlash",
+InsertTableLbl		: "جدول",
+InsertTable			: "گنجاندن/ویرایش ِجدول",
+InsertLineLbl		: "خط",
+InsertLine			: "گنجاندن خط ِافقی",
+InsertSpecialCharLbl: "نویسهٴ ویژه",
+InsertSpecialChar	: "گنجاندن نویسهٴ ویژه",
+InsertSmileyLbl		: "خندانک",
+InsertSmiley		: "گنجاندن خندانک",
+About				: "دربارهٴ FCKeditor",
+Bold				: "درشت",
+Italic				: "خمیده",
+Underline			: "خط‌زیردار",
+StrikeThrough		: "میان‌خط",
+Subscript			: "زیرنویس",
+Superscript			: "بالانویس",
+LeftJustify			: "چپ‌چین",
+CenterJustify		: "میان‌چین",
+RightJustify		: "راست‌چین",
+BlockJustify		: "بلوک‌چین",
+DecreaseIndent		: "کاهش تورفتگی",
+IncreaseIndent		: "افزایش تورفتگی",
+Undo				: "واچیدن",
+Redo				: "بازچیدن",
+NumberedListLbl		: "فهرست شماره‌دار",
+NumberedList		: "گنجاندن/برداشتن فهرست شماره‌دار",
+BulletedListLbl		: "فهرست نقطه‌ای",
+BulletedList		: "گنجاندن/برداشتن فهرست نقطه‌ای",
+ShowTableBorders	: "نمایش لبهٴ جدول",
+ShowDetails			: "نمایش جزئیات",
+Style				: "سبک",
+FontFormat			: "فرمت",
+Font				: "قلم",
+FontSize			: "اندازه",
+TextColor			: "رنگ متن",
+BGColor				: "رنگ پس‌زمینه",
+Source				: "منبع",
+Find				: "جستجو",
+Replace				: "جایگزینی",
+SpellCheck			: "بررسی املا",
+UniversalKeyboard	: "صفحه‌کلید جهانی",
+PageBreakLbl		: "شکستگی ِپایان ِبرگه",
+PageBreak			: "گنجاندن شکستگی ِپایان ِبرگه",
+
+Form			: "فرم",
+Checkbox		: "خانهٴ گزینه‌ای",
+RadioButton		: "دکمهٴ رادیویی",
+TextField		: "فیلد متنی",
+Textarea		: "ناحیهٴ متنی",
+HiddenField		: "فیلد پنهان",
+Button			: "دکمه",
+SelectionField	: "فیلد چندگزینه‌ای",
+ImageButton		: "دکمهٴ تصویری",
+
+FitWindow		: "بیشینه‌سازی ِاندازهٴ ویرایشگر",
+
+// Context Menu
+EditLink			: "ویرایش پیوند",
+CellCM				: "سلول",
+RowCM				: "سطر",
+ColumnCM			: "ستون",
+InsertRow			: "گنجاندن سطر",
+DeleteRows			: "حذف سطرها",
+InsertColumn		: "گنجاندن ستون",
+DeleteColumns		: "حذف ستونها",
+InsertCell			: "گنجاندن سلول",
+DeleteCells			: "حذف سلولها",
+MergeCells			: "ادغام سلولها",
+SplitCell			: "جداسازی سلول",
+TableDelete			: "پاک‌کردن جدول",
+CellProperties		: "ویژگیهای سلول",
+TableProperties		: "ویژگیهای جدول",
+ImageProperties		: "ویژگیهای تصویر",
+FlashProperties		: "ویژگیهای Flash",
+
+AnchorProp			: "ویژگیهای لنگر",
+ButtonProp			: "ویژگیهای دکمه",
+CheckboxProp		: "ویژگیهای خانهٴ گزینه‌ای",
+HiddenFieldProp		: "ویژگیهای فیلد پنهان",
+RadioButtonProp		: "ویژگیهای دکمهٴ رادیویی",
+ImageButtonProp		: "ویژگیهای دکمهٴ تصویری",
+TextFieldProp		: "ویژگیهای فیلد متنی",
+SelectionFieldProp	: "ویژگیهای فیلد چندگزینه‌ای",
+TextareaProp		: "ویژگیهای ناحیهٴ متنی",
+FormProp			: "ویژگیهای فرم",
+
+FontFormats			: "نرمال;فرمت‌شده;آدرس;سرنویس 1;سرنویس 2;سرنویس 3;سرنویس 4;سرنویس 5;سرنویس 6;بند;(DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "پردازش XHTML. لطفا صبر کنید...",
+Done				: "انجام شد",
+PasteWordConfirm	: "کپی شده است. آیا می‌خواهید قبل از چسباندن آن را پاک‌سازی کنید؟ Word متنی که می‌خواهید بچسبانید به نظر می‌رسد از",
+NotCompatiblePaste	: "این فرمان برای مرورگر Internet Explorer از نگارش 5.5 یا بالاتر در دسترس است. آیا می‌خواهید بدون پاک‌سازی، متن را بچسبانید؟",
+UnknownToolbarItem	: "فقرهٴ نوارابزار ناشناخته \"%1\"",
+UnknownCommand		: "نام دستور ناشناخته \"%1\"",
+NotImplemented		: "دستور پیاده‌سازی‌نشده",
+UnknownToolbarSet	: "مجموعهٴ نوارابزار \"%1\" وجود ندارد",
+NoActiveX			: "تنظیمات امنیتی مرورگر شما ممکن است در بعضی از ویژگیهای مرورگر محدودیت ایجاد کند. شما باید گزینهٴ \"Run ActiveX controls and plug-ins\" را فعال کنید. ممکن است شما با خطاهایی روبرو باشید و متوجه کمبود ویژگیهایی شوید.",
+BrowseServerBlocked : "توانایی بازگشایی مرورگر منابع فراهم نیست. اطمینان حاصل کنید که تمامی برنامه‌های پیشگیری از نمایش popup را از کار بازداشته‌اید.",
+DialogBlocked		: "توانایی بازگشایی پنجرهٴ کوچک ِگفتگو فراهم نیست. اطمینان حاصل کنید که تمامی برنامه‌های پیشگیری از نمایش popup را از کار بازداشته‌اید.",
+
+// Dialogs
+DlgBtnOK			: "پذیرش",
+DlgBtnCancel		: "انصراف",
+DlgBtnClose			: "بستن",
+DlgBtnBrowseServer	: "فهرست‌نمایی سرور",
+DlgAdvancedTag		: "پیشرفته",
+DlgOpOther			: "<غیره>",
+DlgInfoTab			: "اطلاعات",
+DlgAlertUrl			: "لطفاً URL را بنویسید",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<تعین‌نشده>",
+DlgGenId			: "شناسه",
+DlgGenLangDir		: "جهت‌نمای زبان",
+DlgGenLangDirLtr	: "چپ به راست (LTR)",
+DlgGenLangDirRtl	: "راست به چپ (RTL)",
+DlgGenLangCode		: "کد زبان",
+DlgGenAccessKey		: "کلید دستیابی",
+DlgGenName			: "نام",
+DlgGenTabIndex		: "نمایهٴ دسترسی با Tab",
+DlgGenLongDescr		: "URL توصیف طولانی",
+DlgGenClass			: "کلاسهای شیوه‌نامه(Stylesheet)",
+DlgGenTitle			: "عنوان کمکی",
+DlgGenContType		: "نوع محتوای کمکی",
+DlgGenLinkCharset	: "نویسه‌گان منبع ِپیوندشده",
+DlgGenStyle			: "شیوه(style)",
+
+// Image Dialog
+DlgImgTitle			: "ویژگیهای تصویر",
+DlgImgInfoTab		: "اطلاعات تصویر",
+DlgImgBtnUpload		: "به سرور بفرست",
+DlgImgURL			: "URL",
+DlgImgUpload		: "انتقال به سرور",
+DlgImgAlt			: "متن جایگزین",
+DlgImgWidth			: "پهنا",
+DlgImgHeight		: "درازا",
+DlgImgLockRatio		: "قفل‌کردن ِنسبت",
+DlgBtnResetSize		: "بازنشانی اندازه",
+DlgImgBorder		: "لبه",
+DlgImgHSpace		: "فاصلهٴ افقی",
+DlgImgVSpace		: "فاصلهٴ عمودی",
+DlgImgAlign			: "چینش",
+DlgImgAlignLeft		: "چپ",
+DlgImgAlignAbsBottom: "پائین مطلق",
+DlgImgAlignAbsMiddle: "وسط مطلق",
+DlgImgAlignBaseline	: "خط‌پایه",
+DlgImgAlignBottom	: "پائین",
+DlgImgAlignMiddle	: "وسط",
+DlgImgAlignRight	: "راست",
+DlgImgAlignTextTop	: "متن بالا",
+DlgImgAlignTop		: "بالا",
+DlgImgPreview		: "پیش‌نمایش",
+DlgImgAlertUrl		: "لطفا URL تصویر را بنویسید",
+DlgImgLinkTab		: "پیوند",
+
+// Flash Dialog
+DlgFlashTitle		: "ویژگیهای Flash",
+DlgFlashChkPlay		: "آغاز ِخودکار",
+DlgFlashChkLoop		: "اجرای پیاپی",
+DlgFlashChkMenu		: "دردسترس‌بودن منوی Flash",
+DlgFlashScale		: "مقیاس",
+DlgFlashScaleAll	: "نمایش همه",
+DlgFlashScaleNoBorder	: "بدون کران",
+DlgFlashScaleFit	: "جایگیری کامل",
+
+// Link Dialog
+DlgLnkWindowTitle	: "پیوند",
+DlgLnkInfoTab		: "اطلاعات پیوند",
+DlgLnkTargetTab		: "مقصد",
+
+DlgLnkType			: "نوع پیوند",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "لنگر در همین صفحه",
+DlgLnkTypeEMail		: "پست الکترونیکی",
+DlgLnkProto			: "پروتکل",
+DlgLnkProtoOther	: "<دیگر>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "یک لنگر برگزینید",
+DlgLnkAnchorByName	: "با نام لنگر",
+DlgLnkAnchorById	: "با شناسهٴ المان",
+DlgLnkNoAnchors		: "<در این سند لنگری دردسترس نیست>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "نشانی پست الکترونیکی",
+DlgLnkEMailSubject	: "موضوع پیام",
+DlgLnkEMailBody		: "متن پیام",
+DlgLnkUpload		: "انتقال به سرور",
+DlgLnkBtnUpload		: "به سرور بفرست",
+
+DlgLnkTarget		: "مقصد",
+DlgLnkTargetFrame	: "<فریم>",
+DlgLnkTargetPopup	: "<پنجرهٴ پاپاپ>",
+DlgLnkTargetBlank	: "پنجرهٴ دیگر (_blank)",
+DlgLnkTargetParent	: "پنجرهٴ والد (_parent)",
+DlgLnkTargetSelf	: "همان پنجره (_self)",
+DlgLnkTargetTop		: "بالاترین پنجره (_top)",
+DlgLnkTargetFrameName	: "نام فریم مقصد",
+DlgLnkPopWinName	: "نام پنجرهٴ پاپاپ",
+DlgLnkPopWinFeat	: "ویژگیهای پنجرهٴ پاپاپ",
+DlgLnkPopResize		: "قابل تغیر اندازه",
+DlgLnkPopLocation	: "نوار موقعیت",
+DlgLnkPopMenu		: "نوار منو",
+DlgLnkPopScroll		: "میله‌های پیمایش",
+DlgLnkPopStatus		: "نوار وضعیت",
+DlgLnkPopToolbar	: "نوارابزار",
+DlgLnkPopFullScrn	: "تمام‌صفحه (IE)",
+DlgLnkPopDependent	: "وابسته (Netscape)",
+DlgLnkPopWidth		: "پهنا",
+DlgLnkPopHeight		: "درازا",
+DlgLnkPopLeft		: "موقعیت ِچپ",
+DlgLnkPopTop		: "موقعیت ِبالا",
+
+DlnLnkMsgNoUrl		: "لطفا URL پیوند را بنویسید",
+DlnLnkMsgNoEMail	: "لطفا نشانی پست الکترونیکی را بنویسید",
+DlnLnkMsgNoAnchor	: "لطفا لنگری را برگزینید",
+DlnLnkMsgInvPopName	: "نام پنجرهٴ پاپاپ باید با یک نویسهٴ الفبایی آغاز گردد و نباید فاصله‌های خالی در آن باشند",
+
+// Color Dialog
+DlgColorTitle		: "گزینش رنگ",
+DlgColorBtnClear	: "پاک‌کردن",
+DlgColorHighlight	: "نمونه",
+DlgColorSelected	: "برگزیده",
+
+// Smiley Dialog
+DlgSmileyTitle		: "گنجاندن خندانک",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "گزینش نویسهٴ‌ویژه",
+
+// Table Dialog
+DlgTableTitle		: "ویژگیهای جدول",
+DlgTableRows		: "سطرها",
+DlgTableColumns		: "ستونها",
+DlgTableBorder		: "اندازهٴ لبه",
+DlgTableAlign		: "چینش",
+DlgTableAlignNotSet	: "<تعین‌نشده>",
+DlgTableAlignLeft	: "چپ",
+DlgTableAlignCenter	: "وسط",
+DlgTableAlignRight	: "راست",
+DlgTableWidth		: "پهنا",
+DlgTableWidthPx		: "پیکسل",
+DlgTableWidthPc		: "درصد",
+DlgTableHeight		: "درازا",
+DlgTableCellSpace	: "فاصلهٴ میان سلولها",
+DlgTableCellPad		: "فاصلهٴ پرشده در سلول",
+DlgTableCaption		: "عنوان",
+DlgTableSummary		: "خلاصه",
+
+// Table Cell Dialog
+DlgCellTitle		: "ویژگیهای سلول",
+DlgCellWidth		: "پهنا",
+DlgCellWidthPx		: "پیکسل",
+DlgCellWidthPc		: "درصد",
+DlgCellHeight		: "درازا",
+DlgCellWordWrap		: "شکستن واژه‌ها",
+DlgCellWordWrapNotSet	: "<تعین‌نشده>",
+DlgCellWordWrapYes	: "بله",
+DlgCellWordWrapNo	: "خیر",
+DlgCellHorAlign		: "چینش ِافقی",
+DlgCellHorAlignNotSet	: "<تعین‌نشده>",
+DlgCellHorAlignLeft	: "چپ",
+DlgCellHorAlignCenter	: "وسط",
+DlgCellHorAlignRight: "راست",
+DlgCellVerAlign		: "چینش ِعمودی",
+DlgCellVerAlignNotSet	: "<تعین‌نشده>",
+DlgCellVerAlignTop	: "بالا",
+DlgCellVerAlignMiddle	: "میان",
+DlgCellVerAlignBottom	: "پائین",
+DlgCellVerAlignBaseline	: "خط‌پایه",
+DlgCellRowSpan		: "گستردگی سطرها",
+DlgCellCollSpan		: "گستردگی ستونها",
+DlgCellBackColor	: "رنگ پس‌زمینه",
+DlgCellBorderColor	: "رنگ لبه",
+DlgCellBtnSelect	: "برگزینید...",
+
+// Find Dialog
+DlgFindTitle		: "یافتن",
+DlgFindFindBtn		: "یافتن",
+DlgFindNotFoundMsg	: "متن موردنظر یافت نشد.",
+
+// Replace Dialog
+DlgReplaceTitle			: "جایگزینی",
+DlgReplaceFindLbl		: "چه‌چیز را می‌یابید:",
+DlgReplaceReplaceLbl	: "جایگزینی با:",
+DlgReplaceCaseChk		: "همسانی در بزرگی و کوچکی نویسه‌ها",
+DlgReplaceReplaceBtn	: "جایگزینی",
+DlgReplaceReplAllBtn	: "جایگزینی همهٴ یافته‌ها",
+DlgReplaceWordChk		: "همسانی با واژهٴ کامل",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "تنظیمات امنیتی مرورگر شما اجازه نمی‌دهد که ویرایشگر به طور خودکار عملکردهای برش را انجام دهد. لطفا با دکمه‌های صفحه‌کلید این کار را انجام دهید (Ctrl+X).",
+PasteErrorCopy	: "تنظیمات امنیتی مرورگر شما اجازه نمی‌دهد که ویرایشگر به طور خودکار عملکردهای کپی‌کردن را انجام دهد. لطفا با دکمه‌های صفحه‌کلید این کار را انجام دهید (Ctrl+C).",
+
+PasteAsText		: "چسباندن به عنوان متن ِساده",
+PasteFromWord	: "چسباندن از Word",
+
+DlgPasteMsg2	: "لطفا متن را با کلیدهای (<STRONG>Ctrl+V</STRONG>) در این جعبهٴ متنی بچسبانید و <STRONG>پذیرش</STRONG> را بزنید.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "چشم‌پوشی از تعاریف نوع قلم",
+DlgPasteRemoveStyles	: "چشم‌پوشی از تعاریف سبک (style)",
+DlgPasteCleanBox		: "پاک‌کردن ناحیه",
+
+// Color Picker
+ColorAutomatic	: "خودکار",
+ColorMoreColors	: "رنگهای بیشتر...",
+
+// Document Properties
+DocProps		: "ویژگیهای سند",
+
+// Anchor Dialog
+DlgAnchorTitle		: "ویژگیهای لنگر",
+DlgAnchorName		: "نام لنگر",
+DlgAnchorErrorName	: "لطفا نام لنگر را بنویسید",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "در واژه‌نامه موجود نیست",
+DlgSpellChangeTo		: "تغیر به",
+DlgSpellBtnIgnore		: "چشم‌پوشی",
+DlgSpellBtnIgnoreAll	: "چشم‌پوشی همه",
+DlgSpellBtnReplace		: "جایگزینی",
+DlgSpellBtnReplaceAll	: "جایگزینی همه",
+DlgSpellBtnUndo			: "واچینش",
+DlgSpellNoSuggestions	: "- پیشنهادی نیست -",
+DlgSpellProgress		: "بررسی املا در حال انجام...",
+DlgSpellNoMispell		: "بررسی املا انجام شد. هیچ غلط‌املائی یافت نشد",
+DlgSpellNoChanges		: "بررسی املا انجام شد. هیچ واژه‌ای تغیر نیافت",
+DlgSpellOneChange		: "بررسی املا انجام شد. یک واژه تغیر یافت",
+DlgSpellManyChanges		: "بررسی املا انجام شد. %1 واژه تغیر یافت",
+
+IeSpellDownload			: "بررسی‌کنندهٴ املا نصب نشده است. آیا می‌خواهید آن را هم‌اکنون دریافت کنید؟",
+
+// Button Dialog
+DlgButtonText		: "متن (مقدار)",
+DlgButtonType		: "نوع",
+DlgButtonTypeBtn	: "دکمه",
+DlgButtonTypeSbm	: "Submit",
+DlgButtonTypeRst	: "بازنشانی (Reset)",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "نام",
+DlgCheckboxValue	: "مقدار",
+DlgCheckboxSelected	: "برگزیده",
+
+// Form Dialog
+DlgFormName		: "نام",
+DlgFormAction	: "اقدام",
+DlgFormMethod	: "متد",
+
+// Select Field Dialog
+DlgSelectName		: "نام",
+DlgSelectValue		: "مقدار",
+DlgSelectSize		: "اندازه",
+DlgSelectLines		: "خطوط",
+DlgSelectChkMulti	: "گزینش چندگانه فراهم باشد",
+DlgSelectOpAvail	: "گزینه‌های موجود",
+DlgSelectOpText		: "متن",
+DlgSelectOpValue	: "مقدار",
+DlgSelectBtnAdd		: "اضافه",
+DlgSelectBtnModify	: "ویرایش",
+DlgSelectBtnUp		: "بالا",
+DlgSelectBtnDown	: "پائین",
+DlgSelectBtnSetValue : "تنظیم به عنوان مقدار ِبرگزیده",
+DlgSelectBtnDelete	: "حذف",
+
+// Textarea Dialog
+DlgTextareaName	: "نام",
+DlgTextareaCols	: "ستونها",
+DlgTextareaRows	: "سطرها",
+
+// Text Field Dialog
+DlgTextName			: "نام",
+DlgTextValue		: "مقدار",
+DlgTextCharWidth	: "پهنای نویسه",
+DlgTextMaxChars		: "بیشینهٴ نویسه‌ها",
+DlgTextType			: "نوع",
+DlgTextTypeText		: "متن",
+DlgTextTypePass		: "گذرواژه",
+
+// Hidden Field Dialog
+DlgHiddenName	: "نام",
+DlgHiddenValue	: "مقدار",
+
+// Bulleted List Dialog
+BulletedListProp	: "ویژگیهای فهرست نقطه‌ای",
+NumberedListProp	: "ویژگیهای فهرست شماره‌دار",
+DlgLstStart			: "آغاز",
+DlgLstType			: "نوع",
+DlgLstTypeCircle	: "دایره",
+DlgLstTypeDisc		: "قرص",
+DlgLstTypeSquare	: "چهارگوش",
+DlgLstTypeNumbers	: "شماره‌ها (1، 2، 3)",
+DlgLstTypeLCase		: "نویسه‌های کوچک (a، b، c)",
+DlgLstTypeUCase		: "نویسه‌های بزرگ (A، B، C)",
+DlgLstTypeSRoman	: "شمارگان رومی کوچک (i، ii، iii)",
+DlgLstTypeLRoman	: "شمارگان رومی بزرگ (I، II، III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "عمومی",
+DlgDocBackTab		: "پس‌زمینه",
+DlgDocColorsTab		: "رنگها و حاشیه‌ها",
+DlgDocMetaTab		: "فراداده",
+
+DlgDocPageTitle		: "عنوان صفحه",
+DlgDocLangDir		: "جهت زبان",
+DlgDocLangDirLTR	: "چپ به راست (LTR(",
+DlgDocLangDirRTL	: "راست به چپ (RTL(",
+DlgDocLangCode		: "کد زبان",
+DlgDocCharSet		: "رمزگذاری نویسه‌گان",
+DlgDocCharSetCE		: "اروپای مرکزی",
+DlgDocCharSetCT		: "چینی رسمی (Big5)",
+DlgDocCharSetCR		: "سیریلیک",
+DlgDocCharSetGR		: "یونانی",
+DlgDocCharSetJP		: "ژاپنی",
+DlgDocCharSetKR		: "کره‌ای",
+DlgDocCharSetTR		: "ترکی",
+DlgDocCharSetUN		: "یونیکُد (UTF-8)",
+DlgDocCharSetWE		: "اروپای غربی",
+DlgDocCharSetOther	: "رمزگذاری نویسه‌گان دیگر",
+
+DlgDocDocType		: "عنوان نوع سند",
+DlgDocDocTypeOther	: "عنوان نوع سند دیگر",
+DlgDocIncXHTML		: "شامل تعاریف XHTML",
+DlgDocBgColor		: "رنگ پس‌زمینه",
+DlgDocBgImage		: "URL تصویر پس‌زمینه",
+DlgDocBgNoScroll	: "پس‌زمینهٴ پیمایش‌ناپذیر",
+DlgDocCText			: "متن",
+DlgDocCLink			: "پیوند",
+DlgDocCVisited		: "پیوند مشاهده‌شده",
+DlgDocCActive		: "پیوند فعال",
+DlgDocMargins		: "حاشیه‌های صفحه",
+DlgDocMaTop			: "بالا",
+DlgDocMaLeft		: "چپ",
+DlgDocMaRight		: "راست",
+DlgDocMaBottom		: "پایین",
+DlgDocMeIndex		: "کلیدواژگان نمایه‌گذاری سند (با کاما جدا شوند)",
+DlgDocMeDescr		: "توصیف سند",
+DlgDocMeAuthor		: "نویسنده",
+DlgDocMeCopy		: "کپی‌رایت",
+DlgDocPreview		: "پیش‌نمایش",
+
+// Templates Dialog
+Templates			: "الگوها",
+DlgTemplatesTitle	: "الگوهای محتویات",
+DlgTemplatesSelMsg	: "لطفا الگوی موردنظر را برای بازکردن در ویرایشگر برگزینید<br>(محتویات کنونی از دست خواهند رفت):",
+DlgTemplatesLoading	: "بارگذاری فهرست الگوها. لطفا صبر کنید...",
+DlgTemplatesNoTpl	: "(الگوئی تعریف نشده است)",
+DlgTemplatesReplace	: "محتویات کنونی جایگزین شوند",
+
+// About Dialog
+DlgAboutAboutTab	: "درباره",
+DlgAboutBrowserInfoTab	: "اطلاعات مرورگر",
+DlgAboutLicenseTab	: "گواهینامه",
+DlgAboutVersion		: "نگارش",
+DlgAboutInfo		: "برای آگاهی بیشتر به این نشانی بروید"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bg.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bg.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/bg.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Bulgarian language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Скрий панела с инструментите",
+ToolbarExpand		: "Покажи панела с инструментите",
+
+// Toolbar Items and Context Menu
+Save				: "Запази",
+NewPage				: "Нова страница",
+Preview				: "Предварителен изглед",
+Cut					: "Изрежи",
+Copy				: "Запамети",
+Paste				: "Вмъкни",
+PasteText			: "Вмъкни само текст",
+PasteWord			: "Вмъкни от MS Word",
+Print				: "Печат",
+SelectAll			: "Селектирай всичко",
+RemoveFormat		: "Изтрий форматирането",
+InsertLinkLbl		: "Връзка",
+InsertLink			: "Добави/Редактирай връзка",
+RemoveLink			: "Изтрий връзка",
+Anchor				: "Добави/Редактирай котва",
+InsertImageLbl		: "Изображение",
+InsertImage			: "Добави/Редактирай изображение",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Добави/Редактиай Flash обект",
+InsertTableLbl		: "Таблица",
+InsertTable			: "Добави/Редактирай таблица",
+InsertLineLbl		: "Линия",
+InsertLine			: "Вмъкни хоризонтална линия",
+InsertSpecialCharLbl: "Специален символ",
+InsertSpecialChar	: "Вмъкни специален символ",
+InsertSmileyLbl		: "Усмивка",
+InsertSmiley		: "Добави усмивка",
+About				: "За FCKeditor",
+Bold				: "Удебелен",
+Italic				: "Курсив",
+Underline			: "Подчертан",
+StrikeThrough		: "Зачертан",
+Subscript			: "Индекс за база",
+Superscript			: "Индекс за степен",
+LeftJustify			: "Подравняване в ляво",
+CenterJustify		: "Подравнявне в средата",
+RightJustify		: "Подравняване в дясно",
+BlockJustify		: "Двустранно подравняване",
+DecreaseIndent		: "Намали отстъпа",
+IncreaseIndent		: "Увеличи отстъпа",
+Undo				: "Отмени",
+Redo				: "Повтори",
+NumberedListLbl		: "Нумериран списък",
+NumberedList		: "Добави/Изтрий нумериран списък",
+BulletedListLbl		: "Ненумериран списък",
+BulletedList		: "Добави/Изтрий ненумериран списък",
+ShowTableBorders	: "Покажи рамките на таблицата",
+ShowDetails			: "Покажи подробности",
+Style				: "Стил",
+FontFormat			: "Формат",
+Font				: "Шрифт",
+FontSize			: "Размер",
+TextColor			: "Цвят на текста",
+BGColor				: "Цвят на фона",
+Source				: "Код",
+Find				: "Търси",
+Replace				: "Замести",
+SpellCheck			: "Провери правописа",
+UniversalKeyboard	: "Универсална клавиатура",
+PageBreakLbl		: "Нов ред",
+PageBreak			: "Вмъкни нов ред",
+
+Form			: "Формуляр",
+Checkbox		: "Поле за отметка",
+RadioButton		: "Поле за опция",
+TextField		: "Текстово поле",
+Textarea		: "Текстова област",
+HiddenField		: "Скрито поле",
+Button			: "Бутон",
+SelectionField	: "Падащо меню с опции",
+ImageButton		: "Бутон-изображение",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Редактирай връзка",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Добави ред",
+DeleteRows			: "Изтрий редовете",
+InsertColumn		: "Добави колона",
+DeleteColumns		: "Изтрий колоните",
+InsertCell			: "Добави клетка",
+DeleteCells			: "Изтрий клетките",
+MergeCells			: "Обедини клетките",
+SplitCell			: "Раздели клетката",
+TableDelete			: "Изтрий таблицата",
+CellProperties		: "Параметри на клетката",
+TableProperties		: "Параметри на таблицата",
+ImageProperties		: "Параметри на изображението",
+FlashProperties		: "Параметри на Flash обекта",
+
+AnchorProp			: "Параметри на котвата",
+ButtonProp			: "Параметри на бутона",
+CheckboxProp		: "Параметри на полето за отметка",
+HiddenFieldProp		: "Параметри на скритото поле",
+RadioButtonProp		: "Параметри на полето за опция",
+ImageButtonProp		: "Параметри на бутона-изображение",
+TextFieldProp		: "Параметри на текстовото-поле",
+SelectionFieldProp	: "Параметри на падащото меню с опции",
+TextareaProp		: "Параметри на текстовата област",
+FormProp			: "Параметри на формуляра",
+
+FontFormats			: "Нормален;Форматиран;Адрес;Заглавие 1;Заглавие 2;Заглавие 3;Заглавие 4;Заглавие 5;Заглавие 6;Параграф (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Обработка на XHTML. Моля изчакайте...",
+Done				: "Готово",
+PasteWordConfirm	: "Текстът, който искате да вмъкнете е копиран от MS Word. Желаете ли да бъде изчистен преди вмъкването?",
+NotCompatiblePaste	: "Тази операция изисква MS Internet Explorer версия 5.5 или по-висока. Желаете ли да вмъкнете запаметеното без изчистване?",
+UnknownToolbarItem	: "Непознат инструмент \"%1\"",
+UnknownCommand		: "Непозната команда \"%1\"",
+NotImplemented		: "Командата не е имплементирана",
+UnknownToolbarSet	: "Панелът \"%1\" не съществува",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "ОК",
+DlgBtnCancel		: "Отказ",
+DlgBtnClose			: "Затвори",
+DlgBtnBrowseServer	: "Разгледай сървъра",
+DlgAdvancedTag		: "Подробности...",
+DlgOpOther			: "<Друго>",
+DlgInfoTab			: "Информация",
+DlgAlertUrl			: "Моля, въведете пълния път (URL)",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<не е настроен>",
+DlgGenId			: "Идентификатор",
+DlgGenLangDir		: "посока на речта",
+DlgGenLangDirLtr	: "От ляво на дясно",
+DlgGenLangDirRtl	: "От дясно на ляво",
+DlgGenLangCode		: "Код на езика",
+DlgGenAccessKey		: "Бърз клавиш",
+DlgGenName			: "Име",
+DlgGenTabIndex		: "Ред на достъп",
+DlgGenLongDescr		: "Описание на връзката",
+DlgGenClass			: "Клас от стиловите таблици",
+DlgGenTitle			: "Препоръчително заглавие",
+DlgGenContType		: "Препоръчителен тип на съдържанието",
+DlgGenLinkCharset	: "Тип на свързания ресурс",
+DlgGenStyle			: "Стил",
+
+// Image Dialog
+DlgImgTitle			: "Параметри на изображението",
+DlgImgInfoTab		: "Информация за изображението",
+DlgImgBtnUpload		: "Прати към сървъра",
+DlgImgURL			: "Пълен път (URL)",
+DlgImgUpload		: "Качи",
+DlgImgAlt			: "Алтернативен текст",
+DlgImgWidth			: "Ширина",
+DlgImgHeight		: "Височина",
+DlgImgLockRatio		: "Запази пропорцията",
+DlgBtnResetSize		: "Възстанови размера",
+DlgImgBorder		: "Рамка",
+DlgImgHSpace		: "Хоризонтален отстъп",
+DlgImgVSpace		: "Вертикален отстъп",
+DlgImgAlign			: "Подравняване",
+DlgImgAlignLeft		: "Ляво",
+DlgImgAlignAbsBottom: "Най-долу",
+DlgImgAlignAbsMiddle: "Точно по средата",
+DlgImgAlignBaseline	: "По базовата линия",
+DlgImgAlignBottom	: "Долу",
+DlgImgAlignMiddle	: "По средата",
+DlgImgAlignRight	: "Дясно",
+DlgImgAlignTextTop	: "Върху текста",
+DlgImgAlignTop		: "Отгоре",
+DlgImgPreview		: "Изглед",
+DlgImgAlertUrl		: "Моля, въведете пълния път до изображението",
+DlgImgLinkTab		: "Връзка",
+
+// Flash Dialog
+DlgFlashTitle		: "Параметри на Flash обекта",
+DlgFlashChkPlay		: "Автоматично стартиране",
+DlgFlashChkLoop		: "Ново стартиране след завършването",
+DlgFlashChkMenu		: "Разрешено Flash меню",
+DlgFlashScale		: "Оразмеряване",
+DlgFlashScaleAll	: "Покажи целия обект",
+DlgFlashScaleNoBorder	: "Без рамка",
+DlgFlashScaleFit	: "Според мястото",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Връзка",
+DlgLnkInfoTab		: "Информация за връзката",
+DlgLnkTargetTab		: "Цел",
+
+DlgLnkType			: "Вид на връзката",
+DlgLnkTypeURL		: "Пълен път (URL)",
+DlgLnkTypeAnchor	: "Котва в текущата страница",
+DlgLnkTypeEMail		: "Е-поща",
+DlgLnkProto			: "Протокол",
+DlgLnkProtoOther	: "<друго>",
+DlgLnkURL			: "Пълен път (URL)",
+DlgLnkAnchorSel		: "Изберете котва",
+DlgLnkAnchorByName	: "По име на котвата",
+DlgLnkAnchorById	: "По идентификатор на елемент",
+DlgLnkNoAnchors		: "<Няма котви в текущия документ>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Адрес за е-поща",
+DlgLnkEMailSubject	: "Тема на писмото",
+DlgLnkEMailBody		: "Текст на писмото",
+DlgLnkUpload		: "Качи",
+DlgLnkBtnUpload		: "Прати на сървъра",
+
+DlgLnkTarget		: "Цел",
+DlgLnkTargetFrame	: "<рамка>",
+DlgLnkTargetPopup	: "<дъщерен прозорец>",
+DlgLnkTargetBlank	: "Нов прозорец (_blank)",
+DlgLnkTargetParent	: "Родителски прозорец (_parent)",
+DlgLnkTargetSelf	: "Активния прозорец (_self)",
+DlgLnkTargetTop		: "Целия прозорец (_top)",
+DlgLnkTargetFrameName	: "Име на целевия прозорец",
+DlgLnkPopWinName	: "Име на дъщерния прозорец",
+DlgLnkPopWinFeat	: "Параметри на дъщерния прозорец",
+DlgLnkPopResize		: "С променливи размери",
+DlgLnkPopLocation	: "Поле за адрес",
+DlgLnkPopMenu		: "Меню",
+DlgLnkPopScroll		: "Плъзгач",
+DlgLnkPopStatus		: "Поле за статус",
+DlgLnkPopToolbar	: "Панел с бутони",
+DlgLnkPopFullScrn	: "Голям екран (MS IE)",
+DlgLnkPopDependent	: "Зависим (Netscape)",
+DlgLnkPopWidth		: "Ширина",
+DlgLnkPopHeight		: "Височина",
+DlgLnkPopLeft		: "Координати - X",
+DlgLnkPopTop		: "Координати - Y",
+
+DlnLnkMsgNoUrl		: "Моля, напишете пълния път (URL)",
+DlnLnkMsgNoEMail	: "Моля, напишете адреса за е-поща",
+DlnLnkMsgNoAnchor	: "Моля, изберете котва",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Изберете цвят",
+DlgColorBtnClear	: "Изчисти",
+DlgColorHighlight	: "Текущ",
+DlgColorSelected	: "Избран",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Добави усмивка",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Изберете специален символ",
+
+// Table Dialog
+DlgTableTitle		: "Параметри на таблицата",
+DlgTableRows		: "Редове",
+DlgTableColumns		: "Колони",
+DlgTableBorder		: "Размер на рамката",
+DlgTableAlign		: "Подравняване",
+DlgTableAlignNotSet	: "<Не е избрано>",
+DlgTableAlignLeft	: "Ляво",
+DlgTableAlignCenter	: "Център",
+DlgTableAlignRight	: "Дясно",
+DlgTableWidth		: "Ширина",
+DlgTableWidthPx		: "пиксели",
+DlgTableWidthPc		: "проценти",
+DlgTableHeight		: "Височина",
+DlgTableCellSpace	: "Разстояние между клетките",
+DlgTableCellPad		: "Отстъп на съдържанието в клетките",
+DlgTableCaption		: "Заглавие",
+DlgTableSummary		: "Резюме",
+
+// Table Cell Dialog
+DlgCellTitle		: "Параметри на клетката",
+DlgCellWidth		: "Ширина",
+DlgCellWidthPx		: "пиксели",
+DlgCellWidthPc		: "проценти",
+DlgCellHeight		: "Височина",
+DlgCellWordWrap		: "пренасяне на нов ред",
+DlgCellWordWrapNotSet	: "<Не е настроено>",
+DlgCellWordWrapYes	: "Да",
+DlgCellWordWrapNo	: "не",
+DlgCellHorAlign		: "Хоризонтално подравняване",
+DlgCellHorAlignNotSet	: "<Не е настроено>",
+DlgCellHorAlignLeft	: "Ляво",
+DlgCellHorAlignCenter	: "Център",
+DlgCellHorAlignRight: "Дясно",
+DlgCellVerAlign		: "Вертикално подравняване",
+DlgCellVerAlignNotSet	: "<Не е настроено>",
+DlgCellVerAlignTop	: "Горе",
+DlgCellVerAlignMiddle	: "По средата",
+DlgCellVerAlignBottom	: "Долу",
+DlgCellVerAlignBaseline	: "По базовата линия",
+DlgCellRowSpan		: "повече от един ред",
+DlgCellCollSpan		: "повече от една колона",
+DlgCellBackColor	: "фонов цвят",
+DlgCellBorderColor	: "цвят на рамката",
+DlgCellBtnSelect	: "Изберете...",
+
+// Find Dialog
+DlgFindTitle		: "Търси",
+DlgFindFindBtn		: "Търси",
+DlgFindNotFoundMsg	: "Указания текст не беше намерен.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Замести",
+DlgReplaceFindLbl		: "Търси:",
+DlgReplaceReplaceLbl	: "Замести с:",
+DlgReplaceCaseChk		: "Със същия регистър",
+DlgReplaceReplaceBtn	: "Замести",
+DlgReplaceReplAllBtn	: "Замести всички",
+DlgReplaceWordChk		: "Търси същата дума",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Настройките за сигурност на вашия бразуър не разрешават на редактора да изпълни изрязването. За целта използвайте клавиатурата (Ctrl+X).",
+PasteErrorCopy	: "Настройките за сигурност на вашия бразуър не разрешават на редактора да изпълни запаметяването. За целта използвайте клавиатурата (Ctrl+C).",
+
+PasteAsText		: "Вмъкни като чист текст",
+PasteFromWord	: "Вмъкни от MS Word",
+
+DlgPasteMsg2	: "Вмъкнете тук съдъжанието с клавиатуарата (<STRONG>Ctrl+V</STRONG>) и натиснете <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Игнорирай шрифтовите дефиниции",
+DlgPasteRemoveStyles	: "Изтрий стиловите дефиниции",
+DlgPasteCleanBox		: "Изчисти",
+
+// Color Picker
+ColorAutomatic	: "По подразбиране",
+ColorMoreColors	: "Други цветове...",
+
+// Document Properties
+DocProps		: "Параметри на документа",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Параметри на котвата",
+DlgAnchorName		: "Име на котвата",
+DlgAnchorErrorName	: "Моля, въведете име на котвата",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Липсва в речника",
+DlgSpellChangeTo		: "Промени на",
+DlgSpellBtnIgnore		: "Игнорирай",
+DlgSpellBtnIgnoreAll	: "Игнорирай всички",
+DlgSpellBtnReplace		: "Замести",
+DlgSpellBtnReplaceAll	: "Замести всички",
+DlgSpellBtnUndo			: "Отмени",
+DlgSpellNoSuggestions	: "- Няма предложения -",
+DlgSpellProgress		: "Извършване на проверката за правопис...",
+DlgSpellNoMispell		: "Проверката за правопис завършена: не са открити правописни грешки",
+DlgSpellNoChanges		: "Проверката за правопис завършена: няма променени думи",
+DlgSpellOneChange		: "Проверката за правопис завършена: една дума е променена",
+DlgSpellManyChanges		: "Проверката за правопис завършена: %1 думи са променени",
+
+IeSpellDownload			: "Инструментът за проверка на правопис не е инсталиран. Желаете ли да го инсталирате ?",
+
+// Button Dialog
+DlgButtonText		: "Текст (Стойност)",
+DlgButtonType		: "Тип",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Име",
+DlgCheckboxValue	: "Стойност",
+DlgCheckboxSelected	: "Отметнато",
+
+// Form Dialog
+DlgFormName		: "Име",
+DlgFormAction	: "Действие",
+DlgFormMethod	: "Метод",
+
+// Select Field Dialog
+DlgSelectName		: "Име",
+DlgSelectValue		: "Стойност",
+DlgSelectSize		: "Размер",
+DlgSelectLines		: "линии",
+DlgSelectChkMulti	: "Разрешено множествено селектиране",
+DlgSelectOpAvail	: "Възможни опции",
+DlgSelectOpText		: "Текст",
+DlgSelectOpValue	: "Стойност",
+DlgSelectBtnAdd		: "Добави",
+DlgSelectBtnModify	: "Промени",
+DlgSelectBtnUp		: "Нагоре",
+DlgSelectBtnDown	: "Надолу",
+DlgSelectBtnSetValue : "Настрой като избрана стойност",
+DlgSelectBtnDelete	: "Изтрий",
+
+// Textarea Dialog
+DlgTextareaName	: "Име",
+DlgTextareaCols	: "Колони",
+DlgTextareaRows	: "Редове",
+
+// Text Field Dialog
+DlgTextName			: "Име",
+DlgTextValue		: "Стойност",
+DlgTextCharWidth	: "Ширина на символите",
+DlgTextMaxChars		: "Максимум символи",
+DlgTextType			: "Тип",
+DlgTextTypeText		: "Текст",
+DlgTextTypePass		: "Парола",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Име",
+DlgHiddenValue	: "Стойност",
+
+// Bulleted List Dialog
+BulletedListProp	: "Параметри на ненумерирания списък",
+NumberedListProp	: "Параметри на нумерирания списък",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Тип",
+DlgLstTypeCircle	: "Окръжност",
+DlgLstTypeDisc		: "Кръг",
+DlgLstTypeSquare	: "Квадрат",
+DlgLstTypeNumbers	: "Числа (1, 2, 3)",
+DlgLstTypeLCase		: "Малки букви (a, b, c)",
+DlgLstTypeUCase		: "Големи букви (A, B, C)",
+DlgLstTypeSRoman	: "Малки римски числа (i, ii, iii)",
+DlgLstTypeLRoman	: "Големи римски числа (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Общи",
+DlgDocBackTab		: "Фон",
+DlgDocColorsTab		: "Цветове и отстъпи",
+DlgDocMetaTab		: "Мета данни",
+
+DlgDocPageTitle		: "Заглавие на страницата",
+DlgDocLangDir		: "Посока на речта",
+DlgDocLangDirLTR	: "От ляво на дясно",
+DlgDocLangDirRTL	: "От дясно на ляво",
+DlgDocLangCode		: "Код на езика",
+DlgDocCharSet		: "Кодиране на символите",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Друго кодиране на символите",
+
+DlgDocDocType		: "Тип на документа",
+DlgDocDocTypeOther	: "Друг тип на документа",
+DlgDocIncXHTML		: "Включи XHTML декларация",
+DlgDocBgColor		: "Цвят на фона",
+DlgDocBgImage		: "Пълен път до фоновото изображение",
+DlgDocBgNoScroll	: "Не-повтарящо се фоново изображение",
+DlgDocCText			: "Текст",
+DlgDocCLink			: "Връзка",
+DlgDocCVisited		: "Посетена връзка",
+DlgDocCActive		: "Активна връзка",
+DlgDocMargins		: "Отстъпи на страницата",
+DlgDocMaTop			: "Горе",
+DlgDocMaLeft		: "Ляво",
+DlgDocMaRight		: "Дясно",
+DlgDocMaBottom		: "Долу",
+DlgDocMeIndex		: "Ключови думи за документа (разделени със запетаи)",
+DlgDocMeDescr		: "Описание на документа",
+DlgDocMeAuthor		: "Автор",
+DlgDocMeCopy		: "Авторски права",
+DlgDocPreview		: "Изглед",
+
+// Templates Dialog
+Templates			: "Шаблони",
+DlgTemplatesTitle	: "Шаблони",
+DlgTemplatesSelMsg	: "Изберете шаблон <br>(текущото съдържание на редактора ще бъде загубено):",
+DlgTemplatesLoading	: "Зареждане на списъка с шаблоните. Моля изчакайте...",
+DlgTemplatesNoTpl	: "(Няма дефинирани шаблони)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "За",
+DlgAboutBrowserInfoTab	: "Информация за браузъра",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "версия",
+DlgAboutInfo		: "За повече информация посетете"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/de.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/de.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/de.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * German language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Symbolleiste einklappen",
+ToolbarExpand		: "Symbolleiste ausklappen",
+
+// Toolbar Items and Context Menu
+Save				: "Speichern",
+NewPage				: "Neue Seite",
+Preview				: "Vorschau",
+Cut					: "Ausschneiden",
+Copy				: "Kopieren",
+Paste				: "Einfügen",
+PasteText			: "aus Textdatei einfügen",
+PasteWord			: "aus MS-Word einfügen",
+Print				: "Drucken",
+SelectAll			: "Alles auswählen",
+RemoveFormat		: "Formatierungen entfernen",
+InsertLinkLbl		: "Link",
+InsertLink			: "Link einfügen/editieren",
+RemoveLink			: "Link entfernen",
+Anchor				: "Anker einfügen/editieren",
+InsertImageLbl		: "Bild",
+InsertImage			: "Bild einfügen/editieren",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Flash einfügen/editieren",
+InsertTableLbl		: "Tabelle",
+InsertTable			: "Tabelle einfügen/editieren",
+InsertLineLbl		: "Linie",
+InsertLine			: "Horizontale Linie einfügen",
+InsertSpecialCharLbl: "Sonderzeichen",
+InsertSpecialChar	: "Sonderzeichen einfügen/editieren",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Smiley einfügen",
+About				: "Über FCKeditor",
+Bold				: "Fett",
+Italic				: "Kursiv",
+Underline			: "Unterstrichen",
+StrikeThrough		: "Durchgestrichen",
+Subscript			: "Tiefgestellt",
+Superscript			: "Hochgestellt",
+LeftJustify			: "Linksbündig",
+CenterJustify		: "Zentriert",
+RightJustify		: "Rechtsbündig",
+BlockJustify		: "Blocksatz",
+DecreaseIndent		: "Einzug verringern",
+IncreaseIndent		: "Einzug erhöhen",
+Undo				: "Rückgängig",
+Redo				: "Wiederherstellen",
+NumberedListLbl		: "Nummerierte Liste",
+NumberedList		: "Nummerierte Liste einfügen/entfernen",
+BulletedListLbl		: "Liste",
+BulletedList		: "Liste einfügen/entfernen",
+ShowTableBorders	: "Zeige Tabellenrahmen",
+ShowDetails			: "Zeige Details",
+Style				: "Stil",
+FontFormat			: "Format",
+Font				: "Schriftart",
+FontSize			: "Größe",
+TextColor			: "Textfarbe",
+BGColor				: "Hintergrundfarbe",
+Source				: "Quellcode",
+Find				: "Finden",
+Replace				: "Ersetzen",
+SpellCheck			: "Rechtschreibprüfung",
+UniversalKeyboard	: "Universal-Tastatur",
+PageBreakLbl		: "Seitenumbruch",
+PageBreak			: "Seitenumbruch einfügen",
+
+Form			: "Formular",
+Checkbox		: "Checkbox",
+RadioButton		: "Radiobutton",
+TextField		: "Textfeld einzeilig",
+Textarea		: "Textfeld mehrzeilig",
+HiddenField		: "verstecktes Feld",
+Button			: "Klickbutton",
+SelectionField	: "Auswahlfeld",
+ImageButton		: "Bildbutton",
+
+FitWindow		: "Editor maximieren",
+
+// Context Menu
+EditLink			: "Link editieren",
+CellCM				: "Zelle",
+RowCM				: "Zeile",
+ColumnCM			: "Spalte",
+InsertRow			: "Zeile einfügen",
+DeleteRows			: "Zeile entfernen",
+InsertColumn		: "Spalte einfügen",
+DeleteColumns		: "Spalte löschen",
+InsertCell			: "Zelle einfügen",
+DeleteCells			: "Zelle löschen",
+MergeCells			: "Zellen vereinen",
+SplitCell			: "Zelle teilen",
+TableDelete			: "Tabelle löschen",
+CellProperties		: "Zellen Eigenschaften",
+TableProperties		: "Tabellen Eigenschaften",
+ImageProperties		: "Bild Eigenschaften",
+FlashProperties		: "Flash Eigenschaften",
+
+AnchorProp			: "Anker Eigenschaften",
+ButtonProp			: "Button Eigenschaften",
+CheckboxProp		: "Checkbox Eigenschaften",
+HiddenFieldProp		: "Verstecktes Feld Eigenschaften",
+RadioButtonProp		: "Optionsfeld Eigenschaften",
+ImageButtonProp		: "Bildbutton Eigenschaften",
+TextFieldProp		: "Textfeld (einzeilig) Eigenschaften",
+SelectionFieldProp	: "Auswahlfeld Eigenschaften",
+TextareaProp		: "Textfeld (mehrzeilig) Eigenschaften",
+FormProp			: "Formular Eigenschaften",
+
+FontFormats			: "Normal;Formatiert;Addresse;Überschrift 1;Überschrift 2;Überschrift 3;Überschrift 4;Überschrift 5;Überschrift 6;Normal (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Bearbeite XHTML. Bitte warten...",
+Done				: "Fertig",
+PasteWordConfirm	: "Der Text, den Sie einfügen möchten, scheint aus MS-Word kopiert zu sein. Möchten Sie ihn zuvor bereinigen lassen?",
+NotCompatiblePaste	: "Diese Funktion steht nur im Internet Explorer ab Version 5.5 zur Verfügung. Möchten Sie den Text unbereinigt einfügen?",
+UnknownToolbarItem	: "Unbekanntes Menüleisten-Objekt \"%1\"",
+UnknownCommand		: "Unbekannter Befehl \"%1\"",
+NotImplemented		: "Befehl nicht implementiert",
+UnknownToolbarSet	: "Menüleiste \"%1\" existiert nicht",
+NoActiveX			: "Die Sicherheitseinstellungen Ihres Browsers beschränken evtl. einige Funktionen des Editors. Aktivieren Sie die Option \"ActiveX-Steuerelemente und Plugins ausführen\" in den Sicherheitseinstellungen, um diese Funktionen nutzen zu können",
+BrowseServerBlocked : "Ein Auswahlfenster konnte nicht geöffnet werden. Stellen Sie sicher, das alle Popup-Blocker ausgeschaltet sind.",
+DialogBlocked		: "Das Dialog-Fenster konnte nicht geöffnet werden. Stellen Sie sicher, das alle Popup-Blocker ausgeschaltet sind.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Abbrechen",
+DlgBtnClose			: "Schließen",
+DlgBtnBrowseServer	: "Server durchsuchen",
+DlgAdvancedTag		: "Erweitert",
+DlgOpOther			: "<andere>",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Bitte tragen Sie die URL ein",
+
+// General Dialogs Labels
+DlgGenNotSet		: "< nichts >",
+DlgGenId			: "ID",
+DlgGenLangDir		: "Schreibrichtung",
+DlgGenLangDirLtr	: "Links nach Rechts (LTR)",
+DlgGenLangDirRtl	: "Rechts nach Links (RTL)",
+DlgGenLangCode		: "Sprachenkürzel",
+DlgGenAccessKey		: "Schlüssel",
+DlgGenName			: "Name",
+DlgGenTabIndex		: "Tab Index",
+DlgGenLongDescr		: "Langform URL",
+DlgGenClass			: "Stylesheet Klasse",
+DlgGenTitle			: "Titel Beschreibung",
+DlgGenContType		: "Content Beschreibung",
+DlgGenLinkCharset	: "Ziel-Zeichensatz",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Bild Eigenschaften",
+DlgImgInfoTab		: "Bild-Info",
+DlgImgBtnUpload		: "Zum Server senden",
+DlgImgURL			: "Bildauswahl",
+DlgImgUpload		: "Upload",
+DlgImgAlt			: "Alternativer Text",
+DlgImgWidth			: "Breite",
+DlgImgHeight		: "Höhe",
+DlgImgLockRatio		: "Größenverhältniss beibehalten",
+DlgBtnResetSize		: "Größe zurücksetzen",
+DlgImgBorder		: "Rahmen",
+DlgImgHSpace		: "H-Abstand",
+DlgImgVSpace		: "V-Abstand",
+DlgImgAlign			: "Ausrichtung",
+DlgImgAlignLeft		: "Links",
+DlgImgAlignAbsBottom: "Abs Unten",
+DlgImgAlignAbsMiddle: "Abs Mitte",
+DlgImgAlignBaseline	: "Baseline",
+DlgImgAlignBottom	: "Unten",
+DlgImgAlignMiddle	: "Mitte",
+DlgImgAlignRight	: "Rechts",
+DlgImgAlignTextTop	: "Text Oben",
+DlgImgAlignTop		: "Oben",
+DlgImgPreview		: "Vorschau",
+DlgImgAlertUrl		: "Bitte geben Sie die Bild-URL an",
+DlgImgLinkTab		: "Link",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Eigenschaften",
+DlgFlashChkPlay		: "autom. Abspielen",
+DlgFlashChkLoop		: "Endlosschleife",
+DlgFlashChkMenu		: "Flash-Menü aktivieren",
+DlgFlashScale		: "Skalierung",
+DlgFlashScaleAll	: "Alles anzeigen",
+DlgFlashScaleNoBorder	: "ohne Rand",
+DlgFlashScaleFit	: "Passgenau",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Link",
+DlgLnkInfoTab		: "Link Info",
+DlgLnkTargetTab		: "Zielseite",
+
+DlgLnkType			: "Link-Typ",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Anker in dieser Seite",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<anderes>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Anker auswählen",
+DlgLnkAnchorByName	: "nach Anker Name",
+DlgLnkAnchorById	: "nach Element Id",
+DlgLnkNoAnchors		: "<keine Anker im Dokument vorhanden>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail Addresse",
+DlgLnkEMailSubject	: "Betreffzeile",
+DlgLnkEMailBody		: "Nachrichtentext",
+DlgLnkUpload		: "Upload",
+DlgLnkBtnUpload		: "Zum Server senden",
+
+DlgLnkTarget		: "Zielseite",
+DlgLnkTargetFrame	: "<Frame>",
+DlgLnkTargetPopup	: "<Pop-up Fenster>",
+DlgLnkTargetBlank	: "Neues Fenster (_blank)",
+DlgLnkTargetParent	: "Oberes Fenster (_parent)",
+DlgLnkTargetSelf	: "Gleiches Fenster (_self)",
+DlgLnkTargetTop		: "Oberstes Fenster (_top)",
+DlgLnkTargetFrameName	: "Ziel-Fenster Name",
+DlgLnkPopWinName	: "Pop-up Fenster Name",
+DlgLnkPopWinFeat	: "Pop-up Fenster Eigenschaften",
+DlgLnkPopResize		: "Vergrößerbar",
+DlgLnkPopLocation	: "Adress-Leiste",
+DlgLnkPopMenu		: "Menü-Leiste",
+DlgLnkPopScroll		: "Rollbalken",
+DlgLnkPopStatus		: "Statusleiste",
+DlgLnkPopToolbar	: "Werkzeugleiste",
+DlgLnkPopFullScrn	: "Vollbild (IE)",
+DlgLnkPopDependent	: "Abhängig (Netscape)",
+DlgLnkPopWidth		: "Breite",
+DlgLnkPopHeight		: "Höhe",
+DlgLnkPopLeft		: "Linke Position",
+DlgLnkPopTop		: "Obere Position",
+
+DlnLnkMsgNoUrl		: "Bitte geben Sie die Link-URL an",
+DlnLnkMsgNoEMail	: "Bitte geben Sie e-Mail Adresse an",
+DlnLnkMsgNoAnchor	: "Bitte wählen Sie einen Anker aus",
+DlnLnkMsgInvPopName	: "Der Name des Popups muss mit einem Buchstaben beginnen und darf keine Leerzeichen enthalten",
+
+// Color Dialog
+DlgColorTitle		: "Farbauswahl",
+DlgColorBtnClear	: "Keine Farbe",
+DlgColorHighlight	: "Vorschau",
+DlgColorSelected	: "Ausgewählt",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Smiley auswählen",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Sonderzeichen auswählen",
+
+// Table Dialog
+DlgTableTitle		: "Tabellen Eigenschaften",
+DlgTableRows		: "Zeile",
+DlgTableColumns		: "Spalte",
+DlgTableBorder		: "Rahmen",
+DlgTableAlign		: "Ausrichtung",
+DlgTableAlignNotSet	: "<nichts>",
+DlgTableAlignLeft	: "Links",
+DlgTableAlignCenter	: "Zentriert",
+DlgTableAlignRight	: "Rechts",
+DlgTableWidth		: "Breite",
+DlgTableWidthPx		: "Pixel",
+DlgTableWidthPc		: "%",
+DlgTableHeight		: "Höhe",
+DlgTableCellSpace	: "Zellenabstand außen",
+DlgTableCellPad		: "Zellenabstand innen",
+DlgTableCaption		: "Überschrift",
+DlgTableSummary		: "Inhaltsübersicht",
+
+// Table Cell Dialog
+DlgCellTitle		: "Zellen-Eigenschaften",
+DlgCellWidth		: "Breite",
+DlgCellWidthPx		: "Pixel",
+DlgCellWidthPc		: "%",
+DlgCellHeight		: "Höhe",
+DlgCellWordWrap		: "Umbruch",
+DlgCellWordWrapNotSet	: "<nichts>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nein",
+DlgCellHorAlign		: "Horizontale Ausrichtung",
+DlgCellHorAlignNotSet	: "<nichts>",
+DlgCellHorAlignLeft	: "Links",
+DlgCellHorAlignCenter	: "Zentriert",
+DlgCellHorAlignRight: "Rechts",
+DlgCellVerAlign		: "Vertikale Ausrichtung",
+DlgCellVerAlignNotSet	: "<nichts>",
+DlgCellVerAlignTop	: "Oben",
+DlgCellVerAlignMiddle	: "Mitte",
+DlgCellVerAlignBottom	: "Unten",
+DlgCellVerAlignBaseline	: "Grundlinie",
+DlgCellRowSpan		: "Zeilen zusammenfassen",
+DlgCellCollSpan		: "Spalten zusammenfassen",
+DlgCellBackColor	: "Hintergrundfarbe",
+DlgCellBorderColor	: "Rahmenfarbe",
+DlgCellBtnSelect	: "Auswahl...",
+
+// Find Dialog
+DlgFindTitle		: "Finden",
+DlgFindFindBtn		: "Finden",
+DlgFindNotFoundMsg	: "Der gesuchte Text wurde nicht gefunden.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Ersetzen",
+DlgReplaceFindLbl		: "Suche nach:",
+DlgReplaceReplaceLbl	: "Ersetze mit:",
+DlgReplaceCaseChk		: "Groß-Kleinschreibung beachten",
+DlgReplaceReplaceBtn	: "Ersetzen",
+DlgReplaceReplAllBtn	: "Alle Ersetzen",
+DlgReplaceWordChk		: "Nur ganze Worte suchen",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch auszuschneiden. Bitte benutzen Sie die System-Zwischenablage über STRG-X (ausschneiden) und STRG-V (einfügen).",
+PasteErrorCopy	: "Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch kopieren. Bitte benutzen Sie die System-Zwischenablage über STRG-C (kopieren).",
+
+PasteAsText		: "Als Text einfügen",
+PasteFromWord	: "Aus Word einfügen",
+
+DlgPasteMsg2	: "Bitte fügen Sie den Text in der folgenden Box über die Tastatur (mit <STRONG>Ctrl+V</STRONG>) ein und bestätigen Sie mit <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignoriere Schriftart-Definitionen",
+DlgPasteRemoveStyles	: "Entferne Style-Definitionen",
+DlgPasteCleanBox		: "Inhalt aufräumen",
+
+// Color Picker
+ColorAutomatic	: "Automatisch",
+ColorMoreColors	: "Weitere Farben...",
+
+// Document Properties
+DocProps		: "Dokument Eigenschaften",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Anker Eigenschaften",
+DlgAnchorName		: "Anker Name",
+DlgAnchorErrorName	: "Bitte geben Sie den Namen des Ankers ein",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Nicht im Wörterbuch",
+DlgSpellChangeTo		: "Ändern in",
+DlgSpellBtnIgnore		: "Ignorieren",
+DlgSpellBtnIgnoreAll	: "Alle Ignorieren",
+DlgSpellBtnReplace		: "Ersetzen",
+DlgSpellBtnReplaceAll	: "Alle Ersetzen",
+DlgSpellBtnUndo			: "Rückgängig",
+DlgSpellNoSuggestions	: " - keine Vorschläge - ",
+DlgSpellProgress		: "Rechtschreibprüfung läuft...",
+DlgSpellNoMispell		: "Rechtschreibprüfung abgeschlossen - keine Fehler gefunden",
+DlgSpellNoChanges		: "Rechtschreibprüfung abgeschlossen - keine Worte geändert",
+DlgSpellOneChange		: "Rechtschreibprüfung abgeschlossen - ein Wort geändert",
+DlgSpellManyChanges		: "Rechtschreibprüfung abgeschlossen - %1 Wörter geändert",
+
+IeSpellDownload			: "Rechtschreibprüfung nicht installiert. Möchten Sie sie jetzt herunterladen?",
+
+// Button Dialog
+DlgButtonText		: "Text (Wert)",
+DlgButtonType		: "Typ",
+DlgButtonTypeBtn	: "Button",
+DlgButtonTypeSbm	: "Absenden",
+DlgButtonTypeRst	: "Zurücksetzen",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Name",
+DlgCheckboxValue	: "Wert",
+DlgCheckboxSelected	: "ausgewählt",
+
+// Form Dialog
+DlgFormName		: "Name",
+DlgFormAction	: "Action",
+DlgFormMethod	: "Method",
+
+// Select Field Dialog
+DlgSelectName		: "Name",
+DlgSelectValue		: "Wert",
+DlgSelectSize		: "Größe",
+DlgSelectLines		: "Linien",
+DlgSelectChkMulti	: "Erlaube Mehrfachauswahl",
+DlgSelectOpAvail	: "Mögliche Optionen",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Wert",
+DlgSelectBtnAdd		: "Hinzufügen",
+DlgSelectBtnModify	: "Ändern",
+DlgSelectBtnUp		: "Hoch",
+DlgSelectBtnDown	: "Runter",
+DlgSelectBtnSetValue : "Setze als Standardwert",
+DlgSelectBtnDelete	: "Entfernen",
+
+// Textarea Dialog
+DlgTextareaName	: "Name",
+DlgTextareaCols	: "Spalten",
+DlgTextareaRows	: "Reihen",
+
+// Text Field Dialog
+DlgTextName			: "Name",
+DlgTextValue		: "Wert",
+DlgTextCharWidth	: "Zeichenbreite",
+DlgTextMaxChars		: "Max. Zeichen",
+DlgTextType			: "Typ",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Passwort",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Name",
+DlgHiddenValue	: "Wert",
+
+// Bulleted List Dialog
+BulletedListProp	: "Listen-Eigenschaften",
+NumberedListProp	: "Nummerierte Listen-Eigenschaften",
+DlgLstStart			: "Start",
+DlgLstType			: "Typ",
+DlgLstTypeCircle	: "Ring",
+DlgLstTypeDisc		: "Kreis",
+DlgLstTypeSquare	: "Quadrat",
+DlgLstTypeNumbers	: "Nummern (1, 2, 3)",
+DlgLstTypeLCase		: "Kleinbuchstaben (a, b, c)",
+DlgLstTypeUCase		: "Großbuchstaben (A, B, C)",
+DlgLstTypeSRoman	: "Kleine römische Zahlen (i, ii, iii)",
+DlgLstTypeLRoman	: "Große römische Zahlen (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Allgemein",
+DlgDocBackTab		: "Hintergrund",
+DlgDocColorsTab		: "Farben und Abstände",
+DlgDocMetaTab		: "Metadaten",
+
+DlgDocPageTitle		: "Seitentitel",
+DlgDocLangDir		: "Schriftrichtung",
+DlgDocLangDirLTR	: "Links nach Rechts",
+DlgDocLangDirRTL	: "Rechts nach Links",
+DlgDocLangCode		: "Sprachkürzel",
+DlgDocCharSet		: "Zeichenkodierung",
+DlgDocCharSetCE		: "Zentraleuropäisch",
+DlgDocCharSetCT		: "traditionell Chinesisch (Big5)",
+DlgDocCharSetCR		: "Kyrillisch",
+DlgDocCharSetGR		: "Griechisch",
+DlgDocCharSetJP		: "Japanisch",
+DlgDocCharSetKR		: "Koreanisch",
+DlgDocCharSetTR		: "Türkisch",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Westeuropäisch",
+DlgDocCharSetOther	: "Andere Zeichenkodierung",
+
+DlgDocDocType		: "Dokumententyp",
+DlgDocDocTypeOther	: "Anderer Dokumententyp",
+DlgDocIncXHTML		: "Beziehe XHTML Deklarationen ein",
+DlgDocBgColor		: "Hintergrundfarbe",
+DlgDocBgImage		: "Hintergrundbild URL",
+DlgDocBgNoScroll	: "feststehender Hintergrund",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Link",
+DlgDocCVisited		: "Besuchter Link",
+DlgDocCActive		: "Aktiver Link",
+DlgDocMargins		: "Seitenränder",
+DlgDocMaTop			: "Oben",
+DlgDocMaLeft		: "Links",
+DlgDocMaRight		: "Rechts",
+DlgDocMaBottom		: "Unten",
+DlgDocMeIndex		: "Schlüsselwörter (durch Komma getrennt)",
+DlgDocMeDescr		: "Dokument-Beschreibung",
+DlgDocMeAuthor		: "Autor",
+DlgDocMeCopy		: "Copyright",
+DlgDocPreview		: "Vorschau",
+
+// Templates Dialog
+Templates			: "Vorlagen",
+DlgTemplatesTitle	: "Vorlagen",
+DlgTemplatesSelMsg	: "Klicken Sie auf eine Vorlage, um sie im Editor zu öffnen (der aktuelle Inhalt wird dabei gelöscht!):",
+DlgTemplatesLoading	: "Liste der Vorlagen wird geladen. Bitte warten...",
+DlgTemplatesNoTpl	: "(keine Vorlagen definiert)",
+DlgTemplatesReplace	: "Aktuellen Inhalt ersetzen",
+
+// About Dialog
+DlgAboutAboutTab	: "Über",
+DlgAboutBrowserInfoTab	: "Browser-Info",
+DlgAboutLicenseTab	: "Lizenz",
+DlgAboutVersion		: "Version",
+DlgAboutInfo		: "Für weitere Informationen siehe"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sv.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sv.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/sv.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Swedish language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Dölj verktygsfält",
+ToolbarExpand		: "Visa verktygsfält",
+
+// Toolbar Items and Context Menu
+Save				: "Spara",
+NewPage				: "Ny sida",
+Preview				: "Förhandsgranska",
+Cut					: "Klipp ut",
+Copy				: "Kopiera",
+Paste				: "Klistra in",
+PasteText			: "Klistra in som text",
+PasteWord			: "Klistra in från Word",
+Print				: "Skriv ut",
+SelectAll			: "Markera allt",
+RemoveFormat		: "Radera formatering",
+InsertLinkLbl		: "Länk",
+InsertLink			: "Infoga/Redigera länk",
+RemoveLink			: "Radera länk",
+Anchor				: "Infoga/Redigera ankarlänk",
+InsertImageLbl		: "Bild",
+InsertImage			: "Infoga/Redigera bild",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Infoga/Redigera Flash",
+InsertTableLbl		: "Tabell",
+InsertTable			: "Infoga/Redigera tabell",
+InsertLineLbl		: "Linje",
+InsertLine			: "Infoga horisontal linje",
+InsertSpecialCharLbl: "Utökade tecken",
+InsertSpecialChar	: "Klistra in utökat tecken",
+InsertSmileyLbl		: "Smiley",
+InsertSmiley		: "Infoga Smiley",
+About				: "Om FCKeditor",
+Bold				: "Fet",
+Italic				: "Kursiv",
+Underline			: "Understruken",
+StrikeThrough		: "Genomstruken",
+Subscript			: "Nedsänkta tecken",
+Superscript			: "Upphöjda tecken",
+LeftJustify			: "Vänsterjustera",
+CenterJustify		: "Centrera",
+RightJustify		: "Högerjustera",
+BlockJustify		: "Justera till marginaler",
+DecreaseIndent		: "Minska indrag",
+IncreaseIndent		: "Öka indrag",
+Undo				: "Ångra",
+Redo				: "Gör om",
+NumberedListLbl		: "Numrerad lista",
+NumberedList		: "Infoga/Radera numrerad lista",
+BulletedListLbl		: "Punktlista",
+BulletedList		: "Infoga/Radera punktlista",
+ShowTableBorders	: "Visa tabellkant",
+ShowDetails			: "Visa radbrytningar",
+Style				: "Anpassad stil",
+FontFormat			: "Teckenformat",
+Font				: "Typsnitt",
+FontSize			: "Storlek",
+TextColor			: "Textfärg",
+BGColor				: "Bakgrundsfärg",
+Source				: "Källa",
+Find				: "Sök",
+Replace				: "Ersätt",
+SpellCheck			: "Stavningskontroll",
+UniversalKeyboard	: "Universellt tangentbord",
+PageBreakLbl		: "Sidbrytning",
+PageBreak			: "Infoga sidbrytning",
+
+Form			: "Formulär",
+Checkbox		: "Kryssruta",
+RadioButton		: "Alternativknapp",
+TextField		: "Textfält",
+Textarea		: "Textruta",
+HiddenField		: "Dolt fält",
+Button			: "Knapp",
+SelectionField	: "Flervalslista",
+ImageButton		: "Bildknapp",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Redigera länk",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Infoga rad",
+DeleteRows			: "Radera rad",
+InsertColumn		: "Infoga kolumn",
+DeleteColumns		: "Radera kolumn",
+InsertCell			: "Infoga cell",
+DeleteCells			: "Radera celler",
+MergeCells			: "Sammanfoga celler",
+SplitCell			: "Separera celler",
+TableDelete			: "Radera tabell",
+CellProperties		: "Cellegenskaper",
+TableProperties		: "Tabellegenskaper",
+ImageProperties		: "Bildegenskaper",
+FlashProperties		: "Flashegenskaper",
+
+AnchorProp			: "Egenskaper för ankarlänk",
+ButtonProp			: "Egenskaper för knapp",
+CheckboxProp		: "Egenskaper för kryssruta",
+HiddenFieldProp		: "Egenskaper för dolt fält",
+RadioButtonProp		: "Egenskaper för alternativknapp",
+ImageButtonProp		: "Egenskaper för bildknapp",
+TextFieldProp		: "Egenskaper för textfält",
+SelectionFieldProp	: "Egenskaper för flervalslista",
+TextareaProp		: "Egenskaper för textruta",
+FormProp			: "Egenskaper för formulär",
+
+FontFormats			: "Normal;Formaterad;Adress;Rubrik 1;Rubrik 2;Rubrik 3;Rubrik 4;Rubrik 5;Rubrik 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Bearbetar XHTML. Var god vänta...",
+Done				: "Klar",
+PasteWordConfirm	: "Texten du vill klistra in verkar vara kopierad från Word. Vill du rensa innan du klistar in?",
+NotCompatiblePaste	: "Denna åtgärd är inte tillgängligt för Internet Explorer version 5.5 eller högre. Vill du klistra in utan att rensa?",
+UnknownToolbarItem	: "Okänt verktygsfält \"%1\"",
+UnknownCommand		: "Okänt kommando \"%1\"",
+NotImplemented		: "Kommandot finns ej",
+UnknownToolbarSet	: "Verktygsfält \"%1\" finns ej",
+NoActiveX			: "Din webläsares säkerhetsinställningar kan begränsa funktionaliteten. Du bör aktivera \"Kör ActiveX kontroller och plug-ins\". Fel och avsaknad av funktioner kan annars uppstå.",
+BrowseServerBlocked : "Kunde Ej öppna resursfönstret. Var god och avaktivera alla popup-blockerare.",
+DialogBlocked		: "Kunde Ej öppna dialogfönstret. Var god och avaktivera alla popup-blockerare.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Avbryt",
+DlgBtnClose			: "Stäng",
+DlgBtnBrowseServer	: "Bläddra på server",
+DlgAdvancedTag		: "Avancerad",
+DlgOpOther			: "Övrigt",
+DlgInfoTab			: "Information",
+DlgAlertUrl			: "Var god och ange en URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ej angivet>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Språkriktning",
+DlgGenLangDirLtr	: "Vänster till Höger (VTH)",
+DlgGenLangDirRtl	: "Höger till Vänster (HTV)",
+DlgGenLangCode		: "Språkkod",
+DlgGenAccessKey		: "Behörighetsnyckel",
+DlgGenName			: "Namn",
+DlgGenTabIndex		: "Tabindex",
+DlgGenLongDescr		: "URL-beskrivning",
+DlgGenClass			: "Stylesheet class",
+DlgGenTitle			: "Titel",
+DlgGenContType		: "Innehållstyp",
+DlgGenLinkCharset	: "Teckenuppställning",
+DlgGenStyle			: "Style",
+
+// Image Dialog
+DlgImgTitle			: "Bildegenskaper",
+DlgImgInfoTab		: "Bildinformation",
+DlgImgBtnUpload		: "Skicka till server",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Ladda upp",
+DlgImgAlt			: "Alternativ text",
+DlgImgWidth			: "Bredd",
+DlgImgHeight		: "Höjd",
+DlgImgLockRatio		: "Lås höjd/bredd förhållanden",
+DlgBtnResetSize		: "Återställ storlek",
+DlgImgBorder		: "Kant",
+DlgImgHSpace		: "Horis. marginal",
+DlgImgVSpace		: "Vert. marginal",
+DlgImgAlign			: "Justering",
+DlgImgAlignLeft		: "Vänster",
+DlgImgAlignAbsBottom: "Absolut nederkant",
+DlgImgAlignAbsMiddle: "Absolut centrering",
+DlgImgAlignBaseline	: "Baslinje",
+DlgImgAlignBottom	: "Nederkant",
+DlgImgAlignMiddle	: "Mitten",
+DlgImgAlignRight	: "Höger",
+DlgImgAlignTextTop	: "Text överkant",
+DlgImgAlignTop		: "Överkant",
+DlgImgPreview		: "Förhandsgranska",
+DlgImgAlertUrl		: "Var god och ange bildens URL",
+DlgImgLinkTab		: "Länk",
+
+// Flash Dialog
+DlgFlashTitle		: "Flashegenskaper",
+DlgFlashChkPlay		: "Automatisk uppspelning",
+DlgFlashChkLoop		: "Upprepa/Loopa",
+DlgFlashChkMenu		: "Aktivera Flashmeny",
+DlgFlashScale		: "Skala",
+DlgFlashScaleAll	: "Visa allt",
+DlgFlashScaleNoBorder	: "Ingen ram",
+DlgFlashScaleFit	: "Exakt passning",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Länk",
+DlgLnkInfoTab		: "Länkinformation",
+DlgLnkTargetTab		: "Mål",
+
+DlgLnkType			: "Länktyp",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Ankare i sidan",
+DlgLnkTypeEMail		: "E-post",
+DlgLnkProto			: "Protokoll",
+DlgLnkProtoOther	: "<övrigt>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Välj ett ankare",
+DlgLnkAnchorByName	: "efter ankarnamn",
+DlgLnkAnchorById	: "efter objektid",
+DlgLnkNoAnchors		: "<Inga ankare kunde hittas>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-postadress",
+DlgLnkEMailSubject	: "Ämne",
+DlgLnkEMailBody		: "Innehåll",
+DlgLnkUpload		: "Ladda upp",
+DlgLnkBtnUpload		: "Skicka till servern",
+
+DlgLnkTarget		: "Mål",
+DlgLnkTargetFrame	: "<ram>",
+DlgLnkTargetPopup	: "<popup-fönster>",
+DlgLnkTargetBlank	: "Nytt fönster (_blank)",
+DlgLnkTargetParent	: "Föregående Window (_parent)",
+DlgLnkTargetSelf	: "Detta fönstret (_self)",
+DlgLnkTargetTop		: "Översta fönstret (_top)",
+DlgLnkTargetFrameName	: "Målets ramnamn",
+DlgLnkPopWinName	: "Popup-fönstrets namn",
+DlgLnkPopWinFeat	: "Popup-fönstrets egenskaper",
+DlgLnkPopResize		: "Kan ändra storlek",
+DlgLnkPopLocation	: "Adressfält",
+DlgLnkPopMenu		: "Menyfält",
+DlgLnkPopScroll		: "Scrolllista",
+DlgLnkPopStatus		: "Statusfält",
+DlgLnkPopToolbar	: "Verktygsfält",
+DlgLnkPopFullScrn	: "Helskärm (endast IE)",
+DlgLnkPopDependent	: "Beroende (endest Netscape)",
+DlgLnkPopWidth		: "Bredd",
+DlgLnkPopHeight		: "Höjd",
+DlgLnkPopLeft		: "Position från vänster",
+DlgLnkPopTop		: "Position från sidans topp",
+
+DlnLnkMsgNoUrl		: "Var god ange länkens URL",
+DlnLnkMsgNoEMail	: "Var god ange E-postadress",
+DlnLnkMsgNoAnchor	: "Var god ange ett ankare",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Välj färg",
+DlgColorBtnClear	: "Rensa",
+DlgColorHighlight	: "Markera",
+DlgColorSelected	: "Vald",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Infoga smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Välj utökat tecken",
+
+// Table Dialog
+DlgTableTitle		: "Tabellegenskaper",
+DlgTableRows		: "Rader",
+DlgTableColumns		: "Kolumner",
+DlgTableBorder		: "Kantstorlek",
+DlgTableAlign		: "Justering",
+DlgTableAlignNotSet	: "<ej angivet>",
+DlgTableAlignLeft	: "Vänster",
+DlgTableAlignCenter	: "Centrerad",
+DlgTableAlignRight	: "Höger",
+DlgTableWidth		: "Bredd",
+DlgTableWidthPx		: "pixlar",
+DlgTableWidthPc		: "procent",
+DlgTableHeight		: "Höjd",
+DlgTableCellSpace	: "Cellavstånd",
+DlgTableCellPad		: "Cellutfyllnad",
+DlgTableCaption		: "Rubrik",
+DlgTableSummary		: "Sammanfattning",
+
+// Table Cell Dialog
+DlgCellTitle		: "Cellegenskaper",
+DlgCellWidth		: "Bredd",
+DlgCellWidthPx		: "pixlar",
+DlgCellWidthPc		: "procent",
+DlgCellHeight		: "Höjd",
+DlgCellWordWrap		: "Automatisk radbrytning",
+DlgCellWordWrapNotSet	: "<Ej angivet>",
+DlgCellWordWrapYes	: "Ja",
+DlgCellWordWrapNo	: "Nej",
+DlgCellHorAlign		: "Horisontal justering",
+DlgCellHorAlignNotSet	: "<Ej angivet>",
+DlgCellHorAlignLeft	: "Vänster",
+DlgCellHorAlignCenter	: "Centrerad",
+DlgCellHorAlignRight: "Höger",
+DlgCellVerAlign		: "Vertikal justering",
+DlgCellVerAlignNotSet	: "<Ej angivet>",
+DlgCellVerAlignTop	: "Topp",
+DlgCellVerAlignMiddle	: "Mitten",
+DlgCellVerAlignBottom	: "Nederkant",
+DlgCellVerAlignBaseline	: "Underst",
+DlgCellRowSpan		: "Radomfång",
+DlgCellCollSpan		: "Kolumnomfång",
+DlgCellBackColor	: "Bakgrundsfärg",
+DlgCellBorderColor	: "Kantfärg",
+DlgCellBtnSelect	: "Välj...",
+
+// Find Dialog
+DlgFindTitle		: "Sök",
+DlgFindFindBtn		: "Sök",
+DlgFindNotFoundMsg	: "Angiven text kunde ej hittas.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Ersätt",
+DlgReplaceFindLbl		: "Sök efter:",
+DlgReplaceReplaceLbl	: "Ersätt med:",
+DlgReplaceCaseChk		: "Skiftläge",
+DlgReplaceReplaceBtn	: "Ersätt",
+DlgReplaceReplAllBtn	: "Ersätt alla",
+DlgReplaceWordChk		: "Inkludera hela ord",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Säkerhetsinställningar i Er webläsare tillåter inte åtgården Klipp ut. Använd (Ctrl+X) istället.",
+PasteErrorCopy	: "Säkerhetsinställningar i Er webläsare tillåter inte åtgården Kopiera. Använd (Ctrl+C) istället",
+
+PasteAsText		: "Klistra in som vanlig text",
+PasteFromWord	: "Klistra in från Word",
+
+DlgPasteMsg2	: "Var god och klistra in Er text i rutan nedan genom att använda (<STRONG>Ctrl+V</STRONG>) klicka sen på <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignorera typsnittsdefinitioner",
+DlgPasteRemoveStyles	: "Radera Stildefinitioner",
+DlgPasteCleanBox		: "Töm rutans innehåll",
+
+// Color Picker
+ColorAutomatic	: "Automatisk",
+ColorMoreColors	: "Fler färger...",
+
+// Document Properties
+DocProps		: "Dokumentegenskaper",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ankaregenskaper",
+DlgAnchorName		: "Ankarnamn",
+DlgAnchorErrorName	: "Var god ange ett ankarnamn",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Saknas i ordlistan",
+DlgSpellChangeTo		: "Ändra till",
+DlgSpellBtnIgnore		: "Ignorera",
+DlgSpellBtnIgnoreAll	: "Ignorera alla",
+DlgSpellBtnReplace		: "Ersätt",
+DlgSpellBtnReplaceAll	: "Ersätt alla",
+DlgSpellBtnUndo			: "Ångra",
+DlgSpellNoSuggestions	: "- Förslag saknas -",
+DlgSpellProgress		: "Stavningskontroll pågår...",
+DlgSpellNoMispell		: "Stavningskontroll slutförd: Inga stavfel påträffades.",
+DlgSpellNoChanges		: "Stavningskontroll slutförd: Inga ord rättades.",
+DlgSpellOneChange		: "Stavningskontroll slutförd: Ett ord rättades.",
+DlgSpellManyChanges		: "Stavningskontroll slutförd: %1 ord rättades.",
+
+IeSpellDownload			: "Stavningskontrollen är ej installerad. Vill du göra det nu?",
+
+// Button Dialog
+DlgButtonText		: "Text (Värde)",
+DlgButtonType		: "Typ",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Namn",
+DlgCheckboxValue	: "Värde",
+DlgCheckboxSelected	: "Vald",
+
+// Form Dialog
+DlgFormName		: "Namn",
+DlgFormAction	: "Funktion",
+DlgFormMethod	: "Metod",
+
+// Select Field Dialog
+DlgSelectName		: "Namn",
+DlgSelectValue		: "Värde",
+DlgSelectSize		: "Storlek",
+DlgSelectLines		: "Linjer",
+DlgSelectChkMulti	: "Tillåt flerval",
+DlgSelectOpAvail	: "Befintliga val",
+DlgSelectOpText		: "Text",
+DlgSelectOpValue	: "Värde",
+DlgSelectBtnAdd		: "Lägg till",
+DlgSelectBtnModify	: "Redigera",
+DlgSelectBtnUp		: "Upp",
+DlgSelectBtnDown	: "Ner",
+DlgSelectBtnSetValue : "Markera som valt värde",
+DlgSelectBtnDelete	: "Radera",
+
+// Textarea Dialog
+DlgTextareaName	: "Namn",
+DlgTextareaCols	: "Kolumner",
+DlgTextareaRows	: "Rader",
+
+// Text Field Dialog
+DlgTextName			: "Namn",
+DlgTextValue		: "Värde",
+DlgTextCharWidth	: "Teckenbredd",
+DlgTextMaxChars		: "Max antal tecken",
+DlgTextType			: "Typ",
+DlgTextTypeText		: "Text",
+DlgTextTypePass		: "Lösenord",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Namn",
+DlgHiddenValue	: "Värde",
+
+// Bulleted List Dialog
+BulletedListProp	: "Egenskaper för punktlista",
+NumberedListProp	: "Egenskaper för numrerad lista",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Typ",
+DlgLstTypeCircle	: "Cirkel",
+DlgLstTypeDisc		: "Punkt",
+DlgLstTypeSquare	: "Ruta",
+DlgLstTypeNumbers	: "Nummer (1, 2, 3)",
+DlgLstTypeLCase		: "Gemener (a, b, c)",
+DlgLstTypeUCase		: "Versaler (A, B, C)",
+DlgLstTypeSRoman	: "Små romerska siffror (i, ii, iii)",
+DlgLstTypeLRoman	: "Stora romerska siffror (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Allmän",
+DlgDocBackTab		: "Bakgrund",
+DlgDocColorsTab		: "Färg och marginal",
+DlgDocMetaTab		: "Metadata",
+
+DlgDocPageTitle		: "Sidtitel",
+DlgDocLangDir		: "Språkriktning",
+DlgDocLangDirLTR	: "Vänster till Höger",
+DlgDocLangDirRTL	: "Höger till Vänster",
+DlgDocLangCode		: "Språkkod",
+DlgDocCharSet		: "Teckenuppsättningar",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Övriga teckenuppsättningar",
+
+DlgDocDocType		: "Sidhuvud",
+DlgDocDocTypeOther	: "Övriga sidhuvuden",
+DlgDocIncXHTML		: "Inkludera XHTML deklaration",
+DlgDocBgColor		: "Bakgrundsfärg",
+DlgDocBgImage		: "Bakgrundsbildens URL",
+DlgDocBgNoScroll	: "Fast bakgrund",
+DlgDocCText			: "Text",
+DlgDocCLink			: "Länk",
+DlgDocCVisited		: "Besökt länk",
+DlgDocCActive		: "Aktiv länk",
+DlgDocMargins		: "Sidmarginal",
+DlgDocMaTop			: "Topp",
+DlgDocMaLeft		: "Vänster",
+DlgDocMaRight		: "Höger",
+DlgDocMaBottom		: "Botten",
+DlgDocMeIndex		: "Sidans nyckelord",
+DlgDocMeDescr		: "Sidans beskrivning",
+DlgDocMeAuthor		: "Författare",
+DlgDocMeCopy		: "Upphovsrätt",
+DlgDocPreview		: "Förhandsgranska",
+
+// Templates Dialog
+Templates			: "Sidmallar",
+DlgTemplatesTitle	: "Sidmallar",
+DlgTemplatesSelMsg	: "Var god välj en mall att använda med editorn<br>(allt nuvarande innehåll raderas):",
+DlgTemplatesLoading	: "Laddar mallar. Var god vänta...",
+DlgTemplatesNoTpl	: "(Ingen mall är vald)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Om",
+DlgAboutBrowserInfoTab	: "Webläsare",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "version",
+DlgAboutInfo		: "För mer information se"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ja.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ja.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/ja.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Japanese language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "ツールバーを隠す",
+ToolbarExpand		: "ツールバーを表示",
+
+// Toolbar Items and Context Menu
+Save				: "保存",
+NewPage				: "新しいページ",
+Preview				: "プレビュー",
+Cut					: "切り取り",
+Copy				: "コピー",
+Paste				: "貼り付け",
+PasteText			: "プレーンテキスト貼り付け",
+PasteWord			: "ワード文章から貼り付け",
+Print				: "印刷",
+SelectAll			: "すべて選択",
+RemoveFormat		: "フォーマット削除",
+InsertLinkLbl		: "リンク",
+InsertLink			: "リンク挿入/編集",
+RemoveLink			: "リンク削除",
+Anchor				: "アンカー挿入/編集",
+InsertImageLbl		: "イメージ",
+InsertImage			: "イメージ挿入/編集",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Flash挿入/編集",
+InsertTableLbl		: "テーブル",
+InsertTable			: "テーブル挿入/編集",
+InsertLineLbl		: "ライン",
+InsertLine			: "横罫線",
+InsertSpecialCharLbl: "特殊文字",
+InsertSpecialChar	: "特殊文字挿入",
+InsertSmileyLbl		: "絵文字",
+InsertSmiley		: "絵文字挿入",
+About				: "FCKeditorヘルプ",
+Bold				: "太字",
+Italic				: "斜体",
+Underline			: "下線",
+StrikeThrough		: "打ち消し線",
+Subscript			: "添え字",
+Superscript			: "上付き文字",
+LeftJustify			: "左揃え",
+CenterJustify		: "中央揃え",
+RightJustify		: "右揃え",
+BlockJustify		: "両端揃え",
+DecreaseIndent		: "インデント解除",
+IncreaseIndent		: "インデント",
+Undo				: "元に戻す",
+Redo				: "やり直し",
+NumberedListLbl		: "段落番号",
+NumberedList		: "段落番号の追加/削除",
+BulletedListLbl		: "箇条書き",
+BulletedList		: "箇条書きの追加/削除",
+ShowTableBorders	: "テーブルボーダー表示",
+ShowDetails			: "詳細表示",
+Style				: "スタイル",
+FontFormat			: "フォーマット",
+Font				: "フォント",
+FontSize			: "サイズ",
+TextColor			: "テキスト色",
+BGColor				: "背景色",
+Source				: "ソース",
+Find				: "検索",
+Replace				: "置き換え",
+SpellCheck			: "スペルチェック",
+UniversalKeyboard	: "ユニバーサル・キーボード",
+PageBreakLbl		: "改ページ",
+PageBreak			: "改ページ挿入",
+
+Form			: "フォーム",
+Checkbox		: "チェックボックス",
+RadioButton		: "ラジオボタン",
+TextField		: "１行テキスト",
+Textarea		: "テキストエリア",
+HiddenField		: "不可視フィールド",
+Button			: "ボタン",
+SelectionField	: "選択フィールド",
+ImageButton		: "画像ボタン",
+
+FitWindow		: "エディタサイズを最大にします",
+
+// Context Menu
+EditLink			: "リンク編集",
+CellCM				: "セル",
+RowCM				: "行",
+ColumnCM			: "カラム",
+InsertRow			: "行挿入",
+DeleteRows			: "行削除",
+InsertColumn		: "列挿入",
+DeleteColumns		: "列削除",
+InsertCell			: "セル挿入",
+DeleteCells			: "セル削除",
+MergeCells			: "セル結合",
+SplitCell			: "セル分割",
+TableDelete			: "テーブル削除",
+CellProperties		: "セル プロパティ",
+TableProperties		: "テーブル プロパティ",
+ImageProperties		: "イメージ プロパティ",
+FlashProperties		: "Flash プロパティ",
+
+AnchorProp			: "アンカー プロパティ",
+ButtonProp			: "ボタン プロパティ",
+CheckboxProp		: "チェックボックス プロパティ",
+HiddenFieldProp		: "不可視フィールド プロパティ",
+RadioButtonProp		: "ラジオボタン プロパティ",
+ImageButtonProp		: "画像ボタン プロパティ",
+TextFieldProp		: "１行テキスト プロパティ",
+SelectionFieldProp	: "選択フィールド プロパティ",
+TextareaProp		: "テキストエリア プロパティ",
+FormProp			: "フォーム プロパティ",
+
+FontFormats			: "標準;書式付き;アドレス;見出し 1;見出し 2;見出し 3;見出し 4;見出し 5;見出し 6;標準 (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML処理中. しばらくお待ちください...",
+Done				: "完了",
+PasteWordConfirm	: "貼り付けを行うテキストは、ワード文章からコピーされようとしています。貼り付ける前にクリーニングを行いますか？",
+NotCompatiblePaste	: "このコマンドはインターネット・エクスプローラーバージョン5.5以上で利用可能です。クリーニングしないで貼り付けを行いますか？",
+UnknownToolbarItem	: "未知のツールバー項目 \"%1\"",
+UnknownCommand		: "未知のコマンド名 \"%1\"",
+NotImplemented		: "コマンドはインプリメントされませんでした。",
+UnknownToolbarSet	: "ツールバー設定 \"%1\" 存在しません。",
+NoActiveX			: "エラー、警告メッセージなどが発生した場合、ブラウザーのセキュリティ設定によりエディタのいくつかの機能が制限されている可能性があります。セキュリティ設定のオプションで\"ActiveXコントロールとプラグインの実行\"を有効にするにしてください。",
+BrowseServerBlocked : "サーバーブラウザーを開くことができませんでした。ポップアップ・ブロック機能が無効になっているか確認してください。",
+DialogBlocked		: "ダイアログウィンドウを開くことができませんでした。ポップアップ・ブロック機能が無効になっているか確認してください。",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "キャンセル",
+DlgBtnClose			: "閉じる",
+DlgBtnBrowseServer	: "サーバーブラウザー",
+DlgAdvancedTag		: "高度な設定",
+DlgOpOther			: "<その他>",
+DlgInfoTab			: "情報",
+DlgAlertUrl			: "URLを挿入してください",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<なし>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "文字表記の方向",
+DlgGenLangDirLtr	: "左から右 (LTR)",
+DlgGenLangDirRtl	: "右から左 (RTL)",
+DlgGenLangCode		: "言語コード",
+DlgGenAccessKey		: "アクセスキー",
+DlgGenName			: "Name属性",
+DlgGenTabIndex		: "タブインデックス",
+DlgGenLongDescr		: "longdesc属性(長文説明)",
+DlgGenClass			: "スタイルシートクラス",
+DlgGenTitle			: "Title属性",
+DlgGenContType		: "Content Type属性",
+DlgGenLinkCharset	: "リンクcharset属性",
+DlgGenStyle			: "スタイルシート",
+
+// Image Dialog
+DlgImgTitle			: "イメージ プロパティ",
+DlgImgInfoTab		: "イメージ 情報",
+DlgImgBtnUpload		: "サーバーに送信",
+DlgImgURL			: "URL",
+DlgImgUpload		: "アップロード",
+DlgImgAlt			: "代替テキスト",
+DlgImgWidth			: "幅",
+DlgImgHeight		: "高さ",
+DlgImgLockRatio		: "ロック比率",
+DlgBtnResetSize		: "サイズリセット",
+DlgImgBorder		: "ボーダー",
+DlgImgHSpace		: "横間隔",
+DlgImgVSpace		: "縦間隔",
+DlgImgAlign			: "行揃え",
+DlgImgAlignLeft		: "左",
+DlgImgAlignAbsBottom: "下部(絶対的)",
+DlgImgAlignAbsMiddle: "中央(絶対的)",
+DlgImgAlignBaseline	: "ベースライン",
+DlgImgAlignBottom	: "下",
+DlgImgAlignMiddle	: "中央",
+DlgImgAlignRight	: "右",
+DlgImgAlignTextTop	: "テキスト上部",
+DlgImgAlignTop		: "上",
+DlgImgPreview		: "プレビュー",
+DlgImgAlertUrl		: "イメージのURLを入力してください。",
+DlgImgLinkTab		: "リンク",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash プロパティ",
+DlgFlashChkPlay		: "再生",
+DlgFlashChkLoop		: "ループ再生",
+DlgFlashChkMenu		: "Flashメニュー可能",
+DlgFlashScale		: "拡大縮小設定",
+DlgFlashScaleAll	: "すべて表示",
+DlgFlashScaleNoBorder	: "外が見えない様に拡大",
+DlgFlashScaleFit	: "上下左右にフィット",
+
+// Link Dialog
+DlgLnkWindowTitle	: "ハイパーリンク",
+DlgLnkInfoTab		: "ハイパーリンク 情報",
+DlgLnkTargetTab		: "ターゲット",
+
+DlgLnkType			: "リンクタイプ",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "このページのアンカー",
+DlgLnkTypeEMail		: "E-Mail",
+DlgLnkProto			: "プロトコル",
+DlgLnkProtoOther	: "<その他>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "アンカーを選択",
+DlgLnkAnchorByName	: "アンカー名",
+DlgLnkAnchorById	: "エレメントID",
+DlgLnkNoAnchors		: "<ドキュメントにおいて利用可能なアンカーはありません。>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "E-Mail アドレス",
+DlgLnkEMailSubject	: "件名",
+DlgLnkEMailBody		: "本文",
+DlgLnkUpload		: "アップロード",
+DlgLnkBtnUpload		: "サーバーに送信",
+
+DlgLnkTarget		: "ターゲット",
+DlgLnkTargetFrame	: "<フレーム>",
+DlgLnkTargetPopup	: "<ポップアップウィンドウ>",
+DlgLnkTargetBlank	: "新しいウィンドウ (_blank)",
+DlgLnkTargetParent	: "親ウィンドウ (_parent)",
+DlgLnkTargetSelf	: "同じウィンドウ (_self)",
+DlgLnkTargetTop		: "最上位ウィンドウ (_top)",
+DlgLnkTargetFrameName	: "目的のフレーム名",
+DlgLnkPopWinName	: "ポップアップウィンドウ名",
+DlgLnkPopWinFeat	: "ポップアップウィンドウ特徴",
+DlgLnkPopResize		: "リサイズ可能",
+DlgLnkPopLocation	: "ロケーションバー",
+DlgLnkPopMenu		: "メニューバー",
+DlgLnkPopScroll		: "スクロールバー",
+DlgLnkPopStatus		: "ステータスバー",
+DlgLnkPopToolbar	: "ツールバー",
+DlgLnkPopFullScrn	: "全画面モード(IE)",
+DlgLnkPopDependent	: "開いたウィンドウに連動して閉じる (Netscape)",
+DlgLnkPopWidth		: "幅",
+DlgLnkPopHeight		: "高さ",
+DlgLnkPopLeft		: "左端からの座標で指定",
+DlgLnkPopTop		: "上端からの座標で指定",
+
+DlnLnkMsgNoUrl		: "リンクURLを入力してください。",
+DlnLnkMsgNoEMail	: "メールアドレスを入力してください。",
+DlnLnkMsgNoAnchor	: "アンカーを選択してください。",
+DlnLnkMsgInvPopName	: "ポップ・アップ名は英字で始まる文字で指定してくだい。ポップ・アップ名にスペースは含めません",
+
+// Color Dialog
+DlgColorTitle		: "色選択",
+DlgColorBtnClear	: "クリア",
+DlgColorHighlight	: "ハイライト",
+DlgColorSelected	: "選択色",
+
+// Smiley Dialog
+DlgSmileyTitle		: "顔文字挿入",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "特殊文字選択",
+
+// Table Dialog
+DlgTableTitle		: "テーブル プロパティ",
+DlgTableRows		: "行",
+DlgTableColumns		: "列",
+DlgTableBorder		: "ボーダーサイズ",
+DlgTableAlign		: "キャプションの整列",
+DlgTableAlignNotSet	: "<なし>",
+DlgTableAlignLeft	: "左",
+DlgTableAlignCenter	: "中央",
+DlgTableAlignRight	: "右",
+DlgTableWidth		: "テーブル幅",
+DlgTableWidthPx		: "ピクセル",
+DlgTableWidthPc		: "パーセント",
+DlgTableHeight		: "テーブル高さ",
+DlgTableCellSpace	: "セル内余白",
+DlgTableCellPad		: "セル内間隔",
+DlgTableCaption		: "ｷｬﾌﾟｼｮﾝ",
+DlgTableSummary		: "テーブル目的/構造",
+
+// Table Cell Dialog
+DlgCellTitle		: "セル プロパティ",
+DlgCellWidth		: "幅",
+DlgCellWidthPx		: "ピクセル",
+DlgCellWidthPc		: "パーセント",
+DlgCellHeight		: "高さ",
+DlgCellWordWrap		: "折り返し",
+DlgCellWordWrapNotSet	: "<なし>",
+DlgCellWordWrapYes	: "Yes",
+DlgCellWordWrapNo	: "No",
+DlgCellHorAlign		: "セル横の整列",
+DlgCellHorAlignNotSet	: "<なし>",
+DlgCellHorAlignLeft	: "左",
+DlgCellHorAlignCenter	: "中央",
+DlgCellHorAlignRight: "右",
+DlgCellVerAlign		: "セル縦の整列",
+DlgCellVerAlignNotSet	: "<なし>",
+DlgCellVerAlignTop	: "上",
+DlgCellVerAlignMiddle	: "中央",
+DlgCellVerAlignBottom	: "下",
+DlgCellVerAlignBaseline	: "ベースライン",
+DlgCellRowSpan		: "縦幅(行数)",
+DlgCellCollSpan		: "横幅(列数)",
+DlgCellBackColor	: "背景色",
+DlgCellBorderColor	: "ボーダーカラー",
+DlgCellBtnSelect	: "選択...",
+
+// Find Dialog
+DlgFindTitle		: "検索",
+DlgFindFindBtn		: "検索",
+DlgFindNotFoundMsg	: "指定された文字列は見つかりませんでした。",
+
+// Replace Dialog
+DlgReplaceTitle			: "置き換え",
+DlgReplaceFindLbl		: "検索する文字列:",
+DlgReplaceReplaceLbl	: "置換えする文字列:",
+DlgReplaceCaseChk		: "部分一致",
+DlgReplaceReplaceBtn	: "置換え",
+DlgReplaceReplAllBtn	: "すべて置換え",
+DlgReplaceWordChk		: "単語単位で一致",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "ブラウザーのセキュリティ設定によりエディタの切り取り操作が自動で実行することができません。実行するには手動でキーボードの(Ctrl+X)を使用してください。",
+PasteErrorCopy	: "ブラウザーのセキュリティ設定によりエディタのコピー操作が自動で実行することができません。実行するには手動でキーボードの(Ctrl+C)を使用してください。",
+
+PasteAsText		: "プレーンテキスト貼り付け",
+PasteFromWord	: "ワード文章から貼り付け",
+
+DlgPasteMsg2	: "キーボード(<STRONG>Ctrl+V</STRONG>)を使用して、次の入力エリア内で貼って、<STRONG>OK</STRONG>を押してください。",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "FontタグのFace属性を無視します。",
+DlgPasteRemoveStyles	: "スタイル定義を削除します。",
+DlgPasteCleanBox		: "入力エリアクリア",
+
+// Color Picker
+ColorAutomatic	: "自動",
+ColorMoreColors	: "その他の色...",
+
+// Document Properties
+DocProps		: "文書 プロパティ",
+
+// Anchor Dialog
+DlgAnchorTitle		: "アンカー プロパティ",
+DlgAnchorName		: "アンカー名",
+DlgAnchorErrorName	: "アンカー名を必ず入力してください。",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "辞書にありません",
+DlgSpellChangeTo		: "変更",
+DlgSpellBtnIgnore		: "無視",
+DlgSpellBtnIgnoreAll	: "すべて無視",
+DlgSpellBtnReplace		: "置換",
+DlgSpellBtnReplaceAll	: "すべて置換",
+DlgSpellBtnUndo			: "やり直し",
+DlgSpellNoSuggestions	: "- 該当なし -",
+DlgSpellProgress		: "スペルチェック処理中...",
+DlgSpellNoMispell		: "スペルチェック完了: スペルの誤りはありませんでした",
+DlgSpellNoChanges		: "スペルチェック完了: 語句は変更されませんでした",
+DlgSpellOneChange		: "スペルチェック完了: １語句変更されました",
+DlgSpellManyChanges		: "スペルチェック完了: %1 語句変更されました",
+
+IeSpellDownload			: "スペルチェッカーがインストールされていません。今すぐダウンロードしますか?",
+
+// Button Dialog
+DlgButtonText		: "テキスト (値)",
+DlgButtonType		: "タイプ",
+DlgButtonTypeBtn	: "ボタン",
+DlgButtonTypeSbm	: "送信",
+DlgButtonTypeRst	: "リセット",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "名前",
+DlgCheckboxValue	: "値",
+DlgCheckboxSelected	: "選択済み",
+
+// Form Dialog
+DlgFormName		: "フォーム名",
+DlgFormAction	: "アクション",
+DlgFormMethod	: "メソッド",
+
+// Select Field Dialog
+DlgSelectName		: "名前",
+DlgSelectValue		: "値",
+DlgSelectSize		: "サイズ",
+DlgSelectLines		: "行",
+DlgSelectChkMulti	: "複数項目選択を許可",
+DlgSelectOpAvail	: "利用可能なオプション",
+DlgSelectOpText		: "選択項目名",
+DlgSelectOpValue	: "選択項目値",
+DlgSelectBtnAdd		: "追加",
+DlgSelectBtnModify	: "編集",
+DlgSelectBtnUp		: "上へ",
+DlgSelectBtnDown	: "下へ",
+DlgSelectBtnSetValue : "選択した値を設定",
+DlgSelectBtnDelete	: "削除",
+
+// Textarea Dialog
+DlgTextareaName	: "名前",
+DlgTextareaCols	: "列",
+DlgTextareaRows	: "行",
+
+// Text Field Dialog
+DlgTextName			: "名前",
+DlgTextValue		: "値",
+DlgTextCharWidth	: "サイズ",
+DlgTextMaxChars		: "最大長",
+DlgTextType			: "タイプ",
+DlgTextTypeText		: "テキスト",
+DlgTextTypePass		: "パスワード入力",
+
+// Hidden Field Dialog
+DlgHiddenName	: "名前",
+DlgHiddenValue	: "値",
+
+// Bulleted List Dialog
+BulletedListProp	: "箇条書き プロパティ",
+NumberedListProp	: "段落番号 プロパティ",
+DlgLstStart			: "開始文字",
+DlgLstType			: "タイプ",
+DlgLstTypeCircle	: "白丸",
+DlgLstTypeDisc		: "黒丸",
+DlgLstTypeSquare	: "四角",
+DlgLstTypeNumbers	: "アラビア数字 (1, 2, 3)",
+DlgLstTypeLCase		: "英字小文字 (a, b, c)",
+DlgLstTypeUCase		: "英字大文字 (A, B, C)",
+DlgLstTypeSRoman	: "ローマ数字小文字 (i, ii, iii)",
+DlgLstTypeLRoman	: "ローマ数字大文字 (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "全般",
+DlgDocBackTab		: "背景",
+DlgDocColorsTab		: "色とマージン",
+DlgDocMetaTab		: "メタデータ",
+
+DlgDocPageTitle		: "ページタイトル",
+DlgDocLangDir		: "言語文字表記の方向",
+DlgDocLangDirLTR	: "左から右に表記(LTR)",
+DlgDocLangDirRTL	: "右から左に表記(RTL)",
+DlgDocLangCode		: "言語コード",
+DlgDocCharSet		: "文字セット符号化",
+DlgDocCharSetCE		: "Central European",
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",
+DlgDocCharSetCR		: "Cyrillic",
+DlgDocCharSetGR		: "Greek",
+DlgDocCharSetJP		: "Japanese",
+DlgDocCharSetKR		: "Korean",
+DlgDocCharSetTR		: "Turkish",
+DlgDocCharSetUN		: "Unicode (UTF-8)",
+DlgDocCharSetWE		: "Western European",
+DlgDocCharSetOther	: "他の文字セット符号化",
+
+DlgDocDocType		: "文書タイプヘッダー",
+DlgDocDocTypeOther	: "その他文書タイプヘッダー",
+DlgDocIncXHTML		: "XHTML宣言をインクルード",
+DlgDocBgColor		: "背景色",
+DlgDocBgImage		: "背景画像 URL",
+DlgDocBgNoScroll	: "スクロールしない背景",
+DlgDocCText			: "テキスト",
+DlgDocCLink			: "リンク",
+DlgDocCVisited		: "アクセス済みリンク",
+DlgDocCActive		: "アクセス中リンク",
+DlgDocMargins		: "ページ・マージン",
+DlgDocMaTop			: "上部",
+DlgDocMaLeft		: "左",
+DlgDocMaRight		: "右",
+DlgDocMaBottom		: "下部",
+DlgDocMeIndex		: "文書のキーワード(カンマ区切り)",
+DlgDocMeDescr		: "文書の概要",
+DlgDocMeAuthor		: "文書の作者",
+DlgDocMeCopy		: "文書の著作権",
+DlgDocPreview		: "プレビュー",
+
+// Templates Dialog
+Templates			: "テンプレート(雛形)",
+DlgTemplatesTitle	: "テンプレート内容",
+DlgTemplatesSelMsg	: "エディターで使用するテンプレートを選択してください。<br>(現在のエディタの内容は失われます):",
+DlgTemplatesLoading	: "テンプレート一覧読み込み中. しばらくお待ちください...",
+DlgTemplatesNoTpl	: "(テンプレートが定義されていません)",
+DlgTemplatesReplace	: "現在のエディタの内容と置換えをします",
+
+// About Dialog
+DlgAboutAboutTab	: "バージョン情報",
+DlgAboutBrowserInfoTab	: "ブラウザ情報",
+DlgAboutLicenseTab	: "ライセンス",
+DlgAboutVersion		: "バージョン",
+DlgAboutInfo		: "より詳しい情報はこちらで"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/he.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/he.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/he.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Hebrew language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "rtl",
+
+ToolbarCollapse		: "כיווץ סרגל הכלים",
+ToolbarExpand		: "פתיחת סרגל הכלים",
+
+// Toolbar Items and Context Menu
+Save				: "שמירה",
+NewPage				: "דף חדש",
+Preview				: "תצוגה מקדימה",
+Cut					: "גזירה",
+Copy				: "העתקה",
+Paste				: "הדבקה",
+PasteText			: "הדבקה כטקסט פשוט",
+PasteWord			: "הדבקה מ-וורד",
+Print				: "הדפסה",
+SelectAll			: "בחירת הכל",
+RemoveFormat		: "הסרת העיצוב",
+InsertLinkLbl		: "קישור",
+InsertLink			: "הוספת/עריכת קישור",
+RemoveLink			: "הסרת הקישור",
+Anchor				: "הוספת/עריכת נקודת עיגון",
+InsertImageLbl		: "תמונה",
+InsertImage			: "הוספת/עריכת תמונה",
+InsertFlashLbl		: "פלאש",
+InsertFlash			: "הוסף/ערוך פלאש",
+InsertTableLbl		: "טבלה",
+InsertTable			: "הוספת/עריכת טבלה",
+InsertLineLbl		: "קו",
+InsertLine			: "הוספת קו אופקי",
+InsertSpecialCharLbl: "תו מיוחד",
+InsertSpecialChar	: "הוספת תו מיוחד",
+InsertSmileyLbl		: "סמיילי",
+InsertSmiley		: "הוספת סמיילי",
+About				: "אודות FCKeditor",
+Bold				: "מודגש",
+Italic				: "נטוי",
+Underline			: "קו תחתון",
+StrikeThrough		: "כתיב מחוק",
+Subscript			: "כתיב תחתון",
+Superscript			: "כתיב עליון",
+LeftJustify			: "יישור לשמאל",
+CenterJustify		: "מרכוז",
+RightJustify		: "יישור לימין",
+BlockJustify		: "יישור לשוליים",
+DecreaseIndent		: "הקטנת אינדנטציה",
+IncreaseIndent		: "הגדלת אינדנטציה",
+Undo				: "ביטול צעד אחרון",
+Redo				: "חזרה על צעד אחרון",
+NumberedListLbl		: "רשימה ממוספרת",
+NumberedList		: "הוספת/הסרת רשימה ממוספרת",
+BulletedListLbl		: "רשימת נקודות",
+BulletedList		: "הוספת/הסרת רשימת נקודות",
+ShowTableBorders	: "הצגת מסגרת הטבלה",
+ShowDetails			: "הצגת פרטים",
+Style				: "סגנון",
+FontFormat			: "עיצוב",
+Font				: "גופן",
+FontSize			: "גודל",
+TextColor			: "צבע טקסט",
+BGColor				: "צבע רקע",
+Source				: "מקור",
+Find				: "חיפוש",
+Replace				: "החלפה",
+SpellCheck			: "בדיקת איות",
+UniversalKeyboard	: "מקלדת אוניברסלית",
+PageBreakLbl		: "שבירת דף",
+PageBreak			: "הוסף שבירת דף",
+
+Form			: "טופס",
+Checkbox		: "תיבת סימון",
+RadioButton		: "לחצן אפשרויות",
+TextField		: "שדה טקסט",
+Textarea		: "איזור טקסט",
+HiddenField		: "שדה חבוי",
+Button			: "כפתור",
+SelectionField	: "שדה בחירה",
+ImageButton		: "כפתור תמונה",
+
+FitWindow		: "הגדל את גודל העורך",
+
+// Context Menu
+EditLink			: "עריכת קישור",
+CellCM				: "תא",
+RowCM				: "שורה",
+ColumnCM			: "עמודה",
+InsertRow			: "הוספת שורה",
+DeleteRows			: "מחיקת שורות",
+InsertColumn		: "הוספת עמודה",
+DeleteColumns		: "מחיקת עמודות",
+InsertCell			: "הוספת תא",
+DeleteCells			: "מחיקת תאים",
+MergeCells			: "מיזוג תאים",
+SplitCell			: "פיצול תאים",
+TableDelete			: "מחק טבלה",
+CellProperties		: "תכונות התא",
+TableProperties		: "תכונות הטבלה",
+ImageProperties		: "תכונות התמונה",
+FlashProperties		: "מאפייני פלאש",
+
+AnchorProp			: "מאפייני נקודת עיגון",
+ButtonProp			: "מאפייני כפתור",
+CheckboxProp		: "מאפייני תיבת סימון",
+HiddenFieldProp		: "מאפיני שדה חבוי",
+RadioButtonProp		: "מאפייני לחצן אפשרויות",
+ImageButtonProp		: "מאפיני כפתור תמונה",
+TextFieldProp		: "מאפייני שדה טקסט",
+SelectionFieldProp	: "מאפייני שדה בחירה",
+TextareaProp		: "מאפיני איזור טקסט",
+FormProp			: "מאפיני טופס",
+
+FontFormats			: "נורמלי;קוד;כתובת;כותרת;כותרת 2;כותרת 3;כותרת 4;כותרת 5;כותרת 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "מעבד XHTML, נא להמתין...",
+Done				: "המשימה הושלמה",
+PasteWordConfirm	: "נראה הטקסט שבכוונתך להדביק מקורו בקובץ וורד. האם ברצונך לנקות אותו טרם ההדבקה?",
+NotCompatiblePaste	: "פעולה זו זמינה לדפדפן אינטרנט אקספלורר מגירסא 5.5 ומעלה. האם להמשיך בהדבקה ללא הניקוי?",
+UnknownToolbarItem	: "פריט לא ידוע בסרגל הכלים \"%1\"",
+UnknownCommand		: "שם פעולה לא ידוע \"%1\"",
+NotImplemented		: "הפקודה לא מיושמת",
+UnknownToolbarSet	: "ערכת סרגל הכלים \"%1\" לא קיימת",
+NoActiveX			: "הגדרות אבטחה של הדפדפן עלולות לגביל את אפשרויות העריכה.יש לאפשר את האופציה \"הרץ פקדים פעילים ותוספות\". תוכל לחוות טעויות וחיווים של אפשרויות שחסרים.",
+BrowseServerBlocked : "לא ניתן לגשת לדפדפן משאבים.אנא וודא שחוסם חלונות הקופצים לא פעיל.",
+DialogBlocked		: "לא היה ניתן לפתוח חלון דיאלוג. אנא וודא שחוסם חלונות קופצים לא פעיל.",
+
+// Dialogs
+DlgBtnOK			: "אישור",
+DlgBtnCancel		: "ביטול",
+DlgBtnClose			: "סגירה",
+DlgBtnBrowseServer	: "סייר השרת",
+DlgAdvancedTag		: "אפשרויות מתקדמות",
+DlgOpOther			: "<אחר>",
+DlgInfoTab			: "מידע",
+DlgAlertUrl			: "אנה הזן URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<לא נקבע>",
+DlgGenId			: "זיהוי (Id)",
+DlgGenLangDir		: "כיוון שפה",
+DlgGenLangDirLtr	: "שמאל לימין (LTR)",
+DlgGenLangDirRtl	: "ימין לשמאל (RTL)",
+DlgGenLangCode		: "קוד שפה",
+DlgGenAccessKey		: "מקש גישה",
+DlgGenName			: "שם",
+DlgGenTabIndex		: "מספר טאב",
+DlgGenLongDescr		: "קישור לתיאור מפורט",
+DlgGenClass			: "גיליונות עיצוב קבוצות",
+DlgGenTitle			: "כותרת מוצעת",
+DlgGenContType		: "Content Type מוצע",
+DlgGenLinkCharset	: "קידוד המשאב המקושר",
+DlgGenStyle			: "סגנון",
+
+// Image Dialog
+DlgImgTitle			: "תכונות התמונה",
+DlgImgInfoTab		: "מידע על התמונה",
+DlgImgBtnUpload		: "שליחה לשרת",
+DlgImgURL			: "כתובת (URL)",
+DlgImgUpload		: "העלאה",
+DlgImgAlt			: "טקסט חלופי",
+DlgImgWidth			: "רוחב",
+DlgImgHeight		: "גובה",
+DlgImgLockRatio		: "נעילת היחס",
+DlgBtnResetSize		: "איפוס הגודל",
+DlgImgBorder		: "מסגרת",
+DlgImgHSpace		: "מרווח אופקי",
+DlgImgVSpace		: "מרווח אנכי",
+DlgImgAlign			: "יישור",
+DlgImgAlignLeft		: "לשמאל",
+DlgImgAlignAbsBottom: "לתחתית האבסולוטית",
+DlgImgAlignAbsMiddle: "מרכוז אבסולוטי",
+DlgImgAlignBaseline	: "לקו התחתית",
+DlgImgAlignBottom	: "לתחתית",
+DlgImgAlignMiddle	: "לאמצע",
+DlgImgAlignRight	: "לימין",
+DlgImgAlignTextTop	: "לראש הטקסט",
+DlgImgAlignTop		: "למעלה",
+DlgImgPreview		: "תצוגה מקדימה",
+DlgImgAlertUrl		: "נא להקליד את כתובת התמונה",
+DlgImgLinkTab		: "קישור",
+
+// Flash Dialog
+DlgFlashTitle		: "מאפיני פלאש",
+DlgFlashChkPlay		: "נגן אוטומטי",
+DlgFlashChkLoop		: "לולאה",
+DlgFlashChkMenu		: "אפשר תפריט פלאש",
+DlgFlashScale		: "גודל",
+DlgFlashScaleAll	: "הצג הכל",
+DlgFlashScaleNoBorder	: "ללא גבולות",
+DlgFlashScaleFit	: "התאמה מושלמת",
+
+// Link Dialog
+DlgLnkWindowTitle	: "קישור",
+DlgLnkInfoTab		: "מידע על הקישור",
+DlgLnkTargetTab		: "מטרה",
+
+DlgLnkType			: "סוג קישור",
+DlgLnkTypeURL		: "כתובת (URL)",
+DlgLnkTypeAnchor	: "עוגן בעמוד זה",
+DlgLnkTypeEMail		: "דוא''ל",
+DlgLnkProto			: "פרוטוקול",
+DlgLnkProtoOther	: "<אחר>",
+DlgLnkURL			: "כתובת (URL)",
+DlgLnkAnchorSel		: "בחירת עוגן",
+DlgLnkAnchorByName	: "עפ''י שם העוגן",
+DlgLnkAnchorById	: "עפ''י זיהוי (Id) הרכיב",
+DlgLnkNoAnchors		: "<אין עוגנים זמינים בדף>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "כתובת הדוא''ל",
+DlgLnkEMailSubject	: "נושא ההודעה",
+DlgLnkEMailBody		: "גוף ההודעה",
+DlgLnkUpload		: "העלאה",
+DlgLnkBtnUpload		: "שליחה לשרת",
+
+DlgLnkTarget		: "מטרה",
+DlgLnkTargetFrame	: "<מסגרת>",
+DlgLnkTargetPopup	: "<חלון קופץ>",
+DlgLnkTargetBlank	: "חלון חדש (_blank)",
+DlgLnkTargetParent	: "חלון האב (_parent)",
+DlgLnkTargetSelf	: "באותו החלון (_self)",
+DlgLnkTargetTop		: "חלון ראשי (_top)",
+DlgLnkTargetFrameName	: "שם מסגרת היעד",
+DlgLnkPopWinName	: "שם החלון הקופץ",
+DlgLnkPopWinFeat	: "תכונות החלון הקופץ",
+DlgLnkPopResize		: "בעל גודל ניתן לשינוי",
+DlgLnkPopLocation	: "סרגל כתובת",
+DlgLnkPopMenu		: "סרגל תפריט",
+DlgLnkPopScroll		: "ניתן לגלילה",
+DlgLnkPopStatus		: "סרגל חיווי",
+DlgLnkPopToolbar	: "סרגל הכלים",
+DlgLnkPopFullScrn	: "מסך מלא (IE)",
+DlgLnkPopDependent	: "תלוי (Netscape)",
+DlgLnkPopWidth		: "רוחב",
+DlgLnkPopHeight		: "גובה",
+DlgLnkPopLeft		: "מיקום צד שמאל",
+DlgLnkPopTop		: "מיקום צד עליון",
+
+DlnLnkMsgNoUrl		: "נא להקליד את כתובת הקישור (URL)",
+DlnLnkMsgNoEMail	: "נא להקליד את כתובת הדוא''ל",
+DlnLnkMsgNoAnchor	: "נא לבחור עוגן במסמך",
+DlnLnkMsgInvPopName	: "שם החלון הקופץ חייב להתחיל באותיות ואסור לכלול רווחים",
+
+// Color Dialog
+DlgColorTitle		: "בחירת צבע",
+DlgColorBtnClear	: "איפוס",
+DlgColorHighlight	: "נוכחי",
+DlgColorSelected	: "נבחר",
+
+// Smiley Dialog
+DlgSmileyTitle		: "הוספת סמיילי",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "בחירת תו מיוחד",
+
+// Table Dialog
+DlgTableTitle		: "תכונות טבלה",
+DlgTableRows		: "שורות",
+DlgTableColumns		: "עמודות",
+DlgTableBorder		: "גודל מסגרת",
+DlgTableAlign		: "יישור",
+DlgTableAlignNotSet	: "<לא נקבע>",
+DlgTableAlignLeft	: "שמאל",
+DlgTableAlignCenter	: "מרכז",
+DlgTableAlignRight	: "ימין",
+DlgTableWidth		: "רוחב",
+DlgTableWidthPx		: "פיקסלים",
+DlgTableWidthPc		: "אחוז",
+DlgTableHeight		: "גובה",
+DlgTableCellSpace	: "מרווח תא",
+DlgTableCellPad		: "ריפוד תא",
+DlgTableCaption		: "כיתוב",
+DlgTableSummary		: "סיכום",
+
+// Table Cell Dialog
+DlgCellTitle		: "תכונות תא",
+DlgCellWidth		: "רוחב",
+DlgCellWidthPx		: "פיקסלים",
+DlgCellWidthPc		: "אחוז",
+DlgCellHeight		: "גובה",
+DlgCellWordWrap		: "גלילת שורות",
+DlgCellWordWrapNotSet	: "<לא נקבע>",
+DlgCellWordWrapYes	: "כן",
+DlgCellWordWrapNo	: "לא",
+DlgCellHorAlign		: "יישור אופקי",
+DlgCellHorAlignNotSet	: "<לא נקבע>",
+DlgCellHorAlignLeft	: "שמאל",
+DlgCellHorAlignCenter	: "מרכז",
+DlgCellHorAlignRight: "ימין",
+DlgCellVerAlign		: "יישור אנכי",
+DlgCellVerAlignNotSet	: "<לא נקבע>",
+DlgCellVerAlignTop	: "למעלה",
+DlgCellVerAlignMiddle	: "לאמצע",
+DlgCellVerAlignBottom	: "לתחתית",
+DlgCellVerAlignBaseline	: "קו תחתית",
+DlgCellRowSpan		: "טווח שורות",
+DlgCellCollSpan		: "טווח עמודות",
+DlgCellBackColor	: "צבע רקע",
+DlgCellBorderColor	: "צבע מסגרת",
+DlgCellBtnSelect	: "בחירה...",
+
+// Find Dialog
+DlgFindTitle		: "חיפוש",
+DlgFindFindBtn		: "חיפוש",
+DlgFindNotFoundMsg	: "הטקסט המבוקש לא נמצא.",
+
+// Replace Dialog
+DlgReplaceTitle			: "החלפה",
+DlgReplaceFindLbl		: "חיפוש מחרוזת:",
+DlgReplaceReplaceLbl	: "החלפה במחרוזת:",
+DlgReplaceCaseChk		: "התאמת סוג אותיות (Case)",
+DlgReplaceReplaceBtn	: "החלפה",
+DlgReplaceReplAllBtn	: "החלפה בכל העמוד",
+DlgReplaceWordChk		: "התאמה למילה המלאה",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות גזירה  אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl+X).",
+PasteErrorCopy	: "הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות העתקה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl+C).",
+
+PasteAsText		: "הדבקה כטקסט פשוט",
+PasteFromWord	: "הדבקה מ-וורד",
+
+DlgPasteMsg2	: "אנא הדבק בתוך הקופסה באמצעות  (<STRONG>Ctrl+V</STRONG>) ולחץ על  <STRONG>אישור</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "התעלם מהגדרות סוג פונט",
+DlgPasteRemoveStyles	: "הסר הגדרות סגנון",
+DlgPasteCleanBox		: "ניקוי קופסה",
+
+// Color Picker
+ColorAutomatic	: "אוטומטי",
+ColorMoreColors	: "צבעים נוספים...",
+
+// Document Properties
+DocProps		: "מאפיני מסמך",
+
+// Anchor Dialog
+DlgAnchorTitle		: "מאפיני נקודת עיגון",
+DlgAnchorName		: "שם לנקודת עיגון",
+DlgAnchorErrorName	: "אנא הזן שם לנקודת עיגון",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "לא נמצא במילון",
+DlgSpellChangeTo		: "שנה ל",
+DlgSpellBtnIgnore		: "התעלם",
+DlgSpellBtnIgnoreAll	: "התעלם מהכל",
+DlgSpellBtnReplace		: "החלף",
+DlgSpellBtnReplaceAll	: "החלף הכל",
+DlgSpellBtnUndo			: "החזר",
+DlgSpellNoSuggestions	: "- אין הצעות -",
+DlgSpellProgress		: "בדיקות איות בתהליך ....",
+DlgSpellNoMispell		: "בדיקות איות הסתיימה: לא נמצאו שגיעות כתיב",
+DlgSpellNoChanges		: "בדיקות איות הסתיימה: לא שונתה אף מילה",
+DlgSpellOneChange		: "בדיקות איות הסתיימה: שונתה מילה אחת",
+DlgSpellManyChanges		: "בדיקות איות הסתיימה: %1 מילים שונו",
+
+IeSpellDownload			: "בודק האיות לא מותקן, האם אתה מעוניין להוריד?",
+
+// Button Dialog
+DlgButtonText		: "טקסט (ערך)",
+DlgButtonType		: "סוג",
+DlgButtonTypeBtn	: "כפתור",
+DlgButtonTypeSbm	: "שלח",
+DlgButtonTypeRst	: "אפס",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "שם",
+DlgCheckboxValue	: "ערך",
+DlgCheckboxSelected	: "בחור",
+
+// Form Dialog
+DlgFormName		: "שם",
+DlgFormAction	: "שלח אל",
+DlgFormMethod	: "סוג שליחה",
+
+// Select Field Dialog
+DlgSelectName		: "שם",
+DlgSelectValue		: "ערך",
+DlgSelectSize		: "גודל",
+DlgSelectLines		: "שורות",
+DlgSelectChkMulti	: "אפשר בחירות מרובות",
+DlgSelectOpAvail	: "אפשרויות זמינות",
+DlgSelectOpText		: "טקסט",
+DlgSelectOpValue	: "ערך",
+DlgSelectBtnAdd		: "הוסף",
+DlgSelectBtnModify	: "שנה",
+DlgSelectBtnUp		: "למעלה",
+DlgSelectBtnDown	: "למטה",
+DlgSelectBtnSetValue : "קבע כברירת מחדל",
+DlgSelectBtnDelete	: "מחק",
+
+// Textarea Dialog
+DlgTextareaName	: "שם",
+DlgTextareaCols	: "עמודות",
+DlgTextareaRows	: "שורות",
+
+// Text Field Dialog
+DlgTextName			: "שם",
+DlgTextValue		: "ערך",
+DlgTextCharWidth	: "רוחב באותיות",
+DlgTextMaxChars		: "מקסימות אותיות",
+DlgTextType			: "סוג",
+DlgTextTypeText		: "טקסט",
+DlgTextTypePass		: "סיסמה",
+
+// Hidden Field Dialog
+DlgHiddenName	: "שם",
+DlgHiddenValue	: "ערך",
+
+// Bulleted List Dialog
+BulletedListProp	: "מאפייני רשימה",
+NumberedListProp	: "מאפייני רשימה ממוספרת",
+DlgLstStart			: "התחלה",
+DlgLstType			: "סוג",
+DlgLstTypeCircle	: "עיגול",
+DlgLstTypeDisc		: "דיסק",
+DlgLstTypeSquare	: "מרובע",
+DlgLstTypeNumbers	: "מספרים (1, 2, 3)",
+DlgLstTypeLCase		: "אותיות קטנות (a, b, c)",
+DlgLstTypeUCase		: "אותיות גדולות (A, B, C)",
+DlgLstTypeSRoman	: "ספרות רומאיות קטנות (i, ii, iii)",
+DlgLstTypeLRoman	: "ספרות רומאיות גדולות (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "כללי",
+DlgDocBackTab		: "רקע",
+DlgDocColorsTab		: "צבעים וגבולות",
+DlgDocMetaTab		: "נתוני META",
+
+DlgDocPageTitle		: "כותרת דף",
+DlgDocLangDir		: "כיוון שפה",
+DlgDocLangDirLTR	: "שמאל לימין (LTR)",
+DlgDocLangDirRTL	: "ימין לשמאל (RTL)",
+DlgDocLangCode		: "קוד שפה",
+DlgDocCharSet		: "קידוד אותיות",
+DlgDocCharSetCE		: "מרכז אירופה",
+DlgDocCharSetCT		: "סיני מסורתי (Big5)",
+DlgDocCharSetCR		: "קירילי",
+DlgDocCharSetGR		: "יוונית",
+DlgDocCharSetJP		: "יפנית",
+DlgDocCharSetKR		: "קוראנית",
+DlgDocCharSetTR		: "טורקית",
+DlgDocCharSetUN		: "יוני קוד (UTF-8)",
+DlgDocCharSetWE		: "מערב אירופה",
+DlgDocCharSetOther	: "קידוד אותיות אחר",
+
+DlgDocDocType		: "הגדרות סוג מסמך",
+DlgDocDocTypeOther	: "הגדרות סוג מסמך אחרות",
+DlgDocIncXHTML		: "כלול הגדרות XHTML",
+DlgDocBgColor		: "צבע רקע",
+DlgDocBgImage		: "URL לתמונת רקע",
+DlgDocBgNoScroll	: "רגע ללא גלילה",
+DlgDocCText			: "טקסט",
+DlgDocCLink			: "קישור",
+DlgDocCVisited		: "קישור שבוקר",
+DlgDocCActive		: " קישור פעיל",
+DlgDocMargins		: "גבולות דף",
+DlgDocMaTop			: "למעלה",
+DlgDocMaLeft		: "שמאלה",
+DlgDocMaRight		: "ימינה",
+DlgDocMaBottom		: "למטה",
+DlgDocMeIndex		: "מפתח עניינים של המסמך )מופרד בפסיק(",
+DlgDocMeDescr		: "תאור מסמך",
+DlgDocMeAuthor		: "מחבר",
+DlgDocMeCopy		: "זכויות יוצרים",
+DlgDocPreview		: "תצוגה מקדימה",
+
+// Templates Dialog
+Templates			: "תבניות",
+DlgTemplatesTitle	: "תביות תוכן",
+DlgTemplatesSelMsg	: "אנא בחר תבנית לפתיחה בעורך <BR>התוכן המקורי ימחק:",
+DlgTemplatesLoading	: "מעלה רשימת תבניות אנא המתן",
+DlgTemplatesNoTpl	: "(לא הוגדרו תבניות)",
+DlgTemplatesReplace	: "החלפת תוכן ממשי",
+
+// About Dialog
+DlgAboutAboutTab	: "אודות",
+DlgAboutBrowserInfoTab	: "גירסת דפדפן",
+DlgAboutLicenseTab	: "רשיון",
+DlgAboutVersion		: "גירסא",
+DlgAboutInfo		: "מידע נוסף ניתן למצוא כאן:"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fi.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fi.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/fi.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Finnish language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Piilota työkalurivi",
+ToolbarExpand		: "Näytä työkalurivi",
+
+// Toolbar Items and Context Menu
+Save				: "Tallenna",
+NewPage				: "Tyhjennä",
+Preview				: "Esikatsele",
+Cut					: "Leikkaa",
+Copy				: "Kopioi",
+Paste				: "Liitä",
+PasteText			: "Liitä tekstinä",
+PasteWord			: "Liitä Wordista",
+Print				: "Tulosta",
+SelectAll			: "Valitse kaikki",
+RemoveFormat		: "Poista muotoilu",
+InsertLinkLbl		: "Linkki",
+InsertLink			: "Lisää linkki/muokkaa linkkiä",
+RemoveLink			: "Poista linkki",
+Anchor				: "Lisää ankkuri/muokkaa ankkuria",
+InsertImageLbl		: "Kuva",
+InsertImage			: "Lisää kuva/muokkaa kuvaa",
+InsertFlashLbl		: "Flash",
+InsertFlash			: "Lisää/muokkaa Flashia",
+InsertTableLbl		: "Taulu",
+InsertTable			: "Lisää taulu/muokkaa taulua",
+InsertLineLbl		: "Murtoviiva",
+InsertLine			: "Lisää murtoviiva",
+InsertSpecialCharLbl: "Erikoismerkki",
+InsertSpecialChar	: "Lisää erikoismerkki",
+InsertSmileyLbl		: "Hymiö",
+InsertSmiley		: "Lisää hymiö",
+About				: "FCKeditorista",
+Bold				: "Lihavoitu",
+Italic				: "Kursivoitu",
+Underline			: "Alleviivattu",
+StrikeThrough		: "Yliviivattu",
+Subscript			: "Alaindeksi",
+Superscript			: "Yläindeksi",
+LeftJustify			: "Tasaa vasemmat reunat",
+CenterJustify		: "Keskitä",
+RightJustify		: "Tasaa oikeat reunat",
+BlockJustify		: "Tasaa molemmat reunat",
+DecreaseIndent		: "Pienennä sisennystä",
+IncreaseIndent		: "Suurenna sisennystä",
+Undo				: "Kumoa",
+Redo				: "Toista",
+NumberedListLbl		: "Numerointi",
+NumberedList		: "Lisää/poista numerointi",
+BulletedListLbl		: "Luottelomerkit",
+BulletedList		: "Lisää/poista luottelomerkit",
+ShowTableBorders	: "Näytä taulun rajat",
+ShowDetails			: "Näytä muotoilu",
+Style				: "Tyyli",
+FontFormat			: "Muotoilu",
+Font				: "Fontti",
+FontSize			: "Koko",
+TextColor			: "Tekstiväri",
+BGColor				: "Taustaväri",
+Source				: "Koodi",
+Find				: "Etsi",
+Replace				: "Korvaa",
+SpellCheck			: "Tarkista oikeinkirjoitus",
+UniversalKeyboard	: "Universaali näppäimistö",
+PageBreakLbl		: "Sivun vaihto",
+PageBreak			: "Lisää sivun vaihto",
+
+Form			: "Lomake",
+Checkbox		: "Valintaruutu",
+RadioButton		: "Radiopainike",
+TextField		: "Tekstikenttä",
+Textarea		: "Tekstilaatikko",
+HiddenField		: "Piilokenttä",
+Button			: "Painike",
+SelectionField	: "Valintakenttä",
+ImageButton		: "Kuvapainike",
+
+FitWindow		: "Suurenna editori koko ikkunaan",
+
+// Context Menu
+EditLink			: "Muokkaa linkkiä",
+CellCM				: "Solu",
+RowCM				: "Rivi",
+ColumnCM			: "Sarake",
+InsertRow			: "Lisää rivi",
+DeleteRows			: "Poista rivit",
+InsertColumn		: "Lisää sarake",
+DeleteColumns		: "Poista sarakkeet",
+InsertCell			: "Lisää solu",
+DeleteCells			: "Poista solut",
+MergeCells			: "Yhdistä solut",
+SplitCell			: "Jaa solu",
+TableDelete			: "Poista taulu",
+CellProperties		: "Solun ominaisuudet",
+TableProperties		: "Taulun ominaisuudet",
+ImageProperties		: "Kuvan ominaisuudet",
+FlashProperties		: "Flash ominaisuudet",
+
+AnchorProp			: "Ankkurin ominaisuudet",
+ButtonProp			: "Painikkeen ominaisuudet",
+CheckboxProp		: "Valintaruudun ominaisuudet",
+HiddenFieldProp		: "Piilokentän ominaisuudet",
+RadioButtonProp		: "Radiopainikkeen ominaisuudet",
+ImageButtonProp		: "Kuvapainikkeen ominaisuudet",
+TextFieldProp		: "Tekstikentän ominaisuudet",
+SelectionFieldProp	: "Valintakentän ominaisuudet",
+TextareaProp		: "Tekstilaatikon ominaisuudet",
+FormProp			: "Lomakkeen ominaisuudet",
+
+FontFormats			: "Normaali;Muotoiltu;Osoite;Otsikko 1;Otsikko 2;Otsikko 3;Otsikko 4;Otsikko 5;Otsikko 6",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Prosessoidaan XHTML:ää. Odota hetki...",
+Done				: "Valmis",
+PasteWordConfirm	: "Teksti, jonka haluat liittää, näyttää olevan kopioitu Wordista. Haluatko puhdistaa sen ennen liittämistä?",
+NotCompatiblePaste	: "Tämä komento toimii vain Internet Explorer 5.5:ssa tai uudemmassa. Haluatko liittää ilman puhdistusta?",
+UnknownToolbarItem	: "Tuntemanton työkalu \"%1\"",
+UnknownCommand		: "Tuntematon komento \"%1\"",
+NotImplemented		: "Komentoa ei ole liitetty sovellukseen",
+UnknownToolbarSet	: "Työkalukokonaisuus \"%1\" ei ole olemassa",
+NoActiveX			: "Selaimesi turvallisuusasetukset voivat rajoittaa joitain editorin ominaisuuksia. Sinun pitää ottaa käyttöön asetuksista \"Suorita ActiveX komponentit ja -plugin-laajennukset\". Saatat kohdata virheitä ja huomata puuttuvia ominaisuuksia.",
+BrowseServerBlocked : "Resurssiselainta ei voitu avata. Varmista, että ponnahdusikkunoiden estäjät eivät ole päällä.",
+DialogBlocked		: "Apuikkunaa ei voitu avaata. Varmista, että ponnahdusikkunoiden estäjät eivät ole päällä.",
+
+// Dialogs
+DlgBtnOK			: "OK",
+DlgBtnCancel		: "Peruuta",
+DlgBtnClose			: "Sulje",
+DlgBtnBrowseServer	: "Selaa palvelinta",
+DlgAdvancedTag		: "Lisäominaisuudet",
+DlgOpOther			: "Muut",
+DlgInfoTab			: "Info",
+DlgAlertUrl			: "Lisää URL",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<ei asetettu>",
+DlgGenId			: "Tunniste",
+DlgGenLangDir		: "Kielen suunta",
+DlgGenLangDirLtr	: "Vasemmalta oikealle (LTR)",
+DlgGenLangDirRtl	: "Oikealta vasemmalle (RTL)",
+DlgGenLangCode		: "Kielikoodi",
+DlgGenAccessKey		: "Pikanäppäin",
+DlgGenName			: "Nimi",
+DlgGenTabIndex		: "Tabulaattori indeksi",
+DlgGenLongDescr		: "Pitkän kuvauksen URL",
+DlgGenClass			: "Tyyliluokat",
+DlgGenTitle			: "Avustava otsikko",
+DlgGenContType		: "Avustava sisällön tyyppi",
+DlgGenLinkCharset	: "Linkitetty kirjaimisto",
+DlgGenStyle			: "Tyyli",
+
+// Image Dialog
+DlgImgTitle			: "Kuvan ominaisuudet",
+DlgImgInfoTab		: "Kuvan tiedot",
+DlgImgBtnUpload		: "Lähetä palvelimelle",
+DlgImgURL			: "Osoite",
+DlgImgUpload		: "Lisää kuva",
+DlgImgAlt			: "Vaihtoehtoinen teksti",
+DlgImgWidth			: "Leveys",
+DlgImgHeight		: "Korkeus",
+DlgImgLockRatio		: "Lukitse suhteet",
+DlgBtnResetSize		: "Alkuperäinen koko",
+DlgImgBorder		: "Raja",
+DlgImgHSpace		: "Vaakatila",
+DlgImgVSpace		: "Pystytila",
+DlgImgAlign			: "Kohdistus",
+DlgImgAlignLeft		: "Vasemmalle",
+DlgImgAlignAbsBottom: "Aivan alas",
+DlgImgAlignAbsMiddle: "Aivan keskelle",
+DlgImgAlignBaseline	: "Alas (teksti)",
+DlgImgAlignBottom	: "Alas",
+DlgImgAlignMiddle	: "Keskelle",
+DlgImgAlignRight	: "Oikealle",
+DlgImgAlignTextTop	: "Ylös (teksti)",
+DlgImgAlignTop		: "Ylös",
+DlgImgPreview		: "Esikatselu",
+DlgImgAlertUrl		: "Kirjoita kuvan osoite (URL)",
+DlgImgLinkTab		: "Linkki",
+
+// Flash Dialog
+DlgFlashTitle		: "Flash ominaisuudet",
+DlgFlashChkPlay		: "Automaattinen käynnistys",
+DlgFlashChkLoop		: "Toisto",
+DlgFlashChkMenu		: "Näytä Flash-valikko",
+DlgFlashScale		: "Levitä",
+DlgFlashScaleAll	: "Näytä kaikki",
+DlgFlashScaleNoBorder	: "Ei rajaa",
+DlgFlashScaleFit	: "Tarkka koko",
+
+// Link Dialog
+DlgLnkWindowTitle	: "Linkki",
+DlgLnkInfoTab		: "Linkin tiedot",
+DlgLnkTargetTab		: "Kohde",
+
+DlgLnkType			: "Linkkityyppi",
+DlgLnkTypeURL		: "Osoite",
+DlgLnkTypeAnchor	: "Ankkuri tässä sivussa",
+DlgLnkTypeEMail		: "Sähköposti",
+DlgLnkProto			: "Protokolla",
+DlgLnkProtoOther	: "<muu>",
+DlgLnkURL			: "Osoite",
+DlgLnkAnchorSel		: "Valitse ankkuri",
+DlgLnkAnchorByName	: "Ankkurin nimen mukaan",
+DlgLnkAnchorById	: "Ankkurin ID:n mukaan",
+DlgLnkNoAnchors		: "<Ei ankkureita tässä dokumentissa>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Sähköpostiosoite",
+DlgLnkEMailSubject	: "Aihe",
+DlgLnkEMailBody		: "Viesti",
+DlgLnkUpload		: "Lisää tiedosto",
+DlgLnkBtnUpload		: "Lähetä palvelimelle",
+
+DlgLnkTarget		: "Kohde",
+DlgLnkTargetFrame	: "<kehys>",
+DlgLnkTargetPopup	: "<popup ikkuna>",
+DlgLnkTargetBlank	: "Uusi ikkuna (_blank)",
+DlgLnkTargetParent	: "Emoikkuna (_parent)",
+DlgLnkTargetSelf	: "Sama ikkuna (_self)",
+DlgLnkTargetTop		: "Päällimmäisin ikkuna (_top)",
+DlgLnkTargetFrameName	: "Kohdekehyksen nimi",
+DlgLnkPopWinName	: "Popup ikkunan nimi",
+DlgLnkPopWinFeat	: "Popup ikkunan ominaisuudet",
+DlgLnkPopResize		: "Venytettävä",
+DlgLnkPopLocation	: "Osoiterivi",
+DlgLnkPopMenu		: "Valikkorivi",
+DlgLnkPopScroll		: "Vierityspalkit",
+DlgLnkPopStatus		: "Tilarivi",
+DlgLnkPopToolbar	: "Vakiopainikkeet",
+DlgLnkPopFullScrn	: "Täysi ikkuna (IE)",
+DlgLnkPopDependent	: "Riippuva (Netscape)",
+DlgLnkPopWidth		: "Leveys",
+DlgLnkPopHeight		: "Korkeus",
+DlgLnkPopLeft		: "Vasemmalta (px)",
+DlgLnkPopTop		: "Ylhäältä (px)",
+
+DlnLnkMsgNoUrl		: "Linkille on kirjoitettava URL",
+DlnLnkMsgNoEMail	: "Kirjoita sähköpostiosoite",
+DlnLnkMsgNoAnchor	: "Valitse ankkuri",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Valitse väri",
+DlgColorBtnClear	: "Tyhjennä",
+DlgColorHighlight	: "Kohdalla",
+DlgColorSelected	: "Valittu",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Lisää hymiö",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Valitse erikoismerkki",
+
+// Table Dialog
+DlgTableTitle		: "Taulun ominaisuudet",
+DlgTableRows		: "Rivit",
+DlgTableColumns		: "Sarakkeet",
+DlgTableBorder		: "Rajan paksuus",
+DlgTableAlign		: "Kohdistus",
+DlgTableAlignNotSet	: "<ei asetettu>",
+DlgTableAlignLeft	: "Vasemmalle",
+DlgTableAlignCenter	: "Keskelle",
+DlgTableAlignRight	: "Oikealle",
+DlgTableWidth		: "Leveys",
+DlgTableWidthPx		: "pikseliä",
+DlgTableWidthPc		: "prosenttia",
+DlgTableHeight		: "Korkeus",
+DlgTableCellSpace	: "Solujen väli",
+DlgTableCellPad		: "Solujen sisennys",
+DlgTableCaption		: "Otsikko",
+DlgTableSummary		: "Yhteenveto",
+
+// Table Cell Dialog
+DlgCellTitle		: "Solun ominaisuudet",
+DlgCellWidth		: "Leveys",
+DlgCellWidthPx		: "pikseliä",
+DlgCellWidthPc		: "prosenttia",
+DlgCellHeight		: "Korkeus",
+DlgCellWordWrap		: "Tekstikierrätys",
+DlgCellWordWrapNotSet	: "<Ei asetettu>",
+DlgCellWordWrapYes	: "Kyllä",
+DlgCellWordWrapNo	: "Ei",
+DlgCellHorAlign		: "Vaakakohdistus",
+DlgCellHorAlignNotSet	: "<Ei asetettu>",
+DlgCellHorAlignLeft	: "Vasemmalle",
+DlgCellHorAlignCenter	: "Keskelle",
+DlgCellHorAlignRight: "Oikealle",
+DlgCellVerAlign		: "Pystykohdistus",
+DlgCellVerAlignNotSet	: "<Ei asetettu>",
+DlgCellVerAlignTop	: "Ylös",
+DlgCellVerAlignMiddle	: "Keskelle",
+DlgCellVerAlignBottom	: "Alas",
+DlgCellVerAlignBaseline	: "Tekstin alas",
+DlgCellRowSpan		: "Rivin jatkuvuus",
+DlgCellCollSpan		: "Sarakkeen jatkuvuus",
+DlgCellBackColor	: "Taustaväri",
+DlgCellBorderColor	: "Rajan väri",
+DlgCellBtnSelect	: "Valitse...",
+
+// Find Dialog
+DlgFindTitle		: "Etsi",
+DlgFindFindBtn		: "Etsi",
+DlgFindNotFoundMsg	: "Etsittyä tekstiä ei löytynyt.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Korvaa",
+DlgReplaceFindLbl		: "Etsi mitä:",
+DlgReplaceReplaceLbl	: "Korvaa tällä:",
+DlgReplaceCaseChk		: "Sama kirjainkoko",
+DlgReplaceReplaceBtn	: "Korvaa",
+DlgReplaceReplAllBtn	: "Korvaa kaikki",
+DlgReplaceWordChk		: "Koko sana",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "Selaimesi turva-asetukset eivät salli editorin toteuttaa leikkaamista. Käytä näppäimistöä leikkaamiseen (Ctrl+X).",
+PasteErrorCopy	: "Selaimesi turva-asetukset eivät salli editorin toteuttaa kopioimista. Käytä näppäimistöä kopioimiseen (Ctrl+C).",
+
+PasteAsText		: "Liitä tekstinä",
+PasteFromWord	: "Liitä Wordista",
+
+DlgPasteMsg2	: "Liitä painamalla (<STRONG>Ctrl+V</STRONG>) ja painamalla <STRONG>OK</STRONG>.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Jätä huomioimatta fonttimääritykset",
+DlgPasteRemoveStyles	: "Poista tyylimääritykset",
+DlgPasteCleanBox		: "Tyhjennä",
+
+// Color Picker
+ColorAutomatic	: "Automaattinen",
+ColorMoreColors	: "Lisää värejä...",
+
+// Document Properties
+DocProps		: "Dokumentin ominaisuudet",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ankkurin ominaisuudet",
+DlgAnchorName		: "Nimi",
+DlgAnchorErrorName	: "Ankkurille on kirjoitettava nimi",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ei sanakirjassa",
+DlgSpellChangeTo		: "Vaihda",
+DlgSpellBtnIgnore		: "Jätä huomioimatta",
+DlgSpellBtnIgnoreAll	: "Jätä kaikki huomioimatta",
+DlgSpellBtnReplace		: "Korvaa",
+DlgSpellBtnReplaceAll	: "Korvaa kaikki",
+DlgSpellBtnUndo			: "Kumoa",
+DlgSpellNoSuggestions	: "Ei ehdotuksia",
+DlgSpellProgress		: "Tarkistus käynnissä...",
+DlgSpellNoMispell		: "Tarkistus valmis: Ei virheitä",
+DlgSpellNoChanges		: "Tarkistus valmis: Yhtään sanaa ei muutettu",
+DlgSpellOneChange		: "Tarkistus valmis: Yksi sana muutettiin",
+DlgSpellManyChanges		: "Tarkistus valmis: %1 sanaa muutettiin",
+
+IeSpellDownload			: "Oikeinkirjoituksen tarkistusta ei ole asennettu. Haluatko ladata sen nyt?",
+
+// Button Dialog
+DlgButtonText		: "Teksti (arvo)",
+DlgButtonType		: "Tyyppi",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nimi",
+DlgCheckboxValue	: "Arvo",
+DlgCheckboxSelected	: "Valittu",
+
+// Form Dialog
+DlgFormName		: "Nimi",
+DlgFormAction	: "Toiminto",
+DlgFormMethod	: "Tapa",
+
+// Select Field Dialog
+DlgSelectName		: "Nimi",
+DlgSelectValue		: "Arvo",
+DlgSelectSize		: "Koko",
+DlgSelectLines		: "Rivit",
+DlgSelectChkMulti	: "Salli usea valinta",
+DlgSelectOpAvail	: "Ominaisuudet",
+DlgSelectOpText		: "Teksti",
+DlgSelectOpValue	: "Arvo",
+DlgSelectBtnAdd		: "Lisää",
+DlgSelectBtnModify	: "Muuta",
+DlgSelectBtnUp		: "Ylös",
+DlgSelectBtnDown	: "Alas",
+DlgSelectBtnSetValue : "Aseta valituksi",
+DlgSelectBtnDelete	: "Poista",
+
+// Textarea Dialog
+DlgTextareaName	: "Nimi",
+DlgTextareaCols	: "Sarakkeita",
+DlgTextareaRows	: "Rivejä",
+
+// Text Field Dialog
+DlgTextName			: "Nimi",
+DlgTextValue		: "Arvo",
+DlgTextCharWidth	: "Leveys",
+DlgTextMaxChars		: "Maksimi merkkimäärä",
+DlgTextType			: "Tyyppi",
+DlgTextTypeText		: "Teksti",
+DlgTextTypePass		: "Salasana",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nimi",
+DlgHiddenValue	: "Arvo",
+
+// Bulleted List Dialog
+BulletedListProp	: "Luettelon ominaisuudet",
+NumberedListProp	: "Numeroinnin ominaisuudet",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tyyppi",
+DlgLstTypeCircle	: "Kehä",
+DlgLstTypeDisc		: "Ympyrä",
+DlgLstTypeSquare	: "Neliö",
+DlgLstTypeNumbers	: "Numerot (1, 2, 3)",
+DlgLstTypeLCase		: "Pienet kirjaimet (a, b, c)",
+DlgLstTypeUCase		: "Isot kirjaimet (A, B, C)",
+DlgLstTypeSRoman	: "Pienet roomalaiset numerot (i, ii, iii)",
+DlgLstTypeLRoman	: "Isot roomalaiset numerot (Ii, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Yleiset",
+DlgDocBackTab		: "Tausta",
+DlgDocColorsTab		: "Värit ja marginaalit",
+DlgDocMetaTab		: "Meta-tieto",
+
+DlgDocPageTitle		: "Sivun nimi",
+DlgDocLangDir		: "Kielen suunta",
+DlgDocLangDirLTR	: "Vasemmalta oikealle (LTR)",
+DlgDocLangDirRTL	: "Oikealta vasemmalle (RTL)",
+DlgDocLangCode		: "Kielikoodi",
+DlgDocCharSet		: "Merkistäkoodaus",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Muu merkistäkoodaus",
+
+DlgDocDocType		: "Dokumentin tyyppi",
+DlgDocDocTypeOther	: "Muu dokumentin tyyppi",
+DlgDocIncXHTML		: "Lisää XHTML julistukset",
+DlgDocBgColor		: "Taustaväri",
+DlgDocBgImage		: "Taustakuva",
+DlgDocBgNoScroll	: "Paikallaanpysyvä tausta",
+DlgDocCText			: "Teksti",
+DlgDocCLink			: "Linkki",
+DlgDocCVisited		: "Vierailtu linkki",
+DlgDocCActive		: "Aktiivinen linkki",
+DlgDocMargins		: "Sivun marginaalit",
+DlgDocMaTop			: "Ylä",
+DlgDocMaLeft		: "Vasen",
+DlgDocMaRight		: "Oikea",
+DlgDocMaBottom		: "Ala",
+DlgDocMeIndex		: "Hakusanat (pilkulla erotettuna)",
+DlgDocMeDescr		: "Kuvaus",
+DlgDocMeAuthor		: "Tekijä",
+DlgDocMeCopy		: "Tekijänoikeudet",
+DlgDocPreview		: "Esikatselu",
+
+// Templates Dialog
+Templates			: "Pohjat",
+DlgTemplatesTitle	: "Sisältöpohjat",
+DlgTemplatesSelMsg	: "Valitse pohja editoriin<br>(aiempi sisältö menetetään):",
+DlgTemplatesLoading	: "Ladataan listaa pohjista. Hetkinen...",
+DlgTemplatesNoTpl	: "(Ei määriteltyjä pohjia)",
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Editorista",
+DlgAboutBrowserInfoTab	: "Selaimen tiedot",
+DlgAboutLicenseTab	: "Lisenssi",
+DlgAboutVersion		: "versio",
+DlgAboutInfo		: "Lisää tietoa osoitteesta"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hi.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hi.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/hi.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Hindi language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "टूलबार सिमटायें",
+ToolbarExpand		: "टूलबार का विस्तार करें",
+
+// Toolbar Items and Context Menu
+Save				: "सेव",
+NewPage				: "नया पेज",
+Preview				: "प्रीव्यू",
+Cut					: "कट",
+Copy				: "कॉपी",
+Paste				: "पेस्ट",
+PasteText			: "पेस्ट (सादा टॅक्स्ट)",
+PasteWord			: "पेस्ट (वर्ड से)",
+Print				: "प्रिन्ट",
+SelectAll			: "सब सॅलॅक्ट करें",
+RemoveFormat		: "फ़ॉर्मैट हटायें",
+InsertLinkLbl		: "लिंक",
+InsertLink			: "लिंक इन्सर्ट/संपादन",
+RemoveLink			: "लिंक हटायें",
+Anchor				: "ऐंकर इन्सर्ट/संपादन",
+InsertImageLbl		: "तस्वीर",
+InsertImage			: "तस्वीर इन्सर्ट/संपादन",
+InsertFlashLbl		: "फ़्लैश",
+InsertFlash			: "फ़्लैश इन्सर्ट/संपादन",
+InsertTableLbl		: "टेबल",
+InsertTable			: "टेबल इन्सर्ट/संपादन",
+InsertLineLbl		: "रेखा",
+InsertLine			: "हॉरिज़ॉन्टल रेखा इन्सर्ट करें",
+InsertSpecialCharLbl: "विशेष करॅक्टर",
+InsertSpecialChar	: "विशेष करॅक्टर इन्सर्ट करें",
+InsertSmileyLbl		: "स्माइली",
+InsertSmiley		: "स्माइली इन्सर्ट करें",
+About				: "FCKeditor के बारे में",
+Bold				: "बोल्ड",
+Italic				: "इटैलिक",
+Underline			: "रेखांकण",
+StrikeThrough		: "स्ट्राइक थ्रू",
+Subscript			: "अधोलेख",
+Superscript			: "अभिलेख",
+LeftJustify			: "बायीं तरफ",
+CenterJustify		: "बीच में",
+RightJustify		: "दायीं तरफ",
+BlockJustify		: "ब्लॉक जस्टीफ़ाई",
+DecreaseIndent		: "इन्डॅन्ट कम करें",
+IncreaseIndent		: "इन्डॅन्ट बढ़ायें",
+Undo				: "अन्डू",
+Redo				: "रीडू",
+NumberedListLbl		: "अंकीय सूची",
+NumberedList		: "अंकीय सूची इन्सर्ट/संपादन",
+BulletedListLbl		: "बुलॅट सूची",
+BulletedList		: "बुलॅट सूची इन्सर्ट/संपादन",
+ShowTableBorders	: "टेबल बॉर्डरयें दिखायें",
+ShowDetails			: "ज्यादा   दिखायें",
+Style				: "स्टाइल",
+FontFormat			: "फ़ॉर्मैट",
+Font				: "फ़ॉन्ट",
+FontSize			: "साइज़",
+TextColor			: "टेक्स्ट रंग",
+BGColor				: "बैक्ग्राउन्ड रंग",
+Source				: "सोर्स",
+Find				: "खोजें",
+Replace				: "रीप्लेस",
+SpellCheck			: "वर्तनी (स्पेलिंग) जाँच",
+UniversalKeyboard	: "यूनीवर्सल कीबोर्ड",
+PageBreakLbl		: "पेज ब्रेक",
+PageBreak			: "पेज ब्रेक इन्सर्ट् करें",
+
+Form			: "फ़ॉर्म",
+Checkbox		: "चॅक बॉक्स",
+RadioButton		: "रेडिओ बटन",
+TextField		: "टेक्स्ट फ़ील्ड",
+Textarea		: "टेक्स्ट एरिया",
+HiddenField		: "गुप्त फ़ील्ड",
+Button			: "बटन",
+SelectionField	: "चुनाव फ़ील्ड",
+ImageButton		: "तस्वीर बटन",
+
+FitWindow		: "एडिटर साइज़ को चरम सीमा तक बढ़ायें",
+
+// Context Menu
+EditLink			: "लिंक संपादन",
+CellCM				: "खाना",
+RowCM				: "पंक्ति",
+ColumnCM			: "कालम",
+InsertRow			: "पंक्ति इन्सर्ट करें",
+DeleteRows			: "पंक्तियाँ डिलीट करें",
+InsertColumn		: "कॉलम इन्सर्ट करें",
+DeleteColumns		: "कॉलम डिलीट करें",
+InsertCell			: "सॅल इन्सर्ट करें",
+DeleteCells			: "सॅल डिलीट करें",
+MergeCells			: "सॅल मिलायें",
+SplitCell			: "सॅल अलग करें",
+TableDelete			: "टेबल डिलीट करें",
+CellProperties		: "सॅल प्रॉपर्टीज़",
+TableProperties		: "टेबल प्रॉपर्टीज़",
+ImageProperties		: "तस्वीर प्रॉपर्टीज़",
+FlashProperties		: "फ़्लैश प्रॉपर्टीज़",
+
+AnchorProp			: "ऐंकर प्रॉपर्टीज़",
+ButtonProp			: "बटन प्रॉपर्टीज़",
+CheckboxProp		: "चॅक बॉक्स प्रॉपर्टीज़",
+HiddenFieldProp		: "गुप्त फ़ील्ड प्रॉपर्टीज़",
+RadioButtonProp		: "रेडिओ बटन प्रॉपर्टीज़",
+ImageButtonProp		: "तस्वीर बटन प्रॉपर्टीज़",
+TextFieldProp		: "टेक्स्ट फ़ील्ड प्रॉपर्टीज़",
+SelectionFieldProp	: "चुनाव फ़ील्ड प्रॉपर्टीज़",
+TextareaProp		: "टेक्स्त एरिया प्रॉपर्टीज़",
+FormProp			: "फ़ॉर्म प्रॉपर्टीज़",
+
+FontFormats			: "साधारण;फ़ॉर्मैटॅड;पता;शीर्षक 1;शीर्षक 2;शीर्षक 3;शीर्षक 4;शीर्षक 5;शीर्षक 6;शीर्षक (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "XHTML प्रोसॅस हो रहा है। ज़रा ठहरें...",
+Done				: "पूरा हुआ",
+PasteWordConfirm	: "आप जो टेक्स्ट पेस्ट करना चाहते हैं, वह वर्ड से कॉपी किया हुआ लग रहा है। क्या पेस्ट करने से पहले आप इसे साफ़ करना चाहेंगे?",
+NotCompatiblePaste	: "यह कमांड इन्टरनॅट एक्स्प्लोरर(Internet Explorer) 5.5 या उसके बाद के वर्ज़न के लिए ही उपलब्ध है। क्या आप बिना साफ़ किए पेस्ट करना चाहेंगे?",
+UnknownToolbarItem	: "अनजान टूलबार आइटम \"%1\"",
+UnknownCommand		: "अनजान कमान्ड \"%1\"",
+NotImplemented		: "कमान्ड इम्प्लीमॅन्ट नहीं किया गया है",
+UnknownToolbarSet	: "टूलबार सॅट \"%1\" उपलब्ध नहीं है",
+NoActiveX			: "आपके ब्राउज़र् की सुरक्शा सेटिंग्स् एडिटर की कुछ् फ़ीचरों को सीमित कर् सकती हैं। क्रिपया \"Run ActiveX controls and plug-ins\" विकल्प को एनेबल करें. आपको एरर्स् और गायब फ़ीचर्स् का अनुभव हो सकता है।",
+BrowseServerBlocked : "रिसोर्सेज़ ब्राउज़र् नहीं खोला जा सका। क्रिपया सभी पॉप्-अप् ब्लॉकर्स् को डिसेबल करें।",
+DialogBlocked		: "डायलग विन्डो नहीं खोला जा सका। क्रिपया सभी पॉप्-अप् ब्लॉकर्स् को डिसेबल करें।",
+
+// Dialogs
+DlgBtnOK			: "ठीक है",
+DlgBtnCancel		: "रद्द करें",
+DlgBtnClose			: "बन्द करें",
+DlgBtnBrowseServer	: "सर्वर ब्राउज़ करें",
+DlgAdvancedTag		: "ऍड्वान्स्ड",
+DlgOpOther			: "<अन्य>",
+DlgInfoTab			: "सूचना",
+DlgAlertUrl			: "URL इन्सर्ट करें",
+
+// General Dialogs Labels
+DlgGenNotSet		: "<सॅट नहीं>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "भाषा लिखने की दिशा",
+DlgGenLangDirLtr	: "बायें से दायें (LTR)",
+DlgGenLangDirRtl	: "दायें से बायें (RTL)",
+DlgGenLangCode		: "भाषा कोड",
+DlgGenAccessKey		: "ऍक्सॅस की",
+DlgGenName			: "नाम",
+DlgGenTabIndex		: "टैब इन्डॅक्स",
+DlgGenLongDescr		: "अधिक विवरण के लिए URL",
+DlgGenClass			: "स्टाइल-शीट क्लास",
+DlgGenTitle			: "परामर्श शीर्शक",
+DlgGenContType		: "परामर्श कन्टॅन्ट प्रकार",
+DlgGenLinkCharset	: "लिंक रिसोर्स करॅक्टर सॅट",
+DlgGenStyle			: "स्टाइल",
+
+// Image Dialog
+DlgImgTitle			: "तस्वीर प्रॉपर्टीज़",
+DlgImgInfoTab		: "तस्वीर की जानकारी",
+DlgImgBtnUpload		: "इसे सर्वर को भेजें",
+DlgImgURL			: "URL",
+DlgImgUpload		: "अपलोड",
+DlgImgAlt			: "वैकल्पिक टेक्स्ट",
+DlgImgWidth			: "चौड़ाई",
+DlgImgHeight		: "ऊँचाई",
+DlgImgLockRatio		: "लॉक अनुपात",
+DlgBtnResetSize		: "रीसॅट साइज़",
+DlgImgBorder		: "बॉर्डर",
+DlgImgHSpace		: "हॉरिज़ॉन्टल स्पेस",
+DlgImgVSpace		: "वर्टिकल स्पेस",
+DlgImgAlign			: "ऍलाइन",
+DlgImgAlignLeft		: "दायें",
+DlgImgAlignAbsBottom: "Abs नीचे",
+DlgImgAlignAbsMiddle: "Abs ऊपर",
+DlgImgAlignBaseline	: "मूल रेखा",
+DlgImgAlignBottom	: "नीचे",
+DlgImgAlignMiddle	: "मध्य",
+DlgImgAlignRight	: "दायें",
+DlgImgAlignTextTop	: "टेक्स्ट ऊपर",
+DlgImgAlignTop		: "ऊपर",
+DlgImgPreview		: "प्रीव्यू",
+DlgImgAlertUrl		: "तस्वीर का URL टाइप करें ",
+DlgImgLinkTab		: "लिंक",
+
+// Flash Dialog
+DlgFlashTitle		: "फ़्लैश प्रॉपर्टीज़",
+DlgFlashChkPlay		: "ऑटो प्ले",
+DlgFlashChkLoop		: "लूप",
+DlgFlashChkMenu		: "फ़्लैश मॅन्यू का प्रयोग करें",
+DlgFlashScale		: "स्केल",
+DlgFlashScaleAll	: "सभी दिखायें",
+DlgFlashScaleNoBorder	: "कोई बॉर्डर नहीं",
+DlgFlashScaleFit	: "बिल्कुल फ़िट",
+
+// Link Dialog
+DlgLnkWindowTitle	: "लिंक",
+DlgLnkInfoTab		: "लिंक  ",
+DlgLnkTargetTab		: "टार्गेट",
+
+DlgLnkType			: "लिंक प्रकार",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "इस पेज का ऐंकर",
+DlgLnkTypeEMail		: "ई-मेल",
+DlgLnkProto			: "प्रोटोकॉल",
+DlgLnkProtoOther	: "<अन्य>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "ऐंकर चुनें",
+DlgLnkAnchorByName	: "ऐंकर नाम से",
+DlgLnkAnchorById	: "ऍलीमॅन्ट Id से",
+DlgLnkNoAnchors		: "<डॉक्यूमॅन्ट में ऐंकर्स की संख्या>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "ई-मेल पता",
+DlgLnkEMailSubject	: "संदेश विषय",
+DlgLnkEMailBody		: "संदेश",
+DlgLnkUpload		: "अपलोड",
+DlgLnkBtnUpload		: "इसे सर्वर को भेजें",
+
+DlgLnkTarget		: "टार्गेट",
+DlgLnkTargetFrame	: "<फ़्रेम>",
+DlgLnkTargetPopup	: "<पॉप-अप विन्डो>",
+DlgLnkTargetBlank	: "नया विन्डो (_blank)",
+DlgLnkTargetParent	: "मूल विन्डो (_parent)",
+DlgLnkTargetSelf	: "इसी विन्डो (_self)",
+DlgLnkTargetTop		: "शीर्ष विन्डो (_top)",
+DlgLnkTargetFrameName	: "टार्गेट फ़्रेम का नाम",
+DlgLnkPopWinName	: "पॉप-अप विन्डो का नाम",
+DlgLnkPopWinFeat	: "पॉप-अप विन्डो फ़ीचर्स",
+DlgLnkPopResize		: "साइज़ बदला जा सकता है",
+DlgLnkPopLocation	: "लोकेशन बार",
+DlgLnkPopMenu		: "मॅन्यू बार",
+DlgLnkPopScroll		: "स्क्रॉल बार",
+DlgLnkPopStatus		: "स्टेटस बार",
+DlgLnkPopToolbar	: "टूल बार",
+DlgLnkPopFullScrn	: "फ़ुल स्क्रीन (IE)",
+DlgLnkPopDependent	: "डिपेन्डॅन्ट (Netscape)",
+DlgLnkPopWidth		: "चौड़ाई",
+DlgLnkPopHeight		: "ऊँचाई",
+DlgLnkPopLeft		: "बायीं तरफ",
+DlgLnkPopTop		: "दायीं तरफ",
+
+DlnLnkMsgNoUrl		: "लिंक URL टाइप करें",
+DlnLnkMsgNoEMail	: "ई-मेल पता टाइप करें",
+DlnLnkMsgNoAnchor	: "ऐंकर चुनें",
+DlnLnkMsgInvPopName	: "पॉप-अप का नाम अल्फाबेट से शुरू होना चाहिये और उसमें स्पेस नहीं होने चाहिए",
+
+// Color Dialog
+DlgColorTitle		: "रंग चुनें",
+DlgColorBtnClear	: "साफ़ करें",
+DlgColorHighlight	: "हाइलाइट",
+DlgColorSelected	: "सॅलॅक्टॅड",
+
+// Smiley Dialog
+DlgSmileyTitle		: "स्माइली इन्सर्ट करें",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "विशेष करॅक्टर चुनें",
+
+// Table Dialog
+DlgTableTitle		: "टेबल प्रॉपर्टीज़",
+DlgTableRows		: "पंक्तियाँ",
+DlgTableColumns		: "कॉलम",
+DlgTableBorder		: "बॉर्डर साइज़",
+DlgTableAlign		: "ऍलाइन्मॅन्ट",
+DlgTableAlignNotSet	: "<सॅट नहीं>",
+DlgTableAlignLeft	: "दायें",
+DlgTableAlignCenter	: "बीच में",
+DlgTableAlignRight	: "बायें",
+DlgTableWidth		: "चौड़ाई",
+DlgTableWidthPx		: "पिक्सॅल",
+DlgTableWidthPc		: "प्रतिशत",
+DlgTableHeight		: "ऊँचाई",
+DlgTableCellSpace	: "सॅल अंतर",
+DlgTableCellPad		: "सॅल पैडिंग",
+DlgTableCaption		: "शीर्षक",
+DlgTableSummary		: "सारांश",
+
+// Table Cell Dialog
+DlgCellTitle		: "सॅल प्रॉपर्टीज़",
+DlgCellWidth		: "चौड़ाई",
+DlgCellWidthPx		: "पिक्सॅल",
+DlgCellWidthPc		: "प्रतिशत",
+DlgCellHeight		: "ऊँचाई",
+DlgCellWordWrap		: "वर्ड रैप",
+DlgCellWordWrapNotSet	: "<सॅट नहीं>",
+DlgCellWordWrapYes	: "हाँ",
+DlgCellWordWrapNo	: "नहीं",
+DlgCellHorAlign		: "हॉरिज़ॉन्टल ऍलाइन्मॅन्ट",
+DlgCellHorAlignNotSet	: "<सॅट नहीं>",
+DlgCellHorAlignLeft	: "दायें",
+DlgCellHorAlignCenter	: "बीच में",
+DlgCellHorAlignRight: "बायें",
+DlgCellVerAlign		: "वर्टिकल ऍलाइन्मॅन्ट",
+DlgCellVerAlignNotSet	: "<सॅट नहीं>",
+DlgCellVerAlignTop	: "ऊपर",
+DlgCellVerAlignMiddle	: "मध्य",
+DlgCellVerAlignBottom	: "नीचे",
+DlgCellVerAlignBaseline	: "मूलरेखा",
+DlgCellRowSpan		: "पंक्ति स्पैन",
+DlgCellCollSpan		: "कॉलम स्पैन",
+DlgCellBackColor	: "बैक्ग्राउन्ड रंग",
+DlgCellBorderColor	: "बॉर्डर का रंग",
+DlgCellBtnSelect	: "चुनें...",
+
+// Find Dialog
+DlgFindTitle		: "खोजें",
+DlgFindFindBtn		: "खोजें",
+DlgFindNotFoundMsg	: "आपके द्वारा दिया गया टेक्स्ट नहीं मिला",
+
+// Replace Dialog
+DlgReplaceTitle			: "रिप्लेस",
+DlgReplaceFindLbl		: "यह खोजें:",
+DlgReplaceReplaceLbl	: "इससे रिप्लेस करें:",
+DlgReplaceCaseChk		: "केस मिलायें",
+DlgReplaceReplaceBtn	: "रिप्लेस",
+DlgReplaceReplAllBtn	: "सभी रिप्लेस करें",
+DlgReplaceWordChk		: "पूरा शब्द मिलायें",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "आपके ब्राउज़र की सुरक्षा सॅटिन्ग्स ने कट करने की अनुमति नहीं प्रदान की है। (Ctrl+X) का प्रयोग करें।",
+PasteErrorCopy	: "आपके ब्राआउज़र की सुरक्षा सॅटिन्ग्स ने कॉपी करने की अनुमति नहीं प्रदान की है। (Ctrl+C) का प्रयोग करें।",
+
+PasteAsText		: "पेस्ट (सादा टॅक्स्ट)",
+PasteFromWord	: "पेस्ट (वर्ड से)",
+
+DlgPasteMsg2	: "Ctrl+V का प्रयोग करके पेस्ट करें और ठीक है करें.",
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "फ़ॉन्ट परिभाषा निकालें",
+DlgPasteRemoveStyles	: "स्टाइल परिभाषा निकालें",
+DlgPasteCleanBox		: "बॉक्स साफ़ करें",
+
+// Color Picker
+ColorAutomatic	: "ऑटोमैटिक",
+ColorMoreColors	: "और रंग...",
+
+// Document Properties
+DocProps		: "डॉक्यूमॅन्ट प्रॉपर्टीज़",
+
+// Anchor Dialog
+DlgAnchorTitle		: "ऐंकर प्रॉपर्टीज़",
+DlgAnchorName		: "ऐंकर का नाम",
+DlgAnchorErrorName	: "ऐंकर का नाम टाइप करें",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "शब्दकोश में नहीं",
+DlgSpellChangeTo		: "इसमें बदलें",
+DlgSpellBtnIgnore		: "इग्नोर",
+DlgSpellBtnIgnoreAll	: "सभी इग्नोर करें",
+DlgSpellBtnReplace		: "रिप्लेस",
+DlgSpellBtnReplaceAll	: "सभी रिप्लेस करें",
+DlgSpellBtnUndo			: "अन्डू",
+DlgSpellNoSuggestions	: "- कोई सुझाव नहीं -",
+DlgSpellProgress		: "वर्तनी की जाँच (स्पॅल-चॅक) जारी है...",
+DlgSpellNoMispell		: "वर्तनी की जाँच : कोई गलत वर्तनी (स्पॅलिंग) नहीं पाई गई",
+DlgSpellNoChanges		: "वर्तनी की जाँच :कोई शब्द नहीं बदला गया",
+DlgSpellOneChange		: "वर्तनी की जाँच : एक शब्द बदला गया",
+DlgSpellManyChanges		: "वर्तनी की जाँच : %1 शब्द बदले गये",
+
+IeSpellDownload			: "स्पॅल-चॅकर इन्स्टाल नहीं किया गया है। क्या आप इसे डा‌उनलोड करना चाहेंगे?",
+
+// Button Dialog
+DlgButtonText		: "टेक्स्ट (वैल्यू)",
+DlgButtonType		: "प्रकार",
+DlgButtonTypeBtn	: "बटन",
+DlgButtonTypeSbm	: "सब्मिट",
+DlgButtonTypeRst	: "रिसेट",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "नाम",
+DlgCheckboxValue	: "वैल्यू",
+DlgCheckboxSelected	: "सॅलॅक्टॅड",
+
+// Form Dialog
+DlgFormName		: "नाम",
+DlgFormAction	: "ऍक्शन",
+DlgFormMethod	: "तरीका",
+
+// Select Field Dialog
+DlgSelectName		: "नाम",
+DlgSelectValue		: "वैल्यू",
+DlgSelectSize		: "साइज़",
+DlgSelectLines		: "पंक्तियाँ",
+DlgSelectChkMulti	: "एक से ज्यादा विकल्प चुनने दें",
+DlgSelectOpAvail	: "उपलब्ध विकल्प",
+DlgSelectOpText		: "टेक्स्ट",
+DlgSelectOpValue	: "वैल्यू",
+DlgSelectBtnAdd		: "जोड़ें",
+DlgSelectBtnModify	: "बदलें",
+DlgSelectBtnUp		: "ऊपर",
+DlgSelectBtnDown	: "नीचे",
+DlgSelectBtnSetValue : "चुनी गई वैल्यू सॅट करें",
+DlgSelectBtnDelete	: "डिलीट",
+
+// Textarea Dialog
+DlgTextareaName	: "नाम",
+DlgTextareaCols	: "कॉलम",
+DlgTextareaRows	: "पंक्तियां",
+
+// Text Field Dialog
+DlgTextName			: "नाम",
+DlgTextValue		: "वैल्यू",
+DlgTextCharWidth	: "करॅक्टर की चौढ़ाई",
+DlgTextMaxChars		: "अधिकतम करॅक्टर",
+DlgTextType			: "टाइप",
+DlgTextTypeText		: "टेक्स्ट",
+DlgTextTypePass		: "पास्वर्ड",
+
+// Hidden Field Dialog
+DlgHiddenName	: "नाम",
+DlgHiddenValue	: "वैल्यू",
+
+// Bulleted List Dialog
+BulletedListProp	: "बुलॅट सूची प्रॉपर्टीज़",
+NumberedListProp	: "अंकीय सूची प्रॉपर्टीज़",
+DlgLstStart			: "प्रारम्भ",
+DlgLstType			: "प्रकार",
+DlgLstTypeCircle	: "गोल",
+DlgLstTypeDisc		: "डिस्क",
+DlgLstTypeSquare	: "चौकॊण",
+DlgLstTypeNumbers	: "अंक (1, 2, 3)",
+DlgLstTypeLCase		: "छोटे अक्षर (a, b, c)",
+DlgLstTypeUCase		: "बड़े अक्षर (A, B, C)",
+DlgLstTypeSRoman	: "छोटे रोमन अंक (i, ii, iii)",
+DlgLstTypeLRoman	: "बड़े रोमन अंक (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "आम",
+DlgDocBackTab		: "बैक्ग्राउन्ड",
+DlgDocColorsTab		: "रंग और मार्जिन",
+DlgDocMetaTab		: "मॅटाडेटा",
+
+DlgDocPageTitle		: "पेज शीर्षक",
+DlgDocLangDir		: "भाषा लिखने की दिशा",
+DlgDocLangDirLTR	: "बायें से दायें (LTR)",
+DlgDocLangDirRTL	: "दायें से बायें (RTL)",
+DlgDocLangCode		: "भाषा कोड",
+DlgDocCharSet		: "करेक्टर सॅट ऍन्कोडिंग",
+DlgDocCharSetCE		: "मध्य यूरोपीय (Central European)",
+DlgDocCharSetCT		: "चीनी (Chinese Traditional Big5)",
+DlgDocCharSetCR		: "सिरीलिक (Cyrillic)",
+DlgDocCharSetGR		: "यवन (Greek)",
+DlgDocCharSetJP		: "जापानी (Japanese)",
+DlgDocCharSetKR		: "कोरीयन (Korean)",
+DlgDocCharSetTR		: "तुर्की (Turkish)",
+DlgDocCharSetUN		: "यूनीकोड (UTF-8)",
+DlgDocCharSetWE		: "पश्चिम यूरोपीय (Western European)",
+DlgDocCharSetOther	: "अन्य करेक्टर सॅट ऍन्कोडिंग",
+
+DlgDocDocType		: "डॉक्यूमॅन्ट प्रकार शीर्षक",
+DlgDocDocTypeOther	: "अन्य डॉक्यूमॅन्ट प्रकार शीर्षक",
+DlgDocIncXHTML		: "XHTML सूचना सम्मिलित करें",
+DlgDocBgColor		: "बैक्ग्राउन्ड रंग",
+DlgDocBgImage		: "बैक्ग्राउन्ड तस्वीर URL",
+DlgDocBgNoScroll	: "स्क्रॉल न करने वाला बैक्ग्राउन्ड",
+DlgDocCText			: "टेक्स्ट",
+DlgDocCLink			: "लिंक",
+DlgDocCVisited		: "विज़िट किया गया लिंक",
+DlgDocCActive		: "सक्रिय लिंक",
+DlgDocMargins		: "पेज मार्जिन",
+DlgDocMaTop			: "ऊपर",
+DlgDocMaLeft		: "बायें",
+DlgDocMaRight		: "दायें",
+DlgDocMaBottom		: "नीचे",
+DlgDocMeIndex		: "डॉक्युमॅन्ट इन्डेक्स संकेतशब्द (अल्पविराम से अलग करें)",
+DlgDocMeDescr		: "डॉक्यूमॅन्ट करॅक्टरन",
+DlgDocMeAuthor		: "लेखक",
+DlgDocMeCopy		: "कॉपीराइट",
+DlgDocPreview		: "प्रीव्यू",
+
+// Templates Dialog
+Templates			: "टॅम्प्लेट",
+DlgTemplatesTitle	: "कन्टेन्ट टॅम्प्लेट",
+DlgTemplatesSelMsg	: "ऍडिटर में ओपन करने हेतु टॅम्प्लेट चुनें(वर्तमान कन्टॅन्ट सेव नहीं होंगे):",
+DlgTemplatesLoading	: "टॅम्प्लेट सूची लोड की जा रही है। ज़रा ठहरें...",
+DlgTemplatesNoTpl	: "(कोई टॅम्प्लेट डिफ़ाइन नहीं किया गया है)",
+DlgTemplatesReplace	: "मूल शब्दों को बदलें",
+
+// About Dialog
+DlgAboutAboutTab	: "FCKEditor के बारे में",
+DlgAboutBrowserInfoTab	: "ब्राउज़र के बारे में",
+DlgAboutLicenseTab	: "लाइसैन्स",
+DlgAboutVersion		: "वर्ज़न",
+DlgAboutInfo		: "अधिक जानकारी के लिये यहाँ जायें:"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/lang/eo.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/lang/eo.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/lang/eo.js	(revision 795)
@@ -0,0 +1,504 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Esperanto language file.
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir					: "ltr",
+
+ToolbarCollapse		: "Kaŝi Ilobreton",
+ToolbarExpand		: "Vidigi Ilojn",
+
+// Toolbar Items and Context Menu
+Save				: "Sekurigi",
+NewPage				: "Nova Paĝo",
+Preview				: "Vidigi Aspekton",
+Cut					: "Eltondi",
+Copy				: "Kopii",
+Paste				: "Interglui",
+PasteText			: "Interglui kiel Tekston",
+PasteWord			: "Interglui el Word",
+Print				: "Presi",
+SelectAll			: "Elekti ĉion",
+RemoveFormat		: "Forigi Formaton",
+InsertLinkLbl		: "Ligilo",
+InsertLink			: "Enmeti/Ŝanĝi Ligilon",
+RemoveLink			: "Forigi Ligilon",
+Anchor				: "Enmeti/Ŝanĝi Ankron",
+InsertImageLbl		: "Bildo",
+InsertImage			: "Enmeti/Ŝanĝi Bildon",
+InsertFlashLbl		: "Flash",	//MISSING
+InsertFlash			: "Insert/Edit Flash",	//MISSING
+InsertTableLbl		: "Tabelo",
+InsertTable			: "Enmeti/Ŝanĝi Tabelon",
+InsertLineLbl		: "Horizonta Linio",
+InsertLine			: "Enmeti Horizonta Linio",
+InsertSpecialCharLbl: "Speciala Signo",
+InsertSpecialChar	: "Enmeti Specialan Signon",
+InsertSmileyLbl		: "Mienvinjeto",
+InsertSmiley		: "Enmeti Mienvinjeton",
+About				: "Pri FCKeditor",
+Bold				: "Grasa",
+Italic				: "Kursiva",
+Underline			: "Substreko",
+StrikeThrough		: "Trastreko",
+Subscript			: "Subskribo",
+Superscript			: "Superskribo",
+LeftJustify			: "Maldekstrigi",
+CenterJustify		: "Centrigi",
+RightJustify		: "Dekstrigi",
+BlockJustify		: "Ĝisrandigi Ambaŭflanke",
+DecreaseIndent		: "Malpligrandigi Krommarĝenon",
+IncreaseIndent		: "Pligrandigi Krommarĝenon",
+Undo				: "Malfari",
+Redo				: "Refari",
+NumberedListLbl		: "Numera Listo",
+NumberedList		: "Enmeti/Forigi Numeran Liston",
+BulletedListLbl		: "Bula Listo",
+BulletedList		: "Enmeti/Forigi Bulan Liston",
+ShowTableBorders	: "Vidigi Borderojn de Tabelo",
+ShowDetails			: "Vidigi Detalojn",
+Style				: "Stilo",
+FontFormat			: "Formato",
+Font				: "Tiparo",
+FontSize			: "Grando",
+TextColor			: "Teksta Koloro",
+BGColor				: "Fona Koloro",
+Source				: "Fonto",
+Find				: "Serĉi",
+Replace				: "Anstataŭigi",
+SpellCheck			: "Literumada Kontrolilo",
+UniversalKeyboard	: "Universala Klavaro",
+PageBreakLbl		: "Page Break",	//MISSING
+PageBreak			: "Insert Page Break",	//MISSING
+
+Form			: "Formularo",
+Checkbox		: "Markobutono",
+RadioButton		: "Radiobutono",
+TextField		: "Teksta kampo",
+Textarea		: "Teksta Areo",
+HiddenField		: "Kaŝita Kampo",
+Button			: "Butono",
+SelectionField	: "Elekta Kampo",
+ImageButton		: "Bildbutono",
+
+FitWindow		: "Maximize the editor size",	//MISSING
+
+// Context Menu
+EditLink			: "Modifier Ligilon",
+CellCM				: "Cell",	//MISSING
+RowCM				: "Row",	//MISSING
+ColumnCM			: "Column",	//MISSING
+InsertRow			: "Enmeti Linion",
+DeleteRows			: "Forigi Liniojn",
+InsertColumn		: "Enmeti Kolumnon",
+DeleteColumns		: "Forigi Kolumnojn",
+InsertCell			: "Enmeti Ĉelon",
+DeleteCells			: "Forigi Ĉelojn",
+MergeCells			: "Kunfandi Ĉelojn",
+SplitCell			: "Dividi Ĉelojn",
+TableDelete			: "Delete Table",	//MISSING
+CellProperties		: "Atributoj de Ĉelo",
+TableProperties		: "Atributoj de Tabelo",
+ImageProperties		: "Atributoj de Bildo",
+FlashProperties		: "Flash Properties",	//MISSING
+
+AnchorProp			: "Ankraj Atributoj",
+ButtonProp			: "Butonaj Atributoj",
+CheckboxProp		: "Markobutonaj Atributoj",
+HiddenFieldProp		: "Atributoj de Kaŝita Kampo",
+RadioButtonProp		: "Radiobutonaj Atributoj",
+ImageButtonProp		: "Bildbutonaj Atributoj",
+TextFieldProp		: "Atributoj de Teksta Kampo",
+SelectionFieldProp	: "Atributoj de Elekta Kampo",
+TextareaProp		: "Atributoj de Teksta Areo",
+FormProp			: "Formularaj Atributoj",
+
+FontFormats			: "Normala;Formatita;Adreso;Titolo 1;Titolo 2;Titolo 3;Titolo 4;Titolo 5;Titolo 6;Paragrafo (DIV)",		//REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML		: "Traktado de XHTML. Bonvolu pacienci...",
+Done				: "Finita",
+PasteWordConfirm	: "La algluota teksto ŝajnas esti Word-devena. Ĉu vi volas purigi ĝin antaŭ ol interglui?",
+NotCompatiblePaste	: "Tiu ĉi komando bezonas almenaŭ Internet Explorer 5.5. Ĉu vi volas daŭrigi sen purigado?",
+UnknownToolbarItem	: "Ilobretero nekonata \"%1\"",
+UnknownCommand		: "Komandonomo nekonata \"%1\"",
+NotImplemented		: "Komando ne ankoraŭ realigita",
+UnknownToolbarSet	: "La ilobreto \"%1\" ne ekzistas",
+NoActiveX			: "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",	//MISSING
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",	//MISSING
+DialogBlocked		: "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",	//MISSING
+
+// Dialogs
+DlgBtnOK			: "Akcepti",
+DlgBtnCancel		: "Rezigni",
+DlgBtnClose			: "Fermi",
+DlgBtnBrowseServer	: "Foliumi en la Servilo",
+DlgAdvancedTag		: "Speciala",
+DlgOpOther			: "<Alia>",
+DlgInfoTab			: "Info",	//MISSING
+DlgAlertUrl			: "Please insert the URL",	//MISSING
+
+// General Dialogs Labels
+DlgGenNotSet		: "<Defaŭlta>",
+DlgGenId			: "Id",
+DlgGenLangDir		: "Skribdirekto",
+DlgGenLangDirLtr	: "De maldekstro dekstren (LTR)",
+DlgGenLangDirRtl	: "De dekstro maldekstren (RTL)",
+DlgGenLangCode		: "Lingva Kodo",
+DlgGenAccessKey		: "Fulmoklavo",
+DlgGenName			: "Nomo",
+DlgGenTabIndex		: "Taba Ordo",
+DlgGenLongDescr		: "URL de Longa Priskribo",
+DlgGenClass			: "Klasoj de Stilfolioj",
+DlgGenTitle			: "Indika Titolo",
+DlgGenContType		: "Indika Enhavotipo",
+DlgGenLinkCharset	: "Signaro de la Ligita Rimedo",
+DlgGenStyle			: "Stilo",
+
+// Image Dialog
+DlgImgTitle			: "Atributoj de Bildo",
+DlgImgInfoTab		: "Informoj pri Bildo",
+DlgImgBtnUpload		: "Sendu al Servilo",
+DlgImgURL			: "URL",
+DlgImgUpload		: "Alŝuti",
+DlgImgAlt			: "Anstataŭiga Teksto",
+DlgImgWidth			: "Larĝo",
+DlgImgHeight		: "Alto",
+DlgImgLockRatio		: "Konservi Proporcion",
+DlgBtnResetSize		: "Origina Grando",
+DlgImgBorder		: "Bordero",
+DlgImgHSpace		: "HSpaco",
+DlgImgVSpace		: "VSpaco",
+DlgImgAlign			: "Ĝisrandigo",
+DlgImgAlignLeft		: "Maldekstre",
+DlgImgAlignAbsBottom: "Abs Malsupre",
+DlgImgAlignAbsMiddle: "Abs Centre",
+DlgImgAlignBaseline	: "Je Malsupro de Teksto",
+DlgImgAlignBottom	: "Malsupre",
+DlgImgAlignMiddle	: "Centre",
+DlgImgAlignRight	: "Dekstre",
+DlgImgAlignTextTop	: "Je Supro de Teksto",
+DlgImgAlignTop		: "Supre",
+DlgImgPreview		: "Vidigi Aspekton",
+DlgImgAlertUrl		: "Bonvolu tajpi la URL de la bildo",
+DlgImgLinkTab		: "Link",	//MISSING
+
+// Flash Dialog
+DlgFlashTitle		: "Flash Properties",	//MISSING
+DlgFlashChkPlay		: "Auto Play",	//MISSING
+DlgFlashChkLoop		: "Loop",	//MISSING
+DlgFlashChkMenu		: "Enable Flash Menu",	//MISSING
+DlgFlashScale		: "Scale",	//MISSING
+DlgFlashScaleAll	: "Show all",	//MISSING
+DlgFlashScaleNoBorder	: "No Border",	//MISSING
+DlgFlashScaleFit	: "Exact Fit",	//MISSING
+
+// Link Dialog
+DlgLnkWindowTitle	: "Ligilo",
+DlgLnkInfoTab		: "Informoj pri la Ligilo",
+DlgLnkTargetTab		: "Celo",
+
+DlgLnkType			: "Tipo de Ligilo",
+DlgLnkTypeURL		: "URL",
+DlgLnkTypeAnchor	: "Ankri en tiu ĉi paĝo",
+DlgLnkTypeEMail		: "Retpoŝto",
+DlgLnkProto			: "Protokolo",
+DlgLnkProtoOther	: "<alia>",
+DlgLnkURL			: "URL",
+DlgLnkAnchorSel		: "Elekti Ankron",
+DlgLnkAnchorByName	: "Per Ankronomo",
+DlgLnkAnchorById	: "Per Elementidentigilo",
+DlgLnkNoAnchors		: "<Ne disponeblas ankroj en la dokumento>",		//REVIEW : Change < and > with ( and )
+DlgLnkEMail			: "Retadreso",
+DlgLnkEMailSubject	: "Temlinio",
+DlgLnkEMailBody		: "Mesaĝa korpo",
+DlgLnkUpload		: "Alŝuti",
+DlgLnkBtnUpload		: "Sendi al Servilo",
+
+DlgLnkTarget		: "Celo",
+DlgLnkTargetFrame	: "<kadro>",
+DlgLnkTargetPopup	: "<ŝprucfenestro>",
+DlgLnkTargetBlank	: "Nova Fenestro (_blank)",
+DlgLnkTargetParent	: "Gepatra Fenestro (_parent)",
+DlgLnkTargetSelf	: "Sama Fenestro (_self)",
+DlgLnkTargetTop		: "Plej Supra Fenestro (_top)",
+DlgLnkTargetFrameName	: "Nomo de Kadro",
+DlgLnkPopWinName	: "Nomo de Ŝprucfenestro",
+DlgLnkPopWinFeat	: "Atributoj de la Ŝprucfenestro",
+DlgLnkPopResize		: "Grando Ŝanĝebla",
+DlgLnkPopLocation	: "Adresobreto",
+DlgLnkPopMenu		: "Menubreto",
+DlgLnkPopScroll		: "Rulumlisteloj",
+DlgLnkPopStatus		: "Statobreto",
+DlgLnkPopToolbar	: "Ilobreto",
+DlgLnkPopFullScrn	: "Tutekrane (IE)",
+DlgLnkPopDependent	: "Dependa (Netscape)",
+DlgLnkPopWidth		: "Larĝo",
+DlgLnkPopHeight		: "Alto",
+DlgLnkPopLeft		: "Pozicio de Maldekstro",
+DlgLnkPopTop		: "Pozicio de Supro",
+
+DlnLnkMsgNoUrl		: "Bonvolu entajpi la URL-on",
+DlnLnkMsgNoEMail	: "Bonvolu entajpi la retadreson",
+DlnLnkMsgNoAnchor	: "Bonvolu elekti ankron",
+DlnLnkMsgInvPopName	: "The popup name must begin with an alphabetic character and must not contain spaces",	//MISSING
+
+// Color Dialog
+DlgColorTitle		: "Elekti",
+DlgColorBtnClear	: "Forigi",
+DlgColorHighlight	: "Emfazi",
+DlgColorSelected	: "Elektita",
+
+// Smiley Dialog
+DlgSmileyTitle		: "Enmeti Mienvinjeton",
+
+// Special Character Dialog
+DlgSpecialCharTitle	: "Enmeti Specialan Signon",
+
+// Table Dialog
+DlgTableTitle		: "Atributoj de Tabelo",
+DlgTableRows		: "Linioj",
+DlgTableColumns		: "Kolumnoj",
+DlgTableBorder		: "Bordero",
+DlgTableAlign		: "Ĝisrandigo",
+DlgTableAlignNotSet	: "<Defaŭlte>",
+DlgTableAlignLeft	: "Maldekstre",
+DlgTableAlignCenter	: "Centre",
+DlgTableAlignRight	: "Dekstre",
+DlgTableWidth		: "Larĝo",
+DlgTableWidthPx		: "Bitbilderoj",
+DlgTableWidthPc		: "elcentoj",
+DlgTableHeight		: "Alto",
+DlgTableCellSpace	: "Interspacigo de Ĉeloj",
+DlgTableCellPad		: "Ĉirkaŭenhava Plenigado",
+DlgTableCaption		: "Titolo",
+DlgTableSummary		: "Summary",	//MISSING
+
+// Table Cell Dialog
+DlgCellTitle		: "Atributoj de Celo",
+DlgCellWidth		: "Larĝo",
+DlgCellWidthPx		: "bitbilderoj",
+DlgCellWidthPc		: "elcentoj",
+DlgCellHeight		: "Alto",
+DlgCellWordWrap		: "Linifaldo",
+DlgCellWordWrapNotSet	: "<Defaŭlte>",
+DlgCellWordWrapYes	: "Jes",
+DlgCellWordWrapNo	: "Ne",
+DlgCellHorAlign		: "Horizonta Ĝisrandigo",
+DlgCellHorAlignNotSet	: "<Defaŭlte>",
+DlgCellHorAlignLeft	: "Maldekstre",
+DlgCellHorAlignCenter	: "Centre",
+DlgCellHorAlignRight: "Dekstre",
+DlgCellVerAlign		: "Vertikala Ĝisrandigo",
+DlgCellVerAlignNotSet	: "<Defaŭlte>",
+DlgCellVerAlignTop	: "Supre",
+DlgCellVerAlignMiddle	: "Centre",
+DlgCellVerAlignBottom	: "Malsupre",
+DlgCellVerAlignBaseline	: "Je Malsupro de Teksto",
+DlgCellRowSpan		: "Linioj Kunfanditaj",
+DlgCellCollSpan		: "Kolumnoj Kunfanditaj",
+DlgCellBackColor	: "Fono",
+DlgCellBorderColor	: "Bordero",
+DlgCellBtnSelect	: "Elekti...",
+
+// Find Dialog
+DlgFindTitle		: "Serĉi",
+DlgFindFindBtn		: "Serĉi",
+DlgFindNotFoundMsg	: "La celteksto ne estas trovita.",
+
+// Replace Dialog
+DlgReplaceTitle			: "Anstataŭigi",
+DlgReplaceFindLbl		: "Serĉi:",
+DlgReplaceReplaceLbl	: "Anstataŭigi per:",
+DlgReplaceCaseChk		: "Kongruigi Usklecon",
+DlgReplaceReplaceBtn	: "Anstataŭigi",
+DlgReplaceReplAllBtn	: "Anstataŭigi Ĉiun",
+DlgReplaceWordChk		: "Tuta Vorto",
+
+// Paste Operations / Dialog
+PasteErrorCut	: "La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras eltondajn operaciojn. Bonvolu uzi la klavaron por tio (ctrl-X).",
+PasteErrorCopy	: "La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras kopiajn operaciojn. Bonvolu uzi la klavaron por tio (ctrl-C).",
+
+PasteAsText		: "Interglui kiel Tekston",
+PasteFromWord	: "Interglui el Word",
+
+DlgPasteMsg2	: "Please paste inside the following box using the keyboard (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.",	//MISSING
+DlgPasteSec		: "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.",	//MISSING
+DlgPasteIgnoreFont		: "Ignore Font Face definitions",	//MISSING
+DlgPasteRemoveStyles	: "Remove Styles definitions",	//MISSING
+DlgPasteCleanBox		: "Clean Up Box",	//MISSING
+
+// Color Picker
+ColorAutomatic	: "Aŭtomata",
+ColorMoreColors	: "Pli da Koloroj...",
+
+// Document Properties
+DocProps		: "Dokumentaj Atributoj",
+
+// Anchor Dialog
+DlgAnchorTitle		: "Ankraj Atributoj",
+DlgAnchorName		: "Ankra Nomo",
+DlgAnchorErrorName	: "Bv tajpi la ankran nomon",
+
+// Speller Pages Dialog
+DlgSpellNotInDic		: "Ne trovita en la vortaro",
+DlgSpellChangeTo		: "Ŝanĝi al",
+DlgSpellBtnIgnore		: "Malatenti",
+DlgSpellBtnIgnoreAll	: "Malatenti Ĉiun",
+DlgSpellBtnReplace		: "Anstataŭigi",
+DlgSpellBtnReplaceAll	: "Anstataŭigi Ĉiun",
+DlgSpellBtnUndo			: "Malfari",
+DlgSpellNoSuggestions	: "- Neniu propono -",
+DlgSpellProgress		: "Literumkontrolado daŭras...",
+DlgSpellNoMispell		: "Literumkontrolado finita: neniu fuŝo trovita",
+DlgSpellNoChanges		: "Literumkontrolado finita: neniu vorto ŝanĝita",
+DlgSpellOneChange		: "Literumkontrolado finita: unu vorto ŝanĝita",
+DlgSpellManyChanges		: "Literumkontrolado finita: %1 vortoj ŝanĝitaj",
+
+IeSpellDownload			: "Literumada Kontrolilo ne instalita. Ĉu vi volas elŝuti ĝin nun?",
+
+// Button Dialog
+DlgButtonText		: "Teksto (Valoro)",
+DlgButtonType		: "Tipo",
+DlgButtonTypeBtn	: "Button",	//MISSING
+DlgButtonTypeSbm	: "Submit",	//MISSING
+DlgButtonTypeRst	: "Reset",	//MISSING
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName		: "Nomo",
+DlgCheckboxValue	: "Valoro",
+DlgCheckboxSelected	: "Elektita",
+
+// Form Dialog
+DlgFormName		: "Nomo",
+DlgFormAction	: "Ago",
+DlgFormMethod	: "Metodo",
+
+// Select Field Dialog
+DlgSelectName		: "Nomo",
+DlgSelectValue		: "Valoro",
+DlgSelectSize		: "Grando",
+DlgSelectLines		: "Linioj",
+DlgSelectChkMulti	: "Permesi Plurajn Elektojn",
+DlgSelectOpAvail	: "Elektoj Disponeblaj",
+DlgSelectOpText		: "Teksto",
+DlgSelectOpValue	: "Valoro",
+DlgSelectBtnAdd		: "Aldoni",
+DlgSelectBtnModify	: "Modifi",
+DlgSelectBtnUp		: "Supren",
+DlgSelectBtnDown	: "Malsupren",
+DlgSelectBtnSetValue : "Agordi kiel Elektitan Valoron",
+DlgSelectBtnDelete	: "Forigi",
+
+// Textarea Dialog
+DlgTextareaName	: "Nomo",
+DlgTextareaCols	: "Kolumnoj",
+DlgTextareaRows	: "Vicoj",
+
+// Text Field Dialog
+DlgTextName			: "Nomo",
+DlgTextValue		: "Valoro",
+DlgTextCharWidth	: "Signolarĝo",
+DlgTextMaxChars		: "Maksimuma Nombro da Signoj",
+DlgTextType			: "Tipo",
+DlgTextTypeText		: "Teksto",
+DlgTextTypePass		: "Pasvorto",
+
+// Hidden Field Dialog
+DlgHiddenName	: "Nomo",
+DlgHiddenValue	: "Valoro",
+
+// Bulleted List Dialog
+BulletedListProp	: "Atributoj de Bula Listo",
+NumberedListProp	: "Atributoj de Numera Listo",
+DlgLstStart			: "Start",	//MISSING
+DlgLstType			: "Tipo",
+DlgLstTypeCircle	: "Cirklo",
+DlgLstTypeDisc		: "Disc",	//MISSING
+DlgLstTypeSquare	: "Kvadrato",
+DlgLstTypeNumbers	: "Ciferoj (1, 2, 3)",
+DlgLstTypeLCase		: "Minusklaj Literoj (a, b, c)",
+DlgLstTypeUCase		: "Majusklaj Literoj (A, B, C)",
+DlgLstTypeSRoman	: "Malgrandaj Romanaj Ciferoj (i, ii, iii)",
+DlgLstTypeLRoman	: "Grandaj Romanaj Ciferoj (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab	: "Ĝeneralaĵoj",
+DlgDocBackTab		: "Fono",
+DlgDocColorsTab		: "Koloroj kaj Marĝenoj",
+DlgDocMetaTab		: "Metadatumoj",
+
+DlgDocPageTitle		: "Paĝotitolo",
+DlgDocLangDir		: "Skribdirekto de la Lingvo",
+DlgDocLangDirLTR	: "De maldekstro dekstren (LTR)",
+DlgDocLangDirRTL	: "De dekstro maldekstren (LTR)",
+DlgDocLangCode		: "Lingvokodo",
+DlgDocCharSet		: "Signara Kodo",
+DlgDocCharSetCE		: "Central European",	//MISSING
+DlgDocCharSetCT		: "Chinese Traditional (Big5)",	//MISSING
+DlgDocCharSetCR		: "Cyrillic",	//MISSING
+DlgDocCharSetGR		: "Greek",	//MISSING
+DlgDocCharSetJP		: "Japanese",	//MISSING
+DlgDocCharSetKR		: "Korean",	//MISSING
+DlgDocCharSetTR		: "Turkish",	//MISSING
+DlgDocCharSetUN		: "Unicode (UTF-8)",	//MISSING
+DlgDocCharSetWE		: "Western European",	//MISSING
+DlgDocCharSetOther	: "Alia Signara Kodo",
+
+DlgDocDocType		: "Dokumenta Tipo",
+DlgDocDocTypeOther	: "Alia Dokumenta Tipo",
+DlgDocIncXHTML		: "Inkluzivi XHTML Deklaroj",
+DlgDocBgColor		: "Fona Koloro",
+DlgDocBgImage		: "URL de Fona Bildo",
+DlgDocBgNoScroll	: "Neruluma Fono",
+DlgDocCText			: "Teksto",
+DlgDocCLink			: "Ligilo",
+DlgDocCVisited		: "Vizitita Ligilo",
+DlgDocCActive		: "Aktiva Ligilo",
+DlgDocMargins		: "Paĝaj Marĝenoj",
+DlgDocMaTop			: "Supra",
+DlgDocMaLeft		: "Maldekstra",
+DlgDocMaRight		: "Dekstra",
+DlgDocMaBottom		: "Malsupra",
+DlgDocMeIndex		: "Ŝlosilvortoj de la Dokumento (apartigita de komoj)",
+DlgDocMeDescr		: "Dokumenta Priskribo",
+DlgDocMeAuthor		: "Verkinto",
+DlgDocMeCopy		: "Kopirajto",
+DlgDocPreview		: "Aspekto",
+
+// Templates Dialog
+Templates			: "Templates",	//MISSING
+DlgTemplatesTitle	: "Content Templates",	//MISSING
+DlgTemplatesSelMsg	: "Please select the template to open in the editor<br />(the actual contents will be lost):",	//MISSING
+DlgTemplatesLoading	: "Loading templates list. Please wait...",	//MISSING
+DlgTemplatesNoTpl	: "(No templates defined)",	//MISSING
+DlgTemplatesReplace	: "Replace actual contents",	//MISSING
+
+// About Dialog
+DlgAboutAboutTab	: "Pri",
+DlgAboutBrowserInfoTab	: "Informoj pri TTT-legilo",
+DlgAboutLicenseTab	: "License",	//MISSING
+DlgAboutVersion		: "versio",
+DlgAboutInfo		: "Por pli da informoj, vizitu"
+};
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/fr.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/fr.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/fr.js	(revision 795)
@@ -0,0 +1,27 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Placholder Italian language file.
+ */
+FCKLang.PlaceholderBtn			= 'Insérer/Modifier Substitut' ;
+FCKLang.PlaceholderDlgTitle		= 'Propriétés de Substitut' ;
+FCKLang.PlaceholderDlgName		= 'Nom de Substitut' ;
+FCKLang.PlaceholderErrNoName	= 'Veuillez saisir le nom de Substitut' ;
+FCKLang.PlaceholderErrNameInUse	= 'Ce nom est déjà utilisé' ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/de.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/de.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/de.js	(revision 795)
@@ -0,0 +1,27 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Placholder German language file.
+ */
+FCKLang.PlaceholderBtn			= 'Einfügen/editieren Platzhalter' ;
+FCKLang.PlaceholderDlgTitle		= 'Platzhalter Eigenschaften' ;
+FCKLang.PlaceholderDlgName		= 'Platzhalter Name' ;
+FCKLang.PlaceholderErrNoName	= 'Bitte den Namen des Platzhalters schreiben' ;
+FCKLang.PlaceholderErrNameInUse	= 'Der angegebene Namen ist schon in Gebrauch' ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/pl.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/pl.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/pl.js	(revision 795)
@@ -0,0 +1,27 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Placholder Polish language file.
+ */
+FCKLang.PlaceholderBtn			= 'Wstaw/Edytuj nagłówek' ;
+FCKLang.PlaceholderDlgTitle		= 'Właśności nagłówka' ;
+FCKLang.PlaceholderDlgName		= 'Nazwa nagłówka' ;
+FCKLang.PlaceholderErrNoName	= 'Proszę wprowadzić nazwę nagłówka' ;
+FCKLang.PlaceholderErrNameInUse	= 'Podana nazwa jest już w użyciu' ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/it.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/it.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/it.js	(revision 795)
@@ -0,0 +1,27 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Placholder Italian language file.
+ */
+FCKLang.PlaceholderBtn			= 'Aggiungi/Modifica Placeholder' ;
+FCKLang.PlaceholderDlgTitle		= 'Proprietà del Placeholder' ;
+FCKLang.PlaceholderDlgName		= 'Nome del Placeholder' ;
+FCKLang.PlaceholderErrNoName	= 'Digitare il nome del placeholder' ;
+FCKLang.PlaceholderErrNameInUse	= 'Il nome inserito è già in uso' ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/en.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/en.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/lang/en.js	(revision 795)
@@ -0,0 +1,27 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Placholder English language file.
+ */
+FCKLang.PlaceholderBtn			= 'Insert/Edit Placeholder' ;
+FCKLang.PlaceholderDlgTitle		= 'Placeholder Properties' ;
+FCKLang.PlaceholderDlgName		= 'Placeholder Name' ;
+FCKLang.PlaceholderErrNoName	= 'Please type the placeholder name' ;
+FCKLang.PlaceholderErrNameInUse	= 'The specified name is already in use' ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/fck_placeholder.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/fck_placeholder.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/fck_placeholder.html	(revision 795)
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Placeholder Plugin.
+-->
+<html>
+	<head>
+		<title>Placeholder Properties</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta content="noindex, nofollow" name="robots">
+		<script language="javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCKLang = oEditor.FCKLang ;
+var FCKPlaceholders = oEditor.FCKPlaceholders ;
+
+window.onload = function ()
+{
+	// First of all, translate the dialog box texts
+	oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+	LoadSelected() ;
+
+	// Show the "Ok" button.
+	window.parent.SetOkButton( true ) ;
+}
+
+var eSelected = oEditor.FCKSelection.GetSelectedElement() ;
+
+function LoadSelected()
+{
+	if ( !eSelected )
+		return ;
+
+	if ( eSelected.tagName == 'SPAN' && eSelected._fckplaceholder )
+		document.getElementById('txtName').value = eSelected._fckplaceholder ;
+	else
+		eSelected == null ;
+}
+
+function Ok()
+{
+	var sValue = document.getElementById('txtName').value ;
+
+	if ( eSelected && eSelected._fckplaceholder == sValue )
+		return true ;
+
+	if ( sValue.length == 0 )
+	{
+		alert( FCKLang.PlaceholderErrNoName ) ;
+		return false ;
+	}
+
+	if ( FCKPlaceholders.Exist( sValue ) )
+	{
+		alert( FCKLang.PlaceholderErrNameInUse ) ;
+		return false ;
+	}
+
+	FCKPlaceholders.Add( sValue ) ;
+	return true ;
+}
+
+		</script>
+	</head>
+	<body scroll="no" style="OVERFLOW: hidden">
+		<table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+			<tr>
+				<td>
+					<table cellSpacing="0" cellPadding="0" align="center" border="0">
+						<tr>
+							<td>
+								<span fckLang="PlaceholderDlgName">Placeholder Name</span><br>
+								<input id="txtName" type="text">
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/fckplugin.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/fckplugin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/placeholder/fckplugin.js	(revision 795)
@@ -0,0 +1,187 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Plugin to insert "Placeholders" in the editor.
+ */
+
+// Register the related command.
+FCKCommands.RegisterCommand( 'Placeholder', new FCKDialogCommand( 'Placeholder', FCKLang.PlaceholderDlgTitle, FCKPlugins.Items['placeholder'].Path + 'fck_placeholder.html', 340, 170 ) ) ;
+
+// Create the "Plaholder" toolbar button.
+var oPlaceholderItem = new FCKToolbarButton( 'Placeholder', FCKLang.PlaceholderBtn ) ;
+oPlaceholderItem.IconPath = FCKPlugins.Items['placeholder'].Path + 'placeholder.gif' ;
+
+FCKToolbarItems.RegisterItem( 'Placeholder', oPlaceholderItem ) ;
+
+
+// The object used for all Placeholder operations.
+var FCKPlaceholders = new Object() ;
+
+// Add a new placeholder at the actual selection.
+FCKPlaceholders.Add = function( name )
+{
+	var oSpan = FCK.CreateElement( 'SPAN' ) ;
+	this.SetupSpan( oSpan, name ) ;
+}
+
+FCKPlaceholders.SetupSpan = function( span, name )
+{
+	span.innerHTML = '[[ ' + name + ' ]]' ;
+
+	span.style.backgroundColor = '#ffff00' ;
+	span.style.color = '#000000' ;
+
+	if ( FCKBrowserInfo.IsGecko )
+		span.style.cursor = 'default' ;
+
+	span._fckplaceholder = name ;
+	span.contentEditable = false ;
+
+	// To avoid it to be resized.
+	span.onresizestart = function()
+	{
+		FCK.EditorWindow.event.returnValue = false ;
+		return false ;
+	}
+}
+
+// On Gecko we must do this trick so the user select all the SPAN when clicking on it.
+FCKPlaceholders._SetupClickListener = function()
+{
+	FCKPlaceholders._ClickListener = function( e )
+	{
+		if ( e.target.tagName == 'SPAN' && e.target._fckplaceholder )
+			FCKSelection.SelectNode( e.target ) ;
+	}
+
+	FCK.EditorDocument.addEventListener( 'click', FCKPlaceholders._ClickListener, true ) ;
+}
+
+// Open the Placeholder dialog on double click.
+FCKPlaceholders.OnDoubleClick = function( span )
+{
+	if ( span.tagName == 'SPAN' && span._fckplaceholder )
+		FCKCommands.GetCommand( 'Placeholder' ).Execute() ;
+}
+
+FCK.RegisterDoubleClickHandler( FCKPlaceholders.OnDoubleClick, 'SPAN' ) ;
+
+// Check if a Placholder name is already in use.
+FCKPlaceholders.Exist = function( name )
+{
+	var aSpans = FCK.EditorDocument.getElementsByTagName( 'SPAN' ) ;
+
+	for ( var i = 0 ; i < aSpans.length ; i++ )
+	{
+		if ( aSpans[i]._fckplaceholder == name )
+			return true ;
+	}
+
+	return false ;
+}
+
+if ( FCKBrowserInfo.IsIE )
+{
+	FCKPlaceholders.Redraw = function()
+	{
+		if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+			return ;
+
+		var aPlaholders = FCK.EditorDocument.body.innerText.match( /\[\[[^\[\]]+\]\]/g ) ;
+		if ( !aPlaholders )
+			return ;
+
+		var oRange = FCK.EditorDocument.body.createTextRange() ;
+
+		for ( var i = 0 ; i < aPlaholders.length ; i++ )
+		{
+			if ( oRange.findText( aPlaholders[i] ) )
+			{
+				var sName = aPlaholders[i].match( /\[\[\s*([^\]]*?)\s*\]\]/ )[1] ;
+				oRange.pasteHTML( '<span style="color: #000000; background-color: #ffff00" contenteditable="false" _fckplaceholder="' + sName + '">' + aPlaholders[i] + '</span>' ) ;
+			}
+		}
+	}
+}
+else
+{
+	FCKPlaceholders.Redraw = function()
+	{
+		if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+			return ;
+
+		var oInteractor = FCK.EditorDocument.createTreeWalker( FCK.EditorDocument.body, NodeFilter.SHOW_TEXT, FCKPlaceholders._AcceptNode, true ) ;
+
+		var	aNodes = new Array() ;
+
+		while ( ( oNode = oInteractor.nextNode() ) )
+		{
+			aNodes[ aNodes.length ] = oNode ;
+		}
+
+		for ( var n = 0 ; n < aNodes.length ; n++ )
+		{
+			var aPieces = aNodes[n].nodeValue.split( /(\[\[[^\[\]]+\]\])/g ) ;
+
+			for ( var i = 0 ; i < aPieces.length ; i++ )
+			{
+				if ( aPieces[i].length > 0 )
+				{
+					if ( aPieces[i].indexOf( '[[' ) == 0 )
+					{
+						var sName = aPieces[i].match( /\[\[\s*([^\]]*?)\s*\]\]/ )[1] ;
+
+						var oSpan = FCK.EditorDocument.createElement( 'span' ) ;
+						FCKPlaceholders.SetupSpan( oSpan, sName ) ;
+
+						aNodes[n].parentNode.insertBefore( oSpan, aNodes[n] ) ;
+					}
+					else
+						aNodes[n].parentNode.insertBefore( FCK.EditorDocument.createTextNode( aPieces[i] ) , aNodes[n] ) ;
+				}
+			}
+
+			aNodes[n].parentNode.removeChild( aNodes[n] ) ;
+		}
+
+		FCKPlaceholders._SetupClickListener() ;
+	}
+
+	FCKPlaceholders._AcceptNode = function( node )
+	{
+		if ( /\[\[[^\[\]]+\]\]/.test( node.nodeValue ) )
+			return NodeFilter.FILTER_ACCEPT ;
+		else
+			return NodeFilter.FILTER_SKIP ;
+	}
+}
+
+FCK.Events.AttachEvent( 'OnAfterSetHTML', FCKPlaceholders.Redraw ) ;
+
+// We must process the SPAN tags to replace then with the real resulting value of the placeholder.
+FCKXHtml.TagProcessors['span'] = function( node, htmlNode )
+{
+	if ( htmlNode._fckplaceholder )
+		node = FCKXHtml.XML.createTextNode( '[[' + htmlNode._fckplaceholder + ']]' ) ;
+	else
+		FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
+
+	return node ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/autogrow/fckplugin.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/autogrow/fckplugin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/autogrow/fckplugin.js	(revision 795)
@@ -0,0 +1,92 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Plugin: automatically resizes the editor until a configurable maximun
+ * height (FCKConfig.AutoGrowMax), based on its contents.
+ */
+
+var FCKAutoGrow_Min = window.frameElement.offsetHeight ;
+
+function FCKAutoGrow_Check()
+{
+	var oInnerDoc = FCK.EditorDocument ;
+
+	var iFrameHeight, iInnerHeight ;
+
+	if ( FCKBrowserInfo.IsIE )
+	{
+		iFrameHeight = FCK.EditorWindow.frameElement.offsetHeight ;
+		iInnerHeight = oInnerDoc.body.scrollHeight ;
+	}
+	else
+	{
+		iFrameHeight = FCK.EditorWindow.innerHeight ;
+		iInnerHeight = oInnerDoc.body.offsetHeight ;
+	}
+
+	var iDiff = iInnerHeight - iFrameHeight ;
+
+	if ( iDiff != 0 )
+	{
+		var iMainFrameSize = window.frameElement.offsetHeight ;
+
+		if ( iDiff > 0 && iMainFrameSize < FCKConfig.AutoGrowMax )
+		{
+			iMainFrameSize += iDiff ;
+			if ( iMainFrameSize > FCKConfig.AutoGrowMax )
+				iMainFrameSize = FCKConfig.AutoGrowMax ;
+		}
+		else if ( iDiff < 0 && iMainFrameSize > FCKAutoGrow_Min )
+		{
+			iMainFrameSize += iDiff ;
+			if ( iMainFrameSize < FCKAutoGrow_Min )
+				iMainFrameSize = FCKAutoGrow_Min ;
+		}
+		else
+			return ;
+
+		window.frameElement.height = iMainFrameSize ;
+	}
+}
+
+FCK.AttachToOnSelectionChange( FCKAutoGrow_Check ) ;
+
+function FCKAutoGrow_SetListeners()
+{
+	if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+		return ;
+
+	FCK.EditorWindow.attachEvent( 'onscroll', FCKAutoGrow_Check ) ;
+	FCK.EditorDocument.attachEvent( 'onkeyup', FCKAutoGrow_Check ) ;
+}
+
+if ( FCKBrowserInfo.IsIE )
+{
+//	FCKAutoGrow_SetListeners() ;
+	FCK.Events.AttachEvent( 'OnAfterSetHTML', FCKAutoGrow_SetListeners ) ;
+}
+
+function FCKAutoGrow_CheckEditorStatus( sender, status )
+{
+	if ( status == FCK_STATUS_COMPLETE )
+		FCKAutoGrow_Check() ;
+}
+
+FCK.Events.AttachEvent( 'OnStatusChange', FCKAutoGrow_CheckEditorStatus ) ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/tablecommands/fckplugin.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/tablecommands/fckplugin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/tablecommands/fckplugin.js	(revision 795)
@@ -0,0 +1,32 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This plugin register the required Toolbar items to be able to insert the
+ * toolbar commands in the toolbar.
+ */
+
+FCKToolbarItems.RegisterItem( 'TableInsertRow'		, new FCKToolbarButton( 'TableInsertRow'	, FCKLang.InsertRow, null, null, null, null, 62 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableDeleteRows'		, new FCKToolbarButton( 'TableDeleteRows'	, FCKLang.DeleteRows, null, null, null, null, 63 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableInsertColumn'	, new FCKToolbarButton( 'TableInsertColumn'	, FCKLang.InsertColumn, null, null, null, null, 64 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableDeleteColumns'	, new FCKToolbarButton( 'TableDeleteColumns', FCKLang.DeleteColumns, null, null, null, null, 65 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableInsertCell'		, new FCKToolbarButton( 'TableInsertCell'	, FCKLang.InsertCell, null, null, null, null, 58 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableDeleteCells'	, new FCKToolbarButton( 'TableDeleteCells'	, FCKLang.DeleteCells, null, null, null, null, 59 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableMergeCells'		, new FCKToolbarButton( 'TableMergeCells'	, FCKLang.MergeCells, null, null, null, null, 60 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableSplitCell'		, new FCKToolbarButton( 'TableSplitCell'	, FCKLang.SplitCell, null, null, null, null, 61 ) ) ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/simplecommands/fckplugin.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/simplecommands/fckplugin.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/plugins/simplecommands/fckplugin.js	(revision 795)
@@ -0,0 +1,29 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This plugin register Toolbar items for the combos modifying the style to
+ * not show the box.
+ */
+
+FCKToolbarItems.RegisterItem( 'SourceSimple'	, new FCKToolbarButton( 'Source', FCKLang.Source, null, FCK_TOOLBARITEM_ONLYICON, true, true, 1 ) ) ;
+FCKToolbarItems.RegisterItem( 'StyleSimple'		, new FCKToolbarStyleCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
+FCKToolbarItems.RegisterItem( 'FontNameSimple'	, new FCKToolbarFontsCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
+FCKToolbarItems.RegisterItem( 'FontSizeSimple'	, new FCKToolbarFontSizeCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
+FCKToolbarItems.RegisterItem( 'FontFormatSimple', new FCKToolbarFontFormatCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/fckdialog.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/fckdialog.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/fckdialog.html	(revision 795)
@@ -0,0 +1,324 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This page is used by all dialog box as the container.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<script type="text/javascript">
+
+// On some Gecko browsers (probably over slow connections) the
+// "dialogArguments" are not set so we must get it from the opener window.
+if ( !window.dialogArguments )
+	window.dialogArguments = window.opener.FCKLastDialogInfo ;
+
+// Sets the Skin CSS
+document.write( '<link href="' + window.dialogArguments.Editor.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+// Sets the language direction.
+window.document.dir = window.dialogArguments.Editor.FCKLang.Dir ;
+
+var sTitle = window.dialogArguments.Title ;
+document.write( '<title>' + sTitle + '<\/title>' ) ;
+
+function LoadInnerDialog()
+{
+	if ( window.onresize )
+		window.onresize() ;
+
+	// First of all, translate the dialog box contents.
+	window.dialogArguments.Editor.FCKLanguageManager.TranslatePage( document ) ;
+
+	window.frames["frmMain"].document.location.href = window.dialogArguments.Page ;
+}
+
+function InnerDialogLoaded()
+{
+	var oInnerDoc = document.getElementById('frmMain').contentWindow.document ;
+
+	// Set the language direction.
+	oInnerDoc.dir = window.dialogArguments.Editor.FCKLang.Dir ;
+
+	// Sets the Skin CSS.
+	oInnerDoc.write( '<link href="' + window.dialogArguments.Editor.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+	SetOnKeyDown( oInnerDoc ) ;
+	DisableContextMenu( oInnerDoc ) ;
+
+	return window.dialogArguments.Editor ;
+}
+
+function SetOkButton( showIt )
+{
+	document.getElementById('btnOk').style.visibility = ( showIt ? '' : 'hidden' ) ;
+}
+
+var bAutoSize = false ;
+
+function SetAutoSize( autoSize )
+{
+	bAutoSize = autoSize ;
+	RefreshSize() ;
+}
+
+function RefreshSize()
+{
+	if ( bAutoSize )
+	{
+		var oInnerDoc = document.getElementById('frmMain').contentWindow.document ;
+
+		var iFrameHeight ;
+		if ( document.all )
+			iFrameHeight = oInnerDoc.body.offsetHeight ;
+		else
+			iFrameHeight = document.getElementById('frmMain').contentWindow.innerHeight ;
+
+		var iInnerHeight = oInnerDoc.body.scrollHeight ;
+
+		var iDiff = iInnerHeight - iFrameHeight ;
+
+		if ( iDiff > 0 )
+		{
+			if ( document.all )
+				window.dialogHeight = ( parseInt( window.dialogHeight, 10 ) + iDiff ) + 'px' ;
+			else
+				window.resizeBy( 0, iDiff ) ;
+		}
+	}
+}
+
+function Ok()
+{
+	if ( window.frames["frmMain"].Ok && window.frames["frmMain"].Ok() )
+		Cancel() ;
+}
+
+function Cancel( dontFireChange )
+{
+	if ( !dontFireChange )
+	{
+		// All dialog windows, by default, will fire the "OnSelectionChange"
+		// event, no matter the Ok or Cancel button has been pressed.
+		window.dialogArguments.Editor.FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+	}
+	window.close() ;
+}
+
+// Object that holds all available tabs.
+var oTabs = new Object() ;
+
+function TabDiv_OnClick()
+{
+	SetSelectedTab( this.TabCode ) ;
+}
+
+function AddTab( tabCode, tabText, startHidden )
+{
+	if ( typeof( oTabs[ tabCode ] ) != 'undefined' )
+		return ;
+
+	var eTabsRow = document.getElementById( 'Tabs' ) ;
+
+	var oCell = eTabsRow.insertCell(  eTabsRow.cells.length - 1 ) ;
+	oCell.noWrap = true ;
+
+	var oDiv = document.createElement( 'DIV' ) ;
+	oDiv.className = 'PopupTab' ;
+	oDiv.innerHTML = tabText ;
+	oDiv.TabCode = tabCode ;
+	oDiv.onclick = TabDiv_OnClick ;
+
+	if ( startHidden )
+		oDiv.style.display = 'none' ;
+
+	eTabsRow = document.getElementById( 'TabsRow' ) ;
+
+	oCell.appendChild( oDiv ) ;
+
+	if ( eTabsRow.style.display == 'none' )
+	{
+		var eTitleArea = document.getElementById( 'TitleArea' ) ;
+		eTitleArea.className = 'PopupTitle' ;
+
+		oDiv.className = 'PopupTabSelected' ;
+		eTabsRow.style.display = '' ;
+
+		if ( ! window.dialogArguments.Editor.FCKBrowserInfo.IsIE )
+			window.onresize() ;
+	}
+
+	oTabs[ tabCode ] = oDiv ;
+}
+
+function SetSelectedTab( tabCode )
+{
+	for ( var sCode in oTabs )
+	{
+		if ( sCode == tabCode )
+			oTabs[sCode].className = 'PopupTabSelected' ;
+		else
+			oTabs[sCode].className = 'PopupTab' ;
+	}
+
+	if ( typeof( window.frames["frmMain"].OnDialogTabChange ) == 'function' )
+		window.frames["frmMain"].OnDialogTabChange( tabCode ) ;
+}
+
+function SetTabVisibility( tabCode, isVisible )
+{
+	var oTab = oTabs[ tabCode ] ;
+	oTab.style.display = isVisible ? '' : 'none' ;
+
+	if ( ! isVisible && oTab.className == 'PopupTabSelected' )
+	{
+		for ( var sCode in oTabs )
+		{
+			if ( oTabs[sCode].style.display != 'none' )
+			{
+				SetSelectedTab( sCode ) ;
+				break ;
+			}
+		}
+	}
+}
+
+function SetOnKeyDown( targetDocument )
+{
+	targetDocument.onkeydown = function ( e )
+	{
+		e = e || event || this.parentWindow.event ;
+		switch ( e.keyCode )
+		{
+			case 13 :		// ENTER
+				var oTarget = e.srcElement || e.target ;
+				if ( oTarget.tagName == 'TEXTAREA' )
+					return true ;
+				Ok() ;
+				return false ;
+			case 27 :		// ESC
+				Cancel() ;
+				return false ;
+				break ;
+		}
+		return true ;
+	}
+}
+SetOnKeyDown( document ) ;
+
+function DisableContextMenu( targetDocument )
+{
+	if ( window.dialogArguments.Editor.FCKBrowserInfo.IsIE ) return ;
+
+	// Disable Right-Click
+	var oOnContextMenu = function( e )
+	{
+		var sTagName = e.target.tagName ;
+		if ( ! ( ( sTagName == "INPUT" && e.target.type == "text" ) || sTagName == "TEXTAREA" ) )
+			e.preventDefault() ;
+	}
+	targetDocument.addEventListener( 'contextmenu', oOnContextMenu, true ) ;
+}
+DisableContextMenu( document ) ;
+
+if ( ! window.dialogArguments.Editor.FCKBrowserInfo.IsIE )
+{
+	window.onresize = function()
+	{
+		var oFrame = document.getElementById("frmMain") ;
+
+		if ( ! oFrame )
+		return ;
+
+		oFrame.height = 0 ;
+
+		var oCell = document.getElementById("FrameCell") ;
+		var iHeight = oCell.offsetHeight ;
+
+		oFrame.height = iHeight - 2 ;
+	}
+}
+
+if ( window.dialogArguments.Editor.FCKBrowserInfo.IsIE )
+{
+	function Window_OnBeforeUnload()
+	{
+		for ( var t in oTabs )
+			oTabs[t] = null ;
+
+		window.dialogArguments.Editor = null ;
+	}
+	window.attachEvent( "onbeforeunload", Window_OnBeforeUnload ) ;
+}
+
+function Window_OnClose()
+{
+	window.dialogArguments.Editor.FCKFocusManager.Unlock() ;
+}
+
+if ( window.addEventListener )
+	window.addEventListener( 'unload', Window_OnClose, false ) ;
+
+		</script>
+	</head>
+	<body onload="LoadInnerDialog();" class="PopupBody">
+		<table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0">
+			<tr>
+				<td id="TitleArea" class="PopupTitle PopupTitleBorder">
+					<script type="text/javascript">
+document.write( sTitle ) ;
+					</script>
+				</td>
+			</tr>
+			<tr id="TabsRow" style="DISPLAY: none">
+				<td class="PopupTabArea">
+					<table border="0" cellpadding="0" cellspacing="0" width="100%">
+						<tr id="Tabs" onselectstart="return false;">
+							<td class="PopupTabEmptyArea">&nbsp;</td>
+							<td class="PopupTabEmptyArea" width="100%">&nbsp;</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+			<tr>
+				<td id="FrameCell" height="100%" valign="top">
+					<iframe id="frmMain" src="javascript:void(0)" name="frmMain" frameborder="0" height="100%" width="100%" scrolling="auto">
+					</iframe>
+				</td>
+			</tr>
+			<tr>
+				<td class="PopupButtons">
+					<table border="0" cellpadding="0" cellspacing="0">
+						<tr>
+							<td width="100%">&nbsp;</td>
+							<td nowrap="nowrap">
+								<input id="btnOk" style="VISIBILITY: hidden;" type="button" value="Ok" class="Button" onclick="Ok();" fckLang="DlgBtnOK" />
+								&nbsp; 
+								<input id="btnCancel" type="button" value="Cancel" class="Button" onclick="Cancel();" fckLang="DlgBtnCancel" />
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/office2003/fck_editor.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/office2003/fck_editor.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/office2003/fck_editor.css	(revision 795)
@@ -0,0 +1,476 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Styles used by the editor IFRAME and Toolbar.
+ */
+
+/*
+	### Basic Editor IFRAME Styles.
+*/
+
+body
+{
+    padding: 1px 1px 1px 1px;
+    margin: 0px 0px 0px 0px;
+}
+
+#xEditingArea
+{
+    border: #696969 1px solid;
+}
+
+.SourceField
+{
+    padding: 5px;
+    margin: 0px;
+    font-family: Monospace;
+}
+
+/*
+	Toolbar
+*/
+
+.TB_ToolbarSet, .TB_Expand, .TB_Collapse
+{
+    cursor: default;
+    background-color: #f7f8fd;
+}
+
+.TB_ToolbarSet
+{
+    border-top: #f7f8fd 1px outset;
+    border-bottom: #f7f8fd 1px outset;
+}
+
+.TB_ToolbarSet TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.TB_Toolbar
+{
+   	background-color: #d6dff7;
+	background-image: url(images/toolbar.bg.gif);
+	background-repeat: repeat-x;
+    display: inline-table;
+}
+
+.TB_Separator
+{
+    width: 1px;
+    height: 16px;
+    margin: 2px;
+    background-color: #B2CBFF;
+}
+
+.TB_Start
+{
+    background-image: url(images/toolbar.start.gif);
+    background-repeat: no-repeat;
+    background-position: center center;
+    margin: 0px;
+    width: 7px;
+    height: 24px;
+}
+
+.TB_End
+{
+    background-image: url(images/toolbar.end.gif);
+    background-repeat: no-repeat;
+    background-position: center left;
+    height: 24px;
+    width: 4px;
+}
+
+.TB_ExpandImg
+{
+    background-image: url(images/toolbar.expand.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_CollapseImg
+{
+    background-image: url(images/toolbar.collapse.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_SideBorder
+{
+    background-color: #696969;
+}
+
+.TB_Expand, .TB_Collapse
+{
+    padding: 2px 2px 2px 2px;
+    border: #f7f8fd 1px outset;
+}
+
+.TB_Collapse
+{
+    width: 5px;
+}
+
+.TB_Break
+{
+    height: 24px; /* IE needs the height to be set, otherwise no break */
+}
+
+/*
+	Toolbar Button
+*/
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+    margin: 1px;
+    height: 22px; /* The height is necessary, otherwise IE will not apply the alpha */
+}
+
+.TB_Button_On
+{
+    margin: 0px;
+    border: #316ac5 1px solid;
+    background-color: #c1d2ee;
+}
+
+.TB_Button_On_Over, .TB_Button_Off_Over
+{
+    margin: 0px ;
+    border: #316ac5 1px solid;
+    background-color: #dff1ff;
+}
+
+.TB_Button_Off
+{
+    filter: alpha(opacity=70); /* IE */
+    opacity: 0.70; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Disabled
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 22px;
+}
+
+.TB_Button_Image
+{
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    margin: 3px;
+    background-repeat: no-repeat;
+}
+
+.TB_Button_Image img
+{
+    position: relative;
+}
+
+.TB_Button_Off .TB_Button_Text
+{
+   	background-color: #d6dff7;  /* Needed because of a bug on ClearType */
+	background-image: url(images/toolbar.bg.gif);
+	background-repeat: repeat-x;
+}
+
+.TB_ConnectionLine
+{
+    background-color: #f7f8fd;
+    height: 1px;
+    margin-left: 1px;   /* ltr */
+    margin-right: 1px;  /* rtl */
+}
+
+.TB_Button_Off .TB_Text
+{
+   	background-color: #d6dff7;  /* Needed because of a bug on ClearType */
+	background-image: url(images/toolbar.bg.gif);
+	background-repeat: repeat-x;
+}
+
+.TB_Button_On_Over .TB_Text
+{
+   	background-color: #dff1ff ;  /* Needed because of a bug on ClearType */
+}
+
+/*
+	Menu
+*/
+
+.MN_Menu
+{
+    border: 1px solid #8f8f73;
+    padding: 2px;
+    background-color: #f7f8fd;
+    cursor: default;
+}
+
+.MN_Menu, .MN_Menu .MN_Label
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.MN_Item_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 20px;
+}
+
+.MN_Icon
+{
+    background-color: #d6dff7;
+    text-align: center;
+    height: 20px;
+}
+
+.MN_Label
+{
+    padding-left: 3px;
+    padding-right: 3px;
+}
+
+.MN_Separator
+{
+    height: 3px;
+}
+
+.MN_Separator_Line
+{
+    border-top: #b9b99d 1px solid;
+}
+
+.MN_Item .MN_Icon IMG
+{
+    filter: alpha(opacity=70);
+    opacity: 0.70;
+}
+
+.MN_Item_Over
+{
+    color: #ffffff;
+    background-color: #7096FA;
+}
+
+.MN_Item_Over .MN_Icon
+{
+    background-color: #466ca6;
+}
+
+.MN_Item_Disabled IMG
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.MN_Item_Disabled .MN_Label
+{
+    color: #b7b7b7;
+}
+
+.MN_Arrow
+{
+    padding-right: 3px;
+    padding-left: 3px;
+}
+
+.MN_ConnectionLine
+{
+    background-color: #f7f8fd;
+}
+
+.Menu .TB_Button_On, .Menu .TB_Button_On_Over
+{
+    border: #8f8f73 1px solid;
+    background-color: #f7f8fd;
+}
+
+/*
+	### Panel Styles
+*/
+
+.FCK_Panel
+{
+    border: #8f8f73 1px solid;
+    padding: 2px;
+    background-color: #f7f8fd;
+}
+
+.FCK_Panel, .FCK_Panel TD
+{
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+    font-size: 11px;
+}
+
+/*
+	### Special Combos
+*/
+
+.SC_Panel
+{
+    overflow: auto;
+    white-space: nowrap;
+    cursor: default;
+    border: 1px solid #8f8f73;
+    padding-left: 2px;
+    padding-right: 2px;
+    background-color: #ffffff;
+}
+
+.SC_Panel, .SC_Panel TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.SC_Item, .SC_ItemSelected
+{
+    margin-top: 2px;
+    margin-bottom: 2px;
+    background-position: left center;
+    padding-left: 11px;
+    padding-right: 3px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    background-repeat: no-repeat;
+    border: #dddddd 1px solid;
+}
+
+.SC_Item *, .SC_ItemSelected *
+{
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.SC_ItemSelected
+{
+    border: #9a9afb 1px solid;
+    background-image: url(images/toolbar.arrowright.gif);
+}
+
+.SC_ItemOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_Field
+{
+    margin-top: 2px ;
+    border: #b7b7a6 1px solid;
+    cursor: default;
+}
+
+.SC_FieldCaption
+{
+    overflow: visible;
+    padding-right: 5px;
+    padding-left: 5px;
+    opacity: 0.75; /* Safari, Opera and Mozilla */
+    filter: alpha(opacity=70); /* IE */ /* -moz-opacity: 0.75; Mozilla (Old) */
+    height: 23px;
+   	background-color: #d6dff7;  /* Needed because of a bug on ClearType */
+	background-image: url(images/toolbar.bg.gif);
+	background-repeat: repeat-x;
+/*    background-color:  inherit;     Maybe this is needed wait to check */
+}
+
+.SC_FieldLabel
+{
+    white-space: nowrap;
+    padding: 2px;
+    width: 100%;
+    cursor: default;
+    background-color: #ffffff;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.SC_FieldButton
+{
+    background-position: center center;
+    background-image: url(images/toolbar.buttonarrow.gif);
+    border-left: #b7b7a6 1px solid;
+    width: 14px;
+    background-repeat: no-repeat;
+}
+
+.SC_FieldDisabled .SC_FieldButton, .SC_FieldDisabled .SC_FieldCaption
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */ /* -moz-opacity: 0.30; Mozilla (Old) */
+}
+
+.SC_FieldOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_FieldOver .SC_FieldButton
+{
+    border-left: #316ac5 1px solid;
+}
+
+/*
+	### Color Selector Panel
+*/
+
+.ColorBoxBorder
+{
+    border: #808080 1px solid;
+    position: static;
+}
+
+.ColorBox
+{
+    font-size: 1px;
+    width: 10px;
+    position: static;
+    height: 10px;
+}
+
+.ColorDeselected, .ColorSelected
+{
+    cursor: default;
+}
+
+.ColorDeselected
+{
+    border: #ffffff 1px solid;
+    padding: 2px;
+    float: left;
+}
+
+.ColorSelected
+{
+    border: #330066 1px solid;
+    padding: 2px;
+    float: left;
+    background-color: #c4cdd6;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/office2003/fck_dialog.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/office2003/fck_dialog.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/office2003/fck_dialog.css	(revision 795)
@@ -0,0 +1,138 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Styles used by the dialog boxes.
+ */
+
+body
+{
+	margin: 0px;
+	padding: 10px;
+	background-color: #f7f8fd;
+}
+
+body, td, input, select, textarea
+{
+	font-size: 11px;
+	font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+body, .BackColor
+{
+	background-color: #f7f8fd;
+}
+
+.PopupBody
+{
+	margin: 0px;
+	padding: 0px;
+}
+
+.PopupTitle
+{
+	font-weight: bold;
+	font-size: 14pt;
+	color: #0e3460;
+	background-color: #8cb2fd;
+	padding: 3px 10px 3px 10px;
+}
+
+.PopupButtons
+{
+	border-top: #466ca6 1px solid;
+	background-color: #8cb2fd;
+	padding: 7px 10px 7px 10px;
+}
+
+.Button
+{
+	border: #1c3460 1px solid;
+	color: #000a28;
+	background-color: #7096d3;
+}
+
+#btnOk
+{
+	width: 100px;
+}
+
+.DarkBackground
+{
+	background-color: #d7d79f;
+}
+
+.LightBackground
+{
+	background-color: #ffffbe;
+}
+
+.PopupTitleBorder
+{
+	border-bottom: #d5d59d 1px solid;
+}
+
+.PopupTabArea
+{
+	color: #0e3460;
+	background-color: #8cb2fd;
+}
+
+.PopupTabEmptyArea
+{
+	padding-left: 10px ;
+	border-bottom: #466ca6 1px solid;
+}
+
+.PopupTab, .PopupTabSelected
+{
+	border-right: #466ca6 1px solid;
+	border-top: #466ca6 1px solid;
+	border-left: #466ca6 1px solid;
+	padding-right: 5px;
+	padding-left: 5px;
+	padding-bottom: 3px;
+	padding-top: 3px;
+	color: #0e3460;
+}
+
+.PopupTab
+{
+	margin-top: 1px;
+	border-bottom: #466ca6 1px solid;
+	cursor: pointer;
+	cursor: hand;
+}
+
+.PopupTabSelected
+{
+	font-weight:bold;
+	cursor: default;
+	padding-top: 4px;
+	border-bottom: #f7f8fd 1px solid;
+	background-color: #f7f8fd;
+}
+
+.PopupSelectionBox
+{
+	border: #1e90ff 1px solid !important;
+	background-color: #add8e6 !important;
+	cursor: pointer;
+	cursor: hand;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/default/fck_editor.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/default/fck_editor.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/default/fck_editor.css	(revision 795)
@@ -0,0 +1,464 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Styles used by the editor IFRAME and Toolbar.
+ */
+
+/*
+	### Basic Editor IFRAME Styles.
+*/
+
+body
+{
+    padding: 1px 1px 1px 1px;
+    margin: 0px 0px 0px 0px;
+}
+
+#xEditingArea
+{
+    border: #696969 1px solid;
+}
+
+.SourceField
+{
+    padding: 5px;
+    margin: 0px;
+    font-family: Monospace;
+}
+
+/*
+	Toolbar
+*/
+
+.TB_ToolbarSet, .TB_Expand, .TB_Collapse
+{
+    cursor: default;
+    background-color: #efefde;
+}
+
+.TB_ToolbarSet
+{
+    border-top: #efefde 1px outset;
+    border-bottom: #efefde 1px outset;
+}
+
+.TB_ToolbarSet TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.TB_Toolbar
+{
+	height: 24px;
+    display: inline-table;	/* inline = Opera jumping buttons bug */
+}
+
+.TB_Separator
+{
+    width: 1px;
+    height: 16px;
+    margin: 2px;
+    background-color: #999966;
+}
+
+.TB_Start
+{
+    background-image: url(images/toolbar.start.gif);
+    margin: 2px;
+    width: 3px;
+    background-repeat: no-repeat;
+    height: 16px;
+}
+
+.TB_End
+{
+    display: none;
+}
+
+.TB_ExpandImg
+{
+    background-image: url(images/toolbar.expand.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_CollapseImg
+{
+    background-image: url(images/toolbar.collapse.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_SideBorder
+{
+    background-color: #696969;
+}
+
+.TB_Expand, .TB_Collapse
+{
+    padding: 2px 2px 2px 2px;
+    border: #efefde 1px outset;
+}
+
+.TB_Collapse
+{
+    width: 5px;
+}
+
+.TB_Break
+{
+    height: 24px; /* IE needs the height to be set, otherwise no break */
+}
+
+/*
+	Toolbar Button
+*/
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+    border: #efefde 1px solid; /* This is the default border */
+    height: 22px; /* The height is necessary, otherwise IE will not apply the alpha */
+}
+
+.TB_Button_On
+{
+    border: #316ac5 1px solid;
+    background-color: #c1d2ee;
+}
+
+.TB_Button_On_Over, .TB_Button_Off_Over
+{
+    border: #316ac5 1px solid;
+    background-color: #dff1ff;
+}
+
+.TB_Button_Off
+{
+    filter: alpha(opacity=70); /* IE */
+    opacity: 0.70; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Disabled
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 22px;
+}
+
+.TB_Button_Image
+{
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    margin: 3px;
+    background-repeat: no-repeat;
+}
+
+.TB_Button_Image img
+{
+    position: relative;
+}
+
+.TB_Button_Off .TB_Button_Text
+{
+   	background-color: #efefde;  /* Needed because of a bug on Clear Type */
+}
+
+.TB_ConnectionLine
+{
+    background-color: #ffffff;
+    height: 1px;
+    margin-left: 1px;   /* ltr */
+    margin-right: 1px;  /* rtl */
+}
+
+.TB_Text
+{
+	height: 22px;
+}
+
+.TB_Button_Off .TB_Text
+{
+   	background-color: #efefde ;  /* Needed because of a bug on ClearType */
+}
+
+.TB_Button_On_Over .TB_Text
+{
+   	background-color: #dff1ff ;  /* Needed because of a bug on ClearType */
+}
+
+/*
+	Menu
+*/
+
+.MN_Menu
+{
+    border: 1px solid #8f8f73;
+    padding: 2px;
+    background-color: #ffffff;
+    cursor: default;
+}
+
+.MN_Menu, .MN_Menu .MN_Label
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.MN_Item_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 20px;
+}
+
+.MN_Icon
+{
+    background-color: #e3e3c7;
+    text-align: center;
+    height: 20px;
+}
+
+.MN_Label
+{
+    padding-left: 3px;
+    padding-right: 3px;
+}
+
+.MN_Separator
+{
+    height: 3px;
+}
+
+.MN_Separator_Line
+{
+    border-top: #b9b99d 1px solid;
+}
+
+.MN_Item .MN_Icon IMG
+{
+    filter: alpha(opacity=70);
+    opacity: 0.70;
+}
+
+.MN_Item_Over
+{
+    color: #ffffff;
+    background-color: #8f8f73;
+}
+
+.MN_Item_Over .MN_Icon
+{
+    background-color: #737357;
+}
+
+.MN_Item_Disabled IMG
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.MN_Item_Disabled .MN_Label
+{
+    color: #b7b7b7;
+}
+
+.MN_Arrow
+{
+    padding-right: 3px;
+    padding-left: 3px;
+}
+
+.MN_ConnectionLine
+{
+    background-color: #ffffff;
+}
+
+.Menu .TB_Button_On, .Menu .TB_Button_On_Over
+{
+    border: #8f8f73 1px solid;
+    background-color: #ffffff;
+}
+
+/*
+	### Panel Styles
+*/
+
+.FCK_Panel
+{
+    border: #8f8f73 1px solid;
+    padding: 2px;
+    background-color: #ffffff;
+}
+
+.FCK_Panel, .FCK_Panel TD
+{
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+    font-size: 11px;
+}
+
+/*
+	### Special Combos
+*/
+
+.SC_Panel
+{
+    overflow: auto;
+    white-space: nowrap;
+    cursor: default;
+    border: 1px solid #8f8f73;
+    padding-left: 2px;
+    padding-right: 2px;
+    background-color: #ffffff;
+}
+
+.SC_Panel, .SC_Panel TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.SC_Item, .SC_ItemSelected
+{
+    margin-top: 2px;
+    margin-bottom: 2px;
+    background-position: left center;
+    padding-left: 11px;
+    padding-right: 3px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    background-repeat: no-repeat;
+    border: #dddddd 1px solid;
+}
+
+.SC_Item *, .SC_ItemSelected *
+{
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.SC_ItemSelected
+{
+    border: #9a9afb 1px solid;
+    background-image: url(images/toolbar.arrowright.gif);
+}
+
+.SC_ItemOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_Field
+{
+    border: #b7b7a6 1px solid;
+    cursor: default;
+}
+
+.SC_FieldCaption
+{
+    overflow: visible;
+    padding-right: 5px;
+    padding-left: 5px;
+    opacity: 0.75; /* Safari, Opera and Mozilla */
+    filter: alpha(opacity=70); /* IE */ /* -moz-opacity: 0.75; Mozilla (Old) */
+    height: 23px;
+    background-color: #efefde;
+}
+
+.SC_FieldLabel
+{
+    white-space: nowrap;
+    padding: 2px;
+    width: 100%;
+    cursor: default;
+    background-color: #ffffff;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.SC_FieldButton
+{
+    background-position: center center;
+    background-image: url(images/toolbar.buttonarrow.gif);
+    border-left: #b7b7a6 1px solid;
+    width: 14px;
+    background-repeat: no-repeat;
+}
+
+.SC_FieldDisabled .SC_FieldButton, .SC_FieldDisabled .SC_FieldCaption
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */ /* -moz-opacity: 0.30; Mozilla (Old) */
+}
+
+.SC_FieldOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_FieldOver .SC_FieldButton
+{
+    border-left: #316ac5 1px solid;
+}
+
+/*
+	### Color Selector Panel
+*/
+
+.ColorBoxBorder
+{
+    border: #808080 1px solid;
+    position: static;
+}
+
+.ColorBox
+{
+    font-size: 1px;
+    width: 10px;
+    position: static;
+    height: 10px;
+}
+
+.ColorDeselected, .ColorSelected
+{
+    cursor: default;
+}
+
+.ColorDeselected
+{
+    border: #ffffff 1px solid;
+    padding: 2px;
+    float: left;
+}
+
+.ColorSelected
+{
+    border: #330066 1px solid;
+    padding: 2px;
+    float: left;
+    background-color: #c4cdd6;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/default/fck_dialog.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/default/fck_dialog.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/default/fck_dialog.css	(revision 795)
@@ -0,0 +1,137 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Styles used by the dialog boxes.
+ */
+
+body
+{
+	margin: 0px;
+	padding: 10px;
+}
+
+body, td, input, select, textarea
+{
+	font-size: 11px;
+	font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+body, .BackColor
+{
+	background-color: #f1f1e3;
+}
+
+.PopupBody
+{
+	margin: 0px;
+	padding: 0px;
+}
+
+.PopupTitle
+{
+	font-weight: bold;
+	font-size: 14pt;
+	color: #737357;
+	background-color: #e3e3c7;
+	padding: 3px 10px 3px 10px;
+}
+
+.PopupButtons
+{
+	border-top: #d5d59d 1px solid;
+	background-color: #e3e3c7;
+	padding: 7px 10px 7px 10px;
+}
+
+.Button
+{
+	border: #737357 1px solid;
+	color: #3b3b1f;
+	background-color: #c7c78f;
+}
+
+#btnOk
+{
+	width: 100px;
+}
+
+.DarkBackground
+{
+	background-color: #d7d79f;
+}
+
+.LightBackground
+{
+	background-color: #ffffbe;
+}
+
+.PopupTitleBorder
+{
+	border-bottom: #d5d59d 1px solid;
+}
+
+.PopupTabArea
+{
+	color: #737357;
+	background-color: #e3e3c7;
+}
+
+.PopupTabEmptyArea
+{
+	padding-left: 10px ;
+	border-bottom: #d5d59d 1px solid;
+}
+
+.PopupTab, .PopupTabSelected
+{
+	border-right: #d5d59d 1px solid;
+	border-top: #d5d59d 1px solid;
+	border-left: #d5d59d 1px solid;
+	padding-right: 5px;
+	padding-left: 5px;
+	padding-bottom: 3px;
+	padding-top: 3px;
+	color: #737357;
+}
+
+.PopupTab
+{
+	margin-top: 1px;
+	border-bottom: #d5d59d 1px solid;
+	cursor: pointer;
+	cursor: hand;
+}
+
+.PopupTabSelected
+{
+	font-weight:bold;
+	cursor: default;
+	padding-top: 4px;
+	border-bottom: #f1f1e3 1px solid;
+	background-color: #f1f1e3;
+}
+
+.PopupSelectionBox
+{
+	border: #ff9933 1px solid !important;
+	background-color: #fffacd !important;
+	cursor: pointer;
+	cursor: hand;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/silver/fck_editor.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/silver/fck_editor.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/silver/fck_editor.css	(revision 795)
@@ -0,0 +1,473 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Styles used by the editor IFRAME and Toolbar.
+ */
+
+/*
+	### Basic Editor IFRAME Styles.
+*/
+
+body
+{
+	padding: 1px 1px 1px 1px;
+	margin: 0px 0px 0px 0px;
+}
+
+#xEditingArea
+{
+	border: #696969 1px solid;
+}
+
+.SourceField
+{
+	padding: 5px;
+	margin: 0px;
+	font-family: Monospace;
+}
+
+/*
+	Toolbar
+*/
+
+.TB_ToolbarSet, .TB_Expand, .TB_Collapse
+{
+    cursor: default;
+	background-color: #f7f7f7;
+}
+
+.TB_ToolbarSet
+{
+	padding: 1px;
+	border-top: #efefde 1px outset;
+	border-bottom: #efefde 1px outset;
+}
+
+.TB_ToolbarSet TD
+{
+	font-size: 11px;
+	font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.TB_Toolbar
+{
+    display: inline-table;
+}
+
+.TB_Separator
+{
+    width: 1px;
+    height: 21px;
+    margin: 2px;
+    background-color: #C6C3BD;
+}
+
+.TB_Start
+{
+    background-image: url(images/toolbar.start.gif);
+    margin-left: 2px;
+    margin-right: 2px;
+    width: 3px;
+    background-repeat: no-repeat;
+    height: 27px;
+    background-position: center center;
+}
+
+.TB_End
+{
+	display: none;
+}
+
+.TB_ExpandImg
+{
+	background-image: url(images/toolbar.expand.gif);
+	background-repeat: no-repeat;
+}
+
+.TB_CollapseImg
+{
+	background-image: url(images/toolbar.collapse.gif);
+	background-repeat: no-repeat;
+}
+
+.TB_SideBorder
+{
+	background-color: #696969;
+}
+
+.TB_Expand, .TB_Collapse
+{
+	padding: 2px 2px 2px 2px;
+	border: #efefde 1px outset;
+}
+
+.TB_Collapse
+{
+	border: #efefde 1px outset;
+	width: 5px;
+}
+
+.TB_Break
+{
+	height: 27px;
+}
+
+/*
+	Toolbar Button
+*/
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+	padding: 1px ;
+	margin:1px;
+	height: 21px;
+}
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+	border: #cec6b5 1px solid;
+}
+
+.TB_Button_On
+{
+	border-color: #316ac5;
+	background-color: #c1d2ee;
+}
+
+.TB_Button_On_Over, .TB_Button_Off_Over
+{
+    border: #316ac5 1px solid;
+    background-color: #dff1ff;
+}
+
+.TB_Button_Off
+{
+	background: #efefef url(images/toolbar.buttonbg.gif) repeat-x;
+}
+
+.TB_Button_Off, .TB_Combo_Off
+{
+	opacity: 0.70; /* Safari, Opera and Mozilla */
+	filter: alpha(opacity=70); /* IE */
+	/* -moz-opacity: 0.70; Mozilla (Old) */
+}
+
+.TB_Button_Disabled
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */
+}
+
+.TB_Button_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 21px;
+}
+
+.TB_Button_Image
+{
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    margin: 3px;
+    margin-top: 4px;
+    margin-bottom: 2px;
+    background-repeat: no-repeat;
+}
+
+/* For composed button ( icon + text, icon + arrow ), we must compensate the table */
+.TB_Button_On TABLE .TB_Button_Image,
+.TB_Button_Off TABLE .TB_Button_Image,
+.TB_Button_On_Over TABLE .TB_Button_Image,
+.TB_Button_Off_Over TABLE .TB_Button_Image,
+.TB_Button_Disabled TABLE .TB_Button_Image
+{
+    margin-top: 3px;
+}
+
+.TB_Button_Image img
+{
+    position: relative;
+}
+
+.TB_ConnectionLine
+{
+    background-color: #ffffff;
+    height: 1px;
+    margin-left: 1px;   /* ltr */
+    margin-right: 1px;  /* rtl */
+}
+
+/*
+	Menu
+*/
+
+.MN_Menu
+{
+    border: 1px solid #8f8f73;
+    padding: 2px;
+    background-color: #f7f7f7;
+    cursor: default;
+}
+
+.MN_Menu, .MN_Menu .MN_Label
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.MN_Item_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 20px;
+}
+
+.MN_Icon
+{
+    background-color: #dedede;
+    text-align: center;
+    height: 20px;
+}
+
+.MN_Label
+{
+    padding-left: 3px;
+    padding-right: 3px;
+}
+
+.MN_Separator
+{
+    height: 3px;
+}
+
+.MN_Separator_Line
+{
+    border-top: #b9b99d 1px solid;
+}
+
+.MN_Item .MN_Icon IMG
+{
+    filter: alpha(opacity=70);
+    opacity: 0.70;
+}
+
+.MN_Item_Over
+{
+    color: #ffffff;
+    background-color: #8a857d;
+}
+
+.MN_Item_Over .MN_Icon
+{
+    background-color: #6c6761;
+}
+
+.MN_Item_Disabled IMG
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.MN_Item_Disabled .MN_Label
+{
+    color: #b7b7b7;
+}
+
+.MN_Arrow
+{
+    padding-right: 3px;
+    padding-left: 3px;
+}
+
+.MN_ConnectionLine
+{
+    background-color: #ffffff;
+}
+
+.Menu .TB_Button_On, .Menu .TB_Button_On_Over
+{
+    border: #8f8f73 1px solid;
+    background-color: #ffffff;
+}
+
+/*
+	### Panel Styles
+*/
+
+.FCK_Panel
+{
+    border: #8f8f73 1px solid;
+    padding: 2px;
+    background-color: #ffffff;
+}
+
+.FCK_Panel, .FCK_Panel TD
+{
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+    font-size: 11px;
+}
+
+/*
+	### Special Combos
+*/
+
+.SC_Panel
+{
+    overflow: auto;
+    white-space: nowrap;
+    cursor: default;
+    border: 1px solid #8f8f73;
+    padding-left: 2px;
+    padding-right: 2px;
+    background-color: #ffffff;
+}
+
+.SC_Panel, .SC_Panel TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.SC_Item, .SC_ItemSelected
+{
+    margin-top: 2px;
+    margin-bottom: 2px;
+    background-position: left center;
+    padding-left: 11px;
+    padding-right: 3px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    background-repeat: no-repeat;
+    border: #dddddd 1px solid;
+}
+
+.SC_Item *, .SC_ItemSelected *
+{
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.SC_ItemSelected
+{
+    border: #9a9afb 1px solid;
+    background-image: url(images/toolbar.arrowright.gif);
+}
+
+.SC_ItemOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_Field
+{
+    margin-top:1px ;
+    border: #b7b7a6 1px solid;
+    cursor: default;
+}
+
+.SC_FieldCaption
+{
+    padding-top: 1px ;
+    overflow: visible;
+    padding-right: 5px;
+    padding-left: 5px;
+    opacity: 0.75; /* Safari, Opera and Mozilla */
+    filter: alpha(opacity=70); /* IE */ /* -moz-opacity: 0.75; Mozilla (Old) */
+    height: 23px;
+    background-color: #f7f7f7;
+}
+
+.SC_FieldLabel
+{
+    white-space: nowrap;
+    padding: 2px;
+    width: 100%;
+    cursor: default;
+    background-color: #ffffff;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.SC_FieldButton
+{
+    background-position: center center;
+    background-image: url(images/toolbar.buttonarrow.gif);
+    border-left: #b7b7a6 1px solid;
+    width: 14px;
+    background-repeat: no-repeat;
+}
+
+.SC_FieldDisabled .SC_FieldButton, .SC_FieldDisabled .SC_FieldCaption
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */ /* -moz-opacity: 0.30; Mozilla (Old) */
+}
+
+.SC_FieldOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_FieldOver .SC_FieldButton
+{
+    border-left: #316ac5 1px solid;
+}
+
+/*
+	### Color Selector Panel
+*/
+
+.ColorBoxBorder
+{
+    border: #808080 1px solid;
+    position: static;
+}
+
+.ColorBox
+{
+    font-size: 1px;
+    width: 10px;
+    position: static;
+    height: 10px;
+}
+
+.ColorDeselected, .ColorSelected
+{
+    cursor: default;
+}
+
+.ColorDeselected
+{
+    border: #ffffff 1px solid;
+    padding: 2px;
+    float: left;
+}
+
+.ColorSelected
+{
+    border: #316ac5 1px solid;
+    padding: 2px;
+    float: left;
+    background-color: #c1d2ee;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/silver/fck_dialog.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/silver/fck_dialog.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/silver/fck_dialog.css	(revision 795)
@@ -0,0 +1,141 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Styles used by the dialog boxes.
+ */
+
+body
+{
+	margin: 0px;
+	padding: 10px;
+	background-color: #f7f7f7;
+}
+
+body, td, input, select, textarea
+{
+	font-size: 11px;
+	font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+body, .BackColor
+{
+	background-color: #f7f7f7;
+}
+
+.PopupBody
+{
+	margin: 0px;
+	padding: 0px;
+}
+
+.PopupTitle
+{
+	padding-right: 10px;
+	padding-left: 10px;
+	font-weight: bold;
+	font-size: 14pt;
+	padding-bottom: 3px;
+	color: #504845;
+	padding-top: 3px;
+	background-color: #dedede;
+}
+
+.PopupButtons
+{
+	border-top: #cec6b5 1px solid;
+	background-color: #DEDEDE;
+	padding: 7px 10px 7px 10px;
+}
+
+.Button
+{
+	border: #7a7261 1px solid;
+	color: #504845;
+	background-color: #cec6b5;
+}
+
+#btnOk
+{
+	width: 100px;
+}
+
+.DarkBackground
+{
+	background-color: #d7d79f;
+}
+
+.LightBackground
+{
+	background-color: #ffffbe;
+}
+
+.PopupTitleBorder
+{
+	border-bottom: #cec6b5 1px solid;
+}
+
+.PopupTabArea
+{
+	color: #504845;
+	background-color: #DEDEDE;
+}
+
+.PopupTabEmptyArea
+{
+	padding-left: 10px ;
+	border-bottom: #cec6b5 1px solid;
+}
+
+.PopupTab, .PopupTabSelected
+{
+	border-right: #cec6b5 1px solid;
+	border-top: #cec6b5 1px solid;
+	border-left: #cec6b5 1px solid;
+	padding-right: 5px;
+	padding-left: 5px;
+	padding-bottom: 3px;
+	padding-top: 3px;
+	color: #504845;
+}
+
+.PopupTab
+{
+	margin-top: 1px;
+	border-bottom: #cec6b5 1px solid;
+	cursor: pointer;
+	cursor: hand;
+}
+
+.PopupTabSelected
+{
+	font-weight:bold;
+	cursor: default;
+	padding-top: 4px;
+	border-bottom: #f1f1e3 1px solid;
+	background-color: #f7f7f7;
+}
+
+.PopupSelectionBox
+{
+	border: #a9a9a9 1px solid !important;
+	background-color: #dcdcdc !important;
+	cursor: pointer;
+	cursor: hand;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/skins/_fckviewstrips.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/skins/_fckviewstrips.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/skins/_fckviewstrips.html	(revision 795)
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Useful page that enumerates all icons in the skins strips.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor - View Icons Strips</title>
+	<style type="text/css">
+		.TB_Button_Image
+		{
+			overflow: hidden;
+			width: 16px;
+			height: 16px;
+			margin: 3px;
+			background-repeat: no-repeat;
+		}
+
+		.TB_Button_Image img
+		{
+			position: relative;
+		}
+	</style>
+	<script type="text/javascript">
+
+window.onload = function()
+{
+	var eImg1 = document.createElement( 'img' ) ;
+	eImg1.onload = Img_OnLoad ;
+	eImg1.src = 'default/fck_strip.gif' ;
+
+	var eImg2 = document.createElement( 'img' ) ;
+	eImg2.onload = Img_OnLoad ;
+	eImg2.src = 'office2003/fck_strip.gif' ;
+
+	var eImg3 = document.createElement( 'img' ) ;
+	eImg3.onload = Img_OnLoad ;
+	eImg3.src = 'silver/fck_strip.gif' ;
+}
+
+var iTotalStrips = 3 ;
+var iMaxHeight = 0 ;
+
+function Img_OnLoad()
+{
+	if ( iMaxHeight < this.height )
+		iMaxHeight = this.height ;
+
+	iTotalStrips-- ;
+
+	if ( iTotalStrips == 0 )
+		LoadIcons( iMaxHeight / 16 ) ;
+}
+
+function LoadIcons( total )
+{
+	var xIconsTable = document.getElementById( 'xIconsTable' ) ;
+
+	for ( var i = 0 ; i < total ; i++ )
+	{
+		var eRow = xIconsTable.insertRow(-1) ;
+
+		var eCell = eRow.insertCell(-1) ;
+		eCell.innerHTML = i + 1 ;
+
+		eCell = eRow.insertCell(-1) ;
+		eCell.align = 'center' ;
+		eCell.style.border = '#dcdcdc 1px solid' ;
+		eCell.innerHTML = '<div class="TB_Button_Image"><img src="default/fck_strip.gif" style="top:-' + ( i * 16 ) + 'px;"><\/div>' ;
+
+		eCell = eRow.insertCell(-1) ;
+		eCell.align = 'center' ;
+		eCell.style.border = '#dcdcdc 1px solid' ;
+		eCell.innerHTML = '<div class="TB_Button_Image"><img src="office2003/fck_strip.gif" style="top:-' + ( i * 16 ) + 'px;"><\/div>' ;
+
+		eCell = eRow.insertCell(-1) ;
+		eCell.align = 'center' ;
+		eCell.style.border = '#dcdcdc 1px solid' ;
+		eCell.innerHTML = '<div class="TB_Button_Image"><img src="silver/fck_strip.gif" style="top:-' + ( i * 16 ) + 'px;"><\/div>' ;
+	}
+}
+
+	</script>
+</head>
+<body>
+	<table id="xIconsTable">
+		<tr>
+			<td rowspan="2">
+				Index</td>
+			<td align="center" colspan="3">
+				Skins</td>
+		</tr>
+		<tr>
+			<td width="80" align="center">
+				default</td>
+			<td width="80" align="center">
+				office2003</td>
+			<td width="80" align="center">
+				silver</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/css/behaviors/disablehandles.htc
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/css/behaviors/disablehandles.htc	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/css/behaviors/disablehandles.htc	(revision 795)
@@ -0,0 +1,15 @@
+<public:component lightweight="true">
+
+<script language="javascript">
+
+function CancelEvent()
+{
+	return false ;
+}
+
+this.onresizestart = CancelEvent ;
+this.onbeforeeditfocus = CancelEvent ;
+
+</script>
+
+</public:component>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/css/behaviors/showtableborders.htc
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/css/behaviors/showtableborders.htc	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/css/behaviors/showtableborders.htc	(revision 795)
@@ -0,0 +1,36 @@
+<public:component lightweight="true">
+
+<public:attach event="oncontentready" onevent="ShowBorders()" />
+<public:attach event="onpropertychange" onevent="OnPropertyChange()" />
+
+<script language="javascript">
+
+var oClassRegex = /\s*FCK__ShowTableBorders/ ;
+
+function ShowBorders()
+{
+	if ( this.border == 0 )
+	{
+		if ( !oClassRegex.test( this.className ) )
+			this.className += ' FCK__ShowTableBorders' ;
+	}
+	else
+	{
+		if ( oClassRegex.test( this.className ) )
+		{
+			this.className = this.className.replace( oClassRegex, '' ) ;
+			if ( this.className.length == 0 )
+				this.removeAttribute( 'className', 0 ) ;
+		}
+	}
+}
+
+function OnPropertyChange()
+{
+	if ( event.propertyName == 'border' || event.propertyName == 'className' )
+		ShowBorders.call(this) ;
+}
+
+</script>
+
+</public:component>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_internal.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_internal.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_internal.css	(revision 795)
@@ -0,0 +1,111 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This CSS Style Sheet defines rules used by the editor for its internal use.
+ */
+
+/* Fix to allow putting the caret at the end of the
+content in Firefox if clicking below the content */
+html
+{
+	min-height: 100%;
+}
+
+
+table.FCK__ShowTableBorders, table.FCK__ShowTableBorders td, table.FCK__ShowTableBorders th
+{
+	border: #d3d3d3 1px solid;
+}
+
+form
+{
+	border: 1px dotted #FF0000;
+	padding: 2px;
+}
+
+.FCK__Flash
+{
+	border: darkgray 1px solid;
+	background-position: center center;
+	background-image: url(images/fck_flashlogo.gif);
+	background-repeat: no-repeat;
+	width: 80px;
+	height: 80px;
+}
+
+/* Empty anchors images */
+.FCK__Anchor
+{
+	border: 1px dotted #00F;
+	background-position: center center;
+	background-image: url(images/fck_anchor.gif);
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 15px;
+	vertical-align: middle;
+}
+
+/* Anchors with content */
+.FCK__AnchorC
+{
+	border: 1px dotted #00F;
+	background-position: 1 center;
+	background-image: url(images/fck_anchor.gif);
+	background-repeat: no-repeat;
+	padding-left: 18px;
+}
+
+/* Any anchor for non-IE, if we combine it
+   with the previous rule IE ignores all. */
+a[name]
+{
+	border: 1px dotted #00F;
+	background-position: 0 center;
+	background-image: url(images/fck_anchor.gif);
+	background-repeat: no-repeat;
+	padding-left: 18px;
+}
+
+.FCK__PageBreak
+{
+	background-position: center center;
+	background-image: url(images/fck_pagebreak.gif);
+	background-repeat: no-repeat;
+	clear: both;
+	display: block;
+	float: none;
+	width: 100%;
+	border-top: #999999 1px dotted;
+	border-bottom: #999999 1px dotted;
+	border-right: 0px;
+	border-left: 0px;
+	height: 5px;
+}
+
+/* Hidden fields */
+.FCK__InputHidden
+{
+	width: 19px;
+	height: 18px;
+	background-image: url(images/fck_hiddenfield.gif);
+	background-repeat: no-repeat;
+	vertical-align: text-bottom;
+	background-position: center center;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_editorarea.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_editorarea.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_editorarea.css	(revision 795)
@@ -0,0 +1,91 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the default CSS file used by the editor area. It defines the
+ * initial font of the editor and background color.
+ *
+ * A user can configure the editor to use another CSS file. Just change
+ * the value of the FCKConfig.EditorAreaCSS key in the configuration
+ * file.
+ */
+
+/*
+    The "body" styles should match your editor web site, mainly regarding
+    background color and font family and size.
+*/
+
+body
+{
+	background-color: #ffffff;
+	padding: 5px 5px 5px 5px;
+	margin: 0px;
+}
+
+body, td
+{
+	font-family: Arial, Verdana, Sans-Serif;
+	font-size: 12px;
+}
+
+a[href]
+{
+	color: #0000FF !important;	/* For Firefox... mark as important, otherwise it becomes black */
+}
+
+/*
+	Just uncomment the following block if you want to avoid spaces between
+	paragraphs. Remember to apply the same style in your output front end page.
+*/
+
+/*
+p, ul, li
+{
+	margin-top: 0px;
+	margin-bottom: 0px;
+}
+*/
+
+/*
+    The following are some sample styles used in the "Styles" toolbar command.
+    You should instead remove them, and include the styles used by the site
+    you are using the editor in.
+*/
+
+.Bold
+{
+	font-weight: bold;
+}
+
+.Title
+{
+	font-weight: bold;
+	font-size: 18px;
+	color: #cc3300;
+}
+
+.Code
+{
+	border: #8b4513 1px solid;
+	padding-right: 5px;
+	padding-left: 5px;
+	color: #000066;
+	font-family: 'Courier New' , Monospace;
+	background-color: #ff9933;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_showtableborders_gecko.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_showtableborders_gecko.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/css/fck_showtableborders_gecko.css	(revision 795)
@@ -0,0 +1,42 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This CSS Style Sheet defines the rules to show table borders on Gecko.
+ */
+
+/* For tables with the "border" attribute set to "0" */
+table[border="0"],
+table[border="0"] > tr > td, table[border="0"] > tr > th,
+table[border="0"] > tbody > tr > td, table[border="0"] > tbody > tr > th,
+table[border="0"] > thead > tr > td, table[border="0"] > thead > tr > th,
+table[border="0"] > tfoot > tr > td, table[border="0"] > tfoot > tr > th
+{
+	border: #d3d3d3 1px dotted ;
+}
+
+/* For tables with no "border" attribute set */
+table:not([border]),
+table:not([border]) > tr > td, table:not([border]) > tr > th,
+table:not([border]) > tbody > tr > td, table:not([border]) > tbody > tr > th,
+table:not([border]) > thead > tr > td, table:not([border]) > thead > tr > th,
+table:not([border]) > tfoot > tr > td, table:not([border]) > tfoot > tr > th
+{
+	border: #d3d3d3 1px dotted ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmresourcetype.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmresourcetype.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmresourcetype.html	(revision 795)
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This page shows the list of available resource types.
+-->
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<link href="browser.css" type="text/css" rel="stylesheet">
+		<script type="text/javascript" src="js/common.js"></script>
+		<script language="javascript">
+
+function SetResourceType( type )
+{
+	window.parent.frames["frmFolders"].SetResourceType( type ) ;
+}
+
+var aTypes = [
+	['File','File'],
+	['Image','Image'],
+	['Flash','Flash'],
+	['Media','Media']
+] ;
+
+window.onload = function()
+{
+	for ( var i = 0 ; i < aTypes.length ; i++ )
+	{
+		if ( oConnector.ShowAllTypes || aTypes[i][0] == oConnector.ResourceType )
+			AddSelectOption( document.getElementById('cmbType'), aTypes[i][1], aTypes[i][0] ) ;
+	}
+}
+
+		</script>
+	</head>
+	<body bottomMargin="0" topMargin="0">
+		<table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+			<tr>
+				<td nowrap>
+					Resource Type<BR>
+					<select id="cmbType" style="WIDTH: 100%" onchange="SetResourceType(this.value);">
+					</select>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/browser.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/browser.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/browser.html	(revision 795)
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This page compose the File Browser dialog frameset.
+-->
+<html>
+	<head>
+		<title>FCKeditor - Resources Browser</title>
+		<link href="browser.css" type="text/css" rel="stylesheet">
+		<script type="text/javascript" src="js/fckxml.js"></script>
+		<script language="javascript">
+
+function GetUrlParam( paramName )
+{
+	var oRegex = new RegExp( '[\?&]' + paramName + '=([^&]+)', 'i' ) ;
+	var oMatch = oRegex.exec( window.top.location.search ) ;
+
+	if ( oMatch && oMatch.length > 1 )
+		return decodeURIComponent( oMatch[1] ) ;
+	else
+		return '' ;
+}
+
+var oConnector = new Object() ;
+oConnector.CurrentFolder	= '/' ;
+
+var sConnUrl = GetUrlParam( 'Connector' ) ;
+
+// Gecko has some problems when using relative URLs (not starting with slash).
+if ( sConnUrl.substr(0,1) != '/' && sConnUrl.indexOf( '://' ) < 0 )
+	sConnUrl = window.location.href.replace( /browser.html.*$/, '' ) + sConnUrl ;
+
+oConnector.ConnectorUrl = sConnUrl + ( sConnUrl.indexOf('?') != -1 ? '&' : '?' ) ;
+
+var sServerPath = GetUrlParam( 'ServerPath' ) ;
+if ( sServerPath.length > 0 )
+	oConnector.ConnectorUrl += 'ServerPath=' + encodeURIComponent( sServerPath ) + '&' ;
+
+oConnector.ResourceType		= GetUrlParam( 'Type' ) ;
+oConnector.ShowAllTypes		= ( oConnector.ResourceType.length == 0 ) ;
+
+if ( oConnector.ShowAllTypes )
+	oConnector.ResourceType = 'File' ;
+
+oConnector.SendCommand = function( command, params, callBackFunction )
+{
+	var sUrl = this.ConnectorUrl + 'Command=' + command ;
+	sUrl += '&Type=' + this.ResourceType ;
+	sUrl += '&CurrentFolder=' + encodeURIComponent( this.CurrentFolder ) ;
+
+	if ( params ) sUrl += '&' + params ;
+
+	var oXML = new FCKXml() ;
+
+	if ( callBackFunction )
+		oXML.LoadUrl( sUrl, callBackFunction ) ;	// Asynchronous load.
+	else
+		return oXML.LoadUrl( sUrl ) ;
+
+	return null ;
+}
+
+oConnector.CheckError = function( responseXml )
+{
+	var iErrorNumber = 0 ;
+	var oErrorNode = responseXml.SelectSingleNode( 'Connector/Error' ) ;
+
+	if ( oErrorNode )
+	{
+		iErrorNumber = parseInt( oErrorNode.attributes.getNamedItem('number').value, 10 ) ;
+
+		switch ( iErrorNumber )
+		{
+			case 0 :
+				break ;
+			case 1 :	// Custom error. Message placed in the "text" attribute.
+				alert( oErrorNode.attributes.getNamedItem('text').value ) ;
+				break ;
+			case 101 :
+				alert( 'Folder already exists' ) ;
+				break ;
+			case 102 :
+				alert( 'Invalid folder name' ) ;
+				break ;
+			case 103 :
+				alert( 'You have no permissions to create the folder' ) ;
+				break ;
+			case 110 :
+				alert( 'Unknown error creating folder' ) ;
+				break ;
+			default :
+				alert( 'Error on your request. Error number: ' + iErrorNumber ) ;
+				break ;
+		}
+	}
+	return iErrorNumber ;
+}
+
+var oIcons = new Object() ;
+
+oIcons.AvailableIconsArray = [
+	'ai','avi','bmp','cs','dll','doc','exe','fla','gif','htm','html','jpg','js',
+	'mdb','mp3','pdf','png','ppt','rdp','swf','swt','txt','vsd','xls','xml','zip' ] ;
+
+oIcons.AvailableIcons = new Object() ;
+
+for ( var i = 0 ; i < oIcons.AvailableIconsArray.length ; i++ )
+	oIcons.AvailableIcons[ oIcons.AvailableIconsArray[i] ] = true ;
+
+oIcons.GetIcon = function( fileName )
+{
+	var sExtension = fileName.substr( fileName.lastIndexOf('.') + 1 ).toLowerCase() ;
+
+	if ( this.AvailableIcons[ sExtension ] == true )
+		return sExtension ;
+	else
+		return 'default.icon' ;
+}
+		</script>
+	</head>
+	<frameset cols="150,*" class="Frame" framespacing="3" bordercolor="#f1f1e3" frameborder="1">
+		<frameset rows="50,*" framespacing="0">
+			<frame src="frmresourcetype.html" scrolling="no" frameborder="0">
+			<frame name="frmFolders" src="frmfolders.html" scrolling="auto" frameborder="1">
+		</frameset>
+		<frameset rows="50,*,50" framespacing="0">
+			<frame name="frmActualFolder" src="frmactualfolder.html" scrolling="no" frameborder="0">
+			<frame name="frmResourcesList" src="frmresourceslist.html" scrolling="auto" frameborder="1">
+			<frameset cols="150,*,0" framespacing="0" frameborder="0">
+				<frame name="frmCreateFolder" src="frmcreatefolder.html" scrolling="no" frameborder="0">
+				<frame name="frmUpload" src="frmupload.html" scrolling="no" frameborder="0">
+				<frame name="frmUploadWorker" src="javascript:void(0)" scrolling="no" frameborder="0">
+			</frameset>
+		</frameset>
+	</frameset>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmfolders.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmfolders.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmfolders.html	(revision 795)
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This page shows the list of folders available in the parent folder
+ * of the current folder.
+-->
+<html>
+	<head>
+		<link href="browser.css" type="text/css" rel="stylesheet">
+		<script type="text/javascript" src="js/common.js"></script>
+		<script language="javascript">
+
+var sActiveFolder ;
+
+var bIsLoaded = false ;
+var iIntervalId ;
+
+var oListManager = new Object() ;
+
+oListManager.Init = function()
+{
+	this.Table = document.getElementById('tableFiles') ;
+	this.UpRow = document.getElementById('trUp') ;
+
+	this.TableRows = new Object() ;
+}
+
+oListManager.Clear = function()
+{
+	// Remove all other rows available.
+	while ( this.Table.rows.length > 1 )
+		this.Table.deleteRow(1) ;
+
+	// Reset the TableRows collection.
+	this.TableRows = new Object() ;
+}
+
+oListManager.AddItem = function( folderName, folderPath )
+{
+	// Create the new row.
+	var oRow = this.Table.insertRow(-1) ;
+	oRow.className = 'FolderListFolder' ;
+
+	// Build the link to view the folder.
+	var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath + '\');return false;">' ;
+
+	// Add the folder icon cell.
+	var oCell = oRow.insertCell(-1) ;
+	oCell.width = 16 ;
+	oCell.innerHTML = sLink + '<img alt="" src="images/spacer.gif" width="16" height="16" border="0"></a>' ;
+
+	// Add the folder name cell.
+	oCell = oRow.insertCell(-1) ;
+	oCell.noWrap = true ;
+	oCell.innerHTML = '&nbsp;' + sLink + folderName + '</a>' ;
+
+	this.TableRows[ folderPath ] = oRow ;
+}
+
+oListManager.ShowUpFolder = function( upFolderPath )
+{
+	this.UpRow.style.display = ( upFolderPath != null ? '' : 'none' ) ;
+
+	if ( upFolderPath != null )
+	{
+		document.getElementById('linkUpIcon').onclick = document.getElementById('linkUp').onclick = function()
+		{
+			LoadFolders( upFolderPath ) ;
+			return false ;
+		}
+	}
+}
+
+function CheckLoaded()
+{
+	if ( window.top.IsLoadedActualFolder
+		&& window.top.IsLoadedCreateFolder
+		&& window.top.IsLoadedUpload
+		&& window.top.IsLoadedResourcesList )
+	{
+		window.clearInterval( iIntervalId ) ;
+		bIsLoaded = true ;
+		OpenFolder( sActiveFolder ) ;
+	}
+}
+
+function OpenFolder( folderPath )
+{
+	sActiveFolder = folderPath ;
+
+	if ( ! bIsLoaded )
+	{
+		if ( ! iIntervalId )
+			iIntervalId = window.setInterval( CheckLoaded, 100 ) ;
+		return ;
+	}
+
+	// Change the style for the select row (to show the opened folder).
+	for ( var sFolderPath in oListManager.TableRows )
+	{
+		oListManager.TableRows[ sFolderPath ].className =
+			( sFolderPath == folderPath ? 'FolderListCurrentFolder' : 'FolderListFolder' ) ;
+	}
+
+	// Set the current folder in all frames.
+	window.parent.frames['frmActualFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ;
+	window.parent.frames['frmCreateFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ;
+	window.parent.frames['frmUpload'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ;
+
+	// Load the resources list for this folder.
+	window.parent.frames['frmResourcesList'].LoadResources( oConnector.ResourceType, folderPath ) ;
+}
+
+function LoadFolders( folderPath )
+{
+	// Clear the folders list.
+	oListManager.Clear() ;
+
+	// Get the parent folder path.
+	var sParentFolderPath ;
+	if ( folderPath != '/' )
+		sParentFolderPath = folderPath.substring( 0, folderPath.lastIndexOf( '/', folderPath.length - 2 ) + 1 ) ;
+
+	// Show/Hide the Up Folder.
+	oListManager.ShowUpFolder( sParentFolderPath ) ;
+
+	if ( folderPath != '/' )
+	{
+		sActiveFolder = folderPath ;
+		oConnector.CurrentFolder = sParentFolderPath ;
+		oConnector.SendCommand( 'GetFolders', null, GetFoldersCallBack ) ;
+	}
+	else
+		OpenFolder( '/' ) ;
+}
+
+function GetFoldersCallBack( fckXml )
+{
+	if ( oConnector.CheckError( fckXml ) != 0 )
+		return ;
+
+	// Get the current folder path.
+	var oNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ;
+	var sCurrentFolderPath = oNode.attributes.getNamedItem('path').value ;
+
+	var oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ;
+
+	for ( var i = 0 ; i < oNodes.length ; i++ )
+	{
+		var sFolderName = oNodes[i].attributes.getNamedItem('name').value ;
+		oListManager.AddItem( sFolderName, sCurrentFolderPath + sFolderName + "/" ) ;
+	}
+
+	OpenFolder( sActiveFolder ) ;
+}
+
+function SetResourceType( type )
+{
+	oConnector.ResourceType = type ;
+	LoadFolders( '/' ) ;
+}
+
+window.onload = function()
+{
+	oListManager.Init() ;
+	LoadFolders( '/' ) ;
+}
+		</script>
+	</head>
+	<body class="FileArea" bottomMargin="10" leftMargin="10" topMargin="10" rightMargin="10">
+		<table id="tableFiles" cellSpacing="0" cellPadding="0" width="100%" border="0">
+			<tr id="trUp" style="DISPLAY: none">
+				<td width="16"><a id="linkUpIcon" href="#"><img alt="" src="images/FolderUp.gif" width="16" height="16" border="0"></a></td>
+				<td nowrap width="100%">&nbsp;<a id="linkUp" href="#">..</a></td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html	(revision 795)
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Page used to create new folders in the current folder.
+-->
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<link href="browser.css" type="text/css" rel="stylesheet">
+		<script type="text/javascript" src="js/common.js"></script>
+		<script language="javascript">
+
+function SetCurrentFolder( resourceType, folderPath )
+{
+	oConnector.ResourceType = resourceType ;
+	oConnector.CurrentFolder = folderPath ;
+}
+
+function CreateFolder()
+{
+	var sFolderName ;
+
+	while ( true )
+	{
+		sFolderName = prompt( 'Type the name of the new folder:', '' ) ;
+
+		if ( sFolderName == null )
+			return ;
+		else if ( sFolderName.length == 0 )
+			alert( 'Please type the folder name' ) ;
+		else
+			break ;
+	}
+
+	oConnector.SendCommand( 'CreateFolder', 'NewFolderName=' + encodeURIComponent( sFolderName) , CreateFolderCallBack ) ;
+}
+
+function CreateFolderCallBack( fckXml )
+{
+	if ( oConnector.CheckError( fckXml ) == 0 )
+		window.parent.frames['frmResourcesList'].Refresh() ;
+
+	/*
+	// Get the current folder path.
+	var oNode = fckXml.SelectSingleNode( 'Connector/Error' ) ;
+	var iErrorNumber = parseInt( oNode.attributes.getNamedItem('number').value ) ;
+
+	switch ( iErrorNumber )
+	{
+		case 0 :
+			window.parent.frames['frmResourcesList'].Refresh() ;
+			break ;
+		case 101 :
+			alert( 'Folder already exists' ) ;
+			break ;
+		case 102 :
+			alert( 'Invalid folder name' ) ;
+			break ;
+		case 103 :
+			alert( 'You have no permissions to create the folder' ) ;
+			break ;
+		case 110 :
+			alert( 'Unknown error creating folder' ) ;
+			break ;
+		default :
+			alert( 'Error creating folder. Error number: ' + iErrorNumber ) ;
+			break ;
+	}
+	*/
+}
+
+window.onload = function()
+{
+	window.top.IsLoadedCreateFolder = true ;
+}
+		</script>
+	</head>
+	<body bottomMargin="0" topMargin="0">
+		<table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+			<tr>
+				<td>
+					<button type="button" style="WIDTH: 100%" onclick="CreateFolder();">
+						<table cellSpacing="0" cellPadding="0" border="0">
+							<tr>
+								<td><img height="16" alt="" src="images/Folder.gif" width="16"></td>
+								<td>&nbsp;</td>
+								<td nowrap>Create New Folder</td>
+							</tr>
+						</table>
+					</button>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/browser.css
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/browser.css	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/browser.css	(revision 795)
@@ -0,0 +1,88 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * CSS styles used by all pages that compose the File Browser.
+ */
+
+body
+{
+	background-color: #f1f1e3;
+}
+
+form
+{
+	margin: 0px 0px 0px 0px ;
+	padding: 0px 0px 0px 0px ;
+}
+
+.Frame
+{
+	background-color: #f1f1e3;
+	border-color: #f1f1e3;
+	border-right: thin inset;
+	border-top: thin inset;
+	border-left: thin inset;
+	border-bottom: thin inset;
+}
+
+body.FileArea
+{
+
+	background-color: #ffffff;
+}
+
+body, td, input, select
+{
+	font-size: 11px;
+	font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+.ActualFolder
+{
+	font-weight: bold;
+	font-size: 14px;
+}
+
+.PopupButtons
+{
+	border-top: #d5d59d 1px solid;
+	background-color: #e3e3c7;
+	padding: 7px 10px 7px 10px;
+}
+
+.Button, button
+{
+	border-right: #737357 1px solid;
+	border-top: #737357 1px solid;
+	border-left: #737357 1px solid;
+	color: #3b3b1f;
+	border-bottom: #737357 1px solid;
+	background-color: #c7c78f;
+}
+
+.FolderListCurrentFolder img
+{
+	background-image: url(images/FolderOpened.gif);
+}
+
+.FolderListFolder img
+{
+	background-image: url(images/Folder.gif);
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmupload.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmupload.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmupload.html	(revision 795)
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Page used to upload new files in the current folder.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<link href="browser.css" type="text/css" rel="stylesheet" />
+		<script type="text/javascript" src="js/common.js"></script>
+		<script type="text/javascript">
+
+function SetCurrentFolder( resourceType, folderPath )
+{
+	var sUrl = oConnector.ConnectorUrl + 'Command=FileUpload' ;
+	sUrl += '&Type=' + resourceType ;
+	sUrl += '&CurrentFolder=' + encodeURIComponent( folderPath ) ;
+
+	document.getElementById('frmUpload').action = sUrl ;
+}
+
+function OnSubmit()
+{
+	if ( document.getElementById('NewFile').value.length == 0 )
+	{
+		alert( 'Please select a file from your computer' ) ;
+		return false ;
+	}
+
+	// Set the interface elements.
+	document.getElementById('eUploadMessage').innerHTML = 'Upload a new file in this folder (Upload in progress, please wait...)' ;
+	document.getElementById('btnUpload').disabled = true ;
+
+	return true ;
+}
+
+function OnUploadCompleted( errorNumber, data )
+{
+	// Reset the Upload Worker Frame.
+	window.parent.frames['frmUploadWorker'].location = 'javascript:void(0)' ;
+
+	// Reset the upload form (On IE we must do a little trick to avout problems).
+	if ( document.all )
+		document.getElementById('NewFile').outerHTML = '<input id="NewFile" name="NewFile" style="WIDTH: 100%" type="file">' ;
+	else
+		document.getElementById('frmUpload').reset() ;
+
+	// Reset the interface elements.
+	document.getElementById('eUploadMessage').innerHTML = 'Upload a new file in this folder' ;
+	document.getElementById('btnUpload').disabled = false ;
+
+	switch ( errorNumber )
+	{
+		case 0 :
+			window.parent.frames['frmResourcesList'].Refresh() ;
+			break ;
+		case 1 :	// Custom error.
+			alert( data ) ;
+			break ;
+		case 201 :
+			window.parent.frames['frmResourcesList'].Refresh() ;
+			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + data + '"' ) ;
+			break ;
+		case 202 :
+			alert( 'Invalid file' ) ;
+			break ;
+		default :
+			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+			break ;
+	}
+}
+
+window.onload = function()
+{
+	window.top.IsLoadedUpload = true ;
+}
+		</script>
+	</head>
+	<body bottommargin="0" topmargin="0">
+		<form id="frmUpload" action="" target="frmUploadWorker" method="post" enctype="multipart/form-data" onsubmit="return OnSubmit();">
+			<table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0">
+				<tr>
+					<td nowrap="nowrap">
+						<span id="eUploadMessage">Upload a new file in this folder</span><br>
+						<table cellspacing="0" cellpadding="0" width="100%" border="0">
+							<tr>
+								<td width="100%"><input id="NewFile" name="NewFile" style="WIDTH: 100%" type="file"></td>
+								<td nowrap="nowrap">&nbsp;<input id="btnUpload" type="submit" value="Upload"></td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+			</table>
+		</form>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/js/fckxml.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/js/fckxml.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/js/fckxml.js	(revision 795)
@@ -0,0 +1,130 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Defines the FCKXml object that is used for XML data calls
+ * and XML processing.
+ *
+ * This script is shared by almost all pages that compose the
+ * File Browser frameset.
+ */
+
+var FCKXml = function()
+{}
+
+FCKXml.prototype.GetHttpRequest = function()
+{
+	// Gecko / IE7
+	if ( typeof(XMLHttpRequest) != 'undefined' )
+		return new XMLHttpRequest() ;
+
+	// IE6
+	try { return new ActiveXObject( 'Msxml2.XMLHTTP' ) ; }
+	catch(e) {}
+
+	// IE5
+	try { return new ActiveXObject( 'Microsoft.XMLHTTP' ) ; }
+	catch(e) {}
+
+	return null ;
+}
+
+FCKXml.prototype.LoadUrl = function( urlToCall, asyncFunctionPointer )
+{
+	var oFCKXml = this ;
+
+	var bAsync = ( typeof(asyncFunctionPointer) == 'function' ) ;
+
+	var oXmlHttp = this.GetHttpRequest() ;
+
+	oXmlHttp.open( "GET", urlToCall, bAsync ) ;
+
+	if ( bAsync )
+	{
+		oXmlHttp.onreadystatechange = function()
+		{
+			if ( oXmlHttp.readyState == 4 )
+			{
+				if ( oXmlHttp.responseXML == null || oXmlHttp.responseXML.firstChild == null)
+				{
+					alert( 'The server didn\'t send back a proper XML response.\r\n\r\n' +
+							'Requested URL: ' + urlToCall + '\r\n' +
+							'Response text:\r\n' + oXmlHttp.responseText ) ;
+					return ;
+				}
+				oFCKXml.DOMDocument = oXmlHttp.responseXML ;
+				if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
+					asyncFunctionPointer( oFCKXml ) ;
+				else
+					alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ;
+			}
+		}
+	}
+
+	oXmlHttp.send( null ) ;
+
+	if ( ! bAsync )
+	{
+		if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
+			this.DOMDocument = oXmlHttp.responseXML ;
+		else
+		{
+			alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ;
+		}
+	}
+}
+
+FCKXml.prototype.SelectNodes = function( xpath )
+{
+	if ( navigator.userAgent.indexOf('MSIE') >= 0 )		// IE
+		return this.DOMDocument.selectNodes( xpath ) ;
+	else					// Gecko
+	{
+		var aNodeArray = new Array();
+
+		var xPathResult = this.DOMDocument.evaluate( xpath, this.DOMDocument,
+				this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
+		if ( xPathResult )
+		{
+			var oNode = xPathResult.iterateNext() ;
+ 			while( oNode )
+ 			{
+ 				aNodeArray[aNodeArray.length] = oNode ;
+ 				oNode = xPathResult.iterateNext();
+ 			}
+		}
+		return aNodeArray ;
+	}
+}
+
+FCKXml.prototype.SelectSingleNode = function( xpath )
+{
+	if ( navigator.userAgent.indexOf('MSIE') >= 0 )		// IE
+		return this.DOMDocument.selectSingleNode( xpath ) ;
+	else					// Gecko
+	{
+		var xPathResult = this.DOMDocument.evaluate( xpath, this.DOMDocument,
+				this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), 9, null);
+
+		if ( xPathResult && xPathResult.singleNodeValue )
+			return xPathResult.singleNodeValue ;
+		else
+			return null ;
+	}
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/js/common.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/js/common.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/js/common.js	(revision 795)
@@ -0,0 +1,55 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Common objects and functions shared by all pages that compose the
+ * File Browser dialog window.
+ */
+
+function AddSelectOption( selectElement, optionText, optionValue )
+{
+	var oOption = document.createElement("OPTION") ;
+
+	oOption.text	= optionText ;
+	oOption.value	= optionValue ;
+
+	selectElement.options.add(oOption) ;
+
+	return oOption ;
+}
+
+var oConnector	= window.parent.oConnector ;
+var oIcons		= window.parent.oIcons ;
+
+
+function StringBuilder( value )
+{
+    this._Strings = new Array( value || '' ) ;
+}
+
+StringBuilder.prototype.Append = function( value )
+{
+    if ( value )
+        this._Strings.push( value ) ;
+}
+
+StringBuilder.prototype.ToString = function()
+{
+    return this._Strings.join( '' ) ;
+}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/test.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/test.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/test.html	(revision 795)
@@ -0,0 +1,180 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Test page for the File Browser connectors.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor - Connectors Tests</title>
+	<script type="text/javascript">
+
+function BuildBaseUrl( command )
+{
+	var sUrl =
+		document.getElementById('cmbConnector').value +
+		'?Command=' + command +
+		'&Type=' + document.getElementById('cmbType').value +
+		'&CurrentFolder=' + document.getElementById('txtFolder').value ;
+
+	return sUrl ;
+}
+
+function SetFrameUrl( url )
+{
+	if ( document.all )
+		eRunningFrame.document.location = url ;
+	else
+		document.getElementById('eRunningFrame').src = url ;
+
+	document.getElementById('eUrl').innerHTML = url ;
+}
+
+function GetFolders()
+{
+	SetFrameUrl( BuildBaseUrl( 'GetFolders' ) ) ;
+	return false ;
+}
+
+function GetFoldersAndFiles()
+{
+	SetFrameUrl( BuildBaseUrl( 'GetFoldersAndFiles' ) ) ;
+	return false ;
+}
+
+function CreateFolder()
+{
+	var sFolder = prompt( 'Type the folder name:', 'Test Folder' ) ;
+
+	if ( ! sFolder )
+		return false ;
+
+	var sUrl = BuildBaseUrl( 'CreateFolder' ) ;
+	sUrl += '&NewFolderName=' + encodeURIComponent( sFolder ) ;
+
+	SetFrameUrl( sUrl ) ;
+	return false ;
+}
+
+function OnUploadCompleted( errorNumber, fileName )
+{
+	switch ( errorNumber )
+	{
+		case 0 :
+			alert( 'File uploaded with no errors' ) ;
+			break ;
+		case 201 :
+			GetFoldersAndFiles() ;
+			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+			break ;
+		case 202 :
+			alert( 'Invalid file' ) ;
+			break ;
+		default :
+			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+			break ;
+	}
+}
+
+this.frames.frmUpload = this ;
+
+function SetAction()
+{
+	var sUrl = BuildBaseUrl( 'FileUpload' ) ;
+	document.getElementById('eUrl').innerHTML = sUrl ;
+	document.getElementById('frmUpload').action = sUrl ;
+}
+
+	</script>
+</head>
+<body>
+	<table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0">
+		<tr>
+			<td>
+				<table cellspacing="0" cellpadding="0" border="0">
+					<tr>
+						<td>
+							Connector:<br />
+							<select id="cmbConnector" name="cmbConnector">
+								<option value="asp/connector.asp" selected="selected">ASP</option>
+								<option value="aspx/connector.aspx">ASP.Net</option>
+								<option value="cfm/connector.cfm">ColdFusion</option>
+								<option value="lasso/connector.lasso">Lasso</option>
+								<option value="perl/connector.cgi">Perl</option>
+								<option value="php/connector.php">PHP</option>
+								<option value="py/connector.py">Python</option>
+							</select>
+						</td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td>
+							Current Folder<br />
+							<input id="txtFolder" type="text" value="/" name="txtFolder" /></td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td>
+							Resource Type<br />
+							<select id="cmbType" name="cmbType">
+								<option value="File" selected="selected">File</option>
+								<option value="Image">Image</option>
+								<option value="Flash">Flash</option>
+								<option value="Media">Media</option>
+								<option value="Invalid">Invalid Type (for testing)</option>
+							</select>
+						</td>
+					</tr>
+				</table>
+				<br />
+				<table cellspacing="0" cellpadding="0" border="0">
+					<tr>
+						<td valign="top">
+							<a href="#" onclick="GetFolders();">Get Folders</a></td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td valign="top">
+							<a href="#" onclick="GetFoldersAndFiles();">Get Folders and Files</a></td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td valign="top">
+							<a href="#" onclick="CreateFolder();">Create Folder</a></td>
+						<td>
+							&nbsp;&nbsp;&nbsp;</td>
+						<td valign="top">
+							<form id="frmUpload" action="" target="eRunningFrame" method="post" enctype="multipart/form-data">
+								File Upload<br />
+								<input id="txtFileUpload" type="file" name="NewFile" />
+								<input type="submit" value="Upload" onclick="SetAction();" />
+							</form>
+						</td>
+					</tr>
+				</table>
+				<br />
+				URL: <span id="eUrl"></span>
+			</td>
+		</tr>
+		<tr>
+			<td height="100%" valign="top">
+				<iframe id="eRunningFrame" src="javascript:void(0)" name="eRunningFrame" width="100%"
+					height="100%"></iframe>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php	(revision 795)
@@ -0,0 +1,113 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the File Manager Connector for PHP.
+ */
+
+ob_start() ;
+
+include('config.php') ;
+include('util.php') ;
+include('io.php') ;
+include('basexml.php') ;
+include('commands.php') ;
+
+if ( !$Config['Enabled'] )
+	SendError( 1, 'This connector is disabled. Please check the "editor/filemanager/browser/default/connectors/php/config.php" file' ) ;
+
+// Get the "UserFiles" path.
+$GLOBALS["UserFilesPath"] = '' ;
+
+if ( isset( $Config['UserFilesPath'] ) )
+	$GLOBALS["UserFilesPath"] = $Config['UserFilesPath'] ;
+else if ( isset( $_GET['ServerPath'] ) )
+	$GLOBALS["UserFilesPath"] = $_GET['ServerPath'] ;
+else
+	$GLOBALS["UserFilesPath"] = '/userfiles/' ;
+
+if ( ! ereg( '/$', $GLOBALS["UserFilesPath"] ) )
+	$GLOBALS["UserFilesPath"] .= '/' ;
+
+if ( strlen( $Config['UserFilesAbsolutePath'] ) > 0 )
+{
+	$GLOBALS["UserFilesDirectory"] = $Config['UserFilesAbsolutePath'] ;
+
+	if ( ! ereg( '/$', $GLOBALS["UserFilesDirectory"] ) )
+		$GLOBALS["UserFilesDirectory"] .= '/' ;
+}
+else
+{
+	// Map the "UserFiles" path to a local directory.
+	$GLOBALS["UserFilesDirectory"] = GetRootPath() . $GLOBALS["UserFilesPath"] ;
+}
+
+DoResponse() ;
+
+function DoResponse()
+{
+	if ( !isset( $_GET['Command'] ) || !isset( $_GET['Type'] ) || !isset( $_GET['CurrentFolder'] ) )
+		return ;
+
+	// Get the main request informaiton.
+	$sCommand		= $_GET['Command'] ;
+	$sResourceType	= $_GET['Type'] ;
+	$sCurrentFolder	= $_GET['CurrentFolder'] ;
+
+	// Check if it is an allowed type.
+	if ( !in_array( $sResourceType, array('File','Image','Flash','Media') ) )
+		return ;
+
+	// Check the current folder syntax (must begin and start with a slash).
+	if ( ! ereg( '/$', $sCurrentFolder ) ) $sCurrentFolder .= '/' ;
+	if ( strpos( $sCurrentFolder, '/' ) !== 0 ) $sCurrentFolder = '/' . $sCurrentFolder ;
+
+	// Check for invalid folder paths (..)
+	if ( strpos( $sCurrentFolder, '..' ) )
+		SendError( 102, "" ) ;
+
+	// File Upload doesn't have to Return XML, so it must be intercepted before anything.
+	if ( $sCommand == 'FileUpload' )
+	{
+		FileUpload( $sResourceType, $sCurrentFolder ) ;
+		return ;
+	}
+
+	CreateXmlHeader( $sCommand, $sResourceType, $sCurrentFolder ) ;
+
+	// Execute the required command.
+	switch ( $sCommand )
+	{
+		case 'GetFolders' :
+			GetFolders( $sResourceType, $sCurrentFolder ) ;
+			break ;
+		case 'GetFoldersAndFiles' :
+			GetFoldersAndFiles( $sResourceType, $sCurrentFolder ) ;
+			break ;
+		case 'CreateFolder' :
+			CreateFolder( $sResourceType, $sCurrentFolder ) ;
+			break ;
+	}
+
+	CreateXmlFooter() ;
+
+	exit ;
+}
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php	(revision 795)
@@ -0,0 +1,75 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * These functions define the base of the XML response sent by the PHP
+ * connector.
+ */
+
+function SetXmlHeaders()
+{
+	ob_end_clean() ;
+
+	// Prevent the browser from caching the result.
+	// Date in the past
+	header('Expires: Mon, 26 Jul 1997 05:00:00 GMT') ;
+	// always modified
+	header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT') ;
+	// HTTP/1.1
+	header('Cache-Control: no-store, no-cache, must-revalidate') ;
+	header('Cache-Control: post-check=0, pre-check=0', false) ;
+	// HTTP/1.0
+	header('Pragma: no-cache') ;
+
+	// Set the response format.
+	header( 'Content-Type:text/xml; charset=utf-8' ) ;
+}
+
+function CreateXmlHeader( $command, $resourceType, $currentFolder )
+{
+	SetXmlHeaders() ;
+
+	// Create the XML document header.
+	echo '<?xml version="1.0" encoding="utf-8" ?>' ;
+
+	// Create the main "Connector" node.
+	echo '<Connector command="' . $command . '" resourceType="' . $resourceType . '">' ;
+
+	// Add the current folder node.
+	echo '<CurrentFolder path="' . ConvertToXmlAttribute( $currentFolder ) . '" url="' . ConvertToXmlAttribute( GetUrlFromPath( $resourceType, $currentFolder ) ) . '" />' ;
+}
+
+function CreateXmlFooter()
+{
+	echo '</Connector>' ;
+}
+
+function SendError( $number, $text )
+{
+	SetXmlHeaders() ;
+
+	// Create the XML document header
+	echo '<?xml version="1.0" encoding="utf-8" ?>' ;
+
+	echo '<Connector><Error number="' . $number . '" text="' . htmlspecialchars( $text ) . '" /></Connector>' ;
+
+	exit ;
+}
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/util.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/util.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/util.php	(revision 795)
@@ -0,0 +1,41 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Utility functions for the File Manager Connector for PHP.
+ */
+
+function RemoveFromStart( $sourceString, $charToRemove )
+{
+	$sPattern = '|^' . $charToRemove . '+|' ;
+	return preg_replace( $sPattern, '', $sourceString ) ;
+}
+
+function RemoveFromEnd( $sourceString, $charToRemove )
+{
+	$sPattern = '|' . $charToRemove . '+$|' ;
+	return preg_replace( $sPattern, '', $sourceString ) ;
+}
+
+function ConvertToXmlAttribute( $value )
+{
+	return utf8_encode( htmlspecialchars( $value ) ) ;
+}
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php	(revision 795)
@@ -0,0 +1,222 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the File Manager Connector for PHP.
+ */
+
+function GetFolders( $resourceType, $currentFolder )
+{
+	// Map the virtual path to the local server path.
+	$sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+	// Array that will hold the folders names.
+	$aFolders	= array() ;
+
+	$oCurrentFolder = opendir( $sServerDir ) ;
+
+	while ( $sFile = readdir( $oCurrentFolder ) )
+	{
+		if ( $sFile != '.' && $sFile != '..' && is_dir( $sServerDir . $sFile ) )
+			$aFolders[] = '<Folder name="' . ConvertToXmlAttribute( $sFile ) . '" />' ;
+	}
+
+	closedir( $oCurrentFolder ) ;
+
+	// Open the "Folders" node.
+	echo "<Folders>" ;
+
+	natcasesort( $aFolders ) ;
+	foreach ( $aFolders as $sFolder )
+		echo $sFolder ;
+
+	// Close the "Folders" node.
+	echo "</Folders>" ;
+}
+
+function GetFoldersAndFiles( $resourceType, $currentFolder )
+{
+	// Map the virtual path to the local server path.
+	$sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+	// Arrays that will hold the folders and files names.
+	$aFolders	= array() ;
+	$aFiles		= array() ;
+
+	$oCurrentFolder = opendir( $sServerDir ) ;
+
+	while ( $sFile = readdir( $oCurrentFolder ) )
+	{
+		if ( $sFile != '.' && $sFile != '..' )
+		{
+			if ( is_dir( $sServerDir . $sFile ) )
+				$aFolders[] = '<Folder name="' . ConvertToXmlAttribute( $sFile ) . '" />' ;
+			else
+			{
+				$iFileSize = filesize( $sServerDir . $sFile ) ;
+				if ( $iFileSize > 0 )
+				{
+					$iFileSize = round( $iFileSize / 1024 ) ;
+					if ( $iFileSize < 1 ) $iFileSize = 1 ;
+				}
+
+				$aFiles[] = '<File name="' . ConvertToXmlAttribute( $sFile ) . '" size="' . $iFileSize . '" />' ;
+			}
+		}
+	}
+
+	// Send the folders
+	natcasesort( $aFolders ) ;
+	echo '<Folders>' ;
+
+	foreach ( $aFolders as $sFolder )
+		echo $sFolder ;
+
+	echo '</Folders>' ;
+
+	// Send the files
+	natcasesort( $aFiles ) ;
+	echo '<Files>' ;
+
+	foreach ( $aFiles as $sFiles )
+		echo $sFiles ;
+
+	echo '</Files>' ;
+}
+
+function CreateFolder( $resourceType, $currentFolder )
+{
+	$sErrorNumber	= '0' ;
+	$sErrorMsg		= '' ;
+
+	if ( isset( $_GET['NewFolderName'] ) )
+	{
+		$sNewFolderName = $_GET['NewFolderName'] ;
+
+		if ( strpos( $sNewFolderName, '..' ) !== FALSE )
+			$sErrorNumber = '102' ;		// Invalid folder name.
+		else
+		{
+			// Map the virtual path to the local server path of the current folder.
+			$sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+			if ( is_writable( $sServerDir ) )
+			{
+				$sServerDir .= $sNewFolderName ;
+
+				$sErrorMsg = CreateServerFolder( $sServerDir ) ;
+
+				switch ( $sErrorMsg )
+				{
+					case '' :
+						$sErrorNumber = '0' ;
+						break ;
+					case 'Invalid argument' :
+					case 'No such file or directory' :
+						$sErrorNumber = '102' ;		// Path too long.
+						break ;
+					default :
+						$sErrorNumber = '110' ;
+						break ;
+				}
+			}
+			else
+				$sErrorNumber = '103' ;
+		}
+	}
+	else
+		$sErrorNumber = '102' ;
+
+	// Create the "Error" node.
+	echo '<Error number="' . $sErrorNumber . '" originalDescription="' . ConvertToXmlAttribute( $sErrorMsg ) . '" />' ;
+}
+
+function FileUpload( $resourceType, $currentFolder )
+{
+	$sErrorNumber = '0' ;
+	$sFileName = '' ;
+
+	if ( isset( $_FILES['NewFile'] ) && !is_null( $_FILES['NewFile']['tmp_name'] ) )
+	{
+		global $Config ;
+
+		$oFile = $_FILES['NewFile'] ;
+
+		// Map the virtual path to the local server path.
+		$sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+		// Get the uploaded file name.
+		$sFileName = $oFile['name'] ;
+
+		// Replace dots in the name with underscores (only one dot can be there... security issue).
+		if ( $Config['ForceSingleExtension'] )
+			$sFileName = preg_replace( '/\\.(?![^.]*$)/', '_', $sFileName ) ;
+
+		$sOriginalFileName = $sFileName ;
+
+		// Get the extension.
+		$sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
+		$sExtension = strtolower( $sExtension ) ;
+
+		$arAllowed	= $Config['AllowedExtensions'][$resourceType] ;
+		$arDenied	= $Config['DeniedExtensions'][$resourceType] ;
+
+		if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) )
+		{
+			$iCounter = 0 ;
+
+			while ( true )
+			{
+				$sFilePath = $sServerDir . $sFileName ;
+
+				if ( is_file( $sFilePath ) )
+				{
+					$iCounter++ ;
+					$sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;
+					$sErrorNumber = '201' ;
+				}
+				else
+				{
+					move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
+
+					if ( is_file( $sFilePath ) )
+					{
+						$oldumask = umask(0) ;
+						chmod( $sFilePath, 0777 ) ;
+						umask( $oldumask ) ;
+					}
+
+					break ;
+				}
+			}
+		}
+		else
+			$sErrorNumber = '202' ;
+	}
+	else
+		$sErrorNumber = '202' ;
+
+	echo '<script type="text/javascript">' ;
+	echo 'window.parent.frames["frmUpload"].OnUploadCompleted(' . $sErrorNumber . ',"' . str_replace( '"', '\\"', $sFileName ) . '") ;' ;
+	echo '</script>' ;
+
+	exit ;
+}
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/config.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/config.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/config.php	(revision 795)
@@ -0,0 +1,56 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Configuration file for the File Manager Connector for PHP.
+ */
+
+global $Config ;
+
+// SECURITY: You must explicitelly enable this "connector". (Set it to "true").
+$Config['Enabled'] = false ;
+
+
+// Path to user files relative to the document root.
+$Config['UserFilesPath'] = '/userfiles/' ;
+
+// Fill the following value it you prefer to specify the absolute path for the
+// user files directory. Usefull if you are using a virtual directory, symbolic
+// link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
+// Attention: The above 'UserFilesPath' must point to the same directory.
+$Config['UserFilesAbsolutePath'] = '' ;
+
+// Due to security issues with Apache modules, it is reccomended to leave the
+// following setting enabled.
+$Config['ForceSingleExtension'] = true ;
+
+$Config['AllowedExtensions']['File']	= array() ;
+$Config['DeniedExtensions']['File']		= array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis') ;
+
+$Config['AllowedExtensions']['Image']	= array('jpg','gif','jpeg','png') ;
+$Config['DeniedExtensions']['Image']	= array() ;
+
+$Config['AllowedExtensions']['Flash']	= array('swf','fla') ;
+$Config['DeniedExtensions']['Flash']	= array() ;
+
+$Config['AllowedExtensions']['Media']	= array('swf','fla','jpg','gif','jpeg','png','avi','mpg','mpeg') ;
+$Config['DeniedExtensions']['Media']	= array() ;
+
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/io.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/io.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/connectors/php/io.php	(revision 795)
@@ -0,0 +1,101 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the File Manager Connector for PHP.
+ */
+
+function GetUrlFromPath( $resourceType, $folderPath )
+{
+	if ( $resourceType == '' )
+		return RemoveFromEnd( $GLOBALS["UserFilesPath"], '/' ) . $folderPath ;
+	else
+		return $GLOBALS["UserFilesPath"] . strtolower( $resourceType ) . $folderPath ;
+}
+
+function RemoveExtension( $fileName )
+{
+	return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ;
+}
+
+function ServerMapFolder( $resourceType, $folderPath )
+{
+	// Get the resource type directory.
+	$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . strtolower( $resourceType ) . '/' ;
+
+	// Ensure that the directory exists.
+	CreateServerFolder( $sResourceTypePath ) ;
+
+	// Return the resource type directory combined with the required path.
+	return $sResourceTypePath . RemoveFromStart( $folderPath, '/' ) ;
+}
+
+function GetParentFolder( $folderPath )
+{
+	$sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-" ;
+	return preg_replace( $sPattern, '', $folderPath ) ;
+}
+
+function CreateServerFolder( $folderPath )
+{
+	$sParent = GetParentFolder( $folderPath ) ;
+
+	// Check if the parent exists, or create it.
+	if ( !file_exists( $sParent ) )
+	{
+		$sErrorMsg = CreateServerFolder( $sParent ) ;
+		if ( $sErrorMsg != '' )
+			return $sErrorMsg ;
+	}
+
+	if ( !file_exists( $folderPath ) )
+	{
+		// Turn off all error reporting.
+		error_reporting( 0 ) ;
+		// Enable error tracking to catch the error.
+		ini_set( 'track_errors', '1' ) ;
+
+		// To create the folder with 0777 permissions, we need to set umask to zero.
+		$oldumask = umask(0) ;
+		mkdir( $folderPath, 0777 ) ;
+		umask( $oldumask ) ;
+
+		$sErrorMsg = $php_errormsg ;
+
+		// Restore the configurations.
+		ini_restore( 'track_errors' ) ;
+		ini_restore( 'error_reporting' ) ;
+
+		return $sErrorMsg ;
+	}
+	else
+		return '' ;
+}
+
+function GetRootPath()
+{
+	$sRealPath = realpath( './' ) ;
+
+	$sSelfPath = $_SERVER['PHP_SELF'] ;
+	$sSelfPath = substr( $sSelfPath, 0, strrpos( $sSelfPath, '/' ) ) ;
+
+	return substr( $sRealPath, 0, strlen( $sRealPath ) - strlen( $sSelfPath ) ) ;
+}
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmactualfolder.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmactualfolder.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmactualfolder.html	(revision 795)
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This page shows the actual folder path.
+-->
+<html>
+	<head>
+		<link href="browser.css" type="text/css" rel="stylesheet">
+		<script type="text/javascript">
+
+function OnResize()
+{
+	divName.style.width = "1px" ;
+	divName.style.width = tdName.offsetWidth + "px" ;
+}
+
+function SetCurrentFolder( resourceType, folderPath )
+{
+	document.getElementById('tdName').innerHTML = folderPath ;
+}
+
+window.onload = function()
+{
+	window.top.IsLoadedActualFolder = true ;
+}
+
+		</script>
+	</head>
+	<body bottomMargin="0" topMargin="0">
+		<table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+			<tr>
+				<td>
+					<button style="WIDTH: 100%" type="button">
+						<table cellSpacing="0" cellPadding="0" width="100%" border="0">
+							<tr>
+								<td><img height="32" alt="" src="images/FolderOpened32.gif" width="32"></td>
+								<td>&nbsp;</td>
+								<td id="tdName" width="100%" nowrap class="ActualFolder">/</td>
+								<td>&nbsp;</td>
+								<td><img height="8" src="images/ButtonArrow.gif" width="12"></td>
+								<td>&nbsp;</td>
+							</tr>
+						</table>
+					</button>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmresourceslist.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmresourceslist.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/browser/default/frmresourceslist.html	(revision 795)
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This page shows all resources available in a folder in the File Browser.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<link href="browser.css" type="text/css" rel="stylesheet" />
+	<script type="text/javascript" src="js/common.js"></script>
+	<script type="text/javascript">
+
+var oListManager = new Object() ;
+
+oListManager.Clear = function()
+{
+	document.body.innerHTML = '' ;
+}
+
+oListManager.GetFolderRowHtml = function( folderName, folderPath )
+{
+	// Build the link to view the folder.
+	var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath.replace( /'/g, '\\\'') + '\');return false;">' ;
+
+	return '<tr>' +
+			'<td width="16">' +
+				sLink +
+				'<img alt="" src="images/Folder.gif" width="16" height="16" border="0"></a>' +
+			'</td><td nowrap colspan="2">&nbsp;' +
+				sLink +
+				folderName +
+				'</a>' +
+		'</td></tr>' ;
+}
+
+oListManager.GetFileRowHtml = function( fileName, fileUrl, fileSize )
+{
+	// Build the link to view the folder.
+	var sLink = '<a href="#" onclick="OpenFile(\'' + fileUrl.replace( /'/g, '\\\'') + '\');return false;">' ;
+
+	// Get the file icon.
+	var sIcon = oIcons.GetIcon( fileName ) ;
+
+	return '<tr>' +
+			'<td width="16">' +
+				sLink +
+				'<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' +
+			'</td><td>&nbsp;' +
+				sLink +
+				fileName +
+				'</a>' +
+			'</td><td align="right" nowrap>&nbsp;' +
+				fileSize +
+				' KB' +
+		'</td></tr>' ;
+}
+
+function OpenFolder( folderPath )
+{
+	// Load the resources list for this folder.
+	window.parent.frames['frmFolders'].LoadFolders( folderPath ) ;
+}
+
+function OpenFile( fileUrl )
+{
+	window.top.opener.SetUrl( fileUrl ) ;
+	window.top.close() ;
+	window.top.opener.focus() ;
+}
+
+function LoadResources( resourceType, folderPath )
+{
+	oListManager.Clear() ;
+	oConnector.ResourceType = resourceType ;
+	oConnector.CurrentFolder = folderPath ;
+	oConnector.SendCommand( 'GetFoldersAndFiles', null, GetFoldersAndFilesCallBack ) ;
+}
+
+function Refresh()
+{
+	LoadResources( oConnector.ResourceType, oConnector.CurrentFolder ) ;
+}
+
+function GetFoldersAndFilesCallBack( fckXml )
+{
+	if ( oConnector.CheckError( fckXml ) != 0 )
+		return ;
+
+	// Get the current folder path.
+	var oFolderNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ;
+	if ( oFolderNode == null )
+	{
+		alert( 'The server didn\'t reply with a proper XML file\r\nCheck your configuration.' ) ;
+		return ;
+	}
+	var sCurrentFolderPath	= oFolderNode.attributes.getNamedItem('path').value ;
+	var sCurrentFolderUrl	= oFolderNode.attributes.getNamedItem('url').value ;
+
+//	var dTimer = new Date() ;
+
+	var oHtml = new StringBuilder( '<table id="tableFiles" cellspacing="1" cellpadding="0" width="100%" border="0">' ) ;
+
+	// Add the Folders.
+	var oNodes ;
+	oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ;
+	for ( var i = 0 ; i < oNodes.length ; i++ )
+	{
+		var sFolderName = oNodes[i].attributes.getNamedItem('name').value ;
+		oHtml.Append( oListManager.GetFolderRowHtml( sFolderName, sCurrentFolderPath + sFolderName + "/" ) ) ;
+	}
+
+	// Add the Files.
+	oNodes = fckXml.SelectNodes( 'Connector/Files/File' ) ;
+	for ( var j = 0 ; j < oNodes.length ; j++ )
+	{
+		var oNode = oNodes[j] ;
+		var sFileName = oNode.attributes.getNamedItem('name').value ;
+		var sFileSize = oNode.attributes.getNamedItem('size').value ;
+
+		// Get the optional "url" attribute. If not available, build the url.
+		var oFileUrlAtt = oNodes[j].attributes.getNamedItem('url') ;
+		var sFileUrl = oFileUrlAtt != null ? oFileUrlAtt.value : sCurrentFolderUrl + sFileName ;
+
+		oHtml.Append( oListManager.GetFileRowHtml( sFileName, sFileUrl, sFileSize ) ) ;
+	}
+
+	oHtml.Append( '<\/table>' ) ;
+
+	document.body.innerHTML = oHtml.ToString() ;
+
+//	window.top.document.title = 'Finished processing in ' + ( ( ( new Date() ) - dTimer ) / 1000 ) + ' seconds' ;
+
+}
+
+window.onload = function()
+{
+	window.top.IsLoadedResourcesList = true ;
+}
+	</script>
+</head>
+<body class="FileArea" bottommargin="10" leftmargin="10" topmargin="10" rightmargin="10">
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/test.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/test.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/test.html	(revision 795)
@@ -0,0 +1,133 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Test page for the "File Uploaders".
+-->
+<html>
+	<head>
+		<title>FCKeditor - Uploaders Tests</title>
+		<script language="javascript">
+
+function SendFile()
+{
+	var sUploaderUrl = cmbUploaderUrl.value ;
+
+	if ( sUploaderUrl.length == 0 )
+		sUploaderUrl = txtCustomUrl.value ;
+
+	if ( sUploaderUrl.length == 0 )
+	{
+		alert( 'Please provide your custom URL or select a default one' ) ;
+		return ;
+	}
+
+	eURL.innerHTML = sUploaderUrl ;
+	txtUrl.value = '' ;
+
+	frmUpload.action = sUploaderUrl ;
+	frmUpload.submit() ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+	switch ( errorNumber )
+	{
+		case 0 :	// No errors
+			txtUrl.value = fileUrl ;
+			alert( 'File uploaded with no errors' ) ;
+			break ;
+		case 1 :	// Custom error
+			alert( customMsg ) ;
+			break ;
+		case 10 :	// Custom warning
+			txtUrl.value = fileUrl ;
+			alert( customMsg ) ;
+			break ;
+		case 201 :
+			txtUrl.value = fileUrl ;
+			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+			break ;
+		case 202 :
+			alert( 'Invalid file' ) ;
+			break ;
+		case 203 :
+			alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+			break ;
+		default :
+			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+			break ;
+	}
+}
+
+		</script>
+	</head>
+	<body>
+		<table cellSpacing="0" cellPadding="0" width="100%" border="0" height="100%">
+			<tr>
+				<td>
+					<table cellSpacing="0" cellPadding="0" width="100%" border="0">
+						<tr>
+							<td nowrap>
+								Select the "File Uploader" to use:<br>
+								<select id="cmbUploaderUrl">
+									<option selected value="asp/upload.asp">ASP</option>
+									<option value="aspx/upload.aspx">ASP.Net</option>
+									<option value="cfm/upload.cfm">ColdFusion</option>
+									<option value="lasso/upload.lasso">Lasso</option>
+									<option value="php/upload.php">PHP</option>
+									<option value="">(Custom)</option>
+								</select>
+							</td>
+							<td nowrap>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+							<td width="100%">
+								Custom Uploader URL:<BR>
+								<input id="txtCustomUrl" style="WIDTH: 100%; BACKGROUND-COLOR: #dcdcdc" disabled type="text">
+							</td>
+						</tr>
+					</table>
+					<br>
+					<table cellSpacing="0" cellPadding="0" width="100%" border="0">
+						<tr>
+							<td noWrap>
+								<form id="frmUpload" target="UploadWindow" enctype="multipart/form-data" action="" method="post">
+									Upload a new file:<br>
+									<input type="file" name="NewFile"><br>
+									<input type="button" value="Send it to the Server" onclick="SendFile();">
+								</form>
+							</td>
+							<td style="WIDTH: 16px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+							<td vAlign="top" width="100%">
+								Uploaded File URL:<br>
+								<INPUT id="txtUrl" style="WIDTH: 100%" readonly type="text">
+							</td>
+						</tr>
+					</table>
+					<br>
+					Post URL: <span id="eURL">&nbsp;</span>
+				</td>
+			</tr>
+			<tr>
+				<td height="100%">
+					<iframe name="UploadWindow" width="100%" height="100%" src="javascript:void(0)"></iframe>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/util.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/util.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/util.php	(revision 795)
@@ -0,0 +1,40 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the File Manager Connector for PHP.
+ */
+
+function RemoveExtension( $fileName )
+{
+	return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ;
+}
+
+function GetRootPath()
+{
+	$sRealPath = realpath( './' ) ;
+
+	$sSelfPath = $_SERVER['PHP_SELF'] ;
+	$sSelfPath = substr( $sSelfPath, 0, strrpos( $sSelfPath, '/' ) ) ;
+
+	return substr( $sRealPath, 0, strlen( $sRealPath ) - strlen( $sSelfPath ) ) ;
+}
+
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/upload.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/upload.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/upload.php	(revision 795)
@@ -0,0 +1,124 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the "File Uploader" for PHP.
+ */
+
+require('config.php') ;
+require('util.php') ;
+
+// This is the function that sends the results of the uploading process.
+function SendResults( $errorNumber, $fileUrl = '', $fileName = '', $customMsg = '' )
+{
+	echo '<script type="text/javascript">' ;
+	echo 'window.parent.OnUploadCompleted(' . $errorNumber . ',"' . str_replace( '"', '\\"', $fileUrl ) . '","' . str_replace( '"', '\\"', $fileName ) . '", "' . str_replace( '"', '\\"', $customMsg ) . '") ;' ;
+	echo '</script>' ;
+	exit ;
+}
+
+// Check if this uploader has been enabled.
+if ( !$Config['Enabled'] )
+	SendResults( '1', '', '', 'This file uploader is disabled. Please check the "editor/filemanager/upload/php/config.php" file' ) ;
+
+// Check if the file has been correctly uploaded.
+if ( !isset( $_FILES['NewFile'] ) || is_null( $_FILES['NewFile']['tmp_name'] ) || $_FILES['NewFile']['name'] == '' )
+	SendResults( '202' ) ;
+
+// Get the posted file.
+$oFile = $_FILES['NewFile'] ;
+
+// Get the uploaded file name extension.
+$sFileName = $oFile['name'] ;
+
+// Replace dots in the name with underscores (only one dot can be there... security issue).
+if ( $Config['ForceSingleExtension'] )
+	$sFileName = preg_replace( '/\\.(?![^.]*$)/', '_', $sFileName ) ;
+
+$sOriginalFileName = $sFileName ;
+
+// Get the extension.
+$sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
+$sExtension = strtolower( $sExtension ) ;
+
+// The the file type (from the QueryString, by default 'File').
+$sType = isset( $_GET['Type'] ) ? $_GET['Type'] : 'File' ;
+
+// Check if it is an allowed type.
+if ( !in_array( $sType, array('File','Image','Flash','Media') ) )
+    SendResults( 1, '', '', 'Invalid type specified' ) ;
+
+// Get the allowed and denied extensions arrays.
+$arAllowed	= $Config['AllowedExtensions'][$sType] ;
+$arDenied	= $Config['DeniedExtensions'][$sType] ;
+
+// Check if it is an allowed extension.
+if ( ( count($arAllowed) > 0 && !in_array( $sExtension, $arAllowed ) ) || ( count($arDenied) > 0 && in_array( $sExtension, $arDenied ) ) )
+	SendResults( '202' ) ;
+
+$sErrorNumber	= '0' ;
+$sFileUrl		= '' ;
+
+// Initializes the counter used to rename the file, if another one with the same name already exists.
+$iCounter = 0 ;
+
+// Get the target directory.
+if ( isset( $Config['UserFilesAbsolutePath'] ) && strlen( $Config['UserFilesAbsolutePath'] ) > 0 )
+	$sServerDir = $Config['UserFilesAbsolutePath'] ;
+else
+	$sServerDir = GetRootPath() . $Config["UserFilesPath"] ;
+
+if ( $Config['UseFileType'] )
+	$sServerDir .= $sType . '/' ;
+
+while ( true )
+{
+	// Compose the file path.
+	$sFilePath = $sServerDir . $sFileName ;
+
+	// If a file with that name already exists.
+	if ( is_file( $sFilePath ) )
+	{
+		$iCounter++ ;
+		$sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;
+		$sErrorNumber = '201' ;
+	}
+	else
+	{
+		move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
+
+		if ( is_file( $sFilePath ) )
+		{
+			$oldumask = umask(0) ;
+			chmod( $sFilePath, 0777 ) ;
+			umask( $oldumask ) ;
+		}
+
+		if ( $Config['UseFileType'] )
+			$sFileUrl = $Config["UserFilesPath"] . $sType . '/' . $sFileName ;
+		else
+			$sFileUrl = $Config["UserFilesPath"] . $sFileName ;
+
+		break ;
+	}
+}
+
+SendResults( $sErrorNumber, $sFileUrl, $sFileName ) ;
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/config.php
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/config.php	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/filemanager/upload/php/config.php	(revision 795)
@@ -0,0 +1,56 @@
+<?php
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Configuration file for the PHP File Uploader.
+ */
+
+global $Config ;
+
+// SECURITY: You must explicitelly enable this "uploader".
+$Config['Enabled'] = false ;
+
+// Set if the file type must be considere in the target path.
+// Ex: /userfiles/image/ or /userfiles/file/
+$Config['UseFileType'] = false ;
+
+// Path to uploaded files relative to the document root.
+$Config['UserFilesPath'] = '/userfiles/' ;
+
+// Fill the following value it you prefer to specify the absolute path for the
+// user files directory. Usefull if you are using a virtual directory, symbolic
+// link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
+// Attention: The above 'UserFilesPath' must point to the same directory.
+$Config['UserFilesAbsolutePath'] = '' ;
+
+// Due to security issues with Apache modules, it is reccomended to leave the
+// following setting enabled.
+$Config['ForceSingleExtension'] = true ;
+
+$Config['AllowedExtensions']['File']	= array() ;
+$Config['DeniedExtensions']['File']		= array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis') ;
+
+$Config['AllowedExtensions']['Image']	= array('jpg','gif','jpeg','png') ;
+$Config['DeniedExtensions']['Image']	= array() ;
+
+$Config['AllowedExtensions']['Flash']	= array('swf','fla') ;
+$Config['DeniedExtensions']['Flash']	= array() ;
+
+?>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/js/fckeditorcode_gecko.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/js/fckeditorcode_gecko.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/js/fckeditorcode_gecko.js	(revision 795)
@@ -0,0 +1,98 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * This file has been compressed for better performance. The original source
+ * can be found at "editor/_source".
+ */
+
+var FCK_STATUS_NOTLOADED=window.parent.FCK_STATUS_NOTLOADED=0;var FCK_STATUS_ACTIVE=window.parent.FCK_STATUS_ACTIVE=1;var FCK_STATUS_COMPLETE=window.parent.FCK_STATUS_COMPLETE=2;var FCK_TRISTATE_OFF=window.parent.FCK_TRISTATE_OFF=0;var FCK_TRISTATE_ON=window.parent.FCK_TRISTATE_ON=1;var FCK_TRISTATE_DISABLED=window.parent.FCK_TRISTATE_DISABLED=-1;var FCK_UNKNOWN=window.parent.FCK_UNKNOWN=-9;var FCK_TOOLBARITEM_ONLYICON=window.parent.FCK_TOOLBARITEM_ONLYICON=0;var FCK_TOOLBARITEM_ONLYTEXT=window.parent.FCK_TOOLBARITEM_ONLYTEXT=1;var FCK_TOOLBARITEM_ICONTEXT=window.parent.FCK_TOOLBARITEM_ICONTEXT=2;var FCK_EDITMODE_WYSIWYG=window.parent.FCK_EDITMODE_WYSIWYG=0;var FCK_EDITMODE_SOURCE=window.parent.FCK_EDITMODE_SOURCE=1;var FCK_IMAGES_PATH='images/';var FCK_SPACER_PATH='images/spacer.gif';var CTRL=1000;var SHIFT=2000;var ALT=4000;
+String.prototype.Contains=function(A){return (this.indexOf(A)>-1);};String.prototype.Equals=function(){var A=arguments;if (A.length==1&&A[0].pop) A=A[0];for (var i=0;i<A.length;i++){if (this==A[i]) return true;};return false;};String.prototype.IEquals=function(){var A=this.toUpperCase();var B=arguments;if (B.length==1&&B[0].pop) B=B[0];for (var i=0;i<B.length;i++){if (A==B[i].toUpperCase()) return true;};return false;};String.prototype.ReplaceAll=function(A,B){var C=this;for (var i=0;i<A.length;i++){C=C.replace(A[i],B[i]);};return C;};Array.prototype.AddItem=function(A){var i=this.length;this[i]=A;return i;};Array.prototype.IndexOf=function(A){for (var i=0;i<this.length;i++){if (this[i]==A) return i;};return-1;};String.prototype.StartsWith=function(A){return (this.substr(0,A.length)==A);};String.prototype.EndsWith=function(A,B){var C=this.length;var D=A.length;if (D>C) return false;if (B){var E=new RegExp(A+'$','i');return E.test(this);}else return (D==0||this.substr(C-D,D)==A);};String.prototype.Remove=function(A,B){var s='';if (A>0) s=this.substring(0,A);if (A+B<this.length) s+=this.substring(A+B,this.length);return s;};String.prototype.Trim=function(){return this.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,'');};String.prototype.LTrim=function(){return this.replace(/^[ \t\n\r]*/g,'');};String.prototype.RTrim=function(){return this.replace(/[ \t\n\r]*$/g,'');};String.prototype.ReplaceNewLineChars=function(A){return this.replace(/\n/g,A);}
+var s=navigator.userAgent.toLowerCase();var FCKBrowserInfo={IsIE:s.Contains('msie'),IsIE7:s.Contains('msie 7'),IsGecko:s.Contains('gecko/'),IsSafari:s.Contains('safari'),IsOpera:s.Contains('opera'),IsMac:s.Contains('macintosh')};(function(A){A.IsGeckoLike=(A.IsGecko||A.IsSafari||A.IsOpera);if (A.IsGecko){var B=s.match(/gecko\/(\d+)/)[1];A.IsGecko10=B<20051111;}else A.IsGecko10=false;})(FCKBrowserInfo);
+var FCKURLParams={};(function(){var A=document.location.search.substr(1).split('&');for (var i=0;i<A.length;i++){var B=A[i].split('=');var C=decodeURIComponent(B[0]);var D=decodeURIComponent(B[1]);FCKURLParams[C]=D;}})();
+var FCKEvents=function(A){this.Owner=A;this._RegisteredEvents={};};FCKEvents.prototype.AttachEvent=function(A,B){var C;if (!(C=this._RegisteredEvents[A])) this._RegisteredEvents[A]=[B];else C.push(B);};FCKEvents.prototype.FireEvent=function(A,B){var C=true;var D=this._RegisteredEvents[A];if (D){for (var i=0;i<D.length;i++) C=(D[i](this.Owner,B)&&C);};return C;};
+var FCK={Name:FCKURLParams['InstanceName'],Status:0,EditMode:0,Toolbar:null,HasFocus:false,GetLinkedFieldValue:function(){return this.LinkedField.value;},GetParentForm:function(){return this.LinkedField.form;},StartupValue:'',IsDirty:function(){if (this.EditMode==1) return (this.StartupValue!=this.EditingArea.Textarea.value);else return (this.StartupValue!=this.EditorDocument.body.innerHTML);},ResetIsDirty:function(){if (this.EditMode==1) this.StartupValue=this.EditingArea.Textarea.value;else if (this.EditorDocument.body) this.StartupValue=this.EditorDocument.body.innerHTML;},StartEditor:function(){this.TempBaseTag=FCKConfig.BaseHref.length>0?'<base href="'+FCKConfig.BaseHref+'" _fcktemp="true"></base>':'';var A=FCK.KeystrokeHandler=new FCKKeystrokeHandler();A.OnKeystroke=_FCK_KeystrokeHandler_OnKeystroke;A.SetKeystrokes(FCKConfig.Keystrokes);if (FCKBrowserInfo.IsIE7){if ((CTRL+86/*V*/) in A.Keystrokes) A.SetKeystrokes([CTRL+86,true]);if ((SHIFT+45/*INS*/) in A.Keystrokes) A.SetKeystrokes([SHIFT+45,true]);};this.EditingArea=new FCKEditingArea(document.getElementById('xEditingArea'));this.EditingArea.FFSpellChecker=false;FCKListsLib.Setup();this.SetHTML(this.GetLinkedFieldValue(),true);},Focus:function(){FCK.EditingArea.Focus();},SetStatus:function(A){this.Status=A;if (A==1){FCKFocusManager.AddWindow(window,true);if (FCKBrowserInfo.IsIE) FCKFocusManager.AddWindow(window.frameElement,true);if (FCKConfig.StartupFocus) FCK.Focus();};this.Events.FireEvent('OnStatusChange',A);},FixBody:function(){var A=FCKConfig.EnterMode;if (A!='p'&&A!='div') return;var B=this.EditorDocument;if (!B) return;var C=B.body;if (!C) return;FCKDomTools.TrimNode(C);var D=C.firstChild;var E;while (D){var F=false;switch (D.nodeType){case 1:if (!FCKListsLib.BlockElements[D.nodeName.toLowerCase()]) F=true;break;case 3:if (E||D.nodeValue.Trim().length>0) F=true;};if (F){var G=D.parentNode;if (!E) E=G.insertBefore(B.createElement(A),D);E.appendChild(G.removeChild(D));D=E.nextSibling;}else{if (E){FCKDomTools.TrimNode(E);E=null;};D=D.nextSibling;}};if (E) FCKDomTools.TrimNode(E);},GetXHTML:function(A){if (FCK.EditMode==1) return FCK.EditingArea.Textarea.value;this.FixBody();var B;var C=FCK.EditorDocument;if (!C) return null;if (FCKConfig.FullPage){B=FCKXHtml.GetXHTML(C.getElementsByTagName('html')[0],true,A);if (FCK.DocTypeDeclaration&&FCK.DocTypeDeclaration.length>0) B=FCK.DocTypeDeclaration+'\n'+B;if (FCK.XmlDeclaration&&FCK.XmlDeclaration.length>0) B=FCK.XmlDeclaration+'\n'+B;}else{B=FCKXHtml.GetXHTML(C.body,false,A);if (FCKConfig.IgnoreEmptyParagraphValue&&FCKRegexLib.EmptyOutParagraph.test(B)) B='';};B=FCK.ProtectEventsRestore(B);if (FCKBrowserInfo.IsIE) B=B.replace(FCKRegexLib.ToReplace,'$1');return FCKConfig.ProtectedSource.Revert(B);},UpdateLinkedField:function(){FCK.LinkedField.value=FCK.GetXHTML(FCKConfig.FormatOutput);FCK.Events.FireEvent('OnAfterLinkedFieldUpdate');},RegisteredDoubleClickHandlers:{},OnDoubleClick:function(A){var B=FCK.RegisteredDoubleClickHandlers[A.tagName];if (B) B(A);},RegisterDoubleClickHandler:function(A,B){FCK.RegisteredDoubleClickHandlers[B.toUpperCase()]=A;},OnAfterSetHTML:function(){FCKDocumentProcessor.Process(FCK.EditorDocument);FCKUndo.SaveUndoStep();FCK.Events.FireEvent('OnSelectionChange');FCK.Events.FireEvent('OnAfterSetHTML');},ProtectUrls:function(A){A=A.replace(FCKRegexLib.ProtectUrlsA,'$& _fcksavedurl=$1');A=A.replace(FCKRegexLib.ProtectUrlsImg,'$& _fcksavedurl=$1');return A;},ProtectEvents:function(A){return A.replace(FCKRegexLib.TagsWithEvent,_FCK_ProtectEvents_ReplaceTags);},ProtectEventsRestore:function(A){return A.replace(FCKRegexLib.ProtectedEvents,_FCK_ProtectEvents_RestoreEvents);},ProtectTags:function(A){var B=FCKConfig.ProtectedTags;if (FCKBrowserInfo.IsIE) B+=B.length>0?'|ABBR':'ABBR';var C;if (B.length>0){C=new RegExp('<('+B+')(?!\w|:)','gi');A=A.replace(C,'<FCK:$1');C=new RegExp('<\/('+B+')>','gi');A=A.replace(C,'<\/FCK:$1>');};B='META';if (FCKBrowserInfo.IsIE) B+='|HR';C=new RegExp('<(('+B+')(?=\s|>)[\s\S]*?)/?>','gi');A=A.replace(C,'<FCK:$1 />');return A;},SetHTML:function(A,B){this.EditingArea.Mode=FCK.EditMode;if (FCK.EditMode==0){A=FCKConfig.ProtectedSource.Protect(A);A=A.replace(FCKRegexLib.InvalidSelfCloseTags,'$1></$2>');A=FCK.ProtectEvents(A);A=FCK.ProtectUrls(A);A=FCK.ProtectTags(A);if (FCKBrowserInfo.IsGecko){A=A.replace(FCKRegexLib.StrongOpener,'<b$1');A=A.replace(FCKRegexLib.StrongCloser,'<\/b>');A=A.replace(FCKRegexLib.EmOpener,'<i$1');A=A.replace(FCKRegexLib.EmCloser,'<\/i>');};this._ForceResetIsDirty=(B===true);var C='';if (FCKConfig.FullPage){if (!FCKRegexLib.HeadOpener.test(A)){if (!FCKRegexLib.HtmlOpener.test(A)) A='<html dir="'+FCKConfig.ContentLangDirection+'">'+A+'</html>';A=A.replace(FCKRegexLib.HtmlOpener,'$&<head></head>');};FCK.DocTypeDeclaration=A.match(FCKRegexLib.DocTypeTag);if (FCKBrowserInfo.IsIE) C=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) C='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';C+='<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';C=A.replace(FCKRegexLib.HeadCloser,C+'$&');if (FCK.TempBaseTag.length>0&&!FCKRegexLib.HasBaseTag.test(A)) C=C.replace(FCKRegexLib.HeadOpener,'$&'+FCK.TempBaseTag);}else{C=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"';if (FCKBrowserInfo.IsIE&&!FCKRegexLib.Html4DocType.test(FCKConfig.DocType)) C+=' style="overflow-y: scroll"';C+='><head><title></title>'+_FCK_GetEditorAreaStyleTags()+'<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';if (FCKBrowserInfo.IsIE) C+=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) C+='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';C+=FCK.TempBaseTag;var D='<body';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) D+=' id="'+FCKConfig.BodyId+'"';if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) D+=' class="'+FCKConfig.BodyClass+'"';C+='</head>'+D+'>';if (FCKBrowserInfo.IsGecko&&(A.length==0||FCKRegexLib.EmptyParagraph.test(A))) C+=GECKO_BOGUS;else C+=A;C+='</body></html>';};this.EditingArea.OnLoad=_FCK_EditingArea_OnLoad;this.EditingArea.Start(C);}else{FCK.EditorWindow=null;FCK.EditorDocument=null;this.EditingArea.OnLoad=null;this.EditingArea.Start(A);this.EditingArea.Textarea._FCKShowContextMenu=true;FCK.EnterKeyHandler=null;if (B) this.ResetIsDirty();FCK.KeystrokeHandler.AttachToElement(this.EditingArea.Textarea);this.EditingArea.Textarea.focus();FCK.Events.FireEvent('OnAfterSetHTML');};if (FCKBrowserInfo.IsGecko) window.onresize();},HasFocus:false,RedirectNamedCommands:{},ExecuteNamedCommand:function(A,B,C){FCKUndo.SaveUndoStep();if (!C&&FCK.RedirectNamedCommands[A]!=null) FCK.ExecuteRedirectedNamedCommand(A,B);else{FCK.Focus();FCK.EditorDocument.execCommand(A,false,B);FCK.Events.FireEvent('OnSelectionChange');};FCKUndo.SaveUndoStep();},GetNamedCommandState:function(A){try{if (!FCK.EditorDocument.queryCommandEnabled(A)) return -1;else return FCK.EditorDocument.queryCommandState(A)?1:0;}catch (e){return 0;}},GetNamedCommandValue:function(A){var B='';var C=FCK.GetNamedCommandState(A);if (C==-1) return null;try{B=this.EditorDocument.queryCommandValue(A);}catch(e) {};return B?B:'';},PasteFromWord:function(){FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.PasteFromWord,'dialog/fck_paste.html',400,330,'Word');},Preview:function(){var A=FCKConfig.ScreenWidth*0.8;var B=FCKConfig.ScreenHeight*0.7;var C=(FCKConfig.ScreenWidth-A)/2;var D=window.open('',null,'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width='+A+',height='+B+',left='+C);var E;if (FCKConfig.FullPage){if (FCK.TempBaseTag.length>0) E=FCK.TempBaseTag+FCK.GetXHTML();else E=FCK.GetXHTML();}else{E=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"><head>'+FCK.TempBaseTag+'<title>'+FCKLang.Preview+'</title>'+_FCK_GetEditorAreaStyleTags()+'</head><body>'+FCK.GetXHTML()+'</body></html>';};D.document.write(E);D.document.close();},SwitchEditMode:function(A){var B=(FCK.EditMode==0);var C=FCK.IsDirty();var D;if (B){if (!A&&FCKBrowserInfo.IsIE) FCKUndo.SaveUndoStep();D=FCK.GetXHTML(FCKConfig.FormatSource);if (D==null) return false;}else D=this.EditingArea.Textarea.value;FCK.EditMode=B?1:0;FCK.SetHTML(D,!C);FCK.Focus();FCKTools.RunFunction(FCK.ToolbarSet.RefreshModeState,FCK.ToolbarSet);return true;},CreateElement:function(A){var e=FCK.EditorDocument.createElement(A);return FCK.InsertElementAndGetIt(e);},InsertElementAndGetIt:function(e){e.setAttribute('FCKTempLabel','true');this.InsertElement(e);var A=FCK.EditorDocument.getElementsByTagName(e.tagName);for (var i=0;i<A.length;i++){if (A[i].getAttribute('FCKTempLabel')){A[i].removeAttribute('FCKTempLabel');return A[i];}};return null;}};FCK.Events=new FCKEvents(FCK);FCK.GetHTML=FCK.GetXHTML;function _FCK_ProtectEvents_ReplaceTags(A){return A.replace(FCKRegexLib.EventAttributes,_FCK_ProtectEvents_ReplaceEvents);};function _FCK_ProtectEvents_ReplaceEvents(A,B){return ' '+B+'_fckprotectedatt="'+A.ReplaceAll([/&/g,/'/g,/"/g,/=/g,/</g,/>/g,/\r/g,/\n/g],['&apos;','&#39;','&quot;','&#61;','&lt;','&gt;','&#10;','&#13;'])+'"';};function _FCK_ProtectEvents_RestoreEvents(A,B){return B.ReplaceAll([/&#39;/g,/&quot;/g,/&#61;/g,/&lt;/g,/&gt;/g,/&#10;/g,/&#13;/g,/&apos;/g],["'",'"','=','<','>','\r','\n','&']);};function _FCK_EditingArea_OnLoad(){FCK.EditorWindow=FCK.EditingArea.Window;FCK.EditorDocument=FCK.EditingArea.Document;FCK.InitializeBehaviors();if (!FCKConfig.DisableEnterKeyHandler) FCK.EnterKeyHandler=new FCKEnterKey(FCK.EditorWindow,FCKConfig.EnterMode,FCKConfig.ShiftEnterMode);FCK.KeystrokeHandler.AttachToElement(FCK.EditorDocument);if (FCK._ForceResetIsDirty) FCK.ResetIsDirty();if (FCKBrowserInfo.IsIE&&FCK.HasFocus) FCK.EditorDocument.body.setActive();FCK.OnAfterSetHTML();if (FCK.Status!=0) return;FCK.SetStatus(1);};function _FCK_GetEditorAreaStyleTags(){var A='';var B=FCKConfig.EditorAreaCSS;for (var i=0;i<B.length;i++) A+='<link href="'+B[i]+'" rel="stylesheet" type="text/css" />';return A;};function _FCK_KeystrokeHandler_OnKeystroke(A,B){if (FCK.Status!=2) return false;if (FCK.EditMode==0){if (B=='Paste') return!FCK.Events.FireEvent('OnPaste');}else{if (B.Equals('Paste','Undo','Redo','SelectAll')) return false;};var C=FCK.Commands.GetCommand(B);return (C.Execute.apply(C,FCKTools.ArgumentsToArray(arguments,2))!==false);};(function(){var A=window.parent.document;var B=A.getElementById(FCK.Name);var i=0;while (B||i==0){if (B&&B.tagName.toLowerCase().Equals('input','textarea')){FCK.LinkedField=B;break;};B=A.getElementsByName(FCK.Name)[i++];}})();var FCKTempBin={Elements:[],AddElement:function(A){var B=this.Elements.length;this.Elements[B]=A;return B;},RemoveElement:function(A){var e=this.Elements[A];this.Elements[A]=null;return e;},Reset:function(){var i=0;while (i<this.Elements.length) this.Elements[i++]==null;this.Elements.length=0;}};var FCKFocusManager=FCK.FocusManager={IsLocked:false,AddWindow:function(A,B){var C;if (FCKBrowserInfo.IsIE) C=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else C=A.document;FCKTools.AddEventListener(C,'blur',FCKFocusManager_Win_OnBlur);FCKTools.AddEventListener(C,'focus',B?FCKFocusManager_Win_OnFocus_Area:FCKFocusManager_Win_OnFocus);},RemoveWindow:function(A){if (FCKBrowserInfo.IsIE) oTarget=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else oTarget=A.document;FCKTools.RemoveEventListener(oTarget,'blur',FCKFocusManager_Win_OnBlur);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus_Area);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus);},Lock:function(){this.IsLocked=true;},Unlock:function(){if (this._HasPendingBlur) FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);this.IsLocked=false;},_ResetTimer:function(){this._HasPendingBlur=false;if (this._Timer){window.clearTimeout(this._Timer);delete this._Timer;}}};function FCKFocusManager_Win_OnBlur(){if (typeof(FCK)!='undefined'&&FCK.HasFocus){FCKFocusManager._ResetTimer();FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);}};function FCKFocusManager_FireOnBlur(){if (FCKFocusManager.IsLocked) FCKFocusManager._HasPendingBlur=true;else{FCK.HasFocus=false;FCK.Events.FireEvent("OnBlur");}};function FCKFocusManager_Win_OnFocus_Area(){FCK.Focus();FCKFocusManager_Win_OnFocus();};function FCKFocusManager_Win_OnFocus(){FCKFocusManager._ResetTimer();if (!FCK.HasFocus&&!FCKFocusManager.IsLocked){FCK.HasFocus=true;FCK.Events.FireEvent("OnFocus");}};
+FCK.Description="FCKeditor for Gecko Browsers";FCK.InitializeBehaviors=function(){if (FCKBrowserInfo.IsGecko) Window_OnResize();FCKFocusManager.AddWindow(this.EditorWindow);this.ExecOnSelectionChange=function(){FCK.Events.FireEvent("OnSelectionChange");};this.ExecOnSelectionChangeTimer=function(){if (FCK.LastOnChangeTimer) window.clearTimeout(FCK.LastOnChangeTimer);FCK.LastOnChangeTimer=window.setTimeout(FCK.ExecOnSelectionChange,100);};this.EditorDocument.addEventListener('mouseup',this.ExecOnSelectionChange,false);this.EditorDocument.addEventListener('keyup',this.ExecOnSelectionChangeTimer,false);this._DblClickListener=function(e){FCK.OnDoubleClick(e.target);e.stopPropagation();};this.EditorDocument.addEventListener('dblclick',this._DblClickListener,true);FCK.ContextMenu._InnerContextMenu.SetMouseClickWindow(FCK.EditorWindow);FCK.ContextMenu._InnerContextMenu.AttachToElement(FCK.EditorDocument);};FCK.MakeEditable=function(){this.EditingArea.MakeEditable();};function Document_OnContextMenu(e){if (!e.target._FCKShowContextMenu) e.preventDefault();};document.oncontextmenu=Document_OnContextMenu;FCK._BaseGetNamedCommandState=FCK.GetNamedCommandState;FCK.GetNamedCommandState=function(A){switch (A){case 'Unlink':return FCKSelection.HasAncestorNode('A')?0:-1;default:return FCK._BaseGetNamedCommandState(A);}};FCK.RedirectNamedCommands={Print:true,Paste:true,Cut:true,Copy:true};FCK.ExecuteRedirectedNamedCommand=function(A,B){switch (A){case 'Print':FCK.EditorWindow.print();break;case 'Paste':try			{ if (FCK.Paste()) FCK.ExecuteNamedCommand('Paste',null,true);}catch (e)	{ FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.Paste,'dialog/fck_paste.html',400,330,'Security');};break;case 'Cut':try			{ FCK.ExecuteNamedCommand('Cut',null,true);}catch (e)	{ alert(FCKLang.PasteErrorCut);};break;case 'Copy':try			{ FCK.ExecuteNamedCommand('Copy',null,true);}catch (e)	{ alert(FCKLang.PasteErrorCopy);};break;default:FCK.ExecuteNamedCommand(A,B);}};FCK.AttachToOnSelectionChange=function(A){this.Events.AttachEvent('OnSelectionChange',A);};FCK.Paste=function(){if (FCKConfig.ForcePasteAsPlainText){FCK.PasteAsPlainText();return false;};return true;};FCK.InsertHtml=function(A){A=FCKConfig.ProtectedSource.Protect(A);A=FCK.ProtectEvents(A);A=FCK.ProtectUrls(A);A=FCK.ProtectTags(A);A=A.replace(FCKRegexLib.StrongOpener,'<b$1');A=A.replace(FCKRegexLib.StrongCloser,'<\/b>');A=A.replace(FCKRegexLib.EmOpener,'<i$1');A=A.replace(FCKRegexLib.EmCloser,'<\/i>');var B=FCKSelection.Delete();var C=B.getRangeAt(0);var D=C.createContextualFragment(A);var E=D.lastChild;C.insertNode(D);FCKSelection.SelectNode(E);FCKSelection.Collapse(false);this.Focus();};FCK.InsertElement=function(A){var B=FCKSelection.Delete();var C=B.getRangeAt(0);C.insertNode(A);FCKSelection.SelectNode(A);FCKSelection.Collapse(false);this.Focus();};FCK.PasteAsPlainText=function(){FCKTools.RunFunction(FCKDialog.OpenDialog,FCKDialog,['FCKDialog_Paste',FCKLang.PasteAsText,'dialog/fck_paste.html',400,330,'PlainText']);};FCK.GetClipboardHTML=function(){return '';};FCK.CreateLink=function(A){FCK.ExecuteNamedCommand('Unlink');if (A.length>0){var B='javascript:void(0);/*'+(new Date().getTime())+'*/';FCK.ExecuteNamedCommand('CreateLink',B);var C=this.EditorDocument.evaluate("//a[@href='"+B+"']",this.EditorDocument.body,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if (C){C.href=A;return C;}};return null;};
+var FCKConfig=FCK.Config={};if (document.location.protocol=='file:'){FCKConfig.BasePath=decodeURIComponent(document.location.pathname.substr(1));FCKConfig.BasePath=FCKConfig.BasePath.replace(/\\/gi, '/');FCKConfig.BasePath='file://'+FCKConfig.BasePath.substring(0,FCKConfig.BasePath.lastIndexOf('/')+1);FCKConfig.FullBasePath=FCKConfig.BasePath;}else{FCKConfig.BasePath=document.location.pathname.substring(0,document.location.pathname.lastIndexOf('/')+1);FCKConfig.FullBasePath=document.location.protocol+'//'+document.location.host+FCKConfig.BasePath;};FCKConfig.EditorPath=FCKConfig.BasePath.replace(/editor\/$/,'');try{FCKConfig.ScreenWidth=screen.width;FCKConfig.ScreenHeight=screen.height;}catch (e){FCKConfig.ScreenWidth=800;FCKConfig.ScreenHeight=600;};FCKConfig.ProcessHiddenField=function(){this.PageConfig={};var A=window.parent.document.getElementById(FCK.Name+'___Config');if (!A) return;var B=A.value.split('&');for (var i=0;i<B.length;i++){if (B[i].length==0) continue;var C=B[i].split('=');var D=decodeURIComponent(C[0]);var E=decodeURIComponent(C[1]);if (D=='CustomConfigurationsPath') FCKConfig[D]=E;else if (E.toLowerCase()=="true") this.PageConfig[D]=true;else if (E.toLowerCase()=="false") this.PageConfig[D]=false;else if (E.length>0&&!isNaN(E)) this.PageConfig[D]=parseInt(E,10);else this.PageConfig[D]=E;}};function FCKConfig_LoadPageConfig(){var A=FCKConfig.PageConfig;for (var B in A) FCKConfig[B]=A[B];};function FCKConfig_PreProcess(){var A=FCKConfig;if (A.AllowQueryStringDebug){try{if ((/fckdebug=true/i).test(window.top.location.search)) A.Debug=true;}catch (e) {/*Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error).*/}};if (!A.PluginsPath.EndsWith('/')) A.PluginsPath+='/';if (typeof(A.EditorAreaCSS)=='string') A.EditorAreaCSS=[A.EditorAreaCSS];var B=A.ToolbarComboPreviewCSS;if (!B||B.length==0) A.ToolbarComboPreviewCSS=A.EditorAreaCSS;else if (typeof(B)=='string') A.ToolbarComboPreviewCSS=[B];};FCKConfig.ToolbarSets={};FCKConfig.Plugins={};FCKConfig.Plugins.Items=[];FCKConfig.Plugins.Add=function(A,B,C){FCKConfig.Plugins.Items.AddItem([A,B,C]);};FCKConfig.ProtectedSource={};FCKConfig.ProtectedSource.RegexEntries=[/<!--[\s\S]*?-->/g,/<script[\s\S]*?<\/script>/gi,/<noscript[\s\S]*?<\/noscript>/gi];FCKConfig.ProtectedSource.Add=function(A){this.RegexEntries.AddItem(A);};FCKConfig.ProtectedSource.Protect=function(A){function _Replace(protectedSource){var B=FCKTempBin.AddElement(protectedSource);return '<!--{PS..'+B+'}-->';};for (var i=0;i<this.RegexEntries.length;i++){A=A.replace(this.RegexEntries[i],_Replace);};return A;};FCKConfig.ProtectedSource.Revert=function(A,B){function _Replace(m,opener,index){var C=B?FCKTempBin.RemoveElement(index):FCKTempBin.Elements[index];return FCKConfig.ProtectedSource.Revert(C,B);};return A.replace(/(<|&lt;)!--\{PS..(\d+)\}--(>|&gt;)/g,_Replace);}
+var FCKDebug={};FCKDebug._GetWindow=function(){if (!this.DebugWindow||this.DebugWindow.closed) this.DebugWindow=window.open(FCKConfig.BasePath+'fckdebug.html','FCKeditorDebug','menubar=no,scrollbars=yes,resizable=yes,location=no,toolbar=no,width=600,height=500',true);return this.DebugWindow;};FCKDebug.Output=function(A,B,C){if (!FCKConfig.Debug) return;try{this._GetWindow().Output(A,B);}catch (e) {}};FCKDebug.OutputObject=function(A,B){if (!FCKConfig.Debug) return;try{this._GetWindow().OutputObject(A,B);}catch (e) {}}
+var FCKDomTools={MoveChildren:function(A,B){if (A==B) return;var C;while ((C=A.firstChild)) B.appendChild(A.removeChild(C));},TrimNode:function(A,B){this.LTrimNode(A);this.RTrimNode(A,B);},LTrimNode:function(A){var B;while ((B=A.firstChild)){if (B.nodeType==3){var C=B.nodeValue.LTrim();var D=B.nodeValue.length;if (C.length==0){A.removeChild(B);continue;}else if (C.length<D){B.splitText(D-C.length);A.removeChild(A.firstChild);}};break;}},RTrimNode:function(A,B){var C;while ((C=A.lastChild)){switch (C.nodeType){case 1:if (C.nodeName.toUpperCase()=='BR'&&(B||C.getAttribute('type',2)=='_moz')){A.removeChild(C);continue;};break;case 3:var D=C.nodeValue.RTrim();var E=C.nodeValue.length;if (D.length==0){C.parentNode.removeChild(C);continue;}else if (D.length<E){C.splitText(D.length);A.lastChild.parentNode.removeChild(A.lastChild);}};break;}},RemoveNode:function(A,B){if (B){var C;while ((C=A.firstChild)) A.parentNode.insertBefore(A.removeChild(C),A);};return A.parentNode.removeChild(A);},GetFirstChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.firstChild;while(C){if (C.nodeType==1&&C.tagName.Equals.apply(C.tagName,B)) return C;C=C.nextSibling;};return null;},GetLastChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.lastChild;while(C){if (C.nodeType==1&&(!B||C.tagName.Equals(B))) return C;C=C.previousSibling;};return null;},GetPreviousSourceElement:function(A,B,C,D){if (!A) return null;if (C&&A.nodeType==1&&A.nodeName.IEquals(C)) return null;if (A.previousSibling) A=A.previousSibling;else return this.GetPreviousSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.lastChild) A=A.lastChild;else return this.GetPreviousSourceElement(A,B,C,D);};return null;},GetNextSourceElement:function(A,B,C,D){if (!A) return null;if (A.nextSibling) A=A.nextSibling;else return this.GetNextSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.firstChild) A=A.firstChild;else return this.GetNextSourceElement(A,B,C,D);};return null;},InsertAfterNode:function(A,B){return A.parentNode.insertBefore(B,A.nextSibling);},GetParents:function(A){var B=[];while (A){B.splice(0,0,A);A=A.parentNode;};return B;},GetIndexOf:function(A){var B=A.parentNode?A.parentNode.firstChild:null;var C=-1;while (B){C++;if (B==A) return C;B=B.nextSibling;};return-1;}};
+var GECKO_BOGUS='<br type="_moz">';var FCKTools={};FCKTools.CreateBogusBR=function(A){var B=A.createElement('br');B.setAttribute('type','_moz');return B;};FCKTools.AppendStyleSheet=function(A,B){if (typeof(B)=='string') return this._AppendStyleSheet(A,B);else{var C=[];for (var i=0;i<B.length;i++) C.push(this._AppendStyleSheet(A,B[i]));return C;}};FCKTools.GetElementDocument=function (A){return A.ownerDocument||A.document;};FCKTools.GetElementWindow=function(A){return this.GetDocumentWindow(this.GetElementDocument(A));};FCKTools.GetDocumentWindow=function(A){if (FCKBrowserInfo.IsSafari&&!A.parentWindow) this.FixDocumentParentWindow(window.top);return A.parentWindow||A.defaultView;};FCKTools.FixDocumentParentWindow=function(A){A.document.parentWindow=A;for (var i=0;i<A.frames.length;i++) FCKTools.FixDocumentParentWindow(A.frames[i]);};FCKTools.HTMLEncode=function(A){if (!A) return '';A=A.replace(/&/g,'&amp;');A=A.replace(/</g,'&lt;');A=A.replace(/>/g,'&gt;');return A;};FCKTools.HTMLDecode=function(A){if (!A) return '';A=A.replace(/&gt;/g,'>');A=A.replace(/&lt;/g,'<');A=A.replace(/&amp;/g,'&');return A;};FCKTools.AddSelectOption=function(A,B,C){var D=FCKTools.GetElementDocument(A).createElement("OPTION");D.text=B;D.value=C;A.options.add(D);return D;};FCKTools.RunFunction=function(A,B,C,D){if (A) this.SetTimeout(A,0,B,C,D);};FCKTools.SetTimeout=function(A,B,C,D,E){return (E||window).setTimeout(function(){if (D) A.apply(C,[].concat(D));else A.apply(C);},B);};FCKTools.SetInterval=function(A,B,C,D,E){return (E||window).setInterval(function(){A.apply(C,D||[]);},B);};FCKTools.ConvertStyleSizeToHtml=function(A){return A.EndsWith('%')?A:parseInt(A,10);};FCKTools.ConvertHtmlSizeToStyle=function(A){return A.EndsWith('%')?A:(A+'px');};FCKTools.GetElementAscensor=function(A,B){var e=A;var C=","+B.toUpperCase()+",";while (e){if (C.indexOf(","+e.nodeName.toUpperCase()+",")!=-1) return e;e=e.parentNode;};return null;};FCKTools.CreateEventListener=function(A,B){var f=function(){var C=[];for (var i=0;i<arguments.length;i++) C.push(arguments[i]);A.apply(this,C.concat(B));};return f;};FCKTools.IsStrictMode=function(A){return ('CSS1Compat'==(A.compatMode||'CSS1Compat'));};FCKTools.ArgumentsToArray=function(A,B,C){B=B||0;C=C||A.length;var D=[];for (var i=B;i<B+C&&i<A.length;i++) D.push(A[i]);return D;};FCKTools.CloneObject=function(A){var B=function() {};B.prototype=A;return new B;};
+FCKTools.CancelEvent=function(e){if (e) e.preventDefault();};FCKTools.DisableSelection=function(A){if (FCKBrowserInfo.IsGecko) A.style.MozUserSelect='none';else A.style.userSelect='none';};FCKTools._AppendStyleSheet=function(A,B){var e=A.createElement('LINK');e.rel='stylesheet';e.type='text/css';e.href=B;A.getElementsByTagName("HEAD")[0].appendChild(e);return e;};FCKTools.ClearElementAttributes=function(A){for (var i=0;i<A.attributes.length;i++){A.removeAttribute(A.attributes[i].name,0);}};FCKTools.GetAllChildrenIds=function(A){var B=[];var C=function(parent){for (var i=0;i<parent.childNodes.length;i++){var D=parent.childNodes[i].id;if (D&&D.length>0) B[B.length]=D;C(parent.childNodes[i]);}};C(A);return B;};FCKTools.RemoveOuterTags=function(e){var A=e.ownerDocument.createDocumentFragment();for (var i=0;i<e.childNodes.length;i++) A.appendChild(e.childNodes[i].cloneNode(true));e.parentNode.replaceChild(A,e);};FCKTools.CreateXmlObject=function(A){switch (A){case 'XmlHttp':return new XMLHttpRequest();case 'DOMDocument':return document.implementation.createDocument('','',null);};return null;};FCKTools.GetScrollPosition=function(A){return { X:A.pageXOffset,Y:A.pageYOffset };};FCKTools.AddEventListener=function(A,B,C){A.addEventListener(B,C,false);};FCKTools.RemoveEventListener=function(A,B,C){A.removeEventListener(B,C,false);};FCKTools.AddEventListenerEx=function(A,B,C,D){A.addEventListener(B,function(e){C.apply(A,[e].concat(D||[]));},false);};FCKTools.GetViewPaneSize=function(A){return { Width:A.innerWidth,Height:A.innerHeight };};FCKTools.SaveStyles=function(A){var B={};if (A.className.length>0){B.Class=A.className;A.className='';};var C=A.getAttribute('style');if (C&&C.length>0){B.Inline=C;A.setAttribute('style','',0);};return B;};FCKTools.RestoreStyles=function(A,B){A.className=B.Class||'';if (B.Inline) A.setAttribute('style',B.Inline,0);else A.removeAttribute('style',0);};FCKTools.RegisterDollarFunction=function(A){A.$=function(id){return this.document.getElementById(id);};};FCKTools.AppendElement=function(A,B){return A.appendChild(A.ownerDocument.createElement(B));};FCKTools.GetElementPosition=function(A,B){var c={ X:0,Y:0 };var C=B||window;var D=FCKTools.GetElementWindow(A);while (A){var E=D.getComputedStyle(A,'').position;if (E&&E!='static'&&A.style.zIndex!=FCKConfig.FloatingPanelsZIndex) break;c.X+=A.offsetLeft-A.scrollLeft;c.Y+=A.offsetTop-A.scrollTop;if (A.offsetParent) A=A.offsetParent;else{if (D!=C){A=D.frameElement;if (A) D=FCKTools.GetElementWindow(A);}else{c.X+=A.scrollLeft;c.Y+=A.scrollTop;break;}}};return c;}
+var FCKeditorAPI;function InitializeAPI(){var A=window.parent;if (!(FCKeditorAPI=A.FCKeditorAPI)){var B='var FCKeditorAPI = {Version : "2.4.2",VersionBuild : "14978",__Instances : new Object(),GetInstance : function( name ){return this.__Instances[ name ];},_FormSubmit : function(){for ( var name in FCKeditorAPI.__Instances ){var oEditor = FCKeditorAPI.__Instances[ name ] ;if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )oEditor.UpdateLinkedField() ;}this._FCKOriginalSubmit() ;},_FunctionQueue	: {Functions : new Array(),IsRunning : false,Add : function( f ){this.Functions.push( f );if ( !this.IsRunning )this.StartNext();},StartNext : function(){var aQueue = this.Functions ;if ( aQueue.length > 0 ){this.IsRunning = true;aQueue[0].call();}else this.IsRunning = false;},Remove : function( f ){var aQueue = this.Functions;var i = 0, fFunc;while( (fFunc = aQueue[ i ]) ){if ( fFunc == f )aQueue.splice( i,1 );i++ ;}this.StartNext();}}}';if (A.execScript) A.execScript(B,'JavaScript');else{if (FCKBrowserInfo.IsGecko10){eval.call(A,B);}else if (FCKBrowserInfo.IsSafari){var C=A.document;var D=C.createElement('script');D.appendChild(C.createTextNode(B));C.documentElement.appendChild(D);}else A.eval(B);};FCKeditorAPI=A.FCKeditorAPI;};FCKeditorAPI.__Instances[FCK.Name]=FCK;};function _AttachFormSubmitToAPI(){var A=FCK.GetParentForm();if (A){FCKTools.AddEventListener(A,'submit',FCK.UpdateLinkedField);if (!A._FCKOriginalSubmit&&(typeof(A.submit)=='function'||(!A.submit.tagName&&!A.submit.length))){A._FCKOriginalSubmit=A.submit;A.submit=FCKeditorAPI._FormSubmit;}}};function FCKeditorAPI_Cleanup(){delete FCKeditorAPI.__Instances[FCK.Name];};FCKTools.AddEventListener(window,'unload',FCKeditorAPI_Cleanup);
+var FCKImagePreloader=function(){this._Images=[];};FCKImagePreloader.prototype={AddImages:function(A){if (typeof(A)=='string') A=A.split(';');this._Images=this._Images.concat(A);},Start:function(){var A=this._Images;this._PreloadCount=A.length;for (var i=0;i<A.length;i++){var B=document.createElement('img');B.onload=B.onerror=_FCKImagePreloader_OnImage;B._FCKImagePreloader=this;B.src=A[i];_FCKImagePreloader_ImageCache.push(B);}}};var _FCKImagePreloader_ImageCache=[];function _FCKImagePreloader_OnImage(){var A=this._FCKImagePreloader;if ((--A._PreloadCount)==0&&A.OnComplete) A.OnComplete();this._FCKImagePreloader=null;}
+var FCKRegexLib={AposEntity:/&apos;/gi,ObjectElements:/^(?:IMG|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|HR|OBJECT|A|UL|OL|LI)$/i,NamedCommands:/^(?:Cut|Copy|Paste|Print|SelectAll|RemoveFormat|Unlink|Undo|Redo|Bold|Italic|Underline|StrikeThrough|Subscript|Superscript|JustifyLeft|JustifyCenter|JustifyRight|JustifyFull|Outdent|Indent|InsertOrderedList|InsertUnorderedList|InsertHorizontalRule)$/i,BodyContents:/([\s\S]*\<body[^\>]*\>)([\s\S]*)(\<\/body\>[\s\S]*)/i,ToReplace:/___fcktoreplace:([\w]+)/ig,MetaHttpEquiv:/http-equiv\s*=\s*["']?([^"' ]+)/i,HasBaseTag:/<base /i,HtmlOpener:/<html\s?[^>]*>/i,HeadOpener:/<head\s?[^>]*>/i,HeadCloser:/<\/head\s*>/i,FCK_Class:/(\s*FCK__[A-Za-z]*\s*)/,ElementName:/(^[a-z_:][\w.\-:]*\w$)|(^[a-z_]$)/,ForceSimpleAmpersand:/___FCKAmp___/g,SpaceNoClose:/\/>/g,EmptyParagraph:/^<([^ >]+)[^>]*>\s*(<\/\1>)?$/,EmptyOutParagraph:/^<([^ >]+)[^>]*>(?:\s*|&nbsp;)(<\/\1>)?$/,TagBody:/></,StrongOpener:/<STRONG([ \>])/gi,StrongCloser:/<\/STRONG>/gi,EmOpener:/<EM([ \>])/gi,EmCloser:/<\/EM>/gi,GeckoEntitiesMarker:/#\?-\:/g,ProtectUrlsImg:/<img(?=\s).*?\ssrc=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi,ProtectUrlsA:/<a(?=\s).*?\shref=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi,Html4DocType:/HTML 4\.0 Transitional/i,DocTypeTag:/<!DOCTYPE[^>]*>/i,TagsWithEvent:/<[^\>]+ on\w+[\s\r\n]*=[\s\r\n]*?('|")[\s\S]+?\>/g,EventAttributes:/\s(on\w+)[\s\r\n]*=[\s\r\n]*?('|")([\s\S]*?)\2/g,ProtectedEvents:/\s\w+_fckprotectedatt="([^"]+)"/g,StyleProperties:/\S+\s*:/g,InvalidSelfCloseTags:/(<(?!base|meta|link|hr|br|param|img|area|input)([a-zA-Z0-9:]+)[^>]*)\/>/gi};
+var FCKListsLib={BlockElements:{ address:1,blockquote:1,center:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },NonEmptyBlockElements:{ p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,address:1,pre:1,ol:1,ul:1,li:1,td:1,th:1 },InlineChildReqElements:{ abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1 },EmptyElements:{ base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 },PathBlockElements:{ address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },PathBlockLimitElements:{ body:1,td:1,th:1,caption:1,form:1 },Setup:function(){if (FCKConfig.EnterMode=='div') this.PathBlockElements.div=1;else this.PathBlockLimitElements.div=1;}};
+var FCKLanguageManager=FCK.Language={AvailableLanguages:{af:'Afrikaans',ar:'Arabic',bg:'Bulgarian',bn:'Bengali/Bangla',bs:'Bosnian',ca:'Catalan',cs:'Czech',da:'Danish',de:'German',el:'Greek',en:'English','en-au':'English (Australia)','en-ca':'English (Canadian)','en-uk':'English (United Kingdom)',eo:'Esperanto',es:'Spanish',et:'Estonian',eu:'Basque',fa:'Persian',fi:'Finnish',fo:'Faroese',fr:'French',gl:'Galician',he:'Hebrew',hi:'Hindi',hr:'Croatian',hu:'Hungarian',it:'Italian',ja:'Japanese',km:'Khmer',ko:'Korean',lt:'Lithuanian',lv:'Latvian',mn:'Mongolian',ms:'Malay',nb:'Norwegian Bokmal',nl:'Dutch',no:'Norwegian',pl:'Polish',pt:'Portuguese (Portugal)','pt-br':'Portuguese (Brazil)',ro:'Romanian',ru:'Russian',sk:'Slovak',sl:'Slovenian',sr:'Serbian (Cyrillic)','sr-latn':'Serbian (Latin)',sv:'Swedish',th:'Thai',tr:'Turkish',uk:'Ukrainian',vi:'Vietnamese',zh:'Chinese Traditional','zh-cn':'Chinese Simplified'},GetActiveLanguage:function(){if (FCKConfig.AutoDetectLanguage){var A;if (navigator.userLanguage) A=navigator.userLanguage.toLowerCase();else if (navigator.language) A=navigator.language.toLowerCase();else{return FCKConfig.DefaultLanguage;};if (A.length>=5){A=A.substr(0,5);if (this.AvailableLanguages[A]) return A;};if (A.length>=2){A=A.substr(0,2);if (this.AvailableLanguages[A]) return A;}};return this.DefaultLanguage;},TranslateElements:function(A,B,C,D){var e=A.getElementsByTagName(B);var E,s;for (var i=0;i<e.length;i++){if ((E=e[i].getAttribute('fckLang'))){if ((s=FCKLang[E])){if (D) s=FCKTools.HTMLEncode(s);eval('e[i].'+C+' = s');}}}},TranslatePage:function(A){this.TranslateElements(A,'INPUT','value');this.TranslateElements(A,'SPAN','innerHTML');this.TranslateElements(A,'LABEL','innerHTML');this.TranslateElements(A,'OPTION','innerHTML',true);},Initialize:function(){if (this.AvailableLanguages[FCKConfig.DefaultLanguage]) this.DefaultLanguage=FCKConfig.DefaultLanguage;else this.DefaultLanguage='en';this.ActiveLanguage={};this.ActiveLanguage.Code=this.GetActiveLanguage();this.ActiveLanguage.Name=this.AvailableLanguages[this.ActiveLanguage.Code];}};
+var FCKXHtmlEntities={};FCKXHtmlEntities.Initialize=function(){if (FCKXHtmlEntities.Entities) return;var A='';var B,e;if (FCKConfig.ProcessHTMLEntities){FCKXHtmlEntities.Entities={' ':'nbsp','¡':'iexcl','¢':'cent','£':'pound','¤':'curren','¥':'yen','¦':'brvbar','§':'sect','¨':'uml','©':'copy','ª':'ordf','«':'laquo','¬':'not','­':'shy','®':'reg','¯':'macr','°':'deg','±':'plusmn','²':'sup2','³':'sup3','´':'acute','µ':'micro','¶':'para','·':'middot','¸':'cedil','¹':'sup1','º':'ordm','»':'raquo','¼':'frac14','½':'frac12','¾':'frac34','¿':'iquest','×':'times','÷':'divide','ƒ':'fnof','•':'bull','…':'hellip','′':'prime','″':'Prime','‾':'oline','⁄':'frasl','℘':'weierp','ℑ':'image','ℜ':'real','™':'trade','ℵ':'alefsym','←':'larr','↑':'uarr','→':'rarr','↓':'darr','↔':'harr','↵':'crarr','⇐':'lArr','⇑':'uArr','⇒':'rArr','⇓':'dArr','⇔':'hArr','∀':'forall','∂':'part','∃':'exist','∅':'empty','∇':'nabla','∈':'isin','∉':'notin','∋':'ni','∏':'prod','∑':'sum','−':'minus','∗':'lowast','√':'radic','∝':'prop','∞':'infin','∠':'ang','∧':'and','∨':'or','∩':'cap','∪':'cup','∫':'int','∴':'there4','∼':'sim','≅':'cong','≈':'asymp','≠':'ne','≡':'equiv','≤':'le','≥':'ge','⊂':'sub','⊃':'sup','⊄':'nsub','⊆':'sube','⊇':'supe','⊕':'oplus','⊗':'otimes','⊥':'perp','⋅':'sdot','◊':'loz','♠':'spades','♣':'clubs','♥':'hearts','♦':'diams','"':'quot','ˆ':'circ','˜':'tilde',' ':'ensp',' ':'emsp',' ':'thinsp','‌':'zwnj','‍':'zwj','‎':'lrm','‏':'rlm','–':'ndash','—':'mdash','‘':'lsquo','’':'rsquo','‚':'sbquo','“':'ldquo','”':'rdquo','„':'bdquo','†':'dagger','‡':'Dagger','‰':'permil','‹':'lsaquo','›':'rsaquo','€':'euro'};for (e in FCKXHtmlEntities.Entities) A+=e;if (FCKConfig.IncludeLatinEntities){B={'À':'Agrave','Á':'Aacute','Â':'Acirc','Ã':'Atilde','Ä':'Auml','Å':'Aring','Æ':'AElig','Ç':'Ccedil','È':'Egrave','É':'Eacute','Ê':'Ecirc','Ë':'Euml','Ì':'Igrave','Í':'Iacute','Î':'Icirc','Ï':'Iuml','Ð':'ETH','Ñ':'Ntilde','Ò':'Ograve','Ó':'Oacute','Ô':'Ocirc','Õ':'Otilde','Ö':'Ouml','Ø':'Oslash','Ù':'Ugrave','Ú':'Uacute','Û':'Ucirc','Ü':'Uuml','Ý':'Yacute','Þ':'THORN','ß':'szlig','à':'agrave','á':'aacute','â':'acirc','ã':'atilde','ä':'auml','å':'aring','æ':'aelig','ç':'ccedil','è':'egrave','é':'eacute','ê':'ecirc','ë':'euml','ì':'igrave','í':'iacute','î':'icirc','ï':'iuml','ð':'eth','ñ':'ntilde','ò':'ograve','ó':'oacute','ô':'ocirc','õ':'otilde','ö':'ouml','ø':'oslash','ù':'ugrave','ú':'uacute','û':'ucirc','ü':'uuml','ý':'yacute','þ':'thorn','ÿ':'yuml','Œ':'OElig','œ':'oelig','Š':'Scaron','š':'scaron','Ÿ':'Yuml'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;};if (FCKConfig.IncludeGreekEntities){B={'Α':'Alpha','Β':'Beta','Γ':'Gamma','Δ':'Delta','Ε':'Epsilon','Ζ':'Zeta','Η':'Eta','Θ':'Theta','Ι':'Iota','Κ':'Kappa','Λ':'Lambda','Μ':'Mu','Ν':'Nu','Ξ':'Xi','Ο':'Omicron','Π':'Pi','Ρ':'Rho','Σ':'Sigma','Τ':'Tau','Υ':'Upsilon','Φ':'Phi','Χ':'Chi','Ψ':'Psi','Ω':'Omega','α':'alpha','β':'beta','γ':'gamma','δ':'delta','ε':'epsilon','ζ':'zeta','η':'eta','θ':'theta','ι':'iota','κ':'kappa','λ':'lambda','μ':'mu','ν':'nu','ξ':'xi','ο':'omicron','π':'pi','ρ':'rho','ς':'sigmaf','σ':'sigma','τ':'tau','υ':'upsilon','φ':'phi','χ':'chi','ψ':'psi','ω':'omega'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;}}else{FCKXHtmlEntities.Entities={};A=' ';};var C='['+A+']';if (FCKConfig.ProcessNumericEntities) C='[^ -~]|'+C;var D=FCKConfig.AdditionalNumericEntities;if (D&&D.length>0) C+='|'+FCKConfig.AdditionalNumericEntities;FCKXHtmlEntities.EntitiesRegex=new RegExp(C,'g');}
+var FCKXHtml={};FCKXHtml.CurrentJobNum=0;FCKXHtml.GetXHTML=function(A,B,C){FCKXHtmlEntities.Initialize();this._NbspEntity=(FCKConfig.ProcessHTMLEntities?'nbsp':'#160');var D=FCK.IsDirty();this._CreateNode=FCKConfig.ForceStrongEm?FCKXHtml_CreateNode_StrongEm:FCKXHtml_CreateNode_Normal;FCKXHtml.SpecialBlocks=[];this.XML=FCKTools.CreateXmlObject('DOMDocument');this.MainNode=this.XML.appendChild(this.XML.createElement('xhtml'));FCKXHtml.CurrentJobNum++;if (B) this._AppendNode(this.MainNode,A);else this._AppendChildNodes(this.MainNode,A,false);var E=this._GetMainXmlString();this.XML=null;E=E.substr(7,E.length-15).Trim();if (FCKBrowserInfo.IsGecko) E=E.replace(/<br\/>$/,'');E=E.replace(FCKRegexLib.SpaceNoClose,' />');if (FCKConfig.ForceSimpleAmpersand) E=E.replace(FCKRegexLib.ForceSimpleAmpersand,'&');if (C) E=FCKCodeFormatter.Format(E);for (var i=0;i<FCKXHtml.SpecialBlocks.length;i++){var F=new RegExp('___FCKsi___'+i);E=E.replace(F,FCKXHtml.SpecialBlocks[i]);};E=E.replace(FCKRegexLib.GeckoEntitiesMarker,'&');if (!D) FCK.ResetIsDirty();return E;};FCKXHtml._AppendAttribute=function(A,B,C){try{if (C==undefined||C==null) C='';else if (C.replace){if (FCKConfig.ForceSimpleAmpersand) C=C.replace(/&/g,'___FCKAmp___');C=C.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity);};var D=this.XML.createAttribute(B);D.value=C;A.attributes.setNamedItem(D);}catch (e){}};FCKXHtml._AppendChildNodes=function(A,B,C){if (C) FCKDomTools.TrimNode(B,true);var D=0;var E=B.firstChild;while (E){if (this._AppendNode(A,E)) D++;E=E.nextSibling;};if (D==0){if (C&&FCKConfig.FillEmptyBlocks){this._AppendEntity(A,this._NbspEntity);return A;};var F=A.nodeName;if (FCKListsLib.InlineChildReqElements[F]) return null;if (!FCKListsLib.EmptyElements[F]) A.appendChild(this.XML.createTextNode(''));};return A;};FCKXHtml._AppendNode=function(A,B){if (!B) return false;switch (B.nodeType){case 1:if (B.getAttribute('_fckfakelement')) return FCKXHtml._AppendNode(A,FCK.GetRealElement(B));if (FCKBrowserInfo.IsGecko&&B.hasAttribute('_moz_editor_bogus_node')) return false;if (B.getAttribute('_fcktemp')) return false;var C=B.tagName.toLowerCase();if (FCKBrowserInfo.IsIE){if (B.scopeName&&B.scopeName!='HTML'&&B.scopeName!='FCK') C=B.scopeName.toLowerCase()+':'+C;}else{if (C.StartsWith('fck:')) C=C.Remove(0,4);};if (!FCKRegexLib.ElementName.test(C)) return false;if (C=='br'&&B.getAttribute('type',2)=='_moz') return false;if (B._fckxhtmljob&&B._fckxhtmljob==FCKXHtml.CurrentJobNum) return false;var D=this._CreateNode(C);FCKXHtml._AppendAttributes(A,B,D,C);B._fckxhtmljob=FCKXHtml.CurrentJobNum;var E=FCKXHtml.TagProcessors[C];if (E) D=E(D,B,A);else D=this._AppendChildNodes(D,B,Boolean(FCKListsLib.NonEmptyBlockElements[C]));if (!D) return false;A.appendChild(D);break;case 3:return this._AppendTextNode(A,B.nodeValue.ReplaceNewLineChars(' '));case 8:if (FCKBrowserInfo.IsIE&&!B.innerHTML) break;try { A.appendChild(this.XML.createComment(B.nodeValue));}catch (e) {/*Do nothing... probably this is a wrong format comment.*/};break;default:A.appendChild(this.XML.createComment("Element not supported - Type: "+B.nodeType+" Name: "+B.nodeName));break;};return true;};function FCKXHtml_CreateNode_StrongEm(A){switch (A){case 'b':A='strong';break;case 'i':A='em';break;};return this.XML.createElement(A);};function FCKXHtml_CreateNode_Normal(A){return this.XML.createElement(A);};FCKXHtml._AppendSpecialItem=function(A){return '___FCKsi___'+FCKXHtml.SpecialBlocks.AddItem(A);};FCKXHtml._AppendEntity=function(A,B){A.appendChild(this.XML.createTextNode('#?-:'+B+';'));};FCKXHtml._AppendTextNode=function(A,B){var C=B.length>0;if (C) A.appendChild(this.XML.createTextNode(B.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity)));return C;};function FCKXHtml_GetEntity(A){var B=FCKXHtmlEntities.Entities[A]||('#'+A.charCodeAt(0));return '#?-:'+B+';';};FCKXHtml._RemoveAttribute=function(A,B,C){var D=A.attributes.getNamedItem(C);if (D&&B.test(D.nodeValue)){var E=D.nodeValue.replace(B,'');if (E.length==0) A.attributes.removeNamedItem(C);else D.nodeValue=E;}};FCKXHtml.TagProcessors={img:function(A,B){if (!A.attributes.getNamedItem('alt')) FCKXHtml._AppendAttribute(A,'alt','');var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'src',C);return A;},a:function(A,B){if (B.innerHTML.Trim().length==0&&!B.name) return false;var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'href',C);if (FCKBrowserInfo.IsIE){FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);};A=FCKXHtml._AppendChildNodes(A,B,false);return A;},script:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/javascript');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.text)));return A;},style:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/css');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.innerHTML)));return A;},title:function(A,B){A.appendChild(FCKXHtml.XML.createTextNode(FCK.EditorDocument.title));return A;},table:function(A,B){if (FCKBrowserInfo.IsIE) FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');A=FCKXHtml._AppendChildNodes(A,B,false);return A;},ol:function(A,B,C){if (B.innerHTML.Trim().length==0) return false;var D=C.lastChild;if (D&&D.nodeType==3) D=D.previousSibling;if (D&&D.nodeName.toUpperCase()=='LI'){B._fckxhtmljob=null;FCKXHtml._AppendNode(D,B);return false;};A=FCKXHtml._AppendChildNodes(A,B);return A;},span:function(A,B){if (B.innerHTML.length==0) return false;A=FCKXHtml._AppendChildNodes(A,B,false);return A;},iframe:function(A,B){var C=B.innerHTML;if (FCKBrowserInfo.IsGecko) C=FCKTools.HTMLDecode(C);C=C.replace(/\s_fcksavedurl="[^"]*"/g,'');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(C)));return A;}};FCKXHtml.TagProcessors.ul=FCKXHtml.TagProcessors.ol;
+FCKXHtml._GetMainXmlString=function(){var A=new XMLSerializer();return A.serializeToString(this.MainNode);};FCKXHtml._AppendAttributes=function(A,B,C){var D=B.attributes;for (var n=0;n<D.length;n++){var E=D[n];if (E.specified){var F=E.nodeName.toLowerCase();var G;if (F.StartsWith('_fck')) continue;else if (F.indexOf('_moz')==0) continue;else if (F=='class') G=E.nodeValue;else if (E.nodeValue===true) G=F;else G=B.getAttribute(F,2);this._AppendAttribute(C,F,G);}}}
+var FCKCodeFormatter={};FCKCodeFormatter.Init=function(){var A=this.Regex={};A.BlocksOpener=/\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.BlocksCloser=/\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.NewLineTags=/\<(BR|HR)[^\>]*\>/gi;A.MainTags=/\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi;A.LineSplitter=/\s*\n+\s*/g;A.IncreaseIndent=/^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i;A.DecreaseIndent=/^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i;A.FormatIndentatorRemove=new RegExp('^'+FCKConfig.FormatIndentator);A.ProtectedTags=/(<PRE[^>]*>)([\s\S]*?)(<\/PRE>)/gi;};FCKCodeFormatter._ProtectData=function(A,B,C,D){return B+'___FCKpd___'+FCKCodeFormatter.ProtectedData.AddItem(C)+D;};FCKCodeFormatter.Format=function(A){if (!this.Regex) this.Init();FCKCodeFormatter.ProtectedData=[];var B=A.replace(this.Regex.ProtectedTags,FCKCodeFormatter._ProtectData);B=B.replace(this.Regex.BlocksOpener,'\n$&');B=B.replace(this.Regex.BlocksCloser,'$&\n');B=B.replace(this.Regex.NewLineTags,'$&\n');B=B.replace(this.Regex.MainTags,'\n$&\n');var C='';var D=B.split(this.Regex.LineSplitter);B='';for (var i=0;i<D.length;i++){var E=D[i];if (E.length==0) continue;if (this.Regex.DecreaseIndent.test(E)) C=C.replace(this.Regex.FormatIndentatorRemove,'');B+=C+E+'\n';if (this.Regex.IncreaseIndent.test(E)) C+=FCKConfig.FormatIndentator;};for (var j=0;j<FCKCodeFormatter.ProtectedData.length;j++){var F=new RegExp('___FCKpd___'+j);B=B.replace(F,FCKCodeFormatter.ProtectedData[j].replace(/\$/g,'$$$$'));};return B.Trim();}
+var FCKUndo={};FCKUndo.SaveUndoStep=function(){}
+var FCKEditingArea=function(A){this.TargetElement=A;this.Mode=0;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKEditingArea_Cleanup);};FCKEditingArea.prototype.Start=function(A,B){var C=this.TargetElement;var D=FCKTools.GetElementDocument(C);while(C.childNodes.length>0) C.removeChild(C.childNodes[0]);if (this.Mode==0){var E=this.IFrame=D.createElement('iframe');E.src='javascript:void(0)';E.frameBorder=0;E.width=E.height='100%';C.appendChild(E);if (FCKBrowserInfo.IsIE) A=A.replace(/(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi,'$1></base>');else if (!B){if (FCKBrowserInfo.IsGecko) A=A.replace(/(<body[^>]*>)\s*(<\/body>)/i,'$1'+GECKO_BOGUS+'$2');var F=A.match(FCKRegexLib.BodyContents);if (F){A=F[1]+'&nbsp;'+F[3];this._BodyHTML=F[2];}else this._BodyHTML=A;};this.Window=E.contentWindow;var G=this.Document=this.Window.document;G.open();G.write(A);G.close();if (FCKBrowserInfo.IsGecko10&&!B){this.Start(A,true);return;};this.Window._FCKEditingArea=this;if (FCKBrowserInfo.IsGecko10) this.Window.setTimeout(FCKEditingArea_CompleteStart,500);else FCKEditingArea_CompleteStart.call(this.Window);}else{var H=this.Textarea=D.createElement('textarea');H.className='SourceField';H.dir='ltr';H.style.width=H.style.height='100%';H.style.border='none';C.appendChild(H);H.value=A;FCKTools.RunFunction(this.OnLoad);}};function FCKEditingArea_CompleteStart(){if (!this.document.body){this.setTimeout(FCKEditingArea_CompleteStart,50);return;};var A=this._FCKEditingArea;A.MakeEditable();FCKTools.RunFunction(A.OnLoad);};FCKEditingArea.prototype.MakeEditable=function(){var A=this.Document;if (FCKBrowserInfo.IsIE){A.body.contentEditable=true;}else{try{A.body.spellcheck=(this.FFSpellChecker!==false);if (this._BodyHTML){A.body.innerHTML=this._BodyHTML;this._BodyHTML=null;};A.designMode='on';try{A.execCommand('styleWithCSS',false,FCKConfig.GeckoUseSPAN);}catch (e){A.execCommand('useCSS',false,!FCKConfig.GeckoUseSPAN);};A.execCommand('enableObjectResizing',false,!FCKConfig.DisableObjectResizing);A.execCommand('enableInlineTableEditing',false,!FCKConfig.DisableFFTableHandles);}catch (e) {}}};FCKEditingArea.prototype.Focus=function(){try{if (this.Mode==0){if (FCKBrowserInfo.IsIE&&this.Document.hasFocus()) return;if (FCKBrowserInfo.IsSafari) this.IFrame.focus();else{this.Window.focus();}}else{var A=FCKTools.GetElementDocument(this.Textarea);if ((!A.hasFocus||A.hasFocus())&&A.activeElement==this.Textarea) return;this.Textarea.focus();}}catch(e) {}};function FCKEditingArea_Cleanup(){this.TargetElement=null;this.IFrame=null;this.Document=null;this.Textarea=null;if (this.Window){this.Window._FCKEditingArea=null;this.Window=null;}};
+var FCKKeystrokeHandler=function(A){this.Keystrokes={};this.CancelCtrlDefaults=(A!==false);};FCKKeystrokeHandler.prototype.AttachToElement=function(A){FCKTools.AddEventListenerEx(A,'keydown',_FCKKeystrokeHandler_OnKeyDown,this);if (FCKBrowserInfo.IsGecko10||FCKBrowserInfo.IsOpera||(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsMac)) FCKTools.AddEventListenerEx(A,'keypress',_FCKKeystrokeHandler_OnKeyPress,this);};FCKKeystrokeHandler.prototype.SetKeystrokes=function(){for (var i=0;i<arguments.length;i++){var A=arguments[i];if (typeof(A[0])=='object') this.SetKeystrokes.apply(this,A);else{if (A.length==1) delete this.Keystrokes[A[0]];else this.Keystrokes[A[0]]=A[1]===true?true:A;}}};function _FCKKeystrokeHandler_OnKeyDown(A,B){var C=A.keyCode||A.which;var D=0;if (A.ctrlKey||A.metaKey) D+=CTRL;if (A.shiftKey) D+=SHIFT;if (A.altKey) D+=ALT;var E=C+D;var F=B._CancelIt=false;var G=B.Keystrokes[E];if (G){if (G===true||!(B.OnKeystroke&&B.OnKeystroke.apply(B,G))) return true;F=true;};if (F||(B.CancelCtrlDefaults&&D==CTRL&&(C<33||C>40))){B._CancelIt=true;if (A.preventDefault) return A.preventDefault();A.returnValue=false;A.cancelBubble=true;return false;};return true;};function _FCKKeystrokeHandler_OnKeyPress(A,B){if (B._CancelIt){if (A.preventDefault) return A.preventDefault();return false;};return true;}
+var FCKListHandler={OutdentListItem:function(A){var B=A.parentNode;if (B.tagName.toUpperCase().Equals('UL','OL')){var C=FCKTools.GetElementDocument(A);var D=new FCKDocumentFragment(C);var E=D.RootNode;var F=false;var G=FCKDomTools.GetFirstChild(A,['UL','OL']);if (G){F=true;var H;while ((H=G.firstChild)) E.appendChild(G.removeChild(H));FCKDomTools.RemoveNode(G);};var I;var J=false;while ((I=A.nextSibling)){if (!F&&I.nodeType==1&&I.nodeName.toUpperCase()=='LI') J=F=true;E.appendChild(I.parentNode.removeChild(I));if (!J&&I.nodeType==1&&I.nodeName.toUpperCase().Equals('UL','OL')) FCKDomTools.RemoveNode(I,true);};var K=B.parentNode.tagName.toUpperCase();var L=(K=='LI');if (L||K.Equals('UL','OL')){if (F){var G=B.cloneNode(false);D.AppendTo(G);A.appendChild(G);}else if (L) D.InsertAfterNode(B.parentNode);else D.InsertAfterNode(B);if (L) FCKDomTools.InsertAfterNode(B.parentNode,B.removeChild(A));else FCKDomTools.InsertAfterNode(B,B.removeChild(A));}else{if (F){var N=B.cloneNode(false);D.AppendTo(N);FCKDomTools.InsertAfterNode(B,N);};var O=C.createElement(FCKConfig.EnterMode=='p'?'p':'div');FCKDomTools.MoveChildren(B.removeChild(A),O);FCKDomTools.InsertAfterNode(B,O);if (FCKConfig.EnterMode=='br'){if (FCKBrowserInfo.IsGecko) O.parentNode.insertBefore(FCKTools.CreateBogusBR(C),O);else FCKDomTools.InsertAfterNode(O,FCKTools.CreateBogusBR(C));FCKDomTools.RemoveNode(O,true);}};if (this.CheckEmptyList(B)) FCKDomTools.RemoveNode(B,true);}},CheckEmptyList:function(A){return (FCKDomTools.GetFirstChild(A,'LI')==null);},CheckListHasContents:function(A){var B=A.firstChild;while (B){switch (B.nodeType){case 1:if (!B.nodeName.IEquals('UL','LI')) return true;break;case 3:if (B.nodeValue.Trim().length>0) return true;};B=B.nextSibling;};return false;}};
+var FCKElementPath=function(A){var B=null;var C=null;var D=[];var e=A;while (e){if (e.nodeType==1){if (!this.LastElement) this.LastElement=e;var E=e.nodeName.toLowerCase();if (!C){if (!B&&FCKListsLib.PathBlockElements[E]!=null) B=e;if (FCKListsLib.PathBlockLimitElements[E]!=null) C=e;};D.push(e);if (E=='body') break;};e=e.parentNode;};this.Block=B;this.BlockLimit=C;this.Elements=D;};
+var FCKDomRange=function(A){this.Window=A;};FCKDomRange.prototype={_UpdateElementInfo:function(){if (!this._Range) this.Release(true);else{var A=this._Range.startContainer;var B=this._Range.endContainer;var C=new FCKElementPath(A);this.StartContainer=C.LastElement;this.StartBlock=C.Block;this.StartBlockLimit=C.BlockLimit;if (A!=B) C=new FCKElementPath(B);this.EndContainer=C.LastElement;this.EndBlock=C.Block;this.EndBlockLimit=C.BlockLimit;}},CreateRange:function(){return new FCKW3CRange(this.Window.document);},DeleteContents:function(){if (this._Range){this._Range.deleteContents();this._UpdateElementInfo();}},ExtractContents:function(){if (this._Range){var A=this._Range.extractContents();this._UpdateElementInfo();return A;}},CheckIsCollapsed:function(){if (this._Range) return this._Range.collapsed;},Collapse:function(A){if (this._Range) this._Range.collapse(A);this._UpdateElementInfo();},Clone:function(){var A=FCKTools.CloneObject(this);if (this._Range) A._Range=this._Range.cloneRange();return A;},MoveToNodeContents:function(A){if (!this._Range) this._Range=this.CreateRange();this._Range.selectNodeContents(A);this._UpdateElementInfo();},MoveToElementStart:function(A){this.SetStart(A,1);this.SetEnd(A,1);},MoveToElementEditStart:function(A){var B;while ((B=A.firstChild)&&B.nodeType==1&&FCKListsLib.EmptyElements[B.nodeName.toLowerCase()]==null) A=B;this.MoveToElementStart(A);},InsertNode:function(A){if (this._Range) this._Range.insertNode(A);},CheckIsEmpty:function(A){if (this.CheckIsCollapsed()) return true;var B=this.Window.document.createElement('div');this._Range.cloneContents().AppendTo(B);FCKDomTools.TrimNode(B,A);return (B.innerHTML.length==0);},CheckStartOfBlock:function(){var A=this.Clone();A.Collapse(true);A.SetStart(A.StartBlock||A.StartBlockLimit,1);var B=A.CheckIsEmpty();A.Release();return B;},CheckEndOfBlock:function(A){var B=this.Clone();B.Collapse(false);B.SetEnd(B.EndBlock||B.EndBlockLimit,2);var C=B.CheckIsCollapsed();if (!C){var D=this.Window.document.createElement('div');B._Range.cloneContents().AppendTo(D);FCKDomTools.TrimNode(D,true);C=true;var E=D;while ((E=E.lastChild)){if (E.previousSibling||E.nodeType!=1||FCKListsLib.InlineChildReqElements[E.nodeName.toLowerCase()]==null){C=false;break;}}};B.Release();if (A) this.Select();return C;},CreateBookmark:function(){var A={StartId:'fck_dom_range_start_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000),EndId:'fck_dom_range_end_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000)};var B=this.Window.document;var C;var D;if (!this.CheckIsCollapsed()){C=B.createElement('span');C.id=A.EndId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(false);D.InsertNode(C);};C=B.createElement('span');C.id=A.StartId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(true);D.InsertNode(C);return A;},MoveToBookmark:function(A,B){var C=this.Window.document;var D=C.getElementById(A.StartId);var E=C.getElementById(A.EndId);this.SetStart(D,3);if (!B) FCKDomTools.RemoveNode(D);if (E){this.SetEnd(E,3);if (!B) FCKDomTools.RemoveNode(E);}else this.Collapse(true);},SetStart:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setStart(A,0);break;case 2:C.setStart(A,A.childNodes.length);break;case 3:C.setStartBefore(A);break;case 4:C.setStartAfter(A);};this._UpdateElementInfo();},SetEnd:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setEnd(A,0);break;case 2:C.setEnd(A,A.childNodes.length);break;case 3:C.setEndBefore(A);break;case 4:C.setEndAfter(A);};this._UpdateElementInfo();},Expand:function(A){var B,oSibling;switch (A){case 'block_contents':if (this.StartBlock) this.SetStart(this.StartBlock,1);else{B=this._Range.startContainer;if (B.nodeType==1){if (!(B=B.childNodes[this._Range.startOffset])) B=B.firstChild;};if (!B) return;while (true){oSibling=B.previousSibling;if (!oSibling){if (B.parentNode!=this.StartBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setStartBefore(B);};if (this.EndBlock) this.SetEnd(this.EndBlock,2);else{B=this._Range.endContainer;if (B.nodeType==1) B=B.childNodes[this._Range.endOffset]||B.lastChild;if (!B) return;while (true){oSibling=B.nextSibling;if (!oSibling){if (B.parentNode!=this.EndBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setEndAfter(B);};this._UpdateElementInfo();}},Release:function(A){if (!A) this.Window=null;this.StartContainer=null;this.StartBlock=null;this.StartBlockLimit=null;this.EndContainer=null;this.EndBlock=null;this.EndBlockLimit=null;this._Range=null;}};
+FCKDomRange.prototype.MoveToSelection=function(){this.Release(true);var A=this.Window.getSelection();if (A.rangeCount==1){this._Range=FCKW3CRange.CreateFromRange(this.Window.document,A.getRangeAt(0));this._UpdateElementInfo();}};FCKDomRange.prototype.Select=function(){var A=this._Range;if (A){var B=this.Window.document.createRange();B.setStart(A.startContainer,A.startOffset);try{B.setEnd(A.endContainer,A.endOffset);}catch (e){if (e.toString().Contains('NS_ERROR_ILLEGAL_VALUE')){A.collapse(true);B.setEnd(A.endContainer,A.endOffset);}else throw(e);};var C=this.Window.getSelection();C.removeAllRanges();C.addRange(B);}};
+var FCKDocumentFragment=function(A,B){this.RootNode=B||A.createDocumentFragment();};FCKDocumentFragment.prototype={AppendTo:function(A){A.appendChild(this.RootNode);},InsertAfterNode:function(A){FCKDomTools.InsertAfterNode(A,this.RootNode);}}
+var FCKW3CRange=function(A){this._Document=A;this.startContainer=null;this.startOffset=null;this.endContainer=null;this.endOffset=null;this.collapsed=true;};FCKW3CRange.CreateRange=function(A){return new FCKW3CRange(A);};FCKW3CRange.CreateFromRange=function(A,B){var C=FCKW3CRange.CreateRange(A);C.setStart(B.startContainer,B.startOffset);C.setEnd(B.endContainer,B.endOffset);return C;};FCKW3CRange.prototype={_UpdateCollapsed:function(){this.collapsed=(this.startContainer==this.endContainer&&this.startOffset==this.endOffset);},setStart:function(A,B){this.startContainer=A;this.startOffset=B;if (!this.endContainer){this.endContainer=A;this.endOffset=B;};this._UpdateCollapsed();},setEnd:function(A,B){this.endContainer=A;this.endOffset=B;if (!this.startContainer){this.startContainer=A;this.startOffset=B;};this._UpdateCollapsed();},setStartAfter:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setStartBefore:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A));},setEndAfter:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setEndBefore:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A));},collapse:function(A){if (A){this.endContainer=this.startContainer;this.endOffset=this.startOffset;}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset;};this.collapsed=true;},selectNodeContents:function(A){this.setStart(A,0);this.setEnd(A,A.nodeType==3?A.data.length:A.childNodes.length);},insertNode:function(A){var B=this.startContainer;var C=this.startOffset;if (B.nodeType==3){B.splitText(C);if (B==this.endContainer) this.setEnd(B.nextSibling,this.endOffset-this.startOffset);FCKDomTools.InsertAfterNode(B,A);return;}else{B.insertBefore(A,B.childNodes[C]||null);if (B==this.endContainer){this.endOffset++;this.collapsed=false;}}},deleteContents:function(){if (this.collapsed) return;this._ExecContentsAction(0);},extractContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(1,A);return A;},cloneContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(2,A);return A;},_ExecContentsAction:function(A,B){var C=this.startContainer;var D=this.endContainer;var E=this.startOffset;var F=this.endOffset;var G=false;var H=false;if (D.nodeType==3) D=D.splitText(F);else{if (D.childNodes.length>0){if (F>D.childNodes.length-1){D=FCKDomTools.InsertAfterNode(D.lastChild,this._Document.createTextNode(''));H=true;}else D=D.childNodes[F];}};if (C.nodeType==3){C.splitText(E);if (C==D) D=C.nextSibling;}else{if (C.childNodes.length>0&&E<=C.childNodes.length-1){if (E==0){C=C.insertBefore(this._Document.createTextNode(''),C.firstChild);G=true;}else C=C.childNodes[E].previousSibling;}};var I=FCKDomTools.GetParents(C);var J=FCKDomTools.GetParents(D);var i,topStart,topEnd;for (i=0;i<I.length;i++){topStart=I[i];topEnd=J[i];if (topStart!=topEnd) break;};var K,levelStartNode,levelClone,currentNode,currentSibling;if (B) K=B.RootNode;for (var j=i;j<I.length;j++){levelStartNode=I[j];if (K&&levelStartNode!=C) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==C));currentNode=levelStartNode.nextSibling;while(currentNode){if (currentNode==J[j]||currentNode==D) break;currentSibling=currentNode.nextSibling;if (A==2) K.appendChild(currentNode.cloneNode(true));else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.appendChild(currentNode);};currentNode=currentSibling;};if (K) K=levelClone;};if (B) K=B.RootNode;for (var k=i;k<J.length;k++){levelStartNode=J[k];if (A>0&&levelStartNode!=D) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==D));if (!I[k]||levelStartNode.parentNode!=I[k].parentNode){currentNode=levelStartNode.previousSibling;while(currentNode){if (currentNode==I[k]||currentNode==C) break;currentSibling=currentNode.previousSibling;if (A==2) K.insertBefore(currentNode.cloneNode(true),K.firstChild);else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.insertBefore(currentNode,K.firstChild);};currentNode=currentSibling;}};if (K) K=levelClone;};if (A==2){var L=this.startContainer;if (L.nodeType==3){L.data+=L.nextSibling.data;L.parentNode.removeChild(L.nextSibling);};var M=this.endContainer;if (M.nodeType==3&&M.nextSibling){M.data+=M.nextSibling.data;M.parentNode.removeChild(M.nextSibling);}}else{if (topStart&&topEnd&&(C.parentNode!=topStart.parentNode||D.parentNode!=topEnd.parentNode)) this.setStart(topEnd.parentNode,FCKDomTools.GetIndexOf(topEnd));this.collapse(true);};if(G) C.parentNode.removeChild(C);if(H&&D.parentNode) D.parentNode.removeChild(D);},cloneRange:function(){return FCKW3CRange.CreateFromRange(this._Document,this);},toString:function(){var A=this.cloneContents();var B=this._Document.createElement('div');A.AppendTo(B);return B.textContent||B.innerText;}};
+var FCKEnterKey=function(A,B,C){this.Window=A;this.EnterMode=B||'p';this.ShiftEnterMode=C||'br';var D=new FCKKeystrokeHandler(false);D._EnterKey=this;D.OnKeystroke=FCKEnterKey_OnKeystroke;D.SetKeystrokes([[13,'Enter'],[SHIFT+13,'ShiftEnter'],[8,'Backspace'],[46,'Delete']]);D.AttachToElement(A.document);};function FCKEnterKey_OnKeystroke(A,B){var C=this._EnterKey;try{switch (B){case 'Enter':return C.DoEnter();break;case 'ShiftEnter':return C.DoShiftEnter();break;case 'Backspace':return C.DoBackspace();break;case 'Delete':return C.DoDelete();}}catch (e){};return false;};FCKEnterKey.prototype.DoEnter=function(A,B){this._HasShift=(B===true);var C=A||this.EnterMode;if (C=='br') return this._ExecuteEnterBr();else return this._ExecuteEnterBlock(C);};FCKEnterKey.prototype.DoShiftEnter=function(){return this.DoEnter(this.ShiftEnterMode,true);};FCKEnterKey.prototype.DoBackspace=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (!B.CheckIsCollapsed()) return false;var C=B.StartBlock;var D=B.EndBlock;if (B.StartBlockLimit==B.EndBlockLimit&&C&&D){if (!B.CheckIsCollapsed()){var E=B.CheckEndOfBlock();B.DeleteContents();if (C!=D){B.SetStart(D,1);B.SetEnd(D,1);};B.Select();A=(C==D);};if (B.CheckStartOfBlock()){var F=B.StartBlock;var G=FCKDomTools.GetPreviousSourceElement(F,true,['BODY',B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,G,F);}else if (FCKBrowserInfo.IsGecko){B.Select();}};B.Release();return A;};FCKEnterKey.prototype._ExecuteBackspace=function(A,B,C){var D=false;if (!B&&C.nodeName.IEquals('LI')&&C.parentNode.parentNode.nodeName.IEquals('LI')){this._OutdentWithSelection(C,A);return true;};if (B&&B.nodeName.IEquals('LI')){var E=FCKDomTools.GetLastChild(B,['UL','OL']);while (E){B=FCKDomTools.GetLastChild(E,'LI');E=FCKDomTools.GetLastChild(B,['UL','OL']);}};if (B&&C){if (C.nodeName.IEquals('LI')&&!B.nodeName.IEquals('LI')){this._OutdentWithSelection(C,A);return true;};var F=C.parentNode;var G=B.nodeName.toLowerCase();if (FCKListsLib.EmptyElements[G]!=null||G=='table'){FCKDomTools.RemoveNode(B);D=true;}else{FCKDomTools.RemoveNode(C);while (F.innerHTML.Trim().length==0){var H=F.parentNode;H.removeChild(F);F=H;};FCKDomTools.TrimNode(C);FCKDomTools.TrimNode(B);A.SetStart(B,2);A.Collapse(true);var I=A.CreateBookmark();FCKDomTools.MoveChildren(C,B);A.MoveToBookmark(I);A.Select();D=true;}};return D;};FCKEnterKey.prototype.DoDelete=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.CheckIsCollapsed()&&B.CheckEndOfBlock(FCKBrowserInfo.IsGecko)){var C=B.StartBlock;var D=FCKDomTools.GetNextSourceElement(C,true,[B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,C,D);};B.Release();return A;};FCKEnterKey.prototype._ExecuteEnterBlock=function(A,B){var C=B||new FCKDomRange(this.Window);if (!B) C.MoveToSelection();if (C.StartBlockLimit==C.EndBlockLimit){if (!C.StartBlock) this._FixBlock(C,true,A);if (!C.EndBlock) this._FixBlock(C,false,A);var D=C.StartBlock;var E=C.EndBlock;if (!C.CheckIsEmpty()) C.DeleteContents();if (D==E){var F;var G=C.CheckStartOfBlock();var H=C.CheckEndOfBlock();if (G&&!H){F=D.cloneNode(false);if (FCKBrowserInfo.IsGeckoLike) F.innerHTML=GECKO_BOGUS;D.parentNode.insertBefore(F,D);if (FCKBrowserInfo.IsIE){C.MoveToNodeContents(F);C.Select();};C.MoveToElementEditStart(D);}else{if (H){var I=D.tagName.toUpperCase();if (G&&I=='LI'){this._OutdentWithSelection(D,C);C.Release();return true;}else{if ((/^H[1-6]$/).test(I)||this._HasShift) F=this.Window.document.createElement(A);else{F=D.cloneNode(false);this._RecreateEndingTree(D,F);};if (FCKBrowserInfo.IsGeckoLike){F.innerHTML=GECKO_BOGUS;if (G) D.innerHTML=GECKO_BOGUS;}}}else{C.SetEnd(D,2);var J=C.ExtractContents();F=D.cloneNode(false);FCKDomTools.TrimNode(J.RootNode);if (J.RootNode.firstChild.nodeType==1&&J.RootNode.firstChild.tagName.toUpperCase().Equals('UL','OL')) F.innerHTML=GECKO_BOGUS;J.AppendTo(F);if (FCKBrowserInfo.IsGecko){this._AppendBogusBr(D);this._AppendBogusBr(F);}};if (F){FCKDomTools.InsertAfterNode(D,F);C.MoveToElementEditStart(F);if (FCKBrowserInfo.IsGecko) F.scrollIntoView(false);}}}else{C.MoveToElementEditStart(E);};C.Select();};C.Release();return true;};FCKEnterKey.prototype._ExecuteEnterBr=function(A){var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.StartBlockLimit==B.EndBlockLimit){B.DeleteContents();B.MoveToSelection();var C=B.CheckStartOfBlock();var D=B.CheckEndOfBlock();var E=B.StartBlock?B.StartBlock.tagName.toUpperCase():'';var F=this._HasShift;if (!F&&E=='LI') return this._ExecuteEnterBlock(null,B);if (!F&&D&&(/^H[1-6]$/).test(E)){FCKDebug.Output('BR - Header');FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createElement('br'));if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createTextNode(''));B.SetStart(B.StartBlock.nextSibling,FCKBrowserInfo.IsIE?3:1);}else{FCKDebug.Output('BR - No Header');var G=this.Window.document.createElement('br');B.InsertNode(G);if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(G,this.Window.document.createTextNode(''));if (D&&FCKBrowserInfo.IsGecko) this._AppendBogusBr(G.parentNode);if (FCKBrowserInfo.IsIE) B.SetStart(G,4);else B.SetStart(G.nextSibling,1);};B.Collapse(true);B.Select();};B.Release();return true;};FCKEnterKey.prototype._FixBlock=function(A,B,C){var D=A.CreateBookmark();A.Collapse(B);A.Expand('block_contents');var E=this.Window.document.createElement(C);A.ExtractContents().AppendTo(E);FCKDomTools.TrimNode(E);A.InsertNode(E);A.MoveToBookmark(D);};FCKEnterKey.prototype._AppendBogusBr=function(A){var B=A.getElementsByTagName('br');if (B) B=B[B.legth-1];if (!B||B.getAttribute('type',2)!='_moz') A.appendChild(FCKTools.CreateBogusBR(this.Window.document));};FCKEnterKey.prototype._RecreateEndingTree=function(A,B){while ((A=A.lastChild)&&A.nodeType==1&&FCKListsLib.InlineChildReqElements[A.nodeName.toLowerCase()]!=null) B=B.insertBefore(A.cloneNode(false),B.firstChild);};FCKEnterKey.prototype._OutdentWithSelection=function(A,B){var C=B.CreateBookmark();FCKListHandler.OutdentListItem(A);B.MoveToBookmark(C);B.Select();}
+var FCKDocumentProcessor={};FCKDocumentProcessor._Items=[];FCKDocumentProcessor.AppendNew=function(){var A={};this._Items.AddItem(A);return A;};FCKDocumentProcessor.Process=function(A){var B,i=0;while((B=this._Items[i++])) B.ProcessDocument(A);};var FCKDocumentProcessor_CreateFakeImage=function(A,B){var C=FCK.EditorDocument.createElement('IMG');C.className=A;C.src=FCKConfig.FullBasePath+'images/spacer.gif';C.setAttribute('_fckfakelement','true',0);C.setAttribute('_fckrealelement',FCKTempBin.AddElement(B),0);return C;};if (FCKBrowserInfo.IsIE||FCKBrowserInfo.IsOpera){var FCKAnchorsProcessor=FCKDocumentProcessor.AppendNew();FCKAnchorsProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('A');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.name.length>0){if (C.innerHTML!=''){if (FCKBrowserInfo.IsIE) C.className+=' FCK__AnchorC';}else{var D=FCKDocumentProcessor_CreateFakeImage('FCK__Anchor',C.cloneNode(true));D.setAttribute('_fckanchor','true',0);C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}}}};var FCKPageBreaksProcessor=FCKDocumentProcessor.AppendNew();FCKPageBreaksProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('DIV');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.style.pageBreakAfter=='always'&&C.childNodes.length==1&&C.childNodes[0].style&&C.childNodes[0].style.display=='none'){var D=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',C.cloneNode(true));C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}};var FCKFlashProcessor=FCKDocumentProcessor.AppendNew();FCKFlashProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('EMBED');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){var D=C.attributes['type'];if ((C.src&&C.src.EndsWith('.swf',true))||(D&&D.nodeValue=='application/x-shockwave-flash')){var E=C.cloneNode(true);if (FCKBrowserInfo.IsIE){var F=['scale','play','loop','menu','wmode','quality'];for (var G=0;G<F.length;G++){var H=C.getAttribute(F[G]);if (H) E.setAttribute(F[G],H);};E.setAttribute('type',D.nodeValue);};var I=FCKDocumentProcessor_CreateFakeImage('FCK__Flash',E);I.setAttribute('_fckflash','true',0);FCKFlashProcessor.RefreshView(I,C);C.parentNode.insertBefore(I,C);C.parentNode.removeChild(C);}}};FCKFlashProcessor.RefreshView=function(A,B){if (B.width>0) A.style.width=FCKTools.ConvertHtmlSizeToStyle(B.width);if (B.height>0) A.style.height=FCKTools.ConvertHtmlSizeToStyle(B.height);};FCK.GetRealElement=function(A){var e=FCKTempBin.Elements[A.getAttribute('_fckrealelement')];if (A.getAttribute('_fckflash')){if (A.style.width.length>0) e.width=FCKTools.ConvertStyleSizeToHtml(A.style.width);if (A.style.height.length>0) e.height=FCKTools.ConvertStyleSizeToHtml(A.style.height);};return e;};if (FCKBrowserInfo.IsIE){FCKDocumentProcessor.AppendNew().ProcessDocument=function(A){var B=A.getElementsByTagName('HR');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){var D=A.createElement('hr');D.mergeAttributes(C,true);FCKDomTools.InsertAfterNode(C,D);C.parentNode.removeChild(C);}}};FCKDocumentProcessor.AppendNew().ProcessDocument=function(A){var B=A.getElementsByTagName('INPUT');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.type=='hidden'){var D=FCKDocumentProcessor_CreateFakeImage('FCK__InputHidden',C.cloneNode(true));D.setAttribute('_fckinputhidden','true',0);C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}}
+var FCKSelection=FCK.Selection={};
+FCKSelection.GetType=function(){this._Type='Text';var A;try { A=FCK.EditorWindow.getSelection();}catch (e) {};if (A&&A.rangeCount==1){var B=A.getRangeAt(0);if (B.startContainer==B.endContainer&&(B.endOffset-B.startOffset)==1&&B.startContainer.nodeType!=Node.TEXT_NODE) this._Type='Control';};return this._Type;};FCKSelection.GetSelectedElement=function(){if (this.GetType()=='Control'){var A=FCK.EditorWindow.getSelection();return A.anchorNode.childNodes[A.anchorOffset];};return null;};FCKSelection.GetParentElement=function(){if (this.GetType()=='Control') return FCKSelection.GetSelectedElement().parentNode;else{var A=FCK.EditorWindow.getSelection();if (A){var B=A.anchorNode;while (B&&B.nodeType!=1) B=B.parentNode;return B;}};return null;};FCKSelection.SelectNode=function(A){var B=FCK.EditorDocument.createRange();B.selectNode(A);var C=FCK.EditorWindow.getSelection();C.removeAllRanges();C.addRange(B);};FCKSelection.Collapse=function(A){var B=FCK.EditorWindow.getSelection();if (A==null||A===true) B.collapseToStart();else B.collapseToEnd();};FCKSelection.HasAncestorNode=function(A){var B=this.GetSelectedElement();if (!B&&FCK.EditorWindow){try		{ B=FCK.EditorWindow.getSelection().getRangeAt(0).startContainer;}catch(e){}};while (B){if (B.nodeType==1&&B.tagName==A) return true;B=B.parentNode;};return false;};FCKSelection.MoveToAncestorNode=function(A){var B;var C=this.GetSelectedElement();if (!C) C=FCK.EditorWindow.getSelection().getRangeAt(0).startContainer;while (C){if (C.nodeName==A) return C;C=C.parentNode;};return null;};FCKSelection.Delete=function(){var A=FCK.EditorWindow.getSelection();for (var i=0;i<A.rangeCount;i++){A.getRangeAt(i).deleteContents();};return A;};
+var FCKTableHandler={};FCKTableHandler.InsertRow=function(){var A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=A.cloneNode(true);A.parentNode.insertBefore(B,A);FCKTableHandler.ClearRow(A);};FCKTableHandler.DeleteRows=function(A){if (!A) A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');if (B.rows.length==1){FCKTableHandler.DeleteTable(B);return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteTable=function(A){if (!A){A=FCKSelection.GetSelectedElement();if (!A||A.tagName!='TABLE') A=FCKSelection.MoveToAncestorNode('TABLE');};if (!A) return;FCKSelection.SelectNode(A);FCKSelection.Collapse();A.parentNode.removeChild(A);};FCKTableHandler.InsertColumn=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex+1;for (var i=0;i<B.rows.length;i++){var D=B.rows[i];if (D.cells.length<C) continue;A=D.cells[C-1].cloneNode(false);if (FCKBrowserInfo.IsGecko) A.innerHTML=GECKO_BOGUS;var E=D.cells[C];if (E) D.insertBefore(A,E);else D.appendChild(A);}};FCKTableHandler.DeleteColumns=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex;for (var i=B.rows.length-1;i>=0;i--){var D=B.rows[i];if (C==0&&D.cells.length==1){FCKTableHandler.DeleteRows(D);continue;};if (D.cells[C]) D.removeChild(D.cells[C]);}};FCKTableHandler.InsertCell=function(A){var B=A?A:FCKSelection.MoveToAncestorNode('TD');if (!B) return null;var C=FCK.EditorDocument.createElement('TD');if (FCKBrowserInfo.IsGecko) C.innerHTML=GECKO_BOGUS;if (B.cellIndex==B.parentNode.cells.length-1){B.parentNode.appendChild(C);}else{B.parentNode.insertBefore(C,B.nextSibling);};return C;};FCKTableHandler.DeleteCell=function(A){if (A.parentNode.cells.length==1){FCKTableHandler.DeleteRows(FCKTools.GetElementAscensor(A,'TR'));return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteCells=function(){var A=FCKTableHandler.GetSelectedCells();for (var i=A.length-1;i>=0;i--){FCKTableHandler.DeleteCell(A[i]);}};FCKTableHandler.MergeCells=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length<2) return;if (A[0].parentNode!=A[A.length-1].parentNode) return;var B=isNaN(A[0].colSpan)?1:A[0].colSpan;var C='';var D=FCK.EditorDocument.createDocumentFragment();for (var i=A.length-1;i>=0;i--){var E=A[i];for (var c=E.childNodes.length-1;c>=0;c--){var F=E.removeChild(E.childNodes[c]);if ((F.hasAttribute&&F.hasAttribute('_moz_editor_bogus_node'))||(F.getAttribute&&F.getAttribute('type',2)=='_moz')) continue;D.insertBefore(F,D.firstChild);};if (i>0){B+=isNaN(E.colSpan)?1:E.colSpan;FCKTableHandler.DeleteCell(E);}};A[0].colSpan=B;if (FCKBrowserInfo.IsGecko&&D.childNodes.length==0) A[0].innerHTML=GECKO_BOGUS;else A[0].appendChild(D);};FCKTableHandler.SplitCell=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length!=1) return;var B=this._CreateTableMap(A[0].parentNode.parentNode);var C=FCKTableHandler._GetCellIndexSpan(B,A[0].parentNode.rowIndex,A[0]);var D=this._GetCollumnCells(B,C);for (var i=0;i<D.length;i++){if (D[i]==A[0]){var E=this.InsertCell(A[0]);if (!isNaN(A[0].rowSpan)&&A[0].rowSpan>1) E.rowSpan=A[0].rowSpan;}else{if (isNaN(D[i].colSpan)) D[i].colSpan=2;else D[i].colSpan+=1;}}};FCKTableHandler._GetCellIndexSpan=function(A,B,C){if (A.length<B+1) return null;var D=A[B];for (var c=0;c<D.length;c++){if (D[c]==C) return c;};return null;};FCKTableHandler._GetCollumnCells=function(A,B){var C=[];for (var r=0;r<A.length;r++){var D=A[r][B];if (D&&(C.length==0||C[C.length-1]!=D)) C[C.length]=D;};return C;};FCKTableHandler._CreateTableMap=function(A){var B=A.rows;var r=-1;var C=[];for (var i=0;i<B.length;i++){r++;if (!C[r]) C[r]=[];var c=-1;for (var j=0;j<B[i].cells.length;j++){var D=B[i].cells[j];c++;while (C[r][c]) c++;var E=isNaN(D.colSpan)?1:D.colSpan;var F=isNaN(D.rowSpan)?1:D.rowSpan;for (var G=0;G<F;G++){if (!C[r+G]) C[r+G]=[];for (var H=0;H<E;H++){C[r+G][c+H]=B[i].cells[j];}};c+=E-1;}};return C;};FCKTableHandler.ClearRow=function(A){var B=A.cells;for (var i=0;i<B.length;i++){if (FCKBrowserInfo.IsGecko) B[i].innerHTML=GECKO_BOGUS;else B[i].innerHTML='';}};
+FCKTableHandler.GetSelectedCells=function(){var A=[];var B=FCK.EditorWindow.getSelection();if (B.rangeCount==1&&B.anchorNode.nodeType==3){var C=FCKTools.GetElementAscensor(B.anchorNode,'TD,TH');if (C){A[0]=C;return A;}};for (var i=0;i<B.rangeCount;i++){var D=B.getRangeAt(i);var E;if (D.startContainer.tagName.Equals('TD','TH')) E=D.startContainer;else E=D.startContainer.childNodes[D.startOffset];if (E.tagName.Equals('TD','TH')) A[A.length]=E;};return A;};
+var FCKXml=function(){};FCKXml.prototype.LoadUrl=function(A){this.Error=false;var B=this;var C=FCKTools.CreateXmlObject('XmlHttp');C.open("GET",A,false);C.send(null);if (C.status==200||C.status==304) this.DOMDocument=C.responseXML;else if (C.status==0&&C.readyState==4) this.DOMDocument=C.responseXML;else this.DOMDocument=null;if (this.DOMDocument==null||this.DOMDocument.firstChild==null){this.Error=true;if (window.confirm('Error loading "'+A+'"\r\nDo you want to see more info?')) alert('URL requested: "'+A+'"\r\nServer response:\r\nStatus: '+C.status+'\r\nResponse text:\r\n'+C.responseText);}};FCKXml.prototype.SelectNodes=function(A,B){if (this.Error) return [];var C=[];var D=this.DOMDocument.evaluate(A,B?B:this.DOMDocument,this.DOMDocument.createNSResolver(this.DOMDocument.documentElement),XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);if (D){var E=D.iterateNext();while(E){C[C.length]=E;E=D.iterateNext();}};return C;};FCKXml.prototype.SelectSingleNode=function(A,B){if (this.Error) return null;var C=this.DOMDocument.evaluate(A,B?B:this.DOMDocument,this.DOMDocument.createNSResolver(this.DOMDocument.documentElement),9,null);if (C&&C.singleNodeValue) return C.singleNodeValue;else return null;}
+var FCKStyleDef=function(A,B){this.Name=A;this.Element=B.toUpperCase();this.IsObjectElement=FCKRegexLib.ObjectElements.test(this.Element);this.Attributes={};};FCKStyleDef.prototype.AddAttribute=function(A,B){this.Attributes[A]=B;};FCKStyleDef.prototype.GetOpenerTag=function(){var s='<'+this.Element;for (var a in this.Attributes) s+=' '+a+'="'+this.Attributes[a]+'"';return s+'>';};FCKStyleDef.prototype.GetCloserTag=function(){return '</'+this.Element+'>';};FCKStyleDef.prototype.RemoveFromSelection=function(){if (FCKSelection.GetType()=='Control') this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement());else this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetParentElement());}
+FCKStyleDef.prototype.ApplyToSelection=function(){if (FCKSelection.GetType()=='Text'&&!this.IsObjectElement){var A=FCK.ToolbarSet.CurrentInstance.EditorWindow.getSelection();var e=FCK.ToolbarSet.CurrentInstance.EditorDocument.createElement(this.Element);for (var i=0;i<A.rangeCount;i++){e.appendChild(A.getRangeAt(i).extractContents());};this._AddAttributes(e);this._RemoveDuplicates(e);var B=A.getRangeAt(0);B.insertNode(e);}else{var C=FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement();if (C.tagName==this.Element) this._AddAttributes(C);}};FCKStyleDef.prototype._AddAttributes=function(A){for (var a in this.Attributes){switch (a.toLowerCase()){case 'src':A.setAttribute('_fcksavedurl',this.Attributes[a],0);default:A.setAttribute(a,this.Attributes[a],0);}}};FCKStyleDef.prototype._RemoveDuplicates=function(A){for (var i=0;i<A.childNodes.length;i++){var B=A.childNodes[i];if (B.nodeType!=1) continue;this._RemoveDuplicates(B);if (this.IsEqual(B)) FCKTools.RemoveOuterTags(B);}};FCKStyleDef.prototype.IsEqual=function(e){if (e.tagName!=this.Element) return false;for (var a in this.Attributes){if (e.getAttribute(a)!=this.Attributes[a]) return false;};return true;};FCKStyleDef.prototype._RemoveMe=function(A){if (!A) return;var B=A.parentNode;if (A.nodeType==1&&this.IsEqual(A)){if (this.IsObjectElement){for (var a in this.Attributes) A.removeAttribute(a,0);return;}else FCKTools.RemoveOuterTags(A);};this._RemoveMe(B);}
+var FCKStylesLoader=function(){this.Styles={};this.StyleGroups={};this.Loaded=false;this.HasObjectElements=false;};FCKStylesLoader.prototype.Load=function(A){var B=new FCKXml();B.LoadUrl(A);var C=B.SelectNodes('Styles/Style');for (var i=0;i<C.length;i++){var D=C[i].attributes.getNamedItem('element').value.toUpperCase();var E=new FCKStyleDef(C[i].attributes.getNamedItem('name').value,D);if (E.IsObjectElement) this.HasObjectElements=true;var F=B.SelectNodes('Attribute',C[i]);for (var j=0;j<F.length;j++){var G=F[j].attributes.getNamedItem('name').value;var H=F[j].attributes.getNamedItem('value').value;if (G.toLowerCase()=='style'){var I=document.createElement('SPAN');I.style.cssText=H;H=I.style.cssText;};E.AddAttribute(G,H);};this.Styles[E.Name]=E;var J=this.StyleGroups[D];if (J==null){this.StyleGroups[D]=[];J=this.StyleGroups[D];};J[J.length]=E;};this.Loaded=true;}
+var FCKNamedCommand=function(A){this.Name=A;};FCKNamedCommand.prototype.Execute=function(){FCK.ExecuteNamedCommand(this.Name);};FCKNamedCommand.prototype.GetState=function(){return FCK.GetNamedCommandState(this.Name);};
+var FCKDialogCommand=function(A,B,C,D,E,F,G){this.Name=A;this.Title=B;this.Url=C;this.Width=D;this.Height=E;this.GetStateFunction=F;this.GetStateParam=G;this.Resizable=false;};FCKDialogCommand.prototype.Execute=function(){FCKDialog.OpenDialog('FCKDialog_'+this.Name,this.Title,this.Url,this.Width,this.Height,null,null,this.Resizable);};FCKDialogCommand.prototype.GetState=function(){if (this.GetStateFunction) return this.GetStateFunction(this.GetStateParam);else return 0;};var FCKUndefinedCommand=function(){this.Name='Undefined';};FCKUndefinedCommand.prototype.Execute=function(){alert(FCKLang.NotImplemented);};FCKUndefinedCommand.prototype.GetState=function(){return 0;};var FCKFontNameCommand=function(){this.Name='FontName';};FCKFontNameCommand.prototype.Execute=function(A){if (A==null||A==""){}else FCK.ExecuteNamedCommand('FontName',A);};FCKFontNameCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontName');};var FCKFontSizeCommand=function(){this.Name='FontSize';};FCKFontSizeCommand.prototype.Execute=function(A){if (typeof(A)=='string') A=parseInt(A,10);if (A==null||A==''){FCK.ExecuteNamedCommand('FontSize',3);}else FCK.ExecuteNamedCommand('FontSize',A);};FCKFontSizeCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontSize');};var FCKFormatBlockCommand=function(){this.Name='FormatBlock';};FCKFormatBlockCommand.prototype.Execute=function(A){if (A==null||A=='') FCK.ExecuteNamedCommand('FormatBlock','<P>');else if (A=='div'&&FCKBrowserInfo.IsGecko) FCK.ExecuteNamedCommand('FormatBlock','div');else FCK.ExecuteNamedCommand('FormatBlock','<'+A+'>');};FCKFormatBlockCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FormatBlock');};var FCKPreviewCommand=function(){this.Name='Preview';};FCKPreviewCommand.prototype.Execute=function(){FCK.Preview();};FCKPreviewCommand.prototype.GetState=function(){return 0;};var FCKSaveCommand=function(){this.Name='Save';};FCKSaveCommand.prototype.Execute=function(){var A=FCK.GetParentForm();if (typeof(A.onsubmit)=='function'){var B=A.onsubmit();if (B!=null&&B===false) return;};A.submit();};FCKSaveCommand.prototype.GetState=function(){return 0;};var FCKNewPageCommand=function(){this.Name='NewPage';};FCKNewPageCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();FCK.SetHTML('');FCKUndo.Typing=true;};FCKNewPageCommand.prototype.GetState=function(){return 0;};var FCKSourceCommand=function(){this.Name='Source';};FCKSourceCommand.prototype.Execute=function(){if (FCKConfig.SourcePopup){var A=FCKConfig.ScreenWidth*0.65;var B=FCKConfig.ScreenHeight*0.65;FCKDialog.OpenDialog('FCKDialog_Source',FCKLang.Source,'dialog/fck_source.html',A,B,null,null,true);}else FCK.SwitchEditMode();};FCKSourceCommand.prototype.GetState=function(){return (FCK.EditMode==0?0:1);};var FCKUndoCommand=function(){this.Name='Undo';};FCKUndoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Undo();else FCK.ExecuteNamedCommand('Undo');};FCKUndoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckUndoState()?0:-1);else return FCK.GetNamedCommandState('Undo');};var FCKRedoCommand=function(){this.Name='Redo';};FCKRedoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Redo();else FCK.ExecuteNamedCommand('Redo');};FCKRedoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckRedoState()?0:-1);else return FCK.GetNamedCommandState('Redo');};var FCKPageBreakCommand=function(){this.Name='PageBreak';};FCKPageBreakCommand.prototype.Execute=function(){var e=FCK.EditorDocument.createElement('DIV');e.style.pageBreakAfter='always';e.innerHTML='<span style="DISPLAY:none">&nbsp;</span>';var A=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',e);A=FCK.InsertElement(A);};FCKPageBreakCommand.prototype.GetState=function(){return 0;};var FCKUnlinkCommand=function(){this.Name='Unlink';};FCKUnlinkCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsGecko){var A=FCK.Selection.MoveToAncestorNode('A');if (A) FCK.Selection.SelectNode(A);};FCK.ExecuteNamedCommand(this.Name);if (FCKBrowserInfo.IsGecko) FCK.Selection.Collapse(true);};FCKUnlinkCommand.prototype.GetState=function(){var A=FCK.GetNamedCommandState(this.Name);if (A==0&&FCK.EditMode==0){var B=FCKSelection.MoveToAncestorNode('A');var C=(B&&B.name.length>0&&B.href.length==0);if (C) A=-1;};return A;};var FCKSelectAllCommand=function(){this.Name='SelectAll';};FCKSelectAllCommand.prototype.Execute=function(){if (FCK.EditMode==0){FCK.ExecuteNamedCommand('SelectAll');}else{var A=FCK.EditingArea.Textarea;if (FCKBrowserInfo.IsIE){A.createTextRange().execCommand('SelectAll');}else{A.selectionStart=0;A.selectionEnd=A.value.length;};A.focus();}};FCKSelectAllCommand.prototype.GetState=function(){return 0;};var FCKPasteCommand=function(){this.Name='Paste';};FCKPasteCommand.prototype={Execute:function(){if (FCKBrowserInfo.IsIE) FCK.Paste();else FCK.ExecuteNamedCommand('Paste');},GetState:function(){return FCK.GetNamedCommandState('Paste');}};
+var FCKSpellCheckCommand=function(){this.Name='SpellCheck';this.IsEnabled=(FCKConfig.SpellChecker=='SpellerPages');};FCKSpellCheckCommand.prototype.Execute=function(){FCKDialog.OpenDialog('FCKDialog_SpellCheck','Spell Check','dialog/fck_spellerpages.html',440,480);};FCKSpellCheckCommand.prototype.GetState=function(){return this.IsEnabled?0:-1;}
+var FCKTextColorCommand=function(A){this.Name=A=='ForeColor'?'TextColor':'BGColor';this.Type=A;var B;if (FCKBrowserInfo.IsIE) B=window;else if (FCK.ToolbarSet._IFrame) B=FCKTools.GetElementWindow(FCK.ToolbarSet._IFrame);else B=window.parent;this._Panel=new FCKPanel(B,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._Panel.MainNode.className='FCK_Panel';this._CreatePanelBody(this._Panel.Document,this._Panel.MainNode);FCKTools.DisableSelection(this._Panel.Document.body);};FCKTextColorCommand.prototype.Execute=function(A,B,C){FCK._ActiveColorPanelType=this.Type;this._Panel.Show(A,B,C);};FCKTextColorCommand.prototype.SetColor=function(A){if (FCK._ActiveColorPanelType=='ForeColor') FCK.ExecuteNamedCommand('ForeColor',A);else if (FCKBrowserInfo.IsGeckoLike){if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,false);FCK.ExecuteNamedCommand('hilitecolor',A);if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,true);}else FCK.ExecuteNamedCommand('BackColor',A);delete FCK._ActiveColorPanelType;};FCKTextColorCommand.prototype.GetState=function(){return 0;};function FCKTextColorCommand_OnMouseOver()	{ this.className='ColorSelected';};function FCKTextColorCommand_OnMouseOut()	{ this.className='ColorDeselected';};function FCKTextColorCommand_OnClick(){this.className='ColorDeselected';this.Command.SetColor('#'+this.Color);this.Command._Panel.Hide();};function FCKTextColorCommand_AutoOnClick(){this.className='ColorDeselected';this.Command.SetColor('');this.Command._Panel.Hide();};function FCKTextColorCommand_MoreOnClick(){this.className='ColorDeselected';this.Command._Panel.Hide();FCKDialog.OpenDialog('FCKDialog_Color',FCKLang.DlgColorTitle,'dialog/fck_colorselector.html',400,330,this.Command.SetColor);};FCKTextColorCommand.prototype._CreatePanelBody=function(A,B){function CreateSelectionDiv(){var C=A.createElement("DIV");C.className='ColorDeselected';C.onmouseover=FCKTextColorCommand_OnMouseOver;C.onmouseout=FCKTextColorCommand_OnMouseOut;return C;};var D=B.appendChild(A.createElement("TABLE"));D.className='ForceBaseFont';D.style.tableLayout='fixed';D.cellPadding=0;D.cellSpacing=0;D.border=0;D.width=150;var E=D.insertRow(-1).insertCell(-1);E.colSpan=8;var C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table cellspacing="0" cellpadding="0" width="100%" border="0">\n			<tr>\n				<td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\n				<td nowrap width="100%" align="center">'+FCKLang.ColorAutomatic+'</td>\n			</tr>\n		</table>';C.Command=this;C.onclick=FCKTextColorCommand_AutoOnClick;var G=FCKConfig.FontColors.toString().split(',');var H=0;while (H<G.length){var I=D.insertRow(-1);for (var i=0;i<8&&H<G.length;i++,H++){C=I.insertCell(-1).appendChild(CreateSelectionDiv());C.Color=G[H];C.innerHTML='<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #'+G[H]+'"></div></div>';C.Command=this;C.onclick=FCKTextColorCommand_OnClick;}};E=D.insertRow(-1).insertCell(-1);E.colSpan=8;C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">'+FCKLang.ColorMoreColors+'</td></tr></table>';C.Command=this;C.onclick=FCKTextColorCommand_MoreOnClick;}
+var FCKPastePlainTextCommand=function(){this.Name='PasteText';};FCKPastePlainTextCommand.prototype.Execute=function(){FCK.PasteAsPlainText();};FCKPastePlainTextCommand.prototype.GetState=function(){return FCK.GetNamedCommandState('Paste');};
+var FCKPasteWordCommand=function(){this.Name='PasteWord';};FCKPasteWordCommand.prototype.Execute=function(){FCK.PasteFromWord();};FCKPasteWordCommand.prototype.GetState=function(){if (FCKConfig.ForcePasteAsPlainText) return -1;else return FCK.GetNamedCommandState('Paste');};
+var FCKTableCommand=function(A){this.Name=A;};FCKTableCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();switch (this.Name){case 'TableInsertRow':FCKTableHandler.InsertRow();break;case 'TableDeleteRows':FCKTableHandler.DeleteRows();break;case 'TableInsertColumn':FCKTableHandler.InsertColumn();break;case 'TableDeleteColumns':FCKTableHandler.DeleteColumns();break;case 'TableInsertCell':FCKTableHandler.InsertCell();break;case 'TableDeleteCells':FCKTableHandler.DeleteCells();break;case 'TableMergeCells':FCKTableHandler.MergeCells();break;case 'TableSplitCell':FCKTableHandler.SplitCell();break;case 'TableDelete':FCKTableHandler.DeleteTable();break;default:alert(FCKLang.UnknownCommand.replace(/%1/g,this.Name));}};FCKTableCommand.prototype.GetState=function(){return 0;}
+var FCKStyleCommand=function(){this.Name='Style';this.StylesLoader=new FCKStylesLoader();this.StylesLoader.Load(FCKConfig.StylesXmlPath);this.Styles=this.StylesLoader.Styles;};FCKStyleCommand.prototype.Execute=function(A,B){FCKUndo.SaveUndoStep();if (B.Selected) B.Style.RemoveFromSelection();else B.Style.ApplyToSelection();FCKUndo.SaveUndoStep();FCK.Focus();FCK.Events.FireEvent("OnSelectionChange");};FCKStyleCommand.prototype.GetState=function(){if (!FCK.EditorDocument) return -1;var A=FCK.EditorDocument.selection;if (FCKSelection.GetType()=='Control'){var e=FCKSelection.GetSelectedElement();if (e) return this.StylesLoader.StyleGroups[e.tagName]?0:-1;};return 0;};FCKStyleCommand.prototype.GetActiveStyles=function(){var A=[];if (FCKSelection.GetType()=='Control') this._CheckStyle(FCKSelection.GetSelectedElement(),A,false);else this._CheckStyle(FCKSelection.GetParentElement(),A,true);return A;};FCKStyleCommand.prototype._CheckStyle=function(A,B,C){if (!A) return;if (A.nodeType==1){var D=this.StylesLoader.StyleGroups[A.tagName];if (D){for (var i=0;i<D.length;i++){if (D[i].IsEqual(A)) B[B.length]=D[i];}}};if (C) this._CheckStyle(A.parentNode,B,C);}
+var FCKFitWindow=function(){this.Name='FitWindow';};FCKFitWindow.prototype.Execute=function(){var A=window.frameElement;var B=A.style;var C=parent;var D=C.document.documentElement;var E=C.document.body;var F=E.style;var G;if (!this.IsMaximized){if(FCKBrowserInfo.IsIE) C.attachEvent('onresize',FCKFitWindow_Resize);else C.addEventListener('resize',FCKFitWindow_Resize,true);this._ScrollPos=FCKTools.GetScrollPosition(C);G=A;while((G=G.parentNode)){if (G.nodeType==1) G._fckSavedStyles=FCKTools.SaveStyles(G);};if (FCKBrowserInfo.IsIE){this.documentElementOverflow=D.style.overflow;D.style.overflow='hidden';F.overflow='hidden';}else{F.overflow='hidden';F.width='0px';F.height='0px';};this._EditorFrameStyles=FCKTools.SaveStyles(A);var H=FCKTools.GetViewPaneSize(C);B.position="absolute";B.zIndex=FCKConfig.FloatingPanelsZIndex-1;B.left="0px";B.top="0px";B.width=H.Width+"px";B.height=H.Height+"px";if (!FCKBrowserInfo.IsIE){B.borderRight=B.borderBottom="9999px solid white";B.backgroundColor="white";};C.scrollTo(0,0);this.IsMaximized=true;}else{if(FCKBrowserInfo.IsIE) C.detachEvent("onresize",FCKFitWindow_Resize);else C.removeEventListener("resize",FCKFitWindow_Resize,true);G=A;while((G=G.parentNode)){if (G._fckSavedStyles){FCKTools.RestoreStyles(G,G._fckSavedStyles);G._fckSavedStyles=null;}};if (FCKBrowserInfo.IsIE) D.style.overflow=this.documentElementOverflow;FCKTools.RestoreStyles(A,this._EditorFrameStyles);C.scrollTo(this._ScrollPos.X,this._ScrollPos.Y);this.IsMaximized=false;};FCKToolbarItems.GetItem('FitWindow').RefreshState();FCK.EditingArea.MakeEditable();FCK.Focus();};FCKFitWindow.prototype.GetState=function(){if (FCKConfig.ToolbarLocation!='In') return -1;else return (this.IsMaximized?1:0);};function FCKFitWindow_Resize(){var A=FCKTools.GetViewPaneSize(parent);var B=window.frameElement.style;B.width=A.Width+'px';B.height=A.Height+'px';};
+var FCKCommands=FCK.Commands={};FCKCommands.LoadedCommands={};FCKCommands.RegisterCommand=function(A,B){this.LoadedCommands[A]=B;};FCKCommands.GetCommand=function(A){var B=FCKCommands.LoadedCommands[A];if (B) return B;switch (A){case 'DocProps':B=new FCKDialogCommand('DocProps',FCKLang.DocProps,'dialog/fck_docprops.html',400,390,FCKCommands.GetFullPageState);break;case 'Templates':B=new FCKDialogCommand('Templates',FCKLang.DlgTemplatesTitle,'dialog/fck_template.html',380,450);break;case 'Link':B=new FCKDialogCommand('Link',FCKLang.DlgLnkWindowTitle,'dialog/fck_link.html',400,330);break;case 'Unlink':B=new FCKUnlinkCommand();break;case 'Anchor':B=new FCKDialogCommand('Anchor',FCKLang.DlgAnchorTitle,'dialog/fck_anchor.html',370,170);break;case 'BulletedList':B=new FCKDialogCommand('BulletedList',FCKLang.BulletedListProp,'dialog/fck_listprop.html?UL',370,170);break;case 'NumberedList':B=new FCKDialogCommand('NumberedList',FCKLang.NumberedListProp,'dialog/fck_listprop.html?OL',370,170);break;case 'About':B=new FCKDialogCommand('About',FCKLang.About,'dialog/fck_about.html',400,330);break;case 'Find':B=new FCKDialogCommand('Find',FCKLang.DlgFindTitle,'dialog/fck_find.html',340,170);break;case 'Replace':B=new FCKDialogCommand('Replace',FCKLang.DlgReplaceTitle,'dialog/fck_replace.html',340,200);break;case 'Image':B=new FCKDialogCommand('Image',FCKLang.DlgImgTitle,'dialog/fck_image.html',450,400);break;case 'Flash':B=new FCKDialogCommand('Flash',FCKLang.DlgFlashTitle,'dialog/fck_flash.html',450,400);break;case 'SpecialChar':B=new FCKDialogCommand('SpecialChar',FCKLang.DlgSpecialCharTitle,'dialog/fck_specialchar.html',400,320);break;case 'Smiley':B=new FCKDialogCommand('Smiley',FCKLang.DlgSmileyTitle,'dialog/fck_smiley.html',FCKConfig.SmileyWindowWidth,FCKConfig.SmileyWindowHeight);break;case 'Table':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html',450,250);break;case 'TableProp':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html?Parent',400,250);break;case 'TableCellProp':B=new FCKDialogCommand('TableCell',FCKLang.DlgCellTitle,'dialog/fck_tablecell.html',550,250);break;case 'Style':B=new FCKStyleCommand();break;case 'FontName':B=new FCKFontNameCommand();break;case 'FontSize':B=new FCKFontSizeCommand();break;case 'FontFormat':B=new FCKFormatBlockCommand();break;case 'Source':B=new FCKSourceCommand();break;case 'Preview':B=new FCKPreviewCommand();break;case 'Save':B=new FCKSaveCommand();break;case 'NewPage':B=new FCKNewPageCommand();break;case 'PageBreak':B=new FCKPageBreakCommand();break;case 'TextColor':B=new FCKTextColorCommand('ForeColor');break;case 'BGColor':B=new FCKTextColorCommand('BackColor');break;case 'Paste':B=new FCKPasteCommand();break;case 'PasteText':B=new FCKPastePlainTextCommand();break;case 'PasteWord':B=new FCKPasteWordCommand();break;case 'TableInsertRow':B=new FCKTableCommand('TableInsertRow');break;case 'TableDeleteRows':B=new FCKTableCommand('TableDeleteRows');break;case 'TableInsertColumn':B=new FCKTableCommand('TableInsertColumn');break;case 'TableDeleteColumns':B=new FCKTableCommand('TableDeleteColumns');break;case 'TableInsertCell':B=new FCKTableCommand('TableInsertCell');break;case 'TableDeleteCells':B=new FCKTableCommand('TableDeleteCells');break;case 'TableMergeCells':B=new FCKTableCommand('TableMergeCells');break;case 'TableSplitCell':B=new FCKTableCommand('TableSplitCell');break;case 'TableDelete':B=new FCKTableCommand('TableDelete');break;case 'Form':B=new FCKDialogCommand('Form',FCKLang.Form,'dialog/fck_form.html',380,230);break;case 'Checkbox':B=new FCKDialogCommand('Checkbox',FCKLang.Checkbox,'dialog/fck_checkbox.html',380,230);break;case 'Radio':B=new FCKDialogCommand('Radio',FCKLang.RadioButton,'dialog/fck_radiobutton.html',380,230);break;case 'TextField':B=new FCKDialogCommand('TextField',FCKLang.TextField,'dialog/fck_textfield.html',380,230);break;case 'Textarea':B=new FCKDialogCommand('Textarea',FCKLang.Textarea,'dialog/fck_textarea.html',380,230);break;case 'HiddenField':B=new FCKDialogCommand('HiddenField',FCKLang.HiddenField,'dialog/fck_hiddenfield.html',380,230);break;case 'Button':B=new FCKDialogCommand('Button',FCKLang.Button,'dialog/fck_button.html',380,230);break;case 'Select':B=new FCKDialogCommand('Select',FCKLang.SelectionField,'dialog/fck_select.html',400,380);break;case 'ImageButton':B=new FCKDialogCommand('ImageButton',FCKLang.ImageButton,'dialog/fck_image.html?ImageButton',450,400);break;case 'SpellCheck':B=new FCKSpellCheckCommand();break;case 'FitWindow':B=new FCKFitWindow();break;case 'Undo':B=new FCKUndoCommand();break;case 'Redo':B=new FCKRedoCommand();break;case 'SelectAll':B=new FCKSelectAllCommand();break;case 'Undefined':B=new FCKUndefinedCommand();break;default:if (FCKRegexLib.NamedCommands.test(A)) B=new FCKNamedCommand(A);else{alert(FCKLang.UnknownCommand.replace(/%1/g,A));return null;}};FCKCommands.LoadedCommands[A]=B;return B;};FCKCommands.GetFullPageState=function(){return FCKConfig.FullPage?0:-1;};
+var FCKPanel=function(A){this.IsRTL=(FCKLang.Dir=='rtl');this.IsContextMenu=false;this._LockCounter=0;this._Window=A||window;var B;if (FCKBrowserInfo.IsIE){this._Popup=this._Window.createPopup();B=this.Document=this._Popup.document;FCK.IECleanup.AddItem(this,FCKPanel_Cleanup);}else{var C=this._IFrame=this._Window.document.createElement('iframe');C.src='javascript:void(0)';C.allowTransparency=true;C.frameBorder='0';C.scrolling='no';C.style.position='absolute';C.style.zIndex=FCKConfig.FloatingPanelsZIndex;C.width=C.height=0;if (this._Window==window.parent&&window.frameElement) window.frameElement.parentNode.insertBefore(C,window.frameElement);else this._Window.document.body.appendChild(C);var D=C.contentWindow;B=this.Document=D.document;B.open();B.write('<html><head></head><body style="margin:0px;padding:0px;"><\/body><\/html>');B.close();FCKTools.AddEventListenerEx(D,'focus',FCKPanel_Window_OnFocus,this);FCKTools.AddEventListenerEx(D,'blur',FCKPanel_Window_OnBlur,this);};B.dir=FCKLang.Dir;B.oncontextmenu=FCKTools.CancelEvent;this.MainNode=B.body.appendChild(B.createElement('DIV'));this.MainNode.style.cssFloat=this.IsRTL?'right':'left';};FCKPanel.prototype.AppendStyleSheet=function(A){FCKTools.AppendStyleSheet(this.Document,A);};FCKPanel.prototype.Preload=function(x,y,A){if (this._Popup) this._Popup.show(x,y,0,0,A);};FCKPanel.prototype.Show=function(x,y,A,B,C){var D;if (this._Popup){this._Popup.show(x,y,0,0,A);this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=(x*-1)+A.offsetWidth-D;};this._Popup.show(x,y,D,this.MainNode.offsetHeight,A);if (this.OnHide){if (this._Timer) CheckPopupOnHide.call(this,true);this._Timer=FCKTools.SetInterval(CheckPopupOnHide,100,this);}}else{if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Lock();if (this.ParentPanel) this.ParentPanel.Lock();this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (!B)	this._IFrame.width=1;if (!C)	this._IFrame.height=1;D=this.MainNode.offsetWidth;var E=FCKTools.GetElementPosition(A.nodeType==9?(FCKTools.IsStrictMode(A)?A.documentElement:A.body):A,this._Window);if (this.IsRTL&&!this.IsContextMenu) x=(x*-1);x+=E.X;y+=E.Y;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=x+A.offsetWidth-D;}else{var F=FCKTools.GetViewPaneSize(this._Window);var G=FCKTools.GetScrollPosition(this._Window);var H=F.Height+G.Y;var I=F.Width+G.X;if ((x+D)>I) x-=x+D-I;if ((y+this.MainNode.offsetHeight)>H) y-=y+this.MainNode.offsetHeight-H;};if (x<0) x=0;this._IFrame.style.left=x+'px';this._IFrame.style.top=y+'px';var J=D;var K=this.MainNode.offsetHeight;this._IFrame.width=J;this._IFrame.height=K;this._IFrame.contentWindow.focus();};this._IsOpened=true;FCKTools.RunFunction(this.OnShow,this);};FCKPanel.prototype.Hide=function(A){if (this._Popup) this._Popup.hide();else{if (!this._IsOpened) return;if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Unlock();this._IFrame.width=this._IFrame.height=0;this._IsOpened=false;if (this.ParentPanel) this.ParentPanel.Unlock();if (!A) FCKTools.RunFunction(this.OnHide,this);}};FCKPanel.prototype.CheckIsOpened=function(){if (this._Popup) return this._Popup.isOpen;else return this._IsOpened;};FCKPanel.prototype.CreateChildPanel=function(){var A=this._Popup?FCKTools.GetDocumentWindow(this.Document):this._Window;var B=new FCKPanel(A,true);B.ParentPanel=this;return B;};FCKPanel.prototype.Lock=function(){this._LockCounter++;};FCKPanel.prototype.Unlock=function(){if (--this._LockCounter==0&&!this.HasFocus) this.Hide();};function FCKPanel_Window_OnFocus(e,A){A.HasFocus=true;};function FCKPanel_Window_OnBlur(e,A){A.HasFocus=false;if (A._LockCounter==0) FCKTools.RunFunction(A.Hide,A);};function CheckPopupOnHide(A){if (A||!this._Popup.isOpen){window.clearInterval(this._Timer);this._Timer=null;FCKTools.RunFunction(this.OnHide,this);}};function FCKPanel_Cleanup(){this._Popup=null;this._Window=null;this.Document=null;this.MainNode=null;}
+var FCKIcon=function(A){var B=A?typeof(A):'undefined';switch (B){case 'number':this.Path=FCKConfig.SkinPath+'fck_strip.gif';this.Size=16;this.Position=A;break;case 'undefined':this.Path=FCK_SPACER_PATH;break;case 'string':this.Path=A;break;default:this.Path=A[0];this.Size=A[1];this.Position=A[2];}};FCKIcon.prototype.CreateIconElement=function(A){var B,eIconImage;if (this.Position){var C='-'+((this.Position-1)*this.Size)+'px';if (FCKBrowserInfo.IsIE){B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path;eIconImage.style.top=C;}else{B=A.createElement('IMG');B.src=FCK_SPACER_PATH;B.style.backgroundPosition='0px '+C;B.style.backgroundImage='url('+this.Path+')';}}else{B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path?this.Path:FCK_SPACER_PATH;};B.className='TB_Button_Image';return B;}
+var FCKToolbarButtonUI=function(A,B,C,D,E,F){this.Name=A;this.Label=B||A;this.Tooltip=C||this.Label;this.Style=E||0;this.State=F||0;this.Icon=new FCKIcon(D);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarButtonUI_Cleanup);};FCKToolbarButtonUI.prototype._CreatePaddingElement=function(A){var B=A.createElement('IMG');B.className='TB_Button_Padding';B.src=FCK_SPACER_PATH;return B;};FCKToolbarButtonUI.prototype.Create=function(A){var B=this.MainElement;if (B){FCKToolbarButtonUI_Cleanup.call(this);if (B.parentNode) B.parentNode.removeChild(B);B=this.MainElement=null;};var C=FCKTools.GetElementDocument(A);B=this.MainElement=C.createElement('DIV');B._FCKButton=this;B.title=this.Tooltip;if (FCKBrowserInfo.IsGecko) B.onmousedown=FCKTools.CancelEvent;this.ChangeState(this.State,true);if (this.Style==0&&!this.ShowArrow){B.appendChild(this.Icon.CreateIconElement(C));}else{var D=B.appendChild(C.createElement('TABLE'));D.cellPadding=0;D.cellSpacing=0;var E=D.insertRow(-1);var F=E.insertCell(-1);if (this.Style==0||this.Style==2) F.appendChild(this.Icon.CreateIconElement(C));else F.appendChild(this._CreatePaddingElement(C));if (this.Style==1||this.Style==2){F=E.insertCell(-1);F.className='TB_Button_Text';F.noWrap=true;F.appendChild(C.createTextNode(this.Label));};if (this.ShowArrow){if (this.Style!=0){E.insertCell(-1).appendChild(this._CreatePaddingElement(C));};F=E.insertCell(-1);var G=F.appendChild(C.createElement('IMG'));G.src=FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif';G.width=5;G.height=3;};F=E.insertCell(-1);F.appendChild(this._CreatePaddingElement(C));};A.appendChild(B);};FCKToolbarButtonUI.prototype.ChangeState=function(A,B){if (!B&&this.State==A) return;var e=this.MainElement;switch (parseInt(A,10)){case 0:e.className='TB_Button_Off';e.onmouseover=FCKToolbarButton_OnMouseOverOff;e.onmouseout=FCKToolbarButton_OnMouseOutOff;e.onclick=FCKToolbarButton_OnClick;break;case 1:e.className='TB_Button_On';e.onmouseover=FCKToolbarButton_OnMouseOverOn;e.onmouseout=FCKToolbarButton_OnMouseOutOn;e.onclick=FCKToolbarButton_OnClick;break;case -1:e.className='TB_Button_Disabled';e.onmouseover=null;e.onmouseout=null;e.onclick=null;break;};this.State=A;};function FCKToolbarButtonUI_Cleanup(){if (this.MainElement){this.MainElement._FCKButton=null;this.MainElement=null;}};function FCKToolbarButton_OnMouseOverOn(){this.className='TB_Button_On_Over';};function FCKToolbarButton_OnMouseOutOn(){this.className='TB_Button_On';};function FCKToolbarButton_OnMouseOverOff(){this.className='TB_Button_Off_Over';};function FCKToolbarButton_OnMouseOutOff(){this.className='TB_Button_Off';};function FCKToolbarButton_OnClick(e){if (this._FCKButton.OnClick) this._FCKButton.OnClick(this._FCKButton);};
+var FCKToolbarButton=function(A,B,C,D,E,F,G){this.CommandName=A;this.Label=B;this.Tooltip=C;this.Style=D;this.SourceView=E?true:false;this.ContextSensitive=F?true:false;if (G==null) this.IconPath=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(G)=='number') this.IconPath=[FCKConfig.SkinPath+'fck_strip.gif',16,G];};FCKToolbarButton.prototype.Create=function(A){this._UIButton=new FCKToolbarButtonUI(this.CommandName,this.Label,this.Tooltip,this.IconPath,this.Style);this._UIButton.OnClick=this.Click;this._UIButton._ToolbarButton=this;this._UIButton.Create(A);};FCKToolbarButton.prototype.RefreshState=function(){var A=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (A==this._UIButton.State) return;this._UIButton.ChangeState(A);};FCKToolbarButton.prototype.Click=function(){var A=this._ToolbarButton||this;FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(A.CommandName).Execute();};FCKToolbarButton.prototype.Enable=function(){this.RefreshState();};FCKToolbarButton.prototype.Disable=function(){this._UIButton.ChangeState(-1);}
+var FCKSpecialCombo=function(A,B,C,D,E){this.FieldWidth=B||100;this.PanelWidth=C||150;this.PanelMaxHeight=D||150;this.Label='&nbsp;';this.Caption=A;this.Tooltip=A;this.Style=2;this.Enabled=true;this.Items={};this._Panel=new FCKPanel(E||window,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._PanelBox=this._Panel.MainNode.appendChild(this._Panel.Document.createElement('DIV'));this._PanelBox.className='SC_Panel';this._PanelBox.style.width=this.PanelWidth+'px';this._PanelBox.innerHTML='<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>';this._ItemsHolderEl=this._PanelBox.getElementsByTagName('TD')[0];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKSpecialCombo_Cleanup);};function FCKSpecialCombo_ItemOnMouseOver(){this.className+=' SC_ItemOver';};function FCKSpecialCombo_ItemOnMouseOut(){this.className=this.originalClass;};function FCKSpecialCombo_ItemOnClick(){this.className=this.originalClass;this.FCKSpecialCombo._Panel.Hide();this.FCKSpecialCombo.SetLabel(this.FCKItemLabel);if (typeof(this.FCKSpecialCombo.OnSelect)=='function') this.FCKSpecialCombo.OnSelect(this.FCKItemID,this);};FCKSpecialCombo.prototype.AddItem=function(A,B,C,D){var E=this._ItemsHolderEl.appendChild(this._Panel.Document.createElement('DIV'));E.className=E.originalClass='SC_Item';E.innerHTML=B;E.FCKItemID=A;E.FCKItemLabel=C||A;E.FCKSpecialCombo=this;E.Selected=false;if (FCKBrowserInfo.IsIE) E.style.width='100%';if (D) E.style.backgroundColor=D;E.onmouseover=FCKSpecialCombo_ItemOnMouseOver;E.onmouseout=FCKSpecialCombo_ItemOnMouseOut;E.onclick=FCKSpecialCombo_ItemOnClick;this.Items[A.toString().toLowerCase()]=E;return E;};FCKSpecialCombo.prototype.SelectItem=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];if (B){B.className=B.originalClass='SC_ItemSelected';B.Selected=true;}};FCKSpecialCombo.prototype.SelectItemByLabel=function(A,B){for (var C in this.Items){var D=this.Items[C];if (D.FCKItemLabel==A){D.className=D.originalClass='SC_ItemSelected';D.Selected=true;if (B) this.SetLabel(A);}}};FCKSpecialCombo.prototype.DeselectAll=function(A){for (var i in this.Items){this.Items[i].className=this.Items[i].originalClass='SC_Item';this.Items[i].Selected=false;};if (A) this.SetLabel('');};FCKSpecialCombo.prototype.SetLabelById=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];this.SetLabel(B?B.FCKItemLabel:'');};FCKSpecialCombo.prototype.SetLabel=function(A){this.Label=A.length==0?'&nbsp;':A;if (this._LabelEl){this._LabelEl.innerHTML=this.Label;FCKTools.DisableSelection(this._LabelEl);}};FCKSpecialCombo.prototype.SetEnabled=function(A){this.Enabled=A;this._OuterTable.className=A?'':'SC_FieldDisabled';};FCKSpecialCombo.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var C=this._OuterTable=A.appendChild(B.createElement('TABLE'));C.cellPadding=0;C.cellSpacing=0;C.insertRow(-1);var D;var E;switch (this.Style){case 0:D='TB_ButtonType_Icon';E=false;break;case 1:D='TB_ButtonType_Text';E=false;break;case 2:E=true;break;};if (this.Caption&&this.Caption.length>0&&E){var F=C.rows[0].insertCell(-1);F.innerHTML=this.Caption;F.className='SC_FieldCaption';};var G=FCKTools.AppendElement(C.rows[0].insertCell(-1),'div');if (E){G.className='SC_Field';G.style.width=this.FieldWidth+'px';G.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label>&nbsp;</label></td><td class="SC_FieldButton">&nbsp;</td></tr></tbody></table>';this._LabelEl=G.getElementsByTagName('label')[0];this._LabelEl.innerHTML=this.Label;}else{G.className='TB_Button_Off';G.innerHTML='<table title="'+this.Tooltip+'" class="'+D+'" cellspacing="0" cellpadding="0" border="0"><tr><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_Text">'+this.Caption+'</td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_ButtonArrow"><img src="'+FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif" width="5" height="3"></td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td></tr></table>';};G.SpecialCombo=this;G.onmouseover=FCKSpecialCombo_OnMouseOver;G.onmouseout=FCKSpecialCombo_OnMouseOut;G.onclick=FCKSpecialCombo_OnClick;FCKTools.DisableSelection(this._Panel.Document.body);};function FCKSpecialCombo_Cleanup(){this._LabelEl=null;this._OuterTable=null;this._ItemsHolderEl=null;this._PanelBox=null;if (this.Items){for (var A in this.Items) this.Items[A]=null;}};function FCKSpecialCombo_OnMouseOver(){if (this.SpecialCombo.Enabled){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_On_Over';break;case 1:this.className='TB_Button_On_Over';break;case 2:this.className='SC_Field SC_FieldOver';break;}}};function FCKSpecialCombo_OnMouseOut(){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_Off';break;case 1:this.className='TB_Button_Off';break;case 2:this.className='SC_Field';break;}};function FCKSpecialCombo_OnClick(e){var A=this.SpecialCombo;if (A.Enabled){var B=A._Panel;var C=A._PanelBox;var D=A._ItemsHolderEl;var E=A.PanelMaxHeight;if (A.OnBeforeClick) A.OnBeforeClick(A);if (FCKBrowserInfo.IsIE) B.Preload(0,this.offsetHeight,this);if (D.offsetHeight>E) C.style.height=E+'px';else C.style.height='';B.Show(0,this.offsetHeight,this);}};
+var FCKToolbarSpecialCombo=function(){this.SourceView=false;this.ContextSensitive=true;this._LastValue=null;};function FCKToolbarSpecialCombo_OnSelect(A,B){FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Execute(A,B);};FCKToolbarSpecialCombo.prototype.Create=function(A){this._Combo=new FCKSpecialCombo(this.GetLabel(),this.FieldWidth,this.PanelWidth,this.PanelMaxHeight,FCKBrowserInfo.IsIE?window:FCKTools.GetElementWindow(A).parent);this._Combo.Tooltip=this.Tooltip;this._Combo.Style=this.Style;this.CreateItems(this._Combo);this._Combo.Create(A);this._Combo.CommandName=this.CommandName;this._Combo.OnSelect=FCKToolbarSpecialCombo_OnSelect;};function FCKToolbarSpecialCombo_RefreshActiveItems(A,B){A.DeselectAll();A.SelectItem(B);A.SetLabelById(B);};FCKToolbarSpecialCombo.prototype.RefreshState=function(){var A;var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (B!=-1){A=1;if (this.RefreshActiveItems) this.RefreshActiveItems(this._Combo,B);else{if (this._LastValue!=B){this._LastValue=B;FCKToolbarSpecialCombo_RefreshActiveItems(this._Combo,B);}}}else A=-1;if (A==this.State) return;if (A==-1){this._Combo.DeselectAll();this._Combo.SetLabel('');};this.State=A;this._Combo.SetEnabled(A!=-1);};FCKToolbarSpecialCombo.prototype.Enable=function(){this.RefreshState();};FCKToolbarSpecialCombo.prototype.Disable=function(){this.State=-1;this._Combo.DeselectAll();this._Combo.SetLabel('');this._Combo.SetEnabled(false);};
+var FCKToolbarFontsCombo=function(A,B){this.CommandName='FontName';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontsCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontsCombo.prototype.GetLabel=function(){return FCKLang.Font;};FCKToolbarFontsCombo.prototype.CreateItems=function(A){var B=FCKConfig.FontNames.split(';');for (var i=0;i<B.length;i++) this._Combo.AddItem(B[i],'<font face="'+B[i]+'" style="font-size: 12px">'+B[i]+'</font>');}
+var FCKToolbarFontSizeCombo=function(A,B){this.CommandName='FontSize';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontSizeCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontSizeCombo.prototype.GetLabel=function(){return FCKLang.FontSize;};FCKToolbarFontSizeCombo.prototype.CreateItems=function(A){A.FieldWidth=70;var B=FCKConfig.FontSizes.split(';');for (var i=0;i<B.length;i++){var C=B[i].split('/');this._Combo.AddItem(C[0],'<font size="'+C[0]+'">'+C[1]+'</font>',C[1]);}}
+var FCKToolbarFontFormatCombo=function(A,B){this.CommandName='FontFormat';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;this.NormalLabel='Normal';this.PanelWidth=190;};FCKToolbarFontFormatCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontFormatCombo.prototype.GetLabel=function(){return FCKLang.FontFormat;};FCKToolbarFontFormatCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;var C=FCKLang['FontFormats'].split(';');var D={p:C[0],pre:C[1],address:C[2],h1:C[3],h2:C[4],h3:C[5],h4:C[6],h5:C[7],h6:C[8],div:C[9]};var E=FCKConfig.FontFormats.split(';');for (var i=0;i<E.length;i++){var F=E[i];var G=D[F];if (F=='p') this.NormalLabel=G;this._Combo.AddItem(F,'<div class="BaseFont"><'+F+'>'+G+'</'+F+'></div>',G);}};if (FCKBrowserInfo.IsIE){FCKToolbarFontFormatCombo.prototype.RefreshActiveItems=function(A,B){if (B==this.NormalLabel){if (A.Label!='&nbsp;') A.DeselectAll(true);}else{if (this._LastValue==B) return;A.SelectItemByLabel(B,true);};this._LastValue=B;}}
+var FCKToolbarStyleCombo=function(A,B){this.CommandName='Style';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarStyleCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarStyleCombo.prototype.GetLabel=function(){return FCKLang.Style;};FCKToolbarStyleCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);B.body.className+=' ForceBaseFont';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;if (!(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsGecko10)) A.OnBeforeClick=this.RefreshVisibleItems;var C=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Styles;for (var s in C){var D=C[s];var E;if (D.IsObjectElement) E=A.AddItem(s,s);else E=A.AddItem(s,D.GetOpenerTag()+s+D.GetCloserTag());E.Style=D;}};FCKToolbarStyleCombo.prototype.RefreshActiveItems=function(A){A.DeselectAll();var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetActiveStyles();if (B.length>0){for (var i=0;i<B.length;i++) A.SelectItem(B[i].Name);A.SetLabelById(B[0].Name);}else A.SetLabel('');};FCKToolbarStyleCombo.prototype.RefreshVisibleItems=function(A){if (FCKSelection.GetType()=='Control') var B=FCKSelection.GetSelectedElement().tagName;for (var i in A.Items){var C=A.Items[i];if ((B&&C.Style.Element==B)||(!B&&!C.Style.IsObjectElement)) C.style.display='';else C.style.display='none';}}
+var FCKToolbarPanelButton=function(A,B,C,D,E){this.CommandName=A;var F;if (E==null) F=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(E)=='number') F=[FCKConfig.SkinPath+'fck_strip.gif',16,E];var G=this._UIButton=new FCKToolbarButtonUI(A,B,C,F,D);G._FCKToolbarPanelButton=this;G.ShowArrow=true;G.OnClick=FCKToolbarPanelButton_OnButtonClick;};FCKToolbarPanelButton.prototype.TypeName='FCKToolbarPanelButton';FCKToolbarPanelButton.prototype.Create=function(A){A.className+='Menu';this._UIButton.Create(A);var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName)._Panel;B._FCKToolbarPanelButton=this;var C=B.Document.body.appendChild(B.Document.createElement('div'));C.style.position='absolute';C.style.top='0px';var D=this.LineImg=C.appendChild(B.Document.createElement('IMG'));D.className='TB_ConnectionLine';D.src=FCK_SPACER_PATH;B.OnHide=FCKToolbarPanelButton_OnPanelHide;};function FCKToolbarPanelButton_OnButtonClick(A){var B=this._FCKToolbarPanelButton;var e=B._UIButton.MainElement;B._UIButton.ChangeState(1);B.LineImg.style.width=(e.offsetWidth-2)+'px';FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(B.CommandName).Execute(0,e.offsetHeight-1,e);};function FCKToolbarPanelButton_OnPanelHide(){var A=this._FCKToolbarPanelButton;A._UIButton.ChangeState(0);};FCKToolbarPanelButton.prototype.RefreshState=FCKToolbarButton.prototype.RefreshState;FCKToolbarPanelButton.prototype.Enable=FCKToolbarButton.prototype.Enable;FCKToolbarPanelButton.prototype.Disable=FCKToolbarButton.prototype.Disable;
+var FCKToolbarItems={};FCKToolbarItems.LoadedItems={};FCKToolbarItems.RegisterItem=function(A,B){this.LoadedItems[A]=B;};FCKToolbarItems.GetItem=function(A){var B=FCKToolbarItems.LoadedItems[A];if (B) return B;switch (A){case 'Source':B=new FCKToolbarButton('Source',FCKLang.Source,null,2,true,true,1);break;case 'DocProps':B=new FCKToolbarButton('DocProps',FCKLang.DocProps,null,null,null,null,2);break;case 'Save':B=new FCKToolbarButton('Save',FCKLang.Save,null,null,true,null,3);break;case 'NewPage':B=new FCKToolbarButton('NewPage',FCKLang.NewPage,null,null,true,null,4);break;case 'Preview':B=new FCKToolbarButton('Preview',FCKLang.Preview,null,null,true,null,5);break;case 'Templates':B=new FCKToolbarButton('Templates',FCKLang.Templates,null,null,null,null,6);break;case 'About':B=new FCKToolbarButton('About',FCKLang.About,null,null,true,null,47);break;case 'Cut':B=new FCKToolbarButton('Cut',FCKLang.Cut,null,null,false,true,7);break;case 'Copy':B=new FCKToolbarButton('Copy',FCKLang.Copy,null,null,false,true,8);break;case 'Paste':B=new FCKToolbarButton('Paste',FCKLang.Paste,null,null,false,true,9);break;case 'PasteText':B=new FCKToolbarButton('PasteText',FCKLang.PasteText,null,null,false,true,10);break;case 'PasteWord':B=new FCKToolbarButton('PasteWord',FCKLang.PasteWord,null,null,false,true,11);break;case 'Print':B=new FCKToolbarButton('Print',FCKLang.Print,null,null,false,true,12);break;case 'SpellCheck':B=new FCKToolbarButton('SpellCheck',FCKLang.SpellCheck,null,null,null,null,13);break;case 'Undo':B=new FCKToolbarButton('Undo',FCKLang.Undo,null,null,false,true,14);break;case 'Redo':B=new FCKToolbarButton('Redo',FCKLang.Redo,null,null,false,true,15);break;case 'SelectAll':B=new FCKToolbarButton('SelectAll',FCKLang.SelectAll,null,null,true,null,18);break;case 'RemoveFormat':B=new FCKToolbarButton('RemoveFormat',FCKLang.RemoveFormat,null,null,false,true,19);break;case 'FitWindow':B=new FCKToolbarButton('FitWindow',FCKLang.FitWindow,null,null,true,true,66);break;case 'Bold':B=new FCKToolbarButton('Bold',FCKLang.Bold,null,null,false,true,20);break;case 'Italic':B=new FCKToolbarButton('Italic',FCKLang.Italic,null,null,false,true,21);break;case 'Underline':B=new FCKToolbarButton('Underline',FCKLang.Underline,null,null,false,true,22);break;case 'StrikeThrough':B=new FCKToolbarButton('StrikeThrough',FCKLang.StrikeThrough,null,null,false,true,23);break;case 'Subscript':B=new FCKToolbarButton('Subscript',FCKLang.Subscript,null,null,false,true,24);break;case 'Superscript':B=new FCKToolbarButton('Superscript',FCKLang.Superscript,null,null,false,true,25);break;case 'OrderedList':B=new FCKToolbarButton('InsertOrderedList',FCKLang.NumberedListLbl,FCKLang.NumberedList,null,false,true,26);break;case 'UnorderedList':B=new FCKToolbarButton('InsertUnorderedList',FCKLang.BulletedListLbl,FCKLang.BulletedList,null,false,true,27);break;case 'Outdent':B=new FCKToolbarButton('Outdent',FCKLang.DecreaseIndent,null,null,false,true,28);break;case 'Indent':B=new FCKToolbarButton('Indent',FCKLang.IncreaseIndent,null,null,false,true,29);break;case 'Link':B=new FCKToolbarButton('Link',FCKLang.InsertLinkLbl,FCKLang.InsertLink,null,false,true,34);break;case 'Unlink':B=new FCKToolbarButton('Unlink',FCKLang.RemoveLink,null,null,false,true,35);break;case 'Anchor':B=new FCKToolbarButton('Anchor',FCKLang.Anchor,null,null,null,null,36);break;case 'Image':B=new FCKToolbarButton('Image',FCKLang.InsertImageLbl,FCKLang.InsertImage,null,false,true,37);break;case 'Flash':B=new FCKToolbarButton('Flash',FCKLang.InsertFlashLbl,FCKLang.InsertFlash,null,false,true,38);break;case 'Table':B=new FCKToolbarButton('Table',FCKLang.InsertTableLbl,FCKLang.InsertTable,null,false,true,39);break;case 'SpecialChar':B=new FCKToolbarButton('SpecialChar',FCKLang.InsertSpecialCharLbl,FCKLang.InsertSpecialChar,null,false,true,42);break;case 'Smiley':B=new FCKToolbarButton('Smiley',FCKLang.InsertSmileyLbl,FCKLang.InsertSmiley,null,false,true,41);break;case 'PageBreak':B=new FCKToolbarButton('PageBreak',FCKLang.PageBreakLbl,FCKLang.PageBreak,null,false,true,43);break;case 'Rule':B=new FCKToolbarButton('InsertHorizontalRule',FCKLang.InsertLineLbl,FCKLang.InsertLine,null,false,true,40);break;case 'JustifyLeft':B=new FCKToolbarButton('JustifyLeft',FCKLang.LeftJustify,null,null,false,true,30);break;case 'JustifyCenter':B=new FCKToolbarButton('JustifyCenter',FCKLang.CenterJustify,null,null,false,true,31);break;case 'JustifyRight':B=new FCKToolbarButton('JustifyRight',FCKLang.RightJustify,null,null,false,true,32);break;case 'JustifyFull':B=new FCKToolbarButton('JustifyFull',FCKLang.BlockJustify,null,null,false,true,33);break;case 'Style':B=new FCKToolbarStyleCombo();break;case 'FontName':B=new FCKToolbarFontsCombo();break;case 'FontSize':B=new FCKToolbarFontSizeCombo();break;case 'FontFormat':B=new FCKToolbarFontFormatCombo();break;case 'TextColor':B=new FCKToolbarPanelButton('TextColor',FCKLang.TextColor,null,null,45);break;case 'BGColor':B=new FCKToolbarPanelButton('BGColor',FCKLang.BGColor,null,null,46);break;case 'Find':B=new FCKToolbarButton('Find',FCKLang.Find,null,null,null,null,16);break;case 'Replace':B=new FCKToolbarButton('Replace',FCKLang.Replace,null,null,null,null,17);break;case 'Form':B=new FCKToolbarButton('Form',FCKLang.Form,null,null,null,null,48);break;case 'Checkbox':B=new FCKToolbarButton('Checkbox',FCKLang.Checkbox,null,null,null,null,49);break;case 'Radio':B=new FCKToolbarButton('Radio',FCKLang.RadioButton,null,null,null,null,50);break;case 'TextField':B=new FCKToolbarButton('TextField',FCKLang.TextField,null,null,null,null,51);break;case 'Textarea':B=new FCKToolbarButton('Textarea',FCKLang.Textarea,null,null,null,null,52);break;case 'HiddenField':B=new FCKToolbarButton('HiddenField',FCKLang.HiddenField,null,null,null,null,56);break;case 'Button':B=new FCKToolbarButton('Button',FCKLang.Button,null,null,null,null,54);break;case 'Select':B=new FCKToolbarButton('Select',FCKLang.SelectionField,null,null,null,null,53);break;case 'ImageButton':B=new FCKToolbarButton('ImageButton',FCKLang.ImageButton,null,null,null,null,55);break;default:alert(FCKLang.UnknownToolbarItem.replace(/%1/g,A));return null;};FCKToolbarItems.LoadedItems[A]=B;return B;}
+var FCKToolbar=function(){this.Items=[];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbar_Cleanup);};FCKToolbar.prototype.AddItem=function(A){return this.Items[this.Items.length]=A;};FCKToolbar.prototype.AddButton=function(A,B,C,D,E,F){if (typeof(D)=='number') D=[this.DefaultIconsStrip,this.DefaultIconSize,D];var G=new FCKToolbarButtonUI(A,B,C,D,E,F);G._FCKToolbar=this;G.OnClick=FCKToolbar_OnItemClick;return this.AddItem(G);};function FCKToolbar_OnItemClick(A){var B=A._FCKToolbar;if (B.OnItemClick) B.OnItemClick(B,A);};FCKToolbar.prototype.AddSeparator=function(){this.AddItem(new FCKToolbarSeparator());};FCKToolbar.prototype.Create=function(A){if (this.MainElement){if (this.MainElement.parentNode) this.MainElement.parentNode.removeChild(this.MainElement);this.MainElement=null;};var B=FCKTools.GetElementDocument(A);var e=this.MainElement=B.createElement('table');e.className='TB_Toolbar';e.style.styleFloat=e.style.cssFloat=(FCKLang.Dir=='ltr'?'left':'right');e.dir=FCKLang.Dir;e.cellPadding=0;e.cellSpacing=0;this.RowElement=e.insertRow(-1);var C;if (!this.HideStart){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_Start';};for (var i=0;i<this.Items.length;i++){this.Items[i].Create(this.RowElement.insertCell(-1));};if (!this.HideEnd){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_End';};A.appendChild(e);};function FCKToolbar_Cleanup(){this.MainElement=null;this.RowElement=null;};var FCKToolbarSeparator=function(){};FCKToolbarSeparator.prototype.Create=function(A){FCKTools.AppendElement(A,'div').className='TB_Separator';}
+var FCKToolbarBreak=function(){};FCKToolbarBreak.prototype.Create=function(A){var B=A.ownerDocument.createElement('div');B.style.clear=B.style.cssFloat=FCKLang.Dir=='rtl'?'right':'left';A.appendChild(B);}
+function FCKToolbarSet_Create(A){var B;var C=A||FCKConfig.ToolbarLocation;switch (C){case 'In':document.getElementById('xToolbarRow').style.display='';B=new FCKToolbarSet(document);break;default:FCK.Events.AttachEvent('OnBlur',FCK_OnBlur);FCK.Events.AttachEvent('OnFocus',FCK_OnFocus);var D;var E=C.match(/^Out:(.+)\((\w+)\)$/);if (E){D=eval('parent.'+E[1]).document.getElementById(E[2]);}else{E=C.match(/^Out:(\w+)$/);if (E) D=parent.document.getElementById(E[1]);};if (!D){alert('Invalid value for "ToolbarLocation"');return this._Init('In');};B=D.__FCKToolbarSet;if (B) break;var F=FCKTools.GetElementDocument(D).createElement('iframe');F.frameBorder=0;F.width='100%';F.height='10';D.appendChild(F);F.unselectable='on';var G=F.contentWindow.document;G.open();G.write('<html><head><script type="text/javascript"> window.onload = window.onresize = function() { window.frameElement.height = document.body.scrollHeight ; } </script></head><body style="overflow: hidden">'+document.getElementById('xToolbarSpace').innerHTML+'</body></html>');G.close();G.oncontextmenu=FCKTools.CancelEvent;FCKTools.AppendStyleSheet(G,FCKConfig.SkinPath+'fck_editor.css');B=D.__FCKToolbarSet=new FCKToolbarSet(G);B._IFrame=F;if (FCK.IECleanup) FCK.IECleanup.AddItem(D,FCKToolbarSet_Target_Cleanup);};B.CurrentInstance=FCK;FCK.AttachToOnSelectionChange(B.RefreshItemsState);return B;};function FCK_OnBlur(A){var B=A.ToolbarSet;if (B.CurrentInstance==A) B.Disable();};function FCK_OnFocus(A){var B=A.ToolbarSet;var C=A||FCK;B.CurrentInstance.FocusManager.RemoveWindow(B._IFrame.contentWindow);B.CurrentInstance=C;C.FocusManager.AddWindow(B._IFrame.contentWindow,true);B.Enable();};function FCKToolbarSet_Cleanup(){this._TargetElement=null;this._IFrame=null;};function FCKToolbarSet_Target_Cleanup(){this.__FCKToolbarSet=null;};var FCKToolbarSet=function(A){this._Document=A;this._TargetElement=A.getElementById('xToolbar');var B=A.getElementById('xExpandHandle');var C=A.getElementById('xCollapseHandle');B.title=FCKLang.ToolbarExpand;B.onclick=FCKToolbarSet_Expand_OnClick;C.title=FCKLang.ToolbarCollapse;C.onclick=FCKToolbarSet_Collapse_OnClick;if (!FCKConfig.ToolbarCanCollapse||FCKConfig.ToolbarStartExpanded) this.Expand();else this.Collapse();C.style.display=FCKConfig.ToolbarCanCollapse?'':'none';if (FCKConfig.ToolbarCanCollapse) C.style.display='';else A.getElementById('xTBLeftBorder').style.display='';this.Toolbars=[];this.IsLoaded=false;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarSet_Cleanup);};function FCKToolbarSet_Expand_OnClick(){FCK.ToolbarSet.Expand();};function FCKToolbarSet_Collapse_OnClick(){FCK.ToolbarSet.Collapse();};FCKToolbarSet.prototype.Expand=function(){this._ChangeVisibility(false);};FCKToolbarSet.prototype.Collapse=function(){this._ChangeVisibility(true);};FCKToolbarSet.prototype._ChangeVisibility=function(A){this._Document.getElementById('xCollapsed').style.display=A?'':'none';this._Document.getElementById('xExpanded').style.display=A?'none':'';if (FCKBrowserInfo.IsGecko){FCKTools.RunFunction(window.onresize);}};FCKToolbarSet.prototype.Load=function(A){this.Name=A;this.Items=[];this.ItemsWysiwygOnly=[];this.ItemsContextSensitive=[];this._TargetElement.innerHTML='';var B=FCKConfig.ToolbarSets[A];if (!B){alert(FCKLang.UnknownToolbarSet.replace(/%1/g,A));return;};this.Toolbars=[];for (var x=0;x<B.length;x++){var C=B[x];var D;if (typeof(C)=='string'){if (C=='/') D=new FCKToolbarBreak();}else{D=new FCKToolbar();for (var j=0;j<C.length;j++){var E=C[j];if (E=='-') D.AddSeparator();else{var F=FCKToolbarItems.GetItem(E);if (F){D.AddItem(F);this.Items.push(F);if (!F.SourceView) this.ItemsWysiwygOnly.push(F);if (F.ContextSensitive) this.ItemsContextSensitive.push(F);}}}};D.Create(this._TargetElement);this.Toolbars[this.Toolbars.length]=D;};FCKTools.DisableSelection(this._Document.getElementById('xCollapseHandle').parentNode);if (FCK.Status!=2) FCK.Events.AttachEvent('OnStatusChange',this.RefreshModeState);else this.RefreshModeState();this.IsLoaded=true;this.IsEnabled=true;FCKTools.RunFunction(this.OnLoad);};FCKToolbarSet.prototype.Enable=function(){if (this.IsEnabled) return;this.IsEnabled=true;var A=this.Items;for (var i=0;i<A.length;i++) A[i].RefreshState();};FCKToolbarSet.prototype.Disable=function(){if (!this.IsEnabled) return;this.IsEnabled=false;var A=this.Items;for (var i=0;i<A.length;i++) A[i].Disable();};FCKToolbarSet.prototype.RefreshModeState=function(A){if (FCK.Status!=2) return;var B=A?A.ToolbarSet:this;var C=B.ItemsWysiwygOnly;if (FCK.EditMode==0){for (var i=0;i<C.length;i++) C[i].Enable();B.RefreshItemsState(A);}else{B.RefreshItemsState(A);for (var j=0;j<C.length;j++) C[j].Disable();}};FCKToolbarSet.prototype.RefreshItemsState=function(A){var B=(A?A.ToolbarSet:this).ItemsContextSensitive;for (var i=0;i<B.length;i++) B[i].RefreshState();};
+var FCKDialog={};FCKDialog.OpenDialog=function(A,B,C,D,E,F,G,H){var I={};I.Title=B;I.Page=C;I.Editor=window;I.CustomValue=F;var J=FCKConfig.BasePath+'fckdialog.html';this.Show(I,A,J,D,E,G,H);};
+FCKDialog.Show=function(A,B,C,D,E,F,G){var H=(FCKConfig.ScreenHeight-E)/2;var I=(FCKConfig.ScreenWidth-D)/2;var J="location=no,menubar=no,toolbar=no,dependent=yes,dialog=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable="+(G?'yes':'no')+",width="+D+",height="+E+",top="+H+",left="+I;if (!F) F=window;FCKFocusManager.Lock();var K=F.open('','FCKeditorDialog_'+B,J,true);if (!K){alert(FCKLang.DialogBlocked);FCKFocusManager.Unlock();return;};K.moveTo(I,H);K.resizeTo(D,E);K.focus();K.location.href=C;K.dialogArguments=A;F.FCKLastDialogInfo=A;this.Window=K;try{window.top.parent.addEventListener('mousedown',this.CheckFocus,true);window.top.parent.addEventListener('mouseup',this.CheckFocus,true);window.top.parent.addEventListener('click',this.CheckFocus,true);window.top.parent.addEventListener('focus',this.CheckFocus,true);}catch (e){}};FCKDialog.CheckFocus=function(){if (typeof(FCKDialog)!="object") return false;if (FCKDialog.Window&&!FCKDialog.Window.closed) FCKDialog.Window.focus();else{try{window.top.parent.removeEventListener('onmousedown',FCKDialog.CheckFocus,true);window.top.parent.removeEventListener('mouseup',FCKDialog.CheckFocus,true);window.top.parent.removeEventListener('click',FCKDialog.CheckFocus,true);window.top.parent.removeEventListener('onfocus',FCKDialog.CheckFocus,true);}catch (e){}};return false;};
+var FCKMenuItem=function(A,B,C,D,E){this.Name=B;this.Label=C||B;this.IsDisabled=E;this.Icon=new FCKIcon(D);this.SubMenu=new FCKMenuBlockPanel();this.SubMenu.Parent=A;this.SubMenu.OnClick=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnClick,this);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuItem_Cleanup);};FCKMenuItem.prototype.AddItem=function(A,B,C,D){this.HasSubMenu=true;return this.SubMenu.AddItem(A,B,C,D);};FCKMenuItem.prototype.AddSeparator=function(){this.SubMenu.AddSeparator();};FCKMenuItem.prototype.Create=function(A){var B=this.HasSubMenu;var C=FCKTools.GetElementDocument(A);var r=this.MainElement=A.insertRow(-1);r.className=this.IsDisabled?'MN_Item_Disabled':'MN_Item';if (!this.IsDisabled){FCKTools.AddEventListenerEx(r,'mouseover',FCKMenuItem_OnMouseOver,[this]);FCKTools.AddEventListenerEx(r,'click',FCKMenuItem_OnClick,[this]);if (!B) FCKTools.AddEventListenerEx(r,'mouseout',FCKMenuItem_OnMouseOut,[this]);};var D=r.insertCell(-1);D.className='MN_Icon';D.appendChild(this.Icon.CreateIconElement(C));D=r.insertCell(-1);D.className='MN_Label';D.noWrap=true;D.appendChild(C.createTextNode(this.Label));D=r.insertCell(-1);if (B){D.className='MN_Arrow';var E=D.appendChild(C.createElement('IMG'));E.src=FCK_IMAGES_PATH+'arrow_'+FCKLang.Dir+'.gif';E.width=4;E.height=7;this.SubMenu.Create();this.SubMenu.Panel.OnHide=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnHide,this);}};FCKMenuItem.prototype.Activate=function(){this.MainElement.className='MN_Item_Over';if (this.HasSubMenu){this.SubMenu.Show(this.MainElement.offsetWidth+2,-2,this.MainElement);};FCKTools.RunFunction(this.OnActivate,this);};FCKMenuItem.prototype.Deactivate=function(){this.MainElement.className='MN_Item';if (this.HasSubMenu) this.SubMenu.Hide();};function FCKMenuItem_SubMenu_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuItem_SubMenu_OnHide(A){A.Deactivate();};function FCKMenuItem_OnClick(A,B){if (B.HasSubMenu) B.Activate();else{B.Deactivate();FCKTools.RunFunction(B.OnClick,B,[B]);}};function FCKMenuItem_OnMouseOver(A,B){B.Activate();};function FCKMenuItem_OnMouseOut(A,B){B.Deactivate();};function FCKMenuItem_Cleanup(){this.MainElement=null;}
+var FCKMenuBlock=function(){this._Items=[];};FCKMenuBlock.prototype.Count=function(){return this._Items.length;};FCKMenuBlock.prototype.AddItem=function(A,B,C,D){var E=new FCKMenuItem(this,A,B,C,D);E.OnClick=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnClick,this);E.OnActivate=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnActivate,this);this._Items.push(E);return E;};FCKMenuBlock.prototype.AddSeparator=function(){this._Items.push(new FCKMenuSeparator());};FCKMenuBlock.prototype.RemoveAllItems=function(){this._Items=[];var A=this._ItemsTable;if (A){while (A.rows.length>0) A.deleteRow(0);}};FCKMenuBlock.prototype.Create=function(A){if (!this._ItemsTable){if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuBlock_Cleanup);this._Window=FCKTools.GetElementWindow(A);var B=FCKTools.GetElementDocument(A);var C=A.appendChild(B.createElement('table'));C.cellPadding=0;C.cellSpacing=0;FCKTools.DisableSelection(C);var D=C.insertRow(-1).insertCell(-1);D.className='MN_Menu';var E=this._ItemsTable=D.appendChild(B.createElement('table'));E.cellPadding=0;E.cellSpacing=0;};for (var i=0;i<this._Items.length;i++) this._Items[i].Create(this._ItemsTable);};function FCKMenuBlock_Item_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuBlock_Item_OnActivate(A){var B=A._ActiveItem;if (B&&B!=this){if (!FCKBrowserInfo.IsIE&&B.HasSubMenu&&!this.HasSubMenu) A._Window.focus();B.Deactivate();};A._ActiveItem=this;};function FCKMenuBlock_Cleanup(){this._Window=null;this._ItemsTable=null;};var FCKMenuSeparator=function(){};FCKMenuSeparator.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var r=A.insertRow(-1);var C=r.insertCell(-1);C.className='MN_Separator MN_Icon';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';}
+var FCKMenuBlockPanel=function(){FCKMenuBlock.call(this);};FCKMenuBlockPanel.prototype=new FCKMenuBlock();FCKMenuBlockPanel.prototype.Create=function(){var A=this.Panel=(this.Parent&&this.Parent.Panel?this.Parent.Panel.CreateChildPanel():new FCKPanel());A.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');FCKMenuBlock.prototype.Create.call(this,A.MainNode);};FCKMenuBlockPanel.prototype.Show=function(x,y,A){if (!this.Panel.CheckIsOpened()) this.Panel.Show(x,y,A);};FCKMenuBlockPanel.prototype.Hide=function(){if (this.Panel.CheckIsOpened()) this.Panel.Hide();}
+var FCKContextMenu=function(A,B){var C=this._Panel=new FCKPanel(A,true);C.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');C.IsContextMenu=true;if (FCKBrowserInfo.IsGecko) C.Document.addEventListener('draggesture',function(e) {e.preventDefault();return false;},true);var D=this._MenuBlock=new FCKMenuBlock();D.Panel=C;D.OnClick=FCKTools.CreateEventListener(FCKContextMenu_MenuBlock_OnClick,this);this._Redraw=true;};FCKContextMenu.prototype.SetMouseClickWindow=function(A){if (!FCKBrowserInfo.IsIE){this._Document=A.document;this._Document.addEventListener('contextmenu',FCKContextMenu_Document_OnContextMenu,false);}};FCKContextMenu.prototype.AddItem=function(A,B,C,D){var E=this._MenuBlock.AddItem(A,B,C,D);this._Redraw=true;return E;};FCKContextMenu.prototype.AddSeparator=function(){this._MenuBlock.AddSeparator();this._Redraw=true;};FCKContextMenu.prototype.RemoveAllItems=function(){this._MenuBlock.RemoveAllItems();this._Redraw=true;};FCKContextMenu.prototype.AttachToElement=function(A){if (FCKBrowserInfo.IsIE) FCKTools.AddEventListenerEx(A,'contextmenu',FCKContextMenu_AttachedElement_OnContextMenu,this);else A._FCKContextMenu=this;};function FCKContextMenu_Document_OnContextMenu(e){var A=e.target;while (A){if (A._FCKContextMenu){FCKTools.CancelEvent(e);FCKContextMenu_AttachedElement_OnContextMenu(e,A._FCKContextMenu,A);};A=A.parentNode;}};function FCKContextMenu_AttachedElement_OnContextMenu(A,B,C){var D=C||this;if (B.OnBeforeOpen) B.OnBeforeOpen.call(B,D);if (B._MenuBlock.Count()==0) return false;if (B._Redraw){B._MenuBlock.Create(B._Panel.MainNode);B._Redraw=false;};FCKTools.DisableSelection(B._Panel.Document.body);B._Panel.Show(A.pageX||A.screenX,A.pageY||A.screenY,A.currentTarget||null);return false;};function FCKContextMenu_MenuBlock_OnClick(A,B){B._Panel.Hide();FCKTools.RunFunction(B.OnItemClick,B,A);}
+FCK.ContextMenu={};FCK.ContextMenu.Listeners=[];FCK.ContextMenu.RegisterListener=function(A){if (A) this.Listeners.push(A);};function FCK_ContextMenu_Init(){var A=FCK.ContextMenu._InnerContextMenu=new FCKContextMenu(FCKBrowserInfo.IsIE?window:window.parent,FCKLang.Dir);A.OnBeforeOpen=FCK_ContextMenu_OnBeforeOpen;A.OnItemClick=FCK_ContextMenu_OnItemClick;var B=FCK.ContextMenu;for (var i=0;i<FCKConfig.ContextMenu.length;i++) B.RegisterListener(FCK_ContextMenu_GetListener(FCKConfig.ContextMenu[i]));};function FCK_ContextMenu_GetListener(A){switch (A){case 'Generic':return {AddItems:function(menu,tag,tagName){menu.AddItem('Cut',FCKLang.Cut,7,FCKCommands.GetCommand('Cut').GetState()==-1);menu.AddItem('Copy',FCKLang.Copy,8,FCKCommands.GetCommand('Copy').GetState()==-1);menu.AddItem('Paste',FCKLang.Paste,9,FCKCommands.GetCommand('Paste').GetState()==-1);}};case 'Table':return {AddItems:function(menu,tag,tagName){var B=(tagName=='TABLE');var C=(!B&&FCKSelection.HasAncestorNode('TABLE'));if (C){menu.AddSeparator();var D=menu.AddItem('Cell',FCKLang.CellCM);D.AddItem('TableInsertCell',FCKLang.InsertCell,58);D.AddItem('TableDeleteCells',FCKLang.DeleteCells,59);D.AddItem('TableMergeCells',FCKLang.MergeCells,60);D.AddItem('TableSplitCell',FCKLang.SplitCell,61);D.AddSeparator();D.AddItem('TableCellProp',FCKLang.CellProperties,57);menu.AddSeparator();D=menu.AddItem('Row',FCKLang.RowCM);D.AddItem('TableInsertRow',FCKLang.InsertRow,62);D.AddItem('TableDeleteRows',FCKLang.DeleteRows,63);menu.AddSeparator();D=menu.AddItem('Column',FCKLang.ColumnCM);D.AddItem('TableInsertColumn',FCKLang.InsertColumn,64);D.AddItem('TableDeleteColumns',FCKLang.DeleteColumns,65);};if (B||C){menu.AddSeparator();menu.AddItem('TableDelete',FCKLang.TableDelete);menu.AddItem('TableProp',FCKLang.TableProperties,39);}}};case 'Link':return {AddItems:function(menu,tag,tagName){var E=(tagName=='A'||FCKSelection.HasAncestorNode('A'));if (E||FCK.GetNamedCommandState('Unlink')!=-1){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0&&F.href.length==0);if (G) return;menu.AddSeparator();if (E) menu.AddItem('Link',FCKLang.EditLink,34);menu.AddItem('Unlink',FCKLang.RemoveLink,35);}}};case 'Image':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&!tag.getAttribute('_fckfakelement')){menu.AddSeparator();menu.AddItem('Image',FCKLang.ImageProperties,37);}}};case 'Anchor':return {AddItems:function(menu,tag,tagName){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0);if (G||(tagName=='IMG'&&tag.getAttribute('_fckanchor'))){menu.AddSeparator();menu.AddItem('Anchor',FCKLang.AnchorProp,36);}}};case 'Flash':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckflash')){menu.AddSeparator();menu.AddItem('Flash',FCKLang.FlashProperties,38);}}};case 'Form':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('FORM')){menu.AddSeparator();menu.AddItem('Form',FCKLang.FormProp,48);}}};case 'Checkbox':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='checkbox'){menu.AddSeparator();menu.AddItem('Checkbox',FCKLang.CheckboxProp,49);}}};case 'Radio':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='radio'){menu.AddSeparator();menu.AddItem('Radio',FCKLang.RadioButtonProp,50);}}};case 'TextField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='text'||tag.type=='password')){menu.AddSeparator();menu.AddItem('TextField',FCKLang.TextFieldProp,51);}}};case 'HiddenField':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckinputhidden')){menu.AddSeparator();menu.AddItem('HiddenField',FCKLang.HiddenFieldProp,56);}}};case 'ImageButton':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='image'){menu.AddSeparator();menu.AddItem('ImageButton',FCKLang.ImageButtonProp,55);}}};case 'Button':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='button'||tag.type=='submit'||tag.type=='reset')){menu.AddSeparator();menu.AddItem('Button',FCKLang.ButtonProp,54);}}};case 'Select':return {AddItems:function(menu,tag,tagName){if (tagName=='SELECT'){menu.AddSeparator();menu.AddItem('Select',FCKLang.SelectionFieldProp,53);}}};case 'Textarea':return {AddItems:function(menu,tag,tagName){if (tagName=='TEXTAREA'){menu.AddSeparator();menu.AddItem('Textarea',FCKLang.TextareaProp,52);}}};case 'BulletedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('UL')){menu.AddSeparator();menu.AddItem('BulletedList',FCKLang.BulletedListProp,27);}}};case 'NumberedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('OL')){menu.AddSeparator();menu.AddItem('NumberedList',FCKLang.NumberedListProp,26);}}};};return null;};function FCK_ContextMenu_OnBeforeOpen(){FCK.Events.FireEvent('OnSelectionChange');var A,sTagName;if ((A=FCKSelection.GetSelectedElement())) sTagName=A.tagName;var B=FCK.ContextMenu._InnerContextMenu;B.RemoveAllItems();var C=FCK.ContextMenu.Listeners;for (var i=0;i<C.length;i++) C[i].AddItems(B,A,sTagName);};function FCK_ContextMenu_OnItemClick(A){FCK.Focus();FCKCommands.GetCommand(A.Name).Execute();};
+var FCKPlugin=function(A,B,C){this.Name=A;this.BasePath=C?C:FCKConfig.PluginsPath;this.Path=this.BasePath+A+'/';if (!B||B.length==0) this.AvailableLangs=[];else this.AvailableLangs=B.split(',');};FCKPlugin.prototype.Load=function(){if (this.AvailableLangs.length>0){var A;if (this.AvailableLangs.IndexOf(FCKLanguageManager.ActiveLanguage.Code)>=0) A=FCKLanguageManager.ActiveLanguage.Code;else A=this.AvailableLangs[0];LoadScript(this.Path+'lang/'+A+'.js');};LoadScript(this.Path+'fckplugin.js');}
+var FCKPlugins=FCK.Plugins={};FCKPlugins.ItemsCount=0;FCKPlugins.Items={};FCKPlugins.Load=function(){var A=FCKPlugins.Items;for (var i=0;i<FCKConfig.Plugins.Items.length;i++){var B=FCKConfig.Plugins.Items[i];var C=A[B[0]]=new FCKPlugin(B[0],B[1],B[2]);FCKPlugins.ItemsCount++;};for (var s in A) A[s].Load();FCKPlugins.Load=null;}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/js/fckeditorcode_ie.js
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/js/fckeditorcode_ie.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/js/fckeditorcode_ie.js	(revision 795)
@@ -0,0 +1,99 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * This file has been compressed for better performance. The original source
+ * can be found at "editor/_source".
+ */
+
+var FCK_STATUS_NOTLOADED=window.parent.FCK_STATUS_NOTLOADED=0;var FCK_STATUS_ACTIVE=window.parent.FCK_STATUS_ACTIVE=1;var FCK_STATUS_COMPLETE=window.parent.FCK_STATUS_COMPLETE=2;var FCK_TRISTATE_OFF=window.parent.FCK_TRISTATE_OFF=0;var FCK_TRISTATE_ON=window.parent.FCK_TRISTATE_ON=1;var FCK_TRISTATE_DISABLED=window.parent.FCK_TRISTATE_DISABLED=-1;var FCK_UNKNOWN=window.parent.FCK_UNKNOWN=-9;var FCK_TOOLBARITEM_ONLYICON=window.parent.FCK_TOOLBARITEM_ONLYICON=0;var FCK_TOOLBARITEM_ONLYTEXT=window.parent.FCK_TOOLBARITEM_ONLYTEXT=1;var FCK_TOOLBARITEM_ICONTEXT=window.parent.FCK_TOOLBARITEM_ICONTEXT=2;var FCK_EDITMODE_WYSIWYG=window.parent.FCK_EDITMODE_WYSIWYG=0;var FCK_EDITMODE_SOURCE=window.parent.FCK_EDITMODE_SOURCE=1;var FCK_IMAGES_PATH='images/';var FCK_SPACER_PATH='images/spacer.gif';var CTRL=1000;var SHIFT=2000;var ALT=4000;
+String.prototype.Contains=function(A){return (this.indexOf(A)>-1);};String.prototype.Equals=function(){var A=arguments;if (A.length==1&&A[0].pop) A=A[0];for (var i=0;i<A.length;i++){if (this==A[i]) return true;};return false;};String.prototype.IEquals=function(){var A=this.toUpperCase();var B=arguments;if (B.length==1&&B[0].pop) B=B[0];for (var i=0;i<B.length;i++){if (A==B[i].toUpperCase()) return true;};return false;};String.prototype.ReplaceAll=function(A,B){var C=this;for (var i=0;i<A.length;i++){C=C.replace(A[i],B[i]);};return C;};Array.prototype.AddItem=function(A){var i=this.length;this[i]=A;return i;};Array.prototype.IndexOf=function(A){for (var i=0;i<this.length;i++){if (this[i]==A) return i;};return-1;};String.prototype.StartsWith=function(A){return (this.substr(0,A.length)==A);};String.prototype.EndsWith=function(A,B){var C=this.length;var D=A.length;if (D>C) return false;if (B){var E=new RegExp(A+'$','i');return E.test(this);}else return (D==0||this.substr(C-D,D)==A);};String.prototype.Remove=function(A,B){var s='';if (A>0) s=this.substring(0,A);if (A+B<this.length) s+=this.substring(A+B,this.length);return s;};String.prototype.Trim=function(){return this.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,'');};String.prototype.LTrim=function(){return this.replace(/^[ \t\n\r]*/g,'');};String.prototype.RTrim=function(){return this.replace(/[ \t\n\r]*$/g,'');};String.prototype.ReplaceNewLineChars=function(A){return this.replace(/\n/g,A);}
+var	FCKIECleanup=function(A){if (A._FCKCleanupObj) this.Items=A._FCKCleanupObj.Items;else{this.Items=[];A._FCKCleanupObj=this;FCKTools.AddEventListenerEx(A,'unload',FCKIECleanup_Cleanup);}};FCKIECleanup.prototype.AddItem=function(A,B){this.Items.push([A,B]);};function FCKIECleanup_Cleanup(){if (!this._FCKCleanupObj) return;var A=this._FCKCleanupObj.Items;while (A.length>0){var B=A.pop();if (B) B[1].call(B[0]);};this._FCKCleanupObj=null;if (CollectGarbage) CollectGarbage();}
+var s=navigator.userAgent.toLowerCase();var FCKBrowserInfo={IsIE:s.Contains('msie'),IsIE7:s.Contains('msie 7'),IsGecko:s.Contains('gecko/'),IsSafari:s.Contains('safari'),IsOpera:s.Contains('opera'),IsMac:s.Contains('macintosh')};(function(A){A.IsGeckoLike=(A.IsGecko||A.IsSafari||A.IsOpera);if (A.IsGecko){var B=s.match(/gecko\/(\d+)/)[1];A.IsGecko10=B<20051111;}else A.IsGecko10=false;})(FCKBrowserInfo);
+var FCKURLParams={};(function(){var A=document.location.search.substr(1).split('&');for (var i=0;i<A.length;i++){var B=A[i].split('=');var C=decodeURIComponent(B[0]);var D=decodeURIComponent(B[1]);FCKURLParams[C]=D;}})();
+var FCKEvents=function(A){this.Owner=A;this._RegisteredEvents={};};FCKEvents.prototype.AttachEvent=function(A,B){var C;if (!(C=this._RegisteredEvents[A])) this._RegisteredEvents[A]=[B];else C.push(B);};FCKEvents.prototype.FireEvent=function(A,B){var C=true;var D=this._RegisteredEvents[A];if (D){for (var i=0;i<D.length;i++) C=(D[i](this.Owner,B)&&C);};return C;};
+var FCK={Name:FCKURLParams['InstanceName'],Status:0,EditMode:0,Toolbar:null,HasFocus:false,GetLinkedFieldValue:function(){return this.LinkedField.value;},GetParentForm:function(){return this.LinkedField.form;},StartupValue:'',IsDirty:function(){if (this.EditMode==1) return (this.StartupValue!=this.EditingArea.Textarea.value);else return (this.StartupValue!=this.EditorDocument.body.innerHTML);},ResetIsDirty:function(){if (this.EditMode==1) this.StartupValue=this.EditingArea.Textarea.value;else if (this.EditorDocument.body) this.StartupValue=this.EditorDocument.body.innerHTML;},StartEditor:function(){this.TempBaseTag=FCKConfig.BaseHref.length>0?'<base href="'+FCKConfig.BaseHref+'" _fcktemp="true"></base>':'';var A=FCK.KeystrokeHandler=new FCKKeystrokeHandler();A.OnKeystroke=_FCK_KeystrokeHandler_OnKeystroke;A.SetKeystrokes(FCKConfig.Keystrokes);if (FCKBrowserInfo.IsIE7){if ((CTRL+86/*V*/) in A.Keystrokes) A.SetKeystrokes([CTRL+86,true]);if ((SHIFT+45/*INS*/) in A.Keystrokes) A.SetKeystrokes([SHIFT+45,true]);};this.EditingArea=new FCKEditingArea(document.getElementById('xEditingArea'));this.EditingArea.FFSpellChecker=false;FCKListsLib.Setup();this.SetHTML(this.GetLinkedFieldValue(),true);},Focus:function(){FCK.EditingArea.Focus();},SetStatus:function(A){this.Status=A;if (A==1){FCKFocusManager.AddWindow(window,true);if (FCKBrowserInfo.IsIE) FCKFocusManager.AddWindow(window.frameElement,true);if (FCKConfig.StartupFocus) FCK.Focus();};this.Events.FireEvent('OnStatusChange',A);},FixBody:function(){var A=FCKConfig.EnterMode;if (A!='p'&&A!='div') return;var B=this.EditorDocument;if (!B) return;var C=B.body;if (!C) return;FCKDomTools.TrimNode(C);var D=C.firstChild;var E;while (D){var F=false;switch (D.nodeType){case 1:if (!FCKListsLib.BlockElements[D.nodeName.toLowerCase()]) F=true;break;case 3:if (E||D.nodeValue.Trim().length>0) F=true;};if (F){var G=D.parentNode;if (!E) E=G.insertBefore(B.createElement(A),D);E.appendChild(G.removeChild(D));D=E.nextSibling;}else{if (E){FCKDomTools.TrimNode(E);E=null;};D=D.nextSibling;}};if (E) FCKDomTools.TrimNode(E);},GetXHTML:function(A){if (FCK.EditMode==1) return FCK.EditingArea.Textarea.value;this.FixBody();var B;var C=FCK.EditorDocument;if (!C) return null;if (FCKConfig.FullPage){B=FCKXHtml.GetXHTML(C.getElementsByTagName('html')[0],true,A);if (FCK.DocTypeDeclaration&&FCK.DocTypeDeclaration.length>0) B=FCK.DocTypeDeclaration+'\n'+B;if (FCK.XmlDeclaration&&FCK.XmlDeclaration.length>0) B=FCK.XmlDeclaration+'\n'+B;}else{B=FCKXHtml.GetXHTML(C.body,false,A);if (FCKConfig.IgnoreEmptyParagraphValue&&FCKRegexLib.EmptyOutParagraph.test(B)) B='';};B=FCK.ProtectEventsRestore(B);if (FCKBrowserInfo.IsIE) B=B.replace(FCKRegexLib.ToReplace,'$1');return FCKConfig.ProtectedSource.Revert(B);},UpdateLinkedField:function(){FCK.LinkedField.value=FCK.GetXHTML(FCKConfig.FormatOutput);FCK.Events.FireEvent('OnAfterLinkedFieldUpdate');},RegisteredDoubleClickHandlers:{},OnDoubleClick:function(A){var B=FCK.RegisteredDoubleClickHandlers[A.tagName];if (B) B(A);},RegisterDoubleClickHandler:function(A,B){FCK.RegisteredDoubleClickHandlers[B.toUpperCase()]=A;},OnAfterSetHTML:function(){FCKDocumentProcessor.Process(FCK.EditorDocument);FCKUndo.SaveUndoStep();FCK.Events.FireEvent('OnSelectionChange');FCK.Events.FireEvent('OnAfterSetHTML');},ProtectUrls:function(A){A=A.replace(FCKRegexLib.ProtectUrlsA,'$& _fcksavedurl=$1');A=A.replace(FCKRegexLib.ProtectUrlsImg,'$& _fcksavedurl=$1');return A;},ProtectEvents:function(A){return A.replace(FCKRegexLib.TagsWithEvent,_FCK_ProtectEvents_ReplaceTags);},ProtectEventsRestore:function(A){return A.replace(FCKRegexLib.ProtectedEvents,_FCK_ProtectEvents_RestoreEvents);},ProtectTags:function(A){var B=FCKConfig.ProtectedTags;if (FCKBrowserInfo.IsIE) B+=B.length>0?'|ABBR':'ABBR';var C;if (B.length>0){C=new RegExp('<('+B+')(?!\w|:)','gi');A=A.replace(C,'<FCK:$1');C=new RegExp('<\/('+B+')>','gi');A=A.replace(C,'<\/FCK:$1>');};B='META';if (FCKBrowserInfo.IsIE) B+='|HR';C=new RegExp('<(('+B+')(?=\s|>)[\s\S]*?)/?>','gi');A=A.replace(C,'<FCK:$1 />');return A;},SetHTML:function(A,B){this.EditingArea.Mode=FCK.EditMode;if (FCK.EditMode==0){A=FCKConfig.ProtectedSource.Protect(A);A=A.replace(FCKRegexLib.InvalidSelfCloseTags,'$1></$2>');A=FCK.ProtectEvents(A);A=FCK.ProtectUrls(A);A=FCK.ProtectTags(A);if (FCKBrowserInfo.IsGecko){A=A.replace(FCKRegexLib.StrongOpener,'<b$1');A=A.replace(FCKRegexLib.StrongCloser,'<\/b>');A=A.replace(FCKRegexLib.EmOpener,'<i$1');A=A.replace(FCKRegexLib.EmCloser,'<\/i>');};this._ForceResetIsDirty=(B===true);var C='';if (FCKConfig.FullPage){if (!FCKRegexLib.HeadOpener.test(A)){if (!FCKRegexLib.HtmlOpener.test(A)) A='<html dir="'+FCKConfig.ContentLangDirection+'">'+A+'</html>';A=A.replace(FCKRegexLib.HtmlOpener,'$&<head></head>');};FCK.DocTypeDeclaration=A.match(FCKRegexLib.DocTypeTag);if (FCKBrowserInfo.IsIE) C=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) C='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';C+='<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';C=A.replace(FCKRegexLib.HeadCloser,C+'$&');if (FCK.TempBaseTag.length>0&&!FCKRegexLib.HasBaseTag.test(A)) C=C.replace(FCKRegexLib.HeadOpener,'$&'+FCK.TempBaseTag);}else{C=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"';if (FCKBrowserInfo.IsIE&&!FCKRegexLib.Html4DocType.test(FCKConfig.DocType)) C+=' style="overflow-y: scroll"';C+='><head><title></title>'+_FCK_GetEditorAreaStyleTags()+'<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';if (FCKBrowserInfo.IsIE) C+=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) C+='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';C+=FCK.TempBaseTag;var D='<body';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) D+=' id="'+FCKConfig.BodyId+'"';if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) D+=' class="'+FCKConfig.BodyClass+'"';C+='</head>'+D+'>';if (FCKBrowserInfo.IsGecko&&(A.length==0||FCKRegexLib.EmptyParagraph.test(A))) C+=GECKO_BOGUS;else C+=A;C+='</body></html>';};this.EditingArea.OnLoad=_FCK_EditingArea_OnLoad;this.EditingArea.Start(C);}else{FCK.EditorWindow=null;FCK.EditorDocument=null;this.EditingArea.OnLoad=null;this.EditingArea.Start(A);this.EditingArea.Textarea._FCKShowContextMenu=true;FCK.EnterKeyHandler=null;if (B) this.ResetIsDirty();FCK.KeystrokeHandler.AttachToElement(this.EditingArea.Textarea);this.EditingArea.Textarea.focus();FCK.Events.FireEvent('OnAfterSetHTML');};if (FCKBrowserInfo.IsGecko) window.onresize();},HasFocus:false,RedirectNamedCommands:{},ExecuteNamedCommand:function(A,B,C){FCKUndo.SaveUndoStep();if (!C&&FCK.RedirectNamedCommands[A]!=null) FCK.ExecuteRedirectedNamedCommand(A,B);else{FCK.Focus();FCK.EditorDocument.execCommand(A,false,B);FCK.Events.FireEvent('OnSelectionChange');};FCKUndo.SaveUndoStep();},GetNamedCommandState:function(A){try{if (!FCK.EditorDocument.queryCommandEnabled(A)) return -1;else return FCK.EditorDocument.queryCommandState(A)?1:0;}catch (e){return 0;}},GetNamedCommandValue:function(A){var B='';var C=FCK.GetNamedCommandState(A);if (C==-1) return null;try{B=this.EditorDocument.queryCommandValue(A);}catch(e) {};return B?B:'';},PasteFromWord:function(){FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.PasteFromWord,'dialog/fck_paste.html',400,330,'Word');},Preview:function(){var A=FCKConfig.ScreenWidth*0.8;var B=FCKConfig.ScreenHeight*0.7;var C=(FCKConfig.ScreenWidth-A)/2;var D=window.open('',null,'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width='+A+',height='+B+',left='+C);var E;if (FCKConfig.FullPage){if (FCK.TempBaseTag.length>0) E=FCK.TempBaseTag+FCK.GetXHTML();else E=FCK.GetXHTML();}else{E=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"><head>'+FCK.TempBaseTag+'<title>'+FCKLang.Preview+'</title>'+_FCK_GetEditorAreaStyleTags()+'</head><body>'+FCK.GetXHTML()+'</body></html>';};D.document.write(E);D.document.close();},SwitchEditMode:function(A){var B=(FCK.EditMode==0);var C=FCK.IsDirty();var D;if (B){if (!A&&FCKBrowserInfo.IsIE) FCKUndo.SaveUndoStep();D=FCK.GetXHTML(FCKConfig.FormatSource);if (D==null) return false;}else D=this.EditingArea.Textarea.value;FCK.EditMode=B?1:0;FCK.SetHTML(D,!C);FCK.Focus();FCKTools.RunFunction(FCK.ToolbarSet.RefreshModeState,FCK.ToolbarSet);return true;},CreateElement:function(A){var e=FCK.EditorDocument.createElement(A);return FCK.InsertElementAndGetIt(e);},InsertElementAndGetIt:function(e){e.setAttribute('FCKTempLabel','true');this.InsertElement(e);var A=FCK.EditorDocument.getElementsByTagName(e.tagName);for (var i=0;i<A.length;i++){if (A[i].getAttribute('FCKTempLabel')){A[i].removeAttribute('FCKTempLabel');return A[i];}};return null;}};FCK.Events=new FCKEvents(FCK);FCK.GetHTML=FCK.GetXHTML;function _FCK_ProtectEvents_ReplaceTags(A){return A.replace(FCKRegexLib.EventAttributes,_FCK_ProtectEvents_ReplaceEvents);};function _FCK_ProtectEvents_ReplaceEvents(A,B){return ' '+B+'_fckprotectedatt="'+A.ReplaceAll([/&/g,/'/g,/"/g,/=/g,/</g,/>/g,/\r/g,/\n/g],['&apos;','&#39;','&quot;','&#61;','&lt;','&gt;','&#10;','&#13;'])+'"';};function _FCK_ProtectEvents_RestoreEvents(A,B){return B.ReplaceAll([/&#39;/g,/&quot;/g,/&#61;/g,/&lt;/g,/&gt;/g,/&#10;/g,/&#13;/g,/&apos;/g],["'",'"','=','<','>','\r','\n','&']);};function _FCK_EditingArea_OnLoad(){FCK.EditorWindow=FCK.EditingArea.Window;FCK.EditorDocument=FCK.EditingArea.Document;FCK.InitializeBehaviors();if (!FCKConfig.DisableEnterKeyHandler) FCK.EnterKeyHandler=new FCKEnterKey(FCK.EditorWindow,FCKConfig.EnterMode,FCKConfig.ShiftEnterMode);FCK.KeystrokeHandler.AttachToElement(FCK.EditorDocument);if (FCK._ForceResetIsDirty) FCK.ResetIsDirty();if (FCKBrowserInfo.IsIE&&FCK.HasFocus) FCK.EditorDocument.body.setActive();FCK.OnAfterSetHTML();if (FCK.Status!=0) return;FCK.SetStatus(1);};function _FCK_GetEditorAreaStyleTags(){var A='';var B=FCKConfig.EditorAreaCSS;for (var i=0;i<B.length;i++) A+='<link href="'+B[i]+'" rel="stylesheet" type="text/css" />';return A;};function _FCK_KeystrokeHandler_OnKeystroke(A,B){if (FCK.Status!=2) return false;if (FCK.EditMode==0){if (B=='Paste') return!FCK.Events.FireEvent('OnPaste');}else{if (B.Equals('Paste','Undo','Redo','SelectAll')) return false;};var C=FCK.Commands.GetCommand(B);return (C.Execute.apply(C,FCKTools.ArgumentsToArray(arguments,2))!==false);};(function(){var A=window.parent.document;var B=A.getElementById(FCK.Name);var i=0;while (B||i==0){if (B&&B.tagName.toLowerCase().Equals('input','textarea')){FCK.LinkedField=B;break;};B=A.getElementsByName(FCK.Name)[i++];}})();var FCKTempBin={Elements:[],AddElement:function(A){var B=this.Elements.length;this.Elements[B]=A;return B;},RemoveElement:function(A){var e=this.Elements[A];this.Elements[A]=null;return e;},Reset:function(){var i=0;while (i<this.Elements.length) this.Elements[i++]==null;this.Elements.length=0;}};var FCKFocusManager=FCK.FocusManager={IsLocked:false,AddWindow:function(A,B){var C;if (FCKBrowserInfo.IsIE) C=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else C=A.document;FCKTools.AddEventListener(C,'blur',FCKFocusManager_Win_OnBlur);FCKTools.AddEventListener(C,'focus',B?FCKFocusManager_Win_OnFocus_Area:FCKFocusManager_Win_OnFocus);},RemoveWindow:function(A){if (FCKBrowserInfo.IsIE) oTarget=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else oTarget=A.document;FCKTools.RemoveEventListener(oTarget,'blur',FCKFocusManager_Win_OnBlur);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus_Area);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus);},Lock:function(){this.IsLocked=true;},Unlock:function(){if (this._HasPendingBlur) FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);this.IsLocked=false;},_ResetTimer:function(){this._HasPendingBlur=false;if (this._Timer){window.clearTimeout(this._Timer);delete this._Timer;}}};function FCKFocusManager_Win_OnBlur(){if (typeof(FCK)!='undefined'&&FCK.HasFocus){FCKFocusManager._ResetTimer();FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);}};function FCKFocusManager_FireOnBlur(){if (FCKFocusManager.IsLocked) FCKFocusManager._HasPendingBlur=true;else{FCK.HasFocus=false;FCK.Events.FireEvent("OnBlur");}};function FCKFocusManager_Win_OnFocus_Area(){FCK.Focus();FCKFocusManager_Win_OnFocus();};function FCKFocusManager_Win_OnFocus(){FCKFocusManager._ResetTimer();if (!FCK.HasFocus&&!FCKFocusManager.IsLocked){FCK.HasFocus=true;FCK.Events.FireEvent("OnFocus");}};
+FCK.Description="FCKeditor for Internet Explorer 5.5+";FCK._GetBehaviorsStyle=function(){if (!FCK._BehaviorsStyle){var A=FCKConfig.FullBasePath;var B='';var C;C='<style type="text/css" _fcktemp="true">';if (FCKConfig.ShowBorders) B='url('+A+'css/behaviors/showtableborders.htc)';C+='INPUT,TEXTAREA,SELECT,.FCK__Anchor,.FCK__PageBreak,.FCK__InputHidden';if (FCKConfig.DisableObjectResizing){C+=',IMG';B+=' url('+A+'css/behaviors/disablehandles.htc)';};C+=' { behavior: url('+A+'css/behaviors/disablehandles.htc) ; }';if (B.length>0) C+='TABLE { behavior: '+B+' ; }';C+='</style>';FCK._BehaviorsStyle=C;};return FCK._BehaviorsStyle;};function Doc_OnMouseUp(){if (FCK.EditorWindow.event.srcElement.tagName=='HTML'){FCK.Focus();FCK.EditorWindow.event.cancelBubble=true;FCK.EditorWindow.event.returnValue=false;}};function Doc_OnPaste(){return (FCK.Status==2&&FCK.Events.FireEvent("OnPaste"));};function Doc_OnKeyDown(){if (FCK.EditorWindow){var e=FCK.EditorWindow.event;if (!(e.keyCode>=16&&e.keyCode<=18)) Doc_OnKeyDownUndo();};return true;};function Doc_OnKeyDownUndo(){if (!FCKUndo.Typing){FCKUndo.SaveUndoStep();FCKUndo.Typing=true;FCK.Events.FireEvent("OnSelectionChange");};FCKUndo.TypesCount++;if (FCKUndo.TypesCount>FCKUndo.MaxTypes){FCKUndo.TypesCount=0;FCKUndo.SaveUndoStep();}};function Doc_OnDblClick(){FCK.OnDoubleClick(FCK.EditorWindow.event.srcElement);FCK.EditorWindow.event.cancelBubble=true;};function Doc_OnSelectionChange(){FCK.Events.FireEvent("OnSelectionChange");};FCK.InitializeBehaviors=function(A){this.EditorDocument.attachEvent('onmouseup',Doc_OnMouseUp);this.EditorDocument.body.attachEvent('onpaste',Doc_OnPaste);FCK.ContextMenu._InnerContextMenu.AttachToElement(FCK.EditorDocument.body);if (FCKConfig.TabSpaces>0){window.FCKTabHTML='';for (i=0;i<FCKConfig.TabSpaces;i++) window.FCKTabHTML+="&nbsp;";};this.EditorDocument.attachEvent("onkeydown",Doc_OnKeyDown);this.EditorDocument.attachEvent("ondblclick",Doc_OnDblClick);this.EditorDocument.attachEvent("onselectionchange",Doc_OnSelectionChange);};FCK.InsertHtml=function(A){A=FCKConfig.ProtectedSource.Protect(A);A=FCK.ProtectEvents(A);A=FCK.ProtectUrls(A);A=FCK.ProtectTags(A);FCK.EditorWindow.focus();FCKUndo.SaveUndoStep();var B=FCK.EditorDocument.selection;if (B.type.toLowerCase()=='control') B.clear();B.createRange().pasteHTML(A);FCKDocumentProcessor.Process(FCK.EditorDocument);};FCK.SetInnerHtml=function(A){var B=FCK.EditorDocument;B.body.innerHTML='<div id="__fakeFCKRemove__">&nbsp;</div>'+A;B.getElementById('__fakeFCKRemove__').removeNode(true);};function FCK_PreloadImages(){var A=new FCKImagePreloader();A.AddImages(FCKConfig.PreloadImages);A.AddImages(FCKConfig.SkinPath+'fck_strip.gif');A.OnComplete=LoadToolbarSetup;A.Start();};function Document_OnContextMenu(){return (event.srcElement._FCKShowContextMenu==true);};document.oncontextmenu=Document_OnContextMenu;function FCK_Cleanup(){this.EditorWindow=null;this.EditorDocument=null;};FCK.Paste=function(){if (FCK._PasteIsRunning) return true;if (FCKConfig.ForcePasteAsPlainText){FCK.PasteAsPlainText();return false;};var A=FCK._CheckIsPastingEnabled(true);if (A===false) FCKTools.RunFunction(FCKDialog.OpenDialog,FCKDialog,['FCKDialog_Paste',FCKLang.Paste,'dialog/fck_paste.html',400,330,'Security']);else{if (FCKConfig.AutoDetectPasteFromWord&&A.length>0){var B=/<\w[^>]*(( class="?MsoNormal"?)|(="mso-))/gi;if (B.test(A)){if (confirm(FCKLang.PasteWordConfirm)){FCK.PasteFromWord();return false;}}};FCK._PasteIsRunning=true;FCK.ExecuteNamedCommand('Paste');delete FCK._PasteIsRunning;};return false;};FCK.PasteAsPlainText=function(){if (!FCK._CheckIsPastingEnabled()){FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.PasteAsText,'dialog/fck_paste.html',400,330,'PlainText');return;};var A=clipboardData.getData("Text");if (A&&A.length>0){A=FCKTools.HTMLEncode(A).replace(/\n/g,'<BR>');this.InsertHtml(A);}};FCK._CheckIsPastingEnabled=function(A){FCK._PasteIsEnabled=false;document.body.attachEvent('onpaste',FCK_CheckPasting_Listener);var B=FCK.GetClipboardHTML();document.body.detachEvent('onpaste',FCK_CheckPasting_Listener);if (FCK._PasteIsEnabled){if (!A) B=true;}else B=false;delete FCK._PasteIsEnabled;return B;};function FCK_CheckPasting_Listener(){FCK._PasteIsEnabled=true;};FCK.InsertElement=function(A){FCK.InsertHtml(A.outerHTML);};FCK.GetClipboardHTML=function(){var A=document.getElementById('___FCKHiddenDiv');if (!A){A=document.createElement('DIV');A.id='___FCKHiddenDiv';var B=A.style;B.position='absolute';B.visibility=B.overflow='hidden';B.width=B.height=1;document.body.appendChild(A);};A.innerHTML='';var C=document.body.createTextRange();C.moveToElementText(A);C.execCommand('Paste');var D=A.innerHTML;A.innerHTML='';return D;};FCK.AttachToOnSelectionChange=function(A){this.Events.AttachEvent('OnSelectionChange',A);};FCK.CreateLink=function(A){FCK.ExecuteNamedCommand('Unlink');if (A.length>0){var B='javascript:void(0);/*'+(new Date().getTime())+'*/';FCK.ExecuteNamedCommand('CreateLink',B);var C=this.EditorDocument.links;for (i=0;i<C.length;i++){var D=C[i];if (D.href==B){var E=D.innerHTML;D.href=A;D.innerHTML=E;return D;}}};return null;};
+var FCKConfig=FCK.Config={};if (document.location.protocol=='file:'){FCKConfig.BasePath=decodeURIComponent(document.location.pathname.substr(1));FCKConfig.BasePath=FCKConfig.BasePath.replace(/\\/gi, '/');FCKConfig.BasePath='file://'+FCKConfig.BasePath.substring(0,FCKConfig.BasePath.lastIndexOf('/')+1);FCKConfig.FullBasePath=FCKConfig.BasePath;}else{FCKConfig.BasePath=document.location.pathname.substring(0,document.location.pathname.lastIndexOf('/')+1);FCKConfig.FullBasePath=document.location.protocol+'//'+document.location.host+FCKConfig.BasePath;};FCKConfig.EditorPath=FCKConfig.BasePath.replace(/editor\/$/,'');try{FCKConfig.ScreenWidth=screen.width;FCKConfig.ScreenHeight=screen.height;}catch (e){FCKConfig.ScreenWidth=800;FCKConfig.ScreenHeight=600;};FCKConfig.ProcessHiddenField=function(){this.PageConfig={};var A=window.parent.document.getElementById(FCK.Name+'___Config');if (!A) return;var B=A.value.split('&');for (var i=0;i<B.length;i++){if (B[i].length==0) continue;var C=B[i].split('=');var D=decodeURIComponent(C[0]);var E=decodeURIComponent(C[1]);if (D=='CustomConfigurationsPath') FCKConfig[D]=E;else if (E.toLowerCase()=="true") this.PageConfig[D]=true;else if (E.toLowerCase()=="false") this.PageConfig[D]=false;else if (E.length>0&&!isNaN(E)) this.PageConfig[D]=parseInt(E,10);else this.PageConfig[D]=E;}};function FCKConfig_LoadPageConfig(){var A=FCKConfig.PageConfig;for (var B in A) FCKConfig[B]=A[B];};function FCKConfig_PreProcess(){var A=FCKConfig;if (A.AllowQueryStringDebug){try{if ((/fckdebug=true/i).test(window.top.location.search)) A.Debug=true;}catch (e) {/*Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error).*/}};if (!A.PluginsPath.EndsWith('/')) A.PluginsPath+='/';if (typeof(A.EditorAreaCSS)=='string') A.EditorAreaCSS=[A.EditorAreaCSS];var B=A.ToolbarComboPreviewCSS;if (!B||B.length==0) A.ToolbarComboPreviewCSS=A.EditorAreaCSS;else if (typeof(B)=='string') A.ToolbarComboPreviewCSS=[B];};FCKConfig.ToolbarSets={};FCKConfig.Plugins={};FCKConfig.Plugins.Items=[];FCKConfig.Plugins.Add=function(A,B,C){FCKConfig.Plugins.Items.AddItem([A,B,C]);};FCKConfig.ProtectedSource={};FCKConfig.ProtectedSource.RegexEntries=[/<!--[\s\S]*?-->/g,/<script[\s\S]*?<\/script>/gi,/<noscript[\s\S]*?<\/noscript>/gi];FCKConfig.ProtectedSource.Add=function(A){this.RegexEntries.AddItem(A);};FCKConfig.ProtectedSource.Protect=function(A){function _Replace(protectedSource){var B=FCKTempBin.AddElement(protectedSource);return '<!--{PS..'+B+'}-->';};for (var i=0;i<this.RegexEntries.length;i++){A=A.replace(this.RegexEntries[i],_Replace);};return A;};FCKConfig.ProtectedSource.Revert=function(A,B){function _Replace(m,opener,index){var C=B?FCKTempBin.RemoveElement(index):FCKTempBin.Elements[index];return FCKConfig.ProtectedSource.Revert(C,B);};return A.replace(/(<|&lt;)!--\{PS..(\d+)\}--(>|&gt;)/g,_Replace);}
+var FCKDebug={};FCKDebug._GetWindow=function(){if (!this.DebugWindow||this.DebugWindow.closed) this.DebugWindow=window.open(FCKConfig.BasePath+'fckdebug.html','FCKeditorDebug','menubar=no,scrollbars=yes,resizable=yes,location=no,toolbar=no,width=600,height=500',true);return this.DebugWindow;};FCKDebug.Output=function(A,B,C){if (!FCKConfig.Debug) return;try{this._GetWindow().Output(A,B);}catch (e) {}};FCKDebug.OutputObject=function(A,B){if (!FCKConfig.Debug) return;try{this._GetWindow().OutputObject(A,B);}catch (e) {}}
+var FCKDomTools={MoveChildren:function(A,B){if (A==B) return;var C;while ((C=A.firstChild)) B.appendChild(A.removeChild(C));},TrimNode:function(A,B){this.LTrimNode(A);this.RTrimNode(A,B);},LTrimNode:function(A){var B;while ((B=A.firstChild)){if (B.nodeType==3){var C=B.nodeValue.LTrim();var D=B.nodeValue.length;if (C.length==0){A.removeChild(B);continue;}else if (C.length<D){B.splitText(D-C.length);A.removeChild(A.firstChild);}};break;}},RTrimNode:function(A,B){var C;while ((C=A.lastChild)){switch (C.nodeType){case 1:if (C.nodeName.toUpperCase()=='BR'&&(B||C.getAttribute('type',2)=='_moz')){A.removeChild(C);continue;};break;case 3:var D=C.nodeValue.RTrim();var E=C.nodeValue.length;if (D.length==0){C.parentNode.removeChild(C);continue;}else if (D.length<E){C.splitText(D.length);A.lastChild.parentNode.removeChild(A.lastChild);}};break;}},RemoveNode:function(A,B){if (B){var C;while ((C=A.firstChild)) A.parentNode.insertBefore(A.removeChild(C),A);};return A.parentNode.removeChild(A);},GetFirstChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.firstChild;while(C){if (C.nodeType==1&&C.tagName.Equals.apply(C.tagName,B)) return C;C=C.nextSibling;};return null;},GetLastChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.lastChild;while(C){if (C.nodeType==1&&(!B||C.tagName.Equals(B))) return C;C=C.previousSibling;};return null;},GetPreviousSourceElement:function(A,B,C,D){if (!A) return null;if (C&&A.nodeType==1&&A.nodeName.IEquals(C)) return null;if (A.previousSibling) A=A.previousSibling;else return this.GetPreviousSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.lastChild) A=A.lastChild;else return this.GetPreviousSourceElement(A,B,C,D);};return null;},GetNextSourceElement:function(A,B,C,D){if (!A) return null;if (A.nextSibling) A=A.nextSibling;else return this.GetNextSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.firstChild) A=A.firstChild;else return this.GetNextSourceElement(A,B,C,D);};return null;},InsertAfterNode:function(A,B){return A.parentNode.insertBefore(B,A.nextSibling);},GetParents:function(A){var B=[];while (A){B.splice(0,0,A);A=A.parentNode;};return B;},GetIndexOf:function(A){var B=A.parentNode?A.parentNode.firstChild:null;var C=-1;while (B){C++;if (B==A) return C;B=B.nextSibling;};return-1;}};
+var GECKO_BOGUS='<br type="_moz">';var FCKTools={};FCKTools.CreateBogusBR=function(A){var B=A.createElement('br');B.setAttribute('type','_moz');return B;};FCKTools.AppendStyleSheet=function(A,B){if (typeof(B)=='string') return this._AppendStyleSheet(A,B);else{var C=[];for (var i=0;i<B.length;i++) C.push(this._AppendStyleSheet(A,B[i]));return C;}};FCKTools.GetElementDocument=function (A){return A.ownerDocument||A.document;};FCKTools.GetElementWindow=function(A){return this.GetDocumentWindow(this.GetElementDocument(A));};FCKTools.GetDocumentWindow=function(A){if (FCKBrowserInfo.IsSafari&&!A.parentWindow) this.FixDocumentParentWindow(window.top);return A.parentWindow||A.defaultView;};FCKTools.FixDocumentParentWindow=function(A){A.document.parentWindow=A;for (var i=0;i<A.frames.length;i++) FCKTools.FixDocumentParentWindow(A.frames[i]);};FCKTools.HTMLEncode=function(A){if (!A) return '';A=A.replace(/&/g,'&amp;');A=A.replace(/</g,'&lt;');A=A.replace(/>/g,'&gt;');return A;};FCKTools.HTMLDecode=function(A){if (!A) return '';A=A.replace(/&gt;/g,'>');A=A.replace(/&lt;/g,'<');A=A.replace(/&amp;/g,'&');return A;};FCKTools.AddSelectOption=function(A,B,C){var D=FCKTools.GetElementDocument(A).createElement("OPTION");D.text=B;D.value=C;A.options.add(D);return D;};FCKTools.RunFunction=function(A,B,C,D){if (A) this.SetTimeout(A,0,B,C,D);};FCKTools.SetTimeout=function(A,B,C,D,E){return (E||window).setTimeout(function(){if (D) A.apply(C,[].concat(D));else A.apply(C);},B);};FCKTools.SetInterval=function(A,B,C,D,E){return (E||window).setInterval(function(){A.apply(C,D||[]);},B);};FCKTools.ConvertStyleSizeToHtml=function(A){return A.EndsWith('%')?A:parseInt(A,10);};FCKTools.ConvertHtmlSizeToStyle=function(A){return A.EndsWith('%')?A:(A+'px');};FCKTools.GetElementAscensor=function(A,B){var e=A;var C=","+B.toUpperCase()+",";while (e){if (C.indexOf(","+e.nodeName.toUpperCase()+",")!=-1) return e;e=e.parentNode;};return null;};FCKTools.CreateEventListener=function(A,B){var f=function(){var C=[];for (var i=0;i<arguments.length;i++) C.push(arguments[i]);A.apply(this,C.concat(B));};return f;};FCKTools.IsStrictMode=function(A){return ('CSS1Compat'==(A.compatMode||'CSS1Compat'));};FCKTools.ArgumentsToArray=function(A,B,C){B=B||0;C=C||A.length;var D=[];for (var i=B;i<B+C&&i<A.length;i++) D.push(A[i]);return D;};FCKTools.CloneObject=function(A){var B=function() {};B.prototype=A;return new B;};
+FCKTools.CancelEvent=function(e){return false;};FCKTools._AppendStyleSheet=function(A,B){return A.createStyleSheet(B).owningElement;};FCKTools.ClearElementAttributes=function(A){A.clearAttributes();};FCKTools.GetAllChildrenIds=function(A){var B=[];for (var i=0;i<A.all.length;i++){var C=A.all[i].id;if (C&&C.length>0) B[B.length]=C;};return B;};FCKTools.RemoveOuterTags=function(e){e.insertAdjacentHTML('beforeBegin',e.innerHTML);e.parentNode.removeChild(e);};FCKTools.CreateXmlObject=function(A){var B;switch (A){case 'XmlHttp':B=['MSXML2.XmlHttp','Microsoft.XmlHttp'];break;case 'DOMDocument':B=['MSXML2.DOMDocument','Microsoft.XmlDom'];break;};for (var i=0;i<2;i++){try { return new ActiveXObject(B[i]);}catch (e){}};if (FCKLang.NoActiveX){alert(FCKLang.NoActiveX);FCKLang.NoActiveX=null;};return null;};FCKTools.DisableSelection=function(A){A.unselectable='on';var e,i=0;while ((e=A.all[i++])){switch (e.tagName){case 'IFRAME':case 'TEXTAREA':case 'INPUT':case 'SELECT':break;default:e.unselectable='on';}}};FCKTools.GetScrollPosition=function(A){var B=A.document;var C={ X:B.documentElement.scrollLeft,Y:B.documentElement.scrollTop };if (C.X>0||C.Y>0) return C;return { X:B.body.scrollLeft,Y:B.body.scrollTop };};FCKTools.AddEventListener=function(A,B,C){A.attachEvent('on'+B,C);};FCKTools.RemoveEventListener=function(A,B,C){A.detachEvent('on'+B,C);};FCKTools.AddEventListenerEx=function(A,B,C,D){var o={};o.Source=A;o.Params=D||[];o.Listener=function(ev){return C.apply(o.Source,[ev].concat(o.Params));};if (FCK.IECleanup) FCK.IECleanup.AddItem(null,function() { o.Source=null;o.Params=null;});A.attachEvent('on'+B,o.Listener);A=null;D=null;};FCKTools.GetViewPaneSize=function(A){var B;var C=A.document.documentElement;if (C&&C.clientWidth) B=C;else B=top.document.body;if (B) return { Width:B.clientWidth,Height:B.clientHeight };else return { Width:0,Height:0 };};FCKTools.SaveStyles=function(A){var B={};if (A.className.length>0){B.Class=A.className;A.className='';};var C=A.style.cssText;if (C.length>0){B.Inline=C;A.style.cssText='';};return B;};FCKTools.RestoreStyles=function(A,B){A.className=B.Class||'';A.style.cssText=B.Inline||'';};FCKTools.RegisterDollarFunction=function(A){A.$=A.document.getElementById;};FCKTools.AppendElement=function(A,B){return A.appendChild(this.GetElementDocument(A).createElement(B));};FCKTools.ToLowerCase=function(A){return A.toLowerCase();}
+var FCKeditorAPI;function InitializeAPI(){var A=window.parent;if (!(FCKeditorAPI=A.FCKeditorAPI)){var B='var FCKeditorAPI = {Version : "2.4.2",VersionBuild : "14978",__Instances : new Object(),GetInstance : function( name ){return this.__Instances[ name ];},_FormSubmit : function(){for ( var name in FCKeditorAPI.__Instances ){var oEditor = FCKeditorAPI.__Instances[ name ] ;if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )oEditor.UpdateLinkedField() ;}this._FCKOriginalSubmit() ;},_FunctionQueue	: {Functions : new Array(),IsRunning : false,Add : function( f ){this.Functions.push( f );if ( !this.IsRunning )this.StartNext();},StartNext : function(){var aQueue = this.Functions ;if ( aQueue.length > 0 ){this.IsRunning = true;aQueue[0].call();}else this.IsRunning = false;},Remove : function( f ){var aQueue = this.Functions;var i = 0, fFunc;while( (fFunc = aQueue[ i ]) ){if ( fFunc == f )aQueue.splice( i,1 );i++ ;}this.StartNext();}}}';if (A.execScript) A.execScript(B,'JavaScript');else{if (FCKBrowserInfo.IsGecko10){eval.call(A,B);}else if (FCKBrowserInfo.IsSafari){var C=A.document;var D=C.createElement('script');D.appendChild(C.createTextNode(B));C.documentElement.appendChild(D);}else A.eval(B);};FCKeditorAPI=A.FCKeditorAPI;};FCKeditorAPI.__Instances[FCK.Name]=FCK;};function _AttachFormSubmitToAPI(){var A=FCK.GetParentForm();if (A){FCKTools.AddEventListener(A,'submit',FCK.UpdateLinkedField);if (!A._FCKOriginalSubmit&&(typeof(A.submit)=='function'||(!A.submit.tagName&&!A.submit.length))){A._FCKOriginalSubmit=A.submit;A.submit=FCKeditorAPI._FormSubmit;}}};function FCKeditorAPI_Cleanup(){delete FCKeditorAPI.__Instances[FCK.Name];};FCKTools.AddEventListener(window,'unload',FCKeditorAPI_Cleanup);
+var FCKImagePreloader=function(){this._Images=[];};FCKImagePreloader.prototype={AddImages:function(A){if (typeof(A)=='string') A=A.split(';');this._Images=this._Images.concat(A);},Start:function(){var A=this._Images;this._PreloadCount=A.length;for (var i=0;i<A.length;i++){var B=document.createElement('img');B.onload=B.onerror=_FCKImagePreloader_OnImage;B._FCKImagePreloader=this;B.src=A[i];_FCKImagePreloader_ImageCache.push(B);}}};var _FCKImagePreloader_ImageCache=[];function _FCKImagePreloader_OnImage(){var A=this._FCKImagePreloader;if ((--A._PreloadCount)==0&&A.OnComplete) A.OnComplete();this._FCKImagePreloader=null;}
+var FCKRegexLib={AposEntity:/&apos;/gi,ObjectElements:/^(?:IMG|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|HR|OBJECT|A|UL|OL|LI)$/i,NamedCommands:/^(?:Cut|Copy|Paste|Print|SelectAll|RemoveFormat|Unlink|Undo|Redo|Bold|Italic|Underline|StrikeThrough|Subscript|Superscript|JustifyLeft|JustifyCenter|JustifyRight|JustifyFull|Outdent|Indent|InsertOrderedList|InsertUnorderedList|InsertHorizontalRule)$/i,BodyContents:/([\s\S]*\<body[^\>]*\>)([\s\S]*)(\<\/body\>[\s\S]*)/i,ToReplace:/___fcktoreplace:([\w]+)/ig,MetaHttpEquiv:/http-equiv\s*=\s*["']?([^"' ]+)/i,HasBaseTag:/<base /i,HtmlOpener:/<html\s?[^>]*>/i,HeadOpener:/<head\s?[^>]*>/i,HeadCloser:/<\/head\s*>/i,FCK_Class:/(\s*FCK__[A-Za-z]*\s*)/,ElementName:/(^[a-z_:][\w.\-:]*\w$)|(^[a-z_]$)/,ForceSimpleAmpersand:/___FCKAmp___/g,SpaceNoClose:/\/>/g,EmptyParagraph:/^<([^ >]+)[^>]*>\s*(<\/\1>)?$/,EmptyOutParagraph:/^<([^ >]+)[^>]*>(?:\s*|&nbsp;)(<\/\1>)?$/,TagBody:/></,StrongOpener:/<STRONG([ \>])/gi,StrongCloser:/<\/STRONG>/gi,EmOpener:/<EM([ \>])/gi,EmCloser:/<\/EM>/gi,GeckoEntitiesMarker:/#\?-\:/g,ProtectUrlsImg:/<img(?=\s).*?\ssrc=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi,ProtectUrlsA:/<a(?=\s).*?\shref=((?:("|').*?\2)|(?:[^"'][^ >]+))/gi,Html4DocType:/HTML 4\.0 Transitional/i,DocTypeTag:/<!DOCTYPE[^>]*>/i,TagsWithEvent:/<[^\>]+ on\w+[\s\r\n]*=[\s\r\n]*?('|")[\s\S]+?\>/g,EventAttributes:/\s(on\w+)[\s\r\n]*=[\s\r\n]*?('|")([\s\S]*?)\2/g,ProtectedEvents:/\s\w+_fckprotectedatt="([^"]+)"/g,StyleProperties:/\S+\s*:/g,InvalidSelfCloseTags:/(<(?!base|meta|link|hr|br|param|img|area|input)([a-zA-Z0-9:]+)[^>]*)\/>/gi};
+var FCKListsLib={BlockElements:{ address:1,blockquote:1,center:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },NonEmptyBlockElements:{ p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,address:1,pre:1,ol:1,ul:1,li:1,td:1,th:1 },InlineChildReqElements:{ abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1 },EmptyElements:{ base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 },PathBlockElements:{ address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },PathBlockLimitElements:{ body:1,td:1,th:1,caption:1,form:1 },Setup:function(){if (FCKConfig.EnterMode=='div') this.PathBlockElements.div=1;else this.PathBlockLimitElements.div=1;}};
+var FCKLanguageManager=FCK.Language={AvailableLanguages:{af:'Afrikaans',ar:'Arabic',bg:'Bulgarian',bn:'Bengali/Bangla',bs:'Bosnian',ca:'Catalan',cs:'Czech',da:'Danish',de:'German',el:'Greek',en:'English','en-au':'English (Australia)','en-ca':'English (Canadian)','en-uk':'English (United Kingdom)',eo:'Esperanto',es:'Spanish',et:'Estonian',eu:'Basque',fa:'Persian',fi:'Finnish',fo:'Faroese',fr:'French',gl:'Galician',he:'Hebrew',hi:'Hindi',hr:'Croatian',hu:'Hungarian',it:'Italian',ja:'Japanese',km:'Khmer',ko:'Korean',lt:'Lithuanian',lv:'Latvian',mn:'Mongolian',ms:'Malay',nb:'Norwegian Bokmal',nl:'Dutch',no:'Norwegian',pl:'Polish',pt:'Portuguese (Portugal)','pt-br':'Portuguese (Brazil)',ro:'Romanian',ru:'Russian',sk:'Slovak',sl:'Slovenian',sr:'Serbian (Cyrillic)','sr-latn':'Serbian (Latin)',sv:'Swedish',th:'Thai',tr:'Turkish',uk:'Ukrainian',vi:'Vietnamese',zh:'Chinese Traditional','zh-cn':'Chinese Simplified'},GetActiveLanguage:function(){if (FCKConfig.AutoDetectLanguage){var A;if (navigator.userLanguage) A=navigator.userLanguage.toLowerCase();else if (navigator.language) A=navigator.language.toLowerCase();else{return FCKConfig.DefaultLanguage;};if (A.length>=5){A=A.substr(0,5);if (this.AvailableLanguages[A]) return A;};if (A.length>=2){A=A.substr(0,2);if (this.AvailableLanguages[A]) return A;}};return this.DefaultLanguage;},TranslateElements:function(A,B,C,D){var e=A.getElementsByTagName(B);var E,s;for (var i=0;i<e.length;i++){if ((E=e[i].getAttribute('fckLang'))){if ((s=FCKLang[E])){if (D) s=FCKTools.HTMLEncode(s);eval('e[i].'+C+' = s');}}}},TranslatePage:function(A){this.TranslateElements(A,'INPUT','value');this.TranslateElements(A,'SPAN','innerHTML');this.TranslateElements(A,'LABEL','innerHTML');this.TranslateElements(A,'OPTION','innerHTML',true);},Initialize:function(){if (this.AvailableLanguages[FCKConfig.DefaultLanguage]) this.DefaultLanguage=FCKConfig.DefaultLanguage;else this.DefaultLanguage='en';this.ActiveLanguage={};this.ActiveLanguage.Code=this.GetActiveLanguage();this.ActiveLanguage.Name=this.AvailableLanguages[this.ActiveLanguage.Code];}};
+var FCKXHtmlEntities={};FCKXHtmlEntities.Initialize=function(){if (FCKXHtmlEntities.Entities) return;var A='';var B,e;if (FCKConfig.ProcessHTMLEntities){FCKXHtmlEntities.Entities={' ':'nbsp','¡':'iexcl','¢':'cent','£':'pound','¤':'curren','¥':'yen','¦':'brvbar','§':'sect','¨':'uml','©':'copy','ª':'ordf','«':'laquo','¬':'not','­':'shy','®':'reg','¯':'macr','°':'deg','±':'plusmn','²':'sup2','³':'sup3','´':'acute','µ':'micro','¶':'para','·':'middot','¸':'cedil','¹':'sup1','º':'ordm','»':'raquo','¼':'frac14','½':'frac12','¾':'frac34','¿':'iquest','×':'times','÷':'divide','ƒ':'fnof','•':'bull','…':'hellip','′':'prime','″':'Prime','‾':'oline','⁄':'frasl','℘':'weierp','ℑ':'image','ℜ':'real','™':'trade','ℵ':'alefsym','←':'larr','↑':'uarr','→':'rarr','↓':'darr','↔':'harr','↵':'crarr','⇐':'lArr','⇑':'uArr','⇒':'rArr','⇓':'dArr','⇔':'hArr','∀':'forall','∂':'part','∃':'exist','∅':'empty','∇':'nabla','∈':'isin','∉':'notin','∋':'ni','∏':'prod','∑':'sum','−':'minus','∗':'lowast','√':'radic','∝':'prop','∞':'infin','∠':'ang','∧':'and','∨':'or','∩':'cap','∪':'cup','∫':'int','∴':'there4','∼':'sim','≅':'cong','≈':'asymp','≠':'ne','≡':'equiv','≤':'le','≥':'ge','⊂':'sub','⊃':'sup','⊄':'nsub','⊆':'sube','⊇':'supe','⊕':'oplus','⊗':'otimes','⊥':'perp','⋅':'sdot','◊':'loz','♠':'spades','♣':'clubs','♥':'hearts','♦':'diams','"':'quot','ˆ':'circ','˜':'tilde',' ':'ensp',' ':'emsp',' ':'thinsp','‌':'zwnj','‍':'zwj','‎':'lrm','‏':'rlm','–':'ndash','—':'mdash','‘':'lsquo','’':'rsquo','‚':'sbquo','“':'ldquo','”':'rdquo','„':'bdquo','†':'dagger','‡':'Dagger','‰':'permil','‹':'lsaquo','›':'rsaquo','€':'euro'};for (e in FCKXHtmlEntities.Entities) A+=e;if (FCKConfig.IncludeLatinEntities){B={'À':'Agrave','Á':'Aacute','Â':'Acirc','Ã':'Atilde','Ä':'Auml','Å':'Aring','Æ':'AElig','Ç':'Ccedil','È':'Egrave','É':'Eacute','Ê':'Ecirc','Ë':'Euml','Ì':'Igrave','Í':'Iacute','Î':'Icirc','Ï':'Iuml','Ð':'ETH','Ñ':'Ntilde','Ò':'Ograve','Ó':'Oacute','Ô':'Ocirc','Õ':'Otilde','Ö':'Ouml','Ø':'Oslash','Ù':'Ugrave','Ú':'Uacute','Û':'Ucirc','Ü':'Uuml','Ý':'Yacute','Þ':'THORN','ß':'szlig','à':'agrave','á':'aacute','â':'acirc','ã':'atilde','ä':'auml','å':'aring','æ':'aelig','ç':'ccedil','è':'egrave','é':'eacute','ê':'ecirc','ë':'euml','ì':'igrave','í':'iacute','î':'icirc','ï':'iuml','ð':'eth','ñ':'ntilde','ò':'ograve','ó':'oacute','ô':'ocirc','õ':'otilde','ö':'ouml','ø':'oslash','ù':'ugrave','ú':'uacute','û':'ucirc','ü':'uuml','ý':'yacute','þ':'thorn','ÿ':'yuml','Œ':'OElig','œ':'oelig','Š':'Scaron','š':'scaron','Ÿ':'Yuml'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;};if (FCKConfig.IncludeGreekEntities){B={'Α':'Alpha','Β':'Beta','Γ':'Gamma','Δ':'Delta','Ε':'Epsilon','Ζ':'Zeta','Η':'Eta','Θ':'Theta','Ι':'Iota','Κ':'Kappa','Λ':'Lambda','Μ':'Mu','Ν':'Nu','Ξ':'Xi','Ο':'Omicron','Π':'Pi','Ρ':'Rho','Σ':'Sigma','Τ':'Tau','Υ':'Upsilon','Φ':'Phi','Χ':'Chi','Ψ':'Psi','Ω':'Omega','α':'alpha','β':'beta','γ':'gamma','δ':'delta','ε':'epsilon','ζ':'zeta','η':'eta','θ':'theta','ι':'iota','κ':'kappa','λ':'lambda','μ':'mu','ν':'nu','ξ':'xi','ο':'omicron','π':'pi','ρ':'rho','ς':'sigmaf','σ':'sigma','τ':'tau','υ':'upsilon','φ':'phi','χ':'chi','ψ':'psi','ω':'omega'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;}}else{FCKXHtmlEntities.Entities={};A=' ';};var C='['+A+']';if (FCKConfig.ProcessNumericEntities) C='[^ -~]|'+C;var D=FCKConfig.AdditionalNumericEntities;if (D&&D.length>0) C+='|'+FCKConfig.AdditionalNumericEntities;FCKXHtmlEntities.EntitiesRegex=new RegExp(C,'g');}
+var FCKXHtml={};FCKXHtml.CurrentJobNum=0;FCKXHtml.GetXHTML=function(A,B,C){FCKXHtmlEntities.Initialize();this._NbspEntity=(FCKConfig.ProcessHTMLEntities?'nbsp':'#160');var D=FCK.IsDirty();this._CreateNode=FCKConfig.ForceStrongEm?FCKXHtml_CreateNode_StrongEm:FCKXHtml_CreateNode_Normal;FCKXHtml.SpecialBlocks=[];this.XML=FCKTools.CreateXmlObject('DOMDocument');this.MainNode=this.XML.appendChild(this.XML.createElement('xhtml'));FCKXHtml.CurrentJobNum++;if (B) this._AppendNode(this.MainNode,A);else this._AppendChildNodes(this.MainNode,A,false);var E=this._GetMainXmlString();this.XML=null;E=E.substr(7,E.length-15).Trim();if (FCKBrowserInfo.IsGecko) E=E.replace(/<br\/>$/,'');E=E.replace(FCKRegexLib.SpaceNoClose,' />');if (FCKConfig.ForceSimpleAmpersand) E=E.replace(FCKRegexLib.ForceSimpleAmpersand,'&');if (C) E=FCKCodeFormatter.Format(E);for (var i=0;i<FCKXHtml.SpecialBlocks.length;i++){var F=new RegExp('___FCKsi___'+i);E=E.replace(F,FCKXHtml.SpecialBlocks[i]);};E=E.replace(FCKRegexLib.GeckoEntitiesMarker,'&');if (!D) FCK.ResetIsDirty();return E;};FCKXHtml._AppendAttribute=function(A,B,C){try{if (C==undefined||C==null) C='';else if (C.replace){if (FCKConfig.ForceSimpleAmpersand) C=C.replace(/&/g,'___FCKAmp___');C=C.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity);};var D=this.XML.createAttribute(B);D.value=C;A.attributes.setNamedItem(D);}catch (e){}};FCKXHtml._AppendChildNodes=function(A,B,C){if (C) FCKDomTools.TrimNode(B,true);var D=0;var E=B.firstChild;while (E){if (this._AppendNode(A,E)) D++;E=E.nextSibling;};if (D==0){if (C&&FCKConfig.FillEmptyBlocks){this._AppendEntity(A,this._NbspEntity);return A;};var F=A.nodeName;if (FCKListsLib.InlineChildReqElements[F]) return null;if (!FCKListsLib.EmptyElements[F]) A.appendChild(this.XML.createTextNode(''));};return A;};FCKXHtml._AppendNode=function(A,B){if (!B) return false;switch (B.nodeType){case 1:if (B.getAttribute('_fckfakelement')) return FCKXHtml._AppendNode(A,FCK.GetRealElement(B));if (FCKBrowserInfo.IsGecko&&B.hasAttribute('_moz_editor_bogus_node')) return false;if (B.getAttribute('_fcktemp')) return false;var C=B.tagName.toLowerCase();if (FCKBrowserInfo.IsIE){if (B.scopeName&&B.scopeName!='HTML'&&B.scopeName!='FCK') C=B.scopeName.toLowerCase()+':'+C;}else{if (C.StartsWith('fck:')) C=C.Remove(0,4);};if (!FCKRegexLib.ElementName.test(C)) return false;if (C=='br'&&B.getAttribute('type',2)=='_moz') return false;if (B._fckxhtmljob&&B._fckxhtmljob==FCKXHtml.CurrentJobNum) return false;var D=this._CreateNode(C);FCKXHtml._AppendAttributes(A,B,D,C);B._fckxhtmljob=FCKXHtml.CurrentJobNum;var E=FCKXHtml.TagProcessors[C];if (E) D=E(D,B,A);else D=this._AppendChildNodes(D,B,Boolean(FCKListsLib.NonEmptyBlockElements[C]));if (!D) return false;A.appendChild(D);break;case 3:return this._AppendTextNode(A,B.nodeValue.ReplaceNewLineChars(' '));case 8:if (FCKBrowserInfo.IsIE&&!B.innerHTML) break;try { A.appendChild(this.XML.createComment(B.nodeValue));}catch (e) {/*Do nothing... probably this is a wrong format comment.*/};break;default:A.appendChild(this.XML.createComment("Element not supported - Type: "+B.nodeType+" Name: "+B.nodeName));break;};return true;};function FCKXHtml_CreateNode_StrongEm(A){switch (A){case 'b':A='strong';break;case 'i':A='em';break;};return this.XML.createElement(A);};function FCKXHtml_CreateNode_Normal(A){return this.XML.createElement(A);};FCKXHtml._AppendSpecialItem=function(A){return '___FCKsi___'+FCKXHtml.SpecialBlocks.AddItem(A);};FCKXHtml._AppendEntity=function(A,B){A.appendChild(this.XML.createTextNode('#?-:'+B+';'));};FCKXHtml._AppendTextNode=function(A,B){var C=B.length>0;if (C) A.appendChild(this.XML.createTextNode(B.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity)));return C;};function FCKXHtml_GetEntity(A){var B=FCKXHtmlEntities.Entities[A]||('#'+A.charCodeAt(0));return '#?-:'+B+';';};FCKXHtml._RemoveAttribute=function(A,B,C){var D=A.attributes.getNamedItem(C);if (D&&B.test(D.nodeValue)){var E=D.nodeValue.replace(B,'');if (E.length==0) A.attributes.removeNamedItem(C);else D.nodeValue=E;}};FCKXHtml.TagProcessors={img:function(A,B){if (!A.attributes.getNamedItem('alt')) FCKXHtml._AppendAttribute(A,'alt','');var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'src',C);return A;},a:function(A,B){if (B.innerHTML.Trim().length==0&&!B.name) return false;var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'href',C);if (FCKBrowserInfo.IsIE){FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);};A=FCKXHtml._AppendChildNodes(A,B,false);return A;},script:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/javascript');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.text)));return A;},style:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/css');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.innerHTML)));return A;},title:function(A,B){A.appendChild(FCKXHtml.XML.createTextNode(FCK.EditorDocument.title));return A;},table:function(A,B){if (FCKBrowserInfo.IsIE) FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');A=FCKXHtml._AppendChildNodes(A,B,false);return A;},ol:function(A,B,C){if (B.innerHTML.Trim().length==0) return false;var D=C.lastChild;if (D&&D.nodeType==3) D=D.previousSibling;if (D&&D.nodeName.toUpperCase()=='LI'){B._fckxhtmljob=null;FCKXHtml._AppendNode(D,B);return false;};A=FCKXHtml._AppendChildNodes(A,B);return A;},span:function(A,B){if (B.innerHTML.length==0) return false;A=FCKXHtml._AppendChildNodes(A,B,false);return A;},iframe:function(A,B){var C=B.innerHTML;if (FCKBrowserInfo.IsGecko) C=FCKTools.HTMLDecode(C);C=C.replace(/\s_fcksavedurl="[^"]*"/g,'');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(C)));return A;}};FCKXHtml.TagProcessors.ul=FCKXHtml.TagProcessors.ol;
+FCKXHtml._GetMainXmlString=function(){return this.MainNode.xml;};FCKXHtml._AppendAttributes=function(A,B,C,D){var E=B.attributes;for (var n=0;n<E.length;n++){var F=E[n];if (F.specified){var G=F.nodeName.toLowerCase();var H;if (G.StartsWith('_fck')) continue;else if (G=='style') H=B.style.cssText.replace(FCKRegexLib.StyleProperties,FCKTools.ToLowerCase);else if (G=='class'||G.indexOf('on')==0) H=F.nodeValue;else if (D=='body'&&G=='contenteditable') continue;else if (F.nodeValue===true) H=G;else{try{H=B.getAttribute(G,2);}catch (e) {}};this._AppendAttribute(C,G,H||F.nodeValue);}}};FCKXHtml.TagProcessors['meta']=function(A,B){var C=A.attributes.getNamedItem('http-equiv');if (C==null||C.value.length==0){var D=B.outerHTML.match(FCKRegexLib.MetaHttpEquiv);if (D){D=D[1];FCKXHtml._AppendAttribute(A,'http-equiv',D);}};return A;};FCKXHtml.TagProcessors['font']=function(A,B){if (A.attributes.length==0) A=FCKXHtml.XML.createDocumentFragment();A=FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['input']=function(A,B){if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);if (B.value&&!A.attributes.getNamedItem('value')) FCKXHtml._AppendAttribute(A,'value',B.value);if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text');return A;};FCKXHtml.TagProcessors['option']=function(A,B){if (B.selected&&!A.attributes.getNamedItem('selected')) FCKXHtml._AppendAttribute(A,'selected','selected');A=FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['area']=function(A,B){if (!A.attributes.getNamedItem('coords')){var C=B.getAttribute('coords',2);if (C&&C!='0,0,0') FCKXHtml._AppendAttribute(A,'coords',C);};if (!A.attributes.getNamedItem('shape')){var D=B.getAttribute('shape',2);if (D&&D.length>0) FCKXHtml._AppendAttribute(A,'shape',D);};return A;};FCKXHtml.TagProcessors['label']=function(A,B){if (B.htmlFor.length>0) FCKXHtml._AppendAttribute(A,'for',B.htmlFor);A=FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['form']=function(A,B){if (B.acceptCharset&&B.acceptCharset.length>0&&B.acceptCharset!='UNKNOWN') FCKXHtml._AppendAttribute(A,'accept-charset',B.acceptCharset);if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);A=FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['textarea']=FCKXHtml.TagProcessors['select']=function(A,B){if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);A=FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['div']=function(A,B){if (B.align.length>0) FCKXHtml._AppendAttribute(A,'align',B.align);A=FCKXHtml._AppendChildNodes(A,B,true);return A;}
+var FCKCodeFormatter={};FCKCodeFormatter.Init=function(){var A=this.Regex={};A.BlocksOpener=/\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.BlocksCloser=/\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.NewLineTags=/\<(BR|HR)[^\>]*\>/gi;A.MainTags=/\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi;A.LineSplitter=/\s*\n+\s*/g;A.IncreaseIndent=/^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i;A.DecreaseIndent=/^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i;A.FormatIndentatorRemove=new RegExp('^'+FCKConfig.FormatIndentator);A.ProtectedTags=/(<PRE[^>]*>)([\s\S]*?)(<\/PRE>)/gi;};FCKCodeFormatter._ProtectData=function(A,B,C,D){return B+'___FCKpd___'+FCKCodeFormatter.ProtectedData.AddItem(C)+D;};FCKCodeFormatter.Format=function(A){if (!this.Regex) this.Init();FCKCodeFormatter.ProtectedData=[];var B=A.replace(this.Regex.ProtectedTags,FCKCodeFormatter._ProtectData);B=B.replace(this.Regex.BlocksOpener,'\n$&');B=B.replace(this.Regex.BlocksCloser,'$&\n');B=B.replace(this.Regex.NewLineTags,'$&\n');B=B.replace(this.Regex.MainTags,'\n$&\n');var C='';var D=B.split(this.Regex.LineSplitter);B='';for (var i=0;i<D.length;i++){var E=D[i];if (E.length==0) continue;if (this.Regex.DecreaseIndent.test(E)) C=C.replace(this.Regex.FormatIndentatorRemove,'');B+=C+E+'\n';if (this.Regex.IncreaseIndent.test(E)) C+=FCKConfig.FormatIndentator;};for (var j=0;j<FCKCodeFormatter.ProtectedData.length;j++){var F=new RegExp('___FCKpd___'+j);B=B.replace(F,FCKCodeFormatter.ProtectedData[j].replace(/\$/g,'$$$$'));};return B.Trim();}
+var FCKUndo={};FCKUndo.SavedData=[];FCKUndo.CurrentIndex=-1;FCKUndo.TypesCount=FCKUndo.MaxTypes=25;FCKUndo.Typing=false;FCKUndo.SaveUndoStep=function(){if (FCK.EditMode!=0) return;FCKUndo.SavedData=FCKUndo.SavedData.slice(0,FCKUndo.CurrentIndex+1);var A=FCK.EditorDocument.body.innerHTML;if (FCKUndo.CurrentIndex>=0&&A==FCKUndo.SavedData[FCKUndo.CurrentIndex][0]) return;if (FCKUndo.CurrentIndex+1>=FCKConfig.MaxUndoLevels) FCKUndo.SavedData.shift();else FCKUndo.CurrentIndex++;var B;if (FCK.EditorDocument.selection.type=='Text') B=FCK.EditorDocument.selection.createRange().getBookmark();FCKUndo.SavedData[FCKUndo.CurrentIndex]=[A,B];FCK.Events.FireEvent("OnSelectionChange");};FCKUndo.CheckUndoState=function(){return (FCKUndo.Typing||FCKUndo.CurrentIndex>0);};FCKUndo.CheckRedoState=function(){return (!FCKUndo.Typing&&FCKUndo.CurrentIndex<(FCKUndo.SavedData.length-1));};FCKUndo.Undo=function(){if (FCKUndo.CheckUndoState()){if (FCKUndo.CurrentIndex==(FCKUndo.SavedData.length-1)){FCKUndo.SaveUndoStep();};FCKUndo._ApplyUndoLevel(--FCKUndo.CurrentIndex);FCK.Events.FireEvent("OnSelectionChange");}};FCKUndo.Redo=function(){if (FCKUndo.CheckRedoState()){FCKUndo._ApplyUndoLevel(++FCKUndo.CurrentIndex);FCK.Events.FireEvent("OnSelectionChange");}};FCKUndo._ApplyUndoLevel=function(A){var B=FCKUndo.SavedData[A];if (!B) return;FCK.SetInnerHtml(B[0]);if (B[1]){var C=FCK.EditorDocument.selection.createRange();C.moveToBookmark(B[1]);C.select();};FCKUndo.TypesCount=0;FCKUndo.Typing=false;}
+var FCKEditingArea=function(A){this.TargetElement=A;this.Mode=0;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKEditingArea_Cleanup);};FCKEditingArea.prototype.Start=function(A,B){var C=this.TargetElement;var D=FCKTools.GetElementDocument(C);while(C.childNodes.length>0) C.removeChild(C.childNodes[0]);if (this.Mode==0){var E=this.IFrame=D.createElement('iframe');E.src='javascript:void(0)';E.frameBorder=0;E.width=E.height='100%';C.appendChild(E);if (FCKBrowserInfo.IsIE) A=A.replace(/(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi,'$1></base>');else if (!B){if (FCKBrowserInfo.IsGecko) A=A.replace(/(<body[^>]*>)\s*(<\/body>)/i,'$1'+GECKO_BOGUS+'$2');var F=A.match(FCKRegexLib.BodyContents);if (F){A=F[1]+'&nbsp;'+F[3];this._BodyHTML=F[2];}else this._BodyHTML=A;};this.Window=E.contentWindow;var G=this.Document=this.Window.document;G.open();G.write(A);G.close();if (FCKBrowserInfo.IsGecko10&&!B){this.Start(A,true);return;};this.Window._FCKEditingArea=this;if (FCKBrowserInfo.IsGecko10) this.Window.setTimeout(FCKEditingArea_CompleteStart,500);else FCKEditingArea_CompleteStart.call(this.Window);}else{var H=this.Textarea=D.createElement('textarea');H.className='SourceField';H.dir='ltr';H.style.width=H.style.height='100%';H.style.border='none';C.appendChild(H);H.value=A;FCKTools.RunFunction(this.OnLoad);}};function FCKEditingArea_CompleteStart(){if (!this.document.body){this.setTimeout(FCKEditingArea_CompleteStart,50);return;};var A=this._FCKEditingArea;A.MakeEditable();FCKTools.RunFunction(A.OnLoad);};FCKEditingArea.prototype.MakeEditable=function(){var A=this.Document;if (FCKBrowserInfo.IsIE){A.body.contentEditable=true;}else{try{A.body.spellcheck=(this.FFSpellChecker!==false);if (this._BodyHTML){A.body.innerHTML=this._BodyHTML;this._BodyHTML=null;};A.designMode='on';try{A.execCommand('styleWithCSS',false,FCKConfig.GeckoUseSPAN);}catch (e){A.execCommand('useCSS',false,!FCKConfig.GeckoUseSPAN);};A.execCommand('enableObjectResizing',false,!FCKConfig.DisableObjectResizing);A.execCommand('enableInlineTableEditing',false,!FCKConfig.DisableFFTableHandles);}catch (e) {}}};FCKEditingArea.prototype.Focus=function(){try{if (this.Mode==0){if (FCKBrowserInfo.IsIE&&this.Document.hasFocus()) return;if (FCKBrowserInfo.IsSafari) this.IFrame.focus();else{this.Window.focus();}}else{var A=FCKTools.GetElementDocument(this.Textarea);if ((!A.hasFocus||A.hasFocus())&&A.activeElement==this.Textarea) return;this.Textarea.focus();}}catch(e) {}};function FCKEditingArea_Cleanup(){this.TargetElement=null;this.IFrame=null;this.Document=null;this.Textarea=null;if (this.Window){this.Window._FCKEditingArea=null;this.Window=null;}};
+var FCKKeystrokeHandler=function(A){this.Keystrokes={};this.CancelCtrlDefaults=(A!==false);};FCKKeystrokeHandler.prototype.AttachToElement=function(A){FCKTools.AddEventListenerEx(A,'keydown',_FCKKeystrokeHandler_OnKeyDown,this);if (FCKBrowserInfo.IsGecko10||FCKBrowserInfo.IsOpera||(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsMac)) FCKTools.AddEventListenerEx(A,'keypress',_FCKKeystrokeHandler_OnKeyPress,this);};FCKKeystrokeHandler.prototype.SetKeystrokes=function(){for (var i=0;i<arguments.length;i++){var A=arguments[i];if (typeof(A[0])=='object') this.SetKeystrokes.apply(this,A);else{if (A.length==1) delete this.Keystrokes[A[0]];else this.Keystrokes[A[0]]=A[1]===true?true:A;}}};function _FCKKeystrokeHandler_OnKeyDown(A,B){var C=A.keyCode||A.which;var D=0;if (A.ctrlKey||A.metaKey) D+=CTRL;if (A.shiftKey) D+=SHIFT;if (A.altKey) D+=ALT;var E=C+D;var F=B._CancelIt=false;var G=B.Keystrokes[E];if (G){if (G===true||!(B.OnKeystroke&&B.OnKeystroke.apply(B,G))) return true;F=true;};if (F||(B.CancelCtrlDefaults&&D==CTRL&&(C<33||C>40))){B._CancelIt=true;if (A.preventDefault) return A.preventDefault();A.returnValue=false;A.cancelBubble=true;return false;};return true;};function _FCKKeystrokeHandler_OnKeyPress(A,B){if (B._CancelIt){if (A.preventDefault) return A.preventDefault();return false;};return true;}
+var FCKListHandler={OutdentListItem:function(A){var B=A.parentNode;if (B.tagName.toUpperCase().Equals('UL','OL')){var C=FCKTools.GetElementDocument(A);var D=new FCKDocumentFragment(C);var E=D.RootNode;var F=false;var G=FCKDomTools.GetFirstChild(A,['UL','OL']);if (G){F=true;var H;while ((H=G.firstChild)) E.appendChild(G.removeChild(H));FCKDomTools.RemoveNode(G);};var I;var J=false;while ((I=A.nextSibling)){if (!F&&I.nodeType==1&&I.nodeName.toUpperCase()=='LI') J=F=true;E.appendChild(I.parentNode.removeChild(I));if (!J&&I.nodeType==1&&I.nodeName.toUpperCase().Equals('UL','OL')) FCKDomTools.RemoveNode(I,true);};var K=B.parentNode.tagName.toUpperCase();var L=(K=='LI');if (L||K.Equals('UL','OL')){if (F){var G=B.cloneNode(false);D.AppendTo(G);A.appendChild(G);}else if (L) D.InsertAfterNode(B.parentNode);else D.InsertAfterNode(B);if (L) FCKDomTools.InsertAfterNode(B.parentNode,B.removeChild(A));else FCKDomTools.InsertAfterNode(B,B.removeChild(A));}else{if (F){var N=B.cloneNode(false);D.AppendTo(N);FCKDomTools.InsertAfterNode(B,N);};var O=C.createElement(FCKConfig.EnterMode=='p'?'p':'div');FCKDomTools.MoveChildren(B.removeChild(A),O);FCKDomTools.InsertAfterNode(B,O);if (FCKConfig.EnterMode=='br'){if (FCKBrowserInfo.IsGecko) O.parentNode.insertBefore(FCKTools.CreateBogusBR(C),O);else FCKDomTools.InsertAfterNode(O,FCKTools.CreateBogusBR(C));FCKDomTools.RemoveNode(O,true);}};if (this.CheckEmptyList(B)) FCKDomTools.RemoveNode(B,true);}},CheckEmptyList:function(A){return (FCKDomTools.GetFirstChild(A,'LI')==null);},CheckListHasContents:function(A){var B=A.firstChild;while (B){switch (B.nodeType){case 1:if (!B.nodeName.IEquals('UL','LI')) return true;break;case 3:if (B.nodeValue.Trim().length>0) return true;};B=B.nextSibling;};return false;}};
+var FCKElementPath=function(A){var B=null;var C=null;var D=[];var e=A;while (e){if (e.nodeType==1){if (!this.LastElement) this.LastElement=e;var E=e.nodeName.toLowerCase();if (!C){if (!B&&FCKListsLib.PathBlockElements[E]!=null) B=e;if (FCKListsLib.PathBlockLimitElements[E]!=null) C=e;};D.push(e);if (E=='body') break;};e=e.parentNode;};this.Block=B;this.BlockLimit=C;this.Elements=D;};
+var FCKDomRange=function(A){this.Window=A;};FCKDomRange.prototype={_UpdateElementInfo:function(){if (!this._Range) this.Release(true);else{var A=this._Range.startContainer;var B=this._Range.endContainer;var C=new FCKElementPath(A);this.StartContainer=C.LastElement;this.StartBlock=C.Block;this.StartBlockLimit=C.BlockLimit;if (A!=B) C=new FCKElementPath(B);this.EndContainer=C.LastElement;this.EndBlock=C.Block;this.EndBlockLimit=C.BlockLimit;}},CreateRange:function(){return new FCKW3CRange(this.Window.document);},DeleteContents:function(){if (this._Range){this._Range.deleteContents();this._UpdateElementInfo();}},ExtractContents:function(){if (this._Range){var A=this._Range.extractContents();this._UpdateElementInfo();return A;}},CheckIsCollapsed:function(){if (this._Range) return this._Range.collapsed;},Collapse:function(A){if (this._Range) this._Range.collapse(A);this._UpdateElementInfo();},Clone:function(){var A=FCKTools.CloneObject(this);if (this._Range) A._Range=this._Range.cloneRange();return A;},MoveToNodeContents:function(A){if (!this._Range) this._Range=this.CreateRange();this._Range.selectNodeContents(A);this._UpdateElementInfo();},MoveToElementStart:function(A){this.SetStart(A,1);this.SetEnd(A,1);},MoveToElementEditStart:function(A){var B;while ((B=A.firstChild)&&B.nodeType==1&&FCKListsLib.EmptyElements[B.nodeName.toLowerCase()]==null) A=B;this.MoveToElementStart(A);},InsertNode:function(A){if (this._Range) this._Range.insertNode(A);},CheckIsEmpty:function(A){if (this.CheckIsCollapsed()) return true;var B=this.Window.document.createElement('div');this._Range.cloneContents().AppendTo(B);FCKDomTools.TrimNode(B,A);return (B.innerHTML.length==0);},CheckStartOfBlock:function(){var A=this.Clone();A.Collapse(true);A.SetStart(A.StartBlock||A.StartBlockLimit,1);var B=A.CheckIsEmpty();A.Release();return B;},CheckEndOfBlock:function(A){var B=this.Clone();B.Collapse(false);B.SetEnd(B.EndBlock||B.EndBlockLimit,2);var C=B.CheckIsCollapsed();if (!C){var D=this.Window.document.createElement('div');B._Range.cloneContents().AppendTo(D);FCKDomTools.TrimNode(D,true);C=true;var E=D;while ((E=E.lastChild)){if (E.previousSibling||E.nodeType!=1||FCKListsLib.InlineChildReqElements[E.nodeName.toLowerCase()]==null){C=false;break;}}};B.Release();if (A) this.Select();return C;},CreateBookmark:function(){var A={StartId:'fck_dom_range_start_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000),EndId:'fck_dom_range_end_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000)};var B=this.Window.document;var C;var D;if (!this.CheckIsCollapsed()){C=B.createElement('span');C.id=A.EndId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(false);D.InsertNode(C);};C=B.createElement('span');C.id=A.StartId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(true);D.InsertNode(C);return A;},MoveToBookmark:function(A,B){var C=this.Window.document;var D=C.getElementById(A.StartId);var E=C.getElementById(A.EndId);this.SetStart(D,3);if (!B) FCKDomTools.RemoveNode(D);if (E){this.SetEnd(E,3);if (!B) FCKDomTools.RemoveNode(E);}else this.Collapse(true);},SetStart:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setStart(A,0);break;case 2:C.setStart(A,A.childNodes.length);break;case 3:C.setStartBefore(A);break;case 4:C.setStartAfter(A);};this._UpdateElementInfo();},SetEnd:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setEnd(A,0);break;case 2:C.setEnd(A,A.childNodes.length);break;case 3:C.setEndBefore(A);break;case 4:C.setEndAfter(A);};this._UpdateElementInfo();},Expand:function(A){var B,oSibling;switch (A){case 'block_contents':if (this.StartBlock) this.SetStart(this.StartBlock,1);else{B=this._Range.startContainer;if (B.nodeType==1){if (!(B=B.childNodes[this._Range.startOffset])) B=B.firstChild;};if (!B) return;while (true){oSibling=B.previousSibling;if (!oSibling){if (B.parentNode!=this.StartBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setStartBefore(B);};if (this.EndBlock) this.SetEnd(this.EndBlock,2);else{B=this._Range.endContainer;if (B.nodeType==1) B=B.childNodes[this._Range.endOffset]||B.lastChild;if (!B) return;while (true){oSibling=B.nextSibling;if (!oSibling){if (B.parentNode!=this.EndBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setEndAfter(B);};this._UpdateElementInfo();}},Release:function(A){if (!A) this.Window=null;this.StartContainer=null;this.StartBlock=null;this.StartBlockLimit=null;this.EndContainer=null;this.EndBlock=null;this.EndBlockLimit=null;this._Range=null;}};
+FCKDomRange.prototype.MoveToSelection=function(){this.Release(true);this._Range=new FCKW3CRange(this.Window.document);var A=this.Window.document.selection;if (A.type!='Control'){B=this._GetSelectionMarkerTag(true);this._Range.setStart(B.parentNode,FCKDomTools.GetIndexOf(B));B.parentNode.removeChild(B);var B=this._GetSelectionMarkerTag(false);this._Range.setEnd(B.parentNode,FCKDomTools.GetIndexOf(B));B.parentNode.removeChild(B);this._UpdateElementInfo();}else{var C=A.createRange().item(0);if (C){this._Range.setStartBefore(C);this._Range.setEndAfter(C);this._UpdateElementInfo();}}};FCKDomRange.prototype.Select=function(){if (this._Range){var A=this.CheckIsCollapsed();var B=this._GetRangeMarkerTag(true);if (!A) var C=this._GetRangeMarkerTag(false);var D=this.Window.document.body.createTextRange();D.moveToElementText(B);D.moveStart('character',1);if (!A){var E=this.Window.document.body.createTextRange();E.moveToElementText(C);D.setEndPoint('EndToEnd',E);D.moveEnd('character',-1);};this._Range.setStartBefore(B);B.parentNode.removeChild(B);if (A){try{D.pasteHTML('&nbsp;');D.moveStart('character',-1);}catch (e){};D.select();D.pasteHTML('');}else{this._Range.setEndBefore(C);C.parentNode.removeChild(C);D.select();}}};FCKDomRange.prototype._GetSelectionMarkerTag=function(A){var B=this.Window.document.selection.createRange();B.collapse(A===true);var C='fck_dom_range_temp_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000);B.pasteHTML('<span id="'+C+'"></span>');return this.Window.document.getElementById(C);};FCKDomRange.prototype._GetRangeMarkerTag=function(A){var B=this._Range;if (!A){B=B.cloneRange();B.collapse(A===true);};var C=this.Window.document.createElement('span');C.innerHTML='&nbsp;';B.insertNode(C);return C;}
+var FCKDocumentFragment=function(A){this._Document=A;this.RootNode=A.createElement('div');};FCKDocumentFragment.prototype={AppendTo:function(A){FCKDomTools.MoveChildren(this.RootNode,A);},AppendHtml:function(A){var B=this._Document.createElement('div');B.innerHTML=A;FCKDomTools.MoveChildren(B,this.RootNode);},InsertAfterNode:function(A){var B=this.RootNode;var C;while((C=B.lastChild)) FCKDomTools.InsertAfterNode(A,B.removeChild(C));}};
+var FCKW3CRange=function(A){this._Document=A;this.startContainer=null;this.startOffset=null;this.endContainer=null;this.endOffset=null;this.collapsed=true;};FCKW3CRange.CreateRange=function(A){return new FCKW3CRange(A);};FCKW3CRange.CreateFromRange=function(A,B){var C=FCKW3CRange.CreateRange(A);C.setStart(B.startContainer,B.startOffset);C.setEnd(B.endContainer,B.endOffset);return C;};FCKW3CRange.prototype={_UpdateCollapsed:function(){this.collapsed=(this.startContainer==this.endContainer&&this.startOffset==this.endOffset);},setStart:function(A,B){this.startContainer=A;this.startOffset=B;if (!this.endContainer){this.endContainer=A;this.endOffset=B;};this._UpdateCollapsed();},setEnd:function(A,B){this.endContainer=A;this.endOffset=B;if (!this.startContainer){this.startContainer=A;this.startOffset=B;};this._UpdateCollapsed();},setStartAfter:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setStartBefore:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A));},setEndAfter:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setEndBefore:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A));},collapse:function(A){if (A){this.endContainer=this.startContainer;this.endOffset=this.startOffset;}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset;};this.collapsed=true;},selectNodeContents:function(A){this.setStart(A,0);this.setEnd(A,A.nodeType==3?A.data.length:A.childNodes.length);},insertNode:function(A){var B=this.startContainer;var C=this.startOffset;if (B.nodeType==3){B.splitText(C);if (B==this.endContainer) this.setEnd(B.nextSibling,this.endOffset-this.startOffset);FCKDomTools.InsertAfterNode(B,A);return;}else{B.insertBefore(A,B.childNodes[C]||null);if (B==this.endContainer){this.endOffset++;this.collapsed=false;}}},deleteContents:function(){if (this.collapsed) return;this._ExecContentsAction(0);},extractContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(1,A);return A;},cloneContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(2,A);return A;},_ExecContentsAction:function(A,B){var C=this.startContainer;var D=this.endContainer;var E=this.startOffset;var F=this.endOffset;var G=false;var H=false;if (D.nodeType==3) D=D.splitText(F);else{if (D.childNodes.length>0){if (F>D.childNodes.length-1){D=FCKDomTools.InsertAfterNode(D.lastChild,this._Document.createTextNode(''));H=true;}else D=D.childNodes[F];}};if (C.nodeType==3){C.splitText(E);if (C==D) D=C.nextSibling;}else{if (C.childNodes.length>0&&E<=C.childNodes.length-1){if (E==0){C=C.insertBefore(this._Document.createTextNode(''),C.firstChild);G=true;}else C=C.childNodes[E].previousSibling;}};var I=FCKDomTools.GetParents(C);var J=FCKDomTools.GetParents(D);var i,topStart,topEnd;for (i=0;i<I.length;i++){topStart=I[i];topEnd=J[i];if (topStart!=topEnd) break;};var K,levelStartNode,levelClone,currentNode,currentSibling;if (B) K=B.RootNode;for (var j=i;j<I.length;j++){levelStartNode=I[j];if (K&&levelStartNode!=C) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==C));currentNode=levelStartNode.nextSibling;while(currentNode){if (currentNode==J[j]||currentNode==D) break;currentSibling=currentNode.nextSibling;if (A==2) K.appendChild(currentNode.cloneNode(true));else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.appendChild(currentNode);};currentNode=currentSibling;};if (K) K=levelClone;};if (B) K=B.RootNode;for (var k=i;k<J.length;k++){levelStartNode=J[k];if (A>0&&levelStartNode!=D) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==D));if (!I[k]||levelStartNode.parentNode!=I[k].parentNode){currentNode=levelStartNode.previousSibling;while(currentNode){if (currentNode==I[k]||currentNode==C) break;currentSibling=currentNode.previousSibling;if (A==2) K.insertBefore(currentNode.cloneNode(true),K.firstChild);else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.insertBefore(currentNode,K.firstChild);};currentNode=currentSibling;}};if (K) K=levelClone;};if (A==2){var L=this.startContainer;if (L.nodeType==3){L.data+=L.nextSibling.data;L.parentNode.removeChild(L.nextSibling);};var M=this.endContainer;if (M.nodeType==3&&M.nextSibling){M.data+=M.nextSibling.data;M.parentNode.removeChild(M.nextSibling);}}else{if (topStart&&topEnd&&(C.parentNode!=topStart.parentNode||D.parentNode!=topEnd.parentNode)) this.setStart(topEnd.parentNode,FCKDomTools.GetIndexOf(topEnd));this.collapse(true);};if(G) C.parentNode.removeChild(C);if(H&&D.parentNode) D.parentNode.removeChild(D);},cloneRange:function(){return FCKW3CRange.CreateFromRange(this._Document,this);},toString:function(){var A=this.cloneContents();var B=this._Document.createElement('div');A.AppendTo(B);return B.textContent||B.innerText;}};
+var FCKEnterKey=function(A,B,C){this.Window=A;this.EnterMode=B||'p';this.ShiftEnterMode=C||'br';var D=new FCKKeystrokeHandler(false);D._EnterKey=this;D.OnKeystroke=FCKEnterKey_OnKeystroke;D.SetKeystrokes([[13,'Enter'],[SHIFT+13,'ShiftEnter'],[8,'Backspace'],[46,'Delete']]);D.AttachToElement(A.document);};function FCKEnterKey_OnKeystroke(A,B){var C=this._EnterKey;try{switch (B){case 'Enter':return C.DoEnter();break;case 'ShiftEnter':return C.DoShiftEnter();break;case 'Backspace':return C.DoBackspace();break;case 'Delete':return C.DoDelete();}}catch (e){};return false;};FCKEnterKey.prototype.DoEnter=function(A,B){this._HasShift=(B===true);var C=A||this.EnterMode;if (C=='br') return this._ExecuteEnterBr();else return this._ExecuteEnterBlock(C);};FCKEnterKey.prototype.DoShiftEnter=function(){return this.DoEnter(this.ShiftEnterMode,true);};FCKEnterKey.prototype.DoBackspace=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (!B.CheckIsCollapsed()) return false;var C=B.StartBlock;var D=B.EndBlock;if (B.StartBlockLimit==B.EndBlockLimit&&C&&D){if (!B.CheckIsCollapsed()){var E=B.CheckEndOfBlock();B.DeleteContents();if (C!=D){B.SetStart(D,1);B.SetEnd(D,1);};B.Select();A=(C==D);};if (B.CheckStartOfBlock()){var F=B.StartBlock;var G=FCKDomTools.GetPreviousSourceElement(F,true,['BODY',B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,G,F);}else if (FCKBrowserInfo.IsGecko){B.Select();}};B.Release();return A;};FCKEnterKey.prototype._ExecuteBackspace=function(A,B,C){var D=false;if (!B&&C.nodeName.IEquals('LI')&&C.parentNode.parentNode.nodeName.IEquals('LI')){this._OutdentWithSelection(C,A);return true;};if (B&&B.nodeName.IEquals('LI')){var E=FCKDomTools.GetLastChild(B,['UL','OL']);while (E){B=FCKDomTools.GetLastChild(E,'LI');E=FCKDomTools.GetLastChild(B,['UL','OL']);}};if (B&&C){if (C.nodeName.IEquals('LI')&&!B.nodeName.IEquals('LI')){this._OutdentWithSelection(C,A);return true;};var F=C.parentNode;var G=B.nodeName.toLowerCase();if (FCKListsLib.EmptyElements[G]!=null||G=='table'){FCKDomTools.RemoveNode(B);D=true;}else{FCKDomTools.RemoveNode(C);while (F.innerHTML.Trim().length==0){var H=F.parentNode;H.removeChild(F);F=H;};FCKDomTools.TrimNode(C);FCKDomTools.TrimNode(B);A.SetStart(B,2);A.Collapse(true);var I=A.CreateBookmark();FCKDomTools.MoveChildren(C,B);A.MoveToBookmark(I);A.Select();D=true;}};return D;};FCKEnterKey.prototype.DoDelete=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.CheckIsCollapsed()&&B.CheckEndOfBlock(FCKBrowserInfo.IsGecko)){var C=B.StartBlock;var D=FCKDomTools.GetNextSourceElement(C,true,[B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,C,D);};B.Release();return A;};FCKEnterKey.prototype._ExecuteEnterBlock=function(A,B){var C=B||new FCKDomRange(this.Window);if (!B) C.MoveToSelection();if (C.StartBlockLimit==C.EndBlockLimit){if (!C.StartBlock) this._FixBlock(C,true,A);if (!C.EndBlock) this._FixBlock(C,false,A);var D=C.StartBlock;var E=C.EndBlock;if (!C.CheckIsEmpty()) C.DeleteContents();if (D==E){var F;var G=C.CheckStartOfBlock();var H=C.CheckEndOfBlock();if (G&&!H){F=D.cloneNode(false);if (FCKBrowserInfo.IsGeckoLike) F.innerHTML=GECKO_BOGUS;D.parentNode.insertBefore(F,D);if (FCKBrowserInfo.IsIE){C.MoveToNodeContents(F);C.Select();};C.MoveToElementEditStart(D);}else{if (H){var I=D.tagName.toUpperCase();if (G&&I=='LI'){this._OutdentWithSelection(D,C);C.Release();return true;}else{if ((/^H[1-6]$/).test(I)||this._HasShift) F=this.Window.document.createElement(A);else{F=D.cloneNode(false);this._RecreateEndingTree(D,F);};if (FCKBrowserInfo.IsGeckoLike){F.innerHTML=GECKO_BOGUS;if (G) D.innerHTML=GECKO_BOGUS;}}}else{C.SetEnd(D,2);var J=C.ExtractContents();F=D.cloneNode(false);FCKDomTools.TrimNode(J.RootNode);if (J.RootNode.firstChild.nodeType==1&&J.RootNode.firstChild.tagName.toUpperCase().Equals('UL','OL')) F.innerHTML=GECKO_BOGUS;J.AppendTo(F);if (FCKBrowserInfo.IsGecko){this._AppendBogusBr(D);this._AppendBogusBr(F);}};if (F){FCKDomTools.InsertAfterNode(D,F);C.MoveToElementEditStart(F);if (FCKBrowserInfo.IsGecko) F.scrollIntoView(false);}}}else{C.MoveToElementEditStart(E);};C.Select();};C.Release();return true;};FCKEnterKey.prototype._ExecuteEnterBr=function(A){var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.StartBlockLimit==B.EndBlockLimit){B.DeleteContents();B.MoveToSelection();var C=B.CheckStartOfBlock();var D=B.CheckEndOfBlock();var E=B.StartBlock?B.StartBlock.tagName.toUpperCase():'';var F=this._HasShift;if (!F&&E=='LI') return this._ExecuteEnterBlock(null,B);if (!F&&D&&(/^H[1-6]$/).test(E)){FCKDebug.Output('BR - Header');FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createElement('br'));if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createTextNode(''));B.SetStart(B.StartBlock.nextSibling,FCKBrowserInfo.IsIE?3:1);}else{FCKDebug.Output('BR - No Header');var G=this.Window.document.createElement('br');B.InsertNode(G);if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(G,this.Window.document.createTextNode(''));if (D&&FCKBrowserInfo.IsGecko) this._AppendBogusBr(G.parentNode);if (FCKBrowserInfo.IsIE) B.SetStart(G,4);else B.SetStart(G.nextSibling,1);};B.Collapse(true);B.Select();};B.Release();return true;};FCKEnterKey.prototype._FixBlock=function(A,B,C){var D=A.CreateBookmark();A.Collapse(B);A.Expand('block_contents');var E=this.Window.document.createElement(C);A.ExtractContents().AppendTo(E);FCKDomTools.TrimNode(E);A.InsertNode(E);A.MoveToBookmark(D);};FCKEnterKey.prototype._AppendBogusBr=function(A){var B=A.getElementsByTagName('br');if (B) B=B[B.legth-1];if (!B||B.getAttribute('type',2)!='_moz') A.appendChild(FCKTools.CreateBogusBR(this.Window.document));};FCKEnterKey.prototype._RecreateEndingTree=function(A,B){while ((A=A.lastChild)&&A.nodeType==1&&FCKListsLib.InlineChildReqElements[A.nodeName.toLowerCase()]!=null) B=B.insertBefore(A.cloneNode(false),B.firstChild);};FCKEnterKey.prototype._OutdentWithSelection=function(A,B){var C=B.CreateBookmark();FCKListHandler.OutdentListItem(A);B.MoveToBookmark(C);B.Select();}
+var FCKDocumentProcessor={};FCKDocumentProcessor._Items=[];FCKDocumentProcessor.AppendNew=function(){var A={};this._Items.AddItem(A);return A;};FCKDocumentProcessor.Process=function(A){var B,i=0;while((B=this._Items[i++])) B.ProcessDocument(A);};var FCKDocumentProcessor_CreateFakeImage=function(A,B){var C=FCK.EditorDocument.createElement('IMG');C.className=A;C.src=FCKConfig.FullBasePath+'images/spacer.gif';C.setAttribute('_fckfakelement','true',0);C.setAttribute('_fckrealelement',FCKTempBin.AddElement(B),0);return C;};if (FCKBrowserInfo.IsIE||FCKBrowserInfo.IsOpera){var FCKAnchorsProcessor=FCKDocumentProcessor.AppendNew();FCKAnchorsProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('A');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.name.length>0){if (C.innerHTML!=''){if (FCKBrowserInfo.IsIE) C.className+=' FCK__AnchorC';}else{var D=FCKDocumentProcessor_CreateFakeImage('FCK__Anchor',C.cloneNode(true));D.setAttribute('_fckanchor','true',0);C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}}}};var FCKPageBreaksProcessor=FCKDocumentProcessor.AppendNew();FCKPageBreaksProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('DIV');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.style.pageBreakAfter=='always'&&C.childNodes.length==1&&C.childNodes[0].style&&C.childNodes[0].style.display=='none'){var D=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',C.cloneNode(true));C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}};var FCKFlashProcessor=FCKDocumentProcessor.AppendNew();FCKFlashProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('EMBED');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){var D=C.attributes['type'];if ((C.src&&C.src.EndsWith('.swf',true))||(D&&D.nodeValue=='application/x-shockwave-flash')){var E=C.cloneNode(true);if (FCKBrowserInfo.IsIE){var F=['scale','play','loop','menu','wmode','quality'];for (var G=0;G<F.length;G++){var H=C.getAttribute(F[G]);if (H) E.setAttribute(F[G],H);};E.setAttribute('type',D.nodeValue);};var I=FCKDocumentProcessor_CreateFakeImage('FCK__Flash',E);I.setAttribute('_fckflash','true',0);FCKFlashProcessor.RefreshView(I,C);C.parentNode.insertBefore(I,C);C.parentNode.removeChild(C);}}};FCKFlashProcessor.RefreshView=function(A,B){if (B.width>0) A.style.width=FCKTools.ConvertHtmlSizeToStyle(B.width);if (B.height>0) A.style.height=FCKTools.ConvertHtmlSizeToStyle(B.height);};FCK.GetRealElement=function(A){var e=FCKTempBin.Elements[A.getAttribute('_fckrealelement')];if (A.getAttribute('_fckflash')){if (A.style.width.length>0) e.width=FCKTools.ConvertStyleSizeToHtml(A.style.width);if (A.style.height.length>0) e.height=FCKTools.ConvertStyleSizeToHtml(A.style.height);};return e;};if (FCKBrowserInfo.IsIE){FCKDocumentProcessor.AppendNew().ProcessDocument=function(A){var B=A.getElementsByTagName('HR');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){var D=A.createElement('hr');D.mergeAttributes(C,true);FCKDomTools.InsertAfterNode(C,D);C.parentNode.removeChild(C);}}};FCKDocumentProcessor.AppendNew().ProcessDocument=function(A){var B=A.getElementsByTagName('INPUT');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.type=='hidden'){var D=FCKDocumentProcessor_CreateFakeImage('FCK__InputHidden',C.cloneNode(true));D.setAttribute('_fckinputhidden','true',0);C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}}
+var FCKSelection=FCK.Selection={};
+FCKSelection.GetType=function(){return FCK.EditorDocument.selection.type;};FCKSelection.GetSelectedElement=function(){if (this.GetType()=='Control'){var A=FCK.EditorDocument.selection.createRange();if (A&&A.item) return FCK.EditorDocument.selection.createRange().item(0);}};FCKSelection.GetParentElement=function(){switch (this.GetType()){case 'Control':return FCKSelection.GetSelectedElement().parentElement;case 'None':return null;default:return FCK.EditorDocument.selection.createRange().parentElement();}};FCKSelection.SelectNode=function(A){FCK.Focus();FCK.EditorDocument.selection.empty();var B;try{B=FCK.EditorDocument.body.createControlRange();B.addElement(A);}catch(e){B=FCK.EditorDocument.body.createTextRange();B.moveToElementText(A);};B.select();};FCKSelection.Collapse=function(A){FCK.Focus();if (this.GetType()=='Text'){var B=FCK.EditorDocument.selection.createRange();B.collapse(A==null||A===true);B.select();}};FCKSelection.HasAncestorNode=function(A){var B;if (FCK.EditorDocument.selection.type=="Control"){B=this.GetSelectedElement();}else{var C=FCK.EditorDocument.selection.createRange();B=C.parentElement();};while (B){if (B.tagName==A) return true;B=B.parentNode;};return false;};FCKSelection.MoveToAncestorNode=function(A){var B,oRange;if (!FCK.EditorDocument) return null;if (FCK.EditorDocument.selection.type=="Control"){oRange=FCK.EditorDocument.selection.createRange();for (i=0;i<oRange.length;i++){if (oRange(i).parentNode){B=oRange(i).parentNode;break;}}}else{oRange=FCK.EditorDocument.selection.createRange();B=oRange.parentElement();};while (B&&B.nodeName!=A) B=B.parentNode;return B;};FCKSelection.Delete=function(){var A=FCK.EditorDocument.selection;if (A.type.toLowerCase()!="none"){A.clear();};return A;};
+var FCKTableHandler={};FCKTableHandler.InsertRow=function(){var A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=A.cloneNode(true);A.parentNode.insertBefore(B,A);FCKTableHandler.ClearRow(A);};FCKTableHandler.DeleteRows=function(A){if (!A) A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');if (B.rows.length==1){FCKTableHandler.DeleteTable(B);return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteTable=function(A){if (!A){A=FCKSelection.GetSelectedElement();if (!A||A.tagName!='TABLE') A=FCKSelection.MoveToAncestorNode('TABLE');};if (!A) return;FCKSelection.SelectNode(A);FCKSelection.Collapse();A.parentNode.removeChild(A);};FCKTableHandler.InsertColumn=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex+1;for (var i=0;i<B.rows.length;i++){var D=B.rows[i];if (D.cells.length<C) continue;A=D.cells[C-1].cloneNode(false);if (FCKBrowserInfo.IsGecko) A.innerHTML=GECKO_BOGUS;var E=D.cells[C];if (E) D.insertBefore(A,E);else D.appendChild(A);}};FCKTableHandler.DeleteColumns=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex;for (var i=B.rows.length-1;i>=0;i--){var D=B.rows[i];if (C==0&&D.cells.length==1){FCKTableHandler.DeleteRows(D);continue;};if (D.cells[C]) D.removeChild(D.cells[C]);}};FCKTableHandler.InsertCell=function(A){var B=A?A:FCKSelection.MoveToAncestorNode('TD');if (!B) return null;var C=FCK.EditorDocument.createElement('TD');if (FCKBrowserInfo.IsGecko) C.innerHTML=GECKO_BOGUS;if (B.cellIndex==B.parentNode.cells.length-1){B.parentNode.appendChild(C);}else{B.parentNode.insertBefore(C,B.nextSibling);};return C;};FCKTableHandler.DeleteCell=function(A){if (A.parentNode.cells.length==1){FCKTableHandler.DeleteRows(FCKTools.GetElementAscensor(A,'TR'));return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteCells=function(){var A=FCKTableHandler.GetSelectedCells();for (var i=A.length-1;i>=0;i--){FCKTableHandler.DeleteCell(A[i]);}};FCKTableHandler.MergeCells=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length<2) return;if (A[0].parentNode!=A[A.length-1].parentNode) return;var B=isNaN(A[0].colSpan)?1:A[0].colSpan;var C='';var D=FCK.EditorDocument.createDocumentFragment();for (var i=A.length-1;i>=0;i--){var E=A[i];for (var c=E.childNodes.length-1;c>=0;c--){var F=E.removeChild(E.childNodes[c]);if ((F.hasAttribute&&F.hasAttribute('_moz_editor_bogus_node'))||(F.getAttribute&&F.getAttribute('type',2)=='_moz')) continue;D.insertBefore(F,D.firstChild);};if (i>0){B+=isNaN(E.colSpan)?1:E.colSpan;FCKTableHandler.DeleteCell(E);}};A[0].colSpan=B;if (FCKBrowserInfo.IsGecko&&D.childNodes.length==0) A[0].innerHTML=GECKO_BOGUS;else A[0].appendChild(D);};FCKTableHandler.SplitCell=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length!=1) return;var B=this._CreateTableMap(A[0].parentNode.parentNode);var C=FCKTableHandler._GetCellIndexSpan(B,A[0].parentNode.rowIndex,A[0]);var D=this._GetCollumnCells(B,C);for (var i=0;i<D.length;i++){if (D[i]==A[0]){var E=this.InsertCell(A[0]);if (!isNaN(A[0].rowSpan)&&A[0].rowSpan>1) E.rowSpan=A[0].rowSpan;}else{if (isNaN(D[i].colSpan)) D[i].colSpan=2;else D[i].colSpan+=1;}}};FCKTableHandler._GetCellIndexSpan=function(A,B,C){if (A.length<B+1) return null;var D=A[B];for (var c=0;c<D.length;c++){if (D[c]==C) return c;};return null;};FCKTableHandler._GetCollumnCells=function(A,B){var C=[];for (var r=0;r<A.length;r++){var D=A[r][B];if (D&&(C.length==0||C[C.length-1]!=D)) C[C.length]=D;};return C;};FCKTableHandler._CreateTableMap=function(A){var B=A.rows;var r=-1;var C=[];for (var i=0;i<B.length;i++){r++;if (!C[r]) C[r]=[];var c=-1;for (var j=0;j<B[i].cells.length;j++){var D=B[i].cells[j];c++;while (C[r][c]) c++;var E=isNaN(D.colSpan)?1:D.colSpan;var F=isNaN(D.rowSpan)?1:D.rowSpan;for (var G=0;G<F;G++){if (!C[r+G]) C[r+G]=[];for (var H=0;H<E;H++){C[r+G][c+H]=B[i].cells[j];}};c+=E-1;}};return C;};FCKTableHandler.ClearRow=function(A){var B=A.cells;for (var i=0;i<B.length;i++){if (FCKBrowserInfo.IsGecko) B[i].innerHTML=GECKO_BOGUS;else B[i].innerHTML='';}};
+FCKTableHandler.GetSelectedCells=function(){var A=[];var B=FCK.EditorDocument.selection.createRange();var C=FCKSelection.GetParentElement();if (C&&C.tagName.Equals('TD','TH')) A[0]=C;else{C=FCKSelection.MoveToAncestorNode('TABLE');if (C){for (var i=0;i<C.cells.length;i++){var D=FCK.EditorDocument.selection.createRange();D.moveToElementText(C.cells[i]);if (B.inRange(D)||(B.compareEndPoints('StartToStart',D)>=0&&B.compareEndPoints('StartToEnd',D)<=0)||(B.compareEndPoints('EndToStart',D)>=0&&B.compareEndPoints('EndToEnd',D)<=0)){A[A.length]=C.cells[i];}}}};return A;};
+var FCKXml=function(){this.Error=false;};FCKXml.prototype.LoadUrl=function(A){this.Error=false;var B=FCKTools.CreateXmlObject('XmlHttp');if (!B){this.Error=true;return;};B.open("GET",A,false);B.send(null);if (B.status==200||B.status==304) this.DOMDocument=B.responseXML;else if (B.status==0&&B.readyState==4){this.DOMDocument=FCKTools.CreateXmlObject('DOMDocument');this.DOMDocument.async=false;this.DOMDocument.resolveExternals=false;this.DOMDocument.loadXML(B.responseText);}else{this.DOMDocument=null;};if (this.DOMDocument==null||this.DOMDocument.firstChild==null){this.Error=true;if (window.confirm('Error loading "'+A+'"\r\nDo you want to see more info?')) alert('URL requested: "'+A+'"\r\nServer response:\r\nStatus: '+B.status+'\r\nResponse text:\r\n'+B.responseText);}};FCKXml.prototype.SelectNodes=function(A,B){if (this.Error) return [];if (B) return B.selectNodes(A);else return this.DOMDocument.selectNodes(A);};FCKXml.prototype.SelectSingleNode=function(A,B){if (this.Error) return null;if (B) return B.selectSingleNode(A);else return this.DOMDocument.selectSingleNode(A);}
+var FCKStyleDef=function(A,B){this.Name=A;this.Element=B.toUpperCase();this.IsObjectElement=FCKRegexLib.ObjectElements.test(this.Element);this.Attributes={};};FCKStyleDef.prototype.AddAttribute=function(A,B){this.Attributes[A]=B;};FCKStyleDef.prototype.GetOpenerTag=function(){var s='<'+this.Element;for (var a in this.Attributes) s+=' '+a+'="'+this.Attributes[a]+'"';return s+'>';};FCKStyleDef.prototype.GetCloserTag=function(){return '</'+this.Element+'>';};FCKStyleDef.prototype.RemoveFromSelection=function(){if (FCKSelection.GetType()=='Control') this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement());else this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetParentElement());}
+FCKStyleDef.prototype.ApplyToSelection=function(){var A=FCK.ToolbarSet.CurrentInstance.EditorDocument.selection;if (A.type=='Text'){var B=A.createRange();var e=document.createElement(this.Element);e.innerHTML=B.htmlText;this._AddAttributes(e);this._RemoveDuplicates(e);B.pasteHTML(e.outerHTML);}else if (A.type=='Control'){var C=FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement();if (C.tagName==this.Element) this._AddAttributes(C);}};FCKStyleDef.prototype._AddAttributes=function(A){for (var a in this.Attributes){switch (a.toLowerCase()){case 'style':A.style.cssText=this.Attributes[a];break;case 'class':A.setAttribute('className',this.Attributes[a],0);break;case 'src':A.setAttribute('_fcksavedurl',this.Attributes[a],0);default:A.setAttribute(a,this.Attributes[a],0);}}};FCKStyleDef.prototype._RemoveDuplicates=function(A){for (var i=0;i<A.children.length;i++){var B=A.children[i];this._RemoveDuplicates(B);if (this.IsEqual(B)) FCKTools.RemoveOuterTags(B);}};FCKStyleDef.prototype.IsEqual=function(e){if (e.tagName!=this.Element) return false;for (var a in this.Attributes){switch (a.toLowerCase()){case 'style':if (e.style.cssText.toLowerCase()!=this.Attributes[a].toLowerCase()) return false;break;case 'class':if (e.getAttribute('className',0)!=this.Attributes[a]) return false;break;default:if (e.getAttribute(a,0)!=this.Attributes[a]) return false;}};return true;};FCKStyleDef.prototype._RemoveMe=function(A){if (!A) return;var B=A.parentElement;if (this.IsEqual(A)){if (this.IsObjectElement){for (var a in this.Attributes){switch (a.toLowerCase()){case 'class':A.removeAttribute('className',0);break;default:A.removeAttribute(a,0);}};return;}else FCKTools.RemoveOuterTags(A);};this._RemoveMe(B);}
+var FCKStylesLoader=function(){this.Styles={};this.StyleGroups={};this.Loaded=false;this.HasObjectElements=false;};FCKStylesLoader.prototype.Load=function(A){var B=new FCKXml();B.LoadUrl(A);var C=B.SelectNodes('Styles/Style');for (var i=0;i<C.length;i++){var D=C[i].attributes.getNamedItem('element').value.toUpperCase();var E=new FCKStyleDef(C[i].attributes.getNamedItem('name').value,D);if (E.IsObjectElement) this.HasObjectElements=true;var F=B.SelectNodes('Attribute',C[i]);for (var j=0;j<F.length;j++){var G=F[j].attributes.getNamedItem('name').value;var H=F[j].attributes.getNamedItem('value').value;if (G.toLowerCase()=='style'){var I=document.createElement('SPAN');I.style.cssText=H;H=I.style.cssText;};E.AddAttribute(G,H);};this.Styles[E.Name]=E;var J=this.StyleGroups[D];if (J==null){this.StyleGroups[D]=[];J=this.StyleGroups[D];};J[J.length]=E;};this.Loaded=true;}
+var FCKNamedCommand=function(A){this.Name=A;};FCKNamedCommand.prototype.Execute=function(){FCK.ExecuteNamedCommand(this.Name);};FCKNamedCommand.prototype.GetState=function(){return FCK.GetNamedCommandState(this.Name);};
+var FCKDialogCommand=function(A,B,C,D,E,F,G){this.Name=A;this.Title=B;this.Url=C;this.Width=D;this.Height=E;this.GetStateFunction=F;this.GetStateParam=G;this.Resizable=false;};FCKDialogCommand.prototype.Execute=function(){FCKDialog.OpenDialog('FCKDialog_'+this.Name,this.Title,this.Url,this.Width,this.Height,null,null,this.Resizable);};FCKDialogCommand.prototype.GetState=function(){if (this.GetStateFunction) return this.GetStateFunction(this.GetStateParam);else return 0;};var FCKUndefinedCommand=function(){this.Name='Undefined';};FCKUndefinedCommand.prototype.Execute=function(){alert(FCKLang.NotImplemented);};FCKUndefinedCommand.prototype.GetState=function(){return 0;};var FCKFontNameCommand=function(){this.Name='FontName';};FCKFontNameCommand.prototype.Execute=function(A){if (A==null||A==""){}else FCK.ExecuteNamedCommand('FontName',A);};FCKFontNameCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontName');};var FCKFontSizeCommand=function(){this.Name='FontSize';};FCKFontSizeCommand.prototype.Execute=function(A){if (typeof(A)=='string') A=parseInt(A,10);if (A==null||A==''){FCK.ExecuteNamedCommand('FontSize',3);}else FCK.ExecuteNamedCommand('FontSize',A);};FCKFontSizeCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontSize');};var FCKFormatBlockCommand=function(){this.Name='FormatBlock';};FCKFormatBlockCommand.prototype.Execute=function(A){if (A==null||A=='') FCK.ExecuteNamedCommand('FormatBlock','<P>');else if (A=='div'&&FCKBrowserInfo.IsGecko) FCK.ExecuteNamedCommand('FormatBlock','div');else FCK.ExecuteNamedCommand('FormatBlock','<'+A+'>');};FCKFormatBlockCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FormatBlock');};var FCKPreviewCommand=function(){this.Name='Preview';};FCKPreviewCommand.prototype.Execute=function(){FCK.Preview();};FCKPreviewCommand.prototype.GetState=function(){return 0;};var FCKSaveCommand=function(){this.Name='Save';};FCKSaveCommand.prototype.Execute=function(){var A=FCK.GetParentForm();if (typeof(A.onsubmit)=='function'){var B=A.onsubmit();if (B!=null&&B===false) return;};A.submit();};FCKSaveCommand.prototype.GetState=function(){return 0;};var FCKNewPageCommand=function(){this.Name='NewPage';};FCKNewPageCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();FCK.SetHTML('');FCKUndo.Typing=true;};FCKNewPageCommand.prototype.GetState=function(){return 0;};var FCKSourceCommand=function(){this.Name='Source';};FCKSourceCommand.prototype.Execute=function(){if (FCKConfig.SourcePopup){var A=FCKConfig.ScreenWidth*0.65;var B=FCKConfig.ScreenHeight*0.65;FCKDialog.OpenDialog('FCKDialog_Source',FCKLang.Source,'dialog/fck_source.html',A,B,null,null,true);}else FCK.SwitchEditMode();};FCKSourceCommand.prototype.GetState=function(){return (FCK.EditMode==0?0:1);};var FCKUndoCommand=function(){this.Name='Undo';};FCKUndoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Undo();else FCK.ExecuteNamedCommand('Undo');};FCKUndoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckUndoState()?0:-1);else return FCK.GetNamedCommandState('Undo');};var FCKRedoCommand=function(){this.Name='Redo';};FCKRedoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Redo();else FCK.ExecuteNamedCommand('Redo');};FCKRedoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckRedoState()?0:-1);else return FCK.GetNamedCommandState('Redo');};var FCKPageBreakCommand=function(){this.Name='PageBreak';};FCKPageBreakCommand.prototype.Execute=function(){var e=FCK.EditorDocument.createElement('DIV');e.style.pageBreakAfter='always';e.innerHTML='<span style="DISPLAY:none">&nbsp;</span>';var A=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',e);A=FCK.InsertElement(A);};FCKPageBreakCommand.prototype.GetState=function(){return 0;};var FCKUnlinkCommand=function(){this.Name='Unlink';};FCKUnlinkCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsGecko){var A=FCK.Selection.MoveToAncestorNode('A');if (A) FCK.Selection.SelectNode(A);};FCK.ExecuteNamedCommand(this.Name);if (FCKBrowserInfo.IsGecko) FCK.Selection.Collapse(true);};FCKUnlinkCommand.prototype.GetState=function(){var A=FCK.GetNamedCommandState(this.Name);if (A==0&&FCK.EditMode==0){var B=FCKSelection.MoveToAncestorNode('A');var C=(B&&B.name.length>0&&B.href.length==0);if (C) A=-1;};return A;};var FCKSelectAllCommand=function(){this.Name='SelectAll';};FCKSelectAllCommand.prototype.Execute=function(){if (FCK.EditMode==0){FCK.ExecuteNamedCommand('SelectAll');}else{var A=FCK.EditingArea.Textarea;if (FCKBrowserInfo.IsIE){A.createTextRange().execCommand('SelectAll');}else{A.selectionStart=0;A.selectionEnd=A.value.length;};A.focus();}};FCKSelectAllCommand.prototype.GetState=function(){return 0;};var FCKPasteCommand=function(){this.Name='Paste';};FCKPasteCommand.prototype={Execute:function(){if (FCKBrowserInfo.IsIE) FCK.Paste();else FCK.ExecuteNamedCommand('Paste');},GetState:function(){return FCK.GetNamedCommandState('Paste');}};
+var FCKSpellCheckCommand=function(){this.Name='SpellCheck';this.IsEnabled=(FCKConfig.SpellChecker=='ieSpell'||FCKConfig.SpellChecker=='SpellerPages');};FCKSpellCheckCommand.prototype.Execute=function(){switch (FCKConfig.SpellChecker){case 'ieSpell':this._RunIeSpell();break;case 'SpellerPages':FCKDialog.OpenDialog('FCKDialog_SpellCheck','Spell Check','dialog/fck_spellerpages.html',440,480);break;}};FCKSpellCheckCommand.prototype._RunIeSpell=function(){try{var A=new ActiveXObject("ieSpell.ieSpellExtension");A.CheckAllLinkedDocuments(FCK.EditorDocument);}catch(e){if(e.number==-2146827859){if (confirm(FCKLang.IeSpellDownload)) window.open(FCKConfig.IeSpellDownloadUrl,'IeSpellDownload');}else alert('Error Loading ieSpell: '+e.message+' ('+e.number+')');}};FCKSpellCheckCommand.prototype.GetState=function(){return this.IsEnabled?0:-1;}
+var FCKTextColorCommand=function(A){this.Name=A=='ForeColor'?'TextColor':'BGColor';this.Type=A;var B;if (FCKBrowserInfo.IsIE) B=window;else if (FCK.ToolbarSet._IFrame) B=FCKTools.GetElementWindow(FCK.ToolbarSet._IFrame);else B=window.parent;this._Panel=new FCKPanel(B,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._Panel.MainNode.className='FCK_Panel';this._CreatePanelBody(this._Panel.Document,this._Panel.MainNode);FCKTools.DisableSelection(this._Panel.Document.body);};FCKTextColorCommand.prototype.Execute=function(A,B,C){FCK._ActiveColorPanelType=this.Type;this._Panel.Show(A,B,C);};FCKTextColorCommand.prototype.SetColor=function(A){if (FCK._ActiveColorPanelType=='ForeColor') FCK.ExecuteNamedCommand('ForeColor',A);else if (FCKBrowserInfo.IsGeckoLike){if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,false);FCK.ExecuteNamedCommand('hilitecolor',A);if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,true);}else FCK.ExecuteNamedCommand('BackColor',A);delete FCK._ActiveColorPanelType;};FCKTextColorCommand.prototype.GetState=function(){return 0;};function FCKTextColorCommand_OnMouseOver()	{ this.className='ColorSelected';};function FCKTextColorCommand_OnMouseOut()	{ this.className='ColorDeselected';};function FCKTextColorCommand_OnClick(){this.className='ColorDeselected';this.Command.SetColor('#'+this.Color);this.Command._Panel.Hide();};function FCKTextColorCommand_AutoOnClick(){this.className='ColorDeselected';this.Command.SetColor('');this.Command._Panel.Hide();};function FCKTextColorCommand_MoreOnClick(){this.className='ColorDeselected';this.Command._Panel.Hide();FCKDialog.OpenDialog('FCKDialog_Color',FCKLang.DlgColorTitle,'dialog/fck_colorselector.html',400,330,this.Command.SetColor);};FCKTextColorCommand.prototype._CreatePanelBody=function(A,B){function CreateSelectionDiv(){var C=A.createElement("DIV");C.className='ColorDeselected';C.onmouseover=FCKTextColorCommand_OnMouseOver;C.onmouseout=FCKTextColorCommand_OnMouseOut;return C;};var D=B.appendChild(A.createElement("TABLE"));D.className='ForceBaseFont';D.style.tableLayout='fixed';D.cellPadding=0;D.cellSpacing=0;D.border=0;D.width=150;var E=D.insertRow(-1).insertCell(-1);E.colSpan=8;var C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table cellspacing="0" cellpadding="0" width="100%" border="0">\n			<tr>\n				<td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\n				<td nowrap width="100%" align="center">'+FCKLang.ColorAutomatic+'</td>\n			</tr>\n		</table>';C.Command=this;C.onclick=FCKTextColorCommand_AutoOnClick;var G=FCKConfig.FontColors.toString().split(',');var H=0;while (H<G.length){var I=D.insertRow(-1);for (var i=0;i<8&&H<G.length;i++,H++){C=I.insertCell(-1).appendChild(CreateSelectionDiv());C.Color=G[H];C.innerHTML='<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #'+G[H]+'"></div></div>';C.Command=this;C.onclick=FCKTextColorCommand_OnClick;}};E=D.insertRow(-1).insertCell(-1);E.colSpan=8;C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">'+FCKLang.ColorMoreColors+'</td></tr></table>';C.Command=this;C.onclick=FCKTextColorCommand_MoreOnClick;}
+var FCKPastePlainTextCommand=function(){this.Name='PasteText';};FCKPastePlainTextCommand.prototype.Execute=function(){FCK.PasteAsPlainText();};FCKPastePlainTextCommand.prototype.GetState=function(){return FCK.GetNamedCommandState('Paste');};
+var FCKPasteWordCommand=function(){this.Name='PasteWord';};FCKPasteWordCommand.prototype.Execute=function(){FCK.PasteFromWord();};FCKPasteWordCommand.prototype.GetState=function(){if (FCKConfig.ForcePasteAsPlainText) return -1;else return FCK.GetNamedCommandState('Paste');};
+var FCKTableCommand=function(A){this.Name=A;};FCKTableCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();switch (this.Name){case 'TableInsertRow':FCKTableHandler.InsertRow();break;case 'TableDeleteRows':FCKTableHandler.DeleteRows();break;case 'TableInsertColumn':FCKTableHandler.InsertColumn();break;case 'TableDeleteColumns':FCKTableHandler.DeleteColumns();break;case 'TableInsertCell':FCKTableHandler.InsertCell();break;case 'TableDeleteCells':FCKTableHandler.DeleteCells();break;case 'TableMergeCells':FCKTableHandler.MergeCells();break;case 'TableSplitCell':FCKTableHandler.SplitCell();break;case 'TableDelete':FCKTableHandler.DeleteTable();break;default:alert(FCKLang.UnknownCommand.replace(/%1/g,this.Name));}};FCKTableCommand.prototype.GetState=function(){return 0;}
+var FCKStyleCommand=function(){this.Name='Style';this.StylesLoader=new FCKStylesLoader();this.StylesLoader.Load(FCKConfig.StylesXmlPath);this.Styles=this.StylesLoader.Styles;};FCKStyleCommand.prototype.Execute=function(A,B){FCKUndo.SaveUndoStep();if (B.Selected) B.Style.RemoveFromSelection();else B.Style.ApplyToSelection();FCKUndo.SaveUndoStep();FCK.Focus();FCK.Events.FireEvent("OnSelectionChange");};FCKStyleCommand.prototype.GetState=function(){if (!FCK.EditorDocument) return -1;var A=FCK.EditorDocument.selection;if (FCKSelection.GetType()=='Control'){var e=FCKSelection.GetSelectedElement();if (e) return this.StylesLoader.StyleGroups[e.tagName]?0:-1;};return 0;};FCKStyleCommand.prototype.GetActiveStyles=function(){var A=[];if (FCKSelection.GetType()=='Control') this._CheckStyle(FCKSelection.GetSelectedElement(),A,false);else this._CheckStyle(FCKSelection.GetParentElement(),A,true);return A;};FCKStyleCommand.prototype._CheckStyle=function(A,B,C){if (!A) return;if (A.nodeType==1){var D=this.StylesLoader.StyleGroups[A.tagName];if (D){for (var i=0;i<D.length;i++){if (D[i].IsEqual(A)) B[B.length]=D[i];}}};if (C) this._CheckStyle(A.parentNode,B,C);}
+var FCKFitWindow=function(){this.Name='FitWindow';};FCKFitWindow.prototype.Execute=function(){var A=window.frameElement;var B=A.style;var C=parent;var D=C.document.documentElement;var E=C.document.body;var F=E.style;var G;if (!this.IsMaximized){if(FCKBrowserInfo.IsIE) C.attachEvent('onresize',FCKFitWindow_Resize);else C.addEventListener('resize',FCKFitWindow_Resize,true);this._ScrollPos=FCKTools.GetScrollPosition(C);G=A;while((G=G.parentNode)){if (G.nodeType==1) G._fckSavedStyles=FCKTools.SaveStyles(G);};if (FCKBrowserInfo.IsIE){this.documentElementOverflow=D.style.overflow;D.style.overflow='hidden';F.overflow='hidden';}else{F.overflow='hidden';F.width='0px';F.height='0px';};this._EditorFrameStyles=FCKTools.SaveStyles(A);var H=FCKTools.GetViewPaneSize(C);B.position="absolute";B.zIndex=FCKConfig.FloatingPanelsZIndex-1;B.left="0px";B.top="0px";B.width=H.Width+"px";B.height=H.Height+"px";if (!FCKBrowserInfo.IsIE){B.borderRight=B.borderBottom="9999px solid white";B.backgroundColor="white";};C.scrollTo(0,0);this.IsMaximized=true;}else{if(FCKBrowserInfo.IsIE) C.detachEvent("onresize",FCKFitWindow_Resize);else C.removeEventListener("resize",FCKFitWindow_Resize,true);G=A;while((G=G.parentNode)){if (G._fckSavedStyles){FCKTools.RestoreStyles(G,G._fckSavedStyles);G._fckSavedStyles=null;}};if (FCKBrowserInfo.IsIE) D.style.overflow=this.documentElementOverflow;FCKTools.RestoreStyles(A,this._EditorFrameStyles);C.scrollTo(this._ScrollPos.X,this._ScrollPos.Y);this.IsMaximized=false;};FCKToolbarItems.GetItem('FitWindow').RefreshState();FCK.EditingArea.MakeEditable();FCK.Focus();};FCKFitWindow.prototype.GetState=function(){if (FCKConfig.ToolbarLocation!='In') return -1;else return (this.IsMaximized?1:0);};function FCKFitWindow_Resize(){var A=FCKTools.GetViewPaneSize(parent);var B=window.frameElement.style;B.width=A.Width+'px';B.height=A.Height+'px';};
+var FCKCommands=FCK.Commands={};FCKCommands.LoadedCommands={};FCKCommands.RegisterCommand=function(A,B){this.LoadedCommands[A]=B;};FCKCommands.GetCommand=function(A){var B=FCKCommands.LoadedCommands[A];if (B) return B;switch (A){case 'DocProps':B=new FCKDialogCommand('DocProps',FCKLang.DocProps,'dialog/fck_docprops.html',400,390,FCKCommands.GetFullPageState);break;case 'Templates':B=new FCKDialogCommand('Templates',FCKLang.DlgTemplatesTitle,'dialog/fck_template.html',380,450);break;case 'Link':B=new FCKDialogCommand('Link',FCKLang.DlgLnkWindowTitle,'dialog/fck_link.html',400,330);break;case 'Unlink':B=new FCKUnlinkCommand();break;case 'Anchor':B=new FCKDialogCommand('Anchor',FCKLang.DlgAnchorTitle,'dialog/fck_anchor.html',370,170);break;case 'BulletedList':B=new FCKDialogCommand('BulletedList',FCKLang.BulletedListProp,'dialog/fck_listprop.html?UL',370,170);break;case 'NumberedList':B=new FCKDialogCommand('NumberedList',FCKLang.NumberedListProp,'dialog/fck_listprop.html?OL',370,170);break;case 'About':B=new FCKDialogCommand('About',FCKLang.About,'dialog/fck_about.html',400,330);break;case 'Find':B=new FCKDialogCommand('Find',FCKLang.DlgFindTitle,'dialog/fck_find.html',340,170);break;case 'Replace':B=new FCKDialogCommand('Replace',FCKLang.DlgReplaceTitle,'dialog/fck_replace.html',340,200);break;case 'Image':B=new FCKDialogCommand('Image',FCKLang.DlgImgTitle,'dialog/fck_image.html',450,400);break;case 'Flash':B=new FCKDialogCommand('Flash',FCKLang.DlgFlashTitle,'dialog/fck_flash.html',450,400);break;case 'SpecialChar':B=new FCKDialogCommand('SpecialChar',FCKLang.DlgSpecialCharTitle,'dialog/fck_specialchar.html',400,320);break;case 'Smiley':B=new FCKDialogCommand('Smiley',FCKLang.DlgSmileyTitle,'dialog/fck_smiley.html',FCKConfig.SmileyWindowWidth,FCKConfig.SmileyWindowHeight);break;case 'Table':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html',450,250);break;case 'TableProp':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html?Parent',400,250);break;case 'TableCellProp':B=new FCKDialogCommand('TableCell',FCKLang.DlgCellTitle,'dialog/fck_tablecell.html',550,250);break;case 'Style':B=new FCKStyleCommand();break;case 'FontName':B=new FCKFontNameCommand();break;case 'FontSize':B=new FCKFontSizeCommand();break;case 'FontFormat':B=new FCKFormatBlockCommand();break;case 'Source':B=new FCKSourceCommand();break;case 'Preview':B=new FCKPreviewCommand();break;case 'Save':B=new FCKSaveCommand();break;case 'NewPage':B=new FCKNewPageCommand();break;case 'PageBreak':B=new FCKPageBreakCommand();break;case 'TextColor':B=new FCKTextColorCommand('ForeColor');break;case 'BGColor':B=new FCKTextColorCommand('BackColor');break;case 'Paste':B=new FCKPasteCommand();break;case 'PasteText':B=new FCKPastePlainTextCommand();break;case 'PasteWord':B=new FCKPasteWordCommand();break;case 'TableInsertRow':B=new FCKTableCommand('TableInsertRow');break;case 'TableDeleteRows':B=new FCKTableCommand('TableDeleteRows');break;case 'TableInsertColumn':B=new FCKTableCommand('TableInsertColumn');break;case 'TableDeleteColumns':B=new FCKTableCommand('TableDeleteColumns');break;case 'TableInsertCell':B=new FCKTableCommand('TableInsertCell');break;case 'TableDeleteCells':B=new FCKTableCommand('TableDeleteCells');break;case 'TableMergeCells':B=new FCKTableCommand('TableMergeCells');break;case 'TableSplitCell':B=new FCKTableCommand('TableSplitCell');break;case 'TableDelete':B=new FCKTableCommand('TableDelete');break;case 'Form':B=new FCKDialogCommand('Form',FCKLang.Form,'dialog/fck_form.html',380,230);break;case 'Checkbox':B=new FCKDialogCommand('Checkbox',FCKLang.Checkbox,'dialog/fck_checkbox.html',380,230);break;case 'Radio':B=new FCKDialogCommand('Radio',FCKLang.RadioButton,'dialog/fck_radiobutton.html',380,230);break;case 'TextField':B=new FCKDialogCommand('TextField',FCKLang.TextField,'dialog/fck_textfield.html',380,230);break;case 'Textarea':B=new FCKDialogCommand('Textarea',FCKLang.Textarea,'dialog/fck_textarea.html',380,230);break;case 'HiddenField':B=new FCKDialogCommand('HiddenField',FCKLang.HiddenField,'dialog/fck_hiddenfield.html',380,230);break;case 'Button':B=new FCKDialogCommand('Button',FCKLang.Button,'dialog/fck_button.html',380,230);break;case 'Select':B=new FCKDialogCommand('Select',FCKLang.SelectionField,'dialog/fck_select.html',400,380);break;case 'ImageButton':B=new FCKDialogCommand('ImageButton',FCKLang.ImageButton,'dialog/fck_image.html?ImageButton',450,400);break;case 'SpellCheck':B=new FCKSpellCheckCommand();break;case 'FitWindow':B=new FCKFitWindow();break;case 'Undo':B=new FCKUndoCommand();break;case 'Redo':B=new FCKRedoCommand();break;case 'SelectAll':B=new FCKSelectAllCommand();break;case 'Undefined':B=new FCKUndefinedCommand();break;default:if (FCKRegexLib.NamedCommands.test(A)) B=new FCKNamedCommand(A);else{alert(FCKLang.UnknownCommand.replace(/%1/g,A));return null;}};FCKCommands.LoadedCommands[A]=B;return B;};FCKCommands.GetFullPageState=function(){return FCKConfig.FullPage?0:-1;};
+var FCKPanel=function(A){this.IsRTL=(FCKLang.Dir=='rtl');this.IsContextMenu=false;this._LockCounter=0;this._Window=A||window;var B;if (FCKBrowserInfo.IsIE){this._Popup=this._Window.createPopup();B=this.Document=this._Popup.document;FCK.IECleanup.AddItem(this,FCKPanel_Cleanup);}else{var C=this._IFrame=this._Window.document.createElement('iframe');C.src='javascript:void(0)';C.allowTransparency=true;C.frameBorder='0';C.scrolling='no';C.style.position='absolute';C.style.zIndex=FCKConfig.FloatingPanelsZIndex;C.width=C.height=0;if (this._Window==window.parent&&window.frameElement) window.frameElement.parentNode.insertBefore(C,window.frameElement);else this._Window.document.body.appendChild(C);var D=C.contentWindow;B=this.Document=D.document;B.open();B.write('<html><head></head><body style="margin:0px;padding:0px;"><\/body><\/html>');B.close();FCKTools.AddEventListenerEx(D,'focus',FCKPanel_Window_OnFocus,this);FCKTools.AddEventListenerEx(D,'blur',FCKPanel_Window_OnBlur,this);};B.dir=FCKLang.Dir;B.oncontextmenu=FCKTools.CancelEvent;this.MainNode=B.body.appendChild(B.createElement('DIV'));this.MainNode.style.cssFloat=this.IsRTL?'right':'left';};FCKPanel.prototype.AppendStyleSheet=function(A){FCKTools.AppendStyleSheet(this.Document,A);};FCKPanel.prototype.Preload=function(x,y,A){if (this._Popup) this._Popup.show(x,y,0,0,A);};FCKPanel.prototype.Show=function(x,y,A,B,C){var D;if (this._Popup){this._Popup.show(x,y,0,0,A);this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=(x*-1)+A.offsetWidth-D;};this._Popup.show(x,y,D,this.MainNode.offsetHeight,A);if (this.OnHide){if (this._Timer) CheckPopupOnHide.call(this,true);this._Timer=FCKTools.SetInterval(CheckPopupOnHide,100,this);}}else{if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Lock();if (this.ParentPanel) this.ParentPanel.Lock();this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (!B)	this._IFrame.width=1;if (!C)	this._IFrame.height=1;D=this.MainNode.offsetWidth;var E=FCKTools.GetElementPosition(A.nodeType==9?(FCKTools.IsStrictMode(A)?A.documentElement:A.body):A,this._Window);if (this.IsRTL&&!this.IsContextMenu) x=(x*-1);x+=E.X;y+=E.Y;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=x+A.offsetWidth-D;}else{var F=FCKTools.GetViewPaneSize(this._Window);var G=FCKTools.GetScrollPosition(this._Window);var H=F.Height+G.Y;var I=F.Width+G.X;if ((x+D)>I) x-=x+D-I;if ((y+this.MainNode.offsetHeight)>H) y-=y+this.MainNode.offsetHeight-H;};if (x<0) x=0;this._IFrame.style.left=x+'px';this._IFrame.style.top=y+'px';var J=D;var K=this.MainNode.offsetHeight;this._IFrame.width=J;this._IFrame.height=K;this._IFrame.contentWindow.focus();};this._IsOpened=true;FCKTools.RunFunction(this.OnShow,this);};FCKPanel.prototype.Hide=function(A){if (this._Popup) this._Popup.hide();else{if (!this._IsOpened) return;if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Unlock();this._IFrame.width=this._IFrame.height=0;this._IsOpened=false;if (this.ParentPanel) this.ParentPanel.Unlock();if (!A) FCKTools.RunFunction(this.OnHide,this);}};FCKPanel.prototype.CheckIsOpened=function(){if (this._Popup) return this._Popup.isOpen;else return this._IsOpened;};FCKPanel.prototype.CreateChildPanel=function(){var A=this._Popup?FCKTools.GetDocumentWindow(this.Document):this._Window;var B=new FCKPanel(A,true);B.ParentPanel=this;return B;};FCKPanel.prototype.Lock=function(){this._LockCounter++;};FCKPanel.prototype.Unlock=function(){if (--this._LockCounter==0&&!this.HasFocus) this.Hide();};function FCKPanel_Window_OnFocus(e,A){A.HasFocus=true;};function FCKPanel_Window_OnBlur(e,A){A.HasFocus=false;if (A._LockCounter==0) FCKTools.RunFunction(A.Hide,A);};function CheckPopupOnHide(A){if (A||!this._Popup.isOpen){window.clearInterval(this._Timer);this._Timer=null;FCKTools.RunFunction(this.OnHide,this);}};function FCKPanel_Cleanup(){this._Popup=null;this._Window=null;this.Document=null;this.MainNode=null;}
+var FCKIcon=function(A){var B=A?typeof(A):'undefined';switch (B){case 'number':this.Path=FCKConfig.SkinPath+'fck_strip.gif';this.Size=16;this.Position=A;break;case 'undefined':this.Path=FCK_SPACER_PATH;break;case 'string':this.Path=A;break;default:this.Path=A[0];this.Size=A[1];this.Position=A[2];}};FCKIcon.prototype.CreateIconElement=function(A){var B,eIconImage;if (this.Position){var C='-'+((this.Position-1)*this.Size)+'px';if (FCKBrowserInfo.IsIE){B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path;eIconImage.style.top=C;}else{B=A.createElement('IMG');B.src=FCK_SPACER_PATH;B.style.backgroundPosition='0px '+C;B.style.backgroundImage='url('+this.Path+')';}}else{B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path?this.Path:FCK_SPACER_PATH;};B.className='TB_Button_Image';return B;}
+var FCKToolbarButtonUI=function(A,B,C,D,E,F){this.Name=A;this.Label=B||A;this.Tooltip=C||this.Label;this.Style=E||0;this.State=F||0;this.Icon=new FCKIcon(D);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarButtonUI_Cleanup);};FCKToolbarButtonUI.prototype._CreatePaddingElement=function(A){var B=A.createElement('IMG');B.className='TB_Button_Padding';B.src=FCK_SPACER_PATH;return B;};FCKToolbarButtonUI.prototype.Create=function(A){var B=this.MainElement;if (B){FCKToolbarButtonUI_Cleanup.call(this);if (B.parentNode) B.parentNode.removeChild(B);B=this.MainElement=null;};var C=FCKTools.GetElementDocument(A);B=this.MainElement=C.createElement('DIV');B._FCKButton=this;B.title=this.Tooltip;if (FCKBrowserInfo.IsGecko) B.onmousedown=FCKTools.CancelEvent;this.ChangeState(this.State,true);if (this.Style==0&&!this.ShowArrow){B.appendChild(this.Icon.CreateIconElement(C));}else{var D=B.appendChild(C.createElement('TABLE'));D.cellPadding=0;D.cellSpacing=0;var E=D.insertRow(-1);var F=E.insertCell(-1);if (this.Style==0||this.Style==2) F.appendChild(this.Icon.CreateIconElement(C));else F.appendChild(this._CreatePaddingElement(C));if (this.Style==1||this.Style==2){F=E.insertCell(-1);F.className='TB_Button_Text';F.noWrap=true;F.appendChild(C.createTextNode(this.Label));};if (this.ShowArrow){if (this.Style!=0){E.insertCell(-1).appendChild(this._CreatePaddingElement(C));};F=E.insertCell(-1);var G=F.appendChild(C.createElement('IMG'));G.src=FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif';G.width=5;G.height=3;};F=E.insertCell(-1);F.appendChild(this._CreatePaddingElement(C));};A.appendChild(B);};FCKToolbarButtonUI.prototype.ChangeState=function(A,B){if (!B&&this.State==A) return;var e=this.MainElement;switch (parseInt(A,10)){case 0:e.className='TB_Button_Off';e.onmouseover=FCKToolbarButton_OnMouseOverOff;e.onmouseout=FCKToolbarButton_OnMouseOutOff;e.onclick=FCKToolbarButton_OnClick;break;case 1:e.className='TB_Button_On';e.onmouseover=FCKToolbarButton_OnMouseOverOn;e.onmouseout=FCKToolbarButton_OnMouseOutOn;e.onclick=FCKToolbarButton_OnClick;break;case -1:e.className='TB_Button_Disabled';e.onmouseover=null;e.onmouseout=null;e.onclick=null;break;};this.State=A;};function FCKToolbarButtonUI_Cleanup(){if (this.MainElement){this.MainElement._FCKButton=null;this.MainElement=null;}};function FCKToolbarButton_OnMouseOverOn(){this.className='TB_Button_On_Over';};function FCKToolbarButton_OnMouseOutOn(){this.className='TB_Button_On';};function FCKToolbarButton_OnMouseOverOff(){this.className='TB_Button_Off_Over';};function FCKToolbarButton_OnMouseOutOff(){this.className='TB_Button_Off';};function FCKToolbarButton_OnClick(e){if (this._FCKButton.OnClick) this._FCKButton.OnClick(this._FCKButton);};
+var FCKToolbarButton=function(A,B,C,D,E,F,G){this.CommandName=A;this.Label=B;this.Tooltip=C;this.Style=D;this.SourceView=E?true:false;this.ContextSensitive=F?true:false;if (G==null) this.IconPath=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(G)=='number') this.IconPath=[FCKConfig.SkinPath+'fck_strip.gif',16,G];};FCKToolbarButton.prototype.Create=function(A){this._UIButton=new FCKToolbarButtonUI(this.CommandName,this.Label,this.Tooltip,this.IconPath,this.Style);this._UIButton.OnClick=this.Click;this._UIButton._ToolbarButton=this;this._UIButton.Create(A);};FCKToolbarButton.prototype.RefreshState=function(){var A=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (A==this._UIButton.State) return;this._UIButton.ChangeState(A);};FCKToolbarButton.prototype.Click=function(){var A=this._ToolbarButton||this;FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(A.CommandName).Execute();};FCKToolbarButton.prototype.Enable=function(){this.RefreshState();};FCKToolbarButton.prototype.Disable=function(){this._UIButton.ChangeState(-1);}
+var FCKSpecialCombo=function(A,B,C,D,E){this.FieldWidth=B||100;this.PanelWidth=C||150;this.PanelMaxHeight=D||150;this.Label='&nbsp;';this.Caption=A;this.Tooltip=A;this.Style=2;this.Enabled=true;this.Items={};this._Panel=new FCKPanel(E||window,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._PanelBox=this._Panel.MainNode.appendChild(this._Panel.Document.createElement('DIV'));this._PanelBox.className='SC_Panel';this._PanelBox.style.width=this.PanelWidth+'px';this._PanelBox.innerHTML='<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>';this._ItemsHolderEl=this._PanelBox.getElementsByTagName('TD')[0];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKSpecialCombo_Cleanup);};function FCKSpecialCombo_ItemOnMouseOver(){this.className+=' SC_ItemOver';};function FCKSpecialCombo_ItemOnMouseOut(){this.className=this.originalClass;};function FCKSpecialCombo_ItemOnClick(){this.className=this.originalClass;this.FCKSpecialCombo._Panel.Hide();this.FCKSpecialCombo.SetLabel(this.FCKItemLabel);if (typeof(this.FCKSpecialCombo.OnSelect)=='function') this.FCKSpecialCombo.OnSelect(this.FCKItemID,this);};FCKSpecialCombo.prototype.AddItem=function(A,B,C,D){var E=this._ItemsHolderEl.appendChild(this._Panel.Document.createElement('DIV'));E.className=E.originalClass='SC_Item';E.innerHTML=B;E.FCKItemID=A;E.FCKItemLabel=C||A;E.FCKSpecialCombo=this;E.Selected=false;if (FCKBrowserInfo.IsIE) E.style.width='100%';if (D) E.style.backgroundColor=D;E.onmouseover=FCKSpecialCombo_ItemOnMouseOver;E.onmouseout=FCKSpecialCombo_ItemOnMouseOut;E.onclick=FCKSpecialCombo_ItemOnClick;this.Items[A.toString().toLowerCase()]=E;return E;};FCKSpecialCombo.prototype.SelectItem=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];if (B){B.className=B.originalClass='SC_ItemSelected';B.Selected=true;}};FCKSpecialCombo.prototype.SelectItemByLabel=function(A,B){for (var C in this.Items){var D=this.Items[C];if (D.FCKItemLabel==A){D.className=D.originalClass='SC_ItemSelected';D.Selected=true;if (B) this.SetLabel(A);}}};FCKSpecialCombo.prototype.DeselectAll=function(A){for (var i in this.Items){this.Items[i].className=this.Items[i].originalClass='SC_Item';this.Items[i].Selected=false;};if (A) this.SetLabel('');};FCKSpecialCombo.prototype.SetLabelById=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];this.SetLabel(B?B.FCKItemLabel:'');};FCKSpecialCombo.prototype.SetLabel=function(A){this.Label=A.length==0?'&nbsp;':A;if (this._LabelEl){this._LabelEl.innerHTML=this.Label;FCKTools.DisableSelection(this._LabelEl);}};FCKSpecialCombo.prototype.SetEnabled=function(A){this.Enabled=A;this._OuterTable.className=A?'':'SC_FieldDisabled';};FCKSpecialCombo.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var C=this._OuterTable=A.appendChild(B.createElement('TABLE'));C.cellPadding=0;C.cellSpacing=0;C.insertRow(-1);var D;var E;switch (this.Style){case 0:D='TB_ButtonType_Icon';E=false;break;case 1:D='TB_ButtonType_Text';E=false;break;case 2:E=true;break;};if (this.Caption&&this.Caption.length>0&&E){var F=C.rows[0].insertCell(-1);F.innerHTML=this.Caption;F.className='SC_FieldCaption';};var G=FCKTools.AppendElement(C.rows[0].insertCell(-1),'div');if (E){G.className='SC_Field';G.style.width=this.FieldWidth+'px';G.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label>&nbsp;</label></td><td class="SC_FieldButton">&nbsp;</td></tr></tbody></table>';this._LabelEl=G.getElementsByTagName('label')[0];this._LabelEl.innerHTML=this.Label;}else{G.className='TB_Button_Off';G.innerHTML='<table title="'+this.Tooltip+'" class="'+D+'" cellspacing="0" cellpadding="0" border="0"><tr><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_Text">'+this.Caption+'</td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_ButtonArrow"><img src="'+FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif" width="5" height="3"></td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td></tr></table>';};G.SpecialCombo=this;G.onmouseover=FCKSpecialCombo_OnMouseOver;G.onmouseout=FCKSpecialCombo_OnMouseOut;G.onclick=FCKSpecialCombo_OnClick;FCKTools.DisableSelection(this._Panel.Document.body);};function FCKSpecialCombo_Cleanup(){this._LabelEl=null;this._OuterTable=null;this._ItemsHolderEl=null;this._PanelBox=null;if (this.Items){for (var A in this.Items) this.Items[A]=null;}};function FCKSpecialCombo_OnMouseOver(){if (this.SpecialCombo.Enabled){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_On_Over';break;case 1:this.className='TB_Button_On_Over';break;case 2:this.className='SC_Field SC_FieldOver';break;}}};function FCKSpecialCombo_OnMouseOut(){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_Off';break;case 1:this.className='TB_Button_Off';break;case 2:this.className='SC_Field';break;}};function FCKSpecialCombo_OnClick(e){var A=this.SpecialCombo;if (A.Enabled){var B=A._Panel;var C=A._PanelBox;var D=A._ItemsHolderEl;var E=A.PanelMaxHeight;if (A.OnBeforeClick) A.OnBeforeClick(A);if (FCKBrowserInfo.IsIE) B.Preload(0,this.offsetHeight,this);if (D.offsetHeight>E) C.style.height=E+'px';else C.style.height='';B.Show(0,this.offsetHeight,this);}};
+var FCKToolbarSpecialCombo=function(){this.SourceView=false;this.ContextSensitive=true;this._LastValue=null;};function FCKToolbarSpecialCombo_OnSelect(A,B){FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Execute(A,B);};FCKToolbarSpecialCombo.prototype.Create=function(A){this._Combo=new FCKSpecialCombo(this.GetLabel(),this.FieldWidth,this.PanelWidth,this.PanelMaxHeight,FCKBrowserInfo.IsIE?window:FCKTools.GetElementWindow(A).parent);this._Combo.Tooltip=this.Tooltip;this._Combo.Style=this.Style;this.CreateItems(this._Combo);this._Combo.Create(A);this._Combo.CommandName=this.CommandName;this._Combo.OnSelect=FCKToolbarSpecialCombo_OnSelect;};function FCKToolbarSpecialCombo_RefreshActiveItems(A,B){A.DeselectAll();A.SelectItem(B);A.SetLabelById(B);};FCKToolbarSpecialCombo.prototype.RefreshState=function(){var A;var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (B!=-1){A=1;if (this.RefreshActiveItems) this.RefreshActiveItems(this._Combo,B);else{if (this._LastValue!=B){this._LastValue=B;FCKToolbarSpecialCombo_RefreshActiveItems(this._Combo,B);}}}else A=-1;if (A==this.State) return;if (A==-1){this._Combo.DeselectAll();this._Combo.SetLabel('');};this.State=A;this._Combo.SetEnabled(A!=-1);};FCKToolbarSpecialCombo.prototype.Enable=function(){this.RefreshState();};FCKToolbarSpecialCombo.prototype.Disable=function(){this.State=-1;this._Combo.DeselectAll();this._Combo.SetLabel('');this._Combo.SetEnabled(false);};
+var FCKToolbarFontsCombo=function(A,B){this.CommandName='FontName';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontsCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontsCombo.prototype.GetLabel=function(){return FCKLang.Font;};FCKToolbarFontsCombo.prototype.CreateItems=function(A){var B=FCKConfig.FontNames.split(';');for (var i=0;i<B.length;i++) this._Combo.AddItem(B[i],'<font face="'+B[i]+'" style="font-size: 12px">'+B[i]+'</font>');}
+var FCKToolbarFontSizeCombo=function(A,B){this.CommandName='FontSize';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontSizeCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontSizeCombo.prototype.GetLabel=function(){return FCKLang.FontSize;};FCKToolbarFontSizeCombo.prototype.CreateItems=function(A){A.FieldWidth=70;var B=FCKConfig.FontSizes.split(';');for (var i=0;i<B.length;i++){var C=B[i].split('/');this._Combo.AddItem(C[0],'<font size="'+C[0]+'">'+C[1]+'</font>',C[1]);}}
+var FCKToolbarFontFormatCombo=function(A,B){this.CommandName='FontFormat';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;this.NormalLabel='Normal';this.PanelWidth=190;};FCKToolbarFontFormatCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontFormatCombo.prototype.GetLabel=function(){return FCKLang.FontFormat;};FCKToolbarFontFormatCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;var C=FCKLang['FontFormats'].split(';');var D={p:C[0],pre:C[1],address:C[2],h1:C[3],h2:C[4],h3:C[5],h4:C[6],h5:C[7],h6:C[8],div:C[9]};var E=FCKConfig.FontFormats.split(';');for (var i=0;i<E.length;i++){var F=E[i];var G=D[F];if (F=='p') this.NormalLabel=G;this._Combo.AddItem(F,'<div class="BaseFont"><'+F+'>'+G+'</'+F+'></div>',G);}};if (FCKBrowserInfo.IsIE){FCKToolbarFontFormatCombo.prototype.RefreshActiveItems=function(A,B){if (B==this.NormalLabel){if (A.Label!='&nbsp;') A.DeselectAll(true);}else{if (this._LastValue==B) return;A.SelectItemByLabel(B,true);};this._LastValue=B;}}
+var FCKToolbarStyleCombo=function(A,B){this.CommandName='Style';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarStyleCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarStyleCombo.prototype.GetLabel=function(){return FCKLang.Style;};FCKToolbarStyleCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);B.body.className+=' ForceBaseFont';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;if (!(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsGecko10)) A.OnBeforeClick=this.RefreshVisibleItems;var C=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Styles;for (var s in C){var D=C[s];var E;if (D.IsObjectElement) E=A.AddItem(s,s);else E=A.AddItem(s,D.GetOpenerTag()+s+D.GetCloserTag());E.Style=D;}};FCKToolbarStyleCombo.prototype.RefreshActiveItems=function(A){A.DeselectAll();var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetActiveStyles();if (B.length>0){for (var i=0;i<B.length;i++) A.SelectItem(B[i].Name);A.SetLabelById(B[0].Name);}else A.SetLabel('');};FCKToolbarStyleCombo.prototype.RefreshVisibleItems=function(A){if (FCKSelection.GetType()=='Control') var B=FCKSelection.GetSelectedElement().tagName;for (var i in A.Items){var C=A.Items[i];if ((B&&C.Style.Element==B)||(!B&&!C.Style.IsObjectElement)) C.style.display='';else C.style.display='none';}}
+var FCKToolbarPanelButton=function(A,B,C,D,E){this.CommandName=A;var F;if (E==null) F=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(E)=='number') F=[FCKConfig.SkinPath+'fck_strip.gif',16,E];var G=this._UIButton=new FCKToolbarButtonUI(A,B,C,F,D);G._FCKToolbarPanelButton=this;G.ShowArrow=true;G.OnClick=FCKToolbarPanelButton_OnButtonClick;};FCKToolbarPanelButton.prototype.TypeName='FCKToolbarPanelButton';FCKToolbarPanelButton.prototype.Create=function(A){A.className+='Menu';this._UIButton.Create(A);var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName)._Panel;B._FCKToolbarPanelButton=this;var C=B.Document.body.appendChild(B.Document.createElement('div'));C.style.position='absolute';C.style.top='0px';var D=this.LineImg=C.appendChild(B.Document.createElement('IMG'));D.className='TB_ConnectionLine';D.src=FCK_SPACER_PATH;B.OnHide=FCKToolbarPanelButton_OnPanelHide;};function FCKToolbarPanelButton_OnButtonClick(A){var B=this._FCKToolbarPanelButton;var e=B._UIButton.MainElement;B._UIButton.ChangeState(1);B.LineImg.style.width=(e.offsetWidth-2)+'px';FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(B.CommandName).Execute(0,e.offsetHeight-1,e);};function FCKToolbarPanelButton_OnPanelHide(){var A=this._FCKToolbarPanelButton;A._UIButton.ChangeState(0);};FCKToolbarPanelButton.prototype.RefreshState=FCKToolbarButton.prototype.RefreshState;FCKToolbarPanelButton.prototype.Enable=FCKToolbarButton.prototype.Enable;FCKToolbarPanelButton.prototype.Disable=FCKToolbarButton.prototype.Disable;
+var FCKToolbarItems={};FCKToolbarItems.LoadedItems={};FCKToolbarItems.RegisterItem=function(A,B){this.LoadedItems[A]=B;};FCKToolbarItems.GetItem=function(A){var B=FCKToolbarItems.LoadedItems[A];if (B) return B;switch (A){case 'Source':B=new FCKToolbarButton('Source',FCKLang.Source,null,2,true,true,1);break;case 'DocProps':B=new FCKToolbarButton('DocProps',FCKLang.DocProps,null,null,null,null,2);break;case 'Save':B=new FCKToolbarButton('Save',FCKLang.Save,null,null,true,null,3);break;case 'NewPage':B=new FCKToolbarButton('NewPage',FCKLang.NewPage,null,null,true,null,4);break;case 'Preview':B=new FCKToolbarButton('Preview',FCKLang.Preview,null,null,true,null,5);break;case 'Templates':B=new FCKToolbarButton('Templates',FCKLang.Templates,null,null,null,null,6);break;case 'About':B=new FCKToolbarButton('About',FCKLang.About,null,null,true,null,47);break;case 'Cut':B=new FCKToolbarButton('Cut',FCKLang.Cut,null,null,false,true,7);break;case 'Copy':B=new FCKToolbarButton('Copy',FCKLang.Copy,null,null,false,true,8);break;case 'Paste':B=new FCKToolbarButton('Paste',FCKLang.Paste,null,null,false,true,9);break;case 'PasteText':B=new FCKToolbarButton('PasteText',FCKLang.PasteText,null,null,false,true,10);break;case 'PasteWord':B=new FCKToolbarButton('PasteWord',FCKLang.PasteWord,null,null,false,true,11);break;case 'Print':B=new FCKToolbarButton('Print',FCKLang.Print,null,null,false,true,12);break;case 'SpellCheck':B=new FCKToolbarButton('SpellCheck',FCKLang.SpellCheck,null,null,null,null,13);break;case 'Undo':B=new FCKToolbarButton('Undo',FCKLang.Undo,null,null,false,true,14);break;case 'Redo':B=new FCKToolbarButton('Redo',FCKLang.Redo,null,null,false,true,15);break;case 'SelectAll':B=new FCKToolbarButton('SelectAll',FCKLang.SelectAll,null,null,true,null,18);break;case 'RemoveFormat':B=new FCKToolbarButton('RemoveFormat',FCKLang.RemoveFormat,null,null,false,true,19);break;case 'FitWindow':B=new FCKToolbarButton('FitWindow',FCKLang.FitWindow,null,null,true,true,66);break;case 'Bold':B=new FCKToolbarButton('Bold',FCKLang.Bold,null,null,false,true,20);break;case 'Italic':B=new FCKToolbarButton('Italic',FCKLang.Italic,null,null,false,true,21);break;case 'Underline':B=new FCKToolbarButton('Underline',FCKLang.Underline,null,null,false,true,22);break;case 'StrikeThrough':B=new FCKToolbarButton('StrikeThrough',FCKLang.StrikeThrough,null,null,false,true,23);break;case 'Subscript':B=new FCKToolbarButton('Subscript',FCKLang.Subscript,null,null,false,true,24);break;case 'Superscript':B=new FCKToolbarButton('Superscript',FCKLang.Superscript,null,null,false,true,25);break;case 'OrderedList':B=new FCKToolbarButton('InsertOrderedList',FCKLang.NumberedListLbl,FCKLang.NumberedList,null,false,true,26);break;case 'UnorderedList':B=new FCKToolbarButton('InsertUnorderedList',FCKLang.BulletedListLbl,FCKLang.BulletedList,null,false,true,27);break;case 'Outdent':B=new FCKToolbarButton('Outdent',FCKLang.DecreaseIndent,null,null,false,true,28);break;case 'Indent':B=new FCKToolbarButton('Indent',FCKLang.IncreaseIndent,null,null,false,true,29);break;case 'Link':B=new FCKToolbarButton('Link',FCKLang.InsertLinkLbl,FCKLang.InsertLink,null,false,true,34);break;case 'Unlink':B=new FCKToolbarButton('Unlink',FCKLang.RemoveLink,null,null,false,true,35);break;case 'Anchor':B=new FCKToolbarButton('Anchor',FCKLang.Anchor,null,null,null,null,36);break;case 'Image':B=new FCKToolbarButton('Image',FCKLang.InsertImageLbl,FCKLang.InsertImage,null,false,true,37);break;case 'Flash':B=new FCKToolbarButton('Flash',FCKLang.InsertFlashLbl,FCKLang.InsertFlash,null,false,true,38);break;case 'Table':B=new FCKToolbarButton('Table',FCKLang.InsertTableLbl,FCKLang.InsertTable,null,false,true,39);break;case 'SpecialChar':B=new FCKToolbarButton('SpecialChar',FCKLang.InsertSpecialCharLbl,FCKLang.InsertSpecialChar,null,false,true,42);break;case 'Smiley':B=new FCKToolbarButton('Smiley',FCKLang.InsertSmileyLbl,FCKLang.InsertSmiley,null,false,true,41);break;case 'PageBreak':B=new FCKToolbarButton('PageBreak',FCKLang.PageBreakLbl,FCKLang.PageBreak,null,false,true,43);break;case 'Rule':B=new FCKToolbarButton('InsertHorizontalRule',FCKLang.InsertLineLbl,FCKLang.InsertLine,null,false,true,40);break;case 'JustifyLeft':B=new FCKToolbarButton('JustifyLeft',FCKLang.LeftJustify,null,null,false,true,30);break;case 'JustifyCenter':B=new FCKToolbarButton('JustifyCenter',FCKLang.CenterJustify,null,null,false,true,31);break;case 'JustifyRight':B=new FCKToolbarButton('JustifyRight',FCKLang.RightJustify,null,null,false,true,32);break;case 'JustifyFull':B=new FCKToolbarButton('JustifyFull',FCKLang.BlockJustify,null,null,false,true,33);break;case 'Style':B=new FCKToolbarStyleCombo();break;case 'FontName':B=new FCKToolbarFontsCombo();break;case 'FontSize':B=new FCKToolbarFontSizeCombo();break;case 'FontFormat':B=new FCKToolbarFontFormatCombo();break;case 'TextColor':B=new FCKToolbarPanelButton('TextColor',FCKLang.TextColor,null,null,45);break;case 'BGColor':B=new FCKToolbarPanelButton('BGColor',FCKLang.BGColor,null,null,46);break;case 'Find':B=new FCKToolbarButton('Find',FCKLang.Find,null,null,null,null,16);break;case 'Replace':B=new FCKToolbarButton('Replace',FCKLang.Replace,null,null,null,null,17);break;case 'Form':B=new FCKToolbarButton('Form',FCKLang.Form,null,null,null,null,48);break;case 'Checkbox':B=new FCKToolbarButton('Checkbox',FCKLang.Checkbox,null,null,null,null,49);break;case 'Radio':B=new FCKToolbarButton('Radio',FCKLang.RadioButton,null,null,null,null,50);break;case 'TextField':B=new FCKToolbarButton('TextField',FCKLang.TextField,null,null,null,null,51);break;case 'Textarea':B=new FCKToolbarButton('Textarea',FCKLang.Textarea,null,null,null,null,52);break;case 'HiddenField':B=new FCKToolbarButton('HiddenField',FCKLang.HiddenField,null,null,null,null,56);break;case 'Button':B=new FCKToolbarButton('Button',FCKLang.Button,null,null,null,null,54);break;case 'Select':B=new FCKToolbarButton('Select',FCKLang.SelectionField,null,null,null,null,53);break;case 'ImageButton':B=new FCKToolbarButton('ImageButton',FCKLang.ImageButton,null,null,null,null,55);break;default:alert(FCKLang.UnknownToolbarItem.replace(/%1/g,A));return null;};FCKToolbarItems.LoadedItems[A]=B;return B;}
+var FCKToolbar=function(){this.Items=[];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbar_Cleanup);};FCKToolbar.prototype.AddItem=function(A){return this.Items[this.Items.length]=A;};FCKToolbar.prototype.AddButton=function(A,B,C,D,E,F){if (typeof(D)=='number') D=[this.DefaultIconsStrip,this.DefaultIconSize,D];var G=new FCKToolbarButtonUI(A,B,C,D,E,F);G._FCKToolbar=this;G.OnClick=FCKToolbar_OnItemClick;return this.AddItem(G);};function FCKToolbar_OnItemClick(A){var B=A._FCKToolbar;if (B.OnItemClick) B.OnItemClick(B,A);};FCKToolbar.prototype.AddSeparator=function(){this.AddItem(new FCKToolbarSeparator());};FCKToolbar.prototype.Create=function(A){if (this.MainElement){if (this.MainElement.parentNode) this.MainElement.parentNode.removeChild(this.MainElement);this.MainElement=null;};var B=FCKTools.GetElementDocument(A);var e=this.MainElement=B.createElement('table');e.className='TB_Toolbar';e.style.styleFloat=e.style.cssFloat=(FCKLang.Dir=='ltr'?'left':'right');e.dir=FCKLang.Dir;e.cellPadding=0;e.cellSpacing=0;this.RowElement=e.insertRow(-1);var C;if (!this.HideStart){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_Start';};for (var i=0;i<this.Items.length;i++){this.Items[i].Create(this.RowElement.insertCell(-1));};if (!this.HideEnd){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_End';};A.appendChild(e);};function FCKToolbar_Cleanup(){this.MainElement=null;this.RowElement=null;};var FCKToolbarSeparator=function(){};FCKToolbarSeparator.prototype.Create=function(A){FCKTools.AppendElement(A,'div').className='TB_Separator';}
+var FCKToolbarBreak=function(){};FCKToolbarBreak.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A).createElement('div');B.className='TB_Break';B.style.clear=FCKLang.Dir=='rtl'?'left':'right';A.appendChild(B);}
+function FCKToolbarSet_Create(A){var B;var C=A||FCKConfig.ToolbarLocation;switch (C){case 'In':document.getElementById('xToolbarRow').style.display='';B=new FCKToolbarSet(document);break;default:FCK.Events.AttachEvent('OnBlur',FCK_OnBlur);FCK.Events.AttachEvent('OnFocus',FCK_OnFocus);var D;var E=C.match(/^Out:(.+)\((\w+)\)$/);if (E){D=eval('parent.'+E[1]).document.getElementById(E[2]);}else{E=C.match(/^Out:(\w+)$/);if (E) D=parent.document.getElementById(E[1]);};if (!D){alert('Invalid value for "ToolbarLocation"');return this._Init('In');};B=D.__FCKToolbarSet;if (B) break;var F=FCKTools.GetElementDocument(D).createElement('iframe');F.frameBorder=0;F.width='100%';F.height='10';D.appendChild(F);F.unselectable='on';var G=F.contentWindow.document;G.open();G.write('<html><head><script type="text/javascript"> window.onload = window.onresize = function() { window.frameElement.height = document.body.scrollHeight ; } </script></head><body style="overflow: hidden">'+document.getElementById('xToolbarSpace').innerHTML+'</body></html>');G.close();G.oncontextmenu=FCKTools.CancelEvent;FCKTools.AppendStyleSheet(G,FCKConfig.SkinPath+'fck_editor.css');B=D.__FCKToolbarSet=new FCKToolbarSet(G);B._IFrame=F;if (FCK.IECleanup) FCK.IECleanup.AddItem(D,FCKToolbarSet_Target_Cleanup);};B.CurrentInstance=FCK;FCK.AttachToOnSelectionChange(B.RefreshItemsState);return B;};function FCK_OnBlur(A){var B=A.ToolbarSet;if (B.CurrentInstance==A) B.Disable();};function FCK_OnFocus(A){var B=A.ToolbarSet;var C=A||FCK;B.CurrentInstance.FocusManager.RemoveWindow(B._IFrame.contentWindow);B.CurrentInstance=C;C.FocusManager.AddWindow(B._IFrame.contentWindow,true);B.Enable();};function FCKToolbarSet_Cleanup(){this._TargetElement=null;this._IFrame=null;};function FCKToolbarSet_Target_Cleanup(){this.__FCKToolbarSet=null;};var FCKToolbarSet=function(A){this._Document=A;this._TargetElement=A.getElementById('xToolbar');var B=A.getElementById('xExpandHandle');var C=A.getElementById('xCollapseHandle');B.title=FCKLang.ToolbarExpand;B.onclick=FCKToolbarSet_Expand_OnClick;C.title=FCKLang.ToolbarCollapse;C.onclick=FCKToolbarSet_Collapse_OnClick;if (!FCKConfig.ToolbarCanCollapse||FCKConfig.ToolbarStartExpanded) this.Expand();else this.Collapse();C.style.display=FCKConfig.ToolbarCanCollapse?'':'none';if (FCKConfig.ToolbarCanCollapse) C.style.display='';else A.getElementById('xTBLeftBorder').style.display='';this.Toolbars=[];this.IsLoaded=false;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarSet_Cleanup);};function FCKToolbarSet_Expand_OnClick(){FCK.ToolbarSet.Expand();};function FCKToolbarSet_Collapse_OnClick(){FCK.ToolbarSet.Collapse();};FCKToolbarSet.prototype.Expand=function(){this._ChangeVisibility(false);};FCKToolbarSet.prototype.Collapse=function(){this._ChangeVisibility(true);};FCKToolbarSet.prototype._ChangeVisibility=function(A){this._Document.getElementById('xCollapsed').style.display=A?'':'none';this._Document.getElementById('xExpanded').style.display=A?'none':'';if (FCKBrowserInfo.IsGecko){FCKTools.RunFunction(window.onresize);}};FCKToolbarSet.prototype.Load=function(A){this.Name=A;this.Items=[];this.ItemsWysiwygOnly=[];this.ItemsContextSensitive=[];this._TargetElement.innerHTML='';var B=FCKConfig.ToolbarSets[A];if (!B){alert(FCKLang.UnknownToolbarSet.replace(/%1/g,A));return;};this.Toolbars=[];for (var x=0;x<B.length;x++){var C=B[x];var D;if (typeof(C)=='string'){if (C=='/') D=new FCKToolbarBreak();}else{D=new FCKToolbar();for (var j=0;j<C.length;j++){var E=C[j];if (E=='-') D.AddSeparator();else{var F=FCKToolbarItems.GetItem(E);if (F){D.AddItem(F);this.Items.push(F);if (!F.SourceView) this.ItemsWysiwygOnly.push(F);if (F.ContextSensitive) this.ItemsContextSensitive.push(F);}}}};D.Create(this._TargetElement);this.Toolbars[this.Toolbars.length]=D;};FCKTools.DisableSelection(this._Document.getElementById('xCollapseHandle').parentNode);if (FCK.Status!=2) FCK.Events.AttachEvent('OnStatusChange',this.RefreshModeState);else this.RefreshModeState();this.IsLoaded=true;this.IsEnabled=true;FCKTools.RunFunction(this.OnLoad);};FCKToolbarSet.prototype.Enable=function(){if (this.IsEnabled) return;this.IsEnabled=true;var A=this.Items;for (var i=0;i<A.length;i++) A[i].RefreshState();};FCKToolbarSet.prototype.Disable=function(){if (!this.IsEnabled) return;this.IsEnabled=false;var A=this.Items;for (var i=0;i<A.length;i++) A[i].Disable();};FCKToolbarSet.prototype.RefreshModeState=function(A){if (FCK.Status!=2) return;var B=A?A.ToolbarSet:this;var C=B.ItemsWysiwygOnly;if (FCK.EditMode==0){for (var i=0;i<C.length;i++) C[i].Enable();B.RefreshItemsState(A);}else{B.RefreshItemsState(A);for (var j=0;j<C.length;j++) C[j].Disable();}};FCKToolbarSet.prototype.RefreshItemsState=function(A){var B=(A?A.ToolbarSet:this).ItemsContextSensitive;for (var i=0;i<B.length;i++) B[i].RefreshState();};
+var FCKDialog={};FCKDialog.OpenDialog=function(A,B,C,D,E,F,G,H){var I={};I.Title=B;I.Page=C;I.Editor=window;I.CustomValue=F;var J=FCKConfig.BasePath+'fckdialog.html';this.Show(I,A,J,D,E,G,H);};
+FCKDialog.Show=function(A,B,C,D,E,F,G){if (!F) F=window;var H='help:no;scroll:no;status:no;resizable:'+(G?'yes':'no')+';dialogWidth:'+D+'px;dialogHeight:'+E+'px';FCKFocusManager.Lock();var I='B';try{I=F.showModalDialog(C,A,H);}catch(e) {};if ('B'===I) alert(FCKLang.DialogBlocked);FCKFocusManager.Unlock();};
+var FCKMenuItem=function(A,B,C,D,E){this.Name=B;this.Label=C||B;this.IsDisabled=E;this.Icon=new FCKIcon(D);this.SubMenu=new FCKMenuBlockPanel();this.SubMenu.Parent=A;this.SubMenu.OnClick=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnClick,this);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuItem_Cleanup);};FCKMenuItem.prototype.AddItem=function(A,B,C,D){this.HasSubMenu=true;return this.SubMenu.AddItem(A,B,C,D);};FCKMenuItem.prototype.AddSeparator=function(){this.SubMenu.AddSeparator();};FCKMenuItem.prototype.Create=function(A){var B=this.HasSubMenu;var C=FCKTools.GetElementDocument(A);var r=this.MainElement=A.insertRow(-1);r.className=this.IsDisabled?'MN_Item_Disabled':'MN_Item';if (!this.IsDisabled){FCKTools.AddEventListenerEx(r,'mouseover',FCKMenuItem_OnMouseOver,[this]);FCKTools.AddEventListenerEx(r,'click',FCKMenuItem_OnClick,[this]);if (!B) FCKTools.AddEventListenerEx(r,'mouseout',FCKMenuItem_OnMouseOut,[this]);};var D=r.insertCell(-1);D.className='MN_Icon';D.appendChild(this.Icon.CreateIconElement(C));D=r.insertCell(-1);D.className='MN_Label';D.noWrap=true;D.appendChild(C.createTextNode(this.Label));D=r.insertCell(-1);if (B){D.className='MN_Arrow';var E=D.appendChild(C.createElement('IMG'));E.src=FCK_IMAGES_PATH+'arrow_'+FCKLang.Dir+'.gif';E.width=4;E.height=7;this.SubMenu.Create();this.SubMenu.Panel.OnHide=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnHide,this);}};FCKMenuItem.prototype.Activate=function(){this.MainElement.className='MN_Item_Over';if (this.HasSubMenu){this.SubMenu.Show(this.MainElement.offsetWidth+2,-2,this.MainElement);};FCKTools.RunFunction(this.OnActivate,this);};FCKMenuItem.prototype.Deactivate=function(){this.MainElement.className='MN_Item';if (this.HasSubMenu) this.SubMenu.Hide();};function FCKMenuItem_SubMenu_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuItem_SubMenu_OnHide(A){A.Deactivate();};function FCKMenuItem_OnClick(A,B){if (B.HasSubMenu) B.Activate();else{B.Deactivate();FCKTools.RunFunction(B.OnClick,B,[B]);}};function FCKMenuItem_OnMouseOver(A,B){B.Activate();};function FCKMenuItem_OnMouseOut(A,B){B.Deactivate();};function FCKMenuItem_Cleanup(){this.MainElement=null;}
+var FCKMenuBlock=function(){this._Items=[];};FCKMenuBlock.prototype.Count=function(){return this._Items.length;};FCKMenuBlock.prototype.AddItem=function(A,B,C,D){var E=new FCKMenuItem(this,A,B,C,D);E.OnClick=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnClick,this);E.OnActivate=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnActivate,this);this._Items.push(E);return E;};FCKMenuBlock.prototype.AddSeparator=function(){this._Items.push(new FCKMenuSeparator());};FCKMenuBlock.prototype.RemoveAllItems=function(){this._Items=[];var A=this._ItemsTable;if (A){while (A.rows.length>0) A.deleteRow(0);}};FCKMenuBlock.prototype.Create=function(A){if (!this._ItemsTable){if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuBlock_Cleanup);this._Window=FCKTools.GetElementWindow(A);var B=FCKTools.GetElementDocument(A);var C=A.appendChild(B.createElement('table'));C.cellPadding=0;C.cellSpacing=0;FCKTools.DisableSelection(C);var D=C.insertRow(-1).insertCell(-1);D.className='MN_Menu';var E=this._ItemsTable=D.appendChild(B.createElement('table'));E.cellPadding=0;E.cellSpacing=0;};for (var i=0;i<this._Items.length;i++) this._Items[i].Create(this._ItemsTable);};function FCKMenuBlock_Item_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuBlock_Item_OnActivate(A){var B=A._ActiveItem;if (B&&B!=this){if (!FCKBrowserInfo.IsIE&&B.HasSubMenu&&!this.HasSubMenu) A._Window.focus();B.Deactivate();};A._ActiveItem=this;};function FCKMenuBlock_Cleanup(){this._Window=null;this._ItemsTable=null;};var FCKMenuSeparator=function(){};FCKMenuSeparator.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var r=A.insertRow(-1);var C=r.insertCell(-1);C.className='MN_Separator MN_Icon';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';}
+var FCKMenuBlockPanel=function(){FCKMenuBlock.call(this);};FCKMenuBlockPanel.prototype=new FCKMenuBlock();FCKMenuBlockPanel.prototype.Create=function(){var A=this.Panel=(this.Parent&&this.Parent.Panel?this.Parent.Panel.CreateChildPanel():new FCKPanel());A.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');FCKMenuBlock.prototype.Create.call(this,A.MainNode);};FCKMenuBlockPanel.prototype.Show=function(x,y,A){if (!this.Panel.CheckIsOpened()) this.Panel.Show(x,y,A);};FCKMenuBlockPanel.prototype.Hide=function(){if (this.Panel.CheckIsOpened()) this.Panel.Hide();}
+var FCKContextMenu=function(A,B){var C=this._Panel=new FCKPanel(A,true);C.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');C.IsContextMenu=true;if (FCKBrowserInfo.IsGecko) C.Document.addEventListener('draggesture',function(e) {e.preventDefault();return false;},true);var D=this._MenuBlock=new FCKMenuBlock();D.Panel=C;D.OnClick=FCKTools.CreateEventListener(FCKContextMenu_MenuBlock_OnClick,this);this._Redraw=true;};FCKContextMenu.prototype.SetMouseClickWindow=function(A){if (!FCKBrowserInfo.IsIE){this._Document=A.document;this._Document.addEventListener('contextmenu',FCKContextMenu_Document_OnContextMenu,false);}};FCKContextMenu.prototype.AddItem=function(A,B,C,D){var E=this._MenuBlock.AddItem(A,B,C,D);this._Redraw=true;return E;};FCKContextMenu.prototype.AddSeparator=function(){this._MenuBlock.AddSeparator();this._Redraw=true;};FCKContextMenu.prototype.RemoveAllItems=function(){this._MenuBlock.RemoveAllItems();this._Redraw=true;};FCKContextMenu.prototype.AttachToElement=function(A){if (FCKBrowserInfo.IsIE) FCKTools.AddEventListenerEx(A,'contextmenu',FCKContextMenu_AttachedElement_OnContextMenu,this);else A._FCKContextMenu=this;};function FCKContextMenu_Document_OnContextMenu(e){var A=e.target;while (A){if (A._FCKContextMenu){FCKTools.CancelEvent(e);FCKContextMenu_AttachedElement_OnContextMenu(e,A._FCKContextMenu,A);};A=A.parentNode;}};function FCKContextMenu_AttachedElement_OnContextMenu(A,B,C){var D=C||this;if (B.OnBeforeOpen) B.OnBeforeOpen.call(B,D);if (B._MenuBlock.Count()==0) return false;if (B._Redraw){B._MenuBlock.Create(B._Panel.MainNode);B._Redraw=false;};FCKTools.DisableSelection(B._Panel.Document.body);B._Panel.Show(A.pageX||A.screenX,A.pageY||A.screenY,A.currentTarget||null);return false;};function FCKContextMenu_MenuBlock_OnClick(A,B){B._Panel.Hide();FCKTools.RunFunction(B.OnItemClick,B,A);}
+FCK.ContextMenu={};FCK.ContextMenu.Listeners=[];FCK.ContextMenu.RegisterListener=function(A){if (A) this.Listeners.push(A);};function FCK_ContextMenu_Init(){var A=FCK.ContextMenu._InnerContextMenu=new FCKContextMenu(FCKBrowserInfo.IsIE?window:window.parent,FCKLang.Dir);A.OnBeforeOpen=FCK_ContextMenu_OnBeforeOpen;A.OnItemClick=FCK_ContextMenu_OnItemClick;var B=FCK.ContextMenu;for (var i=0;i<FCKConfig.ContextMenu.length;i++) B.RegisterListener(FCK_ContextMenu_GetListener(FCKConfig.ContextMenu[i]));};function FCK_ContextMenu_GetListener(A){switch (A){case 'Generic':return {AddItems:function(menu,tag,tagName){menu.AddItem('Cut',FCKLang.Cut,7,FCKCommands.GetCommand('Cut').GetState()==-1);menu.AddItem('Copy',FCKLang.Copy,8,FCKCommands.GetCommand('Copy').GetState()==-1);menu.AddItem('Paste',FCKLang.Paste,9,FCKCommands.GetCommand('Paste').GetState()==-1);}};case 'Table':return {AddItems:function(menu,tag,tagName){var B=(tagName=='TABLE');var C=(!B&&FCKSelection.HasAncestorNode('TABLE'));if (C){menu.AddSeparator();var D=menu.AddItem('Cell',FCKLang.CellCM);D.AddItem('TableInsertCell',FCKLang.InsertCell,58);D.AddItem('TableDeleteCells',FCKLang.DeleteCells,59);D.AddItem('TableMergeCells',FCKLang.MergeCells,60);D.AddItem('TableSplitCell',FCKLang.SplitCell,61);D.AddSeparator();D.AddItem('TableCellProp',FCKLang.CellProperties,57);menu.AddSeparator();D=menu.AddItem('Row',FCKLang.RowCM);D.AddItem('TableInsertRow',FCKLang.InsertRow,62);D.AddItem('TableDeleteRows',FCKLang.DeleteRows,63);menu.AddSeparator();D=menu.AddItem('Column',FCKLang.ColumnCM);D.AddItem('TableInsertColumn',FCKLang.InsertColumn,64);D.AddItem('TableDeleteColumns',FCKLang.DeleteColumns,65);};if (B||C){menu.AddSeparator();menu.AddItem('TableDelete',FCKLang.TableDelete);menu.AddItem('TableProp',FCKLang.TableProperties,39);}}};case 'Link':return {AddItems:function(menu,tag,tagName){var E=(tagName=='A'||FCKSelection.HasAncestorNode('A'));if (E||FCK.GetNamedCommandState('Unlink')!=-1){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0&&F.href.length==0);if (G) return;menu.AddSeparator();if (E) menu.AddItem('Link',FCKLang.EditLink,34);menu.AddItem('Unlink',FCKLang.RemoveLink,35);}}};case 'Image':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&!tag.getAttribute('_fckfakelement')){menu.AddSeparator();menu.AddItem('Image',FCKLang.ImageProperties,37);}}};case 'Anchor':return {AddItems:function(menu,tag,tagName){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0);if (G||(tagName=='IMG'&&tag.getAttribute('_fckanchor'))){menu.AddSeparator();menu.AddItem('Anchor',FCKLang.AnchorProp,36);}}};case 'Flash':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckflash')){menu.AddSeparator();menu.AddItem('Flash',FCKLang.FlashProperties,38);}}};case 'Form':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('FORM')){menu.AddSeparator();menu.AddItem('Form',FCKLang.FormProp,48);}}};case 'Checkbox':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='checkbox'){menu.AddSeparator();menu.AddItem('Checkbox',FCKLang.CheckboxProp,49);}}};case 'Radio':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='radio'){menu.AddSeparator();menu.AddItem('Radio',FCKLang.RadioButtonProp,50);}}};case 'TextField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='text'||tag.type=='password')){menu.AddSeparator();menu.AddItem('TextField',FCKLang.TextFieldProp,51);}}};case 'HiddenField':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckinputhidden')){menu.AddSeparator();menu.AddItem('HiddenField',FCKLang.HiddenFieldProp,56);}}};case 'ImageButton':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='image'){menu.AddSeparator();menu.AddItem('ImageButton',FCKLang.ImageButtonProp,55);}}};case 'Button':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='button'||tag.type=='submit'||tag.type=='reset')){menu.AddSeparator();menu.AddItem('Button',FCKLang.ButtonProp,54);}}};case 'Select':return {AddItems:function(menu,tag,tagName){if (tagName=='SELECT'){menu.AddSeparator();menu.AddItem('Select',FCKLang.SelectionFieldProp,53);}}};case 'Textarea':return {AddItems:function(menu,tag,tagName){if (tagName=='TEXTAREA'){menu.AddSeparator();menu.AddItem('Textarea',FCKLang.TextareaProp,52);}}};case 'BulletedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('UL')){menu.AddSeparator();menu.AddItem('BulletedList',FCKLang.BulletedListProp,27);}}};case 'NumberedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('OL')){menu.AddSeparator();menu.AddItem('NumberedList',FCKLang.NumberedListProp,26);}}};};return null;};function FCK_ContextMenu_OnBeforeOpen(){FCK.Events.FireEvent('OnSelectionChange');var A,sTagName;if ((A=FCKSelection.GetSelectedElement())) sTagName=A.tagName;var B=FCK.ContextMenu._InnerContextMenu;B.RemoveAllItems();var C=FCK.ContextMenu.Listeners;for (var i=0;i<C.length;i++) C[i].AddItems(B,A,sTagName);};function FCK_ContextMenu_OnItemClick(A){FCK.Focus();FCKCommands.GetCommand(A.Name).Execute();};
+var FCKPlugin=function(A,B,C){this.Name=A;this.BasePath=C?C:FCKConfig.PluginsPath;this.Path=this.BasePath+A+'/';if (!B||B.length==0) this.AvailableLangs=[];else this.AvailableLangs=B.split(',');};FCKPlugin.prototype.Load=function(){if (this.AvailableLangs.length>0){var A;if (this.AvailableLangs.IndexOf(FCKLanguageManager.ActiveLanguage.Code)>=0) A=FCKLanguageManager.ActiveLanguage.Code;else A=this.AvailableLangs[0];LoadScript(this.Path+'lang/'+A+'.js');};LoadScript(this.Path+'fckplugin.js');}
+var FCKPlugins=FCK.Plugins={};FCKPlugins.ItemsCount=0;FCKPlugins.Items={};FCKPlugins.Load=function(){var A=FCKPlugins.Items;for (var i=0;i<FCKConfig.Plugins.Items.length;i++){var B=FCKConfig.Plugins.Items[i];var C=A[B[0]]=new FCKPlugin(B[0],B[1],B[2]);FCKPlugins.ItemsCount++;};for (var s in A) A[s].Load();FCKPlugins.Load=null;}
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/fckdebug.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/fckdebug.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/fckdebug.html	(revision 795)
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the Debug window.
+ * It automatically popups if the Debug = true in the configuration file.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor Debug Window</title>
+	<meta name="robots" content="noindex, nofollow" />
+	<script type="text/javascript">
+
+var oWindow ;
+var oDiv ;
+
+if ( !window.FCKMessages )
+	window.FCKMessages = new Array() ;
+
+window.onload = function()
+{
+	oWindow = document.getElementById('xOutput').contentWindow ;
+	oWindow.document.open() ;
+	oWindow.document.write( '<div id="divMsg"><\/div>' ) ;
+	oWindow.document.close() ;
+	oDiv	= oWindow.document.getElementById('divMsg') ;
+}
+
+function Output( message, color, noParse )
+{
+	if ( !noParse && message != null && isNaN( message ) )
+		message = message.replace(/</g, "&lt;") ;
+
+	if ( color )
+		message = '<font color="' + color + '">' + message + '<\/font>' ;
+
+	window.FCKMessages[ window.FCKMessages.length ] = message ;
+	StartTimer() ;
+}
+
+function OutputObject( anyObject, color )
+{
+	var message ;
+
+	if ( anyObject != null )
+	{
+		message = 'Properties of: ' + anyObject + '</b><blockquote>' ;
+
+		for (var prop in anyObject)
+		{
+			try
+			{
+				var sVal = anyObject[ prop ] != null ? anyObject[ prop ] + '' : '[null]' ;
+				message += '<b>' + prop + '</b> : ' + sVal.replace(/</g, '&lt;') + '<br>' ;
+			}
+			catch (e)
+			{
+				try
+				{
+					message += '<b>' + prop + '</b> : [' + typeof( anyObject[ prop ] ) + ']<br>' ;
+				}
+				catch (e)
+				{
+					message += '<b>' + prop + '</b> : [-error-]<br>' ;
+				}
+			}
+		}
+
+		message += '</blockquote><b>' ;
+	} else
+		message = 'OutputObject : Object is "null".' ;
+
+	Output( message, color, true ) ;
+}
+
+function StartTimer()
+{
+	window.setTimeout( 'CheckMessages()', 100 ) ;
+}
+
+function CheckMessages()
+{
+	if ( window.FCKMessages.length > 0 )
+	{
+		// Get the first item in the queue
+		var sMessage = window.FCKMessages[0] ;
+
+		// Removes the first item from the queue
+		var oTempArray = new Array() ;
+		for ( i = 1 ; i < window.FCKMessages.length ; i++ )
+			oTempArray[ i - 1 ] = window.FCKMessages[ i ] ;
+		window.FCKMessages = oTempArray ;
+
+		var d = new Date() ;
+		var sTime =
+			( d.getHours() + 100 + '' ).substr( 1,2 ) + ':' +
+			( d.getMinutes() + 100 + '' ).substr( 1,2 ) + ':' +
+			( d.getSeconds() + 100 + '' ).substr( 1,2 ) + ':' +
+			( d.getMilliseconds() + 1000 + '' ).substr( 1,3 ) ;
+
+		var oMsgDiv = oWindow.document.createElement( 'div' ) ;
+		oMsgDiv.innerHTML = sTime + ': <b>' + sMessage + '<\/b>' ;
+		oDiv.appendChild( oMsgDiv ) ;
+		oMsgDiv.scrollIntoView() ;
+	}
+}
+
+function Clear()
+{
+	oDiv.innerHTML = '' ;
+}
+	</script>
+</head>
+<body style="margin: 10px">
+	<table style="height: 100%" cellspacing="5" cellpadding="0" width="100%" border="0">
+		<tr>
+			<td>
+				<table cellspacing="0" cellpadding="0" width="100%" border="0">
+					<tr>
+						<td style="font-weight: bold; font-size: 1.2em;">
+							FCKeditor Debug Window</td>
+						<td align="right">
+							<input type="button" value="Clear" onclick="Clear();" /></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+		<tr style="height: 100%">
+			<td style="border: #696969 1px solid">
+				<iframe id="xOutput" width="100%" height="100%" scrolling="auto" src="javascript:void(0)"
+					frameborder="0"></iframe>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/editor/fckeditor.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/editor/fckeditor.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/editor/fckeditor.html	(revision 795)
@@ -0,0 +1,227 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Main page that holds the editor.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor</title>
+	<meta name="robots" content="noindex, nofollow" />
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta http-equiv="Cache-Control" content="public" />
+	<script type="text/javascript">
+
+// Instead of loading scripts and CSSs using inline tags, all scripts are
+// loaded by code. In this way we can guarantee the correct processing order,
+// otherwise external scripts and inline scripts could be executed in an
+// unwanted order (IE).
+
+function LoadScript( url )
+{
+	document.write( '<scr' + 'ipt type="text/javascript" src="' + url + '" onerror="alert(\'Error loading \' + this.src);"><\/scr' + 'ipt>' ) ;
+}
+
+function LoadCss( url )
+{
+	document.write( '<link href="' + url + '" type="text/css" rel="stylesheet" onerror="alert(\'Error loading \' + this.src);" />' ) ;
+}
+
+// Main editor scripts.
+var sSuffix = /msie/.test( navigator.userAgent.toLowerCase() ) ? 'ie' : 'gecko' ;
+
+LoadScript( 'js/fckeditorcode_' + sSuffix + '.js' ) ;
+
+// Base configuration file.
+LoadScript( '../fckconfig.js' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+if ( FCKBrowserInfo.IsIE )
+{
+	// Remove IE mouse flickering.
+	try
+	{
+		document.execCommand( 'BackgroundImageCache', false, true ) ;
+	}
+	catch (e)
+	{
+		// We have been reported about loading problems caused by the above
+		// line. For safety, let's just ignore errors.
+	}
+
+	// Create the default cleanup object used by the editor.
+	FCK.IECleanup = new FCKIECleanup( window ) ;
+	FCK.IECleanup.AddItem( FCKTempBin, FCKTempBin.Reset ) ;
+	FCK.IECleanup.AddItem( FCK, FCK_Cleanup ) ;
+}
+
+// The config hidden field is processed immediately, because
+// CustomConfigurationsPath may be set in the page.
+FCKConfig.ProcessHiddenField() ;
+
+// Load the custom configurations file (if defined).
+if ( FCKConfig.CustomConfigurationsPath.length > 0 )
+	LoadScript( FCKConfig.CustomConfigurationsPath ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Load configurations defined at page level.
+FCKConfig_LoadPageConfig() ;
+
+FCKConfig_PreProcess() ;
+
+// Load the active skin CSS.
+LoadCss( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+// Load the language file.
+FCKLanguageManager.Initialize() ;
+LoadScript( 'lang/' + FCKLanguageManager.ActiveLanguage.Code + '.js' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Initialize the editing area context menu.
+FCK_ContextMenu_Init() ;
+
+FCKPlugins.Load() ;
+
+	</script>
+	<script type="text/javascript">
+
+// Set the editor interface direction.
+window.document.dir = FCKLang.Dir ;
+
+// Activate pasting operations.
+if ( FCKConfig.ForcePasteAsPlainText || FCKConfig.AutoDetectPasteFromWord )
+	FCK.Events.AttachEvent( 'OnPaste', FCK.Paste ) ;
+
+	</script>
+	<script type="text/javascript">
+
+window.onload = function()
+{
+	InitializeAPI() ;
+
+	if ( FCKBrowserInfo.IsIE )
+		FCK_PreloadImages() ;
+	else
+		LoadToolbarSetup() ;
+}
+
+function LoadToolbarSetup()
+{
+	FCKeditorAPI._FunctionQueue.Add( LoadToolbar ) ;
+}
+
+function LoadToolbar()
+{
+	var oToolbarSet = FCK.ToolbarSet = FCKToolbarSet_Create() ;
+
+	if ( oToolbarSet.IsLoaded )
+		StartEditor() ;
+	else
+	{
+		oToolbarSet.OnLoad = StartEditor ;
+		oToolbarSet.Load( FCKURLParams['Toolbar'] || 'Default' ) ;
+	}
+}
+
+function StartEditor()
+{
+	// Remove the onload listener.
+	FCK.ToolbarSet.OnLoad = null ;
+
+	FCKeditorAPI._FunctionQueue.Remove( LoadToolbar ) ;
+
+	FCK.Events.AttachEvent( 'OnStatusChange', WaitForActive ) ;
+
+	// Start the editor.
+	FCK.StartEditor() ;
+}
+
+function WaitForActive( editorInstance, newStatus )
+{
+	if ( newStatus == FCK_STATUS_ACTIVE )
+	{
+		if ( FCKBrowserInfo.IsGecko )
+			FCKTools.RunFunction( window.onresize ) ;
+
+		_AttachFormSubmitToAPI() ;
+
+		FCK.SetStatus( FCK_STATUS_COMPLETE ) ;
+
+		// Call the special "FCKeditor_OnComplete" function that should be present in
+		// the HTML page where the editor is located.
+		if ( typeof( window.parent.FCKeditor_OnComplete ) == 'function' )
+			window.parent.FCKeditor_OnComplete( FCK ) ;
+	}
+}
+
+// Gecko browsers doens't calculate well that IFRAME size so we must
+// recalculate it every time the window size changes.
+if ( FCKBrowserInfo.IsGecko )
+{
+	function Window_OnResize()
+	{
+		if ( FCKBrowserInfo.IsOpera )
+			return ;
+
+		var oCell = document.getElementById( 'xEditingArea' ) ;
+
+		var eInnerElement = oCell.firstChild ;
+		if ( eInnerElement )
+		{
+			eInnerElement.style.height = 0 ;
+			eInnerElement.style.height = oCell.scrollHeight - 2 ;
+		}
+	}
+	window.onresize = Window_OnResize ;
+}
+
+	</script>
+</head>
+<body>
+	<table width="100%" cellpadding="0" cellspacing="0" style="height: 100%; table-layout: fixed">
+		<tr id="xToolbarRow" style="display: none">
+			<td id="xToolbarSpace" style="overflow: hidden">
+				<table width="100%" cellpadding="0" cellspacing="0">
+					<tr id="xCollapsed" style="display: none">
+						<td id="xExpandHandle" class="TB_Expand" colspan="3">
+							<img class="TB_ExpandImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+					</tr>
+					<tr id="xExpanded" style="display: none">
+						<td id="xTBLeftBorder" class="TB_SideBorder" style="width: 1px; display: none;"></td>
+						<td id="xCollapseHandle" style="display: none" class="TB_Collapse" valign="bottom">
+							<img class="TB_CollapseImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+						<td id="xToolbar" class="TB_ToolbarSet"></td>
+						<td class="TB_SideBorder" style="width: 1px"></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+		<tr>
+			<td id="xEditingArea" valign="top" style="height: 100%"></td>
+		</tr>
+	</table>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/fckstyles.xml
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/fckstyles.xml	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/fckstyles.xml	(revision 795)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the sample style definitions file. It makes the styles combo
+ * completely customizable.
+ *
+ * See FCKConfig.StylesXmlPath in the configuration file.
+-->
+<Styles>
+	<Style name="Image on Left" element="img">
+		<Attribute name="style" value="padding: 5px; margin-right: 5px" />
+		<Attribute name="border" value="2" />
+		<Attribute name="align" value="left" />
+	</Style>
+	<Style name="Image on Right" element="img">
+		<Attribute name="style" value="padding: 5px; margin-left: 5px" />
+		<Attribute name="border" value="2" />
+		<Attribute name="align" value="right" />
+	</Style>
+	<Style name="Custom Bold" element="span">
+		<Attribute name="style" value="font-weight: bold;" />
+	</Style>
+	<Style name="Custom Italic" element="em" />
+	<Style name="Title" element="span">
+		<Attribute name="class" value="Title" />
+	</Style>
+	<Style name="Code" element="span">
+		<Attribute name="class" value="Code" />
+	</Style>
+	<Style name="Title H3" element="h3" />
+	<Style name="Custom Ruler" element="hr">
+		<Attribute name="size" value="1" />
+		<Attribute name="color" value="#ff0000" />
+	</Style>
+</Styles>
Index: /sandbox/workflow/branches/993/js/fckeditor/_upgrade.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/_upgrade.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/_upgrade.html	(revision 795)
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor - Upgrade</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<style type="text/css">
+		body { font-family: arial, verdana, sans-serif }
+		p { margin-left: 20px }
+	</style>
+</head>
+<body>
+	<h1>
+		FCKeditor Upgrade</h1>
+	<p>
+		Please check the following URL for notes regarding upgrade: <a href="http://wiki.fckeditor.net/Developer%27s_Guide/Upgrade">
+			http://wiki.fckeditor.net/Developer%27s_Guide/Upgrade</a></p>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/_documentation.html
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/_documentation.html	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/_documentation.html	(revision 795)
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor - Documentation</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<style type="text/css">
+		body { font-family: arial, verdana, sans-serif }
+		p { margin-left: 20px }
+	</style>
+</head>
+<body>
+	<h1>
+		FCKeditor Documentation</h1>
+	<p>
+		You can find the official documentation for FCKeditor online, at <a href="http://wiki.fckeditor.net/">
+			http://wiki.fckeditor.net/</a>.</p>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/js/fckeditor/htaccess.txt
===================================================================
--- /sandbox/workflow/branches/993/js/fckeditor/htaccess.txt	(revision 795)
+++ /sandbox/workflow/branches/993/js/fckeditor/htaccess.txt	(revision 795)
@@ -0,0 +1,44 @@
+#
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#
+#  == BEGIN LICENSE ==
+#
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#
+#  == END LICENSE ==
+#
+# -----------------------------------------------------------------------------
+#
+# On some specific Linux installations you could face problems with Firefox.
+# It could give you errors when loading the editor saying that some illegal
+# characters were found (three strange chars in the beginning of the file).
+# This could happen if you map the .js or .css files to PHP, for example.
+#
+# Those characters are the Byte Order Mask (BOM) of the Unicode encoded files.
+# All FCKeditor files are Unicode encoded.
+#
+# Just rename this file to ".htaccess" and leave it in the editor directory.
+# There are no security issues on doing it. It just sets the ".js" and ".css"
+# files to their correct content types.
+#
+
+AddType application/x-javascript .js
+AddType text/css .css
+
+#
+# If PHP is mapped to handle XML files, you could have some issues. The
+# following will disable it.
+#
+
+AddType text/xml .xml
Index: /sandbox/workflow/branches/993/js/monitors/massActions.js
===================================================================
--- /sandbox/workflow/branches/993/js/monitors/massActions.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/monitors/massActions.js	(revision 795)
@@ -0,0 +1,199 @@
+/* contém o e-mail padrão quando se envia somente um e-mail por usuário */
+var workflowMonitorEmailUser = '<font color="#FF6666">Atenção: esta mensagem foi gerada automaticamente pelo sistema e não deve ser respondida.</font><br/><br/>\n\
+\n\
+Caro usuário,<br/>\n\
+As seguintes atividades de workflow do processo <strong>%processo%</strong> estão aguardando execução em sua caixa de tarefas pendentes. Favor providenciar o andamento:<br/><br/>\n\
+%inicio_loop%\n\
+Instância %atual_instancia% de %quantidade_instancia%<br/>\n\
+Atividade: %atividade%<br/>\n\
+Aguardando por: %tempo_atividade% (desde %inicio_atividade%)<br/>\n\
+Identificador: %identificador%<br/>\n\
+Link para execução: %link%<br/>\n\
+<br/><br/>\n\
+%fim_loop%\n\
+\n\
+Atenciosamente,<br/>\n\
+Workflow do Expresso';
+
+/* contém o e-mail padrão quando se envia um e-mail por instância */
+var workflowMonitorEmailInstance = '<font color="#FF6666">Atenção: esta mensagem foi gerada automaticamente pelo sistema e não deve ser respondida.</font><br/><br/>\n\
+\n\
+Caro usuário,<br/>\n\
+Existe uma atividades de workflow do processo <strong>%processo%</strong> que está aguardando execução em sua caixa de tarefas pendentes. Favor providenciar o andamento:<br/><br/>\n\
+\n\
+Atividade: %atividade%<br/>\n\
+Aguardando por: %tempo_atividade% (desde %inicio_atividade%)<br/>\n\
+Identificador: %identificador%<br/>\n\
+Link para execução: %link%<br/>\n\
+<br/>\n\
+\n\
+Atenciosamente,<br/>\n\
+Workflow do Expresso';
+
+/**
+ * Constrói a interface para envio de e-mails (dentro de um elemento LightBox)
+ * @return void
+ */
+function sendMailConfig()
+{
+	var content = '';
+	content += '<div id="emailCompose">';
+	content += '<h2>Enviar E-mail</h2>';
+	content += '<input type="radio" name="emailType" id="onePerUser" value="1" checked="true" onclick="$(\'emailBody\').value = workflowMonitorEmailUser;"/> <label for="onePerUser">Um e-mail por usuário</label>';
+	content += '<label><input type="radio" name="emailType" id="onePerInstance" value="1" onclick="$(\'emailBody\').value = workflowMonitorEmailInstance;"/> <label for="onePerInstance">Um e-mail por instância</label>';
+	content += '<br/><label>Assunto do E-mail <input type="text" id="emailSubject" value="Atividades de Workflow Pendentes" size="40"/></label>';
+	content += '<br/>Texto do E-mail:<br/><textarea style="width: 100%; height: 170px;" id="emailBody">' + workflowMonitorEmailUser + '</textarea>';
+
+	content += '<table style="width: 100%">';
+	content += '<tr><td style="width: 60%"></td>';
+	content += '<td>';
+
+	content += '<button onclick="previewEmail(); return false;">Preview</button>';
+	content += '&nbsp;&nbsp;&nbsp;&nbsp;';
+	content += '<button onclick="sendMail(); return false;">Enviar</button>';
+	content += '&nbsp;&nbsp;&nbsp;&nbsp;';
+	content += '<button onclick="valid.deactivate(); return false;">Cancelar</button>';
+
+	content += '</td>';
+	content += '</tr>';
+	content += '<tr>';
+	content += '<td colspan="2">';
+
+	content += '<table style="width: 100%">';
+	content += '<tr style="color: #FFFFFF; background-color: #000000; font-size: 11px;"><th>Variável</th><th>Significado</th></tr>';
+	content += '<tr><td>%atividade%</td><td>O nome da atividade atual</td></tr>'
+	content += '<tr><td>%usuario%</td><td>O nome do usuário que está com a instância</td></tr>'
+	content += '<tr><td>%processo%</td><td>O nome do processo</td></tr>'
+	content += '<tr><td>%identificador%</td><td>O identificador da instância</td></tr>'
+	content += '<tr><td>%tempo_atividade%</td><td>A duração (até o momento) da atividade atual</td></tr>'
+	content += '<tr><td>%tempo_instancia%</td><td>A duração (até o momento) da instância</td></tr>'
+	content += '<tr><td>%inicio_atividade%</td><td>O início da atividade atual</td></tr>'
+	content += '<tr><td>%inicio_instancia%</td><td>O início da instância</td></tr>'
+	content += '<tr><td>%quantidade_instancia%</td><td>A quantidade de instâncias com o usuário</td></tr>'
+	content += '<tr><td>%atual_instancia%</td><td>A instância atual (número em relação à quantidade)</td></tr>'
+	content += '<tr><td>%link%</td><td>Link para a execução da instância (abre em nova janela)</td></tr>'
+	content += '<tr><td>%url%</td><td>Somente a URL para a execução da instância</td></tr>'
+	content += '<tr><td>%prioridade%</td><td>A prioridade da instância</td></tr>'
+	content += '</table>';
+
+	content += '</td>';
+	content += '</tr>';
+	content += '</table>';
+	content += '</div>';
+
+	content += '<div id="emailPreview" style="display: none;"></div>';
+
+	$('lbContent').innerHTML = content;
+//	$('emailBody').innerHTML = workflowMonitorEmailUser;
+}
+
+/**
+ * Gera uma string contento os parâmetros para as chamadas Ajax do envio de e-mails
+ * @return string A string de parâmetros
+ */
+function commonParams()
+{
+	var output = 'pid=' + workflowMonitorInstancesParams['pid'];
+
+	output += '&p_page=0';
+
+	if (workflowMonitorInstancesParams['filters'])
+		output += '&filters=' + workflowMonitorInstancesParams['filters'];
+
+	return output;
+}
+
+/**
+ * Envia os e-mails para as instâncias selecionadas
+ * @return void
+ */
+function sendMail()
+{
+	function resultSendMail(data)
+	{
+		if (data['error'])
+		{
+			alert(data['error']);
+			return;
+		}
+
+		var content = '';
+		content += '<h2>Resultado de Envio</h2>';
+		content += '<br/><font color="#FF0000">Foram enviados ' + data + ' e-mails alertando sobre as instâncias.</font>'
+		content += '<br/><br/><button onclick="valid.deactivate(); return false;">Fechar</button>';
+		$('lbContent').innerHTML = content;
+
+	}
+
+	if (!confirm('Este e-mail será enviado para todos os usuários listados na tela anterior.\nDeseja continuar?'))
+		return;
+	var params = commonParams();
+	params += '&emailType=' + (($F('onePerUser') == 1) ? 'user' : 'instance');
+	params += '&emailBody=' + escape($F('emailBody'));
+	params += '&emailSubject=' + escape($F('emailSubject'));
+	cExecute('$this.bo_monitors.sendMail', resultSendMail, params);
+}
+
+/**
+ * Gera um preview dos e-mails que serão enviados
+ * @return void
+ */
+function previewEmail()
+{
+	function resultPreviewEmail(data)
+	{
+		if (data['error'])
+		{
+			alert(data['error']);
+			return;
+		}
+
+		var content = '<h2>Preview</h2>';
+		content += '<p><strong>Número de e-mails que serão enviados:</strong> ' + data['emailCount'] + '</p>';
+		content += '<div style="background-color: #FFFFFF; border: 1px solid black; padding: 10px;">' + data['emailBody'] + '</div>';
+		content += '<br/><button onclick="$(\'emailPreview\').hide();$(\'emailCompose\').show()"; return false;>Fechar Preview</button>';
+		$('emailPreview').innerHTML = content;
+		$('emailCompose').hide();
+		$('emailPreview').show();
+	}
+	var params = commonParams();
+	params += '&emailType=' + (($F('onePerUser') == 1) ? 'user' : 'instance');
+	params += '&emailBody=' + escape($F('emailBody'));
+	params += '&emailSubject=' + escape($F('emailSubject'));
+	cExecute('$this.bo_monitors.previewEmail', resultPreviewEmail, params);
+}
+
+/**
+ * Remove as instâncias finalizadas (completadas ou abortadas) que foram selecionadas
+ * @return void
+ */
+function removeCompletedInstances()
+{
+	function resultRemoveCompletedInstances(data)
+	{
+		if (data['error'])
+		{
+			alert(data['error']);
+			return;
+		}
+
+		/* define a mensagem que será exibida */
+		var message = '';
+		if (data < 1)
+			message = 'Nenhuma instância foi removida';
+		else
+			if (data == 1)
+				message = 'Uma instância foi removida';
+			else
+				message = 'Foram removidas ' + data + ' instâncias';
+		write_msg(message);
+
+		/* recarrega a lista de instâncias */
+		filterInstances(true);
+	}
+
+	if (!confirm('Todas as instâncias listadas nesta tela (inclusive as paginadas) serão removidas.\nDeseja continuar?'))
+		return;
+	var params = commonParams();
+	cExecute('$this.bo_monitors.removeCompletedInstances', resultRemoveCompletedInstances, params);
+}
Index: /sandbox/workflow/branches/993/js/monitors/processes.js
===================================================================
--- /sandbox/workflow/branches/993/js/monitors/processes.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/monitors/processes.js	(revision 795)
@@ -0,0 +1,257 @@
+/* retorno do Ajax para listagem de processos */
+function processList(data)
+{
+	if (handleError(data))
+	{
+		var divProcess = document.getElementById("divProcess");
+		divProcess.innerHTML = '';
+		if (data['data'].length == 0)
+		{
+			var parag = document.createElement("P");
+			parag.className = "text_dsp";
+			parag.innerHTML = "Não existem processos";
+			divProcess.appendChild(parag);
+		}
+		else
+		{
+			permissions = data['permissions'];
+			drawProcessesList(data);
+		}
+	}
+}
+
+/* chama o método Ajax que lista os processos */
+function listProcesses()
+{
+	cExecute("$this.bo_monitors.listProcesses", processList);
+}
+
+/* desenha os processos na interface */
+function drawProcessesList(data)
+{
+	var processes = data['data'];
+	var divProcess = document.getElementById("divProcess");
+	var tableHeader = new Array();
+	var tableAtributes = new Array();
+
+	var content = '<table width="100%" align="center" border="1" class="content_table">';
+	content += '<tr><th>ID</th><th>Nome</th></tr>';
+	var processCount = processes.length;
+	for (var i = 0; i < processCount; i++)
+	{
+		content += '<tr id="p_' + processes[i]['wf_p_id'] + '"><td>' + processes[i]['wf_p_id'] + '</td><td><a href="" onclick="drawProcessOptions(' + processes[i]['wf_p_id'] + '); return false;">' + processes[i]['wf_name'] + ' v' + processes[i]['wf_version']  + '</a></td></tr>';
+	}
+	content += '</table>';
+	divProcess.innerHTML = content;
+
+}
+
+/* desenha as opções do processo */
+function drawProcessOptions(pid)
+{
+	$("divInstance").innerHTML = '';
+
+	/* marca o processo selecionado */
+	var tr = document.getElementById('p_' + pid);
+	var table = tr.parentNode;
+	var newClass;
+	$A(table.childNodes).each(function(row)
+		{
+			Element.extend(row).removeClassName('selected')
+		});
+	Element.extend(tr).addClassName('selected');
+
+	/* constrói a tabela de ações */
+	var content = '<table width="100%" align="center" border="1" class="content_table">';
+	content += '<tr><th>Opções</th></tr>';
+
+	content += '<tr><td><a href="" onclick="loadInstances(' + pid + '); return false;">Instâncias Ativas</a></td></tr>';
+	content += '<tr><td><a href="" onclick="loadCompletedInstances(' + pid + '); return false;">Instâncias Finalizadas</a></td></tr>';
+	content += '<tr><td><a href="" onclick="loadInconsistentInstances(' + pid + '); return false;">Instâncias Inconsistentes</a></td></tr>';
+
+	if (permissions[pid]['bits'][IP_VIEW_STATISTICS])
+		content += '<tr><td><a href="" onclick="clickShowStatistics(this, ' + pid + '); return false;">Estatísticas</a></td></tr>';
+
+	if (permissions[pid]['bits'][IP_REPLACE_USER])
+		content += '<tr><td><a href="" onclick="clickReplaceUser(this, ' + pid + '); return false;">Substituir Usuário</a></td></tr>';
+
+	content += '</table>';
+	$('divOptions').innerHTML = content;
+}
+
+function clickReplaceUser(link, pid)
+{
+	function resultClickReplaceUser(data)
+	{
+		$('MonitorLoading').remove();
+		var divInstance = $('divInstance');
+		if (handleError(data))
+		{
+			var users = data['users'];
+			if (users.length > 0)
+			{
+				var content = '<table width="100%">';
+				content += '<tr valign="top"><td>';
+				content += '<h2>Usuários</h2><table><tr><td><label>Usuário Antigo</label></td>';
+				content += '<td><select id="oldUser">';
+				for (var i = 0; i < users.length; i++)
+					content += '<option value="' + users[i]['id'] + '">' + users[i]['name'] + '</option>';
+				content += '</select></td></tr>';
+				content += '<tr><td><label>Novo Usuário</label></td>';
+				content += '<td><input type="hidden" name="newUser" id="newUser" value="" />';
+				content += '<input type="input" name="newUser_desc" id="newUser_desc" value="" readonly="true" size="32" />';
+				content += '<a href="javascript:void(0)" onclick="openParticipants(\'newUser\', \'uid=1&hidegroups=1\');"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/add_user.png"/></a></td></tr>';
+				content += '<tr><td colspan="2"><button onclick="clickLoadActivities(' + pid + ');return false;">Próximo >></button></td></tr></table>';
+				content += '</td>';
+				content += '<td id="tdActivities"></td>';
+				content += '<td id="tdRoles"></td>';
+				content += '</tr></table>';
+				divInstance.innerHTML += content;
+			}
+			else
+				divInstance.innerHTML = '<p class="text_dsp">Este processo não possui instâncias ativas</p>';
+		}
+	}
+
+	$('divInstance').innerHTML = '<h2>Substituir Usuário</h2><div id="MonitorLoading"><img src="workflow/templateFile.php?file=images/loading.gif"/> Carregando ...</div>';
+
+	var params = 'pid=' + pid;
+	cExecute("$this.bo_monitors.getUsersInInstances", resultClickReplaceUser, params);
+}
+
+function clickLoadActivities(pid)
+{
+	function resultClickLoadActivities(data)
+	{
+		$('MonitorLoading').remove();
+		var tdActivities = $('tdActivities');
+		if (handleError(data))
+		{
+			var activities = data['activities'];
+			if (activities.length > 0)
+			{
+				var content = '<table>';
+				content += '<tr><td><label>Atividade</label></td>';
+				content += '<td><select id="activity">';
+				content += '<option value="0">Todas</option>';
+				for (var i = 0; i < activities.length; i++)
+					content += '<option value="' + activities[i]['id'] + '">' + activities[i]['name'] + '</option>';
+				content += '</select></td></tr>';
+				content += '<tr><td colspan="2"><button onclick="clickCheckUserRoles(' + pid + ');return false;">Próximo >></button></td></tr></table>';
+				tdActivities.innerHTML += content;
+			}
+			else
+				tdActivities.innerHTML = '<p class="text_dsp">Este processo não possui instâncias ativas com o usuário selecionado</p>';
+		}
+	}
+
+	var newUser = $F('newUser');
+	if (!newUser)
+	{
+		alert('Selecione o novo usuário');
+		return;
+	}
+	$('tdActivities').innerHTML = '<h2>Ativitidades</h2><div id="MonitorLoading"><img src="workflow/templateFile.php?file=images/loading.gif"/> Carregando ...</div>';
+	var params = 'pid=' + pid + '&user=' + $F('oldUser');
+	cExecute("$this.bo_monitors.getUserActivities", resultClickLoadActivities, params);
+}
+
+function resultClickCheckUserRoles(data)
+{
+	$('MonitorLoading').remove();
+	var tdRoles = $('tdRoles');
+	if (handleError(data))
+	{
+		var roles = data['roles'];
+		if (roles.length > 0)
+		{
+			var content = '<p style="width: 250px">O usuário selecionado não pode acessar as atividades abaixo porque não está mapeado nos perfis necessários. Por favor, faça as correções.</p>';
+			content += '<table>';
+			for (var i = 0; i < roles.length; i++)
+			{
+				content += '<tr valign="middle"><td>' + roles[i]['name'] + '</td>';
+				content += '<td><select id="activity_' + roles[i]['id'] + '">';
+				for (var j = 0; j < roles[i]['possibleRoles'].length; j++)
+					content += '<option value="' + roles[i]['possibleRoles'][j]['id'] + '">' + roles[i]['possibleRoles'][j]['name'] + '</option>';
+				content += '</select></td><td>&nbsp;<a href="javascript:clickAddUserToRole(' + data['pid'] + ', $F(\'activity_' + roles[i]['id'] + '\'))"><img border="0" width="13" height="13" src="workflow/templateFile.php?file=images/add.png"/></a></td>';
+				content += '</tr>';
+			}
+			content += '</table>';
+			tdRoles.innerHTML += content;
+		}
+		else
+		{
+			var content = '<p class="text_dsp">O usuário selecionado já se encontra nos perfis necessários</p>';
+			content += '<br/><center><button onclick="clickReplaceUserAction(' + data['pid'] + ');return false;">Concluir</button></center>';
+			tdRoles.innerHTML = content;
+		}
+	}
+}
+
+function clickCheckUserRoles(pid)
+{
+	if (!$F('newUser'))
+	{
+		alert('Selecione o novo usuário');
+		return;
+	}
+	$('tdRoles').innerHTML = '<h2>Perfis</h2><div id="MonitorLoading"><img src="workflow/templateFile.php?file=images/loading.gif"/> Carregando ...</div>';
+	var params = 'pid=' + pid + '&oldUser=' + $F('oldUser') + '&newUser=' + $F('newUser') + '&activity=' + $F('activity');
+	cExecute("$this.bo_monitors.checkUserRoles", resultClickCheckUserRoles, params);
+}
+
+function clickAddUserToRole(pid, role)
+{
+	$('tdRoles').innerHTML = '<h2>Perfis</h2><div id="MonitorLoading"><img src="workflow/templateFile.php?file=images/loading.gif"/> Carregando ...</div>';
+	var params = 'pid=' + pid + '&oldUser=' + $F('oldUser') + '&newUser=' + $F('newUser') + '&activity=' + $F('activity') + '&role=' + role;
+	cExecute("$this.bo_monitors.addUserToRole", resultClickCheckUserRoles, params);
+}
+
+function clickReplaceUserAction(pid)
+{
+	function resultClickReplaceUserAction(data)
+	{
+		$('MonitorLoading').remove();
+		if (handleError(data))
+		{
+			var content = '<p>' + data['OKCount'] + ' instâncias tiveram seu usuário substituído.</p>';
+			if (data['errorCount'] > 0)
+				content += '<p>' + data['errorCount'] + ' apresentaram problema na atualização. Por favor, tente novamente.</p>';
+			$('divInstance').innerHTML += content;
+		}
+	}
+
+	var params = 'pid=' + pid + '&oldUser=' + $F('oldUser') + '&newUser=' + $F('newUser') + '&activity=' + $F('activity');
+	$('divInstance').innerHTML = '<h2>Substituir Usuário</h2><div id="MonitorLoading"><img src="workflow/templateFile.php?file=images/loading.gif"/> Carregando ...</div>';
+	cExecute("$this.bo_monitors.replaceUser", resultClickReplaceUserAction, params);
+}
+
+function clickShowStatistics(link, pid)
+{
+	function resultShowStatistics(data)
+	{
+		killElement('loading_image_statistics');
+		var divInstance = $('divInstance');
+		if (handleError(data))
+		{
+			if (data.length > 0)
+			{
+				var content = '<h2>Estatísticas</h2>';
+				content += '<table>';
+				for (var i = 0; i < data.length; i++)
+					content += '<tr><td align="center"><img src="' + data[i] + '"/></tr></td>';
+				content += '</table>';
+				divInstance.innerHTML = content;
+			}
+			else
+				divInstance.innerHTML = '<p class="text_dsp">Este processo não possui estatísticas</p>';
+		}
+	}
+
+	var image = document.createElement("IMG");
+	image.setAttribute('src', 'workflow/templateFile.php?file=images/loading.gif');
+	image.setAttribute('height', '11');
+	image.setAttribute('id', 'loading_image_statistics');
+	link.parentNode.appendChild(image);
+	cExecute ("$this.bo_monitors.showStatistics", resultShowStatistics, 'pid=' + pid);
+}
Index: /sandbox/workflow/branches/993/js/monitors/instances.js
===================================================================
--- /sandbox/workflow/branches/993/js/monitors/instances.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/monitors/instances.js	(revision 795)
@@ -0,0 +1,629 @@
+var workflowMonitorUserMapping;
+var workflowMonitorActivityMapping;
+var sortColumn = 2;
+var order = 'A';
+var workflowMonitorInstancesParams = null;
+var completedSortColumn = 1;
+var completedOrder = 'A';
+
+var workflowMonitorCurrentList = '';
+
+/* retorno do Ajax para listagem de instâncias */
+function instanceList(data)
+{
+	if (handleError(data))
+	{
+		/* salva algumas informações vindas da chamada Ajax */
+		workflowMonitorInstancesParams = data['params'];
+		workflowMonitorUserMapping = data['userMapping'];
+		workflowMonitorActivityMapping = data['activityMapping'];
+
+
+		if (!workflowMonitorInstancesParams['filters'])
+		{
+			$('divInstance').innerHTML = '';
+		}
+		else
+		{
+			var objectRemovalList = new Array();
+			objectRemovalList[0] = $('monitorMessage');
+			objectRemovalList[1] = $('instancesTable');
+			objectRemovalList[2] = $('pagingTop');
+			objectRemovalList[3] = $('pagingBottom');
+			for (var i = 0; i < objectRemovalList.length; i++)
+				if (objectRemovalList[i])
+					objectRemovalList[i].remove();
+		}
+
+		if (data['data'].length == 0)
+		{
+			var divInstance = $('divInstance');
+			if (workflowMonitorInstancesParams['filters'])
+			{
+				new Insertion.Bottom(divInstance, '<p id="monitorMessage" style="clear: both;">Nenhuma instância satisfaz o critério de filtragem utilizado</p>');
+				$('instanceCount').innerHTML = '0';
+			}
+			else
+				divInstance.innerHTML = '<p>Este processo não possui instâncias ativas</p>';
+		}
+		else
+			drawInstancesList(data);
+	}
+}
+
+/* retorno do Ajax para listagem de usuários */
+function userList(data)
+{
+	if (handleError(data))
+	{
+		if (data['data'].length == 0)
+		{
+			var parag = document.createElement("P");
+			parag.className = "text_dsp";
+			parag.innerHTML = "Não existem usuários";
+			divInstance.appendChild(parag);
+		}
+		else
+		{
+			var aid = data['params']['aid'];
+			var pid = data['params']['pid'];
+			var uid = data['params']['uid'];
+			var iid = data['params']['iid'];
+			var message = document.getElementById("nu_" + iid);
+			var td = message.parentNode;
+			td.innerHTML = constructSelectBox("nu_" + iid, data['data'], uid);
+			td.innerHTML += "<button onclick=\"updateUser(" + iid + ", " + aid + ", " + pid + "); return false;\" class=\"ok\">OK</button>";
+		}
+	}
+}
+
+/* retorno do Ajax para listagem de atividades */
+function activityList(data)
+{
+	if (handleError(data))
+	{
+		if (data['data'].length == 0)
+		{
+			var parag = document.createElement("P");
+			parag.className = "text_dsp";
+			parag.innerHTML = "Não existem atividades";
+			divInstance.appendChild(parag);
+		}
+		else
+		{
+			var aid = data['params']['aid'];
+			var pid = data['params']['pid'];
+			var iid = data['params']['iid'];
+			var message = document.getElementById("na_" + iid);
+			var td = message.parentNode;
+			td.innerHTML = constructSelectBox("na_" + iid, data['data'], aid);
+			td.innerHTML += "<button onclick=\"updateActivity(" + iid + ", " + pid + "); return false;\" class=\"ok\">OK</button>";
+		}
+	}
+}
+
+/**** LISTA DE INSTÂNCIAS DE UM PROCESSO ****/
+function callInstanceList(pid, srt, p_page, p_filters)
+{
+	workflowMonitorCurrentList = 'active';
+	var params = 'pid=' + pid;
+
+	if (srt == null)
+		srt = sortColumn;
+
+	params += '&srt=' + srt;
+
+	if ((srt == sortColumn) && (p_page == null))
+		order = (order == 'A') ? 'D' : 'A';
+	params += '&ord=' + ((order == 'A') ? '__ASC' : '__DESC');
+
+	if (p_page)
+		params += '&p_page=' + p_page;
+
+	sortColumn = srt;
+
+	if (p_filters)
+		params += '&filters=' + p_filters;
+
+	cExecute('$this.bo_monitors.listInstances', instanceList, params);
+}
+
+function resultCompletedInstanceList(data)
+{
+	if (handleError(data))
+	{
+		/* salva algumas informações vindas da chamada Ajax */
+		workflowMonitorInstancesParams = data['params'];
+		workflowMonitorUserMapping = data['userMapping'];
+
+		if (!workflowMonitorInstancesParams['filters'])
+		{
+			$('divInstance').innerHTML = '';
+		}
+		else
+		{
+			var objectRemovalList = new Array();
+			objectRemovalList[0] = $('monitorMessage');
+			objectRemovalList[1] = $('instancesTable');
+			objectRemovalList[2] = $('pagingTop');
+			objectRemovalList[3] = $('pagingBottom');
+			for (var i = 0; i < objectRemovalList.length; i++)
+				if (objectRemovalList[i])
+					objectRemovalList[i].remove();
+		}
+
+		if (data['data'].length == 0)
+		{
+			var divInstance = $('divInstance');
+			if (workflowMonitorInstancesParams['filters'])
+			{
+				$('instanceCount').innerHTML = '0';
+				new Insertion.Bottom(divInstance, '<p id="monitorMessage" style="clear: both;">Nenhuma instância satisfaz o critério de filtragem utilizado</p>');
+			}
+			else
+				divInstance.innerHTML = '<p>Este processo não possui instâncias finalizadas</p>';
+		}
+		else
+			drawCompletedInstancesList(data);
+	}
+}
+
+function drawCompletedInstancesList(data)
+{
+	var instances = data['data'];
+	var pid = data['params']['pid'];
+	var pagingData = data['pagingData'];
+
+	var divInstance = $('divInstance');
+
+	var menuCreated = false;
+	var content = '';
+
+	if (divInstance.innerHTML == '')
+	{
+		menuCreated = true;
+		content += '<h2>Instâncias Finalizadas</h2>';
+		content += '<div id="monitorMenu">';
+		content += '<ul class="horizontalMenu" id="filterMenu" align="center">';
+		content += '<li><a href="javascript:addFilterSelection(true);"><img src="workflow/templateFile.php?file=images/filter_add.png"/>&nbsp;Adicionar Filtro</a></li>';
+		content += '<li><a href="javascript:filterInstances(true);"><img src="workflow/templateFile.php?file=images/filter.png"/>&nbsp;Filtrar</a></li>';
+		if (permissions[pid]['bits'][IP_REMOVE_COMPLETED_INSTANCES])
+			content += '<li><a href="javascript:void(0)" onclick="removeCompletedInstances();"><img src="workflow/templateFile.php?file=images/del_template.png"/>&nbsp;Remover Instâncias</a></li>';
+		content += '</ul>';
+		content += '<span style="float: left; font-size: 11px !important; height: 2.5em; line-height: 2.5em;">&nbsp;&nbsp;&nbsp;<strong>Total de Instâncias:</strong> <span id="instanceCount">' + data['instanceCount'] + '</span></span>';
+		content += '<br/><br/><br/>';
+		content += '</div>';
+	}
+	else
+	{
+		$('instanceCount').innerHTML = data['instanceCount'];
+	}
+
+	var pagingDataCount = pagingData.length;
+	var pagingLinks = '';
+	for (var i = 0; i < pagingDataCount; i++)
+	{
+		if (pagingData[i].do_link == true)
+			pagingLinks += '<a href="javascript:monitorPaginateInstances(' + pagingData[i].p_page + ');">' + pagingData[i].name + '</a>&nbsp;';
+		else
+			pagingLinks += '<strong>' + pagingData[i].name + '</strong>&nbsp;';
+	}
+
+	content += '<div align="right" id="pagingTop">' + pagingLinks + '</div>';
+	content += '<table width="100%" align="center" border="1" class="content_table" id="instancesTable" style="clear: both;">';
+	content += '<tr><th><span onClick="monitorSortInstances(1);" style="cursor:pointer;">ID</span></th><th><span onClick="monitorSortInstances(2);" style="cursor:pointer;">Identificador</span></th><th><span onClick="monitorSortInstances(3);" style="cursor:pointer;">Proprietário</span></th><th><span onClick="monitorSortInstances(4);" style="cursor:pointer;">Pri.</span></th><th><span onClick="monitorSortInstances(5);" style="cursor:pointer;">Data Início</span></th><th><span onClick="monitorSortInstances(6);" style="cursor:pointer;">Data Fim</span></th><th><span onClick="monitorSortInstances(7);" style="cursor:pointer;">Status</span></th><th>Ações</th></tr>';
+
+	/*** gera a lista de instâncias ****/
+	var instanceCount = instances.length;
+	var ownerName = '';
+	for (var i = 0; i < instanceCount; i++)
+	{
+		if (workflowMonitorUserMapping[instances[i]['wf_owner']])
+			ownerName = workflowMonitorUserMapping[instances[i]['wf_owner']];
+		else
+			ownerName = 'ID: ' + instances[i]['wf_owner'];
+
+		if (!instances[i]['wf_instance_name'])
+			instances[i]['wf_instance_name'] = '';
+
+		content += '<tr>';
+
+		/* id da instância */
+		content += '<td>' + instances[i]['wf_instance_id'] + '</td>';
+
+		/* identificador da instância */
+		content += '<td>' + instances[i]['wf_instance_name'] + '</td>';
+
+		/* proprietário da instância */
+		content += '<td>' + ownerName + '</td>';
+
+		/* prioridade da instância */
+		content += '<td>' + instances[i]['wf_priority'] + '</td>';
+
+		/* data início da instância */
+		content += '<td>' + instances[i]['wf_started'] + '</td>';
+
+		/* data fim da instância */
+		content += '<td>' + instances[i]['wf_ended'] + '</td>';
+
+		/* status da instância */
+		content += '<td>' + statusQuickTranslation[instances[i]['wf_status']] + '</td>';
+
+		/* ações da instância */
+		content += '<td><a href="#" onclick="workflowInboxActionView(' + instances[i]['wf_instance_id'] + ', null); return false;">visualizar</a></td>';
+
+		content += '</tr>';
+	}
+
+	content += '</table>';
+	content += '<div align="right" id="pagingBottom">' + pagingLinks + '</div>';
+	new Insertion.Bottom(divInstance, content);
+	if (menuCreated)
+		lb_initialize();
+}
+
+function callCompletedInstanceList(pid, sort, p_page, p_filters)
+{
+	workflowMonitorCurrentList = 'completed';
+	var params = 'pid=' + pid;
+
+	if (sort == null)
+		sort = 1;
+
+	params += '&sort=' + sort;
+
+	if ((sort == completedSortColumn) && (p_page == null))
+		completedOrder = (completedOrder == 'A') ? 'D' : 'A';
+	params += '&ord=' + ((completedOrder == 'A') ? '__ASC' : '__DESC');
+
+	if (p_page)
+		params += '&p_page=' + p_page;
+
+	completedSortColumn = sort;
+
+	if (p_filters)
+		params += '&filters=' + p_filters;
+
+	cExecute('$this.bo_monitors.listCompletedInstances', resultCompletedInstanceList, params);
+}
+
+function drawInstancesList(data)
+{
+	var instances = data['data'];
+	var pid = data['params']['pid'];
+	var pagingData = data['pagingData'];
+
+	var divInstance = $('divInstance');
+
+	var menuCreated = false;
+	var content = '';
+
+	if (divInstance.innerHTML == '')
+	{
+		menuCreated = true;
+		content += '<h2>Instâncias Ativas</h2>';
+		content += '<div id="monitorMenu">';
+		content += '<ul class="horizontalMenu" id="filterMenu" align="center">';
+		content += '<li><a href="javascript:addFilterSelection(false);"><img src="workflow/templateFile.php?file=images/filter_add.png"/>&nbsp;Adicionar Filtro</a></li>';
+		content += '<li><a href="javascript:filterInstances(false);"><img src="workflow/templateFile.php?file=images/filter.png"/>&nbsp;Filtrar</a></li>';
+		if (permissions[pid]['bits'][IP_SEND_EMAILS])
+			content += '<li><a href="javascript:void(0)" onclick="sendMailConfig();" class="lbOn"><img src="workflow/templateFile.php?file=images/mail_new.png"/>&nbsp;Enviar E-mail</a></li>';
+		content += '</ul>';
+		content += '<span style="float: left; font-size: 11px !important; height: 2.5em; line-height: 2.5em;">&nbsp;&nbsp;&nbsp;<strong>Total de Instâncias:</strong> <span id="instanceCount">' + data['instanceCount'] + '</span></span>';
+		content += '<br/><br/><br/>';
+		content += '</div>';
+	}
+	else
+	{
+		$('instanceCount').innerHTML = data['instanceCount'];
+	}
+
+	var pagingDataCount = pagingData.length;
+	var pagingLinks = '';
+	for (var i = 0; i < pagingDataCount; i++)
+	{
+		if (pagingData[i].do_link == true)
+			pagingLinks += '<a href="javascript:monitorPaginateInstances(' + pagingData[i].p_page + ');">' + pagingData[i].name + '</a>&nbsp;';
+		else
+			pagingLinks += '<strong>' + pagingData[i].name + '</strong>&nbsp;';
+	}
+
+	content += '<div align="right" id="pagingTop">' + pagingLinks + '</div>';
+	content += '<table width="100%" align="center" border="1" class="content_table" id="instancesTable" style="clear: both;">';
+	content += '<tr><th><span onClick="monitorSortInstances(1);" style="cursor:pointer;">ID</span></th><th><span onClick="monitorSortInstances(2);" style="cursor:pointer;">Atividade</span></th><th><span onClick="monitorSortInstances(3);" style="cursor:pointer;">Identificador</span></th><th><span onClick="monitorSortInstances(4);" style="cursor:pointer;">Pri.</span></th><th><span onClick="monitorSortInstances(5);" style="cursor:pointer;">Usuário</span></th><th><span onClick="monitorSortInstances(6);" style="cursor:pointer;">Status</span></th><th>Ações</th></tr>';
+
+	/*** gera a lista de instâncias ****/
+	var instanceCount = instances.length;
+	for (var i = 0; i < instanceCount; i++)
+	{
+		content += '<tr>';
+		/* id da instância */
+		content += '<td>' + instances[i]['wf_instance_id'] + '</td>';
+
+		/* atividade da instância */
+		content += '<td>';
+		if (permissions[pid]['bits'][IP_CHANGE_ACTIVITY])
+			content += "<a href=\"\" onclick=\"clickActivity(this, " + instances[i]['wf_p_id']  + ", " + instances[i]['wf_activity_id']  + ", " + instances[i]['wf_instance_id'] + "); return false;\">" + workflowMonitorActivityMapping[instances[i]['wf_activity_id']] + "</a>";
+		else
+			content += workflowMonitorActivityMapping[instances[i]['wf_activity_id']];
+		content += '</td>';
+
+		/* nome da instância */
+		if (!instances[i]['wf_instance_name'])
+			instances[i]['wf_instance_name'] = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
+		content += '<td>';
+		if (permissions[pid]['bits'][IP_CHANGE_NAME])
+			content += "<a href=\"\" onclick=\"clickName(this, " + instances[i]['wf_instance_id'] + ", " + instances[i]['wf_p_id'] + "); return false;\">" + instances[i]['wf_instance_name']  + "</a>";
+		else
+			content += instances[i]['wf_instance_name'];
+		content += '</td>';
+
+		/* prioridade da instância */
+		content += '<td>';
+		if (permissions[pid]['bits'][IP_CHANGE_PRIORITY])
+			content += "<a href=\"\" onclick=\"clickPriority(this, " + instances[i]['wf_instance_id']  + ", " + instances[i]['wf_p_id'] + "); return false;\">" + instances[i]['wf_priority'] + "</a>";
+		else
+			content += instances[i]['wf_priority'];
+		content += '</td>';
+
+		/* usuário da instância */
+		if (workflowMonitorUserMapping[instances[i]['wf_user']])
+			userName = workflowMonitorUserMapping[instances[i]['wf_user']];
+		else
+			userName = 'ID: ' + instances[i]['wf_user'];
+		content += '<td>';
+		if (permissions[pid]['bits'][IP_CHANGE_USER])
+			content += "<a href=\"\" onclick=\"clickUser(this, " + instances[i]['wf_p_id']  + ", " + instances[i]['wf_activity_id']  + ", " + instances[i]['wf_instance_id'] + ", '" + ((instances[i]['wf_user'] == '*') ? '-1' : instances[i]['wf_user']) + "'); return false;\">" + userName + "</a>";
+		else
+			content += userName;
+		content += '</td>';
+
+		/* staus da instância */
+		content += '<td>';
+		if (permissions[pid]['bits'][IP_CHANGE_STATUS])
+			content += "<a href=\"\" onclick=\"clickStatus(this, " + instances[i]['wf_instance_id'] + ", " + instances[i]['wf_p_id'] + ", '" + instances[i]['wf_status'] + "'); return false;\">" + statusQuickTranslation[instances[i]['wf_status']] + "</a>";
+		else
+			content += statusQuickTranslation[instances[i]['wf_status']];
+		content += '</td>';
+
+		instances[i]['wf_actions'] = '';
+		/* ações da instância */
+		if ((permissions[pid]['bits'][IP_VIEW_PROPERTIES]) || (permissions[pid]['bits'][IP_CHANGE_PROPERTIES]))
+			instances[i]['wf_actions'] += '<a href="#" onclick="editProperties(' + instances[i]['wf_instance_id'] + ', ' + instances[i]['wf_p_id'] + '); return false;">propriedades</a>&nbsp;';
+
+		instances[i]['wf_actions'] += '<a href="#" onclick="workflowInboxActionView(' + instances[i]['wf_instance_id'] + ', null); return false;">visualizar</a>';
+
+		content += '<td>';
+		if (!instances[i]['wf_actions'])
+			content += "&nbsp;";
+		else
+			content += instances[i]['wf_actions'];
+		content += '</td>';
+
+		content += '</tr>';
+	}
+
+	content += '</table>';
+	content += '<div align="right" id="pagingBottom">' + pagingLinks + '</div>';
+	new Insertion.Bottom(divInstance, content);
+	if (menuCreated)
+		lb_initialize();
+}
+
+/**** AÇÕES DE ATUALIZAÇÃO DA INSTÂNCIA ****/
+function clickPriority(link, iid, pid)
+{
+	var td = link.parentNode;
+	var previousValue = link.innerHTML;
+	var items = new Array();
+	for (var i = 0; i < 5; i++)
+	{
+		items[i] = new Array();
+		items[i]['id'] = i;
+		items[i]['name'] = i;
+	}
+	td.innerHTML = constructSelectBox('np_' + iid, items, link.innerHTML);
+	td.innerHTML += "<button onclick=\"updatePriority(" + iid + ", " + pid + "); return false;\" class=\"ok\">OK</button>";
+}
+
+function updatePriority(iid, pid)
+{
+	var selectBox = document.getElementById('np_' + iid);
+	var np = selectBox.value;
+	cExecute ("$this.bo_monitors.updatePriority", updatePriorityResult, 'iid=' + iid + '&pid=' + pid + '&np=' + np);
+	selectBox.parentNode.innerHTML = "<p id=\"np_" + iid  + "\" class=\"ajax_message\"> (atualizando) </p>";
+}
+
+function updatePriorityResult(data)
+{
+	if (handleError(data))
+	{
+		var message = document.getElementById('np_' + data['iid']);
+		message.parentNode.innerHTML = "<a href=\"\" onclick=\"clickPriority(this, " + data['iid']  + ", " + data['pid']  + "); return false;\">" + data['np'] + "</a>";
+	}
+}
+
+function clickUser(link, pid, aid, iid, uid)
+{
+	link.parentNode.innerHTML = "<p id=\"nu_" + iid + "\" class=\"ajax_message\"> (carregando lista) </p>";
+	cExecute ("$this.bo_monitors.listUsers", userList, 'pid=' + pid + '&aid=' + aid + '&iid=' + iid  + '&uid=' + uid);
+}
+
+function updateUser(iid, aid, pid)
+{
+	var selectBox = document.getElementById("nu_" + iid);
+	var uid = selectBox.value;
+	cExecute ("$this.bo_monitors.updateUser", updateUserResult, 'iid=' + iid + '&user=' + uid + '&aid=' + aid + '&pid=' + pid);
+	selectBox.parentNode.innerHTML = "<p id=\"nu_" + iid + "\" class=\"ajax_message\"> (atualizando) </p>";
+}
+
+function updateUserResult(data)
+{
+	if (handleError(data))
+	{
+		var message = document.getElementById('nu_' + data['iid']);
+		message.parentNode.innerHTML = "<a href=\"\" onclick=\"clickUser(this, " + data['pid']  + ", " + data['aid']  + ", " + data['iid'] + ", " + data['user']  + "); return false;\">" + data['fullname'] + "</a>";
+	}
+}
+
+function clickActivity(link, pid, aid, iid)
+{
+	link.parentNode.innerHTML = "<p id=\"na_" + iid + "\" class=\"ajax_message\"> (carregando lista) </p>";
+	cExecute ("$this.bo_monitors.listActivities", activityList, 'pid=' + pid + '&aid=' + aid + '&iid=' + iid);
+}
+
+function updateActivity(iid, pid)
+{
+	var selectBox = document.getElementById("na_" + iid);
+	var aid = selectBox.value;
+	cExecute ("$this.bo_monitors.updateActivity", updateActivityResult, 'iid=' + iid + '&aid=' + aid + '&pid=' + pid);
+	selectBox.parentNode.innerHTML = "<p id=\"na_" + iid + "\" class=\"ajax_message\"> (atualizando) </p>";
+}
+
+function updateActivityResult(data)
+{
+	if (handleError(data))
+	{
+		var message = document.getElementById('na_' + data['iid']);
+		message.parentNode.innerHTML = "<a href=\"\" onclick=\"clickActivity(this, " + data['pid']  + ", " + data['aid']  + ", " + data['iid'] + "); return false;\">" + data['name'] + "</a>";
+	}
+}
+
+function clickStatus(link, iid, pid, selected)
+{
+	var td = link.parentNode;
+	td.innerHTML = constructSelectBox('np_' + iid, statusCorrelation, selected);
+	td.innerHTML += "<button onclick=\"updateStatus(" + iid + ", " + pid + "); return false;\" class=\"ok\">OK</button>";
+}
+
+function updateStatus(iid, pid)
+{
+	var selectBox = document.getElementById('np_' + iid);
+	cExecute ("$this.bo_monitors.updateStatus", updateStatusResult, 'iid=' + iid + '&pid=' + pid + '&ns=' + selectBox.value);
+	selectBox.parentNode.innerHTML = "<p id=\"np_" + iid  + "\" class=\"ajax_message\"> (atualizando) </p>";
+}
+
+function updateStatusResult(data)
+{
+	if (handleError(data))
+	{
+		var message = document.getElementById('np_' + data['iid']);
+		if (data['ns'] == 'aborted')
+			message.parentNode.parentNode.remove();
+		else
+			message.parentNode.innerHTML = "<a href=\"\" onclick=\"clickStatus(this, " + data['iid'] + ", " + data['pid'] + ", '" + data['ns'] + "'); return false;\">" + statusQuickTranslation[data['ns']] + "</a>";
+	}
+}
+
+function clickName(link, iid, pid)
+{
+	var td = link.parentNode;
+	if (link.innerHTML == "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")
+		link.innerHTML = "";
+	td.innerHTML = '<input type="text" value="' + link.innerHTML + '" id="nn_' + iid + '"/>';
+	td.innerHTML += "<button onclick=\"updateName(" + iid + ", " + pid + "); return false;\" class=\"ok\">OK</button>";
+	td.childNodes[0].focus();
+	td.childNodes[0].select();
+}
+
+function updateName(iid, pid)
+{
+	var text = document.getElementById("nn_" + iid);
+	cExecute ("$this.bo_monitors.updateName", updateNameResult, 'iid=' + iid + '&pid=' + pid + '&nn=' + escape(text.value));
+	text.parentNode.innerHTML = "<p id=\"nn_" + iid + "\" class=\"ajax_message\"> (atualizando) </p>";
+}
+
+function updateNameResult(data)
+{
+	if (handleError(data))
+	{
+		var message = document.getElementById('nn_' + data['iid']);
+		if (data['nn'] == "")
+			data['nn'] = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
+		message.parentNode.innerHTML = "<a href=\"\" onclick=\"clickName(this, " + data['iid'] + ", " + data['pid'] + "); return false;\">" + data['nn'] + "</a>";
+	}
+}
+
+function editProperties(iid, pid)
+{
+	var border_id = create_border("Propriedades - ID: " + iid);
+	elem = $("content_id_" + border_id);
+	loadProperties(iid, pid, elem);
+}
+
+function monitorPaginateInstances(p_page)
+{
+	if (workflowMonitorCurrentList == 'active')
+		callInstanceList(workflowMonitorInstancesParams['pid'], workflowMonitorInstancesParams['str'], p_page, workflowMonitorInstancesParams['filters']);
+	else
+		callCompletedInstanceList(workflowMonitorInstancesParams['pid'], workflowMonitorInstancesParams['str'], p_page, workflowMonitorInstancesParams['filters']);
+}
+
+function monitorSortInstances(sort)
+{
+	if (workflowMonitorCurrentList == 'active')
+		callInstanceList(workflowMonitorInstancesParams['pid'], sort, null, workflowMonitorInstancesParams['filters']);
+	else
+		callCompletedInstanceList(workflowMonitorInstancesParams['pid'], sort, null, workflowMonitorInstancesParams['filters']);
+}
+
+function loadInstances(pid)
+{
+	for (var i = 0; i < filters.length; i++)
+		filters[i] = null;
+	filters = new Array();
+	callInstanceList(pid, null, 0);
+}
+
+function loadCompletedInstances(pid)
+{
+	for (var i = 0; i < filters.length; i++)
+		filters[i] = null;
+	filters = new Array();
+	callCompletedInstanceList(pid, null, 0);
+}
+
+function loadInconsistentInstances(pid)
+{
+	cExecute('$this.bo_monitors.loadInconsistentInstances', resultInconsistentInstances, 'pid=' + pid);
+}
+
+function resultInconsistentInstances(data)
+{
+	var instances = data['instances'];
+	var names = data['names'];
+	var divInstance = $('divInstance');
+	var content = '';
+
+	content += '<h2>Instâncias Inconsistentes</h2>';
+
+	for (var i = 0; i < instances.length; i++)
+	{
+		content += '<br/><br/><h2 style="text-align: left;">' + instances[i]['name'] + '</h2>';
+		content += '<p style="text-align: left;">' + instances[i]['description'] + '</p>';
+		var instanceList = instances[i]['items'];
+		if (instanceList.length == 0)
+		{
+			content += '<p style="font-weight: bold; font-size: 120%;">Nenhuma ocorrência encontrada.</p>';
+			continue;
+		}
+		content += '<table width="100%" align="center" border="1" class="content_table" id="instancesTable" style="clear: both;">';
+		content += '<tr><th>ID</th><th>Atividade</th><th>Identificador</th><th>Pri.</th><th>Usuário</th><th>Status</th></tr>';
+		for (var j = 0; j < instanceList.length; j++)
+		{
+			if (!instanceList[j]['wf_instance_name'])
+				instanceList[j]['wf_instance_name'] = '';
+			content += '<tr>';
+			content += '<td>' + instanceList[j]['wf_instance_id'] + '</td>';
+			content += '<td>' + instanceList[j]['wf_activity_name'] + '</td>';
+			content += '<td>' + instanceList[j]['wf_instance_name'] + '</td>';
+			content += '<td>' + instanceList[j]['wf_priority'] + '</td>';
+			content += '<td>' + names[instanceList[j]['wf_user']] + '</td>';
+			content += '<td>' + statusQuickTranslation[instanceList[j]['wf_status']] + '</td>';
+			content += '</tr>';
+		}
+		content += '</table>';
+	}
+
+	divInstance.innerHTML = content;
+}
Index: /sandbox/workflow/branches/993/js/monitors/filters.js
===================================================================
--- /sandbox/workflow/branches/993/js/monitors/filters.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/monitors/filters.js	(revision 795)
@@ -0,0 +1,529 @@
+var filters = new Array();
+var completedFilters = new Array();
+
+var Filter = Class.create();
+
+Filter.prototype =
+{
+	initialize: function()
+	{
+		this.index = null;
+		this.id = '';
+	},
+
+	generateHTML: function()
+	{
+	},
+
+	remove: function()
+	{
+		var div = $('divFilterSelection_' + this.index);
+		if (div)
+			div.remove();
+		div = $('filter_' + this.index)
+		if (div)
+			div.remove();
+	},
+
+	removeButtonHTML: function()
+	{
+		var output = '';
+		output = '<a href="javascript:removeFilter(' + this.index + ')"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/button_cancel.png"/></a>';
+		return output;
+	},
+
+	setup: function()
+	{
+	},
+
+	serialize: function(data)
+	{
+		return JSON.stringify(data);
+	},
+
+	ajaxData: function()
+	{
+		return '';
+	}
+};
+
+var FilterActivityDate =
+{
+	id: 'activityDate',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'A <strong>data de chegada na atividade</strong> atual é <select id="' + this.id + '_' + this.index + '_operator">';
+		output += '<option value="EQ">Igual a</option>';
+		output += '<option value="LT">Antes de</option>';
+		output += '<option value="GT">Depois de</option>';
+		output += '</select>';
+		output += ' <input type="text" id="' + this.id + '_' + this.index + '_date" name="' + this.id + '_' + this.index + '_date" value="" size="10" maxlength="10" onkeypress="return(formatCalendarInput(this, event))"/>';
+		output += '<button id="' + this.id + '_' + this.index + '_date-trigger">...</button>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	setup: function()
+	{
+		Calendar.setup({"inputField":this.id + '_' + this.index + '_date',"button":this.id + '_' + this.index + '_date-trigger',"singleClick":true,"name":this.id + '_' + this.index + '_date',"default":true});
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				operator: $F(this.id + '_' + this.index + '_operator'),
+				date: $F(this.id + '_' + this.index + '_date')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceName =
+{
+	id: 'instanceName',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'O <strong>identificador da instância</strong> contém: <input type="text" id="' + this.id + '_' + this.index + '_name">';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				name: $F(this.id + '_' + this.index + '_name')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceID =
+{
+	id: 'instanceID',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'O <strong>ID da instância</strong> é <select id="' + this.id + '_' + this.index + '_operator">';
+		output += '<option value="EQ">Igual a</option>';
+		output += '<option value="LT">Menor que</option>';
+		output += '<option value="GT">Maior que</option>';
+		output += '</select>';
+		output += ' <input type="text" id="' + this.id + '_' + this.index + '_number" size="5"/>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				operator: $F(this.id + '_' + this.index + '_operator'),
+				number: $F(this.id + '_' + this.index + '_number')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstancePriority =
+{
+	id: 'instancePriority',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'A <strong>prioridade da instância</strong> é <select id="' + this.id + '_' + this.index + '_operator">';
+		output += '<option value="EQ">Igual a</option>';
+		output += '<option value="LT">Menor que</option>';
+		output += '<option value="GT">Maior que</option>';
+		output += '</select>';
+		output += ' <select id="' + this.id + '_' + this.index + '_priority">';
+		for (var i = 0; i < 5; i++)
+			output += '<option value="' + i + '">' + i + '</option>';
+		output += '</select>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				operator: $F(this.id + '_' + this.index + '_operator'),
+				priority: $F(this.id + '_' + this.index + '_priority')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceDate =
+{
+	id: 'instanceDate',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'A <strong>data de criação da instância</strong> é <select id="' + this.id + '_' + this.index + '_operator">';
+		output += '<option value="EQ">Igual a</option>';
+		output += '<option value="LT">Antes de</option>';
+		output += '<option value="GT">Depois de</option>';
+		output += '</select>';
+		output += ' <input type="text" id="' + this.id + '_' + this.index + '_date" name="' + this.id + '_' + this.index + '_date" value="" size="10" maxlength="10" onkeypress="return(formatCalendarInput(this, event))"/>';
+		output += '<button id="' + this.id + '_' + this.index + '_date-trigger">...</button>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	setup: function()
+	{
+		Calendar.setup({"inputField":this.id + '_' + this.index + '_date',"button":this.id + '_' + this.index + '_date-trigger',"singleClick":true,"name":this.id + '_' + this.index + '_date',"default":true});
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				operator: $F(this.id + '_' + this.index + '_operator'),
+				date: $F(this.id + '_' + this.index + '_date')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceEndDate =
+{
+	id: 'instanceEndDate',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'A <strong>data de finalização da instância</strong> é <select id="' + this.id + '_' + this.index + '_operator">';
+		output += '<option value="EQ">Igual a</option>';
+		output += '<option value="LT">Antes de</option>';
+		output += '<option value="GT">Depois de</option>';
+		output += '</select>';
+		output += ' <input type="text" id="' + this.id + '_' + this.index + '_date" name="' + this.id + '_' + this.index + '_date" value="" size="10" maxlength="10" onkeypress="return(formatCalendarInput(this, event))"/>';
+		output += '<button id="' + this.id + '_' + this.index + '_date-trigger">...</button>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	setup: function()
+	{
+		Calendar.setup({"inputField":this.id + '_' + this.index + '_date',"button":this.id + '_' + this.index + '_date-trigger',"singleClick":true,"name":this.id + '_' + this.index + '_date',"default":true});
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				operator: $F(this.id + '_' + this.index + '_operator'),
+				date: $F(this.id + '_' + this.index + '_date')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceStatus =
+{
+	id: 'instanceStatus',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'O <strong>status da instância</strong> é: ';
+		output += ' <select id="' + this.id + '_' + this.index + '_status">';
+		for (var i = 0; i < statusCorrelation.length; i++)
+			output += '<option value="' + statusCorrelation[i]['id'] + '">' + statusCorrelation[i]['name'] + '</option>';
+		output += '</select>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				status: $F(this.id + '_' + this.index + '_status')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceActivity =
+{
+	id: 'instanceActivity',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'A <strong>instância encontra-se na atividade</strong>: ';
+		output += '<span id="dummy_' + this.index + '"></span>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	setup: function()
+	{
+		var filterIndex = this.index;
+		var filterID = this.id;
+		function resultInstanceActivitySetup(data)
+		{
+			var content = '';
+			content += ' <select id="' + filterID + '_' + filterIndex + '_activity">';
+			for (var i = 0; i < data['data'].length; i++)
+				content += '<option value="' + data['data'][i]['id'] + '">' + data['data'][i]['name'] + '</option>';
+			content += '</select>';
+
+			new Insertion.Before($('dummy_' + filterIndex), content);
+			$('dummy_' + filterIndex).remove();
+		}
+		cExecute('$this.bo_monitors.listActivities', resultInstanceActivitySetup, 'pid=' + workflowMonitorInstancesParams['pid']);
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				activity: $F(this.id + '_' + this.index + '_activity')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceUser =
+{
+	id: 'instanceUser',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'A <strong>instância encontra-se com o usuário</strong>: ';
+		output += '<span id="dummy_' + this.index + '"></span>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	setup: function()
+	{
+		var filterIndex = this.index;
+		var filterID = this.id;
+		function resultInstanceUserSetup(data)
+		{
+			var content = '';
+			content += ' <select id="' + filterID + '_' + filterIndex + '_user">';
+			for (var i = 0; i < data['users'].length; i++)
+				content += '<option value="' + data['users'][i]['id'] + '">' + data['users'][i]['name'] + '</option>';
+			content += '</select>';
+
+			new Insertion.Before($('dummy_' + filterIndex), content);
+			$('dummy_' + filterIndex).remove();
+		}
+		cExecute("$this.bo_monitors.getUsersInInstances", resultInstanceUserSetup, 'pid=' + workflowMonitorInstancesParams['pid']);
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				user: $F(this.id + '_' + this.index + '_user')
+			};
+		return this.serialize(data);
+	}
+};
+
+var FilterInstanceOwner =
+{
+	id: 'instanceOwner',
+	generateHTML: function()
+	{
+		var output = '';
+		output += '<div id="filter_' + this.index + '">';
+		output += 'O <strong> proprietário da instância</strong> é: ';
+		output += '<span id="dummy_' + this.index + '"></span>';
+		output += '&nbsp;' + this.removeButtonHTML();
+		output += '</div>';
+		return output;
+	},
+
+	setup: function()
+	{
+		var filterIndex = this.index;
+		var filterID = this.id;
+		function resultInstanceOwnerSetup(data)
+		{
+			var content = '';
+			content += ' <select id="' + filterID + '_' + filterIndex + '_owners">';
+			for (var i = 0; i < data['owners'].length; i++)
+				content += '<option value="' + data['owners'][i]['id'] + '">' + (data['owners'][i]['name'] ? data['owners'][i]['name'] : 'ID: ' + data['owners'][i]['id']) + '</option>';
+			content += '</select>';
+
+			new Insertion.Before($('dummy_' + filterIndex), content);
+			$('dummy_' + filterIndex).remove();
+		}
+		cExecute("$this.bo_monitors.getInstancesOwners", resultInstanceOwnerSetup, 'pid=' + workflowMonitorInstancesParams['pid'] + '&currentList=' + workflowMonitorCurrentList);
+	},
+
+	ajaxData: function()
+	{
+		var data =
+			{
+				id: this.id,
+				owner: $F(this.id + '_' + this.index + '_owners')
+			};
+		return this.serialize(data);
+	}
+};
+
+function addFilterSelection(onlyCompletedInstances)
+{
+	var content = '';
+	var index = filters.length;
+
+	var objFilter = new Filter();
+	objFilter.index = index;
+	filters[index] = objFilter;
+
+	content += '<div id="divFilterSelection_' + index + '">';
+	content += '<select id="filterSelect_' + index + '">';
+	if (!onlyCompletedInstances)
+		content += '<option value="instanceActivity">Atividade da Instância</option>';
+	content += '<option value="instanceDate">Data da Instância</option>';
+	if (onlyCompletedInstances)
+		content += '<option value="instanceEndDate">Data de Finalização da Instância</option>';
+	if (!onlyCompletedInstances)
+		content += '<option value="activityDate">Data na Atividade</option>';
+	content += '<option value="instanceID">ID da Instância</option>';
+	content += '<option value="instanceName">Identificador</option>';
+	content += '<option value="instancePriority">Prioridade da Instância</option>';
+	content += '<option value="instanceOwner">Proprietário da Instância</option>';
+	content += '<option value="instanceStatus">Status da Instância</option>';
+	if (!onlyCompletedInstances)
+		content += '<option value="instanceUser">Usuário da Instância</option>';
+	content += '</select>';
+	content += '&nbsp;<a href="javascript:addFilter(' + index + ')"><img border="0" width="16" height="16" src="workflow/templateFile.php?file=images/apply.png"/></a>';
+	content += '&nbsp;' + objFilter.removeButtonHTML();
+	content += '</div>';
+	new Insertion.Before($('filterMenu'), content)
+}
+
+function addFilter(index)
+{
+	var div = $('divFilterSelection_' + index);
+	var selectBox = $('filterSelect_' + index);
+	var selected = $F(selectBox);
+	var content = '';
+
+	switch (selected)
+	{
+		case 'activityDate':
+			Object.extend(filters[index], FilterActivityDate);
+			break;
+
+		case 'instanceName':
+			Object.extend(filters[index], FilterInstanceName);
+			break;
+
+		case 'instanceID':
+			Object.extend(filters[index], FilterInstanceID);
+			break;
+
+		case 'instancePriority':
+			Object.extend(filters[index], FilterInstancePriority);
+			break;
+
+		case 'instanceDate':
+			Object.extend(filters[index], FilterInstanceDate);
+			break;
+
+		case 'instanceEndDate':
+			Object.extend(filters[index], FilterInstanceEndDate);
+			break;
+
+		case 'instanceStatus':
+			Object.extend(filters[index], FilterInstanceStatus);
+			break;
+
+		case 'instanceActivity':
+			Object.extend(filters[index], FilterInstanceActivity);
+			break;
+
+		case 'instanceUser':
+			Object.extend(filters[index], FilterInstanceUser);
+			break;
+
+		case 'instanceOwner':
+			Object.extend(filters[index], FilterInstanceOwner);
+			break;
+	}
+	content += filters[index].generateHTML();
+	new Insertion.Before(div, content);
+
+	filters[index].setup();
+	div.remove();
+}
+
+function removeFilter(index)
+{
+	filters[index].remove();
+	filters[index] = null;
+}
+
+function filterInstances(completedInstances)
+{
+	var ajaxData = new Array();
+	var currentData = '';
+	for (var i = 0; i < filters.length; i++)
+	{
+		/* ignora se o filtro foi removido */
+		if (filters[i] == null)
+			continue;
+
+		/* verifica se os critérios foram satisfeitos */
+		currentData = filters[i].ajaxData();
+		if (currentData == '')
+			continue;
+
+		/* filtro com JSON */
+		ajaxData[ajaxData.length] = filters[i].ajaxData();
+	}
+
+	if (completedInstances)
+	{
+		if (ajaxData.length > 0)
+			callCompletedInstanceList(workflowMonitorInstancesParams['pid'], workflowMonitorInstancesParams['str'], 0, JSON.stringify(ajaxData));
+		else
+			callCompletedInstanceList(workflowMonitorInstancesParams['pid'], workflowMonitorInstancesParams['str'], 0);
+	}
+	else
+	{
+		if (ajaxData.length > 0)
+			callInstanceList(workflowMonitorInstancesParams['pid'], workflowMonitorInstancesParams['str'], 0, JSON.stringify(ajaxData));
+		else
+			callInstanceList(workflowMonitorInstancesParams['pid'], workflowMonitorInstancesParams['str'], 0);
+	}
+}
Index: /sandbox/workflow/branches/993/js/monitors/properties.js
===================================================================
--- /sandbox/workflow/branches/993/js/monitors/properties.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/monitors/properties.js	(revision 795)
@@ -0,0 +1,175 @@
+var vazio = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
+
+function expandInput(name, iid, pid)
+{
+	var input = document.getElementById(name);
+	var td = input.parentNode;
+	var value = input.value;
+
+	td.innerHTML = '<textarea id="' + name  + '" cols="80" rows="10"/>' + value  + '</textarea><button onclick="updateProperty(\'' + name + '\', ' + iid + ', ' + pid + '); return false;">OK</button>';
+}
+
+function loadProperties(iid, pid, div)
+{
+	function loadPropertiesResult(data)
+	{
+		if (handleError(data))
+		{
+			var canChangeProperties = permissions[pid]['bits'][IP_CHANGE_PROPERTIES];
+			var content = '<table width="100%" align="center" border="1" class="content_table" id="tabela_propriedades">';
+			content += '<tr><th>Nome</th><th>Valor</th><th>Ações</th></tr>';
+
+			var row;
+			var propertiesCount = data.length;
+			for (var i = 0; i < propertiesCount; i++)
+			{
+				row = data[i];
+				content += '<tr>';
+
+				/* nome */
+				content += '<td>' + row['name'] + '</td>';
+
+				/* valor */
+				if (row['value'] == '')
+					row['value'] = vazio;
+				content += '<td>';
+
+				if (canChangeProperties)
+				{
+					if (row['complete'] == 1)
+						content += '<a href="#" onclick="clickProperty(this, ' + data['params']['iid'] + ', ' + data['params']['pid'] + '); return false;">' + row['value'] + '</a>';
+					else
+						content += '<a href="#" onclick="clickLargeProperty(this, ' + data['params']['iid'] + ', ' + data['params']['pid'] + ', \'' + row['name'] + '\'); return false;">' + row['value'] + '</a>';
+				}
+				else
+					content += row['value'];
+
+				content += '</td>';
+
+				/* ações */
+				content += '<td>';
+				if (canChangeProperties)
+					content += '<a href="#" onclick="removeProperty(this, ' + data['params']['iid'] + ', ' + data['params']['pid'] + '); return false;">remover</a>';
+				else
+					content += '<i>nenhuma</i>';
+				content += '</td>';
+
+				content += '</tr>';
+			}
+
+			content += '</table>';
+
+			/* adiciona o botão para a criação de novas propriedades */
+			if (canChangeProperties)
+				content = '<table width="75%" align="center"><tr><td><a href="#" onclick="addProperty(' + data['params']['iid'] + ', ' + data['params']['pid'] + '); return false;">Adicionar Propriedade</a></td></tr><tr><td>' + content + '</td></tr></table>';
+			div.innerHTML = content;
+		}
+	}
+	cExecute("$this.bo_monitors.listInstanceProperties", loadPropertiesResult, 'iid=' + iid + '&pid=' + pid);
+}
+
+function clickProperty(link, iid, pid)
+{
+	var value = link.innerHTML;
+	var td = link.parentNode;
+	var name = td.parentNode.childNodes[0].innerHTML;
+	var minimumSize = 7;
+	value = value.replace(/"/g, "&quot;");
+	if (value == vazio)
+		value = "";
+
+	td.innerHTML = '<input type="text" id="' + name  + '" value="' + value + '" size="' + ((value.length > minimumSize) ? value.length : minimumSize) + '" /><button onclick="updateProperty(\'' + name + '\', ' + iid + ', ' + pid + '); return false;">OK</button><button onclick="expandInput(\'' + name + '\', ' + iid + ', ' + pid + '); return false;">+</button>';
+}
+
+function clickLargeProperty(link, iid, pid, name)
+{
+	var td = link.parentNode;
+	var name = td.parentNode.childNodes[0].innerHTML;
+
+	function largePropertyResult(data)
+	{
+		if (handleError(data))
+		{
+			data['value'] = data['value'].replace(/"/g, "&quot;");
+			td.innerHTML = '<textarea id="' + name  + '" cols="80" rows="10"/>' + data['value']  + '</textarea><button onclick="updateProperty(\'' + name + '\', ' + iid + ', ' + pid + '); return false;">OK</button>';
+		}
+	}
+
+	cExecute ("$this.bo_monitors.getCompletePropertyValue", largePropertyResult, 'iid=' + iid + '&pid=' + pid + '&name=' + name);
+}
+
+function updateProperty(name, iid, pid)
+{
+	function updatePropertyResult(data)
+	{
+		if (handleError(data))
+		{
+			data['value'] = data['value'].replace(/"/g, "&quot;");
+			if (data['value'] == "")
+				data['value'] = vazio;
+			if (data['complete'] == 1)
+				document.getElementById(name).parentNode.innerHTML = '<a href="javacript:void(0)" onclick="clickProperty(this, ' + iid + ', ' + pid + '); return false;">' + data['value'] + '</a>';
+			else
+				document.getElementById(name).parentNode.innerHTML = '<a href="javacript:void(0)" onclick="clickLargeProperty(this, ' + iid + ', ' + pid + '); return false;">' + data['value'] + '</a>';
+		}
+	}
+
+	var value = document.getElementById(name).value;
+	if (value == vazio)
+		value = "";
+	cExecute ("$this.bo_monitors.updateProperty", updatePropertyResult, 'iid=' + iid + '&pid=' + pid + '&name=' + name + '&value=' + escape(value));
+}
+
+function addProperty(iid, pid)
+{
+	var novaPropriedade = prompt("Qual o nome da nova propriedade?");
+	if (novaPropriedade)
+	{
+		novaPropriedade = novaPropriedade.replace(/^[ 	]+/g, "");
+		novaPropriedade = novaPropriedade.replace(/[ 	]+$/g, "");
+		novaPropriedade = novaPropriedade.replace(/ /g, "_");
+		novaPropriedade = novaPropriedade.replace(/[^0-9A-Za-z\_]/g, "");
+		if (novaPropriedade.length < 1)
+		{
+			alert("Nome inválido, tente outro.");
+			return;
+		}
+
+		var tabela = $("tabela_propriedades");
+		for (var i = 1; i < tabela.childNodes[0].childNodes.length; i++)
+		{
+			if (tabela.childNodes[0].childNodes[i].childNodes[0].innerHTML == novaPropriedade)
+			{
+				alert("Já existe uma propriedade com este nome.\nModifique a existente ou escolha outro nome.");
+				return;
+			}
+		}
+		var tr = document.createElement("TR");
+		var td01 = document.createElement("TD");
+		var td02 = document.createElement("TD");
+		var td03 = document.createElement("TD");
+		td01.innerHTML = novaPropriedade;
+		td02.innerHTML = '<input type="text" id="' + novaPropriedade  + '" value="" size="27" /><button onclick="updateProperty(\'' + novaPropriedade + '\', ' + iid + ', ' + pid + '); return false;">OK</button><button onclick="expandInput(\'' + novaPropriedade + '\', ' + iid + ', ' + pid + '); return false;">+</button>';
+		td03.innerHTML = '<a href="#" onclick="removeProperty(this, ' + iid + ', ' + pid + '); return false;">remover</a>';
+		tr.appendChild(td01);
+		tr.appendChild(td02);
+		tr.appendChild(td03);
+		tabela.childNodes[0].appendChild(tr);
+	}
+}
+
+function removeProperty(link, iid, pid)
+{
+	function removePropertyResult(data)
+	{
+		if (handleError(data))
+		{
+			var tr = link.parentNode.parentNode;
+			tr.parentNode.removeChild(tr);
+		}
+	}
+
+	var name = link.parentNode.parentNode.childNodes[0].innerHTML;
+	if (confirm("Tem certeza que deseja remover a propriedade \"" + name + "\"?"))
+		cExecute ("$this.bo_monitors.removeProperty", removePropertyResult, 'iid=' + iid + '&pid=' + pid + '&name=' + name);
+}
Index: /sandbox/workflow/branches/993/js/monitors/general.js
===================================================================
--- /sandbox/workflow/branches/993/js/monitors/general.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/monitors/general.js	(revision 795)
@@ -0,0 +1,160 @@
+/* permission index */
+var IP_CHANGE_PRIORITY = 0;
+var IP_CHANGE_USER = 1;
+var IP_CHANGE_STATUS = 2;
+var IP_CHANGE_NAME = 3;
+var IP_CHANGE_ACTIVITY = 4;
+var IP_VIEW_PROPERTIES = 5;
+var IP_CHANGE_PROPERTIES = 6;
+var IP_VIEW_STATISTICS = 7;
+var IP_REMOVE_COMPLETED_INSTANCES = 8;
+var IP_REPLACE_USER = 9;
+var IP_SEND_EMAILS = 10;
+
+/* general use variables */
+var permissions;
+var statusCorrelation = new Array();
+var statusQuickTranslation = new Array();
+for (var k = 0; k < 4; k++)
+	statusCorrelation[k] = new Array();
+statusCorrelation[0]['id'] = 'completed';
+statusCorrelation[0]['name'] = 'completada';
+statusCorrelation[1]['id'] = 'active';
+statusCorrelation[1]['name'] = 'ativa';
+statusCorrelation[2]['id'] = 'aborted';
+statusCorrelation[2]['name'] = 'abortada';
+statusCorrelation[3]['id'] = 'exception';
+statusCorrelation[3]['name'] = 'em exceção';
+
+for (var k = 0; k < 4; k++)
+	statusQuickTranslation[statusCorrelation[k]['id']] = statusCorrelation[k]['name'];
+
+/* constrói tabelas */
+function constructTable(header, content, atributes)
+{
+	/*** constrói a tabela ***/
+	var table = document.createElement("TABLE");
+	/* configura a tabela */
+	if (atributes)
+		for (var i = 0; i < atributes.length; i++)
+			table.setAttribute(atributes[i].key, atributes[i].value);
+	var tbody = document.createElement("TBODY");
+	var tr;
+	var td;
+
+	/* cabeçalho */
+	tr = document.createElement("TR");
+	for (var j = 0; j < header.length; j++)
+	{
+		td = document.createElement("TH");
+		td.innerHTML = header[j].name;
+		tr.appendChild(td);
+	}
+	tbody.appendChild(tr);
+	/* elementos da tabela */
+	for (var i = 0; i < content.length; i++)
+	{
+		tr = document.createElement("TR");
+		if (content[i]['id'])
+			tr.setAttribute('id', content[i]['id']);
+		for (var j = 0; j < header.length; j++)
+		{
+			td = document.createElement("TD");
+			td.innerHTML = content[i][header[j].id];
+			tr.appendChild(td);
+		}
+		tbody.appendChild(tr);
+	}
+	table.appendChild(tbody);
+
+	return table;
+}
+
+/* constrói select boxes */
+function constructSelectBox(name, items, selected)
+{
+	var output = '';
+
+	output = '<select name=\"' + name + '\" id=\"' + name  + '\">';
+	for (var i = 0; i < items.length; i++)
+	{
+		output += '<option value=\"' + items[i]['id']  + '\"';
+		output += ((items[i]['id'] == selected) ? ' selected' : '') + '>';
+		output += items[i]['name'] + '</option>';
+	}
+	output += '</select>';
+
+	return output;
+}
+
+/* constrói o esqueleto da interface */
+function buildProcessInterface()
+{
+	var divContent = document.getElementById('content_id_0');
+	var center = document.createElement("CENTER");
+	var table = document.createElement("TABLE");
+	var tbody = document.createElement("TBODY");
+	var tr = document.createElement("TR");
+	var td1 = document.createElement("TD");
+	var td2 = document.createElement("TD");
+	var div = document.createElement("DIV");
+	var h2 = document.createElement("H2");
+	
+	table.setAttribute('class', 'container');
+	table.setAttribute('className', 'container'); /* required for IE */
+	h2.innerHTML = "Processos";
+	td1.setAttribute('id', 'divProcess');
+	td2.setAttribute('id', 'divOptions');
+	div.setAttribute('id', 'divInstance');
+	tr.appendChild(td1);
+	tr.appendChild(td2);
+	tbody.appendChild(tr);
+	table.appendChild(tbody);
+	center.appendChild(h2);
+	center.appendChild(table);
+	center.appendChild(div);
+
+	divContent.appendChild(center);
+}
+
+/* gerencia possíveis erros oriundos do método chamado pelo Ajax */
+function handleError(data)
+{
+	if (typeof(data) == "string")
+	{
+		write_errors(data);
+		return false;
+	}
+	else
+		return true;
+}
+
+/* gerencia a mudança de aba */
+function changeFolder(index)
+{
+	if (alternate_border(index) == 0)
+	{
+		switch (index)
+		{
+			case 0:
+				buildProcessInterface();
+				listProcesses();
+				break;
+		}
+	}
+}
+
+/* inicia a interface */
+function initMonitoringInterface()
+{
+	initBorders(1);
+
+	var main_body = document.getElementById("main_body");
+	main_body.style.display = '';
+
+	changeFolder(0);
+}
+
+Event.observe(window, 'load', function() {
+	initMonitoringInterface();
+});
Index: /sandbox/workflow/branches/993/js/adminaccess/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminaccess/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminaccess/main.js	(revision 795)
@@ -0,0 +1,99 @@
+var ID_CONTROL_FOLDER   = 0;
+var window_list = new Array;
+
+/* permissions index */
+var permissionList = new Array();
+for (var i = 0; i < 11; i++)
+	permissionList[i] = new Array();
+permissionList[0]['name'] = "Alterar prioridade da instância";
+permissionList[0]['value'] = 0;
+permissionList[1]['name'] = "Alterar usuário da instância";
+permissionList[1]['value'] = 1;
+permissionList[2]['name'] = "Alterar status da instância";
+permissionList[2]['value'] = 2;
+permissionList[3]['name'] = "Alterar identificador da instância";
+permissionList[3]['value'] = 3;
+permissionList[4]['name'] = "Alterar a atividade da instância";
+permissionList[4]['value'] = 4;
+permissionList[5]['name'] = "Visualizar as propriedades da instância";
+permissionList[5]['value'] = 5;
+permissionList[6]['name'] = "Editar as propriedades da instância";
+permissionList[6]['value'] = 6;
+permissionList[7]['name'] = "Visualizar estatísticas";
+permissionList[7]['value'] = 7;
+permissionList[8]['name'] = "Remover instâncias finalizadas";
+permissionList[8]['value'] = 8;
+permissionList[9]['name'] = "Substituir usuário";
+permissionList[9]['value'] = 9;
+permissionList[10]['name'] = "Disparar e-mails";
+permissionList[10]['value'] = 10;
+
+function show_window(titulo,div,width,height)
+{
+  if (!window_list[div.id]) 
+  {
+    if(is_ie){
+        div.style.height = (height + 10) + 'px';
+        div.style.width = (width + 50) + 'px';
+    } else {
+        div.style.height = height + 'px';
+        div.style.width = width + 'px';
+    }
+
+    div.style.visibility = "hidden";
+    div.style.position = "absolute";
+    div.style.zIndex = "10002";
+    var wHeight = div.offsetHeight + "px";
+    var wWidth =  div.offsetWidth   + "px";
+
+    win = new dJSWin({
+         id: 'window_'+div.id,
+         content_id: div.id,
+         width: wWidth,
+         height: wHeight,
+         title_color: '#3978d6',
+         bg_color: '#eee',
+         title: titulo,
+         title_text_color: 'white',
+         button_x_img: _icon_dir + '/winclose.gif',
+         border: true 
+	});
+
+    win.draw();
+	window_list[div.id] = win;
+  } else {
+	win = window_list[div.id];
+  }
+
+  win.open();
+}
+
+function getFolder(id_folder) 
+{
+	return document.getElementById("content_id_"+id_folder);
+}
+
+function init_user_interface() {
+
+	if ((!is_gecko) && (!is_ie6up)) {
+		alert('Seu navegador não suporta o módulo de Workflow.\nInstale o Mozilla FireFox 1.0+ ou Internet Explorer 6.0+.');
+	} else {
+		BordersArray[0] = new setBorderAttributes(0);
+		BordersArray[1] = new setBorderAttributes(1);
+		BordersArray[2] = new setBorderAttributes(2);
+		BordersArray[3] = new setBorderAttributes(3);
+		BordersArray[4] = new setBorderAttributes(4);
+		BordersArray[5] = new setBorderAttributes(5);
+
+		var main_body = document.getElementById("main_body");
+		main_body.style.display = '';
+
+		if (alternate_border(ID_CONTROL_FOLDER) == 0) {
+			draw_control_folder();
+		}
+	}
+}
+
+Event.observe(window, 'load', function() {
+	init_user_interface();
+});
Index: /sandbox/workflow/branches/993/js/adminaccess/control_folder.js
===================================================================
--- /sandbox/workflow/branches/993/js/adminaccess/control_folder.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/adminaccess/control_folder.js	(revision 795)
@@ -0,0 +1,1080 @@
+function change_folder(index)
+{
+	if (alternate_border(index) == 0)
+	{
+		switch (index)
+		{
+			case 0:
+				draw_administration_control();
+				break;
+
+			case 1:
+				draw_development_control();
+				break;
+
+			case 2:
+				draw_organogram_control();
+				break;
+
+			case 3:
+				draw_process_control();
+				break;
+
+			case 4:
+				draw_monitor_control();
+				break;
+
+			case 5:
+				draw_external_application_control();
+				break;
+		}
+	}
+}
+
+function setSelectValue(obj, value)
+{
+	/* IE MAGIC */
+	if (obj.outerHTML)
+	{
+		obj.innerHTML = '';
+		obj.outerHTML = obj.outerHTML.match(/<select[^>]*>/gi) + value + '</select>';
+	}
+	else
+		obj.innerHTML = value;
+}
+
+function del_option_values(element)
+{
+	for (var i = 0; i < element.options.length; i++)
+       	element.options[i--] = null;
+}
+
+function del_selected_reg(id_name)
+{
+	element = document.getElementById(id_name);
+	for(var i = 0;i < element.options.length; i++)
+    	if (element.options[i].selected)
+		{
+       		element.options[i] = null;
+			if (element.options[i])
+				element.options[i].selected = true;
+			else
+				if (i > 0)
+					element.options[--i].selected = true;
+
+			break;
+		}
+}
+
+function del_organogram_admin()
+{
+	var hndDelAdmin = function(data)
+	{
+		refresh_org_admins(data);
+	};
+
+	if (confirm('Tem certeza que deseja excluir o registro selecionado?'))
+	{
+		var sel_org = document.getElementById('sel_org');
+		var sel_org_admin = document.getElementById('sel_org_admin');
+		cExecute ("$this.bo_adminaccess.del_organogram_admin", hndDelAdmin, "org_id="+sel_org.value+"&admin_id="+sel_org_admin.value);
+	}
+}
+
+function del_process_admin()
+{
+	var hndDelProc = function(data)
+	{
+		refresh_proc_admins(data);
+	};
+
+	if (confirm('Tem certeza que deseja excluir o registro selecionado?'))
+	{
+		var sel_proc = document.getElementById('sel_proc');
+		var sel_proc_admin = document.getElementById('sel_proc_admin');
+		cExecute ("$this.bo_adminaccess.del_process_admin", hndDelProc, "proc_id="+sel_proc.value+"&admin_id="+sel_proc_admin.value);
+	}
+}
+
+function del_monitor_admin()
+{
+	var hndDelProc = function(data)
+	{
+		refresh_mon_admins(data);
+	};
+
+	if (confirm('Tem certeza que deseja excluir o registro selecionado?'))
+	{
+		var sel_mon = document.getElementById('sel_mon');
+		var sel_mon_admin = document.getElementById('sel_mon_admin');
+		cExecute ("$this.bo_adminaccess.del_monitor_admin", hndDelProc, "proc_id="+sel_mon.value+"&admin_id="+sel_mon_admin.value);
+	}
+}
+
+function refresh_org_admins(data)
+{
+	var se = document.getElementById('sel_org_admin');
+	
+	del_option_values(se);
+
+	for (i = 0; i < data.length; i++) 
+	{
+		op = document.createElement("OPTION");
+		op.setAttribute('value',data[i]['uidnumber']);
+		op.innerHTML = data[i]['cn'];
+		se.appendChild(op);
+	}
+}
+
+function refresh_proc_admins(data)
+{
+	var se = document.getElementById('sel_proc_admin');
+	
+	del_option_values(se);
+
+	for (i = 0; i < data.length; i++) 
+	{
+		op = document.createElement("OPTION");
+		op.setAttribute('value',data[i]['uidnumber']);
+		op.innerHTML = data[i]['cn'];
+		se.appendChild(op);
+	}
+}
+
+function refresh_mon_admins(data)
+{
+	/* remove information about the user levels */
+	var divUserLevels = document.getElementById("userLevel");
+	divUserLevels.innerHTML = "";
+
+	var se = document.getElementById('sel_mon_admin');
+	
+	del_option_values(se);
+
+	for (i = 0; i < data.length; i++) 
+	{
+		op = document.createElement("OPTION");
+		op.setAttribute('value',data[i]['uidnumber']);
+		op.innerHTML = data[i]['cn'];
+		se.appendChild(op);
+	}
+}
+
+function add_organogram_admins()
+{
+	var hndAddAdmin = function(data)
+	{
+		refresh_org_admins(data);
+		
+		se = document.getElementById('sel_org_user');
+		del_option_values(se); 
+	};
+
+	var sel_org = document.getElementById('sel_org');
+	if (sel_org.value == -1) {
+		alert('É necessário selecionar uma organização.');
+		return;
+	}
+
+	element = document.getElementById('sel_org_user');
+	if (element.options.length == 0) return;
+
+	ids = '';
+	for(var i = 0;i < element.options.length; i++)
+	{
+		if (i) {
+			ids += '.'+element.options[i].value;
+		} else {
+			ids = element.options[i].value;
+		}
+	}
+
+	cExecute ("$this.bo_adminaccess.add_organogram_admins", hndAddAdmin, "org_id="+sel_org.value+"&user_ids="+ids);
+}
+
+function add_process_admins()
+{
+	var hndAddAdmin = function(data)
+	{
+		refresh_proc_admins(data);
+		
+		var se = document.getElementById('sel_proc_user');
+		del_option_values(se); 
+	};
+
+	var sel_proc = document.getElementById('sel_proc');
+	if (sel_proc.value == -1) {
+		alert('É necessário selecionar um processo.');
+		return;
+	}
+
+	var element = document.getElementById('sel_proc_user');
+	if (element.options.length == 0) return;
+
+	ids = '';
+	for(var i = 0;i < element.options.length; i++)
+	{
+		if (i) {
+			ids += '.'+element.options[i].value;
+		} else {
+			ids = element.options[i].value;
+		}
+	}
+
+	cExecute ("$this.bo_adminaccess.add_process_admins", hndAddAdmin, "proc_id="+sel_proc.value+"&user_ids="+ids);
+}
+
+function add_monitor_admins()
+{
+	var hndAddAdmin = function(data)
+	{
+		refresh_mon_admins(data);
+		
+		var se = document.getElementById('sel_mon_user');
+		del_option_values(se); 
+	};
+
+	var sel_mon = document.getElementById('sel_mon');
+	if (sel_mon.value == -1) {
+		alert('É necessário selecionar um processo.');
+		return;
+	}
+
+	var element = document.getElementById('sel_mon_user');
+	if (element.options.length == 0) return;
+
+	ids = '';
+	for(var i = 0;i < element.options.length; i++)
+	{
+		if (i) {
+			ids += '.'+element.options[i].value;
+		} else {
+			ids = element.options[i].value;
+		}
+	}
+
+	cExecute ("$this.bo_adminaccess.add_monitor_admins", hndAddAdmin, "proc_id="+sel_mon.value+"&user_ids="+ids);
+}
+
+function fillOrgAdmins()
+{
+	var hndAdminList = function(data)
+	{
+		refresh_org_admins(data);
+	};
+
+	var sel_org = document.getElementById('sel_org');
+	cExecute ("$this.bo_adminaccess.get_organogram_admins", hndAdminList, "org_id="+sel_org.value);
+}
+
+function fillProcAdmins()
+{
+	var hndAdminList = function(data)
+	{
+		refresh_proc_admins(data);
+	};
+
+	var sel_proc = document.getElementById('sel_proc');
+	cExecute ("$this.bo_adminaccess.get_process_admins", hndAdminList, "proc_id="+sel_proc.value);
+}
+
+function fillMonAdmins()
+{
+	var hndAdminList = function(data)
+	{
+		refresh_mon_admins(data);
+	};
+
+	var sel_mon = document.getElementById('sel_mon');
+	cExecute ("$this.bo_adminaccess.get_monitor_admins", hndAdminList, "proc_id="+sel_mon.value);
+}
+
+function draw_organogram_control()
+{
+	var fillOrgs = function(data)
+	{
+		se = document.getElementById('sel_org');
+
+		op = document.createElement("OPTION");
+		op.setAttribute('value',-1);
+		se.appendChild(op);
+
+		for (i = 0; i < data.length; i++) 
+		{
+			op = document.createElement("OPTION");
+			op.setAttribute('value',data[i]['organizacao_id']);
+			op.innerHTML = data[i]['nome'];
+			se.appendChild(op);
+		}
+	};
+
+
+	var control_folder = getFolder(2);
+	var input_width = '300px';
+	var input_height = '150px';
+
+	control_folder.appendChild(document.createElement('BR'));
+	control_folder.appendChild(document.createElement('BR'));
+
+	tb_out = document.createElement("TABLE");
+	to_out = document.createElement("TBODY");
+	tr_out = document.createElement("TR");
+	td_out = document.createElement("TD");
+
+	tb = document.createElement("TABLE");
+	to = document.createElement("TBODY");
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+
+	td.innerHTML = 'Organização:<br>';
+	se = document.createElement("SELECT");
+	se.setAttribute('name','sel_org');
+	se.setAttribute('id','sel_org');
+	se.onchange = function() { fillOrgAdmins();  };
+	se.style.width = input_width;
+
+	td.appendChild(se);
+	tr.appendChild(td);	
+
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+	td.setAttribute("colSpan", 3);
+	td.innerHTML = "&nbsp;";
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+
+	td.innerHTML = 'Administradores do organograma:<br>';
+	se = document.createElement("SELECT");
+	se.setAttribute('size','10');
+	se.setAttribute('id','sel_org_admin');
+	se.style.width = input_width;
+	se.style.height = input_height;
+
+	td.appendChild(se);
+	tr.appendChild(td);	
+	to.appendChild(tr);
+
+	td = document.createElement('TD');
+	td.setAttribute('align','center');
+	li = document.createElement('A');
+	li.setAttribute('href',"javascript:add_organogram_admins()");
+	im = new Image();
+	im.src = _icon_dir+'/add_org_admin.png';
+	li.appendChild(im);
+	td.appendChild(li);
+	td.appendChild(document.createElement('BR'));
+	li = document.createElement('A');
+	li.setAttribute('href',"javascript:add_organogram_admins()");
+	li.innerHTML = 'Adicionar';
+	td.appendChild(li);
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	td.innerHTML = 'Usuários para adicionar:<br>';
+	td.setAttribute('valign','top');
+	se = document.createElement("SELECT");
+	se.setAttribute('name','file');
+	se.setAttribute('id','sel_org_user');
+	se.setAttribute('size','10');
+	se.style.width  = input_width;
+	se.style.height = input_height;
+
+	td.appendChild(se);
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	
+	td = document.createElement("TD");
+	td.setAttribute('align','right');
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Remover');
+	bt.setAttribute('value','Remover');
+	bt.onclick = function() { del_organogram_admin(); };
+	td.appendChild(bt);
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	td.setAttribute('align','right');
+	
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Selecionar');
+	bt.setAttribute('value','Selecionar');
+	bt.onclick = function() { openParticipants('sel_org_user', 'hidegroups=1'); };
+	td.appendChild(bt);
+
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Remover');
+	bt.setAttribute('value','Remover');
+	bt.onclick = function() { del_selected_reg('sel_org_user'); };
+	td.appendChild(bt);
+	tr.appendChild(td);
+
+	to.appendChild(tr);
+	tb.appendChild(to);
+
+	tb_out.setAttribute('align','center');
+	td_out.appendChild(tb);
+	tr_out.appendChild(td_out);
+	to_out.appendChild(tr_out);
+	tb_out.appendChild(to_out);
+
+	control_folder.appendChild(tb_out);	
+
+	cExecute ("$this.bo_orgchart.listOrganization", fillOrgs, "");
+}
+
+function draw_process_control()
+{
+	var fillProcs = function(data)
+	{
+		var se = document.getElementById('sel_proc');
+
+		var op = document.createElement("OPTION");
+		op.setAttribute('value',-1);
+		se.appendChild(op);
+
+		for (i = 0; i < data.length; i++) 
+		{
+			op = document.createElement("OPTION");
+			op.setAttribute('value',data[i]['proc_in_id']);
+			op.innerHTML = data[i]['proc_st_name'];
+			se.appendChild(op);
+		}
+	};
+
+
+	var control_folder = getFolder(3);
+	var input_width = '300px';
+	var input_height = '150px';
+
+	control_folder.appendChild(document.createElement('BR'));
+	control_folder.appendChild(document.createElement('BR'));
+
+	tb_out = document.createElement("TABLE");
+	to_out = document.createElement("TBODY");
+	tr_out = document.createElement("TR");
+	td_out = document.createElement("TD");
+
+	tb = document.createElement("TABLE");
+	to = document.createElement("TBODY");
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+
+	td.innerHTML = 'Processo:<br>';
+	se = document.createElement("SELECT");
+	se.setAttribute('name','sel_proc');
+	se.setAttribute('id','sel_proc');
+	se.onchange = function() { fillProcAdmins();  };
+	se.style.width = input_width;
+
+	td.appendChild(se);
+	tr.appendChild(td);	
+
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+	td.setAttribute("colSpan", 3);
+	td.innerHTML = "&nbsp;";
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+
+	td.innerHTML = 'Administradores do processo:<br>';
+	se = document.createElement("SELECT");
+	se.setAttribute('size','10');
+	se.setAttribute('id','sel_proc_admin');
+	se.style.width = input_width;
+	se.style.height = input_height;
+
+	td.appendChild(se);
+	tr.appendChild(td);	
+	to.appendChild(tr);
+
+	td = document.createElement('TD');
+	td.setAttribute('align','center');
+	li = document.createElement('A');
+	li.setAttribute('href',"javascript:add_process_admins()");
+	im = new Image();
+	im.src = _icon_dir+'/add_org_admin.png';
+	li.appendChild(im);
+	td.appendChild(li);
+	td.appendChild(document.createElement('BR'));
+	li = document.createElement('A');
+	li.setAttribute('href',"javascript:add_process_admins()");
+	li.innerHTML = 'Adicionar';
+	td.appendChild(li);
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	td.innerHTML = 'Usuários para adicionar:<br>';
+	td.setAttribute('valign','top');
+	se = document.createElement("SELECT");
+	se.setAttribute('name','file');
+	se.setAttribute('id','sel_proc_user');
+	se.setAttribute('size','10');
+	se.style.width  = input_width;
+	se.style.height = input_height;
+
+	td.appendChild(se);
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	
+	td = document.createElement("TD");
+	td.setAttribute('align','right');
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Remover');
+	bt.setAttribute('value','Remover');
+	bt.onclick = function() { del_process_admin(); };
+	td.appendChild(bt);
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	td.setAttribute('align','right');
+	
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Selecionar');
+	bt.setAttribute('value','Selecionar');
+	bt.onclick = function() { openParticipants('sel_proc_user', ''); };
+	td.appendChild(bt);
+
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Remover');
+	bt.setAttribute('value','Remover');
+	bt.onclick = function() { del_selected_reg('sel_proc_user'); };
+	td.appendChild(bt);
+	tr.appendChild(td);
+
+	to.appendChild(tr);
+	tb.appendChild(to);
+
+	tb_out.setAttribute('align','center');
+	td_out.appendChild(tb);
+	tr_out.appendChild(td_out);
+	to_out.appendChild(tr_out);
+	tb_out.appendChild(to_out);
+
+	control_folder.appendChild(tb_out);	
+
+	cExecute ("$this.bo_adminaccess.get_all_processes", fillProcs, "");
+}
+
+function draw_monitor_control()
+{
+	var fillProcsMon = function(data)
+	{
+		var se = document.getElementById('sel_mon');
+
+		var op = document.createElement("OPTION");
+		op.setAttribute('value',-1);
+		se.appendChild(op);
+
+		for (i = 0; i < data.length; i++) 
+		{
+			op = document.createElement("OPTION");
+			op.setAttribute('value',data[i]['proc_in_id']);
+			op.innerHTML = data[i]['proc_st_name'];
+			se.appendChild(op);
+		}
+	};
+
+
+	var control_folder = getFolder(4);
+	var input_width = '300px';
+	var input_height = '150px';
+
+	control_folder.appendChild(document.createElement('BR'));
+	control_folder.appendChild(document.createElement('BR'));
+
+	tb_out = document.createElement("TABLE");
+	to_out = document.createElement("TBODY");
+	tr_out = document.createElement("TR");
+	td_out = document.createElement("TD");
+
+	tb = document.createElement("TABLE");
+	to = document.createElement("TBODY");
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+
+	td.innerHTML = 'Processo:<br>';
+	se = document.createElement("SELECT");
+	se.setAttribute('name','sel_mon');
+	se.setAttribute('id','sel_mon');
+	se.onchange = function() { fillMonAdmins();  };
+	se.style.width = input_width;
+
+	td.appendChild(se);
+	tr.appendChild(td);	
+
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+	td.setAttribute("colSpan", 3);
+	td.innerHTML = "&nbsp;";
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+
+	td.innerHTML = 'Usuários monitores:<br>';
+	se = document.createElement("SELECT");
+	se.setAttribute('size','10');
+	se.setAttribute('id','sel_mon_admin');
+	se.onchange = function() { loadLevel();  };
+	se.style.width = input_width;
+	se.style.height = input_height;
+
+	td.appendChild(se);
+	tr.appendChild(td);	
+	to.appendChild(tr);
+
+	td = document.createElement('TD');
+	td.setAttribute('align','center');
+	li = document.createElement('A');
+	li.setAttribute('href',"javascript:add_monitor_admins()");
+	im = new Image();
+	im.src = _icon_dir+'/add_org_admin.png';
+	li.appendChild(im);
+	td.appendChild(li);
+	td.appendChild(document.createElement('BR'));
+	li = document.createElement('A');
+	li.setAttribute('href',"javascript:add_monitor_admins()");
+	li.innerHTML = 'Adicionar';
+	td.appendChild(li);
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	td.innerHTML = 'Usuários para adicionar:<br>';
+	td.setAttribute('valign','top');
+	se = document.createElement("SELECT");
+	se.setAttribute('name','file');
+	se.setAttribute('id','sel_mon_user');
+	se.setAttribute('size','10');
+	se.style.width  = input_width;
+	se.style.height = input_height;
+
+	td.appendChild(se);
+	tr.appendChild(td);
+	to.appendChild(tr);
+
+	tr = document.createElement("TR");
+	
+	td = document.createElement("TD");
+	td.setAttribute('align','right');
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Remover');
+	bt.setAttribute('value','Remover');
+	bt.onclick = function() { del_monitor_admin(); };
+	td.appendChild(bt);
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	tr.appendChild(td);
+	
+	td = document.createElement("TD");
+	td.setAttribute('align','right');
+	
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Selecionar');
+	bt.setAttribute('value','Selecionar');
+	bt.onclick = function() { openParticipants('sel_mon_user', ''); };
+	td.appendChild(bt);
+
+	bt = document.createElement("INPUT");
+	bt.setAttribute('type','button');
+	bt.setAttribute('name','Remover');
+	bt.setAttribute('value','Remover');
+	bt.onclick = function() { del_selected_reg('sel_mon_user'); };
+	td.appendChild(bt);
+	tr.appendChild(td);
+
+	to.appendChild(tr);
+
+	/* include the cell that will hold the user level interface */
+	tr = document.createElement("TR");
+	td = document.createElement("TD");
+	td.setAttribute("id", "userLevel");
+	td.setAttribute("colSpan", 3);
+	tr.appendChild(td);
+	to.appendChild(tr);
+	tb.appendChild(to);
+
+	tb_out.setAttribute('align','center');
+	td_out.appendChild(tb);
+	tr_out.appendChild(td_out);
+	to_out.appendChild(tr_out);
+	tb_out.appendChild(to_out);
+
+	control_folder.appendChild(tb_out);	
+
+	cExecute ("$this.bo_adminaccess.get_all_processes", fillProcsMon, "");
+}
+
+function draw_external_application_control()
+{
+	function fillExternalApplications(data)
+	{
+		var content = '<option value="-1"></option>';
+		for (i = 0; i < data.length; i++)
+			content += '<option value="' + data[i]['external_application_id'] + '">' + data[i]['name'] + '</option>';
+		setSelectValue(document.getElementById('sel_exa'), content);
+	}
+
+	var inputWidth = '300px';
+	var inputHeight = '150px';
+
+	var content = '<br/><br/>';
+	content += '<table align="center"><tr><td>';
+	content += '<table>';
+	content += '<tr><td>Aplicações Externas:<br/><select name="sel_exa" id="sel_exa" onchange="fillExternalApplicationAdmins();" style="width: ' + inputWidth + ';"></select></td><td></td><td></td></tr>';
+	content += '<tr><td colspan="3">&nbsp;</td></tr>';
+	content += '<tr>';
+	content += '<td>Usuários com acesso:<br/><select id="sel_exa_admin" size="10" style="width: ' + inputWidth + '; height: ' + inputHeight + ';"/></td>';
+	content += '<td align="center"><a href="javascript:addExternalApplicationAdmins()"><img src="' + _icon_dir + 'add_org_admin.png"/></a><br/><a href="javascript:addExternalApplicationAdmins();">Adicionar</a></td>';
+	content += '<td valign="top">Usuários para adicionar:<br/><select id="sel_exa_user" name="file" size="10" style="width: ' + inputWidth + '; height: ' + inputHeight + ';"/></td>';
+	content += '</tr>';
+	content += '<tr>';
+	content += '<td align="right"><input type="button" name="Remover" value="Remover" onclick="deleteExternalApplicationAdmin();"/></td>';
+	content += '<td></td>';
+	content += '<td align="right"><input type="button" name="Selecionar" value="Selecionar" onclick="openParticipants(\'sel_exa_user\', \'\')"/><input type="button" name="Remover" value="Remover" onclick="del_selected_reg(\'sel_exa_user\');"/></td>';
+	content += '</tr>';
+	content += '<tr><td colspan="3"></td></tr>';
+	content += '</table></td></tr></table>';
+
+	getFolder(5).innerHTML = content;
+	cExecute ("$this.bo_external_applications.getExternalApplications", fillExternalApplications, "");
+}
+
+function fillExternalApplicationAdmins()
+{
+	cExecute ("$this.bo_adminaccess.getExternalApplicationAdmins", refreshExternalApplicationAdmins, "external_application_id=" + document.getElementById('sel_exa').value);
+}
+
+function deleteExternalApplicationAdmin()
+{
+	if (confirm('Tem certeza que deseja excluir o registro selecionado?'))
+		cExecute ("$this.bo_adminaccess.deleteExternalApplicationAdmin", refreshExternalApplicationAdmins, "external_application_id=" + document.getElementById('sel_exa').value + "&admin_id=" + document.getElementById('sel_exa_admin').value);
+}
+
+function addExternalApplicationAdmins()
+{
+	var sel_exa = document.getElementById('sel_exa');
+	if (sel_exa.value == -1)
+	{
+		alert('É necessário selecionar uma Aplicação Externa.');
+		return;
+	}
+
+	var element = document.getElementById('sel_exa_user');
+	if (element.options.length == 0)
+		return;
+
+	var ids = '';
+	for(var i = 0; i < element.options.length; i++)
+		ids += ((i == 0) ? '' : '.') + element.options[i].value;
+
+	cExecute("$this.bo_adminaccess.addExternalApplicationAdmins", function(data){refreshExternalApplicationAdmins(data); document.getElementById('sel_exa_user').innerHTML = '';}, "external_application_id="+sel_exa.value+"&user_ids="+ids);
+}
+
+function refreshExternalApplicationAdmins(data)
+{
+	var content = '';
+	for (var i = 0; i < data.length; i++)
+		content += '<option value="' + data[i]['uidnumber'] + '">' + data[i]['cn'] + '</option>';
+	setSelectValue(document.getElementById('sel_exa_admin'), content);
+}
+
+function draw_administration_control()
+{
+	var inputWidth = '300px';
+	var inputHeight = '150px';
+
+	var content = '<br/><br/>';
+	content += '<table align="center"><tr><td>';
+	content += '<table>';
+	content += '<tr>';
+	content += '<td>Administradores do Módulo:<br/><select id="selectWorkflowAdmins" size="10" style="width: ' + inputWidth + '; height: ' + inputHeight + ';"/></td>';
+	content += '<td align="center"><a href="javascript:addWorkflowAdministrators()"><img src="' + _icon_dir + 'add_org_admin.png"/></a><br/><a href="javascript:addWorkflowAdministrators();">Adicionar</a></td>';
+	content += '<td valign="top">Usuários para adicionar:<br/><select id="selectWorkflowUsers" name="file" size="10" style="width: ' + inputWidth + '; height: ' + inputHeight + ';"/></td>';
+	content += '</tr>';
+	content += '<tr>';
+	content += '<td align="right"><input type="button" name="Remover" value="Remover" onclick="deleteWorkflowAdministrators();"/></td>';
+	content += '<td></td>';
+	content += '<td align="right"><input type="button" name="Selecionar" value="Selecionar" onclick="openParticipants(\'selectWorkflowUsers\', \'\')"/><input type="button" name="Remover" value="Remover" onclick="del_selected_reg(\'selectWorkflowUsers\');"/></td>';
+	content += '</tr>';
+	content += '<tr><td colspan="3"></td></tr>';
+	content += '</table></td></tr></table>';
+
+	getFolder(0).innerHTML = content;
+	cExecute ("$this.bo_adminaccess.getWorkflowAdministrators", refreshWorkflowAdministrators, "");
+}
+
+function refreshWorkflowAdministrators(data)
+{
+	var content = '';
+	for (var i = 0; i < data.length; i++)
+		content += '<option value="' + data[i]['uidnumber'] + '">' + data[i]['cn'] + '</option>';
+	setSelectValue(document.getElementById('selectWorkflowAdmins'), content);
+}
+
+function addWorkflowAdministrators()
+{
+	var element = document.getElementById('selectWorkflowUsers');
+	if (element.options.length == 0)
+		return;
+
+	var ids = '';
+	for(var i = 0; i < element.options.length; i++)
+		ids += ((i == 0) ? '' : '.') + element.options[i].value;
+
+	cExecute("$this.bo_adminaccess.addWorkflowAdministrators", function(data){refreshWorkflowAdministrators(data); document.getElementById('selectWorkflowUsers').innerHTML = '';}, "user_ids="+ids);
+}
+
+function deleteWorkflowAdministrators()
+{
+	if (confirm('Tem certeza que deseja excluir o registro selecionado?'))
+		cExecute("$this.bo_adminaccess.deleteWorkflowAdministrators", refreshWorkflowAdministrators, "admin_id=" + document.getElementById('selectWorkflowAdmins').value);
+}
+
+function draw_development_control()
+{
+	var inputWidth = '300px';
+	var inputHeight = '150px';
+
+	var content = '<br/><br/>';
+	content += '<table align="center"><tr><td>';
+	content += '<table>';
+	content += '<tr>';
+	content += '<td>Desenvolvedores de processos:<br/><select id="selectDevelopmentAdmins" size="10" style="width: ' + inputWidth + '; height: ' + inputHeight + ';"/></td>';
+	content += '<td align="center"><a href="javascript:addDevelopmentAdministrators()"><img src="' + _icon_dir + 'add_org_admin.png"/></a><br/><a href="javascript:addDevelopmentAdministrators();">Adicionar</a></td>';
+	content += '<td valign="top">Usuários para adicionar:<br/><select id="selectDevelopmentUsers" name="file" size="10" style="width: ' + inputWidth + '; height: ' + inputHeight + ';"/></td>';
+	content += '</tr>';
+	content += '<tr>';
+	content += '<td align="right"><input type="button" name="Remover" value="Remover" onclick="deleteDevelopmentAdministrators();"/></td>';
+	content += '<td></td>';
+	content += '<td align="right"><input type="button" name="Selecionar" value="Selecionar" onclick="openParticipants(\'selectDevelopmentUsers\', \'\')"/><input type="button" name="Remover" value="Remover" onclick="del_selected_reg(\'selectDevelopmentUsers\');"/></td>';
+	content += '</tr>';
+	content += '<tr><td colspan="3"></td></tr>';
+	content += '</table></td></tr></table>';
+
+	getFolder(1).innerHTML = content;
+	cExecute ("$this.bo_adminaccess.getDevelopmentAdministrators", refreshDevelopmentAdministrators, "");
+}
+
+function refreshDevelopmentAdministrators(data)
+{
+	var content = '';
+	for (var i = 0; i < data.length; i++)
+		content += '<option value="' + data[i]['uidnumber'] + '">' + data[i]['cn'] + '</option>';
+	setSelectValue(document.getElementById('selectDevelopmentAdmins'), content);
+}
+
+function addDevelopmentAdministrators()
+{
+	var element = document.getElementById('selectDevelopmentUsers');
+	if (element.options.length == 0)
+		return;
+
+	var ids = '';
+	for(var i = 0; i < element.options.length; i++)
+		ids += ((i == 0) ? '' : '.') + element.options[i].value;
+
+	cExecute("$this.bo_adminaccess.addDevelopmentAdministrators", function(data){refreshDevelopmentAdministrators(data); document.getElementById('selectDevelopmentUsers').innerHTML = '';}, "user_ids="+ids);
+}
+
+function deleteDevelopmentAdministrators()
+{
+	if (confirm('Tem certeza que deseja excluir o registro selecionado?'))
+		cExecute("$this.bo_adminaccess.deleteDevelopmentAdministrators", refreshDevelopmentAdministrators, "admin_id=" + document.getElementById('selectDevelopmentAdmins').value);
+}
+
+/* construct the user level interface */
+function loadLevel()
+{
+	/* required parameters */
+	var pid = document.getElementById('sel_mon').value;
+	var uid = document.getElementById('sel_mon_admin').value;
+
+	var loadLevelHandler = function(data)
+	{
+		var userLevelContainer = document.getElementById("userLevel");
+		userLevelContainer.innerHTML = "";
+
+		/* checkboxes creation */
+		var checkBoxesPerRow = 2;
+		var tb_out = document.createElement("TABLE");
+		var to_out = document.createElement("TBODY");
+		var tr = document.createElement("TR");
+		var td = document.createElement("TD");
+		td.innerHTML = "Permissões de Acesso:";
+		tr.appendChild(td);
+		to_out.appendChild(tr);
+		var table = document.createElement("TABLE");
+		var tbody = document.createElement("TBODY");
+		table.style.border='1px solid gray';
+		tr = null;
+		td = null;
+		for (var i = 0; i < permissionList.length; i++)
+		{
+			/* create the checkbox and the label */
+			var checkBox = document.createElement("INPUT");
+			checkBox.setAttribute("id", "cb_" + permissionList[i]['value']);
+			checkBox.setAttribute("type", "checkbox");
+			if (data['bits'][permissionList[i]['value']])
+				checkBox.defaultChecked = true;
+
+			var label = "<label for=\"cb_" + permissionList[i]['value']  + "\">" + permissionList[i]['name']  + "</label>";
+			/* if necessary, start a new row */
+			if (!tr || (tr.childNodes.length == 2*checkBoxesPerRow))
+				tr = document.createElement("TR");
+			td = document.createElement("TD");
+			td.innerHTML = label;
+			tr.appendChild(td);
+			td = document.createElement("TD");
+			td.appendChild(checkBox);
+			tr.appendChild(td);
+
+			/* check if the row is "complete" */
+			if (tr.childNodes.length == 2*checkBoxesPerRow)
+			{
+				tbody.appendChild(tr);
+			}
+			else
+			{
+				if (i == (permissionList.length - 1))
+				{
+					tr.appendChild(document.createElement("TD"));
+					tr.appendChild(document.createElement("TD"));
+					tbody.appendChild(tr);
+				}
+			}
+		}
+		tr = document.createElement("TR");
+		td = document.createElement("TD");
+		td.colSpan = 4;
+		td.align = 'center';
+		var toggleButton = document.createElement("BUTTON");
+		toggleButton.onclick = toggleCheckboxes;
+		toggleButton.innerHTML = 'Marcar/Desmarcar Tudo';
+
+		td.appendChild(toggleButton);
+		tr.appendChild(td);
+		tbody.appendChild(tr);
+		table.appendChild(tbody);
+
+		/* submit button */
+		var button = document.createElement("BUTTON");
+		button.onclick = function() { changeUserLevel(); };
+		button.innerHTML = "Salvar";
+
+		tr = document.createElement("TR");
+		td = document.createElement("TD");
+		td.appendChild(table);
+		tr.appendChild(td);
+		to_out.appendChild(tr);
+
+		tr = document.createElement("TR");
+		td = document.createElement("TD");
+		td.setAttribute("align", "right");
+		td.appendChild(button);
+		tr.appendChild(td);
+		to_out.appendChild(tr);
+
+		tb_out.appendChild(to_out);
+		userLevelContainer.appendChild(tb_out);
+	};
+
+	cExecute ("$this.bo_adminaccess.get_monitor_admin_level", loadLevelHandler, "pid=" + pid + "&uid=" + uid);
+}
+
+/* change the user level */
+function changeUserLevel()
+{
+	/* required parameters */
+	var pid = document.getElementById('sel_mon').value;
+	var uid = document.getElementById('sel_mon_admin').value;
+
+	/* check for error (ajax callback) */
+	var changeUserLevelHandler = function(data)
+	{
+		if (typeof(data) == "string")
+			write_errors(data);
+		else
+			write_msg('As permissões foram salvas');
+	};
+	
+	/* generate the new permission string */
+	var newPermission = "";
+	for (var i = 0; i < permissionList.length; i++)
+	{
+		var cb = document.getElementById("cb_" + permissionList[i]['value']);
+		newPermission += permissionList[i]['value'] + "=" + ((cb.checked) ? "1" : "0") + "_";
+	}
+	newPermission = newPermission.substring(0, newPermission.length-1);
+	
+	/* call ajax */
+	cExecute ("$this.bo_adminaccess.set_monitor_admin_level", changeUserLevelHandler, "pid=" + pid + "&uid=" + uid + "&np=" + newPermission);
+}
+
+function toggleCheckboxes()
+{
+	var value = !document.getElementById('cb_' + permissionList[0]['value']).checked;
+	for (var i = 0; i < permissionList.length; i++)
+		document.getElementById('cb_' + permissionList[i]['value']).checked = value;
+}
+
+function draw_control_folder()
+{
+	change_folder(0);
+}
+
+function delUsers()
+{
+    target = window.document.getElementById('user_list');
+
+    for(var i = 0; i < target.options.length; i++)
+    {
+        if(target.options[i].selected)
+        {
+            target.options[i--] = null;
+        }
+    }
+}
Index: /sandbox/workflow/branches/993/js/htmleditor/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmleditor/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmleditor/main.js	(revision 795)
@@ -0,0 +1,34 @@
+function show_messages(text) 
+{
+	messages.addText(text);
+}
+
+/*
+function phpeditor_checksyntax()
+{
+	var chkSyntax = function(data) {
+		show_messages(data);
+	}
+	var txtcode;
+
+	txtcode = editor.getContents();
+	frmSend.code.value = txtcode;
+	cExecuteFormData("$this.bo_editor.check_syntax",frmSend,chkSyntax);
+	editor.setInputFocus();
+}
+*/
+
+function phpeditor_salvar()
+{
+	var hndSalvar = function(data) {
+		show_messages(data);
+	};
+	var txtcode;
+
+	document.title = editor.window_title;
+	txtcode = editor.getContents();
+	frmSend.code.value = txtcode;
+	cExecuteFormData("$this.bo_editor.save_template_source",frmSend,hndSalvar);
+	editor.setInputFocus();
+	editor.unsaved = false;
+}
Index: /sandbox/workflow/branches/993/js/htmleditor/highlight.js
===================================================================
--- /sandbox/workflow/branches/993/js/htmleditor/highlight.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/htmleditor/highlight.js	(revision 795)
@@ -0,0 +1,709 @@
+    /******************************************************************
+     highlight.js                                           Muze Helene
+     ------------------------------------------------------------------
+     Author: Muze (info@muze.nl)
+     Date: 28 februari 2004
+
+     Copyright 2002 Muze
+
+     This file is part of Helene.
+
+     Helene is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published 
+     by the Free Software Foundation; either version 2 of the License, 
+     or (at your option) any later version.
+ 
+     Helene is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with Helene; if not, write to the Free Software 
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  
+     02111-1307  USA
+
+    -------------------------------------------------------------------
+
+     This file contains the syntax highlighting parser
+
+    ******************************************************************/
+  // Parsing smarty tags http://smarty.php.net/
+  // Cofigure the smarty delimiters below ('{%' and '%}' by default)
+  // Unset this flag if you need to parse only PHP
+  var parseSmarty = true;
+
+	/* states */
+	var YY_STATE_HTML = 0;
+	var YY_STATE_PINP = 1;
+	var YY_STATE_DQSTRING = 2;
+	var YY_STATE_SQSTRING = 3;
+  var YY_STATE_SCRIPT = 4;
+  var YY_STATE_BLOCKCOMMENT = 5;
+
+  /* Smarty states */
+  var YYS_STATE_TAG = 101;
+  var YYS_STATE_PARAM = 102;
+  var YYS_STATE_QPARAM = 103;
+
+	/* tokens */
+	var T_VAR = 0;
+	var T_IDENT = 1;
+	var T_FUNCTION = 2;
+	var T_TOKEN = 3;
+	var T_UNKNOWN = 4;
+	var T_PINP_START = 5;
+	var T_PINP_BLOCK = 6;
+	var T_PINP_END = 7;
+	var T_SPACE = 8;
+	var T_DQUOTE = 9;
+	var T_SQUOTE = 10;
+	var T_ESCAPE = 11;
+	var T_SPECIAL_CHAR = 12;
+	var T_OPERATOR = 13;
+	var T_SINGLE_COMMENTS = 14;
+	var T_BLOCKCOMMENT = 15;
+	var T_BLOCKCOMMENT_END = 16;
+	var T_PHP_START = 17;
+	var T_PHP_END = 18;
+	var T_SCRIPT_START = 19;
+	var T_SCRIPT_END = 20;
+	var T_TAB = 21;
+	var T_EMPTY_LINE = 22;
+
+  /*Smarty tokens*/
+  var TS_SMARTY_START = 101;
+  var TS_SMARTY_END = 102;
+  var TS_KEYWORD = 103;
+  var TS_ATTRIBUTE = 104;
+  var TS_ATTRVALUE = 105;
+  var TS_VAR = 106;
+	var TS_ENDTAG = 107;
+
+	var hLines = new Array();
+	var debug = 0;
+	var scannerPos = 0;
+  var hStyles = new Array();
+	var hStateStyles = new Array();
+
+  // May be there is the better place for it but now there
+  initStyleDefault();
+	// Making object from keywords, it makes a big perfomance overhead in IE
+	// and slightly better perfomance in Mozilla
+	// You can define any amount of keyword groups
+	// Words should match ([a-z0-9][a-z0-9_]*) and should be separated by spaces
+	var hPHPKeywords = cacheKeywords( /// TODO: Add more keywords here 
+		"a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dir div dfn dl dt em fieldset font form frame frameset h1 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol optgroup option p param pre q s samp script select small span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt u ul var xmp",
+		"abbr accept accept-charset accesskey action align alink alt archive axis background bgcolor border cellpadding cellspacing char charoff charset checked cite class classid clear code codebase codetype color cols colspan compact content coords data datetime declare defer dir disabled enctype face for frame frameborder headers height href hreflang hspace http-equiv id ismap label lang language link longdesc marginheight marginwidth maxlength media method multiple name nohref noresize noshade nowrap object onblur onchange onclick ondblclick onfocus onkeydown onkeypress onkeyup onload onmousedown onmousemove onmouseout onmouseover onmouseup onreset onselect onsubmit onunload profile prompt readonly rel rev rows rowspan rules scheme scope scrolling selected shape size span src standby start style summary tabindex target text title type usemap valign value valuetype version vlink vspace width" // standart functions
+		);	
+	var hSmartyKeywords = cacheKeywords(
+		"capture config_load foreach foreachelse include include_php insert if else elseif else ldelim rdelim literal php section sectionelse strip assign counter cycle debug eval fetch html_checkboxes html_image html_options html_radios html_select_date html_select_time html_table math mailto popup_init popup textformat", 
+		"name assign file scope global from item key var once script eq ne neq gt lt gte ge lte le not mod is even odd by loop start step max show value skip direction print advance delimiter output selected options separator labels height width basedir alt href prefix time start_year end_year display_days display_months display_years month_format day_format day_value_format year_as_text reverse_years field_array day_size month_size year_size all_extra day_extra month_extra year_extra field_order field_separator month_value_format year_empty month_empty day_empty display_hours diplay_minutes display_seconds display_meridian use_24_hours minute_interval second_interval field_array all_extra hour_extra minute_extra second_extra meridian_extra cols rows inner table_attr tr_attr td_attr trailpad hdir vdir equation format address text encode cc bcc subject newsgroups followupto extra indent indent_first indent_char wrap wrap_char wrap_cut",
+		"capitalize count_characteres cat count_paragraphs count_sentences count_words date_format default escape indent lower nl2br regex_replace replace spacify string_format strip strip_tags truncate upper wordwrap"  
+		); 
+
+	function hLineToken(tokenType, tokenData) {
+		this.type = tokenType;
+		this.data = tokenData;
+		this.reallength = tokenData.length;
+    this.newState = -1;
+
+		switch (this.data) {
+			case '<':	
+				this.data='&lt;';
+			break;
+			case '>':
+				this.data='&gt;';
+			break;
+			case '&':
+				this.data='&amp;';
+			break;
+		}
+	
+		switch (this.type) {
+			case T_PINP_START:
+			case T_PHP_START:
+			case T_PINP_END:
+			case T_PHP_END:
+			case T_SCRIPT_START:
+			case T_SINGLE_COMMENTS:
+			case T_BLOCKCOMMENT:
+			case T_BLOCKCOMMENT_END:
+				this.data = this.data.replace(/[<]/g, '&lt;');
+                this.data = this.data.replace(/[>]/g, '&gt;');
+				var myTabRest = scannerPos % 8;
+                var addLength = 8 - myTabRest;
+				this.data = this.data.replace(/[\t]/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
+                scannerPos += (addLength -1);
+			break;
+			case T_SCRIPT_END:
+				this.data = this.data.replace(/[<]/g, '&lt;');
+				this.data = this.data.replace(/[>]/g, '&gt;');
+			case T_SPACE:
+				this.data = this.data.replace(/[ ]/g, '&nbsp;');
+			break;
+			case T_TAB:
+				var myTabRest = scannerPos % 8;
+				var addLength = 8 - myTabRest;
+				// alert( 'scannerPos ' + scannerPos + ' myTabRest ' + myTabRest + ' addLength ' + addLength);
+				this.data = this.data.replace(/[\t]/g, '<span style="padding-left: '+ (addLength*letterWidth) + 'px;"></span>');
+				scannerPos += (addLength -1);
+			break;
+			case T_EMPTY_LINE:
+				this.data = '<span style="padding-left: 1px;"></span>';
+			break;
+		}
+		scannerPos += tokenData.length;
+	}
+
+	function getToken(sData) {
+		var re, match;
+
+		/* empty line, required for Firefox 1.5.x */
+		if (sData == "")
+		{
+			result = new hLineToken(T_EMPTY_LINE, "");
+			return result;
+		}
+
+		/* white space */
+		re = /^([ ]+)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_SPACE, match[1]);
+			return result;
+		}
+
+		re = /^([\t])/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_TAB, match[1]);
+			return result;
+		}
+
+    /* Smarty tokens */
+    if(parseSmarty) {
+      	re = /^\{\$[a-z_][a-z0-9_]*/i;           // Matches $smarty->left_delimiter
+      	match = re.exec(sData);
+      	if(match) {
+        	return new hLineToken(TS_SMARTY_START, match[0]);
+      	}
+
+      	re = /^\{/;           // Matches $smarty->left_delimiter
+      	match = re.exec(sData);
+      	if(match) {
+        	return new hLineToken(TS_SMARTY_START, match[0]);
+      	}
+
+      	re = /^\}/;           // Matches $smarty->right_delimiter
+      	match = re.exec(sData);
+      	if(match) {
+        	return new hLineToken(TS_SMARTY_END, match[0]);
+      	}
+	  
+	  	//re = /^\/[a-z0-9][a-z0-9_]*/i;
+	  	//match = re.exec(sData);
+	  	//if (match) {
+	    //	result = new hLineToken(TS_ENDTAG, match[0]);
+		//	return result;
+	  	//}		
+    }
+    /* end of smarty tokens */
+
+		/* variable or ident */
+		re = /^([$]|->)?([a-z0-9_][a-z0-9_]*)/i;
+		match = re.exec(sData);
+		if (match) {
+			if (match[1]) {
+				result = new hLineToken(T_VAR, match[0]);
+			} else {
+				result = new hLineToken(T_IDENT, match[2]);
+			}
+			return result;
+		}
+
+		/* single tokens */
+		re = /^([(){},"'\\])/;
+		match = re.exec(sData);
+		if (match) {
+			switch (match[1]) {
+				case '\\':
+					result = new hLineToken(T_ESCAPE, match[1]); 
+				break;
+				case '"':
+					result = new hLineToken(T_DQUOTE, match[1]); 
+				break;
+				case "'":
+					result = new hLineToken(T_SQUOTE, match[1]);
+				break;
+				default:
+					result = new hLineToken(T_SPECIAL_CHAR, match[1]);
+				break;
+			}
+			return result;
+		}
+
+		re = /^((\<\!\-\-)|(\-\-\>))/;
+		match = re.exec(sData);
+		if (match) {
+			if (match[2]) {
+				result = new hLineToken(T_BLOCKCOMMENT, match[2]);
+			} else {
+				result = new hLineToken(T_BLOCKCOMMENT_END, match[3]);
+			}
+			return result;
+		}
+
+		/* comments */
+		re = /^(\/\/.*)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_SINGLE_COMMENTS, match[1]);
+			return result;
+		}
+
+		/* php end tags */
+		re = /^(>)/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_PHP_END, match[0]);
+			return result;
+		}
+
+		re = /^([\-\+\.\*\/\=\%])/;
+		match = re.exec(sData);
+		if (match) {
+			result = new hLineToken(T_OPERATOR, match[1]);
+			return result;
+		}
+
+
+		/* pinp/php tags */
+        re = /^((<))/i;
+		match = re.exec(sData);
+		if (match) {
+			if (match[3]) {
+				result = new hLineToken(T_PINP_END, match[0]);
+			} else
+			if (match[2]) {
+				result = new hLineToken(T_PINP_START, match[0]);
+			} else {
+				result = new hLineToken(T_PINP_START, match[0]);
+			}
+			return result;
+		}
+
+		/* javascript */
+		re = /^<(\/)?script[^>]*>/;
+		match = re.exec(sData);
+		if (match) {
+			if (match[1]) {
+				result = new hLineToken(T_SCRIPT_END, match[0]);
+			} else {
+				result = new hLineToken(T_SCRIPT_START, match[0]);
+			}
+			return result;
+		}
+				
+		return new hLineToken(T_UNKNOWN, sData.charAt(0));
+	}
+
+	function hLineParseString(sData) {
+		var token;
+		this.tokens = new Array();
+
+		scannerPos = 0;
+		do
+		{
+			token = getToken(sData);
+			this.tokens[this.tokens.length] = token;	
+			sData=sData.substring(token.reallength);
+		} while (sData != '');
+	}
+
+      function getElmSpan(token) { /// In the past styles were here
+		var result = '';							// UPDATE: it is better to produce whole span tag here
+    var cls = hStyles[token.type];
+    if(cls!='') result = '<span class="'+cls+'">';
+		else result = '<span>';
+		return result;
+	}
+      function getStateSpan(token) { /// Style span for states
+		var result = '';								// UPDATE: it is better to produce whole span tag here
+    var cls = hStateStyles[token.newState];
+    if(cls!='') result = '<span class="'+cls+'">';
+		else result = '<span>';
+		return result;
+	}
+
+	function hLineDoHighlight(callback) {
+		var state = new Array();
+		var result = '';
+		if (this.lineNo) {
+			/* load parent state */
+			state = state.concat(hLines[this.lineNo-1].getEndState());
+//			alert((this.lineNo-1)+':'+state.length);
+		}
+		for (var i = 0; i<state.length; i++) {
+			if (!state[i].noMultiLine) {
+				result += getStateSpan(state[i]);
+			}
+		}
+		if (this.tokens) {
+			for (var i=0; i<this.tokens.length; i++) {
+				var cState = 0;
+				var token = this.tokens[i];
+				if (state.length) {
+          cState = state[state.length-1].newState; 
+          status = cState;
+				}
+
+        switch (cState) {         // In the past state was the type of opening token
+          case YY_STATE_HTML:     // It is a real state now
+						switch (token.type) {
+              //Smarty highlighting
+              case TS_SMARTY_START:
+                token.newState = YYS_STATE_TAG;
+                result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+                state.push(token);
+              break;
+              //End of smarty highlighting
+							case T_PHP_START:
+							case T_PINP_START:
+								token.newState = YY_STATE_PINP; // We fix the new state here
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token); // But we still saving opening token
+							break;
+							case T_SCRIPT_START:
+                token.newState = YY_STATE_SCRIPT;
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token);
+							break;
+							case T_BLOCKCOMMENT:
+                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
+								result += getStateSpan(token);
+								result += token.data;
+								state.push(token);
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_SCRIPT:
+						switch (token.type) {
+							case T_PHP_START:
+							case T_PINP_START:
+                token.newState = YY_STATE_PINP;
+								if (i == 1 && this.tokens[i-1].type == T_SPACE) {
+									result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
+								} else {
+									result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
+								}
+								state.push(token);
+							break;
+							case T_SCRIPT_END:
+								result += getElmSpan(token)+token.data+'</span>';
+								result += '</span>';
+								state.pop();
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_PINP:
+						switch (token.type) {
+							case T_IDENT:
+								var lower_data = token.data.toLowerCase();
+								var t = hPHPKeywords[lower_data];
+								if(typeof(t)!='undefined') {
+									result += '<span class="h_phpkeywords'+t+'">';
+								} else {
+									result += getElmSpan(token);
+								}
+								result += token.data + '</span>';
+							break;
+							case T_DQUOTE:
+                token.newState = YY_STATE_DQSTRING;
+							case T_SQUOTE:
+                if(token.newState<0) token.newState = YY_STATE_SQSTRING;
+							case T_BLOCKCOMMENT:
+                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
+								result += getStateSpan(token);
+								result += token.data;
+								state.push(token);
+							break;
+							case T_PHP_END:
+							case T_PINP_END:
+								result += getElmSpan(token)+token.data+'</span>';
+								result += '</span>';
+								state.pop();
+							break;
+							case T_VAR:
+							case T_OPERATOR:
+							case T_SPECIAL_CHAR:
+							case T_SINGLE_COMMENTS:
+								result += getElmSpan(token);
+								result += token.data;
+								result += '</span>';
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_BLOCKCOMMENT:
+						switch (token.type) {
+							case T_BLOCKCOMMENT_END:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YY_STATE_DQSTRING:
+						switch (token.type) {
+              case T_DQUOTE:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							case T_ESCAPE:
+								result += token.data;
+								token = this.tokens[++i];
+								result += token.data;
+							break;
+							case T_VAR:
+								result += getElmSpan(token);
+								result += token.data;
+								result += '</span>';
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+                                      case YY_STATE_SQSTRING:
+						switch (token.type) {
+                                                      case T_SQUOTE:
+								result += token.data+'</span>';
+								state.pop();
+							break;
+							case T_ESCAPE:
+								result += token.data;
+								token = this.tokens[++i];
+								result += token.data;
+							break;
+							default:
+								result += token.data;
+							break;
+						}
+					break;
+          case YYS_STATE_TAG:
+            switch (token.type) {
+              case TS_SMARTY_END:
+                result += getElmSpan(token) + token.data + '</span></span>';
+                state.pop();
+              break;
+							case TS_ENDTAG:
+								var t = hSmartyKeywords[token.data.substr(1)];
+								if(t==1) {	// Only the first group has closing tags
+									result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
+								} else {
+									result += token.data;
+								}
+							break;
+							case T_VAR:
+                result += getElmSpan(token) + token.data + '</span>';
+                //result += token.data;
+								break;								
+							case T_IDENT:
+								var t = hSmartyKeywords[token.data];
+								if(typeof(t)!='undefined' /*&& 
+									(t>3 ||	// first three groups of keywords may appear
+										(i>0 && this.tokens[i-1].type==TS_SMARTY_START))	// immediately after TS_SMARTY_START token only
+										*/) {
+									result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
+								} else {
+									result += token.data;
+								}
+							break;
+              default:
+							result += token.data;
+              break;
+            }
+          break;
+					default:
+						result += token.data;
+					break;
+				}
+			}
+//			alert(this.lineNo+'::'+this.tokens.length+'::'+result);
+
+		}
+		var stateChanged = 0;
+		if (state.length != this.getEndState().length) {
+			stateChanged = 1;
+		}
+
+		for (i=state.length-1; i>=0; i--) {
+			if (!stateChanged && state[i].type!=this.getEndState()[i].type) {
+				stateChanged = 1;
+			}
+			if (!state[i].noMultiLine) {
+				result += getElmSpan(state[i]);
+			}
+		}
+
+		/* report update */
+		if (callback) {
+//			alert(this.lineNo+"::"+result);
+			if (result) {
+//				alert(this.lineNo+': 2 eol chars: "'+result.substr(result.length-2)+'"');
+			}
+			callback(this.lineNo, result);
+		}
+		this.setEndState(state);
+              if (stateChanged) {
+			if (debug) alert('updating: '+this.lineNo+1); 
+      /// This makes a stack overflow
+      /// so we are returning 'true' that means next line must be updated
+      //~ hLines[this.lineNo+1].doHighlight(callback);
+                      return true;
+		}
+    /// Next line need not be updated
+    return false;
+	}
+
+	function hLineSetEndState(newEndState) {
+//		alert(this.lineNo+': new endstate: '+newEndState.length);
+		var frop=new Array();
+		if (newEndState.length) {
+//			alert(':'+newEndState.toString()+':');
+			this.endState=frop.concat(newEndState); //newEndState; //.toSource();
+		} else {
+			this.endState=new Array();
+		}
+/*
+		var line = hLines[2];
+		if (line) {
+			alert(this.lineNo+'->'+line.endState.length);
+		}
+*/
+	}
+
+	function hLineGetEndState() {
+		return this.endState;
+	}
+
+	function hLineRemove() {
+		if (this.lineNo < (hLines.length-1)) {
+			var len = hLines.length-1;
+			for (var i=this.lineNo; i<len; i++) {
+				hLines[i] = hLines[i+1];
+				hLines[i].lineNo = i;
+			}
+		}
+		hLines.pop();
+	}
+
+	function hLine(lineNo, lineString) {
+		this.lineNo = lineNo;
+		if (lineNo && (lineNo != hLines.length)) {
+			var hLinesLen = hLines.length;
+			for (var i=hLinesLen; i>lineNo; i--) {
+				hLines[i] = hLines[i-1];
+				hLines[i].lineNo = i;
+			}
+		}
+		hLines[lineNo] = this;
+		this.tokens = new Array();
+		this.setEndState = hLineSetEndState;
+		this.setEndState(new Array());
+		this.getEndState = hLineGetEndState;
+		this.remove = hLineRemove;
+
+		this.parseString = hLineParseString;
+		this.parseString(lineString);
+
+		if (debug) alert(this.lineNo);
+		this.doHighlight = hLineDoHighlight;
+	}
+
+	function highlightUpdateLine(lineNo, lineContent, callback) {
+//		alert('update line: '+lineNo+'::'+lineContent);
+		hLines[lineNo].parseString(lineContent);
+              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightDeleteLine(lineNo, callback) {
+//		alert('remove line: '+lineNo);
+		line = hLines[lineNo];
+		line.remove();
+              if (hLines.length && (lineNo < hLines.length))
+      while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightReset() {
+		hLines = new Array();
+		new hLine(0, '');
+	}
+
+	function highlightInsertLine(lineNo, lineContent, callback) {
+		if (lineNo) {
+			lineNo -= 1;
+		}
+//		alert('insert at: '+lineNo+'::'+lineContent);
+		line = new hLine(lineNo, lineContent);
+              while(line.doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+	function highlightAppendLine(lineNo, lineContent, callback) {
+//		alert('append at: '+(lineNo+1)+'::'+lineContent);
+		line = new hLine(lineNo+1, new String(lineContent));
+              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
+	}
+
+  function initStyleDefault() {
+    hStyles[T_PINP_START] =
+    hStyles[T_PINP_END] =
+    hStyles[T_PHP_START] = //'h_pinp';
+    hStyles[T_PHP_END] = //'h_pinp';
+    hStyles[T_VAR] = 'h_var';
+    hStyles[T_IDENT] = 'h_ident';
+    hStyles[T_DQUOTE] = 'h_doublequote';
+    hStyles[T_SQUOTE] = 'h_singlequote';
+    hStyles[T_SPECIAL_CHAR] = 'h_special_char';
+    hStyles[T_OPERATOR] = 'h_operator';
+    hStyles[T_SINGLE_COMMENTS] = 'h_single_comments';
+    hStyles[T_BLOCKCOMMENT] = 'h_blockcomment';
+    hStyles[TS_SMARTY_START] = 'h_smartymarkers';
+    hStyles[TS_SMARTY_END] = 'h_smartymarkers';
+		
+	hStateStyles[YY_STATE_HTML] = '';
+	hStateStyles[YY_STATE_PINP] = 'h_pinp_block';
+	hStateStyles[YY_STATE_DQSTRING] = 'h_doublequote';
+	hStateStyles[YY_STATE_SQSTRING] = 'h_singlequote';
+	hStateStyles[YY_STATE_BLOCKCOMMENT] = 'h_blockcomment';
+	hStateStyles[YY_STATE_SCRIPT] = 'h_scriptblock';
+	hStateStyles[YYS_STATE_TAG] = 'h_smartytag';
+  }
+	function cacheKeywords() {
+		var res = new Object();
+		for(var i=0;i<arguments.length;i++) {
+			var t = String(arguments[i]).split(" ");
+			for(var j=0;j<t.length;j++)
+				res[t[j]]=i+1;
+		}
+		return res;
+	}
Index: /sandbox/workflow/branches/993/js/move_instances/main.js
===================================================================
--- /sandbox/workflow/branches/993/js/move_instances/main.js	(revision 795)
+++ /sandbox/workflow/branches/993/js/move_instances/main.js	(revision 795)
@@ -0,0 +1,213 @@
+function callAjax(action, mode, handler, parameters)
+{
+	var url = '$this.' + action + '.' + mode;
+	if (parameters)
+		cExecute(url, handler, $H(parameters).toQueryString());
+	else
+		cExecute(url, handler);
+}
+
+/* check for error on ajax calls */
+function checkError(data)
+{
+	if (data['error'])
+	{
+		alert(data['error']);
+		return true;
+	}
+	else
+		return false;
+}
+
+/* construct the processes list (combos) */
+function buildProcessesList(data)
+{
+	if (checkError(data))
+		return;
+
+	function createCombo(data, name)
+	{
+		var output = '<select name="' + name + '" id="' + name + '" onchange="loadActivities();">';
+		output += '<option value="-1"></option>';
+		for (var i = 0; i < data.length; i++)
+			output += '<option value="' + data[i]['wf_p_id'] + '">' + data[i]['wf_name'] + ' (v' + data[i]['wf_version'] + ')</option>';
+		output += '</select>';
+		return output;
+	}
+
+	$('divFrom').innerHTML = '<h3>Origem</h3>' + createCombo(data, 'processFrom');
+	$('divTo').innerHTML = '<h3>Destino</h3>' + createCombo(data, 'processTo');
+}
+
+/* load the activities of the selected process */
+function loadActivities()
+{
+	function loadActivitiesResult(data)
+	{
+		if (checkError(data))
+			return;
+
+		var divFromActivities;
+		var divToActivities;
+		if ($('divFromActivities') != null)
+		{
+			$('divTo').removeChild($('divToActivities'));
+			$('divFrom').removeChild($('divWindow'));
+		}
+
+		new Insertion.Bottom($('divTo'), '<div id="divToActivities"></div>');
+		new Insertion.Bottom($('divFrom'), '<div class="window" id="divWindow" style="position: fixed;"><h3 id="fromTitle">Atividades</h3><div id="divFromActivities" class="activities"></div></div>');
+		divToActivities = $('divToActivities');
+		divFromActivities = $('divFromActivities');
+
+		/* create the "from" activities list */
+		var current;
+		for (var i = 0; i < data['from'].length; i++)
+		{
+			current = data['from'][i];
+			divFromActivities.innerHTML += '<h2 class="activity" id="af' + current['wf_activity_id'] + '">' + current['wf_name'] + '</h2>';
+		}
+		/* make the activities draggable */
+		for (var i = 0; i < data['from'].length; i++)
+			new Draggable('af' + data['from'][i]['wf_activity_id'], {revert:true});
+
+		/* create the "to" activities list */
+		for (var i = 0; i < data['to'].length; i++)
+		{
+			current = data['to'][i];
+			divToActivities.innerHTML += '<div class="window"><h3>' + current['wf_name'] + '</h3><div class="activities" style="min-height: 30px;" id="at' + current['wf_activity_id'] + '"></div></div>';
+		}
+
+		/* add a drop zone to the activities div */
+		for (var i = 0; i < data['to'].length; i++)
+			Droppables.add('at' + data['to'][i]['wf_activity_id'], {accept: 'activity', onDrop: dropActivity});
+
+		/* round the corners of the divs */
+		Nifty("div.window h3","top");
+
+		/* add the "Move Instances" button */
+		if (!$('moveInstancesButton'))
+		{
+			new Insertion.Bottom($('mainBody'), '<p id="pInfo">Mova as atividades do processo de origem para as atividades correspondentes do processo de destino</p>')
+			var newContent = '<center><table><tr><td><label><input type="checkbox" name="active" id="active" checked="checked"/> Incluir instâncias ativas</label></td></tr>';
+			newContent += '<tr><td><label><input type="checkbox" name="completed" id="completed" checked="checked"/> Incluir instâncias finalizadas</label></td></tr>';
+			newContent += '<tr><td align="center"><button onclick="moveInstances(); return false;" style="display: none;" id="moveInstancesButton" class="moveInstancesButton">Mover Instâncias</button></td></tr></table></center>';
+			new Insertion.Bottom($('mainBody'), newContent)
+		}
+
+		/* pre-match some activities (based on their names) */
+		autoAssignActivities(data['pre-match']);
+	}
+
+	if (($F('processFrom') == -1) || ($F('processTo') == -1))
+	{
+		if ($('divFromActivities'))
+		{
+			$('divTo').removeChild($('divToActivities'));
+			$('divFrom').removeChild($('divWindow'));
+			$('moveInstancesButton').hide();
+		}
+		return false;
+	}
+	var params = {
+		from: $F('processFrom'),
+		to: $F('processTo')
+	};
+
+	callAjax('bo_move_instances', 'loadActivities', loadActivitiesResult, params);
+}
+
+/* move the instances from on process to another */
+function moveInstances()
+{
+	if ($F('processFrom') == $F('processTo'))
+	{
+		alert('O processo de origem e destino são o mesmo.');
+		return false;
+	}
+
+	if ($$('div#divFromActivities h2').length > 0)
+	{
+		alert('Todas as atividades do processo de origem devem ser mapeadas.');
+		return false;
+	}
+
+	if (!confirm("Tem certeza que deseja mover as instâncias?"))
+		return false;
+
+	function moveInstancesResult(data)
+	{
+		if (checkError(data))
+			return;
+
+		if (data)
+			alert("As instâncias foram movidas com sucesso");
+	}
+
+	var activityMappings = new Array();
+	$A($('divToActivities').childNodes).each(function(toElement)
+		{
+			if (toElement.childNodes[1].childNodes.length > 0)
+			{
+				var toID = toElement.childNodes[1].id.substring(2);
+				activityMappings[toID] = new Array();
+				$A(toElement.childNodes[1].childNodes).each(function (fromElement)
+					{
+						activityMappings[toID][activityMappings[toID].length] = fromElement.id.substring(2);
+					}
+				);
+				activityMappings[toID] = $H(activityMappings[toID]);
+			}
+		}
+	);
+
+	var params = {
+		from: $F('processFrom'),
+		to: $F('processTo'),
+		activityMappings: JSON.stringify($H(activityMappings)),
+		active: $F('active'),
+		completed: $F('completed')
+	};
+
+	callAjax('bo_move_instances', 'moveInstances', moveInstancesResult, params);
+}
+
+/* drag and drop manager */
+function dropActivity(dragElement, dropElement)
+{
+	var parentElement = dragElement.parentNode;
+	dropElement.appendChild(dragElement);
+	if ($('pInfo'))
+	{
+		$('mainBody').removeChild($('pInfo'));
+	}
+	if ((parentElement.childNodes.length == 0) && (parentElement.id == 'divFromActivities'))
+	{
+		var paragraph = document.createElement('p');
+		paragraph.innerHTML = 'sem atividades';
+		parentElement.appendChild(paragraph);
+		$('moveInstancesButton').show();
+	}
+}
+
+/* assign pre-matched activities based on their names */
+function autoAssignActivities(matches)
+{
+	for (var i = 0; i < matches.length; i++)
+		$('at' + matches[i]['to']).appendChild($('af' + matches[i]['from']));
+	if ($('divFromActivities').childNodes.length == 0)
+	{
+		var paragraph = document.createElement('p');
+		paragraph.innerHTML = 'sem atividades';
+		$('divFromActivities').appendChild(paragraph);
+		$('moveInstancesButton').show();
+	}
+	else
+		$('moveInstancesButton').hide();
+}
+
+/* interface start */
+window.onload = function()
+{
+	callAjax('bo_move_instances', 'loadProcesses', buildProcessesList);
+};
Index: /sandbox/workflow/branches/993/index.php
===================================================================
--- /sandbox/workflow/branches/993/index.php	(revision 2372)
+++ /sandbox/workflow/branches/993/index.php	(revision 2372)
@@ -0,0 +1,55 @@
+<?php
+/**************************************************************************\
+* eGroupWare                                                 			   *
+* http://www.egroupware.org                                                *
+* --------------------------------------------                             *
+*  This program is free software; you can redistribute it and/or modify it *
+*  under the terms of the GNU General Public License as published by the   *
+*  Free Software Foundation; either version 2 of the License, or (at your  *
+*  option) any later version.                                              *
+\**************************************************************************/
+
+/* if the menuaction variable is set, then let the expresso index deal with it */
+if (isset($_GET['menuaction']))
+{
+	/* in case it's an Ajax call from the processes, then check for expired session */
+	if (($_GET['menuaction'] == 'workflow.run_activity.goAjax'))
+	{
+		if (empty($_SESSION['phpgw_session']['session_id']))
+		{
+			/* the session is expired, return a NanoAjax exception */
+			require_once dirname(__FILE__) . '/inc/nano/JSON.php';
+			require_once dirname(__FILE__) . '/inc/nano/NanoJsonConverter.class.php';
+			$nanoController = &Factory::newInstance('NanoController');
+			$nanoController->throwErrorOnAllVirtualRequests('__NANOAJAX_SESSION_EXPIRED__');
+			exit;
+		}
+	}
+	chdir('..');
+	require_once 'index.php';
+}
+else
+{
+	$phpgw_info = array();
+	$GLOBALS['phpgw_info']['flags'] = array(
+		'currentapp' => 'workflow',
+		'noheader'   => True,
+		'nonavbar'   => True
+	);
+	require_once '../header.inc.php';
+	require_once 'inc/common.inc.php';
+
+	if (isset($_GET['start_tab']))
+	{
+		$start_tab = $_GET['start_tab'];
+	}
+	else
+	{
+		$GLOBALS['phpgw']->preferences->read_repository();
+		$start_tab = $GLOBALS['phpgw_info']['user']['preferences']['workflow']['startpage'];
+		if (is_null($start_tab))
+			$start_tab = 1;
+	}
+	ExecMethod('workflow.ui_userinterface.draw', $start_tab);
+}
+?>
Index: /sandbox/workflow/branches/993/templates/default/map_roles.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/map_roles.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/map_roles.tpl	(revision 795)
@@ -0,0 +1,136 @@
+{*Smarty template*}
+<a class="pagetitle" href="tiki-g-map_roles.php?p_id={$p_id}">{tr}Map process roles{/tr}</a><br/><br/>
+<a class="linkbut" href="tiki-g-admin_processes.php">{tr}admin processes{/tr}</a>
+<a class="linkbut" href="tiki-g-admin_activities.php?p_id={$p_id}">{tr}admin activities{/tr}</a>
+<a class="linkbut" href="tiki-g-admin_roles.php?p_id={$p_id}">{tr}admin roles{/tr}</a>
+<a class="linkbut" href="tiki-g-admin_processes.php?p_id={$p_id}">{tr}edit this process{/tr}</a><br/><br/>
+{tr}Process:{/tr} {$proc_info.name} {$proc_info.version}<br/>
+
+process graph<br/>
+
+{if count($errors) > 0}
+<div class="wikitext">
+Errors:<br/>
+{section name=ix loop=$errors}
+<small>{$errors[ix]}</small><br/>
+{/section}
+</div>
+{/if}
+
+{if count($roles) > 0}
+	<h3>{tr}Map users to roles{/tr}</h3>
+	<form method="post" action="tiki-g-map_roles.php">
+	<input type="hidden" name="p_id" value="{$p_id|escape}" />
+	<input type="hidden" name="offset" value="{$offset|escape}" />
+	<input type="hidden" name="sort_mode" value="{$sort_mode|escape}" />
+	<input type="hidden" name="find" value="{$find|escape}" />
+	<table class="normal">
+	<tr>
+		<td class="formcolor">{tr}Map{/tr}</td>
+		<td class="formcolor">
+		  <table border="1" >
+		  	<tr>
+		  		<td class="formcolor" >
+		  		{tr}Users{/tr}:
+				<input type="text" size="10" name="find_users" value="{$find_users|escape}" />
+				<input type="submit" name="findusers" value="{tr}filter{/tr}" />	  
+		  		</td>
+		  		<td class="formcolor" >
+	  			{tr}Roles{/tr}:<br/>		  		
+		  		</td>
+		  	</tr>
+		  	<tr>
+		  		<td class="formcolor" >
+					<select name="user[]" multiple="multiple" size="10">
+					{section name=ix loop=$users}
+					<option value="{$users[ix].user|escape}">{$users[ix].user}</option>
+					{/section}
+					</select>
+		  		</td>
+		  		<td class="formcolor" >
+
+					<select name="role[]" multiple="multiple" size="10">
+					{section name=ix loop=$roles}
+					<option value="{$roles[ix].roleId|escape}">{$roles[ix].name}</option>
+					{/section}
+					</select>	  		
+		  		</td>
+		  	</tr>
+		  </table>
+		</td>
+	</tr>
+	
+	<tr>
+		<td class="formcolor">&nbsp;</td>
+		<td class="formcolor">
+			<input type="submit" name="save" value="{tr}map{/tr}" />
+		</td>
+	</tr>
+	</table>
+	</form>
+{else}
+	<h3>{tr}Warning{/tr}</h3>
+	{tr}No roles are defined yet so no roles can be mapped{/tr}<br/>
+{/if}
+
+<h3>{tr}List of mappings{/tr}</h3>
+<form action="tiki-g-map_roles.php" method="post">
+<input type="hidden" name="p_id" value="{$p_id|escape}" />
+<input type="hidden" name="offset" value="{$offset|escape}" />
+<input type="hidden" name="sort_mode" value="{$sort_mode|escape}" />
+{tr}Find{/tr}:<input size="8" type="text" name="find" value="{$find|escape}" />
+<input type="submit" name="filter" value="{tr}find{/tr}" />
+</form>
+<form action="tiki-g-map_roles.php" method="post">
+<input type="hidden" name="p_id" value="{$p_id|escape}" />
+<input type="hidden" name="offset" value="{$offset|escape}" />
+<input type="hidden" name="find" value="{$find|escape}" />
+<input type="hidden" name="sort_mode" value="{$sort_mode|escape}" />
+<table class="normal">
+<tr>
+<td class="heading"><input type="submit" name="delete" value="{tr}del{/tr}" /></td>
+<td class="heading" ><a class="tableheading" href="tiki-g-map_roles.php?p_id={$p_id}&amp;find={$find}&amp;offset={$offset}&amp;sort_mode={if $sort_mode eq 'name_desc'}name_asc{else}name_desc{/if}">{tr}Role{/tr}</a></td>
+<td class="heading" ><a class="tableheading" href="tiki-g-map_roles.php?p_id={$p_id}&amp;find={$find}&amp;offset={$offset}&amp;sort_mode={if $sort_mode eq 'user_desc'}user_asc{else}user_desc{/if}">{tr}User{/tr}</a></td>
+</tr>
+{cycle values="odd,even" print=false}
+{section name=ix loop=$items}
+<tr>
+	<td class="{cycle advance=false}">
+		<input type="checkbox" name="map[{$items[ix].user}:::{$items[ix].roleId}]" />
+	</td>
+	<td class="{cycle advance=false}">
+	  {$items[ix].name}
+	</td>
+	<td class="{cycle}">
+	  {$items[ix].user}
+	</td>
+</tr>
+{sectionelse}
+<tr>
+	<td class="{cycle advance=false}" colspan="3">
+	{tr}No mappings defined yet{/tr}
+	</td>
+</tr>	
+{/section}
+</table>
+</form>
+
+<div class="mini">
+<div align="center">
+{if $prev_offset >= 0}
+[<a class="prevnext" href="{sameurl offset=$prev_offset}">{tr}prev{/tr}</a>]&nbsp;
+{/if}
+{tr}Page{/tr}: {$actual_page}/{$cant_pages}
+{if $next_offset >= 0}
+&nbsp;[<a class="prevnext" href="{sameurl offset=$next_offset}">{tr}next{/tr}</a>]
+{/if}
+{if $direct_pagination eq 'y'}
+<br/>
+{section loop=$cant_pages name=foo}
+{assign var=selector_offset value=$smarty.section.foo.index|times:$maxRecords}
+<a class="prevnext" href="{sameurl offset=$selector_offset}">
+{$smarty.section.foo.index_next}</a>&nbsp;
+{/section}
+{/if}
+</div>
+</div> 
Index: /sandbox/workflow/branches/993/templates/default/editor_messages.html
===================================================================
--- /sandbox/workflow/branches/993/templates/default/editor_messages.html	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/editor_messages.html	(revision 795)
@@ -0,0 +1,29 @@
+<html>
+<script language="javascript1.2">
+
+function addText(txt) {
+	divMsg = document.getElementById('editor_messages');
+	divMsg.innerHTML = txt;
+}
+
+function scrollwin(px)
+{
+	window.scrollBy(0,px);
+}
+
+</script>
+
+<style type="text/css">
+ body,table {	
+ 		font-family: courier, lucidatypewriter;
+        font-size: 11px;
+		color : red;
+		font-weight : bold;
+		background-color : #E8E8E8;
+	  }
+</style>
+<body>
+	<div id='editor_messages' style="position:absolute;top:0px;">
+	</div>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/templates/default/editor.html
===================================================================
--- /sandbox/workflow/branches/993/templates/default/editor.html	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/editor.html	(revision 795)
@@ -0,0 +1,22 @@
+<html>
+<head>
+
+  <title>PHP Editor</title>
+  <link rel="stylesheet" type="text/css" href="css/editor.css">
+  <link rel="stylesheet" type="text/css" href="css/highlight.css">
+  <script src="../../js/phpeditor/highlight.js"></script>
+  <script src="../../js/phpeditor/editor.js"></script>
+</head>
+<body onLoad="init();">
+<div id='codeframe'>
+<div id="linenumbers"></div>
+<div id="inputLine">
+<textarea id="inputLineEntry" wrap="off"></textarea>
+</div>
+<div id="content">
+<ol id="lines"><li>&nbsp;
+</li></ol>
+</div>
+</div>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/templates/default/admin_roles.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/admin_roles.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/admin_roles.tpl	(revision 795)
@@ -0,0 +1,214 @@
+<script language="javascript1.2" src="workflow/js/jscode/participants.js"></script>
+<div style="color:red; text-align:center">{message}</div>
+<div>
+	<div>
+		{proc_bar}
+	</div>
+	<div>
+		{errors}
+	</div>
+</div>
+
+<form action="{form_action_adminroles}" method="post">
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="role_id" value="{role_info_role_id}" />
+<input type="hidden" name="sort_mode" value="{sort_mode}" />
+<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+<input type="hidden" name="find" value="{find}" />
+<input type="hidden" name="start" value="{start}" />
+<table style="border: 1px solid black;width:100%; margin-bottom:10px">
+	<tr class="th">
+		<td colspan="2" style="font-size: 120%; font-weight:bold">
+			{lang_Add_or_edit_a_role}
+		</td>
+	</tr>
+	<tr class="row_on">
+	  <td>{lang_Name}</td>
+	  <td><input type="text" name="name" value="{role_info_name}" /></td>
+	</tr>
+	<tr class="row_off">
+	  <td>{lang_Description}</td>
+	  <td><textarea name="description" rows="4" cols="60">{role_info_description}</textarea></td>
+	</tr>
+	<tr class="th">
+          <td colspan="2">
+	  <table cellpadding="0" cellspacing="0" width="100%">
+		<tr>
+		  <td style="text-align: left; font-weight:bold;"><input type="submit" name="save" value="{lang_save}" /> </td>
+		  <td style="text-align: right; font-weight:bold;"> <input type="submit" name="new_role" value="{lang_New}" /></td>
+		</tr>
+	  </table>
+          </td>
+	</tr>
+</table>
+</form>
+
+<form action="{form_action_adminroles}" method="post">
+<input type="hidden" name="sort_mode" value="{sort_mode}" />
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="role_id" value="{info_role_id}" />
+<input type="hidden" name="sort_mode" value="{sort_mode}" />
+<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+<input type="hidden" name="find" value="{find}" />
+<input type="hidden" name="start" value="{start}" />
+<table style="border: 1px solid black;width:100%; margin-bottom:10px">
+	<tr class="th">
+		<td colspan="3" style="font-size: 120%; font-weight: bold;">
+			{lang_Process_roles}
+		</td>
+	</tr>
+	<tr class="th">
+		<td>{lang_Name}</td>
+		<td>{lang_Description}</td>
+		<td width="1%">&nbsp;</td>
+	</tr>
+	<!-- BEGIN block_process_roles_list -->
+	<tr bgcolor="{color_line}">
+		<td>
+		  <a href="{all_roles_href}">{all_roles_name}</a>
+		</td>
+		<td>
+		  {all_roles_description}
+		</td>
+		<td>
+			<input type="checkbox" name="role[{all_roles_role_id}]" />
+		</td>
+	</tr>
+	<!-- END block_process_roles_list -->
+	<tr class="th">
+		<td colspan="3" align="right">
+			<input type="submit" name="delete_roles" value="{lang_delete_selected}" />
+		</td>
+	</tr>
+</table>
+</form>	
+
+<!-- BEGIN block_map_roles -->
+	<form method="post" action="{form_action_adminroles}">
+	<input type="hidden" name="p_id"       value="{p_id}" />
+	<input type="hidden" name="start"      value="{start}" />
+	<input type="hidden" name="sort_mode"  value="{sort_mode}" />
+	<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+	<input type="hidden" name="search_str" value="{search_str}" />
+	<input type="hidden" name="save_map"   value="{lang_map}" />
+	<table style="border: 1px solid black;width:100%; margin-bottom:10px">
+	<tr class="th">
+		<td colspan="2" style="font-size: 120%; font-weight:bold">
+			{lang_Map_users/groups_to_roles}
+		</td>
+	</tr>
+	<tr class="th">
+		<td width="50%" align="center">
+			{lang_Roles}		  		
+		</td>
+		<td width="50%" align="center">
+			{lang_Users/Groups}
+		</td>
+	</tr>
+	<tr>
+		<td align="center" valign=top>
+			<select name="role[]" size=10 style="width:250px;height:200px;" id='role_list'>
+				<!-- BEGIN block_select_roles -->
+				<option value="{select_role_id}">{select_role_name}</option>
+				<!-- END block_select_roles -->
+			</select>	  		
+		</td>
+		<td align="center" valign=top>
+			<table border=0>
+			<tr><td>
+				<select name="user[]" multiple="multiple" style="width:250px;height:200px" id="user_list">
+					<!-- BEGIN block_select_users -->
+					<!-- <option value="{account_id}">{account_name}</option> -->
+					<!-- END block_select_users -->
+				</select>
+			</td><td valign=center align=center>
+				<a href='javascript:void(0)' onclick="openParticipants('user_list', 'entities=ug&usePreffix=1');"><img border=0 src={src_img_add_users}></a>
+				<br>
+				<a href='javascript:void(0)' onclick="openParticipants('user_list', 'entities=ug&usePreffix=1');">{lang_Add}</a>
+				<br><br>
+				<a href="javascript:void(0)" onclick="participantsRemoveUser(document.getElementById('user_list'));"><img border=0 src={src_img_del_users}></a>
+				<br>
+				<a href='javascript:void(0)' onclick="participantsRemoveUser(document.getElementById('user_list'));">{lang_Remove}</a>
+				<br><br>
+			</td></tr>
+			</table>
+		</td>
+	</tr>
+	<tr class="th">
+		<td colspan="2" style="text-align:center;" class="formcolor">
+			<input type="button" onclick="mapUsers(this.form);" value="{lang_map}" />
+		</td>
+	</tr>
+	</table>
+	</form>
+<!-- END block_map_roles -->
+
+<form action="{form_action_adminroles}" method="post">
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="start" value="{start}" />
+<input type="hidden" name="find" value="{find}" />
+<input type="hidden" name="sort_mode" value="{sort_mode}" />
+<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+<table style="border: 1px solid black;width:100%;">
+	<tr class="th">
+		<td colspan="3" style="font-size: 120%; font-weight:bold">
+			{lang_List_of_mappings}
+		</td>
+	</tr>
+	<tr class="th">
+		<td width="50%">{lang_Role}</td>
+		<td width="49%">{lang_User/Group}</td>
+		<td width="1%">&nbsp;</td>
+	</tr>
+	<!-- BEGIN block_list_mappings -->
+	<tr bgcolor="{color_line}">
+		<td>
+		  {map_role_name}
+		</td>
+		<td>
+		  {map_user_name}
+		</td>
+		<td>
+			<input type="checkbox" name="map[{map_user_id}:::{map_role_id}]" />
+		</td>
+	</tr>
+	<!-- END block_list_mappings -->
+	<tr class="th">
+		<td colspan="3" align="right">
+			<input type="submit" name="delete_map" value="{lang_delete_selected}" />
+		</td>
+	</tr>
+</table>
+</form>
+
+<script language="javascript1.2">
+
+function mapUsers(frm)
+{
+	//selecionou pelo menos um perfil?
+	roles = window.document.getElementById('role_list');
+	role_selected = false;
+	for(var i = 0; i < roles.options.length; i++)
+	{
+		if (roles.options[i].selected)
+		{
+			role_selected = true;
+			break;
+		}
+	}
+
+	//se não selecionou deve avisar o usuário e não efetuar o submit
+	if (!role_selected)
+	{
+		alert("{lang_No_role_was_selected}");
+		return;
+	}
+
+	users = window.document.getElementById('user_list');
+	for(var i = 0;i < users.options.length; i++)
+	{
+		users.options[i].selected = true;
+	}
+	frm.submit();
+}
+</script>
Index: /sandbox/workflow/branches/993/templates/default/external_bridge.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/external_bridge.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/external_bridge.tpl	(revision 795)
@@ -0,0 +1,25 @@
+<html>
+<head>
+<script language="JavaScript">
+{literal}
+function enviarPost()
+{
+	document.getElementById("formBridge").submit();
+}
+{/literal}
+</script>
+</head>
+<body>
+<form name="formBridge" id="formBridge" method="POST" action="{$siteAddress}">
+{$encodedForm}
+</form>
+<script language="JavaScript">
+enviarPost();
+document.write('<p>Se a página não for atualizada em alguns instantes, <a href="#" onClick="enviarPost();">clique aqui</a></p>');
+</script>
+</body>
+<noscript>
+	<p>Seu navegador não suporta JavaScript e, por este motivo, o acesso não poderá ser feito.</p>
+	<p>Tente acessar diretamente o link a seguir e efetue a autenticação: <a href="{$siteAddress}">{$siteAddress}</a></p>
+</noscript>
+</html>
Index: /sandbox/workflow/branches/993/templates/default/userinterface.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/userinterface.tpl	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/userinterface.tpl	(revision 2371)
@@ -0,0 +1,26 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading"/>
+<input type="hidden" value="{$startTab}" id="workflowUserInterfaceStartTab"/>
+{$css}
+{$javaScripts}
+<div id="main_body" style="display:none; width:99.5%;">
+	<table id="border_table" width="auto" height="26" cellspacing="0" cellpadding="0" border="0">
+		<tbody id="border_tbody">
+			<tr id="border_tr">
+			{foreach from=$tabs item=tab name="feTabs"}
+				{assign var='index' value=$smarty.foreach.feTabs.index}
+				<td nowrap class="menu" id="border_id_{$index}" onClick="changeTab({$index})">
+					&nbsp;&nbsp;{$tab}&nbsp;&nbsp;
+				</td>
+			{/foreach}
+				<td nowrap id="border_blank" class="last_menu" width="100%">
+					&nbsp;
+				</td>
+			</tr>
+		</tbody>
+	</table>
+{foreach from=$tabs item=tab name="feTabs"}
+	<div id="content_id_{$smarty.foreach.feTabs.index}" class="conteudo"></div>
+{/foreach}
+</div>
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/notworking.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/notworking.tpl	(revision 1227)
+++ /sandbox/workflow/branches/993/templates/default/notworking.tpl	(revision 1227)
@@ -0,0 +1,21 @@
+{$header}
+<div id="main_body" style="width:99.5%;">
+	<table id="border_table" width="auto" height="26" cellspacing="0" cellpadding="0" border="0" align="center">
+		<tbody>
+			<tr>
+				<td width="100%" align='center' height="100%" valign="center">
+				<div style="background-color:white;height:150px;padding:20px;width:80%;border:1px dashed black"><br>
+					<img align="left" src="templates/default/images/notworking.png" style="margin-right:15px;">
+					<br>
+					<p style="color:darkblue;text-align:justify;font-size:12px">Caro Usu&aacute;rio, <br><br>O <u>m&oacute;dulo workflow</u> do Expresso encontra-se temporariamente indispon&iacute;vel. Por favor, retorne mais tarde.</p>
+					<div style="color:darkblue;font-size:12px" align="right"><b>Suporte Expresso Livre</b></div>
+				</div>
+				{foreach item=msg from=$errors}
+					{$msg}<br>
+				{/foreach}
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</div>
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/after_running.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/after_running.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/after_running.tpl	(revision 795)
@@ -0,0 +1,99 @@
+{* define the variables depending on the event (completed or cancelled) *}
+{if $activityEvent == 'completed'}
+	{assign var="eventImage" value="apply.png"}
+	{assign var="eventTitle" value="Atividade Completada"}
+{else}
+	{assign var="eventImage" value="button_cancel.png"}
+	{assign var="eventTitle" value="Atividade Cancelada"}
+{/if}
+
+{$header}
+
+{* activity errors are displayed here *}
+{if count($activityErrors) > 0}
+	<div id="wf_run_activity_message">
+	{foreach from=$activityErrors item=activityError}
+		<p>{$activityError}</p>
+	{/foreach}
+	</div>
+{/if}
+
+<br/>
+<div id="activityCompleteMessage" align="center">{$activityCompleteMessage}</div>
+<br/><br/>
+
+<table style="border: 1px solid black;margin:0 auto;width:300px;" align="center">
+<tr class="th">
+	<td colspan="2" style="font-size: 18px; font-weight:bold; text-align:center; font-family: Verdana, Arial, Helvetica, sans-serif;">
+		<img align="middle" border="0" src="workflow/templateFile.php?file=images/{$eventImage}">
+        &nbsp;&nbsp;&nbsp;
+		{$eventTitle}
+	</td>
+</tr>
+<tr class="row_on">
+	<td class="th">Processo:</td>
+	<td>{$processName} {$processVersion}</td>
+</tr>
+<tr class="row_off">
+	<td class="th">Atividade:</td>
+	<td>{$activityName}</td>
+</tr>
+<tr class="row_on">
+	<td class="th">Ir Para:</td>
+	<td>{html_options name="redirectionMenu" id="redirectionMenu" options=$activityList onchange="redirectMenu();"}</td>
+</tr>
+</table>
+<br />
+<br/>
+<table style="border: 0px;margin:0 auto; width:600px" align="center">
+	<tr>
+		<td align="center">
+			<a href="workflow/index.php?start_tab=0">
+				<img border=0 src="workflow/templateFile.php?file=images/inbox.png" alt="Atividades Pendentes" title="Atividades Pendentes">
+				<br/>
+				Tarefas Pendentes
+			</a>
+		</td>
+		<td align="center">
+			<a href="workflow/index.php?start_tab=1">
+				<img border=0 src="workflow/templateFile.php?file=images/process.png" alt="Lista de processos" title="Lista de processos">
+				<br/>
+				Processos
+			</a>
+		</td>
+		<td align="center">
+			<a href="workflow/index.php?start_tab=2">
+				<img border=0 src="workflow/templateFile.php?file=images/goto.png" alt="Acompanhamento das atividades" title="Acompanhamento das atividades">
+				<br/>
+				Acompanhamento
+			</a>
+		</td>
+		<td align="center">
+			<a href="workflow/index.php?start_tab=3">
+				<img border=0 src="workflow/templateFile.php?file=images/network.png" alt="Aplicações Externas" title="Aplicações Externas">
+				<br/>
+				Aplicações Externas
+			</a>
+		</td>
+		<td align="center">
+			<a href="workflow/index.php?start_tab=4">
+				<img border=0 src="workflow/templateFile.php?file=images/organograma.png" alt="Organograma" title="Organograma">
+				<br/>
+				Organograma
+			</a>
+		</td>
+	</tr>
+</table>
+<br/>
+<br/>
+
+<script language="javascript1.2">
+{literal}
+function redirectMenu()
+{
+	var element = document.getElementById("redirectionMenu");
+	var activityID = element.options[element.options.selectedIndex].value;
+	location.href = "{/literal}{$activityBaseURL}{literal}/index.php?menuaction=workflow.run_activity.go&activity_id=" + activityID;
+}
+{/literal}
+</script>
Index: /sandbox/workflow/branches/993/templates/default/adminjobs.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/adminjobs.tpl	(revision 989)
+++ /sandbox/workflow/branches/993/templates/default/adminjobs.tpl	(revision 989)
@@ -0,0 +1,144 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading">
+<input type="hidden" value="{$processID}" id="processID">
+<input type="hidden" name="jobID" id="jobID" value=""/>
+{$css}
+{$javaScripts}
+<ul class="horizontalMenu">
+	<li style="height: 2.5em;"><center>Processo<br/><strong>{$processNameVersion}</strong>&nbsp;&nbsp;&nbsp;</center></li>
+	<li><a href="index.php?menuaction=workflow.ui_adminprocesses.form&p_id={$processID}"><img src="workflow/templateFile.php?file=images/change.gif"/>&nbsp;&nbsp;Editar</a></li>
+	<li><a href="index.php?menuaction=workflow.ui_adminactivities.form&p_id={$processID}"><img src="workflow/templateFile.php?file=images/Activity.gif"/>&nbsp;&nbsp;Atividades</a></li>
+	<li><a href="index.php?menuaction=workflow.ui_adminsource.form&p_id={$processID}"><img src="workflow/templateFile.php?file=images/code.png"/>&nbsp;&nbsp;Código</a></li>
+	<li><a href="index.php?menuaction=workflow.ui_adminroles.form&p_id={$processID}"><img src="workflow/templateFile.php?file=images/roles.png"/>&nbsp;&nbsp;Perfis</a></li>
+	<li><a href="index.php?menuaction=workflow.ui_adminactivities.show_graph&p_id={$processID}"><img src="workflow/templateFile.php?file=images/Process.gif"/>&nbsp;&nbsp;Gráfico</a></li>
+	<li><a href="index.php?menuaction=workflow.WorkflowUtils.export&p_id={$processID}"><img src="workflow/templateFile.php?file=images/save.png"/>&nbsp;&nbsp;Exportar</a></li>
+</ul>
+
+<br/><br/><br/>
+<div id="mainBody" style="width:99.5%; clear: both;">
+<div id="jobList"></div>
+<div id="jobResult" style="display: none;"></div>
+<div id="jobForm" style="display: none;">
+	<table>
+		<tr>
+			<td>
+				<label for="name">Nome</label>
+			</td>
+			<td>
+				<input type="text" id="name" name="name" size="49" maxlength="100"/>
+			</td>
+		</tr>
+		<tr>
+			<td>
+				<label for="_description">Descrição</label>
+			</td>
+			<td>
+				<textarea name="_description" id="_description" cols="40" rows="5"></textarea>
+			</td>
+		</tr>
+		<tr>
+			<td colspan="2">
+				<label><input type="checkbox" id="active" />Ativo</label>
+			</td>
+		</tr>
+		<tr>
+			<td>
+				<label for="startDate">Data de Início</label>
+			</td>
+			<td>
+				{wf_calendar name="startDate" default=true}
+			</td>
+		</tr>
+		<tr>
+			<td>
+				<label for="executionTime">Hora de Execução</label>
+			</td>
+			<td>
+				{html_select_time use_24_hours=true display_seconds=false prefix="executionTime_" hour_extra='id="executionTime_Hour"' minute_extra='id="executionTime_Minute"'}
+			</td>
+		</tr>
+		<tr>
+			<td>
+				<label>Tipo de Data</label>
+			</td>
+			<td>
+				<table>
+					<tr>
+						<td>
+							<label><input type="radio" name="dateType" id="dateType_0" checked="checked" value="0"/>Data Absoluta</label>
+						</td>
+						<td>
+							<label><input type="radio" name="dateType" id="dateType_1" value="1"/>Dias da Semana</label>
+						</td>
+						<td>
+							<label><input type="radio" name="dateType" id="dateType_2" value="2"/>Data Relativa do Mês</label>
+						</td>
+					</tr>
+					<tr>
+						<td style="color: gray;"><i>Ideal para Jobs que possuem um intervalo de execução bem definido. e.g.: executar o Job a partir do dia 07/05/2008 e repetir a cada 3 dias.</i></td>
+						<td style="color: gray;"><i>Para Jobs que têm sua execução baseada em dias da semana. e.g.: a partir do dia 14/04/2008, executar o Job às segundas, quartas e sextas com repetição a cada duas semanas.</i></td>
+						<td style="color: gray;"><i>Para Jobs que devem ser executados em relação ao número de dias para o fim do mês. e.g.: executar o Job a cada 6 meses, no último dia do mês.</i></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+		<tr id="date_1" style="display: none;">
+			<td colspan="2">
+				Executar o job nos seguintes dias:<br/>
+				<table width="100%">
+					<tr>
+						<td><label><input type="checkbox" id="weekDateDay_0" value="1"/> Domingo</label></td>
+						<td><label><input type="checkbox" id="weekDateDay_1" value="2"/> Segunda-feira</label></td>
+						<td><label><input type="checkbox" id="weekDateDay_2" value="4"/> Terça-feira</label></td>
+						<td><label><input type="checkbox" id="weekDateDay_3" value="8"/> Quarta-feira</label></td>
+						<td><label><input type="checkbox" id="weekDateDay_4" value="16"/> Quinta-feira</label></td>
+						<td><label><input type="checkbox" id="weekDateDay_5" value="32"/> Sexta-feira</label></td>
+						<td><label><input type="checkbox" id="weekDateDay_6" value="64"/> Sábado</label></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+		<tr id="date_2" style="display: none;">
+			<td colspan="2">
+				Executar quando faltar <input type="text" size="1" name="relativeDateMonthOffset" id="relativeDateMonthOffset" value="1"/> dias para o próximo mês.
+				<font color="gray">(e.g.: utilize 1 para o última dia do mês; 2 para o penúltimo dia do mês e assim por diante)</font><br/>
+			</td>
+		</tr>
+		<tr>
+			<td colspan="2"><label><input type="checkbox" id="repeatJob" /><strong>Repetição do Job</strong></label></td>
+		</tr>
+		<tr id="repeatDate_1"><td colspan="2">Repetir o job a cada <input type="text" size="1" name="weekDateIntervalValue" id="weekDateIntervalValue" value="1"/> semanas.</td></tr>
+		<tr id="repeatDate_2"><td colspan="2">Repetir o job a cada <input type="text" size="1" name="relativeDateIntervalValue" id="relativeDateIntervalValue" value="1"/> meses.</td></tr>
+		<tr id="repeatDate_0" style="display: none;">
+			<td colspan="2">
+				Repetir o job a cada <input type="text" size="3" name="absoluteDateIntervalValue" id="absoluteDateIntervalValue" value="1"/>
+				<select name="absoluteDateIntervalUnity" id="absoluteDateIntervalUnity">
+					<option value="5">minutos</option>
+					<option value="4">horas</option>
+					<option value="3" selected>dias</option>
+					<option value="1">meses</option>
+					<option value="0">anos</option>
+				</select>
+			</td>
+		</tr>
+		<tr id="actions">
+			<td colspan="2">
+				<button onclick="Effect.BlindUp('jobForm'); Effect.BlindDown('jobList'); return false;">Voltar</button>
+				<button onclick="saveJob(); return false;">Salvar</button>
+			</td>
+		</tr>
+		<tr id="saving" style="display: none;">
+			<td colspan="2">
+				<img src="workflow/templateFile.php?file=images/loading.gif"/> Salvando o Job ...
+			</td>
+		</tr>
+	</table>
+</div>
+<div id="logList" style="display: none;"></div>
+</div>
+{literal}
+<script type="text/javascript" language="javascript">
+window.onload = function(){ addEventWatchers(); loadJobList(); };
+</script>
+{/literal}
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/orgchart.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/orgchart.tpl	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/orgchart.tpl	(revision 2371)
@@ -0,0 +1,23 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading">
+{$css}
+{$javaScripts}
+<div id="main_body" style="width:99.5%;">
+	<table id="border_table" width="auto" height="26" cellspacing="0" cellpadding="0" border="0">
+		<tbody id="border_tbody">
+			<tr id="border_tr">
+				<td nowrap class="menu" id="border_id_0" onClick="(alternate_border(0) == 0) ? draw_org_folder() : ''">
+					&nbsp;&nbsp;Organograma&nbsp;&nbsp;
+				</td>
+				<td nowrap id="border_blank" class="last_menu" width="100%">
+					&nbsp;
+				</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="content_id_0" class="conteudo"></div>
+</div>
+{$footer}
+<script type="text/javascript">
+init_orgchart({$tabIndex});
+</script>
Index: /sandbox/workflow/branches/993/templates/default/adminsource.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/adminsource.tpl	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/adminsource.tpl	(revision 2371)
@@ -0,0 +1,25 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading"/>
+<input type="hidden" value="{$processID}" id="workflowAdminSourceProcessID"/>
+{$css}
+{$javaScripts}
+<div id="main_body" style="display:none; width:99.5%;">
+	<table id="border_table" width="auto" height="26" cellspacing="0" cellpadding="0" border="0">
+		<tbody id="border_tbody">
+			<tr id="border_tr">
+			{foreach from=$tabs item=tab name="feTabs"}
+				{assign var='index' value=$smarty.foreach.feTabs.index}
+				<td nowrap class="menu" id="border_id_{$index}" onClick="change_folder({$index})">
+					&nbsp;&nbsp;{$tab}&nbsp;&nbsp;
+				</td>
+			{/foreach}
+				<td nowrap id="border_blank" class="last_menu" width="100%">
+					&nbsp;
+				</td>
+			</tr>
+		</tbody>
+	</table>
+{foreach from=$tabs item=tab name="feTabs"}
+	<div id="content_id_{$smarty.foreach.feTabs.index}" class="conteudo"></div>
+{/foreach}
+</div>
Index: /sandbox/workflow/branches/993/templates/default/app.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/app.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/app.css	(revision 795)
@@ -0,0 +1,63 @@
+/********************* WAIT WHILE LOADING BOX *************/
+#loading {
+	width: 400px;
+	height: 50px;
+	background-color: #D3DCE3;
+	color: #ff3333;
+	position: absolute;
+	left: 250px;
+	top: 200px;
+	text-align: center;
+	border: 1px solid black;
+}
+
+/********************* INSTANCE STATUS COLOR *************/
+.wf_active
+{
+        color: green;
+}
+a.wf_active
+{
+        color: green;
+}
+.wf_completed
+{
+        color: black;
+}
+a.wf_completed
+{
+        color: black;
+}
+.wf_aborted
+{
+        color: grey;
+}
+a.wf_aborted
+{
+        color: grey;
+}
+.wf_exception
+{
+        color: red;
+}
+a.wf_exception
+{
+        color: red;
+}
+
+/********************* MESSAGE *************/
+.message
+{
+        color: red;
+        text-align: center;
+}
+
+/********************* NICE TABLES *************/
+tr.row_on:hover
+{
+  background            : #FFF url(images/tr_bck.gif) repeat;
+}
+tr.row_off:hover
+{
+  background            : #FFF url(images/tr_bck.gif) repeat;
+}
Index: /sandbox/workflow/branches/993/templates/default/monitors.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/monitors.tpl	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/monitors.tpl	(revision 2371)
@@ -0,0 +1,24 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading"/>
+{$css}
+{$javaScripts}
+<div id="main_body" style="display:none; width:99.5%;">
+	<table id="border_table" width="auto" height="26" cellspacing="0" cellpadding="0" border="0">
+		<tbody id="border_tbody">
+			<tr id="border_tr">
+			{foreach from=$tabs item=tab name="feTabs"}
+				{assign var='index' value=$smarty.foreach.feTabs.index}
+				<td nowrap class="menu" id="border_id_{$index}" onClick="changeFolder({$index})">
+					&nbsp;&nbsp;{$tab}&nbsp;&nbsp;
+				</td>
+			{/foreach}
+				<td nowrap id="border_blank" class="last_menu" width="100%">
+					&nbsp;
+				</td>
+			</tr>
+		</tbody>
+	</table>
+{foreach from=$tabs item=tab name="feTabs"}
+	<div id="content_id_{$smarty.foreach.feTabs.index}" class="conteudo"></div>
+{/foreach}
+</div>
Index: /sandbox/workflow/branches/993/templates/default/tpleditor.html
===================================================================
--- /sandbox/workflow/branches/993/templates/default/tpleditor.html	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/tpleditor.html	(revision 795)
@@ -0,0 +1,22 @@
+<html>
+<head>
+
+  <title>PHP Editor</title>
+  <link rel="stylesheet" type="text/css" href="css/editor.css">
+  <link rel="stylesheet" type="text/css" href="css/highlighthtml.css">
+  <script src="../../js/htmleditor/highlight.js"></script>
+  <script src="../../js/phpeditor/editor.js"></script>
+</head>
+<body onLoad="init();">
+<div id='codeframe'>
+<div id="linenumbers"></div>
+<div id="inputLine">
+<textarea id="inputLineEntry" wrap="off"></textarea>
+</div>
+<div id="content">
+<ol id="lines"><li>&nbsp;
+</li></ol>
+</div>
+</div>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/templates/default/admin_agent_mail_smtp.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/admin_agent_mail_smtp.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/admin_agent_mail_smtp.tpl	(revision 795)
@@ -0,0 +1,30 @@
+{shared_part}
+<tr class="th">
+	<th class="th">{lang_configuration_option}</th>
+	<th class="th">{lang_configuration_value}</th>
+</tr>
+
+<!-- BEGIN block_ag_config_option_input -->
+<tr class="{row_class}">
+  <td width="20%">{ag_config_label_i}</td>
+  <td width="80%"><input type="text" {ag_config_size_i} name="{ag_config_name_i}" value="{ag_config_value_i}" /></td>
+</tr>
+<!-- END block_ag_config_option_input -->
+
+<!-- BEGIN block_ag_config_option_textarea -->
+<tr class="{row_class}">
+  <td width="20%">{ag_config_label_t}</td>
+  <td width="80%"><textarea name="{ag_config_name_t}" COLS="80" ROWS="5">{ag_config_value_t}</textarea></td>
+</tr>
+<!-- END block_ag_config_option_textarea -->
+
+<!-- BEGIN block_ag_config_option_select -->
+<tr class="{row_class}">
+  <td width="20%">{ag_config_label_s}</td>
+  <td width="80%"><select name="{ag_config_name_s}" >
+<!-- BEGIN block_ag_config_option_select_option -->
+	<option value="{ag_config_value_s_key}" {ag_config_value_s_selected}>{ag_config_value_s_value}</option>
+<!-- END block_ag_config_option_select_option -->
+  </select></td>
+</tr>
+<!-- END block_ag_config_option_select -->
Index: /sandbox/workflow/branches/993/templates/default/admin_activities.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/admin_activities.tpl	(revision 1710)
+++ /sandbox/workflow/branches/993/templates/default/admin_activities.tpl	(revision 1710)
@@ -0,0 +1,436 @@
+<script language="javascript1.2" src="workflow/js/jscode/participants.js"></script>
+<script language="javascript1.2" src="workflow/js/jscode/adminInterface.js"></script>
+<div style="color:red; text-align:center">{message}</div>
+<div>
+	<div>
+		{proc_bar}
+	</div>
+	<div>
+		{errors}
+	</div>
+</div>
+<br />
+<form action="{form_details_action}" method="post">
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="activity_id" value="{activity_id}" />
+<input type="hidden" name="where2" value="{where2}" />
+<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+<input type="hidden" name="find" value="{find}" />
+<input type="hidden" name="where" value="{where}" />
+<input type="hidden" name="sort_mode" value="{sort_mode}" />
+<input type="hidden" name="filter_type" value="{filter_type_value}" />
+<input type="hidden" name="filter_interactive" value="{filter_interactive_value}" />
+<input type="hidden" name="filter_autoroute" value="{filter_autoroute_value}" />
+<input type="hidden" name="filter_trans_from" value="{filter_trans_from_value}" />
+<table id="activitiesPropertiesTable" style="border: 1px solid black;width:100%; margin-bottom:10px">
+	<tr class="th">
+		<td colspan="2" style="font-size: 120%; font-weight:bold">
+				{lang_Add_or_edit_an_activity} - <a id="toggleLink" href="javascript:toggleTableVisibility('activitiesPropertiesTable')">Contrair</a>
+		</td>
+	</tr>
+	<tr class="row_on">
+	  <td width="20%">{lang_Name}</td>
+	  <td><input type="text" name="name" value="{name}" /></td>
+	</tr>
+	<tr class="row_off">
+	  <td>{lang_Description}</td>
+	  <td><textarea name="description" rows="4" cols="60">{description}</textarea></td>
+	</tr>
+	<tr class="row_on">  
+	<td>{lang_Type}</td>
+		<td>
+			<select name="type">
+				<!-- BEGIN block_select_type -->
+					<option value="{type_value}" {type_selected}>{type_name}</option>
+				<!-- END block_select_type -->
+			</select>
+		</td>
+	</tr>
+	<tr class="row_off">
+         <td>{lang_Properties}</td>
+         <td>
+               <table cellpading="1" cellspacing="1">
+			<tr class="row_off">
+				<td colspan="4">{lang_users_can_act_on_activity_before_its_execution_with_form_and_after_by_sending_it_to_the_next_activity}</td>
+			</tr>
+			<tr class="row_on">
+				<td>{img_interactive}</td>
+                               	<td>{lang_Interactive}</td>
+                               	<td><input type="checkbox" name="is_interactive" {checked_interactive} /></td>
+				<td>{lang_interactive_activities_show_form_before_being_executed}</td>
+			</tr>
+                       	<tr class="row_on">
+				<td>{img_transition_auto}</td>
+                               	<td>{lang_auto_routed}</td>
+                               	<td><input type="checkbox" name="is_autorouted" {checked_autorouted} /></td>
+				<td>{lang_autorouted_activities_does_not_need_to_be_sent_by_any_user_after_their_execution}</td>
+                       	</tr>
+               </table>
+         </td>
+       </tr>
+	<tr class="row_on">
+	  <td>{lang_menu_path}</td>
+	  <td><input type="text" name="menu_path" value="{menu_path}" /></td>
+	</tr>
+       <tr class="row_off">
+	  <td>{lang_Add_transitions}</td>
+	  <td>
+		<table border="0" width="70%">
+			<tr>
+				<td>
+					{lang_Add_transitions_from}:<br/>
+					{add_trans_from}
+				</td>
+				<td>
+					{lang_Add_transitions_to}:<br/>
+					{add_trans_to}
+				</td>
+			</tr>    
+		</table>
+	  </td>
+	</tr>
+
+	<tr class="row_on">
+	  <td>{lang_Roles_assigned_to_this_activity}</td>
+	  <td>
+		<table style="border: 0;width:75%;">
+		<tr class="th">
+			<th>{txt_read_only}</th>
+			<th>{txt_role_name}</th>
+			<th>&nbsp;</th>
+		</tr>
+	  <!-- BEGIN block_activity_roles -->
+	  <tr class="tr_activity_role">
+	    <td width="25%" class="td_activity_role_ro" style="text-align:center"><input type="checkbox" name="activity_role_ro[{act_role_id}]" {act_role_ro_checked} disabled="disabled" /></td>
+	    <td width="70%" class="td_activity_role_name">{act_role_name}</td>
+	    <td width="5%" class="td_activity_role_del"><input type="checkbox" name="activity_role_delete[{act_role_id}]" {act_role_delete_checked} /></td>
+	  </tr>
+	  <!-- END block_activity_roles -->
+		<tr class="tr_activity_role">
+			<td colspan="3" style="text-align:right"><input type="submit" name="remove_roles" value="{txt_Remove_selected_roles}"></td>
+		</tr>
+		</table>
+	  </td>
+	</tr>
+	<tr class="row_off">
+
+	  <td>{lang_Add_role}</td>
+	  <td>
+		<table style="width=100%; border=0;">
+		<tr class="th">
+			<th>{txt_Use_existing_roles}</th>
+			<th>{lang_Add_new_role}</th>
+		</tr>
+		<tr>
+			<td>
+	  {txt_read_only}<input type="checkbox" name="userole_ro" {userole_ro_checked} />
+	  <select name="userole">
+	  <option value=""> </option>
+	  <!-- BEGIN block_process_roles -->
+	  <option value="{proc_roleId}">{proc_roleName}</option>
+	  <!-- END block_process_roles -->
+	  </select>
+			</td>
+			<td>
+	  {txt_read_only}<input type="checkbox" name="newrole_ro" {userole_ro_checked} />
+	  <input type="text" name="rolename" size="30"/>
+			</td>
+		</tr>
+		<tr>
+			<td>&nbsp;</td>
+			<td>{lang_Description}<input type="text" name="roledescription" size="50"/></td>
+		</tr>
+		</table>
+	  </td>
+	</tr>
+	<tr class="row_on">
+	  <td>{lang_Agents_assigned_to_this_activity}</td>
+	  <td>
+		<ul class="ul_activity_agents">
+	  <!-- BEGIN block_activity_agents -->
+	  <li class="li_activity_agent">{act_agent_type}&nbsp;&nbsp;[<a href="{act_agent_href}">{lang_delete}</a>]<br/>
+	  <!-- END block_activity_agents -->
+		<ul>
+	  </td>
+	</tr>
+	<tr class="row_off">
+	  <td>{lang_Add_agent}</td>
+	  <td>
+	  <select name="useagent">
+	  <option value="">{lang_None}</option>
+	  <!-- BEGIN block_select_agents -->
+	  <option value="{select_agentType}">{select_agentType}</option>
+	  <!-- END block_select_agents -->
+	  </select>
+	  </td>
+	</tr>
+       <tr class="row_on">
+         <td>
+			{lang_Default_User}
+		 </td>
+         <td valign="top">
+			<input type="hidden" name="default_user" id="default_user" value="{wf_default_user}" />
+			<input type="hidden" name="default_user_temp" id="default_user_temp" value="{wf_default_user}" />
+
+			<input type="radio" value="0" {default_user_option_checked_0} onclick="toggleDefaultUserVisibility(0);" id="default_user_option_0" name="default_user_option"/><label for="default_user_option_0">{lang_select_only_one_user}</label>
+			<input type="radio" value="1" {default_user_option_checked_1} onclick="toggleDefaultUserVisibility(1);" id="default_user_option_1" name="default_user_option"/><label for="default_user_option_1">{lang_select_one_process_role}</label>
+
+			<div id="div_default_user_option_0" style="display:none;">
+				<input type="input" name="default_user_desc" id="default_user_desc" value="{wf_default_user_desc}" readonly="true" size="40" />
+				<a href="javascript:void(0)" onclick="openParticipants('default_user', 'uid=1&hidegroups=1');"><img border="0" src="workflow/templateFile.php?file=images/add_user.png" /></a>
+				<button onclick="document.getElementById('default_user_desc').value=''; document.getElementById('default_user').value='*'; return false">{lang_without_default_user}</button>
+				<br>
+				<span style="color: gray">
+					{lang_the_default_user_will_only_be_set_if_he_is_mapped_to_a_role_on_the_activity} ({lang_setNextUser_directives_can_override_it}).
+				</span>
+			</div>
+
+			<div id="div_default_user_option_1" style="display:none;">
+				<select name="default_roles" id="default_roles" onchange="document.getElementById('default_user').value=document.getElementById('default_roles').value;">
+			    <option value="*"></option>
+			    <!-- BEGIN block_default_roles -->
+					<option value="{proc_roleId}" {proc_role_selected}>{proc_roleName}</option>
+		 	    <!-- END block_default_roles -->
+			    </select>
+				<br>
+				<span style="color: gray">
+					{lang_default_role_will_be_set_only_if_it_is_mapped_on_the_activity} ({lang_setNextUser_directives_can_override_it}).
+				</span>
+			</div>
+		<br/>
+         </td>
+       </tr>
+	{agents_config_rows}
+	<tr class="th">
+	        <td colspan="2">
+			<table width="100%" cellpadding="0" cellspacing="0">
+			<tr><td style="font-size: 120%; font-weight:bold">
+				<input type="submit" name="save_act" value="{lang_save}" />
+			</td><td style="text-align: right;font-size: 120%; font-weight:bold">
+				<input type="submit" name="new_activity" value="{lang_new}" />
+			</td></tr>
+			</table>
+		</td>
+	</tr>
+
+</table>
+</form>
+
+<div style="border: 1px solid black;margin-bottom:10px">
+<form action="{form_process_activities_action}" method="post">
+<div class="th" style="font-weight:bold; font-size:120%; margin-bottom:4px">{lang_Process_activities}</div>
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="activity_id" value="{activity_id}" />
+<input type="hidden" name="where2" value="{where2}" />
+<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+<input type="hidden" name="filter_trans_from" value="{filter_trans_from_value}" />
+<table width="100%" cellpadding="0" cellspacing="0">
+<tr class="th">
+	{left_arrow}
+	<td style="text-align:center">
+		{lang_Type}:
+			<select name="filter_type" >
+				<option {selected_filter_type_all} value="">{lang_All}</option>
+				<!-- BEGIN block_select_filter_type -->
+				<option {selected_filter_type} value="{filter_type_en_name}">{filter_type_name}</option>
+				<!-- END block_select_filter_type -->
+			</select>
+		{lang_Interactivity}:
+			<select name="filter_interactive">
+				<option {selected_filter_interactive_all} value="">{lang_All}</option>
+				<!-- BEGIN block_select_filter_interactive -->
+				<option {selected_filter_interactive} value="{filter_interactive_value}">{filter_interactive_name}</option>
+				<!-- END block_select_filter_interactive -->
+			</select>
+		{lang_Routing}:
+			<select name="filter_autoroute">
+				<option {selected_filter_autoroute_all} value="">{lang_All}</option>
+				<!-- BEGIN block_select_filter_autoroute -->
+				<option {selected_filter_autoroute} value="{filter_autoroute_value}">{filter_autoroute_name}</option>
+				<!-- END block_select_filter_autoroute -->
+			</select>
+		{lang_Search}:&nbsp;
+		<input size="18" type="text" name="find" value="{find}" />
+		<input type="submit" name="filter" value="{lang_Filter}" />
+	</td>
+	{right_arrow}
+</tr>
+</table>	
+</form>
+
+<form action="{form_process_activities_action}" method="post">
+<input type="hidden" name="find" value="{find}" />
+<input type="hidden" name="where" value="{where}" />
+<input type="hidden" name="sort_mode" value="{sort_mode}" />
+<input type="hidden" name="where2" value="{where2}" />
+<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="activity_id" value="{activity_id}" />
+				<input type="hidden" name="filter_type" value="{filter_type_value}" />
+				<input type="hidden" name="filter_interactive" value="{filter_interactive_value}" />
+				<input type="hidden" name="filter_autoroute" value="{filter_autoroute_value}" />
+<input type="hidden" name="filter_trans_from" value="{filter_trans_from_value}" />
+<div style="position:relative">
+<table border="0" width="100%">
+<!-- BEGIN block_process_activities_header -->
+<tr class="th" style="font-weight:bold">
+	<td style="width: 20px;" align="center">#</td>
+	<td style="width: 40%;">{header_name}</a></td>
+	<td align="center">{header_type}</a></td>
+	<td align="center">{header_interactive}</a></td>
+	<td align="center">{header_route}</a></td>
+	<td align="center">{header_default_user}</a></td>
+	<td width="70px">{lang_Action}</td>
+</tr>
+<!-- END block_process_activities_header -->
+<!-- BEGIN block_process_activities -->
+<tr bgcolor="{color_line}">
+	<td style="text-align:center;">
+	  {act_flowNum}
+	</td>
+	<td>
+	  <a href="{act_href}">{act_name}</a>
+	  {no_roles}
+	</td>
+	<td style="text-align:center;">
+		{act_icon}
+	</td>
+	<td style="text-align:center;">
+	  <input type="checkbox" name="activity_inter[{act_activity_id}]" {act_inter_checked} />
+	</td>
+    	<td style="text-align:center;">
+	  <input type="checkbox" name="activity_route[{act_activity_id}]" {act_route_checked} />
+	</td>
+        <td style="text-align:center;">
+          {act_default_user}
+        </td>
+	<td>
+		<a href="{act_href_edit}"><img src="{img_code}" alt="{lang_edit}" title="{lang_edit}" /></a>
+		{act_template}
+		<input style="position:absolute; right:5px" type="checkbox" name="activities[{act_activity_id}]" />
+	</td>
+</tr>
+<!-- END block_process_activities -->
+<!-- BEGIN block_process_activities_footer -->
+<tr class="th">
+<td colspan="7">
+	<input type="submit" name="update_act" value="{lang_update}" />
+	<input style="position:absolute; right:5px" type="submit" name="delete_act" value="{lang_Delete_selected}" />
+</td>
+</tr>
+<!-- END block_process_activities_footer -->
+</table>
+</div>
+</form>	
+</div>
+
+<table border="0" width="100%" style="border: 1px solid black;">
+	<tr class="th">
+		<td colspan="2" style="font-size: 120%; font-weight:bold">
+			{img_transition}{lang_Process_transitions}
+		</td>
+	</tr>
+	<tr valign="top">
+		<td width="50%">
+			<form action="{form_list_transitions_action}" method="post">
+				<input type="hidden" name="p_id" value="{p_id}" />
+				<input type="hidden" name="activity_id" value="{activity_id}" />
+				<input type="hidden" name="find" value="{find2}" />
+				<input type="hidden" name="where" value="{where2}" />
+				<input type="hidden" name="sort_mode" value="{sort_mode}" />
+				<input type="hidden" name="where2" value="{where2}" />
+				<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+				<input type="hidden" name="filter_type" value="{filter_type_value}" />
+				<input type="hidden" name="filter_interactive" value="{filter_interactive_value}" />
+				<input type="hidden" name="filter_autoroute" value="{filter_autoroute_value}" />
+				<input type="hidden" name="find" value="{find_value}" />
+			<table border="0" width="100%">
+				<tr class="th">
+					<td>
+						<span style="font-weight:bold; margin-right:15px">{lang_List_of_transitions}</span>{lang_From}: {filter_trans_from}
+					</td>
+					<td>
+						<input type="submit" name="filter" value="{lang_Filter}" />
+					</td>
+				</tr>
+				<!-- BEGIN block_transitions_table -->
+				<tr bgcolor="{color_line}">
+					<td>
+						<a href="{trans_href_from}">{trans_actFromName}</a>
+						<img src='{trans_arrow}' alt='{lang_To}' />
+						<a href="{trans_href_to}">{trans_actToName}</a>
+					</td>
+					<td>
+						<input type="checkbox" name="transition[{trans_actFromId}_{trans_actToId}]" />
+					</td>
+				</tr>
+				<!-- END block_transitions_table -->
+				<!-- BEGIN block_transitions_table_footer -->
+				<tr class="th">
+					<td align="right">
+						{img_transition_delete}
+					</td>
+					<td style="text-align:right;"><input type="submit" name="delete_tran" value="{lang_Delete_selected}" /></td>
+				</tr>
+				<!-- END block_transitions_table_footer -->
+				</table>
+			</form>		
+		</td>
+		<td width="50%" valign="top" align="left">
+			<form action="{form_list_transitions_action}" method="post">
+			<input type="hidden" name="p_id" value="{p_id}" />
+			<input type="hidden" name="activity_rd" value="{activity_id}" />
+			<input type="hidden" name="find" value="{find2}" />
+			<input type="hidden" name="where" value="{where2}" />
+			<input type="hidden" name="sort_mode" value="{sort_mode}" />
+			<input type="hidden" name="where2" value="{where2}" />
+			<input type="hidden" name="sort_mode2" value="{sort_mode2}" />
+			<input type="hidden" name="filter_type" value="{filter_type_value}" />
+			<input type="hidden" name="filter_interactive" value="{filter_interactive_value}" />
+			<input type="hidden" name="filter_autoroute" value="{filter_autoroute_value}" />
+			<input type="hidden" name="filter_trans_from" value="{filter_trans_from_value}" />
+			<input type="hidden" name="find" value="{find_value}" />
+			<table class="normal" width="100%">
+			<tr class="th" style="font-weight:bold">
+				<td colspan="2">
+					{lang_Add_a_transition}
+				</td>
+			</tr>
+			<tr class="row_off">
+			  <td>
+			  {lang_From}:
+			  </td>
+			  <td width="90%">
+				{add_a_trans_from}
+			  </td>
+			</tr>
+			<tr class="row_on">
+			  <td>
+			  {lang_To}: 
+			  </td>
+			  <td>
+				{add_a_trans_to}
+			  </td>
+			</tr>
+			<tr class="th">
+			  <td align="right">
+			  	{img_transition_add}
+			  </td>
+			  <td>
+				<input type="submit" name="add_trans" value="{lang_Add_Transition}" />
+			  </td>
+			</tr>
+			</table>	
+			</form>
+		</td>
+	</tr>
+</table>	
+<script language="javascript">
+if (!{expandTable})
+	toggleTableVisibility('activitiesPropertiesTable');
+
+if (document.getElementById('default_user_option_1').checked)
+	toggleDefaultUserVisibility(1);
+else
+	toggleDefaultUserVisibility(0);
+</script>
Index: /sandbox/workflow/branches/993/templates/default/admin_processes.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/admin_processes.tpl	(revision 989)
+++ /sandbox/workflow/branches/993/templates/default/admin_processes.tpl	(revision 989)
@@ -0,0 +1,261 @@
+{processes_css}
+<script language="javascript1.2" src="workflow/js/jscode/prototype.js"></script>
+<script language="javascript1.2" src="workflow/js/jscode/adminInterface.js"></script>
+<div style="color:red; text-align:center">{message}</div>
+<div>
+	<div>
+		{proc_bar}
+	</div>
+	<div>
+		{errors}
+	</div>
+</div>
+
+<form action="{form_action}" method="post">
+<input type="hidden" name="version" value="{version}" />
+<input type="hidden" name="p_id" value="{p_id}" />
+<input type="hidden" name="search_str" value="{search_str}" />
+<input type="hidden" name="start" value="0" />
+<input type="hidden" name="sort" value="{sort}" />
+<input type="hidden" name="order" value="{order}" />
+
+<br/>
+<table id="processesPropertiesTable" style="border: 1px solid black;width:100%; margin-bottom:10px">
+	<tr>
+		<td colspan="2" style="font-size: 120%; font-weight:bold">
+			{lang_Add_or_edit_a_process} - <a id="toggleLink" href="javascript:toggleTableVisibility('processesPropertiesTable')">Contrair</a>
+		</td>
+	</tr>
+	<tr>
+	</tr>
+	<tr class="row_on">
+		<td>{txt_Process_Name}</td>
+		<td><input type="text" maxlength="80" name="name" value="{name}" /> ver:{version}</td>
+	</tr>
+	<tr class="row_off">
+	 	<td>{lang_Description}</td>
+	 	<td><textarea rows="5" cols="60" name="description">{description}</textarea></td>
+	</tr>
+	<tr class="row_on">
+		<td>{lang_is_active}?</td>
+		<td><input type="checkbox" name="isActive" {is_active} /></td>
+	</tr>
+	<tr class="row_off">
+		<td>{lang_Config_values}</td>
+		<td>
+		<table width="100%">
+			<tr class="head">
+				<td>
+					{txt_consult_site_config_with_link}
+				</td>
+			</tr>
+	<!-- BEGIN block_config_table -->
+			<!-- BEGIN block_config_table_empty -->
+			<tr bgcolor="{color_line}">
+				<td colspan="2">
+					{config_empty}
+				</td>
+			</tr>
+			<!-- END block_config_table_empty -->
+			<!-- BEGIN block_config_table_title -->
+			<tr bgcolor="{color_line}">
+				<td colspan="2">
+					{config_name_trad}
+				</td>
+			</tr>
+			<!-- END block_config_table_title -->
+			<!-- BEGIN block_config_table_yesno -->
+			<tr bgcolor="{color_line}">
+				<td>
+					{config_name_trad}
+				</td>
+				<td>
+					<select name="config_yesno[{config_name}]">
+                                        <option value="default" {config_default_selected}>{lang_Use_default}</option>
+                                        <option value="yes" {config_yes_selected}>{lang_yes}</option>
+					<option value="no" {config_no_selected}>{lang_no}</option>
+                                        </select>
+				</td>
+			</tr>
+			<!-- END block_config_table_yesno -->
+			<!-- BEGIN block_config_table_password -->
+			<tr bgcolor="{color_line}">
+				<td>
+					{config_name_trad}
+				</td>
+				<td>
+				<table>
+				<tr><td>
+					<input type="password" maxlength="80" name="config_value[{config_name}]" value="{config_value}" />
+				</td><td>
+					<label><input type="checkbox" name="config_use_default[{config_name}]" {config_use_default_checked} />{txt_Use_Default}</label>
+				</td></tr>
+				</table>
+				</td>
+			</tr>
+			<!-- END block_config_table_password -->
+			<!-- BEGIN block_config_table_text -->
+			<tr bgcolor="{color_line}">
+				<td>
+					{config_name_trad}
+				</td>
+				<td>
+				<table>
+				<tr><td>
+					<input type="text" maxlength="80" name="config_value[{config_name}]" value="{config_value}" />
+				</td><td>
+					<label><input type="checkbox" name="config_use_default[{config_name}]" {config_use_default_checked} />{txt_Use_Default}</label>
+				</td></tr>
+				</table>
+				</td>
+			</tr>
+			<!-- END block_config_table_text -->
+			<!-- BEGIN block_config_table_select -->
+			<tr bgcolor="{color_line}">
+				<td>
+					{config_name_trad}
+				</td>
+				<td>
+					<select name="config_value[{config_name}]">
+						<option value="default" {config_default_selected}>{lang_Use_default}</option>
+						<!-- BEGIN block_config_table_select_option -->
+						<option value="{config_option_value}" {config_option_selected} >{config_option_name}</option>
+						<!-- END block_config_table_select_option -->
+					</select>
+				</td>
+			</tr>
+			<!-- END block_config_table_select -->
+	<!-- END block_config_table -->
+		</table>
+		</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;</td>
+		<td><input type="submit" name="save" value="{btn_update_create}" /></td>
+	</tr>
+</table>
+</form>
+
+<form enctype="multipart/form-data" action="{form_action}" method="post">
+<table style="border: 1px solid black;width:100%; margin-bottom:10px">
+<tr class="th">
+	<td colspan="2" style="font-size: 120%; font-weight:bold">
+		{lang_Or_import_a_process}
+	</td>
+</tr>
+<tr>
+  <td style="width: 200px">
+	  {lang_Upload_file}:
+  </td>
+  <td>
+	  <input type="hidden" name="MAX_FILE_SIZE" value="10000000000000" /><input size="16" name="userfile1" type="file" /><input style="font-size:9px;" type="submit" name="upload" value="{lang_upload}" />
+  </td>
+</tr>
+<tr>
+	<td colspan="2">
+		<label><input type="checkbox" name="customImport" id="customImport" onclick="$('newNameRow').style.display = $('newVersionRow').style.display = (this.checked ? '' : 'none');"/>{lang_customize_the_process}</label>
+	</td>
+</tr>
+<tr id="newNameRow" style="display: none;">
+	<td>
+		{lang_process_name}
+	</td>
+	<td>
+		<input type="text" name="newName" maxlength="80" /> <i>({lang_if_left_blank,_the_original_value_will_be_used})</i>
+	</td>
+</tr>
+<tr id="newVersionRow" style="display: none;">
+	<td>
+		{lang_process_version}
+	</td>
+	<td>
+		<input type="text" name="newVersion" maxlength="5" size="5"/> <i>({lang_if_left_blank,_the_original_value_will_be_used})</i>
+	</td>
+</tr>
+</table>
+</form>
+
+<div style="border: 1px solid black">
+<form action="{form_action}" method="post">
+<input type="hidden" name="search_str" value="{search_str}" />
+<input type="hidden" name="start" value="0" />
+<input type="hidden" name="sort" value="{sort}" />
+<input type="hidden" name="order" value="{order}" />
+<div class="th" style="font-weight:bold; font-size:120%; margin-bottom:4px">{list_processes}</div>
+<table width="100%" cellpadding="0" cellspacing="0">
+	<tr class="th">
+		<td style="text-align:center">
+			{lang_Status}:
+				<select name="filter_active" onChange="this.form.submit();">
+					<option value="" {filter_active_selected_all}>{lang_All}</option>
+					<option value="y" {filter_active_selected_y}>{lang_Active}</option>
+					<option value="n" {filter_active_selected_n}>{lang_Inactive}</option>
+				</select>
+			<input size="20" type="text" name="search_str" value="{search_str}" /> <input type="submit" name="filter" value="{lang_Search}">
+		</td>
+	</tr>
+</table>
+</form>
+<table style="border: 0px ;width:100%;">
+	<tr><td colspan="5">
+        <table style="border: 0px;width:100%; margin:0 auto">
+		<tr class="th" style="font-weight:bold">
+                	{left}
+	        	<td><div align="center">{lang_showing}</div></td>
+	                {right}
+        	</tr>
+	</table>
+<form action="{form_action}" method="post">
+<input type="hidden" name="search_str" value="{search_str}" />
+<input type="hidden" name="start" value="0" />
+<input type="hidden" name="sort" value="{sort}" />
+<input type="hidden" name="order" value="{order}" />
+	</td></tr>
+	<tr class="th" style="font-weight:bold">
+		<td>{header_wf_name}</td>
+		<td>{header_wf_version}</td>
+		<td>{header_wf_is_active}</td>
+		<td>{header_wf_is_valid}</td>
+		<td>{lang_Action}</td>
+	</tr>
+
+<!-- BEGIN block_items -->
+<tr bgcolor="{color_line}">
+	<td width="40%">
+	  <a href="{href_item_name}">{item_name}</a>
+	</td>
+	<td style="text-align:right;">
+	  {item_version}
+	</td>
+	<td style="text-align:center;">
+		{img_active}
+	</td>
+	<td style="text-align:center;">
+		{img_valid}
+	</td>
+	<td style="text-align:right;">
+	  <table><tr>
+	  <td><a href="{href_item_minor}"><img src="{img_new}" alt="{lang_New_minor_version}" title="{lang_New_minor_version}"/>{lang_New_minor}</a></td>
+	  <td><a href="{href_item_major}"><img src="{img_new}" alt="{lang_New_major_version}" title="{lang_New_major_version}"/>{lang_New_major}</a></td>
+	  <td><a href="{href_item_activities}"><img src="{img_activities}" alt="{lang_Activities}" title="{lang_Activities}"/>{lang_Activities}</a></td>
+	  <td><a href="{href_item_code}"><img src="{img_code}" alt="{lang_Code}" title="{lang_Code}"/>{lang_Code}</a></td>
+	  <td><a href="{href_item_roles}"><img src="{img_roles}" alt="{lang_Roles}" title="{lang_Roles}"/>{lang_Roles}</a></td>
+	  <td><a href="{href_item_jobs}"><img src="{img_jobs}" alt="{lang_Jobs}" title="{lang_Jobs}"/>{lang_Jobs}</a></td>
+	  <td><a href="{href_item_export}"><img src="{img_export}" alt="{lang_Export}" title="{lang_Export}"/>{lang_Export}</a></td>
+		<td><input type="checkbox" name="process[{item_wf_p_id}]" /></td>
+	</tr></table>
+	</td>
+</tr>
+<!-- END block_items -->
+<tr class="th">
+	<td colspan="5" style="text-align:right">
+		<input type="submit" onclick="return confirm('Tem certeza que deseja excluir os processos selecionados?');" name="delete" value="{lang_Delete_selected}">
+	</td>
+</form>
+</tr>
+</table>
+</div>
+<script language="javascript">
+if ({p_id} == 0)
+	toggleTableVisibility('processesPropertiesTable');
+</script>
Index: /sandbox/workflow/branches/993/templates/default/editor.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/editor.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/editor.tpl	(revision 795)
@@ -0,0 +1,119 @@
+<html>
+<head>
+{$css}
+{$javaScripts}
+
+<script language="javascript1.2">
+{literal}
+function initEditor()
+{
+{/literal}
+	editor.setContents("{$fileData}");
+{literal}
+	editor.keyBinding["c83"] = phpeditor_salvar;
+	editor.keyBinding["c70"] = function() { document.getElementById('txtFind').focus(); };
+{/literal}
+	{if $type == 'php'}
+	editor.keyBinding["c89"] = phpeditor_checksyntax;
+	{/if}
+{literal}
+}
+
+function FindInCode()
+{
+	editor.do_FindNext(document.getElementById('txtFind').value);
+}
+{/literal}
+</script>
+
+<title>{$processNameVersion} - {$fileName}</title>
+</head>
+<body onload='initEditor();'>
+<input type="hidden" value="{$txt_loading}" id="txt_loading">
+
+<script language="javascript1.2">
+{literal}
+	function mouseover(obj) { obj.style.backgroundColor='#f5f5f5'; 	}
+	function mouseout(obj) 	{ obj.style.backgroundColor='#d8d8d8'; 	}
+{/literal}
+</script>
+
+<table border=0 style="width:2000px;border-top:1px solid;border-left:1px solid;" bgcolor="#d8d8d8">
+<tr>
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);" onclick="phpeditor_salvar()"><img border=0 src="workflow/templateFile.php?file=images/helene_save.png" title="Salvar (Ctrl+S)"></a>	
+	</td>
+	{if $type == 'php'}
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);" onclick="phpeditor_checksyntax()"><img border=0 src="workflow/templateFile.php?file=images/helene_checksyntax.png" title="Check PHP Syntax (Ctrl+Y)"></a>	
+	</td>
+	{/if}
+	<td valign=center align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<input id="txtFind" type=text name=frmFind>
+	</td>
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);" onclick="FindInCode()"><img border=0 src="workflow/templateFile.php?file=images/helene_next.png"></a>	
+	</td>
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);" onclick="javascript:editor.blur();editor.do_Replace();"><img border=0 src="workflow/templateFile.php?file=images/helene_replace.png" title="Substituir")></a>	
+	</td>
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);" onclick="javascript:editor.do_Indent();"><img border=0 src="workflow/templateFile.php?file=images/helene_addindent.png" title="Adiciona Identação"></a>	
+	</td>
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);" onclick="javascript:editor.do_Unindent();"><img border=0 src="workflow/templateFile.php?file=images/helene_delindent.png" title="Remove Identação"></a>	
+	</td>
+	<td align=center onmouseover="mouseover(this);" onmouseout="mouseout(this);" width="25px">
+		<a href="javascript:void(0);"><img border=0 src="workflow/templateFile.php?file=images/helene_help.png"></a>	
+	</td>
+	<td>
+	</td>
+</tr>
+</table>
+
+<iframe id="phpeditor" name="editor" scrolling=no src="workflow/templateFile.php?file={$HTMLFile}" style="width: 2000px; height:78%; border-width:1px;"></iframe>
+
+<table border=0 width=2000px style="border-top:0px solid;border-left:1px solid;border-bottom:1px solid;border-right:1px solid;border-color:black;font-size:11px;">
+	<tr>
+		<td>
+			<div id="info">&nbsp;</div>
+		</td>
+	</tr>
+</table>
+<table border=0 width=2000px style="border-top:0px solid;border-left:1px solid;border-bottom:1px solid;border-right:1px solid;border-color:black;">
+<tr>
+	<td width=5px valign=top>
+		<table style="font-size:8px;height:50px;" bgcolor=#d5d5d5 cellpadding=0 cellspacing=0>
+		<tr>
+			<td valign=top style="height:10px;" bgcolor="#f5f5f5">
+				<a href="javascript:messages.scrollwin(-20);"><img border=0 src="workflow/templateFile.php?file=images/up_arrow.png"></a>
+			</td>
+		</tr>
+		<tr>
+			<td style="height:28px;">
+			</td>
+		</tr>
+		<tr>
+			<td valign=bottom style="height:10px;" bgcolor="#f5f5f5">
+				<a href="javascript:messages.scrollwin(20);"><img border=0 src="workflow/templateFile.php?file=images/down_arrow.png"></a>
+			</td>
+		</tr>
+		</table>
+	</td>
+	<td>
+		<iframe name="messages" scrolling=yes src="workflow/templateFile.php?file=editor_messages.html" style="width: 100%; height: 60px; border-width:0px;"></iframe>
+	</td>
+</tr>
+</table>
+
+<form name=frmSend method=POST enctype="multipart/form-data">
+	<textarea name='code' style='display:none'></textarea>
+	<input type='hidden' name='proc_name' value="{$processName}">
+	<input type='hidden' name='file_name' value="{$fileName}">
+	<input type='hidden' name='tipo_codigo' value="{$tipoCodigo}">
+	<input type='hidden' name='proc_id' value="{$processID}">
+	<input type='hidden' name='activity_id' value="{$activityId}">
+</form>
+
+</body>
+</html>
Index: /sandbox/workflow/branches/993/templates/default/orgchartPrint.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/orgchartPrint.tpl	(revision 2107)
+++ /sandbox/workflow/branches/993/templates/default/orgchartPrint.tpl	(revision 2107)
@@ -0,0 +1,33 @@
+<html>
+<head>
+</head>
+<body>
+{$header}
+{$css}
+{$javaScripts}
+<div class="invisiblePrint">
+	<h1>Configurar Impressão</h1>
+	<label><input type="checkbox" checked id="employeesVisibility" /> Exibir funcionários</label>
+	<br/>
+	<label><input type="checkbox" checked id="groupByArea" /> Agrupar por área</label>
+	<br/>
+	<label><input type="checkbox" checked id="highlightSupervisor" /> Ressaltar titular</label>
+	<br/>
+	<label><input type="checkbox" checked id="orgchartPathVisibility" /> Exibir "caminho completo" da área</label>
+	<br/><br/>
+	<button id="printButton">Imprimir</button>
+</div>
+
+
+{if !empty($organizationName)}
+<h1 class="organizationName">{$organizationName}</h1>
+{/if}
+
+<div id="areas_content" />
+
+{$footer}
+</body>
+</html>
+<script language="javascript">
+var areas = {$areasJson};
+</script>
Index: /sandbox/workflow/branches/993/templates/default/proc_bar.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/proc_bar.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/proc_bar.tpl	(revision 795)
@@ -0,0 +1,30 @@
+<table cellpadding='0' cellspacing='0' width="100%" style="border:1px solid black">
+<tr>
+	<td>
+		<div style="height:20px; padding-top:2px; padding-bottom:2px;background-color:white; color:black; font-size:10px;">
+			<table  cellpadding="0" cellspacing="0" width="100%" border="0">
+				<tr>
+					<td>
+						<b>{proc_name}:{version}</b>
+						{lang_validity:}&nbsp;<img border="0" src="{img_validity}" alt="{alt_validity}" title="{alt_validity}">
+					</td>
+					<td align='right'>
+						<table cellpadding='0' cellspacing='2' width="100%">
+							<tr>
+								{start_stop}
+								<td><a href="{link_admin_activities}"><img border="0" src="{img_activity}" alt="{lang_Activities}" title="{lang_Activities}" />{lang_Activities}</a></td>
+								<td><a href="{link_admin_processes}"><img border="0" src="{img_change}" alt="{lang_Edit}" title="{lang_Edit}" />{lang_Edit}</a></td>
+								<td><a href="{link_admin_shared_source}"><img border="0" src="{img_code}" alt="{lang_Code}" title="{lang_Code}" />{lang_Code}</a></td>
+								<td><a href="{link_admin_roles}"><img border="0" src="{img_roles}" alt="{lang_Roles}" title="{lang_Roles}" />{lang_Roles}</a></td>
+								<td><a href="{link_admin_jobs}"><img border="0" src="{img_job}" alt="{lang_Jobs}" title="{lang_Jobs}" />{lang_Jobs}</a></td>
+								<td><a href="{link_graph}" target="_external"><img src="{img_process}" border="0" title="{lang_Graph}" alt="{lang_Graph}" />{lang_Graph}</a></td>
+								<td><a href="{link_admin_export}"><img border="0" src="{img_save}" alt="{lang_Export}" title="{lang_Export}" />{lang_Export}</a></td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+			</table>
+		</div>
+	</td>
+</tr>
+</table>
Index: /sandbox/workflow/branches/993/templates/default/external_applications.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/external_applications.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/external_applications.tpl	(revision 795)
@@ -0,0 +1,9 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading"/>
+{$css}
+{$javaScripts}
+<div id="main_body" style="width:99.5%;">
+	<h2>Applicações Externas</h2>
+	<div id="conteudo"></div>
+</div>
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/admin_agents.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/admin_agents.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/admin_agents.tpl	(revision 795)
@@ -0,0 +1,9 @@
+<tr class="row_on">
+  <td width="100%">{lang_Agents_configuration}</td>
+  <td>
+	<table width="80%">
+		{each_agent_rows}
+	</table>
+  </td>
+</tr>
+
Index: /sandbox/workflow/branches/993/templates/default/css/orgchartPrintPreview.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/orgchartPrintPreview.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/orgchartPrintPreview.css	(revision 795)
@@ -0,0 +1,33 @@
+body
+{
+	font-family: Verdana,Arial,Helvetica,sans-serif;
+}
+
+span.employee
+{
+	margin: 0px;
+}
+
+span.employeesupervisor
+{
+	margin: 0px;
+	font-weight: bold;	
+}
+
+div.area h1
+{
+	margin: 10px 0px 0px 0px;
+	font-size: 20px;
+}
+
+h1.organizationName
+{
+	font-size: 22px;
+	margin: 0px 0px 20px 0px;
+	text-align: center;
+}
+
+span.telephoneNumber
+{
+	margin: 50px;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/common.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/common.css	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/css/common.css	(revision 2371)
@@ -0,0 +1,322 @@
+/** Estilo de elementos comuns **/
+
+* {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+a:link, a:visited
+{
+    cursor: pointer;
+    color: black;
+    text-decoration: none;
+}
+
+a:hover, a:active
+{
+    cursor: pointer;
+    color: darkblue;
+    text-decoration: none;
+}
+
+input, button
+{
+    font-size: 11px;
+    color: rgb(0, 102, 153);
+    font-family: Arial, Helvetica, sans-serif;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-style: solid;
+    border-right-style: solid;
+    border-bottom-style: solid;
+    border-left-style: solid;
+    border-top-color: rgb(187, 187, 187);
+    border-right-color: rgb(187, 187, 187);
+    border-bottom-color: rgb(187, 187, 187);
+    border-left-color: rgb(187, 187, 187);
+}
+
+textarea
+{
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 13px;
+}
+
+/** Estilo das abas em qualquer das interfaces **/
+
+.abas_menu_sel
+{
+    text-decoration: none;
+    font: bold 12px Arial;
+    color: #505050;
+    height: 20px;
+    margin-left: 5px;
+    margin-bottom: 0px;
+    padding: 2px 2px 2px 2px;
+
+    border-right: 1px solid #000000;
+    border-left: 1px solid #000000;
+    border-top: 1px solid #000000;
+
+    color: black;
+
+    -moz-border-radius: 6px 6px 3px 3px;
+    cursor: pointer;
+    border-bottom-style: none;
+    background-color: #F7F7F7;
+}
+
+.abas_menu
+{
+    text-decoration: none;
+    font: bold 12px Arial; 		/*tab font */
+    color: #505050; 			/*font color */
+    height: 20px; 				/*height of tab  */
+    margin-left: 5px; 			/*spacing between tabs */
+    background-color:#E5E5E5;
+    margin-bottom: 0px;
+    padding: 2px 2px 2px 2px; 	/* offset of tab text to border (top left bottom right) */
+    background-color: #e5e5e5;
+    border-left: solid 1px #c0c0c0;
+    border-top: solid 1px #c0c0c0;
+    border-right: solid 1px #c0c0c0;       
+    border-bottom: 1px solid #000000;
+    -moz-border-radius: 4px 4px 0px 0px;
+    cursor: pointer;   
+}
+
+.abas_last_menu
+{
+	border-bottom: 1px solid #000000;
+	-moz-border-radius: 4px 4px 0px 0px;
+}
+
+/** Estilo para a divisão principal das interfaces **/
+
+.conteudo_div {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size: 10px;
+    font-weight: normal;
+    color: #000033;
+    padding: 2px;
+    border-color: gray gray gray gray;
+    border-right: 1px solid #000000;
+    border-left: 1px solid #000000;
+    border-bottom: 1px solid #000000;
+    width:99.5%;
+    -moz-border-radius: 0px 0px 6px 6px;
+}
+
+.conteudo_div_ie {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size: 10px;
+    font-weight: normal;
+    color: #000033;
+    padding: 2px;
+    border-color: gray gray gray gray;
+    border-right: 1px solid #000000;
+    border-left: 1px solid #000000;
+    border-bottom: 1px solid #000000;
+    width:100%;
+    -moz-border-radius: 0px 0px 6px 6px;
+}
+
+/** Estilo para exibição de texto **/
+
+.text_dsp
+{
+	color: black;
+	margin-left: 10px;
+	padding: 6px 6px 6px 6px;	
+}
+
+.version_dsp
+{
+	font: normal 10px Arial;
+	color: black;
+}
+
+.text_bold
+{
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size: 10px;
+    font-weight: bold;
+    color: black;
+}
+
+/** Estilo para a exibição de erros na região compreendida entre o cabeçalho do Expresso e as abas das interfaces **/
+
+.msg_erro_table {
+	border-spacing: 0px 0px;
+}
+
+.msg_erro_th {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 13px;
+	border-width: 0px 0px 0px 0px;
+	padding: 3px 10px 3px 10px;
+	border-style: inset inset inset inset;
+	border-color: gray gray gray gray;
+	background-color: rgb(250, 209, 99);
+	-moz-border-radius: 6px 6px 6px 6px;
+}
+
+.msg_erro_text
+{
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	color: #000066;
+	font-size: 14px;
+	font-weight: bold;
+}
+
+/** Estilo da tabela de visualização de dados sobre processos ou instâncias **/
+
+.info_table {
+	color: black;
+	font-family: Arial;
+	font-size: 13px;	
+	background-color: #CCCCCC;
+	padding: 1px;
+	cursor: default;
+	border-width: 1px 1px 1px 1px;
+	border-spacing: 0px 1px;
+	border-style: outset outset outset outset;
+	border-color: black;
+	border-collapse: separate;
+	-moz-border-radius: 3px 3px 3px 3px;
+}
+
+.info_tr_header{
+	/*background-color: #cccccc;*/
+	font-weight: bold;
+	font-size: 13px;	
+}
+
+.info_tr_simple {
+	background-color: #ffffff;
+	font-weight: normal;
+	font-size: 13px;		
+}
+
+.info_tr_sub_header {
+	background-color: #ffffff;
+	font-size: 11px;	
+	color: #505050;
+}
+
+.info_td_activ {
+	font-weight: normal;
+	color: black;
+	vertical-align: top;
+}
+
+/** Inativo: antigo estilo do menu de atividades dos processos **/
+
+.drop_menu_div
+{
+	position: absolute;
+	visibility: hidden;
+}
+
+.drop_menu_table {
+	background-color: #ffffff;
+	color: black;
+	border-style: solid;
+	border-width: 1px;
+	border-color: #bbbbbb;
+	font-family: Arial;
+	font-size: 13px;
+	cursor: pointer;
+}
+
+.drop_menu_td {
+	background-color: white;
+	color: black;
+	text_decoration: none;
+}
+
+.drop_menu_td_sel {
+	background-color: whitesmoke;
+	color: darkblue;
+	text_decoration: none;
+}
+
+/** Estilo das imagens exibidas nas listas de ações **/
+
+.img_link {
+	cursor: pointer;
+}
+
+.img_no_link {
+	cursor: default;
+}
+
+/** Estilo da tabela principal das interfaces. P.ex: lista de instâncias da aba de Tarefas Pendentes **/
+
+.table_elements
+{
+	width: 100%;
+	color: black;
+	border-style: solid;
+	border-width: 0px;
+	border-collapse: collapse;
+	border-color: #bbbbbb;
+	font-family: Arial;
+	font-size: 13px;	
+}
+
+.table_elements_tr_header {
+	/*background-color: #ABC6E1;*/
+}
+
+.table_elements_tr_line {
+	background-color: #ffffff;
+	border-bottom:1px solid #cfcfcf;
+}
+
+ul.horizontalMenu
+{
+	list-style: none;
+	padding: 0px;
+	margin: 0px;
+}
+
+ul.horizontalMenu li
+{
+	float: left;
+	margin: 0pt;
+	text-align: left;
+}
+
+ul.horizontalMenu li a
+{
+	border: 1px solid buttonface;
+	padding: 0px 05px 0px 05px;
+	height: 2.5em;
+	line-height: 2.5em;
+	float: left;
+	display: block;
+	color: #000000 !important;
+	text-decoration: none;
+	text-align: center;
+	font-size: 11px !important;
+}
+
+ul.horizontalMenu li a:hover
+{
+	background-color: #FFFFFF !important;
+	border: 1px solid #000000;
+	color: darkblue !important;
+	text-decoration: none !important;
+}
+
+ul.horizontalMenu li a:visited
+{
+	color: #000000 !important;
+}
+
+ul.horizontalMenu li a img
+{
+	vertical-align: middle;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/external_applications.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/external_applications.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/external_applications.css	(revision 795)
@@ -0,0 +1,5 @@
+select.externalApplicationList
+{
+	width: 300px;
+	height: 320px;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/run_activity_print.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/run_activity_print.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/run_activity_print.css	(revision 795)
@@ -0,0 +1,144 @@
+p 
+{
+	orphans: 20; /*at least 20 lines in a single page*/
+}
+body 
+{
+	font-family: georgia, "Times New Roman", Times, serif;
+	size: 21.0cm 29.7cm; /* A4 */
+	size: portrait;
+	background-color: #FFF;
+}
+a {
+	color: #000;
+	text-decoration: none;
+	font-weight: bold;
+}
+.th
+{
+	 background-color: #CCCCCC;
+}
+.row_on
+{
+	 background-color: #EEEEEE;
+}
+.row_off
+{
+	background-color: #FFF;
+}
+#wf_run_activity_zone
+{
+	line-height: 14pt;
+	font-size: 12pt;
+	background-image: none; 
+	width : 100%;
+	background-color: #FFF;
+}
+
+#wf_run_activity_message
+{
+	color: #FF0000;
+}
+
+/*********************  ACTIVITY ZONE *************/
+#wf_activity_playground
+{
+	width:100%;
+	margin-bottom:10px;
+}
+#wf_activity_title
+{
+	font-size: 120%;
+	font-weight:bold;
+}
+#wf_activity_template
+{
+}
+
+/*********************  PRIORITY ZONE *************/
+#wf_priority_zone
+{
+	display:inline;
+}
+#wf_priority_label
+{
+	text-align: right;
+	margin: 3px;
+}
+#wf_priority_select
+{
+	text-align: left;
+}
+/********************* NEXT USER ZONE *************/
+#wf_set_next_user_zone
+{
+	display: inline;
+}
+#wf_set_next_user_label
+{
+	text-align: right;
+	margin: 3px;
+}
+#wf_set_next_user_select
+{
+	text-align: left;
+}
+
+/********************* SET OWNER ZONE *************/
+#wf_set_owner_zone
+{
+	background-color: #FFF;
+	display: inline;
+}
+#wf_set_owner_label
+{
+	text-align: right;
+	margin: 3px;
+}
+#wf_set_owner_select
+{
+	text-align: left;
+}
+
+/*********************  SUBMIT ZONE *************/
+#wf_submit_zone
+{
+	display: none;
+}
+
+/*********************  WORKFLOW INFO ZONE *************/
+#workflow_info_zone
+{
+	position : relative;
+	align : left;
+	font-size:0.5em;
+	margin-bottom:10px;
+}
+table.table_info
+{
+	width: 100%;
+	border: 1px solid #000000;
+	margin: auto; /*IE5 doesn't understand it*/
+}
+tr.row_info
+{
+	height: 10px;
+}
+td.cell_info_label
+{
+	border:0px;
+	text-align: right;
+	background-color: #f1f1f1;
+}
+td.cell_info_value
+{
+	border:0px;
+	text-align: left;
+	background-color: #fafafa;
+}
+
+/******************** FOOTER ***********************/
+#divPoweredBy
+{
+	display: none;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/highlighthtml.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/highlighthtml.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/highlighthtml.css	(revision 795)
@@ -0,0 +1,62 @@
+	.h_pinp_block {
+		background-color: white;
+	}
+	.h_pinp {
+		color: #9400D3;
+	}
+	.h_special_char {
+		color: darkcyan;
+	}
+	.h_operator {
+		color: 	#cc0000;
+	}
+	.h_doublequote {
+		color: #cc0000;
+	}
+	.h_singlequote {
+		color: #cc0000;
+	}
+	.h_var {
+		color: #000080;
+	}
+	.h_ident {
+		color: #000000;
+	}
+	.h_single_comments {
+		color:		#ff9900;
+	}
+	.h_blockcomment {
+		color: 		#ff9900;
+	}
+	.h_script_block {
+		background-color: #FFFFFF;
+	}
+	.h_script {
+		color: #0000cc;
+	}
+  .h_smartymarkers {
+    color: darkblue;
+  }
+  .h_smartykeywords1 {
+    color: #006600;
+    /*font-weight:bold;*/
+  }
+  .h_smartykeywords2 {
+    color: #9400D3;
+    /*font-weight:bold;*/
+  }
+  .h_smartykeywords3 {
+    color: #9400D3;
+    /*font-weight:bold;*/
+  }
+  .h_smartytag {
+    background-color: white;
+  }
+  .h_phpkeywords1 {
+		color: 		#006600;
+    /*font-weight:bold;*/
+  }
+  .h_phpkeywords2 {
+		color: #9400D3;
+    /*font-weight:bold;*/
+  }
Index: /sandbox/workflow/branches/993/templates/default/css/lb.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/lb.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/lb.css	(revision 795)
@@ -0,0 +1,64 @@
+#lightbox
+{
+	background-color:#eee;
+	padding: 10px;
+	border-bottom: 2px solid #666;
+	border-right: 2px solid #666;
+}
+
+#lightboxDetails
+{
+	font-size: 0.8em;
+	padding-top: 0.4em;
+}
+
+#lightboxCaption
+{
+	float: left;
+}
+
+#keyboardMsg
+{
+	float: right;
+}
+
+#closeButton
+{
+	top: 5px;
+	right: 5px;
+}
+
+#lightbox img
+{
+	border: none;
+	clear: both;
+}
+
+#overlay img
+{
+	border: none;
+}
+
+#overlay
+{
+	background-image: url(../images/lb_overlay.png);
+}
+
+* html #overlay
+{
+	background-color: #333;
+	back\ground-color: transparent;
+	background-image: url(../images/blank.gif);
+	filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../images/lb_overlay.png", sizingMethod="scale");
+}
+
+kbd
+{
+	background-color:#DDDDDD;
+	border-bottom:1px solid #CCCCCC;
+	border-right:1px solid #CCCCCC;
+	color:#555555;
+	font-family:inherit;
+	font-size:inherit;
+	padding:0pt 3px 2px 4px;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/userinterface.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/userinterface.css	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/css/userinterface.css	(revision 2371)
@@ -0,0 +1,145 @@
+.proc_filter_div
+{
+	position: relative;
+	visibility: hidden;
+}
+
+/** Estilo do menu de atividades dos processos **/
+
+div.menuInternoOut
+{
+	font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;
+	font-size: 11px;
+	text-decoration: none;
+	border-left: 5px solid #BADAEF;
+	padding: 2px;
+	color: #000;
+}
+
+div.menuInternoOver
+{
+	font: 11px Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;
+	text-decoration: none !important;
+	border-left: 5px solid #8CB0DD;
+	padding: 2px;
+	color: #000000;
+}
+
+a.menuExternoOut
+{
+	text-decoration : none;
+	border: 1px solid #BADAEF;
+	background: #E4F0F9;
+}
+
+a.menuExternoOver
+{
+	text-decoration : none;
+	border: 1px solid #BADAEF;
+	background: #E4F0F9;
+}
+
+div.submenuInternoOut
+{
+	font: 11px Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;
+	text-decoration: none;
+	padding: 2px;
+	color: #000000;
+}
+
+div.submenuInternoOver
+{
+	font: 11px Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;
+	padding: 2px;
+	color: #000000;
+}
+
+a.submenuExternoOut
+{
+	text-decoration : none;
+	border: 1px solid #53A69A;
+	background: #E4F9F0;
+}
+
+a.submenuExternoOver
+{
+	text-decoration : none;
+	border: 1px solid #53A69A;
+	background: #E4F9F0;
+}
+
+div.advancedActions
+{
+	position: absolute;
+	background-color: #FFFFFF;
+	border: 1px solid #000000;
+	padding: 4px;
+}
+
+ul.submenu
+{
+	position: absolute;
+	margin: 0pt 0pt;
+	display: block;
+	border: 1px solid #000000;
+	background-color: #CCCCCC !important;
+	list-style-type: none;
+	padding-left: 10px;
+	font-size: 11px;
+	list-style-image: none;
+}
+
+ul.submenu li
+{
+	background-color: #FFFFFF !important;
+	padding-right: 10px;
+	padding-top: 5px;
+	padding-bottom: 5px;
+}
+
+ul.submenu li a
+{
+	color: #000000 !important;
+	display: block;
+}
+
+ul.submenu li a:visited
+{
+	color: #000000 !important;
+	display: block;
+}
+
+table.inboxElements
+{
+	width: 100%;
+	color: black;
+	border-style: solid;
+	border-width: 0px;
+	border-collapse: collapse;
+	border-color: #BBBBBB;
+	font-family: Arial;
+	font-size: 13px;
+}
+
+table.inboxElements th
+{
+	font-size: 11px !important;
+	font-weight: normal;
+	/*background-color: #ABC6E1;*/
+}
+
+table.inboxElements th a
+{
+	color: #000000 !important;
+}
+
+table.inboxElements th a:visited
+{
+	color: #000000 !important;
+}
+
+table.inboxElements tr
+{
+	background-color: #FFFFFF;
+	border-bottom: 1px solid #CFCFCF;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/monitor_tabs.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/monitor_tabs.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/monitor_tabs.css	(revision 795)
@@ -0,0 +1,22 @@
+.active_tab
+{
+	color:#000000;
+	background-color:#D3DCE3;
+	border-top-width : 1px;
+	border-top-style : solid;
+	border-top-color : Black;
+	border-left-width : 1px;
+	border-left-style : solid;
+	border-left-color : Black;
+	border-right-width : 1px;
+	border-right-style : solid;
+	border-right-color : Black;
+}
+.inactive_tab
+{
+	color:#000000;
+	background-color:#E8F0F0;
+	border-bottom-width : 1px;
+	border-bottom-style : solid;
+	border-bottom-color : Black;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/processes.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/processes.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/processes.css	(revision 795)
@@ -0,0 +1,40 @@
+/**************************************************
+ * Define here colors and graphics associated     *
+ * with all your processes. This file is included *
+ * on each common workflow listing, this is not   *
+ * the place for process-sprecific definition, see*
+ * run_activity.css for such things               *
+ * Processes are referenced with their            *
+ * normalized names (with versions)               *
+ ***************************************************/
+
+/* workflow Processes examples *********************/ 
+/***************************************/
+/*     Test Join2                      */
+/***************************************/
+
+td.row_TestJoin2_17
+{
+	background: #f2ebd0 url(../images/testjoin2_20.gif) top left no-repeat;
+}
+span.TestJoin2_17
+{
+	font-style: italic;
+	margin-left: 20px;
+}
+/***************************************/
+/*     Test Mail                       */
+/***************************************/
+td.row_testMail_11
+{
+        background: #d0ebf2 url(../images/testmail_20.gif) top left no-repeat;
+}
+span.testMail_11
+{
+        font-style: italic;
+        margin-left: 20px;
+}
+
+
+
+/** write your own here:... ***********************/
Index: /sandbox/workflow/branches/993/templates/default/css/adminjobs.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/adminjobs.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/adminjobs.css	(revision 795)
@@ -0,0 +1,122 @@
+table.jobList
+{
+	border-collapse: collapse;
+	border-bottom: 1px solid #CCCCCC;
+	width: 60%;
+}
+
+table.jobList tr
+{
+	border-top: 1px solid #CCCCCC;
+}
+
+table.jobList tr td.jobListIcon
+{
+	width: 32px;
+}
+
+table.jobList tr td.jobListActions
+{
+	text-align: right;
+}
+
+table.jobList tr td h1
+{
+	font-size: 16px;
+	margin: 0px;
+}
+
+table.jobList tr td h3
+{
+	font-size: 10px;
+	margin: 0;
+	color: gray;
+}
+
+table.logList
+{
+	border-collapse: collapse;
+}
+
+table.logList tr
+{
+	height: 32px;
+	background-repeat: no-repeat;
+}
+
+table.logList tr td.logListIcon
+{
+	padding-left: 35px;
+	background-repeat: no-repeat;
+}
+
+table.logList tr.fail
+{
+	background-color: #FFD;
+}
+
+table.logList tr.fail td.logListIcon
+{
+	background-image: url('../../../templateFile.php?file=images/exclamation.png');
+}
+
+table.logList tr.success
+{
+	background-color: #DFD;
+}
+
+table.logList tr.success td.logListIcon
+{
+	background-image: url('../../../templateFile.php?file=images/apply.png');
+}
+
+table.logList tr.unknown
+{
+	background-color: #DDD;
+}
+
+table.logList tr.unknown td.logListIcon
+{
+	background-image: url('../../../templateFile.php?file=images/question.png');
+}
+
+table.logList tr.error
+{
+	background-color: #FDD;
+}
+
+table.logList tr.error td.logListIcon
+{
+	background-image: url('../../../templateFile.php?file=images/button_cancel.png');
+}
+
+table.logList
+{
+	width: 70%;
+}
+
+table.logList tr td.logDate
+{
+	font-size: 15px !important;
+	font-weight: bold;
+	width: 120px;
+}
+
+table.jobResult
+{
+	border-collapse: collapse;
+	border: 1px dashed #CCCCCC;
+	width: 100%;
+}
+
+table.jobResult tr th
+{
+	background-color: #AAAAAA;
+	font-size: 11px;
+	font-weight: bold;
+}
+
+table.jobResult tr td
+{
+	font-size: 11px;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/highlight.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/highlight.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/highlight.css	(revision 795)
@@ -0,0 +1,62 @@
+	.h_pinp_block {
+		background-color: white;
+	}
+	.h_pinp {
+		color: #9400D3;
+	}
+	.h_special_char {
+		color: darkcyan;
+	}
+	.h_operator {
+		color: 	#cc0000;
+	}
+	.h_doublequote {
+		color: #cc0000;
+	}
+	.h_singlequote {
+		color: #cc0000;
+	}
+	.h_var {
+		color: #000080;
+	}
+	.h_ident {
+		color: #9400D3;
+	}
+	.h_single_comments {
+		color:		#ff9900;
+	}
+	.h_blockcomment {
+		color: 		#ff9900;
+	}
+	.h_script_block {
+		background-color: #FFFFFF;
+	}
+	.h_script {
+		color: #0000cc;
+	}
+  .h_smartymarkers {
+    color: darkblue;
+  }
+  .h_smartykeywords1 {
+    color: darkblue;
+    /*font-weight:bold;*/
+  }
+  .h_smartykeywords2 {
+    color: darkblue;
+    /*font-weight:bold;*/
+  }
+  .h_smartykeywords3 {
+    color: orange;
+    /*font-weight:bold;*/
+  }
+  .h_smartytag {
+    background-color: #F0F0FF;
+  }
+  .h_phpkeywords1 {
+		color: 		#006600;
+    /*font-weight:bold;*/
+  }
+  .h_phpkeywords2 {
+		color: #9400D3;
+    /*font-weight:bold;*/
+  }
Index: /sandbox/workflow/branches/993/templates/default/css/orgchart.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/orgchart.css	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/css/orgchart.css	(revision 2371)
@@ -0,0 +1,188 @@
+tr.alerta
+{
+	background-color: #FCC !important;
+}
+
+table.organizationList
+{
+	width: 100%;
+	margin-left: auto;
+	margin-right: auto;
+	font-size: 13px;
+	border-collapse: collapse;
+	clear: both;
+}
+
+table.organizationList tbody tr th
+{
+	/*background-color: #CCCCCC;*/
+}
+
+table.organizationList tbody tr.linha0
+{
+	/*background-color: #F2F2F2;*/
+	font-size: 12px;
+}
+
+table.organizationList tbody tr.linha1
+{
+	/*background-color: #E5E5E5;*/
+	font-size: 12px;
+}
+
+table.organizationList tbody tr td a
+{
+	color: #000000 !important;
+}
+
+table.organizationList tbody tr td a:hover
+{
+	color: #009ACD !important;
+	text-decoration: underline !important;
+}
+
+table.orgchartUpdateTable
+{
+	margin-left: auto;
+	margin-right: auto;
+	font-size: 13px;
+	border: 1px solid;
+	border-collapse: collapse;
+	clear: both;
+}
+
+table.orgchartUpdateTable tbody tr th
+{
+	background-color: #CCCCCC;
+	border: 1px solid;
+	border-style: none inset;
+	padding: 0px 20px;
+}
+
+table.orgchartUpdateTable tbody tr td
+{
+	border: 1px solid;
+	border-style: none inset;
+}
+
+table.orgchartUpdateTable tbody tr.linha0
+{
+	background-color: #F2F2F2;
+	font-size: 12px;
+}
+
+table.orgchartUpdateTable tbody tr.linha1
+{
+	background-color: #E5E5E5;
+	font-size: 12px;
+}
+
+table.orgchartUpdateTable tbody tr td a
+{
+	color: #000000 !important;
+}
+
+table.orgchartUpdateTable tbody tr td a:hover
+{
+	color: #009ACD !important;
+	text-decoration: underline !important;
+}
+
+
+
+
+
+
+
+
+
+
+
+table.employeeList
+{
+	width: 100%;
+}
+
+table.employeeList tbody th
+{
+	/*background-color: #CCCCCC;*/
+	font-size: 13px;
+}
+
+table.employeeList tbody tr.linha0
+{
+	/*background-color: #FFF;*/
+	font-size: 12px;
+}
+
+table.employeeList tbody tr.linha1
+{
+	/*background-color: #F7F7F7;*/
+	font-size: 12px;
+}
+
+table.employeeList tbody tr.highlight0
+{
+	background-color: #FFDDDD !important;
+}
+
+table.employeeList tbody tr.highlight1
+{
+	background-color: #FFBBBB !important;
+}
+
+table.employeeList tbody tr td a
+{
+	color: #000000 !important;
+}
+
+table.employeeList tbody tr td a:hover
+{
+	color: #009ACD !important;
+	text-decoration: underline !important;
+}
+
+div.orgchartAreas
+{
+	float: left;
+	width: 20%;
+	border: 1px solid;
+	background-color: #FFFFFF;
+	clear: both;
+}
+
+div.orgchartAreas a
+{
+	color: #000000 !important;
+}
+
+div.orgchartAreas a:hover
+{
+	color: #009ACD !important;
+	text-decoration: underline !important;
+}
+
+div.orgchartAreas a.destaque
+{
+	color: #FF0000 !important;
+	text-decoration: underline !important;
+}
+
+div.orgchartEmployees
+{
+	float: right;
+	width: 79%;
+}
+
+div.orgchartFooter
+{
+	clear: both;
+}
+
+div.employeeInfo
+{
+	position: absolute;
+	background-color: #FFFFFF;
+	border: 1px solid #000000;
+	padding: 4px;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/monitors.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/monitors.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/monitors.css	(revision 795)
@@ -0,0 +1,51 @@
+table.container
+{
+	border-collapse: collapse;
+	padding: 0px;
+	border: 0px;
+	width: 100%;
+}
+
+table.container tr
+{
+	vertical-align: top;
+}
+
+table.content_table
+{
+    color: black;
+    border-style: solid;
+    border-width: 0px;
+    border-collapse: collapse;
+    border-color: #bbbbbb;
+    font-family: Arial;
+    font-size: 13px;
+}
+
+table.content_table th
+{
+    background-color: #CCCCCC;
+}
+
+table.content_table tr
+{
+    background-color: #ffffff;
+    border-bottom: 1px solid #cfcfcf;
+}
+
+table.content_table tr.selected
+{
+	background-color: #FFFFEF;
+}
+
+button.ok
+{
+	font-size: 8px;
+	height: 17px;
+}
+
+p.ajax_message
+{
+	color: #999;
+	font-style: italic;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/category.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/category.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/category.css	(revision 795)
@@ -0,0 +1,33 @@
+/* Adapt this file to the colors you want for your categories */
+.category_1
+{
+	background-color:	#dff0df;
+}
+.category_2
+{
+	background-color:	#d5e3d5;
+}
+.category_3
+{
+	background-color:	#badaba;
+}
+.category_4
+{
+	background-color:	#8ada8a;
+}
+.category_5
+{
+	background-color:	#5fdd5f;
+}
+.category_6 
+{
+	background-color:	#00e000;
+}
+.category_7 
+{
+	background-color:	#da4a4a;
+}
+.category_8 
+{
+	background-color:	#da8a8a;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/move_instances.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/move_instances.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/move_instances.css	(revision 795)
@@ -0,0 +1,47 @@
+h2.activity
+{
+	font-size: 11px;
+	font-weight: bold;
+	cursor: default;
+}
+
+div.activities
+{
+	background-color: #FFFFFF;
+	border: 1px solid #000000;
+	/* IE Hack */
+#	height: 50px;
+}
+
+div.activities p
+{
+	text-align: center;
+}
+
+div.window
+{
+	margin-top: 10px;
+	width: 200px;
+}
+
+div.window h3
+{
+	background-color: #000000;
+	color: #FFFFFF;
+	text-align: center;
+	font-size: 12px;
+	font-weight: bold;
+	padding-top: 1px;
+	margin: 0px;
+}
+
+div#mainBody
+{
+	text-align: center;
+}
+
+button.moveInstancesButton
+{
+	margin-top: 20px !important;
+	padding: 5px !important;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/lightbox.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/lightbox.css	(revision 1990)
+++ /sandbox/workflow/branches/993/templates/default/css/lightbox.css	(revision 1990)
@@ -0,0 +1,76 @@
+/* - - - - - - - - - - - - - - - - - - - - -
+
+Title : Lightbox CSS
+Author : Kevin Hale
+URL : http://particletree.com/features/lightbox-gone-wild/
+
+Created : January 13, 2006
+Modified : February 1, 2006
+
+- - - - - - - - - - - - - - - - - - - - - */
+
+#lightbox{
+	display:none;
+	position: absolute;
+	top:50%;
+	left:50%;
+	z-index:9999;
+	width:600px;
+	min-height:50px;
+	max-height:480px;
+	height:auto !important;
+	height:480px;
+	margin:-220px 0 0 -300px;
+	border:1px solid #000000;
+/*	background:#FDFCE9;*/
+	background:#EEEEEE;
+	text-align:left;
+	overflow: auto;
+	padding: 5px;
+	height: expression(this.scrollHeight > 480 ? "480px" : "auto");/* solução para o problema de altura minima no IE */
+}
+
+.div_lightbox_body{
+	width:570px;
+	max-height:270px;
+	height:auto !important;
+	height:240px;
+	overflow: auto;
+}
+
+#lightbox[id]{
+	position:fixed;
+}
+
+#overlay{
+	display:none;
+	position:absolute;
+	top:0;
+	left:0;
+	width:100%;
+	height:100%;
+	z-index:5000;
+}
+#overlay[id]{
+	position:fixed;
+}
+
+#lightbox.done #lbLoadMessage{
+	display:none;
+}
+#lightbox.done #lbContent{
+	display:block;
+}
+#lightbox.loading #lbContent{
+	display:none;
+}
+#lightbox.loading #lbLoadMessage{
+	display:block;
+}
+
+/*
+#lightbox.done img{
+	width:100%;
+	height:100%;
+}
+*/
Index: /sandbox/workflow/branches/993/templates/default/css/run_activity.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/run_activity.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/run_activity.css	(revision 795)
@@ -0,0 +1,157 @@
+#wf_run_activity_zone
+{
+	width : 100%;
+}
+
+#wf_run_activity_message
+{
+	color: #FF0000;
+}
+
+.row_on
+{
+	 background-color: #EEEEEE;
+}
+.row_off
+{
+	background-color: #FFF;
+}
+/*********************  ACTIVITY ZONE *************/
+#wf_activity_playground
+{
+	border: 1px solid black;
+	margin-bottom:10px;
+}
+#wf_activity_title
+{
+	font-size: 120%;
+	font-weight:bold;
+}
+#wf_activity_template
+{
+	border: 0;
+	width: 100%;
+	margin : 0;
+	padding: 0;
+	color :#000000;
+}
+
+/*********************  PRIORITY ZONE *************/
+#wf_priority_zone
+{
+	background-color: #F1F1F1;
+	display:inline;
+}
+#wf_priority_label
+{
+	text-align: right;
+	margin: 3px;
+	background-color: #d3dce3;
+}
+#wf_priority_select
+{
+	text-align: left;
+}
+/********************* NEXT USER ZONE *************/
+#wf_set_next_user_zone
+{
+	background-color: #F1F1F1;
+	display: inline;
+}
+#wf_set_next_user_label
+{
+	text-align: right;
+	margin: 3px;
+	background-color: #d3dce3;
+}
+#wf_set_next_user_select
+{
+	text-align: left;
+}
+
+/********************* SET OWNER ZONE *************/
+#wf_set_owner_zone
+{
+	background-color: #F1F1F1;
+	display: inline;
+}
+#wf_set_owner_label
+{
+	text-align: right;
+	margin: 3px;
+	background-color: #d3dce3;
+}
+#wf_set_owner_select
+{
+	text-align: left;
+}
+
+/*********************  PRINT MODE ZONE *************/
+#wf_print_mode_zone
+{
+	background-color: #F1F1F1;
+	display: inline;
+	position : relative;
+	width:100%;
+	margin-left: 50px;
+	text-align: right;
+}
+.wf_print_mode_button
+{
+	width=20%;
+        font-weight:bold;
+        text-align:right;
+        background-color: #D3DCE3;
+}
+
+/*********************  SUBMIT ZONE *************/
+#wf_submit_zone
+{
+	text-align: right;
+	background-color: #F1F1F1;
+	width: 100%;
+	border-top: 1px solid black;
+}
+table.table_submit_buttons
+{
+	width: 100%;
+	border: 0; /*1px solid black;*/
+}
+.wf_submit_buttons_button
+{
+	font-weight:bold;
+	text-align:right;
+	background-color: #D3DCE3;
+}
+
+
+/*********************  WORKFLOW INFO ZONE *************/
+#workflow_info_zone
+{
+	position : relative;
+	align : center;
+	font-size:0.5em;
+	margin-bottom:10px;
+}
+table.table_info
+{
+	width: 90%;
+	border: 1px solid #000000;
+	margin: auto; /*IE5 doesn't understand it*/
+}
+tr.row_info
+{
+	height: 10px;
+}
+td.cell_info_label
+{
+	border:0px;
+	text-align: right;
+	background-color: #f1f1f1;
+}
+td.cell_info_value
+{
+	border:0px;
+	text-align: left;
+	background-color: #fafafa;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/priority.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/priority.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/priority.css	(revision 795)
@@ -0,0 +1,40 @@
+.priority_1
+{
+	background-color:	#dadada;
+}
+.priority_2
+{
+	background-color:	#dacaca;
+}
+.priority_3
+{
+	background-color:	#dababa;
+}
+.priority_4
+{
+	background-color:	#daaaaa;
+}
+.priority_5
+{
+	background-color:	#da9a9a;
+}
+.priority_6
+{
+	background-color:	#da8a8a;
+}
+.priority_7
+{
+	background-color:	#da7a7a;
+}
+.priority_8
+{
+	background-color:	#da6a6a;
+}
+.priority_9
+{
+	background-color:	#da5a5a;
+}
+.priority_10
+{
+	background-color:	#da4a4a;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/experience.panorama.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/experience.panorama.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/experience.panorama.css	(revision 795)
@@ -0,0 +1,136 @@
+/* -------------------------------------------------------------------------- *
+ *   Experience Javascript Library (version 1.0b)
+ *  (c) 2007 Ahmed Saad <ahmeds@users.sourceforge.net>
+ *
+ *  Experience is freely distributable under the terms of an MIT-style license.
+ *  For details, see project website at http://experience.sf.net
+ * -------------------------------------------------------------------------- */
+
+/* Styling for the Experience::Panorama GUI component */
+
+.panoramaCanvas {      
+    background-color: white;
+
+    /* Don't edit any of the following 
+       unless you know what you're doing .. */
+    margin: 0;
+    padding: 0;
+    border: 0;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    width: 100%;
+    height: 100%;
+    visibility: hidden; 
+    overflow: hidden;
+    /* position */
+}
+
+.panoramaImage {
+    margin: 0;
+    padding: 0;
+    border-width: 0;
+}
+
+.panoramaCloseIcon {
+   position: absolute;
+   right: 10px; 
+   top: 10px; 
+   cursor: pointer;
+}
+
+.panoramaAboutIcon {
+    top: 10px;
+    left: 10px;
+    position: absolute;
+    cursor: pointer;    
+}
+
+.panoramaZoomInIcon {
+    top: 10px;
+    left: 40px;
+    position: absolute;
+    cursor: pointer;
+}
+
+.panoramaZoomOutIcon {
+    top: 10px;
+    left: 60px;
+    position: absolute;
+    cursor: pointer;
+}
+
+.panoramaRestoreSizeIcon {
+    top: 10px;
+    left: 80px;
+    position: absolute;
+    cursor: pointer;
+}
+
+.panoramaRestorePositionIcon {
+    top: 10px;
+    left: 100px;
+    position: absolute;
+    cursor: pointer;
+}
+
+/*
+    Navigator positioning is done 
+    according to the following model
+
+    -------------------
+    16 | 16 | 16 | 10
+    16 | 16 | 16 | 10
+    16 | 16 | 16 | 10
+    10 | 10 | 10 |
+    ------------------ 
+
+    16 is icon size
+    10 is margin
+*/
+
+.panoramaGoDownIcon {
+    bottom: 10px;
+    right: 26px;
+    position: absolute;
+    cursor: default;
+}
+
+.panoramaGoUpIcon {
+    bottom: 42px;
+    right: 26px;
+    position: absolute;
+    cursor: default;
+}
+
+.panoramaGoRightIcon {
+    bottom: 26px;
+    right: 10px;
+    position: absolute;
+    cursor: default;
+}
+
+.panoramaGoLeftIcon {
+    bottom: 26px;
+    right: 42px;
+    position: absolute;
+    cursor: default;
+}
+
+.panoramaZoomDropdown{
+    bottom: 10px;
+    left: 10px;
+    position: absolute;
+    border-width: 0;
+    background-color: #93C16A;
+    color: black;
+    cursor: default;
+}
+
+.panoramaStatus {
+    top: 10px;
+    right: 40px;
+    position: absolute;
+    color: white;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/niftyCorners.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/niftyCorners.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/niftyCorners.css	(revision 795)
@@ -0,0 +1,35 @@
+/*Nifty Corners Cube CSS by Alessandro Fulciniti
+The following classes are added dinamically by javascript,
+and their use should be avoided in the markup */
+
+b.niftycorners,b.niftyfill{display:block}
+b.niftycorners *{display:block;height: 1px;line-height:1px;font-size: 1px;
+    overflow:hidden;border-style:solid;border-width: 0 1px}
+/*normal*/
+b.r1{margin: 0 3px;border-width: 0 2px}
+b.r2{margin: 0 2px}
+b.r3{margin: 0 1px}
+b.r4{height: 2px}
+b.rb1{margin: 0 8px;border-width:0 2px}
+b.rb2{margin: 0 6px;border-width:0 2px}
+b.rb3{margin: 0 5px}
+b.rb4{margin: 0 4px}
+b.rb5{margin: 0 3px}
+b.rb6{margin: 0 2px}
+b.rb7{margin: 0 1px;height:2px}
+b.rb8{margin: 0;height:2px}
+b.rs1{margin: 0 1px}
+/*transparent inside*/
+b.t1{border-width: 0 5px}
+b.t2{border-width: 0 3px}
+b.t3{border-width: 0 2px}
+b.t4{height: 2px}
+b.tb1{border-width: 0 10px}
+b.tb2{border-width: 0 8px}
+b.tb3{border-width: 0 6px}
+b.tb4{border-width: 0 5px}
+b.tb5{border-width: 0 4px}
+b.tb6{border-width: 0 3px}
+b.tb7{border-width: 0 2px;height:2px}
+b.tb8{border-width: 0 1px;height:2px}
+b.ts1{border-width: 0 2px}
Index: /sandbox/workflow/branches/993/templates/default/css/orgchartPrint.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/orgchartPrint.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/orgchartPrint.css	(revision 795)
@@ -0,0 +1,4 @@
+.invisiblePrint
+{
+	display: none;
+}
Index: /sandbox/workflow/branches/993/templates/default/css/editor.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/editor.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/editor.css	(revision 795)
@@ -0,0 +1,78 @@
+	#linenumbers {
+		width: 43px;
+		height: 100%;
+		overflow: auto;
+		position: absolute;
+		top: 0px;
+		left: 0px;
+		z-Index: 1;
+		background-color: #EEEEEE;
+		border: 0px;
+		border-right: 1px; outset buttonhighlight;
+	}
+	#codeframe > #linenumbers {
+		width: 42px;
+	}
+	#codeframe {
+		padding: 0px;
+		padding-left: 40px;
+		background-color: white;
+		height: 100%;
+		width: auto;
+	}
+	BODY {
+		font-family: courier, lucidatypewriter;	
+		font-size: 14px;
+		margin: 0px;
+	}
+    #inputLine {
+		position: absolute;
+		top:  -2px;
+		left: 44px;
+		width: 100%;
+		height: 20px;
+		overflow: display;
+		z-Index: 3;
+		margin: 0px;
+		border: 0px;
+		padding: 0px;
+    }
+	#inputLine FORM {
+		border: 0px;
+		margin: 0px;
+		padding: 0px;
+	}
+    #inputLine #inputLineEntry {
+		border: 0px; 
+		width: 100%; 
+		margin: 0px; 
+		padding: 0px;
+		background-color: #E6E6FA; 
+		font-family: courier, lucidatypewriter;	
+	}
+	code, code li, pre {
+		word-break: keep-all;
+		white-space: no-wrap;
+		font-family: courier, lucidatypewriter;	
+		font-size: 16px;
+	}
+    #content {
+		margin: 0px;
+		padding: 0px;
+		border: 0px;
+		padding-left: 4px;
+		padding-right: 4px;
+		width: auto;
+		position: absolute;
+		left: 0px;
+		z-Index: 2;
+	}
+	#content code {
+		margin: 0px;
+		padding: 0px;
+		border: 0px;
+	}
+
+	#content ol {
+		margin-top: 0px;	
+	}
Index: /sandbox/workflow/branches/993/templates/default/css/user_tabs.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/css/user_tabs.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/css/user_tabs.css	(revision 795)
@@ -0,0 +1,22 @@
+.active_tab
+{
+	color:#000000;
+	background-color:#D3DCE3;
+	border-top-width : 1px;
+	border-top-style : solid;
+	border-top-color : Black;
+	border-left-width : 1px;
+	border-left-style : solid;
+	border-left-color : Black;
+	border-right-width : 1px;
+	border-right-style : solid;
+	border-right-color : Black;
+}
+.inactive_tab
+{
+	color:#000000;
+	background-color:#E8F0F0;
+	border-bottom-width : 1px;
+	border-bottom-style : solid;
+	border-bottom-color : Black;
+}
Index: /sandbox/workflow/branches/993/templates/default/admin_agent_shared.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/admin_agent_shared.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/admin_agent_shared.tpl	(revision 795)
@@ -0,0 +1,11 @@
+<tr class="th">
+	<th class="th" colspan="2">{agent_title}</th>
+</tr>
+<tr class="th">
+	<td width="20%">{lang_Description}</th>
+	<td>{agent_description}</td>
+</tr>
+<tr class="th">
+	<td width="20%">{lang_Help}</th>
+	<td>{agent_help}</td>
+</tr>
Index: /sandbox/workflow/branches/993/templates/default/participants.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/participants.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/participants.tpl	(revision 795)
@@ -0,0 +1,134 @@
+{$header}
+{$javaScripts}
+{literal}
+<style>
+#divPoweredBy
+{
+   	display: none;
+}
+</style>
+{/literal}
+<input type="hidden" value="" id="txt_loading"/>
+<input type="hidden" id="entities" value="{$entities}"/>
+<input type="hidden" id="id" value="{$id}"/>
+<input type="hidden" id="target" value="{$target}"/>
+<input type="hidden" id="usePreffix" value="{$usePreffix}"/>
+<table border="0" width="400">
+{if !($hideOrganizations && $hideSectors)}
+	<tr id="organizationSectors">
+		{if !$hideOrganizations}
+		<td {if $hideSectors} colspan="2"{/if}>
+			{html_options values=$organizations|upper output=$organizations selected=$selectedOrganization|upper name="organization" id="organization"}
+		</td>
+		{/if}
+		{if !$hideSectors}
+		<td {if $hideOrganizations}colspan="2"{else}style="text-align: right;"{/if}>
+			{html_options options=$sectors name="sector" id="sector"}
+		</td>
+		{/if}
+	</tr>
+{/if}
+	<tr id="globalSearchTitle" style="display: none;">
+		<td colspan="2">
+			<p style="text-align: center; font-weight: bold; font-size: 130%;">Busca Global</p>
+		</td>
+	</tr>
+	{if !($hideOrganizations && $hideSectors)}
+	<tr>
+		<td>
+			<label><input type="checkbox" name="useGlobalSearch" id="useGlobalSearch"/> Utilizar busca global</label>
+		</td>
+		<td>
+			<p id="globalSearchWarnings" style="color: #FF0000; text-align: right;"></p>
+		</td>
+	</tr>
+	{/if}
+	<tr>
+		<td colspan="2">
+			<input type="text" name="search" id="search" value="" style="width: 480px;" autocomplete="off"/>
+		</td>
+	</tr>
+	<tr>
+		<td colspan="2">
+			<table border="0">
+				<tr>
+					<td>
+						{if !($hideOrganizations && $hideSectors)}
+						{html_options options=$participants name="participants" id="participants" multiple="multiple" style="height: 210px; width: 425px;"}
+						{else}
+						{html_options options=$participants name="participants" id="participants" multiple="multiple" style="height: 260px; width: 425px;"}
+						{/if}
+					</td>
+					<td>
+						<a id="addUserLink"><img src="workflow/templateFile.php?file=images/add_user_big.png" alt="Adicionar" title="Adicionar" id="addUser" style="cursor: pointer;"/></a>
+						<br/><br/><br/>
+						<a id="exitLink"><img src="workflow/templateFile.php?file=images/exit_big.png" alt="Sair" title="Sair" id="exit" style="cursor: pointer;"/></a>
+					</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+
+	{*<title>{lang_Add_Participants}</title>
+	<script src="{js_participant_file}" type="text/javascript"></script>
+	<form name="frmAdd" method="POST" onsubmit="javascript:{add_function}; return false;">
+	 <center>
+	  <table cellspacing="3" cellpadding="3">
+	   <tr>
+		 <td>
+		  <div id="divAppboxHeader">{lang_Add_Participants}</div>
+		  <div id="divAppbox">
+		   <table border=0>
+			<tr><td>{lang_Organization}:</td></tr>
+			<tr><td>
+				<select name="organization" style='width:250px;' onchange="frmAdd.change_org.value='True';frmAdd.submit();">
+					<!-- BEGIN organization_block -->
+					<option value="{org_id}" {org_selected}>{org_name}</option>
+					<!-- END organization_block -->
+				</select>
+			</td></tr>
+			<tr><td>{lang_sector}:</td></tr>
+			<tr><td>
+				<select name="sector" style='width:250px;' onchange="frmAdd.submit()">
+					<!-- BEGIN sector_block -->
+					<option value="{sector_id}" {sector_selected}>{sector_name}</option>
+					<!-- END sector_block -->
+				</select></td></tr>
+			<input type="hidden" name="change_org" value="false">
+			<tr>
+			 <td>
+			  <select name="participants" multiple style="width:250px" size="18" id="participant_list">
+				<!-- BEGIN user_group_block -->
+				{participant_options}
+				<!-- END user_group_block -->
+			  </select>
+			 </td>
+		    </tr>
+			<tr><td>&nbsp;</td>	</tr>
+			<tr>
+			 <td>
+			  <center>{lang_to_Search}:&nbsp;<input type="text" id="query" name="query" onkeyup="optionFinder(this, event)" autocomplete="off" /></center>
+			 </td>
+			</tr>
+			<tr><td>&nbsp;</td>	</tr>
+			<tr>
+			 <td>
+			  <center>
+			   <input type="button" id="addButton" class="button" value={lang_Add} onClick="javascript:{add_function}">
+			   <input type="button" id="closeButton" value={lang_Close} onClick="javascript:window.close()">
+			  </center>
+			 </td>
+			</tr>
+		   </table>
+		  </div>
+		 </td>
+		</tr>
+	   </table>
+	  </center>
+	 </form>
+<script>
+	setLists('participant_list','{target_element}');
+	document.getElementById("query").focus();
+</script>
+*}
Index: /sandbox/workflow/branches/993/templates/default/config.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/config.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/config.tpl	(revision 795)
@@ -0,0 +1,555 @@
+<!-- BEGIN header -->
+<form method="POST" action="{action_url}">
+<table border="0" align="center" cellspacing="1" cellpading="1" width="90%">
+   <tr class="th">
+	   <td colspan="3"><font color="{th_text}">&nbsp;<b>{title}</b></font></td>
+   </tr>
+   <tr class="row_on" bgcolor="{th_err}">
+    <td colspan="3">&nbsp;<b>{error}</b></font></td>
+   </tr>
+<!-- END header -->
+<!-- BEGIN body -->
+	<tr class="th">
+		<td colspan="3">&nbsp;<b>{lang_Workflow_configuration}</b></font></td>
+	</tr>
+	<tr class="row_on">
+		<td colspan="3">&nbsp;<b>{error}</b></font></td>
+	</tr>
+	<tr class="th">
+		<td colspan="2">&nbsp;<b>{lang_Default_settings_for_processes}</b></font></td>
+		<td class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;<b>{lang_Graphic_options}</b></font></td>
+		<td colspan="2" class="row_on">&nbsp;</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_draw_roles_on_the_graph_beside_activity_name_like_[that]}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_draw_roles}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[draw_roles]">
+                                <option value="False" {selected_draw_roles_False}>{lang_No}</option>
+                                <option value="True" {selected_draw_roles_True}>{lang_Yes}</option>
+                        </select>
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_size_of_the_font_used_on_the_graph_12_should_be_a_good_default_value}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_font_size}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="3" name="newsettings[font_size]" value="{value_font_size}">
+		</td>
+	</tr>
+
+	<tr class="th">
+		<td>&nbsp;<b>{lang_Running_activities_options}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_this_will_automatically_release_the_instance_when_leaving_an_activity_without_completing}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_auto-release_on_leaving_activity}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[auto-release_on_leaving_activity]">
+                               	<option value="False" {selected_auto-release_on_leaving_activity_False}>{lang_No}</option>
+                                <option value="True" {selected_auto-release_on_leaving_activity_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_the_activities_will_be_executed_using_secure_connection}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_use_secure_connection}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[execute_activities_using_secure_connection]">
+				<option value="False" {selected_execute_activities_using_secure_connection_False}>{lang_No}</option>
+				<option value="True" {selected_execute_activities_using_secure_connection_True}>{lang_Yes}</option>
+			</select>
+		</td>
+	</tr>
+
+	<tr class="th">
+		<td>&nbsp;<b>{lang_Actions_Right_Options}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_owner_of_the_instance_will_have_the_right_to_abort_the_instance_at_any_time}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ownership_give_abort_right}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[ownership_give_abort_right]">
+                               	<option value="False" {selected_ownership_give_abort_right_False}>{lang_No}</option>
+                                <option value="True" {selected_ownership_give_abort_right_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_owner_of_the_instance_will_have_the_right_to_exception_or_resume_the_instance_at_any_time}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ownership_give_exception_right}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[ownership_give_exception_right]">
+                               	<option value="False" {selected_ownership_give_exception_right_False}>{lang_No}</option>
+                                <option value="True" {selected_ownership_give_exception_right_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_owner_of_the_instance_will_have_the_right_to_release_(un-assign)_an_activity_assigned_to_an_user}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ownership_give_release_right}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[ownership_give_release_right]">
+                               	<option value="False" {selected_ownership_give_release_right_False}>{lang_No}</option>
+                                <option value="True" {selected_ownership_give_release_right_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_if_user_is_in_a_role_for_an_activity_he_will_have_the_right_to_abort_the_related_instance}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_role_give_abort_right}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[role_give_abort_right]">
+                               	<option value="False" {selected_role_give_abort_right_False}>{lang_No}</option>
+                                <option value="True" {selected_role_give_abort_right_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_if_user_is_in_a_role_for_an_activity_he_will_have_the_right_to_exception_or_resume_the_related_instance}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_role_give_exception_right}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[role_give_exception_right]">
+                               	<option value="False" {selected_role_give_exception_right_False}>{lang_No}</option>
+                                <option value="True" {selected_role_give_exception_right_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_if_user_is_in_a_role_for_an_activity_he_will_have_the_right_to_release_(un-assign)_the_related_instance}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_role_give_release_right}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[role_give_release_right]">
+                               	<option value="False" {selected_role_give_release_right_False}>{lang_No}</option>
+                                <option value="True" {selected_role_give_release_right_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_disable_advanced_actions_for_all_users}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_disable_advanced_actions}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[disable_advanced_actions]">
+                               	<option value="False" {selected_disable_advanced_actions_False}>{lang_No}</option>
+                                <option value="True" {selected_disable_advanced_actions_True}>{lang_Yes}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;<b>{lang_log_options_for_workflow}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_log_level_for_workflow}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_log_level}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[log_level]">
+                               	<option value="0" {selected_log_level_0}>{lang_emergency}</option>
+                                <option value="1" {selected_log_level_1}>{lang_alert}</option>
+                                <option value="2" {selected_log_level_2}>{lang_critical}</option>
+                                <option value="3" {selected_log_level_3}>{lang_error}</option>
+                                <option value="4" {selected_log_level_4}>{lang_warning}</option>
+                                <option value="5" {selected_log_level_5}>{lang_notice}</option>
+                                <option value="6" {selected_log_level_6}>{lang_information}</option>
+                                <option value="7" {selected_log_level_7}>{lang_debug}</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_allowed_log_types_for_workflow}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_log_types}:
+		</td>
+		<td width="20%" class="td_right">
+			<table cellpadding="0" cellspacing="0">
+				<tr>
+					<td>
+						{lang_file}&nbsp;&nbsp;&nbsp;
+					</td>
+					<td>
+						<select name="newsettings[log_type_file]">
+							<option value="False" {selected_log_type_file_False}>{lang_No}</option>
+							<option value="True" {selected_log_type_file_True}>{lang_Yes}</option>
+						</select>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						{lang_firebug}&nbsp;&nbsp;&nbsp;
+					</td>
+					<td>
+						<select name="newsettings[log_type_firebug]">
+							<option value="False" {selected_log_type_firebug_False}>{lang_No}</option>
+							<option value="True" {selected_log_type_firebug_True}>{lang_Yes}</option>
+						</select>
+					</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+
+	<tr class="th">
+		<td>&nbsp;<b>{lang_database_options_for_workflow}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_name_of_the_database_used_to_store_data_of_the_workflow_module}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_name}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[workflow_database_name]" value="{value_workflow_database_name}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_database_server_where_the_database_is_stored}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_host}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[workflow_database_host]" value="{value_workflow_database_host}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_port_used_to_connect_to_database_server}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_port}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[workflow_database_port]" value="{value_workflow_database_port}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_user_to_access_the_database}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_user}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[workflow_database_user]" value="{value_workflow_database_user}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_password_of_the_default_user}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_password}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[workflow_database_password]" value="{value_workflow_database_password}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_type_of_the_database}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_type}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[workflow_database_type]">
+				<option value="pgsql" {selected_workflow_database_type_pgsql}>PostgreSQL</option>
+			</select>
+		</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;<b>{lang_database_options_for_processes}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_name_of_the_database_used_to_store_data_from_workflow_processes}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_name}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[database_name]" value="{value_database_name}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_database_server_where_the_database_is_stored}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_host}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[database_host]" value="{value_database_host}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_port_used_to_connect_to_database_server}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_port}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[database_port]" value="{value_database_port}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_default_user_to_access_the_database}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_user}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[database_admin_user]" value="{value_database_admin_user}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_password_of_the_default_user}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_password}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[database_admin_password]" value="{value_database_admin_password}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_type_of_the_database}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_database_type}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[database_type]">
+                               	<option value="pgsql" {selected_database_type_pgsql}>PostgreSQL</option>
+       	                </select>
+		</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;<b>{lang_ldap_options}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_host_of_the_ldap}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ldap_host}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[ldap_host]" value="{value_ldap_host}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_user_context_of_the_ldap}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ldap_user_context}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[ldap_user_context]" value="{value_ldap_user_context}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_group_context_of_the_ldap}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ldap_group_context}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[ldap_group_context]" value="{value_ldap_group_context}" />
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_follow_ldap_referrals}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_follow_referrals}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[ldap_follow_referrals]">
+				<option value="False" {selected_ldap_follow_referrals_False}>{lang_No}</option>
+				<option value="True" {selected_ldap_follow_referrals_True}>{lang_Yes}</option>
+			</select>
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_user_of_the_ldap}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ldap_user}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[ldap_user]" value="{value_ldap_user}"/>
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_password_of_the_ldap_user}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_ldap_password}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[ldap_password]" value="{value_ldap_password}"/>
+		</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;<b>{lang_mainframe_options}</b></font></td>
+		<td colspan="2" class="row_off">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_ip_of_the_mainframe}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_mainframe_ip}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[mainframe_ip]" value="{value_mainframe_ip}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_port_used_to_connect_the_mainframe}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_access_mainframe_port}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[mainframe_port]" value="{value_mainframe_port}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_key_used_to_access_the_mainframe}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_access_mainframe_key}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[mainframe_key]" value="{value_mainframe_key}">
+		</td>
+	</tr>
+	<tr class="row_off">
+		<td width="60%" class="td_left">
+			{lang_password_used_to_access_the_mainframe}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_access_mainframe_password}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[mainframe_password]" value="{value_mainframe_password}">
+		</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_environment_application_to_mainframe}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_mainframe_environment}:
+		</td>
+		<td width="20%" class="td_right">
+			<select name="newsettings[mainframe_environment]">
+				<option value="D" {selected_mainframe_environment_D}>(D) Desenvolvimento</option>
+				<option value="P" {selected_mainframe_environment_P}>(P) Produção</option>
+			</select>
+		</td>
+	</tr>
+	<tr class="th">
+		<td>&nbsp;<b>{lang_External_Applications_options}</b></font></td>
+		<td colspan="2" class="row_on">&nbsp;</td>
+	</tr>
+	<tr class="row_on">
+		<td width="60%" class="td_left">
+			{lang_subnetworks_of_the_intranet_(separed_by_;)}
+		</td>
+		<td width="20%" class="td_right">
+			{lang_subnetworks}:
+		</td>
+		<td width="20%" class="td_right">
+			<input type="text" size="20" name="newsettings[intranet_subnetworks]" value="{value_intranet_subnetworks}"/>
+		</td>
+	</tr>
+<!-- END body -->
+<!-- BEGIN footer -->
+  <tr class="row_off">
+    <td colspan="3">
+&nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td colspan="3" align="center">
+      <input type="submit" name="submit" value="{lang_submit}">
+      <input type="submit" name="cancel" value="{lang_cancel}">
+    </td>
+  </tr>
+</table>
+</form>
+<!-- END footer -->
Index: /sandbox/workflow/branches/993/templates/default/reseditor.html
===================================================================
--- /sandbox/workflow/branches/993/templates/default/reseditor.html	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/reseditor.html	(revision 795)
@@ -0,0 +1,22 @@
+<html>
+<head>
+
+  <title>Resource Editor</title>
+  <link rel="stylesheet" type="text/css" href="css/editor.css">
+  <link rel="stylesheet" type="text/css" href="css/highlighthtml.css">
+  <script src="../../js/resourceeditor/highlight.js"></script>
+  <script src="../../js/phpeditor/editor.js"></script>
+</head>
+<body onLoad="init();">
+<div id='codeframe'>
+<div id="linenumbers"></div>
+<div id="inputLine">
+<textarea id="inputLineEntry" wrap="off"></textarea>
+</div>
+<div id="content">
+<ol id="lines"><li>&nbsp;
+</li></ol>
+</div>
+</div>
+</body>
+</html>
Index: /sandbox/workflow/branches/993/templates/default/processes/header.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/processes/header.tpl	(revision 1450)
+++ /sandbox/workflow/branches/993/templates/default/processes/header.tpl	(revision 1450)
@@ -0,0 +1,59 @@
+{* ARQUIVOS CSS *}
+<link rel="stylesheet" type="text/css" href="{$wf_default_resources_path}/default.css">
+<link rel="stylesheet" type="text/css" href="{$wf_default_resources_path}/screen.css">
+{* ARQUIVOS JS *}
+{* componente que faz a ligação entre a camada view e a camada de controle *}
+<script type="text/javascript" src="{$wf_js_path}/../scriptaculous/prototype.js"></script>
+{literal}
+<script type="text/javascript">
+function actionDelete()
+{
+	return (confirm('Deseja realmente remover o registro?'));
+}
+
+function dispatch(acaoSolicitada, args)
+{
+	if (acaoSolicitada == 'Excluir')
+		if (!actionDelete())
+			return;
+
+	document.forms["workflow_form"].elements["action"].value = acaoSolicitada;
+	if (args) {
+		document.forms["workflow_form"].elements["params"].value = args;
+	}
+	document.forms["workflow_form"].submit();
+}
+</script>
+{/literal}
+{* CABEÇALHO HTML *}
+<span class="titulo">{$activity_title}</span>
+<div id="barra_acao_top">
+  <table width="100%">
+    <tr>
+      <td width="150">{wf_redir_menu}</td>
+      <td><div id="menu">
+          <ul>
+          	{* variáveis $inbox e $processes são configuradas no controlador do processo *}
+            <li><a href="{$wf_workflow_path}/index.php?start_tab=0" title="Tarefas Pendentes">Tarefas Pendentes</a></li>
+            <li><a href="{$wf_workflow_path}/index.php?start_tab=1" title="Executar Processos">Processos</a></li>
+          </ul>
+        </div></td>
+      <td>
+      <td width="30"><a href="javascript:history.back()" title="Voltar para página anterior">voltar</a></td>
+      <td width="16"><a href="javascript:history.back()"><img src="{$wf_default_resources_path}/icon_voltar.png" border="0"></a></td>
+      {* NÃO IMPLEMENTADO!!! *}
+	  {if $help ne ""}
+	      <td width="30"><a href="#" title="Obter ajuda do sistema">&nbsp;ajuda</a></td>
+    	  <td width="16"><a href="#"><img src="{$wf_default_resources_path}/icon_ajuda.png" border="0"></a></td>
+	  {/if}
+      </td>
+    </tr>
+  </table>
+</div>
+<div>
+
+</div>
+{* componente de navegação que informa ao controlador mvc qual a ação solicitada *}
+<input  type="hidden" name="action" value="">
+{* argumentos opcionais enviados para o controlador mvc repassar a camada model *}
+<input  type="hidden" name="params" value="">
Index: /sandbox/workflow/branches/993/templates/default/processes/footer.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/processes/footer.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/processes/footer.tpl	(revision 795)
@@ -0,0 +1,9 @@
+{* RODAPï¿œ HTML *}
+<div id="barra_acao_bottom">
+	<table align="right" cellspacing="0">
+		<tr>
+			<td><a href="javascript: window.scrollTo(0, 0); void 0">topo&nbsp;</a></td><td><a href="javascript: window.scrollTo(0, 0); void 0"><img src="{$wf_default_resources_path}/icon_topo.png" border="0"></a></td>
+			<td>&nbsp;</td>
+		</tr>
+	</table>
+</div>
Index: /sandbox/workflow/branches/993/templates/default/processes/screen.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/processes/screen.css	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/processes/screen.css	(revision 795)
@@ -0,0 +1,49 @@
+/* Default styles */
+
+#etapa {
+	display:block;
+	position:absolute;
+	left:100%;
+	font-family:Verdana, Arial, Helvetica, sans-serif;
+	color:#000000;
+	font-size:10px;
+	margin-left:-100px;
+	margin-top:-13px;
+}
+
+#list_tabela th a{
+	border-bottom:1px solid #5F6E86;
+	border-left:1px solid #FFFFFF;
+	color: #FFFFFF;
+	padding-left: 2px;
+	padding-right: 2px;
+	text-align:left;
+	font-size:11px;
+}
+
+#list_tabela th a:hover{
+	color: #009900;
+}
+
+.form_tabela td.form_label {
+	width:-50%;	
+}
+h1 img {
+	position:relative;
+	margin-bottom:-2px;
+}
+h2 p {
+	float:right;
+	margin-top:-16px;
+}
+
+h2 a {
+	margin-top:-18px;
+	color:#FFFFFF;
+}
+
+
+h2 a img{
+	border:none;
+}
+
Index: /sandbox/workflow/branches/993/templates/default/processes/default.css
===================================================================
--- /sandbox/workflow/branches/993/templates/default/processes/default.css	(revision 1428)
+++ /sandbox/workflow/branches/993/templates/default/processes/default.css	(revision 1428)
@@ -0,0 +1,785 @@
+/* Default styles */
+body {
+	margin: 0px;
+	padding: 0px;
+	background-color:#FFF;
+
+}
+a {
+	color: #000000 !important;
+}
+a:hover {
+	color: #000000 !important;
+	text-decoration: underline !important;
+}
+a:visited {
+	color: #2663A6 !important;
+}
+
+.titulo {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 15px !important;
+	#font-size: 13px;
+	color: #000559 !important;
+	font-weight: bold;
+}
+#msg, .msg, .destaque_formulario {
+	background-color:#F7F3EF;
+	border: 1px solid #CDC0B0;
+	padding: 7px;
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 12px;
+	color: #000000;
+	text-align:left !important;
+	margin-bottom:8px;
+}
+.msg_erro {
+	color:#CC0000 !important;
+	font-size: 12px !important;
+}
+.msg_aviso {
+	color:#000000 !important;
+	font-size: 12px !important;
+}
+.msg_sucesso {
+	color:#006600 !important;
+	font-size: 12px !important;
+}
+
+.msg_descricao {
+	color:#999999 !important;
+	font-style:italic !important;
+}
+#conteudo {
+    text-align:center;
+	background-color:#FFFFFF;
+	padding: 15px;
+	position:relative;
+	color: #000000 !important;
+	#width:99%;
+
+}
+#conteudo_corpo {
+	background-color:#F7F3EF;
+	border: 1px solid #CDC0B0;
+	padding: 15px;
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 11px !important;
+	color: #000000 !important;
+	text-align:left;
+	margin-top:8px;
+	line-height:150%;
+	_width:100%;
+	-moz-border-radius-topright: 9px;
+	-moz-border-radius-topleft: 9px;
+	-moz-border-radius-bottomright: 9px;
+	-moz-border-radius-bottomleft: 9px;
+
+}
+#conteudo_abas {
+	background-color:#FFFFFF;
+	border-top: none;
+	padding: 0px;
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 12px;
+	color: #000000 !important;
+	text-align:left;
+	line-height:150%;
+
+}
+
+.abas {
+	background-color:#F7F3EF;
+	font-size: 12px !important;
+	text-align:center;
+	color: #000000 !important;
+	border-top: 1px solid #8B7D6B;
+	border-right: 1px solid #8B7D6B;
+	border-bottom: 1px solid #8B7D6B;
+	margin-top:8px;
+}
+
+.abas td {
+	padding:5px;
+	border-left:1px solid #FF1CAE;
+	border-bottom:1px solid #FF1CAE;
+	text-align:center;
+}
+.abas a {
+	color:#000000 !important;
+}
+.abas a:hover {
+	color:#FF1CAE;
+}
+
+.aba_inicial_esquerda {
+	border-bottom: 5px solid #8B7D6B;
+	border-right: 1px solid #8B7D6B;
+}
+
+.aba_inicial_direita {
+	border-bottom: 5px solid #8B7D6B;
+}
+
+.aba_selecionada {
+	text-align:center;
+	font-size: 12px !important;
+	color:#000000 !important;
+	background-color:#FFFFFF;
+	font-weight: bold;
+	border-bottom:1px solid #FFFFFF !important;
+	border-top: 1px solid #8B7D6B;
+	border-right: 1px solid #8B7D6B;
+}
+
+.aba_simples {
+	border-left: 1px solid #CDC0B0;
+	border-right: 1px solid #CDC0B0;
+}
+
+.aba_simples_selecionada {
+	border-left: 1px solid #CDC0B0;
+	border-right: 1px solid #CDC0B0;
+	background-color: #CDC0B0;
+}
+
+
+#list_tabela {
+	margin-top:5px;
+    margin-bottom:5px;
+    border-top:1px solid #CDC0B0;
+    border-right:1px solid #CDC0B0;
+    border-bottom:1px solid #CDC0B0;
+}
+
+#list_tabela th {
+	background-color: #8B7D6B;
+    border-bottom:1px solid #CDC0B0;
+    border-left:1px solid #CDC0B0;
+    color: #FFFFFF;
+    padding-left: 2px;
+    padding-right: 2px;
+    text-align:left;
+    font-size:12px !important;
+    font-weight:bold;
+    height: 18px;
+}
+
+.separator_list {
+	background-color: #C6B891;
+	border-bottom:1px;
+	border-left:1px;
+	color: #FFFFFF !important;
+	padding-left: 2px;
+	padding-right: 2px;
+	text-align:left;
+	font-size:11px;
+	font-weight:bold;
+	height: 18px;
+}
+
+#list_tabela td {
+	padding:3px;
+    border-left:1px solid #CDC0B0;
+    color:#000000 !important;
+    font-size: 11px !important;
+}
+.list_cor_sim {
+	background-color: #F7F3EF;
+}
+.list_cor_hover {
+	background-color:#E6D9CC;
+}
+.list_cor_nao {
+	background-color: #FFFAFA;
+}
+.list_sem_cor {
+	border-top:1px solid #CDC0B0;
+}
+
+fieldset {
+	border: 0 none;
+}
+.div_form_linha {
+	margin-top:7px;
+	margin-bottom:8px;
+	clear: left;
+}
+.form_label, .div_form_label {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 11px !important;
+	color: #000000 !important;
+	vertical-align: top;
+	padding: 3px;
+	text-align:left;
+	font-weight:bold;
+}
+.div_form_label {
+	clear: left;
+	float: left;
+	padding-left: 10px;
+	width: 163px;
+}
+.obrigatorio{
+	padding-left: 0px !important;
+	width: 173px;
+}
+.form_botao {
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	color: black !important;
+	font-size:12px !important;
+	padding-top:2px !important;
+	padding-right:4px !important;
+	padding-bottom:2px !important;
+	padding-left:4px !important;
+	margin-left:1px !important;
+	margin-right:1px !important;
+	margin-top:2px !important;
+	background-color: #eeeeee !important;
+	border-right: 2px solid #808281 !important;
+	border-bottom: 2px solid #808281 !important;
+	border-top: 2px solid white !important;
+	border-left: 2px solid white !important;
+}
+
+.form_opcoes {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 10px;
+	color: #FFFFFF;
+	text-align:center;
+	margin-top:10px;
+}
+.form_opcoes a {
+	color: #FFFFFF;
+}
+.form_opcoes a:hover {
+	color: #0067CE;
+}
+#cabecalho {
+	display:block;
+	background-color:#0099FF;
+	height:43px;
+	padding:0px;
+	margin:0px;
+	border-top:3px solid #5EB0FF;
+}
+
+#menu ul {
+	padding:0px;
+	margin:0px;
+	float: left;
+	width: 100%;
+	background-color:#F7F3EF;
+	list-style:none;
+	font:80% Tahoma;
+}
+
+#menu ul li { display: inline; }
+
+#menu ul li a {
+	background-color:#F7F3EF;
+	color: #333 !important;
+	text-decoration: none !important;
+	border-bottom:3px solid #8B7D6B;
+	padding: 2px 10px;
+	float:left;
+	margin-right:2px;
+}
+
+#menu ul li a:hover {
+/*	background-color:#D6D6D6; */
+	color: #5EB0FF !important;
+	border-bottom:3px solid #5EB0FF;
+	text-decoration: none !important;
+/*	font-weight:bold;
+*/}
+
+#rodape {
+	width:668px;
+	height:53px;
+	display:block;
+	background-color:#F6C491;
+	position: absolute;
+	top: 324px;
+	left:50%;
+	margin-left:-334px;
+}
+#rodape table {
+	width:100%;
+}
+.text_rodape {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 10px !important;
+	color: #87470E !important;
+	text-align:left;
+	padding-left:10px;
+	padding-right:10px;
+	line-height:150%;
+}
+h1 {
+	font-family:Arial, Helvetica, sans-serif !important;
+	font-size:14px !important;
+	font-weight:bold;
+	color:#000000 !important;
+	text-align:left;
+	margin: 0px 0px 2px 0px;
+	border-bottom:1px solid #8B7D6B;
+	#font-size:12px;
+}
+h2 {
+	display:block;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:11px !important;
+	font-weight:bold;
+	color:#FFFFFF !important;
+	height:18px;
+	background-color:#333333;
+	padding: 4px 1px 1px 10px;
+	margin:3px 0px 0px 0px;
+	-moz-border-radius-topright: 9px;
+	-moz-border-radius-topleft: 9px;
+}
+
+hr {
+	border-top:1px dashed #CDC0B0;
+	border-right:none;
+	border-bottom:none;
+	border-left:none;
+	height:1px;
+	margin:3px 0px 3px 0px;
+}
+
+.form_tabela, .div_form {
+	text-align:left !important;
+	background-color:#FBFAF8 !important;
+	padding:10px !important;
+	#border: 10px solid #FBFAF8;
+}
+.div_form {
+	padding: 4px !important;
+}
+.dark_table  {
+	background-color: #EFEFEF !important;
+	border: 0px !important!;
+}
+
+
+.form_tabela td {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 11px !important;
+	color:#000000 !important;
+	padding: 3px;
+
+}
+form {
+	margin: 0px;
+	padding: 0px;
+}
+input {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 12px !important;
+	color: #000559 !important;
+	padding: 1px 0px 1px 4px !important;
+	border-top: 1px solid #808281 !important;
+	border-left: 1px solid #808281 !important;
+	border-right: 1px solid white !important;
+	border-bottom: 1px solid white !important;
+	vertical-align: middle !important;
+
+}
+.input_like_label {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 12px !important;
+	color: #000559 !important;
+	padding: 1px 0px 1px 4px !important;
+	vertical-align: middle !important;
+	border-width: 0px !important;
+	background-color: transparent !important;
+}
+input.checkbox {
+	border: 0px !important;
+}
+select {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 12px !important;
+	border-top: 1px solid #808281 !important;
+	border-left: 1px solid #808281 !important;
+	border-right: 1px solid white !important;
+	border-bottom: 1px solid white !important;
+
+}
+textarea {
+	font-family: Verdana, Arial, Helvetica, sans-serif !important;
+	font-size: 12px !important;
+	color: #000559 !important;
+	padding: 1px 0px 1px 4px !important;
+	border-top: 1px solid #808281 !important;
+	border-left: 1px solid #808281 !important;
+	border-right: 1px solid white !important;
+	border-bottom: 1px solid white !important;
+
+}
+
+#barra_acao_top {
+	display:block;
+	border: 1px solid #CDC0C0 !important;
+	background-color:#F7F3EF !important;
+	padding-right:15px !important;
+	height:29px !important;
+	#width:99%;
+}
+#barra_acao_top a,td {
+	color:#000000 !important;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:10px !important;
+	text-decoration:none !important;
+}
+#barra_acao_top a:hover {
+	text-decoration:underline !important;
+	color:#0067CE !important;
+}
+#barra_localizacao {
+	color:#333333 !important;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:10px !important;
+	float:left;
+	padding-left:10px;
+	padding-top:4px;
+}
+#barra_paginacao {
+	color:#000000 !important;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:10px !important;
+	width:100%;
+}
+#barra_paginacao td {
+	color:#000000 !important;
+}
+#barra_paginacao a {
+	color:#000000 !important;
+}
+#barra_paginacao a:hover {
+	color: #0067CE !important;
+}
+#barra_acao_bottom {
+	display:block;
+	border: 1px solid #CDC0B0;
+	background-color:#F7F3EF;
+	padding-right:15px;
+	height:19px;
+	#width:99%;
+}
+#barra_acao_bottom a,td {
+	color:#000000 !important;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:10px !important;
+	text-decoration:none !important;
+}
+#barra_acao_bottom a:hover {
+	text-decoration:underline !important;
+	color:#0067CE !important;
+}
+.obs_obrigatorio {
+	color:#333333 !important;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:11px !important;
+	text-align:left;
+	margin:0px;
+}
+.exemplo {
+	color: #ff4200;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:11px !important;
+	text-align:left;
+	margin:0px;
+	font-weight: normal;
+}
+#destacado, .destaque {
+	border: 0px solid #333333;
+	background-color: #E1DFD2;
+	font-size: 12px !important;
+	#font-size: 11px !important;
+	padding: 10px;
+	color: #403c31 !important;
+	-moz-border-radius-topright: 9px;
+	-moz-border-radius-topleft: 9px;
+	-moz-border-radius-bottomright: 9px;
+	-moz-border-radius-bottomleft: 9px;
+}
+
+#wf_activity_playground {
+ 	border: 0px;
+}
+
+.borda_table {
+	border-collapse: collapse;
+	border: 2px solid #333333;
+	background-color:#FBFAF8;
+	padding: 10px;
+}
+
+.borda_table tr {
+	background-color:#FBFAF8;
+}
+
+.borda_table td {
+	background-color:#FBFAF8;
+}
+
+.th_borda_table {
+	display:block;
+	font-family:Verdana, Arial, Helvetica, sans-serif !important;
+	font-size:11px !important;
+	font-weight:bold;
+	color:#FFFFFF !important;
+	background-color:#333333;
+	height:18px;
+	padding:4px 1px 1px 10px;
+	margin:0px 0px 0px 0px;
+	-moz-border-radius-topright: 9px;
+	-moz-border-radius-topleft: 9px;
+}
+
+#list_tabela_clara {
+    margin-top:5px;
+    margin-bottom:5px;
+    border-top:1px solid #CDC0B0;
+    border-right:1px solid #CDC0B0;
+    border-bottom:1px solid #CDC0B0;
+}
+
+#list_tabela_clara th {
+    background-color: #8B7D6B;
+    border-bottom:1px solid #CDC0B0;
+    border-left:1px solid #CDC0B0;
+    color: #FFFFFF;
+    padding-left: 2px;
+    padding-right: 2px;
+    text-align:left;
+    font-size:12px !important;
+    font-weight:bold;
+    height: 18px;
+}
+
+#list_tabela_clara td {
+    padding:3px;
+    border-left:1px solid #CDC0B0;
+    color:#000000 !important;
+    font-size: 11px !important;
+}
+
+img{
+	vertical-align:middle;
+}
+
+#lightbox {
+	background-color: #333333 !important;
+}
+
+#sheet, .sheet {
+	background-color:#FFFFFF;
+	border-top: 	1px solid #000000;
+	border-left: 	1px solid #000000;
+	border-bottom: 	3px solid #000000;
+	border-right: 	3px solid #000000;
+	padding-top: 	40px;
+	padding-left: 	40px;
+	padding-bottom:	40px;
+	padding-right: 	40px;
+	text-align:left !important;
+}
+
+ul.horizontalMenu
+{
+	list-style: none;
+	padding: 0px;
+	margin: 0px;
+}
+
+ul.horizontalMenu li
+{
+	float: left;
+	margin: 0pt;
+	text-align: left;
+}
+
+ul.horizontalMenu li a
+{
+	border: 1px solid #E6D9CC;
+	background-color: #F7F3EF !important;
+	padding: 0px 05px 0px 05px;
+	height: 2.5em;
+	line-height: 2.5em;
+	float: left;
+	display: block;
+	color: #333333 !important;
+	text-decoration: none;
+	text-align: center;
+	font-size: 11px !important;
+}
+
+ul.horizontalMenu li a:hover
+{
+	background-color: #E6D9CC !important;
+	border: 1px solid #8B7D6B;
+	color: darkblue !important;
+	text-decoration: none !important;
+}
+
+ul.horizontalMenu li a:visited
+{
+	color: #000000 !important;
+}
+
+ul.horizontalMenu li a img
+{
+	vertical-align: middle;
+}
+
+ul.horizontalMenu
+{
+    list-style: none;
+    padding: 0px;
+    margin: 0px;
+}
+
+ul.horizontalMenu li
+{
+    float: left;
+    margin: 0pt;
+    text-align: left;
+}
+
+ul.horizontalMenu li a
+{
+    border: 1px solid #E6D9CC;
+    background-color: #F7F3EF !important;
+    padding: 0px 05px 0px 05px;
+    height: 2.5em;
+    line-height: 2.5em;
+    float: left;
+    display: block;
+    color: #333333 !important;
+    text-decoration: none;
+    text-align: center;
+    font-size: 11px !important;
+}
+
+ul.horizontalMenu li a:hover
+{
+    background-color: #E6D9CC !important;
+    border: 1px solid #8B7D6B;
+    color: darkblue !important;
+    text-decoration: none !important;
+}
+
+ul.horizontalMenu li a:visited
+{
+    color: #000000 !important;
+}
+
+ul.horizontalMenu li a img
+{
+    vertical-align: middle;
+}
+
+ul.horizontalMenu
+{
+    list-style: none;
+    padding: 0px;
+    margin: 0px;
+}
+
+ul.horizontalMenu li
+{
+    float: left;
+    margin: 0pt;
+    text-align: left;
+}
+
+ul.horizontalMenu li a
+{
+    border: 1px solid #E6D9CC;
+    background-color: #F7F3EF !important;
+    padding: 0px 05px 0px 05px;
+    height: 2.5em;
+    line-height: 2.5em;
+    float: left;
+    display: block;
+    color: #333333 !important;
+    text-decoration: none;
+    text-align: center;
+    font-size: 11px !important;
+}
+
+ul.horizontalMenu li a:hover
+{
+    background-color: #E6D9CC !important;
+    border: 1px solid #8B7D6B;
+    color: darkblue !important;
+    text-decoration: none !important;
+}
+
+ul.horizontalMenu li a:visited
+{
+    color: #000000 !important;
+}
+
+ul.horizontalMenu li a img
+{
+    vertical-align: middle;
+}
+
+div.autocomplete {
+    margin:0px;
+    padding:0px;
+    width:355px;
+    background:#fff;
+    border:1px solid #888;
+    position:absolute;
+}
+
+div.autocomplete ul {
+    margin:0px;
+    padding:0px;
+    list-style-type:none;
+}
+
+div.autocomplete ul li.selected {
+    background-color:#ffb;
+}
+
+div.autocomplete ul li {
+    margin:0;
+    padding:2px;
+    height:16px;
+    display:block;
+    list-style-type:none;
+    cursor:pointer;
+}
+
+.span_message_notice, .span_message_success, .span_message_error {
+    font-weight: bold;
+    font-size: 90%;
+    padding: 1px 6px;
+    -moz-border-radius: 3px;
+    -webkit-border-radius: 3px;
+    border-radius: 3px;
+    margin-left: 5px;
+    background:#FFF6BF;
+    color:#514721;
+    border: 1px solid #FFD324;
+    opacity: 100;
+}
+
+.span_message_success {
+    background:#E6EFC2 !important;
+    color:#264409 !important;
+    border-color:#C6D880 !important;
+}
+
+.span_message_error {
+    background:#FBE3E4 !important;
+    color:#8A1F11 !important;
+    border-color:#FBC2C4 !important;
+}
Index: /sandbox/workflow/branches/993/templates/default/adminaccess.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/adminaccess.tpl	(revision 2371)
+++ /sandbox/workflow/branches/993/templates/default/adminaccess.tpl	(revision 2371)
@@ -0,0 +1,25 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading"/>
+{$css}
+{$javaScripts}
+<div id="main_body" style="display:none; width:99.5%;">
+	<table id="border_table" width="auto" height="26" cellspacing="0" cellpadding="0" border="0">
+		<tbody id="border_tbody">
+			<tr id="border_tr">
+			{foreach from=$tabs item=tab name="feTabs"}
+				{assign var='index' value=$smarty.foreach.feTabs.index}
+				<td nowrap class="menu" id="border_id_{$index}" onClick="change_folder({$index})">
+					&nbsp;&nbsp;{$tab}&nbsp;&nbsp;
+				</td>
+			{/foreach}
+				<td nowrap id="border_blank" class="last_menu" width="100%">
+					&nbsp;
+				</td>
+			</tr>
+		</tbody>
+	</table>
+{foreach from=$tabs item=tab name="feTabs"}
+	<div id="content_id_{$smarty.foreach.feTabs.index}" class="conteudo"></div>
+{/foreach}
+</div>
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/generic_select.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/generic_select.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/generic_select.tpl	(revision 795)
@@ -0,0 +1,40 @@
+{$header}
+<title>Adicionar Itens</title>
+{$javaScripts}
+<form name="frmAdd" method="POST" onsubmit="javascript:genericListAdd(); return false;">
+	<center>
+		<table cellspacing="3" cellpadding="3">
+			<tr>
+				<td>
+					<div id="divAppboxHeader">Adicionar Itens</div>
+					<div id="divAppbox">
+						<table border="0">
+							<tr><td>Lista:</td></tr>
+							<tr><td>{html_options name="genericList" id="genericList" multiple="multiple" style="width:250px" size="18" options=$list selected=$selected}</td></tr>
+							<tr><td>&nbsp;</td></tr>
+							<tr>
+								<td>
+									<center>{$lang_to_Search}:&nbsp;<input type="text" id="query" name="query" onkeyup="genericListOptionFinder(this, event)" autocomplete="off"></center>
+								</td>
+							</tr>
+							<tr><td>&nbsp;</td>	</tr>
+							<tr>
+								<td>
+									<center>
+										<input type="button" id="addButton" class="button" value={$lang_Add} onClick="javascript:genericListAdd()">
+										<input type="button" id="closeButton" value={$lang_Close} onClick="javascript:window.close()">
+									</center>
+								</td>
+							</tr>
+						</table>
+					</div>
+				</td>
+			</tr>
+		</table>
+	</center>
+</form>
+<script type="text/javascript">
+	genericListSetLists('genericList','{$targetElement}');
+	document.getElementById("query").focus();
+</script>
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/move_instances.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/move_instances.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/move_instances.tpl	(revision 795)
@@ -0,0 +1,10 @@
+{$header}
+<input type="hidden" value="{$txt_loading}" id="txt_loading">
+{$css}
+{$javaScripts}
+<div id="mainBody" style="width:99.5%;">
+<h2>Mover Instâncias</h2>
+<div id="divFrom" style="float: left;"></div>
+<div id="divTo" style="float: right;"></div>
+</div>
+{$footer}
Index: /sandbox/workflow/branches/993/templates/default/run_activity.tpl
===================================================================
--- /sandbox/workflow/branches/993/templates/default/run_activity.tpl	(revision 795)
+++ /sandbox/workflow/branches/993/templates/default/run_activity.tpl	(revision 795)
@@ -0,0 +1,21 @@
+{$header}
+{* activity errors are displayed here *}
+{if count($activityErrors) > 0}
+	<div id="wf_run_activity_message">
+	{foreach from=$activityErrors item=activityError}
+		<p>{$activityError}</p>
+	{/foreach}
+	</div>
+{/if}
+
+<link href="{$CSSLink}"  type="text/css" rel="StyleSheet" media="{$CSSMedia}" />
+<div id="wf_run_activity_zone">
+	<form method="post" enctype='multipart/form-data' name="workflow_form" id="workflow_form" action="{$actionURL}">
+		<div id="wf_activity_playground">
+			<div id="wf_activity_template">
+				{$activityOutput}
+			</div>
+		</div>
+	</form>
+</div>
+{$footer}
