RORHL7 ;HCIOFO/SG - HL7 UTILITIES ; 11/2/05 10:30am
;;1.5;CLINICAL CASE REGISTRIES;;Feb 17, 2006
;
Q
;
;***** ADDS THE SEGMENT TO THE HL7 MESSAGE BUFFER
;
; .SOURCE Reference to a local variable where the
; source data is stored
;
; [SRCTYPE] Type and format of the source data
; "C" Complete segment (see the ADDSEGC^RORHL7A
; for source data format description)
; "F" List of field values (see the ADDSEGF^RORHL7A
; for source data format description).
; This is the default parameter value.
;
ADDSEG(SOURCE,SRCTYPE) ;
I $G(SRCTYPE)?."F" D ADDSEGF^RORHL7A(.SOURCE) Q
I SRCTYPE="C" D ADDSEGC^RORHL7A(.SOURCE) Q
D ERROR^RORERR(-88,,,,"SRCTYPE",$G(SRCTYPE))
Q
;
;***** CREATES A NEW MESSAGE IN THE BATCH
;
; The function adds a new message header to the batch. If the batch
; does not exist yet, it is created.
;
; [.RORMSH] Reference to a variable in what a MSH segment of
; the message is returned.
;
; Return Values:
; <0 Error Code
; >0 Index of a subnode of the ^TMP("HLS",$J) that
; contains the new MSH segment.
;
; MSH segment is returned as a value of the RORMSH parameter. In case
; of a long segment, continuations are returned as subnodes.
;
; Several nodes (HL7*) in ROREXT are set and the ^TMP("HLS",$J) node
; is deleted by this entry point before it creates a new batch.
;
CREATE(RORMSH) ;
N NDX,RC,TMP K RORMSH
Q:$G(ROREXT("HL7PROT"))="" $$ERROR^RORERR(-25)
;--- Create a message stub for the new batch message
; (if it has not been created before)
I '$G(ROREXT("HL7MTIEN")) D Q:$G(RC)<0 RC
. N RORMID,RORIEN,RORDT
. ;--- Set up HL7 environment variables
. S RC=$$INIT($NA(^TMP("HLS",$J))) Q:RC<0
. ;--- Create a stub
. S RORDT=$S($G(ROREXT("HDTIEN"))>0:$G(ROREXT("HL7DT")),1:"")
. D CREATE^HLTF(.RORMID,.RORIEN,.RORDT)
. ;--- Save parameters of the new batch message
. S (ROREXT("HL7CNT"),ROREXT("HL7SIZE"))=0
. S ROREXT("HL7DT")=RORDT
. S ROREXT("HL7MID")=RORMID
. S ROREXT("HL7MTIEN")=RORIEN
. ;--- Initialize temporary storage
. K ^TMP("HLS",$J)
;--- Initialize the HL7 environment variables
S RC=$$INIT() Q:RC<0 RC
S NDX=$G(ROREXT("HL7PTR"))+1
;--- Reset the Set ID's for all supported segments
F TMP="OBR","OBX","PID","PV1","ZRD","ZSP" D
. S ROREXT("HL7SID",TMP)=1
;--- Create and store a MSH segment for individual message
S ROREXT("HL7CNT")=ROREXT("HL7CNT")+1
S TMP=ROREXT("HL7MID")_"-"_ROREXT("HL7CNT")
D MSH^HLFNC2(.RORHL,TMP,.RORMSH)
S:$P(RORMSH,RORHL("FS"),17)="US" $P(RORMSH,RORHL("FS"),17)="USA"
M ^TMP("HLS",$J,NDX)=RORMSH
S ROREXT("HL7SIZE")=ROREXT("HL7SIZE")+$L(RORMSH)+$L($G(RORMSH(1)))+1
S ROREXT("HL7PTR")=NDX
Q NDX
;
;***** REPLACES ENCODING CHARACTERS WITH ESCAPE CODES
;
; STR Source string
;
; The HLFS and HLECH variables must be initialized before
; calling this function (either by the INIT^HLFNC2 or manually).
;
; The function returns the source string with encoding
; characters replaced with corresponding escape codes.
;
ESCAPE(STR) ;
Q:STR="" STR
N BUF,ESC,CH,I1,I2,SCLST
S SCLST=HLECH_HLFS
;--- Find all occurrences of encoding characters and
; save their positions to a local array
F I1=1:1:5 S CH=$E(SCLST,I1),I2=1 Q:CH="" D
. F S I2=$F(STR,CH,I2) Q:'I2 S BUF(I2-1)=I1
Q:$D(BUF)<10 STR
;--- Replace encoding characters with escape codes
S (BUF,I2)="",ESC=$E(HLECH,3) S:ESC="" ESC="\"
F S I1=I2,I2=$O(BUF(I2)) Q:I2="" D
. S BUF=BUF_$E(STR,I1+1,I2-1)_ESC_$E("SRETF",BUF(I2))_ESC
Q BUF_$E(STR,I1+1,$L(STR))
;
;***** CHECKS THE DATE/TIME AND CONVERTS IT TO HL7 FORMAT
;
; DATE Date/time in FileMan format
;
FM2HL(DATE) ;
Q:'$G(DATE) """"""
S DATE=$$FMTHL7^XLFDT(DATE)
Q $S(DATE>0:DATE,1:"")
;
;***** INITIALIZES THE HL7 SEPARATORS
;
; [.CS] Reference to a local variable where the
; component separator will be returned to.
;
; [.SCS] Reference to a local variable where the
; sub-component separator will be returned to.
;
; [.RPS] Reference to a local variable where the
; repetition separator will be returned to.
;
ECH(CS,SCS,RPS) ;
S HLECH=$G(RORHL("ECH"),"^~\&")
S CS=$E(HLECH,1),SCS=$E(HLECH,4),RPS=$E(HLECH,2)
Q
;
;***** INITIALIZES THE HL7 ENVIRONMENT VARIABLES
;
; [ROR8FILE] Closed root of the buffer that will be used for
; construction of the HL7 message.
;
; Return Values:
; <0 Error Code
; 0 Ok
;
INIT(ROR8FILE) ;
N TMP K RORHL
D INIT^HLFNC2(ROREXT("HL7PROT"),.RORHL)
Q:$G(RORHL) $$ERROR^RORERR(-23,,RORHL)
S TMP=$G(RORHL("ECH"))
Q:$L(TMP)<4 $$ERROR^RORERR(-75)
;--- Initialize the nodes required for the API's
S:$G(ROR8FILE)'="" ROREXT("HL7BUF")=ROR8FILE
D:$G(ROREXT("HL7BUF"))'=""
. S ROREXT("HL7PTR")=+$O(@ROREXT("HL7BUF")@(""),-1)
Q 0
;
;***** CHECKS IF MAXIMUM BATCH SIZE IS REACHED
;
; [RESERVE] Number of bytes reserved in the batch (0 by default)
;
; Return Values:
; 0 Messages can be added to the batch
; 1 Maximum size of the batch has been reached
;
ISMAXSZ(RESERVE) ;
Q:$G(ROREXT("MAXHL7SIZE"))'>0 0
Q:($G(ROREXT("HL7SIZE"))+$G(RESERVE))<ROREXT("MAXHL7SIZE") 0
S $P(ROREXT("HL7SIZE"),U,2)=1
Q 1
;
;***** RETURNS NUMBER OF MESSAGES IN THE CURRENT BATCH
MSGCNT() ;
Q $G(ROREXT("HL7CNT"))
;
;***** RETURNS THE POINTER TO LAST SEGMENT IN THE MESSAGE BUFFER
PTR() Q +$G(ROREXT("HL7PTR"))
;
;***** DELETES THE SEGMENTS FROM THE HL7 MESSAGE BUFFER
;
; SEGPTR An index of the HL7 segment in the message buffer
;
; [KEEP] Keep the segment referenced by the SEGPTR and start
; the rollback from the next segment.
;
ROLLBACK(SEGPTR,KEEP) ;
N BUF,I,I1,MSH,NODE,SEGNAME
S NODE=ROREXT("HL7BUF"),HLFS=$G(RORHL("FS"),"|")
S I=$S($G(KEEP):$O(@NODE@(SEGPTR)),1:+SEGPTR)
S MSH=$S(I>0:$P($G(@NODE@(I)),HLFS)="MSH",1:0)
;---
F Q:I'>0 D S I=$O(@NODE@(I))
. S BUF=$G(@NODE@(I))
. ;--- Decrement the batch size indicator
. S ROREXT("HL7SIZE")=$G(ROREXT("HL7SIZE"))-$L(BUF)-1
. S I1=""
. F S I1=$O(@NODE@(I,I1)) Q:I1="" D
. . S ROREXT("HL7SIZE")=ROREXT("HL7SIZE")-$L(@NODE@(I,I1))
. ;--- Decrement the 'Set ID' counter if necessary
. S SEGNAME=$P(BUF,HLFS),I1=+$G(ROREXT("HL7SID",SEGNAME))
. I I1>0 S:$P(BUF,HLFS,2)>0 ROREXT("HL7SID",SEGNAME)=I1-1
. ;--- Delete the segment
. K @NODE@(I)
;--- Validate current size of the batch
S:$G(ROREXT("HL7SIZE"))<0 ROREXT("HL7SIZE")=0
;--- Decrease number of messages in the batch if necessary
I MSH S:$G(ROREXT("HL7CNT"))>0 ROREXT("HL7CNT")=ROREXT("HL7CNT")-1
Q
;
;***** SENDS THE BATCH MESSAGE
;
; .MID Reference to a local variable where the batch
; message ID (returned by the GENERATE^HLMA) is
; returned to.
;
; Return Values:
; <0 Error Code
; 0 Ok
; >0 There was nothing to send
;
; Several nodes (HL7*) in the ROREXT and the ^TMP("HLS",$J) node
; are deleted by this entry point.
;
SEND(MID) ;
N RC,RORBUF,RORHLP S MID=""
Q:$G(ROREXT("HL7PROT"))="" $$ERROR^RORERR(-25)
;--- Quit if there is nothing to send
Q:'$G(ROREXT("HL7MTIEN"))!($D(^TMP("HLS",$J))<10) 1
;--- Set up the HL7 environment variables
D INIT^HLFNC2(ROREXT("HL7PROT"),.RORHL)
Q:$G(RORHL) $$ERROR^RORERR(-23,,RORHL)
;--- Send the message
S RORHLP("NAMESPACE")="ROR"
D GENERATE^HLMA(ROREXT("HL7PROT"),"GB",1,.RORBUF,ROREXT("HL7MTIEN"),.RORHLP)
S RC=$S($P(RORBUF,U,2):$$ERROR^RORERR(-24,,RORBUF),1:0)
S MID=$P(RORBUF,U)
;--- Cleanup if there is no error or not in debug mode
D:'$G(RORPARM("DEBUG"))!(RC'<0)
. F TMP="HL7CNT","HL7MTIEN","HL7SIZE" K ROREXT(TMP)
. K ^TMP("HLS",$J)
Q RC
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HRORHL7 8035 printed Dec 13, 2024@01:42:07 Page 2
RORHL7 ;HCIOFO/SG - HL7 UTILITIES ; 11/2/05 10:30am
+1 ;;1.5;CLINICAL CASE REGISTRIES;;Feb 17, 2006
+2 ;
+3 QUIT
+4 ;
+5 ;***** ADDS THE SEGMENT TO THE HL7 MESSAGE BUFFER
+6 ;
+7 ; .SOURCE Reference to a local variable where the
+8 ; source data is stored
+9 ;
+10 ; [SRCTYPE] Type and format of the source data
+11 ; "C" Complete segment (see the ADDSEGC^RORHL7A
+12 ; for source data format description)
+13 ; "F" List of field values (see the ADDSEGF^RORHL7A
+14 ; for source data format description).
+15 ; This is the default parameter value.
+16 ;
ADDSEG(SOURCE,SRCTYPE) ;
+1 IF $GET(SRCTYPE)?."F"
DO ADDSEGF^RORHL7A(.SOURCE)
QUIT
+2 IF SRCTYPE="C"
DO ADDSEGC^RORHL7A(.SOURCE)
QUIT
+3 DO ERROR^RORERR(-88,,,,"SRCTYPE",$GET(SRCTYPE))
+4 QUIT
+5 ;
+6 ;***** CREATES A NEW MESSAGE IN THE BATCH
+7 ;
+8 ; The function adds a new message header to the batch. If the batch
+9 ; does not exist yet, it is created.
+10 ;
+11 ; [.RORMSH] Reference to a variable in what a MSH segment of
+12 ; the message is returned.
+13 ;
+14 ; Return Values:
+15 ; <0 Error Code
+16 ; >0 Index of a subnode of the ^TMP("HLS",$J) that
+17 ; contains the new MSH segment.
+18 ;
+19 ; MSH segment is returned as a value of the RORMSH parameter. In case
+20 ; of a long segment, continuations are returned as subnodes.
+21 ;
+22 ; Several nodes (HL7*) in ROREXT are set and the ^TMP("HLS",$J) node
+23 ; is deleted by this entry point before it creates a new batch.
+24 ;
CREATE(RORMSH) ;
+1 NEW NDX,RC,TMP
KILL RORMSH
+2 if $GET(ROREXT("HL7PROT"))=""
QUIT $$ERROR^RORERR(-25)
+3 ;--- Create a message stub for the new batch message
+4 ; (if it has not been created before)
+5 IF '$GET(ROREXT("HL7MTIEN"))
Begin DoDot:1
+6 NEW RORMID,RORIEN,RORDT
+7 ;--- Set up HL7 environment variables
+8 SET RC=$$INIT($NAME(^TMP("HLS",$JOB)))
if RC<0
QUIT
+9 ;--- Create a stub
+10 SET RORDT=$SELECT($GET(ROREXT("HDTIEN"))>0:$GET(ROREXT("HL7DT")),1:"")
+11 DO CREATE^HLTF(.RORMID,.RORIEN,.RORDT)
+12 ;--- Save parameters of the new batch message
+13 SET (ROREXT("HL7CNT"),ROREXT("HL7SIZE"))=0
+14 SET ROREXT("HL7DT")=RORDT
+15 SET ROREXT("HL7MID")=RORMID
+16 SET ROREXT("HL7MTIEN")=RORIEN
+17 ;--- Initialize temporary storage
+18 KILL ^TMP("HLS",$JOB)
End DoDot:1
if $GET(RC)<0
QUIT RC
+19 ;--- Initialize the HL7 environment variables
+20 SET RC=$$INIT()
if RC<0
QUIT RC
+21 SET NDX=$GET(ROREXT("HL7PTR"))+1
+22 ;--- Reset the Set ID's for all supported segments
+23 FOR TMP="OBR","OBX","PID","PV1","ZRD","ZSP"
Begin DoDot:1
+24 SET ROREXT("HL7SID",TMP)=1
End DoDot:1
+25 ;--- Create and store a MSH segment for individual message
+26 SET ROREXT("HL7CNT")=ROREXT("HL7CNT")+1
+27 SET TMP=ROREXT("HL7MID")_"-"_ROREXT("HL7CNT")
+28 DO MSH^HLFNC2(.RORHL,TMP,.RORMSH)
+29 if $PIECE(RORMSH,RORHL("FS"),17)="US"
SET $PIECE(RORMSH,RORHL("FS"),17)="USA"
+30 MERGE ^TMP("HLS",$JOB,NDX)=RORMSH
+31 SET ROREXT("HL7SIZE")=ROREXT("HL7SIZE")+$LENGTH(RORMSH)+$LENGTH($GET(RORMSH(1)))+1
+32 SET ROREXT("HL7PTR")=NDX
+33 QUIT NDX
+34 ;
+35 ;***** REPLACES ENCODING CHARACTERS WITH ESCAPE CODES
+36 ;
+37 ; STR Source string
+38 ;
+39 ; The HLFS and HLECH variables must be initialized before
+40 ; calling this function (either by the INIT^HLFNC2 or manually).
+41 ;
+42 ; The function returns the source string with encoding
+43 ; characters replaced with corresponding escape codes.
+44 ;
ESCAPE(STR) ;
+1 if STR=""
QUIT STR
+2 NEW BUF,ESC,CH,I1,I2,SCLST
+3 SET SCLST=HLECH_HLFS
+4 ;--- Find all occurrences of encoding characters and
+5 ; save their positions to a local array
+6 FOR I1=1:1:5
SET CH=$EXTRACT(SCLST,I1)
SET I2=1
if CH=""
QUIT
Begin DoDot:1
+7 FOR
SET I2=$FIND(STR,CH,I2)
if 'I2
QUIT
SET BUF(I2-1)=I1
End DoDot:1
+8 if $DATA(BUF)<10
QUIT STR
+9 ;--- Replace encoding characters with escape codes
+10 SET (BUF,I2)=""
SET ESC=$EXTRACT(HLECH,3)
if ESC=""
SET ESC="\"
+11 FOR
SET I1=I2
SET I2=$ORDER(BUF(I2))
if I2=""
QUIT
Begin DoDot:1
+12 SET BUF=BUF_$EXTRACT(STR,I1+1,I2-1)_ESC_$EXTRACT("SRETF",BUF(I2))_ESC
End DoDot:1
+13 QUIT BUF_$EXTRACT(STR,I1+1,$LENGTH(STR))
+14 ;
+15 ;***** CHECKS THE DATE/TIME AND CONVERTS IT TO HL7 FORMAT
+16 ;
+17 ; DATE Date/time in FileMan format
+18 ;
FM2HL(DATE) ;
+1 if '$GET(DATE)
QUIT """"""
+2 SET DATE=$$FMTHL7^XLFDT(DATE)
+3 QUIT $SELECT(DATE>0:DATE,1:"")
+4 ;
+5 ;***** INITIALIZES THE HL7 SEPARATORS
+6 ;
+7 ; [.CS] Reference to a local variable where the
+8 ; component separator will be returned to.
+9 ;
+10 ; [.SCS] Reference to a local variable where the
+11 ; sub-component separator will be returned to.
+12 ;
+13 ; [.RPS] Reference to a local variable where the
+14 ; repetition separator will be returned to.
+15 ;
ECH(CS,SCS,RPS) ;
+1 SET HLECH=$GET(RORHL("ECH"),"^~\&")
+2 SET CS=$EXTRACT(HLECH,1)
SET SCS=$EXTRACT(HLECH,4)
SET RPS=$EXTRACT(HLECH,2)
+3 QUIT
+4 ;
+5 ;***** INITIALIZES THE HL7 ENVIRONMENT VARIABLES
+6 ;
+7 ; [ROR8FILE] Closed root of the buffer that will be used for
+8 ; construction of the HL7 message.
+9 ;
+10 ; Return Values:
+11 ; <0 Error Code
+12 ; 0 Ok
+13 ;
INIT(ROR8FILE) ;
+1 NEW TMP
KILL RORHL
+2 DO INIT^HLFNC2(ROREXT("HL7PROT"),.RORHL)
+3 if $GET(RORHL)
QUIT $$ERROR^RORERR(-23,,RORHL)
+4 SET TMP=$GET(RORHL("ECH"))
+5 if $LENGTH(TMP)<4
QUIT $$ERROR^RORERR(-75)
+6 ;--- Initialize the nodes required for the API's
+7 if $GET(ROR8FILE)'=""
SET ROREXT("HL7BUF")=ROR8FILE
+8 if $GET(ROREXT("HL7BUF"))'=""
Begin DoDot:1
+9 SET ROREXT("HL7PTR")=+$ORDER(@ROREXT("HL7BUF")@(""),-1)
End DoDot:1
+10 QUIT 0
+11 ;
+12 ;***** CHECKS IF MAXIMUM BATCH SIZE IS REACHED
+13 ;
+14 ; [RESERVE] Number of bytes reserved in the batch (0 by default)
+15 ;
+16 ; Return Values:
+17 ; 0 Messages can be added to the batch
+18 ; 1 Maximum size of the batch has been reached
+19 ;
ISMAXSZ(RESERVE) ;
+1 if $GET(ROREXT("MAXHL7SIZE"))'>0
QUIT 0
+2 if ($GET(ROREXT("HL7SIZE"))+$GET(RESERVE))<ROREXT("MAXHL7SIZE")
QUIT 0
+3 SET $PIECE(ROREXT("HL7SIZE"),U,2)=1
+4 QUIT 1
+5 ;
+6 ;***** RETURNS NUMBER OF MESSAGES IN THE CURRENT BATCH
MSGCNT() ;
+1 QUIT $GET(ROREXT("HL7CNT"))
+2 ;
+3 ;***** RETURNS THE POINTER TO LAST SEGMENT IN THE MESSAGE BUFFER
PTR() QUIT +$GET(ROREXT("HL7PTR"))
+1 ;
+2 ;***** DELETES THE SEGMENTS FROM THE HL7 MESSAGE BUFFER
+3 ;
+4 ; SEGPTR An index of the HL7 segment in the message buffer
+5 ;
+6 ; [KEEP] Keep the segment referenced by the SEGPTR and start
+7 ; the rollback from the next segment.
+8 ;
ROLLBACK(SEGPTR,KEEP) ;
+1 NEW BUF,I,I1,MSH,NODE,SEGNAME
+2 SET NODE=ROREXT("HL7BUF")
SET HLFS=$GET(RORHL("FS"),"|")
+3 SET I=$SELECT($GET(KEEP):$ORDER(@NODE@(SEGPTR)),1:+SEGPTR)
+4 SET MSH=$SELECT(I>0:$PIECE($GET(@NODE@(I)),HLFS)="MSH",1:0)
+5 ;---
+6 FOR
if I'>0
QUIT
Begin DoDot:1
+7 SET BUF=$GET(@NODE@(I))
+8 ;--- Decrement the batch size indicator
+9 SET ROREXT("HL7SIZE")=$GET(ROREXT("HL7SIZE"))-$LENGTH(BUF)-1
+10 SET I1=""
+11 FOR
SET I1=$ORDER(@NODE@(I,I1))
if I1=""
QUIT
Begin DoDot:2
+12 SET ROREXT("HL7SIZE")=ROREXT("HL7SIZE")-$LENGTH(@NODE@(I,I1))
End DoDot:2
+13 ;--- Decrement the 'Set ID' counter if necessary
+14 SET SEGNAME=$PIECE(BUF,HLFS)
SET I1=+$GET(ROREXT("HL7SID",SEGNAME))
+15 IF I1>0
if $PIECE(BUF,HLFS,2)>0
SET ROREXT("HL7SID",SEGNAME)=I1-1
+16 ;--- Delete the segment
+17 KILL @NODE@(I)
End DoDot:1
SET I=$ORDER(@NODE@(I))
+18 ;--- Validate current size of the batch
+19 if $GET(ROREXT("HL7SIZE"))<0
SET ROREXT("HL7SIZE")=0
+20 ;--- Decrease number of messages in the batch if necessary
+21 IF MSH
if $GET(ROREXT("HL7CNT"))>0
SET ROREXT("HL7CNT")=ROREXT("HL7CNT")-1
+22 QUIT
+23 ;
+24 ;***** SENDS THE BATCH MESSAGE
+25 ;
+26 ; .MID Reference to a local variable where the batch
+27 ; message ID (returned by the GENERATE^HLMA) is
+28 ; returned to.
+29 ;
+30 ; Return Values:
+31 ; <0 Error Code
+32 ; 0 Ok
+33 ; >0 There was nothing to send
+34 ;
+35 ; Several nodes (HL7*) in the ROREXT and the ^TMP("HLS",$J) node
+36 ; are deleted by this entry point.
+37 ;
SEND(MID) ;
+1 NEW RC,RORBUF,RORHLP
SET MID=""
+2 if $GET(ROREXT("HL7PROT"))=""
QUIT $$ERROR^RORERR(-25)
+3 ;--- Quit if there is nothing to send
+4 if '$GET(ROREXT("HL7MTIEN"))!($DATA(^TMP("HLS",$JOB))<10)
QUIT 1
+5 ;--- Set up the HL7 environment variables
+6 DO INIT^HLFNC2(ROREXT("HL7PROT"),.RORHL)
+7 if $GET(RORHL)
QUIT $$ERROR^RORERR(-23,,RORHL)
+8 ;--- Send the message
+9 SET RORHLP("NAMESPACE")="ROR"
+10 DO GENERATE^HLMA(ROREXT("HL7PROT"),"GB",1,.RORBUF,ROREXT("HL7MTIEN"),.RORHLP)
+11 SET RC=$SELECT($PIECE(RORBUF,U,2):$$ERROR^RORERR(-24,,RORBUF),1:0)
+12 SET MID=$PIECE(RORBUF,U)
+13 ;--- Cleanup if there is no error or not in debug mode
+14 if '$GET(RORPARM("DEBUG"))!(RC'<0)
Begin DoDot:1
+15 FOR TMP="HL7CNT","HL7MTIEN","HL7SIZE"
KILL ROREXT(TMP)
+16 KILL ^TMP("HLS",$JOB)
End DoDot:1
+17 QUIT RC