Quantcast
Channel: Adobe Community : Popular Discussions - After Effects SDK
Viewing all 73444 articles
Browse latest View live

Unclear handling of sequence data

$
0
0

Hi guys,

 

here I have yet another bunch of questions in regard to the handling of sequence data.

I have checked and compared all of the examples from the SDK in various versions, and all of them seem to do things differently, and the SDK documentation does not really shed any way on what is the expected or correct behaviour.

This applies especially to disposing and copying sequence data pointers, which can result in big problems concerning data leaks or access violations if done incorrectly, I suppose.

 

I tried to code a simple example that uses a very simple SequenceData (a struct only containing one int, see below), so I won't have to cope with flattening/unflattening.

In the snippet below, I implemented SequenceSetup(), SequenceSetdown() and SequenceResetup() and marked 6 parts with questions where the documentation and/or implementation in the examples is inconsistent.

 

It would be great if anyone with more insight could give some reliable answers on what you are expected to do there. :-)

 

Thanks,

Toby

 

struct SequenceData
{    int param;
};

static PF_Err SequenceSetup(PF_InData* in_data, PF_OutData* out_data)
{
    AEGP_SuiteHandler suites(in_data->pica_basicP);    // Q1: Are we allowed (or required) to delete the input sequence data if it exists ???    if (in_data->sequence_data)        suites.HandleSuite1()->host_dispose_handle(in_data->sequence_data);    // Q2: Are we allowed (or required) to delete the output sequence data if it exists ???    if (out_data->sequence_data)        suites.HandleSuite1()->host_dispose_handle(out_data->sequence_data);    PF_Handle outH = suites.HandleSuite1()->host_new_handle(sizeof(SequenceData));    if (!outH) return PF_Err_OUT_OF_MEMORY;    SequenceData* outP = static_cast<SequenceData*>(suites.HandleSuite1()->host_lock_handle(outH));    if (outP)    {        AEFX_CLR_STRUCT(*outP);        outP->param = 0;        out_data->sequence_data = outH;        // Q3: Do we really NOT have to set flat_sdata_size ???        // (according to the spec, it is unused, but still some samples set it)        out_data->flat_sdata_size = sizeof(SequenceData);        suites.HandleSuite1()->host_unlock_handle(outH);    }    if (!out_data->sequence_data) return PF_Err_INTERNAL_STRUCT_DAMAGED;    return PF_Err_NONE;
}

static PF_Err SequenceSetdown(PF_InData* in_data, PF_OutData* out_data)
{
    AEGP_SuiteHandler suites(in_data->pica_basicP);    if (in_data->sequence_data)        suites.HandleSuite1()->host_dispose_handle(in_data->sequence_data);    // Q4: Are we required to set both in_data and out_data sequence_data pointers to NULL ???    in_data->sequence_data = NULL;    out_data->sequence_data = NULL;    return PF_Err_NONE;
}

static PF_Err SequenceResetup(PF_InData* in_data, PF_OutData* out_data)
{
    AEGP_SuiteHandler suites(in_data->pica_basicP);    PF_Handle outH = suites.HandleSuite1()->host_new_handle(sizeof(SequenceData));    if (!outH) return PF_Err_OUT_OF_MEMORY;    SequenceData* outP = static_cast<SequenceData*>(suites.HandleSuite1()->host_lock_handle(outH));    if (outP)    {        AEFX_CLR_STRUCT(*outP);        if (in_data->sequence_data)        {            SequenceData* inP = static_cast<SequenceData*>(DH(in_data->sequence_data));            if (inP)            {                outP->param = inP->param;            }            // Q5: Are we allowed (or required) to delete the input sequence data if it exists ???            suites.HandleSuite1()->host_dispose_handle(in_data->sequence_data);        }        // Q6: Are we allowed (or required) to delete the output sequence data if it exists ???        if (out_data->sequence_data) suites.HandleSuite1()->host_dispose_handle(out_data->sequence_data);        out_data->sequence_data = outH;        suites.HandleSuite1()->host_unlock_handle(outH);    }    if (!out_data->sequence_data) return PF_Err_INTERNAL_STRUCT_DAMAGED;    return PF_Err_NONE;
}

Force re-render in Premiere

$
0
0

Hi, is there any way to force re-rendering in Premiere Pro? I've read that this can be done by calling AEGP_SetStreamValue in After Effects. But AEGP is stated to be unavailable in Premiere Pro, what can be the approach here?

It looks to be possible because the built-in Warp Stabilizer displays "analyzing" message over video and then successfully hides it.


Thanks,

Roman

Bezier curve conversion between value graph and speed graph

$
0
0

Hello everyone,

 

I have a question about the formula for graph conversion between value graph and speed graph on Graph Editor. Especially, when those graphs are Bezier Curves.

 

On the value graph you can define the Bezier curve by moving the control points oht x and y axises, which position can be gotten as spacial tangent values by the AE SDK. On the other hand, on the speed graph you can define the curve by moving the control points only on x axis and these are defiend by these two values "speed" and "influence". (please refer the defenition of AEGP_KeyframeEase). I guess, the speed graph is differentail of value graph mathematically, and I would like to know how those two bezier curves are converted each other. especially, given two control points on speed graph, how do you get the two control points on value graph?

 

スクリーンショット-2013-12-19-1.21.14.jpg

 

The reason why I am trying to figure out this formula is that there is only Speed Graph for path animation on Graph editor. As you can see below, even if Value Graph is selected the editor shows us Speed graph, which is I guess because the unit of this variation is not a simple unit something like pixel or seconds.

スクリーンショット 2013-12-19 0.53.59.png

 

I know it is not a question about the functions of AE, but more like about mathematics. However, I would really appreciate if someone can shed some light on here or refer me some good website that I can research.

 

Thanks!

Remove Cinema 4D Plugin

$
0
0

I'm trying to slim down the After Effects install for my render farm. The After Effects install is 2.5 GB and 721 MB of that is the Cinema 4D plugin. I tried deleting the plugin but After Effects refuses to start if the plugin doesn't exist even though it's not in the "Required" directory.

 

Is it possible to remove the Cinema 4D plugin from After Effects?

 

I tried fooling AE by compiling my own empty plugin named "Cineware_AE_Effect.aex" but I probably have the PiPL values incorrect.

 

Anyone have ideas?

 

Thanks!

Rob

Release configuration in SDK XCode examples

$
0
0

Hello,

 

All XCode projects from SDK examples have only one build configuration - Debug. What is the reason? How to add Release configuration properly? Do we need this configuration or it's ok to use Debug for production plugin? I even didn't find "_DEBUG" preprocessor macro in the Debug configuration properties...

 

 

Thanks!

Saving Data in Project for AEGP Plugin

$
0
0

Hi,

 

Is there anyway of saving custom data into project file while saving the Project for AEGP Plugin?

 

Thanks in Advace,

Suma

Creating an ACV file for Color Correction

$
0
0

Hello,

 

So I've been trying to perform automated color correction, and found that AE can read ACV files and apply them to a layer. By ACV I mean the Adobe Curve files. I have an external module performing the color correction within the CIE Lab space, that essentially outputs a vector for an input color that points to the color it is transformed to.

 

Now to get this into AE, I need to be able to store the transform in an ACV file so that AE can read it. Here's the best of what I could find on the internet:

 

http://www.lessthanthree.com/?p=5

 

Now I don't completely understand that. Could someone please elaborate on how I can write to an ACV file if I have a set of vectors that point from a source color to a destination color?

 

That would be a huge help.

 

Thanks,

Chirag

Detect parenting event

$
0
0

Hi!

 

Is there a way to detect when user sets parenting on a layer?

PF_Event   may be?

 

Thanx,

François


Is it possible to create Qt Widgets inside After Effects using the SDK?

$
0
0

Hi,

 

I would like to use Qt to create Dialogs and Widgets inside AfterEffects.

 

I started out with the Panelator example in the SDK. I can include QtGui into the project, but as soon as I create any object with QObject as a base-class After Effects crashes immediately with the following error: '[...] could not be loaded (48::46)'

When I try delay load QtCore.dll and QtGui.dll I can at least start the plugin and see, that the crash happens in the initializer of the QObject.

 

I use

VS 2010

QT 4.8.5

and my buildenvironment is x64

 

I was wondering if there is any kind of incompatibility of embedding Qt in After Effects (due to linker/compiler setting or defines or something like this).

 

This is the debugger output:

 

Locals:

locals.PNG

 

Threads:

threads1.PNG

My code in the Panel-constructor function:

 

    int argc = 0;

    char *argv[1] = {""};

 

 

    QApplication* a = new QApplication(argc, argv); // THE ERROR OCCURS IN THIS LINE. for a test I exchanged it to QWidget* w = new QWidget(); and it happens as well.

    QWidget* w = new QWidget();

    w->show();

    a->exec();

 

Outside of AfterFX Qt works fine and I also can delay-load QtGui and QtCore.

 

If anyone of you already has experience in using QT in AfterEffects, I would really appreciate your help!

 

Thanks in advance.

GLator for dummies (and from dummy...)

$
0
0

Hi every one!

 

I open this post to summarize what I've been grabing here and there about the GLator sample. It's been discussed a lot already, but it still drives a lot of people nuts!

If you have any usefull info about it, please share! And may be one day we'll all have a proper OpenGL structure to work with...

 

Finally, here is a complete working version of GLator:

 

So let's take it point by point:

 

First of all, one shoud start from the CC example as it's more stable. If you build for lower versions and some suites are not available, just change the suites number.

 

For simplicity's sake, I have (and probably will) edited this post.

 

 

1_Window / context:

 

The GLator example doesn't set context's size, and it crashes when the size of the picture is over 1024x1024, when user purge the cache...

To solve this, one has to remove the AESDK_OpenGL_InitResources() function from GlobalSetup(), and paste it in Render() call. Now in render call, one can set width and height like this:

 

First use SetPluginContext()

 

Then

 

if( (error_desc = AESDK_OpenGL_InitResources(S_GLator_EffectCommonData, Width, Height)) != AESDK_OpenGL_OK)

  {

  PF_SPRINTF(out_data->return_msg, ReportError(error_desc).c_str());

  CHECK(PF_Err_INTERNAL_STRUCT_DAMAGED);

  }

 

Then, all the functions using S_GLator_EffectCommonData.mRenderBufferWidthSu and S_GLator_EffectCommonData.mRenderBufferHeightSu should be replaced by width and height.

 

And then switch back to AE with SetHostContext()

 

EDIT: once the context has been switched back to AE, I used to delete the plugin context and window like so (windows code):

wglDeleteContext( S_GLator_EffectCommonData.mHRC );

DestroyWindow( S_GLator_EffectCommonData.mHWnd);

 

It's working in CS5 and CS5.5, but mess everything up starting from CS6! So let opengl do the cleaning...

 

IMPORTANT EDIT: what's written above does work, but something important is missing: the use of AESDK_OpenGL_Startup() and AESDK_OpenGL_Shutdown()

 

In the sample, AESDK_OpenGL_Startup() is set during GlobalSetup, while AESDK_OpenGL_Shutdown() is called during SequenceSetdown. This is a mistake! One should add a GlobalSetdown function and move the AESDK_OpenGL_Shutdown() from SequenceSetdown to GlobalSetdown. Otherwise, the plugin will seem to work fine, but won't be able to render if a new project is opened. It would work again if you close and re-open AE. The reason is GlobalSetup (and so AESDK_OpenGL_Startup()) will be called only once per AE session, and SequenceSetdown (and so AESDK_OpenGL_Shutdown()) will be called everytime a project is closed.

 

2_AE to OpenGL camera

 

Use the code in the Resizer sample (getting camera matrix) as a base.

 

Then I see 2 options:

 

A_The matrix conversion:

 

You can find more details in this thread (the whole code's a bit long): Help with AE camera matrix >> Opengl Matrix? | Adobe Community

and this one https://forums.adobe.com/thread/1357716

 

convert the output matrix from AEGP_GetLayerToWorldXform() to column-order and serializing it in a float array.

On the OpenGL side, use the following snippet before drawing:

 

Thanks to Tobias Fleischer (reduxFX) for sharing his code:

 

void my_gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)

{

  GLdouble xmin, xmax, ymin, ymax;

 

  ymax = zNear * tan(fovy * 3.14159265358979323 / 360.0);

  ymin = -ymax;

  xmin = ymin * aspect;

  xmax = ymax * aspect;

 

 

  glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);

}


then


{

    ...

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    my_gluPerspective(45.0, (GLdouble)widthL / heightL, 0.1, 1000.0 );

    glViewport(0, 0, (int)(dataP->w[0]), (int)(dataP->h[0]));

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();   

    glClearDepth(1.0f);                           

    glEnable(GL_DEPTH_TEST);                       

    glDepthFunc(GL_LEQUAL);                           

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    dataP->glMatrix[12] -= widthL*0.5f;

    dataP->glMatrix[13] -= heightL*0.5f;

    glLoadMatrixf(dataP->glMatrix);

    ...

}


With this code, we're almost there. I must say I still had troubles to get the proper perspective distortion when I tried to include it in my own OpenGL process. But I'm far from being an opengl expert!

 

So I finally tried to develop my own camera conversion:

 

B_the gluLookAt() option:

 

I grab the camera matrix the same way. Then I define:

 

A_longWidth, Height, FullWidth, FullHeight;

 

Width = outputP->width;
Height = outputP->height;
FullWidth = Width*in_data->downsample_x.den;
FullHeight = Height*in_data->downsample_y.den;

 

//Define th Fov

float Fov = 2.0 * PF_DEGREE_PER_RAD * atan(FullHeight / (2.0 * camDataD.zoom));

 

  gluPerspective( Fov, (GLdouble)Width / Height, 10.0, 10000.0 );

 

  glViewport( 0, 0, Width, Height);

  glMatrixMode( GL_MODELVIEW );

  glLoadIdentity();

 

  point3 target;

  float distCam = distance3D(    camDataD.matrix.mat[3][0] - FullWidth*.5,

                                              camDataD.matrix.mat[3][1] - FullHeight*.5,

                                              camDataD.matrix.mat[3][2]);

 

 

  target.x = camDataD.matrix.mat[2][0] * distCam + camDataD.matrix.mat[3][0];

  target.y = camDataD.matrix.mat[2][1] * distCam + camDataD.matrix.mat[3][1];

  target.z = camDataD.matrix.mat[2][2] * distCam + camDataD.matrix.mat[3][2];

 

A_Matrix4invMat = camDataD.matrix;

 

 

ScaleMatrix4(&invMat, 1.0,1.0,-1.0);
invMat = invertMatrix4(invMat);

 

 

point3orientation_vector = {0,1,0};

 

 

orientation_vector.x = invMat.mat[0][1];
orientation_vector.y = invMat.mat[1][1];
orientation_vector.z = invMat.mat[2][1];

 

 

normalize( &orientation_vector);

 

 

gluLookAt(camDataD.matrix.mat[3][0],
camDataD.matrix.mat[3][1],
-camDataD.matrix.mat[3][2],
target.x,
target.y,
-target.z,
orientation_vector.x,
orientation_vector.y,

orientation_vector.z);


If like me you're more used to AE than OpenGL, then this method is more intuitive. The lookAt function acts just like an after effects camera, showing a world using the same coordinates than AE world. Then grabing lights or other layers becomes "easy" as developping can be...

 

This part caused me the biggest headaches, so if you want to use it, you owe me a beer!

 

 

 

3_Using GLator to render polygons.

 

I've tried rendering polygons and hit a wall: antialiasing. Though you can still use glEnable(GL_LINE_SMOOTH); for antialiased lines, GL_POLYGON_SMOOTH is now deprecated. It means antialiasing has to be done another way. I couldn't figure it out, but see 2 options: MultiSampling, or post-process AA through Shader. If someone successfully used MultiSampling, I'm curious to see how.

 

EDIT: another option is superSampling (write to a bigger buffer, and resize it to layer's size). Though it's a bit of an overkill, openGL speed makes it a not so bad option...

 

4_Using Shaders:

 

In the sample, in order to use Shaders, one has to define

#define USE_SHADERS 1

I personnally took the option to add a checkbox parameter and embed the shader functions in a "if (params[USE_SHADER]->u.bd.value) {}" statement.

 

To use the shaders properly, one should replace "GL_TEXTURE_2D" by "GL_TEXTURE_RECTANGLE_ARB", and in the Shaders, "sampler2D" by "sampler2DRect" and "texture2D" by "texture2DRect".

This tip comes from Gutsblow in this thread: GLator Quirks..Help needed!

 

Anyway, I must say, though the shaders compile fine and are actually used by my plugin, I can't see it act on the final render... I probably set the functions in a wrong place, so any help will be appreciated...

 

Edit: in fact, the shaders work just fine! My knowledge of shaders was too close to the ground to see it was actually working...

 

Actually, the "GL_TEXTURE_2D" to "GL_TEXTURE_RECTANGLE_ARB" switch is not only for shaders and should be done anyway to avoid troubles.

 

 

5_Red and Alpha channels swap

 

When using OpenGL colors, Red and Alpha channels will be swapped.

One shoud use glReadPixels() with GL_ABGR_EXT instead of GL_RGBA, only colors will be swapped, and alpha operations (blending and so on...) will be OK. If you swap the BLUE/RED colors before rendering, it should work without losing speed.


This depends on what you ask OpenGL to render: textures or polygons.



I write this post as answered, but if any of you have any tip to share and make it better / stronger, please share!


Cheers,

François

resize the output

$
0
0

I want to change the size of output buffer. So I need to put my code in Frame_Setup according to the "Resizer" sample project.

What embarassed me is that only after calculation can I get the expected size.But I can't obtain the input image in Frame_Setup.

I don't know how can I solve this problem. I will be grateful if you can give me advice.

 

btw, It's not necessary to calculate the size every time before rendering. What I exactly need is getting input image the first time

I enter Frame_Setup function. Then I can make sure what size is of the output video.

can someone guide for after effects plugin development??

$
0
0

Can someone guide for after effects plugin development??

Its very hard to find directions to do one.

 

Have written some scripts in extended script with support of adobe community and online tutorials.


But i know Plugin development is not easy task but my curiosity kills me if i dont try.Can someone plz guide.

 

I have downloaded SDK CC 2015. There are bunch of examples, template Skelton, AEGP folder.All Visual studio solutions.

When i try to open it, it says project not loaded some installation components are missing, reinstall by turning microsoft visual studio c++ 2015 on.

 

Can someone just share a very small step by step brief from start to end.??

 

From Coding to .aex format??

 

thanks

Create Puppet Pin programmatically

$
0
0

Hi all,

 

I'd like to ask whether is it possible to create puppet pins programmatically...

 

I have tried to copy stream structure ("ADBE FreePin3", "ADBE FreePin3 Mesh", "ADBE FreePin3 PosPin Position", ...) of manually created pins with

corresponding values, but when I create streams this way they are disabled (AEGP_DynStreamFlag_DISABLED - and greyed out in UI).

 

I suppose that the vertex index "ADBE FreePin3 PosPin Vtx Index" is just an index to the array stored internally as arbitrary data so the mesh and pins must be created somehow before setting these values.

 

I've found this thread where they try to do the same thing using scripting (also without success  )Create Puppet Pin on existing mesh via scripting

 

I have some ideas about how this could be done using SDK, but all of them involve diving in very dark waters..

- call the EffectSuite::AEGP_EffectCallGeneric method with fake mouse click events (PF_Cmd_EVENT) or some direct PF_Cmd_COMPLETELY_GENERAL commands if the FreePin effect supports it

- use "FreePin Suite" - which is not a part of public SDK but can be aquired using AquireSuite... - but as it's not public I suppose it operates with memory which is not so safe to touch even if I managed to get/create proper header file for this suite

 

Maybe there is a simple elegant way of creating these pins which I completely overlooked, so I would be really thankful for any suggestions

 

Thanks a lot!

 

Martin

Training on developing plugins for after effects

$
0
0

We need training, a couple of days,on the development of plugins for after effects. The company is in Paris.
Does Adobe provides pluginsdevelopment trainingforafter effects ?

C-plus-plus-ifying Your Plugins

$
0
0

I was wondering how many folks round these parts use C++, as opposed to C to write their plugins.

 

The SDK doesn't really encourage C++ coding, as much of the example projects are still mostly C, with the odd bit using C++ (like acquiring suites; although there's a new way to do this, as I've just posted about here: Using the new AEFX_SuiteScoper Template Class ).

 

After seeing just how much code repetition you can avoid (the arbitrary parameter handler was a big eye-opener for me), I've recently begun to rewrite bits of my new plugin using classes.

 

In particular I've written a parameter checkout class that goes from (as an extreme example):

 

     PF_ParamDef my_param;

     AEFX_CLR_STRUCT(my_param);

 

     ERR(PF_CHECKOUT_PARAM(in_data, MY_PARAM, in_data->current_time, in_data->time_step, in_data->time_scale, &my_param));

 

     PF_AngleParamSuite1 *apsP = NULL;

     ERR(AEFX_AcquireSuite(in_data, out_data, kPFAngleParamSuite, kPFAngleParamSuiteVersion1, "Couldn't load suite", (void**)&apsP));

 

     PF_FpLong angleF;

     ERR(apsP->PF_GetFloatingPointValueFromPointDef(in_data->effect_ref, &my_param, &angleF));

 

     ERR2(AEFX_ReleaseSuite(in_data, out_data, kPFAngleParamSuite, kPFAngleParamSuiteVersion1, "Couldn't release suite"));

 

     ERR2(PF_CHECKIN_PARAM(in_data, &my_param));

 

To:

 

     // This stores the pointer to in_data, and acquires pointers to the param suites - pass into all ParamHandler objects

     ParamContext param_ctx(in_data);

 

     ParamHandler my_param(param_ctx, MY_PARAM);

 

     PF_FpLong angleF = my_param.AngleValue();

    

     // No need to release anything as it's done in the class destructors

 

I'd be interested in hearing about your approaches to C++ifying things like this, and your general approach to coding.


New After Effects CC 2017 plug-in SDK is live

FXAA

$
0
0

Hi. I've drawn a curved line but it's very jagged and don't know how to smooth it. Does anyone know if it's possible to implement FXAA or a similar method?

 

I've considered drawing my line at a much higher res and then downscaling, but I think FXAA would be more efficient. Thanks!Screen Shot 2017-03-05 at 2.42.05 am.png

AEIO_InitOutputSpec

$
0
0

I am trying to write an output plugin based on the FBIO example and I am confused about how to set the proper output options.  When the sample code initializes the output spec it uses a pseudo file header and sets the size of the options handle to the size of this pseudo file header structure.  Are the fields of this header also a definition of what is necessary for a proper output spec?  Do I set them only by using the AEGPIOOutSuit4 functions?  The sample code also seems to treat this information as options which are just for this output format and stored separately from the spec in a "disk-safe copy of your options data."

 

I gather AEIO plugins distinguish between "user data" to be embedded in the file (what I would call the file header) and "options" which are information about the file, such as dimensions, compression, etc.  If these are options which can be set when a specific file is written, surely they are also embedded in the file header so that it can be read properly.

 

I'm obviously not getting something and would appreciate any pointers as to what to read or where to look at more sample code.

 

Thanks.

Output Width and Height in Iterate Float

$
0
0

I am trying to write an effect that needs to process an entire frame at once. (I want to replace all the pixels with the average pixel value in the frame.)  I tried setting the area rectangle for the Iterate function to be the entire frame, but when it does the iteration it thinks the output width and height are greater than the actual frame.  The comp is set to 1024 x 768 (from a source image which is 2048 x 1556), but the output width and height in the function call are 1230 x 924.  Where are these numbers coming from?  My effect crashes (it gets an exception error while iterating) and I assume it is because it is trying to write beyond the memory bounds for the output frame.

 

I am using the latest version of After Effects on a Mac with Xcode 9 and my plug-in is based on the Smarty Pants example.  I did change the iterate_origin to just the iterate function since I want to get the entire frame at once.

 

Is there a better way to do this?  I need to read the entire frame to get the average value and then make a second pass to write the average value to each pixel. Perhaps I should just use the fill_float function instead, but I'd like to know why the plug-in thinks my height and width greater than the comp height and width.

there is not release build option on CS6 sample plugins.

$
0
0

Hi, everyone!.

 

I have strange problem with CS6 sample plugins.

I cannot see release build option on vs 2015. there is only debug option.

How can I compile release version?

 

 

Regards,

Igor.

Viewing all 73444 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>