git-svn-id: https://svn.coded.pt/svn/SIPRP@1005 bb69d46d-e84e-40c8-a05a-06db0d633741

lxbfYeaa
João Neto 17 years ago
parent 1632419bb3
commit 6c46ac7f14

Binary file not shown.

@ -62,7 +62,7 @@ import com.evolute.utils.ui.window.LoginWindow;
public class Main implements com.evolute.utils.ui.window.Connector public class Main implements com.evolute.utils.ui.window.Connector
{ {
public final static String SHST_VERSION = "11.1.2"; public final static String SHST_VERSION = "11.1.3";
private final static ClassLoader classLoader = new EVUtilsImageLib().getClass().getClassLoader(); private final static ClassLoader classLoader = new EVUtilsImageLib().getClass().getClassLoader();
@ -121,7 +121,7 @@ public class Main implements com.evolute.utils.ui.window.Connector
// new IBookDataLoader().load(); // new IBookDataLoader().load();
dbase = (String)Singleton.getInstance( SingletonConstants.LOCAL_DB_NAME ); dbase = (String)Singleton.getInstance( SingletonConstants.LOCAL_DB_NAME );
dbase = "siprp_local3"; // dbase = "siprp_local3";
/* Calendar cal = Calendar.getInstance(); /* Calendar cal = Calendar.getInstance();
cal.set( 2004, 06, 14 ); cal.set( 2004, 06, 14 );
if( cal.before( Calendar.getInstance() ) ) if( cal.before( Calendar.getInstance() ) )
@ -214,7 +214,7 @@ public class Main implements com.evolute.utils.ui.window.Connector
{ {
//server = "192.168.1.191"; //server = "192.168.1.191";
server = (String)Singleton.getInstance( SingletonConstants.LOCAL_URL ); server = (String)Singleton.getInstance( SingletonConstants.LOCAL_URL );
server = "storage"; // server = "storage";
// server = "ws_fpalma"; // server = "ws_fpalma";
} }
String prefix = (String)Singleton.getInstance( SingletonConstants.LOCAL_URL_PREFIX ); String prefix = (String)Singleton.getInstance( SingletonConstants.LOCAL_URL_PREFIX );

@ -38,7 +38,7 @@ public class LegislacaoAplicavelToPrint
{ {
Element diplomaElement = new Element( "diploma" ); Element diplomaElement = new Element( "diploma" );
diplomaElement.setText( diploma ); diplomaElement.setText( diploma );
legislacaoAplicavelElement.addContent( diploma ); legislacaoAplicavelElement.addContent( diplomaElement );
} }
return legislacaoAplicavelElement; return legislacaoAplicavelElement;
} }

@ -6,6 +6,7 @@ import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import org.jdom.Document; import org.jdom.Document;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter; import org.jdom.output.XMLOutputter;
import siprp.Main; import siprp.Main;
@ -20,9 +21,11 @@ public class PlanoActuacaoPDFCreator
{ {
PlanoActuacaoToPrint plano = PlanoActuacaoPrintDataProvider.getProvider( web ).getPlanoToPrint( planoId ); PlanoActuacaoToPrint plano = PlanoActuacaoPrintDataProvider.getProvider( web ).getPlanoToPrint( planoId );
Document foDoc = new Document( plano.toJdomElement() ); Document foDoc = new Document( plano.toJdomElement() );
XMLOutputter outputter = new XMLOutputter(); XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
ByteArrayOutputStream foBaos = new ByteArrayOutputStream(); ByteArrayOutputStream foBaos = new ByteArrayOutputStream();
outputter.output( foDoc, foBaos ); outputter.output( foDoc, foBaos );
byte fo[] = byte fo[] =
applyTemplate( applyTemplate(
getClass().getClassLoader().getResourceAsStream( getClass().getClassLoader().getResourceAsStream(
@ -32,8 +35,8 @@ public class PlanoActuacaoPDFCreator
new ByteArrayInputStream( foBaos.toByteArray() ) ); new ByteArrayInputStream( foBaos.toByteArray() ) );
FileOutputStream fos = new FileOutputStream("/home/jneto/Desktop/a.fo"); // FileOutputStream fos = new FileOutputStream("/home/jneto/Desktop/a.fo");
fos.write(fo); // fos.write(fo);
PDFCreator.setUserConfig(Main.fopConfigFile); PDFCreator.setUserConfig(Main.fopConfigFile);

@ -179,33 +179,75 @@ public class PlanoActuacaoPrintDataProvider
return array.columnLength() > 0 ? ( Integer ) array.get( 0, 0 ) : null; return array.columnLength() > 0 ? ( Integer ) array.get( 0, 0 ) : null;
} }
// public LegislacaoAplicavelToPrint getLegislacaoAplicavel( Integer planoId )
// throws Exception
// {
// Select select =
// new Select2(
// new String[]{ "hs_relatorio_legislacao" },
// new Integer[]{},
// new Expression[]{},
// new String[]{ "hs_relatorio_legislacao.categoria", "hs_relatorio_legislacao.descricao" },
// new Field( "hs_relatorio_legislacao.hs_relatorio_id" ).isEqual( planoId ).and(
// new Field( "hs_relatorio_legislacao.categoria" ).isEqual( null ) ),
// null,
// null,
// null,
// null );
// Virtual2DArray array = LOCAL_EXECUTER.executeQuery( select );
// Vector<String> diplomas = new Vector<String>();
// for( int n = 0; n < array.columnLength(); n++ )
// {
// String descricao = ( String ) array.get( n, 0 );
// diplomas.add( descricao );
// }
// LegislacaoAplicavelToPrint legislacao =
// new LegislacaoAplicavelToPrint( diplomas );
//
// return legislacao;
// }
public LegislacaoAplicavelToPrint getLegislacaoAplicavel( Integer planoId ) public LegislacaoAplicavelToPrint getLegislacaoAplicavel( Integer planoId )
throws Exception throws Exception
{
Select select =
new Select2(
new String[]{ "hs_relatorio_legislacao" },
new Integer[]{},
new Expression[]{},
new String[]{ "hs_relatorio_legislacao.categoria", "hs_relatorio_legislacao.descricao" },
new Field( "hs_relatorio_legislacao.hs_relatorio_id" ).isEqual( planoId ),
new String[]{ "hs_relatorio_legislacao.categoria DESC" },
null,
null,
null );
Virtual2DArray array = LOCAL_EXECUTER.executeQuery( select );
Vector<String> diplomasGerais = new Vector<String>();
Vector<String> nomes = new Vector<String>();
Vector<Vector<String>> diplomas = new Vector<Vector<String>>();
String last = null;
for( int n = 0; n < array.columnLength(); n++ )
{ {
Select select = String categoria = ( String ) array.get( n, 0 );
new Select2( String descricao = ( String ) array.get( n, 1 );
new String[]{ "hs_relatorio_legislacao" }, if( categoria == null || categoria.trim().length() == 0 )
new Integer[]{},
new Expression[]{},
new String[]{ "hs_relatorio_legislacao.categoria", "hs_relatorio_legislacao.descricao" },
new Field( "hs_relatorio_legislacao.hs_relatorio_id" ).isEqual( planoId ).and(
new Field( "hs_relatorio_legislacao.categoria" ).isEqual( null ) ),
null,
null,
null,
null );
Virtual2DArray array = LOCAL_EXECUTER.executeQuery( select );
Vector<String> diplomas = new Vector<String>();
for( int n = 0; n < array.columnLength(); n++ )
{ {
String descricao = ( String ) array.get( n, 0 ); diplomasGerais.add( descricao );
diplomas.add( descricao ); }
else
{
if( !categoria.equals( last ) )
{
nomes.add( categoria );
diplomas.add( new Vector<String>() );
}
diplomas.lastElement().add( descricao );
} }
LegislacaoAplicavelToPrint legislacao =
new LegislacaoAplicavelToPrint( diplomas );
return legislacao;
} }
LegislacaoAplicavelToPrint legislacao =
new LegislacaoAplicavelToPrint( diplomasGerais);
return legislacao;
}
public Vector<AreaToPrint> getAreasToPrintByPlanoId( Integer planoId, boolean validacaoDl, boolean validacaoDns ) public Vector<AreaToPrint> getAreasToPrintByPlanoId( Integer planoId, boolean validacaoDl, boolean validacaoDns )
throws Exception throws Exception
@ -303,7 +345,7 @@ public class PlanoActuacaoPrintDataProvider
riscos.add( riscos.add(
new RiscoToPrint( new RiscoToPrint(
descricao, descricao,
valor, valor+"",
getMedidasToPrintByRiscoId( id ), getMedidasToPrintByRiscoId( id ),
responsavelExecucao, responsavelExecucao,
recursosNecessarios, recursosNecessarios,
@ -318,17 +360,18 @@ public class PlanoActuacaoPrintDataProvider
{ {
Select select = Select select =
new Select2( new Select2(
new String[]{ "hs_relatorio_risco", "hs_relatorio_posto_risco", "hs_relatorio_posto" }, new String[]{ "hs_relatorio_risco", "hs_relatorio_posto_risco", "hs_relatorio_posto", "hs_relatorio_risco_valor_qualitativo" },
new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER }, new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_LEFT_OUTER },
new Expression[]{ new Expression[]{
new Field( "hs_relatorio_risco.id" ).isEqual( new Field( "hs_relatorio_posto_risco.risco_id" ) ), new Field( "hs_relatorio_risco.id" ).isEqual( new Field( "hs_relatorio_posto_risco.risco_id" ) ),
new Field( "hs_relatorio_posto_risco.posto_id" ).isEqual( new Field( "hs_relatorio_posto.id" ) ) new Field( "hs_relatorio_posto_risco.posto_id" ).isEqual( new Field( "hs_relatorio_posto.id" ) ),
new Field( "hs_relatorio_posto_risco.valor_qualitativo_id" ).isEqual(new Field("hs_relatorio_risco_valor_qualitativo.id"))
}, },
new String[]{ "hs_relatorio_risco.id", new String[]{ "hs_relatorio_risco.id",
"hs_relatorio_risco.description", "hs_relatorio_risco.description",
"hs_relatorio_posto_risco.probabilidade * hs_relatorio_posto_risco.severidade", "hs_relatorio_posto_risco.probabilidade * hs_relatorio_posto_risco.severidade",
"null", "hs_relatorio_risco_valor_qualitativo.description",
"null", "hs_relatorio_posto.id",
"null", "null",
"null", "null",
"null", "null",
@ -344,32 +387,47 @@ public class PlanoActuacaoPrintDataProvider
array = LOCAL_EXECUTER.executeQuery( select ); array = LOCAL_EXECUTER.executeQuery( select );
Vector<String> riscosVector = new Vector<String>(); Vector<String> riscosVector = new Vector<String>();
HashMap<String,Vector<Integer>> riscosIdMap = new HashMap<String,Vector<Integer>>(); HashMap<String,Vector<Integer>> riscosIdMap = new HashMap<String,Vector<Integer>>();
HashMap<Integer,Integer> riscoPostoMap = new HashMap<Integer, Integer>();
for( int n = 0; n < array.columnLength(); n++ ) for( int n = 0; n < array.columnLength(); n++ )
{ {
Integer id = ( Integer ) array.get( n, 0 ); Integer id = ( Integer ) array.get( n, 0 );
String descricao = ( String ) array.get( n, 1 ); String descricao = ( String ) array.get( n, 1 );
Integer risco = ( Integer ) array.get( n, 2 ); Integer risco = ( Integer ) array.get( n, 2 );
if( risco == null ) String risco_qual = ((String) array.get( n, 3));
{ if(risco_qual!=null){
risco_qual = risco_qual.substring(0, 3).toUpperCase();
}
Integer posto = ( Integer ) array.get( n, 4 );
String finalRisco;
if(risco!=null){
finalRisco = ""+risco;
}else if(risco_qual!=null){
finalRisco = ""+risco_qual;
}else{
continue; continue;
} }
String key = descricao + "_" + risco;
String key = descricao + "_" + finalRisco;
if( !riscosIdMap.containsKey( key ) ) if( !riscosIdMap.containsKey( key ) )
{ {
riscosIdMap.put( key, new Vector<Integer>() ); riscosIdMap.put( key, new Vector<Integer>() );
riscosVector.add( key ); riscosVector.add( key );
} }
riscosIdMap.get( key ).add( id ); riscosIdMap.get( key ).add( id );
riscoPostoMap.put(id, posto);
} }
for( String risco : riscosVector ) for( String risco : riscosVector )
{ {
int index = risco.lastIndexOf( "_" ); int index = risco.lastIndexOf( "_" );
String descricao = risco.substring( 0, index ); String descricao = risco.substring( 0, index );
Integer valor = new Integer( risco.substring( index + 1, risco.length() ) ); String valor = risco.substring( index + 1, risco.length() ) ;
Vector<MedidaToPrint> medidas = new Vector<MedidaToPrint>(); Vector<MedidaToPrint> medidas = new Vector<MedidaToPrint>();
for( Integer id : riscosIdMap.get( risco ) ) for( Integer id : riscosIdMap.get( risco ) )
{ {
medidas.addAll( getMedidasToPrintByRiscoId( id ) ); Integer posto = riscoPostoMap.get(id);
medidas.addAll( getMedidasToPrintByRiscoId( id , posto) );
} }
if( medidas.size() > 0 ) if( medidas.size() > 0 )
{ {
@ -392,7 +450,11 @@ public class PlanoActuacaoPrintDataProvider
return riscos; return riscos;
} }
public Vector<MedidaToPrint> getMedidasToPrintByRiscoId( Integer riscoId ) public Vector<MedidaToPrint> getMedidasToPrintByRiscoId( Integer riscoId) throws Exception{
return getMedidasToPrintByRiscoId(riscoId, null);
}
public Vector<MedidaToPrint> getMedidasToPrintByRiscoId( Integer riscoId, Integer posto )
throws Exception throws Exception
{ {
Vector<MedidaToPrint> medidas = new Vector<MedidaToPrint>(); Vector<MedidaToPrint> medidas = new Vector<MedidaToPrint>();
@ -414,15 +476,21 @@ public class PlanoActuacaoPrintDataProvider
} }
else else
{ {
Expression filter = new Field( "hs_relatorio_medida.risco_id" ).isEqual( riscoId ).and(
new Field( "hs_relatorio_medida.deleted_date" ).isEqual( null ) )
.and(new Field("hs_relatorio_medida.description").isDifferent(""));
if(posto!=null){
filter = filter.and(new Field("hs_relatorio_posto_medida.posto_id").isEqual(posto));
}
Select select = Select select =
new Select2( new Select2(
new String[]{ "hs_relatorio_medida" }, new String[]{"hs_relatorio_medida", "hs_relatorio_posto_medida"},
new Integer[]{}, new Integer[]{Select2.JOIN_INNER},
new Expression[]{}, new Expression[]{new Field("hs_relatorio_medida.id").isEqual(new Field("hs_relatorio_posto_medida.medida_id"))},
new String[]{ "hs_relatorio_medida.id", "hs_relatorio_medida.description" }, new String[]{ "hs_relatorio_medida.id", "hs_relatorio_medida.description", "hs_relatorio_posto_medida.is_plano_actuacao" },
new Field( "hs_relatorio_medida.risco_id" ).isEqual( riscoId ).and( filter,
new Field( "hs_relatorio_medida.deleted_date" ).isEqual( null ) )
.and(new Field("hs_relatorio_medida.description").isDifferent("")),
new String[]{ "hs_relatorio_medida.id" }, new String[]{ "hs_relatorio_medida.id" },
null, null,
null, null,
@ -433,8 +501,9 @@ public class PlanoActuacaoPrintDataProvider
{ {
Integer id = ( Integer ) array.get( n, 0 ); Integer id = ( Integer ) array.get( n, 0 );
String descricao = ( String ) array.get( n, 1 ); String descricao = ( String ) array.get( n, 1 );
Boolean isPlanoActuacao = ( Boolean ) array.get( n, 2 );
Vector<PostoToPrint> postos = getPostosToPrintByMedidaId( id ); Vector<PostoToPrint> postos = getPostosToPrintByMedidaId( id );
if( postos.size() > 0 ) if( postos.size() > 0 && isPlanoActuacao)
{ {
medidas.add( new MedidaToPrint( descricao, postos ) ); medidas.add( new MedidaToPrint( descricao, postos ) );
} }

@ -8,7 +8,7 @@ public class RiscoToPrint
implements PrintableInterface implements PrintableInterface
{ {
protected String descricao; protected String descricao;
protected Integer valor; protected String valor;
protected Vector<MedidaToPrint> medidas; protected Vector<MedidaToPrint> medidas;
protected String responsavel; protected String responsavel;
protected String recursos; protected String recursos;
@ -18,7 +18,7 @@ public class RiscoToPrint
protected String parecerDns; protected String parecerDns;
protected String verificacaoSiprp; protected String verificacaoSiprp;
public RiscoToPrint( String descricao, Integer valor, public RiscoToPrint( String descricao, String valor,
Vector<MedidaToPrint> medidas, String responsavel, String recursos, Vector<MedidaToPrint> medidas, String responsavel, String recursos,
DataToPrint dataPrevistaInicio, DataToPrint dataPrevistaConclusao, DataToPrint dataPrevistaInicio, DataToPrint dataPrevistaConclusao,
String parecerDl, String parecerDns, String verificacaoSiprp ) String parecerDl, String parecerDns, String verificacaoSiprp )
@ -86,12 +86,12 @@ public class RiscoToPrint
this.descricao = descricao; this.descricao = descricao;
} }
public Integer getValor() public String getValor()
{ {
return valor; return valor;
} }
public void setValor( Integer valor ) public void setValor( String valor )
{ {
this.valor = valor; this.valor = valor;
} }

@ -91,8 +91,8 @@
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <!-- fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block-->
<fo:block font-size="12pt" text-align="center"> <fo:block font-size="12pt" text-align="center">
<!-- <fo:external-graphic--> <!-- <fo:external-graphic-->
<!-- src="url('http://www.evolute.pt/~siprp/planoactuacao/auchan_jumbo_lado.jpg')"--> <!-- src="url('http://www.evolute.pt/~siprp/planoactuacao/auchan_jumbo_lado.jpg')"-->
@ -146,7 +146,7 @@
<fo:flow flow-name="xsl-region-body"> <fo:flow flow-name="xsl-region-body">
<fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block> <fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block>
<fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block> <fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block>
<fo:block font-size="16pt" text-decoration="underline" font-weight="bold" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in">ÍNDICE  </fo:block> <fo:block font-size="16pt" text-decoration="underline" font-weight="bold" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in">ÍNDICE</fo:block>
<fo:block text-align-last="justify" line-height="17pt" font-size="14pt" space-after="3pt" text-align="start" text-indent="0cm"> <fo:block text-align-last="justify" line-height="17pt" font-size="14pt" space-after="3pt" text-align="start" text-indent="0cm">
<fo:basic-link internal-destination="N67898">1. OBJECTIVO</fo:basic-link> <fo:basic-link internal-destination="N67898">1. OBJECTIVO</fo:basic-link>
<fo:leader leader-pattern="dots" leader-pattern-width="5pt" /> <fo:leader leader-pattern="dots" leader-pattern-width="5pt" />
@ -574,7 +574,7 @@
</fo:table-row> </fo:table-row>
</fo:table-body> </fo:table-body>
</fo:table> </fo:table>
<fo:block font-size="13pt" text-align="justify"> </fo:block> <fo:block break-before="page"> </fo:block>
<fo:block font-size="13pt" text-align="justify">A determinação da valoração do risco permite <fo:block font-size="13pt" text-align="justify">A determinação da valoração do risco permite
hierarquizar as intervenções, definir as acções hierarquizar as intervenções, definir as acções
e estabelecer prazos de execução, como se e estabelecer prazos de execução, como se

@ -91,8 +91,8 @@
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <!-- fo:block font-size="12pt"> </fo:block>
<fo:block font-size="12pt"> </fo:block> <fo:block font-size="12pt"> </fo:block-->
<fo:block font-size="12pt" text-align="center"> <fo:block font-size="12pt" text-align="center">
<!-- <fo:external-graphic--> <!-- <fo:external-graphic-->
<!-- src="url('http://www.evolute.pt/~siprp/planoactuacao/auchan_jumbo_lado.jpg')"--> <!-- src="url('http://www.evolute.pt/~siprp/planoactuacao/auchan_jumbo_lado.jpg')"-->
@ -147,7 +147,7 @@
<fo:flow flow-name="xsl-region-body"> <fo:flow flow-name="xsl-region-body">
<fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block> <fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block>
<fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block> <fo:block font-size="11pt" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in"> </fo:block>
<fo:block font-size="16pt" text-decoration="underline" font-weight="bold" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in">ÍNDICE  </fo:block> <fo:block font-size="16pt" text-decoration="underline" font-weight="bold" margin-right="0in" text-indent="-0.1972in" text-align="center" line-height="130%" margin-left="0.1972in">ÍNDICE</fo:block>
<fo:block text-align-last="justify" line-height="17pt" font-size="14pt" space-after="3pt" text-align="start" text-indent="0cm"> <fo:block text-align-last="justify" line-height="17pt" font-size="14pt" space-after="3pt" text-align="start" text-indent="0cm">
<fo:basic-link internal-destination="N67898">1. OBJECTIVO</fo:basic-link> <fo:basic-link internal-destination="N67898">1. OBJECTIVO</fo:basic-link>
<fo:leader leader-pattern="dots" leader-pattern-width="5pt" /> <fo:leader leader-pattern="dots" leader-pattern-width="5pt" />
@ -576,6 +576,7 @@
</fo:table-body> </fo:table-body>
</fo:table> </fo:table>
<fo:block font-size="13pt" text-align="justify"> </fo:block> <fo:block font-size="13pt" text-align="justify"> </fo:block>
<fo:block font-size="12pt" margin-right="-0.0146in" text-indent="-0.1972in" text-align="justify" line-height="150%" break-before="page" margin-left="0.1972in" margin-top="0.0835in" margin-bottom="0.0835in"> </fo:block>
<fo:block font-size="13pt" text-align="justify">A determinação da valoração do risco permite <fo:block font-size="13pt" text-align="justify">A determinação da valoração do risco permite
hierarquizar as intervenções, definir as acções hierarquizar as intervenções, definir as acções
e estabelecer prazos de execução, como se e estabelecer prazos de execução, como se

Loading…
Cancel
Save