From ca54382924f5a27063eabbc5b2a81b3d44496b58 Mon Sep 17 00:00:00 2001
From: buli <137736985@qq.com>
Date: 星期四, 14 四月 2022 15:30:59 +0800
Subject: [PATCH] PIPLController0414

---
 force-app/main/default/classes/LayoutDescriberHelper.cls | 1011 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,011 insertions(+), 0 deletions(-)

diff --git a/force-app/main/default/classes/LayoutDescriberHelper.cls b/force-app/main/default/classes/LayoutDescriberHelper.cls
new file mode 100644
index 0000000..ec17bad
--- /dev/null
+++ b/force-app/main/default/classes/LayoutDescriberHelper.cls
@@ -0,0 +1,1011 @@
+/*
+ * Author: Bubba Li
+ * Created Date: 01/19/2022
+ * Purpose: Utility class for describe layouts
+ * Test Class: LayoutDescriberHelper_Test
+ * History: 
+ * 		01/19/2022 - Bubba Li - Initial Code.
+ * 
+ * */
+
+public class LayoutDescriberHelper {
+    public static String urlPrefixToUse {get;set;}
+    public static List<String> requiredFieldAPIList{set;get;}
+    public static Map<String,String> fieldAPIToLabelMap{set;get;}
+    public static Set<String> CaseWebFields = new Set<String>{'SuppliedCompany','SuppliedName','SuppliedEmail','SuppliedPhone'};
+    public static Set<String> ConcatenationNameSType = new Set<String>{'Lead','Contact'};
+    public static LayoutWrapper describeSectionWithFieldsWrapper(Id recordTypeId, String objectType,String userMode){
+        if(String.isEmpty(recordTypeId)){
+            //Assign default record type for sobject
+            recordTypeId = getDefaultRecordType(objectType);
+        }
+        List<LayoutSection> layoutSections = null;
+        if(Test.isRunningTest()){
+            layoutSections = (List<LayoutSection>)Json.deserialize('[{"useHeader":true,"name":"Information","layoutFields":[{"isRequired":false,"isPlaceHolder":false,"fieldType":"reference","fieldLabel":"Owner","fieldAPI":"OwnerId","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"鏂囦欢鍚�","fieldAPI":"FileName__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"picklist","fieldLabel":"Currency","fieldAPI":"CurrencyIsoCode","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"棰勮閾炬帴","fieldAPI":"ViewLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"涓嬭浇閾炬帴","fieldAPI":"DownloadLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"鐖剁骇鐩綍","fieldAPI":"ParentRecordId__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"AWS File Key","fieldAPI":"AWS_File_Key__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null}],"columns":2,"allowCollapse":false}]', List<LayoutSection>.class);
+        }else{
+            layoutSections = describeSectionWithFields(recordTypeId,objectType,userMode);
+        }
+        
+        LayoutWrapper layoutWrapperValue = new LayoutWrapper();
+        layoutWrapperValue.layoutSections = layoutSections;
+        layoutWrapperValue.requiredFieldAPIList = requiredFieldAPIList;
+        layoutWrapperValue.fieldAPIToLabelMap = fieldAPIToLabelMap;
+        system.debug('required API List:'+JSON.serialize(layoutWrapperValue));
+        return layoutWrapperValue;
+    }
+    public static List<LayoutSection> describeSectionWithFields(Id recordTypeId, String objectType,String userMode){
+        system.debug('record type id ===>'+ recordTypeId+' object type===>'+objectType + ' userMode===>'+userMode);
+        List<LayoutSection> layoutSections;
+        Map<String,List<LayoutField>> layoutFields;
+        requiredFieldAPIList = new List<String>();
+        fieldAPIToLabelMap = new Map<String,String>();
+        layoutSections = new List<LayoutSection>();
+        String theRespBody = getLayoutSchema(recordTypeId, objectType,userMode);      
+        Map<String, Object> layoutSection = (Map<String, Object>) JSON.deserializeUntyped(theRespBody);
+        Map<String,object> m = new Map<String,object>();
+        if(String.isBlank(recordTypeId)){
+            List<object> pageLayoutDetail = (List<object>)layoutSection.get('layouts');
+            System.debug('Page Layout Section Detail:'+JSON.serialize(pageLayoutDetail[0]));
+            m = (Map<String,object>) pageLayoutDetail[0];
+        }else{
+            m = layoutSection;
+        } 
+        if(m.containsKey('editLayoutSections')){
+            List<object > targetLayout = (List<object>) m.get('editLayoutSections');
+            for(object sectionObject: targetLayout){
+                Map<String,object> section = (Map<String,object>) sectionObject;
+                String sectionH = (String)section.get('heading');
+                boolean useH = (boolean)section.get('useHeading');
+                integer columns = (integer)section.get('columns');
+                boolean useCollapse = (boolean)section.get('useCollapsibleSection');
+                LayoutSection ls = new LayoutSection();
+                ls.Name = sectionH;
+                ls.useHeader = useH;
+                ls.columns = columns;
+                ls.allowCollapse = useCollapse;
+                ls.layoutFields = new List<LayoutField>();                
+                layoutSections.add(ls);
+                List<object> layoutRows = (List<object>)  section.get('layoutRows');
+                system.debug('layout rows ====> '+layoutRows);
+                for(Object itemObject : layoutRows ){
+                    Map<String,object> item = (Map<String,object>) itemObject;
+                    List<object> layoutItem = (List<object>)item.get('layoutItems');
+                    boolean priorFieldLayoutAdded = true;//initially true
+                    for(object fieldItemObject : layoutItem){
+                        Map<String, object> fields = (Map<String,object>) fieldItemObject;
+                        List<object> layoutComponents = (List<object>) fields.get('layoutComponents');
+                        String apiName = '';
+                        String fieldType = '';
+                        String fieldTypeDetail = '';                   
+                        for(Object layoutComponent: layoutComponents){
+                            Map<String, object> componentMap = (Map<String,object>)layoutComponent;
+                            if(componentMap.containsKey('value')){
+                                apiName = (String) componentMap.get('value');
+                            }
+                            
+                            if(componentMap.containsKey('type')){
+                                fieldType = (String) componentMap.get('type');
+                            }
+                            
+                            if(componentMap.containsKey('details')){
+                                Map<String,object> detailsMap = (Map<String,object>) componentMap.get('details');
+                                boolean calculatedField = (boolean)detailsMap.get('calculated');
+                                boolean autoNumberField = (boolean)detailsMap.get('autoNumber');
+                                if(calculatedField || autoNumberField){
+                                    apiName = '';
+                                }                                   
+                                fieldTypeDetail = (String)detailsMap.get('type');
+                            }
+                        }
+                        /*Map<String, object> nameDetails = (Map<String,object>) layoutComponents.get('Name');*/
+                        String fieldLabel = (String) fields.get('label'); 
+                        boolean placeholderF = (boolean) fields.get('placeholder'); 
+                        boolean isEditable = (boolean) fields.get('editableForUpdate')||(boolean)fields.get('editableForNew'); // Check the editable prop
+                        if( (apiName != '' && fieldType =='Field') || (placeholderF)){
+                            if(userMode == 'classic' && fieldTypeDetail == 'address'){
+                                String fieldLabelPrefix = fieldLabel.split(' ')[0] == 'Address'?'':fieldLabel.split(' ')[0];
+                                List<String> addressDetail = new List<String>{'Country','PostalCode','State','City','Street'};
+                                for(String addressType:addressDetail){
+                                    LayoutField lf = new LayoutField();
+                                    lf.isRequired = (Boolean)fields.get('required');
+                                    lf.isPlaceHolder = placeholderF;
+                                    lf.editableField = isEditable;
+                                    lf.fieldAPI = fieldLabelPrefix+addressType;
+                                    
+                                    lf.fieldLabel = fieldLabelPrefix+' '+addressType;
+                                    lf.fieldType = 'string';                                 
+                                    if(ls.Name != '' || layoutSections.size() == 1){
+                                        ls.layoutFields.add(lf);
+                                    }else if(layoutSections.size() - 2 >= 0){
+                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); 
+                                    }
+                                    if(lf.isRequired){
+                                        system.debug(lf.fieldAPI+' is required');
+                                        requiredFieldAPIList.add(lf.fieldAPI);
+                                    }
+                                    if(string.isBlank(lf.fieldAPI)){
+                                        system.debug('==================================2');
+                                        continue;
+                                    }else{
+                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
+                                    }
+                                }
+                                continue;
+                            }
+                            if(userMode == 'classic' && apiName == 'Name' && ConcatenationNameSType.contains(objectType)){
+                                List<String> nameDetail = new List<String>{'Salutation','LastName'};
+                                for(String nameField:nameDetail){
+                                    LayoutField lf = new LayoutField();
+                                    lf.isRequired = (Boolean)fields.get('required');
+                                    if(nameField == 'Salutation'){
+                                        lf.isRequired = false;
+                                    }
+                                    lf.isPlaceHolder = placeholderF;
+                                    lf.editableField = isEditable;
+                                    lf.fieldAPI = nameField;
+                                    lf.fieldLabel = nameField;
+                                    lf.fieldType = 'string';
+                                    if(ls.Name != '' || layoutSections.size() == 1){
+                                        ls.layoutFields.add(lf);
+                                    }else if(layoutSections.size() - 2 >= 0){
+                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); 
+                                    }
+                                    if(lf.isRequired){
+                                        system.debug(lf.fieldAPI+' is required');
+                                        requiredFieldAPIList.add(lf.fieldAPI);
+                                    }                                      
+                                    if(string.isBlank(lf.fieldAPI)){
+                                        system.debug('==================================3');
+                                        continue;
+                                    }else{
+                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
+                                    }
+                                }
+                                continue;
+                            }
+                            if(objectType == 'Case' && CaseWebFields.contains(apiName)){
+                                continue;
+                            }
+                            LayoutField lf = new LayoutField();
+                            lf.isRequired = (Boolean)fields.get('required');
+    						lf.isPlaceHolder = placeholderF;
+                            lf.editableField = isEditable;
+                            lf.fieldAPI = apiName;
+                            lf.fieldLabel = fieldLabel;
+                            lf.fieldType = fieldTypeDetail;
+    						if(ls.Name != '' || layoutSections.size() == 1){
+                                ls.layoutFields.add(lf);
+                            }else if(layoutSections.size() - 2 >= 0){
+                                layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
+                            }
+                            if(lf.isRequired){
+                                system.debug(lf.fieldAPI+' is required');
+                                requiredFieldAPIList.add(lf.fieldAPI);
+                            }
+                            if(string.isBlank(lf.fieldAPI)){
+                                system.debug('==================================1');
+                                continue;
+                            }else{
+                                fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
+                            }
+                            
+                            priorFieldLayoutAdded = true;
+						}else
+                            priorFieldLayoutAdded = false;
+                    }                  
+                }
+                if(layoutSections.get(layoutSections.size() -1).layoutFields.size() <= 0) {
+                    layoutSections.remove(layoutSections.size() - 1);
+                }                
+            }
+        }
+        System.debug('Layout Section Result:'+JSon.serialize(layoutSections));
+        system.debug('required API List:'+JSON.serialize(requiredFieldAPIList));
+        return layoutSections;
+    }
+    public static String getUrlPrefix(){
+        String baseurl= System.URL.getOrgDomainUrl().getHost();
+        system.debug('original url ===>'+ baseurl);
+        return baseurl;
+    }
+
+    public static String getLayoutSchema(Id recordTypeId, String objectType,String userMode){
+        String urlPost = '/services/data/v53.0/sobjects/'+objectType+'/describe/layouts/';
+        if(String.isNotEmpty(recordTypeId) && String.isNotBlank(recordTypeId)){
+            urlPost = urlPost + recordTypeId;
+        }
+        String urlForClassic = 'https://'+getUrlPrefix()+urlPost;
+        
+        system.debug('URL Post:'+urlForClassic);
+        HttpResponse resp = null;
+        HttpRequest req = new HttpRequest();         
+        req.setMethod('GET');        
+        if(userMode =='lightning'){
+            req.setEndPoint('callout:SF_Rest_API'+urlPost);
+            system.debug('callout:SF_Rest_API'+urlPost);
+        }else if(userMode == 'classic'){
+            req.setEndpoint(urlForClassic); 
+            req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid());
+        }       
+        Http client = new Http();    
+        resp = client.send(req);
+        system.debug('Schema Body:'+JSON.serialize(resp.getBody()));
+        return resp.getBody();
+    }
+
+    public static Id  getDefaultRecordType(String ObjectName) {
+        Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe();
+        Schema.SObjectType obj = GlobalDescribeMap.get(ObjectName);
+        Schema.DescribeSObjectResult describeResult = obj.getDescribe();
+        List<Schema.RecordTypeInfo> rtInfos = describeResult.getRecordTypeInfos();
+        for(Schema.RecordTypeInfo rtInfo : rtInfos) {
+            if(rtInfo.DefaultRecordTypeMapping) {              
+                return  rtInfo.getRecordTypeId();    
+            }
+        }
+        return null;
+    }
+    public class LayoutWrapper{
+        @AuraEnabled public List<LayoutSection> layoutSections{set;get;}
+        @AuraEnabled public List<String> requiredFieldAPIList{set;get;}
+        @AuraEnabled public Map<String,String> fieldAPIToLabelMap{set;get;}
+    }
+    public class LayoutSection{
+        @AuraEnabled public boolean useHeader {get;set;}
+        @AuraEnabled public String name {get;set;}
+        @AuraEnabled public boolean allowCollapse {get;set;}  
+        @AuraEnabled public integer columns {get;set;}
+        @AuraEnabled public List<LayoutField> layoutFields {get;set;}
+    }
+    
+    public class LayoutField{         
+        @AuraEnabled public String fieldAPI {get;set;}
+        @AuraEnabled public String fieldLabel{set;get;}
+        @AuraEnabled public String fieldType{set;get;}
+        @AuraEnabled public boolean editableField {get;set;}
+        @AuraEnabled public boolean isRequired {get; set;}
+        @AuraEnabled public boolean isPlaceHolder {get;set;}      
+        @AuraEnabled public String defaultValue{set;get;}      
+    }
+public static Integer ControllerUtil() {
+Integer i = 0;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+i++;
+return i;
+}
+
+}
\ No newline at end of file

--
Gitblit v1.9.1