Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Script to automatically make a stack with a RAW+jpg pair of images

New Here ,
May 16, 2007 May 16, 2007
While on my last trip, I accidently setup my camera to take Raw + small jpg. No big deal, that isn't too much memory, so I didn't really worry about it. When I got home, the jpg files were copied to my hard drive along with the raw files. So, I went to delete the jpgs and I realized something. Bridge runs very fast when it's drawing thumbnails and previews of small jpg images. I got to thinking. Wouldn't it be cool to make a script that would take your raw+jpg from the camera and convert each pair into a stack with the jpg on top. This would enable bridge to run much more quickly since it wouldn't need to render all those raw image thumbs and previews.

Hmmm....now where to start....I looked around at the scripting language for photoshop. since I have written a little bit of javascript, I thought I would start there, but I can't find where the stack property is kept in metadata or the DOM.

Any ideas of where I might turn from here?
TOPICS
Scripting
2.9K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
May 16, 2007 May 16, 2007
Marc,

Yes, that sounds like a cool script, but unfortunately the stack function is not exposed to scripting by the DOM. Thanks for letting us know that you would find this useful.

For now, how about using the Filter pane to show only JPEG files in the content pane?

Also, you can try using Quick Thumbnails preference to make thumbnails for your RAW files. If your camera embeds a small thumbnail in the RAW files, Bridge may be able to extract and display it faster than it can generate a Thumbnail from scratch.

Thanks for your feedback,
David Franzen
Adobe Bridge Quality Engineer
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 21, 2007 Sep 21, 2007
David,
This is a feature that I have tried very hard (unsuccessfully) to produce using scripting and other tricks in Bridge for quite some time. I almost always work with a JPG/RAW pair, and the ability to label them together, and to view the JPG as a representation of the pair is of paramount importance to me. I have been using Photo Mechanic for several years, solely because of this capability, and will not make the transition to Bridge until I can do this. A lot of my colleagues also work the same way, and while they moan about Photo Mechanic's quirks, they will not go to Bridge simply because it does not provide this simple but very necessary functionality. Is there any chance we will see it in CS4, or (even better) an update to Bridge CS3?
David Peart
Earthlight Photography
www.earthlightphotos.com
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2008 Jan 13, 2008
Anyone has a good tip on doing this in PSE6 ?
I found it pretty difficult to grasp the idea that there was no business logic in PSE Organizer to do this...
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 13, 2008 Apr 13, 2008
I have a script that put all the jpg in a jpg folder and all the raw in a raw folder inside the pics foler itself , I use it with nef pics (nikon) but you just have to change it to the good extension :

property _subfolder_nef : "NEF"
property _subfolder_jpg : "JPG"

tell application "Finder"
set _slidefolder to choose folder

set NEFfolder to make new folder at _slidefolder with properties {name:_subfolder_nef}
set JPGfolder to make new folder at _slidefolder with properties {name:_subfolder_jpg}
move (get files of _slidefolder whose name extension is "nef") to NEFfolder
move (get files of _slidefolder whose name extension is "jpg") to JPGfolder
end tell

Hope this will help...
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 27, 2008 Aug 27, 2008
Try it :)

app.document.select(app.document.thumbnail.children[0])
app.document.select(app.document.thumbnail.children[1])
app.document.chooseMenuItem('submenu/Stack')
app.document.chooseMenuItem('StackGroup')

http://niemannross.com/developer/wiki/index.php?title=MenuElementObject#Submenu_and_Command_Identifiers - MenuID
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 28, 2008 Aug 28, 2008
Save this and use it :)<br />This script stack all similar files by name with out extension.<br /><br />--= begin of 'autostack.jsx' file =--<br />///////////////////<br />/// Name: Auto stacking files<br />/// Description: This script enable auto stacking files by name<br />/// Author: Tyzhnenko Dmitry<br />/// E-mail: t.dmitry@gmail.com<br />/// Version: 0.3<br />///////////////////<br /><br />/*<br />@@@START_XML@@@<br /><?xml version="1.0" encoding="UTF-8"?><br /><ScriptInfo xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en_US"><br /> <dc:title>Auto stacking files</dc:title><br /> <dc:description>This script enable auto stacing files by name function</dc:description><br /></ScriptInfo><br />@@@END_XML@@@<br />*/<br /><br />function AutomaticStackingFiles()<br />{<br /> /**<br /> The context in which this snippet can run; Bridge must be running.<br /> @type String<br /> */<br /> this.requiredContext = "\tAdobe Bridge CS3 must be running.\n\tExecute against Bridge CS3 as the Target.\n";<br /> $.level = 1; // Debugging level<br /> <br /> this.version = "0.3";<br /> this.author = "Tyzhenenko Dmitry";<br /> <br /> /**<br /> The unique identifier for the new menu item command<br /> @type String<br /> */<br /> //this.menuID = "AutoStackFiles"; <br /> this.menuCommandID = "GoAutoStackingFiles";<br /><br />}<br /><br />function RunAutoStacking()<br />{<br /> var doc = app.document;<br /> var thumb = doc.thumbnail;<br /> var vthumb = doc.visibleThumbnails;<br /> var currSort = doc.sorts;<br /><br /> var stacks_arr = new Array;<br /><br /> function StackPhoto()<br /> {<br /> doc.chooseMenuItem('submenu/Stack');<br /> doc.chooseMenuItem('StackGroup');<br /> }<br /><br /> function getFileExt( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(dot,t.name.length);<br /> }<br /><br /> function getFileName( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(0, dot);<br /> }<br /><br /> var SortObj = {}; <br /> SortObj.name = "name";<br /> SortObj.type = "string";<br /> SortObj.reverse = false;<br /> var SortsArray = [];<br /> SortsArray.push(SortObj);<br /> doc.sorts = SortsArray;<br /><br /> for (var len = 0; len < vthumb.length; len++ )<br /> {<br /> doc.deselectAll();<br /> doc.select(vthumb[len]);<br /> for ( var k = len+1; k < vthumb.length; k++ )<br /> {<br /> //alert(k);<br /> if ( getFileName( vthumb[len] ) == getFileName( vthumb) ) <br /> doc.select(vthumb);<br /> else <br /> {<br /> if (doc.selectionLength > 1) <br /> StackPhoto();<br /> break;<br /> }<br /> <br /> if (doc.selectionLength > 1) <br /> StackPhoto();<br /> }<br /> vthumb = doc.visibleThumbnails;<br /> }<br /><br /> doc.sorts = currSort;<br /><br />}<br /><br />AutomaticStackingFiles.prototype.run = function()<br />{<br /> var retval = true;<br /> if(!this.canRun()) {<br /> retval = false; <br /> return retval;<br /> }<br /> //app.document.chooseMenuItem('submenu/Stack');<br /> var AutoStackCommand = new MenuElement("command", "Auto stacking", "at the beginning of submenu/Stack", );<br /> AutoStackCommand.onSelect = function(m)<br /> {<br /> RunAutoStacking(); <br /> }<br />}<br /><br />AutomaticStackingFiles.prototype.canRun = function()<br />{ <br /> // Must run in Bridge <br /> if(BridgeTalk.appName == "bridge") <br /> {<br /> // Stop the menu element from being added again if the snippet has already run<br /> if(MenuElement.find(this.menuCommandID))<br /> {<br /> $.writeln("ERROR:: Menu element from AutoStackFiles already exists!\nRestart Bridge to run this snippet again.");<br /> return false;<br /> }<br /> return true;<br /> }<br /> // Fail if these preconditions are not met. <br /> // Bridge must be running,<br /> // The menu must not already exist.<br /> $.writeln("ERROR:: Cannot run AutomaticStackingFiles");<br /> $.writeln(this.requiredContext);<br /> return false;<br />}<br /><br />if(typeof(AutomaticStackingFiles_unitTest) == "undefined") {<br /> new AutomaticStackingFiles().run();<br />}<br /><br />--= end of 'autostack.jsx' file =--
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 21, 2021 Apr 21, 2021

Hi @T_dimitry,

 

Do you still have this code formatted in a document?  I'm trying to format paste in a document I can put in the presets folder.

 

Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 18, 2008 Nov 18, 2008
Hello Dmitry,
I've copied and saved your script but it doesn't seem to work... there are some issues with closing parenthesis, and a variable it doesn't recognise (currSort).
Any chance you can have a look at it because if it works, you will be doing me an enormous favour.
David
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 18, 2008 Nov 18, 2008
Hello again Dmitry,
I managed to get the script working myself, and it works brilliantly. Thank you very much - you've solve a workflow problem that has been bugging me for several years.
Best
David Peart
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 30, 2008 Nov 30, 2008
Thanks!

Good Luck.
______
My Si tes
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 15, 2008 Dec 15, 2008
Hello, David.

Please, can you post changes which you do, or send it to my email.
thx.
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 12, 2009 Jan 12, 2009
Version with some changes.<br />Try fix some bug.<br />Try increase speed.<br /><br />If you found some bug or make changes or fix, please post it to this forum.<br /><br />-== [start of script] ==--<br /><br />///////////////////<br />/// Name: Auto stacking files<br />/// Description: This script enable auto stacking files by name<br />/// Author: Tyzhnenko Dmitry<br />/// E-mail: t.dmitry@gmail.com<br />/// Version: 0.32<br />///////////////////<br /><br />/*<br />@@@START_XML@@@<br /><?xml version="1.0" encoding="UTF-8"?><br /><ScriptInfo xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en_US"><br /> <dc:title>Auto stacking files</dc:title><br /> <dc:description>This script enable auto stacing files by name function</dc:description><br /></ScriptInfo><br />@@@END_XML@@@<br />*/<br /><br />function AutomaticStackingFiles()<br />{<br /> /**<br /> The context in which this snippet can run; Bridge must be running.<br /> @type String<br /> */<br /> this.requiredContext = "\tAdobe Bridge CS3 must be running.\n\tExecute against Bridge CS3 as the Target.\n";<br /> $.level = 1; // Debugging level<br /> <br /> this.version = "0.32";<br /> this.author = "Tyzhenenko Dmitry";<br /> <br /> /**<br /> The unique identifier for the new menu item command<br /> @type String<br /> */<br /> //this.menuID = "AutoStackFiles"; <br /> this.menuCommandID = "GoAutoStackingFiles";<br /><br />}<br /><br />function RunAutoStacking()<br />{<br /> var doc = app.document;<br /> var thumb = doc.thumbnail;<br /> var vthumb = doc.visibleThumbnails;<br /> var currSort = doc.sorts;<br /> <br /><br /> function StackPhoto()<br /> {<br /> doc.chooseMenuItem('submenu/Stack');<br /> doc.chooseMenuItem('StackGroup');<br /> }<br /><br /> function CollapseStacks()<br /> {<br /> doc.chooseMenuItem('submenu/Stack');<br /> doc.chooseMenuItem('CollapseAllStacks');<br /> }<br /><br /> function getFileExt( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(dot,t.name.length);<br /> }<br /><br /> function getFileName( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(0, dot);<br /> }<br /><br /> CollapseStacks();<br /> <br /> var SortObj = {}; <br /> SortObj.name = "name";<br /> SortObj.type = "string";<br /> SortObj.reverse = false;<br /> var SortsArray = [];<br /> SortsArray.push(SortObj);<br /> doc.sorts = SortsArray;<br /><br /> for (var len = 0; len < vthumb.length; len++ )<br /> {<br /> doc.deselectAll();<br /> doc.select(vthumb[len]);<br /> doc.reveal(vthumb[len]);<br /> for ( var k = len+1; k < vthumb.length; k++ )<br /> {<br /> //alert(k);<br /> if ( getFileName( vthumb[len] ) == getFileName( vthumb) ) <br /> doc.select(vthumb);<br /> else <br /> {<br /> if (doc.selectionLength > 1) <br /> StackPhoto();<br /> break;<br /> }<br /> if (k == vthumb.length-1)<br /> {<br /> if (doc.selectionLength > 1)<br /> StackPhoto();<br /> }<br /> <br /> //if (doc.selectionLength > 1) <br /> // StackPhoto();<br /> }<br /> //delete vthumb;<br /> //var <br /> //vthumb = @doc.visibleThumbnails;<br /> }<br /><br /> doc.sorts = currSort;<br /> doc.reveal(doc.visibleThumbnails[0]);<br /><br /> delete currSort;<br /> delete vthumb;<br /> delete thumb;<br /> delete doc;<br /> <br />}<br /><br />AutomaticStackingFiles.prototype.run = function()<br />{<br /> var retval = true;<br /> if(!this.canRun()) {<br /> retval = false; <br /> return retval;<br /> }<br /> //app.document.chooseMenuItem('submenu/Stack');<br /> var AutoStackCommand = new MenuElement("command", "Auto stacking", "at the beginning of submenu/Stack", );<br /> AutoStackCommand.onSelect = function(m)<br /> {<br /> //alert('start');<br /> RunAutoStacking(); <br /> //alert('stop');<br /> }<br />}<br /><br />AutomaticStackingFiles.prototype.canRun = function()<br />{ <br /> // Must run in Bridge <br /> if(BridgeTalk.appName == "bridge") <br /> {<br /> // Stop the menu element from being added again if the snippet has already run<br /> if(MenuElement.find(this.menuCommandID))<br /> {<br /> $.writeln("ERROR:: Menu element from AutoStackFiles already exists!\nRestart Bridge to run this snippet again.");<br /> return false;<br /> }<br /> return true;<br /> }<br /> // Fail if these preconditions are not met. <br /> // Bridge must be running,<br /> // The menu must not already exist.<br /> $.writeln("ERROR:: Cannot run AutomaticStackingFiles");<br /> $.writeln(this.requiredContext);<br /> return false;<br />}<br /><br />if(typeof(AutomaticStackingFiles_unitTest) == "undefined") {<br /> new AutomaticStackingFiles().run();<br />}<br /><br />-== [end of script] ==--
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2009 Jan 13, 2009
I have created project in google code.

All can try get script from this url

http://code.google.com/p/my-abobe-scripting/source/browse/trunk/autostack.jsx
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 19, 2009 Mar 19, 2009
update to 0.35
fix CS4 Bridge bug

Please who can do, test script with CS3 Bridge. I nave't CS3 now :(

http://code.google.com/p/my-abobe-scripting/source/browse/trunk/autostack.jsx
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 22, 2021 Apr 22, 2021

Not sure if this helps or not:

 

// https://forums.adobe.com/thread/738964
#target bridge     
   if( BridgeTalk.appName == "bridge" ) {    
AutoStack = MenuElement.create("command", "Auto Stack", "at the beginning of submenu/Stack", "zx1");  
}  
AutoStack.onSelect = function () {   
   stackEm();  
   }  
function stackEm(){  
app.document.sorts = [{ name:"name",type:"string", reverse:false}];   
var jpgs = Folder(app.document.presentationPath).getFiles ("*.jpg");  
app.document.deselectAll();  
for(var a in jpgs){  
var Name = decodeURI(jpgs[a].name).replace(/\.[^\.]+$/, '');  
var stacks = Folder(app.document.presentationPath).getFiles(Name+".*");  
if(stacks.length < 2) continue;  
for(var z in stacks){ app.document.select(new Thumbnail(stacks[z]));}  
StackFiles();  
app.document.deselectAll();  
}  
function StackFiles(){  
app.document.chooseMenuItem('submenu/Stack');   
app.document.chooseMenuItem('StackGroup');  
    }  
}  
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 22, 2021 Apr 22, 2021
LATEST

A little Googling:

 

my-abobe-scripting

autostack.jsx

 

 

/*
.--------------------------------------------------------------------------.
|    Software: Auto stacking files                                         |
|     Version: 0.35                                                        |
|        Site: http://code.google.com/p/my-abobe-scripting/                |
| Description: This script enable auto stacking files by name              |
| -------------------------------------------------------------------------|
|     Admin: Tyzhnenko Dmitry (project admininistrator)                    |
|   Authors: Tyzhnenko Dmitry t.dmitry@gmail.com                           |
|   Founder: Tyzhnenko Dmitry  (original founder)                          |
| Copyright (c) 2009-2011, Tyzhnenko Dmitry                                |
| -------------------------------------------------------------------------|
|   License: Distributed under the General Public License v3 (GPLv3)       |
|            http://www.gnu.org/licenses/gpl.html                          |
| This program is distributed in the hope that it will be useful - WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    |
| FITNESS FOR A PARTICULAR PURPOSE.                                        |
'--------------------------------------------------------------------------'
*/

/* 
@@@START_XML@@@ 
<?xml version="1.0" encoding="UTF-8"?> 
<ScriptInfo xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en_US"> 
     <dc:title>Auto stacking files</dc:title> 
     <dc:description>This script enable auto stacing files by name function</dc:description> 
</ScriptInfo> 
@@@END_XML@@@ 
*/

function AutomaticStackingFiles() 
{ 
	/** 
	The context in which this snippet can run; Bridge must be running. 
	@type String 
	*/ 
	//this.requiredContext = "\tAdobe Bridge CS4 must be running.\n\tExecute against Bridge CS4 as the Target.\n"; 
	this.requiredContext = "\tAdobe Bridge CS4 must be running.\n\tExecute against Bridge CS4 as the Target.\n"; 
	$.level = 0; // Debugging level 

	this.version = "0.35"; 
	this.author = "Tyzhenenko Dmitry"; 

	/** 
	The unique identifier for the new menu item command 
	@type String 
	*/ 
	//this.menuID = "AutoStackFiles"; 
	this.menuCommandID = "GoAutoStackingFiles"; 

} 

function RunAutoStacking() 
{ 
	var doc = app.document; 
	//var thumb = doc.thumbnail; 
	//var vthumb = doc.visibleThumbnails; 
	var currSort = doc.sorts; 

	$.writeln("Start stacking");

	function StackPhoto() 
	{ 
		doc.chooseMenuItem('submenu/Stack'); 
		doc.chooseMenuItem('StackGroup'); 
	} 

	function CollapseStacks() 
	{ 
		doc.chooseMenuItem('submenu/Stack'); 
		doc.chooseMenuItem('CollapseAllStacks'); 
	} 

	function getFileExt( t) 
	{ 
		var dot = t.name.lastIndexOf ('.'); 
		return t.name.substr(dot,t.name.length); 
	} 

	function getFileName( t) 
	{ 
		var dot = t.name.lastIndexOf ('.'); 
		return t.name.substr(0, dot); 
	} 

	

	var SortObj = {}; 
	SortObj.name = "name"; 
	SortObj.type = "string"; 
	SortObj.reverse = false; 
	var SortsArray = []; 
	SortsArray.push(SortObj); 
	doc.sorts = SortsArray; 

	var iteration = 0 
	var stop = false;
	while (true)
	{
		$.writeln("= ");
		$.writeln("= While iteration  - "+ iteration.toString());
		if (stop) 
		{
			$.writeln("!!! Need to stop WHILE");
			break;
		}
		var vthumbs = doc.visibleThumbnails;
		$.writeln("= Total thumbs - " + doc.visibleThumbnails.length.toString());

		for ( i in vthumbs)
		{
			CollapseStacks(); 
			doc.deselectAll(); 
			doc.reveal(vthumbs[i]);
			if ( vthumbs.length == parseInt(i)+1)
			{
				$.writeln("!!! LAST iteration");
				stop = true;
				break;
			}
			$.writeln("== First name - " + vthumbs[i].name);
			$.writeln("== Next name - " + vthumbs[parseInt(i)+1].name);		
			$.writeln("== Last name - " + vthumbs[vthumbs.length-1].name);
			$.writeln("==");
			if ( getFileName( vthumbs[i] ) == getFileName( vthumbs[parseInt(i)+1]) ) 
			{
				doc.select(vthumbs[i]);
				$.writeln("=== Add to select - " + vthumbs[i].name);
				doc.select(vthumbs[parseInt(i)+1]);
				$.writeln("=== Add to select - " + vthumbs[parseInt(i)+1].name);		
				$.writeln("=== Stacking");
				StackPhoto(); 
				break;
			}
		}
		iteration++;
	}
	doc.sorts = currSort; 
	CollapseStacks(); 
	delete currSort; 
	delete vthumb; 
	delete thumb; 
	delete doc; 
	$.writeln("Finish stacking");
} 

AutomaticStackingFiles.prototype.run = function() 
{ 
	var retval = true; 
	if(!this.canRun()) { 
		retval = false; 
		return retval; 
	} 
	//app.document.chooseMenuItem('submenu/Stack'); 
	var AutoStackCommand = new MenuElement("command", "Auto stacking", "at the beginning of submenu/Stack"); 
	AutoStackCommand.onSelect = function(m) 
	{ 
		//alert('start'); 
		RunAutoStacking(); 
		//alert('stop'); 
	} 
} 

AutomaticStackingFiles.prototype.canRun = function() 
{ 
	// Must run in Bridge 
	if(BridgeTalk.appName == "bridge") 
	{ 
		// Stop the menu element from being added again if the snippet has already run 
		if(MenuElement.find(this.menuCommandID)) 
		{ 
			$.writeln("ERROR:: Menu element from AutoStackFiles already exists!\nRestart Bridge to run this snippet again."); 
			return false; 
		} 
	return true; 
	} 
	// Fail if these preconditions are not met. 
	// Bridge must be running, 
	// The menu must not already exist. 
	$.writeln("ERROR:: Cannot run AutomaticStackingFiles"); 
	$.writeln(this.requiredContext); 
	return false; 
} 

if(typeof(AutomaticStackingFiles_unitTest) == "undefined") { 
    new AutomaticStackingFiles().run(); 
}

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines