/**
 * 基建项目触发器
 * Created by ssm 2023/07/18
 */
public without sharing class InfrastructureProductTriggerHandler extends Oly_TriggerHandler {
    private List<Infrastructure_Project__c> oldList;
    private List<Infrastructure_Project__c> newList;
    private Map<Id,Infrastructure_Project__c> oldMap;
    private Map<Id,Infrastructure_Project__c> newMap;

    public InfrastructureProductTriggerHandler() {
        this.oldList = (List<Infrastructure_Project__c>) Trigger.old;
        this.newList = (List<Infrastructure_Project__c>) Trigger.new;
        this.oldMap = (Map<Id,Infrastructure_Project__c>) Trigger.oldMap;
        this.newMap = (Map<Id,Infrastructure_Project__c>) Trigger.newMap;
    }

    protected override void beforeInsert() {
        
    }

    protected override void beforeUpdate() {
        // 反映询价跟进
        updateOpportunityFollow();
        // 基建项目 状态控制
        Statecontrol();

    }

    protected override void afterInsert() {
        setShare();
    }

    protected override void afterUpdate() {
        setShare();
    }

    // 反映询价跟进
    // 仅对标记为true的数据进行更新
    private void updateOpportunityFollow() {
        // 获得待更新的基建项目
        Map<String, Integer> projectIds = new Map<String, Integer>();
        for (Infrastructure_Project__c project : this.newList){
            if (project.OpportunityFollow__c) {
                projectIds.put(project.Id, 0);
            }
        }
        System.debug('projectIds:' + projectIds);
        if (projectIds.size() > 0) {
            // 取得与基建项目相关的，状态不是取消的询价
            List<Opportunity> opps = [select Id, StageName, Infrastructure_Project__c from Opportunity where StageName != '削除' and Infrastructure_Project__c in :projectIds.keySet()];
            for (Opportunity opp : opps) {
                projectIds.put(opp.Infrastructure_Project__c, 1);
            }
            System.debug('projectIds:' + projectIds);
            for (String projectId : projectIds.keySet()) {
                System.debug('projectId:' + projectId);
                Infrastructure_Project__c project = this.newMap.get(projectId);
                // 更新是否询价跟进
                project.IfFollow__c = projectIds.get(projectId);
                // 2023-10-20 WYL  新增 关联询价日 start
                if (project.IfFollow__c > 0 && project.RelatedInquiryDate__c == null) {
                    project.RelatedInquiryDate__c = Date.today();
                }
                // 2023-11-27 WYL update start
                // else {
                //     project.RelatedInquiryDate__c = null;
                // }
                // 2023-11-27 WYL update end
               // 2023-10-20 WYL  新增 关联询价日 end
                // 重置标记
                project.OpportunityFollow__c = false;
            }
        }
    }

    // 设置共享
    // 当关联医院不为空或关联医院发生变化时给关联医院的担当赋值
    private void setShare() {
        // 新建共享
        List<Infrastructure_Project__Share> addShares = new List<Infrastructure_Project__Share>();
        Map<String, String> hospitals = new Map<String, String>();
        for (Infrastructure_Project__c newpro : this.newList) {
            if (this.oldList == null || 
                this.oldList.size() == 0 || 
                System.Label.InfrastructureSetShare == '1' || 
                (String.isNotBlank(newpro.OCSM_Hospital__c) && this.oldMap.get(newpro.Id) != null && this.oldMap.get(newpro.Id).OCSM_Hospital__c != newpro.OCSM_Hospital__c)) {
                    hospitals.put(newpro.Id, newpro.OCSM_Hospital__c);
                }
        }
        if (hospitals != null && hospitals.size() > 0) {
            // 医院Map
            Map<String, Account> mapHospital = new Map<String, Account>();
            // 医院各担当信息
            List<Account> lstHospital = [select Id,
                    GI_Main__c, GI_Main__r.IsActive, GI_Product_Leader__c,        // 消化
                    BF_owner__c, BF_owner__r.IsActive, BF_Product_Leader__c,       // 呼吸
                    ENT_owner_ID__c, ENT_owner_ID__r.IsActive, ENT_Product_Leader__c,  // 耳鼻喉
                    URO_owner_ID__c, URO_owner_ID__r.IsActive, URO_Produc_Leader__c,   // 泌尿
                    SP_Main__c, SP_Main__r.IsActive, GS_Product_Leader__c,        // 普外
                    GYN_owner__c, GYN_owner__r.IsActive, GYN_Product_Leader__c,     // 妇科
                    OCM_man_province_HP__c,                  // 办事处(OCSM管理省)
                    FSE_GI_Main_Leader__c, FSE_GI_Main_Leader__r.IsActive, 
                    FSE_SP_Main_Leader__c, FSE_SP_Main_Leader__r.IsActive // FSE
                from Account where Id in :hospitals.values()];
            // 担当
            Map<String, String> product_leaders = new Map<String, String>();
            for (Account acc: lstHospital) {
                mapHospital.put(acc.Id, acc);
                // 获得担当的文本
                if (String.isNotBlank(acc.GI_Product_Leader__c)) {
                    String[] names = acc.GI_Product_Leader__c.split(',');
                    for(String name : names) {
                        if (String.isNotBlank(name)) {
                            product_leaders.put(name, null);
                        }
                    }
                }
                if (String.isNotBlank(acc.BF_Product_Leader__c)) {
                    String[] names = acc.BF_Product_Leader__c.split(',');
                    for(String name : names) {
                        if (String.isNotBlank(name)) {
                            product_leaders.put(name, null);
                        }
                    }
                }
                if (String.isNotBlank(acc.ENT_Product_Leader__c)) {
                    String[] names = acc.ENT_Product_Leader__c.split(',');
                    for(String name : names) {
                        if (String.isNotBlank(name)) {
                            product_leaders.put(name, null);
                        }
                    }
                }
                if (String.isNotBlank(acc.URO_Produc_Leader__c)) {
                    String[] names = acc.URO_Produc_Leader__c.split(',');
                    for(String name : names) {
                        if (String.isNotBlank(name)) {
                            product_leaders.put(name, null);
                        }
                    }
                }
                if (String.isNotBlank(acc.GS_Product_Leader__c)) {
                    String[] names = acc.GS_Product_Leader__c.split(',');
                    for(String name : names) {
                        if (String.isNotBlank(name)) {
                            product_leaders.put(name, null);
                        }
                    }
                }
                if (String.isNotBlank(acc.GYN_Product_Leader__c)) {
                    String[] names = acc.GYN_Product_Leader__c.split(',');
                    for(String name : names) {
                        if (String.isNotBlank(name)) {
                            product_leaders.put(name, null);
                        }
                    }
                }
            }
            // 获得担当
            if (product_leaders.size() > 0) {
                List<User> lstUsers = [select Id, Alias from User where Alias in :product_leaders.keySet() and IsActive = true];
                for (User user : lstUsers) {
                    product_leaders.put(user.Alias, user.Id);
                }
            }
            // 权限类型
            List<String> rowCauseList = new List<String>();
            String rowCauseEdit = Schema.Infrastructure_Project__Share.RowCause.JSEdit__c;
            String rowCauseRead = Schema.Infrastructure_Project__Share.RowCause.JSRead__c;
            rowCauseList.add(rowCauseEdit);
            rowCauseList.add(rowCauseRead);
            // 清理共享
            List<Infrastructure_Project__Share> delShares = [select Id from Infrastructure_Project__Share where ParentId in :hospitals.keySet() and RowCause in :rowCauseList];
            if (delShares != null && delShares.size() > 0) {
                delete delShares;
            }
            for (String newproId : hospitals.keySet()) {
                Map<String, Infrastructure_Project__Share> shares = new Map<String, Infrastructure_Project__Share>();
                String hospitalId = hospitals.get(newproId);
                Account hospital = String.isNotBlank(hospitalId) && mapHospital.get(hospitalId) != null ? mapHospital.get(hospitalId) : null;
                if (hospital != null) {
                    // 主担当和担当
                    // 先担当(READ)  后主担当(EDIT)
                    if (String.isNotBlank(hospital.GI_Product_Leader__c)) {
                        String[] users = hospital.GI_Product_Leader__c.split(',');
                        for (String user : users) {
                            if (product_leaders.get(user) != null) {
                                shares.put(product_leaders.get(user), makeShare(newproId, rowCauseRead, product_leaders.get(user), 'Read'));
                            }
                        }
                    }
                    if (String.isNotBlank(hospital.BF_Product_Leader__c)) {
                        String[] users = hospital.BF_Product_Leader__c.split(',');
                        for (String user : users) {
                            if (product_leaders.get(user) != null) {
                                shares.put(product_leaders.get(user), makeShare(newproId, rowCauseRead, product_leaders.get(user), 'Read'));
                            }
                        }
                    }
                    if (String.isNotBlank(hospital.ENT_Product_Leader__c)) {
                        String[] users = hospital.ENT_Product_Leader__c.split(',');
                        for (String user : users) {
                            if (product_leaders.get(user) != null) {
                                shares.put(product_leaders.get(user), makeShare(newproId, rowCauseRead, product_leaders.get(user), 'Read'));
                            }
                        }
                    }
                    if (String.isNotBlank(hospital.URO_Produc_Leader__c)) {
                        String[] users = hospital.URO_Produc_Leader__c.split(',');
                        for (String user : users) {
                            if (product_leaders.get(user) != null) {
                                shares.put(product_leaders.get(user), makeShare(newproId, rowCauseRead, product_leaders.get(user), 'Read'));
                            }
                        }
                    }
                    if (String.isNotBlank(hospital.GS_Product_Leader__c)) {
                        String[] users = hospital.GS_Product_Leader__c.split(',');
                        for (String user : users) {
                            if (product_leaders.get(user) != null) {
                                shares.put(product_leaders.get(user), makeShare(newproId, rowCauseRead, product_leaders.get(user), 'Read'));
                            }
                        }
                    }
                    if (String.isNotBlank(hospital.GYN_Product_Leader__c)) {
                        String[] users = hospital.GYN_Product_Leader__c.split(',');
                        for (String user : users) {
                            if (product_leaders.get(user) != null) {
                                shares.put(product_leaders.get(user), makeShare(newproId, rowCauseRead, product_leaders.get(user), 'Read'));
                            }
                        }
                    }
                    // if (String.isNotBlank(hospital.FSE_GI_Main_Leader__c)) {
                    //     shares.put(hospital.FSE_GI_Main_Leader__c, makeShare(newproId, rowCauseRead, hospital.FSE_GI_Main_Leader__c, 'Read'));
                    // }
                    // if (String.isNotBlank(hospital.FSE_SP_Main_Leader__c)) {
                    //     shares.put(hospital.FSE_SP_Main_Leader__c, makeShare(newproId, rowCauseRead, hospital.FSE_SP_Main_Leader__c, 'Read'));
                    // }

                    if (String.isNotBlank(hospital.GI_Main__c) && hospital.GI_Main__r.IsActive) {
                        shares.put(hospital.GI_Main__c, makeShare(newproId, rowCauseEdit, hospital.GI_Main__c, 'Edit'));
                    }
                    if (String.isNotBlank(hospital.BF_owner__c) && hospital.BF_owner__r.IsActive) {
                        shares.put(hospital.BF_owner__c, makeShare(newproId, rowCauseEdit, hospital.BF_owner__c, 'Edit'));
                    }
                    if (String.isNotBlank(hospital.ENT_owner_ID__c) && hospital.ENT_owner_ID__r.IsActive) {
                        shares.put(hospital.ENT_owner_ID__c, makeShare(newproId, rowCauseEdit, hospital.ENT_owner_ID__c, 'Edit'));
                    }
                    if (String.isNotBlank(hospital.URO_owner_ID__c) && hospital.URO_owner_ID__r.IsActive) {
                        shares.put(hospital.URO_owner_ID__c, makeShare(newproId, rowCauseEdit, hospital.URO_owner_ID__c, 'Edit'));
                    }
                    if (String.isNotBlank(hospital.SP_Main__c) && hospital.SP_Main__r.IsActive) {
                        shares.put(hospital.SP_Main__c, makeShare(newproId, rowCauseEdit, hospital.SP_Main__c, 'Edit'));
                    }
                    if (String.isNotBlank(hospital.GYN_owner__c) && hospital.GYN_owner__r.IsActive) {
                        shares.put(hospital.GYN_owner__c, makeShare(newproId, rowCauseEdit, hospital.GYN_owner__c, 'Edit'));
                    }
                    
                }
                // 把map里的share堆到list里，最后一起insert
                if (shares.size() > 0) {
                    addShares.addAll(shares.values());
                }
            }
        }
        // OCSM管理省
        Map<String, OCM_Management_Province__c> OCMProvinces = new Map<String, OCM_Management_Province__c>();
        List<String> ocsmp_change = new List<String>();

        // 省助理处理
        for (Infrastructure_Project__c newpro : this.newList) {
            if (this.oldList == null || 
                this.oldList.size() == 0 || 
                System.Label.InfrastructureSetShare == '1' || 
                (String.isNotBlank(newpro.OCSMProvince__c) && this.oldMap.get(newpro.Id) != null && this.oldMap.get(newpro.Id).OCSMProvince__c != newpro.OCSMProvince__c)) {
                    OCMProvinces.put(newpro.OCSMProvince__c, null);
                    ocsmp_change.add(newpro.Id);
            }
        }
        
        // 获取管理省数据
        if (OCMProvinces.size() > 0) {
            List<OCM_Management_Province__c> lstOCMProvince = [select Id, Name, GI_assistant__c, GI_assistant__r.IsActive, SP_assistant__c, SP_assistant__r.IsActive, Window1__c, Window1__r.IsActive from OCM_Management_Province__c where Name in :OCMProvinces.keySet()];
            for (OCM_Management_Province__c pro : lstOCMProvince) {
                OCMProvinces.put(pro.Name, pro);
            }
            
            // 助理权限
            String rowCauseAssistant = Schema.Infrastructure_Project__Share.RowCause.JSEditAssistant__c;
            // 清理共享
            List<Infrastructure_Project__Share> delShares = [select Id from Infrastructure_Project__Share where ParentId in :ocsmp_change and RowCause = :rowCauseAssistant];
            if (delShares != null && delShares.size() > 0) {
                delete delShares;
            }
            for (String proid : ocsmp_change) {
                Infrastructure_Project__c project = newMap.get(proid);
                Map<String, Infrastructure_Project__Share> shares = new Map<String, Infrastructure_Project__Share>();
                // 助理和窗口（2S6）
                if (String.isNotBlank(project.OCSMProvince__c)) {
                    OCM_Management_Province__c pro = OCMProvinces.get(project.OCSMProvince__c);
                    if (pro != null && String.isNotBlank(pro.GI_assistant__c) && pro.GI_assistant__r.IsActive) {
                        shares.put(pro.GI_assistant__c, makeShare(proid, rowCauseAssistant, pro.GI_assistant__c, 'Edit'));
                    }
                    if (pro != null && String.isNotBlank(pro.SP_assistant__c) && pro.SP_assistant__r.IsActive) {
                        shares.put(pro.SP_assistant__c, makeShare(proid, rowCauseAssistant, pro.SP_assistant__c, 'Edit'));
                    }
                    if (pro != null && String.isNotBlank(pro.Window1__c) && pro.Window1__r.IsActive) {
                        shares.put(pro.Window1__c, makeShare(proid, rowCauseAssistant, pro.Window1__c, 'Edit'));
                    }
                }
                // 把map里的share堆到list里，最后一起insert
                if (shares.size() > 0) {
                    addShares.addAll(shares.values());
                }
            }
        }

        if (addShares.size() > 0) {
            insert addShares;
        }
    }
    // 2023-10-20 WYL  新增  字段自动更新逻辑 Start
    private void Statecontrol(){
        for (Infrastructure_Project__c project : this.newList){
            // 检查是否关联了客户
            if (oldMap.get(project.id).OCSM_Hospital__c != project.OCSM_Hospital__c && oldMap.get(project.id).OCSM_Hospital__c == null) {
                project.Customer_association_date__c = Date.today();
            }
            // 担当知晓日
            if (oldMap.get(project.id).sale_confirmation__c !=project.sale_confirmation__c &&  project.sale_confirmation__c== '已知晓') {
                project.AwarenessDay__c = Date.today();
            }
            // 担当不知晓日
            if (oldMap.get(project.id).sale_confirmation__c !=project.sale_confirmation__c &&  project.sale_confirmation__c== '不知晓') {
                project.DoNotknowtheday__c = Date.today();
            }
            // 担当跟进日
            if (oldMap.get(project.id).sale_confirmation__c !=project.sale_confirmation__c &&  project.sale_confirmation__c== '跟进中') {
                project.Follow_up_Day__c = Date.today();
            }
            // 2023-11-27 WYL update start
            // else {
            //     project.Follow_up_Day__c = null;
            // }
            // 2023-11-27 WYL update end
            // 竣工日 CompletionDate__c
            // 2023-12-18 ZXN DB202312340374 start
            if (oldMap.get(project.id).Node_Options__c != project.Node_Options__c &&  project.Node_Options__c == '竣工封顶') {
                project.CompletionDate__c = Date.today();
            }
            // 2023-12-18 ZXN DB202312340374 end
            // 2023-11-27 WYL update start
            // else {
            //     project.CompletionDate__c = null;
            // }
            // 2023-11-27 WYL update end
            // 2023-12-06 WYL DB202311561115 start
            if (oldMap.get(project.id).Node_Options__c != project.Node_Options__c &&  project.Node_Options__c == '验收运营') {
                project.Acceptance_operation_date__c = Date.today();
            }
            // 2023-12-06 WYL DB202311561115 end
        }
    }
    // 2023-10-20 WYL  新增  字段自动更新逻辑 end
    // 共享对象
    private Infrastructure_Project__Share makeShare(String parentId, String rowCause, String userId, String accessLevel) {
        return new Infrastructure_Project__Share(ParentId = parentId, RowCause = rowCause, UserOrGroupId = userId, AccessLevel = accessLevel);
    }

            //add by allen 拆分部署ali生产
            public void testMock(){
                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++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
                i++;
            }
}