Want to get rid of Google Ads, click here.
+ Reply to Thread
Results 1 to 17 of 17

Thread: Possible to execute GUI-based RAD/Process from js/background?

  1. #1
    Junior Member
    Join Date
    Aug 2008
    Posts
    8

    Question Possible to execute GUI-based RAD/Process from js/background?

    Hey there,

    I need to raise a pertinent call after create an incident(both needs to be done in javascript/ScriptLibrary). Whereas incident creation works fine now, I'm struggling to create a related call for it.

    Basically It seems preferable to invoke RAD application 'us.screlate.options' as existed in process 'us.screlate' in that it is the same process as selecting 'Relate>Calls>Open' menu item, as opposed to manually create a call and link it to the incident by inserting a screlation record:

    var rteReturnValue = new SCDatum();
    var rteNames = new SCDatum();
    var rteValues = new SCDatum();
    var argNames = new SCDatum();
    var argVals = new SCDatum();

    //Parameter names for RAD app Template.apply
    rteNames.push("record");
    rteNames.push("second.file");
    rteNames.push("name");

    rteValues.push(system.vars.$L_file); //pre-set to theIncident
    rteValues.push(system.vars.$L_object); //pre-set to 'probsummary' Object record
    rteValues.push("opencall"); // opencall is the $L.action for opening a call for an incident

    print(rteValues);

    system.functions.rtecall("callrad",
    rteReturnValue,
    "us.screlate.options",
    rteNames,
    rteValues,
    false);

    It looks all fine and the print statement displays the all arguments correctly. But the following error is received:
    16744 10/23/2008 14:31:13 Cannot evaluate expression (us.screlate.options,add)

    So what went wrong here? Many thanks in advance.

    P.S. just a side note: I previously tried to directly invoke process 'us.screlate' but got 'Error attempting to execute an RIO panel in non-GUI mode. I guess it's because the process opens up a GUI('Open new call' format will be presented) thus it failed when called from the background. So my other question is whether it's possible to execute a GUI process from the background, e.g. via javascript??

  2. #2
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    Look what us.screlate.options application expects - probably you are not passing
    the required parameters.
    When I use callrad I first test it in SM environment - without JavaScript.
    Then it is easier to implement it in JS.

    regards
    Artur
    ps. If you succeed - please check if you are able to read the returned value(s) in rteReturnValue - I have big problem with it.

  3. #3
    Junior Member
    Join Date
    Aug 2008
    Posts
    8

    Default

    Hey Artur,

    Many thanks for your response.

    I suppose I pass in the right arguments for us.screlate.options as per the attachment.

    As the goal is to open a related call for an existing incident, so doesn't matter what's in rteReturnValue? I'm still relatively new to SC so can you please advise how I can test 'radcall' in SM environment?

    Kind regards
    Frank
    Attached Files

  4. #4
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    In your situation it is irrelevant. But it is not irrelevant for me

    The easiest way to test JS:
    add your function in any script library.
    when you write the name of it with arguments, it will be executed when you hit EXECUTE button. Do not forget to hit compile button.

    Example of script:

    // we are testing here your code
    MyNewFunction("IM10001");


    function MyNewFunction(id)
    {
    // the whole function goes here

    }


    regards
    Artur
    ps. as far as your error message - sorry, really have no time today.
    Look into script library - you will find at least 3 examples of callrad

    ps. 2 be sure the $L.action is set correctly - it may be read somewhere in application. So I suggest:

    system.vars.$L_action = "opencall";
    rteValues.push(system.vars.$L_action);
    Last edited by Artur; 2008-10-28 at 12:16.

  5. #5
    Junior Member
    Join Date
    Aug 2008
    Posts
    8

    Default

    Thanks Artur. I tried it out(attached is the ScriptLibrary code I use) and it now gives out a slightly different error:

    Cannot evaluate expression (us.screlate.options,process.option), as opposed to previously:

    Cannot evaluate expression (us.screlate.options,add)

    I have been trying to locate the exact panel firing the error by checking all 31 records for 'us.screlate.options' in 'application' file, but none is labeled 'process.options' or 'add'. Any thoughts?

    Also, a search of 'callrad' on ScriptLibrary returned only ones I've created. No sign of the 3 occasions of 'callrad'. Are you sure they're OOB?

    Oh I would still appreciate if you could look into this tomorrow since you're quite occupied today as you said
    Attached Files
    Last edited by aimaple; 2008-10-29 at 02:04. Reason: Attaching doc

  6. #6
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    Yes, I am sure they are OOB. I am attaching them here.
    I will try to look at your script. No promises, just try.

    Regards
    Artur


    Code:
     
    function sendEmail ( strSDInteractionNumber, strCompleteStatus, strNotificationName, fSvcCartItem)
    {   
     var fSDInteraction = new SCFile( "incidents" );     
         
     rc = fSDInteraction.doSelect("incident.id=\"" + strSDInteractionNumber + "\"");
     if ( rc != RC_SUCCESS ) 
     {
      var msg = system.functions.scmsg( 139, "ScriptLibrary", [er] );
      print(msg);
      //print("Fatal! Can't find interaction " + strSDInteractionNumber + "."); 
      return -1;
     }
     else
     {
      var rteReturnValue = new SCDatum();
      var rteNames = new SCDatum();
      var rteValues = new SCDatum();
      var scMsgStrings = new SCDatum();
      var argNames = new SCDatum();
      var argVals = new SCDatum();
         
      //Parameter names for RAD app us.notify   
      rteNames.push("name");   //Notification Name - INTO.NAME
      rteNames.push("record");   //Current File - INTO.FILE
      rteNames.push("names");   //Extra Arguements - INTO.ARGS
      rteNames.push("second.file"); //Save copy of the current file - INTO.OLD
      rteNames.push("types");   //Extra Arguement Names - INTO.ARG.NAMES
      
      //Adding arrays to an array is tricky. First we have to set the types by hand.
      var argVal;
      
      argVals.setType(8);  //type array
      argNames.setType(8); //type array
      
      
      //modified to match new Datum push behavior -Hua   
      //argVal=new SCDatum();
      //argVal.setType(2); //string     
      argVals.push(strCompleteStatus);
      //argVals.push(argVal);
      
      //argVal=new SCDatum();
      //argVal.setType(2); //string     
      argVals.push(fSvcCartItem.item_description);
      //argVals.push(argVal);
      
      //argVal=new SCDatum();
      //argVal.setType(2); //string
      //argVals.push("$L.status");
      //argNames.push(argVal);
      argNames.push("$L.status");
      
      //argVal=new SCDatum();
      //argVal.setType(2); //string
      //argVal.push("$L.item.desc");
      //argNames.push(new SCDatum(argVal));
      argNames.push("$L.item.desc");
      
      //Now we set the array type for rteValues and use system.functions.insert to get 
      //the arg arrays in properly into the rteValue array. You can't mix push() with 
      //system.functions.insert() or the rteValues array will become corrupt. 
      
      rteValues.setType(8);
      rteValues=system.functions.insert(rteValues, 0, 1, strNotificationName);
      rteValues=system.functions.insert(rteValues, 0, 1, fSDInteraction);
      rteValues=system.functions.insert(rteValues, 0, 1, argVals);
      rteValues=system.functions.insert(rteValues, 0, 1, fSDInteraction); //won't be used
      rteValues=system.functions.insert(rteValues, 0, 1, argNames);
        
      system.functions.rtecall("callrad", 
             rteReturnValue, 
             "us.notify", //RAD app name
             rteNames, 
             rteValues,
             false); //false to run in same thread, true to run in new thread
     }
     
     return 1; 
    }
    
     
     
    function getDecoratorImageAttributes( fCIDevice, bGetCIIcon )
    { 
     var urlObj;
     var strFilterString;
     var retVal=new Array();
     var decoratorArray = lib.ciVizCacheManager.getDecorators();
     
     for (var i=0; i < decoratorArray.length; i++) 
     {  
      /* do this again once the parse eval bug is fixed */  
      //var parsedata = system.functions.parse(decoratorArray[i].filter_criteria, 2);   
      //var evaldata = system.functions.evaluate(parsedata);
      
      var parsestring = decoratorArray[i].filter_criteria;
      
      //print("parse decoratorArray[i] "+parsestring);
        
      parsestring = parsestring.replace("$L.file", "$G.parsefile"); 
      system.vars.$parsestring=parsestring;
      system.vars.$G_parsefile=fCIDevice;
      
      system.functions.rtecall("callrad", 
              new SCDatum(), 
             "civiz.parse.eval.helper", //RAD app name
             new SCDatum(), 
             new SCDatum(),
             false);
             
      var evaldata = system.vars.$retval; 
      var hasExtLink = true;
        
      if(decoratorArray[i].change_link_type == null || decoratorArray[i].change_link_type == "none")
       hasExtLink = false;     
      
      if(evaldata && hasExtLink)
      {
       //print("check decorator "+decoratorArray[i].name+" and link type "+decoratorArray[i].change_link_type);
       var daysOut = "0";
       
       if(decoratorArray[i].change_link_type == "future" && decoratorArray[i].days_in_advance!=null )
        daysOut =  decoratorArray[i].days_in_advance;
        
       var tableName = "cm3r";
       
       if(decoratorArray[i].change_link_type == "incident")
        tableName = "probsummary";
        
       if(decoratorArray[i].change_link_type == "breached")
        tableName = "slamonthly";
        
       var result = lib.ciVizProcessExternal.hasDecoratorForExternal(fCIDevice,tableName,"",daysOut);
       //print("result is "+result);
       evaldata = evaldata && result;
       //print("evaldata ="+evaldata);
      }
      
      if (evaldata == true)  
      {    
       urlObj = new Object();
       
       urlObj.name = decoratorArray[i].name;
       urlObj.ciname = fCIDevice.logical_name;
       urlObj.priority = decoratorArray[i].priority;
       urlObj.highlight_upstream = decoratorArray[i].highlight_upstream;
       urlObj.highlight_downstream = decoratorArray[i].highlight_downstream;
       urlObj.position = decoratorArray[i].position;
       urlObj.external_table_name = decoratorArray[i].external_table_name;
       urlObj.change_link_type = decoratorArray[i].change_link_type;
       urlObj.days_in_advance = decoratorArray[i].days_in_advance;
       //urlObj.balloon_display_field = decoratorArray[i].balloon_display_field;
       //urlObj.balloon_display_label = decoratorArray[i].balloon_display_label;
       urlObj.balloon_display_field = copyArray(decoratorArray[i].balloon_display_field);
       urlObj.balloon_display_label = copyArray(decoratorArray[i].balloon_display_label); 
       urlObj.category = decoratorArray[i].category; 
       urlObj.group_label = decoratorArray[i].group_label;
       urlObj.strSysAttach = decoratorArray[i].strSysAttach;   
       
       retVal.push(urlObj);          
      }
      system.functions.cleanup(evaldata);      
     }
     
     if (bGetCIIcon)
     {  
      var ciVizDev = getCIVisualizationDevice( fCIDevice );
      var SysAttachment = getCIVisualAttr( fCIDevice );
      
      urlObj = new Object();
     
      if (ciVizDev != null)
      {
       //urlObj.strSysAttach = ciVizDev.default_url;
       urlObj.balloon_display_field = copyArray(ciVizDev.balloon_display_field);
       urlObj.balloon_display_label = copyArray(ciVizDev.balloon_display_label); 
       urlObj.priority = 0;
      }
      
      if (SysAttachment != null)
      {
       urlObj.strSysAttach = "scattach://img:" + SysAttachment.uid + ":" + SysAttachment.filename + ":" + SysAttachment.application + ":" + SysAttachment.topic;
       retVal.push(urlObj);
      }
     }
     
     retVal.sort(prioritySort);  
     
     return retVal;
    }
     
     
    function domessageBox(message)
    {
     //if we are in a background process...just print the message
     if(vars.$G_bg || vars.$L_bg)
     {
      print(message);
      return;
     }
     var rteReturnValue = new SCDatum();
     var argNames = new SCDatum();
     var argVals = new SCDatum();
     argVals.setType(8);     //type array
     argNames.setType(8);    //type array
     var argVal;
     
     argVal=new SCDatum();
           argVal.setType(2); //string                           
           argVal="text";
           argNames.push(argVal);
     
     argVal=new SCDatum();
           argVal.setType(2); //string                           
           argVal=message;
           argVals.push(argVal);      
           
     
     
     
     
     system.functions.rtecall("callrad", 
                                    rteReturnValue, 
                                    "mb.ok", //RAD app name
                                    argNames, 
                                    argVals,
                                    true); //false to run in same thread, true to run in new thread
    }
    
     
     
     
     
    // Artur - this one below was not in function, just as you see below:
     
    test  var rteReturnValue = new SCDatum();
    var rteNames = new SCDatum();
    var rteValues = new SCDatum();
    var argNames = new SCDatum();
    var argVals = new SCDatum();
         
    rteNames.push("file");   
    rteNames.push("record");   
    rteNames.push("name");   
    rteNames.push("prompt");   
    rteNames.push("boolean1");   
    var olddbdict=new SCFile("dbdict");
    var newdbdict=new SCFile("dbdict");
    var log=new SCDatum();
    var retcode=new SCDatum();
    olddbdict.doSelect("name=\"svcCatalog\"");
    newdbdict.doSelect("name=\"extaccess\"");
    log=system.functions.denull(log);
    print(log);
    rteValues.setType(8);
    rteValues=system.functions.insert(rteValues, 0, 1, olddbdict);
    rteValues=system.functions.insert(rteValues, 0, 1, newdbdict);
    rteValues=system.functions.insert(rteValues, 0, 1, log);
    rteValues=system.functions.insert(rteValues, 0, 1, retcode); //won't be used
    rteValues=system.functions.insert(rteValues, 0, 1, false);
    system.functions.rtecall("callrad", 
           rteReturnValue, 
           "apm.upgrade.merge.new", //RAD app name
           rteNames, 
           rteValues,
           false); //false to run in same thread, true to run in new thread      
    test_FF  var fCatalogItem=new SCFile("svcCatalog");
    var abc=new Array(2);
    //var bFlag=lib.setConnectorParms.setConnectorParms(fCatalogItem,"Open MAC Ticket,MAC,move,3 - Multiple Users,3 - Average,");
    //abc=['parts,266,10,1,required,speaker,','parts,211,10,1,required,cpu,','parts,281,51,1,optional,upgrade,','parts,261,4,1,optional,monitor,','parent_group,speaker,','parent_group,monitor,','dependent_group,cpu,','dependent_group,upgrade,','dependency_group,instock,','dependency_group,close,'];
    //var bFlag=lib.setConnectorParms.setConnectorParms(fCatalogItem,"Open New Request,customer,parts,parent_group,dependent_group,dependency_group,",abc);
    var bFlag=lib.setConnectorParms.setConnectorParms(fCatalogItem,"Open a Change,RFC,CM 1,Incident/Problem Resolution,1 - Enterprise,1 - Critical,assets,",['assets,ACMEpc012,','assets,ACMEpc015,','assets,ACMEserver002,']);
     print("Falg="+bFlag);
    test_hua  //var value = lib.Approval.getApprovalGroups("incidents","hzhang");
    //print(value);
    //var ftest = new SCFile("probsummary");
    //rc = ftest.doSelect("file.logical.name.file.vendor.location=\"houston\"");
    
    //var value = lib.complexQueryBuilder.buildQuery("probsummary","assignment#\"LAN SUPPORT\" and (  status=\"alert stage 3\") or flag=true");
    //print(value);
     var test1=lib.TemplateFilter.getAllowedTemplateTables();
     //var test1=lib.TemplateFilter.getGroupID("cm3r");
     print(test1);

  7. #7
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    But it is possible they are comming from IIA.
    I did not checked that.

    regards
    Artur

  8. #8
    Junior Member
    Join Date
    Aug 2008
    Posts
    8

    Default

    Totally no sign of 'callrad' in the entire ScriptLibrary on my system so I also reckon that piece of code is from IIA or elsewhere.

    Really appreciate you having a close look if at all possible! Look forward to hearing from you again

    Best regards
    Frank

  9. #9
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    I hope you using SM, not SC6 ?
    There is some function which saves all scripts in one file. Then is is much easier to look
    what HP is doing. I have found that script after export of JS in one file as well, so both ways are available.

    I did check your script and tried mine - but no scuccess. Sometimes I just get some error, sometimes client crashes But never the same errors you have mentioned.
    What version do you use ? SM 7.01.53 ?
    I am affraid it looks bad ..... I will try again tomorrow or later...

    regards
    Artur

  10. #10
    Junior Member
    Join Date
    Aug 2008
    Posts
    8

    Default

    We're still using SC 6.1.2.0 here.

    What error did you get? Same as mine? Did you try it the same way as I did, i.e. create a new ScriptLibrary record with the code like the one I posted earlier?

    Thanks for helping me on this Artur! But I'm kinda astounded that nobody else, other than you, would even give this a try...

    Look forward to your posts

    Kind regards
    Frank

  11. #11
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    I am using SM, not SC. I am affraid that there is too much difference between those two
    systems. I do not remeber the message, but it wass different - as I wrote.
    Yes, I tried yor script.

    Maybe people are not using callrad so much in JS .....

    I am thinking about using scripts invoked in JS in case callrad will fail.
    So you will have tocreate simple script to invoke the app but all this will be launched in JS. Sounds OK ?


    regards
    Artur

  12. #12
    Junior Member
    Join Date
    Aug 2008
    Posts
    8

    Default

    Thanks Artur for the suggestion of using scripts! That might just work but I've just tried out another way which seems going a bit further also:

    I created gen.us.screlate.opencall Process, almost an exact copy of 'us.screlate' and calling it on the ‘Next Process’ tab of the Process im.first.genevents(created by my colleague and to be called in JavaScript to insert incidents into probsummary, based on im.first. I had a look basically a simplified version of im.first). So gen.us.screlate.opencall will be invoked immediately following im.first.genevents(i.e. after an incident being successfully created by JavaScript). I now get the following errors:

    2868 10/30/2008 15:07:14 Incident IM141601 has been opened.
    2868 10/30/2008 15:07:14 Incident IM141601 has been opened.
    2868 10/30/2008 15:07:14 Please provide a contact.
    2868 10/30/2008 15:07:14 Error attempting to execute an RIO panel in non-GUI mode (display,show.rio)
    2868 10/30/2008 15:07:14 Display application error exit during RIO on screen cc.first
    2868 10/30/2008 15:07:14 Unrecoverable error in application: se.view.engine on panel display.go
    2868 10/30/2008 15:07:14 sc relation error: Application error occured.
    2868 10/30/2008 15:07:14 Error exit during relation processing for primary file probsummary, destination file=incidents, and unique=IM141601
    2868 10/30/2008 15:07:14 Unrecoverable error in application: se.screlate.options on panel screlate
    2868 10/30/2008 15:07:14 Unrecoverable error in application: se.call.process on panel call.rad.1
    2868 10/30/2008 15:07:14 Unrecoverable error in application: se.call.process on panel call.addl.process

    > 2868 10/30/2008 15:07:14 Please provide a contact.
    seems this is fired by 'apm.quick' formatctrl. What I don’t get is that why because contact.name is filled in on the incident so when we select ‘Related>Calls>Open’ which takes us to a new call screen, the contact.name is carried forward. Is it’s lost somewhere here?

    > 2868 10/30/2008 15:07:14 Error attempting to execute an RIO panel in non-GUI mode (display,show.rio)
    I tried to locate the wizard opening a new call screen just like when ‘Related>Calls>Open’ is selected, but didn’t find anything relevant in ‘wizard’ file(I saw wizards have an option of ‘Skip Display’ which, if activated, might make it work at the background)

    > [for all other unrecoverable application errors]
    I located all the panels of the applications involved but cannot see any of it calling any wizard (to display the create new call format as when ‘Related>Calls>Open’). Anything I'm missing here?


    Many thanks Artur and regards
    Frank

  13. #13
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default

    Hi Frank,

    in about few days I will very likely need some javascript which will be able to fire the SM script, so I will post it here if I succeed.
    I just need to make a caluclations with calendar.calc.date or calendar.calc.date.fc and I have not found the way for the first one to return the calculated date to invoking javascript.

    I think your way is a good one too. Usually I debug the processess with
    Initial JavaScript and Final JavaScript tab an a lot of print().
    In debugger I also use "ba" command.

    good luck
    Artur

  14. #14
    Senior Member
    Join Date
    Apr 2006
    Location
    Poland
    Posts
    680

    Default My (working) example

    Hi,

    As I worte I tried scripts. But - for whatever reason - I could not properly
    handle over values in thread variables. Strange.
    As I have no time for extensive researches - I did it with process.
    The only one disadvantage is that process require some file. So I use
    the short one which will be in DB cache anyway: category.
    Here is my script and screenshot of the Process:

    Code:
     
    // This function calculate the date using calendar.calc.date in a process
    // 
    function CalcDate(dstart, priority)
    {
    //the file is required so category is choosed as a smallest and well cached by DB
     
      var catfile = new SCFile("category");
      if (catfile.doSelect('name = \"incident\"') == RC_SUCCESS) {    
     
     var rteReturnValue = new SCDatum();
     var argNames = new SCDatum();
     var argVals = new SCDatum();
     argVals.setType(8);     //type array
     argNames.setType(8);    //type array
     var argVal;
     argVal=new SCDatum();
           argVal.setType(2); //string                           
           argVal="file";
           argNames.push(argVal);
     
     argVal=new SCDatum();
           argVal.setType(6); //string                           
           argVal=catfile;
           argVals.push(argVal);      
     
     argVal=new SCDatum();
           argVal.setType(2); //string                           
           argVal="name";
           argNames.push(argVal);
     
     argVal=new SCDatum();
           argVal.setType(2); //string                           
           argVal="CalcDate";
           argVals.push(argVal);      
     // argument for application  calendar.calc.date
     vars.$dstart = dstart;
     if (priority=="1") 
      {
      vars.$dshift = system.functions.val('02:00:00',3);
      vars.$calendar = "IM_P1P3";
      }
     if (priority=="2")   
      {
      vars.$dshift = system.functions.val('04:00:00',3);
      vars.$calendar = "IM_P1P3";
      }
     if (priority=="3")
      {
      vars.$dshift = system.functions.val('06:00:00',3);
      vars.$calendar = "IM_P1P3";
      }
     
     if (priority=="4")
      {
      vars.$dshift = system.functions.val('12:00:00',3);
      vars.$calendar = "IM_P4P5";
      }
     
     system.functions.rtecall("callrad", 
                                    rteReturnValue, 
                                    "se.call.process", //RAD app name
                                    argNames, 
                                    argVals,
                                    false); //false to run in same thread, true to run in new thread
     
     return vars.$dresult;
      }
    }


    Nothing really exciting - but maybe usefull.


    regards
    Artur
    Attached Images

  15. #15
    Administrator tommy's Avatar
    Join Date
    Nov 2001
    Location
    Copenhagen
    Posts
    4,272

    Default

    You actually don't need to use the unsuported callrad to call a process.

    Create a dummy object, dummy state and add the processes to that. Then initiate that object and call the process normally filevar.processname doing it this way you can get support as opposed to using callrad.
    Best regards Tommy
    Blog - - ITIL certified - Accredited Integration Specialist – HP OpenView Service Management

    Want to keep this site alive? Consider making a donation. Click here.

  16. #16
    Junior Member
    Join Date
    Jan 2009
    Posts
    1

    Default

    hi tommy
    You actually don't need to use the unsuported callrad to call a process.

    Create a dummy object, dummy state and add the processes to that. Then initiate that object and call the process normally filevar.processname doing it this way you can get support as opposed to using callrad.

    Can you explain with more detail
    thanks

  17. #17
    Senior Member
    Join Date
    Jan 2002
    Location
    The Netherlands
    Posts
    930

    Default

    As to the gui, you can pass a background parameter to screlate to ensure all is handled in the background. Even if you do not have an SM7 system, you might want to use it for reference. If you use an SM7.10, there is some code (wrapped as part of the escalation wizard) that triggers background IM and ChM record creation.

    Good luck!

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Tags for this Thread

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts