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

bulk action solution needed

Community Beginner ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

Does anyone know a way to bulk stack pairs of photos (raw and edited jpeg) so they can be auto aligned and then blended via opacity change in one? Prefer adobe based platform but don't think it's possible.

Was ideally looking at doing this from LR to PS, but honestly don't care how it's done. Pretty simple but only know how to do this for one pair of photos at a time. 

 

TOPICS
Actions and scripting , Windows

Views

1.7K

Translate

Translate

Report

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

correct answers 1 Correct answer

Community Expert , Jul 16, 2024 Jul 16, 2024

@jonathanb67250519 

 

You can try this first draft script. It's mostly there and should only require cosmetic tweaking, such as removing the manual save folder selection step if you want to save the merged files to the TIFF input folder or automatically create a new merged output folder alongside or within the TIFF input folder.

 

Notes:

* Saves a layered TIFF file, change the boolean from true to false to save a flattened TIFF file  [line 71]

* Layer opacity at 40%  [line 108]

* Optional featur

...

Votes

Translate

Translate
Adobe
Community Expert ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

Please provide sample images or at least meaningful screenshots to illustrate the process, the imagery, the file structure and the naming convention. 

 

It sounds like a case for Photoshop Scripting; several Scripts have been posted about combining X images. 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

@jonathanb67250519 

 

I have a couple of generic batch scripts posted here:

 

 
The scripts are designed to fast-track the development of custom scripts, as they perform the basic processing. These versions don't auto-align, they expect that the files are the same size and that the content is aligned. The script assumes alphabetically sorting file pairs from a single folder or top-level folder + sub-folders. It's also possible to select 2 different source folders. It's hard to make a generic script cover all workflows, however, I am happy to change things as needed if you can't adapt your workflow to the script.
 
You will first need to use Lr or ACR to batch render the raw files to an appropriate format such as TIFF or PSD.
 
The script can call an action, so if you find it easier to do the processing of the two stacked layers via an action then you don't need to know how to script those steps.
 
I did look at auto-align in this script:
 
 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

I wonder, though, to what end one would need to align the RAW and the jpg – which makes me wonder whether I understood the OP’s intended process. 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

I shoot in raw, multiple brackets. Want to blend in the base ambient bracket (can be saved as a different file with a basic preset) into an edit from outsourcing. Helps with producing a consistent product, with natural ambient light/shadows/etc  to an otherwise commonly produced and over rendered style. Cost and time is major players in why this would be needed

 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

quote

I shoot in raw, multiple brackets. Want to blend in the base ambient bracket (can be saved as a different file with a basic preset) into an edit from outsourcing. Helps with producing a consistent product, with natural ambient light/shadows/etc  to an otherwise commonly produced and over rendered style. Cost and time is major players in why this would be needed

 


By @jonathanb67250519

Strange, didn’t get a notification about the posts on this thread … Forum on the fritz again? 

 

@jonathanb67250519 , I don’t quite follow your description. 

Why align degraded, edited images to the original processed raw images? (»degraded« referring to the jpgs’ lossy compression.)

 

Please post screenshots to unequivocally clarify the file structure and the naming convention. 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

quote

I wonder, though, to what end one would need to align the RAW and the jpg – which makes me wonder whether I understood the OP’s intended process. 


By @c.pfaffenbichler


Yes, good point! My expectation is that they would match in document pixel dimensions and content wouldn't need alignment as this would naturally be the case.

 

2 or 3 sample file pairs and real examples of the naming is always helpful.

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

edits have alignment adjustments so the auto align fixes this prior to the blending of the two images. after blend, overlap is cropped

 

 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

find examples of a dng and jpg. Tried to add the blended PSD but it's too large so I uploaded the final blend (as a jpg). It's simply aligned and the raw is blended in typically 30-40% (from opacity adjustment) to help bring in natural light to edit.

Not the perfect photo for axample purposes, but blend helps for a more naturalistic window view and the addition of some of the original ambient light/shadows/highlights.

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

system won't allow me to upload dng or nef file, something about it fil extension not matching file type.

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

As previously mentioned, I would need the raw files rendered to PSD or TIFF etc. I can do that for my tests from your samples.

 

What is a real example of the raw filename and the JPEG filename?

 

EDIT: Looking at your layered example –

 

2024-07-16_23-21-24 (1).png

 

There is no correlation in the naming of the raw and JPEG file.

 

How would an automated solution know which files to pair?

 

If the raw and JPEG files were in two separate folders and the first, second, third etc. alphabetical sorting file in each folder matched the order in the other folder, that would be workable for automation.

 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

I can change the jpg and raw (which will be saves as a Tiff) names to whatever is easiest for the script.

 

Typically I name the houses with letters A,B,C,D depending on how many homes are shot each day. That said, if it's best for them all to be A and I manually sort later that's fine, whatever is easiest. 

 

They are typically kept in different folders, but can be combined into one if best for a script. Folder names can be names for whatever is best of the script. 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

To keep it simple lets just go with file name A, so A-1.jpg and A-1.tiff from two different folders.

Tiff file would be top layer.

After the auto align and blend of 30% via opacity change, I save as so it imports back into LR as a new tiff file. 

That should help with clarification, if not, let me know. 

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

quote

To keep it simple lets just go with file name A, so A-1.jpg and A-1.tiff from two different folders.

Tiff file would be top layer.

After the auto align and blend of 30% via opacity change, I save as so it imports back into LR as a new tiff file. 

That should help with clarification, if not, let me know. 


By @jonathanb67250519

 

OK, that is workable... What settings would you use for Edit > Auto-Align Layers...

 

I tested Auto and the result wasn't the same as per your PSD example.

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

hopefully that action helped clarify the auto align step, if not, let me know. thanks

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

The action download has been deleted, however, if you say that you use the Auto setting then that is all I need to know, a screenshot would suffice if that is the only thing that you do to auto-align the two layers.

Votes

Translate

Translate

Report

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 ,
Jul 17, 2024 Jul 17, 2024

Copy link to clipboard

Copied

see auto align here

Votes

Translate

Translate

Report

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
LEGEND ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

Why not just use an HDR feature for blending? And I don't get why you would blend an edited and unedited shot.

I just use adjustment layers with masking and am able to get pretty much any effect. Its rare that I blend multiple exposures unless I'm doing a panorama.

Votes

Translate

Translate

Report

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 ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

@jonathanb67250519 

 

You can try this first draft script. It's mostly there and should only require cosmetic tweaking, such as removing the manual save folder selection step if you want to save the merged files to the TIFF input folder or automatically create a new merged output folder alongside or within the TIFF input folder.

 

Notes:

* Saves a layered TIFF file, change the boolean from true to false to save a flattened TIFF file  [line 71]

* Layer opacity at 40%  [line 108]

* Optional feature to crop to transparency, remove the leading double-forward slash // comments to enable  [line 111]

* Adds a '_Merged' filename suffix to the saved TIFF file, you could change this name or remove the content inside the single quotes ''  [line 112]

 

I'm happy to make other modifications if required.

 

/*
Stack and Blend 2 Input Folder Files to TIFF.jsx
v1.0, 17th July 2024 - Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/bulk-action-solution-needed/td-p/14741490
*/

#target photoshop

    (function () {

        if (app.documents.length === 0) {

            try {

                // JPEG Input folder
                var folder1 = Folder.selectDialog("Select the JPEG image folder:");
                if (folder1 === null) {
                    alert('Script cancelled!');
                    return;
                }

                // TIFF Input folder
                var folder2 = Folder.selectDialog("Select the TIFF image folder:");
                if (folder2 === null) {
                    alert('Script cancelled!');
                    return;
                }

                // Validate input folder selection
                var validateInputDir = (folder1.fsName === folder2.fsName);
                if (validateInputDir === true) {
                    alert("Script cancelled as both the input folders are the same!");
                    return;
                }

                // Limit the file input to jpg/jpeg
                var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
                var list2 = folder2.getFiles(/\.(tif|tiff)$/i);

                // Alpha-numeric sort
                list1.sort();
                list2.sort();

                // Validate that folder 1 & 2 lists are not empty 
                var validateEmptyList = (list1.length > 0 && list2.length > 0);
                if (validateEmptyList === false) {
                    alert("Script cancelled as one of the input folders is empty!");
                    return;
                }

                // Validate that the item count in folder 1 & 2 matches
                var validateListLength = (list1.length === list2.length);
                if (validateListLength === false) {
                    alert("Script cancelled as the input folders don't have equal quantities of images!");
                    return;
                }

                // Output folder
                var saveFolder = Folder.selectDialog("Please select the folder to save to...");

                // Save and set the dialog display settings
                var savedDisplayDialogs = app.displayDialogs;
                app.displayDialogs = DialogModes.NO;

                // TIFF save options
                var tiffSaveOptions = new TiffSaveOptions();
                tiffSaveOptions.imageCompression = TIFFEncoding.NONE; // TIFFLZW | TIFFZIP | JPEG
                tiffSaveOptions.embedColorProfile = true;
                tiffSaveOptions.byteOrder = ByteOrder.IBM;
                tiffSaveOptions.transparency = true;
                tiffSaveOptions.layers = true;
                tiffSaveOptions.layerCompression = LayerCompression.ZIP;
                tiffSaveOptions.interleaveChannels = true;
                tiffSaveOptions.alphaChannels = true;
                tiffSaveOptions.annotations = true;
                tiffSaveOptions.spotColors = true;
                tiffSaveOptions.saveImagePyramid = false;

                // Hide the Photoshop panels
                app.togglePalettes();

                // Script running notification window - courtesy of William Campbell
                /* https://www.marspremedia.com/download?asset=adobe-script-tutorial-11.zip
                   https://youtu.be/JXPeLi6uPv4?si=Qx0OVNLAOzDrYPB4 */
                var working;
                working = new Window("palette");
                working.preferredSize = [300, 80];
                working.add("statictext");
                working.t = working.add("statictext");
                working.add("statictext");
                working.display = function (message) {
                    this.t.text = message || "Script running, please wait...";
                    this.show();
                    app.refresh();
                };
                working.display();

                // Set the file processing counter
                var counter = 0;

                // Perform the stacking and saving
                for (var i = 0; i < list1.length; i++) {
                    var doc = open(list1[i]);
                    var docName = doc.name.replace(/\.[^\.]+$/, '');
                    placeFile(list2[i], 100);
                    resetTransforms();
                    app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
                    app.activeDocument.activeLayer.opacity = 40; // Layer opacity
                    selectAllLayers();
                    autoAlign();
                    cropTransparency(); // Optional crop
                    app.activeDocument.saveAs(new File(saveFolder + '/' + docName + '_Merged' + '.tif'), tiffSaveOptions);
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                    counter++; // Increment the counter
                }

                // Ensure Photoshop has focus before closing the running script notification window
                app.bringToFront();
                working.close();

                // End of script notification
                app.displayDialogs = savedDisplayDialogs;
                app.beep();
                alert('Script completed!' + '\r' + counter + ' merged TIFF files saved to:' + '\r' + saveFolder.fsName);

                // Restore the Photoshop panels
                app.togglePalettes();

            } catch (err) {
                while (app.documents.length > 0) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
                alert("Error!" + "\r" + err + ' ' + err.line);
            }

        } else {
            alert('Please close all open documents before running this script!');
        }


        ///// Functions /////

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);
            } catch (e) { }
        }

        function resetTransforms() {
            try {
                var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
            } catch (e) {
                //alert("Error!" + "\r" + e + ' ' + e.line); // Errors in 2019 version
                app.refresh();
            }
        }

        function selectAllLayers() {
            try {
                var c2t = function (s) {
                    return app.charIDToTypeID(s);
                };
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(c2t("null"), reference2);
                executeAction(s2t("selectAllLayers"), descriptor, DialogModes.NO);
                // Add the Background layer if it exists
                reference.putProperty(s2t("layer"), s2t("background"));
                descriptor2.putReference(c2t("null"), reference);
                descriptor2.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
                descriptor2.putBoolean(s2t("makeVisible"), false);
                executeAction(s2t("select"), descriptor2, DialogModes.NO);
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

        function autoAlign() {
            try {
                var desc = new ActionDescriptor();
                var ref = new ActionReference();
                ref.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
                desc.putReference(charIDToTypeID('null'), ref);
                desc.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('ADSt'), stringIDToTypeID('ADSContent'));
                desc.putEnumerated(charIDToTypeID('Aply'), stringIDToTypeID('projection'), charIDToTypeID('Auto'));
                desc.putBoolean(stringIDToTypeID('vignette'), false);
                desc.putBoolean(stringIDToTypeID('radialDistort'), false);
                executeAction(charIDToTypeID('Algn'), desc, DialogModes.NO);
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

        function cropTransparency() {
            try {
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var descriptor3 = new ActionDescriptor();
                var descriptor4 = new ActionDescriptor();
                var descriptor5 = new ActionDescriptor();
                var descriptor6 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                var reference3 = new ActionReference();
                var reference4 = new ActionReference();
                // Dupe layers to temp merged layer
                descriptor.putBoolean(s2t("duplicate"), true);
                executeAction(s2t("mergeLayersNew"), descriptor, DialogModes.NO);
                // Load selection from layer transparency
                reference.putProperty(s2t("channel"), s2t("selection"));
                descriptor2.putReference(s2t("null"), reference);
                reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("transparencyEnum"));
                descriptor2.putReference(s2t("to"), reference2);
                executeAction(s2t("set"), descriptor2, DialogModes.NO);
                // Enter quick mask mode
                reference3.putProperty(s2t("property"), s2t("quickMask"));
                reference3.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                descriptor3.putReference(s2t("null"), reference3);
                // Threshold to 255 levels
                executeAction(s2t("set"), descriptor3, DialogModes.NO);
                descriptor4.putInteger(s2t("level"), 255);
                executeAction(s2t("thresholdClassEvent"), descriptor4, DialogModes.NO);
                // Exit quick mask mode
                reference4.putProperty(s2t("property"), s2t("quickMask"));
                reference4.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                descriptor5.putReference(s2t("null"), reference4);
                // Crop selection
                executeAction(s2t("clearEvent"), descriptor5, DialogModes.NO);
                descriptor6.putBoolean(s2t("delete"), true);
                executeAction(s2t("crop"), descriptor6, DialogModes.NO);
                // Clean up
                app.activeDocument.activeLayer.remove();
                app.activeDocument.selection.deselect();
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

    }());

 

Instructions for saving and use:

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

Votes

Translate

Translate

Report

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 ,
Jul 17, 2024 Jul 17, 2024

Copy link to clipboard

Copied

Awesome, appreciate that very much. Let me give it a shot and see how it does. Should be a huge time saver. 

Votes

Translate

Translate

Report

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 ,
Jul 17, 2024 Jul 17, 2024

Copy link to clipboard

Copied

It works! I never knew an automated process like this was possible, it's a huge time saver. Thank you very much! Now that I know this is possible, will try to think of additional ways to streamline my editing process. 

Votes

Translate

Translate

Report

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 ,
Jul 17, 2024 Jul 17, 2024

Copy link to clipboard

Copied

quote

It works! I never knew an automated process like this was possible, it's a huge time saver. Thank you very much! 


By @jonathanb67250519


You're welcome! Please mark my previous reply with the script code as a correct answer.

Votes

Translate

Translate

Report

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 ,
Jul 23, 2024 Jul 23, 2024

Copy link to clipboard

Copied

After using the script a bit more, some of the blends aren't aligning properly and are blurry. Have tried to trouble shoot to see if there is a specific cause and can't figure it out. Any ideas why this maybe happening? Almost seems random as it maybe a few within a specific set for a house. 

Votes

Translate

Translate

Report

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