public static IGetSDMX GetSdmxImplementation(EndpointSettings endpoint)
        {
            IGetSDMX obj = null;

            try
            {
                switch (endpoint._TypeEndpoint)
                {
                case ISTAT.WebClient.WidgetComplements.Model.Enum.EndpointType.V20:
                    obj = new GetSDMX_WSV20(endpoint);
                    break;

                case ISTAT.WebClient.WidgetComplements.Model.Enum.EndpointType.V21:
                    obj = new GetSDMX_WSV21(endpoint);
                    break;

                case ISTAT.WebClient.WidgetComplements.Model.Enum.EndpointType.REST:
                    obj = new GetSDMX_WSRest(endpoint);
                    break;
                }
            }
            catch { }

            return(obj);
        }
        public static void GetDataSetStream(IDataSetRenderer renderer, DataObjectForStreaming dataStream, TextWriter streamResponse)
        {
            EndpointSettings DataObjConfiguration = dataStream.Configuration;

            IDataStructureObject kf = dataStream.structure.DataStructures.First();

            //DataObjectForStreaming
            SDMXWSFunction op = SDMXWSFunction.GetCompactData;
            //DataObjConfiguration

            bool cross = (DataObjConfiguration._TypeEndpoint == EndpointType.V21 || DataObjConfiguration._TypeEndpoint == EndpointType.REST)
                          ? NsiClientHelper.DataflowDsdIsCrossSectional(kf) : !Utils.IsTimeSeries(kf);

            if (cross)
            {
                op = SDMXWSFunction.GetCrossSectionalData;
            }
            var ser = new JavaScriptSerializer();

            ser.MaxJsonLength = int.MaxValue;
            try
            {
                IGetSDMX       GetSDMXObject = WebServiceSelector.GetSdmxImplementation(DataObjConfiguration);
                BaseDataObject BDO           = new BaseDataObject(DataObjConfiguration, @"c:\pippo.txt");


                //GetSDMXObject.ExecuteQuery(BDO.CreateQueryBean(_  df, kf, Criterias), op, FileTmpData);
                //GetSDMXObject.ExecuteQuery(BDO.CreateQueryBean(, kf, Criterias), op, FileTmpData);
            }
            catch (Exception ex)
            {
            }
            //throw new NotImplementedException();
        }
        public DOTSTAT_Widget(GetCodemapObject codemapObj, SessionImplObject sessionObj)
        {
            Org.Sdmxsource.Sdmx.Api.Exception.SdmxException.SetMessageResolver(new Org.Sdmxsource.Util.ResourceBundle.MessageDecoder());

            CodemapObj    = codemapObj;
            SessionObj    = sessionObj;
            GetSDMXObject = ISTAT.WebClient.WidgetEngine.Model.WebServiceSelector.GetSdmxImplementation(this.CodemapObj.Configuration);
        }
        public DOTSTAT_Widget(GetCodemapObject codemapObj, SessionImplObject sessionObj)
        {
            Org.Sdmxsource.Sdmx.Api.Exception.SdmxException.SetMessageResolver(new Org.Sdmxsource.Util.ResourceBundle.MessageDecoder());

            CodemapObj = codemapObj;
            SessionObj = sessionObj;
            GetSDMXObject = ISTAT.WebClient.WidgetEngine.Model.WebServiceSelector.GetSdmxImplementation(this.CodemapObj.Configuration);
        }
        public DataWidget(GetDataObject dataObj, SessionImplObject sessionObj, bool useAttr)
        {
            DataObj       = dataObj;
            SessionObj    = sessionObj;
            GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.DataObj.Configuration);
            BDO           = new BaseDataObject(dataObj.Configuration, System.IO.Path.GetTempFileName());

            this._useAttr = useAttr;
        }
        public DataWidget(GetDataObject dataObj, SessionImplObject sessionObj, bool useAttr)
        {
            DataObj = dataObj;
            SessionObj = sessionObj;
            GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.DataObj.Configuration);
            BDO = new BaseDataObject(dataObj.Configuration, System.IO.Path.GetTempFileName());

            this._useAttr = useAttr;
        }
        public CodemapWidget(GetCodemapObject codemapObj, SessionImplObject sessionObj)
        {
            CodemapObj = codemapObj;
            SessionObj = sessionObj;
            GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.CodemapObj.Configuration);

            if (this.SessionObj == null)
            {
                this.SessionObj = new SessionImplObject();
                this.SessionObj.SdmxObject = new SdmxObjectsImpl();
            }
        }
Beispiel #8
0
        public LayoutWidget(GetCodemapObject layoutObj, SessionImplObject sessionObj, SessionQuery sessionQuery)
        {
            LayObj     = layoutObj;
            SessionObj = sessionObj;

            if (sessionQuery._IGetSDMX == null || (sessionQuery._endpointSettings != null && this.LayObj.Configuration.EndPoint != sessionQuery._endpointSettings.EndPoint))
            {
                GetSDMXObject          = WebServiceSelector.GetSdmxImplementation(this.LayObj.Configuration);
                sessionQuery._IGetSDMX = GetSDMXObject;
            }
            else
            {
                GetSDMXObject = sessionQuery._IGetSDMX;
            }
        }
Beispiel #9
0
        public StreamResponseAction ExportSDMXQuery()
        {
            SessionQuery query = SessionQueryManager.GetSessionQuery(Session);

            //ControllerSupport CS = new ControllerSupport();
            //GetCodemapObject PostDataArrived = CS.GetPostData<GetCodemapObject>(this.Request);
            //PostDataArrived.Configuration.Locale = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;

            string request = "";
            var    xdoc    = new XmlDocument();

            EndpointSettings DataObjConfiguration = new EndpointSettings();

            DataObjConfiguration = query._endpointSettings;


            //IGetSDMX GetSDMXObject = WebServiceSelector.GetSdmxImplementation(DataObjConfiguration);
            IGetSDMX       GetSDMXObject = (query._IGetSDMX == null) ? WebServiceSelector.GetSdmxImplementation(DataObjConfiguration) : query._IGetSDMX;
            BaseDataObject BDO           = new BaseDataObject(DataObjConfiguration, "appo.xml");

            ISdmxObjects         structure = query.Structure;
            IDataflowObject      df        = structure.Dataflows.First();
            IDataStructureObject kf        = structure.DataStructures.First();
            IDataQuery           sdmxQuery = BDO.CreateQueryBean(df, kf, query.GetCriteria());

            GetSDMXObject.GetSdmxQuery(sdmxQuery, out request);

            string filename = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", query.Dataflow.Id, "xml");

            this.HttpContext.Response.Clear();
            this.HttpContext.Response.ContentType     = "text/xml";
            this.HttpContext.Response.ContentEncoding = Encoding.UTF8;
            string contentDisposition = string.Format(
                CultureInfo.InvariantCulture,
                Constants.AttachmentFilenameFormat,
                filename);

            this.HttpContext.Response.AddHeader(Constants.ContentDispositionHttpHeader, contentDisposition);



            this.HttpContext.Response.AddHeader("content-disposition", contentDisposition);
            this.HttpContext.Response.Write(request);
            this.HttpContext.Response.End();
            throw new NotImplementedException();
        }
        private ISdmxObjects GetSdmxObject(EndpointSettings endpointSettings, SessionQuery sessionQuery)
        {
            //   IGetSDMX GetSDMXObject = WebServiceSelector.GetSdmxImplementation(endpointSettings);
            IGetSDMX GetSDMXObject = null;

            if (sessionQuery._IGetSDMX == null || (sessionQuery._endpointSettings != null && endpointSettings.EndPoint != sessionQuery._endpointSettings.EndPoint))
            {
                GetSDMXObject          = WebServiceSelector.GetSdmxImplementation(endpointSettings);
                sessionQuery._IGetSDMX = GetSDMXObject;
            }
            else
            {
                GetSDMXObject = sessionQuery._IGetSDMX;
            }


            return(GetSDMXObject.RetrieveTree());
        }
        public DataWidget(GetDataObject dataObj, SessionImplObject sessionObj, bool useAttr, SessionQuery sessionQuery)
        {
            DataObj    = dataObj;
            SessionObj = sessionObj;

            if (sessionQuery._IGetSDMX == null || (sessionQuery._endpointSettings != null && this.DataObj.Configuration.EndPoint != sessionQuery._endpointSettings.EndPoint))
            {
                GetSDMXObject          = WebServiceSelector.GetSdmxImplementation(this.DataObj.Configuration);
                sessionQuery._IGetSDMX = GetSDMXObject;
            }
            else
            {
                GetSDMXObject = sessionQuery._IGetSDMX;
            }

            BDO = new BaseDataObject(dataObj.Configuration, System.IO.Path.GetTempFileName());

            this._useAttr = useAttr;
        }
Beispiel #12
0
        public void GetDataSet(IDataSetRenderer renderer, DataObjectForStreaming dataStream, TextWriter streamResponse, string endPointType, SessionQuery sessionQuery)
        {
            EndpointSettings DataObjConfiguration = dataStream.Configuration;

            IDataStructureObject kf = dataStream.structure.DataStructures.First();

            //DataObjectForStreaming
            SDMXWSFunction op = SDMXWSFunction.GetCompactData;
            //DataObjConfiguration

            bool cross = (DataObjConfiguration._TypeEndpoint == ISTAT.WebClient.WidgetComplements.Model.Enum.EndpointType.V21 || DataObjConfiguration._TypeEndpoint == ISTAT.WebClient.WidgetComplements.Model.Enum.EndpointType.REST)
                          ? NsiClientHelper.DataflowDsdIsCrossSectional(kf) : !Utils.IsTimeSeries(kf);

            if (cross)
            {
                op = SDMXWSFunction.GetCrossSectionalData;
            }
            var ser = new JavaScriptSerializer();

            ser.MaxJsonLength = int.MaxValue;
            try
            {
                //IGetSDMX GetSDMXObject = WebServiceSelector.GetSdmxImplementation(DataObjConfiguration);
                IGetSDMX       GetSDMXObject = (sessionQuery._IGetSDMX == null) ? WebServiceSelector.GetSdmxImplementation(DataObjConfiguration) : sessionQuery._IGetSDMX;
                BaseDataObject BDO           = new BaseDataObject(DataObjConfiguration, "tem.txt");

                string fullPath = Utils.App_Data_Path + @"\Download\" + GetFileName(_iD, "xml");

                IDataQuery query = BDO.CreateQueryBean(dataStream.structure.Dataflows.First(), kf, dataStream.Criterias);
                GetSDMXObject.ExecuteQuery(query, op, fullPath);

                //if (endPointType == "V21")
                //{
                //    SendAttachment(ConvertTo21(fullPath),GetFileName(_iD, "xml")) ;
                //    return;
                //}
                SendAttachmentFile(fullPath);
            }
            catch (Exception ex)
            {
            }
            //throw new NotImplementedException();
        }
        public ChartWidget(GetChartObject chartObj, SessionImplObject sessionObj, CultureInfo cFrom, CultureInfo cTo, SessionQuery sessionQuery)
        {
            ChartObj   = chartObj;
            SessionObj = sessionObj;
            //GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.ChartObj.Configuration);

            if (sessionQuery._IGetSDMX == null || (sessionQuery._endpointSettings != null && this.ChartObj.Configuration.EndPoint != sessionQuery._endpointSettings.EndPoint))
            {
                GetSDMXObject          = WebServiceSelector.GetSdmxImplementation(this.ChartObj.Configuration);
                sessionQuery._IGetSDMX = GetSDMXObject;
            }
            else
            {
                GetSDMXObject = sessionQuery._IGetSDMX;
            }


            BDO = new BaseDataObject(chartObj.Configuration, System.IO.Path.GetTempFileName());

            this.cFrom = cFrom;
            this.cTo   = cTo;
        }
        private ISdmxObjects GetSdmxObject(EndpointSettings endpointSettings)
        {
            IGetSDMX GetSDMXObject = WebServiceSelector.GetSdmxImplementation(endpointSettings);

            return(GetSDMXObject.RetrieveTree());
        }
        public int GetCountObservation(SessionQuery query)
        {
            ISdmxObjects structure = query.Structure;
            IDataflowObject df = structure.Dataflows.First();
            IDataStructureObject kf = structure.DataStructures.First();

            if (kf == null)
                throw new InvalidOperationException("DataStructure is not set");
            if (df == null)
                throw new InvalidOperationException("Dataflow is not set");

            var currentComponent = "CL_COUNT";

            IContentConstraintMutableObject criteria = new ContentConstraintMutableCore();
            criteria.Id = currentComponent;
            criteria.AddName("en", "english");
            criteria.AgencyId = "agency";
            ICubeRegionMutableObject region = new CubeRegionMutableCore();

            if (currentComponent != null)
            {
                IKeyValuesMutable keyValue = new KeyValuesMutableImpl();
                keyValue.Id = currentComponent;
                keyValue.AddValue(SpecialValues.DummyMemberValue);
                region.AddKeyValue(keyValue);

                if (query.Criteria != null)
                {
                    foreach (string costreintKey in query.Criteria.Keys)
                    {
                        if (costreintKey == currentComponent) continue;
                        if (costreintKey == kf.TimeDimension.Id)
                        {

                            // Qui considerare il caso in qui in CodemapObj.PreviusCostraint[costreintKey][0] ci sia solo un valore, ke equivale alla data da.
                            if (query.Criteria[costreintKey].Count > 1)
                            {
                                DateTime MinDate = GetDateTimeFromSDMXTimePeriod(query.Criteria[costreintKey][0].ToString(), 'M'); //DateTime.ParseExact(CodemapObj.PreviusCostraint[costreintKey][0].ToString(), "yyyy-MM-dd", CultureInfo.CurrentCulture, DateTimeStyles.None);
                                DateTime MaxDate = GetDateTimeFromSDMXTimePeriod(query.Criteria[costreintKey][1].ToString(), 'M'); //DateTime.ParseExact(CodemapObj.PreviusCostraint[costreintKey][1].ToString(), "yyyy-MM-dd", CultureInfo.CurrentCulture, DateTimeStyles.None);
                                //baco fabio
                                if (MinDate.CompareTo(MaxDate) > 0)
                                {
                                    criteria.StartDate = MaxDate;
                                    criteria.EndDate = MinDate;
                                }
                                else
                                {
                                    criteria.StartDate = MinDate;
                                    criteria.EndDate = MaxDate;
                                }

                            }
                        }
                        else
                        {
                            foreach (var code in query.Criteria[costreintKey])
                            {
                                IKeyValuesMutable _keyValue = new KeyValuesMutableImpl();
                                _keyValue.Id = costreintKey;
                                _keyValue.AddValue(code);
                                region.AddKeyValue(_keyValue);
                            }
                        }
                    }
                }

            }
            criteria.IncludedCubeRegion = region;

            GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.CodemapObj.Configuration);

            int count = GetSDMXObject.GetDataflowDataCount(df, criteria);

            return count;
        }
        internal IDataSetStore GetDataset(IDataflowObject df, IDataStructureObject kf, List <DataCriteria> Criterias, ref Dictionary <string, List <DataChacheObject> > DataCache, bool useAttr, SessionQuery query)
        {
            // if it is not time series then assume it is cross
            SDMXWSFunction op    = SDMXWSFunction.GetCompactData;
            bool           cross = (DataObjConfiguration._TypeEndpoint == EndpointType.V21 || DataObjConfiguration._TypeEndpoint == EndpointType.REST)
                          ? NsiClientHelper.DataflowDsdIsCrossSectional(kf) : !Utils.IsTimeSeries(kf);

            if (cross)
            {
                op = SDMXWSFunction.GetCrossSectionalData;
            }

            var ser = new JavaScriptSerializer();

            ser.MaxJsonLength = int.MaxValue;
            try
            {
                #region Connessione e Creazione DB SQLLite FABIO se nullo lo istanzio
                string   table         = null;
                IGetSDMX GetSDMXObject = (query._IGetSDMX == null) ? WebServiceSelector.GetSdmxImplementation(DataObjConfiguration) : query._IGetSDMX;
                GetSDMXObject.ExecuteQuery(CreateQueryBean(df, kf, Criterias), op, FileTmpData);

                #region Connessione e Creazione DB SQLLite
                table = Path.Combine(Utils.GetAppPath(), string.Format(CultureInfo.InvariantCulture, "{0}-{1}.sqlite", Utils.MakeKey(df).Replace("+", "_").Replace(".", ""), Guid.NewGuid()));
                string        ConnectionString = string.Format(CultureInfo.InvariantCulture, Constants.FileDBSettingsFormat, table);
                var           info             = new DBInfo(ConnectionString);
                string        tempTable        = "table_" + Utils.MakeKey(df).Replace("+", "_").Replace(".", "");
                IDataSetStore store            = new DataSetStoreDB(info, tempTable, kf, true, useAttr);
                #endregion

                using (var dataLocation = new FileReadableDataLocation(FileTmpData))
                {
                    switch (op)
                    {
                    case SDMXWSFunction.GetCompactData:
                        var compact       = new CompactDataReaderEngine(dataLocation, df, kf);
                        var readerCompact = new SdmxDataReader(kf, store);
                        readerCompact.ReadData(compact);
                        break;

                    case SDMXWSFunction.GetCrossSectionalData:
                        var dsdCrossSectional = (ICrossSectionalDataStructureObject)kf;
                        var crossSectional    = new CrossSectionalDataReaderEngine(dataLocation, dsdCrossSectional, df);
                        var reader            = new SdmxDataReader(kf, store);
                        reader.ReadData(crossSectional);
                        break;

                    default:
                        throw new ArgumentException(Resources.ExceptionUnsupported_operation + op.ToString(), "operation");
                    }
                }

                #endregion FABIO



                return(store);
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.Message, ex);
                throw ex;
            }
            finally
            {
                //delete the temporary file
                if (File.Exists(FileTmpData))
                {
                    File.Delete(FileTmpData);
                }
            }
        }
Beispiel #17
0
 public LayoutWidget(GetCodemapObject layoutObj, SessionImplObject sessionObj)
 {
     LayObj        = layoutObj;
     SessionObj    = sessionObj;
     GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.LayObj.Configuration);
 }
 public LayoutWidget(GetCodemapObject layoutObj, SessionImplObject sessionObj)
 {
     LayObj = layoutObj;
     SessionObj = sessionObj;
     GetSDMXObject = WebServiceSelector.GetSdmxImplementation(this.LayObj.Configuration);
 }
        internal IDataSetStore GetDataset(IDataflowObject df, IDataStructureObject kf, List <DataCriteria> Criterias, ref Dictionary <string, List <DataChacheObject> > DataCache, bool useAttr)
        {
            // if it is not time series then assume it is cross
            SDMXWSFunction op    = SDMXWSFunction.GetCompactData;
            bool           cross = (DataObjConfiguration._TypeEndpoint == EndpointType.V21 || DataObjConfiguration._TypeEndpoint == EndpointType.REST)
                          ? NsiClientHelper.DataflowDsdIsCrossSectional(kf) : !Utils.IsTimeSeries(kf);

            if (cross)
            {
                op = SDMXWSFunction.GetCrossSectionalData;
            }

            var ser = new JavaScriptSerializer();

            ser.MaxJsonLength = int.MaxValue;
            try
            {
                //commentato vecchio codice
                //IGetSDMX GetSDMXObject = WebServiceSelector.GetSdmxImplementation(DataObjConfiguration);
                //GetSDMXObject.ExecuteQuery(CreateQueryBean(df, kf, Criterias), op, FileTmpData);

                /*
                 #region Connessione e Creazione DB SQLLite
                 * string table = Path.Combine(Utils.GetAppPath(), string.Format(CultureInfo.InvariantCulture, "{0}-{1}.sqlite", Utils.MakeKey(df).Replace("+", "_").Replace(".", ""), Guid.NewGuid()));
                 * string ConnectionString = string.Format(CultureInfo.InvariantCulture, Constants.FileDBSettingsFormat, table);
                 * var info = new DBInfo(ConnectionString);
                 * string tempTable = "table_" + Utils.MakeKey(df).Replace("+", "_").Replace(".", "");
                 * IDataSetStore store = new DataSetStoreDB(info, tempTable, kf, true, useAttr);
                 #endregion
                 * fine vecchio codice*/

                //Salvo in Session

                /*
                 * if (DataCache == null)
                 *  DataCache = new Dictionary<string, List<DataChacheObject>>();
                 * if (!DataCache.ContainsKey(Utils.MakeKey(df)))
                 *  DataCache[Utils.MakeKey(df)] = new List<DataChacheObject>();
                 */
                //string table=null;
                //FABIO NEW
                //IDataSetStore store = FindDataCacheChart(df, kf, Criterias, ref DataCache, useAttr,out table);

                //if (store == null) store = GetDataset(df, kf, Criterias, ref DataCache, useAttr);
                #region Connessione e Creazione DB SQLLite FABIO se nullo lo istanzio
//                if (store == null)
//                {
                string   table         = null;
                IGetSDMX GetSDMXObject = WebServiceSelector.GetSdmxImplementation(DataObjConfiguration);
                GetSDMXObject.ExecuteQuery(CreateQueryBean(df, kf, Criterias), op, FileTmpData);

                #region Connessione e Creazione DB SQLLite
                table = Path.Combine(Utils.GetAppPath(), string.Format(CultureInfo.InvariantCulture, "{0}-{1}.sqlite", Utils.MakeKey(df).Replace("+", "_").Replace(".", ""), Guid.NewGuid()));
                string        ConnectionString = string.Format(CultureInfo.InvariantCulture, Constants.FileDBSettingsFormat, table);
                var           info             = new DBInfo(ConnectionString);
                string        tempTable        = "table_" + Utils.MakeKey(df).Replace("+", "_").Replace(".", "");
                IDataSetStore store            = new DataSetStoreDB(info, tempTable, kf, true, useAttr);
                #endregion

                using (var dataLocation = new FileReadableDataLocation(FileTmpData))
                {
                    switch (op)
                    {
                    case SDMXWSFunction.GetCompactData:
                        var compact       = new CompactDataReaderEngine(dataLocation, df, kf);
                        var readerCompact = new SdmxDataReader(kf, store);
                        readerCompact.ReadData(compact);
                        break;

                    case SDMXWSFunction.GetCrossSectionalData:
                        var dsdCrossSectional = (ICrossSectionalDataStructureObject)kf;
                        var crossSectional    = new CrossSectionalDataReaderEngine(dataLocation, dsdCrossSectional, df);
                        var reader            = new SdmxDataReader(kf, store);
                        reader.ReadData(crossSectional);
                        break;

                    default:
                        throw new ArgumentException(Resources.ExceptionUnsupported_operation + op.ToString(), "operation");
                    }
                }

//                }
                #endregion FABIO



                //using (var dataLocation = new FileReadableDataLocation(FileTmpData))
                //{
                //    switch (op)
                //    {
                //        case SDMXWSFunction.GetCompactData:
                //            var compact = new CompactDataReaderEngine(dataLocation, df, kf);
                //            var readerCompact = new SdmxDataReader(kf, store);
                //            readerCompact.ReadData(compact);
                //            break;

                //        case SDMXWSFunction.GetCrossSectionalData:
                //            var dsdCrossSectional = (ICrossSectionalDataStructureObject)kf;
                //            var crossSectional = new CrossSectionalDataReaderEngine(dataLocation, dsdCrossSectional, df);
                //            var reader = new SdmxDataReader(kf, store);
                //            reader.ReadData(crossSectional);
                //            break;

                //        default:
                //            throw new ArgumentException(Resources.ExceptionUnsupported_operation + op.ToString(), "operation");
                //    }
                //}



                /*
                 * Dictionary<string, List<string>> Criteri = new Dictionary<string, List<string>>();
                 * Criterias.ForEach(c => Criteri.Add(c.component, c.values));
                 * DataChacheObject dco = new DataChacheObject()
                 * {
                 *  Criterias = Criteri,
                 *  DBFileName = table,
                 * };
                 *
                 * //aggiunta da fabio
                 * DataCache[Utils.MakeKey(df)].Clear();
                 * //fine aggiunta fabio
                 * DataCache[Utils.MakeKey(df)].Add(dco);
                 */
                return(store);
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.Message, ex);
                throw ex;
            }
            finally
            {
                //delete the temporary file
                if (File.Exists(FileTmpData))
                {
                    File.Delete(FileTmpData);
                }
            }
        }