| 
					
				 | 
			
			
				@@ -13,7 +13,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "1", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "定额直接费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "F2+F3+F4", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "@('2')+@('3')+@('4')", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "人工费+材料费+机械费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             memo: '' 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -23,7 +22,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "1.1", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "人工费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "HJ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "HJ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "合计", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: 50, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'labour', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -34,7 +32,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "1.2", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "材料费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "HJ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "HJ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "合计", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: 30, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'material', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -45,7 +42,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "1.3", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "机械费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "HJ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "HJ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "合计", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: 20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'machine', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -56,7 +52,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "2", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "企业管理费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "F1", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "@('1')", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "定额直接费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'manage', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -67,7 +62,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "3", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "利润", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "F1", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "@('1')", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "定额直接费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'profit', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -78,7 +72,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "4", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "风险费用", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "F1", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "@('1')", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "定额直接费", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'risk', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -89,7 +82,6 @@ let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             code: "5", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name: "综合单价", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dispExpr: "F1+F5+F6+F7", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expression: "@('1')+@('5')+@('6')+@('7')", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             statement: "定额直接费+企业管理费+利润+风险费用", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             feeRate: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fieldName: 'common', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -702,14 +694,13 @@ const rationCalcBases = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 let analyzer = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    calcTemplate: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     standard: function(expr){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let str = expr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         str = str.replace(/\s/g, "");               // 去空格、去中文空格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         str = str.replace(/(/g, "(");              // 中文括号"("换成英文括号"(" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         str = str.replace(/)/g, ")");              // 中文括号")"换成英文括号")" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         str = str.replace(/f/g, "F");               // f换成F 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        str = str.replace(/l/g, "L");               // l换成L 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return str; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     getFArr: function (expr) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -722,40 +713,44 @@ let analyzer = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let arr = expr.match(patt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return arr ? arr : []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getFID: function (FName) {          // F3、F22 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getBaseArr: function (expr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let pattBase = new RegExp(/\[[\u4E00-\u9FA5]+\]/gi); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let arrBase = expr.match(pattBase); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return arrBase ? arrBase : []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getFID: function (FName, calcTemplate) {          // F3、F22 → 4、99 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let idx = FName.slice(1) - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let id = me.calcTemplate.calcItems[idx] ? me.calcTemplate.calcItems[idx].ID : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let id = calcTemplate.calcItems[idx] ? calcTemplate.calcItems[idx].ID : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getFItem: function (FName){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getFItem: function (FName, calcTemplate){      // F3 → calcItems[2] → {Object} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let idx = FName.slice(1) - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return me.calcTemplate.calcItems[idx]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return calcTemplate.calcItems[idx]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    isCycleCalc: function (expr) {     // @5+@6  这里已经是ID引用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    isCycleCalc: function (expression, calcTemplate) {     // 这里判断expression,是ID引用: @5+@6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = analyzer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        function isCycle(nodeExpr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function isCycle(nodeExpr, template) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let atIDArr = me.getAtIDArr(nodeExpr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (let atID of atIDArr){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let ID = atID.slice(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                let item = me.calcTemplate.compiledCalcItems[ID]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let item = template.compiledCalcItems[ID]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (item.expression.includes(atID)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    isCycle(item.expression); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    isCycle(item.expression, template); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return isCycle(expr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return isCycle(expression, calcTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    isLegal: function (expr) {   // 调用前必须先标准化 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    isLegal: function (dispExpr, calcTemplate) {  // 检测包括:无效字符、基数是否中括号、基数是否定义、行引用、循环计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = analyzer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let expr = me.standard(dispExpr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let invalidChars = /[^0-9\u4e00-\u9fa5\+\-\*\/\(\)\.\[\]F%]/g; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (invalidChars.test(expr)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             alert('表达式中含有无效的字符!'); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -787,38 +782,72 @@ let analyzer = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 行引用检测、行引用转ID引用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let arrF = me.getFArr(expr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for (let F of arrF){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let num = F.slice(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (num > me.calcTemplate.calcItems.length){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (num > calcTemplate.calcItems.length){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 alert('表达式中 “F'+ num +'” 行号引用错误!'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let id = me.getFID(F); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let fn = new RegExp(F, "g"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expr = expr.replace(fn, `@('${id}')`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 循环计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (me.isCycleCalc(expr)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let expression = me.getExpression(expr, calcTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (me.isCycleCalc(expression, calcTemplate)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             alert('表达式中有循环计算!'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    analyzeUserExpr: function(calcTemplate, calcItem){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        me.calcTemplate = calcTemplate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    analyzeUserExpr: function(calcItem, calcTemplate){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = analyzer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let expr = calcItem.dispExpr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         expr = me.standard(expr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         calcItem.dispExpr = expr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (me.isLegal(expr)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (me.isLegal(expr, calcTemplate)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             calcItem.expression = expr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getExpression: function (dispExpr, calcTemplate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        function refLineToID(expr, template) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let rst = expr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let fArr = me.getFArr(rst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let IDArr = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (let F of fArr){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let ID = me.getFID(F, template); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                IDArr.push(ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (let i = 0; i < fArr.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let patt = new RegExp(fArr[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let val = `@${IDArr[i]}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                rst = rst.replace(patt, val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return rst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = analyzer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let expr = me.standard(dispExpr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return refLineToID(expr, calcTemplate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getCompiledExpr: function (expression) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = analyzer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let rst = expression; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let atIDArr = me.getAtIDArr(rst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let IDArr = atIDArr.map(function (atID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return atID.slice(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var i = 0; i < atIDArr.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let patt = new RegExp(atIDArr[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let val = `$CE.at(${IDArr[i]})`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rst = rst.replace(patt, val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rst = rst.replace(/\[/g, "$CE.base('"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rst = rst.replace(/\]/g, "')"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return rst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -950,7 +979,7 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         template.hasCompiled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         template.errs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let private_extract_ID = function(str, idx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /*let private_extract_ID = function(str, idx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let rst = '', lBracket = 0, rBracket = 0, firstIdx = idx, lastIdx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (let i = idx; i < str.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (str[i] === '(') { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -973,8 +1002,8 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return rst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let private_parse_ref = function(item, itemIdx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        };*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /*let private_parse_ref = function(item, itemIdx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let idx = item.expression.indexOf('@(', 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             while (idx >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let ID = private_extract_ID(item.expression, idx); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -996,6 +1025,37 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (template.compiledSeq.indexOf(itemIdx) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 template.compiledSeq.push(itemIdx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        };*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let private_extract_ID = function(str, idx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let subStr = str.slice(idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let patt = new RegExp(/@\d+/); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let atID = subStr.match(patt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let ID = atID ? atID[0].slice(1) : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let private_parse_ref = function(item, itemIdx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let idx = item.expression.indexOf('@', 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while (idx >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let ID = private_extract_ID(item.expression, idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let len = ID ? ID.toString().length : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (len) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    let subItem = template.compiledCalcItems[ID]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (subItem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (subItem.ID !== item.ID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            private_parse_ref(subItem, template.compiledCalcItems[ID + "_idx"]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            template.errs.push("循环引用ID: " + ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        template.errs.push("找不到ID: " + ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        console.log('找不到ID: ' + ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                idx = item.expression.indexOf('@', idx + len + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (template.compiledSeq.indexOf(itemIdx) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                template.compiledSeq.push(itemIdx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let private_compile_items = function() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (let idx of template.compiledSeq) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1003,10 +1063,8 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 item.dispExprUser = item.dispExpr;    // 用于界面显示。disExpr是公式模板,不允许修改:人工系数占位符被修改后变成数值,第二次无法正确替换。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (item.expression == 'HJ') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     item.compiledExpr = '$CE.HJ()' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    item.compiledExpr = item.expression.split('@(').join('$CE.at('); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    item.compiledExpr = item.compiledExpr.split('base(').join('$CE.base('); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    item.compiledExpr = analyzer.getCompiledExpr(item.expression); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (item.labourCoeID){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     let lc = me.compiledLabourCoes[item.labourCoeID].coe; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1035,6 +1093,7 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (let i = 0; i < template.calcItems.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let item = template.calcItems[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                item.expression = analyzer.getExpression(item.dispExpr, template); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 template.compiledCalcItems[item.ID] = item; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 template.compiledCalcItems[item.ID + "_idx"] = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1379,7 +1438,8 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* 计算所有树结点(分3种情况),并返回发生变动的零散的多个树结点。参数取值如下: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         calcAllType.catAll       计算所有树结点 (不指定参数时的默认值) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         calcAllType.catBills     计算所有清单 (改变项目属性中清单取费算法时会用到) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        calcAllType.catRations   计算所有定额、工料机形式的定额、量价,因为它们都走自己的计算程序 (改变人工系数、费率值、工料机单价时会用到) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        calcAllType.catRations   计算所有定额、工料机形式的定额、量价,因为它们都走自己的计算程序 (改变人工系数、费率值、工料机单价时会用到)  不要用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        缺陷:calcAllType.catRations 参数情况不会计算父结点。(calcAllType.catBills 可以,因为清单的父结点也是清单会计算) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     calcAllNodes(calcType = calcAllType.catAll){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let me = this; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1514,4 +1574,6 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         baseNodes.push(calcTools.getNodeByFlag(fixedFlag.CHARGE)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return me.getTotalFee(baseNodes, excludeNodes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// export default analyzer; 
			 |