From 0cdfda43fa2f992614a1c0f3bd1aee48eac13797 Mon Sep 17 00:00:00 2001
From: 南骏 池 <chiffly@163.com>
Date: 星期二, 19 八月 2025 10:49:11 +0800
Subject: [PATCH] 1.AGV4个接口 2.其他入库优化
---
service/Wom/WomdaaManager.cs | 191 +++++++++++++++++++++
Controllers/Wom/WomdaaController.cs | 97 ++++++++++
Dto/Warehouse/DefineTask006Dto.cs | 50 +++++
Dto/Warehouse/DefineTask002Dto.cs | 21 ++
Dto/Warehouse/DefineTask001Dto.cs | 50 +++++
Controllers/AGV/AgvApiController.cs | 42 +++-
Dto/Warehouse/DefineTask005Dto.cs | 16 +
service/Warehouse/MesItemQtrkManager.cs | 21 +-
8 files changed, 470 insertions(+), 18 deletions(-)
diff --git a/Controllers/AGV/AgvApiController.cs b/Controllers/AGV/AgvApiController.cs
index 3249fbf..f979be1 100644
--- a/Controllers/AGV/AgvApiController.cs
+++ b/Controllers/AGV/AgvApiController.cs
@@ -7,6 +7,7 @@
using Newtonsoft.Json.Linq;
using System.ServiceModel;
using System.IO;
+using NewPdaSqlServer.Dto.Warehouse;
namespace NewPdaSqlServer.Controllers.AGV;
@@ -57,7 +58,7 @@
//绔嬪簱閫佹
[HttpPost("DefineTask_001")]
- public ResponseResult DefineTask_001(dynamic queryObj)
+ public ResponseResult DefineTask_001(DefineTask001Dto dto)
{
try
{
@@ -71,7 +72,16 @@
var factory = new ChannelFactory<IImesInterface>(binding, endpoint);
var channel = factory.CreateChannel();
- string result = channel.DefineTask_001("GS2025070700001","TEST.01","AGV娴嬭瘯鐗╂枡鍚嶇О", "AGV娴嬭瘯鐗╂枡瑙勬牸",100,"鍙�",1);
+ //string result = channel.DefineTask_001("GS2025070700001","TEST.01","AGV娴嬭瘯鐗╂枡鍚嶇О", "AGV娴嬭瘯鐗╂枡瑙勬牸",100,"鍙�",1);
+ string result = channel.DefineTask_001(
+ dto.MesId,
+ dto.MatId,
+ dto.MatName,
+ dto.MatStandard,
+ dto.MatNumber,
+ dto.MatUnit,
+ dto.Postition);
+
((IClientChannel)channel).Close();
return new ResponseResult
@@ -89,7 +99,7 @@
//绔嬪簱妫�楠�
[HttpPost("DefineTask_002")]
- public ResponseResult DefineTask_002(dynamic queryObj)
+ public ResponseResult DefineTask_002(DefineTask002Dto dto)
{
try
{
@@ -103,7 +113,11 @@
var factory = new ChannelFactory<IImesInterface>(binding, endpoint);
var channel = factory.CreateChannel();
- string result = channel.DefineTask_002("GS2025070900010", "鍚堟牸");
+ //string result = channel.DefineTask_002("GS2025070900010", "鍚堟牸");
+ string result = channel.DefineTask_002(
+ dto.MesId,
+ dto.MatStatus);
+
((IClientChannel)channel).Close();
return new ResponseResult
@@ -121,7 +135,7 @@
//绔嬪簱鍛煎彨
[HttpPost("DefineTask_005")]
- public ResponseResult DefineTask_005(dynamic queryObj)
+ public ResponseResult DefineTask_005(DefineTask005Dto dto)
{
try
{
@@ -135,7 +149,9 @@
var factory = new ChannelFactory<IImesInterface>(binding, endpoint);
var channel = factory.CreateChannel();
- string result = channel.DefineTask_005(2);
+ //string result = channel.DefineTask_005(2);
+ string result = channel.DefineTask_005(
+ dto.Postition);
((IClientChannel)channel).Close();
return new ResponseResult
@@ -154,7 +170,7 @@
//绔嬪簱鍏ュ簱
[HttpPost("DefineTask_006")]
- public ResponseResult DefineTask_006(dynamic queryObj)
+ public ResponseResult DefineTask_006(DefineTask006Dto dto)
{
try
{
@@ -168,7 +184,15 @@
var factory = new ChannelFactory<IImesInterface>(binding, endpoint);
var channel = factory.CreateChannel();
- string result = channel.DefineTask_006("C2025070400040", "2.02.51.463", "绠$嚎楗按鏈�", "C638-1HA(涓囧拰VGX-SR-1A-XM鐧�)", 48, "鍙�", 4);
+ //string result = channel.DefineTask_006("C2025070400040", "2.02.51.463", "绠$嚎楗按鏈�", "C638-1HA(涓囧拰VGX-SR-1A-XM鐧�)", 48, "鍙�", 4);
+ string result = channel.DefineTask_006(
+ dto.MesId,
+ dto.MatId,
+ dto.MatName,
+ dto.MatStandard,
+ dto.MatNumber,
+ dto.MatUnit,
+ dto.Postition);
((IClientChannel)channel).Close();
return new ResponseResult
@@ -215,4 +239,4 @@
[OperationContract(Action = "http://tempuri.org/ImesInterface/DefineTask_006",
ReplyAction = "http://tempuri.org/ImesInterface/DefineTask_006Response")]
string DefineTask_006(string MesId,string MatId,string MatName,string MatStandard,int MatNumber,string MatUnit,int Postition);
-}
\ No newline at end of file
+}
diff --git a/Controllers/Wom/WomdaaController.cs b/Controllers/Wom/WomdaaController.cs
index dee58fa..809832b 100644
--- a/Controllers/Wom/WomdaaController.cs
+++ b/Controllers/Wom/WomdaaController.cs
@@ -686,4 +686,101 @@
}
#endregion
+
+
+
+ #region pda璋冪敤AGV鐩稿叧
+ /// <summary>
+ /// AGV閫佹
+ /// </summary>
+ [HttpPost("handleAGVInspection")]
+ public ResponseResult HandleAGVInspection([FromBody] dynamic query)
+ {
+ try
+ {
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.tbBillList = m.HandleAGVInspection(query);
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ /// <summary>
+ /// AGV鍛煎彨
+ /// </summary>
+ [HttpPost("handleAGVCall")]
+ public ResponseResult HandleAGVCall([FromBody] dynamic query)
+ {
+ try
+ {
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.tbBillList = m.HandleAGVCall(query);
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ /// <summary>
+ /// AGV妫�楠屽鐞�
+ /// </summary>
+ [HttpPost("handleAgvJy")]
+ public ResponseResult HandleAgvJy([FromBody] dynamic query)
+ {
+ try
+ {
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.tbBillList = m.HandleAgvJy(query);
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ /// <summary>
+ /// AGV鍏ョ珛搴�
+ /// </summary>
+ [HttpPost("handleAgvRk")]
+ public ResponseResult HandleAgvRk([FromBody] dynamic query)
+ {
+ try
+ {
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.tbBillList = m.HandleAgvRk(query);
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/Dto/Warehouse/DefineTask001Dto.cs b/Dto/Warehouse/DefineTask001Dto.cs
new file mode 100644
index 0000000..a98d722
--- /dev/null
+++ b/Dto/Warehouse/DefineTask001Dto.cs
@@ -0,0 +1,50 @@
+namespace NewPdaSqlServer.Dto.Warehouse;
+using System.ComponentModel.DataAnnotations;
+/// <summary>
+/// 绔嬪簱閫佹鏁版嵁浼犺緭瀵硅薄
+/// </summary>
+public class DefineTask001Dto
+{
+ /// <summary>
+ /// MES浠诲姟鏍囪瘑
+ /// </summary>
+ [Required(ErrorMessage = "MES浠诲姟鏍囪瘑蹇呭~")]
+ public string MesId { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡缂栫爜
+ /// </summary>
+ [Required(ErrorMessage = "鐗╂枡缂栫爜蹇呭~")]
+ public string MatId { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡鍚嶇О
+ /// </summary>
+ public string MatName { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡瑙勬牸
+ /// </summary>
+ public string MatStandard { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡鏁伴噺
+ /// </summary>
+ [Range(1, int.MaxValue, ErrorMessage = "鐗╂枡鏁伴噺蹇呴』澶т簬0涓斾负鏁存暟")]
+ public int MatNumber { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡鍗曚綅
+ /// </summary>
+ [Required(ErrorMessage = "鐗╂枡鍗曚綅蹇呭~")]
+ public string MatUnit { get; set; }
+
+ /// <summary>
+ /// 涓婃枡浣嶇疆
+ /// </summary>
+ [Range(1, int.MaxValue, ErrorMessage = "鏈夋晥浣嶇疆缂栧彿蹇呭~")]
+ public int Postition { get; set; }
+}
+
+
+
diff --git a/Dto/Warehouse/DefineTask002Dto.cs b/Dto/Warehouse/DefineTask002Dto.cs
new file mode 100644
index 0000000..160c258
--- /dev/null
+++ b/Dto/Warehouse/DefineTask002Dto.cs
@@ -0,0 +1,21 @@
+using System.ComponentModel.DataAnnotations;
+namespace NewPdaSqlServer.Dto.Warehouse{
+
+ public class DefineTask002Dto
+ {
+ /// <summary>
+ /// 鏉$爜缂栧彿
+ /// </summary>
+ [Required(ErrorMessage = "MES浠诲姟鏍囪瘑蹇呭~")]
+ public string MesId { get; set; }
+ /// <summary>
+ /// 妫�楠岀姸鎬�
+ /// </summary>
+ [Required(ErrorMessage = "妫�楠岀姸鎬佸繀濉�")]
+ public string MatStatus { get; set; }
+ }
+
+}
+
+
+
diff --git a/Dto/Warehouse/DefineTask005Dto.cs b/Dto/Warehouse/DefineTask005Dto.cs
new file mode 100644
index 0000000..b738781
--- /dev/null
+++ b/Dto/Warehouse/DefineTask005Dto.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+namespace NewPdaSqlServer.Dto.Warehouse{
+
+ public class DefineTask005Dto
+ {
+ /// <summary>
+ /// 鍛煎彨鐐逛綅
+ /// </summary>
+ [Range(1, int.MaxValue, ErrorMessage = "鏈夋晥浣嶇疆缂栧彿蹇呭~")]
+ public int Postition { get; set; }
+ }
+
+}
+
+
+
diff --git a/Dto/Warehouse/DefineTask006Dto.cs b/Dto/Warehouse/DefineTask006Dto.cs
new file mode 100644
index 0000000..16c623c
--- /dev/null
+++ b/Dto/Warehouse/DefineTask006Dto.cs
@@ -0,0 +1,50 @@
+namespace NewPdaSqlServer.Dto.Warehouse;
+using System.ComponentModel.DataAnnotations;
+
+/// <summary>
+/// 绔嬪簱鍏ュ簱鏁版嵁浼犺緭瀵硅薄
+/// </summary>
+public class DefineTask006Dto
+{
+ /// <summary>
+ /// MES浠诲姟鏍囪瘑
+ /// </summary>
+ [Required(ErrorMessage = "MES浠诲姟鏍囪瘑蹇呭~")]
+ public string MesId { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡缂栫爜
+ /// </summary>
+ [Required(ErrorMessage = "鐗╂枡缂栫爜蹇呭~")]
+ public string MatId { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡鍚嶇О
+ /// </summary>
+ public string MatName { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡瑙勬牸
+ /// </summary>
+ public string MatStandard { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡鏁伴噺
+ /// </summary>
+ [Range(1, int.MaxValue, ErrorMessage = "鐗╂枡鏁伴噺蹇呴』澶т簬0涓斾负鏁存暟")]
+ public int MatNumber { get; set; }
+
+ /// <summary>
+ /// 鐗╂枡鍗曚綅
+ /// </summary>
+ public string MatUnit { get; set; }
+
+ /// <summary>
+ /// 鎵�鍦ㄦゼ灞�
+ /// </summary>
+ [Range(1, int.MaxValue, ErrorMessage = "鎵�鍦ㄦゼ灞傚繀濉�")]
+ public int Postition { get; set; }
+}
+
+
+
diff --git a/service/Warehouse/MesItemQtrkManager.cs b/service/Warehouse/MesItemQtrkManager.cs
index 2ef12c8..b9a1539 100644
--- a/service/Warehouse/MesItemQtrkManager.cs
+++ b/service/Warehouse/MesItemQtrkManager.cs
@@ -124,17 +124,16 @@
var sqlParams = new List<SugarParameter> { new("@barcode", p_item_barcode), new("@billNo", p_bill_no) };
- var sql1 = @" SELECT TOP 1 A.rkCkId
-FROM MES_QA_ITEMS_DETECT_01 A
- LEFT JOIN MES_INV_ITEM_BARCODES B ON A.item_id = B.ITEM_ID
-WHERE order_type = '鍏跺畠鍏ュ簱妫�'
- AND A.lot_no = @billNo
- AND ITEM_BARCODE = @barcode ";
+// var sql1 = @" SELECT TOP 1 A.rkCkId
+//FROM MES_QA_ITEMS_DETECT_01 A
+// LEFT JOIN MES_INV_ITEM_BARCODES B ON A.item_id = B.ITEM_ID
+//WHERE order_type = '鍏跺畠鍏ュ簱妫�'
+// AND A.lot_no = @billNo
+// AND ITEM_BARCODE = @barcode ";
- var appDepotInfo = Db.Ado.SqlQuery<dynamic>(sql1, sqlParams).First();
+// var appDepotInfo = Db.Ado.SqlQuery<dynamic>(sql1, sqlParams).First();
- if(appDepotInfo.rkCkId != c_depot_id)
- throw new Exception($"璇� {p_section_code} 瀵瑰簲鐨勪粨搴� 涓� 妫�楠屽垽瀹氱殑鍏ュ簱浠撳簱涓嶄竴鑷达紝璇风‘璁わ紒");
+
var mesDepost = Db.Queryable<MesDepots>()
@@ -173,6 +172,10 @@
if (qtrk == null) throw new Exception("鍏朵粬鍏ュ簱鐢宠鍗曚笉瀛樺湪锛�");
+
+ if (qtrk.Qt008 != c_depot_id.ToString())
+ throw new Exception($"璇� {p_section_code} 瀵瑰簲鐨勪粨搴� 涓� 妫�楠屽垽瀹氱殑鍏ュ簱浠撳簱涓嶄竴鑷达紝璇风‘璁わ紒");
+
var sql = @"SELECT c.item_no ItemNo,c.item_name ItemName,c.item_model ItemModel,
ISNULL(A.qd007,0) FQty,ISNULL(A.qd008,0) SQty,ISNULL(A.qd007,0) - ISNULL(A.qd008,0) DSQty
FROM MES_ITEM_QTRR_DETAIL A
diff --git a/service/Wom/WomdaaManager.cs b/service/Wom/WomdaaManager.cs
index 1ed19c5..1c101e1 100644
--- a/service/Wom/WomdaaManager.cs
+++ b/service/Wom/WomdaaManager.cs
@@ -1315,4 +1315,195 @@
return XtItem;
}
+ /// <summary>
+ /// AGV閫佹
+ /// </summary>
+ /// <param name="query"></param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentNullException"></exception>
+ /// <exception cref="ArgumentException"></exception>
+ /// <exception cref="Exception"></exception>
+ public dynamic HandleAGVInspection(dynamic query)
+ {
+ if (query == null) throw new ArgumentNullException(nameof(query));
+
+ if (string.IsNullOrEmpty(query.userAccount?.ToString()))
+ throw new ArgumentException("鐢ㄦ埛璐﹀彿涓嶈兘涓虹┖", nameof(query.userAccount));
+
+ if (string.IsNullOrEmpty(query.KbBar?.ToString()))
+ throw new ArgumentException("鍗℃澘鏉$爜涓嶈兘涓虹┖", nameof(query.KbBar));
+
+ using (var conn = new SqlConnection(DbHelperSQL.strConn))
+ {
+ using (var cmd = new SqlCommand("prc_pda_AgvSj", conn))
+ {
+ cmd.CommandType = CommandType.StoredProcedure;
+ var parameters = new SqlParameter[]
+ {
+ new("@pi_user", SqlDbType.NVarChar, 100) { Value = query.userAccount },
+ new("@pi_kb_barcode", SqlDbType.NVarChar, 100) { Value = query.KbBar },
+ new("@outMsg", SqlDbType.NVarChar, 2500) { Direction = ParameterDirection.Output },
+ new("@outSum", SqlDbType.Int) { Direction = ParameterDirection.Output }
+ };
+
+ cmd.Parameters.AddRange(parameters);
+ conn.Open();
+ cmd.ExecuteNonQuery();
+
+ var result = new
+ {
+ message = parameters[2].Value?.ToString(),
+ status = Convert.ToInt32(parameters[3].Value)
+ };
+
+ if (result.status <= 0)
+ throw new Exception(result.message);
+
+ return result;
+ }
+ }
+ }
+
+ public dynamic HandleAGVCall(dynamic query)
+ {
+ if (query == null) throw new ArgumentNullException(nameof(query));
+
+ if (string.IsNullOrEmpty(query.userAccount?.ToString()))
+ throw new ArgumentException("鐢ㄦ埛璐﹀彿涓嶈兘涓虹┖", nameof(query.userAccount));
+
+ if (string.IsNullOrEmpty(query.XtNum?.ToString()))
+ throw new ArgumentException("绾夸綋缂栧彿涓嶈兘涓虹┖", nameof(query.XtNum));
+
+ using (var conn = new SqlConnection(DbHelperSQL.strConn))
+ {
+ using (var cmd = new SqlCommand("prc_pda_AgvHj", conn))
+ {
+ cmd.CommandType = CommandType.StoredProcedure;
+ var parameters = new SqlParameter[]
+ {
+ new("@pi_user", SqlDbType.NVarChar, 100) { Value = query.userAccount },
+ new("@pi_xtNum", SqlDbType.NVarChar, 100) { Value = query.XtNum },
+ new("@outMsg", SqlDbType.NVarChar, 2500) { Direction = ParameterDirection.Output },
+ new("@outSum", SqlDbType.Int) { Direction = ParameterDirection.Output }
+ };
+
+ cmd.Parameters.AddRange(parameters);
+ conn.Open();
+ cmd.ExecuteNonQuery();
+
+ var result = new
+ {
+ message = parameters[2].Value?.ToString(),
+ status = Convert.ToInt32(parameters[3].Value)
+ };
+
+ if (result.status <= 0)
+ throw new Exception(result.message);
+
+ return result;
+ }
+ }
+ }
+
+
+ public dynamic HandleAgvJy(dynamic query)
+ {
+ if (query == null) throw new ArgumentNullException(nameof(query));
+
+ // 鍙傛暟楠岃瘉寮哄寲
+ if (string.IsNullOrEmpty(query.userAccount?.ToString()))
+ throw new ArgumentException("鐢ㄦ埛鍚嶄笉鍏佽涓虹┖", nameof(query.userAccount));
+
+ if (string.IsNullOrEmpty(query.KbBar?.ToString()))
+ throw new ArgumentException("鍗℃澘鏉$爜涓嶅厑璁镐负绌�", nameof(query.KbBar));
+
+ if (string.IsNullOrEmpty(query.jyz?.ToString()))
+ throw new ArgumentException("妫�楠岀粨鏋滀笉鍏佽涓虹┖", nameof(query.jyz));
+
+ var _strMsg = "";
+ var _intSum = "";
+
+ using (var conn = new SqlConnection(DbHelperSQL.strConn))
+ {
+ using (var cmd = new SqlCommand("prc_pda_AgvJy", conn))
+ {
+ cmd.CommandType = CommandType.StoredProcedure;
+
+ // 娣诲姞瀛樺偍杩囩▼鍙傛暟
+ SqlParameter[] parameters =
+ {
+ new("@pi_user", SqlDbType.NVarChar, 100) { Value = query.userAccount },
+ new("@pi_kbBarcode", SqlDbType.NVarChar, 100) { Value = query.KbBar },
+ new("@pi_jyz", SqlDbType.NVarChar, 100) { Value = query.jyz },
+ new("@outMsg", SqlDbType.NVarChar, 2500) { Direction = ParameterDirection.Output },
+ new("@outSum", SqlDbType.Int) { Direction = ParameterDirection.Output }
+ };
+
+ foreach (var parameter in parameters)
+ cmd.Parameters.Add(parameter);
+
+ conn.Open();
+ cmd.ExecuteNonQuery();
+
+ _strMsg = parameters[3].Value?.ToString() ?? "";
+ _intSum = parameters[4].Value?.ToString() ?? "-1";
+
+ var result = Convert.ToInt32(_intSum);
+ if (result <= 0) throw new Exception(_strMsg);
+
+ return new
+ {
+ message = _strMsg,
+ status = result,
+ kbBarcode = query.KbBar
+ };
+ }
+ }
+ }
+
+ public dynamic HandleAgvRk(dynamic query)
+ {
+ if (query == null) throw new ArgumentNullException(nameof(query));
+
+ if (string.IsNullOrEmpty(query.userAccount?.ToString()))
+ throw new ArgumentException("鐢ㄦ埛璐﹀彿涓嶈兘涓虹┖", nameof(query.userAccount));
+
+ if (string.IsNullOrEmpty(query.KbBar?.ToString()))
+ throw new ArgumentException("鍗℃澘鏉$爜涓嶈兘涓虹┖", nameof(query.KbBar));
+
+ if (string.IsNullOrEmpty(query.Postition?.ToString()))
+ throw new ArgumentException("妤煎眰浣嶇疆涓嶈兘涓虹┖", nameof(query.Postition));
+
+ using (var conn = new SqlConnection(DbHelperSQL.strConn))
+ {
+ using (var cmd = new SqlCommand("prc_pda_AgvRk", conn))
+ {
+ cmd.CommandType = CommandType.StoredProcedure;
+ var parameters = new SqlParameter[]
+ {
+ new("@pi_user", SqlDbType.NVarChar, 100) { Value = query.userAccount },
+ new("@pi_kb_barcode", SqlDbType.NVarChar, 100) { Value = query.KbBar },
+ new("@pi_kb_Postition", SqlDbType.NVarChar, 100) { Value = query.Postition },
+ new("@outMsg", SqlDbType.NVarChar, 2500) { Direction = ParameterDirection.Output },
+ new("@outSum", SqlDbType.Int) { Direction = ParameterDirection.Output }
+ };
+
+ cmd.Parameters.AddRange(parameters);
+ conn.Open();
+ cmd.ExecuteNonQuery();
+
+ var result = new
+ {
+ message = parameters[3].Value?.ToString(),
+ status = Convert.ToInt32(parameters[4].Value)
+ };
+
+ if (result.status <= 0)
+ throw new Exception(result.message);
+
+ return result;
+ }
+ }
+ }
+
}
\ No newline at end of file
--
Gitblit v1.9.3