Simple Play With Interrupt
This inbound or outbound application sample starts by playing a wav file (long.wav).
Before the play has completed you should interrupt it (using the
rest_interrupt web service).
Once the play action has been interrupted the application is redirected to a page that issues a new play
action to acknowledge the interrupt and say goodbye.
This application requires the wav file long.wav to be available in the cloud media store.
This application requires the wav file long.wav to be available in the cloud media store.
Uses actions: Play
{
"actions" :
[
{
"play" :
{
"play_list" :
[
{
"file_to_play" : "long.wav"
}
]
}
}
],
"token" : "my instance id",
"api_version": "2.0"
}
{
"actions" :
[
{
"play" :
{
"play_list" :
[
{
"text_to_say" : "This call has been interrupted. Goodbye."
}
]
}
}
],
"token" : "my instance id",
"api_version": "2.0"
}
{
[
],
"token" : "Error for Action: xxxx ActionIndex: xxxx Result: xxxx"
}
{
}
Implementing this sample as an ASP.Net Web application:
// CSharp Wrapper sample for the Aculab Telephony REST API.
//
// Simple Play With Interrupt:
// A simple application that plays a long wav file to an answered inbound call.
// It is intended to be interrupted using the rest_interrupt web service.
using System;
using System.Collections.Generic;
using System.IO;
using Aculab.Cloud.RestAPIWrapper;
public partial class SimplePlayWithInterrupt : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(Request);
String callFrom = ourRequest.InstanceInfo.ThisCall.CallFrom;
// Only write out the app instanced id if we haven't yet finished
if (ourRequest.InstanceInfo.ActionResult == null)
{
File.WriteAllText(Path.GetTempPath() + "SimplePlayWithInterrupt.txt", ourRequest.InstanceInfo.ApplicationInstanceId);
}
// Setup the actions
List<TelephonyAction> actions = new List<TelephonyAction>();
Play playAction = Play.PlayFile("long.wav");
actions.Add(playAction);
// Respond
String token = String.Format("my instance id");
TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
ourResponse.ToHttpResponse(Response);
}
}
// CSharp Wrapper sample for the Aculab Telephony REST API.
//
// A page from the Simple Play With Interrupt sample:
// This acknowledges the interrupt to play by saying some text
// before the call is hung up.
using System;
using System.Collections.Generic;
using Aculab.Cloud.RestAPIWrapper;
public partial class AcknowledgeInterrupt : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(Request);
// Get interrupt details from the action result.
string previousAction = ourRequest.InstanceInfo.ActionResult.Action;
bool interrupted = ourRequest.InstanceInfo.ActionResult.Interrupted;
// Setup the actions
List<TelephonyAction> actions = new List<TelephonyAction>();
if (interrupted)
{
Play playAction = Play.SayText("This call has been interrupted. Goodbye.");
actions.Add(playAction);
}
// Respond
TelephonyResponse ourResponse = new TelephonyResponse(actions, "my instance id");
ourResponse.ToHttpResponse(Response);
}
}
using System;
using Aculab.Cloud.RestAPIWrapper;
public partial class ErrorPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(Request);
ErrorResult result = ourRequest.InstanceInfo.ErrorResult;
String token = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}",
result.Action, result.ActionIndex, result.Result);
// Respond
TelephonyResponse ourResponse = new TelephonyResponse(null, token);
ourResponse.ToHttpResponse(Response);
}
}
using System;
using Aculab.Cloud.RestAPIWrapper;
public partial class FinalPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(Request);
}
}
Implementing this sample as an ASP.Net Core Web application:
// ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
//
// Simple Play With Interrupt:
// A simple application that plays a long wav file to an answered inbound call.
// It is intended to be interrupted using the rest_interrupt web service.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Aculab.Cloud.RestAPIWrapper;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
{
[Route("SimplePlayWithInterrupt")]
public class SimplePlayWithInterruptController : ControllerBase
{
// Process the GET or POST request, set up the actions and construct the json response.
[Route("FirstPage")]
[HttpGet]
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> SimplePlayWithInterrupt()
{
try
{
// Unpack the request
var telephonyRequest = await TelephonyRequest.UnpackRequestAsync(Request);
String callFrom = telephonyRequest.InstanceInfo.ThisCall.CallFrom;
// Only write out the app instanced id if we haven't yet finished
if (telephonyRequest.InstanceInfo.ActionResult == null)
{
System.IO.File.WriteAllText(Path.GetTempPath() + "SimplePlayWithInterrupt.txt", telephonyRequest.InstanceInfo.ApplicationInstanceId);
}
// Setup the actions required
List<TelephonyAction> actions = new List<TelephonyAction>();
Play playAction = Play.PlayFile("long.wav");
actions.Add(playAction);
// Create response
String token = String.Format("my instance id");
TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
return new OkObjectResult(ourResponse.ToJson(this));
}
catch (ArgumentException)
{
return BadRequest();
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}
}
}
}
// ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
//
// Simple Play With Interrupt:
// A simple application that plays a long wav file to an answered inbound call.
// It is intended to be interrupted using the rest_interrupt web service.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Aculab.Cloud.RestAPIWrapper;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
{
[Route("SimplePlayWithInterrupt")]
public class SimplePlayWithInterruptController : ControllerBase
{
// Process the GET or POST request, set up the actions and construct the json response.
[Route("AcknowledgeInterrupt")]
[HttpGet]
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> AcknowledgeInterrupt()
{
try
{
// Unpack the request
var telephonyRequest = await TelephonyRequest.UnpackRequestAsync(Request);
// Get interrupt details from the action result.
string previousAction = telephonyRequest.InstanceInfo.ActionResult.Action;
bool interrupted = telephonyRequest.InstanceInfo.ActionResult.Interrupted;
// Setup the actions required
List<TelephonyAction> actions = new List<TelephonyAction>();
if (interrupted)
{
Play playAction = Play.SayText("This call has been interrupted. Goodbye.");
actions.Add(playAction);
}
// Create response
TelephonyResponse ourResponse = new TelephonyResponse(actions, "my instance id");
return new OkObjectResult(ourResponse.ToJson(this));
}
catch (ArgumentException)
{
return BadRequest();
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}
}
}
}
// ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
using System;
using Microsoft.AspNetCore.Mvc;
using Aculab.Cloud.RestAPIWrapper;
using System.Net;
using System.Threading.Tasks;
namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
{
public class RESTSampleController : ControllerBase
{
// Process the GET or POST request for the Error condition
[Route("ErrorPage")]
[HttpGet]
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> ErrorPage()
{
try
{
// Unpack the request
var telephonyRequest = await TelephonyRequest.UnpackRequestAsync(Request);
ErrorResult result = telephonyRequest.InstanceInfo.ErrorResult;
String token = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}",
result.Action, result.ActionIndex, result.Result);
// Create response
TelephonyResponse ourResponse = new TelephonyResponse(null, token);
return new OkObjectResult(ourResponse.ToJson(this));
}
catch (ArgumentException)
{
return BadRequest();
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}
}
}
}
// ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
using System;
using Microsoft.AspNetCore.Mvc;
using Aculab.Cloud.RestAPIWrapper;
using System.Net;
using System.Threading.Tasks;
namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
{
public class RESTSampleController : ControllerBase
{
// Process the GET or POST request for the Final Page
[Route("FinalPage")]
[HttpGet]
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> FinalPage()
{
try
{
// Unpack the request
var telephonyRequest = await TelephonyRequest.UnpackRequestAsync(Request);
String token = telephonyRequest.InstanceInfo.Token;
// Create response
// Only very limited actions can be returned here
TelephonyResponse ourResponse = new TelephonyResponse(null, token);
return new OkObjectResult(ourResponse.ToJson(this));
}
catch (ArgumentException)
{
return BadRequest();
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}
}
}
}
Implemented as an ASP.Net Web App:
' Visual Basic Wrapper sample for the Aculab Telephony REST API.
'
' The first page for the Simple Play With Interrupt sample:
' A simple application that plays a long wav file to an answered inbound call.
' It is intended to be interrupted using the rest_interrupt web service.
Imports System.Collections.Generic
Imports System.IO
Imports Aculab.Cloud.RestAPIWrapper
Partial Class SimplePlayWithInterrupt
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' Unpack the request
Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
Dim callFrom As String = ourRequest.InstanceInfo.ThisCall.CallFrom
' Only write out the app instanced id if we haven't yet finished
If IsNothing(ourRequest.InstanceInfo.ActionResult) Then
File.WriteAllText(Path.GetTempPath() + "SimplePlayWithInterrupt.txt", ourRequest.InstanceInfo.ApplicationInstanceId)
End If
' Setup the actions
Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
Dim playAction As Play = Play.PlayFile("long.wav")
actions.Add(playAction)
' Respond
Dim token As String = String.Format("my instance id")
Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
ourResponse.ToHttpResponse(Response)
End Sub
End Class
' Visual Basic Wrapper sample for the Aculab Telephony REST API.
'
' A page from the Simple Play With Interrupt sample:
' This acknowledges the interrupt to play by saying some text
' before the call is hung up.
Imports System.Collections.Generic
Imports Aculab.Cloud.RestAPIWrapper
Partial Class AcknowledgeInterrupt
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' Unpack the request
Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
' Get interrupt details from the action result.
Dim previousAction As String = ourRequest.InstanceInfo.ActionResult.Action
Dim interrupted As Boolean = ourRequest.InstanceInfo.ActionResult.Interrupted
' Setup the actions
Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
If interrupted Then
Dim playAction As Play = Play.SayText("This call has been interrupted. Goodbye.")
actions.Add(playAction)
End If
' Respond
Dim token As String = String.Format("my instance id")
Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
ourResponse.ToHttpResponse(Response)
End Sub
End Class
' Visual Basic Wrapper sample for the Aculab Telephony REST API.
'
' A generic error page for all the samples.
Imports Aculab.Cloud.RestAPIWrapper
Partial Class ErrorPage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' Unpack the request
Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
Dim result As ErrorResult = ourRequest.InstanceInfo.ErrorResult
Dim token As String = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}", _
result.Action, result.ActionIndex, result.Result)
' Respond
Dim ourResponse As TelephonyResponse = New TelephonyResponse(token)
ourResponse.ToHttpResponse(Response)
End Sub
End Class
' Visual Basic Wrapper sample for the Aculab Telephony REST API.
'
' A generic final page for all the samples:
Imports Aculab.Cloud.RestAPIWrapper
Partial Class FinalPage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' Unpack the request
Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
' Do application tidying up
' ...
End Sub
End Class
Implemented as a Java Servlet:
// Java Servlet sample for the Aculab Telephony REST API.
//
// Simple Play With Interrupt:
// A simple application that plays a long wav file to an answered inbound call.
// It is intended to be interrupted using the rest_interrupt web service.
package com.aculab.telephonyrestapi.samples;
import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import com.aculab.telephonyrestapi.*;
public class SimplePlayWithInterrupt extends HttpServlet
{
private static final long serialVersionUID = 5134039861818805711L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
private void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(request);
String callFrom = ourRequest.getInstanceInfo().getThisCall().getCallFrom();
// Write the application instanced id to file if we haven't yet finished
if (ourRequest.getInstanceInfo().getActionResult() == null)
{
String tempFilePath = System.getProperty("java.io.tmpdir");
String SimplePlayWithInterrupt_filename = tempFilePath + File.separator + "SimplePlayWithInterrupt.txt";
PrintWriter appInstanceFile = new PrintWriter(SimplePlayWithInterrupt_filename);
appInstanceFile.write(ourRequest.getInstanceInfo().getApplicationInstanceId());
appInstanceFile.close();
}
// Setup the actions
List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
Play playAction = Play.playFile("long.wav");
actions.add(playAction);
// Respond
String token = "my instance id";
TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
ourResponse.setHttpServletResponse(response);
}
}
// Java Servlet sample for the Aculab Telephony REST API.
//
// A page from the Simple Play With Interrupt sample:
// This acknowledges the interrupt to play by saying some text
// before the call is hung up.
package com.aculab.telephonyrestapi.samples;
import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.aculab.telephonyrestapi.*;
public class AcknowledgeInterrupt extends HttpServlet
{
private static final long serialVersionUID = -2939417779810757027L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
private void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(request);
// Get interrupt details from the action result.
ActionResult result = ourRequest.getInstanceInfo().getActionResult();
String previousAction = result.getAction();
boolean interrupted = result.getInterrupted();
// Setup the actions
List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
Play playAction = Play.sayText("This call has been interrupted. Goodbye.");
actions.add(playAction);
// Respond
String token = "my instance id";
TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
ourResponse.setHttpServletResponse(response);
}
}
// Java Servlet sample for the Aculab Telephony REST API.
//
package com.aculab.telephonyrestapi.samples;
import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.aculab.telephonyrestapi.*;
public class ErrorPage extends HttpServlet
{
private static final long serialVersionUID = -4842873371047361437L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
private void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(request);
ErrorResult result = ourRequest.getInstanceInfo().getErrorResult();
String token = String.format("Action: %s\nActionIndex: %d\nResult: %s", result.getAction(), result.getActionIndex(), result.getResult());
// Respond
List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
ourResponse.setHttpServletResponse(response);
}
}
// Java Servlet sample for the Aculab Telephony REST API.
//
package com.aculab.telephonyrestapi.samples;
import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import com.aculab.telephonyrestapi.*;
public class FinalPage extends HttpServlet
{
private static final long serialVersionUID = 5940620014313056844L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
handleRequest(request, response);
}
private void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
// Unpack the request
TelephonyRequest ourRequest = new TelephonyRequest(request);
}
}
Implemented as a Flask web application:
@app.route('/SimplePlayWithInterrupt', methods=['GET','POST'])
def handle_SimplePlayWithInterrupt():
my_request = TelephonyRequest(request)
app_inst_id = my_request.get_application_instance_id()
print("SimplePlayWithInterrupt: app_inst_id='{}'".format(app_inst_id))
play_action = Play(file_to_play='long.wav')
print("Application Instance ID: {0}".format(app_inst_id))
list_of_actions = []
list_of_actions.append(play_action)
my_response = TelephonyResponse(list_of_actions, token='my instance id')
return Response(response=my_response.get_json(), content_type='application/json;charset=utf-8')
@app.route('/AcknowledgeInterrupt', methods=['GET','POST'])
def handle_AcknowledgeInterrupt():
my_request = TelephonyRequest(request)
my_token = my_request.get_token()
print("Play was interrupted")
list_of_actions = []
list_of_actions.append(Play(text_to_say='This call has been interrupted. Goodbye.'))
my_response = TelephonyResponse(list_of_actions, "my instance id")
return Response(response=my_response.get_json(), content_type='application/json;charset=utf-8')
@app.route('/ErrorPage', methods=['GET','POST'])
def handle_ErrorPage():
my_request = TelephonyRequest(request)
token = my_request.get_token()
app_inst_id = my_request.get_application_instance_id()
error_result_dict = my_request.get_error_result()
action_string = error_result_dict.get('action', "?")
result_string = error_result_dict.get('result', "?")
print("ErrorPage: app_inst_id='{}' token='{}' action='{}' result='{}'".format(app_inst_id, token, action_string, result_string))
my_response = TelephonyResponse([Play(text_to_say='An error has occurred')])
return Response(response=my_response.get_json(), content_type='application/json;charset=utf-8')
@app.route('/FinalPage', methods=['GET','POST'])
def handle_FinalPage():
# The FinalPage handler follows the guidelines on:
# https://www.aculab.com/cloud/voice-and-fax-apis/rest-api/rest-api-version-2/writing-a-rest-application
# The guidelines are:
# "Your final page should return an empty response, a 204 is preferable, but empty JSON is acceptable."
my_request = TelephonyRequest(request)
token = my_request.get_token()
app_inst_id = my_request.get_application_instance_id()
print("FinalPage: app_inst_id='{}' token='{}'".format(app_inst_id, token))
empty_json = '{}'.encode('utf-8')
return Response(response=empty_json, status=204, content_type='application/json;charset=utf-8')
<?php
header("Content-Type: application/json; charset=UTF-8");
require __DIR__ . "/../../autoload.php";
use Aculab\TelephonyRestAPI\Play;
use Aculab\TelephonyRestAPI\Response;
use Aculab\TelephonyRestAPI\InstanceInfo;
// write the application instance id to the error log, so it can be used to interrupt the play
$info = InstanceInfo::getInstanceInfo();
$appInstanceId = $info->getApplicationInstanceId();
$info_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "simple_play_with_interrupt.txt";
$f = fopen($info_file, "w");
fwrite($f, 'ApplicationInstanceId to interrupt is:' . $appInstanceId);
fclose($f);
$play = new Play();
$play->addFile('long.wav');
$response = new Response();
$response->setToken('my instance id');
$response->addAction($play);
print $response;
<?php
header("Content-Type: application/json; charset=UTF-8");
require __DIR__ . "/../../autoload.php";
use Aculab\TelephonyRestAPI\Play;
use Aculab\TelephonyRestAPI\Response;
$play = new Play();
$play->addText('This call has been interrupted. Goodbye.');
$response = new Response();
$response->setToken('my instance id');
$response->addAction($play);
print $response;
<?php
header("Content-Type: application/json; charset=UTF-8");
require __DIR__ . "/../../autoload.php";
use Aculab\TelephonyRestAPI\Play;
use Aculab\TelephonyRestAPI\Response;
use Aculab\TelephonyRestAPI\InstanceInfo;
$info = InstanceInfo::getInstanceInfo();
$error = $info->getErrorResult();
$action = $error->getAction();
$desc = $error->getResult();
if (!is_null($action)) {
error_log("Error from action \"$action\" with result:" . PHP_EOL . "$desc" . PHP_EOL);
} else {
error_log("Error result:" . PHP_EOL . "$desc" . PHP_EOL);
}
$response = new Response();
$response->setToken('Error');
$play = new Play();
$play->addText('An error has occurred.');
$response->addAction($play);
print $response;
<?php
require __DIR__ . "/../../autoload.php";
http_response_code(204);
header("Content-Type: application/json; charset=UTF-8");
use Aculab\TelephonyRestAPI\InstanceInfo;
$info = InstanceInfo::getInstanceInfo();
$call = $info->getThisCallInfo();
$callid = $call->getCallId();
$duration = $call->getSecondsCallDuration();
error_log("This call id: $callid" . PHP_EOL . "This call duration: $duration" . PHP_EOL);