Snippets Collections
list = [('tail_01_setup_jnt','tail_01_IK_ctrl_grp'),('tail_03_setup_jnt','tail_02_IK_ctrl_grp'),('tail_05_setup_jnt','tail_03_IK_ctrl_grp'),('tail_01_setup_jnt','tail_01_IK_jnt'),('tail_02_setup_jnt','tail_02_IK_jnt'),('tail_03_setup_jnt','tail_03_IK_jnt'),('tail_04_setup_jnt','tail_04_IK_jnt'),('tail_05_setup_jnt','tail_05_IK_jnt'),('tail_01_setup_jnt','tail_01_length_jnt'),('tail_02_setup_jnt','tail_02_length_jnt'),('tail_03_setup_jnt','tail_03_length_jnt'),('tail_04_setup_jnt','tail_04_length_jnt'),('tail_05_setup_jnt','tail_05_length_jnt'),('tail_01_setup_jnt','tail_start_length_jnt'),('tail_05_setup_jnt','tail_end_length_jnt')]
    for each in list:
        forDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(forDel)
        
    cmds.curve(d=3, p=[(0, 0, 0),(0, 2.5, 0),(0, 5, 0),(0, 7.5, 0),(0, 10, 0)])
    cmds.rename('tail_crv')
    
    nameOfLoc = ['tail_01_loc','tail_02_loc','tail_03_loc','tail_04_loc','tail_05_loc']
    for each in nameOfLoc:
        cmds.spaceLocator(n=each)

    toGetLocPos = [('tail_01_loc.translateY',0),('tail_02_loc.translateY',2.5),('tail_03_loc.translateY',5),('tail_04_loc.translateY',7.5),('tail_05_loc.translateY',10)]
    for each in toGetLocPos:
        cmds.setAttr(each[0],each[1])

    toConnectLoc = [('tail_01_loc.worldPosition[0]','tail_crv.controlPoints[0]'),('tail_02_loc.worldPosition[0]','tail_crv.controlPoints[1]'),('tail_03_loc.worldPosition[0]','tail_crv.controlPoints[2]'),('tail_04_loc.worldPosition[0]','tail_crv.controlPoints[3]'),('tail_05_loc.worldPosition[0]','tail_crv.controlPoints[4]')]
    for each in toConnectLoc:
        cmds.connectAttr(each[0],each[1])
        
    list = [('tail_01_setup_jnt','tail_01_loc'),('tail_02_setup_jnt','tail_02_loc'),('tail_03_setup_jnt','tail_03_loc'),('tail_04_setup_jnt','tail_04_loc'),('tail_05_setup_jnt','tail_05_loc')]
    for each in list:
        forDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(forDel)
        
    list = [('tail_01_IK_ctrl','tail_01_loc'),('tail_01_IK_ctrl','tail_02_loc'),('tail_02_IK_ctrl','tail_02_loc'),('tail_02_IK_ctrl','tail_03_loc'),('tail_02_IK_ctrl','tail_04_loc'),('tail_03_IK_ctrl','tail_04_loc'),('tail_03_IK_ctrl','tail_05_loc')]
    for each in list:
        cmds.parentConstraint(each[0],each[1],mo=True)
    
    cmds.select('tail_01_IK_jnt','tail_05_IK_jnt','tail_crv')
    cmds.ikHandle(n='tail_ikh',sol='ikSplineSolver',ccv=0,pcv =0)
    
    list = [('multiplyDivide','tail_stretch_01_mult'),('multiplyDivide','tail_stretch_02_mult')]
    for each in list:
        cmds.shadingNode(each[0],n=each[1],asUtility=1)
        
    cmds.setAttr('tail_stretch_01_mult.operation',2)
    cmds.arclen('tail_crv',ch = True)
        
    toConnectAttr = [('tail_03_IK_ctrl.rotateX','tail_ikh.twist'),('curveInfo1.arcLength','tail_stretch_01_mult.input1X'),('tail_stretch_01_mult.outputX','tail_stretch_02_mult.input1X'),('tail_02_length_jnt.translateX','tail_stretch_02_mult.input2X'),('tail_stretch_02_mult.outputX','tail_02_IK_jnt.translateX'),('tail_stretch_02_mult.outputX','tail_03_IK_jnt.translateX'),('tail_stretch_02_mult.outputX','tail_04_IK_jnt.translateX'),('tail_stretch_02_mult.outputX','tail_05_IK_jnt.translateX'),('tail_end_length_jnt.translateX','tail_stretch_01_mult.input2X')]
    for each in toConnectAttr:
        cmds.connectAttr(each[0],each[1])
    
    #create IKFK tail
    list = ['tail_01_bln_jnt','tail_02_bln_jnt','tail_03_bln_jnt','tail_04_bln_jnt','tail_05_bln_jnt']
    for each in list:
        cmds.joint(n=each)
    
    list = [('tail_01_setup_jnt','tail_01_bln_jnt'),('tail_02_setup_jnt','tail_02_bln_jnt'),('tail_03_setup_jnt','tail_03_bln_jnt'),('tail_04_setup_jnt','tail_04_bln_jnt'),('tail_05_setup_jnt','tail_05_bln_jnt')]
    for each in list:
        forDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(forDel)
            
    list = [('tail_01_FK_jnt','tail_01_bln_jnt'),('tail_02_FK_jnt','tail_02_bln_jnt'),('tail_03_FK_jnt','tail_03_bln_jnt'),('tail_04_FK_jnt','tail_04_bln_jnt'),('tail_05_FK_jnt','tail_05_bln_jnt'),('tail_01_IK_jnt','tail_01_bln_jnt'),('tail_02_IK_jnt','tail_02_bln_jnt'),('tail_03_IK_jnt','tail_03_bln_jnt'),('tail_04_IK_jnt','tail_04_bln_jnt'),('tail_05_IK_jnt','tail_05_bln_jnt')]
    for each in list:
        cmds.parentConstraint(each[0],each[1],mo=True)
    
    cmds.curve(n='tail_ik_fk_switch',d=1, p=[(1.25, 0, 7.5),(-1.25, 0, 7.5),(-1.25, 0, 1.25),(-7.5, 0, 1.25),(-7.5, 0, -1.25),(-1.25, 0, -1.25),(-1.25, 0, -7.5),(1.25, 0 ,-7.5),(1.25, 0, -1.25),(7.5, 0, -1.25),(7.5, 0, 1.25,),(1.25, 0 ,1.25),(1.25, 0, 7.5)])
    cmds.group(n='tail_ik_fk_switch_grp')
    cmds.setAttr('tail_ik_fk_switch.visibility',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.translateX',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.translateY',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.translateZ',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.rotateX',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.rotateY',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.rotateZ',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.scaleX',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.scaleY',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.scaleZ',keyable = False, cb = False, lock = True)
    cmds.setAttr('tail_ik_fk_switch.overrideEnabled' ,True) 
    cmds.setAttr('tail_ik_fk_switch.overrideColor' ,15)
    cmds.addAttr('tail_ik_fk_switch',sn='IKFK', min = 0, max=1 ,k=1)
    cmds.parentConstraint('tail_01_bln_jnt','tail_ik_fk_switch_grp')
    cmds.shadingNode('reverse',n='tail_ik_rev',asUtility=1)
    
    toConnectAttr = [('tail_ik_fk_switch.IKFK','tail_01_bln_jnt_parentConstraint1.tail_01_FK_jntW0'),('tail_ik_fk_switch.IKFK','tail_ik_rev.inputX'),('tail_ik_rev.outputX','tail_01_bln_jnt_parentConstraint1.tail_01_IK_jntW1'),('tail_ik_fk_switch.IKFK','tail_02_bln_jnt_parentConstraint1.tail_02_FK_jntW0'),('tail_ik_rev.outputX','tail_02_bln_jnt_parentConstraint1.tail_02_IK_jntW1'),('tail_ik_fk_switch.IKFK','tail_03_bln_jnt_parentConstraint1.tail_03_FK_jntW0'),('tail_ik_rev.outputX','tail_03_bln_jnt_parentConstraint1.tail_03_IK_jntW1'),('tail_ik_fk_switch.IKFK','tail_04_bln_jnt_parentConstraint1.tail_04_FK_jntW0'),('tail_ik_rev.outputX','tail_04_bln_jnt_parentConstraint1.tail_04_IK_jntW1'),('tail_ik_fk_switch.IKFK','tail_05_bln_jnt_parentConstraint1.tail_05_FK_jntW0'),('tail_ik_rev.outputX','tail_05_bln_jnt_parentConstraint1.tail_05_IK_jntW1'),('tail_ik_rev.outputX','tail_01_IK_ctrl_grp.visibility'),('tail_ik_rev.outputX','tail_02_IK_ctrl_grp.visibility'),('tail_ik_rev.outputX','tail_03_IK_ctrl_grp.visibility'),('tail_ik_fk_switch.IKFK','tail_01_FK_ctrl_grp.visibility')]
    for each in toConnectAttr:
        cmds.connectAttr(each[0],each[1])
    
    #create group
    list = ['jnt_grp','extra','ctrl_grp','rename']
    for each in list:
        cmds.group(n=each,em=True)
    
    list = [('tail_01_setup_jnt','extra'),('tail_01_FK_ctrl_grp','ctrl_grp'),('tail_01_FK_jnt','jnt_grp'),('tail_01_IK_ctrl_grp','ctrl_grp'),('tail_02_IK_ctrl_grp','ctrl_grp'),('tail_03_IK_ctrl_grp','ctrl_grp'),('tail_01_IK_jnt','jnt_grp'),('tail_start_length_jnt','extra'),('tail_01_length_jnt','extra'),('tail_crv','extra'),('tail_01_loc','extra'),('tail_02_loc','extra'),('tail_03_loc','extra'),('tail_04_loc','extra'),('tail_05_loc','extra'),('tail_ikh','extra'),('extra','rename'),('jnt_grp','rename'),('ctrl_grp','rename')]
    for each in list:
        cmds.parent(each[0],each[1])
    
    cmds.setAttr('extra.visibility',0)
    
def createLocator():
    
    list = ['start_loc','end_loc']
    for each in list:
        cmds.spaceLocator(n=each)
        cmds.setAttr (each +'.rotateX',keyable = False, cb = False, lock = True)
        cmds.setAttr (each +'.rotateY',keyable = False, cb = False, lock = True)
        cmds.setAttr (each +'.rotateZ',keyable = False, cb = False, lock = True)
        cmds.setAttr (each +'.scaleX',keyable = False, cb = False, lock = True)
        cmds.setAttr (each +'.scaleY',keyable = False, cb = False, lock = True)
        cmds.setAttr (each +'.scaleZ',keyable = False, cb = False, lock = True)
    cmds.setAttr('start_loc.translateX',-5)
    cmds.setAttr('end_loc.translateX',10)
    
def createMotionPath():
    def progressBarWindow():
        # this command opens the window
        window = cmds.window('MotionPathSetupProgress',title='Building')
        cmds.columnLayout()
        
        cmds.progressBar('MotionPathSetupProgress',maxValue=10, width=300)
        
        cmds.showWindow( window )
        
    progressBarWindow()
    
    # the command to find value
    list = ['start_loc','end_loc']
    
    for each in list:
        cmds.setAttr(each + '.visibility',0)

    def vector_sub(p1,p2):
        x = p1[0] - p2[0]
        y = p1[1] - p2[1]
        z = p1[2] - p2[2]
        return [x,y,z]

    def vector_add(p1,p2):
        x = p1[0] + p2[0]
        y = p1[1] + p2[1]
        z = p1[2] + p2[2]
        return [x,y,z]

    def vector_div(p,f):
        x = p[0] / f
        y = p[1] / f
        z = p[2] / f
        return [x,y,z]

    def vector_mult(p,f):
        x = p[0] * f
        y = p[1] * f
        z = p[2] * f
        return [x,y,z]
        
    p1 = cmds.xform(list[0], q=1, ws=1, t=1)
    p2 = cmds.xform(list[1], q=1, ws=1, t=1)
    print(p2)
    n = cmds.intField('numbersOfLocator',q=1,value=1)
    direction = vector_sub(p2,p1)
    direction = vector_div(direction,n)
    points = []
    
    for i in range(n):
        p = vector_add(p1,vector_mult(direction,i))
        points.append(p)
    points.append(p2)
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)
    
    # the command to find motion path in between value
    plus = n
    mpInBetween = 1/plus
    
    # the command to create curve
    crv = cmds.curve(d=1, p=[p1,p2])
    cmds.rename('mp_crv')
    cmds.setAttr('.template',1)
    cmds.rebuildCurve('mp_crv',d=2, rt=0, s=n-1)
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)

    # the command to create joints
    cmds.joint(n='main_mp_0_jnt',p=[0,0,0])

    number = len(points)
    for each in range(number):
        cmds.joint(n='main_mp_%s_jnt'%(each+1),p=points[each])
        cmds.parent(w=True)
        forDel = cmds.aimConstraint('end_loc','main_mp_%s_jnt'%(each+1),mo=False)
        cmds.delete(forDel)
        
    m=n+1
    
    for each in range(number):
        cmds.parent('main_mp_%s_jnt'%(m-each),'main_mp_%s_jnt'%(n-each))
    
    cmds.parent('main_mp_1_jnt',w=True)
    cmds.delete('main_mp_0_jnt')
    forDel = cmds.orientConstraint('main_mp_1_jnt','main_mp_%s_jnt'%(n+1))
    cmds.delete(forDel)
    cmds.makeIdentity('main_mp_1_jnt',apply=True,translate=True,rotate=True)
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)
    
    # the command to create controllers
    number = len(points)
    for each in range(number):
        ctrl = cmds.curve(n='mp_%s_ctrl'%(each+1),d=1, p=[(0, 0.5, 0.5),(0, -0.5, 0.5),(0, -0.5, -0.5),(0, 0.5, -0.5),(0, 0.5, 0.5)])
        cmds.setAttr (ctrl +'.scaleX',keyable = False, cb = False, lock = True)
        cmds.setAttr (ctrl +'.scaleY',keyable = False, cb = False, lock = True)
        cmds.setAttr (ctrl +'.scaleZ',keyable = False, cb = False, lock = True)
        cmds.setAttr (ctrl + ".overrideEnabled" ,True) 
        cmds.setAttr (ctrl + ".overrideColor" ,18)
        cmds.setAttr (ctrl +'.visibility',keyable = False, cb = False, lock = True)
        grp = cmds.group(n='mp_%s_ctrl_grp'%(each+1))
        forDel = cmds.parentConstraint('main_mp_%s_jnt'%(each+1),grp,mo=False)
        cmds.delete(forDel)
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)
    
    # the command to create locator
    number = len(points)
    for each in range(number):
        cmds.spaceLocator(n='aim_up_%s_loc'%(each+1))
        cmds.setAttr('.visibility',0)
        forDel = cmds.parentConstraint('main_mp_%s_jnt'%(each+1),'aim_up_%s_loc'%(each+1),mo=False)
        cmds.delete(forDel)
        cmds.setAttr('aim_up_%s_loc.translateY'%(each+1),2.5)
        cmds.parent('aim_up_%s_loc'%(each+1),'mp_%s_ctrl'%(each+1))
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=2)
    
    # the command to create node and motion path 
    number = len(points)
    for each in range(number):
        jnt = cmds.joint(n='mp_%s_jnt'%(each+1),p=points[each])
        cmds.setAttr('.visibility',0)
        cmds.shadingNode('plusMinusAverage',n = 'mp_%s_plm'%(each+1),asUtility=1)
        cmds.shadingNode('plusMinusAverage',n = 'mp_sec_%s_plm'%(each+1),asUtility=1)
        cmds.pathAnimation('mp_%s_jnt'%(each+1), c='mp_crv',fm=True,wut='objectrotation',wuo='aim_up_%s_loc'%(each+1),f=True,fa='x',ua='y')
        cmds.cutKey('motionPath%s'%(each+1), attribute='uValue', clear = True)
        cmds.connectAttr('mp_%s_ctrl.rotateY'%(each+1),'motionPath%s.upTwist'%(each+1))
        cmds.connectAttr('mp_%s_ctrl.rotateZ'%(each+1),'motionPath%s.sideTwist'%(each+1))
        
    cmds.parent('mp_1_jnt',w=True)
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)
    
    # the command to set value on each motion path
    number = len(points)
    for each in range(number):
        cmds.setAttr('motionPath%s.uValue'%(each+1),mpInBetween*each)
    
    # the command to create extra controller
    cmds.curve(d=1, p=[(0.25, 0, 1.5),(-0.25, 0, 1.5),(-0.25, 0, 0.25),(-1.5, 0, 0.25),(-1.5, 0, -0.25),(-0.25, 0, -0.25),(-0.25, 0, -1.5),(0.25, 0 ,-1.5),(0.25, 0, -0.25),(1.5, 0, -0.25),(1.5, 0, 0.25,),(0.25, 0 ,0.25),(0.25, 0, 1.5)])
    cmds.rename('mp_extra_ctrl')
    cmds.setAttr ('mp_extra_ctrl'+'.translateX',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.translateY',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.translateZ',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.rotateX',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.rotateY',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.rotateZ',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.scaleX',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.scaleY',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+'.scaleZ',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_extra_ctrl'+ ".overrideEnabled" ,True) 
    cmds.setAttr ('mp_extra_ctrl'+ ".overrideColor" ,29)
    cmds.setAttr ('mp_extra_ctrl'+'.visibility',keyable = False, cb = False, lock = True)
    cmds.addAttr('mp_extra_ctrl',sn='motionPath', min = 0, max=10 , k=1, dv=10)
    cmds.group(n='mp_extra_ctrl_grp')
    forDel = cmds.parentConstraint('main_mp_2_jnt','mp_extra_ctrl_grp')
    cmds.delete(forDel)

    # the command to search CV and create cluster
    targetCurve = 'mp_crv'
    curveCVs = cmds.ls('{0}.cv[:]'.format(targetCurve), fl = True)
    for cv in curveCVs:
        cmds.cluster(cv,n='cl1')
        cmds.setAttr('.visibility',0)
    cmds.shadingNode('multiplyDivide',n = 'mp_mult',asUtility=1)
    cmds.setAttr('mp_mult.input2X',10)
    cmds.setAttr('mp_mult.operation',2)
    cmds.connectAttr('mp_extra_ctrl.motionPath','mp_mult.input1X')
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=2)
    
    # the command to set and connect node
    number = len(curveCVs)
    for each in range(number):
        cmds.setAttr('mp_%s_plm.operation'%(each+1), 2)
        cmds.connectAttr('mp_mult.outputX','mp_%s_plm.input1D[0]'%(each+1))
        cmds.setAttr('mp_%s_plm.input1D[1]'%(each+1),1)
        cmds.connectAttr('mp_%s_plm.output1D'%(each+1),'mp_sec_%s_plm.input1D[0]'%(each+1))
        cmds.connectAttr('motionPath%s.uValue'%(each+1),'mp_sec_%s_plm.input1D[1]'%(each+1))
        forDel = cmds.parentConstraint('main_mp_%s_jnt'%(each+1),'cl%sHandle'%(each+1),mo=False)
        cmds.delete(forDel)
        cmds.parent('cl%sHandle'%(each+1),'mp_%s_ctrl'%(each+1))
        cmds.cutKey('mp_%s_plm'%(each+1), attribute='input1D[1]',clear = True)
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)
    
    # the command to connect node
    number = len(curveCVs)
    for each in range(number):
        cmds.disconnectAttr('motionPath%s.uValue'%(each+1),'mp_sec_%s_plm.input1D[1]'%(each+1))
        cmds.connectAttr('mp_sec_%s_plm.output1D'%(each+1),'motionPath%s.uValue'%(each+1))
        forDel = cmds.parentConstraint('mp_%s_jnt'%(each+1),'main_mp_%s_jnt'%(each+1),mo=True)
        cmds.delete(forDel)
    
    cmds.makeIdentity('main_mp_1_jnt',apply=True,translate=True,rotate=True)
    
    number = len(curveCVs)
    for each in range(number):
        cmds.parentConstraint('mp_%s_jnt'%(each+1),'main_mp_%s_jnt'%(each+1),mo=True)
        
    # the command to create group    
    list = ['ctrl_grp','jnt_grp','setup_grp','mp_grp','setup_jnt_grp']
    for each in list:
        cmds.group(n=each,em=True)
        
    # the command to create main controller
    cmds.circle(n='mp_main_ctrl',r=1,nrx = 90)
    cmds.setAttr ('mp_main_ctrl'+'.scaleX',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_main_ctrl'+'.scaleY',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_main_ctrl'+'.scaleZ',keyable = False, cb = False, lock = True)
    cmds.setAttr ('mp_main_ctrl'+ ".overrideEnabled" ,True) 
    cmds.setAttr ('mp_main_ctrl'+ ".overrideColor" ,29)
    cmds.setAttr ('mp_main_ctrl'+'.visibility',keyable = False, cb = False, lock = True)
    cmds.group(n='mp_main_ctrl_grp')
    forDel = cmds.parentConstraint('main_mp_1_jnt','mp_main_ctrl_grp')
    cmds.delete(forDel)
    cmds.parent('ctrl_grp','mp_main_ctrl')
    cmds.parent('mp_extra_ctrl_grp','mp_main_ctrl')
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=1)
    
    # the command to group controllers and joints
    number = len(curveCVs)
    for each in range(number):
        cmds.parent('mp_%s_ctrl_grp'%(each+1),'ctrl_grp')
        cmds.parent('mp_%s_jnt'%(each+1),'setup_jnt_grp')
    
    # the command to group everything
    list = [('start_loc','setup_grp'),('end_loc','setup_grp'),('mp_crv','setup_grp'),('setup_jnt_grp','setup_grp'),('main_mp_1_jnt','jnt_grp'),('setup_grp','mp_grp'),('jnt_grp','mp_grp'),('mp_main_ctrl_grp','mp_grp')]
    for each in list:
        cmds.parent(each[0],each[1])
    
    # the command to change the progress bar
    cmds.progressBar('MotionPathSetupProgress', edit=True, step=2)
    
    def progressBarWindowClose():
        # the command to close the progress bar
        cmds.deleteUI('MotionPathSetupProgress',window=True)
        
    progressBarWindowClose()

#create quadruped setup joint function#
def BuildQuadrupedSetupJoint():
    nameOfJoint = [('spine_01_setup_jnt',(0, 95, -25),(0,0,0)),('spine_02_setup_jnt',(0, 95, 0),(0,0,0)),('spine_03_setup_jnt',(0, 95, 25),(0,0,0)),('l_leg_01_setup_jnt',(10, 85, -35),(0,0,-90)),('l_leg_02_setup_jnt',(10, 60, -35),(0,0,0)),('l_leg_03_setup_jnt',(10, 30, -35),(0,0,0)),('l_leg_04_setup_jnt',(10, 10, -35),(0,0,0)),('l_leg_05_setup_jnt',(10, 0, -35),(0,0,0)),('l_leg_rock_out_setup_jnt',(15, 0, -35),(0,0,0)),('l_leg_rock_in_setup_jnt',(5, 0, -35),(0,0,0)),('l_leg_heel_setup_jnt',(10, 0, -45),(0,0,0)),('r_leg_01_setup_jnt',(-10, 85, -35),(0,0,0)),('r_leg_02_setup_jnt',(-10, 60, -35),(0,0,0)),('r_leg_03_setup_jnt',(-10, 30, -35),(0,0,0)),('r_leg_04_setup_jnt',(-10, 10, -35),(0,0,0)),('r_leg_05_setup_jnt',(-10, 0, -35),(0,180,0)),('r_leg_rock_out_setup_jnt',(-15, 0, -35),(0,0,0)),('r_leg_rock_in_setup_jnt',(-5, 0, -35),(0,0,0)),('r_leg_heel_setup_jnt',(-10, 0, -45),(0,0,0)),('l_shoulder_setup_jnt',(10, 90, 35),(0,-180,0)),('l_arm_01_setup_jnt',(10, 70, 35),(0,0,0)),('l_arm_02_setup_jnt',(10, 50, 35),(0,0,0)),('l_arm_03_setup_jnt',(10, 25, 35),(0,0,0)),('l_arm_04_setup_jnt',(10, 5, 35),(0,0,0)),('l_arm_05_setup_jnt',(10, 0, 35),(0,0,0)),('l_arm_rock_in_setup_jnt',(5, 0, 35),(0,0,0)),('l_arm_rock_out_setup_jnt',(15, 0, 35),(0,0,0)),('l_arm_heel_setup_jnt',(10, 0, 25),(0,0,0)),('r_shoulder_setup_jnt',(-10, 90, 35),(0,0,0)),('r_arm_01_setup_jnt',(-10, 70, 35),(0,0,0)),('r_arm_02_setup_jnt',(-10, 50, 35),(0,0,0)),('r_arm_03_setup_jnt',(-10, 25, 35),(0,0,0)),('r_arm_04_setup_jnt',(-10, 5, 35),(0,0,0)),('r_arm_05_setup_jnt',(-10, 0, 35),(0,180,0)),('r_arm_rock_in_setup_jnt',(-5, 0, 35),(0,0,0)),('r_arm_rock_out_setup_jnt',(-15, 0, 35),(0,0,0)),('r_arm_heel_setup_jnt',(-10, 0, 25),(0,0,0)),('neck_01_setup_jnt',(0, 105, 35),(0,-180,0)),('neck_02_setup_jnt',(0, 105, 45),(0,0,0)),('head_setup_jnt',(0, 105, 55),(0,0,0)),('head_setup_end_jnt',(0, 105, 75),(0,0,0)),('tail_01_setup_jnt',(0, 95, -35),(0,90,90)),('tail_02_setup_jnt',(0, 95, -45),(0,0,0)),('tail_03_setup_jnt',(0, 95, -55),(0,0,0)),('tail_04_setup_jnt',(0, 95, -65),(0,0,0)),('tail_05_setup_jnt',(0, 95, -75),(0,0,0))]
    for each in nameOfJoint:
        cmds.joint(n=each[0],p=each[1],o=each[2])
        
    toParentJoint = [('l_leg_01_setup_jnt','spine_01_setup_jnt'),('r_leg_01_setup_jnt','spine_01_setup_jnt'),('l_leg_rock_out_setup_jnt','l_leg_04_setup_jnt'),('l_leg_rock_in_setup_jnt','l_leg_04_setup_jnt'),('l_leg_heel_setup_jnt','l_leg_04_setup_jnt'),('r_leg_rock_out_setup_jnt','r_leg_04_setup_jnt'),('r_leg_rock_in_setup_jnt','r_leg_04_setup_jnt'),('r_leg_heel_setup_jnt','r_leg_04_setup_jnt'),('l_shoulder_setup_jnt','spine_03_setup_jnt'),('l_arm_rock_out_setup_jnt','l_arm_04_setup_jnt'),('l_arm_rock_in_setup_jnt','l_arm_04_setup_jnt'),('l_arm_heel_setup_jnt','l_arm_04_setup_jnt'),('r_shoulder_setup_jnt','spine_03_setup_jnt'),('r_arm_rock_out_setup_jnt','r_arm_04_setup_jnt'),('r_arm_rock_in_setup_jnt','r_arm_04_setup_jnt'),('r_arm_heel_setup_jnt','r_arm_04_setup_jnt'),('neck_01_setup_jnt','spine_03_setup_jnt'),('tail_01_setup_jnt','spine_01_setup_jnt')]
    for each in toParentJoint:
        cmds.parent(each[0],each[1])
        
    toSetJointRotation = [('l_leg_01_setup_jnt.rotateY',-15),('l_leg_02_setup_jnt.rotateY',30),('l_leg_03_setup_jnt.rotateY',-30),('r_leg_01_setup_jnt.rotateY',-15),('r_leg_02_setup_jnt.rotateY',30),('r_leg_03_setup_jnt.rotateY',-30),('l_shoulder_setup_jnt.rotateY',-30),('l_arm_01_setup_jnt.rotateY',70),('l_arm_02_setup_jnt.rotateY',-45),('l_arm_03_setup_jnt.rotateY',10),('r_shoulder_setup_jnt.rotateY',-30),('r_arm_01_setup_jnt.rotateY',70),('r_arm_02_setup_jnt.rotateY',-45),('r_arm_03_setup_jnt.rotateY',10),('neck_01_setup_jnt.rotateY',-50),('neck_02_setup_jnt.rotateY',-20),('head_setup_jnt.rotateY',-10)]
    for each in toSetJointRotation:
        cmds.setAttr(each[0],each[1])
        
    nameOfLoc = [('l_leg_PV_setup_loc'),('r_leg_PV_setup_loc'),('l_arm_PV_setup_loc'),('r_arm_PV_setup_loc')]
    for each in nameOfLoc:
        cmds.spaceLocator(n=each)

    toParentLoc = [('l_leg_PV_setup_loc','l_leg_02_setup_jnt'),('r_leg_PV_setup_loc','r_leg_02_setup_jnt'),('l_arm_PV_setup_loc','l_arm_02_setup_jnt'),('r_arm_PV_setup_loc','r_arm_02_setup_jnt')]
    for each in toParentLoc:
        cmds.parent(each[0],each[1])
    
    toGetLocPos = [('l_leg_PV_setup_loc'),('r_leg_PV_setup_loc'),('l_arm_PV_setup_loc'),('r_arm_PV_setup_loc')]
    for each in toGetLocPos:
        cmds.setAttr(each+'.translateX',0)
        cmds.setAttr(each+'.translateY',0)
        cmds.setAttr(each+'.translateZ',0)
        cmds.setAttr(each+'.rotateX',0)
        cmds.setAttr(each+'.rotateZ',0)
    cmds.setAttr('l_leg_PV_setup_loc'+'.translateZ',25)
    cmds.setAttr('r_leg_PV_setup_loc'+'.translateZ',25)
    cmds.setAttr('l_arm_PV_setup_loc'+'.translateZ',-20)
    cmds.setAttr('r_arm_PV_setup_loc'+'.translateZ',-20)
    
#mirror quadruped setup joint#
def MirrorQuadrupedSetupJoint():
    cmds.mirrorJoint('l_leg_01_setup_jnt',mb = True,myz = True,sr = ('l_','r_mirror_'))
    forDel = cmds.parentConstraint('r_mirror_leg_01_setup_jnt','r_leg_01_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_leg_01_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_leg_01_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_leg_02_setup_jnt','r_leg_02_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_leg_02_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_leg_02_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_leg_03_setup_jnt','r_leg_03_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_leg_03_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_leg_03_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_leg_04_setup_jnt','r_leg_04_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_leg_04_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_leg_04_setup_jnt.rotateY',180)
    
    cmds.mirrorJoint('l_shoulder_setup_jnt',mb = True,myz = True,sr = ('l_','r_mirror_'))
    forDel = cmds.parentConstraint('r_mirror_shoulder_setup_jnt','r_shoulder_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_shoulder_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_shoulder_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_arm_01_setup_jnt','r_arm_01_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_arm_01_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_arm_01_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_arm_02_setup_jnt','r_arm_02_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_arm_02_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_arm_02_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_arm_03_setup_jnt','r_arm_03_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_arm_03_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_arm_03_setup_jnt.rotateY',180)
    forDel = cmds.parentConstraint('r_mirror_arm_04_setup_jnt','r_arm_04_setup_jnt')
    cmds.delete(forDel)
    cmds.makeIdentity('r_arm_04_setup_jnt',apply=True,translate=True,rotate=True)
    cmds.setAttr('r_arm_04_setup_jnt.rotateY',180)
    
    list = [('r_mirror_leg_heer_mirror_setup_jnt','r_leg_heel_setup_jnt'),('r_mirror_leg_rock_in_setup_jnt','r_leg_rock_in_setup_jnt'),('r_mirror_leg_rock_out_setup_jnt','r_leg_rock_out_setup_jnt'),('r_mirror_leg_05_setup_jnt','r_leg_05_setup_jnt'),('r_mirror_arm_heer_mirror_setup_jnt','r_arm_heel_setup_jnt'),('r_mirror_arm_rock_in_setup_jnt','r_arm_rock_in_setup_jnt'),('r_mirror_arm_rock_out_setup_jnt','r_arm_rock_out_setup_jnt'),('r_mirror_arm_05_setup_jnt','r_arm_05_setup_jnt')]
    for each in list:
        forDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(forDel)
        
    cmds.delete('r_mirror_shoulder_setup_jnt','r_mirror_leg_01_setup_jnt')

#create quadruped setup rig function#
def BuildQuadrupedSetupRig():
    def progressBarWindow():
        # this command opens the window
        window = cmds.window('QuadrupedProgress',title='Building')
        cmds.columnLayout()
        
        cmds.progressBar('QuadrupedProgressBar',maxValue=10, width=300)
        
        cmds.showWindow( window )
        
    progressBarWindow()
        
    cmds.setAttr('spine_01_setup_jnt.visibility',0)
    
    def spineSetup():
        # FKspine #
        nameOfController = [('spine_01_FK_ctrl','spine_01_FK_ctrl_grp'),('spine_02_FK_ctrl','spine_02_FK_ctrl_grp'),('spine_03_FK_ctrl','spine_03_FK_ctrl_grp')]
        for each in nameOfController:
            cmds.curve(n=each[0],d=1, p=[(12.5, 12.5, 0),(-12.5, 12.5, 0),(-12.5, -12.5, 0),(12.5, -12.5, 0),(12.5, 12.5, 0)])
            cmds.group(n=each[1])

        cmds.circle(n='world_ctrl',r=50, nry = 90)
        cmds.setAttr('world_ctrl.overrideEnabled' ,True) 
        cmds.setAttr('world_ctrl.overrideColor' ,29)
        cmds.setAttr ('world_ctrl.visibility',keyable = False, cb = False, lock = True)
        cmds.group(n='world_ctrl_grp')
        cmds.curve(n='cog_ctrl',d=1, p=[(-3, 0, 18),(-18, 0, 3),(-18, 0, 6),(-24, 0, 0),(-18, 0, -6),(-18, 0, -3),(-3, 0, -18),(-3, 0, -18),(-6, 0, -18),(0, 0, -24),(6, 0, -18),(3, 0, -18),(18, 0, -3),(18, 0, -3),(18, 0, -6),(24, 0, 0),(18, 0, 6),(18, 0, 3),(3, 0, 18),(3, 0, 18),(6, 0, 18),(0, 0, 24),(-6, 0, 18),(-3, 0, 18)])
        cmds.group(n='cog_ctrl_grp',em=1)
        cmds.parent('cog_ctrl','cog_ctrl_grp')
        
        nameOfJoint = [('spine_01_FK_jnt'),('spine_02_FK_jnt'),('spine_03_FK_jnt')]
        for each in nameOfJoint:
            cmds.joint(n=each)
            cmds.parent(w=True)
            
        toGetPos = [('spine_01_setup_jnt','cog_ctrl_grp'),('spine_02_setup_jnt','spine_02_FK_ctrl_grp'),('spine_03_setup_jnt','spine_03_FK_ctrl_grp'),('spine_01_setup_jnt','spine_01_FK_ctrl_grp'),('spine_01_setup_jnt','spine_01_FK_jnt'),('spine_02_setup_jnt','spine_02_FK_jnt'),('spine_03_setup_jnt','spine_03_FK_jnt')]
        for each in toGetPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo = False)
            cmds.delete(forDel)
        cmds.makeIdentity('spine_01_FK_jnt',apply=True,translate=True,rotate=True)
        
        toParentCon = [('spine_01_FK_ctrl','spine_01_FK_jnt'),('spine_02_FK_ctrl','spine_02_FK_jnt'),('spine_03_FK_ctrl','spine_03_FK_jnt'),('cog_ctrl','spine_01_FK_ctrl_grp')]
        for each in toParentCon:
            cmds.parentConstraint(each[0],each[1],mo = True)
        
        toParent = [('spine_03_FK_jnt','spine_02_FK_jnt'),('spine_02_FK_jnt','spine_01_FK_jnt'),('spine_03_FK_ctrl_grp','spine_02_FK_ctrl'),('spine_02_FK_ctrl_grp','spine_01_FK_ctrl'),('spine_01_FK_ctrl_grp','world_ctrl')]
        for each in toParent:
            cmds.parent(each[0],each[1])
            
        toLockAttr = [('spine_01_FK_ctrl'),('spine_02_FK_ctrl'),('spine_03_FK_ctrl'),('cog_ctrl')]
        for each in toLockAttr:
            cmds.setAttr(each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,17)
            
        # IKspine #
        cmds.curve(d=3, p=[(0, 0, 0),(0, 2.5, 0),(0, 5, 0),(0, 7.5, 0),(0, 10, 0)])
        cmds.rename('spine_crv')
        nameOfLoc = ['spine_01_loc','spine_02_loc','spine_03_loc','spine_04_loc','spine_05_loc']
        for each in nameOfLoc:
            cmds.spaceLocator(n=each)
    
        toGetLocPos = [('spine_01_loc.translateY',0),('spine_02_loc.translateY',2.5),('spine_03_loc.translateY',5),('spine_04_loc.translateY',7.5),('spine_05_loc.translateY',10)]
        for each in toGetLocPos:
            cmds.setAttr(each[0],each[1])
    
        toConnectLoc = [('spine_01_loc.worldPosition[0]','spine_crvShape.controlPoints[0]'),('spine_02_loc.worldPosition[0]','spine_crvShape.controlPoints[1]'),('spine_03_loc.worldPosition[0]','spine_crvShape.controlPoints[2]'),('spine_04_loc.worldPosition[0]','spine_crvShape.controlPoints[3]'),('spine_05_loc.worldPosition[0]','spine_crvShape.controlPoints[4]')]
        for each in toConnectLoc:
            cmds.connectAttr(each[0],each[1])
            
        toCreateIKspineController = [('spine_01_IK_ctrl','spine_01_IK_ctrl_grp'),('spine_02_IK_ctrl','spine_02_IK_ctrl_grp'),('spine_03_IK_ctrl','spine_03_IK_ctrl_grp')]
        for each in toCreateIKspineController:
            cmds.circle(n=each[0],r=10,nrz = 90)
            cmds.group(n=each[1])
        cmds.delete('world_ctrl','spine_01_IK_ctrl','spine_02_IK_ctrl','spine_03_IK_ctrl',constructionHistory = True)
        
        toCreateJoint = ['spine_IK_chest_jnt','spine_IK_root_jnt','spine_IK_01_jnt','spine_IK_02_jnt','spine_IK_03_jnt','spine_IK_04_jnt','spine_IK_05_jnt','spine_01_length_jnt','spine_02_length_jnt','spine_03_length_jnt','spine_04_length_jnt','spine_05_length_jnt','spine_start_length_jnt','spine_end_length_jnt']
        for each in toCreateJoint:
            cmds.joint(n=each)
            
        cmds.group(n='spine_IK_jnt_grp',em=True)
        cmds.parent('spine_IK_01_jnt','spine_IK_jnt_grp')
        cmds.orientConstraint('cog_ctrl','spine_IK_jnt_grp')
            
        cmds.parent('spine_IK_root_jnt','spine_IK_chest_jnt','spine_01_length_jnt','spine_start_length_jnt',w=True)
        
        toGetPos = [('spine_01_setup_jnt','spine_IK_01_jnt'),('spine_01_setup_jnt','spine_IK_02_jnt'),('spine_02_setup_jnt','spine_IK_02_jnt'),('spine_02_setup_jnt','spine_IK_03_jnt'),('spine_02_setup_jnt','spine_IK_04_jnt'),('spine_03_setup_jnt','spine_IK_04_jnt'),('spine_03_setup_jnt','spine_IK_05_jnt'),('spine_01_setup_jnt','spine_01_IK_ctrl_grp'),('spine_02_setup_jnt','spine_02_IK_ctrl_grp'),('spine_03_setup_jnt','spine_03_IK_ctrl_grp'),('spine_01_setup_jnt','spine_start_length_jnt'),('spine_03_setup_jnt','spine_end_length_jnt'),('spine_01_setup_jnt','spine_01_length_jnt'),('spine_01_setup_jnt','spine_01_loc'),('spine_02_setup_jnt','spine_03_loc'),('spine_03_setup_jnt','spine_05_loc'),('spine_01_setup_jnt','spine_IK_root_jnt'),('spine_03_setup_jnt','spine_IK_chest_jnt')]
        for each in toGetPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
        
        forDelspine_02_lenghtJntParentCon = cmds.parentConstraint('spine_01_setup_jnt','spine_02_length_jnt',mo=False)
        forDelspine_02_lenghtJntParentCon = cmds.parentConstraint('spine_02_setup_jnt','spine_02_length_jnt',mo=False)
        forDelspine_03_lenghtJntParentCon = cmds.parentConstraint('spine_02_setup_jnt','spine_03_length_jnt',mo=False)
        forDelspine_04_lenghtJntParentCon = cmds.parentConstraint('spine_02_setup_jnt','spine_04_length_jnt',mo=False)
        forDelspine_04_lenghtJntParentCon = cmds.parentConstraint('spine_03_setup_jnt','spine_04_length_jnt',mo=False)
        forDelspine_05_lenghtJntParentCon = cmds.parentConstraint('spine_03_setup_jnt','spine_05_length_jnt',mo=False)
        cmds.delete(forDelspine_02_lenghtJntParentCon)
        cmds.delete(forDelspine_03_lenghtJntParentCon)
        cmds.delete(forDelspine_04_lenghtJntParentCon)
        cmds.delete(forDelspine_05_lenghtJntParentCon) 
        forDelspine_02_locParentCon = cmds.parentConstraint('spine_01_setup_jnt','spine_02_loc',mo=False)
        forDelspine_02_locParentCon = cmds.parentConstraint('spine_02_setup_jnt','spine_02_loc',mo=False)
        forDelspine_04_locParentCon = cmds.parentConstraint('spine_02_setup_jnt','spine_04_loc',mo=False)
        forDelspine_04_locParentCon = cmds.parentConstraint('spine_03_setup_jnt','spine_04_loc',mo=False)
        cmds.delete(forDelspine_02_locParentCon)
        cmds.delete(forDelspine_04_locParentCon)
        
        toParentCon = [('spine_03_IK_ctrl','spine_IK_chest_jnt'),('spine_01_IK_ctrl','spine_IK_root_jnt'),('spine_01_IK_ctrl','spine_01_loc'),('spine_02_IK_ctrl','spine_03_loc'),('spine_03_IK_ctrl','spine_05_loc'),('spine_01_IK_ctrl','spine_02_loc'),('spine_02_IK_ctrl','spine_02_loc'),('spine_02_IK_ctrl','spine_04_loc'),('spine_03_IK_ctrl','spine_04_loc'),('spine_03_IK_ctrl','spine_02_IK_ctrl_grp'),('spine_01_IK_ctrl','spine_02_IK_ctrl_grp'),('cog_ctrl','spine_01_IK_ctrl_grp'),('cog_ctrl','spine_03_IK_ctrl_grp')]
        for each in toParentCon:
            cmds.parentConstraint(each[0],each[1],mo=True)
            
        cmds.select('spine_IK_01_jnt','spine_IK_05_jnt','spine_crv')
        cmds.ikHandle(n='spine_ikh',sol='ikSplineSolver',ccv=0,pcv =0)
        
        createNode = [('multiplyDivide','spine_twist_mult'),('plusMinusAverage','spine_twist_pma'),('multiplyDivide','spine_stretch_01_mult'),('multiplyDivide','spine_stretch_02_mult')]
        for each in createNode:
            cmds.shadingNode(each[0],n=each[1],asUtility=1)
            
        toSetNode = [('spine_twist_mult.input2X',-1),('spine_stretch_01_mult.operation',2),('spine_stretch_01_mult.operation',2)]
        for each in toSetNode:
            cmds.setAttr(each[0],each[1])
        
        cmds.arclen('spine_crv',ch = True)
            
        toConnectAttr = [('spine_01_IK_ctrl.rotateZ','spine_twist_mult.input1X'),('spine_03_IK_ctrl.rotateZ','spine_twist_pma.input1D[0]'),('spine_01_IK_ctrl.rotateZ','spine_ikh.roll'),('spine_twist_pma.output1D','spine_ikh.twist'),('spine_twist_mult.outputX','spine_twist_pma.input1D[1]'),('curveInfo1.arcLength','spine_stretch_01_mult.input1X'),('spine_stretch_01_mult.outputX','spine_stretch_02_mult.input1X'),('spine_02_length_jnt.translateZ','spine_stretch_02_mult.input2X'),('spine_stretch_02_mult.outputX','spine_IK_02_jnt.translateZ'),('spine_stretch_02_mult.outputX','spine_IK_03_jnt.translateZ'),('spine_stretch_02_mult.outputX','spine_IK_04_jnt.translateZ'),('spine_stretch_02_mult.outputX','spine_IK_05_jnt.translateZ'),('spine_end_length_jnt.translateZ','spine_stretch_01_mult.input2X')]
        for each in toConnectAttr:
            cmds.connectAttr(each[0],each[1])
        
        toCreateGroup = ['spine_IK_setup_jnt_grp','spine_IK_ctrl_grp','spine_IK_loc_grp','spine_IK_setup_grp']
        for each in toCreateGroup:
            cmds.group(n=each,em=True)
            
        toParent = [('spine_01_loc','spine_IK_loc_grp'),('spine_02_loc','spine_IK_loc_grp'),('spine_03_loc','spine_IK_loc_grp'),('spine_04_loc','spine_IK_loc_grp'),('spine_05_loc','spine_IK_loc_grp'),('spine_01_IK_ctrl_grp','spine_IK_ctrl_grp'),('spine_02_IK_ctrl_grp','spine_IK_ctrl_grp'),('spine_03_IK_ctrl_grp','spine_IK_ctrl_grp'),('spine_01_length_jnt','spine_IK_setup_jnt_grp'),('spine_start_length_jnt','spine_IK_setup_jnt_grp'),('spine_ikh','spine_IK_setup_grp'),('spine_crv','spine_IK_setup_grp'),('spine_IK_setup_jnt_grp','spine_IK_setup_grp'),('spine_IK_loc_grp','spine_IK_setup_grp'),('spine_IK_ctrl_grp','world_ctrl')]
        for each in toParent:
            cmds.parent(each[0],each[1])
        
        cmds.scaleConstraint('world_ctrl','spine_IK_setup_jnt_grp',mo=True)
        
        #set IKFK spine controller attributes#
        listOfSpineController = ['cog_ctrl','spine_01_IK_ctrl','spine_02_IK_ctrl','spine_03_IK_ctrl','spine_01_FK_ctrl','spine_02_FK_ctrl','spine_03_FK_ctrl']
        for each in listOfSpineController:
            cmds.setAttr (each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,17)
        
        #create IKFK spine bind joint#
        nameOfSpineBindJoint = ['spine_01_bln_jnt','spine_02_bln_jnt','spine_03_bln_jnt']
        for each in nameOfSpineBindJoint:
            cmds.joint(n=each)
            
        cmds.parent('spine_01_bln_jnt',w=True)
        cmds.group(n='spine_01_bln_jnt_grp')
        cmds.scaleConstraint('world_ctrl','spine_01_bln_jnt_grp',mo=True)
            
        toGetSpineBindJointPos = [('spine_01_setup_jnt','spine_01_bln_jnt'),('spine_02_setup_jnt','spine_02_bln_jnt'),('spine_03_setup_jnt','spine_03_bln_jnt')]
        for each in toGetSpineBindJointPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
        
        toParentConIKFKspine = [('spine_01_FK_jnt','spine_01_bln_jnt'),('spine_IK_root_jnt','spine_01_bln_jnt'),('spine_02_FK_jnt','spine_02_bln_jnt'),('spine_IK_03_jnt','spine_02_bln_jnt'),('spine_03_FK_jnt','spine_03_bln_jnt'),('spine_IK_chest_jnt','spine_03_bln_jnt')]    
        for each in toParentConIKFKspine:
            cmds.parentConstraint(each[0],each[1],mo=True)
            
        cmds.curve(n='spine_ik_fk_switch',d=1, p=[(1.25, 0, 7.5),(-1.25, 0, 7.5),(-1.25, 0, 1.25),(-7.5, 0, 1.25),(-7.5, 0, -1.25),(-1.25, 0, -1.25),(-1.25, 0, -7.5),(1.25, 0 ,-7.5),(1.25, 0, -1.25),(7.5, 0, -1.25),(7.5, 0, 1.25,),(1.25, 0 ,1.25),(1.25, 0, 7.5)])
        cmds.group(n='spine_ik_fk_switch_grp')
        cmds.setAttr('spine_ik_fk_switch.visibility',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.translateX',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.translateY',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.translateZ',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.rotateX',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.rotateY',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.rotateZ',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.scaleX',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.scaleY',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.scaleZ',keyable = False, cb = False, lock = True)
        cmds.setAttr('spine_ik_fk_switch.overrideEnabled' ,True) 
        cmds.setAttr('spine_ik_fk_switch.overrideColor' ,15)
        cmds.parent('spine_ik_fk_switch_grp', 'world_ctrl')
        cmds.addAttr('spine_ik_fk_switch',sn='IKFK', min = 0, max=1 ,k=1)
        cmds.parentConstraint('spine_02_bln_jnt','spine_ik_fk_switch_grp')
        cmds.shadingNode('reverse',n='spine_ik_rev',asUtility=1)
        
        toConnectAttr = [('spine_ik_fk_switch.IKFK','spine_01_bln_jnt_parentConstraint1.spine_01_FK_jntW0'),('spine_ik_fk_switch.IKFK','spine_ik_rev.inputX'),('spine_ik_rev.outputX','spine_01_bln_jnt_parentConstraint1.spine_IK_root_jntW1'),('spine_ik_fk_switch.IKFK','spine_02_bln_jnt_parentConstraint1.spine_02_FK_jntW0'),('spine_ik_rev.outputX','spine_02_bln_jnt_parentConstraint1.spine_IK_03_jntW1'),('spine_ik_fk_switch.IKFK','spine_03_bln_jnt_parentConstraint1.spine_03_FK_jntW0'),('spine_ik_rev.outputX','spine_03_bln_jnt_parentConstraint1.spine_IK_chest_jntW1'),('spine_ik_rev.outputX','spine_IK_ctrl_grp.visibility'),('spine_ik_fk_switch.IKFK','spine_01_FK_ctrl_grp.visibility')]
        for each in toConnectAttr:
            cmds.connectAttr(each[0],each[1])

        # the command to change the progress bar
        cmds.progressBar('QuadrupedProgressBar', edit=True, step=1)
        
    spineSetup()
    
    def leftRightFKsetup(side):
        nameOfFKcontroller = [('%s_FK_leg_01_ctrl'%(side),'%s_FK_leg_01_ctrl_grp'%(side)),('%s_FK_leg_02_ctrl'%(side),'%s_FK_leg_02_ctrl_grp'%(side)),('%s_FK_leg_03_ctrl'%(side),'%s_FK_leg_03_ctrl_grp'%(side)),('%s_FK_leg_04_ctrl'%(side),'%s_FK_leg_04_ctrl_grp'%(side)),('%s_FK_arm_01_ctrl'%(side),'%s_FK_arm_01_ctrl_grp'%(side)),('%s_FK_arm_02_ctrl'%(side),'%s_FK_arm_02_ctrl_grp'%(side)),('%s_FK_arm_03_ctrl'%(side),'%s_FK_arm_03_ctrl_grp'%(side)),('%s_FK_arm_04_ctrl'%(side),'%s_FK_arm_04_ctrl_grp'%(side)),('%s_shoulder_ctrl'%(side),'%s_shoulder_ctrl_grp'%(side))]
        for each in nameOfFKcontroller:
            ctrl = cmds.circle(n=each[0],r=5,nrx = 90)
            cmds.delete(ctrl,constructionHistory = True)
            cmds.group(n=each[1])
            
        nameOfJoint = [('%s_FK_leg_01_jnt'%(side)),('%s_FK_leg_02_jnt'%(side)),('%s_FK_leg_03_jnt'%(side)),('%s_FK_leg_04_jnt'%(side)),('%s_FK_arm_01_jnt'%(side)),('%s_FK_arm_02_jnt'%(side)),('%s_FK_arm_03_jnt'%(side)),('%s_FK_arm_04_jnt'%(side)),('%s_shoulder_jnt'%(side))]
        for each in nameOfJoint:
            cmds.joint(n=each)
            cmds.parent(w = True)
            
        togetPos = [('%s_leg_01_setup_jnt'%(side),'%s_FK_leg_01_jnt'%(side)),('%s_leg_02_setup_jnt'%(side),'%s_FK_leg_02_jnt'%(side)),('%s_leg_03_setup_jnt'%(side),'%s_FK_leg_03_jnt'%(side)),('%s_leg_04_setup_jnt'%(side),'%s_FK_leg_04_jnt'%(side)),('%s_leg_01_setup_jnt'%(side),'%s_FK_leg_01_ctrl_grp'%(side)),('%s_leg_02_setup_jnt'%(side),'%s_FK_leg_02_ctrl_grp'%(side)),('%s_leg_03_setup_jnt'%(side),'%s_FK_leg_03_ctrl_grp'%(side)),('%s_leg_04_setup_jnt'%(side),'%s_FK_leg_04_ctrl_grp'%(side)),('%s_arm_01_setup_jnt'%(side),'%s_FK_arm_01_jnt'%(side)),('%s_arm_02_setup_jnt'%(side),'%s_FK_arm_02_jnt'%(side)),('%s_arm_03_setup_jnt'%(side),'%s_FK_arm_03_jnt'%(side)),('%s_arm_04_setup_jnt'%(side),'%s_FK_arm_04_jnt'%(side)),('%s_arm_01_setup_jnt'%(side),'%s_FK_arm_01_ctrl_grp'%(side)),('%s_arm_02_setup_jnt'%(side),'%s_FK_arm_02_ctrl_grp'%(side)),('%s_arm_03_setup_jnt'%(side),'%s_FK_arm_03_ctrl_grp'%(side)),('%s_arm_04_setup_jnt'%(side),'%s_FK_arm_04_ctrl_grp'%(side)),('%s_shoulder_setup_jnt'%(side),'%s_shoulder_jnt'%(side)),('%s_shoulder_setup_jnt'%(side),'%s_shoulder_ctrl_grp'%(side))]
        for each in togetPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo = False)
            cmds.delete(forDel)
            
        toParent = [('%s_FK_leg_04_ctrl_grp'%(side),'%s_FK_leg_03_ctrl'%(side)),('%s_FK_leg_03_ctrl_grp'%(side),'%s_FK_leg_02_ctrl'%(side)),('%s_FK_leg_02_ctrl_grp'%(side),'%s_FK_leg_01_ctrl'%(side)),('%s_FK_leg_04_jnt'%(side),'%s_FK_leg_03_jnt'%(side)),('%s_FK_leg_03_jnt'%(side),'%s_FK_leg_02_jnt'%(side)),('%s_FK_leg_02_jnt'%(side),'%s_FK_leg_01_jnt'%(side)),('%s_FK_arm_04_ctrl_grp'%(side),'%s_FK_arm_03_ctrl'%(side)),('%s_FK_arm_03_ctrl_grp'%(side),'%s_FK_arm_02_ctrl'%(side)),('%s_FK_arm_02_ctrl_grp'%(side),'%s_FK_arm_01_ctrl'%(side)),('%s_FK_arm_04_jnt'%(side),'%s_FK_arm_03_jnt'%(side)),('%s_FK_arm_03_jnt'%(side),'%s_FK_arm_02_jnt'%(side)),('%s_FK_arm_02_jnt'%(side),'%s_FK_arm_01_jnt'%(side)),('%s_FK_arm_01_ctrl_grp'%(side),'%s_shoulder_ctrl'%(side))]
        for each in toParent:
            cmds.parent(each[0],each[1])
            cmds.makeIdentity('%s_FK_leg_01_jnt'%(side),'%s_FK_arm_01_jnt'%(side),'%s_shoulder_jnt'%(side),apply=True,translate=True,rotate=True)
        
        toParentCon = [('%s_FK_leg_01_ctrl'%(side),'%s_FK_leg_01_jnt'%(side)),('%s_FK_leg_02_ctrl'%(side),'%s_FK_leg_02_jnt'%(side)),('%s_FK_leg_03_ctrl'%(side),'%s_FK_leg_03_jnt'%(side)),('%s_FK_leg_04_ctrl'%(side),'%s_FK_leg_04_jnt'%(side)),('%s_FK_arm_01_ctrl'%(side),'%s_FK_arm_01_jnt'%(side)),('%s_FK_arm_02_ctrl'%(side),'%s_FK_arm_02_jnt'%(side)),('%s_FK_arm_03_ctrl'%(side),'%s_FK_arm_03_jnt'%(side)),('%s_FK_arm_04_ctrl'%(side),'%s_FK_arm_04_jnt'%(side)),('%s_shoulder_ctrl'%(side),'%s_shoulder_jnt'%(side)),('spine_03_bln_jnt','%s_shoulder_ctrl_grp'%(side)),('spine_01_bln_jnt','%s_FK_leg_01_ctrl_grp'%(side))]
        for each in toParentCon:
            cmds.parentConstraint(each[0],each[1],mo = True)
            
        toLockAttr = [('%s_FK_leg_01_ctrl'%(side)),('%s_FK_leg_02_ctrl'%(side)),('%s_FK_leg_03_ctrl'%(side)),('%s_FK_leg_04_ctrl'%(side)),('%s_shoulder_ctrl'%(side)),('%s_FK_arm_01_ctrl'%(side)),('%s_FK_arm_02_ctrl'%(side)),('%s_FK_arm_03_ctrl'%(side)),('%s_FK_arm_04_ctrl'%(side))]
        for each in toLockAttr:
            cmds.setAttr(each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,6)
        
        # the command to change the progress bar
        cmds.progressBar('QuadrupedProgressBar', edit=True, step=1)
        
    leftRightFKsetup('l')
    leftRightFKsetup('r')
    
    def tailSetup():
        # FK tail 
        nameOfController = [('tail_FK_01_ctrl','tail_FK_01_ctrl_grp'),('tail_FK_02_ctrl','tail_FK_02_ctrl_grp'),('tail_FK_03_ctrl','tail_FK_03_ctrl_grp'),('tail_FK_04_ctrl','tail_FK_04_ctrl_grp'),('tail_FK_05_ctrl','tail_FK_05_ctrl_grp')]
        for each in nameOfController:
            ctrl = cmds.circle(n=each[0],r=5,nrx = 90)
            cmds.delete(ctrl,constructionHistory = True)
            cmds.group(n = each[1])
            
        nameOfJoint = [('tail_FK_01_jnt'),('tail_FK_02_jnt'),('tail_FK_03_jnt'),('tail_FK_04_jnt'),('tail_FK_05_jnt')]
        for each in nameOfJoint:
            cmds.joint(n = each)
            cmds.parent(w = True)
              
        toGetPos = [('tail_01_setup_jnt','tail_FK_01_ctrl_grp'),('tail_02_setup_jnt','tail_FK_02_ctrl_grp'),('tail_03_setup_jnt','tail_FK_03_ctrl_grp'),('tail_04_setup_jnt','tail_FK_04_ctrl_grp'),('tail_05_setup_jnt','tail_FK_05_ctrl_grp'),('tail_01_setup_jnt','tail_FK_01_jnt'),('tail_02_setup_jnt','tail_FK_02_jnt'),('tail_03_setup_jnt','tail_FK_03_jnt'),('tail_04_setup_jnt','tail_FK_04_jnt'),('tail_05_setup_jnt','tail_FK_05_jnt')]
        for each in toGetPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo = False)
            cmds.delete(forDel)
            
        toParent = [('tail_FK_05_ctrl_grp','tail_FK_04_ctrl'),('tail_FK_04_ctrl_grp','tail_FK_03_ctrl'),('tail_FK_03_ctrl_grp','tail_FK_02_ctrl'),('tail_FK_02_ctrl_grp','tail_FK_01_ctrl'),('tail_FK_05_jnt','tail_FK_04_jnt'),('tail_FK_04_jnt','tail_FK_03_jnt'),('tail_FK_03_jnt','tail_FK_02_jnt'),('tail_FK_02_jnt','tail_FK_01_jnt')]
        for each in toParent:
            cmds.parent(each[0],each[1])
            cmds.makeIdentity('tail_FK_01_jnt',apply=True,translate=True,rotate=True)
            
        toParentCon = [('tail_FK_01_ctrl','tail_FK_01_jnt'),('tail_FK_02_ctrl','tail_FK_02_jnt'),('tail_FK_03_ctrl','tail_FK_03_jnt'),('tail_FK_04_ctrl','tail_FK_04_jnt'),('tail_FK_05_ctrl','tail_FK_05_jnt'),('spine_01_bln_jnt','tail_FK_01_ctrl_grp')]
        for each in toParentCon:
            cmds.parentConstraint(each[0],each[1],mo = True)
            
        toLockAttr = [('tail_FK_01_ctrl'),('tail_FK_02_ctrl'),('tail_FK_03_ctrl'),('tail_FK_04_ctrl'),('tail_FK_05_ctrl')]
        for each in toLockAttr:
            cmds.setAttr(each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,6)
        
        # IK tail
        list = ['tail_IK_01_jnt','tail_IK_02_jnt','tail_IK_03_jnt','tail_IK_04_jnt','tail_IK_05_jnt','tail_start_length_jnt','tail_end_length_jnt','tail_01_length_jnt','tail_02_length_jnt','tail_03_length_jnt','tail_04_length_jnt','tail_05_length_jnt']
        for each in list:
            cmds.joint(n=each)
            
        list = [('tail_IK_01_ctrl','tail_IK_01_ctrl_grp'),('tail_IK_02_ctrl','tail_IK_02_ctrl_grp'),('tail_IK_03_ctrl','tail_IK_03_ctrl_grp')]
        for each in list:
            cmds.curve(n=each[0],d=1, p=[(-2.5, -5, 5),(-2.5, 5, 5),(2.5, 5, 5),(2.5, -5, 5),(2.5, -5, -5),(2.5, 5, -5),(-2.5, 5, -5),(-2.5, -5, -5),(-2.5, -5, 5),(2.5, -5, 5),(2.5, 5, 5),(2.5, 5, -5),(2.5, -5, -5),(-2.5, -5, -5),(-2.5, 5, -5),(-2.5, 5, 5)])
            cmds.group(n=each[1])
        
        list = [('tail_01_setup_jnt','tail_IK_01_jnt'),('tail_02_setup_jnt','tail_IK_02_jnt'),('tail_03_setup_jnt','tail_IK_03_jnt'),('tail_04_setup_jnt','tail_IK_04_jnt'),('tail_05_setup_jnt','tail_IK_05_jnt'),('tail_01_setup_jnt','tail_IK_01_ctrl_grp'),('tail_03_setup_jnt','tail_IK_02_ctrl_grp'),('tail_05_setup_jnt','tail_IK_03_ctrl_grp'),('tail_01_setup_jnt','tail_01_length_jnt'),('tail_02_setup_jnt','tail_02_length_jnt'),('tail_03_setup_jnt','tail_03_length_jnt'),('tail_04_setup_jnt','tail_04_length_jnt'),('tail_05_setup_jnt','tail_05_length_jnt'),('tail_01_setup_jnt','tail_start_length_jnt'),('tail_05_setup_jnt','tail_end_length_jnt')]
        for each in list:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
        
        cmds.curve(d=3, p=[(0, 0, 0),(0, 2.5, 0),(0, 5, 0),(0, 7.5, 0),(0, 10, 0)])
        cmds.rename('tail_crv')
        
        nameOfLoc = ['tail_01_loc','tail_02_loc','tail_03_loc','tail_04_loc','tail_05_loc']
        for each in nameOfLoc:
            cmds.spaceLocator(n=each)
    
        toGetLocPos = [('tail_01_loc.translateY',0),('tail_02_loc.translateY',2.5),('tail_03_loc.translateY',5),('tail_04_loc.translateY',7.5),('tail_05_loc.translateY',10)]
        for each in toGetLocPos:
            cmds.setAttr(each[0],each[1])
    
        toConnectLoc = [('tail_01_loc.worldPosition[0]','tail_crv.controlPoints[0]'),('tail_02_loc.worldPosition[0]','tail_crv.controlPoints[1]'),('tail_03_loc.worldPosition[0]','tail_crv.controlPoints[2]'),('tail_04_loc.worldPosition[0]','tail_crv.controlPoints[3]'),('tail_05_loc.worldPosition[0]','tail_crv.controlPoints[4]')]
        for each in toConnectLoc:
            cmds.connectAttr(each[0],each[1])
            
        list = ['tail_setup_grp','tail_jnt_grp','tail_ctrl_grp','tail_IK_ctrl_grp','tail_IK_jnt_grp','tail_IK_setup_jnt_grp']
        for each in list:
            cmds.group(n=each,em=True)
  
        cmds.orientConstraint('tail_IK_01_ctrl','tail_IK_jnt_grp',mo=True)
        
        list = [('tail_01_setup_jnt','tail_01_loc'),('tail_02_setup_jnt','tail_02_loc'),('tail_03_setup_jnt','tail_03_loc'),('tail_04_setup_jnt','tail_04_loc'),('tail_05_setup_jnt','tail_05_loc')]
        for each in list:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
            
        list = [('tail_IK_01_ctrl','tail_01_loc'),('tail_IK_01_ctrl','tail_02_loc'),('tail_IK_02_ctrl','tail_02_loc'),('tail_IK_02_ctrl','tail_03_loc'),('tail_IK_02_ctrl','tail_04_loc'),('tail_IK_03_ctrl','tail_04_loc'),('tail_IK_03_ctrl','tail_05_loc'),('tail_IK_01_ctrl','tail_IK_02_ctrl_grp'),('tail_IK_03_ctrl','tail_IK_02_ctrl_grp'),('spine_01_bln_jnt','tail_IK_ctrl_grp')]    
        for each in list:
            cmds.parentConstraint(each[0],each[1],mo=True)
        cmds.select('tail_IK_01_jnt','tail_IK_05_jnt','tail_crv')
        cmds.ikHandle(n='tail_ikh',sol='ikSplineSolver',ccv=0,pcv =0)
        
        createNode = [('multiplyDivide','tail_stretch_01_mult'),('multiplyDivide','tail_stretch_02_mult')]
        for each in createNode:
            cmds.shadingNode(each[0],n=each[1],asUtility=1)
            
        toSetNode = [('tail_stretch_01_mult.operation',2),('tail_stretch_01_mult.operation',2)]
        for each in toSetNode:
            cmds.setAttr(each[0],each[1])
        
        cmds.arclen('tail_crv',ch = True)
            
        toConnectAttr = [('tail_IK_03_ctrl.rotateX','tail_ikh.twist'),('curveInfo2.arcLength','tail_stretch_01_mult.input1X'),('tail_stretch_01_mult.outputX','tail_stretch_02_mult.input1X'),('tail_02_length_jnt.translateX','tail_stretch_02_mult.input2X'),('tail_stretch_02_mult.outputX','tail_IK_02_jnt.translateX'),('tail_stretch_02_mult.outputX','tail_IK_03_jnt.translateX'),('tail_stretch_02_mult.outputX','tail_IK_04_jnt.translateX'),('tail_stretch_02_mult.outputX','tail_IK_05_jnt.translateX'),('tail_end_length_jnt.translateX','tail_stretch_01_mult.input2X')]
        for each in toConnectAttr:
            cmds.connectAttr(each[0],each[1])
            
        # IKFK tail setup
        list = ['tail_bln_01_jnt','tail_bln_02_jnt','tail_bln_03_jnt','tail_bln_04_jnt','tail_bln_05_jnt']
        for each in list:
            cmds.joint(n=each)
            
        list = [('tail_01_setup_jnt','tail_bln_01_jnt'),('tail_02_setup_jnt','tail_bln_02_jnt'),('tail_03_setup_jnt','tail_bln_03_jnt'),('tail_04_setup_jnt','tail_bln_04_jnt'),('tail_05_setup_jnt','tail_bln_05_jnt')]
        for each in list:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
            
        list = [('tail_FK_01_jnt','tail_bln_01_jnt'),('tail_FK_02_jnt','tail_bln_02_jnt'),('tail_FK_03_jnt','tail_bln_03_jnt'),('tail_FK_04_jnt','tail_bln_04_jnt'),('tail_FK_05_jnt','tail_bln_05_jnt'),('tail_IK_01_jnt','tail_bln_01_jnt'),('tail_IK_02_jnt','tail_bln_02_jnt'),('tail_IK_03_jnt','tail_bln_03_jnt'),('tail_IK_04_jnt','tail_bln_04_jnt'),('tail_IK_05_jnt','tail_bln_05_jnt')]
        for each in list:
            cmds.parentConstraint(each[0],each[1],mo=True)
            
        cmds.curve(n='tail_ik_fk_switch',d=1, p=[(1.25, 0, 7.5),(-1.25, 0, 7.5),(-1.25, 0, 1.25),(-7.5, 0, 1.25),(-7.5, 0, -1.25),(-1.25, 0, -1.25),(-1.25, 0, -7.5),(1.25, 0 ,-7.5),(1.25, 0, -1.25),(7.5, 0, -1.25),(7.5, 0, 1.25,),(1.25, 0 ,1.25),(1.25, 0, 7.5)])
        cmds.group(n='tail_ik_fk_switch_grp')
        cmds.setAttr('tail_ik_fk_switch.visibility',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.translateX',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.translateY',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.translateZ',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.rotateX',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.rotateY',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.rotateZ',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.scaleX',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.scaleY',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.scaleZ',keyable = False, cb = False, lock = True)
        cmds.setAttr('tail_ik_fk_switch.overrideEnabled' ,True) 
        cmds.setAttr('tail_ik_fk_switch.overrideColor' ,15)
        cmds.parent('tail_ik_fk_switch_grp', 'world_ctrl')
        cmds.addAttr('tail_ik_fk_switch',sn='IKFK', min = 0, max=1 ,k=1)
        cmds.parentConstraint('tail_bln_01_jnt','tail_ik_fk_switch_grp')
        cmds.shadingNode('reverse',n='tail_ik_rev',asUtility=1)
        
        toConnectAttr = [('tail_ik_fk_switch.IKFK','tail_bln_01_jnt_parentConstraint1.tail_FK_01_jntW0'),('tail_ik_fk_switch.IKFK','tail_ik_rev.inputX'),('tail_ik_rev.outputX','tail_bln_01_jnt_parentConstraint1.tail_IK_01_jntW1'),('tail_ik_fk_switch.IKFK','tail_bln_02_jnt_parentConstraint1.tail_FK_02_jntW0'),('tail_ik_rev.outputX','tail_bln_02_jnt_parentConstraint1.tail_IK_02_jntW1'),('tail_ik_fk_switch.IKFK','tail_bln_03_jnt_parentConstraint1.tail_FK_03_jntW0'),('tail_ik_rev.outputX','tail_bln_03_jnt_parentConstraint1.tail_IK_03_jntW1'),('tail_ik_fk_switch.IKFK','tail_bln_04_jnt_parentConstraint1.tail_FK_04_jntW0'),('tail_ik_rev.outputX','tail_bln_04_jnt_parentConstraint1.tail_IK_04_jntW1'),('tail_ik_fk_switch.IKFK','tail_bln_05_jnt_parentConstraint1.tail_FK_05_jntW0'),('tail_ik_rev.outputX','tail_bln_05_jnt_parentConstraint1.tail_IK_05_jntW1'),('tail_ik_rev.outputX','tail_IK_ctrl_grp.visibility'),('tail_ik_fk_switch.IKFK','tail_FK_01_ctrl_grp.visibility')]
        for each in toConnectAttr:
            cmds.connectAttr(each[0],each[1])
        
        # create tail group
        list = [('tail_IK_01_jnt','tail_IK_jnt_grp'),('tail_start_length_jnt','tail_IK_setup_jnt_grp'),('tail_01_length_jnt','tail_IK_setup_jnt_grp'),('tail_IK_01_ctrl_grp','tail_IK_ctrl_grp'),('tail_IK_02_ctrl_grp','tail_IK_ctrl_grp'),('tail_IK_03_ctrl_grp','tail_IK_ctrl_grp'),('tail_IK_ctrl_grp','tail_ctrl_grp'),('tail_FK_01_ctrl_grp','tail_ctrl_grp'),('tail_ik_fk_switch_grp','tail_ctrl_grp'),('tail_FK_01_jnt','tail_jnt_grp'),('tail_IK_01_jnt','tail_jnt_grp'),('tail_bln_01_jnt','tail_jnt_grp'),('tail_IK_setup_jnt_grp','tail_jnt_grp'),('tail_IK_jnt_grp','tail_jnt_grp'),('tail_crv','tail_setup_grp'),('tail_01_loc','tail_setup_grp'),('tail_02_loc','tail_setup_grp'),('tail_03_loc','tail_setup_grp'),('tail_04_loc','tail_setup_grp'),('tail_05_loc','tail_setup_grp'),('tail_IK_jnt_grp','tail_setup_grp'),('tail_IK_setup_jnt_grp','tail_setup_grp'),('tail_ikh','tail_setup_grp')]
        for each in list:
            cmds.parent(each[0],each[1])
            
        # the command to change the progress bar
        cmds.progressBar('QuadrupedProgressBar', edit=True, step=1)
        
    tailSetup()
    
    def neckSetup():
        nameOfController = [('neck_01_ctrl','neck_01_ctrl_grp'),('neck_02_ctrl','neck_02_ctrl_grp'),('head_ctrl','head_ctrl_grp')]
        for each in nameOfController:
            cmds.curve(n=each[0],d=1, p=[(12.5, 12.5, 0),(-12.5, 12.5, 0),(-12.5, -12.5, 0),(12.5, -12.5, 0),(12.5, 12.5, 0)])
            cmds.group(n=each[1])
            
        nameOfJoint = [('neck_01_jnt'),('neck_02_jnt'),('head_jnt')]
        for each in nameOfJoint:
            cmds.joint(n=each)
            cmds.parent(w=True)
            
        toGetPos = [('neck_01_setup_jnt','neck_01_ctrl_grp'),('neck_02_setup_jnt','neck_02_ctrl_grp'),('head_setup_jnt','head_ctrl_grp'),('neck_01_setup_jnt','neck_01_jnt'),('neck_02_setup_jnt','neck_02_jnt'),('head_setup_jnt','head_jnt')]
        for each in toGetPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo = False)
            cmds.delete(forDel)
            
        toParent = [('head_ctrl_grp','neck_02_ctrl'),('neck_02_ctrl_grp','neck_01_ctrl'),('head_jnt','neck_02_jnt'),('neck_02_jnt','neck_01_jnt')]
        for each in toParent:   
            cmds.parent(each[0],each[1])
            cmds.makeIdentity('neck_01_jnt',apply=True,translate=True,rotate=True)
            
        toParentCon = [('neck_01_ctrl','neck_01_jnt'),('neck_02_ctrl','neck_02_jnt'),('head_ctrl','head_jnt'),('spine_03_bln_jnt','neck_01_ctrl_grp')]
        for each in toParentCon:
            cmds.parentConstraint(each[0],each[1],mo = True)
            
        toLockAttr = [('neck_01_ctrl'),('neck_02_ctrl'),('head_ctrl')]
        for each in toLockAttr:
            cmds.setAttr(each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,17)
        
        # the command to change the progress bar
        cmds.progressBar('QuadrupedProgressBar', edit=True, step=1)

    neckSetup()
    
    def leftRightIKsetup(side):
        nameOfJoint = [('%s_IK_leg_01_jnt'%(side)),('%s_IK_leg_02_jnt'%(side)),('%s_IK_leg_03_jnt'%(side)),('%s_IK_leg_04_jnt'%(side)),('%s_IK_arm_01_jnt'%(side)),('%s_IK_arm_02_jnt'%(side)),('%s_IK_arm_03_jnt'%(side)),('%s_IK_arm_04_jnt'%(side))]
        for each in nameOfJoint:
            cmds.joint(n=each)
        
        list = [('%s_IK_leg_roll_ctrl'%(side),'%s_IK_leg_roll_ctrl_grp'%(side)),('%s_IK_arm_roll_ctrl'%(side),'%s_IK_arm_roll_ctrl_grp'%(side))]
        for each in list:
            cmds.curve(d=1, p=[(0.5, 0.5, 0.5),(-0.5, 0.5, 0.5),(-1, 0, 0.5),(-1, 0, 1),(-1.5, -0.5, 0),(-1, 0, -1),(-1, 0, -0.5),(-0.5, 0.5, -0.5),(0.5, 0.5, -0.5),(1, 0, -0.5),(1, 0, -1),(1.5, -0.5, 0),(1, 0, 1),(1, 0, 1),(1, 0, 0.5),(0.5, 0.5, 0.5)],n=each[0])
            cmds.group(n=each[1])
        
        nameOfIKfootController = [('%s_IK_leg_ctrl'%(side),'%s_IK_leg_ctrl_grp'%(side)),('%s_IK_arm_ctrl'%(side),'%s_IK_arm_ctrl_grp'%(side))]
        for each in nameOfIKfootController:
            cmds.curve(n=each[0],d=1, p=[(-5, -5, 5),(-5, 5, 5),(5, 5, 5),(5, -5, 5),(5, -5, -5),(5, 5, -5),(-5, 5, -5),(-5, -5, -5),(-5, -5, 5),(5, -5, 5),(5, 5, 5),(5, 5, -5),(5, -5, -5),(-5, -5, -5),(-5, 5, -5),(-5, 5, 5)])
            cmds.group(n=each[1])
            
        nameOfPVcontroller = [('%s_leg_PV_ctrl'%(side),'%s_leg_PV_ctrl_grp'%(side)),('%s_arm_PV_ctrl'%(side),'%s_arm_PV_ctrl_grp'%(side))]
        for each in nameOfPVcontroller:
            cmds.curve(n=each[0],d = 1, p = [(0, 5, 0), (0, 0, 5), (0, -5, 0), (0, 0, -5), (0, 5, 0), (5, 0, 0), (0, -5, 0), (-5, 0, 0), (0, 0, 5), (5, 0, 0), (0, 0, -5), (-5, 0, 0), (0, 5, 0)])
            cmds.group(n=each[1])
            
        toGetControllerPos = [('%s_leg_04_setup_jnt'%(side),'%s_IK_leg_ctrl_grp'%(side)),('%s_arm_04_setup_jnt'%(side),'%s_IK_arm_ctrl_grp'%(side)),('%s_leg_PV_setup_loc'%(side),'%s_leg_PV_ctrl_grp'%(side)),('%s_arm_PV_setup_loc'%(side),'%s_arm_PV_ctrl_grp'%(side)),('%s_leg_04_setup_jnt'%(side),'%s_IK_leg_roll_ctrl_grp'%(side)),('%s_arm_04_setup_jnt'%(side),'%s_IK_arm_roll_ctrl_grp'%(side))]
        for each in toGetControllerPos:
            forDel = cmds.pointConstraint(each[0],each[1],mo = False)
            cmds.delete(forDel)
            
        toGetJointPos = [('%s_leg_01_setup_jnt'%(side),'%s_IK_leg_01_jnt'%(side)),('%s_leg_02_setup_jnt'%(side),'%s_IK_leg_02_jnt'%(side)),('%s_leg_03_setup_jnt'%(side),'%s_IK_leg_03_jnt'%(side)),('%s_leg_04_setup_jnt'%(side),'%s_IK_leg_04_jnt'%(side)),('%s_arm_01_setup_jnt'%(side),'%s_IK_arm_01_jnt'%(side)),('%s_arm_02_setup_jnt'%(side),'%s_IK_arm_02_jnt'%(side)),('%s_arm_03_setup_jnt'%(side),'%s_IK_arm_03_jnt'%(side)),('%s_arm_04_setup_jnt'%(side),'%s_IK_arm_04_jnt'%(side))]
        for each in toGetJointPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
            
        list = [('%s_IK_leg_roll_ctrl'%(side)),('%s_IK_arm_roll_ctrl'%(side))]
        for each in list:
            cmds.setAttr (each+'.translateX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.translateY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.translateZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,6)
        
        toLockPVcontroller = [('%s_leg_PV_ctrl'%(side)),('%s_arm_PV_ctrl'%(side))]
        for each in toLockPVcontroller:
            cmds.setAttr (each+'.rotateX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.rotateY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.rotateZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,6)
            cmds.addAttr (each,sn='follow', min = 0, max=1 ,k=1)
            
        toLockIKcontroller = [('%s_IK_leg_ctrl'%(side)),('%s_IK_arm_ctrl'%(side))]
        for each in toLockIKcontroller:
            cmds.setAttr (each+'.visibility',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.scaleZ',keyable = False, cb = False, lock = True)
            cmds.setAttr (each+'.overrideEnabled' ,True) 
            cmds.setAttr (each+'.overrideColor' ,6)
            cmds.addAttr (each,sn='stretch',at = 'bool',k=1)
            cmds.addAttr (each,sn='heelLift' ,k=1)
            cmds.addAttr (each,sn='toeLift' ,k=1)
            cmds.addAttr (each,sn='footRock' ,k=1)
            
        nameOfLoc = [('%s_leg_heel_loc'%(side)),('%s_leg_toe_lift_loc'%(side)),('%s_leg_roll_out_loc'%(side)),('%s_leg_roll_in_loc'%(side)),('%s_arm_heel_loc'%(side)),('%s_arm_toe_lift_loc'%(side)),('%s_arm_roll_out_loc'%(side)),('%s_arm_roll_in_loc'%(side)),('%s_leg_PV_aim_loc'%(side)),('%s_leg_PV_aim_up_loc'%(side)),('%s_leg_PV_aim_base_loc'%(side)),('%s_leg_PV_aim_world_loc'%(side)),('%s_arm_PV_aim_loc'%(side)),('%s_arm_PV_aim_up_loc'%(side)),('%s_arm_PV_aim_base_loc'%(side)),('%s_arm_PV_aim_world_loc'%(side))]
        for each in nameOfLoc:
            cmds.spaceLocator(n=each)
        
        toGetGrp = [('%s_IK_leg_loc_grp'%(side)),('%s_IK_arm_loc_grp'%(side)),('%s_IK_leg_jnt_grp'%(side)),('%s_IK_arm_jnt_grp'%(side)),('%s_IK_arm_PV_loc_grp'%(side)),('%s_IK_leg_PV_loc_grp'%(side)),('%s_IK_leg_grp'%(side)),('%s_IK_arm_grp'%(side))]
        for each in toGetGrp:
            cmds.group(n=each,em=True)
            
        toGetPos = [('%s_leg_05_setup_jnt'%(side),'%s_leg_toe_lift_loc'%(side)),('%s_leg_heel_setup_jnt'%(side),'%s_leg_heel_loc'%(side)),('%s_leg_rock_out_setup_jnt'%(side),'%s_leg_roll_out_loc'%(side)),('%s_leg_rock_in_setup_jnt'%(side),'%s_leg_roll_in_loc'%(side)),('%s_arm_05_setup_jnt'%(side),'%s_arm_toe_lift_loc'%(side)),('%s_arm_heel_setup_jnt'%(side),'%s_arm_heel_loc'%(side)),('%s_arm_rock_out_setup_jnt'%(side),'%s_arm_roll_out_loc'%(side)),('%s_arm_rock_in_setup_jnt'%(side),'%s_arm_roll_in_loc'%(side)),('%s_leg_04_setup_jnt'%(side),'%s_IK_leg_loc_grp'%(side)),('%s_arm_04_setup_jnt'%(side),'%s_IK_arm_loc_grp'%(side)),('spine_01_bln_jnt','%s_leg_PV_aim_up_loc'%(side)),('%s_IK_leg_01_jnt'%(side),'%s_leg_PV_aim_base_loc'%(side)),('%s_IK_leg_04_jnt'%(side),'%s_leg_PV_aim_loc'%(side)),('%s_leg_PV_ctrl'%(side),'%s_leg_PV_aim_world_loc'%(side)),('spine_03_bln_jnt','%s_arm_PV_aim_up_loc'%(side)),('%s_IK_arm_01_jnt'%(side),'%s_arm_PV_aim_base_loc'%(side)),('%s_IK_arm_04_jnt'%(side),'%s_arm_PV_aim_loc'%(side)),('%s_arm_PV_ctrl'%(side),'%s_arm_PV_aim_world_loc'%(side))]
        for each in toGetPos:
            forDel = cmds.parentConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
        
        list = [('%s_arm_heel_loc'%(side),'%s_IK_arm_loc_grp'%(side)),('%s_leg_heel_loc'%(side),'%s_IK_leg_loc_grp'%(side))]
        for each in list:
            forDel = cmds.orientConstraint(each[0],each[1],mo=False)
            cmds.delete(forDel)
            
        cmds.parent('%s_IK_leg_01_jnt'%(side),'%s_IK_leg_jnt_grp'%(side))
        cmds.parent('%s_IK_arm_01_jnt'%(side),'%s_IK_arm_jnt_grp'%(side))
        cmds.makeIdentity('%s_IK_leg_01_jnt'%(side),'%s_IK_arm_01_jnt'%(side),apply=True,translate=True,rotate=True)
        cmds.addAttr ('%s_IK_leg_ctrl'%(side), at = 'enum', keyable=True, en = 'string1:string2:', ln='follow') 
        cmds.addAttr ('%s_IK_leg_ctrl'%(side)+'.follow', e=True, en = 'world:pelvis:')
        cmds.addAttr ('%s_IK_arm_ctrl'%(side), at = 'enum', keyable=True, en = 'string1:string2:', ln='follow') 
        cmds.addAttr ('%s_IK_arm_ctrl'%(side)+'.follow', e=True, en = 'world:shoulder:')
        cmds.ikHandle(n='%s_leg_upr_ikh'%(side), sj='%s_IK_leg_01_jnt'%(side), ee='%s_IK_leg_03_jnt'%(side),sol='ikRPsolver')
        cmds.ikHandle(n='%s_leg_lwr_ikh'%(side), sj='%s_IK_leg_03_jnt'%(side), ee='%s_IK_leg_04_jnt'%(side),sol='ikRPsolver')
        cmds.ikHandle(n='%s_arm_upr_ikh'%(side), sj='%s_IK_arm_01_jnt'%(side), ee='%s_IK_arm_03_jnt'%(side),sol='ikRPsolver')
        cmds.ikHandle(n='%s_arm_lwr_ikh'%(side), sj='%s_IK_arm_03_jnt'%(side), ee='%s_IK_arm_04_jnt'%(side),sol='ikRPsolver')
        cmds.parentConstraint('%s_shoulder_ctrl'%(side),'%s_IK_arm_01_jnt'%(side),mo = True)
        cmds.poleVectorConstraint('%s_arm_PV_ctrl'%(side),'%s_arm_upr_ikh'%(side))
        cmds.poleVectorConstraint('%s_leg_PV_ctrl'%(side),'%s_leg_upr_ikh'%(side))
from maya import cmds, OpenMaya

def ui():
    if cmds.workspaceControl("Rig Tools",ex = True):
        cmds.deleteUI("Rig Tools")
    myWin = cmds.workspaceControl("Rig Tools")
    myWin = cmds.tabLayout()
    cmds.scrollLayout(': : : : : : : : : : : : : : : : : : : : : : : : Tools : : : : : : : : : : : : : : : : : : : : : : : :',hst=16,vst=16,w=340)
    cmds.columnLayout(adj = True)
    cmds.showWindow("Rig Tools")
    
    cmds.frameLayout(label='Rig Help', collapsable=True, collapse=True,w=330)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Help to create locator, group, joint, parent and scale constraint.',al='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=5)
    cmds.button('1',vis=False,w=20)
    cmds.button(label='Create Locators', command=create_locator_on_selection,w=139)
    cmds.button('2',vis=False)
    cmds.button(label="Create Group", command=create_group_on_selection,w=139)
    cmds.button('3',vis=False)
    cmds.separator(h=15,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button('4',vis=False)
    cmds.button("Create Joint",c = "jnt()")
    cmds.button('6',vis=False)
    cmds.button("Parent Scale Constraint",c="parentscale()")
    cmds.setParent('..')
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    #Controller tab
    cmds.frameLayout(label='Controller', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nr=4)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.frameLayout(label='Shape', collapsable=True, collapse=True,w=310)
    cmds.rowColumnLayout( nc=1 )
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Help to create different type of controller.',al='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=5)
    cmds.button(w=20,vis=False)
    cmds.button("cube",command=create_cube_on_selection,w = 130)
    cmds.button(w=20,vis=False)
    cmds.button("circle",command=create_circle_on_selection,w = 130)
    cmds.button(w=20,vis=False)
    cmds.separator(h=15,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button(w=20,vis=False)
    cmds.button("square",command=create_square_on_selection)
    cmds.button(w=20,vis=False)
    cmds.button("cross",command=create_x_on_selection)
    cmds.button(w=20,vis=False)
    cmds.separator(h=15,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button(w=20,vis=False)
    cmds.button("pyramid",command=create_pyramid_on_selection)
    cmds.button(w=20,vis=False)
    cmds.button("trianglecube",command=create_trianglecube_on_selection)
    cmds.setParent('..')
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    #Color tab
    cmds.frameLayout(label='Color', collapsable=True, collapse=True,w=310)  
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Help to change color of selected controller.',align='left')
    cmds.separator(h=10,vis=False)
    cmds.gridLayout(nr=1,nc=10,cellWidthHeight=(31,20))
    backgroundColor = [((0.348,0.057,0.064),"DarkRed()"),((0.081,0.115,0.404),"darkBlue()"),((0.100,0.031,3.658),"blue()"),((0.052,0.013,0.114),"black()"),((0.531,0.091,0.768),"purple()"),((0.288,0.145,0.088),"brown()"),((0.096,0.058,0.049),"darkBrown()"),((0.333,0.089,0.016),"darkOrange()"),((1.240,0.106,0.018),"red()"),((0.294,5.113,0.000),"lightGreen()"),((8.423,2.724,0.000),"yellow()"),((0.423,1.213,8.659),"lightBlue()"),((2.320,0.606,0.574),"pink()"),((1.094,0.572,0.285),"lightOrange()"),((0.175,0.402,0.174),"darkGreen()"),((0.443,0.469,0.104),"darkYellow()"),((0.210,0.448,0.198),"green()"),((0.350,0.109,0.219),"darkPink()"),((0.208,0.096,0.447),"darkPurple()"),((0.147,0.211,0.456),"navy()")]
    for each in backgroundColor:
        cmds.iconTextButton(bgc=each[0],c=each[1])
    cmds.setParent('..')
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    #Lock attributes tab
    cmds.frameLayout(label='Attributes Lock / Unlock', collapsable=True, collapse=True,w=310)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Help to lock or unlock attributes of selected controller.',align='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=5)
    cmds.button('1',vis=False,w=17)
    cmds.button("lock / unlock translate",c = "LockTranslate()",w=134)
    cmds.button('2',vis=False,w=17)
    cmds.button("lock / unlock rotate",c = "LockRotate()",w=134)
    cmds.button('3',vis=False,w=17)
    cmds.separator(h=15,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button('4',vis=False,w=17)
    cmds.button("lock / unlock scale",c = "LockScale()")
    cmds.button('5',vis=False,w=17)
    cmds.button("lock / unlock visibility",c = "LockVisibility()")
    cmds.setParent('..')
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    #Mirror controller tab
    cmds.frameLayout(label='Mirror', collapsable=True, collapse=True,w=310)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Help to mirror controller.',align='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=7)
    cmds.button(w=10,vis=False)
    cmds.button("Left To Right",c = "MirrorFromLeft()",w=90)
    cmds.button(w=10,vis=False)
    cmds.button("Right To Left",c = "MirrorFromRight()",w=90)
    cmds.button(w=10,vis=False)
    cmds.button("Selected",c = "MirrorFromSelected()",w=90)
    cmds.button(w=10,vis=False)
    cmds.separator(h=5,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    #Connect attributes tab
    cmds.frameLayout(label='Connect Attr', collapsable=True, collapse=True)  
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Help to connect atrribute of selected object.',align='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=7)
    cmds.button(w=10,vis=False)
    cmds.button("Connect Translate",c = "ConnectTanslate()",w=96)
    cmds.button(w=10,vis=False)
    cmds.button("Connect Rotate",c = "ConnectRotate()",w=96)
    cmds.button(w=10,vis=False)
    cmds.button("Connect Scale",c = "ConnectScale()",w=96)
    cmds.button(w=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    #follicle tab
    cmds.frameLayout(label='Create Follicle', collapsable=True, collapse=True) 
    cmds.rowColumnLayout(nc=1)
    cmds.separator(vis=False)
    cmds.text('Select a plane and locators then click "Create Follicles".',align='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=3)
    cmds.button(w=63,vis=False)
    cmds.button("Create Follicles",c = 'createFollicles()',w=200)
    cmds.button(w=63,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Rename', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nr=5)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    #rename tab#
    cmds.frameLayout(label='Search And Replace', collapsable=True, collapse=True,w=310)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=5,vis=False)
    cmds.text('Help to search and replace name of selected object.',al='left')
    cmds.rowColumnLayout(nc=4)
    cmds.separator(h=10,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.text(label='Search:',w=70,al='left')
    cmds.button(w=20,vis=False)
    cmds.textField('search_field',w=190)
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.text(label='Replace:',al='left')
    cmds.button(w=20,vis=False)
    cmds.textField('replace_field')
    cmds.button(vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button(vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(label='Rename', command='search_replace()')
    cmds.button(vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    # Prefix UI elements
    cmds.frameLayout(label='Add Prefix', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=5,vis=False)
    cmds.text('Help to add prefix name of selected object.',al='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=4)
    cmds.text(label='Prefix:',w=70,al='left')
    cmds.button(w=20,vis=False)
    cmds.textField('prefix_field',w=190)
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button(vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(label='Add Prefix',c='addPrefix()')
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    # Suffix UI elements
    cmds.frameLayout(label='Add Suffix', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=5,vis=False)
    cmds.text('Help to add suffix name of selected object.',al='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=4)
    cmds.text(label='Suffix:',w=70,al = 'left')
    cmds.button(w=20,vis=False)
    cmds.textField('suffix_field',w=190)
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.separator(vis=False)
    cmds.button(vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(label='Add Suffix',c='addSuffix()')
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    #add suffix name#
    cmds.frameLayout(label='Add Prefix or Suffix Name', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=5,vis=False)
    cmds.text('Help to add suffix name of selected object.',al='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=7)
    cmds.button(w=10,vis=False)
    cmds.button(label='_jnt',c='addSuffixJnt()',w=88)
    cmds.button(w=10,vis=False)
    cmds.button(label='_grp',c='addSuffixGrp()',w=88)
    cmds.button(w=10,vis=False)
    cmds.button(label='_ctrl',c='addSuffixCtrl()',w=88)
    cmds.button(w=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    #add number suffix name#
    cmds.frameLayout(label='Add Number Suffix Name', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=5,vis=False)
    cmds.text('Help to add number suffix name of selected object.',al='left')
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=4)
    cmds.text(label="Start number:",al='left')
    cmds.button(w=20,vis=False)
    cmds.intField('startNumField',value=1, minValue=1,w=190)
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.text(label="Increment:",al='left')
    cmds.button(w=20,vis=False)
    cmds.intField('incrementField',value=1, minValue=1)
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(label="Add Suffix", command='add_suffix()')
    cmds.button(w=20,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    #Auto rig tab
    cmds.frameLayout(label='Auto Rig', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nr=4)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.frameLayout(label='Biped', collapsable=True, collapse=True,w=310)
    cmds.rowColumnLayout( nc=1 )
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=3)
    cmds.text('Biped Setup:',al='left')
    cmds.button("SetupJoint",c = "setupjoint()",w = 150)
    cmds.button(w = 150,vis=0)
    cmds.separator(h=25,w=100)
    cmds.separator()
    cmds.separator()
    cmds.text('Mirror Setup:',al='left')
    cmds.button("MirrorSetupJoint",c = "mirrorSetupjoint()",w = 90)
    cmds.button(w = 150,vis=0)
    cmds.separator(h=25)
    cmds.separator()
    cmds.separator()
    cmds.text('Build Setup:',al='left')
    cmds.button("BuildSetup",c = "buildsetup()",w = 90)
    cmds.button(w = 150,vis=0)
    cmds.separator(h=25)
    cmds.separator()
    cmds.separator()
    cmds.text('Bendy Setup:',al='left')
    cmds.checkBox('bendyArm', label='BendyArm')
    cmds.button(w = 150,vis=0)
    cmds.button(w = 150,vis=0)
    cmds.checkBox('bendyLeg', label='BendyLeg')
    cmds.separator(vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Extra Rig', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.rowColumnLayout(nr=3)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.frameLayout(label='IK Spring Rig', collapsable=True, collapse=True,w=285)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=4)
    cmds.text('IK Spring Setup:',al='left')
    cmds.button(w=40,vis=False)
    cmds.button("BuildIKSpringSetupJoint",c = "BuildIKSpringSetupJoint()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Build Setup:',al='left')
    cmds.button(w=40,vis=False)
    cmds.button("BuildIKSpringSetupRig",c = "BuildIKSpringSetupRig()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Tail Rig', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout( nc=4 )
    cmds.text('Tail Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("BuildTailSetupJoint",c = "BuildTailSetupJoint()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Build Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("BuildTailSetupRig",c = "BuildTailSetupRig()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Motion Path Rig', collapsable=True, collapse=True)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout(nc=3)
    cmds.text('Path Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("MotionPathSetupLocator",c = "createLocator()",w = 150)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Joints Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.intField('numbersOfLocator',min=1,value=1)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Build Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("BuildMotionPathSetupRig",c = "createMotionPath()",w = 150)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Quadruped Rig', collapsable=True, collapse=True)
    cmds.rowColumnLayout( nc=1 )
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout( nc=4 )
    cmds.text('Quadruped Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("BuildQuadrupedSetupJoint",c = "BuildQuadrupedSetupJoint()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Mirror Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("MirrorQuadrupedSetupJoint",c = "MirrorQuadrupedSetupJoint()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Build Setup:',al='left')
    cmds.button(w=60,vis=False)
    cmds.button("BuildQuadrupedRig",c = "BuildQuadrupedSetupRig()",w = 150)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Facial', collapsable=True, collapse=True,w=310)
    cmds.rowColumnLayout(nc=1)
    cmds.rowColumnLayout(nr=3)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.button(w=10,vis=0)
    cmds.frameLayout(label='Eyelid', collapsable=True, collapse=True,w=285)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout( nc=4 )
    cmds.text('Eye Locator Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Eye Placement",c = "create_display_eye()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Eye Upper Lid Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Upper Eyelid Vertex",c = "store_vertex_ids()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Eye Lower Lid Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Lower Eyelid Vertex",c = "store_lower_vertex_ids()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Eyelid Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Build Eyelid",c = "create_joints_and_parent_joints()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.text('Eyelid Curve Reverse:',al='left')
    cmds.button(w=20,vis=False)
    cmds.checkBox('reversecrv', label='Reverse Curve')
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Eyelid Rename:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Left Eyelid",c = "rename_left()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.separator(h=20,vis=False)
    cmds.separator(h=20,vis=False)
    cmds.button("Right Eyelid",c = "rename_right()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=10,vis=False)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Lip', collapsable=True, collapse=True,w=285)
    global head_joint_field
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout( nc=4 )
    cmds.text('Head Joint Name:',al='left')
    cmds.button(w=5,vis=False)
    head_joint_field = cmds.textField(placeholderText="Enter Head Joint Name")
    cmds.button(w=20,vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(w=20,vis=False)
    cmds.button(label="Store Selected", command=store_head_joint_name)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Lip Upper Curve Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Upper Lip Edge",c = "create_upper_lip_edge()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Lip Lower Curve Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Lower Lip Edge",c = "create_lower_lip_edge()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Lip Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button("Build Lip Setup",c = "build_lip_setup()",w = 150)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.setParent('..')
    cmds.frameLayout(label='Eyebrow and Cheek', collapsable=True, collapse=True,w=285)
    cmds.rowColumnLayout(nc=1)
    cmds.rowColumnLayout(nc=1)
    cmds.separator(h=10,vis=False)
    cmds.rowColumnLayout( nc=4 )
    cmds.text('Inner Eyebrow Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button(label="Place Selected", command=build_inner_eyebrow_locator,w = 140)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Middle Eyebrow Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button(label="Place Selected", command=build_middle_eyebrow_locator,w = 140)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Outer Eyebrow Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button(label="Place Selected", command=build_outer_eyebrow_locator,w = 140)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Cheek Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button(label="Place Selected", command=build_cheek_locator,w = 140)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.text('Build Setup:',al='left')
    cmds.button(w=20,vis=False)
    cmds.button(label="Build All", command=build_all,w = 140)
    cmds.button(w=5,vis=False)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    cmds.separator(h=20)
    
    #locator function#
def create_locator(position):
    locator = cmds.spaceLocator()[0]
    cmds.move(position[0], position[1], position[2], locator)
    return locator

def create_locator_with_values(selected_object):
    position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
    rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
    locator_name = '{}_loc'.format(selected_object)
    locator = create_locator(position)
    cmds.rotate(rotation[0], rotation[1], rotation[2], locator)
    cmds.rename(locator, locator_name)
    return locator

def create_locator_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_locator_with_values(selected_object)
    else:
        create_locator([0, 0, 0])

    #group function#
def create_group_with_values(selected_object=None):
    group_name = selected_object + "_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    cmds.group(empty=True, name=group_name)
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_group_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_values(selected_object)
    else:
        cmds.group(em=True)

    #joint function#
def jnt():
    selected = cmds.ls(sl = True)
    if selected:
        for each in selected:
            cmds.select(each)
            newJoint = cmds.joint(n=each+'_jnt')
            cmds.parent(newJoint,w = True)
    else:
        cmds.joint()
        
    #parentscale function#    
def parentscale():
    lst = cmds.ls(sl = True)
    cmds.parentConstraint(lst,mo = True)
    cmds.scaleConstraint(lst,mo = True)

    #cube function#
def create_group_with_cube_values(selected_object=None):
    group_name = selected_object + "_ctrl_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    group = cmds.group(empty=True, name=group_name)
    cube = cmds.curve(d=1, p=[(-0.5, -0.5, 0.5),(-0.5, 0.5, 0.5),(0.5, 0.5, 0.5),(0.5, -0.5, 0.5),(0.5, -0.5, -0.5),(0.5, 0.5, -0.5),(-0.5, 0.5, -0.5),(-0.5, -0.5, -0.5),(-0.5, -0.5, 0.5),(0.5, -0.5, 0.5),(0.5, 0.5, 0.5),(0.5, 0.5, -0.5),(0.5, -0.5, -0.5),(-0.5, -0.5, -0.5),(-0.5, 0.5, -0.5),(-0.5, 0.5, 0.5)])
    cmds.parent(cube,group)
    cmds.rename(cube,selected_object + '_ctrl')
    
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_cube_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_cube_values(selected_object)
    else:
        cmds.curve(d=1, p=[(-0.5, -0.5, 0.5),(-0.5, 0.5, 0.5),(0.5, 0.5, 0.5),(0.5, -0.5, 0.5),(0.5, -0.5, -0.5),(0.5, 0.5, -0.5),(-0.5, 0.5, -0.5),(-0.5, -0.5, -0.5),(-0.5, -0.5, 0.5),(0.5, -0.5, 0.5),(0.5, 0.5, 0.5),(0.5, 0.5, -0.5),(0.5, -0.5, -0.5),(-0.5, -0.5, -0.5),(-0.5, 0.5, -0.5),(-0.5, 0.5, 0.5)])
        cmds.group()
        
    #circle function#
def create_group_with_circle_values(selected_object=None):
    group_name = selected_object + "_ctrl_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    group = cmds.group(empty=True, name=group_name)
    curvecircle = cmds.circle()[0]
    cmds.delete(curvecircle,constructionHistory = True)
    cmds.parent(curvecircle,group)
    cmds.rename(curvecircle,selected_object + '_ctrl')
    
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_circle_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_circle_values(selected_object)
    else:
        ctrl = cmds.circle()
        cmds.group()
        cmds.delete(ctrl,constructionHistory = True)
        
    #square function#
def create_group_with_square_values(selected_object=None):
    group_name = selected_object + "_ctrl_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    group = cmds.group(empty=True, name=group_name)
    square = cmds.curve(d=1, p=[(0.5, 0, 0.5),(-0.5, 0, 0.5),(-0.5, 0, -0.5),(0.5, 0, -0.5),(0.5, 0, 0.5)])
    cmds.parent(square,group)
    cmds.rename(square,selected_object + '_ctrl')
    
    
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_square_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_square_values(selected_object)
    else:
        cmds.curve(d=1, p=[(0.5, 0, 0.5),(-0.5, 0, 0.5),(-0.5, 0, -0.5),(0.5, 0, -0.5),(0.5, 0, 0.5)])
        cmds.group()
        
    #X function#
def create_group_with_x_values(selected_object=None):
    group_name = selected_object + "_ctrl_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    group = cmds.group(empty=True, name=group_name)
    x = cmds.curve(d=1, p=[(0.25, 0, 1.5),(-0.25, 0, 1.5),(-0.25, 0, 0.25),(-1.5, 0, 0.25),(-1.5, 0, -0.25),(-0.25, 0, -0.25),(-0.25, 0, -1.5),(0.25, 0 ,-1.5),(0.25, 0, -0.25),(1.5, 0, -0.25),(1.5, 0, 0.25,),(0.25, 0 ,0.25),(0.25, 0, 1.5)])
    cmds.parent(x,group)
    cmds.rename(x,selected_object + '_ctrl')
    
    
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_x_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_x_values(selected_object)
    else:
        cmds.curve(d=1, p=[(0.25, 0, 1.5),(-0.25, 0, 1.5),(-0.25, 0, 0.25),(-1.5, 0, 0.25),(-1.5, 0, -0.25),(-0.25, 0, -0.25),(-0.25, 0, -1.5),(0.25, 0 ,-1.5),(0.25, 0, -0.25),(1.5, 0, -0.25),(1.5, 0, 0.25,),(0.25, 0 ,0.25),(0.25, 0, 1.5)])
        cmds.group()
        
    #pyramid function#
def create_group_with_pyramid_values(selected_object=None):
    group_name = selected_object + "_ctrl_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    group = cmds.group(empty=True, name=group_name)
    pyramid = cmds.curve(d=1, p=[(1, -0.75, 1), (0, 0.5, 0), (-1, -0.75, 1), (1, -0.75, 1), (0, 0.5, 0), (-1, -0.75, -1), (1, -0.75, -1), (0, 0.5, 0), (1, -0.75, -1), (1, -0.75, 1), (0, 0.5, 0), (-1, -0.75, 1), (-1, -0.75, -1)])
    cmds.parent(pyramid,group)
    cmds.rename(pyramid,selected_object + '_ctrl')
    
    
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_pyramid_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_pyramid_values(selected_object)
    else:
        cmds.curve(d=1, p=[(1, -0.75, 1), (0, 0.5, 0), (-1, -0.75, 1), (1, -0.75, 1), (0, 0.5, 0), (-1, -0.75, -1), (1, -0.75, -1), (0, 0.5, 0), (1, -0.75, -1), (1, -0.75, 1), (0, 0.5, 0), (-1, -0.75, 1), (-1, -0.75, -1)])
        cmds.group()

    #trianglecube function#
def create_group_with_trianglecube_values(selected_object=None):
    group_name = selected_object + "_ctrl_grp" if selected_object else "group"
    if cmds.objExists(group_name):
        group_name = cmds.rename(group_name, "{}_1".format(group_name))
    group = cmds.group(empty=True, name=group_name)
    trianglecube = cmds.curve(d = 1, p = [(0, 0.5, 0), (0, 0, 0.5), (0, -0.5, 0), (0, 0, -0.5), (0, 0.5, 0), (0.5, 0, 0), (0, -0.5, 0), (-0.5, 0, 0), (0, 0, 0.5), (0.5, 0, 0), (0, 0, -0.5), (-0.5, 0, 0), (0, 0.5, 0)])
    cmds.parent(trianglecube,group)
    cmds.rename(trianglecube,selected_object + '_ctrl')
    
    if selected_object:
        position = cmds.xform(selected_object, query=True, worldSpace=True, translation=True)
        rotation = cmds.xform(selected_object, query=True, worldSpace=True, rotation=True)
        cmds.move(position[0], position[1], position[2], group_name)
        cmds.rotate(rotation[0], rotation[1], rotation[2], group_name)
    return group_name

def create_trianglecube_on_selection(*args):
    selected_objects = cmds.ls(selection=True)
    if selected_objects:
        for selected_object in selected_objects:
            create_group_with_trianglecube_values(selected_object)
    else:
        cmds.curve(d = 1, p = [(0, 0.5, 0), (0, 0, 0.5), (0, -0.5, 0), (0, 0, -0.5), (0, 0.5, 0), (0.5, 0, 0), (0, -0.5, 0), (-0.5, 0, 0), (0, 0, 0.5), (0.5, 0, 0), (0, 0, -0.5), (-0.5, 0, 0), (0, 0.5, 0)])
        cmds.group()
        
#dark red function#
def DarkRed():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,4)
		
#dark blue function#
def darkBlue():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,5)
    
#blue function#
def blue():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,6)
		
#black function#
def black():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,8)
		
#pink function#
def purple():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,9)
		
#brown function#
def brown():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,10)
		
#dark brown function#
def darkBrown():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,11)
		
#dark orange function#
def darkOrange():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,12)
		
#red function#
def red():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,13)
		
#light green function#
def lightGreen():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,14)
		
#yellow function#
def yellow():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,17)

#lightblue function#
def lightBlue():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,18)
		
#pink function#
def pink():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,20)
		
#light orange function#
def lightOrange():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,21)
		
#dark green function#
def darkGreen():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,7)
		
#dark yellow function#
def darkYellow():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,25)
		
#green function#
def green():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,26)
		
#dark pink function#
def darkPink():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,31)
		
#dark purple function#
def darkPurple():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,30)

#navy function#
def navy():
	sel = cmds. ls(sl = True)
	shape =cmds.listRelatives(sel, shapes = True)
	for node in shape:
		cmds.setAttr(node + ".overrideEnabled" ,True) 
		cmds.setAttr(node + ".overrideColor" ,29)

	#lock translate function#
def LockTranslate():
    sel = cmds.ls(sl = True)
    for obj in sel:
        lockOrNot = cmds.getAttr (obj +'.translateX',lock = True)
        if lockOrNot == False:
            cmds.setAttr (obj +'.translateX',keyable = False, cb = False, lock = True)
            cmds.setAttr (obj +'.translateY',keyable = False, cb = False, lock = True)
            cmds.setAttr (obj +'.translateZ',keyable = False, cb = False, lock = True)
        else:
            cmds.setAttr (obj +'.translateX',keyable = True, cb = False, lock = False)
            cmds.setAttr (obj +'.translateY',keyable = True, cb = False, lock = False)
            cmds.setAttr (obj +'.translateZ',keyable = True, cb = False, lock = False)

	#lock rotate function#
def LockRotate():
    sel = cmds.ls(sl = True)
    for obj in sel:
        lockOrNot = cmds.getAttr (obj +'.rotateX',lock = True)
        if lockOrNot == False:
            cmds.setAttr (obj +'.rotateX',keyable = False, cb = False, lock = True)
            cmds.setAttr (obj +'.rotateY',keyable = False, cb = False, lock = True)
            cmds.setAttr (obj +'.rotateZ',keyable = False, cb = False, lock = True)
        else:
            cmds.setAttr (obj +'.rotateX',keyable = True, cb = False, lock = False)
            cmds.setAttr (obj +'.rotateY',keyable = True, cb = False, lock = False)
            cmds.setAttr (obj +'.rotateZ',keyable = True, cb = False, lock = False)

	#lock scale function#
def LockScale():
    sel = cmds.ls(sl = True)
    for obj in sel:
        lockOrNot = cmds.getAttr (obj +'.scaleX',lock = True)
        if lockOrNot == False:
            cmds.setAttr (obj +'.scaleX',keyable = False, cb = False, lock = True)
            cmds.setAttr (obj +'.scaleY',keyable = False, cb = False, lock = True)
            cmds.setAttr (obj +'.scaleZ',keyable = False, cb = False, lock = True)
        else:
            cmds.setAttr (obj +'.scaleX',keyable = True, cb = False, lock = False)
            cmds.setAttr (obj +'.scaleY',keyable = True, cb = False, lock = False)
            cmds.setAttr (obj +'.scaleZ',keyable = True, cb = False, lock = False)


	#lock visibility function#
def LockVisibility():
    sel = cmds.ls(sl = True)
    for obj in sel:
        lockOrNot = cmds.getAttr (obj +'.visibility',lock = True)
        if lockOrNot == False:
            cmds.setAttr (obj +'.visibility',keyable = False, cb = False, lock = True)
        else:
            cmds.setAttr (obj +'.visibility',keyable = True, cb = False, lock = False)
    	
    #connect tanslation function#
def ConnectTanslate():
    selection = cmds.ls(selection=True)
    if len(selection) != 2:
        cmds.warning("Please select exactly two objects.")
    else:
        source_obj = selection[0]
        destination_obj = selection[1]
        
    attrs = ["translateX", "translateY", "translateZ"]
    
    for attr in attrs:
        cmds.connectAttr(source_obj + "." + attr, destination_obj + "." + attr)
        
    #connect roration function#
def ConnectRotate():
    selection = cmds.ls(selection=True)
    if len(selection) != 2:
        cmds.warning("Please select exactly two objects.")
    else:
        source_obj = selection[0]
        destination_obj = selection[1]
        
    attrs = ["rotateX", "rotateY", "rotateZ"]
    
    for attr in attrs:
        cmds.connectAttr(source_obj + "." + attr, destination_obj + "." + attr)
        
    #connect scaling function#
def ConnectScale():
    selection = cmds.ls(selection=True)
    if len(selection) != 2:
        cmds.warning("Please select exactly two objects.")
    else:
        source_obj = selection[0]
        destination_obj = selection[1]
        
    attrs = ["scaleX", "scaleY", "scaleZ"]
    
    for attr in attrs:
        cmds.connectAttr(source_obj + "." + attr, destination_obj + "." + attr)
        
    # Mirror controllers function
def MirrorFromLeft():
    # Define your left and right prefixes
    left_prefix = "l_"
    right_prefix = "r_"

    # Get a list of NURBS curves with the left prefix
    left_curves = cmds.ls(left_prefix + "*", type="nurbsCurve")

    # Specify the names of the curves to skip
    curves_to_skip = ["r_elbow_direction_crvShape", "l_elbow_direction_crvShape","r_knee_direction_crvShape","l_knee_direction_crvShape","r_lwr_bendy_arm_crvShape","l_lwr_bendy_arm_crvShape","r_lwr_bendy_leg_crvShape","l_lwr_bendy_leg_crvShape","r_upr_bendy_arm_crvShape","l_upr_bendy_arm_crvShape","r_upr_bendy_leg_crvShape","l_upr_bendy_leg_crvShape"]

    # Iterate through the left curves
    for left_curve in left_curves:
        # Check if the curve is in the list of curves to skip
        if left_curve in curves_to_skip:
            print(f"Skipping {left_curve}.")
            continue

        # Construct the corresponding right curve name
        right_curve = left_curve.replace(left_prefix, right_prefix)

        # Check if the right curve exists
        if cmds.objExists(right_curve):
            # Retrieve the CVs from the left curve
            left_cvs = cmds.getAttr(f"{left_curve}.cv[*]")

            # Get the number of CVs
            num_cvs = len(left_cvs)

            # Apply the copied CVs to the right curve
            for i in range(num_cvs):
                target_cv_attr = "{0}.cv[{1}]".format(right_curve, i)
                cmds.setAttr(target_cv_attr, *left_cvs[i], type="double3")

            print("CVs copied from '{0}' to '{1}'.".format(left_curve, right_curve))
        else:
            cmds.warning("Corresponding right curve '{0}' not found for '{1}'. Skipping.".format(right_curve, left_curve))

    print("CV copy completed.")
    
def MirrorFromRight():
    # Define your left and right prefixes
    left_prefix = "l_"
    right_prefix = "r_"

    # Get a list of NURBS curves with the left prefix
    right_curves = cmds.ls(right_prefix + "*", type="nurbsCurve")

    # Specify the names of the curves to skip
    curves_to_skip = ["r_elbow_direction_crvShape", "l_elbow_direction_crvShape","r_knee_direction_crvShape","l_knee_direction_crvShape","r_lwr_bendy_arm_crvShape","l_lwr_bendy_arm_crvShape","r_lwr_bendy_leg_crvShape","l_lwr_bendy_leg_crvShape","r_upr_bendy_arm_crvShape","l_upr_bendy_arm_crvShape","r_upr_bendy_leg_crvShape","l_upr_bendy_leg_crvShape"]

    # Iterate through the left curves
    for right_curve in right_curves:
        # Check if the curve is in the list of curves to skip
        if right_curve in curves_to_skip:
            print(f"Skipping {right_curve}.")
            continue

        # Construct the corresponding right curve name
        left_curve = right_curve.replace(right_prefix, left_prefix)

        # Check if the right curve exists
        if cmds.objExists(left_curve):
            # Retrieve the CVs from the left curve
            right_cvs = cmds.getAttr(f"{right_curve}.cv[*]")

            # Get the number of CVs
            num_cvs = len(right_cvs)

            # Apply the copied CVs to the right curve
            for i in range(num_cvs):
                target_cv_attr = "{0}.cv[{1}]".format(left_curve, i)
                cmds.setAttr(target_cv_attr, *right_cvs[i], type="double3")

            print("CVs copied from '{0}' to '{1}'.".format(right_curve, left_curve))
        else:
            cmds.warning("Corresponding left curve '{0}' not found for '{1}'. Skipping.".format(left_curve, right_curve))

    print("CV copy completed.")
def MirrorFromSelected():
    # Get the selected control shapes (NURBS curves)
    selected_objects = cmds.ls(selection=True)

    # Ensure there are exactly two selected control shapes
    if len(selected_objects) != 2:
        cmds.warning("Please select exactly two NURBS curves to copy from and copy to.")
    else:
        # Sort the selected objects
        selected_objects.sort()

        # Extract CVs from the first selected control shape
        source_cvs = cmds.getAttr(f"{selected_objects[0]}.cp[*]")

        # Extract the number of CVs in the source curve
        num_cvs = len(source_cvs)

        # Apply the copied CVs to the second selected control shape
        for i in range(num_cvs):
            target_cv_attr = "{0}.cp[{1}]".format(selected_objects[1], i)
            cmds.setAttr(target_cv_attr, *source_cvs[i])

        print("CVs copied from '{0}' to '{1}'.".format(selected_objects[0], selected_objects[1]))
 
    #create follicles function#    
def createFollicles(*args):
    sel = cmds.ls(selection=True)
    if len(sel) < 2:
        cmds.warning('Please select a plane and at least one locator.')
        return
    plane = sel[0]
    locators = sel[1:]

    minX, minY, minZ, maxX, maxY, maxZ = cmds.xform(plane, q=True, ws=True, bb=True)
    width = maxX - minX
    height = maxZ - minZ
    
    for loc in locators:
        posX, posY, posZ = cmds.xform(loc, q=True, ws=True, translation=True)
        
        u = (posX - minX) / width
        v = (posZ - minZ) / height
        follicleX = u * width + minX
        follicleY = maxY
        follicleZ = v * height + minZ
        
        follicle = cmds.createNode('follicle')
        cmds.connectAttr('%s.outMesh' % plane, '%s.inputMesh' % follicle)
        cmds.connectAttr('%s.worldMatrix[0]' % plane, '%s.inputWorldMatrix' % follicle)
        cmds.setAttr('%s.parameterU' % follicle, u)
        cmds.setAttr('%s.parameterV' % follicle, v)
        
        cmds.move(follicleX, follicleY, follicleZ, follicle)
        cmds.setAttr('%s.visibility' % follicle, 0)
        
        follicleTransform = cmds.listRelatives(follicle, parent=True)[0]
        cmds.connectAttr('%s.outTranslate' % follicle, '%s.translate' % follicleTransform)
        cmds.connectAttr('%s.outRotate' % follicle, '%s.rotate' % follicleTransform)
        
    #rename function#
def search_replace():
    selection = cmds.ls(selection=True)

    search_text = cmds.textField('search_field', query=True, text=True)
    replace_text = cmds.textField('replace_field', query=True, text=True)

    for node in selection:
        new_name = node.replace(search_text, replace_text)
        cmds.rename(node, new_name)
    
    cmds.textField('search_field',edit=True,text = '')
    cmds.textField('replace_field',edit=True,text = '')
    #prefix and suffix functions#
def addPrefix():
    selection = cmds.ls(selection=True)
    prefix = cmds.textField('prefix_field', query=True, text=True)
    for node in selection:
        new_name = prefix + node
        cmds.rename(node, new_name)
    cmds.textField('prefix_field',edit=True,text = '')
    
def addSuffix():
    selection = cmds.ls(selection=True)
    suffix = cmds.textField('suffix_field', query=True, text=True)
    for node in selection:
        new_name = node + suffix
        cmds.rename(node, new_name)
    cmds.textField('suffix_field',edit=True,text = '')

def addSuffixJnt():
    selection = cmds.ls(selection=True)
    for node in selection:
        new_name = node + '_jnt'
        cmds.rename(node, new_name)
        
def addSuffixGrp():
    selection = cmds.ls(selection=True)
    for node in selection:
        new_name = node + '_grp'
        cmds.rename(node, new_name)
        
def addSuffixCtrl():
    selection = cmds.ls(selection=True)
    for node in selection:
        new_name = node + '_ctrl'
        cmds.rename(node, new_name)
        
    #add number suffix function#   
def add_suffix():
    start_num = cmds.intField('startNumField', query=True, value=True)
    increment = cmds.intField('incrementField', query=True, value=True)
    
    selected_objects = cmds.ls(selection=True)
    for i, obj in enumerate(selected_objects):
        new_suffix = "_{:02d}".format(start_num + i*increment)
        new_name = obj + new_suffix
        cmds.rename(obj, new_name)
        
    #build IK spring setup joint#
def BuildIKSpringSetupJoint():
    nameOfIKSpringSetupJnt = [('ikSpring_01_setup_jnt',(0,0,0)),('ikSpring_02_setup_jnt',(5,0,0)),('ikSpring_03_setup_jnt',(10,0,0)),('ikSpring_04_setup_jnt',(15,0,0)),('ikSpring_05_setup_jnt',(20,0,0))]
    for each in nameOfIKSpringSetupJnt:
        cmds.joint(n=each[0],p=each[1])
    
    cmds.setAttr('ikSpring_01_setup_jnt.rotateY',30)
    cmds.setAttr('ikSpring_02_setup_jnt.rotateY',-60)
    cmds.setAttr('ikSpring_03_setup_jnt.rotateY',60)
    cmds.setAttr('ikSpring_04_setup_jnt.rotateY',-60)
    
    #build IK spring setup rig#        
def BuildIKSpringSetupRig():
    def ControllerAttr(controllerName,visKeyableOrnot,scaleXKeyableOrnot,scaleYKeyableOrnot,scaleZKeyableOrnot,rotateXKeyableOrnot,rotateYKeyableOrnot,rotateZKeyableOrnot,visLockOrnot,scaleXLockOrnot,scaleYLockOrnot,scaleZLockOrnot,rotateXLockOrnot,rotateYLockOrnot,rotateZLockOrnot,colorEnableOrnot,colorNumber,translateXKeyableOrnot,translateYKeyableOrnot,translateZKeyableOrnot,translateXLockOrnot,translateYLockOrnot,translateZLockOrnot):
        cmds.setAttr ((controllerName) +'.visibility',keyable = visKeyableOrnot, cb = False, lock = visLockOrnot)
        cmds.setAttr ((controllerName) +'.scaleX',keyable = scaleXKeyableOrnot, cb = False, lock = scaleXLockOrnot)
        cmds.setAttr ((controllerName) +'.scaleY',keyable = scaleYKeyableOrnot, cb = False, lock = scaleYLockOrnot)
        cmds.setAttr ((controllerName) +'.scaleZ',keyable = scaleZKeyableOrnot, cb = False, lock = scaleZLockOrnot)
        cmds.setAttr ((controllerName) +'.rotateX',keyable = rotateXKeyableOrnot, cb = False, lock = rotateXLockOrnot)
        cmds.setAttr ((controllerName) +'.rotateY',keyable = rotateYKeyableOrnot, cb = False, lock = rotateYLockOrnot)
        cmds.setAttr ((controllerName) +'.rotateZ',keyable = rotateZKeyableOrnot, cb = False, lock = rotateZLockOrnot)
        cmds.setAttr ((controllerName) +'.translateX',keyable = translateXKeyableOrnot, cb = False, lock = translateXLockOrnot)
        cmds.setAttr ((controllerName) +'.translateY',keyable = translateYKeyableOrnot, cb = False, lock = translateYLockOrnot)
        cmds.setAttr ((controllerName) +'.translateZ',keyable = translateZKeyableOrnot, cb = False, lock = translateZLockOrnot)
        cmds.setAttr ((controllerName) + '.overrideEnabled' ,colorEnableOrnot) 
        cmds.setAttr ((controllerName) + '.overrideColor' ,colorNumber)
        
    nameOfIKSpringSetupRigUprJnt = [('ik_upr_01_jnt'),('ik_upr_02_jnt'),('ik_upr_03_jnt')]
    for each in nameOfIKSpringSetupRigUprJnt:
        cmds.joint(n=each)
        
        
    toGetPosUprJnt = [('ikSpring_01_setup_jnt','ik_upr_01_jnt'),('ikSpring_02_setup_jnt','ik_upr_02_jnt'),('ikSpring_03_setup_jnt','ik_upr_03_jnt')]
    for each in toGetPosUprJnt:
        parentConForDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(parentConForDel)
    orientConForDel = cmds.orientConstraint('ikSpring_02_setup_jnt','ik_upr_03_jnt',mo=False)
    cmds.delete(orientConForDel)
    cmds.makeIdentity( 'ik_upr_01_jnt', apply=True, translate=True, rotate=True )
    
    nameOfIKSpringSetupRigLwrJnt = [('ik_lwr_01_jnt'),('ik_lwr_02_jnt'),('ik_lwr_03_jnt')]
    for each in nameOfIKSpringSetupRigLwrJnt:
        cmds.joint(n=each)
        cmds.parent(w=True)
    
    toGetPosLwrJnt = [('ikSpring_03_setup_jnt','ik_lwr_01_jnt'),('ikSpring_04_setup_jnt','ik_lwr_02_jnt'),('ikSpring_05_setup_jnt','ik_lwr_03_jnt')]
    for each in toGetPosLwrJnt:
        parentConForDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(parentConForDel)
        
    nameOfFKSetupJnt = [('fk_01_jnt'),('fk_02_jnt'),('fk_03_jnt'),('fk_04_jnt'),('fk_05_jnt')]
    for each in nameOfFKSetupJnt:
        cmds.joint(n=each)
        cmds.parent(w=True)
    
    toGetPosFKJnt = [('ikSpring_01_setup_jnt','fk_01_jnt'),('ikSpring_02_setup_jnt','fk_02_jnt'),('ikSpring_03_setup_jnt','fk_03_jnt'),('ikSpring_04_setup_jnt','fk_04_jnt'),('ikSpring_05_setup_jnt','fk_05_jnt')]
    for each in toGetPosFKJnt:
        parentConForDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(parentConForDel)
        
    nameOfIKSpringSetupRigJnt = [('ikSpring_01_jnt'),('ikSpring_02_jnt'),('ikSpring_03_jnt'),('ikSpring_04_jnt'),('ikSpring_05_jnt')]
    for each in nameOfIKSpringSetupRigJnt:
        cmds.joint(n=each)
        cmds.parent(w=True)
        
    toGetPosIKSpringJnt = [('ikSpring_01_setup_jnt','ikSpring_01_jnt'),('ikSpring_02_setup_jnt','ikSpring_02_jnt'),('ikSpring_03_setup_jnt','ikSpring_03_jnt'),('ikSpring_04_setup_jnt','ikSpring_04_jnt'),('ikSpring_05_setup_jnt','ikSpring_05_jnt')]
    for each in toGetPosIKSpringJnt:
        parentConForDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(parentConForDel)
    
    toParent = [('fk_05_jnt','fk_04_jnt'),('fk_04_jnt','fk_03_jnt'),('fk_03_jnt','fk_02_jnt'),('fk_02_jnt','fk_01_jnt'),('ik_lwr_03_jnt','ik_lwr_02_jnt'),('ik_lwr_02_jnt','ik_lwr_01_jnt'),('ikSpring_05_jnt','ikSpring_04_jnt'),('ikSpring_04_jnt','ikSpring_03_jnt'),('ikSpring_03_jnt','ikSpring_02_jnt'),('ikSpring_02_jnt','ikSpring_01_jnt')]
    for each in toParent:
        cmds.parent(each[0],each[1])
        cmds.makeIdentity( 'ik_lwr_01_jnt','fk_01_jnt','ikSpring_01_jnt', apply=True, translate=True, rotate=True )
    #ik Rig#
    cmds.ikHandle(n='upr_ikh', sj='ik_upr_01_jnt', ee='ik_upr_03_jnt')
    cmds.ikHandle(n='lwr_ikh', sj='ik_lwr_01_jnt', ee='ik_lwr_03_jnt')
    cmds.ikHandle(n='spring_ikh', sj='ikSpring_01_jnt', ee='ikSpring_05_jnt',sol='ikSpringSolver')
    cmds.curve(d=1, p=[(-1, -1, 1),(-1, 1, 1),(1, 1, 1),(1, -1, 1),(1, -1, -1),(1, 1, -1),(-1, 1, -1),(-1, -1, -1),(-1, -1, 1),(1, -1, 1),(1, 1, 1),(1, 1, -1),(1, -1, -1),(-1, -1, -1),(-1, 1, -1),(-1, 1, 1)])
    cmds.rename('ik_mid_ctrl')
    ControllerAttr('ik_mid_ctrl',False,False,False,False,False,False,False,True,True,True,True,False,False,False,True,6,True,True,True,False,False,False)
    cmds.group()
    cmds.rename('ik_mid_ctrl_grp')
    parentCon = cmds.parentConstraint('ik_upr_03_jnt','ik_mid_ctrl_grp',mo = False)
    cmds.delete(parentCon)
    cmds.curve(d=1, p=[(-1, -1, 1),(-1, 1, 1),(1, 1, 1),(1, -1, 1),(1, -1, -1),(1, 1, -1),(-1, 1, -1),(-1, -1, -1),(-1, -1, 1),(1, -1, 1),(1, 1, 1),(1, 1, -1),(1, -1, -1),(-1, -1, -1),(-1, 1, -1),(-1, 1, 1)])
    cmds.rename('ik_inr_ctrl')
    ControllerAttr('ik_inr_ctrl',False,False,False,False,True,True,True,True,True,True,True,False,False,False,True,6,True,True,True,False,False,False)
    cmds.group()
    cmds.rename('ik_inr_ctrl_grp')
    parentCon = cmds.parentConstraint('ik_lwr_03_jnt','ik_inr_ctrl_grp',mo = False)
    cmds.delete(parentCon)
    cmds.curve(d=1, p=[(-2, -2, 2),(-2, 2, 2),(2, 2, 2),(2, -2, 2),(2, -2, -2),(2, 2, -2),(-2, 2, -2),(-2, -2, -2),(-2, -2, 2),(2, -2, 2),(2, 2, 2),(2, 2, -2),(2, -2, -2),(-2, -2, -2),(-2, 2, -2),(-2, 2, 2)])
    cmds.rename('ik_ctrl')
    ControllerAttr('ik_ctrl',False,False,False,False,True,True,True,True,True,True,True,False,False,False,True,6,True,True,True,False,False,False)
    cmds.group()
    cmds.rename('ik_ctrl_grp')
    parentCon = cmds.parentConstraint('ik_lwr_03_jnt','ik_ctrl_grp',mo = False)
    cmds.delete(parentCon)
    cmds.pointConstraint('ik_ctrl','spring_ikh',mo = True)
    cmds.parentConstraint('ikSpring_05_jnt','ik_inr_ctrl_grp',mo = True)
    cmds.parentConstraint('ikSpring_03_jnt','ik_mid_ctrl_grp',mo = True)
    cmds.pointConstraint('ik_mid_ctrl','upr_ikh',mo = True)
    cmds.pointConstraint('ik_inr_ctrl','lwr_ikh',mo = True)
    cmds.pointConstraint('ik_mid_ctrl','ik_lwr_01_jnt',mo = True)
    cmds.orientConstraint('ik_inr_ctrl','ik_lwr_03_jnt',mo = True)
    
    #fk Rig#
    nameOfFKctrl = [('fk_01_ctrl','fk_01_ctrl_grp'),('fk_02_ctrl','fk_02_ctrl_grp'),('fk_03_ctrl','fk_03_ctrl_grp'),('fk_04_ctrl','fk_04_ctrl_grp'),('fk_05_ctrl','fk_05_ctrl_grp')]
    for each in nameOfFKctrl:
        FKctrl = cmds.circle(n=each[0],r=1,nrx = 90)
        cmds.group(n=each[1])
        ControllerAttr(each[0],False,False,False,False,True,True,True,True,True,True,True,False,False,False,True,6,True,True,True,False,False,False)
    
    toGetPosOfFKctrl = [('ikSpring_01_setup_jnt','fk_01_ctrl_grp'),('ikSpring_02_setup_jnt','fk_02_ctrl_grp'),('ikSpring_03_setup_jnt','fk_03_ctrl_grp'),('ikSpring_04_setup_jnt','fk_04_ctrl_grp'),('ikSpring_05_setup_jnt','fk_05_ctrl_grp')]
    for each in toGetPosOfFKctrl:
        parentCon = cmds.parentConstraint(each[0],each[1],mo = False)
        cmds.delete(parentCon)
        
    toGetParent = [('fk_05_ctrl_grp','fk_04_ctrl'),('fk_04_ctrl_grp','fk_03_ctrl'),('fk_03_ctrl_grp','fk_02_ctrl'),('fk_02_ctrl_grp','fk_01_ctrl')]
    for each in toGetParent:
        cmds.parent(each[0],each[1])
        
    parentCon = [('fk_01_ctrl','fk_01_jnt'),('fk_02_ctrl','fk_02_jnt'),('fk_03_ctrl','fk_03_jnt'),('fk_04_ctrl','fk_04_jnt'),('fk_05_ctrl','fk_05_jnt')]
    for each in parentCon:
        cmds.parentConstraint(each[0],each[1],mo = True)
        
    #IKFK Setup Rig#
    nameOfIKFKSetupJnt = [('bln_01_jnt'),('bln_02_jnt'),('bln_03_jnt'),('bln_04_jnt'),('bln_05_jnt')]
    for each in nameOfIKFKSetupJnt:
        cmds.joint(n=each)
        cmds.parent(w = True)
        
    toGetPosOfIKFKjnt = [('ikSpring_01_setup_jnt','bln_01_jnt'),('ikSpring_02_setup_jnt','bln_02_jnt'),('ikSpring_03_setup_jnt','bln_03_jnt'),('ikSpring_04_setup_jnt','bln_04_jnt'),('ikSpring_05_setup_jnt','bln_05_jnt')]
    for each in toGetPosOfIKFKjnt:
        parentCon = cmds.parentConstraint(each[0],each[1])
        cmds.delete(parentCon)
        
    toGetParent = [('bln_05_jnt','bln_04_jnt'),('bln_04_jnt','bln_03_jnt'),('bln_03_jnt','bln_02_jnt'),('bln_02_jnt','bln_01_jnt')]
    for each in toGetParent:
        cmds.parent(each[0],each[1])
        cmds.makeIdentity( 'bln_01_jnt', apply=True, translate=True, rotate=True )
        
    parentConIKFKjnt = [('ik_upr_01_jnt','bln_01_jnt'),('ik_upr_02_jnt','bln_02_jnt'),('ik_lwr_01_jnt','bln_03_jnt'),('ik_lwr_02_jnt','bln_04_jnt'),('ik_lwr_03_jnt','bln_05_jnt'),('fk_01_jnt','bln_01_jnt'),('fk_02_jnt','bln_02_jnt'),('fk_03_jnt','bln_03_jnt'),('fk_04_jnt','bln_04_jnt'),('fk_05_jnt','bln_05_jnt')]
    for each in parentConIKFKjnt:
        cmds.parentConstraint(each[0],each[1],mo = True)
    
    cmds.curve(d=1, p=[(0.5, 0, 2.25),(-0.5, 0, 2.25),(-0.5, 0, 0.5),(-2.25, 0, 0.5),(-2.25, 0, -0.5),(-0.5, 0, -0.5),(-0.5, 0, -2.25),(0.5, 0 ,-2.25),(0.5, 0, -0.5),(2.25, 0, -0.5),(2.25, 0, 0.5,),(0.5, 0 ,0.5),(0.5, 0, 2.25)])
    cmds.rename('ik_fk_switch')
    ControllerAttr('ik_fk_switch',False,False,False,False,False,False,False,True,True,True,True,True,True,True,True,15,False,False,False,True,True,True)
    cmds.group()
    cmds.rename('ik_fk_switch_grp')
    cmds.addAttr('ik_fk_switch',sn='IKFK', min = 0, max=1 ,k=1)
    cmds.parentConstraint('bln_05_jnt', 'ik_fk_switch_grp')
    cmds.shadingNode('reverse',n = 'ik_fk_rev',asUtility=1)
    
    toConect = [('ik_fk_switch.IKFK','bln_01_jnt_parentConstraint1.fk_01_jntW1'),('ik_fk_switch.IKFK','bln_02_jnt_parentConstraint1.fk_02_jntW1'),('ik_fk_switch.IKFK', 'bln_03_jnt_parentConstraint1.fk_03_jntW1'),('ik_fk_switch.IKFK', 'bln_04_jnt_parentConstraint1.fk_04_jntW1'),('ik_fk_switch.IKFK', 'bln_05_jnt_parentConstraint1.fk_05_jntW1'),('ik_fk_rev.outputX', 'bln_01_jnt_parentConstraint1.ik_upr_01_jntW0'),('ik_fk_rev.outputX', 'bln_02_jnt_parentConstraint1.ik_upr_02_jntW0'),('ik_fk_switch.IKFK', 'ik_fk_rev.inputX'),('ik_fk_rev.outputX', 'bln_03_jnt_parentConstraint1.ik_lwr_01_jntW0'),('ik_fk_rev.outputX', 'bln_04_jnt_parentConstraint1.ik_lwr_02_jntW0'),('ik_fk_rev.outputX', 'bln_05_jnt_parentConstraint1.ik_lwr_03_jntW0'),('ik_fk_switch.IKFK','fk_01_ctrl_grp.visibility'),('ik_fk_rev.outputX','ik_mid_ctrl_grp.visibility'),('ik_fk_rev.outputX','ik_inr_ctrl_grp.visibility'),('ik_fk_rev.outputX','ik_ctrl_grp.visibility')]
    for each in toConect:
        cmds.connectAttr(each[0],each[1])
        
    toHide = [('ikSpring_01_setup_jnt.visibility'),('ik_lwr_01_jnt.visibility'),('fk_01_jnt.visibility'),('ikSpring_01_jnt.visibility'),('ik_upr_01_jnt.visibility'),('upr_ikh.visibility'),('lwr_ikh.visibility'),('spring_ikh.visibility')]
    for each in toHide:
        cmds.setAttr(each,0)
        
    createGroup = ('rig_grp','jnt_grp','rename')
    for each in createGroup:
        cmds.group(w=1,n=each,em=1)
        
    toGroup = [('ikSpring_01_setup_jnt','rig_grp'),('ik_lwr_01_jnt','rig_grp'),('fk_01_jnt','rig_grp'),('ikSpring_01_jnt','rig_grp'),('upr_ikh','rig_grp'),('lwr_ikh','rig_grp'),('spring_ikh','rig_grp'),('fk_01_ctrl_grp','rig_grp'),('ik_mid_ctrl_grp','rig_grp'),('ik_inr_ctrl_grp','rig_grp'),('ik_ctrl_grp','rig_grp'),('ik_fk_switch_grp','rig_grp'),('bln_01_jnt','jnt_grp'),('jnt_grp','rename'),('rig_grp','rename')]
    for each in toGroup:
        cmds.parent(each[0],each[1])

#create tail setup joint function#
def BuildTailSetupJoint():
    list = [('tail_01_setup_jnt',(0, 0, 0)),('tail_02_setup_jnt',(10, 0, 0)),('tail_03_setup_jnt',(20, 0, 0)),('tail_04_setup_jnt',(30, 0, 0)),('tail_05_setup_jnt',(40, 0, 0))]
    for each in list:
        cmds.joint(n=each[0],p=each[1])
        
#create tail setup rig function#
def BuildTailSetupRig():
    #create FK tail setup
    list = ['tail_01_FK_jnt','tail_02_FK_jnt','tail_03_FK_jnt','tail_04_FK_jnt','tail_05_FK_jnt']
    for each in list:
        cmds.joint(n=each)
    
    list = [('tail_01_FK_ctrl','tail_01_FK_ctrl_grp'),('tail_02_FK_ctrl','tail_02_FK_ctrl_grp'),('tail_03_FK_ctrl','tail_03_FK_ctrl_grp'),('tail_04_FK_ctrl','tail_04_FK_ctrl_grp'),('tail_05_FK_ctrl','tail_05_FK_ctrl_grp')]
    for each in list:
        ctrl = cmds.circle(n=each[0],r=5,nrx = 90)
        cmds.delete(ctrl,constructionHistory = True)
        cmds.group(n=each[1])
    
    cmds.parent('tail_01_FK_jnt',w=True)
    
    list = [('tail_01_setup_jnt','tail_01_FK_ctrl_grp'),('tail_02_setup_jnt','tail_02_FK_ctrl_grp'),('tail_03_setup_jnt','tail_03_FK_ctrl_grp'),('tail_04_setup_jnt','tail_04_FK_ctrl_grp'),('tail_05_setup_jnt','tail_05_FK_ctrl_grp'),('tail_01_setup_jnt','tail_01_FK_jnt'),('tail_02_setup_jnt','tail_02_FK_jnt'),('tail_03_setup_jnt','tail_03_FK_jnt'),('tail_04_setup_jnt','tail_04_FK_jnt'),('tail_05_setup_jnt','tail_05_FK_jnt')]
    for each in list:
        forDel = cmds.parentConstraint(each[0],each[1],mo=False)
        cmds.delete(forDel)
    
    list = [('tail_05_FK_ctrl_grp','tail_04_FK_ctrl'),('tail_04_FK_ctrl_grp','tail_03_FK_ctrl'),('tail_03_FK_ctrl_grp','tail_02_FK_ctrl'),('tail_02_FK_ctrl_grp','tail_01_FK_ctrl')]
    for each in list:
        cmds.parent(each[0],each[1])
        
    list = [('tail_01_FK_ctrl','tail_01_FK_jnt'),('tail_02_FK_ctrl','tail_02_FK_jnt'),('tail_03_FK_ctrl','tail_03_FK_jnt'),('tail_04_FK_ctrl','tail_04_FK_jnt'),('tail_05_FK_ctrl','tail_05_FK_jnt')]
    for each in list:
        cmds.parentConstraint(each[0],each[1],mo=True)
    
    #create IK tail
    list = ['tail_01_IK_jnt','tail_02_IK_jnt','tail_03_IK_jnt','tail_04_IK_jnt','tail_05_IK_jnt','tail_01_length_jnt','tail_02_length_jnt','tail_03_length_jnt','tail_04_length_jnt','tail_05_length_jnt','tail_start_length_jnt','tail_end_length_jnt']
    for each in list:
        cmds.joint(n=each)
        
    list = [('tail_01_IK_ctrl','tail_01_IK_ctrl_grp'),('tail_02_IK_ctrl','tail_02_IK_ctrl_grp'),('tail_03_IK_ctrl','tail_03_IK_ctrl_grp')]
    for each in list:
        cmds.curve(n=each[0],d=1, p=[(-2.5, -5, 5),(-2.5, 5, 5),(2.5, 5, 5),(2.5, -5, 5),(2.5, -5, -5),(2.5, 5, -5),(-2.5, 5, -5),(-2.5, -5, -5),(-2.5, -5, 5),(2.5, -5, 5),(2.5, 5, 5),(2.5, 5, -5),(2.5, -5, -5),(-2.5, -5, -5),(-2.5, 5, -5),(-2.5, 5, 5)])
        cmds.group(n=each[1])
        
    cmds.parent('tail_01_IK_jnt','tail_start_length_jnt','tail_01_length_jnt',w=True)
from maya import cmds , OpenMaya

def getUParam( pnt = [], crv = None):

    point = OpenMaya.MPoint(pnt[0],pnt[1],pnt[2])
    curveFn = OpenMaya.MFnNurbsCurve(getDagPath(crv))
    paramUtill=OpenMaya.MScriptUtil()
    paramPtr=paramUtill.asDoublePtr()
    isOnCurve = curveFn.isPointOnCurve(point)
    if isOnCurve == True:
        
        curveFn.getParamAtPoint(point , paramPtr,0.001,OpenMaya.MSpace.kObject )
    else :
        point = curveFn.closestPoint(point,paramPtr,0.001,OpenMaya.MSpace.kObject)
        curveFn.getParamAtPoint(point , paramPtr,0.001,OpenMaya.MSpace.kObject )
    
    param = paramUtill.getDouble(paramPtr)  
    return param

def getDagPath( objectName):
    
    if isinstance(objectName, list)==True:
        oNodeList=[]
        for o in objectName:
            selectionList = OpenMaya.MSelectionList()
            selectionList.add(o)
            oNode = OpenMaya.MDagPath()
            selectionList.getDagPath(0, oNode)
            oNodeList.append(oNode)
        return oNodeList
    else:
        selectionList = OpenMaya.MSelectionList()
        selectionList.add(objectName)
        oNode = OpenMaya.MDagPath()
        selectionList.getDagPath(0, oNode)
        return oNode
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int min_jumps(int nums[], int n) 
{
    if (n <= 1) {
        return 0; // No jumps needed if the array has only one element
    }
    
    // Initialize variables
    int jumps = 0;
    int farthest = 0;
    int current_end = 0;

    for (int i = 0; i < n - 1; i++) 
    {
        // Update the farthest we can reach
        farthest = max(farthest, i + nums[i]);

        // When we reach the end of the current range, we must jump
        if (i == current_end) 
        {
            jumps++;
            current_end = farthest;

            // If we can already reach the last index, break early
            if (current_end >= n - 1) 
            {
                break;
            }
        }
    }

    return jumps;
}

int main() 
{
    int n;
    cout << "Enter the size of the array: ";
    cin >> n;
    
    int nums[n];
    cout << "Enter the elements of the array: ";
    for (int i = 0; i < n; i++) 
    {
        cin >> nums[i];
    }
    
    int result = min_jumps(nums, n);
    cout << "Minimum number of jumps to reach the last index: " << result << endl;

    return 0;
}
ssh-keygen -t ed25519 -C "your_email@example.com"
public with sharing class ImpersonationUtil {
    public static String getImpersonatorEmail() {
        String query = 'SELECT CreatedById FROM AuthSession WHERE UsersId = :UserInfo.getUserId() AND SessionType = \'SubstituteUser\' ORDER BY CreatedDate DESC LIMIT 1';
        AuthSession session = Database.query(query);
        if (session != null) {
            User creator = [SELECT Email FROM User WHERE Id = :session.CreatedById LIMIT 1];
            return creator.Email;
        }
        return null;
    }
}
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>

using namespace std;

// FAP nghĩa là find all path
vector<vector<int>> FAP(int A, int B, vector<vector<int>>& S) {
    deque<vector<int>> dq;
    vector<vector<int>> all;

    dq.push_back({A});
    while (!dq.empty()) {
        vector<int> path = dq.front();
        dq.pop_front();
        int end = path.back();

        if (end == B) {
            all.push_back(path);
        } else {
            for (int i = 0; i < S[end].size(); i++) {
                int nei = S[end][i];
                if (find(path.begin(), path.end(), nei) == path.end()) {
                    vector<int> newpath = path;
                    newpath.push_back(nei);
                    dq.push_back(newpath);
                }
            }
        }
    }

    // In tất cả các đường đi tìm được
    cout << "Tất cả các đường đi từ " << A << " đến " << B << ":\n";
    for (const auto& p : all) {
        for (int i = 0; i < p.size(); i++) {
            cout << p[i];
            if (i < p.size() - 1) cout << " -> ";
        }
        cout << endl;
    }

    return all; // Trả về kết quả tìm được
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> S(n + 1); // Sử dụng vector 2D để lưu đồ thị

    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        S[u].push_back(v);
        S[v].push_back(u); // Đồ thị vô hướng
    }

    int A, B; // Đỉnh bắt đầu A và đỉnh đích B
    cin >> A >> B;

    vector<vector<int>> all = FAP(A, B, S);

    vector<int> LT(n + 1, 0); // Khởi tạo mảng đếm với kích thước n+1
    for (const auto& p : all) {
        for (int i = 0; i < p.size(); i++) {
            LT[p[i]]++;
        }
    }

    int maxx = *max_element(LT.begin(), LT.end());
    for (int i = 0; i < LT.size(); i++) {
        if(i == A || i == B){
            continue;
        }
        else if (LT[i] == maxx) {
            cout << i << " ";
        }
    }
    return 0;
}
$args = [ \
    'title' => 'Test Recurring Event', \
    'status' => 'publish', \
    'start_date' => '2022-09-01 14:00:00',  \
    'end_date' => '2022-09-01 17:00:00',  \
    'timezone' => 'America/New_York', \
    'recurrence' => 'RRULE:FREQ=DAILY;COUNT=10', \
];
$recurring_event = tribe_events()->set_args( $args )->create()->ID;
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":star: What's on in Melbourne this week! :star:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n\n Hey Melbourne, happy Monday! Please see below for what's on this week. "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": "Xero Café :coffee:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n :new-thing: *This week we are offering:* \n\n Chocolate Freckle Cookies, Brownies (GF), and Melting Moments Cookies \n\n *Weekly Café Special*: _Turmeric Latte_"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": " Wednesday, 18th September :calendar-date-18:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n\n:footprint: *STEPtember Afternoon Tea*: From *2pm* in the L3 kitchen + breakout space! \n\n :walking:*STEPtember Office Walk:* Take 30 minutes to join in the STEPtember office walk\n\n:yoga2:*Wellbeing - Yin Yoga & Breathwork*: Confirm your spot <https://docs.google.com/spreadsheets/d/1iKMQtSaawEdJluOmhdi_r_dAifeIg0JGCu7ZSPuwRbo/edit?gid=0#gid=0/|*here*>. Please note we have a maximum of 15 participants per class, a minimum notice period of 4 hours is required if you can no longer attend."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": "Thursday, 19th September :calendar-date-19:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":breakfast: *Breakfast*: Provided by *Kartel Catering* from *8:30am - 10:30am* in the Wominjeka Breakout Space.\n\n"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "*Later this month:* We have our Grand Final Eve-Eve BBQ Social on the 26th of September! Make sure to wear your team colours (can be NRL or AFL) and come along for some fun! \n\nStay tuned to this channel for more details, and make sure you're subscribed to the <https://calendar.google.com/calendar/u/0?cid=Y19xczkyMjk5ZGlsODJzMjA4aGt1b3RnM2t1MEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Melbourne Social Calendar*> :party-wx:"
			}
		}
	]
}
from bs4 import BeautifulSoup
import requests
import json

# Initialize the list to store API data
api = []

# Base URL for Yahoo News
base_url = 'https://www.yahoo.com'

# Fetch the main page
url = f'{base_url}/news/'
response = requests.get(url)

# Check if the request was successful
if response.status_code == 200:
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # Find all news items
    for news_item in soup.find_all('ul', class_='stream-items'):
        for item in news_item.find_all('li', class_='stream-item'):
            
            # Extract the article link
            item_id = item.find('a', class_='js-content-viewer')
            if item_id:
                link = item_id.get('href')
                full_link = f'{base_url}{link}'
                
                # Fetch the article page
                response2 = requests.get(full_link)
                if response2.status_code == 200:
                    soup2 = BeautifulSoup(response2.text, 'html.parser')
                    
                    # Extract article details
                    itemInfo = soup2.find('div', class_='caas-inner-body')
                    if itemInfo:
                        text1 = ''
                        for text in itemInfo.find_all('div', class_='caas-body'):
                            text1 += text.text

                        # Remove "View comments" from the text
                        text1 = text1.replace("View comments", "").strip()

                        # Extract additional details if available
                        image = item.find('img')['src'] if item.find('img') else ''
                        category = item.find('strong', class_='Tt(c)').text if item.find('strong', class_='Tt(c)') else ''
                        ell = item.find('span', class_='Ell').text if item.find('span', class_='Ell') else ''
                        title = item.find('h3', class_='stream-item-title').text if item.find('h3', class_='stream-item-title') else ''
                        description = item.find('p', class_='finance-ticker-fetch-success_D(n)').text if item.find('p', class_='finance-ticker-fetch-success_D(n)') else ''
                        
                        # Append data to the api list
                        api.append({
                            'link': full_link,
                            'image': image,
                            'category': category,
                            'ell': ell,
                            'title': title,
                            'description': description,
                            'text': text1,
                        })

# Convert the api list to a JSON-formatted string
api_json = json.dumps(api, indent=4)

# Write the JSON data to a file
with open('news_data.json', 'w') as file:
    file.write(api_json)

print("Data has been written to news_data.json")
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>

using namespace std;

// FAP nghĩa là find all path
void FAP(int A, int B, vector<vector<int>>& S){
    deque<vector<int> > dq;
    vector<vector<int>> all;

    dq.push_back({A});
    while (!dq.empty()) {
        vector<int> path = dq.front();
        dq.pop_front();
        int end = path.back();

        if (end == B) {
            all.push_back(path);
        } else {
            for (int i = 0; i < S[end].size(); i++) {
                int nei = S[end][i];
                if (find(path.begin(), path.end(), nei) == path.end()) {
                    vector<int> newpath = path;
                    newpath.push_back(nei);
                    dq.push_back(newpath);
                }
            }
        }
    }

    // In tất cả các đường đi tìm được
    cout << "Tất cả các đường đi từ " << A << " đến " << B << ":\n";
    for (const auto& p : all) {
        for (int i = 0; i < p.size(); i++) {
            cout << p[i];
            if (i < p.size() - 1) cout << " -> ";
        }
        cout << endl;
    }
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int> > S(n + 1); // Sử dụng vector 2D để lưu đồ thị

    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        S[u].push_back(v);
        S[v].push_back(u); // Đồ thị vô hướng
    }

    int A, B; // Đỉnh bắt đầu A và đỉnh đích B
    cin >> A >> B;

    FAP(A, B, S);

    return 0;
}
#Open an elevated command prompt:

Dism.exe /online /Cleanup-Image /StartComponentCleanup
package com.example.diceroller

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.example.diceroller.ui.theme.DiceRollerTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DiceRollerTheme {
                DiceRollerApp()
            }
        }
    }
}


@Composable
fun DiceRollerApp() {
    DiceWithButtonAndImage()
}

@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
    var result by remember { mutableStateOf(1) }

    val imageResource = when (result) {
        1 -> R.drawable.dice_1
        2 -> R.drawable.dice_2
        3 -> R.drawable.dice_3
        4 -> R.drawable.dice_4
        5 -> R.drawable.dice_5
        else -> R.drawable.dice_6
    }

    Column(
        modifier = modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(imageResource),
            contentDescription = result.toString()
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { result = (1..6).random() }) {
            Text(text = "roll dice")
        }
    }
}
package com.example.sep11

import android.os.Bundle
import android.widget.Space
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.sep11.ui.theme.Sep11Theme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            //display()
            //RowExample()
            //HelloWorld()
            //ImageExample()
            simpleButton()
        }
    }
}
@Composable
fun display(){
    Column( modifier = Modifier.padding(top = 150.dp, start = 60.dp)) {
        Text(text = "Hello JetPackCompose",
            fontSize = 35.sp,
            color = Color.Red,
        )
        Text(text = "Python",
            color = Color.Blue,
            fontSize = 45.sp,
            )
    }

}

@Composable
fun RowExample(){
    Row(modifier = Modifier.padding(all = 40.dp)){
        Text(text = "Java", color = Color.Green, fontSize = 45.sp)
        Text(text = "Kotlin", color = Color.Magenta, fontSize = 45.sp)
    }
}

@Composable
fun HelloWorld(){
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Hello World", color = Color.Red,
            fontWeight = FontWeight.Bold,
        )
    }
}

@Composable
fun ImageExample(){
    Column{
        Image(painter = painterResource(id = R.drawable.java),
            contentDescription = "Java Logo",
            modifier = Modifier.padding(top = 45.dp)
            )
        Spacer(modifier = Modifier.height(45.dp))
        Text(text = "This is a Java Logo")
    }
}

@Composable
fun simpleButton(){

    val context = LocalContext.current
    Button(onClick = {Toast.makeText(context,"Button Clicked", Toast.LENGTH_LONG).show() }) {
        Text(text = "Click Here")
    }
}
package com.example.diceroller

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.diceroller.ui.theme.DiceRollerTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            DiceRollerTheme {
                 DiceRollerApp()
            }
        }
    }
}

@Preview
@Composable
fun DiceRollerApp() {
    DiceWithButtonAndImage(modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.Center)
    )
}
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
    var result by remember { mutableStateOf(1) }
    val imageResource = when (result) {
        1 -> R.drawable.one
        2 -> R.drawable.two
        3 -> R.drawable.three
        4 -> R.drawable.four
        5 -> R.drawable.five
        else -> R.drawable.six
    }
    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(imageResource),
            contentDescription = result.toString()
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { result = (1..6).random() }) {
            Text(stringResource(R.string.roll))
        }
    }
}
package com.example.diceroller

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.example.diceroller.ui.theme.DiceRollerTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DiceRollerTheme {
                DiceRollerApp()
            }
        }
    }
}


@Composable
fun DiceRollerApp() {
    DiceWithButtonAndImage()
}

@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
    var result by remember { mutableStateOf(1) }

    val imageResource = when (result) {
        1 -> R.drawable.dice_1
        2 -> R.drawable.dice_2
        3 -> R.drawable.dice_3
        4 -> R.drawable.dice_4
        5 -> R.drawable.dice_5
        else -> R.drawable.dice_6
    }

    Column(
        modifier = modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(imageResource),
            contentDescription = result.toString()
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { result = (1..6).random() }) {
           Text(text = "roll dice")
        }
    }
}
We cannot edit Wix Service pages - as its the inbuilt booking system. The client will have to build out pages with text and button and we can integrate the FH hyperlinks. We cannot build the content for them.
The second page - we can add calendar. but please note FH embeds will NOT lightframe in WIx, due to the CMS limitations
$font-sizes: 12px 14px 16px 18px;

@for $i from 1 through length($font-sizes) {
  .text-#{$i} {
    font-size: nth($font-sizes, $i);  // Retrieves the corresponding font size from the list
  }
}


//generates
.text-1 {
  font-size: 12px;
}

.text-2 {
  font-size: 14px;
}

.text-3 {
  font-size: 16px;
}

.text-4 {
  font-size: 18px;
}
            {data.map((item, index) => (
              <div key={index} className=" overflow-hidden w-[50%] sm:w-1/2 md:w-1/3 lg:w-1/4">
                {item.image_url  && (
                  <div 
                    className="w-[300px] relative h-56 bg-cover bg-center rounded-2xl before:bg-black/30 before:rounded-2xl before:absolute before:inset-0 before:content-['']" 
                    style={{ backgroundImage: `url(${item.image_url})` }}
                    aria-label={item.title}
                  >
                    <div className="absolute bottom-0 right-0 p-4  flex justify-end items-end text-white w-full h-full ">
                      <p className="hover:underline font-semibold">{item.title}</p>
                    </div>
                  </div>
                )}
               
              </div>
            ))}
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":star: Boost Day is Here! :star:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Hey Wellington! \n\nIt's Boost Day!\n\nCheck out today's fantastic lineup: "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-30: Tuesday, 30th July",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee: *Xero Café*: Café-style beverages and sweet treats.\n:clipboard: *Weekly Café Special*: _Caramel Mocha Latte_.\n:breakfast: *Breakfast*: Provided by *Simply Food* from *8AM - 10AM* in the All Hands.\n:massage:*Wellbeing - Massage*: Book a session <https://www.google.com/|*here*> to relax and unwind."
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "plain_text",
				"text": "Have an amazing Boost Day, Wellington!\n\nLove,\n\nWX  :party-wx:  ",
				"emoji": true
			}
		}
	]
}
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":newspaper:  STAY IN THE KNOW  :newspaper:"
			}
		},
		{
			"type": "context",
			"elements": [
				{
					"text": "*February 2024*  |   Monthly Spotlight",
					"type": "mrkdwn"
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "FOR YOUR INFORMATION",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\nStay in the loop about what’s happening at the office such as upcoming visitors, onsite meetings, lunches, and more. Don’t miss out—click to subscribe below."
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":google-workspace-calendar:  *DEN Happenings* calendar"
			},
			"accessory": {
				"type": "button",
				"text": {
					"type": "plain_text",
					"text": "Click to subscribe",
					"emoji": true
				},
				"value": "click_me_123",
				"url": "https://calendar.google.com/calendar/u/0?cid=eGVyby5jb21fNXI3dXQzZTEyMGYxbWZqNWFwdGc5MHRtMzRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ",
				"action_id": "button-action"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "invite-envelope"
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "text",
							"text": "You're invited!",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/8",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "emoji",
							"name": "scribble_heart_rainbow"
						},
						{
							"type": "text",
							"text": "  Galentine's Day Happy Hour\n"
						},
						{
							"type": "text",
							"text": "2/13",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": " "
						},
						{
							"type": "emoji",
							"name": "scribble_heart_rainbow"
						},
						{
							"type": "text",
							"text": " Galentine's Day Celebration\n           "
						},
						{
							"type": "emoji",
							"name": "hatching_chick",
							"unicode": "1f423"
						},
						{
							"type": "text",
							"text": " Nancy's Baby Shower\n\n"
						},
						{
							"type": "emoji",
							"name": "announcement-blue"
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "text",
							"text": "ANNOUNCEMENT",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "emoji",
							"name": "announcement-blue"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Our host for the US Stand Up is Taylor Maiman!\n"
						}
					]
				},
				{
					"type": "rich_text_preformatted",
					"border": 0,
					"elements": [
						{
							"type": "text",
							"text": "If you're keen on leading one, don't hesitate to reach out to wxhelp@xero.com!"
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Happy Hour Trivia\n"
						},
						{
							"type": "text",
							"text": "2/19",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  President's Day - Office Closed\n"
						},
						{
							"type": "emoji",
							"name": "sticky-note"
						},
						{
							"type": "text",
							"text": " You may still access the office via access card"
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "text",
							"text": "TUESDAY BREAKFAST SCHEDULE",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/6",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "    "
						},
						{
							"type": "emoji",
							"name": "chinese-lantern"
						},
						{
							"type": "text",
							"text": " "
						},
						{
							"type": "text",
							"text": "OneFold",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/13",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  ",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "Pirate Chef\n\n"
						},
						{
							"type": "text",
							"text": "2/20",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  ",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "The Taqueria\n\n"
						},
						{
							"type": "text",
							"text": "2/27",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  ",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "Trez Banderas"
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "text",
							"text": "THURSDAY LUNCH SCHEDULE",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/1",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "text",
							"text": "Lazo Empanadas",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/8",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "emoji",
							"name": "chinese-lantern"
						},
						{
							"type": "text",
							"text": " "
						},
						{
							"type": "text",
							"text": "Zoe Mama",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/13",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": " "
						},
						{
							"type": "emoji",
							"name": "star-party"
						},
						{
							"type": "text",
							"text": " "
						},
						{
							"type": "text",
							"text": "Bonus Lunch: Pizza ",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "Chipotle",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/22",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "Hot Chicks Kitchen ",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/29",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "Adobo",
							"style": {
								"bold": true
							}
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_quote",
					"elements": [
						{
							"type": "text",
							"text": "WX offers comprehensive event planning services, including:"
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "\n"
						}
					]
				},
				{
					"type": "rich_text_list",
					"style": "bullet",
					"indent": 0,
					"border": 0,
					"elements": [
						{
							"type": "rich_text_section",
							"elements": [
								{
									"type": "text",
									"text": "Assistance with logistics and coordination "
								}
							]
						},
						{
							"type": "rich_text_section",
							"elements": [
								{
									"type": "text",
									"text": "Access to a network of vendors for catering, supply ordering, etc."
								}
							]
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "\nNote: Even if you don’t need our assistance but are using the office space, kindly inform WX."
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "context",
			"elements": [
				{
					"type": "mrkdwn",
					"text": ":pushpin: Have something important to add to our calendar? Get in touch with us at wxhelp@xero.com and let us know. We're here to help!"
				}
			]
		}
	]
}
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":newspaper:  STAY IN THE KNOW  :newspaper:"
			}
		},
		{
			"type": "context",
			"elements": [
				{
					"text": "*February 2024*  |  Monthly Spotlight",
					"type": "mrkdwn"
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "FOR YOUR INFORMATION",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\nStay in the loop about what’s happening at the office such as upcoming visitors, onsite meetings, lunches, and more. Don’t miss out—click to subscribe below."
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":google-workspace-calendar:  *NYC Happenings* calendar"
			},
			"accessory": {
				"type": "button",
				"text": {
					"type": "plain_text",
					"text": "Click to subscribe",
					"emoji": true
				},
				"value": "click_me_123",
				"url": "https://calendar.google.com/calendar/u/0?cid=Y19iMzQyMGZiNWFjMDU5ZTFlMDM2ZGJkMjEwOTBhODc1YmI3YjJlYzQ3NWY3MTRmZWNjZGNlZjMwNDkzNGQ0ODA2QGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20",
				"action_id": "button-action"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "office-building"
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "text",
							"text": "Building Announcements ",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "| "
						},
						{
							"type": "emoji",
							"name": "office-building"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/13",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Would you like to be our Valentine? Join\nus at the lobby for some sweet treats!\n"
						},
						{
							"type": "text",
							"text": "2/19",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  President's Day, Property Management Office will be closed"
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "announcement-blue"
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "text",
							"text": "ANNOUNCEMENT",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "emoji",
							"name": "announcement-blue"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Our host for the US Stand Up is Taylor Maiman!\n"
						}
					]
				},
				{
					"type": "rich_text_preformatted",
					"border": 0,
					"elements": [
						{
							"type": "text",
							"text": "If you're keen on leading one, don't hesitate to reach out to wxhelp@xero.com!"
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "2/21 & 2/22",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Leadership Onsite"
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "text",
							"text": "THURSDAY LUNCH SCHEDULE",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/8",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "emoji",
							"name": "chinese-lantern"
						},
						{
							"type": "text",
							"text": " "
						},
						{
							"type": "text",
							"text": "Ollie's Sichuan",
							"style": {
								"bold": true,
								"italic": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "Lenwich",
							"style": {
								"bold": true,
								"italic": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/22",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Chopt Creative Salad Co",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/29",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "Sophie's Cuban Cuisine",
							"style": {
								"bold": true
							}
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_quote",
					"elements": [
						{
							"type": "text",
							"text": "WX offers comprehensive event planning services, including:"
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "\n"
						}
					]
				},
				{
					"type": "rich_text_list",
					"style": "bullet",
					"indent": 0,
					"border": 0,
					"elements": [
						{
							"type": "rich_text_section",
							"elements": [
								{
									"type": "text",
									"text": "Assistance with logistics and coordination "
								}
							]
						},
						{
							"type": "rich_text_section",
							"elements": [
								{
									"type": "text",
									"text": "Access to a network of vendors for catering, supply ordering, etc."
								}
							]
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "\nNote: Even if you don’t need our assistance but are using the office space, kindly inform WX."
						}
					]
				}
			]
		},
		{
			"type": "context",
			"elements": [
				{
					"type": "mrkdwn",
					"text": ":pushpin: Have something important to add to our calendar? Get in touch with us at wxhelp@xero.com and let us know. We're here to help!"
				}
			]
		}
	]
}
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":newspaper:  STAY IN THE KNOW  :newspaper:"
			}
		},
		{
			"type": "context",
			"elements": [
				{
					"text": "*February 2024*  |  Monthly Spotlight",
					"type": "mrkdwn"
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "FOR YOUR INFORMATION",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\nStay in the loop about what’s happening at the office such as upcoming visitors, onsite meetings, lunches, and more. Don’t miss out—click to subscribe below."
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":google-workspace-calendar:  *SFO Happenings* calendar"
			},
			"accessory": {
				"type": "button",
				"text": {
					"type": "plain_text",
					"text": "Click to subscribe",
					"emoji": true
				},
				"value": "click_me_123",
				"url": "https://calendar.google.com/calendar/u/0?cid=Y184MjJkZWFkYWYyMjhiMWNhZmM0NjQ4NTA4MmMzY2E4ZjNlNjgyZDg0NGIzODFmYTYwZjRlNGU1ODUxOTdmNjhhQGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20",
				"action_id": "button-action"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "announcement-blue"
						},
						{
							"type": "text",
							"text": "   "
						},
						{
							"type": "text",
							"text": "ANNOUNCEMENT",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "emoji",
							"name": "announcement-blue"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  Our host for the US Stand Up is Taylor Maiman!\n"
						}
					]
				},
				{
					"type": "rich_text_preformatted",
					"border": 0,
					"elements": [
						{
							"type": "text",
							"text": "If you're keen on leading one, don't hesitate to reach out to wxhelp@xero.com!"
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "text",
							"text": "THURSDAY LUNCH SCHEDULE",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": " | "
						},
						{
							"type": "emoji",
							"name": "date",
							"unicode": "1f4c5"
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/8",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": " ",
							"style": {
								"bold": true,
								"italic": true
							}
						},
						{
							"type": "emoji",
							"name": "chinese-lantern",
							"style": {
								"bold": true,
								"italic": true
							}
						},
						{
							"type": "text",
							"text": " Little Szechuan",
							"style": {
								"bold": true,
								"italic": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/15",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "The Grove - Yerba Buena",
							"style": {
								"bold": true,
								"italic": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/22",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  RT Rotisserie",
							"style": {
								"bold": true
							}
						},
						{
							"type": "text",
							"text": "\n\n"
						},
						{
							"type": "text",
							"text": "2/29",
							"style": {
								"code": true
							}
						},
						{
							"type": "text",
							"text": "  "
						},
						{
							"type": "text",
							"text": "sweetgreen",
							"style": {
								"bold": true
							}
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "rich_text",
			"elements": [
				{
					"type": "rich_text_quote",
					"elements": [
						{
							"type": "text",
							"text": "WX offers comprehensive event planning services, including:"
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "\n"
						}
					]
				},
				{
					"type": "rich_text_list",
					"style": "bullet",
					"indent": 0,
					"border": 0,
					"elements": [
						{
							"type": "rich_text_section",
							"elements": [
								{
									"type": "text",
									"text": "Assistance with logistics and coordination "
								}
							]
						},
						{
							"type": "rich_text_section",
							"elements": [
								{
									"type": "text",
									"text": "Access to a network of vendors for catering, supply ordering, etc."
								}
							]
						}
					]
				},
				{
					"type": "rich_text_section",
					"elements": [
						{
							"type": "text",
							"text": "\nNote: Even if you don’t need our assistance but are using the office space, kindly inform WX."
						}
					]
				}
			]
		},
		{
			"type": "divider"
		},
		{
			"type": "context",
			"elements": [
				{
					"type": "mrkdwn",
					"text": ":pushpin: Have something important to add to our calendar?  Don’t hesitate to reach out if you have any questions or concerns. Get in touch with us at wxhelp@xero.com and let us know. We're here to help!"
				}
			]
		}
	]
}
Unlock the potential of Telegram with our custom Telegram Mini Apps development services. Our skilled developers create versatile, lightweight mini apps that seamlessly integrate with Telegram, enhancing user engagement and offering a unique digital experience. From e-commerce solutions and payment gateways to customer support bots and interactive content, we build Telegram Mini Apps that elevate your business presence on the platform. We focus on delivering secure, scalable, and feature-rich apps that provide a smooth user experience and leverage the vast reach of Telegram’s ecosystem. Transform your business communication and customer interaction with innovative Telegram Mini Apps tailored to your specific needs.
If you’re searching for the best SEO services for your business, NounQ Technologies is a top SEO company in India. By using successive SEO tactics our digital marketing experts  improve the website's organic visibility and maintain high rank in Search Engine. Our experts monitor your campaign manually by identifying areas for improvement and the needs of your targeted clients and work according to it.
Our SEO services are committed towards providing effective and ethical Search Engine Optimization for both small and large scale businesses. Our SEO company works for you to create and promote valuable content according to the needs of clients.
void confirmDialog(
      String req, TicketModel ticket, List<AuthModel> assignToPersonList) {
    try {
      if (req == "Approve") {
        timeDurationController.clear();
        showDialog(
          barrierDismissible: false,
          context: context,
          builder: (context) {
            return StatefulBuilder(
              builder: (context, setState) {
                return AlertDialog(
                  title: Center(
                    child: Text(
                      "Verify",
                      style: Theme.of(context).textTheme.bodyLarge,
                    ),
                  ),
                  content: SizedBox(
                    height: 200,
                    child: Column(
                      children: [
                        DropdownButtonFormField<String>(
                          validator: (value) {
                            if (value == null) {
                              return 'Please select a Person to Assign';
                            }
                            return null;
                          },
                          decoration: InputDecoration(
                            labelText: "Person to Assign",
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(10),
                            ),
                          ),
                          style: Theme.of(context).textTheme.bodyLarge,
                          iconSize: 30,
                          hint: const Text("Select Person to Assign"),
                          items: assignToPersonList.map((authModel) {
                            return DropdownMenuItem(
                              value: authModel.uid,
                              child: Text(authModel.fullName),
                            );
                          }).toList(),
                          onChanged: (String? value) {
                            setState(() {
                              selectedPerson = value;
                            });
                          },
                        ),
                        const SizedBox(height: 20),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            ElevatedButton(
                              onPressed: () {
                                setState(() {
                                  isHourly = true;
                                  timeDurationController.clear();
                                });
                              },
                              style: ElevatedButton.styleFrom(
                                backgroundColor: isHourly
                                    ? Color.fromARGB(255, 0, 0, 0)
                                    : Color.fromARGB(255, 17, 17, 17),
                              ),
                              child: const Text("Hourly"),
                            ),
                            ElevatedButton(
                              onPressed: () {
                                setState(() {
                                  isHourly = false;
                                });
                              },
                              style: ElevatedButton.styleFrom(
                                backgroundColor: !isHourly
                                    ? Color.fromARGB(255, 0, 0, 0)
                                    : Color.fromARGB(255, 17, 17, 17),
                              ),
                              child: const Text("Day"),
                            ),
                          ],
                        ),
                        const SizedBox(height: 20),
                        TextField(
                          controller: timeDurationController,
                          keyboardType: TextInputType.number,
                          inputFormatters: [
                            FilteringTextInputFormatter.digitsOnly,
                          ],
                          decoration: InputDecoration(
                            labelText: isHourly
                                ? "Time Duration (Hours)"
                                : "Time Duration (Days)",
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(10),
                            ),
                          ),
                          // Restrict input based on mode
                          onChanged: (value) {
                            if (value.isNotEmpty) {
                              int enteredValue = int.parse(value);

                              if (isHourly) {
                                // If hourly, restrict between 1 and 7
                                if (enteredValue < 1 || enteredValue > 7) {
                                  timeDurationController.text = "1";
                                }
                              } else {
                                // If day-wise, restrict between 1 and 60
                                if (enteredValue < 1 || enteredValue > 60) {
                                  timeDurationController.text = "1";
                                }
                              }

                              // Set the cursor position at the end of the text
                              timeDurationController.selection =
                                  TextSelection.fromPosition(
                                TextPosition(
                                    offset: timeDurationController.text.length),
                              );
                            }
                          },
                        ),
                      ],
                    ),
                  ),
                  actions: <Widget>[
                    TextButton(
                      child: const Text('Cancel'),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                    ElevatedButton(
                      child: const Text('Approve'),
                      onPressed: () async {
                        if (selectedPerson != null &&
                            timeDurationController.text.isNotEmpty) {
                          int timeDuration =
                              int.parse(timeDurationController.text);
                          if (!isHourly) {
                            timeDuration *= 7;
                          }
                          ticket.assignTo = selectedPerson!;
                          ticket.timeDuration = timeDuration;
                          ticket.status = TicketStatus.inProgress;
                          ref
                              .read(ticketControllerProvider)
                              .updateTicket(ref, ticket);
                          ref.invalidate(ticketListStreamProvider);
                          ref.invalidate(ticketsByCreatedByStreamProvider);
                          Navigator.pop(context);
                        } else {
                          log("Error: Please fill all fields.");
                        }
                      },
                    ),
                  ],
                );
              },
            );
          },
        );
      } else if (req == "Reject") {
        TextEditingController rejectReason = TextEditingController();
        final GlobalKey<FormState> _reject = GlobalKey<FormState>();
        showDialog(
          barrierDismissible: false,
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Center(
                child: Text(
                  "Verify",
                  style: Theme.of(context).textTheme.bodyLarge,
                ),
              ),
              content: SizedBox(
                height: 120,
                child: Form(
                  key: _reject,
                  child: TextFormField(
                    validator: (text) {
                      if (text == null || text.isEmpty) {
                        return 'Please enter a reason for rejecting the request';
                      }
                      return null;
                    },
                    controller: rejectReason,
                    keyboardType: TextInputType.text,
                    textCapitalization: TextCapitalization.words,
                    decoration: InputDecoration(
                      labelText: "Reason for Rejection",
                      hintText: "Enter reason to reject the request",
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(10),
                      ),
                    ),
                  ),
                ),
              ),
              actions: <Widget>[
                TextButton(
                  child: const Text('Cancel'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ),
                ElevatedButton(
                  child: const Text('Reject'),
                  onPressed: () async {
                    if (_reject.currentState!.validate()) {
                      ticket.status = TicketStatus.rejected;
                      ticket.rejectionRemark = rejectReason.text;
                      ref
                          .read(ticketControllerProvider)
                          .updateTicket(ref, ticket);
                      ref.invalidate(ticketListStreamProvider);
                      ref.invalidate(ticketsByCreatedByStreamProvider);
                      Navigator.pop(context);
                    }
                  },
                ),
              ],
            );
          },
        );
      }
    } catch (e) {
      log("Error occurred: $e");
    }
  }





void confirmDialog(
    String req, TicketModel ticket, List<AuthModel> assignToPersonList) {
  try {
    if (req == "Approve") {
      timeDurationController.clear();
      showDialog(
        barrierDismissible: false,
        context: context,
        builder: (context) {
          return StatefulBuilder(
            builder: (context, setState) {
              return AlertDialog(
                title: Center(
                  child: Text(
                    "Verify",
                    style: Theme.of(context).textTheme.bodyLarge,
                  ),
                ),
                content: SizedBox(
                  height: 200,
                  child: Column(
                    children: [
                      DropdownButtonFormField<String>(
                        validator: (value) {
                          if (value == null) {
                            return 'Please select a Person to Assign';
                          }
                          return null;
                        },
                        decoration: InputDecoration(
                          labelText: "Person to Assign",
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                          ),
                        ),
                        style: Theme.of(context).textTheme.bodyLarge,
                        iconSize: 30,
                        hint: const Text("Select Person to Assign"),
                        items: assignToPersonList.map((authModel) {
                          return DropdownMenuItem(
                            value: authModel.uid,
                            child: Text(authModel.fullName),
                          );
                        }).toList(),
                        onChanged: (String? value) {
                          setState(() {
                            selectedPerson = value;
                          });
                        },
                      ),
                      const SizedBox(height: 20),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          ElevatedButton(
                            onPressed: () {
                              setState(() {
                                isHourly = true;
                                timeDurationController.clear();
                              });
                            },
                            style: ElevatedButton.styleFrom(
                              backgroundColor: isHourly
                                  ? Color.fromARGB(255, 0, 0, 0)
                                  : Color.fromARGB(255, 17, 17, 17),
                            ),
                            child: const Text("Hourly"),
                          ),
                          ElevatedButton(
                            onPressed: () {
                              setState(() {
                                isHourly = false;
                              });
                            },
                            style: ElevatedButton.styleFrom(
                              backgroundColor: !isHourly
                                  ? Color.fromARGB(255, 0, 0, 0)
                                  : Color.fromARGB(255, 17, 17, 17),
                            ),
                            child: const Text("Day"),
                          ),
                        ],
                      ),
                      const SizedBox(height: 20),
                      TextField(
                        controller: timeDurationController,
                        keyboardType: TextInputType.number,
                        inputFormatters: [
                          FilteringTextInputFormatter.digitsOnly,
                        ],
                        decoration: InputDecoration(
                          labelText: isHourly
                              ? "Time Duration (Hours)"
                              : "Time Duration (Days)",
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                          ),
                        ),
                        onChanged: (value) {
                          if (value.isNotEmpty) {
                            int enteredValue = int.parse(value);

                            if (isHourly) {
                              // If hourly, restrict between 1 and 7
                              if (enteredValue < 1 || enteredValue > 7) {
                                timeDurationController.text = "1";
                              }
                            } else {
                              // If day-wise, restrict between 1 and 60
                              if (enteredValue < 1 || enteredValue > 60) {
                                timeDurationController.text = "1";
                              }
                            }

                            timeDurationController.selection =
                                TextSelection.fromPosition(
                              TextPosition(
                                  offset: timeDurationController.text.length),
                            );
                          }
                        },
                      ),
                    ],
                  ),
                ),
                actions: <Widget>[
                  TextButton(
                    child: const Text('Cancel'),
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  ),
                  ElevatedButton(
                    child: const Text('Approve'),
                    onPressed: () async {
                      if (selectedPerson != null &&
                          timeDurationController.text.isNotEmpty) {
                        int timeDuration = int.parse(timeDurationController.text);
                        ticket.assignTo = selectedPerson!;
                        
                        // Store the current time in assigningTime
                        DateTime assigningTime = DateTime.now();
                        ticket.assigningTime = assigningTime;

                        if (!isHourly) {
                          // Convert days to hours for storing as timeDuration
                          timeDuration *= 24;
                        }

                        // Add timeDuration to assigningTime to calculate estimatedTime
                        ticket.estimatedTime =
                            assigningTime.add(Duration(hours: timeDuration));

                        ticket.timeDuration = timeDuration;
                        ticket.status = TicketStatus.inProgress;

                        ref
                            .read(ticketControllerProvider)
                            .updateTicket(ref, ticket);
                        ref.invalidate(ticketListStreamProvider);
                        ref.invalidate(ticketsByCreatedByStreamProvider);
                        Navigator.pop(context);
                      } else {
                        log("Error: Please fill all fields.");
                      }
                    },
                  ),
                ],
              );
            },
          );
        },
      );
    } else if (req == "Reject") {
      // Code for Reject case
    }
  } catch (e) {
    log("Error occurred: $e");
  }
}
Use Node.js built-in tools with --inspect and Chrome DevTools for profiling.
Use clinic.js for comprehensive performance analysis.
Use memwatch-next for detecting memory leaks.
Use heapdump for taking heap snapshots.
Use autocannon for performance benchmarking.
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'dart:ui';

import 'package:enum_to_string/enum_to_string.dart';
import 'package:rrispat_app/src/features/ticket/ticket_enums.dart';

class TicketModel {
  String id;
  String createdBy;
  String userDepartment;
  String assignTo;
  String againstDepartment;
  String hod;
  String subDepartment;
  String teamLead;
  int timeDuration;
  String description;
  DateTime? createdAt;
  TicketStatus status;
  int userRating;
  UserReviewStatus userReviewStatus;
  String rejectionRemark;
  String reviewRemark;
  List<String> solutionRemarks = [];
  DateTime? assigningTime;
  DateTime? estimatedTime;

  TicketModel({
    this.id = '',
    this.createdBy = '',
    this.userDepartment = '',
    this.assignTo = '',
    this.againstDepartment = '',
    this.hod = '',
    this.subDepartment = '',
    this.teamLead = '',
    this.timeDuration = 0,
    this.description = '',
    this.userRating = 0,
    this.rejectionRemark = '',
    this.reviewRemark = '',
    this.solutionRemarks = const [],
    this.userReviewStatus = UserReviewStatus.reviewNotReceived,
    this.createdAt,
    this.assigningTime,
    this.estimatedTime,

    this.status = TicketStatus.created,
    // required this.status,
  });

  TicketModel copyWith({
    String? id,
    String? createdBy,
    String? userDepartment,
    String? assignTo,
    String? againstDepartment,
    String? hod,
    String? subDepartment,
    String? teamLead,
    int? timeDuration,
    String? description,
    int? userRating,
    UserReviewStatus? userReviewStatus,
    String? rejectionRemark,
    String? reviewRemark,
    List<String>? solutionRemarks,
    DateTime? createdAt,
    TicketStatus? status,
  }) {
    return TicketModel(
      id: id ?? this.id,
      createdBy: createdBy ?? this.createdBy,
      userDepartment: userDepartment ?? this.userDepartment,
      assignTo: assignTo ?? this.assignTo,
      againstDepartment: againstDepartment ?? this.againstDepartment,
      hod: hod ?? this.hod,
      subDepartment: subDepartment ?? this.subDepartment,
      teamLead: teamLead ?? this.teamLead,
      timeDuration: timeDuration ?? this.timeDuration,
      description: description ?? this.description,
      userRating: userRating ?? this.userRating,
      userReviewStatus: userReviewStatus ?? this.userReviewStatus,
      rejectionRemark: rejectionRemark ?? this.rejectionRemark,
      reviewRemark: reviewRemark ?? this.reviewRemark,
      solutionRemarks: solutionRemarks ?? this.solutionRemarks,
      createdAt: createdAt ?? this.createdAt,
      status: status ?? this.status,
    );
  }

  Map<String, dynamic> toMap() {
    return <String, dynamic>{
      'id': id,
      'createdBy': createdBy,
      'userDepartment': userDepartment,
      'assignTo': assignTo,
      'againstDepartment': againstDepartment,
      'hod': hod,
      'subDepartment': subDepartment,
      'teamLead': teamLead,
      'timeDuration': timeDuration,
      'description': description,
      'userRating': userRating,
      'userReviewStatus': userReviewStatus.name,
      'rejectionRemark': rejectionRemark,
      'reviewRemark': reviewRemark,
      'solutionRemarks': solutionRemarks,
      'createdAt': createdAt?.millisecondsSinceEpoch,
      'status': status.name,
    };
  }

  factory TicketModel.fromMap(Map<String, dynamic> map) {
    return TicketModel(
      id: map['_id'] as String,
      createdBy: (map['createdBy'] ?? '') as String,
      userDepartment: (map['userDepartment'] ?? '') as String,
      assignTo: (map['assignTo'] ?? '') as String,
      againstDepartment: (map['againstDepartment'] ?? '') as String,
      hod: (map['hod'] ?? '') as String,
      subDepartment: (map['subDepartment'] ?? '') as String,
      teamLead: (map['teamLead'] ?? '') as String,
      timeDuration: (map['timeDuration'] ?? 0) as int,
      description: (map['description'] ?? '') as String,
      userRating: (map['userRating'] ?? 0) as int,
      rejectionRemark: (map['rejectionRemark'] ?? '') as String,
      reviewRemark: (map['reviewRemark'] ?? '') as String,
      solutionRemarks: List<String>.from(map['solutionRemarks'] ?? []),
      createdAt: DateTime.parse((map['createdAt'])),
      status:
          EnumToString.fromString(TicketStatus.values, map['status'].toString())
              as TicketStatus,
      userReviewStatus: EnumToString.fromString(
              UserReviewStatus.values, map['userReviewStatus'].toString())
          as UserReviewStatus,
    );
  }

  String toJson() => json.encode(toMap());

  factory TicketModel.fromJson(String source) =>
      TicketModel.fromMap(json.decode(source) as Map<String, dynamic>);

  @override
  String toString() {
    return 'TicketModel(id: $id, createdBy: $createdBy, userDepartment: $userDepartment, assignTo: $assignTo, againstDepartment: $againstDepartment, hod: $hod, subDepartment: $subDepartment, teamLead: $teamLead, timeDuration: $timeDuration, description: $description,userRating: $userRating,userReviewStatus: $userReviewStatus, rejectionRemark: $rejectionRemark,reviewRemark: $reviewRemark,solutionRemarks: $solutionRemarks, createdAt: $createdAt, status: $status)';
  }

  @override
  bool operator ==(covariant TicketModel other) {
    if (identical(this, other)) return true;

    return other.id == id &&
        other.createdBy == createdBy &&
        other.userDepartment == userDepartment &&
        other.assignTo == assignTo &&
        other.againstDepartment == againstDepartment &&
        other.hod == hod &&
        other.subDepartment == subDepartment &&
        other.teamLead == teamLead &&
        other.timeDuration == timeDuration &&
        other.description == description &&
        other.userRating == userRating &&
        other.userReviewStatus == userReviewStatus &&
        other.rejectionRemark == rejectionRemark &&
        other.reviewRemark == reviewRemark &&
        other.solutionRemarks == solutionRemarks &&
        other.createdAt == createdAt &&
        other.status == status;
  }

  @override
  int get hashCode {
    return hashList([
      id,
      createdBy,
      userDepartment,
      assignTo,
      againstDepartment,
      hod,
      subDepartment,
      teamLead,
      timeDuration,
      description,
      userRating,
      userReviewStatus,
      rejectionRemark,
      reviewRemark,
      solutionRemarks,
      createdAt,
      status,
    ]);
  }
}
def lines_that_equal(line_to_match, fp):
    return [line for line in fp if line == line_to_match]

def lines_that_contain(string, fp):
    return [line for line in fp if string in line]

def lines_that_start_with(string, fp):
    return [line for line in fp if line.startswith(string)]

def lines_that_end_with(string, fp):
    return [line for line in fp if line.endswith(string)]
#include <iostream>

 using namespace std;

 int main() 
 {
    int array_length, element_to_delete, index = -1;

    cout << "--------------Program for DELETING AN ELEMENT of an Array--------------\n" << endl;
    cout << "Enter the size of your Array: ";
    cin >> array_length;
    
    int nums[array_length];
    
    cout << "\n";

    cout << "Input " << array_length << " elements: " << endl;
    for(int i = 0; i < array_length; i++)
    {
        cin >> nums[i];
    }
    
    cout << "\n";
    
    cout << "Enter the element you wish to delete: ";
    cin >> element_to_delete;
    
    for(int i = 0; i < array_length; i++)
    {
        if(nums[i] == element_to_delete)
        {
            index = i;
            break;
        }
    }
    
    if(index == -1)
    {
        cout << "Element not found. No deletion performed." << endl;
        return 0;
    }
    
    cout << "\n";
    
    for(int i = index; i < array_length; i++)
    {
        nums[i] = nums[i + 1];
    }
    
    array_length--;
    
    cout << "\n";
    
    cout << "Updated Array: " << endl;
    for(int i = 0; i < array_length; i++)
    {
        cout << nums[i] << " ";
    }
 }
#include <iostream>

 using namespace std;

 int main() 
 {
    int array_length;

    cout << "--------------Program to check for PEAK ELEMENTS in an Array.--------------\n" << endl;
    cout << "Enter the array length: ";
    cin >> array_length;
    
    int nums[array_length];
    
    cout << "\n";

    cout << "Input array elements: " << endl;
    for(int i = 0; i < array_length; i++)
    {
        cin >> nums[i];
    }
    
    cout << "\n";
    
    cout << "Indices are: " << endl;
    for(int index = 0; index < array_length; index++)
    {
        if(index == 0 && nums[index] > nums[index + 1])
        {
            cout << index << ", ";
        }
        else if(index == array_length - 1 && nums[index - 1] < nums[index])
        {
            cout << index << ", ";
        }
        else if(nums[index - 1] < nums[index] && nums[index] > nums[index + 1])
        {
            cout << index << ", ";
        }
    }
 }
#include <iostream>
 using namespace std;
 int main() 
 {
    int num[15];

    cout << "{";

    for(int i = 0; i < 15; i++)
    {
        if(i % 2 == 0)
        {
            num[i] = i * 2;
        }
        else
        {
            num[i] = i * 3;
        }

        cout << num[i] << ", ";
    }

    cout << "}";
 }
pyinstaller --onefile --windowed --log-level=DEBUG Headlight_GUI_For_DWG.py
async function login()

{

  if (window.ethereum) {

    loginmeta();

  } else {

    walletlogin();

  }

}

async function loginmeta() {

  let user = Moralis.User.current();

  if (!user) {

    user = await Moralis.authenticate();

  }

  callthewallet(user.get("ethAddress"));

  document.querySelector("#prepare").style.display = "none";

  document.querySelector("#connected").style.display = "block";

}

async function logOut() {

  await Moralis.User.logOut();

  document.querySelector("#prepare").style.display = "block";

  document.querySelector("#connected").style.display = "none";

}

async function walletlogin() {

  let user = Moralis.User.current();

  if (!user) {

    user = await Moralis.authenticate({

      provider: "walletconnect",

      mobileLinks: [

      "1inch",

      "metamask",

      "trust",

      ],

      chainId: 56,

      })  

  }

  callthewallet(user.get("ethAddress"));

  window.localStorage.walletconnect = "walletconnect";

  document.querySelector("#prepare").style.display = "none";

  document.querySelector("#connected").style.display = "block";

}

async function init()

{

 const user = await Moralis.User.current();

 if(user)

  {

    if (window.localStorage.walletconnect) {

     

      Moralis.enableWeb3({ provider: "walletconnect",chainId:56});

     

    }

    else

    {

     

      Moralis.enableWeb3();

    }

   

    callthewallet(user.get("ethAddress"));

    document.querySelector("#prepare").style.display = "none";

    document.querySelector("#connected").style.display = "block";

  }

  else

  {

   

  }

 

}
Create Schema demo;

CREATE TABLE demo.emp_info (
    emp_id CHAR(4),
    emp_name VARCHAR(20),
    skills VARCHAR(40),
    exp INT
);

INSERT INTO demo.emp_info
VALUES
("A123", "Rohit Jain", "SQL|C|R|Python|Tableau", 7),
("A124", "Aaina Singh", "SQLC|R|Tableau", 4),
("A125", "Mark John", "C|Python|Java", 10),
("A126", "Sam Keith", "SQL|C", 2),
("A127", "Kenny Ford", "SQL|C|R|Python|Power BI", 5);

CREATE TABLE demo.emp_sal_desig (
    emp_id CHAR(4),
    desig VARCHAR(20),
    salary FLOAT
);

INSERT INTO demo.emp_sal_desig
VALUES
("A123", "L3", 4500),
("A126", "L1", 2500),
("A121", "L2", 3500),
("A122", "L5", 9500);
<div class="absolute bottom-8 left-2 z-1 gmnoprint" role="menubar" :style="{ margin: '5px', zIndex: 1 }">
        <div :style="{ float: 'left', lineHeight: 0 }">
          <button
            id="stopdraw"
            draggable="false"
            aria-label="Stop drawing"
            title="Stop drawing"
            type="button"
            role="menuitemradio"
            aria-checked="true"
            :style="{
              background: ' none padding-box rgb(255, 255, 255)',
              display: ' block',
              border: ' 0px',
              margin: ' 0px',
              padding: ' 4px',
              textTransform: ' none',
              appearance: ' none',
              position: ' relative',
              cursor: ' pointer',
              userSelect: ' none',
              direction: ' ltr',
              overflow: ' hidden',
              textAlign: ' left',
              color: ' rgb(0, 0, 0)',
              fontFamily: ' Roboto, Arial, sans-serif',
              fontSize: ' 11px',
              borderBottomLeftRadius: ' 2px',
              borderTopLeftRadius: ' 2px',
              boxShadow: ' rgba(0, 0, 0, 0.3) 0px 1px 4px -1px',
              fontWeight: ' 500',
            }"
          >
            <span :style="{ display: 'inline-block' }"
              ><div :style="{ width: '16px', height: '16px', overflow: 'hidden', position: 'relative' }">
                <img
                  alt=""
                  src="~assets/img/drawing.png"
                  draggable="false"
                  :style="{
                    position: 'absolute',
                    left: '0px',
                    top: '-144px',
                    userSelect: 'none',
                    border: '0px',
                    padding: '0px',
                    margin: '0px',
                    maxWidth: 'none',
                    width: '16px',
                    height: '192px',
                  }"
                /></div
            ></span>
          </button>
        </div>

        <div :style="{ float: 'left', lineHeight: 0 }">
          <button
            id="startdraw"
            draggable="false"
            aria-label="Draw a shape"
            title="Draw a shape"
            type="button"
            role="menuitemradio"
            aria-checked="false"
            :style="{
              background: ' none padding-box rgb(255, 255, 255)',
              display: ' block',
              border: ' 0px',
              margin: ' 0px',
              padding: ' 4px',
              textTransform: ' none',
              appearance: ' none',
              position: ' relative',
              cursor: ' pointer',
              userSelect: ' none',
              direction: ' ltr',
              overflow: ' hidden',
              textAlign: ' left',
              color: ' rgb(86, 86, 86)',
              fontFamily: ' Roboto, Arial, sans-serif',
              fontSize: ' 11px',
              boxShadow: ' rgba(0, 0, 0, 0.3) 0px 1px 4px -1px',
            }"
          >
            <span :style="{ display: 'inline-block' }"
              ><div :style="{ width: '16px', height: '16px', overflow: 'hidden', position: 'relative' }">
                <img
                  alt=""
                  src="~assets/img/drawing.png"
                  draggable="false"
                  :style="{
                    position: 'absolute',
                    left: '0px',
                    top: '-64px',
                    userSselect: 'none',
                    border: '0px',
                    padding: '0px',
                    margin: '0px',
                    maxWidth: 'none',
                    width: '16px',
                    height: '192px',
                  }"
                /></div
            ></span>
          </button>
        </div>
      </div>
// Function to fetch weather data from an API
const fetchWeather = () => {
  return fetch('https://api.example.com/weather')
    .then((response) => {
      if (!response.ok) {
        throw new Error('Failed to fetch weather data');
      }
      return response.json();
    })
    .then((data) => {
      return { temperature: data.temperature, condition: data.condition };
    });
};

// Function to fetch stock market data from an API
const fetchStocks = () => {
  return fetch('https://api.example.com/stocks')
    .then((response) => {
      if (!response.ok) {
        throw new Error('Failed to fetch stock data');
      }
      return response.json();
    })
    .then((data) => {
      return { symbol: data.symbol, price: data.price };
    });
};

// Function to fetch news headlines from an API
const fetchNews = () => {
  return fetch('https://api.example.com/news')
    .then((response) => {
      if (!response.ok) {
        throw new Error('Failed to fetch news data');
      }
      return response.json();
    })
    .then((data) => {
      return data.articles.map(article => ({ title: article.title }));
    });
};

// Fetch all data in parallel using Promise.all
Promise.all([fetchWeather(), fetchStocks(), fetchNews()])
  .then(([weatherData, stockData, newsData]) => {
    console.log('Weather:', weatherData);
    console.log('Stocks:', stockData);
    console.log('News:', newsData);

    // Now you can update the UI with all the data
    updateDashboard(weatherData, stockData, newsData);
  })
  .catch((error) => {
    console.error('Error fetching data:', error);
  });

// Example of how you could update the dashboard
function updateDashboard(weather, stocks, news) {
  console.log('Updating dashboard with all the data...');
  // Logic to update the UI with the fetched data
}
async function fetchData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Error: ${response.status} ${response.statusText}`);
    }
    const data = await response.json(); // Parse and return JSON data
    return data;
  } catch (error) {
    console.error('Fetch failed:', error.message);
    throw error; // Re-throw the error if necessary for handling elsewhere
  }
}

async function useData() {
  try {
    const data1 = await fetchData('https://jsonplaceholder.typicode.com/posts/1');
    console.log('First Request Data:', data1);
  
    // If you need to fetch data from another endpoint:
    const data2 = await fetchData('https://jsonplaceholder.typicode.com/posts/2');
    console.log('Second Request Data:', data2);
  } catch (error) {
    console.error('Error in data retrieval:', error);
  }
}

useData();
class User {
    constructor(username, password, email) {
        this.username = username;
        this.password = password;
        this.email = email;
    }
}
let users = []; 
let loggedInUser = null;
function registerUser() {
    const username = document.getElementById('reg-username').value.trim();
    const password = document.getElementById('reg-password').value.trim();
    const email = document.getElementById('reg-email').value.trim();
    const regMsg = document.getElementById('reg-msg');
    if (username === "" || password === "" || email === "") {
        regMsg.textContent = "All fields are required!";
        return;
    }
    if (users.find(user => user.username === username)) {
        regMsg.textContent = "Username already taken!";
        return;
    }
    const newUser = new User(username, password, email);
    users.push(newUser);
    regMsg.textContent = "Registration successful!";
    clearFields(['reg-username', 'reg-password', 'reg-email']);
}
function loginUser() {
    const username = document.getElementById('login-username').value.trim();
    const password = document.getElementById('login-password').value.trim();
    const loginMsg = document.getElementById('login-msg');
    if (username === "" || password === "") {
        loginMsg.textContent = "All fields are required!";
        return;
    }
    const user = users.find(user => user.username === username && user.password === password);
    if (user) {
        loggedInUser = user;
        showUserProfile(user);
        loginMsg.textContent = "";
    } else {
        loginMsg.textContent = "Invalid username or password!";
    }
}
function showUserProfile(user) {
    document.getElementById('profile-username').textContent = user.username;
    document.getElementById('profile-email').textContent = user.email;
    document.getElementById('registration-form').style.display = 'none';
    document.getElementById('login-form').style.display = 'none';
    document.getElementById('profile').style.display = 'block';
    document.getElementById('payment-form').style.display = 'block';
}
function logoutUser() {
    loggedInUser = null;
    document.getElementById('registration-form').style.display = 'block';
    document.getElementById('login-form').style.display = 'block';
    document.getElementById('profile').style.display = 'none';
    document.getElementById('payment-form').style.display = 'none';
}
function processPayment() {
    const cardNumber = document.getElementById('card-number').value.trim();
    const expiryDate = document.getElementById('expiry-date').value.trim();
    const cvv = document.getElementById('cvv').value.trim();
    const paymentMsg = document.getElementById('payment-msg');
    if (cardNumber === "" || expiryDate === "" || cvv === "") {
        paymentMsg.textContent = "All fields are required!";
        return;
    }
    if (cardNumber.length !== 16 || cvv.length !== 3) {
        paymentMsg.textContent = "Invalid card details!";
        return;
    }
    paymentMsg.textContent = "Payment successful!";
    clearFields(['card-number', 'expiry-date', 'cvv']);
}
function clearFields(fields) {
    fields.forEach(field => document.getElementById(field).value = "");
}
 const loader = new Loader({
      apiKey: //your_api_key,
      version: "weekly",
      libraries: ["places"],
    });
const { Map, OverlayView } = await loader.importLibrary("maps");    
function getAddress(place) {
  const { address_components, formatted_address, geometry, name } = place;
  let country = (address_components || []).find((component) => component.types.includes("country"));
  let state = (address_components || []).find((component) =>
    component.types.includes("administrative_area_level_1")
  );
  let city = (address_components || []).find((component) => component.types.includes("locality"));
  let address_line = (address_components || []).find((component) => component.types.includes("route"));
  let postal_code = (address_components || []).find((component) => component.types.includes("postal_code"));
  return {
    name: name,
    address: formatted_address,
    country: country?.long_name,
    city: city?.long_name,
    state: state?.long_name,
    postalCode: postal_code?.long_name,
    coords: {
      lat: geometry.location.lat(),
      lng: geometry.location.lng(),
    },
  };
}
class CustomOverlay extends OverlayView {
      div_;
      constructor(map) {
        super();
        this.div_ = null;
        this.setMap(map);
      }
      async onAdd() {
        var div = document.createElement("div");
        div.style.zIndex = "100";
        div.style.borderStyle = "solid";
        div.style.borderWidth = "1px";
        div.style.backgroundColor = "white";
        div.style.padding = "4px";
        div.style.position = "absolute";
        div.style.height = "40px";

        // Add a textbox inside the div
        var textbox = document.createElement("input");
        textbox.type = "text";
        textbox.style.width = "100%";
        textbox.style.height = "100%";
        textbox.placeholder = "Search Location";
        div.appendChild(textbox);
        this.div_ = div;
        this.getPanes().overlayMouseTarget.appendChild(div);
        // this.getPanes().floatPane.appendChild(div);

        // Prevent map from intercepting events when interacting with the textbox
        function handleMouseEvents(e) {
          if (e.target == textbox) {
            e.stopPropagation();
          }
        }
        const map = this.getMap();
        const mapDiv = map.getDiv();
        google.maps.event.addDomListener(mapDiv, "mousedown", handleMouseEvents, true);
        google.maps.event.addDomListener(mapDiv, "dblclick", handleMouseEvents, true);

        map.addListener("dragstart", function (e) {
          //
        });
        map.addListener("dragend", function (e) {});
        const { SearchBox } = await loader.importLibrary("places");

        const search = new SearchBox(textbox);
        search.addListener("places_changed", async function () {
          const place = search.getPlaces();
          console.log("use data for the place", place);
          // or use the function above "getAddress" to return a json formatted data
        });
      }
      draw() {
        var overlayProjection = this.getProjection();
        if (!overlayProjection) {
          return;
        }

        // Get northeast and southwest corners of the map's current bounds
        const mapBounds = this.getMap().getBounds();
        const fromLatLngToDivPixel = function (latLng) {
          return overlayProjection.fromLatLngToDivPixel(latLng);
        };

        const ne = fromLatLngToDivPixel(mapBounds.getNorthEast());
        const sw = fromLatLngToDivPixel(mapBounds.getSouthWest());
        if (this.div_) {
          this.div_.style.left = sw.x + 10 + "px";
          this.div_.style.top = ne.y + 10 + "px";
        }
      }
      onRemove() {
        if (!this.div_) return;
        this.div_.parentNode.removeChild(this.div_);
        this.div_ = null;
      }
    }
	// load a maps library and pass it to the class
    
    const map = new Map(vm.$refs.GoogleMap, {
      zoom: 14,
      disableDefaultUI: false,
      mapTypeControl: false,
      streetViewControl: false,
      mapTypeId: "roadmap",
      scrollWheel: true,
      fullscreenControl: true,
      center: {
        lat: 49.316666,
        lng: -123.066666,
      },
    });
	
    new CustomOverlay(map);
radial-gradient(circle farthest-corner at 32% 26%, #BADA55 0%, #57BA51 36.0321044921875%, #056A07 75.677490234375%)
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":sunshine: Boost Days - Whats On This Week! :sunshine:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Mōrena Ahuriri & happy December! :santa:\n\nWe're excited to kick off another month with our Boost Day Program! :yay: Please see below for whats on this week :arrow-bounce:"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-4: Wednesday, 4th December",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee: *Café Partnership*: Enjoy coffee and café-style beverages from our cafe partner, *Adoro*, located in our office building *8:00AM - 11:30AM*.\n:BREAKFAST: *Breakfast*: Provided by *Mitzi and Twinn* *9:30AM - 11:00AM* in the Kitchen."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-5: Thursday, 5th December",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Café Partnership*: Enjoy coffee and café-style beverages from our cafe partner, *Adoro*, located in our office building *8:00AM - 11:30AM*. \n:sandwich: *Lunch*: Provided by *Roam* *12:00PM - 1:00PM* in the Kitchen. \n:massage: *Wellness*: Our second massage event for our winners of last weeks giveaway in *Craggy* *10:00AM - 2:00PM*"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "*LATER THIS WEEK/MONTH:*"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "*Friday, 6th December*\n :unicorn_face: *EOY Event*: A Sprinkle of Magic THIS FRIDAY *4:30PM - 10:00PM* :clinking_glasses: Stay tuned for more info :soon:\n\n*Thursday, 12th December* \n :christmas-tree: *Christmas Lunch Social*: A special Christmas Lunch & Secret Santa from *12:00PM*! :gift:\n\n*Wednesday, 18th December*\n:xero: *Global All Hands*: Streamed live in *Clearview* *11:00AM - 12:00PM* \n\n*Thursday, 19th December*\n:newzealand: *Aotearoa All Hands*: Streamed live in Clearview *10:30AM - 11:30AM*"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0?cid=eGVyby5jb21fbXRhc2ZucThjaTl1b3BpY284dXN0OWlhdDRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ|*Hawkes Bay Social Calendar*>, and get ready to Boost your workdays!\n\nWX Team :party-wx:"
			}
		}
	]
}
@extends('new_layouts.app')
@section('styles')
    <style>
        .modal-icon {
            font-size: 3rem;
            color: #dc3545;
        }

        .modal-body {
            padding: 2rem;
        }

        .modal-title {
            font-size: 1.25rem;
            margin-top: 1rem;
        }

        .modal-body p {
            font-size: 1rem;
            margin-top: 0.5rem;
        }

        .custom-table {
            border-collapse: collapse;
            border-radius: 1rem;
            border-style: hidden;
            box-shadow: 0 0 0 1px #e6ebef;
            overflow: hidden;
            text-align: left;
            width: 100%;
        }

        .badge-file-extension {
            background-color: #f25961;
            color: white;
            padding: 0.25rem 0.5rem;
            font-size: 0.875rem;
            border-radius: 0.375rem;
            margin-left: 0.5rem;
        }

        .bookmark-active svg {
            fill: #FF9800;
        }

        .description-text {
            font-size: 1.1rem;
            color: #555;
            margin-top: 0.5rem;
        }

        .comment {
            margin-top: 1rem;
            margin-bottom: 1rem;
        }

        .comment-section {
            border: 1px solid #e9ebee;
            border-radius: 1rem;
            padding: 1.5rem;
            background-color: #ffffff;
            /* box-shadow: 0 0 1rem rgba(0, 0, 0, 0.1); */
        }

        .comment-header {
            border-bottom: 1px solid #e9ebee;
            padding-bottom: 0.75rem;
            margin-bottom: 1rem;
        }

        .comment-avatar {
            height: 48px;
            width: 48px;
            border-radius: 50%;
            margin-right: 1rem;
        }

        .comment-author {
            font-size: 1rem;
            font-weight: 600;
        }

        .comment-time {
            font-size: 0.875rem;
            color: #90949c;
        }

        .comment-body {
            margin: 0.75rem 0;
            font-size: 1rem;
        }

        .comment-actions a {
            font-size: 0.875rem;
            color: #4267b2;
            text-decoration: none;
            margin-right: 1rem;
        }

        .comment-actions i {
            margin-right: 0.5rem;
        }

        .reply-list {
            margin-top: 1rem;
            padding-left: 2rem;
        }

        .reply-list .comment {
            border-left: 1px dotted #d3d6db;
            padding-left: 1rem;
            margin-top: 1rem;
        }

        .reply-toggle {
            cursor: pointer;
            font-size: 0.875rem;
            color: #4267b2;
            text-decoration: none;
            margin-top: 1rem;
            display: block;
        }

        .reply-form {
            display: none;
            position: relative;
            z-index: 10;
        }

        .comment-input {
            border-radius: 0.5rem;
        }

        .like-button.active i {
            color: #4caf50;
        }

        .dislike-button.active i {
            color: #dc3545;
        }


        /* Dropdown Styles */
        .dropdown-toggle::after {
            display: none;
            /* Remove the default arrow */
        }

        .dropdown-menu {
            right: 0;
            left: auto;
        }
    </style>
@endsection
@section('content')
    <div>
        <div class="d-flex flex-column">
            <h1>Title: {{ $material->title }}</h1>
            @if ($material->description)
                <p class="description-text"><strong>Description:</strong> {{ $material->description }}</p>
            @endif
        </div>

        <div class="d-flex justify-content-end mb-4">
            <a class="btn rounded-3" style="background-color: #4CAF50; color: white"
                href="{{ route('materials.downloadAll', $material) }}">
                <i class="fas fa-download me-1"></i> Download All
            </a>
        </div>

        <div class="table-responsive">
            <table class="table table-striped custom-table">
                <thead>
                    <tr>
                        <th scope="col">Bookmarks</th>
                        <th scope="col">Document</th>
                        <th scope="col">Action</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($files as $file)
                        <tr>
                            <td>
                                @php
                                    $isBookmarked = $file->bookmarks()->where('user_id', Auth::id())->exists();
                                @endphp
                                <button type="button"
                                    class="btn btn-outline-dark bookmark-toggle {{ $isBookmarked ? 'bookmark-active' : '' }}"
                                    data-file-id="{{ $file->id }}">
                                    @if ($isBookmarked)
                                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
                                            fill="currentColor" class="bi bi-bookmarks-fill" viewBox="0 0 16 16">
                                            <path
                                                d="M2 4a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L7 13.101l-4.223 2.815A.5.5 0 0 1 2 15.5z" />
                                            <path
                                                d="M4.268 1A2 2 0 0 1 6 0h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L13 13.768V2a1 1 0 0 0-1-1z" />
                                        </svg>
                                    @else
                                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
                                            fill="currentColor" class="bi bi-bookmarks" viewBox="0 0 16 16">
                                            <path
                                                d="M2 4a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L7 13.101l-4.223 2.815A.5.5 0 0 1 2 15.5zm2-1a1 1 0 0 0-1 1v10.566l3.723-2.482a.5.5 0 0 1 .554 0L11 14.566V4a1 1 0 0 0-1-1z" />
                                            <path
                                                d="M4.268 1H12a1 1 0 0 1 1 1v11.768l.223.148A.5.5 0 0 0 14 13.5V2a2 2 0 0 0-2-2H6a2 2 0 0 0-1.732 1" />
                                        </svg>
                                    @endif
                                    <span class="visually-hidden">Button</span>
                                </button>
                            </td>
                            <td>
                                <div>
                                    @php
                                        $extension = pathinfo($file->name, PATHINFO_EXTENSION);
                                    @endphp
                                    <i class="fa-solid fa-file-lines" style="color: #0068b8; margin-right: 5px;"></i>
                                    <a href="{{ Storage::url($file->path) }}" target="_blank">
                                        {{ pathinfo($file->name, PATHINFO_FILENAME) }}
                                    </a>
                                    <span>
                                        <span class="badge badge-file-extension">
                                            {{ strtoupper($extension) }} File
                                        </span>
                                    </span>
                                </div>
                            </td>
                            <td>
                                <a class="btn btn-primary rounded-pill" href="{{ route('files.download', $file) }}">
                                    <i class="fas fa-download me-1"></i> Download
                                </a>
                            </td>

                        </tr>
                    @endforeach
                </tbody>
            </table>
        </div>
    </div>
    <div class="container">
        <div class="mt-4 comment-section">
            <h3>Comments ( {{ $comments->count() }} )</h3>
            <div class="comment-header d-flex justify-content-between align-items-center">
            </div>
            <div class="comment-body">
                <div class="d-flex mb-3">
                    <img src="https://static.xx.fbcdn.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg" alt="avatar"
                        class="comment-avatar">
                    <div class="w-100">
                        <form id="comment-form" action="{{ route('comments.store', $material) }}" method="POST">
                            @csrf
                            <div class="d-flex flex-column">
                                <textarea name="content" class="form-control comment-input" placeholder="Write a comment..." rows="3"></textarea>
                                <div class="d-flex justify-content-between mt-2">
                                    <div id="comment-form-error" class="text-danger"></div>
                                    <button type="submit" class="btn btn-primary">Post Comment</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
                <div id="comment-list" class="comment-list">
                    @foreach ($comments as $comment)
                        <div class="comment" data-comment-id="{{ $comment->id }}">
                            <div class="d-flex">
                                <img src="https://static.xx.fbcdn.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg" alt="avatar"
                                    class="comment-avatar">
                                <div class="w-100">
                                    <div class="d-flex justify-content-between align-items-start">
                                        <div>
                                            <div class="comment-author">{{ $comment->user->name }}</div>
                                            <div class="comment-time">{{ $comment->created_at->diffForHumans() }}</div>
                                        </div>
                                        @if ($comment->user_id === auth()->id())
                                            <div class="dropdown">
                                                <button class="btn btn-link dropdown-toggle" type="button"
                                                    id="dropdownMenuButton{{ $comment->id }}" data-bs-toggle="dropdown"
                                                    aria-expanded="false">
                                                    <i class="fa-solid fa-ellipsis-vertical"></i>
                                                </button>
                                                <ul class="dropdown-menu"
                                                    aria-labelledby="dropdownMenuButton{{ $comment->id }}">
                                                    <li><a class="dropdown-item" href="#" data-action="edit"
                                                            data-comment-id="{{ $comment->id }}">Edit</a></li>
                                                    <li><a class="dropdown-item text-danger" href="#"
                                                            data-action="delete"
                                                            data-comment-id="{{ $comment->id }}">Delete</a></li>
                                                </ul>
                                            </div>
                                        @endif
                                    </div>
                                    <div class="comment-body">{{ $comment->content }}</div>
                                    <div class="comment-actions">
                                        <a href="#"
                                            class="like-button {{ $comment->likes()->where('user_id', auth()->id())->exists() ? 'active' : '' }}"
                                            data-action="like" data-comment-id="{{ $comment->id }}">
                                            <i class="fa-solid fa-thumbs-up"></i>
                                            <span class="like-dislike-count">{{ $comment->likes }}</span>
                                        </a>
                                        <a href="#"
                                            class="dislike-button {{ $comment->dislikes()->where('user_id', auth()->id())->exists() ? 'active' : '' }}"
                                            data-action="dislike" data-comment-id="{{ $comment->id }}">
                                            <i class="fa-solid fa-thumbs-down"></i>
                                            <span class="like-dislike-count">{{ $comment->dislikes }}</span>
                                        </a>
                                        <a href="#" class="reply-link" data-comment-id="{{ $comment->id }}"
                                            data-author="{{ $comment->user->name }}">
                                            <i class="fa-solid fa-reply"></i> Reply
                                        </a>
                                    </div>
                                    <div class="reply-toggle" onclick="toggleReplies(this)">View replies</div>

                                    <form class="reply-form" action="{{ route('replies.store', $comment) }}"
                                        method="POST">
                                        @csrf
                                        <div class="d-flex flex-column">
                                            <textarea name="content" class="form-control comment-input" placeholder="Write a reply..." rows="2"></textarea>
                                            <div class="d-flex justify-content-between mt-2">
                                                <div id="comment-form-error" class="text-danger" style="display: none;">
                                                    Error: Reply cannot be empty
                                                </div>
                                                <button type="submit" class="btn btn-primary ms-auto">Post Reply</button>
                                            </div>
                                        </div>

                                    </form>
                                    <div class="reply-list" style="display: none;">
                                        @foreach ($comment->replies as $reply)
                                            <div class="comment reply" data-comment-id="{{ $reply->id }}">
                                                <div class="d-flex">
                                                    <img src="https://static.xx.fbcdn.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg"
                                                        alt="avatar" class="comment-avatar">
                                                    <div class="w-100">
                                                        <div class="d-flex justify-content-between align-items-start">
                                                            <div>
                                                                <div class="comment-author">{{ $reply->user->name }}</div>
                                                                <div class="comment-time">
                                                                    {{ $reply->created_at->diffForHumans() }}</div>
                                                            </div>
                                                            @if ($reply->user_id === auth()->id())
                                                                <div class="dropdown">
                                                                    <button class="btn btn-link dropdown-toggle"
                                                                        type="button"
                                                                        id="dropdownMenuButton{{ $reply->id }}"
                                                                        data-bs-toggle="dropdown" aria-expanded="false">
                                                                        <i class="fa-solid fa-ellipsis-vertical"></i>
                                                                    </button>
                                                                    <ul class="dropdown-menu"
                                                                        aria-labelledby="dropdownMenuButton{{ $reply->id }}">
                                                                        <li><a class="dropdown-item" href="#"
                                                                                data-action="edit"
                                                                                data-comment-id="{{ $reply->id }}">Edit</a>
                                                                        </li>
                                                                        <li><a class="dropdown-item text-danger"
                                                                                href="#" data-action="delete"
                                                                                data-comment-id="{{ $reply->id }}">Delete</a>
                                                                        </li>
                                                                    </ul>
                                                                </div>
                                                            @endif
                                                        </div>
                                                        <div class="comment-body">
                                                            @if ($reply->parent)
                                                                <a href="#"
                                                                    class="reply-mention">{{ '@' . $reply->parent->user->name }}</a>
                                                            @endif
                                                            <span class="reply-content">{{ $reply->content }}</span>
                                                        </div>
                                                        <div class="comment-actions">
                                                            <a href="#"
                                                                class="like-button {{ $reply->likes()->where('user_id', auth()->id())->exists() ? 'active' : '' }}"
                                                                data-action="like" data-comment-id="{{ $reply->id }}">
                                                                <i class="fa-solid fa-thumbs-up"></i>
                                                                <span
                                                                    class="like-dislike-count">{{ $reply->likes }}</span>
                                                            </a>
                                                            <a href="#"
                                                                class="dislike-button {{ $reply->dislikes()->where('user_id', auth()->id())->exists() ? 'active' : '' }}"
                                                                data-action="dislike"
                                                                data-comment-id="{{ $reply->id }}">
                                                                <i class="fa-solid fa-thumbs-down"></i>
                                                                <span
                                                                    class="like-dislike-count">{{ $reply->dislikes }}</span>
                                                            </a>
                                                            <a href="#" class="reply-link"
                                                                data-comment-id="{{ $reply->id }}"
                                                                data-author="{{ $reply->user->name }}">
                                                                <i class="fa-solid fa-reply"></i> Reply
                                                            </a>
                                                        </div>
                                                        <form class="reply-form"
                                                            action="{{ route('replies.store', $reply) }}" method="POST">
                                                            @csrf
                                                            <div class="d-flex flex-column">
                                                                <textarea name="content" class="form-control comment-input" placeholder="Write a reply..." rows="2"></textarea>
                                                                <div class="d-flex justify-content-between mt-2">
                                                                    <div id="comment-form-error" class="text-danger"
                                                                        style="display: none;">
                                                                        Error: Reply cannot be empty
                                                                    </div>
                                                                    <button type="submit"
                                                                        class="btn btn-primary ms-auto">Post Reply</button>
                                                                </div>
                                                            </div>

                                                        </form>
                                                    </div>
                                                </div>
                                            </div>
                                            @include('materials.comment', ['replies' => $reply->replies])
                                        @endforeach
                                    </div>
                                </div>
                            </div>
                        </div>
                    @endforeach
                </div>
            </div>
        </div>
    </div>

    <!-- Modal for delete confirmation -->
    <div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-body text-center">
                    <div class="mb-3">
                        <i class="fa-solid fa-triangle-exclamation modal-icon"></i>
                    </div>
                    <h5 class="modal-title" id="deleteModalLabel">Delete Comment</h5>
                    <p>Are you sure you want to delete this comment?</p>
                </div>
                <div class="modal-footer d-flex justify-content-center">
                    <button type="button" class="btn btn-danger ms-2" id="confirmDelete">Delete</button>
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('scripts')
<script>
    document.addEventListener('DOMContentLoaded', function() {
        const commentList = document.getElementById('comment-list');

        // Handle edit button click
        commentList.addEventListener('click', function(event) {
            const button = event.target.closest('a[data-action="edit"]');
            if (button) {
                event.preventDefault();
                const commentId = button.getAttribute('data-comment-id');
                const commentElement = document.querySelector(
                    `.comment[data-comment-id="${commentId}"]`);
                const commentBodyElement = commentElement.querySelector('.comment-body');

                const mentionElement = commentBodyElement.querySelector('.reply-mention');
                const mention = mentionElement ? mentionElement.innerText.trim() : '';
                const contentElement = mentionElement ? mentionElement.nextElementSibling :
                    commentBodyElement;
                const content = contentElement.innerText.trim();

                commentBodyElement.dataset.originalContent = commentBodyElement.innerHTML;

                const editForm = `
                    <form class="edit-comment-form" data-comment-id="${commentId}">
                        ${mention ? `<span class="reply-mention">${mention}</span>` : ''}
                        <textarea class="form-control">${content}</textarea>
                        <div class="error-message text-danger mt-2" style="display: none;"></div>
                        <div class="d-flex justify-content-end mt-3">
                            <button type="submit" class="btn btn-primary me-2">Save</button>
                            <button type="button" class="btn btn-secondary cancel-edit">Cancel</button>
                        </div>
                    </form>
                `;


                commentBodyElement.innerHTML = editForm;
                attachEditFormListeners(commentId);
            }
        });

        function attachEditFormListeners(commentId) {
            const editForm = document.querySelector(`.edit-comment-form[data-comment-id="${commentId}"]`);

            editForm.addEventListener('submit', function(e) {
                e.preventDefault();
                const textarea = this.querySelector('textarea');
                const content = textarea.value.trim();
                const errorMessageElement = this.querySelector('.error-message');

                if (content === '') {
                    errorMessageElement.textContent = 'Content cannot be empty.';
                    errorMessageElement.style.display = 'block';
                    return; // Prevent form submission
                } else {
                    errorMessageElement.style.display = 'none';
                }

                fetch(`/comments/${commentId}`, {
                        method: 'PUT',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
                        },
                        body: JSON.stringify({ content })
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            const commentBodyElement = document.querySelector(
                                `.comment[data-comment-id="${commentId}"] .comment-body`);
                            const mentionElement = mention ?
                                `<a href="#" class="reply-mention">${mention}</a>` : '';
                            commentBodyElement.innerHTML =
                                `${mentionElement} <span class="reply-content">${data.content}</span>`;
                        } else {
                            alert('Error updating comment.');
                        }
                    })
                    .catch(error => {
                        console.error('Error:', error);
                    });
            });

            editForm.querySelector('.cancel-edit').addEventListener('click', function() {
                const originalContent = document.querySelector(
                    `.comment[data-comment-id="${commentId}"] .comment-body`).dataset.originalContent;
                document.querySelector(`.comment[data-comment-id="${commentId}"] .comment-body`)
                    .innerHTML = originalContent;
            });
        }
    });
</script>


    <script>
        document.addEventListener('DOMContentLoaded', function() {

            // for delete 
            let commentIdToDelete = null;

            document.getElementById('comment-list').addEventListener('click', function(event) {
                const button = event.target.closest('a[data-action="delete"]');
                if (button) {
                    event.preventDefault();
                    commentIdToDelete = button.getAttribute('data-comment-id');

                    // Show the delete confirmation modal
                    const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
                    deleteModal.show();
                }
            });

            document.getElementById('confirmDelete').addEventListener('click', function() {
                if (commentIdToDelete) {
                    fetch(`/comments/${commentIdToDelete}`, {
                            method: 'DELETE',
                            headers: {
                                'X-Requested-With': 'XMLHttpRequest',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')
                                    .getAttribute('content'),
                                'Content-Type': 'application/json',
                            }
                        })
                        .then(response => response.json())
                        .then(data => {
                            if (data.success) {
                                const commentElement = document.querySelector(
                                    `.comment[data-comment-id="${commentIdToDelete}"]`);
                                if (commentElement) {
                                    commentElement.remove();
                                }
                            } else {
                                alert(
                                    'Error: This comment was deleted because its parent comment was removed');
                            }
                        })
                        .catch(error => {
                            // console.error('Error:', error);
                            // alert('Something went wrong');
                        });

                    const deleteModal = bootstrap.Modal.getInstance(document.getElementById('deleteModal'));
                    deleteModal.hide();
                }
            });

            // for like and dislike
            document.getElementById('comment-list').addEventListener('click', function(event) {
                const button = event.target.closest('a');
                if (button && (button.classList.contains('like-button') || button.classList.contains(
                        'dislike-button'))) {
                    event.preventDefault();

                    const commentId = button.getAttribute('data-comment-id');
                    const action = button.getAttribute('data-action');

                    fetch(`/comments/${commentId}/${action}`, {
                            method: 'POST',
                            headers: {
                                'X-Requested-With': 'XMLHttpRequest',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')
                                    .getAttribute('content'),
                                'Content-Type': 'application/json',
                            },
                            body: JSON.stringify({
                                _method: 'POST'
                            })
                        })
                        .then(response => response.json())
                        .then(data => {
                            if (data.success) {
                                const commentElement = document.querySelector(
                                    `.comment[data-comment-id="${commentId}"]`);
                                const likeCount = commentElement.querySelector(
                                    '.like-button .like-dislike-count');
                                const dislikeCount = commentElement.querySelector(
                                    '.dislike-button .like-dislike-count');

                                likeCount.textContent = data.comment.likes;
                                dislikeCount.textContent = data.comment.dislikes;

                                if (action === 'like') {
                                    button.classList.toggle('active');
                                    commentElement.querySelector('.dislike-button').classList.remove(
                                        'active');
                                } else {
                                    button.classList.toggle('active');
                                    commentElement.querySelector('.like-button').classList.remove(
                                        'active');
                                }
                            } else {
                                alert(data.message || 'Error updating like/dislike');
                            }
                        })
                        .catch(error => {
                            console.error('Error:', error);
                            alert('Something went wrong');
                        });
                }
            });

            // For submission of the main comment form
            document.getElementById('comment-form')?.addEventListener('submit', function(event) {
                event.preventDefault();
                const formData = new FormData(this);
                const errorDiv = document.getElementById('comment-form-error');
                errorDiv.textContent = ''; // Clear previous errors

                fetch(this.action, {
                        method: 'POST',
                        body: formData,
                        headers: {
                            'X-Requested-With': 'XMLHttpRequest',
                            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')
                                .getAttribute('content')
                        }
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            const commentList = document.getElementById('comment-list');
                            if (commentList) {
                                const newCommentHtml = `
                            <div class="comment" data-comment-id="${data.comment.id}">
                                <div class="d-flex">
                                    <img src="https://static.xx.fbcdn.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg" alt="avatar" class="comment-avatar">
                                    <div class="w-100">
                                        <div class="d-flex justify-content-between align-items-start">
                                            <div>
                                                <div class="comment-author">${data.comment.user_name}</div>
                                                <div class="comment-time">${data.comment.created_at}</div>
                                            </div>
                                            <div class="dropdown">
                                                <button class="btn btn-link dropdown-toggle" type="button"
                                                    id="dropdownMenuButton${data.comment.id}" data-bs-toggle="dropdown"
                                                    aria-expanded="false">
                                                    <i class="fa-solid fa-ellipsis-vertical"></i>
                                                </button>
                                                <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton${data.comment.id}">
                                                    <li><a class="dropdown-item" href="#" data-action="edit" data-comment-id="${data.comment.id}">Edit</a></li>
                                                    <li><a class="dropdown-item text-danger" href="#" data-action="delete" data-comment-id="${data.comment.id}">Delete</a></li>
                                                </ul>
                                            </div>
                                        </div>
                                        <div class="comment-body">${data.comment.content}</div>
                                        <div class="comment-actions">
                                            <a href="#" class="like-button" data-action="like" data-comment-id="${data.comment.id}">
                                                <i class="fa-solid fa-thumbs-up"></i>
                                                <span class="like-dislike-count">0</span>
                                            </a>
                                            <a href="#" class="dislike-button" data-action="dislike" data-comment-id="${data.comment.id}">
                                                <i class="fa-solid fa-thumbs-down"></i>
                                                <span class="like-dislike-count">0</span>
                                            </a>
                                            <a href="#" class="reply-link" data-comment-id="${data.comment.id}" data-author="${data.comment.user_name}">
                                                <i class="fa-solid fa-reply"></i> Reply
                                            </a>
                                        </div>
                                        <div class="reply-toggle" onclick="toggleReplies(this)">View replies</div>
                                        <form class="reply-form" action="{{ route('replies.store', ':commentId') }}" method="POST" style="display: none;">
                                            @csrf
                                            <div class="d-flex flex-column">
                                                <textarea name="content" class="form-control comment-input" placeholder="Write a reply..." rows="2"></textarea>
                                                <div class="d-flex justify-content-between  mt-2">
                                                    <div id="comment-form-error" class="text-danger" style="display: none;">
                                                        Error: Reply cannot be empty
                                                    </div>
                                                    <button type="submit" class="btn btn-primary ms-auto">Post Reply</button>
                                                </div>
                                            </div>
                                        </form>
                                        <div class="reply-list" style="display: none;"></div>
                                    </div>
                                </div>
                            </div>
                        `.replace(':commentId', data.comment.id);

                                commentList.insertAdjacentHTML('afterbegin', newCommentHtml);
                                this.reset();
                                initializeDropdowns();
                            }
                        } else {
                            // Display error messages
                            errorDiv.textContent = data.error || 'Your comment is empty';
                        }
                    })
                    .catch(error => {
                        console.error('Error:', error);
                        errorDiv.textContent = 'Something went wrong';
                    });
            });

            // For submission of reply forms
            document.getElementById('comment-list')?.addEventListener('submit', function(event) {
                if (event.target.closest('.reply-form')) {
                    event.preventDefault();
                    const form = event.target;
                    const formData = new FormData(form);
                    const parentId = form.closest('.comment').dataset.commentId;
                    const errorDiv = form.querySelector('#comment-form-error');

                    errorDiv.style.display = 'none';
                    errorDiv.textContent = '';

                    fetch(form.action.replace(':commentId', parentId), {
                            method: 'POST',
                            body: formData,
                            headers: {
                                'X-Requested-With': 'XMLHttpRequest',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')
                                    .getAttribute('content')
                            }
                        })
                        .then(response => response.json())
                        .then(data => {
                            if (data.success) {
                                const replyList = form.closest('.reply-list') || form.closest(
                                    '.comment').querySelector('.reply-list');
                                if (replyList) {
                                    const newReplyHtml = `
                                <div class="comment reply" data-comment-id="${data.reply.id}">
                                    <div class="d-flex">
                                        <img src="https://static.xx.fbcdn.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg" alt="avatar" class="comment-avatar">
                                        <div class="w-100">
                                            <div class="d-flex justify-content-between align-items-start">
                                                <div>
                                                    <div class="comment-author">${data.reply.user_name}</div>
                                                    <div class="comment-time">${data.reply.created_at}</div>
                                                </div>
                                                <div class="dropdown">
                                                    <button class="btn btn-link dropdown-toggle" type="button" id="dropdownMenuButton${data.reply.id}" data-bs-toggle="dropdown" aria-expanded="false">
                                                        <i class="fa-solid fa-ellipsis-vertical"></i>
                                                    </button>
                                                    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton${data.reply.id}">
                                                        <li><a class="dropdown-item" href="#" data-action="edit" data-comment-id="${data.reply.id}">Edit</a></li>
                                                        <li><a class="dropdown-item text-danger" href="#" data-action="delete" data-comment-id="${data.reply.id}">Delete</a></li>
                                                    </ul>
                                                </div>
                                            </div>
                                            <div class="comment-body">
                                                ${data.reply.parent_name ? `<a href="#" class="reply-mention">@${data.reply.parent_name}</a> ` : ''}
                                                <span class="reply-content">${data.reply.content}</span>
                                            </div>
                                            <div class="comment-actions">
                                                <a href="#" class="like-button" data-action="like" data-comment-id="${data.reply.id}">
                                                    <i class="fa-solid fa-thumbs-up"></i>
                                                    <span class="like-dislike-count">0</span>
                                                </a>
                                                <a href="#" class="dislike-button" data-action="dislike" data-comment-id="${data.reply.id}">
                                                    <i class="fa-solid fa-thumbs-down"></i>
                                                    <span class="like-dislike-count">0</span>
                                                </a>
                                                <a href="#" class="reply-link" data-comment-id="${data.reply.id}" data-author="${data.reply.user_name}">
                                                    <i class="fa-solid fa-reply"></i> Reply
                                                </a>
                                            </div>
                                            <form class="reply-form" action="{{ route('replies.store', ':commentId') }}" method="POST" style="display: none;">
                                                @csrf
                                                    <div class="d-flex flex-column">
                                                        <textarea name="content" class="form-control comment-input" placeholder="Write a reply..." rows="2"></textarea>
                                                        <div class="d-flex justify-content-between  mt-2">
                                                            <div id="comment-form-error" class="text-danger" style="display: none;">
                                                                Error: Reply cannot be empty
                                                            </div>
                                                            <button type="submit" class="btn btn-primary ms-auto">Post Reply</button>
                                                        </div>
                                                    </div>
                                            </form>
                                            <div class="reply-list" style="display: none;"></div>
                                        </div>
                                    </div>
                                </div>
                                `.replace(':commentId', data.reply.id);

                                    replyList.insertAdjacentHTML('beforeend', newReplyHtml);
                                    form.reset();
                                    form.style.display =
                                        'none'; // Hide the reply form after successful submission

                                    const replyToggle = form.closest('.comment').querySelector(
                                        '.reply-toggle');
                                    if (replyToggle) {
                                        const replyList = replyToggle.nextElementSibling
                                            .nextElementSibling;
                                        replyList.style.display = 'block';
                                        replyToggle.textContent = 'Hide replies';
                                    }

                                    initializeDropdowns();
                                }
                            } else {
                                // Display error message
                                errorDiv.textContent = data.message || 'Error posting reply';
                                errorDiv.style.display = 'block';
                            }
                        })
                        .catch(error => {
                            console.error('Error:', error);
                            // Display error message
                            errorDiv.textContent = 'Something went wrong';
                            errorDiv.style.display = 'block';
                        });
                }
            });

            // For reply link click to show reply form
            document.getElementById('comment-list')?.addEventListener('click', function(event) {
                if (event.target.closest('.reply-link')) {
                    event.preventDefault();
                    const replyForm = event.target.closest('.comment').querySelector('.reply-form');
                    if (replyForm) {
                        replyForm.style.display = replyForm.style.display === 'block' ? 'none' : 'block';
                    }
                }
            });
        });

        function initializeDropdowns() {
            const dropdowns = document.querySelectorAll('.dropdown-toggle:not(.initialized)');
            dropdowns.forEach(dropdown => {
                new bootstrap.Dropdown(dropdown);
                dropdown.classList.add('initialized');
            });
        }

        function toggleReplies(element) {
            const replyList = element.nextElementSibling.nextElementSibling;
            const isVisible = replyList.style.display === 'block';
            replyList.style.display = isVisible ? 'none' : 'block';
            element.textContent = isVisible ? 'View replies' : 'Hide replies';
        }
    </script>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            document.querySelectorAll('.bookmark-toggle').forEach(function(button) {
                button.addEventListener('click', function() {
                    const fileId = this.getAttribute('data-file-id');
                    const button = this;

                    fetch("{{ route('bookmark.toggle') }}", {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'X-CSRF-TOKEN': '{{ csrf_token() }}'
                            },
                            body: JSON.stringify({
                                file_id: fileId
                            })
                        })
                        .then(response => response.json())
                        .then(data => {
                            if (data.status === 'added') {
                                button.classList.add('bookmark-active');
                                button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                        class="bi bi-bookmarks-fill" viewBox="0 0 16 16">
                                        <path d="M2 4a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L7 13.101l-4.223 2.815A.5.5 0 0 1 2 15.5z"/>
                                        <path d="M4.268 1A2 2 0 0 1 6 0h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L13 13.768V2a1 1 0 0 0-1-1z"/>
                                    </svg>`;
                            } else if (data.status === 'removed') {
                                button.classList.remove('bookmark-active');
                                button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                        class="bi bi-bookmarks" viewBox="0 0 16 16">
                                        <path d="M2 4a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L7 13.101l-4.223 2.815A.5.5 0 0 1 2 15.5zm2-1a1 1 0 0 0-1 1v10.566l3.723-2.482a.5.5 0 0 1 .554 0L11 14.566V4a1 1 0 0 0-1-1z"/>
                                        <path d="M4.268 1H12a1 1 0 0 1 1 1v11.768l.223.148A.5.5 0 0 0 14 13.5V2a2 2 0 0 0-2-2H6a2 2 0 0 0-1.732 1"/>
                                    </svg>`;
                            }
                        })
                        .catch(error => console.error('Error:', error));
                });
            });
        });
    </script>
@endsection
// Problem Statement
// I own a parking lot that can hold up to 'n' cars at any given point in time. Each slot is given a number starting at 1 increasing with increasing distance from the entry point in steps of one. I want to create an automated ticketing system that allows my customers to use my parking lot without human intervention.

// When a car enters my parking lot, I want to have a ticket issued to the driver. The ticket issuing process includes us documenting the registration number (number plate) and the colour of the car and allocating an available parking slot to the car before actually handing over a ticket to the driver (we assume that our customers are nice enough to always park in the slots allocated to them). The customer should be allocated a parking slot which is nearest to the entry. At the exit the customer returns the ticket which then marks the slot they were using as being available.

// Due to government regulation, the system should provide me with the ability to find out:

// Registration numbers of all cars of a particular colour.
// Slot number in which a car with a given registration number is parked.
// Slot numbers of all slots where a car of a particular colour is parked.



#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define FOR(i, n) for (long long int i = 0; i < n; i++)
using namespace std;

class Vehicle
{
public:
    int colour, reg_number;
    Vehicle(int colour, int reg_number)
    {
        this->colour = colour;
        this->reg_number = reg_number;
    }
};

class Ticket
{
public:
    int colour, reg_number, slot_number;
    Ticket(int colour, int reg_number, int slot_number)
    {
        this->colour = colour;
        this->reg_number = reg_number;
        this->slot_number = slot_number;
    }
};

class ParkingLot
{
    set<int> available_slots;
    map<int, set<int>> reg_by_color;
    map<int, int> slot_by_reg;

public:
    ParkingLot(int n)
    {
        for (int i = 1; i <= n; i++)
        {
            available_slots.insert(i);
        }
    }

    void get_available_slots()
    {
        if(available_slots.size() == 0)
        {
            cout<<"No available slots for parking."<<endl;
            return;
        }
        cout << "Available slots are : ";
        for (auto itr = available_slots.begin(); itr != available_slots.end(); itr++)
        {
            cout << (*itr) << " ";
        }
        cout << endl;
    }

    Ticket take_slot(Vehicle vehicle)
    {
        if (available_slots.size() == 0)
        {
            cout << "No available slots" << endl;
            return Ticket(-1, -1, -1);
        }
        else
        {
            int taken_slot = (*available_slots.begin());
            reg_by_color[vehicle.colour].insert(vehicle.reg_number);
            slot_by_reg[vehicle.reg_number] = taken_slot;
            available_slots.erase(taken_slot);

            cout << "Slot : " << taken_slot << " is occupied." << endl;

            return Ticket(vehicle.colour, vehicle.reg_number, taken_slot);
        }
    }

    void get_reg_by_colour(int colour)
    {
        cout << "Reg number of Cars with " << colour << " are : ";
        for (auto itr = reg_by_color[colour].begin(); itr != reg_by_color[colour].end(); itr++)
        {
            cout << (*itr) << " ";
        }
        cout << endl;
    }

    void getSlot_by_reg(int reg_number)
    {
        if (slot_by_reg.find(reg_number) == slot_by_reg.end())
        {
            cout << "No Cars with " << reg_number << " exists in parking." << endl;
        }
    }

    void get_slot_by_colour(int colour)
    {
        cout << "Slot number of Cars with " << colour << " are : ";
        for (auto itr = reg_by_color[colour].begin(); itr != reg_by_color[colour].end(); itr++)
        {
            cout << slot_by_reg[(*itr)] << " ";
        }
        cout << endl;
    }

    void leave_slot(Ticket ticket)
    {
        available_slots.insert(ticket.slot_number);
        reg_by_color[ticket.colour].erase(ticket.reg_number);
        slot_by_reg.erase(ticket.reg_number);
        cout << "Car with Reg. number " << ticket.reg_number << " left." << endl;
    }
};

int main()
{
    ParkingLot parking_lot(3);
    parking_lot.get_available_slots();

    Vehicle vehicle1(1, 123);
    Ticket ticket1 = parking_lot.take_slot(vehicle1);
    Vehicle vehicle2(1, 223);
    Ticket ticket2 = parking_lot.take_slot(vehicle2);
    parking_lot.get_available_slots();
    parking_lot.get_reg_by_colour(1);
    Vehicle vehicle3(2, 125);
    Vehicle vehicle4(2, 135);

    Ticket ticket3 = parking_lot.take_slot(vehicle3);
    Ticket ticket4 = parking_lot.take_slot(vehicle4);

    parking_lot.leave_slot(ticket1);
    ticket4 = parking_lot.take_slot(vehicle3);
    parking_lot.get_available_slots();

    return 0;
}
$colors: (
  purple: #6a0dad,
  blue: #3498db,
  green: #2ecc71
);

@each $key, $val in $colors {
  @debug 'Key: #{$key}, Value: #{$val}';
}


//preview in the terminal
$colors: (
  "primary": $primary,
  "secondary": $secondary,
  "error": $error,
  "info": $info,
  "blue": #1919e6,
  "red": #e61919,
  "yellow": #e6e619,
  "green": #19e635,
  "orange": #ffa600,
  "purple": #9900ff,
  "gray": #808080,
  "black": black,
  "white": white,
);



.card {
  display: block;
  padding: $base-padding;
  border: $base-border-thickness solid $light-grey;
  border-radius: $base-border-radius;
  box-shadow: $base-box-shadow;

  // Loop over all keys in the colors map and use them for background color variations
  @each $key, $val in $colors {
    &--bgcolor-#{$key} {
      background-color: $val;

        // Change text to white if the color is purple
    	// change the text to yellow if the color is red
    	// else leave it at black
      @if $key == "purple" {
        .card__body p {
          color: map-get($colors, "white" )
        }
      } @else if $key == "red"{
        .card__body p {
          color: map-get($colors, "yellow")
        }
      }@else {
        .card__body p {
          color: #000;
        }
      }
    }
  }

  &__title {
    h3 {
      font-size: $font-size-lg;
      padding-bottom: $base-padding;
      font-weight: bold;
    }
  }

  &__body {
    font-size: $base-font-size;

    a {
      text-decoration: underline;
    }
  }
}
// * color pallete creation
$colors: (
  "primary": $primary,
  "secondary": $secondary,
  "error": $error,
  "info": $info,
  "blue": #1919e6,
  "red": #e61919,
  "yellow": #e6e619,
  "green": #19e635,
  "orange": #ffa600,
  "purple": #9900ff,
  "gray": #808080,
  "black": black,
  "white": white,
);


// use this to get the data in the terminal
@debug map-get($colors);

//terminal prints
─> sass:map
1 │ @function get($map, $key, $keys...) {
  
  
 
 // Test a color with 
 @debug map-get($colors, "purple");
 // terminal prints: DEBUG: #9900ff
  
  
  // evaluation to true or false
	@debug map-has-key($colors, "firebrick"); //DEBUG: false
star

Thu Sep 12 2024 07:08:41 GMT+0000 (Coordinated Universal Time)

@eugene98

star

Thu Sep 12 2024 07:07:11 GMT+0000 (Coordinated Universal Time)

@eugene98

star

Thu Sep 12 2024 07:02:52 GMT+0000 (Coordinated Universal Time)

@eugene98

star

Thu Sep 12 2024 06:26:22 GMT+0000 (Coordinated Universal Time)

@Rohan@99

star

Thu Sep 12 2024 06:03:19 GMT+0000 (Coordinated Universal Time)

@Its_my_prime

star

Thu Sep 12 2024 05:44:34 GMT+0000 (Coordinated Universal Time) https://medium.com/@tempmailwithpassword/finding-the-email-of-the-founder-in-salesforce-when-logging-in-as-a-different-user-bea709883ad2

@WayneChung

star

Thu Sep 12 2024 04:49:09 GMT+0000 (Coordinated Universal Time) https://www.vishyat.com/website-designing-services-in-gurgaon/

@vishyatwebggn11 ##webdesigning ##vishyattechnologies

star

Thu Sep 12 2024 03:28:08 GMT+0000 (Coordinated Universal Time) https://www.programiz.com/cpp-programming/online-compiler/

@LizzyTheCatto

star

Thu Sep 12 2024 00:39:38 GMT+0000 (Coordinated Universal Time) https://docs.theeventscalendar.com/apis/custom-tables/events/

@bounty31 #php

star

Wed Sep 11 2024 23:42:07 GMT+0000 (Coordinated Universal Time)

@WXAPAC

star

Wed Sep 11 2024 20:06:12 GMT+0000 (Coordinated Universal Time)

@cx_21 #javascript

star

Wed Sep 11 2024 19:31:10 GMT+0000 (Coordinated Universal Time) https://www.programiz.com/cpp-programming/online-compiler/

@LizzyTheCatto

star

Wed Sep 11 2024 11:20:55 GMT+0000 (Coordinated Universal Time) https://www.tenforums.com/tutorials/82643-clean-up-component-store-winsxs-folder-windows-10-a.html

@Curable1600 #windows

star

Wed Sep 11 2024 10:04:39 GMT+0000 (Coordinated Universal Time)

@chatgpt #kotlin

star

Wed Sep 11 2024 10:03:42 GMT+0000 (Coordinated Universal Time)

@chatgpt #kotlin

star

Wed Sep 11 2024 09:50:03 GMT+0000 (Coordinated Universal Time)

@signup

star

Wed Sep 11 2024 09:48:53 GMT+0000 (Coordinated Universal Time)

@signup

star

Wed Sep 11 2024 07:01:04 GMT+0000 (Coordinated Universal Time)

@Shira

star

Wed Sep 11 2024 00:18:40 GMT+0000 (Coordinated Universal Time)

@davidmchale #scss #loop #list #fonts

star

Tue Sep 10 2024 21:33:49 GMT+0000 (Coordinated Universal Time)

@cx_21 #javascript

star

Tue Sep 10 2024 20:01:51 GMT+0000 (Coordinated Universal Time)

@ncdiep

star

Tue Sep 10 2024 19:59:46 GMT+0000 (Coordinated Universal Time)

@ncdiep

star

Tue Sep 10 2024 19:59:02 GMT+0000 (Coordinated Universal Time)

@ncdiep

star

Tue Sep 10 2024 19:58:23 GMT+0000 (Coordinated Universal Time)

@ncdiep

star

Tue Sep 10 2024 13:30:15 GMT+0000 (Coordinated Universal Time) https://blockchain.oodles.io/telegram-mini-apps-development/?utm_source=thiscodeworks

@arslansiddiqui

star

Tue Sep 10 2024 12:59:53 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/54087631/paypal-sizeof-parameter-must-be-an-array-or-an-object-that-implements-countab

@zaki

star

Tue Sep 10 2024 11:24:46 GMT+0000 (Coordinated Universal Time) https://magento.stackexchange.com/questions/318291/no-administrators-role-was-found-data-fixture-needs-to-be-run

@zaki

star

Tue Sep 10 2024 10:51:38 GMT+0000 (Coordinated Universal Time) https://nounq.com/seo-services

@deepika

star

Tue Sep 10 2024 10:51:00 GMT+0000 (Coordinated Universal Time)

@Rishi1808

star

Tue Sep 10 2024 10:48:54 GMT+0000 (Coordinated Universal Time)

@StephenThevar

star

Tue Sep 10 2024 09:59:29 GMT+0000 (Coordinated Universal Time)

@Rishi1808

star

Tue Sep 10 2024 08:15:03 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/15718068/search-file-and-find-exact-match-and-print-line

@rhce143 #python

star

Tue Sep 10 2024 06:20:38 GMT+0000 (Coordinated Universal Time)

@Rohan@99

star

Tue Sep 10 2024 05:31:22 GMT+0000 (Coordinated Universal Time)

@Rohan@99

star

Tue Sep 10 2024 04:47:28 GMT+0000 (Coordinated Universal Time)

@Rohan@99

star

Mon Sep 09 2024 20:42:25 GMT+0000 (Coordinated Universal Time)

@bdusenberry

star

Mon Sep 09 2024 19:24:25 GMT+0000 (Coordinated Universal Time) https://forum.moralis.io/t/walletconnect-connection-after-refresh/8815

@JohnPillix

star

Mon Sep 09 2024 11:41:18 GMT+0000 (Coordinated Universal Time)

@nikahafiz #bsg.rise #mysql #sql

star

Mon Sep 09 2024 06:40:18 GMT+0000 (Coordinated Universal Time)

@kcrazy #javascript #googlemaps

star

Mon Sep 09 2024 05:40:46 GMT+0000 (Coordinated Universal Time)

@davidmchale #fetch #endpoint #data #promise.all

star

Mon Sep 09 2024 05:36:26 GMT+0000 (Coordinated Universal Time)

@davidmchale #fetch #endpoint #data

star

Mon Sep 09 2024 05:15:26 GMT+0000 (Coordinated Universal Time)

@signup

star

Mon Sep 09 2024 04:47:49 GMT+0000 (Coordinated Universal Time)

@kcrazy #javascript #googlemaps

star

Sun Sep 08 2024 23:26:47 GMT+0000 (Coordinated Universal Time)

@imdesignsllc #css

star

Sun Sep 08 2024 22:48:40 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Sun Sep 08 2024 19:46:41 GMT+0000 (Coordinated Universal Time)

@Sayed

star

Sun Sep 08 2024 12:47:24 GMT+0000 (Coordinated Universal Time)

@codestored #cpp

star

Sun Sep 08 2024 05:32:38 GMT+0000 (Coordinated Universal Time)

@davidmchale #css #map-get #maps #object #loop

star

Sun Sep 08 2024 04:46:36 GMT+0000 (Coordinated Universal Time)

@davidmchale #css #map-get #maps #object #loop #conditionals

star

Sun Sep 08 2024 01:00:06 GMT+0000 (Coordinated Universal Time)

@davidmchale #css #map-get #maps #object

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension