Exemplo n.º 1
0
        /// <summary>
        /// 添加一个单视野视觉配置参数
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cfg"></param>
        public void AddSingleVisionCfg(string name, JFSingleVisionCfgParam cfg)
        {
            if (null == cfg)
            {
                throw new ArgumentNullException("JFVisionManager.AddSingleVisionCfgParam(cfg) failed by cfg == null");
            }

            if (_lstSVCfgs.Contains(cfg))
            {
                throw new ArgumentException("JFVisionManager.AddSingleVisionCfgParam(cfg) failed by cfg had Contained-in!");
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("JFVisionManager.AddSingleVisionCfgParam(cfg) failed by cfg.Name is null or empty");
            }

            if (ContainSingleVisionCfgByName(name))
            {
                throw new ArgumentException("JFVisionManager.AddSingleVisionCfgParam(name ...) failed by name = " + name + " is Existed!");
            }

            cfg.Name = name;
            _lstSVCfgs.Add(cfg);
            _cfg.Save();
        }
Exemplo n.º 2
0
        /// <summary>
        /// 编辑/保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btEditSave_Click(object sender, EventArgs e)
        {
            if (tabControlCF1.SelectedIndex < 0)
            {
                return;
            }
            if (!isEditting)
            {
                TableLayoutPanel panel = tabControlCF1.SelectedTab.Controls[0] as TableLayoutPanel;
                if (0 == panel.Controls.Count)
                {
                    MessageBox.Show("没有可供编辑的参数项");
                    return;
                }
                foreach (UcJFParamEdit ucParam in panel.Controls)
                {
                    ucParam.IsValueReadOnly = false;
                }
                isEditting          = true;
                btEditSave.Text     = "保存";
                btCancel.Enabled    = true;
                btSaveAs.Enabled    = true;
                btAddItem.Enabled   = true;
                btDeletItem.Enabled = true;
            }
            else
            {
                TableLayoutPanel panel = tabControlCF1.SelectedTab.Controls[0] as TableLayoutPanel;
                foreach (UcJFParamEdit ucParam in panel.Controls)
                {
                    string paramName = ucParam.GetParamDesribe().DisplayName;
                    object paramVal;
                    if (!ucParam.GetParamValue(out paramVal))
                    {
                        MessageBox.Show("未能获取参数 Name = " + paramName);
                        return;
                    }
                    //_station.SetCfgParamValue(paramName, paramVal);
                    //ucParam.IsValueReadOnly = false;
                }

                foreach (UcJFParamEdit ucParam in panel.Controls)
                {
                    string paramName = ucParam.GetParamDesribe().DisplayName;
                    object paramVal;
                    ucParam.GetParamValue(out paramVal);
                    _cfg.SetItemValue(paramName, paramVal);//_station.SetCfgParamValue(paramName, paramVal);
                    ucParam.IsValueReadOnly = true;
                }
                _cfg.Save();

                isEditting          = false;
                btEditSave.Text     = "编辑";
                btCancel.Enabled    = false;
                btSaveAs.Enabled    = false;
                btAddItem.Enabled   = false;
                btDeletItem.Enabled = false;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 设置工站使能
        /// </summary>
        /// <param name="stationName"></param>
        /// <param name="enable"></param>
        public void SetStationEnabled(string stationName, bool enable)
        {
            if (!_initorStationNames().Contains(stationName))
            {
                throw new ArgumentException("stationName = \"" + stationName + "\" is not included by Station-Name List");
            }
            if (!_dictStationEnabled.ContainsKey(stationName))
            {
                _dictStationEnabled.Add(stationName, enable);
                return;
            }
            else
            {
                _dictStationEnabled[stationName] = enable;
            }
            IJFStation station = GetStation(stationName);

            if (enable)
            {
                station.WorkStatusChanged   += StationWorkStatusChanged;
                station.CustomStatusChanged += StationCustomStatusChanged;
                if (station is JFCmdWorkBase)
                {
                    (station as JFCmdWorkBase).WorkMsg2Outter += StationTxtMsg;
                }
                if (station is JFStationBase)
                {
                    (station as JFStationBase).EventCustomizeMsg    += StationCustomizeMsg;
                    (station as JFStationBase).EventProductFinished += StationProductFinished;
                }
            }
            else
            {
                station.WorkStatusChanged   -= StationWorkStatusChanged;
                station.CustomStatusChanged -= StationCustomStatusChanged;
                if (station is JFCmdWorkBase)
                {
                    (station as JFCmdWorkBase).WorkMsg2Outter -= StationTxtMsg;
                }

                if (station is JFStationBase)
                {
                    (station as JFStationBase).EventCustomizeMsg    -= StationCustomizeMsg;
                    (station as JFStationBase).EventProductFinished -= StationProductFinished;
                }
            }
            _cfg.Save();
        }
Exemplo n.º 4
0
        private void btSingleVisionCfgEdit_Click(object sender, EventArgs e)
        {
            JFXCfg cfg = new JFXCfg(); //序列化存储已测试
            List <JFSingleVisionCfgParam> _lst = new List <JFSingleVisionCfgParam>();
            JFSingleVisionCfgParam        cp1  = new JFSingleVisionCfgParam();

            //cp1.Name = "hehe";
            cp1.LightChnNames    = new string[] { "Light1", "Light2" };
            cp1.LightIntensities = new int[] { 11, 22 };
            //cp1.TestMethodFlowTxt = "测试方法流Demo";
            JFSingleVisionCfgParam cp2 = new JFSingleVisionCfgParam();

            //cp2.Name = "haha";
            cp2.LightChnNames    = new string[] { "Light3", "Light4" };
            cp2.LightIntensities = new int[] { 33, 44 };

            _lst.Add(cp1);
            _lst.Add(cp2);
            cfg.AddItem("SVCfgs", _lst, "单视野参数配置");
            cfg.Save("视觉配置Demo");


            JFXCfg cfg1 = new JFXCfg();

            cfg1.Load("视觉配置Demo", false);
            List <JFSingleVisionCfgParam> _lst1 = cfg1.GetItemValue("SVCfgs") as List <JFSingleVisionCfgParam>;
        }
Exemplo n.º 5
0
        /// <summary>
        /// 工站点位存取测试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btLoadSaveAxisPos_Click(object sender, EventArgs e)
        {
            JFXCfg cfg = new JFXCfg();

            cfg.Load("StationDemoPosTable.xml", true);
            List <JFMultiAxisPosition> maPoses = new List <JFMultiAxisPosition>();
            JFMultiAxisPosition        maPos1  = new JFMultiAxisPosition();

            maPos1.Name = "Pos1";
            maPos1.Positions.Add(JFAxisPos.Create("X", 1.23));
            maPos1.Positions.Add(JFAxisPos.Create("Y", 4.56));
            maPoses.Add(maPos1);
            JFMultiAxisPosition maPos2 = new JFMultiAxisPosition();

            maPos2.Name = "Pos2";
            maPos2.Positions.Add(JFAxisPos.Create("Y", 9.87));
            maPos2.Positions.Add(JFAxisPos.Create("Z", 6.54));
            maPoses.Add(maPos2);
            if (!cfg.ContainsItem("Positions"))
            {
                cfg.AddItem("Positions", maPoses);
            }
            else
            {
                cfg.SetItemValue("Positions", maPoses);
            }
            cfg.Save();

            JFXCfg cfgAnother = new JFXCfg();

            cfgAnother.Load("StationDemoPosTable.xml", false);
            List <JFMultiAxisPosition> maPoses1 = cfgAnother.GetItemValue("Positions") as List <JFMultiAxisPosition>;//测试OK,可获取
        }
Exemplo n.º 6
0
        public void Save()
        {
            if (!IsInitOK)
            {
                return;
            }
            JFXmlDictionary <string, List <string[]> > dctRecipesInCfg = _cfg.GetItemValue("Cate-Recipes") as JFXmlDictionary <string, List <string[]> >;

            foreach (string categoty in _dctRecipes.Keys)
            {
                Dictionary <string, JFCommonRecipe> dctMmry = _dctRecipes[categoty]; //所有recipe内存对象
                List <string[]> lstInCfg = dctRecipesInCfg[categoty];
                foreach (KeyValuePair <string, JFCommonRecipe> kv in dctMmry)
                {
                    foreach (string[] idAndTxt in lstInCfg)
                    {
                        if (idAndTxt[0] == kv.Key)
                        {
                            string xmlTxt  = null;
                            string typeTxt = null;
                            JFFunctions.ToXTString(kv.Value.Dict, out xmlTxt, out typeTxt);
                            idAndTxt[1] = xmlTxt;
                            break;
                        }
                    }
                }
            }
            _cfg.Save();
        }
Exemplo n.º 7
0
        public bool SetCurrRecipeID(string recipeID, out string errorInfo)
        {
            if (string.IsNullOrEmpty(recipeID))
            {
                errorInfo = "产品ID为null/空字串";
                return(false);
            }
            if (!CheckRecipeMgr(out errorInfo))
            {
                return(false);
            }

            JFDLAFRecipeManager rm = JFHubCenter.Instance.RecipeManager as JFDLAFRecipeManager;

            string[] allRecipeIDs = rm.AllRecipeIDsInCategoty(SCN_CategotyProd);
            if (null == allRecipeIDs || !allRecipeIDs.Contains(recipeID))
            {
                errorInfo = "产品ID:\"" + recipeID + "\"在配方管理器中不存在";
                return(false);
            }
            if (WorkStatus == JFWorkStatus.Running || WorkStatus == JFWorkStatus.Interactiving || WorkStatus == JFWorkStatus.Pausing)
            {
                errorInfo = "正在运行,不能修改产品ID";
                return(false);
            }

            IJFDataPool dp   = JFHubCenter.Instance.DataPool;
            bool        isOK = dp.SetItemValue(SDN_CurrRecipeID, recipeID);

            if (!isOK)
            {
                errorInfo = "写入数据池失败";
            }
            else
            {
                //将当前产品信息写入SystemCfg
                JFXCfg sysCfg = JFHubCenter.Instance.SystemCfg;
                if (sysCfg.ContainsItem(SCN_CurrentRecipeID))
                {
                    sysCfg.SetItemValue(SCN_CurrentRecipeID, recipeID); //将当前产品ID 加到配置项中
                    sysCfg.Save();
                }
                errorInfo = "Success";
            }
            return(isOK);
        }
Exemplo n.º 8
0
        public bool Save()
        {
            string path = @"BoxData.ini";

            JFXCfg cfg = new JFXCfg();
            int    i   = 0;

            foreach (var pair in Dir_Boxes)
            {
                Box item = pair.Value;
                cfg.SetItemValue("Box_" + i, item);
                i++;
            }
            Num = Dir_Boxes.Count;
            cfg.SetItemValue("Count", Num);

            cfg.Save(path);
            return(true);
        }
Exemplo n.º 9
0
        public bool SetCurrLotID(string lotID, out string errorInfo)
        {
            if (string.IsNullOrEmpty(lotID))
            {
                errorInfo = "LotID为null/空字串";
                return(false);
            }


            if (WorkStatus == JFWorkStatus.Running || WorkStatus == JFWorkStatus.Interactiving || WorkStatus == JFWorkStatus.Pausing)
            {
                errorInfo = "正在运行,不能修改LotID";
                return(false);
            }

            IJFDataPool dp   = JFHubCenter.Instance.DataPool;
            bool        isOK = dp.SetItemValue(SDN_CurrLotID, lotID);

            if (!isOK)
            {
                errorInfo = "LotID写入数据池失败";
            }
            else
            {
                //将当前产品信息写入SystemCfg
                JFXCfg sysCfg = JFHubCenter.Instance.SystemCfg;
                if (sysCfg.ContainsItem(SCN_CurrentLotID))
                {
                    sysCfg.SetItemValue(SCN_CurrentLotID, lotID); //将当前LotID 保存到配置项中
                    sysCfg.Save();
                }



                errorInfo = "Success";
            }
            return(isOK);
        }
Exemplo n.º 10
0
        private void button3_Click(object sender, EventArgs e)
        {
            bool isArray = typeof(List <int>).IsArray;                        //不是

            isArray = typeof(object[]).IsArray;                               //是

            Type bt     = typeof(List <int>).GetElementType();                //返回null
            bool isList = typeof(IList).IsAssignableFrom(typeof(List <int>)); //是

            bt = typeof(object[]).GetElementType();                           //可以获取

            Type t = typeof(string[]);

            SerializableAttribute[] sas = t.GetCustomAttributes(typeof(SerializableAttribute), false) as SerializableAttribute[];


            JFXCfg        cfg = new JFXCfg();
            List <object> lst = new List <object>();

            lst.Add(0);
            lst.Add(new string[] { "hehe", "haha" });
            cfg.AddItem("测试复合类型", lst);
            cfg.Save("测试CfgDemo.xml");
        }
Exemplo n.º 11
0
        /// <summary>
        /// 检查配置文件是否合规(如果缺少必要的数据项,则返回false)
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="isOpenOrCreate">如果文件不存在,是否创建</param>
        bool _CheckSysCfg(string filePath, bool isOpenOrCreate, out string errorInfo)
        {
            errorInfo = "";
            if (string.IsNullOrEmpty(filePath))
            {
                errorInfo = "文件名为空值(或空格)";
                return(false);
            }



            if (!File.Exists(filePath)) //文件不存在
            {
                if (!isOpenOrCreate)
                {
                    errorInfo = "文件不存在";
                    return(false);
                }
                try
                {
                    JFXCfg cfg = new JFXCfg();
                    cfg.Load(filePath, true);
                    cfg.AddItem(CK_ExpandDllFiles, new List <string>(), CT_DLL);
                    cfg.AddItem(CK_InitDevParams, new JFXmlSortedDictionary <string, List <object> >(), CT_DEV);
                    ////////////////////////////////////////////////
                    ///添加其他配置项初始化动作
                    ///
                    ///

                    cfg.Save();
                    return(true);
                }
                catch (Exception ex)
                {
                    errorInfo = ex.Message;
                    return(false);
                }

                //break;
            }
            else //文件已存在,检查格式(只检查必须项是否存在)
            {
                try
                {
                    bool          isCheckOK = true;
                    StringBuilder sbError   = new StringBuilder();
                    JFXCfg        cfg       = new JFXCfg();
                    cfg.Load(filePath, false);
                    if (!cfg.ContainsItem(CK_ExpandDllFiles))
                    {
                        sbError.Append("文件中不存在配置项:" + CK_ExpandDllFiles + "\n");
                        isCheckOK = false;
                    }

                    if (!cfg.ContainsItem(CK_InitDevParams))
                    {
                        sbError.Append("文件中不存在配置项:" + CK_InitDevParams + "\n");
                        isCheckOK = false;
                    }

                    ////////////////////////////////////////////////
                    ///添加其他配置项检查动作
                    ///
                    ///
                    if (!isCheckOK)
                    {
                        errorInfo = sbError.ToString();
                    }
                    return(isCheckOK);
                }
                catch (Exception ex)
                {
                    errorInfo = ex.Message;
                    return(false);
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>运动控制卡Compare Trigger初始化 </summary>
        internal void Open()
        {
            if (IsOpen)
            {
                return;
            }

            int StartAxisId = 0, TotalAxis = 0, CardName = 0;

            APS168.APS_get_first_axisId(BoardID, ref StartAxisId, ref TotalAxis);
            APS168.APS_get_card_name(BoardID, ref CardName);
            if (/*CardName != (Int32)APS_Define.DEVICE_NAME_PCI_825458 && */ CardName != (Int32)APS_Define.DEVICE_NAME_AMP_20408C)
            {
                throw new Exception(string.Format("AMP204MC.Initialize Failed :运动控制卡型号不是204C或208C!"));
            }

            if (CardName == (Int32)APS_Define.DEVICE_NAME_AMP_20408C && TotalAxis == 4)
            {
                TrigChannels    = 2;
                EncoderChannels = 4;
                for (int i = 0; i < TrigChannels; i++)
                {
                    if (!lcmpSource.ContainsKey(i))
                    {
                        lcmpSource.Add(i, (Int32)APS_Define.TGR_LCMP0_SRC + i);
                        tcmpSource.Add(i, (Int32)APS_Define.TGR_TCMP0_SRC + i);
                        tcmpDir.Add(i, (Int32)APS_Define.TGR_TCMP0_DIR + i);
                    }
                }
            }
            if (CardName == (Int32)APS_Define.DEVICE_NAME_AMP_20408C && TotalAxis == 8)
            {
                TrigChannels    = 4;
                EncoderChannels = 8;
                for (int i = 0; i < TrigChannels; i++)
                {
                    if (i < 2)
                    {
                        if (!lcmpSource.ContainsKey(i))
                        {
                            lcmpSource.Add(i, (Int32)APS_Define.TGR_LCMP0_SRC + i);
                            tcmpSource.Add(i, (Int32)APS_Define.TGR_TCMP0_SRC + i);
                            tcmpDir.Add(i, (Int32)APS_Define.TGR_TCMP0_DIR + i);
                        }
                    }
                    else
                    {
                        if (!lcmpSource.ContainsKey(i))
                        {
                            lcmpSource.Add(i, (Int32)APS_Define.TGR_LCMP2_SRC + i);
                            tcmpSource.Add(i, (Int32)APS_Define.TGR_TCMP2_SRC + i);
                            tcmpDir.Add(i, (Int32)APS_Define.TGR_TCMP2_DIR + i);
                        }
                    }
                }
            }

            #region Dictionary 初始化
            lock (_jf168Cfg)
            {
                if (!_jf168Cfg.ContainsItem("Card_" + BoardID))
                {
                    _jf168Cfg.AddItem("Card_" + BoardID, new JFXmlDictionary <string, object>());
                }
                _dictCT = _jf168Cfg.GetItemValue("Card_" + BoardID) as JFXmlDictionary <string, object>;

                if (_dictCT.ContainsKey(TrigTablesKeyName))
                {
                    trigTables = _dictCT[TrigTablesKeyName] as JFXmlDictionary <int, double[]>;
                }
                else
                {
                    for (int i = 0; i < EncoderChannels; i++)
                    {
                        if (trigTables.ContainsKey(i))
                        {
                            trigTables[i] = new double[0];
                        }
                        else
                        {
                            trigTables.Add(i, new double[0]);
                        }
                    }
                    _dictCT.Add(TrigTablesKeyName, trigTables);
                }


                if (_dictCT.ContainsKey(TrigLinersKeyName))
                {
                    trigLiners = _dictCT[TrigLinersKeyName] as JFXmlDictionary <int, JFCompareTrigLinerParam>;
                }
                else
                {
                    for (int i = 0; i < EncoderChannels; i++)
                    {
                        if (trigLiners.ContainsKey(i))
                        {
                            trigLiners[i] = new JFCompareTrigLinerParam();
                        }
                        else
                        {
                            trigLiners.Add(i, new JFCompareTrigLinerParam());
                        }
                    }
                    _dictCT.Add(TrigLinersKeyName, trigLiners);
                }

                if (_dictCT.ContainsKey(TrigModesKeyName))
                {
                    trigModes = _dictCT[TrigModesKeyName] as JFXmlDictionary <int, JFCompareTrigMode>;
                }
                else
                {
                    for (int i = 0; i < EncoderChannels; i++)
                    {
                        if (trigModes.ContainsKey(i))
                        {
                            trigModes[i] = JFCompareTrigMode.disable;
                        }
                        else
                        {
                            trigModes.Add(i, JFCompareTrigMode.disable);
                        }
                    }
                    _dictCT.Add(TrigModesKeyName, trigModes);
                }

                if (_dictCT.ContainsKey(ChnTrigKeyName))
                {
                    chnTrig = _dictCT[ChnTrigKeyName] as JFXmlDictionary <int, int[]>;
                }


                if (_dictCT.ContainsKey(TrigEnableKeyName))
                {
                    trigEnables = _dictCT[TrigEnableKeyName] as JFXmlDictionary <int, bool>;
                }
                else
                {
                    for (int i = 0; i < TrigChannels; i++)
                    {
                        if (trigEnables.ContainsKey(i))
                        {
                            trigEnables[i] = false;
                        }
                        else
                        {
                            trigEnables.Add(i, false);
                        }
                    }
                    _dictCT.Add(TrigEnableKeyName, trigEnables);
                }

                if (_dictCT.ContainsKey(LCmprUsedKeyName))
                {
                    lcmprUsed = _dictCT[LCmprUsedKeyName] as JFXmlDictionary <int, bool>;
                }
                else
                {
                    for (int i = 0; i < TrigChannels; i++)
                    {
                        if (lcmprUsed.ContainsKey(i))
                        {
                            lcmprUsed[i] = false;
                        }
                        else
                        {
                            lcmprUsed.Add(i, false);
                        }
                    }
                    _dictCT.Add(LCmprUsedKeyName, lcmprUsed);
                }

                if (_dictCT.ContainsKey(TCmprUsedKeyName))
                {
                    tcmprUsed = _dictCT[TCmprUsedKeyName] as JFXmlDictionary <int, bool>;
                }
                else
                {
                    for (int i = 0; i < TrigChannels; i++)
                    {
                        if (tcmprUsed.ContainsKey(i))
                        {
                            tcmprUsed[i] = false;
                        }
                        else
                        {
                            tcmprUsed.Add(i, false);
                        }
                    }
                    _dictCT.Add(TCmprUsedKeyName, tcmprUsed);
                }

                if (_dictCT.ContainsKey(TrigLCmprKeyName))
                {
                    trigLCmprSource = _dictCT[TrigLCmprKeyName] as JFXmlDictionary <int, List <int> >;
                }

                if (_dictCT.ContainsKey(TrigTCmprKeyName))
                {
                    trigTCmprSource = _dictCT[TrigTCmprKeyName] as JFXmlDictionary <int, List <int> >;
                }


                if (_dictCT.ContainsKey(ChnTCmprKeyName))
                {
                    chnTcmpr = _dictCT[ChnTCmprKeyName] as JFXmlDictionary <int, int>;
                }

                if (_dictCT.ContainsKey(ChnLCmprKeyName))
                {
                    chnLcmpr = _dictCT[ChnLCmprKeyName] as JFXmlDictionary <int, int>;
                }

                if (!_dictCT.ContainsKey("PulseFactor"))
                {
                    pulseFactors = new double[TotalAxis];
                    for (int i = 0; i < TotalAxis; i++)
                    {
                        pulseFactors[i] = 1;
                    }
                }
                else
                {
                    pulseFactors = _dictCT["PulseFactor"] as double[];
                    if (pulseFactors.Length < TotalAxis)
                    {
                        _dictCT.Remove("PulseFactor");
                        pulseFactors = new double[TotalAxis];
                        for (int i = 0; i < TotalAxis; i++)
                        {
                            pulseFactors[i] = 1;
                        }
                        _dictCT.Add("PulseFactor", pulseFactors);
                    }
                }



                _jf168Cfg.Save();
            }

            #endregion

            for (int i = 0; i < TrigChannels; i++)
            {
                if (APS168.APS_reset_trigger_count(BoardID, i) != 0)//reset count
                {
                    throw new Exception(string.Format("AMP204MC.APS_reset_trigger_count Failed :重置触发通道{0}计数器失败!", i));
                }


                if (APS168.APS_set_trigger_param(BoardID, (Int32)APS_Define.TGR_TRG0_SRC + i, 0) != 0)//Trig source bind
                {
                    throw new Exception(string.Format("AMP204MC.APS_set_trigger_param Failed :接触触发通道{0}绑定关系!", i));
                }

                //if (SetTrigEnable(i, trigEnables[i]) != (int)ErrorDef.Success)//enable or disable trig    //调用慢,先屏蔽   remarked by Boby
                //    throw new Exception(string.Format("AMP204MC.SetTrigEnable Failed :设置触发通道{0}使能状态失败!", i));
            }

            for (int i = 0; i < EncoderChannels; i++)
            {
                if (!chnTrig.ContainsKey(i))
                {
                    continue;
                }
                if (chnTrig[i].Length <= 0)
                {
                    continue;
                }
                int[] TrigChns = new int[chnTrig[i].Length];
                TrigChns = chnTrig[i];
                //if(SetEncoderTrigBind(i, TrigChns)!=(int)ErrorDef.Success)    //调用慢,先屏蔽 remarked by Boby
                //    throw new Exception(string.Format("AMP204MC.SetEncoderTrigBind Failed :绑定编码器{0}和触发通道{1}失败!",i, chnTrig[i]));
            }
            IsOpen = true;
        }