//======================================================================
//	new_template_color_picker
//======================================================================

WHATAFAG.new_template_color_picker =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	options

				var options =
					{
						"flat" : true
					};

				if ( that.args.callback_change )
				{
					options.onChange = that.args.callback_change;
				}

				//	create color picker

				that.j_template.ColorPicker( options );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_color_picker" ).clone( false );

		//	return that

		return that;
	};
//======================================================================
//	new_template_composer
//======================================================================

WHATAFAG.new_template_composer =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get
		//======================================================================

		that.get =
			function()
			{
				var that = this;

				return that.j_textarea.val();
			};

		//======================================================================
		//	set
		//======================================================================

		that.set =
			function( text )
			{
				var that = this;

				that.j_textarea.val( text );

				return that;
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_composer" ) ).clone();

		that.j_textarea = that.j_template.find( "textarea" );

		if ( args_init.value !== undefined ) that.set( args_init.value );
		if ( args_init.classes !== undefined ) that.j_textarea.attr( "class", args_init.classes );
		if ( args_init.placeholder !== undefined ) that.j_textarea.attr( "placeholder", args_init.placeholder );

		//	return that

		return that;
	};
//======================================================================
//	new_template_dialogue
//======================================================================

WHATAFAG.new_template_dialogue =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				return that;
			};

		//======================================================================
		//	handle_updated_resource_account_target
		//======================================================================

		that.handle_updated_resource_account_target =
			function ( properties, properties_changed )
			{
				return that;
			};

		//======================================================================
		//	handle_updated_resource_search_messages
		//======================================================================

		that.handle_updated_resource_search_messages =
			function ( properties, properties_changed )
			{
				if ( properties.count_total_rows_possible === 0 )
				{
					that.j_template.find( ".container_template_search_list" ).hide();
				}
				else
				{
					that.j_template.find( ".container_template_search_list" ).show();
				}
			};

		//======================================================================
		//	submit_form_message_create
		//======================================================================

		that.submit_form_message_create =
			function ()
			{
				var properties_form = { "message" : that.template_composer.get() };
				var processing_area = that.processing_area_message_create;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_message_create( properties_form, processing_area ) )
				{
					var data = { "message" : properties_form.message, "uri_target" : args_init.uri_account_target, "context" : "account_to_account" };

					WHATAFAG.actions.message_create( data )
						.then
						(
							function ()
							{
								that.template_composer.set( "" );
								that.observers.resource_search_messages.refresh();
								processing_area.reset();
								processing_area.set_status_auto_dismiss( "Message sent" );
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_dialogue" ) ).clone();

		//	add templates

		that.template_composer = WHATAFAG.new_template_composer( { "classes" : "small" } );
		that.add_template_child( that.template_composer, that.j_template.find( ".container_template_composer" ) );

		//	create observers

		that.observers.resource_account_target = new_observer();
		that.observers.resource_account_target.bind( "change", that.handle_updated_resource_account_target );
		that.observers.resource_account_target.set_target( WHATAFAG.resource_library.resource( args_init.uri_account_target ) );

		that.observers.resource_search_messages = new_observer();
		that.observers.resource_search_messages.bind( "change", that.handle_updated_resource_search_messages );
		that.observers.resource_search_messages.set_target( WHATAFAG.resource_library.resource( jQuery.param.querystring( "/rest/query/dialogue", { "uri_account_other" : args_init.uri_account_target } ) ) );

		{
			//	create a new search list

			that.template_search_list = WHATAFAG.new_template_search_list( {} );
			that.add_template_child( that.template_search_list, that.j_template.find( ".container_template_search_list" ), "template_search_list" );
			that.template_search_list
				.update_arguments
				(
					{
						"uri" : jQuery.param.querystring( "/rest/query/dialogue", { "uri_account_other" : args_init.uri_account_target } ),
						"html_placeholder" : "No messages",
						"args_expanding_list" :
							{
								"do_use_hr" : false,
								"name_constructor" : "new_template_message_in_dialogue",
								"args_constructor" : {}
							}
					}
				);
		}

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	processing areas

		that.processing_area_message_create = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_message_create" ) );

		//	hook up events

		that.j_template.find( ".button_submit_message_create" ).click( condition_for_event( function () { that.submit_form_message_create(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_message_create
//======================================================================

WHATAFAG.validators.form_message_create =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.message === "" ) return false;
		else return true

		return false;
	};

//======================================================================
//	actions.message_create
//======================================================================

WHATAFAG.actions.message_create =
	function ( data )
	{
		return request_resource_create( "/rest/messages", { "message" : data.message, "uri_target" : data.uri_target, "context" : "account_to_account" } );
	};
//======================================================================
//	new_template_response_create_inline
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_response_create_inline =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri_subject" : undefined,
						"callback_create" : undefined
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the observed resources

				observer_user_active.refresh();

				//	because the child template is already correctly configured at this point, we can immediately forward the refresh

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_resource_user
		//======================================================================

		that.handle_updated_resource_user =
			function ( properties, properties_changed )
			{
				if ( properties_changed.has_credentials !== undefined )
				{
					that.j_template.find( ".section_guest" ).toggle( !properties.has_credentials );
					that.j_template.find( ".section_member" ).toggle( properties.has_credentials );
				}
			};

		//======================================================================
		//	destroy
		//======================================================================

		that.destroy =
			function ()
			{
				var that = this;

				observer_user_active.unbind( "change", that.handle_updated_resource_user );

				that.destroy_root();
			};

		//======================================================================
		//	submit_form_create
		//======================================================================

		that.submit_form_create =
			function ( event, j_element )
			{
				var processing_area = that.processing_area;

				processing_area.reset();

				var message = trim( that.j_template.find( "[name='message']" ).val() );

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( message === "" )
				{
					processing_area.set_and_show_message( "Please enter a message." );
				}

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	create
					//======================================================================

					var hash_properties_form = {};

					hash_properties_form[ "uri_subject" ] = that.args.uri_subject;
					hash_properties_form[ "message" ] = message;

					request_resource_create
					(
						"/rest/comments",
						hash_properties_form,
						function ( uri )
						{
							processing_area.reset();

							that.j_template.find( "[name='message']" ).val( "" );

							if ( typeof that.args.callback_create === "function" ) that.args.callback_create( uri );
						},
						undefined,
						false
					);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_response_create_inline" ).clone( false );

		//	processing areas

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	hook up events

		that.j_template.find( ".button_create" ).click( condition_for_event( that.submit_form_create ) );

		//	bind to observers

		observer_user_active.bind( "change", that.handle_updated_resource_user, true );

		//	return that

		return that;
	};
//======================================================================
//	new_template_site_frame
//======================================================================

WHATAFAG.new_template_site_frame =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
			};

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				if ( properties[ "has_credentials" ] )
				{
					that.j_template.find( ".links_members" ).css( "display", "inline-block" );
					that.j_template.find( ".links_guests" ).hide();
				}
				else
				{
					that.j_template.find( ".links_members" ).hide();
					that.j_template.find( ".links_guests" ).css( "display", "inline-block" );
				}

				that.j_template.find( ".link_visit_profile" ).attr( "href", get_href_for_account( properties ) );

				that.observers.resource_search_messages.set_target( WHATAFAG.resource_library.resource( properties.uri_messages_search_unread ) );
			};

		//======================================================================
		//	handle_updated_resource_search_messages
		//======================================================================

		that.handle_updated_resource_search_messages =
			function ( properties, properties_changed )
			{
				if ( properties.count_total_rows_possible === 0 )
				{
					that.j_template.find( ".message_notification" ).empty();
				}
				else
				{
					that.j_template.find( ".message_notification" ).html( "<a href=\"#!/messages\">" + properties.count_total_rows_possible + " <img src=\"/resources/images/woocons/Mail.png/18x18\" style=\"width: 18px; height: 18px; vertical-align: text-bottom;\" /></a>" );
				}
			};

		//======================================================================
		//	handle_updated_fragment
		//======================================================================

		that.handle_updated_fragment =
			function ( properties_fragment )
			{
				var id_component = "template_" + properties_fragment.page_command;

				//======================================================================
				//	set arguments for the template
				//======================================================================

				var args = {};

				if ( properties_fragment.page_arguments !== undefined ) args = properties_fragment.page_arguments;

				args.name_template = id_component;

				//======================================================================
				//	child templates can be stored/restored as "components" (think "pages")
				//	to make top-level page-switching speedy
				//
				//	fun fact : templates marked as "components" don't get destroyed, their j_template
				//	gets moved into a holding container called "container_rendered_components".
				//======================================================================

				if ( WHATAFAG.components[ id_component ] === undefined )
				{
					//	build a new template

					that.component = WHATAFAG[ "new_" + id_component ]( args );

					if ( that.component.is_eligible_for_component )
					{
						that.component.is_component = true;
						WHATAFAG.components[ id_component ] = that.component;
					}
				}
				else
				{
					that.component = WHATAFAG.components[ id_component ]
				}

				//======================================================================
				//	is the component already in place?
				//======================================================================

				if ( that.component.j_template.parent().get( 0 ) === that.j_template.find( ".container_template" ).get( 0 ) )
				{
					//	do nothing
				}
				else
				{
					//======================================================================
					//	insert the component
					//======================================================================

					that.delete_templates_children();

					that.add_template_child( that.component, that.j_template.find( ".container_template" ) );

					//======================================================================
					//	scroll to the top of the page
					//======================================================================

					jQuery.scrollTo( 0 );
				}

				//======================================================================
				//	pass arguments to the component
				//======================================================================

				that.component.update_arguments( args );

				//======================================================================
				//	start a refresh chain
				//======================================================================

				that.refresh();

				return that;
			};

		//======================================================================
		//	handle_tumblr_data
		//======================================================================

		that.handle_tumblr_data =
			function ( data )
			{
				try
				{
					if ( data && data.posts )
					{
						jQuery
							.each
							(
								data.posts,
								function ( index, post )
								{
									that.j_template.find( ".footer .section_blog" ).append( "<p><a href=\"" + post[ "url-with-slug" ] + "\">" + post[ "regular-title" ] + "</a> - From our <a href=\"http://blog.whatafag.com/\" class=\"ghost_link\">blog</a>, " + pretty_date( post[ "unix-timestamp" ] ) + "</p>" );
								}
							);

						that.j_template.find( ".footer .section_blog" ).show();
					}
					else
					{
					}
				}
				catch ( err )
				{
				}
			};

		//======================================================================
		//	handle_twitter_data
		//======================================================================

		that.handle_twitter_data =
			function ( data )
			{
				try
				{
					jQuery
						.each
						(
							data,
							function ( index, tweet )
							{
								that.j_template.find( ".footer .section_twitter" ).append( "<p><img src=\"/resources/images/social media/16/twitter.png\" /> " + linkify_entities( tweet ) + "</p>" );

								that.j_template.find( ".footer .section_twitter" ).show();
							}
						);
				}
				catch ( err )
				{
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_site_frame" ) ).clone();

		that.component = null;

		//	hook up events

		that.j_template.find( ".link_log_out" ).click( condition_for_event( submit_form_log_out ) );

		//	create observers

		that.observers.resource_search_messages = new_observer();
		that.observers.resource_search_messages.bind( "change", that.handle_updated_resource_search_messages );
		that.observers.resource_search_messages.bind( "expire", function () { that.observers.resource_search_messages.refresh(); } );

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//======================================================================
		//	get tumblr data only once when the template is created
		//======================================================================

		jQuery
			.ajax
			(
				{
					"url" : "http://blog.whatafag.com/api/read/json?num=3&filter=text&tagged=news",
					"cache" : true,
					"success" : that.handle_tumblr_data,
					"dataType" : "jsonp"
				}
			);

		//======================================================================
		//	get twitter data only once when the template is created
		//======================================================================

		jQuery
			.ajax
			(
				{
					"url" : "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=VisitWhatAFag&trim_user=true&count=2&include_entities=true",
					"cache" : true,
					"success" : that.handle_twitter_data,
					"dataType" : "jsonp"
				}
			);

		//	start watching the fragment

		that.follow( watched_fragment, "change", that.handle_updated_fragment );

		//	return that

		return that;
	};
//======================================================================
//	new_template_account_manage
//======================================================================

WHATAFAG.new_template_account_manage =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	email address
				//======================================================================

				that.j_template.find( "[name='email_address_login']" ).val( properties[ "email_address_login" ] );

				//======================================================================
				//	clear the pass phrase fields
				//======================================================================

				that.j_template.find( "[name='pass_phrase_login_old'],[name='pass_phrase_login_new'],[name='pass_phrase_login_confirmation']" ).val( "" );

				return that;
			};

		//======================================================================
		//	submit_form_email_address_login_update
		//======================================================================

		that.submit_form_email_address_login_update =
			function ()
			{
				var that = this;

				var processing_area = that.processing_area_email_address_login_update;

				processing_area.reset();

				var email_address_login = trim( that.j_template.find( "[name='email_address_login']" ).val() );

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( email_address_login === "" )
				{
					processing_area.set_and_show_message( "Please enter your email address." );
				}

				//======================================================================
				//	server checks
				//======================================================================

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	update
					//======================================================================

					var hash_properties_form = {}

					hash_properties_form[ "email_address_login" ] = email_address_login;

					resource_account_active
						.set( hash_properties_form )
						.then
						(
							function ( properties_resource )
							{
								processing_area.reset();
								processing_area.set_status_auto_dismiss( "Email address updated" );
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	submit_form_pass_phrase_login_update
		//======================================================================

		that.submit_form_pass_phrase_login_update =
			function ()
			{
				var that = this;

				var processing_area = that.processing_area_pass_phrase_login_update;

				processing_area.reset();

				var pass_phrase_login_old = trim( that.j_template.find( "[name='pass_phrase_login_old']" ).val() );
				var pass_phrase_login_new = trim( that.j_template.find( "[name='pass_phrase_login_new']" ).val() );
				var pass_phrase_login_confirmation = trim( that.j_template.find( "[name='pass_phrase_login_confirmation']" ).val() );

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( pass_phrase_login_old === "" || pass_phrase_login_new === "" || pass_phrase_login_confirmation === "" )
				{
					processing_area.set_and_show_message( "Please enter your current password and your new password twice." );
				}

				else if ( pass_phrase_login_new !== pass_phrase_login_confirmation )
				{
					processing_area.set_and_show_message( "Your new password was entered twice but they do not match. Please enter the same, new password twice." );
				}

				//======================================================================
				//	server checks
				//======================================================================

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	update
					//======================================================================

					var hash_properties_form = {}

					hash_properties_form[ "pass_phrase_login_old" ] = pass_phrase_login_old;
					hash_properties_form[ "pass_phrase_login" ] = pass_phrase_login_new;

					resource_account_active
						.set( hash_properties_form )
						.then
						(
							function ( properties_resource )
							{
								processing_area.reset();
								processing_area.set_status_auto_dismiss( "Password updated" );

								that.j_template.find( "[name='pass_phrase_login_old'],[name='pass_phrase_login_new'],[name='pass_phrase_login_confirmation']" ).val( "" );
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_account_manage" ) ).clone();

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	processing areas

		that.processing_area_email_address_login_update = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_email_address_login_update" ) );
		that.processing_area_pass_phrase_login_update = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_pass_phrase_login_update" ) );

		//	hook up events

		that.j_template.find( ".button_submit_email_address_login_update" ).click( condition_for_event( function () { that.submit_form_email_address_login_update(); } ) );
		that.j_template.find( ".button_submit_pass_phrase_login_update" ).click( condition_for_event( function () { that.submit_form_pass_phrase_login_update(); } ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_credits
//======================================================================

WHATAFAG.new_template_credits =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_credits" ).clone( false );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_form_sign_up
//======================================================================

WHATAFAG.new_template_form_sign_up =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	submit_form
		//======================================================================

		that.submit_form =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( "form" ) )
				var processing_area = that.processing_area;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_sign_up( properties_form, processing_area ) )
				{
					WHATAFAG.actions.sign_up( properties_form )
						.then
						(
							function ()
							{
								processing_area.reset();

								that.j_template.find( "[name='email_address_login']" ).val( "" );
								that.j_template.find( "[name='pass_phrase_login']" ).val( "" );
								that.j_template.find( "[name='label']" ).val( "" );
								that.j_template.find( "[name='username']" ).val( "" );

								WHATAFAG.url_processor.push_new_fragment( "#!/welcome" );
							},
							function ( xml_http_request, text_status, error_thrown )
							{
								processing_area.reset();
								processing_area.set_and_show_message( "<p>Sorry, but there was an unexpected problem creating your account. Please try again?</p>" );
							}
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_form_sign_up" ) ).clone();

		//	processing areas

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	hook up events

		that.j_template.find( ".button_submit_form" ).click( condition_for_event( function () { that.submit_form(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validtors.form_sign_up
//======================================================================

WHATAFAG.validators.form_sign_up =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( resource_account_active.properties.has_credentials ) processing_area.set_and_show_message( "<p>You are already registered and logged in, no need to sign up again.</p>" );
		else if ( properties_form.email_address_login === "" ) processing_area.set_and_show_message( "Please enter your email address." );
		else if ( properties_form.pass_phrase_login === "" ) processing_area.set_and_show_message( "Please enter a password." );
		else if ( properties_form.label === "" ) processing_area.set_and_show_message( "Please enter your name or nickname." );
		else if ( properties_form.username === "" ) processing_area.set_and_show_message( "Please enter a preferred username." );
		else if ( properties_form.username.match( /[^a-zA-Z0-9]/ ) ) processing_area.set_and_show_message( "Your preferred username should have only numbers and letters." );
		else return true;

		return false;
	};

//======================================================================
//	actions.sign_up
//======================================================================

WHATAFAG.actions.sign_up =
	function ( data )
	{
		var dfd = jQuery.Deferred();

		//======================================================================
		//	update account
		//======================================================================

		resource_account_active
			.set( data )
			.then
			(
				function ( properties_resource )
				{
					//======================================================================
					//	log in
					//
					//	search
					//======================================================================

					var hash_properties_form = {};

					hash_properties_form.email_address_login = data.email_address_login;
					hash_properties_form.pass_phrase_login = data.pass_phrase_login;

					request_resource_search( "/rest/authentication_tokens", true, hash_properties_form, true )
						.then
						(
							function ( list_uris_authentication_tokens )
							{
								//======================================================================
								//	cookie is set by the HTTP response; no need to set it manually
								//======================================================================

								if ( list_uris_authentication_tokens.length === 1 )
								{
									ajax_refresh
									(
										function ()
										{
											dfd.resolve();
										}
									);
								}
								else
								{
									dfd.reject( "Crazy error!" );
								}
							},
							function ( xml_http_request, text_status, error_thrown )
							{
								handle_ajax_failure( xml_http_request, text_status, error_thrown );
								dfd.reject( xml_http_request, text_status, error_thrown );
							}
						);
				},
				function ( xml_http_request, text_status, error_thrown )
				{
					handle_ajax_failure( xml_http_request, text_status, error_thrown );
					dfd.reject( xml_http_request, text_status, error_thrown );
				}
			);

		return dfd.promise();
	};
//======================================================================
//	new_template_hottie
//======================================================================

WHATAFAG.new_template_hottie =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default = function() { return { "width" : 800, "height" : 480 }; };

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	find the account for the given username

				request_resource_search( "/rest/accounts", undefined, { "username" : that.args.username }, true )
					.then
					(
						function ( list_uri_account )
						{
							//======================================================================
							//	cookie is set by the HTTP response; no need to set it manually
							//======================================================================

							if ( list_uri_account.length === 1 )
							{
								that.observers.resource_account_target.set_target( WHATAFAG.resource_library.resource( list_uri_account[ 0 ] ) );
							}
							else
							{
								handle_message_simple( "<p>User " + that.args.username + " could not be found.</p>" );
								dfd.reject( "Crazy error!" );
							}
						},
						function ( xml_http_request, text_status, error_thrown ) { handle_message_simple( xml_http_request.responseText ); }
					);
			};

		//======================================================================
		//	handle_updated_resource_account_target
		//======================================================================

		that.handle_updated_resource_account_target =
			function ( properties, properties_changed )
			{
				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_changed );

				//	description

				var j_applicable_nodes = find_applicable_nodes( that.j_template );

				if ( properties_changed.description !== undefined )
				{
					j_applicable_nodes.filter( ".description" ).html( "<div>" + properties.description_html + "</div>" );
					j_applicable_nodes.filter( ".section_description" ).toggle( properties.description !== null );
				}

				if ( properties_changed.uri_gallery_avatars !== undefined )
				{
					//	create a new gallery template

					that.delete_templates_children( "template_gallery_simple" );

					var template_gallery_simple = WHATAFAG.new_template_gallery_simple( { "uri_gallery" : properties.uri_gallery_avatars } );
					that.add_template_child( template_gallery_simple, that.j_template.find( ".container_template_gallery_simple" ), "template_gallery_simple" );
				}

				if ( properties_changed.uri !== undefined )
				{
					//	create a new dialogue template

					that.delete_templates_children( "template_dialogue" );

					var template_dialogue = WHATAFAG.new_template_dialogue( { "uri_account_target" : properties.uri } );
					that.add_template_child( template_dialogue, that.j_template.find( ".container_template_dialogue" ), "template_dialogue" );
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_hottie" ) ).clone();

		//	create observers

		that.observers.resource_account_target = new_observer();
		that.observers.resource_account_target.bind( "change", that.handle_updated_resource_account_target );

		//	return that

		return that;
	};
//======================================================================
//	new_template_log_in
//======================================================================

WHATAFAG.new_template_log_in =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	submit_form_login
		//======================================================================

		that.submit_form_login =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( ".form_log_in" ) )
				var processing_area = that.processing_area;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_log_in( properties_form, processing_area ) )
				{
					WHATAFAG.actions.log_in( properties_form )
						.then
						(
							function ()
							{
								processing_area.reset();

								that.j_template.find( "[name='email_address_login']" ).val( "" );
								that.j_template.find( "[name='pass_phrase_login']" ).val( "" );

								WHATAFAG.url_processor.push_new_fragment( "#!" );

								handle_message_auto_dismiss( "<p>Welcome back.</p>", 2 );
							},
							function ( xml_http_request, text_status, error_thrown )
							{
								processing_area.reset();
								processing_area.set_and_show_message( "<p>Failed to log in with that email address and password. Please try again, or use the <a href=\"#!pass_phrase_reset_request\">password reset</a> tool.</p>" );
							}
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_log_in" ) ).clone();

		//	processing areas

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	hook up events

		that.j_template.find( ".button_submit_form" ).click( condition_for_event( function () { that.submit_form_login(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_log_in
//======================================================================

WHATAFAG.validators.form_log_in =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.email_address_login === "" ) processing_area.set_and_show_message( "<p>Please enter your email address.</p>" );
		else if ( properties_form.pass_phrase_login === "" ) processing_area.set_and_show_message( "<p>Please enter a password.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.log_in
//======================================================================

WHATAFAG.actions.log_in =
	function ( data )
	{
		var dfd = jQuery.Deferred();

		request_resource_search( "/rest/authentication_tokens", true, data, true )
			.then
			(
				function ( list_uris_authentication_tokens )
				{
					//======================================================================
					//	cookie is set by the HTTP response; no need to set it manually
					//======================================================================

					if ( list_uris_authentication_tokens.length === 1 )
					{
						ajax_refresh
						(
							function ()
							{
								dfd.resolve();
							}
						);
					}
					else
					{
						dfd.reject();
					}
				},
				dfd.reject
			);

		return dfd.promise();
	};
//======================================================================
//	new_template_log_out
//======================================================================

WHATAFAG.new_template_log_out =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_log_out" ) ).clone();

		WHATAFAG.url_processor.push_new_fragment( "#!" );

		//	return that

		return that;
	};
//======================================================================
//	new_template_messages
//======================================================================

WHATAFAG.new_template_messages =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				if ( properties_changed.uri_messages_search_recent !== undefined )
				{
					//	create a new search list

					that.delete_templates_children( "template_search_list" );

					var template_search_list = WHATAFAG.new_template_search_list( {} );
					that.add_template_child( template_search_list, that.j_template.find( ".container_template_search_list" ), "template_search_list" );
					template_search_list
						.update_arguments
						(
							{
								"uri" : properties.uri_messages_search_recent,
								"html_placeholder" : "No messages",
								"args_expanding_list" :
									{
										"do_use_hr" : false,
										"name_constructor" : "new_template_message_one_line",
										"args_constructor" : {}
									}
							}
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_messages" ) ).clone();

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	return that

		return that;
	};
//======================================================================
//	new_template_pass_phrase_reset_confirmation
//======================================================================

WHATAFAG.new_template_pass_phrase_reset_confirmation =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	submit_form
		//======================================================================

		that.submit_form =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( "form" ) )
				var processing_area = that.processing_area;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_pass_phrase_reset_confirmation( properties_form, processing_area ) )
				{
					var data = jQuery.extend( {}, properties_form, { "pass_phrase_reset_code" : that.args.code } );

					WHATAFAG.actions.pass_phrase_reset_confirmation( data )
						.then
						(
							function ()
							{
								processing_area.reset();

								WHATAFAG.url_processor.push_new_fragment( "#!/log_in" );

								handle_message_auto_dismiss( "<p>Your password has been reset. You can now log in.</p>", 10 );
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_pass_phrase_reset_confirmation" ) ).clone();

		//	processing areas

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	hook up events

		that.j_template.find( ".button_submit_form" ).click( condition_for_event( function () { that.submit_form(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_pass_phrase_reset_confirmation
//======================================================================

WHATAFAG.validators.form_pass_phrase_reset_confirmation =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.pass_phrase_login === "" ) processing_area.set_and_show_message( "<p>Please enter a password.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.pass_phrase_reset_confirmation
//======================================================================

WHATAFAG.actions.pass_phrase_reset_confirmation =
	function ( data )
	{
		return request_resource_create( "/rest/pass_phrase_reset_confirmations", data, undefined, undefined, false );
	};
//======================================================================
//	new_template_pass_phrase_reset_request
//======================================================================

WHATAFAG.new_template_pass_phrase_reset_request =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_changed );

				//	email_address_login

				that.j_template.find( "[name='email_address_login']" ).val( properties.email_address_login );
			};

		//======================================================================
		//	submit_form
		//======================================================================

		that.submit_form =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( "form" ) )
				var processing_area = that.processing_area;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_pass_phrase_reset_request( properties_form, processing_area ) )
				{
					WHATAFAG.actions.pass_phrase_reset_request( properties_form )
						.then
						(
							function ()
							{
								processing_area.reset();

								that.j_template.find( "[name='email_address_login']" ).val( "" );

								WHATAFAG.url_processor.push_new_fragment( "#!" );

								handle_message_auto_dismiss( "<p>A password reset confirmation has been emailed to you. Please follow the link included within that email within the next 10 minutes.</p>", 30 );
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_pass_phrase_reset_request" ) ).clone();

		//	processing areas

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	bind to the observer

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	hook up events

		that.j_template.find( ".button_submit_form" ).click( condition_for_event( function () { that.submit_form(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_pass_phrase_reset_request
//======================================================================

WHATAFAG.validators.form_pass_phrase_reset_request =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.email_address_login === "" ) processing_area.set_and_show_message( "<p>Please enter your email address.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.pass_phrase_reset_request
//======================================================================

WHATAFAG.actions.pass_phrase_reset_request =
	function ( data )
	{
		return request_resource_create( "/rest/pass_phrase_reset_requests", data, undefined, undefined, false );
	};
//======================================================================
//	new_template_profile_browser
//======================================================================

WHATAFAG.new_template_profile_browser =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				if ( properties_changed.location_latitude !== undefined || properties_changed.location_longitude !== undefined )
				{
					//	create a new search list

					that.delete_templates_children( "template_search_list" );

					var template_search_list = WHATAFAG.new_template_search_list( {} );
					that.add_template_child( template_search_list, that.j_template.find( ".container_template_search_list" ), "template_search_list" );
					template_search_list
						.update_arguments
						(
							{
								"uri" : jQuery.param.querystring( "/rest/query/accounts_nearby", { "latitude" : observer_account_active.target.get( "location_latitude" ), "longitude" : observer_account_active.target.get( "location_longitude" ) } ),
								"html_placeholder" : "No profiles yet",
								"args_expanding_list" :
									{
										"do_use_hr" : true,
										"hr_html" : " ",
										"name_constructor" : "new_template_account_front_page",
										"args_constructor" : {}
									}
							}
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_profile_browser" ) ).clone();

		//	create observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	return that

		return that;
	};

//======================================================================
//	new_template_profile_manage
//======================================================================

WHATAFAG.new_template_profile_manage =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	point observers
				//======================================================================

				that.observers.resource_gallery_avatars.set_target( WHATAFAG.resource_library.resource( properties.uri_gallery_avatars ) );

				//======================================================================
				//	file uploader
				//======================================================================

				if ( properties_changed.uri_gallery_avatars !== undefined )
				{
					that.delete_templates_children( "file_uploader" );

					var args_template_file_uploader = 
						{
							"context" : "avatar",
							"label_button" : "Upload a new picture",
							"uri_gallery" : properties.uri_gallery_avatars,
							"callback_success" : function ( uri_image ) { request_resource_update( properties.uri, { "uri_image_avatar" : uri_image } ); that.observers.resource_search_images_avatars.refresh(); }
						};

					var template_file_uploader = WHATAFAG.new_template_file_uploader( args_template_file_uploader );
					that.add_template_child( template_file_uploader, that.j_template.find( ".container_template_file_uploader" ), "file_uploader" );
					template_file_uploader.update_arguments( args_template_file_uploader );
				}

				//======================================================================
				//	form fields
				//======================================================================

				if ( properties_changed.label ) find_applicable_nodes( that.j_template ).filter( "[name='label']" ).val( properties.label );
				if ( properties_changed.description ) that.template_composer.set( properties.description );
				that.j_template.find( "[name='location_method']" ).val( properties.location_method );
				that.j_template.find( "[name='location_label']" ).val( properties.location_label );

				//======================================================================
				//	location_method
				//======================================================================

				if ( properties_changed.location_method )
				{
					that.j_template.find( ".section_location_method_manual" ).toggle( properties.location_method === "manual" );
					that.j_template.find( ".section_location_method_automatic" ).toggle( properties.location_method === "automatic" );
				}

				//======================================================================
				//	location_latitude and location_longitude
				//======================================================================

				if ( properties_changed.location_latitude || properties_changed.location_longitude )
				{
					that.delete_templates_children( "map_with_targets" );

					var template_map_with_targets = WHATAFAG.new_template_map_with_targets( {} );

					template_map_with_targets.event_manager
						.bind
						(
							"active",
							function ()
							{
								template_map_with_targets.create_markers( [ { "latitude" : properties.location_latitude, "longitude" : properties.location_longitude } ] );
							}
						);

					that.add_template_child( template_map_with_targets, that.j_template.find( ".container_template_map_with_targets" ), "map_with_targets" );
					template_map_with_targets.update_arguments( {} );
				}

				//======================================================================
				//	select new image
				//======================================================================

				if ( properties_changed.uri_image_avatar !== undefined )
				{
					that.select_correct_image();
				}

				return that;
			};

		//======================================================================
		//	handle_updated_resource_gallery_avatars
		//======================================================================

		that.handle_updated_resource_gallery_avatars =
			function ( properties, properties_changed )
			{
				var uri_search = jQuery.param.querystring( properties.uri_search_images, { "sort_by" : "date_created_desc" } );

				//	point the avatar image search observer to the new target

				that.observers.resource_search_images_avatars.set_target( WHATAFAG.resource_library.resource( uri_search ) );

				//	create a new search list

				that.delete_templates_children( "search_list" );

				var template_search_list = WHATAFAG.new_template_search_list( {} );
				that.add_template_child( template_search_list, that.j_template.find( ".container_template_search_list" ), "search_list" );
				template_search_list
					.update_arguments
					(
						{
							"uri" : uri_search,
							"html_placeholder" : "No pictures yet",
							"args_expanding_list" :
								{
									"do_use_hr" : true,
									"hr_html" : " ",
									"name_constructor" : "new_template_image_list_item",
									"args_constructor" : {}
								}
						}
					);
			};

		//======================================================================
		//	handle_updated_resource_search_images_avatars
		//======================================================================

		that.handle_updated_resource_search_images_avatars =
			function ( properties, properties_changed )
			{
				var list_uris_images = properties.list_uris_resources;

				//	unbind and remove old images

				that.j_template.find( ".image_chooser img" ).unbind( "click.WHATAFAG" );
				that.j_template.find( ".container_images_custom" ).empty();

				//	add new images

				for ( var counter = 0; counter < list_uris_images.length; counter++ )
				{
					var uri_image = list_uris_images[ counter ];
					var j_img = jQuery( "<img src=\"" + uri_image + "/100x100\" /> " );
					j_img.data( "uri", uri_image );
					that.j_template.find( ".container_images_custom" ).append( j_img ).append( " " );
				}

				//	bind click events for the images

				that.j_template.find( ".image_chooser img" )
					.bind
					(
						"click.WHATAFAG",
						function ( event )
						{
							var j_img = jQuery( this );

							request_resource_update( hash_properties_account.uri, { "uri_image_avatar" : j_img.data( "uri" ) } );
						}
					);

				that.select_correct_image();
			};

		//======================================================================
		//	select_correct_image
		//======================================================================

		that.select_correct_image =
			function ()
			{
				//	highlight the selected image

				that.j_template.find( ".image_chooser img" ).removeClass( "selected" );
				that.j_template.find( ".image_chooser img" )
					.each
					(
						function ( index )
						{
							var j_element = jQuery( this );

							if ( j_element.data( "uri" ) === hash_properties_account.uri_image_avatar )
							{
								j_element.addClass( "selected" );
							}
						}
					);
			};

		//======================================================================
		//	submit_form_account_label_update
		//======================================================================

		that.submit_form_account_label_update =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( ".form_account_label_update" ) )
				var processing_area = that.processing_area_account_label_update;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_account_label_update( properties_form, processing_area ) )
				{
					WHATAFAG.actions.account_label_update( properties_form )
						.then
						(
							function () { processing_area.reset(); processing_area.set_status_auto_dismiss( "Name updated" ); },
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	submit_form_account_description_update
		//======================================================================

		that.submit_form_account_description_update =
			function ()
			{
				var properties_form = { "description" : that.template_composer.get() };
				var processing_area = that.processing_area_account_description_update;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_account_description_update( properties_form, processing_area ) )
				{
					WHATAFAG.actions.account_description_update( properties_form )
						.then
						(
							function () { processing_area.reset(); processing_area.set_status_auto_dismiss( "Description updated" ); },
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	submit_form_account_location_method_update
		//======================================================================

		that.submit_form_account_location_method_update =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( ".form_account_location_method_update" ) )
				var processing_area = that.processing_area_account_location_method_update;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_account_location_method_update( properties_form, processing_area ) )
				{
					WHATAFAG.actions.account_location_method_update( properties_form )
						.then
						(
							function ()
							{
								if ( observer_account_active.target.get( "location_method" ) === "automatic" )
								{
									that.get_location();
								}
								else if ( observer_account_active.target.get( "location_method" ) === "manual" )
								{
									that.j_template.find( "[name='location_label']" ).val( observer_account_active.target.get( "location_label" ) );
									that.submit_form_account_location_label_update();
								}

								processing_area.reset();
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	submit_form_account_location_label_update
		//======================================================================

		that.submit_form_account_location_label_update =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( ".form_account_location_label_update" ) )
				var processing_area = that.processing_area_account_location_label_update;

				processing_area.reset();
				processing_area.show_processing();

				//	have google geocode the address

				var geocoder = new google.maps.Geocoder();

				geocoder.geocode
				(
					{ "address" : properties_form.location_label },
					function ( list_results, status )
					{
						if ( status === "OK" )
						{
							var data = {};
							data.location_label = list_results[ 0 ].formatted_address;
							data.location_latitude = list_results[ 0 ].geometry.location.lat();
							data.location_longitude = list_results[ 0 ].geometry.location.lng();

							//	update the location_label field with what we get back from google

							that.j_template.find( ".form_account_location_label_update" ).val( data.location_label )

							//======================================================================
							//	validate
							//======================================================================

							if ( WHATAFAG.validators.form_account_location_label_update( data, processing_area ) )
							{
								WHATAFAG.actions.account_location_label_update( data )
									.then
									(
										function () { processing_area.reset(); processing_area.set_status_auto_dismiss( "Location updated" ); },
										function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
									);
							}
						}
						else
						{
							processing_area.reset();
							processing_area.set_status_auto_dismiss( "Google could not understand that address, try again?" );
						}
					}
				);


			};

		//======================================================================
		//	get_location
		//======================================================================

		that.get_location =
			function ()
			{
				var processing_area = that.processing_area_account_location_method_update;

				processing_area.reset();
				processing_area.show_processing();

				if ( navigator.geolocation )
				{
					navigator.geolocation
						.getCurrentPosition
						(
							function ( position )
							{
								resource_account_active.set( { "location_latitude" : position.coords.latitude, "location_longitude" : position.coords.longitude } )
									.then
									(
										function () { processing_area.reset(); processing_area.set_status_auto_dismiss( "Location updated" ); },
										function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
									);
							},
							function ( error_code )
							{
								processing_area.reset();
								processing_area.set_status_auto_dismiss( "Could not update location" );
							},
							{ "enableHighAccuracy" : false, "timeout" : 60000, "maximumAge" : 50000 }
						);
				}
				else
				{
					processing_area.reset();
					processing_area.set_status_auto_dismiss( "Auto-updating not available with your browser." );
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_profile_manage" ) ).clone();

		//	add templates

		that.template_composer = WHATAFAG.new_template_composer( {} );
		that.add_template_child( that.template_composer, that.j_template.find( ".container_template_composer" ) );

		//	create observers

		that.observers.resource_gallery_avatars = new_observer();
		that.observers.resource_gallery_avatars.bind( "change", that.handle_updated_resource_gallery_avatars );

		that.observers.resource_search_images_avatars = new_observer();
		that.observers.resource_search_images_avatars.bind( "change", that.handle_updated_resource_search_images_avatars );

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	processing areas

		that.processing_area_account_label_update = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_account_label_update" ) );
		that.processing_area_account_description_update = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_account_description_update" ) );
		that.processing_area_account_location_method_update = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_account_location_method_update" ) );
		that.processing_area_account_location_label_update = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_account_location_label_update" ) );

		//	hook up events

		that.j_template.find( ".button_submit_account_label_update" ).click( condition_for_event( function () { that.submit_form_account_label_update(); } ) );
		that.j_template.find( ".button_submit_account_description_update" ).click( condition_for_event( function () { that.submit_form_account_description_update(); } ) );
		that.j_template.find( "[name='location_method']" ).change( condition_for_event( function () { that.submit_form_account_location_method_update(); } ) );
		that.j_template.find( ".button_submit_account_location_label_update" ).click( condition_for_event( function () { that.submit_form_account_location_label_update(); } ) );
		that.j_template.find( ".button_get_location" ).click( condition_for_event( function () { that.get_location(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_account_label_update
//======================================================================

WHATAFAG.validators.form_account_label_update =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.label === "" ) processing_area.set_and_show_message( "<p>Please enter a name or nickname.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.account_label_update
//======================================================================

WHATAFAG.actions.account_label_update =
	function ( data )
	{
		return observer_account_active.target.set( data );
	};

//======================================================================
//	validators.form_account_description_update
//======================================================================

WHATAFAG.validators.form_account_description_update =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.description === "" ) processing_area.set_and_show_message( "<p>Please enter a name or nickname.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.account_description_update
//======================================================================

WHATAFAG.actions.account_description_update =
	function ( data )
	{
		return observer_account_active.target.set( data );
	};

//======================================================================
//	validators.form_account_location_method_update
//======================================================================

WHATAFAG.validators.form_account_location_method_update =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.location_method === "" ) processing_area.set_and_show_message( "<p>Please enter a location method.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.account_location_method_update
//======================================================================

WHATAFAG.actions.account_location_method_update =
	function ( data )
	{
		return observer_account_active.target.set( data );
	};

//======================================================================
//	validators.form_account_location_label_update
//======================================================================

WHATAFAG.validators.form_account_location_label_update =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.location_label === "" ) processing_area.set_and_show_message( "<p>Please enter a location.</p>" );
		if ( properties_form.location_latitude === "" ) processing_area.set_and_show_message( "<p>A latitude must be sent.</p>" );
		if ( properties_form.location_longitude === "" ) processing_area.set_and_show_message( "<p>A longitude must be sent.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.account_location_label_update
//======================================================================

WHATAFAG.actions.account_location_label_update =
	function ( data )
	{
		return observer_account_active.target.set( data );
	};
//======================================================================
//	new_template_sign_up
//======================================================================

WHATAFAG.new_template_sign_up =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_sign_up" ) ).clone();

		//	add sub-templates

		var template_form = WHATAFAG.new_template_form_sign_up( { "name_template" : "template_form_sign_up" } );
		that.add_template_child( template_form, that.j_template.find( ".container_form" ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_site_contact_us
//======================================================================

WHATAFAG.new_template_site_contact_us =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	reset_form
		//======================================================================

		that.reset_form =
			function()
			{
				//	name

				var name;

				if ( hash_properties_account.label === "Anonymous" )
				{
					name = "";
				}
				else
				{
					name = hash_properties_account.label;
				}

				that.j_template.find( "[name='name']" ).val( name );

				//	email_address

				var email_address;

				if ( hash_properties_account.email_address_login === null )
				{
					email_address = "";
				}
				else
				{
					email_address = hash_properties_account.email_address_login;
				}

				that.j_template.find( "[name='email_address']" ).val( email_address );

				//	message

				that.j_template.find( "[name='message']" ).val( "" );
			};

		//======================================================================
		//	submit_form
		//======================================================================

		that.submit_form =
			function ()
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( "form" ) )
				var processing_area = that.processing_area;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_contact_us( properties_form, processing_area ) )
				{
					var data = {};

					data.uri_target = "/rest/virtual_groups/2";
					data.context = "contact_us";
					data.message = "From: " + properties_form.name + "\n\n" + "Contact information: " + properties_form.email_address + "\n\n" + properties_form.message;

					WHATAFAG.actions.contact_us( data )
						.then
						(
							function ()
							{
								processing_area.reset();
								processing_area.set_status_auto_dismiss( "Thank you! Your message was received." );
								that.reset_form();
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_site_contact_us" ) ).clone();

		//	processing area

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	hook up events

		that.j_template.find( ".button_submit_form" ).click( condition_for_event( that.submit_form ) );

		that.reset_form();

		//	return that

		return that;
	};

//======================================================================
//	validators.form_contact_us
//======================================================================

WHATAFAG.validators.form_contact_us =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.name === "" ) processing_area.set_and_show_message( "<p>Please enter your name.</p>" );
		else if ( properties_form.message === "" ) processing_area.set_and_show_message( "<p>Please enter a message.</p>" );
		else return true

		return false;
	};

//======================================================================
//	actions.contact_us
//======================================================================

WHATAFAG.actions.contact_us =
	function ( data )
	{
		return request_resource_create( "/rest/messages", data, undefined, undefined, false );
	};
//======================================================================
//	new_template_welcome
//======================================================================

WHATAFAG.new_template_welcome =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();


		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_welcome" ) ).clone();

		//	return that

		return that;
	};
//======================================================================
//	new_template_whats_up
//======================================================================

WHATAFAG.new_template_whats_up =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_changed )
			{
				if ( properties_changed.has_credentials )
				{
					that.j_template.find( ".section_form" ).toggle( properties.has_credentials );
				}

				if ( properties_changed.uri_search_activity !== undefined )
				{
					//	point targets

					that.observers.resource_search_activity.set_target( WHATAFAG.resource_library.resource( jQuery.param.querystring( properties.uri_search_activity, { "distance" : 500000 } ) ) );

					//	create a new search list

					that.delete_templates_children( "template_search_list" );

					var template_search_list = WHATAFAG.new_template_search_list( {} );
					that.add_template_child( template_search_list, that.j_template.find( ".container_template_search_list" ), "template_search_list" );
					template_search_list
						.update_arguments
						(
							{
								"uri" : jQuery.param.querystring( properties.uri_search_activity, { "distance" : 500000 } ),
								"html_placeholder" : "No activity",
								"args_expanding_list" :
									{
										"do_use_hr" : false,
										"name_constructor" : "new_template_activity",
										"args_constructor" : {}
									}
							}
						);
				}
			};

		//======================================================================
		//	handle_updated_resource_search_activity
		//======================================================================

		that.handle_updated_resource_search_activity =
			function ( properties, properties_changed )
			{
			};

		//======================================================================
		//	submit_form_blog_entry_create
		//======================================================================

		that.submit_form_blog_entry_create =
			function ()
			{
				var properties_form = { "message" : that.template_composer.get() };
				var processing_area = that.processing_area_blog_entry_create;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_blog_entry_create( properties_form, processing_area ) )
				{
					WHATAFAG.actions.blog_entry_create( properties_form )
						.then
						(
							function () { that.template_composer.set( "" ); that.observers.resource_search_activity.refresh(); processing_area.reset(); processing_area.set_status_auto_dismiss( "Post created" ); },
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_whats_up" ) ).clone();

		//	add templates

		that.template_composer = WHATAFAG.new_template_composer( { "classes" : "small" } );
		that.add_template_child( that.template_composer, that.j_template.find( ".container_template_composer" ) );

		//	create observers

		that.observers.resource_search_activity = new_observer();
		that.observers.resource_search_activity.bind( "change", that.handle_updated_resource_search_activity );

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	processing areas

		that.processing_area_blog_entry_create = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_blog_entry_create" ) );

		//	hook up events

		that.j_template.find( ".button_submit_blog_entry_create" ).click( condition_for_event( function () { that.submit_form_blog_entry_create(); } ) );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_blog_entry_create
//======================================================================

WHATAFAG.validators.form_blog_entry_create =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.message === "" ) return false;
		else return true

		return false;
	};

//======================================================================
//	actions.blog_entry_create
//======================================================================

WHATAFAG.actions.blog_entry_create =
	function ( data )
	{
		return request_resource_create( "/rest/blog_entries", { "message" : data.message } );
	};
//======================================================================
//	new_template_gallery_read
//======================================================================

WHATAFAG.new_template_gallery_read =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : undefined,
						"width" : 800,
						"height" : 480
					};

				return args_default;
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.resource_gallery.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_gallery
		//======================================================================

		that.handle_updated_resource_gallery =
			function ( properties, properties_new )
			{
				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_new );

				//	create a new gallery template

				that.delete_templates_children( "slideshow_container" );

				var template_slideshow_container = WHATAFAG.new_template_slideshow_container();
				that.add_template_child( template_slideshow_container, that.j_template.find( ".container_template_slideshow_container" ), "slideshow_container" );
				template_slideshow_container.update_arguments( { "uri" : properties.uri_search_images, "width" : that.args.width, "height" : that.args.height } );

				template_gallery.refresh();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_gallery_read" ).clone( false );

		//	create observers

		that.observers.resource_gallery = new_observer();
		that.observers.resource_gallery.bind( "change", that.handle_updated_resource_gallery );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_gallery_simple
//======================================================================

WHATAFAG.new_template_gallery_simple =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	searches must be refreshed by hand; delay forwarding the refresh

				that.observers.resource_search_image.refresh().done( function () { that.refresh_children( callback ); } );
			};

		//======================================================================
		//	handle_updated_resource_gallery
		//======================================================================

		that.handle_updated_resource_gallery =
			function ( properties, properties_changed )
			{
				if ( properties_changed.uri_search_images !== undefined )
				{
					that.observers.resource_search_image.set_target( WHATAFAG.resource_library.resource( properties.uri_search_images ) );
				}
			};

		//======================================================================
		//	handle_updated_resource_search_image
		//======================================================================

		that.handle_updated_resource_search_image =
			function ( properties, properties_changed )
			{
				if ( properties_changed.list_uris_resources !== undefined )
				{
					that.delete_templates_children( "template_image_summary" );

					jQuery
						.each
						(
							properties.list_uris_resources,
							function ( index, uri_image )
							{
								//	create template_image_summary

								that.template_image_summary = WHATAFAG.new_template_image_summary( { "uri" : uri_image, "width" : 300, "height" : 300 } );
								that.add_template_child( that.template_image_summary, that.j_template, "template_image_summary" );
							}
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_gallery_simple" ) ).clone();

		//	create observers

		that.observers.resource_search_image = new_observer();
		that.observers.resource_search_image.bind( "change", that.handle_updated_resource_search_image );

		that.observers.resource_gallery = new_observer();
		that.observers.resource_gallery.bind( "change", that.handle_updated_resource_gallery );

		//	set targets

		that.observers.resource_gallery.set_target( WHATAFAG.resource_library.resource( args_init.uri_gallery ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_slideshow
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_slideshow =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	update css settings
				//
				//	we have to do this *again*, after the initialization, because of a "bug" in the way the slideshow works.
				//	it expects widths and hights on elements to be set in the stylesheet (not inline), and it takes liberties
				//	with the inline style="", wiping out values that i put in there. however i need them there to start so that
				//	it can calculate the width and height of elements during start-up

				that.j_template.find( ".shade_box_outer" ).css( { "width" : ( that.args.width + 28 ) + "px", "height" : ( that.args.height + 28 ) + "px" } );
				that.j_template.find( ".shade_box_inner" ).css( { "width" : that.args.width + "px", "height" : that.args.height + "px" } );
				that.j_template.find( ".slides_container" ).css( { "width" : that.args.width + "px" } );
				that.j_template.find( ".slides_container div.slide" ).css( { "width" : that.args.width + "px", "height" : that.args.height + "px" } );
				that.j_template.find( ".caption" ).css( { "width" : that.args.width + "px" } );
				that.j_template.find( ".prev" ).css( { "left" : "-39px", "top" : ( Math.round( that.args.height / 2 ) - 21 ) + "px" } );
				that.j_template.find( ".next" ).css( { "left" : ( that.args.width + 15 ) + "px", "top" : ( Math.round( that.args.height / 2 ) - 21 ) + "px" } );

				//

				jQuery
					.each
					(
						properties.list_photos,
						function ( index, properties_photo )
						{
							var j_html = jQuery( "<div class=\"slide\"><img src=\"" + properties_photo.src + "\" width=\"" + properties_photo.width + "\" height=\"" + properties_photo.height + "\" alt=\"Slide 1\"></div>" );

							if ( properties_photo.j_caption )
							{
								j_html.append( jQuery( "<div class=\"caption\"></div>" ).append( properties_photo.j_caption ) );
							}

							that.j_template.find( ".slides_container" ).append( j_html );
						}
					);

				//	initialize slideshow

				that.slideshow =
					that.j_template.find( ".slides" )
						.slides
						(
							{
								preload : true,
								preloadImage : '/resources/images/slides/1.1.5/loading.gif',
								play : 0,
								generatePagination : false,
								pagination : false,
								pause : 5000,
								next: "next",
								prev: "prev",
								hoverPause : true,
								animationStart :
									function( current )
									{
										that.j_template.find( ".caption" ).animate( { bottom : -35 }, 100 );
									},
								animationComplete :
									function( current )
									{
										that.j_template.find( ".caption" ).animate( { bottom : 0 }, 200 );
									},
								slidesLoaded :
									function()
									{
										that.j_template.find( ".caption" ).animate( { bottom : 0 }, 200 );
									}
							}
						);

				//	hack hack hack : update the css settings again
				//
				//	see above for an explanation
				//	we also have to style the new (post-initialization) element with the class .slides_control

				that.j_template.find( ".shade_box_outer" ).css( { "width" : that.args.width + 28 + "px", "height" : that.args.height + 28 + "px" } );
				that.j_template.find( ".shade_box_inner" ).css( { "width" : that.args.width + "px", "height" : that.args.height + "px" } );
				that.j_template.find( ".slides_container" ).css( { "width" : that.args.width + "px" } );
				that.j_template.find( ".slides_container .slides_control" ).css( { "width" : that.args.width + "px", "height" : that.args.height + "px" } );
				that.j_template.find( ".slides_container div.slide" ).css( { "width" : that.args.width + "px", "height" : that.args.height + "px" } );
				that.j_template.find( ".caption" ).css( { "width" : that.args.width + "px" } );
			};

		//======================================================================
		//	set_inactive
		//======================================================================

		that.set_inactive_old = that.set_inactive;

		that.set_inactive =
			function ()
			{
				var that = this;

				if ( that.slideshow ) that.slideshow.stop();
				
				that.set_inactive_old();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_slideshow" ) ).clone();

		that.slideshow = undefined;

		//	return that

		return that;
	};
//======================================================================
//	new_template_slideshow_container
//======================================================================

WHATAFAG.new_template_slideshow_container =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default = function() { return { "uri" : undefined, "width" : 460, "height" : 250, "do_limit_search" : true, "limit_page_size" : 10, "limit_page_index" : 0 }; };

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the search resource; if it changes, the refresh is forwarded in the update handler; if it doesn't change, forward the refresh
				//	pass refresh to children only after refreshing the search resource

				that.observers.resource_search.refresh().done( function () { that.refresh_children( callback ); } );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	calculate the new search uri
				//======================================================================

				var arguments_query_string = {};

				//	limit the number of returned uris

				if ( that.args.do_limit_search )
				{
					arguments_query_string.page_size = that.args.limit_page_size;
					arguments_query_string.page = that.args.limit_page_index;
				}

				//	request the inclusion of tag-along resources

				arguments_query_string.do_tag_along = true;

				//	assemble the search uri

				var uri_search = jQuery.param.querystring( that.args.uri, arguments_query_string );

				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( uri_search ) );
			};

		//======================================================================
		//	handle_updated_resource_search
		//======================================================================

		that.handle_updated_resource_search =
			function ( properties, properties_changed )
			{
				if ( properties_changed.list_uris_resources )
				{
					that.delete_templates_children( "slideshow" );

					collect_resources( properties.list_uris_resources )
						.done
						(
							function ()
							{
								var list_photos = [];

								jQuery
									.each
									(
										arguments,
										function ( index, properties_image )
										{
											var args = { "src" : properties_image.uri + "/" + that.args.width + "x" + that.args.height, "width" : that.args.width, "height" : that.args.height };

											if ( properties_image.label !== null )
											{
												args.j_caption = jQuery( "<p>" + properties_image.label + "</p>" );

												if ( properties_image.uri_gallery !== null )
												{
													request_resource_show( properties_image.uri_gallery )
														.done
														(
															function ( properties_gallery )
															{
																request_resource_show( properties_gallery.uri_search_accounts )
																	.done
																	(
																		function ( properties )
																		{
																			if ( properties.list_uris_resources[ 0 ] !== undefined )
																			{
																				request_resource_show( properties.list_uris_resources[ 0 ] )
																					.done
																					(
																						function ( properties_account )
																						{
																							args.j_caption.append( " - " );
																							var j_link = jQuery( "<a href=\"" + get_href_for_account( properties_account ) + "\">" + properties_account.label + "</a>" );
																							args.j_caption.append( j_link );
																						}
																					);
																			}
																		}
																	);
															}
														);
												}
											}

											list_photos.push( args );
										}
									);

								//	create a new slideshow template

								that.template_slideshow = WHATAFAG.new_template_slideshow( {} );
								that.add_template_child( that.template_slideshow, that.j_template.find( ".container_template_slideshow" ), "slideshow" );
								that.template_slideshow.update_arguments( { "list_photos" : list_photos, "width" : that.args.width, "height" : that.args.height } );
							}
						);
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_slideshow_container" ) ).clone();

		//	create observers

		that.observers.resource_search = new_observer();
		that.observers.resource_search.bind( "change", that.handle_updated_resource_search );

		//	return that

		return that;
	};
//======================================================================
//	new_template_message_in_dialogue
//======================================================================

WHATAFAG.new_template_message_in_dialogue =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_message
		//======================================================================

		that.handle_updated_message =
			function ( properties, properties_changed )
			{
				that.j_template.find( ".date" ).html( pretty_date_and_time( properties.created_timestamp ) );
				that.j_template.find( ".message" ).html( properties.message );

				WHATAFAG.resource_library.resource( properties.uri_source ).refresh()
					.done
					(
						function ( properties )
						{
							that.j_template.find( ".from" ).html( "<a href=\"" + get_href_for_account( properties ) + "\">" + properties.label + "</a>" )
						}
					);

				if ( properties.uri_source === resource_account_active.uri )
				{
					that.j_template.addClass( "me" );
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_message_in_dialogue" ) ).clone();

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_message );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_message_one_line
//======================================================================

WHATAFAG.new_template_message_one_line =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_message
		//======================================================================

		that.handle_updated_message =
			function ( properties, properties_changed )
			{
				that.j_template.find( ".date" ).html( pretty_date_and_time( properties.created_timestamp ) );
				that.j_template.find( ".summary" ).html( properties.message );

				WHATAFAG.resource_library.resource( properties.uri_source ).refresh()
					.done
					(
						function ( properties )
						{
							that.j_template.find( ".from" ).html( "<a href=\"" + get_href_for_account( properties ) + "\">" + properties.label + "</a>" )
						}
					);
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_message_one_line" ) ).clone();

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_message );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_image_link_to_profile
//======================================================================

WHATAFAG.new_template_image_link_to_profile =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
			};

		//======================================================================
		//	handle_updated_image
		//======================================================================

		that.handle_updated_image =
			function ( properties, properties_changed )
			{
				if ( properties_changed.uri_gallery )
				{
					that.j_template.empty();

					if ( properties.uri_gallery !== null )
					{
						WHATAFAG.resource_library.resource( properties.uri_gallery ).refresh()
							.done
							(
								function ( properties_gallery )
								{
									WHATAFAG.resource_library.resource( properties_gallery.uri_search_accounts ).refresh()
										.done
										(
											function ( properties_search )
											{
												if ( properties_search.list_uris_resources[ 0 ] !== undefined )
												{
													WHATAFAG.resource_library.resource( properties_search.list_uris_resources[ 0 ] ).refresh()
														.done
														(
															function ( properties_account )
															{
																that.j_template.append( jQuery( "<a href=\"" + get_href_for_account( properties_account ) + "\"><img src=\"" + properties.uri + "/fit_v/250x100\" /></a>" ) );
															}
														);
												}
											}
										);
								}
							);
					}
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_image_link_to_profile" ) ).clone();

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_image );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_image_list_item
//======================================================================

WHATAFAG.new_template_image_list_item =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				that.j_template.empty().append( "<a href=\"#!/image_update;uri=" + properties.uri + "\"><img src=\"" + properties.uri + "/100x100\" /></a>" );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_image_list_item" ) ).clone();

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_resource );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_image_summary
//======================================================================

WHATAFAG.new_template_image_summary =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				that.j_template.empty().append( jQuery( "<div class=\"shade_box_outer\" style=\"display: inline-block; margin: 0px 20px 20px 0px;\"><img src=\"" + properties.uri + "/fit_v/600x250\" class=\"shade_box_inner\"/></div>" ) );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_image_summary" ) ).clone();

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_resource );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_image_update
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_image_update =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : null,
						"callback_update" : null,
						"callback_delete" : null
					};

				return args_default;
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the resource to the correct target

				that.observers.resource_image.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_image
		//======================================================================

		that.handle_updated_resource_image =
			function ( properties, properties_changed )
			{
				//	image

				if ( properties_changed.uri )
				{
					that.j_template.find( ".container_image" ).empty().append( "<img src=\"" + properties.uri + "/full_width\" />" );
				}

				//	label

console.info( properties );
				if ( properties_changed.label )
				{
					that.j_template.find( "[name='label']" ).val( properties.label );
				}

				/*
				//	description

				if ( properties_changed.description )
				{
					that.template_composer_description.set_html( properties.description );
				}
				*/
			};

		//======================================================================
		//	submit_form_update
		//======================================================================

		that.submit_form_update =
			function ( event, j_element )
			{
				var properties_form = WHATAFAG.collect_form_properties( that.j_template.find( "form" ) )
				var processing_area = that.processing_area_update_caption;

				processing_area.reset();
				processing_area.show_processing();

				//======================================================================
				//	validate
				//======================================================================

				if ( WHATAFAG.validators.form_image_update( properties_form, processing_area ) )
				{
					properties_form.uri = that.args.uri;

					WHATAFAG.actions.image_update( properties_form )
						.then
						(
							function ()
							{
								processing_area.reset();
								processing_area.set_status_auto_dismiss( "Success" );

								//	handle_message_auto_dismiss( "<p>Your picture has been updated.</p>", 2 );
								//	WHATAFAG.url_processor.push_new_fragment( "#!/images_manage" );
							},
							function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
						);
				}
			};

		//======================================================================
		//	submit_form_delete
		//======================================================================

		that.submit_form_delete =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_update_caption;

				processing_area.show_processing();

				//======================================================================
				//	delete
				//======================================================================

				request_resource_delete( that.args.uri )
					.then
					(
						function ()
						{
							processing_area.reset();

							that.j_template.find( ".container_image" ).empty();
							that.j_template.find( "[name='label']" ).val( "" );
							//	that.template_composer_description.set_html( "" );

							that.observers.resource_image.unset_target();

							handle_message_auto_dismiss( "<p>Your picture has been deleted.</p>", 2 );

							WHATAFAG.url_processor.push_new_fragment( "#!/profile_manage" );
						},
						function ( xml_http_request, text_status, error_thrown ) { processing_area.reset(); processing_area.set_and_show_message( xml_http_request.responseText ); }
					);
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_image_update" ) ).clone();

		//	processing areas

		that.processing_area_update_caption = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_update_caption" ) );

		//	hook up events

		that.j_template.find( ".button_update" ).click( condition_for_event( that.submit_form_update ) );
		that.j_template.find( ".button_delete" ).click( condition_for_event( that.submit_form_delete ) );
		that.j_template.find( ".button_toggle_dialogue_delete" ).click( condition_for_event( function () { that.j_template.find( ".dialogue_delete" ).toggle(); } ) );

		//	create observers

		that.observers.resource_image = new_observer();
		that.observers.resource_image.bind( "change", that.handle_updated_resource_image );

		//	return that

		return that;
	};

//======================================================================
//	validators.form_image_update
//======================================================================

WHATAFAG.validators.form_image_update =
	function ( properties_form, processing_area )
	{
		processing_area.reset();

		if ( properties_form.label.length > 48 ) processing_area.set_and_show_message( "Please keep your caption limited to no more than 48 characters (yours is " + label.length + " characters)" );
		else return true

		return false;
	};

//======================================================================
//	actions.image_update
//======================================================================

WHATAFAG.actions.image_update =
	function ( data )
	{
		return request_resource_update( data.uri, { "label" : data.label } );
	};
//======================================================================
//	new_template_images_manage
//======================================================================

WHATAFAG.new_template_images_manage =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource_account
		//======================================================================

		that.handle_updated_resource_account =
			function ( properties, properties_new )
			{
				//	point the observer to the new resource

				that.observers.resource_gallery_avatars.set_target( WHATAFAG.resource_library.resource( properties.uri_gallery_avatars ) );

				//	create a new file uploader
				//	use the updated gallery uri

				if ( properties_new.uri_gallery_avatars )
				{
					that.delete_templates_children( "uploader" );

					var args = 
						{
							"context" : "avatar",
							"label_button" : "Add a new picture to your gallery",
							"uri_gallery" : properties.uri_gallery_avatars,
							"allow_front_page" : true,
							"callback_success" :
								function ( uri_image )
								{
									//	handle_message_auto_dismiss( "<p>Your image has been added to the gallery.</p>", 2 );

									WHATAFAG.url_processor.push_new_fragment( "#!/image_update;uri=" + encodeURIComponent( uri_image ) );
								}
						};

					that.template_file_uploader = WHATAFAG.new_template_file_uploader( args );
					that.add_template_child( that.template_file_uploader, that.j_template.find( ".container_template_file_uploader" ), "uploader" );
					that.template_file_uploader.update_arguments( args );

					//	that.template_file_uploader.refresh();
				}
			};

		//======================================================================
		//	handle_updated_resource_gallery
		//======================================================================

		that.handle_updated_resource_gallery =
			function ( properties, properties_new )
			{
				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( properties.uri_search_images ) );

				//	create a new search list

				that.delete_templates_children( "search_list" );

				var template_search_list = WHATAFAG.new_template_search_list( {} );
				that.add_template_child( template_search_list, that.j_template.find( ".container_template_search_list" ), "search_list" );
				template_search_list
					.update_arguments
					(
						{
							"uri" : properties.uri_search_images,
							"html_placeholder" : "Nothing yet",
							"args_expanding_list" :
								{
									"do_use_hr" : true,
									"hr_html" : "<br />",
									"name_constructor" : "new_template_image_list_item",
									"args_constructor" : {}
								}
						}
					);

				//	template_search_list.refresh();
			};

		//======================================================================
		//	handle_updated_resource_search
		//======================================================================

		that.handle_updated_resource_search =
			function ( properties, properties_new )
			{
				//	update the status

				that.j_template.find( ".status_search" ).html( "Found " + properties.list_uris_resources.length + ( properties.list_uris_resources.length === 1 ? " Image" : " Images" ) );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_images_manage" ) ).clone();

		//	create observers

		that.observers.resource_gallery_avatars = new_observer( that.handle_updated_resource_gallery );
		that.observers.resource_search = new_observer( that.handle_updated_resource_search );

		//	bind to observers

		observer_account_active.bind( "change", that.handle_updated_resource_account, true );

		//	return that

		return that;
	};
//======================================================================
//	new_template_data
//======================================================================

WHATAFAG.new_template_data =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	add in a fresh html framework

				that.delete_templates_children();
				that.j_template.empty();
				that.j_template.append( jQuery( "#container_templates > ." + that.args.name_template ).clone( false ) );

				//	re-populate the template every time the resource changes

				if ( that.args.name_builder ) WHATAFAG[ that.args.name_builder ]( that, properties, properties_changed );
				else { that.populate_template_with_data( properties, properties_changed ); }
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_data" ).clone( false );

		//	return that

		return that;
	};
//======================================================================
//	new_template_expanding_list
//======================================================================

WHATAFAG.new_template_expanding_list =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	add_uris
		//======================================================================

		that.add_uris =
			function ( list_uris )
			{
				var that = this;

				//	loop over the uris

				var counter;

				for ( counter = 0; counter < list_uris.length; counter++ )
				{
					var uri = list_uris[ counter ];

					//	break

					if ( that.args.do_use_hr && that.has_shown_first )
					{
						that.j_template.find( ".container_list" ).append( that.args.hr_html );
					}

					//	create and place the list items

					var args_constructor = jQuery.extend( {}, that.args.args_constructor, { "uri" : uri } );

					var template_list_item = WHATAFAG[ that.args.name_constructor ]( args_constructor );
					that.add_template_child( template_list_item, that.j_template.find( ".container_list" ) );
					template_list_item.update_arguments( args_constructor );

					that.has_shown_first = true;
				}

				return that;
			};

		//======================================================================
		//	add_rows
		//======================================================================

		that.add_rows =
			function ( direction, rows )
			{
				var that = this;

				//	create the arguments

				var args_constructor = jQuery.extend( {}, row, that.args.args_constructor );

				//	loop over the rows

				var counter;

				if ( direction === "down" )
				{
					for ( counter = 0; counter < rows.length; counter++ )
					{
						var row = rows[ counter ];

						//	break

						if ( that.args.do_use_hr && that.has_shown_first )
						{
							that.j_template.find( ".container_list" ).append( that.args.hr_html );
						}

						//	create and place the list items

						var template_list_item = WHATAFAG[ that.args.name_constructor ]( args_constructor );
						that.add_template_child( template_list_item, that.j_template.find( ".container_list" ) );
						template_list_item.update_arguments( args_constructor );

						that.has_shown_first = true;
					}
				}
				else
				{
					for ( counter = rows.length - 1; counter >= 0; counter-- )
					{
						var row = rows[ counter ];

						//	break

						if ( that.args.do_use_hr && that.has_shown_first )
						{
							that.j_template.find( ".container_list" ).prepend( that.args.hr_html );
						}

						//	create and place the list items

						var template_list_item = WHATAFAG[ that.args.name_constructor ]( args_constructor );
						that.add_template_child( template_list_item, that.j_template.find( ".container_list" ) );
						template_list_item.update_arguments( args_constructor );

						that.has_shown_first = true;
					}
				}

				return that;
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_expanding_list" ) ).clone();

		that.has_shown_first = false;

		//	return that

		return that;
	};
//======================================================================
//	new_template_link_to_resource
//======================================================================

WHATAFAG.new_template_link_to_resource =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				if ( properties_changed.type_resource !== undefined )
				{
					if ( properties.type_resource === "accounts" )
					{
						that.j_template.html( "<a href=\"" + get_href_for_account( properties ) + "\">" + ( args_init.label || properties.label ) + "</a>" );
					}
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_link_to_resource" ) ).clone();

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_resource );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_multi
//
//	monitors arguments
//	monitors a resource
//
//	arguments :
//
//		uri
//		name_template
//		names_templates
//======================================================================

WHATAFAG.new_template_multi =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	temporarily flag each child template to keep track of which templates remain through the (possible) arrival of a changed resource

				that.flag_children();

				//	any children that haven't been created (and refreshed) by the single (in this case) resource handler will be refreshed now

				that.observers.resource.refresh( function () { that.refresh_flagged_children(); }, null, null, null );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				if ( properties_changed.name_template )
				{
					that.delete_templates_children();
					that.j_template.empty();
					that.j_template.append( jQuery( "#container_templates > ." + that.args.name_template ).clone( false ) );
				}

				//	point the observer to the new resource

				that.observers.resource.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				//	there are multiple ways to use a multi template, based on the args given :
				//
				//	these two configurations BUILD the structure of the template once and POPULATE that structure at least once (but possibly multiple times)
				//	that.args.name_template (ONLY) : copy the html of the template in as the body of this template; run populate_template_with_data on it every time the resource changes
				//	that.args.name_template AND that.args.name_builder : same as above, only use the builder function INSTEAD of populate_template_with_data
				//
				//	these two configurations BUILD the structure of the template whenever the resource type changes and POPULATE that structure at least once (but possibly multiple times)
				//	that.args.names_templates (ONLY) is a variation of the above where the html used is based on the TYPE of resource
				//	that.args.names_templates AND that.args.names_builders is a variation of the above

				if ( that.args.names_templates && properties_changed.type_resource )
				{
					that.delete_templates_children();
					that.j_template.empty();
					that.j_template.append( jQuery( "#container_templates > ." + that.args.names_templates[ properties.type_resource ] ).clone( false ) );
				}

				//	re-populate the template every time the resource changes

				if ( that.args.name_builder ) WHATAFAG[ that.args.name_builder ]( that, properties, properties_changed, that.args );
				else if ( that.args.names_builders ) WHATAFAG[ that.args.names_builders[ properties.type_resource ] ]( that, properties, properties_changed, that.args );
				else if ( that.args.name_template || that.args.names_templates ) { that.populate_template_with_data( properties, properties_changed ); WHATAFAG.show_delayed_images( that.j_template ); }
				else  { console.info( that.args ); console.info( "Error 31513" ); }
			};

		//======================================================================
		//	handle_unavailable_resource
		//======================================================================

		that.handle_unavailable_resource =
			function ( properties, properties_changed )
			{
				console.info( that.args.uri + " is unavailable" );

				that.j_template.hide();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_multi" ).clone( false );

		//	create observers

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_resource );
		that.observers.resource.bind( "unavailable", that.handle_unavailable_resource );

		//	return that

		return that;
	};
//======================================================================
//	new_template_query_list
//
//	monitors arguments
//	monitors the resource passed in as uri
//
//	embed an expanding list template to hold the templates, one for each row
//
//	arguments :
//		uri : uri of query
//		names_templates : the class name of the template to use for each item in the expanding list; passed on to expanding_list
//
//		limit_starting_index : index to start the query at; if present, this will alter the uri
//		limit_size : ask the server to limit the results to this number of items; if present, this will alter the uri
//		sort_by : sort method : if present, this will alter the uri
//======================================================================

WHATAFAG.new_template_query_list =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : undefined,

						"do_limit_query" : false,
						"limit_page_size" : 200,
						"limit_page_index" : 0,
						"html_placeholder" : "Nothing yet",

						//	everything else passed on to expanding_list
						
						"do_use_hr" : true,
						"hr_html" : undefined
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the query resource; if it changes, the refresh is forwarded in the update handler; if it doesn't change, forward the refresh
				//	pass refresh to children only after refreshing the query resource

				that.observers.resource_query.refresh( null, null, null, function () { that.refresh_children( callback ); } );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	placeholder text

				if ( properties_changed.html_placeholder )
				{
					that.j_template.find( ".container_placeholder" ).html( that.args.html_placeholder );
				}

				//	calculate the new query uri

				var arguments_query_string = {};

				//	limit the number of returned uris

				if ( that.args.do_limit_query )
				{
					arguments_query_string.page_size = that.args.limit_page_size;
					arguments_query_string.page = that.args.limit_page_index;
				}
				else
				{
				}

				//	request the inclusion of tag-along resources

				arguments_query_string.do_tag_along = true;

				//	assemble the query uri

				var uri_query = jQuery.param.querystring( that.args.uri, arguments_query_string );

				//	point the observer to the new resource

				that.observers.resource_query.set_target( WHATAFAG.resource_library.resource( uri_query ) );
			};

		//======================================================================
		//	handle_updated_resource_query
		//======================================================================

		that.handle_updated_resource_query =
			function ( properties, properties_changed )
			{
				if ( properties_changed.rows !== undefined )
				{
					that.delete_templates_children();

					//	placeholder for no list items

					if ( properties.rows.length === 0 )
					{
						that.j_template.find( ".container_placeholder" ).show();
						that.j_template.find( ".container_template_expanding_list" ).hide();
					}

					//	expanding list

					else
					{
						that.j_template.find( ".container_template_expanding_list" ).show();
						that.j_template.find( ".container_placeholder" ).hide();

						//	clone the arguments; pass to the expanding list

						var args_forwarding = underscore.clone( that.args );

						delete args_forwarding.uri;
						delete args_forwarding.do_limit_query;
						delete args_forwarding.limit_page_size;
						delete args_forwarding.limit_page_index;
						delete args_forwarding.html_placeholder;

						//	create a new expanding list

						var template_expanding_list = WHATAFAG.new_template_expanding_list();
						that.add_template_child( template_expanding_list, that.j_template.find( ".container_template_expanding_list" ) );
						template_expanding_list.update_arguments( args_forwarding );

						template_expanding_list.refresh();

						//	add uris to the expanding list

						template_expanding_list.add_rows( "down", properties.rows );
					}

					//	more buttons

					that.j_template.find( ".container_button_more_down" ).toggle( ( properties.index_resource_first + properties.rows.length ) < properties.count_total_resources_possible );
				}
			};

		//======================================================================
		//	more
		//======================================================================

		that.more =
			function( direction )
			{
				var that = this;

				that.args.limit_page_size += 200;

				that.handle_updated_margs();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_query_list" ).clone( false );

		//	hook up buttons

		that.j_template.find( ".button_more_up" ).click( condition_for_event( function () { that.more( "up" ); } ) );
		that.j_template.find( ".button_more_down" ).click( condition_for_event( function () { that.more( "down" ); } ) );
		that.j_template.find( ".button_sort_date_created_desc" ).click( condition_for_event( function () { that.sort_by_date(); } ) );
		that.j_template.find( ".button_sort_votes_desc" ).click( condition_for_event( function () { that.sort_by_popularity(); } ) );

		//	create observers

		that.observers.resource_query = new_observer( that.handle_updated_resource_query );

		//	return that

		return that;
	};
//======================================================================
//	new_template_search_list
//======================================================================

WHATAFAG.new_template_search_list =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the search resource; if it changes, the refresh is forwarded in the update handler; if it doesn't change, forward the refresh
				//	pass refresh to children only after refreshing the search resource

				that.observers.resource_search.refresh().done( function () { that.refresh_children( callback ); } );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	placeholder text

				if ( properties_changed.html_placeholder )
				{
					that.j_template.find( ".container_placeholder" ).html( that.args.html_placeholder );
				}

				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_search
		//======================================================================

		that.handle_updated_resource_search =
			function ( properties, properties_changed )
			{
				if ( properties_changed.list_uris_resources !== undefined )
				{
					that.delete_templates_children();

					//	placeholder for no list items

					if ( properties.list_uris_resources.length === 0 )
					{
						that.j_template.find( ".container_placeholder" ).show();
						that.j_template.find( ".container_template_expanding_list" ).hide();
					}

					//	expanding list

					else
					{
						that.j_template.find( ".container_template_expanding_list" ).show();
						that.j_template.find( ".container_placeholder" ).hide();

						//	clone the arguments; pass to the expanding list

						var args_expanding_list = underscore.clone( that.args.args_expanding_list );

						//	create a new expanding list

						var template_expanding_list = WHATAFAG.new_template_expanding_list( args_expanding_list );
						that.add_template_child( template_expanding_list, that.j_template.find( ".container_template_expanding_list" ) );
						template_expanding_list.update_arguments( args_expanding_list );

						//	template_expanding_list.refresh();

						//	add uris to the expanding list

						template_expanding_list.add_uris( properties.list_uris_resources );
					}
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_search_list" ) ).clone();

		//	create observers

		that.observers.resource_search = new_observer( that.handle_updated_resource_search );

		//	return that

		return that;
	};
//======================================================================
//	new_template_search_list_advanced
//
//	monitors arguments
//	monitors the resource passed in as uri
//
//	embed an expanding list template to hold the templates, one for each search result
//
//	arguments :
//		uri : uri of search/collection
//		names_templates : the class name of the template to use for each item in the expanding list; passed on to expanding_list
//
//		limit_starting_index : index to start the search at; if present, this will alter the uri
//		limit_size : ask the server to limit the results to this number of items; if present, this will alter the uri
//		sort_by : sort method : if present, this will alter the uri
//======================================================================

WHATAFAG.new_template_search_list_advanced =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : undefined,

						"do_show_controls" : false,

						"do_show_sort_controls" : true,
						"do_show_sort_control_date_created_asc" : true,
						"do_show_sort_control_date_created_desc" : true,
						"do_show_sort_control_label_asc" : true,
						"do_show_sort_control_label_desc" : true,
						"do_show_sort_control_votes_desc" : true,
						"selected_sort_control" : "date_created_desc",

						"do_limit_search" : false,
						"limit_page_size" : 200,
						"limit_page_index" : 0,

						"html_placeholder" : "<p>Nothing yet</p>",

						//	forward to expanding_list
						
						"do_use_hr" : true,
						"hr_html" : undefined
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the search resource; if it changes, the refresh is forwarded in the update handler; if it doesn't change, forward the refresh
				//	pass refresh to children only after refreshing the search resource

				that.observers.resource_search.refresh( null, null, null, function () { that.refresh_children( callback ); } );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point one observer to the original search uri (changes to the original search create a refresh() on this template)

				that.observers.resource_search_original.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );

				//	placeholder text

				if ( properties_changed.html_placeholder )
				{
					that.j_template.find( ".container_placeholder" ).html( that.args.html_placeholder );
				}

				//	sort controls

				that.j_template.find( ".section_controls" ).toggle( that.args.do_show_controls );
				that.j_template.find( ".section_sort_controls" ).toggle( that.args.do_show_sort_controls );

				if ( properties_changed.do_show_sort_control_date_created_asc !== undefined ) that.j_template.find( ".button_sort_date_created_asc" ).toggle( properties.do_show_sort_control_date_created_asc );
				if ( properties_changed.do_show_sort_control_date_created_desc !== undefined ) that.j_template.find( ".button_sort_date_created_desc" ).toggle( properties.do_show_sort_control_date_created_desc );
				if ( properties_changed.do_show_sort_control_label_asc !== undefined ) that.j_template.find( ".button_sort_label_asc" ).toggle( properties.do_show_sort_control_label_asc );
				if ( properties_changed.do_show_sort_control_label_desc !== undefined ) that.j_template.find( ".button_sort_label_desc" ).toggle( properties.do_show_sort_control_label_desc );
				if ( properties_changed.do_show_sort_control_votes_desc !== undefined ) that.j_template.find( ".button_sort_votes_desc" ).toggle( properties.do_show_sort_control_votes_desc );

				if ( properties_changed.selected_sort_control )
				{
					if ( properties.selected_sort_control === "date_created_asc" ) css_select( that.j_template.find( ".button_sort_date_created_asc" ) );
					else if ( properties.selected_sort_control === "date_created_desc" ) css_select( that.j_template.find( ".button_sort_date_created_desc" ) );
					else if ( properties.selected_sort_control === "label_asc" ) css_select( that.j_template.find( ".button_sort_label_asc" ) );
					else if ( properties.selected_sort_control === "label_desc" ) css_select( that.j_template.find( ".button_sort_label_desc" ) );
					else if ( properties.selected_sort_control === "votes_desc" ) css_select( that.j_template.find( ".button_sort_votes_desc" ) );
				}

				//	calculate the new search uri

				var arguments_query_string = {};

				arguments_query_string.sort_by = that.args.selected_sort_control;

				//	limit the number of returned uris

				if ( that.args.do_limit_search )
				{
					arguments_query_string.page_size = that.args.limit_page_size;
					arguments_query_string.page = that.args.limit_page_index;
				}
				else
				{
				}

				//	request the inclusion of tag-along resources

				arguments_query_string.do_tag_along = true;

				//	assemble the search uri

				var uri_search = jQuery.param.querystring( that.args.uri, arguments_query_string );

				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( uri_search ) );
			};

		//======================================================================
		//	handle_updated_resource_search
		//======================================================================

		that.handle_updated_resource_search =
			function ( properties, properties_new )
			{
				if ( properties_new.list_uris_resources )
				{
					that.delete_templates_children();

					//	more buttons

					that.j_template.find( ".container_button_more_down" ).toggle( ( properties[ "index_resource_first" ] + properties[ "list_uris_resources" ].length ) < properties[ "count_total_resources_possible" ] );

					//	sort buttons

					if ( that.args.do_show_sort_controls && properties.list_uris_resources.length > 1 )
					{
						that.j_template.find( ".section_sort_controls" ).show();
					}
					else
					{
						that.j_template.find( ".section_sort_controls" ).hide();
					}

					//	placeholder for no list items

					if ( properties.list_uris_resources.length === 0 )
					{
						that.j_template.find( ".container_placeholder" ).show();
						that.j_template.find( ".container_template_expanding_list" ).hide();
					}

					//	expanding list

					else
					{
						that.j_template.find( ".container_template_expanding_list" ).show();
						that.j_template.find( ".container_placeholder" ).hide();

						//	clone the arguments; pass to the expanding list

						var args_forwarding = underscore.clone( that.args );

						delete args_forwarding.uri;
						delete args_forwarding.do_show_controls;
						delete args_forwarding.do_show_sort_controls;
						delete args_forwarding.available_sort_controls;
						delete args_forwarding.do_show_sort_control_date_created_asc;
						delete args_forwarding.do_show_sort_control_date_created_desc;
						delete args_forwarding.do_show_sort_control_label_asc;
						delete args_forwarding.do_show_sort_control_label_desc;
						delete args_forwarding.do_show_sort_control_votes_desc;
						delete args_forwarding.selected_sort_control;
						delete args_forwarding.do_limit_search;
						delete args_forwarding.limit_page_size;
						delete args_forwarding.limit_page_index;
						delete args_forwarding.html_placeholder;

						//	create a new expanding list

						var template_expanding_list = WHATAFAG.new_template_expanding_list();
						that.add_template_child( template_expanding_list, that.j_template.find( ".container_template_expanding_list" ) );
						template_expanding_list.update_arguments( args_forwarding );

						template_expanding_list.refresh();

						//	add uris to the expanding list

						template_expanding_list.add_uris( "down", properties[ "list_uris_resources" ] );
					}
				}
			};

		//======================================================================
		//	more
		//======================================================================

		that.more =
			function( direction )
			{
				var that = this;

				that.args.limit_page_size += 200;

				that.handle_updated_margs();
			};

		//======================================================================
		//	sort_by_date_asc
		//======================================================================

		that.sort_by_date_asc =
			function()
			{
				var that = this;

				if ( that.args.selected_sort_control !== "date_created_asc" )
				{
					that.update_arguments( jQuery.extend( true, {}, that.args, { "selected_sort_control" : "date_created_asc" } ) );
				}

				return that;
			};

		//======================================================================
		//	sort_by_date_desc
		//======================================================================

		that.sort_by_date_desc =
			function()
			{
				var that = this;

				if ( that.args.selected_sort_control !== "date_created_desc" )
				{
					that.update_arguments( jQuery.extend( true, {}, that.args, { "selected_sort_control" : "date_created_desc" } ) );
				}

				return that;
			};

		//======================================================================
		//	sort_by_label_asc
		//======================================================================

		that.sort_by_label_asc =
			function()
			{
				var that = this;

				if ( that.args.selected_sort_control !== "label_asc" )
				{
					that.update_arguments( jQuery.extend( true, {}, that.args, { "selected_sort_control" : "label_asc" } ) );
				}

				return that;
			};

		//======================================================================
		//	sort_by_label_desc
		//======================================================================

		that.sort_by_label_desc =
			function()
			{
				var that = this;

				if ( that.args.selected_sort_control !== "label_desc" )
				{
					that.update_arguments( jQuery.extend( true, {}, that.args, { "selected_sort_control" : "label_desc" } ) );
				}

				return that;
			};

		//======================================================================
		//	sort_by_votes_desc
		//======================================================================

		that.sort_by_votes_desc =
			function()
			{
				var that = this;

				if ( that.args.selected_sort_control !== "votes_desc" )
				{
					that.update_arguments( jQuery.extend( true, {}, that.args, { "selected_sort_control" : "votes_desc" } ) );
				}

				return that;
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_search_list_advanced" ).clone( false );

		//	hook up buttons

		that.j_template.find( ".button_more_up" ).click( condition_for_event( function () { that.more( "up" ); } ) );
		that.j_template.find( ".button_more_down" ).click( condition_for_event( function () { that.more( "down" ); } ) );
		that.j_template.find( ".button_sort_date_created_asc" ).click( condition_for_event( function () { that.sort_by_date_asc(); } ) );
		that.j_template.find( ".button_sort_date_created_desc" ).click( condition_for_event( function () { that.sort_by_date_desc(); } ) );
		that.j_template.find( ".button_sort_label_asc" ).click( condition_for_event( function () { that.sort_by_label_asc(); } ) );
		that.j_template.find( ".button_sort_label_desc" ).click( condition_for_event( function () { that.sort_by_label_desc(); } ) );
		that.j_template.find( ".button_sort_votes_desc" ).click( condition_for_event( function () { that.sort_by_votes_desc(); } ) );

		//	create observers

		that.observers.resource_search = new_observer();
		that.observers.resource_search.bind( "change", that.handle_updated_resource_search );

		that.observers.resource_search_original = new_observer();
		that.observers.resource_search_original.bind( "change", function ( properties, properties_changed ) { that.observers.resource_search.refresh(); } );

		//	return that

		return that;
	};
//======================================================================
//	new_template_activity
//======================================================================

WHATAFAG.new_template_activity =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_activity
		//======================================================================

		that.handle_updated_activity =
			function ( properties, properties_changed )
			{
				that.delete_templates_children( "template_child" );

				if ( properties.category === "new_image" )
				{
					var template_activity_new_image = WHATAFAG.new_template_activity_new_image( { "uri_image" : properties.data.uri_image } );
					that.add_template_child( template_activity_new_image, that.j_template, "template_child" );
				}
				if ( properties.category === "new_blog_entry" )
				{
					var template_activity_new_blog_entry = WHATAFAG.new_template_activity_new_blog_entry( { "uri_blog_entry" : properties.data.uri_blog_entry } );
					that.add_template_child( template_activity_new_blog_entry, that.j_template, "template_child" );
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_activity" ) ).clone();

		//	create observers

		that.observers.resource_activity = new_observer();
		that.observers.resource_activity.bind( "change", that.handle_updated_activity );
		that.observers.resource_activity.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_activity_new_blog_entry
//======================================================================

WHATAFAG.new_template_activity_new_blog_entry =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_blog_entry
		//======================================================================

		that.handle_updated_blog_entry =
			function ( properties, properties_changed )
			{
				if ( properties_changed.uri_source )
				{
					that.delete_templates_children( "template_link_to_resource" );

					var template_link_to_resource = WHATAFAG.new_template_link_to_resource( { "uri" : properties.uri_source } );
					that.add_template_child( template_link_to_resource, that.j_template.find( ".container_template_link_to_resource" ), "template_link_to_resource" );
				}

				if ( properties_changed.message_html )
				{
					that.j_template.find( ".container_message" ).empty().append( "<div>" + properties.message_html + "</div>" );
				}
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_activity_new_blog_entry" ) ).clone();

		//	create observers

		that.observers.resource_blog_entry = new_observer();
		that.observers.resource_blog_entry.bind( "change", that.handle_updated_blog_entry );
		that.observers.resource_blog_entry.set_target( WHATAFAG.resource_library.resource( args_init.uri_blog_entry ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_activity_new_image
//======================================================================

WHATAFAG.new_template_activity_new_image =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_image
		//======================================================================

		that.handle_updated_image =
			function ( properties, properties_changed )
			{
				if ( properties.uri_gallery !== null )
				{
					WHATAFAG.resource_library.resource( properties.uri_gallery ).refresh()
						.done
						(
							function ( properties_gallery )
							{
								WHATAFAG.resource_library.resource( properties_gallery.uri_search_accounts ).refresh()
									.done
									(
										function ( properties )
										{
											if ( properties.list_uris_resources[ 0 ] !== undefined )
											{
												that.delete_templates_children( "template_link_to_resource" );

												var template_link_to_resource = WHATAFAG.new_template_link_to_resource( { "uri" : properties.list_uris_resources[ 0 ] } );
												that.add_template_child( template_link_to_resource, that.j_template.find( ".container_template_link_to_resource" ), "template_link_to_resource" );
											}
										}
									);
							}
						);
				}

				that.delete_templates_children( "template_image_link_to_profile" );

				var template_image_link_to_profile = WHATAFAG.new_template_image_link_to_profile( { "uri" : properties.uri } );
				that.add_template_child( template_image_link_to_profile, that.j_template.find( ".container_template_image_link_to_profile" ), "template_image_link_to_profile" );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_activity_new_image" ) ).clone();

		//	create observers

		that.observers.resource_image = new_observer();
		that.observers.resource_image.bind( "change", that.handle_updated_image );
		that.observers.resource_image.set_target( WHATAFAG.resource_library.resource( args_init.uri_image ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_blog_read
//
//	monitors arguments
//	monitors the resource passed in as uri_blog
//======================================================================

WHATAFAG.new_template_blog_read =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : null,
						"sort_by" : "date_created_desc",
						"do_show_sort_control_date_created_asc" : false,
						"do_show_sort_control_label_asc" : false,
						"do_show_sort_control_label_desc" : false,
						"html_placeholder" : "<p>No blog entries yet</p>",
						"names_templates" : { "blog_entries" : "template_blog_entry_summary" },
						"names_builders" : { "blog_entries" : "build_template_blog_entry_summary" },
						"do_show_controls" : true
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the blog resource

				that.observers.blog.refresh();

				//	forward refresh to child templates without waiting

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.blog.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_blog
		//======================================================================

		that.handle_updated_resource_blog =
			function ( properties, properties_new )
			{
				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_new );

				//	pass on all arguments except .uri (which we override)

				var arguments_new = underscore.clone( that.args );

				delete arguments_new.uri;

				arguments_new.uri = properties.uri_search_blog_entries;

				//	initialize a new child template

				that.delete_templates_children();

				var template_search_list_advanced = WHATAFAG.new_template_search_list_advanced();
				that.add_template_child( template_search_list_advanced, that.j_template.find( ".container_template_search_list_advanced" ) );
				template_search_list_advanced.update_arguments( arguments_new );

				template_search_list_advanced.refresh();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_blog_read" ).clone( false );

		//	create observers

		that.observers.blog = new_observer( that.handle_updated_resource_blog );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_blog_read_front_page
//
//	monitors arguments
//	monitors the resource passed in as uri_blog
//======================================================================

WHATAFAG.new_template_blog_read_front_page =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : null,
						"sort_by" : "date_created_desc",
						"do_show_sort_control_date_created_asc" : false,
						"do_show_sort_control_label_asc" : false,
						"do_show_sort_control_label_desc" : false,
						"html_placeholder" : "<p>No Announcements yet</p>",
						"names_templates" : { "blog_entries" : "template_blog_entry_front_page" },
						"names_builders" : { "blog_entries" : "build_template_blog_entry_front_page" },
						"do_show_controls" : true,
						"do_use_hr" : false
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the blog resource

				that.observers.blog.refresh();

				//	forward refresh to child templates without waiting

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.blog.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_blog
		//======================================================================

		that.handle_updated_resource_blog =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	section_admin
				//======================================================================

				if ( properties_changed.is_owner !== undefined )
				{
					that.j_template.find( ".section_admin" ).toggle( properties.is_owner );
				}

				//	pass on all arguments except .uri (which we override)

				var arguments_new = underscore.clone( that.args );

				delete arguments_new.uri;

				arguments_new.uri = properties.uri_search_blog_entries;

				//	initialize a new child template

				that.delete_templates_children();

				var template_search_list_advanced = WHATAFAG.new_template_search_list_advanced();
				template_search_list_advanced.j_template.find( ".unbundle .margin_20" ).removeClass( "margin_20" );	//	remove unwanted class
				template_search_list_advanced.j_template.find( ".unbundle" ).removeClass( "unbundle" );	//	remove unwanted class
				that.add_template_child( template_search_list_advanced, that.j_template.find( ".container_template_search_list_advanced" ) );
				template_search_list_advanced.update_arguments( arguments_new );

				template_search_list_advanced.refresh();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_blog_read_front_page" ).clone( false );

		//	create observers

		that.observers.blog = new_observer( that.handle_updated_resource_blog );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_discussion_read
//
//	monitors arguments
//	monitors the resource passed in as uri
//======================================================================

WHATAFAG.new_template_discussion_read =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	observe the new resource
				//======================================================================

				that.observers.resource.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );

				//======================================================================
				//	create a new "lead" template
				//======================================================================

				that.delete_templates_children( "lead" );

				var template_lead = WHATAFAG.new_template_multi();
				that.add_template_child( template_lead, that.j_template.find( ".container_template_lead" ), "lead" );
				template_lead.update_arguments( { "uri" : that.args.uri, "names_templates" : { "blog_entries" : "template_blog_entry_lead", "comments" : "template_comment_lead" } } );

				template_lead.refresh();

				//======================================================================
				//	create a new response template
				//======================================================================

				that.delete_templates_children( "response_create_inline" );

				var template_response_create_inline = WHATAFAG.new_template_response_create_inline();
				that.add_template_child( template_response_create_inline, that.j_template.find( ".container_template_response_create_inline" ), "response_create_inline" );
				template_response_create_inline.update_arguments( { "uri_subject" : that.args.uri, "callback_create" : that.callback_create } );

				template_lead.refresh();
			};

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( properties.uri_search_comments ) );

				//======================================================================
				//	create a new "advanced search" template
				//======================================================================

				that.delete_templates_children( "search_list_advanced" );

				var template_search_list_advanced = WHATAFAG.new_template_search_list_advanced();
				that.add_template_child( template_search_list_advanced, that.j_template.find( ".container_template_search_list_advanced" ), "search_list_advanced" );
				template_search_list_advanced.update_arguments( { "uri" : properties.uri_search_comments, "selected_sort_control" : "date_created_asc", "do_show_sort_control_date_created_desc" : false, "do_show_sort_control_label_desc" : false, "do_show_sort_control_label_asc" : false, "html_placeholder" : "<p>No comments yet</p>", "names_templates" : { "comments" : "template_comment_response" }, "do_show_controls" : true } );

				template_search_list_advanced.refresh();
			};

		//======================================================================
		//	callback_create
		//======================================================================

		that.callback_create =
			function()
			{
				handle_message_auto_dismiss( "<p>Your comment has been created.</p>", 2 );

				that.observers.resource_search.refresh();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_discussion_read" ).clone( false );

		//	create an observer

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_resource );

		that.observers.resource_search = new_observer();

		//	return that

		return that;
	};
//======================================================================
//	new_template_forum_read
//
//	monitors arguments
//	monitors the resource passed in as uri_forum
//======================================================================

WHATAFAG.new_template_forum_read =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : null,
						"sort_by" : "date",
						"type" : "all"
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the observed resources

				observer_user_active.refresh();

				//	because the child template is already correctly configured at this point, we can immediately forward the refresh

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.forum.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_user
		//======================================================================

		that.handle_updated_resource_user =
			function ( properties, properties_changed )
			{
				if ( properties_changed.has_credentials !== undefined )
				{
					that.j_template.find( ".section_guest" ).toggle( !properties.has_credentials );
					that.j_template.find( ".section_member" ).toggle( properties.has_credentials );
				}
			};

		//======================================================================
		//	handle_updated_resource_forum
		//======================================================================

		that.handle_updated_resource_forum =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( properties.uri_search_comments ) );

				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_changed );

				//	initialize a new child template

				that.delete_templates_children();

				var template_search_list_advanced = WHATAFAG.new_template_search_list_advanced();
				that.add_template_child( template_search_list_advanced, that.j_template.find( ".container_template_search_list_advanced" ) );
				template_search_list_advanced.update_arguments( { "uri" : properties.uri_search_comments, "do_show_sort_control_date_created_asc" : false, "do_show_sort_control_label_desc" : false, "do_show_sort_control_label_asc" : false, "html_placeholder" : "<p>No questions have been asked yet</p>", "names_templates" : { "comments" : "template_comment_tease" }, "names_builders" : { "comments" : "build_template_comment_tease" }, "do_show_controls" : true } );

				template_search_list_advanced.refresh();
			};

		//======================================================================
		//	handle_updated_resource_search
		//======================================================================

		that.handle_updated_resource_search =
			function ( properties, properties_changed )
			{
				if ( properties_changed.list_uris_resources )
				{
					//	link_create
					//	copy the link_create button and manually add it to the "advanced search" template

					var j_link_create = that.j_template.find( ".link_create" );

					j_link_create.html( properties.list_uris_resources.length === 0 ? "Ask the first question" : "Ask a question" );
					j_link_create.attr( "href" , "#/comment_create;uri_subject=" + that.args.uri + "&type=comment" );
				}
			};

		//======================================================================
		//	destroy
		//======================================================================

		that.destroy =
			function ()
			{
				var that = this;

				observer_user_active.unbind( "change", that.handle_updated_resource_user );

				that.destroy_root();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_forum_read" ).clone( false );

		//	bind to observers

		observer_user_active.bind( "change", that.handle_updated_resource_user, true );

		//	create observers

		that.observers.forum = new_observer();
		that.observers.forum.bind( "change", that.handle_updated_resource_forum );

		that.observers.resource_search = new_observer();
		that.observers.resource_search.bind( "change", that.handle_updated_resource_search );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_image_read
//======================================================================

WHATAFAG.new_template_image_read =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.resource_image.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_image
		//======================================================================

		that.handle_updated_resource_image =
			function ( properties, properties_changed )
			{
				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_changed );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_image_read" ).clone( false );

		//	create observers

		that.observers.resource_image = new_observer();
		that.observers.resource_image.bind( "change", that.handle_updated_resource_image );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_read
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_read =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	create a new child template based on the resource type
				//	only do this once (don't worry about creating an observer) because a resource's type cannot change
				//======================================================================

				that.delete_templates_children();

				//	fetch the item

				request_resource_show
				(
					that.args.uri,
					function ( properties_resource )
					{
						//	build a "read" template for the item

						switch ( properties_resource[ "type_resource" ] )
						{
							case "blog_entries" :
							{
								var template_discussion_read = WHATAFAG.new_template_discussion_read();
								that.add_template_child( template_discussion_read, that.j_template );
								template_discussion_read.update_arguments( { "uri" : that.args.uri } );

								template_discussion_read.refresh();

								break;
							}
							case "forums" :
							{
								var template_forum_read = WHATAFAG.new_template_forum_read();
								that.add_template_child( template_forum_read, that.j_template );
								template_forum_read.update_arguments( { "uri" : that.args.uri } );

								template_forum_read.refresh();

								break;
							}
							case "galleries" :
							{
								var template_gallery_read = WHATAFAG.new_template_gallery_read();
								that.add_template_child( template_gallery_read, that.j_template );
								template_gallery_read.update_arguments( { "uri" : that.args.uri } );

								//	template_gallery_read.refresh();

								break;
							}
							case "images" :
							{
								var template_image_read = WHATAFAG.new_template_image_read();
								that.add_template_child( template_image_read, that.j_template );
								template_image_read.update_arguments( { "uri" : that.args.uri } );

								template_image_read.refresh();

								break;
							}
							case "comments" :
							{
								var template_discussion_read = WHATAFAG.new_template_discussion_read();
								that.add_template_child( template_discussion_read, that.j_template );
								template_discussion_read.update_arguments( { "uri" : that.args.uri } );

								template_discussion_read.refresh();

								break;
							}
						}
					}
				);
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_read" ).clone( false );

		//	return that

		return that;
	};
//======================================================================
//	new_template_blog_entries_manage
//
//	monitors observer_organization_active
//	monitors the search resource
//======================================================================

WHATAFAG.new_template_blog_entries_manage =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				observer_organization_active.refresh();
				that.observers.resource_search.refresh();

				//	forward refresh to child templates without waiting

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_resource_organization
		//======================================================================

		that.handle_updated_resource_organization =
			function ( properties, properties_new )
			{
				//	point the observer to the new resource

				that.observers.resource_blog.set_target( WHATAFAG.resource_library.resource( properties.uri_blog ) );
			};

		//======================================================================
		//	handle_updated_resource_blog
		//======================================================================

		that.handle_updated_resource_blog =
			function ( properties, properties_new )
			{
				//	point the observer to the new resource

				that.observers.resource_search.set_target( WHATAFAG.resource_library.resource( properties.uri_search_blog_entries ) );

				//	create a new search list

				that.delete_templates_children( "search_list" );

				var template_search_list = WHATAFAG.new_template_search_list();
				that.add_template_child( template_search_list, that.j_template.find( ".container_template_search_list" ), "search_list" );
				template_search_list.update_arguments( { "uri" : properties.uri_search_blog_entries, "do_use_hr" : false, "html_placeholder" : "No Announcements have been created yet.", "names_templates" : { "blog_entries" : "template_blog_entry_list_item" }, "names_builders" : { "blog_entries" : "build_template_blog_entry_list_item" } } );

				//	template_search_list.refresh();
			};

		//======================================================================
		//	handle_updated_resource_search
		//======================================================================

		that.handle_updated_resource_search =
			function ( properties, properties_new )
			{
				//	update the status

				that.j_template.find( ".status_search" ).html( "Found " + properties.list_uris_resources.length + ( properties.list_uris_resources.length === 1 ? " Announcement" : " Announcements" ) );
			};

		//======================================================================
		//	destroy
		//======================================================================

		that.destroy =
			function ()
			{
				var that = this;

				observer_organization_active.unbind( "change", that.handle_updated_resource_organization );

				that.destroy_root();
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_blog_entries_manage" ).clone( false );

		//	create observers

		that.observers.resource_blog = new_observer( that.handle_updated_resource_blog );
		that.observers.resource_search = new_observer( that.handle_updated_resource_search );

		//	bind to observers

		observer_organization_active.bind( "change", that.handle_updated_resource_organization, true );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_blog_entry_create
//
//	monitors arguments
//	monitors the resource passed in as uri_blog
//======================================================================

WHATAFAG.new_template_blog_entry_create =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri_blog" : hash_properties_organization.uri_blog
					};

				return args_default;
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	change gets forwarded to handle_updated_resource_blog

				that.observers.resource_blog.set_target( WHATAFAG.resource_library.resource( that.args.uri_blog ) );
			};

		//======================================================================
		//	handle_updated_resource_blog
		//======================================================================

		that.handle_updated_resource_blog =
			function ( properties, properties_changed )
			{
				if ( properties_changed.uri )
				{
					that.reset();
				}

				if ( properties_changed.label !== undefined )
				{
					that.j_template.find( ".label" ).html( properties.label );
				}
			};

		//======================================================================
		//	reset
		//======================================================================

		that.reset =
			function ()
			{
				//	create a new create-update blog entry template

				that.delete_templates_children();

				var template_blog_entry_create_update = WHATAFAG.new_template_blog_entry_create_update();
				that.add_template_child( template_blog_entry_create_update, that.j_template.find( ".container_template_blog_entry_create_update" ) );
				template_blog_entry_create_update.update_arguments( { "uri" : null, "uri_blog" : that.args.uri_blog, "callback_create" : that.callback_create } );

				template_blog_entry_create_update.refresh();
			};

		//======================================================================
		//	callback_create
		//======================================================================

		that.callback_create =
			function( uri )
			{
				that.reset();

				handle_message_auto_dismiss( "<p>Your Announcement has been created.</p>", 2 );

				WHATAFAG.url_processor.push_new_fragment( "#!" + get_href_for_organization( hash_properties_organization ) + "/read;uri=" + encodeURIComponent( uri ) );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_blog_entry_create" ).clone( false );

		//	create observers

		that.observers.resource_blog = new_observer()
		that.observers.resource_blog.bind( "change", that.handle_updated_resource_blog );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_blog_entry_create_update
//
//	monitors arguments
//	monitors a blog_entry resource (optionally) passed in as uri
//======================================================================

WHATAFAG.new_template_blog_entry_create_update =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : null,
						"uri_blog" : null,
						"callback_create" : null,
						"callback_update" : null,
						"callback_delete" : null
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the resource

				that.observers.resource.refresh();

				//	forward refresh to child templates without waiting

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	this is a create

				if ( that.args.uri === null )
				{
					//	unset the target

					that.observers.resource.unset_target();
				}

				//	this is an update

				else
				{
					//	point the resource to the correct target

					that.observers.resource.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
				}
			};

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				//	this is a create

				if ( properties === undefined )
				{
					//	show/hide fields

					that.j_template.find( ".button_create" ).show();
					that.j_template.find( ".button_update" ).hide();
					that.j_template.find( ".button_delete,.button_toggle_dialogue_delete" ).hide();

					//	is_archived

					that.j_template.find( ".section_is_archived" ).hide();

					//	summary

					that.j_template.find( "[name='summary']" ).val( "" );

					//	title_nav

					that.j_template.find( "[name='title_nav']" ).val( "" );

					//	message

					that.template_composer_message.set_html( "" );
				}

				//	this is an update

				else
				{
					//	show/hide fields

					that.j_template.find( ".button_create" ).hide();
					that.j_template.find( ".button_update" ).show();
					that.j_template.find( ".button_delete,.button_toggle_dialogue_delete" ).show();

					//	is_archived

					that.j_template.find( ".section_is_archived" ).show();
					that.j_template.find( "[name='is_archived']" ).val( properties.is_archived ? "true" : "false" );

					//	summary

					that.j_template.find( "[name='summary']" ).val( properties.summary );

					//	title_nav

					that.j_template.find( "[name='title_nav']" ).val( properties.title_nav );

					//	message

					that.template_composer_message.set_html( properties.message );
				}
			};

		//======================================================================
		//	submit_form_create
		//======================================================================

		that.submit_form_create =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_create_update_blog_entry;

				processing_area.reset();

				var is_archived = false;
				var summary = trim( that.j_template.find( "[name='summary']" ).val() );
				var title_nav = trim( that.j_template.find( "[name='title_nav']" ).val() );
				var do_include_in_nav = ( title_nav !== "" );
				var message = that.template_composer_message.get_html();

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( summary === "" )
				{
					processing_area.set_and_show_message( "Please enter a headline." );
				}

				else if ( title_nav.length > 32 )
				{
					processing_area.set_and_show_message( "Please keep navigation titles under 32 characters (yours is " + title_nav.length + " characters)" );
				}

				else if ( message === "" )
				{
					processing_area.set_and_show_message( "Please enter a message." );
				}

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	create
					//======================================================================

					var hash_properties_form = {};

					hash_properties_form[ "is_archived" ] = is_archived;
					hash_properties_form[ "uri_blog" ] = that.args.uri_blog;
					hash_properties_form[ "summary" ] = summary;
					hash_properties_form[ "title_nav" ] = title_nav;
					hash_properties_form[ "do_include_in_nav" ] = do_include_in_nav;
					hash_properties_form[ "message" ] = message;

					request_resource_create
					(
						"/rest/blog_entries",
						hash_properties_form,
						function ( uri )
						{
							processing_area.reset();

							that.args.uri = uri;

							that.observers.resource.set_target( WHATAFAG.resource_library.resource( uri ) );

							//	if we're on our own site and created this blog entry then we need to refresh the navigation search (we possibly just added an item)

							WHATAFAG.resource_library.resource( hash_properties_organization.uri_search_blog_entries_with_nav ).refresh();

							if ( typeof that.args.callback_create === "function" ) that.args.callback_create( uri );
						},
						undefined,
						false
					);
				}
			};

		//======================================================================
		//	submit_form_update
		//======================================================================

		that.submit_form_update =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_create_update_blog_entry;

				processing_area.reset();

				var is_archived = that.j_template.find( "[name='is_archived']" ).val();
				var summary = trim( that.j_template.find( "[name='summary']" ).val() );
				var title_nav = trim( that.j_template.find( "[name='title_nav']" ).val() );
				var do_include_in_nav = ( title_nav !== "" );
				var message = that.template_composer_message.get_html();

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( summary === "" )
				{
					processing_area.set_and_show_message( "Please enter a headline." );
				}

				else if ( title_nav.length > 32 )
				{
					processing_area.set_and_show_message( "Please keep navigation titles under 32 characters (yours is " + title_nav.length + " characters)" );
				}

				else if ( message === "" )
				{
					processing_area.set_and_show_message( "Please enter a message." );
				}

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	update
					//======================================================================

					var hash_properties_form = {};

					hash_properties_form[ "is_archived" ] = is_archived;
					hash_properties_form[ "summary" ] = summary;
					hash_properties_form[ "title_nav" ] = title_nav;
					hash_properties_form[ "do_include_in_nav" ] = do_include_in_nav;
					hash_properties_form[ "message" ] = message;

					request_resource_update
					(
						that.args.uri,
						hash_properties_form,
						function ( hash_properties_blog_entry )
						{
							processing_area.reset();

							//	if we're on our own site and changed the nav title for this blog entry then we need to either refresh the search (for created or deleted titles) or force a rebuild (for updated titles)

							var resource_search = WHATAFAG.resource_library.resource( hash_properties_organization.uri_search_blog_entries_with_nav );
							resource_search.refresh( undefined, undefined, undefined, resource_search.change() );

							if ( typeof that.args.callback_update === "function" ) that.args.callback_update( hash_properties_blog_entry.uri );
						},
						undefined,
						false
					);
				}
			};

		//======================================================================
		//	submit_form_delete
		//======================================================================

		that.submit_form_delete =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_create_update_blog_entry;

				processing_area.show_processing();

				//======================================================================
				//	delete
				//======================================================================

				request_resource_delete
				(
					that.args.uri,
					function ()
					{
						processing_area.reset();

						that.args.uri = null;

						that.observers.resource.unset_target();

						//	if we're on our own site and deleted this blog entry then we need to refresh the navigation search (we possibly just removed an item)

						WHATAFAG.resource_library.resource( hash_properties_organization.uri_search_blog_entries_with_nav ).refresh();

						if ( typeof that.args.callback_delete === "function" ) that.args.callback_delete();
					}
				);
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_blog_entry_create_update" ).clone( false );

		//	composers

		that.template_composer_message = WHATAFAG.new_template_composer();
		that.add_template_child( that.template_composer_message, that.j_template.find( ".container_template_composer_message" ) );
		that.template_composer_message.update_arguments( { "variation_image" : "/full_width" } );

		//	create observers

		that.observers.resource = new_observer()
		that.observers.resource.bind( "change", that.handle_updated_resource );
		that.observers.resource.bind( "unset", that.handle_updated_resource, true );

		//	processing areas

		that.processing_area_create_update_blog_entry = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_create_update_blog_entry" ) );

		//	hook up events

		that.j_template.find( ".button_create" ).click( condition_for_event( that.submit_form_create ) );
		that.j_template.find( ".button_update" ).click( condition_for_event( that.submit_form_update ) );
		that.j_template.find( ".button_delete" ).click( condition_for_event( that.submit_form_delete ) );
		that.j_template.find( ".button_toggle_dialogue_delete" ).click( condition_for_event( function () { that.j_template.find( ".dialogue_delete" ).toggle(); } ) );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_blog_entry_update
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_blog_entry_update =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri_blog" : hash_properties_organization.uri_blog
					};

				return args_default;
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				that.reset();
			};

		//======================================================================
		//	reset
		//======================================================================

		that.reset =
			function ()
			{
				//	create a new create-update blog_entry template

				that.delete_templates_children();

				var template_blog_entry_create_update = WHATAFAG.new_template_blog_entry_create_update();
				that.add_template_child( template_blog_entry_create_update, that.j_template.find( ".container_template_blog_entry_create_update" ) );
				template_blog_entry_create_update.update_arguments( { "uri" : that.args.uri, "uri_blog" : that.args.uri_blog, "callback_update" : that.callback_update, "callback_delete" : that.callback_delete } );

				template_blog_entry_create_update.refresh();
			};

		//======================================================================
		//	callback_update
		//======================================================================

		that.callback_update =
			function()
			{
				that.reset();

				handle_message_auto_dismiss( "<p>Your Announcement has been updated.</p>", 2 );

				//	WHATAFAG.url_processor.push_new_fragment( "#!/blog_entries_manage" );
			};

		//======================================================================
		//	callback_delete
		//======================================================================

		that.callback_delete =
			function()
			{
				that.delete_templates_children();

				handle_message_auto_dismiss( "<p>Your Announcement has been deleted.</p>", 2 );

				WHATAFAG.url_processor.push_new_fragment( "#!/blog_entries_manage" );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_blog_entry_update" ).clone( false );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	new_template_comment_create
//
//	monitors arguments
//	monitors the resource passed in as uri_subject
//======================================================================

WHATAFAG.new_template_comment_create =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri_subject" : undefined
					};

				return args_default;
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	change gets forwarded to handle_updated_resource_subject

				that.observers.resource_subject.set_target( WHATAFAG.resource_library.resource( that.args.uri_subject ) );
			};

		//======================================================================
		//	handle_updated_resource_subject
		//======================================================================

		that.handle_updated_resource_subject =
			function ( properties, properties_changed )
			{
				if ( properties_changed.uri )
				{
					that.reset();
				}

				if ( properties_changed.label !== undefined )
				{
					that.j_template.find( ".label" ).html( properties.label );
				}
			};

		//======================================================================
		//	reset
		//======================================================================

		that.reset =
			function ()
			{
				//	create a new create-update comment template

				that.delete_templates_children();

				var template_comment_create_update = WHATAFAG.new_template_comment_create_update();
				that.add_template_child( template_comment_create_update, that.j_template.find( ".container_template_comment_create_update" ) );
				template_comment_create_update.update_arguments( { "uri" : null, "uri_subject" : that.args.uri_subject, "callback_create" : that.callback_create } );

				template_comment_create_update.refresh();
			};

		//======================================================================
		//	callback_create
		//======================================================================

		that.callback_create =
			function()
			{
				that.reset();

				handle_message_auto_dismiss( "<p>Your comment has been created.</p>", 2 );

				WHATAFAG.url_processor.push_new_fragment( "#!/read;uri=" + encodeURIComponent( that.args.uri_subject ) );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_comment_create" ).clone( false );

		//	create observers

		that.observers.resource_subject = new_observer()
		that.observers.resource_subject.bind( "change", that.handle_updated_resource_subject );

		//	return that

		return that;
	};
//======================================================================
//	new_template_comment_create_update
//
//	monitors arguments
//	monitors a comment resource (optionally) passed in as uri
//======================================================================

WHATAFAG.new_template_comment_create_update =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : null,
						"uri_subject" : null,
						"callback_create" : null,
						"callback_update" : null,
						"callback_delete" : null
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the resource

				that.observers.resource.refresh();

				//	forward refresh to child templates without waiting

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	this is a create

				if ( that.args.uri === null )
				{
					//	unset the target

					that.observers.resource.unset_target();
				}

				//	this is an update

				else
				{
					//	point the resource to the correct target

					that.observers.resource.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
				}
			};

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				//	this is a create

				if ( properties === undefined )
				{
					//	show/hide fields

					that.j_template.find( ".button_create" ).show();
					that.j_template.find( ".button_update" ).hide();
					that.j_template.find( ".button_delete,.button_toggle_dialogue_delete" ).hide();

					//	summary

					that.j_template.find( "[name='summary']" ).val( "" );

					//	message

					that.template_composer_message.set_html( "" );
				}

				//	this is an update

				else
				{
					//	show/hide fields

					that.j_template.find( ".button_create" ).hide();
					that.j_template.find( ".button_update" ).show();
					that.j_template.find( ".button_delete,.button_toggle_dialogue_delete" ).show();

					//	summary

					that.j_template.find( "[name='summary']" ).val( properties.summary );

					//	message

					that.template_composer_message.set_html( properties.message );
				}
			};

		//======================================================================
		//	submit_form_create
		//======================================================================

		that.submit_form_create =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_create_update_comment;

				processing_area.reset();

				var summary = that.j_template.find( "[name='summary']" ).val();
				var message = that.template_composer_message.get_html();

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( summary === "" )
				{
					processing_area.set_and_show_message( "Please enter a summary." );
				}

				else if ( message === "" )
				{
					processing_area.set_and_show_message( "Please enter a message." );
				}

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	create
					//======================================================================

					var hash_properties_form = {};

					hash_properties_form[ "uri_subject" ] = that.args.uri_subject;
					hash_properties_form[ "type" ] = that.args.type;
					hash_properties_form[ "summary" ] = summary;
					hash_properties_form[ "message" ] = message;

					request_resource_create
					(
						"/rest/comments",
						hash_properties_form,
						function ( uri )
						{
							processing_area.reset();

							that.args.uri = uri;

							that.observers.resource.set_target( WHATAFAG.resource_library.resource( uri ) );

							if ( typeof that.args.callback_create === "function" ) that.args.callback_create( uri );
						},
						undefined,
						false
					);
				}
			};

		//======================================================================
		//	submit_form_update
		//======================================================================

		that.submit_form_update =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_create_update_comment;

				processing_area.reset();

				var summary = that.j_template.find( "[name='summary']" ).val();
				var message = that.template_composer_message.get_html();

				//======================================================================
				//	in-browser checks
				//======================================================================

				if ( summary === "" )
				{
					processing_area.set_and_show_message( "Please enter a summary." );
				}

				else if ( message === "" )
				{
					processing_area.set_and_show_message( "Please enter a message." );
				}

				//======================================================================
				//	clear to go
				//======================================================================

				else
				{
					processing_area.show_processing();

					//======================================================================
					//	update
					//======================================================================

					var hash_properties_form = {};

					hash_properties_form[ "summary" ] = summary;
					hash_properties_form[ "message" ] = message;

					request_resource_update
					(
						that.args.uri,
						hash_properties_form,
						function ( hash_properties_comment )
						{
							processing_area.reset();

							if ( typeof that.args.callback_update === "function" ) that.args.callback_update( hash_properties_comment.uri );
						},
						undefined,
						false
					);
				}
			};

		//======================================================================
		//	submit_form_delete
		//======================================================================

		that.submit_form_delete =
			function ( event, j_element )
			{
				var processing_area = that.processing_area_create_update_comment;

				processing_area.show_processing();

				//======================================================================
				//	delete
				//======================================================================

				request_resource_delete
				(
					that.args.uri,
					function ()
					{
						processing_area.reset();

						that.args.uri = null;

						that.observers.resource.unset_target();

						if ( typeof that.args.callback_delete === "function" ) that.args.callback_delete();
					}
				);
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_comment_create_update" ).clone( false );

		//	composers

		that.template_composer_message = WHATAFAG.new_template_composer();
		that.add_template_child( that.template_composer_message, that.j_template.find( ".container_template_composer_message" ) );
		that.template_composer_message.update_arguments( { "variation_image" : "/full_width" } );

		//	create observers

		that.observers.resource = new_observer()
		that.observers.resource.bind( "change", that.handle_updated_resource );
		that.observers.resource.bind( "unset", that.handle_updated_resource, true );

		//	processing areas

		that.processing_area_create_update_comment = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_create_update_comment" ) );

		//	hook up events

		that.j_template.find( ".button_create" ).click( condition_for_event( that.submit_form_create ) );
		that.j_template.find( ".button_update" ).click( condition_for_event( that.submit_form_update ) );
		that.j_template.find( ".button_delete" ).click( condition_for_event( that.submit_form_delete ) );
		that.j_template.find( ".button_toggle_dialogue_delete" ).click( condition_for_event( function () { that.j_template.find( ".dialogue_delete" ).toggle(); } ) );

		//	return that

		return that;
	};
//======================================================================
//	new_template_comment_update
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_comment_update =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri_subject" : undefined
					};

				return args_default;
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				that.reset();
			};

		//======================================================================
		//	reset
		//======================================================================

		that.reset =
			function ()
			{
				//	create a new create-update comment template

				that.delete_templates_children();

				var template_comment_create_update = WHATAFAG.new_template_comment_create_update();
				that.add_template_child( template_comment_create_update, that.j_template.find( ".container_template_comment_create_update" ) );
				template_comment_create_update.update_arguments( { "uri" : that.args.uri, "uri_subject" : that.args.uri_subject, "callback_update" : that.callback_update, "callback_delete" : that.callback_delete } );

				template_comment_create_update.refresh();
			};

		//======================================================================
		//	callback_update
		//======================================================================

		that.callback_update =
			function()
			{
				that.reset();

				handle_message_auto_dismiss( "<p>Your comment has been updated.</p>", 2 );

				WHATAFAG.url_processor.push_new_fragment( "#!/read;uri=" + encodeURIComponent( that.args.uri_subject ) );
			};

		//======================================================================
		//	callback_delete
		//======================================================================

		that.callback_delete =
			function()
			{
				that.delete_templates_children();

				handle_message_auto_dismiss( "<p>Your comment has been deleted.</p>", 2 );

				WHATAFAG.url_processor.push_new_fragment( "#!/read;uri=" + encodeURIComponent( that.args.uri_subject ) );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_comment_update" ).clone( false );

		//	return that

		return that;
	};
//======================================================================
//	build_template_score_summary
//======================================================================

function build_template_score_summary( callback, uri_subject )
{
	//	clone the template

	var j_template_active = jQuery( "#container_templates > [name='template_score_summary']" ).clone( true );

	//	get the subject

	request_resource_show
	(
		uri_subject,
		function ( hash_properties_resource )
		{
			if ( typeof hash_properties_resource[ "reviews_is_enabled" ] === "undefined" || hash_properties_resource[ "reviews_is_enabled" ] === null || hash_properties_resource[ "reviews_is_enabled" ] === true )
			{
				j_template_active.find( ".reviews_not_allowed" ).hide();
			}
			else
			{
				j_template_active.find( ".reviews_not_allowed" ).show();
			}

			if ( typeof hash_properties_resource[ "score" ] === "undefined" || hash_properties_resource[ "score" ] === null )
			{
				j_template_active.find( ".score" ).hide();
				j_template_active.find( ".no_score" ).show();
			}
			else
			{
				j_template_active.find( ".score" ).html( "<a href=\"#reviews" + uri_subject + "\">" + hash_properties_resource[ "score" ] + " stars</a>" );

				j_template_active.find( ".score" ).show();
				j_template_active.find( ".no_score" ).hide();
			}

			//	callback

			if ( typeof callback === "function" ) callback( j_template_active );
		}
	);

	//	return the template

	return j_template_active;
}
//======================================================================
//	new_template_vote_basket_update
//
//	monitors the resource passed in as uri
//======================================================================

WHATAFAG.new_template_vote_basket_update =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the vote basket resource

				that.observers.vote_basket.refresh();
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//	point the observer to the new resource

				that.observers.vote_basket.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
			};

		//======================================================================
		//	handle_updated_resource_vote_basket
		//======================================================================

		that.handle_updated_resource_vote_basket =
			function ( properties, properties_new )
			{
				//	populate the template based on markup + resource data

				that.populate_template_with_data( properties, properties_new );

				//	toggle button

				if ( properties[ "my_vote"] === "up" )
				{
					that.action_on_vote = "down";
					that.j_template.find( ".pill_selection" ).addClass( "selected" );
				}
				else
				{
					that.action_on_vote = "up";
					that.j_template.find( ".pill_selection" ).removeClass( "selected" );
				}
			};

		//======================================================================
		//	vote_toggle
		//======================================================================

		that.vote_toggle =
			function ()
			{
				var that = this;

				//	update

				var hash_properties_form = {};

				hash_properties_form[ "vote" ] = that.action_on_vote;

				request_resource_update
				(
					that.args.uri,
					hash_properties_form,
					function ( uri )
					{
						that.refresh();
					}
				);

				return that;
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_vote_basket_update" ).clone( false );

		that.action_on_vote = null;

		//	create observers

		that.observers.vote_basket = new_observer( that.handle_updated_resource_vote_basket );

		//	hook up events

		that.j_template.find( ".button_vote_toggle" ).click( condition_for_event( function () { that.vote_toggle(); } ) );

		//	delayed images

		WHATAFAG.show_delayed_images( that.j_template );

		//	return that

		return that;
	};
//======================================================================
//	build_template_vote_summary
//======================================================================

function build_template_vote_summary( callback, count_votes_up, count_votes_down )
{
	//	clone the template

	var j_template_active = jQuery( "#container_templates > [name='template_vote_summary']" ).clone( true );

	//	label

	j_template_active.find( ".label_votes" ).html( count_votes_up + " of " + ( count_votes_up + count_votes_down ) + " " + ( count_votes_up === 1 ? "person" : "people" ) + " liked this" );

	//	callback

	if ( typeof callback === "function" ) callback( j_template_active );

	//	return the template

	return j_template_active;
}
//======================================================================
//	new_template_map_with_targets
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_map_with_targets =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	set_active
		//======================================================================

		that.set_active_old = that.set_active;

		that.set_active =
			function ()
			{
				if ( that.map_status === "loaded" ) google.maps.event.trigger( that.map, "resize" );

				that.set_active_old();
			};

		//======================================================================
		//	initialize_map
		//
		//	google map utilities are guaranteed to be loaded already by this point (done in create_markers())
		//======================================================================

		that.initialize_map =
			function ( hash_properties_map, callback )
			{
				that.marker_selected = new google.maps.MarkerImage( "http://www.google.com/mapfiles/marker_green.png", new google.maps.Size( 20, 34 ), new google.maps.Point( 0, 0 ), new google.maps.Point( 10, 34 ) );
				that.marker_unselected = new google.maps.MarkerImage( "http://www.google.com/mapfiles/marker.png", new google.maps.Size( 20, 34 ), new google.maps.Point( 0, 0 ), new google.maps.Point( 10, 34 ) );
				that.marker_shadow = new google.maps.MarkerImage( "http://www.google.com/mapfiles/shadow50.png", new google.maps.Size( 37, 34 ), new google.maps.Point( 0, 0 ), new google.maps.Point( 10, 34 ) );

				//	create the map

				that.map = new google.maps.Map( that.j_template.find( ".map" ).get( 0 ), hash_properties_map );

				that.map_status = "loaded";

				if ( typeof callback === "function" ) callback();
			};

		//======================================================================
		//	create_markers
		//======================================================================

		that.create_markers =
			function ( list_coords )
			{
				var that = this;

				//	delete markers

				that.delete_markers();

				//	get the bounds of all locations
				//	do this first so that the map doesn't re-draw between creation and setting the markers

				var bounds_markers = new google.maps.LatLngBounds();

				jQuery
					.each
					(
						list_coords,
						function ( index, coords )
						{
							var address_latitude_longitude = new google.maps.LatLng( coords.latitude, coords.longitude );
							bounds_markers.extend( address_latitude_longitude );
						}
					);

				//	callback to run after creating the map

				var callback =
					function ()
					{
						jQuery
							.each
							(
								list_coords,
								function ( index, coords )
								{
									var address_latitude_longitude = new google.maps.LatLng( coords.latitude, coords.longitude );

									//	add marker to map and to list of markers

									var marker =
										new google.maps.Marker
										(
											{
												"position" : address_latitude_longitude,
												"map" : that.map,
												"title" : null,
												"icon" : that.marker_unselected,
												"shadow" : that.marker_shadow
											}
										)

									that.hash_markers.push( marker );

									//	re-center the map to include all the markers

									if ( list_coords.length === 1 )
									{
										that.map.setCenter( new google.maps.LatLng( list_coords[ 0 ].latitude, list_coords[ 0 ].longitude ) );
										that.map.setZoom( 14 );
									}
									else
									{
										//	that.map.fitBounds( bounds_markers );	//	already set above
									}
								}
							);
					};

				//	run the callback now, or wait until after the map is loaded

				if ( that.map_status === "loaded" )
				{
					callback();
				}
				else if ( that.map_status === "unloaded" )
				{
					//	the initial map will have the right center (center of the bounds) but wrong zoom; force it to 14 so it's not too-far-away

					var hash_properties_map =
						{
							"zoom" : 14,
							"center" : bounds_markers.getCenter(),
							"mapTypeId" : google.maps.MapTypeId.ROADMAP,
							"scrollwheel" : false
						};

					that.initialize_map( hash_properties_map, callback );
				}

				return that;
			};

		//======================================================================
		//	delete_markers
		//======================================================================

		that.delete_markers =
			function ()
			{
				var that = this;

				if ( that.map_status === "loaded" )
				{
					//	remove the sidebar

					that.delete_templates_children( "sidebar" );

					//	delete old markers

					var marker = null;

					while ( market = that.hash_markers.pop() )
					{
						//	remove the marker from the map

						market.setMap( null );
					}
				}

				return that;
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_map_with_targets" ) ).clone();

		that.map = null;
		that.map_status = "unloaded";
		that.hash_markers = [];
		that.marker_selected = null;
		that.marker_unselected = null;
		that.marker_shadow = null;

		//	return that

		return that;
	};
//======================================================================
//	new_template_file_uploader
//
//	monitors arguments
//======================================================================

WHATAFAG.new_template_file_uploader =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				that.j_form.find( "[name='label']" ).val( that.args.label || "" );
				that.j_form.find( "[name='context']" ).val( that.args.context || "image" );
				that.j_form.find( "[name='description']" ).val( that.args.description || "" );
				that.j_form.find( "[name='allow_front_page']" ).val( that.args.allow_front_page || "false" );
				that.j_form.find( "[name='uri_gallery']" ).val( that.args.uri_gallery || "" );
				that.j_template.find( ".button_upload_file" ).html( "<img src=\"/resources/images/core/upload image icon.gif/32x32\" style=\"width: 32px; height: 32px; margin-right: 10px;\" />" + that.args.label_button );
			};

		//======================================================================
		//	set_active
		//======================================================================

		that.set_active_old = that.set_active;

		that.set_active =
			function ()
			{
				var width = that.j_template.find( ".base" ).outerWidth();
				var height = that.j_template.find( ".base" ).outerHeight();

				that.j_template.find( ".overlay" ).css( { "width" : width + "px", "height" : height + "px" } );

				that.set_active_old();
			};

		//======================================================================
		//	submit_form
		//
		//	we should NOT stop the event; so don't use our custom "condition_for_event" here
		//======================================================================

		that.submit_form =
			function ( event )
			{
				var that = this;

				that.processing_area.reset();

				that.j_input_file.hide();

				that.processing_area.set_status( "Uploading your file now..." );

				var id_iframe = make_id( 8 );

				var j_iframe = jQuery( "<iframe id=\"" + id_iframe + "\" name=\"" + id_iframe + "\" src=\"javascript:;\" style=\"display: none;\" />" );

				jQuery( "body" ).prepend( j_iframe );

				that.j_form.attr( "target", id_iframe );

				j_iframe
					.load
					(
						function ( event )
						{
							that.j_form.get( 0 ).reset();
							that.j_input_file.show();
							that.processing_area.clear_status();

							var response = jQuery.parseJSON( j_iframe.contents().find("body").html() );
							var uri_image = response[ "uri" ];

							if ( typeof that.args.callback_success === "function" ) that.args.callback_success( uri_image );

							//	remove the iframe; don't do this in "load" because it'll cause firefox to spin spin spin
							
							setTimeout( function ( event ) { j_iframe.remove(); }, 5000 );
						}
					);

				//	continue submissions normally

				return true;
			}

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_file_uploader" ) ).clone();

		that.j_form = that.j_template.find( "form" );
		that.j_input_file = that.j_template.find( "input[type='file']" );

		//	format the button immediately so that we can get the size of it immediately

		that.j_template.find( ".button_upload_file" ).html( "<img src=\"/resources/images/core/upload image icon.gif/32x32\" style=\"width: 32px; height: 32px; margin-right: 10px;\" />" + args_init.label_button );

		//	processing areas

		that.processing_area = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area" ) );

		//	hook up events

		that.j_form.submit( function ( event ) { that.submit_form(); } );
		that.j_input_file.change( function ( event ) { that.j_form.submit(); } );

		//	return that

		return that;
	};
//======================================================================
//	new_template_single_image_manager
//
//	monitors arguments
//	monitors a resource
//======================================================================

WHATAFAG.new_template_single_image_manager =
	function ()
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	get_args_default
		//======================================================================

		that.get_args_default =
			function()
			{
				var that = this;

				var args_default =
					{
						"uri" : undefined,

						"context" : null,
						"uri_source" : null,

						"callback_create" : null,
						"callback_update" : null,
						"callback_delete" : null,

						"label_button" : "Upload a picture",
						"label_delete" : "Delete picture"
					};

				return args_default;
			};

		//======================================================================
		//	refresh
		//======================================================================

		that.refresh =
			function ( callback )
			{
				var that = this;

				//	refresh the resource

				that.observers.resource_image.refresh();

				//	forward refresh to child templates without waiting

				that.refresh_children( callback );
			};

		//======================================================================
		//	handle_updated_margs
		//======================================================================

		that.handle_updated_margs =
			function ( properties, properties_changed )
			{
				//======================================================================
				//	label_delete
				//======================================================================

				if ( properties_changed.label_delete )
				{
					that.j_template.find( ".button_delete_image" ).html( properties.label_delete );
				}

				//======================================================================
				//	file uploader
				//======================================================================

				that.delete_templates_children( "file_uploader" );

				var args_template_file_uploader = 
					{
						"context" : that.args.context,
						"label_button" : that.args.label_button,
						"callback_success" :
							function ( uri_image )
							{
								var is_create = ( that.args.uri === undefined );

								that.update_arguments( jQuery.extend( {}, that.args, { "uri" : uri_image } ) );

								that.refresh();

								if ( is_create )
								{
									if ( typeof that.args.callback_create === "function" ) that.args.callback_create( uri_image );
								}
								else
								{
									if ( typeof that.args.callback_update === "function" ) that.args.callback_update( uri_image );
								}
							}
					};

				var template_file_uploader = WHATAFAG.new_template_file_uploader();
				that.add_template_child( template_file_uploader, that.j_template.find( ".container_template_file_uploader" ), "file_uploader" );
				template_file_uploader.update_arguments( args_template_file_uploader );
				//	template_file_uploader.refresh();

				//	this is a create

				if ( that.args.uri === undefined )
				{
					//	unset the target

					that.observers.resource_image.unset_target();
				}

				//	this is an update

				else
				{
					//	point the resource to the correct target

					that.observers.resource_image.set_target( WHATAFAG.resource_library.resource( that.args.uri ) );
				}
			};

		//======================================================================
		//	handle_updated_resource
		//======================================================================

		that.handle_updated_resource =
			function ( properties, properties_changed )
			{
				//	this is a create

				if ( properties === undefined )
				{
					//	show/hide fields

					that.j_template.find( ".has_image" ).hide();

					//	remove the thumbnail

					that.j_template.find( ".thumbnail" ).hide();
				}

				//	this is an update

				else
				{
					//	show/hide fields

					that.j_template.find( ".has_image" ).show();

					//	show the thumbnail

					that.j_template.find( ".thumbnail" ).attr( "src", properties.uri + "/100x100" ).show();
				}
			};

		//======================================================================
		//	clear
		//======================================================================

		that.clear =
			function()
			{
				var that = this;

				var arguments_new = underscore.clone( that.args );
				delete arguments_new.uri;
				that.update_arguments( arguments_new );
			};

		//======================================================================
		//	set_uri_image
		//======================================================================

		that.set_uri_image =
			function( uri_image )
			{
				var that = this;

				var arguments_new = underscore.clone( that.args );
				arguments_new.uri = uri_image;
				that.update_arguments( arguments_new );
			};

		//======================================================================
		//	get_uri_image
		//======================================================================

		that.get_uri_image =
			function()
			{
				var that = this;

				return ( that.args.uri || null );
			};

		//======================================================================
		//	delete_image
		//======================================================================

		that.delete_image =
			function ()
			{
				var processing_area = that.processing_area_delete_image;

				processing_area.show_processing();

				//======================================================================
				//	delete
				//======================================================================

				request_resource_delete
				(
					that.args.uri,
					function ()
					{
						processing_area.reset();

						var arguments_new = underscore.clone( that.args );

						delete arguments_new.uri;

						that.update_arguments( arguments_new );

						//	that.refresh();

						if ( typeof that.args.callback_delete === "function" ) that.args.callback_delete();
					}
				);
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > .template_single_image_manager" ).clone( false );

		//	processing areas

		that.processing_area_delete_image = WHATAFAG.new_processing_area( that.j_template.find( ".processing_area_delete_image" ) );

		//	hook up events

		that.j_template.find( ".button_delete_image" ).click( condition_for_event( that.delete_image ) );

		//	create observers

		that.observers.resource_image = new_observer()
		that.observers.resource_image.bind( "change", that.handle_updated_resource );
		that.observers.resource_image.bind( "unset", that.handle_updated_resource, true );

		//	return that

		return that;
	};
//======================================================================
//	new_template_account_front_page
//======================================================================

WHATAFAG.new_template_account_front_page =
	function ( args_init )
	{
		var that = WHATAFAG.new_template();

		//======================================================================
		//	handle_updated_account
		//======================================================================

		that.handle_updated_account =
			function ( properties, properties_changed )
			{
				if ( properties_changed.label !== undefined ) that.j_template.find( ".label" ).html( properties.label );
				if ( properties_changed.is_online !== undefined ) that.j_template.find( ".section_online" ).toggle( properties.is_online );

				that.j_template.find( ".container_avatar" )
					.empty()
					.append
					(
						jQuery( "<a href=\"" + get_href_for_account( properties ) + "\"><img src=\"" + properties.uri_image_avatar + "/150x150\" /></a>" )
					);

				that.observers.resource_distance_to.set_target( WHATAFAG.resource_library.resource( properties.uri_distance_to ) );
			};

		//======================================================================
		//	handle_updated_distance_to
		//======================================================================

		that.handle_updated_distance_to =
			function ( properties, properties_changed )
			{
				/*
				var label = "";

				if ( properties.distance < 1 ) label = Math.round( properties.distance * 1000 ) + " meters away";
				else if ( properties.distance < 5 ) label = properties.distance.toPrecision( 2 ) + " km away";
				else label = properties.distance.toPrecision( 2 ) + " km away";
				*/

				that.j_template.find( ".label_distance" ).html( properties.distance );
			};

		//======================================================================
		//	constructor
		//======================================================================

		that.j_template = jQuery( "#container_templates > ." + ( args_init.name_template || "template_account_front_page" ) ).clone();

		//	create observers

		that.observers.resource_distance_to = new_observer();
		that.observers.resource_distance_to.bind( "change", that.handle_updated_distance_to );

		that.observers.resource = new_observer();
		that.observers.resource.bind( "change", that.handle_updated_account );
		that.observers.resource.set_target( WHATAFAG.resource_library.resource( args_init.uri ) );

		//	return that

		return that;
	};

