//This file has been generated by AdvancedSkeletonSelector//
//Using AdvancedSkeleton Version: 6.065//

global proc asSelectorface ()
{
if (`window -q -ex asSelectorface`)
	{
	asPopulateNameSpaceMenu asSelectorface;
	asShowSelJob;
	asSelChange;
	showWindow asSelectorface;
	return;
	}

string $asSelectorScriptLocation=`asSelectorScriptLocation`;
string $asIconLocation=$asSelectorScriptLocation+"face/";
window -rtf 1 -mb 1 -t face asSelectorface;
asSetFilterUpdateWindowTitle asSelectorface;
menu -l File;
	menuItem -l "Create Reference.." -c "asReferenceBrowser 0";
	menuItem -l "Reference Editor" -c "asReferenceEditor";
	menuItem -l "Replace" -sm 1 -postMenuCommand "asPopulateReplaceMenu asSelectorface" asSelectorfaceFileReplaceMenuItem;
		setParent -menu ..;
	menuItem -d 1;
	menuItem -l "Export Fbx.." -c "asExportFbxBrowser asSelectorface";
	setParent..;
menu -l Edit;
	menuItem -l Refresh -c "asPopulateNameSpaceMenu asSelectorface";
	menuItem -l Filter -c "asFilterNameSpaceMenuUI asSelectorface";
	setParent..;
menu -l Display;
	menuItem -l Controls -c asControlsVisibilityToggle;
	menuItem -l "Set HotKey" -c "asSetupControlVisibilityHotKeyDialog";
	menuItem -d 1;
	menuItem -l "GimbalLock" -c "asVisualizeGimbalLock asSelectorface";
	menuItem -d 1;
	menuItem -l "FaceCtrls detach" -c "asFaceCtrlsDetach asSelectorface";
	setParent..;
menu -l Pose -aob 1;
	menuItem -l Copy -c "asCopyToClipBoard asSelectorface 0";
	menuItem -l Paste -c "asPasteFromClipBoard asSelectorface 0";
	menuItem -d 1;
	menuItem -l Reset -c "asGoToBuildPose asSelectorface";
	menuItem -l Tpose -c "asGoToTPose asSelectorbiped";
	menuItem -d 1;
	menuItem -l Mirror -c "asMirror asSelectorface";
	menuItem -optionBox 1 -c "asMirrorOptions asSelectorface";
	menuItem -d 1;
	setParent..;
menu -l Anim;
	menuItem -l Copy -c "asCopyToClipBoard asSelectorface 1";
	menuItem -l Paste -c "asPasteFromClipBoard asSelectorface 1";
	menuItem -d 1;
	menuItem -l Clean -c "asDeleteStaticChannels asSelectorface";
	menuItem -d 1;
	menuItem -l Bake -c "asAnimBake asSelectorface";
	menuItem -d 1;
	menuItem -l SwitchFKIK -c asAutoSwitchFKIK;
	menuItem -l SwitchPivot -c asAutoSwitchPivot;
	menuItem -d 1;
	menuItem -l PivotControl -c asPivotControl;
	menuItem -d 1;
	menuItem -l QuickIK -c asQuickIK;
	menuItem -d 1;
	menuItem -l HumanIK -c "asHumanIKUI asSelectorbiped";
	menuItem -d 1;
	menuItem -l MoCapMatcher -c "asMoCapMatcherUI asSelectorface";
	menuItem -l MoCapLibrary -c "asMoCapLibraryUI asSelectorface";
	menuItem -d 1;
	menuItem -l "Connect ARKit" -c "asConnectARKitUI asSelectorface";
	menuItem -l "Connect MocapX" -c "asConnectMocapX asSelectorface";
	menuItem -l "MetaHumanAnimator" -c "asMetaHumanAnimatorUI asSelectorface";
	menuItem -d 1;
	menuItem -l "VideoMoCap" -c "asVideoMoCapUI asSelectorface";
	menuItem -d 1;
	menuItem -l "Auto lipsync" -c "asAutoLipSyncUI asSelectorface";
	menuItem -l "Audio2Face" -c "asAudio2FaceUI asSelectorface";
	menuItem -d 1;
	menuItem -l "Deformable" -c "asDeformableUI asSelectorface";
	menuItem -l "TimeEcho" -c "asTimeEchoUI asSelectorface";
menu -l Dynamics;
	menuItem -l "Add Controller-Dynamics" -c "asCtrlDynAdd asSelectorbiped";
	menuItem -l "Add JointChain-Dynamics" -c "asDynAdd asSelectorbiped";
	menuItem -l "Add JointChain-Dynamics (HairSystem)" -c "asDynAddHairSystem asSelectorbiped";
	menuItem -l "Remove from selected" -c "asDynRemove asSelectorbiped";
	menuItem -d 1;
	menuItem -l "Set Initial State" -c "asDynSetInitialState asSelectorface";
	menuItem -l "Interactive Playback" -c "asDynSetInteractivePlayback asSelectorface";
	menuItem -d 1;
	menuItem -l Bake -c "asDynBake asSelectorface";
menu -l Parent;
	menuItem -l "Add parent constraint" -c "asParentAdd asSelectorface 0";
	menuItem -l "Add parent constraint (Extra)" -c "asParentAdd asSelectorface 1";

columnLayout -adj 1;
text -m 0 -l "FaceControlSet " asSelectorfaceControlSetsText;
rowLayout -nc 5 -adj 1 -cat 1 right 0 -cw 2 30 -cw 3 65 -cw 4 50 -cw 5 60;
optionMenu -cc "asNameSpaceChange asSelectorface" asSelectorfaceOptionMenu;
button -l set -c "asSetNameSpaceFromSelection asSelectorface";
checkBox -v `optionVar -q asShowSelection` -cc "optionVar -iv asShowSelection #1;asSelChangeToggle;" -l Selection asSelectorfaceSelectionCheckBox;
checkBox -v `optionVar -q asShowKeyed` -cc "optionVar -iv asShowKeyed #1;asSelChangeToggle;" -l Keyed asSelectorfaceKeyedCheckBox;
checkBox -v `optionVar -q asShowExtra` -cc "optionVar -iv asShowExtra #1;asSelChangeToggle;" -l Extra asSelectorfaceExtraCheckBox;
setParent..;
formLayout asSelectorfaceFormLayout;

//Controls Begin//
//image -en 0 -w 640 -h 480 -i ($asIconLocation+"face_background.png") "asSelectorfaceBGPicture";
iconTextButton -w 86 -h 11 -olc 0 1 0 -c "asSelect \"face\" {\"Jaw_M\"};" -bgc 0 1 0 -ann "Jaw_M" "Jaw_M:116:225";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Jaw_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Jaw_M\"};";
iconTextButton -w 28 -h 7 -olc 0 1 0 -c "asSelect \"face\" {\"upperTeeth_M\"};" -bgc 0 1 0 -ann "upperTeeth_M" "upperTeeth_M:236:170";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperTeeth_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperTeeth_M\"};";
iconTextButton -w 28 -h 7 -olc 0 1 0 -c "asSelect \"face\" {\"lowerTeeth_M\"};" -bgc 0 1 0 -ann "lowerTeeth_M" "lowerTeeth_M:236:188";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerTeeth_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerTeeth_M\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlBrow_R\"};" -bgc 1 1 0 -ann "ctrlBrow_R" "ctrlBrow_R:268:15";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlBrow_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlBrow_R\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlBrow_L\"};" -bgc 1 1 0 -ann "ctrlBrow_L" "ctrlBrow_L:298:15";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlBrow_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlBrow_L\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlEye_R\"};" -bgc 1 1 0 -ann "ctrlEye_R" "ctrlEye_R:268:49";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlEye_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlEye_R\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlEye_L\"};" -bgc 1 1 0 -ann "ctrlEye_L" "ctrlEye_L:298:49";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlEye_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlEye_L\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlCheek_R\"};" -bgc 1 1 0 -ann "ctrlCheek_R" "ctrlCheek_R:268:85";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlCheek_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlCheek_R\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlCheek_L\"};" -bgc 1 1 0 -ann "ctrlCheek_L" "ctrlCheek_L:298:85";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlCheek_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlCheek_L\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlNose_R\"};" -bgc 1 1 0 -ann "ctrlNose_R" "ctrlNose_R:268:121";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlNose_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlNose_R\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlNose_L\"};" -bgc 1 1 0 -ann "ctrlNose_L" "ctrlNose_L:298:121";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlNose_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlNose_L\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlLips_M\"};" -bgc 1 1 0 -ann "ctrlLips_M" "ctrlLips_M:284:153";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlLips_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlLips_M\"};";
iconTextButton -w 18 -h 10 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlMouth_M\"};" -bgc 1 1 0 -ann "ctrlMouth_M" "ctrlMouth_M:284:183";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlMouth_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlMouth_M\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlMouthCorner_R\"};" -bgc 1 1 0 -ann "ctrlMouthCorner_R" "ctrlMouthCorner_R:268:203";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlMouthCorner_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlMouthCorner_R\"};";
iconTextButton -w 18 -h 18 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlMouthCorner_L\"};" -bgc 1 1 0 -ann "ctrlMouthCorner_L" "ctrlMouthCorner_L:298:203";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlMouthCorner_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlMouthCorner_L\"};";
iconTextButton -w 61 -h 4 -olc 1 1 0 -c "asSelect \"face\" {\"ctrlBox\"};" -bgc 1 1 0 -ann "ctrlBox" "ctrlBox:260:8";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ctrlBox\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ctrlBox\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowInner_R\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowInner_R" "EyeBrowInner_R:140:31";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowInner_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowInner_R\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowMid1_R\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowMid1_R" "EyeBrowMid1_R:128:29";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowMid1_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowMid1_R\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowMid2_R\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowMid2_R" "EyeBrowMid2_R:115:30";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowMid2_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowMid2_R\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowMid3_R\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowMid3_R" "EyeBrowMid3_R:102:34";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowMid3_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowMid3_R\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowOuter_R\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowOuter_R" "EyeBrowOuter_R:89:43";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowOuter_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowOuter_R\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowCenter_M\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowCenter_M" "EyeBrowCenter_M:154:38";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowCenter_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowCenter_M\"};";
iconTextButton -w 6 -h 9 -olc 0 1 0 -c "asSelect \"face\" {\"innerLid_R\"};" -bgc 0 1 0 -ann "innerLid_R" "innerLid_R:150:79";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"innerLid_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"innerLid_R\"};";
iconTextButton -w 6 -h 9 -olc 0 1 0 -c "asSelect \"face\" {\"outerLid_R\"};" -bgc 0 1 0 -ann "outerLid_R" "outerLid_R:91:79";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"outerLid_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"outerLid_R\"};";
iconTextButton -w 11 -h 6 -olc 0 1 0 -c "asSelect \"face\" {\"upperLid_R\"};" -bgc 0 1 0 -ann "upperLid_R" "upperLid_R:118:66";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid_R\"};";
iconTextButton -w 11 -h 6 -olc 0 1 0 -c "asSelect \"face\" {\"lowerLid_R\"};" -bgc 0 1 0 -ann "lowerLid_R" "lowerLid_R:118:95";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid1_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLid1_R" "upperLid1_R:141:73";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid1_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid1_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid2_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLid2_R" "upperLid2_R:133:67";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid2_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid2_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid3_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLid3_R" "upperLid3_R:109:67";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid3_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid3_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid4_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLid4_R" "upperLid4_R:99:73";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid4_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid4_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid1_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid1_R" "lowerLid1_R:141:87";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid1_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid1_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid2_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid2_R" "lowerLid2_R:133:91";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid2_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid2_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid3_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid3_R" "lowerLid3_R:109:91";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid3_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid3_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid4_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid4_R" "lowerLid4_R:99:87";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid4_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid4_R\"};";
iconTextButton -w 16 -h 4 -olc 0.189 0.63 0.365 -c "asSelect \"face\" {\"lowerLidOuter_R\"};" -bgc 0.189 0.63 0.365 -ann "lowerLidOuter_R" "lowerLidOuter_R:115:103";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLidOuter_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLidOuter_R\"};";
iconTextButton -w 11 -h 11 -olc 0 0 1 -c "asSelect \"face\" {\"CheekBone_R\"};" -bgc 0 0 1 -ann "CheekBone_R" "CheekBone_R:93:124";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"CheekBone_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"CheekBone_R\"};";
iconTextButton -w 11 -h 11 -olc 0 0 1 -c "asSelect \"face\" {\"Cheek_R\"};" -bgc 0 0 1 -ann "Cheek_R" "Cheek_R:86:176";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Cheek_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Cheek_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"NoseCorner_R\"};" -bgc 0 0 1 -ann "NoseCorner_R" "NoseCorner_R:139:136";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseCorner_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseCorner_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"Nostril_R\"};" -bgc 0 0 1 -ann "Nostril_R" "Nostril_R:147:136";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Nostril_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Nostril_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"Nose_M\"};" -bgc 0 0 1 -ann "Nose_M" "Nose_M:156:136";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Nose_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Nose_M\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"NoseSide_R\"};" -bgc 0 0 1 -ann "NoseSide_R" "NoseSide_R:146:119";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseSide_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseSide_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"NoseCrease_M\"};" -bgc 0 0 1 -ann "NoseCrease_M" "NoseCrease_M:156:94";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseCrease_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseCrease_M\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"NoseBridge_M\"};" -bgc 0 0 1 -ann "NoseBridge_M" "NoseBridge_M:156:117";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseBridge_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseBridge_M\"};";
iconTextButton -w 19 -h 4 -olc 0 0 1 -c "asSelect \"face\" {\"NoseUnder_M\"};" -bgc 0 0 1 -ann "NoseUnder_M" "NoseUnder_M:151:147";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseUnder_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseUnder_M\"};";
iconTextButton -w 6 -h 9 -olc 0 1 0 -c "asSelect \"face\" {\"Lip_R\"};" -bgc 0 1 0 -ann "Lip_R" "Lip_R:116:178";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Lip_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Lip_R\"};";
iconTextButton -w 11 -h 6 -olc 0 1 0 -c "asSelect \"face\" {\"upperLip_M\"};" -bgc 0 1 0 -ann "upperLip_M" "upperLip_M:154:167";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLip_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLip_M\"};";
iconTextButton -w 11 -h 6 -olc 0 1 0 -c "asSelect \"face\" {\"lowerLip_M\"};" -bgc 0 1 0 -ann "lowerLip_M" "lowerLip_M:154:199";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLip_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLip_M\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLipA_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLipA_R" "upperLipA_R:156:175";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLipA_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLipA_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLipB_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLipB_R" "upperLipB_R:144:175";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLipB_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLipB_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLipC_R\"};" -bgc 0.683 0.107 0.148 -ann "upperLipC_R" "upperLipC_R:133:176";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLipC_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLipC_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"cornerLip_R\"};" -bgc 0.683 0.107 0.148 -ann "cornerLip_R" "cornerLip_R:124:180";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"cornerLip_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"cornerLip_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLipA_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLipA_R" "lowerLipA_R:156:189";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLipA_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLipA_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLipB_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLipB_R" "lowerLipB_R:144:187";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLipB_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLipB_R\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLipC_R\"};" -bgc 0.683 0.107 0.148 -ann "lowerLipC_R" "lowerLipC_R:133:186";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLipC_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLipC_R\"};";
iconTextButton -w 3 -h 16 -olc 1 1 0 -c "asSelect \"face\" {\"SmilePull_R\"};" -bgc 1 1 0 -ann "SmilePull_R" "SmilePull_R:110:175";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"SmilePull_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"SmilePull_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"SmileBulge_R\"};" -bgc 0 0 1 -ann "SmileBulge_R" "SmileBulge_R:111:159";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"SmileBulge_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"SmileBulge_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"FrownBulge_R\"};" -bgc 0 0 1 -ann "FrownBulge_R" "FrownBulge_R:111:200";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"FrownBulge_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"FrownBulge_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"ChinCrease_M\"};" -bgc 0 0 1 -ann "ChinCrease_M" "ChinCrease_M:156:209";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"ChinCrease_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"ChinCrease_M\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"upperLip_R\"};" -bgc 0 0 1 -ann "upperLip_R" "upperLip_R:137:165";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLip_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLip_R\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"lowerLip_R\"};" -bgc 0 0 1 -ann "lowerLip_R" "lowerLip_R:137:197";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLip_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLip_R\"};";
iconTextButton -w 40 -h 9 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"squashMiddle_M\"};" -bgc 0.683 0.107 0.148 -ann "squashMiddle_M" "squashMiddle_M:7:27";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"squashMiddle_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"squashMiddle_M\"};";
iconTextButton -w 9 -h 63 -olc 1 1 0 -c "asSelect \"face\" {\"AimEye_M\"};" -bgc 1 1 0 -ann "AimEye_M" "AimEye_M:23:92";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"AimEye_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"AimEye_M\"};";
iconTextButton -w 19 -h 11 -olc 0 1 0 -c "asSelect \"face\" {\"EyeRegion_R\"};" -bgc 0 1 0 -ann "EyeRegion_R" "EyeRegion_R:56:78";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeRegion_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeRegion_R\"};";
iconTextButton -w 40 -h 9 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"squashBase_M\"};" -bgc 0.683 0.107 0.148 -ann "squashBase_M" "squashBase_M:7:43";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"squashBase_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"squashBase_M\"};";
iconTextButton -w 19 -h 11 -olc 0 1 0 -c "asSelect \"face\" {\"EyeBrowRegion_R\"};" -bgc 0 1 0 -ann "EyeBrowRegion_R" "EyeBrowRegion_R:56:45";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowRegion_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowRegion_R\"};";
iconTextButton -w 37 -h 29 -style textOnly -l All -olc 0 0.275 0.098 -c "asSelect \"face\" {\"FaceControlSet\"};" -bgc 0 0.275 0.098 -ann "FaceControlSet" "FaceControlSet:55:5";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"FaceControlSet\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"FaceControlSet\"};";
iconTextButton -w 27 -h 6 -olc 1 1 0 -c "asSelect \"face\" {\"upperFace_M\"};" -bgc 1 1 0 -ann "upperFace_M" "upperFace_M:49:124";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperFace_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperFace_M\"};";
iconTextButton -w 18 -h 7 -olc 1 1 0 -c "asSelect \"face\" {\"AimEye_L\"};" -bgc 1 1 0 -ann "AimEye_L" "AimEye_L:35:105";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"AimEye_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"AimEye_L\"};";
iconTextButton -w 18 -h 7 -olc 1 1 0 -c "asSelect \"face\" {\"AimEye_R\"};" -bgc 1 1 0 -ann "AimEye_R" "AimEye_R:2:105";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"AimEye_R\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"AimEye_R\"};";
iconTextButton -w 42 -h 8 -olc 0 0 1 -c "asSelect \"face\" {\"Tongue1_M\"};" -bgc 0 0 1 -ann "Tongue1_M" "Tongue1_M:7:191";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Tongue1_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Tongue1_M\"};";
iconTextButton -w 42 -h 8 -olc 0 0 1 -c "asSelect \"face\" {\"Tongue0_M\"};" -bgc 0 0 1 -ann "Tongue0_M" "Tongue0_M:7:171";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Tongue0_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Tongue0_M\"};";
iconTextButton -w 19 -h 11 -olc 0 1 0 -c "asSelect \"face\" {\"LipRegion_M\"};" -bgc 0 1 0 -ann "LipRegion_M" "LipRegion_M:54:178";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"LipRegion_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"LipRegion_M\"};";
iconTextButton -w 42 -h 8 -olc 0 0 1 -c "asSelect \"face\" {\"Tongue2_M\"};" -bgc 0 0 1 -ann "Tongue2_M" "Tongue2_M:7:210";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Tongue2_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Tongue2_M\"};";
iconTextButton -w 27 -h 6 -olc 1 1 0 -c "asSelect \"face\" {\"lowerFace_M\"};" -bgc 1 1 0 -ann "lowerFace_M" "lowerFace_M:49:149";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerFace_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerFace_M\"};";
iconTextButton -w 27 -h 6 -olc 1 1 0 -c "asSelect \"face\" {\"middleFace_M\"};" -bgc 1 1 0 -ann "middleFace_M" "middleFace_M:49:136";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"middleFace_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"middleFace_M\"};";
iconTextButton -w 42 -h 8 -olc 0 0 1 -c "asSelect \"face\" {\"Tongue3_M\"};" -bgc 0 0 1 -ann "Tongue3_M" "Tongue3_M:7:229";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Tongue3_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Tongue3_M\"};";
iconTextButton -w 40 -h 9 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"squashTop_M\"};" -bgc 0.683 0.107 0.148 -ann "squashTop_M" "squashTop_M:7:11";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"squashTop_M\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"squashTop_M\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowInner_L\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowInner_L" "EyeBrowInner_L:170:31";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowInner_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowInner_L\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowMid1_L\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowMid1_L" "EyeBrowMid1_L:182:29";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowMid1_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowMid1_L\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowMid2_L\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowMid2_L" "EyeBrowMid2_L:195:30";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowMid2_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowMid2_L\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowMid3_L\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowMid3_L" "EyeBrowMid3_L:208:34";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowMid3_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowMid3_L\"};";
iconTextButton -w 10 -h 10 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"EyeBrowOuter_L\"};" -bgc 0.683 0.107 0.148 -ann "EyeBrowOuter_L" "EyeBrowOuter_L:221:43";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowOuter_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowOuter_L\"};";
iconTextButton -w 6 -h 9 -olc 0 1 0 -c "asSelect \"face\" {\"innerLid_L\"};" -bgc 0 1 0 -ann "innerLid_L" "innerLid_L:164:79";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"innerLid_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"innerLid_L\"};";
iconTextButton -w 6 -h 9 -olc 0 1 0 -c "asSelect \"face\" {\"outerLid_L\"};" -bgc 0 1 0 -ann "outerLid_L" "outerLid_L:223:79";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"outerLid_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"outerLid_L\"};";
iconTextButton -w 11 -h 6 -olc 0 1 0 -c "asSelect \"face\" {\"upperLid_L\"};" -bgc 0 1 0 -ann "upperLid_L" "upperLid_L:191:66";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid_L\"};";
iconTextButton -w 11 -h 6 -olc 0 1 0 -c "asSelect \"face\" {\"lowerLid_L\"};" -bgc 0 1 0 -ann "lowerLid_L" "lowerLid_L:191:95";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid1_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLid1_L" "upperLid1_L:172:73";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid1_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid1_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid2_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLid2_L" "upperLid2_L:180:67";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid2_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid2_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid3_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLid3_L" "upperLid3_L:204:67";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid3_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid3_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLid4_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLid4_L" "upperLid4_L:214:73";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLid4_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLid4_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid1_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid1_L" "lowerLid1_L:172:87";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid1_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid1_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid2_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid2_L" "lowerLid2_L:180:91";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid2_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid2_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid3_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid3_L" "lowerLid3_L:204:91";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid3_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid3_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLid4_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLid4_L" "lowerLid4_L:214:87";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLid4_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLid4_L\"};";
iconTextButton -w 16 -h 4 -olc 0.189 0.63 0.365 -c "asSelect \"face\" {\"lowerLidOuter_L\"};" -bgc 0.189 0.63 0.365 -ann "lowerLidOuter_L" "lowerLidOuter_L:189:103";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLidOuter_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLidOuter_L\"};";
iconTextButton -w 11 -h 11 -olc 0 0 1 -c "asSelect \"face\" {\"CheekBone_L\"};" -bgc 0 0 1 -ann "CheekBone_L" "CheekBone_L:216:124";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"CheekBone_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"CheekBone_L\"};";
iconTextButton -w 11 -h 11 -olc 0 0 1 -c "asSelect \"face\" {\"Cheek_L\"};" -bgc 0 0 1 -ann "Cheek_L" "Cheek_L:223:176";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Cheek_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Cheek_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"NoseCorner_L\"};" -bgc 0 0 1 -ann "NoseCorner_L" "NoseCorner_L:174:136";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseCorner_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseCorner_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"Nostril_L\"};" -bgc 0 0 1 -ann "Nostril_L" "Nostril_L:166:136";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Nostril_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Nostril_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"NoseSide_L\"};" -bgc 0 0 1 -ann "NoseSide_L" "NoseSide_L:167:119";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"NoseSide_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"NoseSide_L\"};";
iconTextButton -w 6 -h 9 -olc 0 1 0 -c "asSelect \"face\" {\"Lip_L\"};" -bgc 0 1 0 -ann "Lip_L" "Lip_L:198:178";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"Lip_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"Lip_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLipA_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLipA_L" "upperLipA_L:157:175";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLipA_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLipA_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLipB_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLipB_L" "upperLipB_L:169:175";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLipB_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLipB_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"upperLipC_L\"};" -bgc 0.683 0.107 0.148 -ann "upperLipC_L" "upperLipC_L:180:176";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLipC_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLipC_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"cornerLip_L\"};" -bgc 0.683 0.107 0.148 -ann "cornerLip_L" "cornerLip_L:189:180";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"cornerLip_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"cornerLip_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLipA_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLipA_L" "lowerLipA_L:157:189";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLipA_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLipA_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLipB_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLipB_L" "lowerLipB_L:169:187";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLipB_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLipB_L\"};";
iconTextButton -w 7 -h 7 -olc 0.683 0.107 0.148 -c "asSelect \"face\" {\"lowerLipC_L\"};" -bgc 0.683 0.107 0.148 -ann "lowerLipC_L" "lowerLipC_L:180:186";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLipC_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLipC_L\"};";
iconTextButton -w 3 -h 16 -olc 1 1 0 -c "asSelect \"face\" {\"SmilePull_L\"};" -bgc 1 1 0 -ann "SmilePull_L" "SmilePull_L:207:175";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"SmilePull_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"SmilePull_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"SmileBulge_L\"};" -bgc 0 0 1 -ann "SmileBulge_L" "SmileBulge_L:202:159";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"SmileBulge_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"SmileBulge_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"FrownBulge_L\"};" -bgc 0 0 1 -ann "FrownBulge_L" "FrownBulge_L:202:200";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"FrownBulge_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"FrownBulge_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"upperLip_L\"};" -bgc 0 0 1 -ann "upperLip_L" "upperLip_L:176:165";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"upperLip_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"upperLip_L\"};";
iconTextButton -w 7 -h 7 -olc 0 0 1 -c "asSelect \"face\" {\"lowerLip_L\"};" -bgc 0 0 1 -ann "lowerLip_L" "lowerLip_L:176:197";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"lowerLip_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"lowerLip_L\"};";
iconTextButton -w 19 -h 11 -olc 0 1 0 -c "asSelect \"face\" {\"EyeRegion_L\"};" -bgc 0 1 0 -ann "EyeRegion_L" "EyeRegion_L:245:78";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeRegion_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeRegion_L\"};";
iconTextButton -w 19 -h 11 -olc 0 1 0 -c "asSelect \"face\" {\"EyeBrowRegion_L\"};" -bgc 0 1 0 -ann "EyeBrowRegion_L" "EyeBrowRegion_L:245:45";
popupMenu;
	menuItem -l Key -c "asKey \"face\" {\"EyeBrowRegion_L\"};";
	menuItem -l LinearKey -c "asLinearKey \"face\" {\"EyeBrowRegion_L\"};";
//Controls End//

formLayout -e
	-af "Jaw_M:116:225" left 116
	-af "Jaw_M:116:225" top 225
	-af "upperTeeth_M:236:170" left 236
	-af "upperTeeth_M:236:170" top 170
	-af "lowerTeeth_M:236:188" left 236
	-af "lowerTeeth_M:236:188" top 188
	-af "ctrlBrow_R:268:15" left 268
	-af "ctrlBrow_R:268:15" top 15
	-af "ctrlBrow_L:298:15" left 298
	-af "ctrlBrow_L:298:15" top 15
	-af "ctrlEye_R:268:49" left 268
	-af "ctrlEye_R:268:49" top 49
	-af "ctrlEye_L:298:49" left 298
	-af "ctrlEye_L:298:49" top 49
	-af "ctrlCheek_R:268:85" left 268
	-af "ctrlCheek_R:268:85" top 85
	-af "ctrlCheek_L:298:85" left 298
	-af "ctrlCheek_L:298:85" top 85
	-af "ctrlNose_R:268:121" left 268
	-af "ctrlNose_R:268:121" top 121
	-af "ctrlNose_L:298:121" left 298
	-af "ctrlNose_L:298:121" top 121
	-af "ctrlLips_M:284:153" left 284
	-af "ctrlLips_M:284:153" top 153
	-af "ctrlMouth_M:284:183" left 284
	-af "ctrlMouth_M:284:183" top 183
	-af "ctrlMouthCorner_R:268:203" left 268
	-af "ctrlMouthCorner_R:268:203" top 203
	-af "ctrlMouthCorner_L:298:203" left 298
	-af "ctrlMouthCorner_L:298:203" top 203
	-af "ctrlBox:260:8" left 260
	-af "ctrlBox:260:8" top 8
	-af "EyeBrowInner_R:140:31" left 140
	-af "EyeBrowInner_R:140:31" top 31
	-af "EyeBrowMid1_R:128:29" left 128
	-af "EyeBrowMid1_R:128:29" top 29
	-af "EyeBrowMid2_R:115:30" left 115
	-af "EyeBrowMid2_R:115:30" top 30
	-af "EyeBrowMid3_R:102:34" left 102
	-af "EyeBrowMid3_R:102:34" top 34
	-af "EyeBrowOuter_R:89:43" left 89
	-af "EyeBrowOuter_R:89:43" top 43
	-af "EyeBrowCenter_M:154:38" left 154
	-af "EyeBrowCenter_M:154:38" top 38
	-af "innerLid_R:150:79" left 150
	-af "innerLid_R:150:79" top 79
	-af "outerLid_R:91:79" left 91
	-af "outerLid_R:91:79" top 79
	-af "upperLid_R:118:66" left 118
	-af "upperLid_R:118:66" top 66
	-af "lowerLid_R:118:95" left 118
	-af "lowerLid_R:118:95" top 95
	-af "upperLid1_R:141:73" left 141
	-af "upperLid1_R:141:73" top 73
	-af "upperLid2_R:133:67" left 133
	-af "upperLid2_R:133:67" top 67
	-af "upperLid3_R:109:67" left 109
	-af "upperLid3_R:109:67" top 67
	-af "upperLid4_R:99:73" left 99
	-af "upperLid4_R:99:73" top 73
	-af "lowerLid1_R:141:87" left 141
	-af "lowerLid1_R:141:87" top 87
	-af "lowerLid2_R:133:91" left 133
	-af "lowerLid2_R:133:91" top 91
	-af "lowerLid3_R:109:91" left 109
	-af "lowerLid3_R:109:91" top 91
	-af "lowerLid4_R:99:87" left 99
	-af "lowerLid4_R:99:87" top 87
	-af "lowerLidOuter_R:115:103" left 115
	-af "lowerLidOuter_R:115:103" top 103
	-af "CheekBone_R:93:124" left 93
	-af "CheekBone_R:93:124" top 124
	-af "Cheek_R:86:176" left 86
	-af "Cheek_R:86:176" top 176
	-af "NoseCorner_R:139:136" left 139
	-af "NoseCorner_R:139:136" top 136
	-af "Nostril_R:147:136" left 147
	-af "Nostril_R:147:136" top 136
	-af "Nose_M:156:136" left 156
	-af "Nose_M:156:136" top 136
	-af "NoseSide_R:146:119" left 146
	-af "NoseSide_R:146:119" top 119
	-af "NoseCrease_M:156:94" left 156
	-af "NoseCrease_M:156:94" top 94
	-af "NoseBridge_M:156:117" left 156
	-af "NoseBridge_M:156:117" top 117
	-af "NoseUnder_M:151:147" left 151
	-af "NoseUnder_M:151:147" top 147
	-af "Lip_R:116:178" left 116
	-af "Lip_R:116:178" top 178
	-af "upperLip_M:154:167" left 154
	-af "upperLip_M:154:167" top 167
	-af "lowerLip_M:154:199" left 154
	-af "lowerLip_M:154:199" top 199
	-af "upperLipA_R:156:175" left 156
	-af "upperLipA_R:156:175" top 175
	-af "upperLipB_R:144:175" left 144
	-af "upperLipB_R:144:175" top 175
	-af "upperLipC_R:133:176" left 133
	-af "upperLipC_R:133:176" top 176
	-af "cornerLip_R:124:180" left 124
	-af "cornerLip_R:124:180" top 180
	-af "lowerLipA_R:156:189" left 156
	-af "lowerLipA_R:156:189" top 189
	-af "lowerLipB_R:144:187" left 144
	-af "lowerLipB_R:144:187" top 187
	-af "lowerLipC_R:133:186" left 133
	-af "lowerLipC_R:133:186" top 186
	-af "SmilePull_R:110:175" left 110
	-af "SmilePull_R:110:175" top 175
	-af "SmileBulge_R:111:159" left 111
	-af "SmileBulge_R:111:159" top 159
	-af "FrownBulge_R:111:200" left 111
	-af "FrownBulge_R:111:200" top 200
	-af "ChinCrease_M:156:209" left 156
	-af "ChinCrease_M:156:209" top 209
	-af "upperLip_R:137:165" left 137
	-af "upperLip_R:137:165" top 165
	-af "lowerLip_R:137:197" left 137
	-af "lowerLip_R:137:197" top 197
	-af "squashMiddle_M:7:27" left 7
	-af "squashMiddle_M:7:27" top 27
	-af "AimEye_M:23:92" left 23
	-af "AimEye_M:23:92" top 92
	-af "EyeRegion_R:56:78" left 56
	-af "EyeRegion_R:56:78" top 78
	-af "squashBase_M:7:43" left 7
	-af "squashBase_M:7:43" top 43
	-af "EyeBrowRegion_R:56:45" left 56
	-af "EyeBrowRegion_R:56:45" top 45
	-af "FaceControlSet:55:5" left 55
	-af "FaceControlSet:55:5" top 5
	-af "upperFace_M:49:124" left 49
	-af "upperFace_M:49:124" top 124
	-af "AimEye_L:35:105" left 35
	-af "AimEye_L:35:105" top 105
	-af "AimEye_R:2:105" left 2
	-af "AimEye_R:2:105" top 105
	-af "Tongue1_M:7:191" left 7
	-af "Tongue1_M:7:191" top 191
	-af "Tongue0_M:7:171" left 7
	-af "Tongue0_M:7:171" top 171
	-af "LipRegion_M:54:178" left 54
	-af "LipRegion_M:54:178" top 178
	-af "Tongue2_M:7:210" left 7
	-af "Tongue2_M:7:210" top 210
	-af "lowerFace_M:49:149" left 49
	-af "lowerFace_M:49:149" top 149
	-af "middleFace_M:49:136" left 49
	-af "middleFace_M:49:136" top 136
	-af "Tongue3_M:7:229" left 7
	-af "Tongue3_M:7:229" top 229
	-af "squashTop_M:7:11" left 7
	-af "squashTop_M:7:11" top 11
	-af "EyeBrowInner_L:170:31" left 170
	-af "EyeBrowInner_L:170:31" top 31
	-af "EyeBrowMid1_L:182:29" left 182
	-af "EyeBrowMid1_L:182:29" top 29
	-af "EyeBrowMid2_L:195:30" left 195
	-af "EyeBrowMid2_L:195:30" top 30
	-af "EyeBrowMid3_L:208:34" left 208
	-af "EyeBrowMid3_L:208:34" top 34
	-af "EyeBrowOuter_L:221:43" left 221
	-af "EyeBrowOuter_L:221:43" top 43
	-af "innerLid_L:164:79" left 164
	-af "innerLid_L:164:79" top 79
	-af "outerLid_L:223:79" left 223
	-af "outerLid_L:223:79" top 79
	-af "upperLid_L:191:66" left 191
	-af "upperLid_L:191:66" top 66
	-af "lowerLid_L:191:95" left 191
	-af "lowerLid_L:191:95" top 95
	-af "upperLid1_L:172:73" left 172
	-af "upperLid1_L:172:73" top 73
	-af "upperLid2_L:180:67" left 180
	-af "upperLid2_L:180:67" top 67
	-af "upperLid3_L:204:67" left 204
	-af "upperLid3_L:204:67" top 67
	-af "upperLid4_L:214:73" left 214
	-af "upperLid4_L:214:73" top 73
	-af "lowerLid1_L:172:87" left 172
	-af "lowerLid1_L:172:87" top 87
	-af "lowerLid2_L:180:91" left 180
	-af "lowerLid2_L:180:91" top 91
	-af "lowerLid3_L:204:91" left 204
	-af "lowerLid3_L:204:91" top 91
	-af "lowerLid4_L:214:87" left 214
	-af "lowerLid4_L:214:87" top 87
	-af "lowerLidOuter_L:189:103" left 189
	-af "lowerLidOuter_L:189:103" top 103
	-af "CheekBone_L:216:124" left 216
	-af "CheekBone_L:216:124" top 124
	-af "Cheek_L:223:176" left 223
	-af "Cheek_L:223:176" top 176
	-af "NoseCorner_L:174:136" left 174
	-af "NoseCorner_L:174:136" top 136
	-af "Nostril_L:166:136" left 166
	-af "Nostril_L:166:136" top 136
	-af "NoseSide_L:167:119" left 167
	-af "NoseSide_L:167:119" top 119
	-af "Lip_L:198:178" left 198
	-af "Lip_L:198:178" top 178
	-af "upperLipA_L:157:175" left 157
	-af "upperLipA_L:157:175" top 175
	-af "upperLipB_L:169:175" left 169
	-af "upperLipB_L:169:175" top 175
	-af "upperLipC_L:180:176" left 180
	-af "upperLipC_L:180:176" top 176
	-af "cornerLip_L:189:180" left 189
	-af "cornerLip_L:189:180" top 180
	-af "lowerLipA_L:157:189" left 157
	-af "lowerLipA_L:157:189" top 189
	-af "lowerLipB_L:169:187" left 169
	-af "lowerLipB_L:169:187" top 187
	-af "lowerLipC_L:180:186" left 180
	-af "lowerLipC_L:180:186" top 186
	-af "SmilePull_L:207:175" left 207
	-af "SmilePull_L:207:175" top 175
	-af "SmileBulge_L:202:159" left 202
	-af "SmileBulge_L:202:159" top 159
	-af "FrownBulge_L:202:200" left 202
	-af "FrownBulge_L:202:200" top 200
	-af "upperLip_L:176:165" left 176
	-af "upperLip_L:176:165" top 165
	-af "lowerLip_L:176:197" left 176
	-af "lowerLip_L:176:197" top 197
	-af "EyeRegion_L:245:78" left 245
	-af "EyeRegion_L:245:78" top 78
	-af "EyeBrowRegion_L:245:45" left 245
	-af "EyeBrowRegion_L:245:45" top 45
	asSelectorfaceFormLayout;




asPopulateNameSpaceMenu "asSelectorface";
asShowSelJob;
asSelChange;
showWindow;
//some systems `resizeToFitChildren` incorrectly leaving too big window, so force-reduce
window -e -w 321 -h 295 asSelectorface;
}
asSelectorface;

//-- ASTools Procedures Starts Here --//
global proc string asGetASToolsProceduresVersionAsString ()
{
string $asToolsProceduresVersion=6.7852;
return $asToolsProceduresVersion;
}

global proc asSelChange ()
{
global int $asfileLoading;
global int $asSelChangeSwitching;
if ($asfileLoading)
	return;
if (!`optionVar -q asShowSelection` && !`optionVar -q asShowKeyed` && !$asSelChangeSwitching)
	return;
int $undoState=`undoInfo -q -state`;
float $bgc[];
float $selectedBGC[]={0.263,1.0,0.639};
string $sel[]=`ls -sl`;
string $name,$obj,$nodeType,$projectName,$ann;
string $ctls[],$buffer[],$connections[];
int $numLetters,$numTok,$keyed;
string $ext=".png";
string $currImage,$buttonImageFile,$buttonImageFileOnK0,$buttonImageFileOnK1,$buttonImageFileOffK0,$buttonImageFileOffK1;
string $windows[]=`lsUI -windows`;
string $layout;

for ($window in $windows)
	{
	$layout="";
	if (size($window)>11)
		$layout="asSelector"+`substring $window 11 999`+"FormLayout";
	if (!`formLayout -q -ex $layout`)
		continue;
	$numLetters=size($layout);
	$name=`substring $layout 11 ($numLetters-10)`;
	$ctls=`formLayout -q -ca $layout`;
	for ($ctl in $ctls)
		{
		if (!`iconTextButton -q -ex $ctl`)
			continue;
		if (`optionVar -q asShowSelection` && !$asSelChangeSwitching)
			$selState="On";
		else
			$selState="Off";
		$keyed=0;
		$ann=`iconTextButton -q -ann $ctl`;
		$numTok=`tokenize $ann ";" $buffer`;
		for ($i=0;$i<$numTok;$i++)
			{
			$obj=`asSelectorResolveNameSpace $name $buffer[$i]`;
			if (!`stringArrayCount $obj $sel`)
				$selState="Off";
			if (`optionVar -q asShowKeyed` && `objExists $obj`)// && !$asSelChangeSwitching
				{
				$connections=`listConnections -s 1 -d 0 $obj`;
				for ($node in $connections)
					{
					$nodeType=`objectType $node`;
					if (`gmatch $nodeType "animCurve*"`)
						$keyed=1;
					}
				}
			}
		if (`gmatch $ann "*AllSet"`)
			{$selState="Off";$keyed=0;}

		$currImage=`iconTextButton -q -i1 $ctl`;
		if ($currImage=="") //!$haveBG
			{
			if ($selState=="On")
				$bgc=$selectedBGC;
			else
				$bgc=`iconTextButton -q -olc $ctl`;//-overlayLabelColor
			if ($keyed)
				$bgc={1,0,0};
			if ($keyed && $selState=="On")
				$bgc={1.0,0.5,0.5};
			iconTextButton -e -bgc $bgc[0] $bgc[1] $bgc[2] $ctl;
			continue;
			}

		$numTok=`tokenize $currImage "_" $buffer`;
		if ($numTok<3)
			continue;
		$projectName=$buffer[0];
		for ($b=1;$b<size($buffer)-3;$b++)
			$projectName+="_"+$buffer[$b];
		$buttonImageFile=$projectName+"_"+$buffer[$numTok-3]+"_"+$buffer[$numTok-2]+"_"+$selState+"K"+$keyed+$ext;

		if ($buttonImageFile!=$currImage)
			iconTextButton -e -i $buttonImageFile $ctl;
		}
	}

//PickerSelChange
if (!`optionMenu -q -ex asPickerOptionMenu`)
	return;
int $selectedTabIndex,$overrideColor;
string $picCtrls[],$selPicCtrls[],$selChrCtrls[],$tabLabels[];
string $picNs,$chrNs,$picCtrl,$chrCtrl;

if (`optionMenu -q -ex asPickerOptionMenu`)
	$chrNs=`optionMenu -q -v asPickerOptionMenu`;
if ($chrNs==":")
	$chrNs="";
if (`tabLayout -q -ex asPickerTabLayout`)
	{
	$tabLabels=`tabLayout -q -tl asPickerTabLayout`;
	$selectedTabIndex=`tabLayout -q -selectTabIndex asPickerTabLayout`;
	$picNs="picker_"+$tabLabels[$selectedTabIndex-1]+":";
	if (`text -q -ex ("asPickerEmbeddedPickerNameSpace"+$selectedTabIndex)`)
		if (`text -q -l ("asPickerEmbeddedPickerNameSpace"+$selectedTabIndex)`!="")
			$picNs=`text -q -l ("asPickerEmbeddedPickerNameSpace"+$selectedTabIndex)`+":";
	}
$picCtrls=`ls -type transform ($picNs+"*")`;
$selPicCtrls=`ls -sl -type transform ($picNs+"*")`;
$selChrCtrls=`ls -sl -type transform ($chrNs+"*")`;

//All .overrideColor==0 off first
if ($undoState) undoInfo -stateWithoutFlush 0;

//set keyed color
for ($i=0;$i<size($picCtrls);$i++)
	{
	$overrideColor=0;
	$chrCtrl=`substitute $picNs $picCtrls[$i] $chrNs`;
	if (`optionVar -q asShowExtra`) $chrCtrl=`substitute "FK" $chrCtrl "FKExtra"`;
	if (`objExists $chrCtrl`)
		if (`optionVar -q asShowKeyed` && `asHaveAnimation $chrCtrl`)
			$overrideColor=13;
	setAttr ($picCtrls[$i]+".overrideColor") $overrideColor;
	}

if (!size($selPicCtrls) && !size($selChrCtrls))
	{
	if ($undoState) undoInfo -stateWithoutFlush 1;
	return;
	}

//set selected color
for ($i=0;$i<size($sel);$i++)
	{
	if (`optionVar -q asShowSelection`)
		$overrideColor=14;
	if (`gmatch $sel[$i] ($picNs+"*")`) // $picNs > $chrNs
		{
		$chrCtrl=`substitute $picNs $sel[$i] $chrNs`;
		if (`optionVar -q asShowExtra`) $chrCtrl=`substitute "FK" $chrCtrl "FKExtra"`;
		if (`objExists $chrCtrl` && `optionVar -q asShowSelection`)
			{
			select -d $sel[$i];
			select -tgl $chrCtrl;
			if (`stringArrayCount $chrCtrl $sel`)//deselected
				{
				$overrideColor=0;
				if (`optionVar -q asShowKeyed` && `asHaveAnimation $chrCtrl`)
					$overrideColor=13;
				}
			setAttr ($sel[$i]+".overrideColor") $overrideColor;
			}
		else
			print ("// "+$chrCtrl+" not found.\n");
		}
	if (`gmatch $sel[$i] ($chrNs+"*")`) // $chrNs > $picNs
		{
		if ($chrNs=="")
			$picCtrl=$picNs+$sel[$i];
		else
			$picCtrl=`substitute $chrNs $sel[$i] $picNs`;
		if (`optionVar -q asShowExtra`)
			{
			if (!`gmatch $picCtrl "*Extra*"`) continue;
			$picCtrl=`substitute "FKExtra" $picCtrl "FK"`;
			}
		if (`objExists $picCtrl`)
			setAttr ($picCtrl+".overrideColor") $overrideColor;
		}
	}
if ($undoState) undoInfo -stateWithoutFlush 1;
}

global proc asNameSpaceChange (string $name)
{
string $nameSpace;
string $allAttrs[],$poses[],$menuItemArray[];
string $skipAttrs[]={"run","preRebuildScript","postRebuildScript","objectsSkin","objectsAll","objectsRightEye","objectsLeftEye","fitSkeletonTemplate"};

//re-populate Poses
if (`window -q -ex $name` && `optionMenu -q -ex ($name+"OptionMenu")`)
	{
	$nameSpace=`asNameSpaceFromUIName $name`;
	if (!`objExists ($nameSpace+"FitSkeleton")`)
		return;
	$allAttrs=`listAttr -ud ($nameSpace+"FitSkeleton")`;
	for ($i=0;$i<size($allAttrs);$i++)
		if (`getAttr -type ($nameSpace+"FitSkeleton."+$allAttrs[$i])`=="string")
			if (!`stringArrayCount $allAttrs[$i] $skipAttrs`)
				$poses[size($poses)]=$allAttrs[$i];

	$menuArray=`window -q -menuArray $name`;
	for ($i=0;$i<size($menuArray);$i++)
		if (`menu -q -l $menuArray[$i]`=="Pose")
			{
			$menuItemArray=`menu -q -itemArray $menuArray[$i]`;
			for ($y=0;$y<size($menuItemArray);$y++)
				if (`gmatch $menuItemArray[$y] "asCustomPoseCommandsMenuItem*"`)
					deleteUI $menuItemArray[$y];
			setParent -menu $menuArray[$i];

			for ($y=0;$y<size($poses);$y++)
				menuItem -l $poses[$y] -c ("asPoseAttributeCommand "+$nameSpace+"FitSkeleton."+$poses[$y]) ("asCustomPoseCommandsMenuItem"+$name+$y);
			}
	}

asSelChange;
}

global proc asPoseAttributeCommand (string $objAttr)
{
int $numTok;
string $tempString[],$cmdBuffer[],$spaceBuffer[];
string $nameSpace,$stringAttr,$cmd;

tokenize $objAttr ":" $tempString;
for ($i=0;$i<size($tempString)-1;$i++)
	$nameSpace+=$tempString[$i]+":";

$stringAttr=`getAttr $objAttr`;
tokenize $stringAttr ";" $cmdBuffer;
for ($z=0;$z<size($cmdBuffer);$z++)
	{
	$numTok=`tokenize $cmdBuffer[$z] $spaceBuffer`;
	if ($nameSpace!="" && $numTok>2)//insert nameSpace
		$cmd+=`substitute $spaceBuffer[1] $cmdBuffer[$z] ($nameSpace+$spaceBuffer[1])`+";";
	else
		$cmd+=$cmdBuffer[$z]+";";
	}

evalEcho ($cmd);
}

global proc float asGetScale ()
{
float $scale=1;
if (!`objExists FitSkeleton`)
	return $scale;
float $maxY;
float $pos[];
$tempString=`listRelatives -f -ad -type joint FitSkeleton`;
for ($i=0;$i<size($tempString);$i++)
	{
	$pos=`xform -q -ws -t $tempString[$i]`;
	if ($pos[1]>$maxY)
		$maxY=$pos[1];
	}
if ($maxY>0)
	$scale=$maxY/17.176163;
if ($scale<0.01)
	$scale=0.01;
return $scale;
}

global proc asAlign (string $object, string $alignToObject, int $translate, int $rotate, int $jointOrient, int $rotateOrder)
{
string $parents[]=`listRelatives -p $object`;
string $orientConstraint[];
float $rotation[];

parent $object $alignToObject;
//Might have generated a Xform
string $generatedXform;
string $tempString[]=`listRelatives -p $object`;
if ($tempString[0]!=$alignToObject)
	$generatedXform=$tempString[0];
if ($translate)
	{
	xform -os -t 0 0 0 $object;
	if ($generatedXform!="")
		xform -os -t 0 0 0 $generatedXform;
	}
if ($rotateOrder)
	setAttr ($object+".rotateOrder") `getAttr ($alignToObject+".rotateOrder")`;
if ($rotate)
	{
	xform -os -ro 0 0 0 $object;
	if ($generatedXform!="")
		xform -os -ro 0 0 0 $generatedXform;
	}
if ($jointOrient && $rotate)
	setAttr -type float3 ($object+".jointOrient") 0 0 0;
	
if (`objExists $parents[0]`)
	parent $object $parents[0];
else
	parent -w $object;

if ($generatedXform!="")
	delete $generatedXform;

if ($jointOrient && !$rotate)
	{
	if (`getAttr ($alignToObject+".rotateOrder")`!=0)
		warning "Aligning jointOrient for objects without aligning rotation, and non-default rotationOrder, may cause problems.";
	$orientConstraint=`orientConstraint $alignToObject $object`;
	$rotation=`xform -q -os -ro $object`;
	delete $orientConstraint[0];
	setAttr -type float3 ($object+".jointOrient") $rotation[0] $rotation[1] $rotation[2];
	setAttr -type float3 ($object+".rotate") 0 0 0;
	}
}

global proc asProximityPin ()
{//seems `ProximityPin` does not have any scriptable options, so. 
string $name,$side,$parent;
string $sel[]=`ls -sl`;
string $tempString[],$tempString2[],$tempString3[];

tokenize $sel[1] "_" $tempString;
$name=$tempString[0];
$side="_"+$tempString[1];

$tempString=`listRelatives -p $sel[1]`;
$parent=$tempString[0];
parent -w $sel[1];//avoids the Warning: Transforms were not parented properly..

$tempString2=`ls -type proximityPin`;
select $sel;
ProximityPin;
//parent ($sel[1]) ("FKOffset"+$name+$side);
$tempString3=`ls -type proximityPin`;
for ($y=0;$y<size($tempString3);$y++)
	if (!`stringArrayCount $tempString3[$y] $tempString2`)
		{
		rename $tempString3[$y] ("proximityPin"+$name+$side);
		break;
		}
select ("proximityPin"+$name+$side);
$tempString2=`listConnections ("proximityPin"+$name+$side+".inputMatrix[0]")`;
if ($tempString2[0]==$sel[1])//input=existingTransform option was used, disconnect it.
	disconnectAttr ($sel[1]+".matrix") ("proximityPin"+$name+$side+".inputMatrix[0]");
else if ($tempString2[0]!="")//input=newLocator option was used, remove it.
	{
	$m=`getAttr ("proximityPin"+$name+$side+".inputMatrix[0]")`;
	delete $tempString2[0];
	setAttr ("proximityPin"+$name+$side+".inputMatrix[0]") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
	}
$tempString2=`listConnections ("proximityPin"+$name+$side+".outputMatrix[0]")`;
if ($tempString2[0]!=$sel[1])//output=newLocator option was used, remove it.
	{
	connectAttr -f ("proximityPin"+$name+$side+".outputMatrix[0]") ($sel[1]+".offsetParentMatrix");
	xform -os -t 0 0 0 -ro 0 0 0 $sel[1];
	delete $tempString2[0];
	}
$tempString2=`listConnections ($sel[1]+".offsetParentMatrix")`;
rename $tempString2[0] ("proximityPin"+$name+$side);
//default attrs
setAttr ("proximityPin"+$name+$side+".coordMode") 0;
setAttr ("proximityPin"+$name+$side+".normalAxis") 0;
setAttr ("proximityPin"+$name+$side+".relativeSpaceMode") 0;

if (`objExists $parent`)
	parent -r $sel[1] $parent;
}

global proc float asRoundOff (float $value, int $decimals)
{
float $rounded;
if ($value>=0) $rounded=(trunc($value*`pow 10 $decimals`+0.5)/`pow 10 $decimals`);
else $rounded=(trunc(abs($value)*`pow 10 $decimals`+0.5)/`pow 10 $decimals`)*-1;
return $rounded;
}

global proc asFL ()
{
string $framLayouts[]=`lsUI -type frameLayout`;
for ($i=0;$i<size($framLayouts);$i++)
	if (`gmatch $framLayouts[$i] "as*FrameLayout"`)
		optionVar -iv $framLayouts[$i] `frameLayout -q -cl $framLayouts[$i]`;
}

global proc asLockAttr (string $object, int $trans, int $rot, int $scale, int $vis)
{
string $XYZ[]={"X","Y","Z"};

for ($z=0;$z<size($XYZ);$z++)
	{
	setAttr -l $trans -k (!$trans) ($object+".translate"+$XYZ[$z]);
	setAttr -l $rot -k (!$rot) ($object+".rotate"+$XYZ[$z]);
	setAttr -l $scale -k (!$scale) ($object+".scale"+$XYZ[$z]);
	}
setAttr -l $vis -k (!$vis) ($object+".v");

//in case of UnLock, also unlock the double3 type attrs, as these can have been locked by user
if (!$trans) setAttr -l $trans -k 0 ($object+".translate");
if (!$rot)   setAttr -l $rot   -k 0 ($object+".rotate");
if (!$scale) setAttr -l $scale -k 0 ($object+".scale");
}

global proc float asMayaVersionAsFloat ()
{
float $version=2012;
if (`about -v`=="2016 Extension 2")
	return 2016.5;
if (`exists getApplicationVersionAsFloat`)
	return `getApplicationVersionAsFloat`;
string $versionString=`about -v`;
string $tempString[];
string $char;
tokenize $versionString $tempString;
//default to 2012, if versionString is not all numbers
for ($i=0;$i<size($tempString[0]);$i++)
	{
	$char=`substring $tempString[0] ($i+1) ($i+1)`;
	if (!`gmatch $char "[0-9]"`)
		return 2012;
	}
$version=$tempString[0];
return $version;
}

global proc asSelChangeToggle ()
{
global int $asSelChangeSwitching;
$asSelChangeSwitching=1;
string $sel[]=`ls -sl`;
select -cl;
asSelChange;
$asSelChangeSwitching=0;
select $sel;
}

global proc asCharChange (string $uiName)
{
string $gridOrder[];
if (`gridLayout -q -ex ($uiName+"GridLayout")`)
	{
	$gridOrder=`gridLayout -q -go ($uiName+"GridLayout")`;
	for ($i=1;$i<size($gridOrder)+1;$i++)
		if (`floatSlider -q -ex ($uiName+"FloatSlider"+$i)`)
			{
			$ann=`floatSlider -q -ann ($uiName+"FloatSlider"+$i)`;
			$resolvedName=`asPoserResolveNameSpace $uiName $ann`;
			if (`objExists $resolvedName`)
				connectControl ($uiName+"FloatSlider"+$i) $resolvedName;
			}
	}
asSelChange;
}

global proc asShowSelJob ()
{
global int $asSelChangeScripJobNr;
if ($asSelChangeScripJobNr)
	return;
$asSelChangeScripJobNr=`scriptJob -e "SelectionChanged" "asSelChange"`;
}

global proc string asSelectorResolveNameSpace (string $name, string $obj)
{
string $nameSpace;
string $tempString[];
if (`optionMenu -q -ex ("asSelector"+$name+"OptionMenu")`)
	$nameSpace=`optionMenu -q -v ("asSelector"+$name+"OptionMenu")`;
else if (`optionMenu -q -ex ("asPickerOptionMenu")`)
	$nameSpace=`optionMenu -q -v ("asPickerOptionMenu")`;
else if (`gmatch $name "*:*"`)
	{
	tokenize $name ":" $tempString;
	for ($i=0;$i<size($tempString)-1;$i++)
		$nameSpace+=$tempString[$i]+":";
	}
if ($nameSpace==":")
	$nameSpace="";
string $extraObj;
//Extra control
if (`checkBox -q -ex ("asSelector"+$name+"ExtraCheckBox")`)
	if (`checkBox -q -v ("asSelector"+$name+"ExtraCheckBox")`)
		if (size($obj)>2)
			{
			$extraObj=`substring $obj 1 2`+"Extra"+`substring $obj 3 99`;
			if (`gmatch $obj "*RootX*"`)
				$extraObj=`substring $obj 1 4`+"Extra"+`substring $obj 5 99`;
			if (`objExists ($nameSpace+$extraObj)`)
				return ($nameSpace+$extraObj);
			}
return ($nameSpace+$obj);
}

global proc asSelect (string $name, string $objs[])
{
for ($i=0;$i<size($objs);$i++)
	$objs[$i]=`asSelectorResolveNameSpace $name $objs[$i]`;

int $modifier=`getModifiers`;
if (($modifier %  2)==0)
	select -cl;
if ($objs[0]=="")
	{
	select -cl;
	return;
	}
for ($obj in $objs)
	if (!`objExists $obj`)
		error ("Object:\""+$obj+"\" does not exists !");
for ($obj in $objs)
	select -tgl $obj;
//enable hotKeys
string $formLayout="asSelector"+$name+"FormLayout";
if (`formLayout -q -ex $formLayout`)
	setFocus $formLayout;
}

global proc asKey (string $name, string $objs[])
{
for ($i=0;$i<size($objs);$i++)
	$objs[$i]=`asSelectorResolveNameSpace $name $objs[$i]`;

for ($obj in $objs)
	setKeyframe $obj;
select `ls -sl`;
asSelChange;
}

global proc asLinearKey (string $name, string $objs[])
{
for ($i=0;$i<size($objs);$i++)
	$objs[$i]=`asSelectorResolveNameSpace $name $objs[$i]`;

for ($obj in $objs)
	setKeyframe -itt linear -ott linear $obj;
select `ls -sl`;
asSelChange;
}

global proc asAlignIK2FK (string $nameSpace, string $objs[])
{
//asAssembleAlignSwitchCmd $nameSpace $objs "asAlignFKIK" "IK2FK";
asAssembleAlignSwitchCmd $nameSpace $objs "asAlignFKIK" "FK2IK";
}

global proc asAlignFK2IK (string $nameSpace, string $objs[])
{
//asAssembleAlignSwitchCmd $nameSpace $objs "asAlignFKIK" "FK2IK";
asAssembleAlignSwitchCmd $nameSpace $objs "asAlignFKIK" "IK2FK";
}

global proc asSwitchIK2FK (string $nameSpace, string $objs[])
{
asAssembleAlignSwitchCmd $nameSpace $objs "asSwitchFKIK" "IK2FK";
}

global proc asSwitchFK2IK (string $nameSpace, string $objs[])
{
asAssembleAlignSwitchCmd $nameSpace $objs "asSwitchFKIK" "FK2IK";
}

global proc asAssembleAlignSwitchCmd (string $nameSpace, string $objs[], string $alignSwitchCmd, string $W2K)
{
global int $asBakeFKIK;
$asBakeFKIK=0;
int $numLetters=size($objs[0]);
string $IK=`substring $objs[0] 5 ($numLetters-2)`;
string $side=`substring $objs[0] ($numLetters-1) $numLetters`;
eval ($alignSwitchCmd+" \""+$nameSpace+"\" "+$IK+" "+$side+" "+$W2K);
}

global proc asAlignFKIK (string $name, string $IK, string $side, string $W2K)
{
global int $asBakeFKIK;
int $isSplineIK,$numIkCtrls,$cvNr,$ikNr,$bakingMoCap,$opm,$c,$ikCtrlNr,$y,$hasBiasWarned;
float $IKCurveLenght,$stiff,$middleJointLenght,$endJointLenght,$joFac,$maxJo,$shiftDist,$samplerDist,$value,$version,$u;
float $shiftPolarity=1;
float $b=1;
if ($side=="_L") $b=-1;
float $pos[],$rot[],$posA[],$posB[],$sca[],$tempFloat[],$alignIkToFloat[],$jo[],$w[],$aimVector[],$upVector[];
string $sel[]=`ls -sl`;
string $nameSpace=`asNameSpaceFromShortUIName $name`;
if (!`objExists ($nameSpace+"Pole"+$IK+$side)`)
	$isSplineIK=1;
string $controlCurve=$nameSpace+"FKIK"+$IK+$side;
if (!`objExists $controlCurve`)
	error ("Object:\""+$controlCurve+"\" does not exists !");
string $startJoint=`getAttr ($controlCurve+".startJoint")`;
string $middleJoint=`getAttr ($controlCurve+".middleJoint")`;
string $endJoint=`getAttr ($controlCurve+".endJoint")`;
string $startMiddleEnd[]={$startJoint,$middleJoint,$endJoint};
string $toesJoint=`asGetToesJoint $nameSpace $endJoint $side`;
string $qToesJoints[]=`asGetQToesJoints $nameSpace $endJoint $side`;
string $curveCmd,$roo,$childLabel,$target,$sideLess,$partJoint,$rollCtrlToAim,$ikHandleWithLocalOrient,$aimAtTarget;
string $priAxis="X";
string $secAxis="Y";
string $terAxis="Z";
string $shiftAxis="Y";
string $tempLoc1[],$tempLoc2[],$tempConstraint[],$tempConstraintAttrs[],$chainJoints[],$tempString[],$tempLocShift1[],$tempLocShift2[];
string $requiredObj[]={($nameSpace+"Main"),($nameSpace+"FKX"+$startJoint+$side),($nameSpace+"IKX"+$startJoint+$side),($nameSpace+"IKX"+$middleJoint+$side)};

//compatability pre check
if (`attributeExists version ($nameSpace+"Main")`)
	{
	$version=`getAttr ($nameSpace+"Main.version")`;
	if ($version>6.240 && $version<6.261)
		error ("Detected Rig version:\""+$version+"\" which has issues with Switch FK2Ik, Update to the latest version, and run \"ReBuild AdvancedSkeleton\" to fix this.");
	}

if ($isSplineIK)
	{
	$chainJoints=`asgetChainJoints ($nameSpace+$startJoint+$side) ($nameSpace+$endJoint+$side)`;
	for ($i=0;$i<size($chainJoints);$i++)
		$chainJoints[$i]=`substitute $nameSpace $chainJoints[$i] ""`;
	for ($i=1;$i<99;$i++)
		{
		if (!`objExists ($nameSpace+"IK"+$IK+$i+$side)`)
			break;
		$numIkCtrls=$i;
		}
	}
else
	$requiredObj=`stringArrayCatenate $requiredObj {($nameSpace+"Pole"+$IK+$side),($nameSpace+"FKX"+$endJoint+$side)}`;
for ($obj in $requiredObj)
	if (!`objExists $obj`)
		error ("Object:\""+$obj+"\" does not exists !");
float $charsize=`getAttr ($nameSpace+"Main.height")`;
int $autoKey=`autoKeyframe -q -st`;
if ($autoKey)
	autoKeyframe -st 0;
if ($asBakeFKIK)
	autoKeyframe -st 1;

if (`attributeExists useOffsetParentMatrix ($nameSpace+"FitSkeleton")`)
	$opm=`getAttr ($nameSpace+"FitSkeleton.useOffsetParentMatrix")`;

//Not using `optionVar -q asBakingMoCap` as it could get stuck at wrong state
if (`checkBox -q -ex asAnimBakingMoCapCheckBox`)
	$bakingMoCap=`checkBox -q -v asAnimBakingMoCapCheckBox`;

string $deleteObjs[]={"IK2FKTempCurve","IK2FKTempXform1","IK2FKTempXform2","IK2FKTempCurveInfo"};
for ($i=0;$i<size($deleteObjs);$i++)
	if (`objExists $deleteObjs[$i]`)
		delete $deleteObjs[$i];

if ($W2K=="FK2IK" && !$isSplineIK)
	{
	//Default values for RollHeel, RollToes, RollToesEnd, and UD attrs such as roll,etc
	asSetCustomAttrToDefault ($nameSpace+"IK"+$IK+$side);
	$tempString=`listRelatives -ad -type transform ($nameSpace+"IK"+$IK+$side)`;
	for ($i=0;$i<size($tempString);$i++)
		if (`sets -im ($nameSpace+"ControlSet") $tempString[$i]`)
			{
			if (!`getAttr -l ($tempString[$i]+".tx")`)
				setAttr ($tempString[$i]+".t") -type float3 0 0 0;
			if (!`getAttr -l ($tempString[$i]+".rx")`)
				setAttr ($tempString[$i]+".r") -type float3 0 0 0;
			}
	//zero out leg-aim for easier alignment
	if (`attributeExists legAim ($nameSpace+"IK"+$IK+$side)`)
		setAttr ($nameSpace+"IK"+$IK+$side+".legAim") 0;

	//Ik Handle
	$tempFloat=`xform -q -ws -t ($nameSpace+"FK"+$endJoint+$side)`;
	if (size($qToesJoints))
		$tempFloat=`xform -q -ws -t ($nameSpace+"FK"+$qToesJoints[size($qToesJoints)-1]+$side)`;
	xform -ws -t $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"IK"+$IK+$side);

	$roo=`xform -q -roo ($nameSpace+"IK"+$IK+$side)`;
	xform -p 1 -roo $roo ($nameSpace+"AlignIKTo"+$endJoint+$side);
	$tempFloat=`xform -q -ws -ro ($nameSpace+"AlignIKTo"+$endJoint+$side)`;
	if (size($qToesJoints) && `objExists ($nameSpace+"AlignIKTo"+$qToesJoints[0]+$side)`)
		$tempFloat=`xform -q -ws -ro ($nameSpace+"AlignIKTo"+$qToesJoints[0]+$side)`;
	xform -ws -ro $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"IK"+$IK+$side);

//	asCustomOrientedAlignUpdate $nameSpace ("IK"+$IK+$side);

//	if (`attributeExists mirroredTranslate ($nameSpace+"IK"+$IK+$side)` && `getAttr ($nameSpace+"IK"+$IK+$side+".mirroredTranslate")` && $side=="_L")
//		rotate -r -eu 0 0 -180 ($nameSpace+"IK"+$IK+$side);

	//Pole
	//Default values for Pole attrs as well e.g. follow & lock
	asSetCustomAttrToDefault ($nameSpace+"Pole"+$IK+$side);

	$tempLoc1=`spaceLocator`;
	$tempConstraint=`pointConstraint ($nameSpace+"FKX"+$startJoint+$side) ($nameSpace+"FKX"+$endJoint+$side) $tempLoc1[0]`;
	$tempConstraintAttrs=`listAttr -ud $tempConstraint`;
/*
	$middleJointLenght=`getAttr ($nameSpace+"FKOffset"+$middleJoint+$side+".tx")`;
	$endJointLenght=`getAttr ($nameSpace+"FKOffset"+$endJoint+$side+".tx")`;
	if ($opm && `objExists ($nameSpace+$middleJoint)` && `objExists ($nameSpace+$endJoint)`)
		{//opm uses FitSkeleton for now
		$middleJointLenght=`getAttr ($nameSpace+$middleJoint+".tx")`;
		$endJointLenght=`getAttr ($nameSpace+$endJoint+".tx")`;
		}
*/
	$middleJointLenght=`asGetAttrOPM ($nameSpace+"FKOffset"+$middleJoint+$side+".tx")`;
	$endJointLenght=`asGetAttrOPM ($nameSpace+"FKOffset"+$endJoint+$side+".tx")`;

	setAttr ($tempLoc1[0]+"_pointConstraint1."+$tempConstraintAttrs[0]) `abs($endJointLenght)`;
	setAttr ($tempLoc1[0]+"_pointConstraint1."+$tempConstraintAttrs[1]) `abs($middleJointLenght)`;
	delete $tempConstraint[0];
	if ($bakingMoCap)
		{
		//ShiftAxis
		$tempLocShift1=`spaceLocator`;
		parent -r $tempLocShift1[0] ($nameSpace+"FKX"+$middleJoint+$side);
		$tempLocShift2=`spaceLocator`;
		parent -r $tempLocShift2[0] ($nameSpace+"FKX"+$endJoint+$side);
		parent $tempLocShift2[0] $tempLocShift1[0];
		$pos=`getAttr ($tempLocShift2[0]+".t")`;
		$posA={abs($pos[0]),abs($pos[1]),abs($pos[2])};
		if ($posA[1]>$posA[0] && $posA[1]>$posA[2]) $priAxis="Y";
		if ($posA[2]>$posA[0] && $posA[2]>$posA[1]) $priAxis="Z";
		$jo=`getAttr ($nameSpace+$middleJoint+$side+".jo")`;
		if ($opm)
			$jo=`asTransformValuesFromMatrixPlug ($nameSpace+$middleJoint+$side) offsetParentMatrix rotate`;
		if (abs($jo[0])>abs($jo[1]) && abs($jo[0])>abs($jo[2])) $maxJo=$jo[0];
		if (abs($jo[1])>abs($jo[0]) && abs($jo[1])>abs($jo[2])) $maxJo=$jo[1];
		if (abs($jo[2])>abs($jo[0]) && abs($jo[2])>abs($jo[1])) $maxJo=$jo[2];
		$joFac=15.0/abs($maxJo);//15 degree bend check
		setAttr ($tempLocShift1[0]+".r") -type float3 ($jo[0]*$joFac) ($jo[1]*$joFac) ($jo[2]*$joFac);
		parent -w $tempLocShift2[0];
		setAttr ($tempLocShift1[0]+".r") -type float3 0 0 0;
		parent $tempLocShift2[0] $tempLocShift1[0];
		setAttr ($tempLocShift2[0]+".translate"+$priAxis) 0;
		$pos=`getAttr ($tempLocShift2[0]+".t")`;
		$posA={abs($pos[0]),abs($pos[1]),abs($pos[2])};
		if ($posA[0]>$posA[1] && $posA[0]>$posA[2]) $shiftAxis="X";
		if ($posA[2]>$posA[0] && $posA[2]>$posA[1]) $shiftAxis="Z";
		if (`getAttr ($tempLocShift2[0]+".translate"+$shiftAxis)`<0) $shiftPolarity=-1;
		$shiftDist=($charsize/10)*$shiftPolarity;
		delete $tempLocShift1[0];
		//Move locator1 backwards relative to $startJoint, allowing for rotation of $middleJoint past zero, w/o poleVec flip
		parent $tempLoc1[0] ($nameSpace+"FKX"+$middleJoint+$side);
		setAttr ($tempLoc1[0]+".t") -type float3 0 0 0;
		setAttr ($tempLoc1[0]+".translate"+$shiftAxis) (`getAttr ($tempLoc1[0]+".translate"+$shiftAxis)`+$shiftDist);
		parent -w $tempLoc1[0];
		}
	$tempConstraint=`aimConstraint -aimVector 1 0 0 ($nameSpace+"FKX"+$middleJoint+$side) $tempLoc1[0]`;
	$tempLoc2=`spaceLocator`;
	parent $tempLoc2[0] $tempLoc1[0];
	setAttr ($tempLoc2[0]+".t") -type float3 0 0 0;
	$posA=`xform -q -ws -t $tempLoc2[0]`;
	$posB=`xform -q -ws -t ($nameSpace+$middleJoint+$side)`;
	$samplerDist=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;
	setAttr -type float3 ($tempLoc2[0]+".translate") (($charsize/3.333)+$samplerDist) 0 0;
	$tempFloat=`xform -q -ws -t $tempLoc2[0]`;
	xform -ws -t $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"Pole"+$IK+$side);
	delete $tempLoc1;

	if (`objExists ($nameSpace+$toesJoint)` && `objExists ($nameSpace+"AlignIKToToes"+$side)`)
		{
		if (`attributeExists "roll" ($nameSpace+"IK"+$IK+$side)`)
			setAttr ($nameSpace+"IK"+$IK+$side+".roll") 0;
		$rot=`xform -q -ws -ro ($nameSpace+"AlignIKToToes"+$side)`;
		xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"IKToes"+$side);
		}
	$tempFloat=`getAttr ($nameSpace+$endJoint+$side+".s")`;
	setAttr ($nameSpace+"IK"+$IK+$side+".s") -type float3 $tempFloat[0] $tempFloat[1] $tempFloat[2];


	setAttr ($nameSpace+"IK"+$IK+$side+".stretchy") 10;
	setAttr ($nameSpace+"IK"+$IK+$side+".volume") 10;
	//position
	$tempFloat=`xform -q -ws -t ($nameSpace+"FKX"+$endJoint+$side)`;
	if (size($qToesJoints))
		$tempFloat=`xform -q -ws -t ($nameSpace+"FK"+$qToesJoints[size($qToesJoints)-1]+$side)`;
	xform -ws -t $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"IK"+$IK+$side);

	//scale (hands/feet)
	$sca=`xform -q -os -r -s ($nameSpace+"FK"+$endJoint+$side)`;
	xform -os -a -s $sca[0] $sca[1] $sca[2] ($nameSpace+"IK"+$IK+$side);

	if (`objExists ($nameSpace+"IKX"+$middleJoint+$side+"_IKLenght"+$side)` && `objExists ("IKX"+$middleJoint+$side+"_IKmessureDiv"+$side)`)
		{//Lenght1 & Lenght2
		$pos=`xform -q -ws -t ($nameSpace+"FK"+$startJoint+$side)`;
		$posA=`xform -q -ws -t ($nameSpace+"FK"+$middleJoint+$side)`;
		$posB=`xform -q -ws -t ($nameSpace+"FK"+$endJoint+$side)`;
		$tempFloat[0]=`mag<<$pos[0]-$posA[0],$pos[1]-$posA[1],$pos[2]-$posA[2]>>`;
		$tempFloat[1]=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;		
		setAttr ($nameSpace+"IK"+$IK+$side+".Lenght1") (($tempFloat[0]/(`getAttr ($nameSpace+"IKX"+$middleJoint+$side+"_IKLenght"+$side+".input2X")`*$b))/`getAttr ("IKX"+$middleJoint+$side+"_IKmessureDiv"+$side+".input1X")`);
		setAttr ($nameSpace+"IK"+$IK+$side+".Lenght2") (($tempFloat[1]/(`getAttr ($nameSpace+"IKX"+$endJoint+$side+"_IKLenght"+$side+".input2X")`*$b))/`getAttr ("IKX"+$middleJoint+$side+"_IKmessureDiv"+$side+".input1X")`);
		//allow for scaled character
		if (`objExists ($nameSpace+"MainScaleMultiplyDivide")`)
			{
			setAttr ($nameSpace+"IK"+$IK+$side+".Lenght1") (`getAttr ($nameSpace+"IK"+$IK+$side+".Lenght1")`/`getAttr ($nameSpace+"MainScaleMultiplyDivide.outputX")`);
			setAttr ($nameSpace+"IK"+$IK+$side+".Lenght2") (`getAttr ($nameSpace+"IK"+$IK+$side+".Lenght2")`/`getAttr ($nameSpace+"MainScaleMultiplyDivide.outputX")`);
			}
		}

	//Qtoes (roll toes) to reverse-aim, use toesAim attr to find ctrl that needs aiming
	if (`attributeExists toesAim ($nameSpace+"IK"+$IK+$side)`)
		{
//		if (size($qToesJoints)==1)
			{
			$rollCtrlToAim=$nameSpace+"Roll"+$qToesJoints[0]+$side;
			if (size($qToesJoints)>1)
				$rollCtrlToAim=$nameSpace+"Roll"+$qToesJoints[size($qToesJoints)-1]+$side;
//			$tempString=`listRelatives -c -type ikHandle $rollCtrlToAim`;
			$tempString=`listRelatives -ad -type ikHandle $rollCtrlToAim`;
			$ikHandleWithLocalOrient=$tempString[0];
			$aimAtTarget=$nameSpace+"FK"+$endJoint+$side;
			createNode -n tempXform1 -p $ikHandleWithLocalOrient transform;
			createNode -n tempXform2 -p $rollCtrlToAim transform;
			parent tempXform2 tempXform1;
			$tempString=`listRelatives -p $rollCtrlToAim`;
			parent tempXform1 $tempString[0];
//			aimConstraint -offset 0 0 0 -weight 1 -aimVector ($b*-1) 0 0 -upVector 0 $b 0 -worldUpType "objectrotation" -worldUpObject ($nameSpace+"IK"+$IK+$side) $aimAtTarget tempXform1;
			aimConstraint -offset 0 0 0 -weight 1 -aimVector ($b*-1) 0 0 -upVector 0 $b 0 -worldUpType "objectrotation" -worldUpObject $aimAtTarget $aimAtTarget tempXform1;
			$tempFloat=`xform -q -ws -ro tempXform2`;
			xform -ws -ro $tempFloat[0] $tempFloat[1] $tempFloat[2] $rollCtrlToAim;
			delete tempXform1;
			}

		if (size($qToesJoints)>1)//MultiQtoes have HybridCtrls
			for ($i=size($qToesJoints)-1;$i>-1;$i--)
				{
				$rollCtrlToAim=$nameSpace+"Roll"+$qToesJoints[0]+$side;
				$tempFloat=`xform -q -ws -ro ("FKX"+$qToesJoints[$i]+$side)`;
				xform -ws -ro $tempFloat[0] $tempFloat[1] $tempFloat[2] ("IKhybrid"+$qToesJoints[$i]+$side);
				}
		}
	}
if ($W2K=="FK2IK" && $isSplineIK)
	{
	if (`objExists FK2IKCurve`)
		delete FK2IKCurve;
	$curveCmd="curve -n FK2IKCurve -d 1";
	for ($i=0;$i<size($chainJoints);$i++)
		{
		$pos=`xform -q -ws-t ($nameSpace+$chainJoints[$i])`;
		$curveCmd+=" -p "+$pos[0]+" "+$pos[1]+" "+$pos[2];
		}
	eval ($curveCmd);
	rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 0 -d 3 -tol 0.01 FK2IKCurve;
	addAttr -ln nameSpace -dt "string" FK2IKCurve;
	setAttr -type "string" FK2IKCurve.nameSpace $nameSpace;
	if (`objExists tempPointOnCurveInfo`) delete tempPointOnCurveInfo;
	createNode -n tempPointOnCurveInfo pointOnCurveInfo;
	setAttr tempPointOnCurveInfo.turnOnPercentage 1;
	connectAttr -f FK2IKCurve.worldSpace[0] tempPointOnCurveInfo.inputCurve;

	//First IKHybrid
	for ($i=1;$i<$numIkCtrls+1;$i++)
		{
		$u=($i-1.0)/($numIkCtrls-1.0);
		setAttr tempPointOnCurveInfo.parameter $u;
		$pos=`getAttr tempPointOnCurveInfo.position`;
		$tempString=`asGetDeformJointsByDistance $pos`;
		$tempFloat=$pos;
		$rot=`xform -q -ws -ro $tempString[0]`;
		xform -ws -t $pos[0] $pos[1] $pos[2] -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"IKhybrid"+$IK+$i+$side);
		asCustomOrientedAlignUpdate $nameSpace ("IKhybrid"+$IK+$i+$side);
		}

	//then IK
	for ($i=0;$i<$numIkCtrls;$i++)
		{
		//`shuffle` again
		$y=$i;
		if ($i==0) {$y=1;$c=0;}
		if ($i==1) {$y=$numIkCtrls;$c=size($chainJoints)-1;}

		$u=($y-1.0)/($numIkCtrls-1.0);
		setAttr tempPointOnCurveInfo.parameter $u;
		$pos=`getAttr tempPointOnCurveInfo.position`;
		$tempString=`asGetDeformJointsByDistance $pos`;
		$tempFloat=$pos;

		xform -ws -t $pos[0] $pos[1] $pos[2] ($nameSpace+"IK"+$IK+$y+$side);
		xform -os -ro 0 0 0 ($nameSpace+"IK"+$IK+$y+$side);
		//last IKhybrid is `limb-oriented`, but last fk is `child-oriented`, orient IK instead of IKhybrid
		if ($i==1 || ($i==0 && $chainJoints[0]=="Root_M"))// also IKSpine1_M to be oriented, since it affect legs(in fk) but hybrid does not
			{
			$roo=`xform -q -roo ($nameSpace+"IK"+$IK+$y+$side)`;
			xform -p 1 -roo $roo ($nameSpace+"AlignIKTo"+$chainJoints[$c]);
			$rot=`xform -q -ws -ro ($nameSpace+"AlignIKTo"+$chainJoints[$c])`;
			xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"IK"+$IK+$y+$side);
			}
		if ($y==1)
			asCustomOrientedAlignUpdate $nameSpace ("IK"+$IK+$y+$side);
		}
	delete FK2IKCurve;
/*
	//removed, since FK ctrls can be moved (stretched) causing very non-unifor distribution of FK-joints,
	//and trasnferring this non-unifor distribution to the IK is probably not what the user wants
	//then do  IKcvCtrls
	for ($i=1;$i<size($chainJoints)-1;$i++)
		{
		$pos=`xform -q -ws -t ($nameSpace+"FKX"+$chainJoints[$i])`;
		xform -ws -t $pos[0] $pos[1] $pos[2] ($nameSpace+"IKcv"+$IK+$i+$side);
		}
*/
	print "// Switching from FK to Curve-Based-IK, Target might not fully Align.\n";
	}
if ($W2K=="IK2FK" && !$isSplineIK)
	{
	for ($x=0;$x<size($startMiddleEnd);$x++)
		{
		xform -os -t 0 0 0 ($nameSpace+"FK"+$startMiddleEnd[$x]+$side);
//		asFKIKOrientAlign $nameSpace ("IKX"+$startMiddleEnd[$x]+$side) ("FK"+$startMiddleEnd[$x]+$side);
		$rot=`xform -q -ws -ro ($nameSpace+"IKX"+$startMiddleEnd[$x]+$side)`;
		xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FK"+$startMiddleEnd[$x]+$side);
		asCustomOrientedAlignUpdate $nameSpace ("FK"+$startMiddleEnd[$x]+$side);
		}

	//scale (hands/feet)
	$sca=`xform -q -os -r -s ($nameSpace+"IK"+$IK+$side)`;
	xform -os -a -s $sca[0] $sca[1] $sca[2] ($nameSpace+"FK"+$startMiddleEnd[2]+$side);

	if (`objExists ($nameSpace+$toesJoint)` && `objExists ($nameSpace+"IKXToes"+$side)`)
		{
		xform -os -t 0 0 0 ($nameSpace+"FKToes"+$side);
//		asFKIKOrientAlign $nameSpace ("IKXToes"+$side) ("FKToes"+$side);
		$rot=`xform -q -ws -ro ($nameSpace+"IKXToes"+$side)`;
		xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FKToes"+$side);
		asCustomOrientedAlignUpdate $nameSpace ("FKToes"+$side);
		}


	//stretchy IK
//	if (`getAttr ($nameSpace+"IK"+$IK+$side+".stretchy")`>0.01)
		{
		//volume
		$tempFloat=`getAttr ($nameSpace+$startJoint+$side+".s")`;
		setAttr ($nameSpace+"FK"+$startJoint+$side+".s") -type float3 $tempFloat[0] $tempFloat[1] $tempFloat[2];
		$tempFloat=`getAttr ($nameSpace+$middleJoint+$side+".s")`;
		setAttr ($nameSpace+"FK"+$middleJoint+$side+".s") -type float3 $tempFloat[0] $tempFloat[1] $tempFloat[2];
		//position
		$tempFloat=`xform -q -ws -t ($nameSpace+"IKX"+$middleJoint+$side)`;
		xform -ws -t $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"FK"+$middleJoint+$side);
		$tempFloat=`xform -q -ws -t ($nameSpace+"IKX"+$endJoint+$side)`;
		xform -ws -t $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"FK"+$endJoint+$side);
		}
	//toesAim
	if (`attributeExists toesAim ($nameSpace+"IK"+$IK+$side)`)
		{
		if (`getAttr ($nameSpace+"IK"+$IK+$side+".toesAim")`>0)
			{
			$rot=`xform -q -ws -ro ($nameSpace+"IKX"+$qToesJoints[0]+$side)`;
			xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FK"+$qToesJoints[0]+$side);
			asCustomOrientedAlignUpdate $nameSpace ("FK"+$qToesJoints[0]+$side);
			}
		}
	//qToes
	for ($i=size($qToesJoints)-1;$i>-1;$i--)
		{
		$tempFloat=`xform -q -ws -t ($nameSpace+"IKX"+$qToesJoints[$i]+$side)`;
		xform -ws -t $tempFloat[0] $tempFloat[1] $tempFloat[2] ($nameSpace+"FK"+$qToesJoints[$i]+$side);
		$rot=`xform -q -ws -ro ($nameSpace+"IKX"+$qToesJoints[$i]+$side)`;
		xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FK"+$qToesJoints[$i]+$side);
		asCustomOrientedAlignUpdate $nameSpace ("FK"+$qToesJoints[$i]+$side);
		}
	}
if ($W2K=="IK2FK" && $isSplineIK)
	{
	for ($i=0;$i<size($chainJoints);$i++)
		{
		if (!`objExists ($nameSpace+"IKX"+$chainJoints[$i])` || !`objExists ($nameSpace+"FK"+$chainJoints[$i])`)
			continue;
		if (!`sets -im ($nameSpace+"ControlSet") ($nameSpace+"FK"+$chainJoints[$i])`)
			continue;
/*
		// RootX_M.legLock warning
		if ($chainJoints[$i]=="Root")
			if (`attributeExists legLock RootX_M`)
				if (`getAttr RootX_M.legLock`!=10)
					print ("// Switching from IK to FK for the Spine, Set RootX_M.legLock to 10, for more accurate switching.\n");
*/
/*
		// bias
		if (`attributeExists bias ($nameSpace+"FK"+$chainJoints[$i])`)
			if (`getAttr ($nameSpace+"FK"+$chainJoints[$i]+".bias")`!=10)
				{
				if (!$hasBiasWarned)
					warning ("Settting \"bias\" attribute of Fk-controllers to 10, for improved accuracy");
				setAttr ($nameSpace+"FK"+$chainJoints[$i]+".bias") 10;
				$hasBiasWarned=1;
				}
*/		
		$pos=`xform -q -ws -t ($nameSpace+"IKX"+$chainJoints[$i])`;
		$rot=`xform -q -ws -ro ($nameSpace+"IKX"+$chainJoints[$i])`;

		xform -ws -t $pos[0] $pos[1] $pos[2] -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FK"+$chainJoints[$i]);
		xform -ws -t $pos[0] $pos[1] $pos[2] -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FK"+$chainJoints[$i]);

		asCustomOrientedAlignUpdate $nameSpace ("FK"+$chainJoints[$i]);
/*
		clear $w;
		for ($y=0;$y<99;$y++)
			if (`attributeExists ("w"+$y) ($nameSpace+"FK"+$chainJoints[$i])`)
				$w[$y]=`getAttr ($nameSpace+"FK"+$chainJoints[$i]+".w"+$y)`;
			else
				break;

		if (!size($w))
			xform -ws -t $pos[0] $pos[1] $pos[2] -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"FK"+$chainJoints[$i]);

		if ($i==size($chainJoints)-1)
			asCustomOrientedAlignUpdate $nameSpace ("FK"+$chainJoints[$i]);

		//inbetween, to compute controller rot needed to best align childFK
		if (size($w))
			{
			createNode -n InbetweenIK2FKTarget transform;
			asAlign InbetweenIK2FKTarget ($nameSpace+"FKOffset"+$chainJoints[$i]) 1 1 0 0;
			createNode -n InbetweenIK2FKAimer -p InbetweenIK2FKTarget transform;
			$numChar=size($chainJoints[$i]);
			$sideLess=`substring $chainJoints[$i] 1 ($numChar-2)`;
			$target=`asRlaChild ($nameSpace+$sideLess)`+$side;
			for ($y=0;$y<size($w)+1;$y++)
				{
				createNode -n ("InbetweenIK2FKTarget"+$y) -p InbetweenIK2FKTarget transform;
				if ($y==0)
					orientConstraint InbetweenIK2FKAimer InbetweenIK2FKTarget0;
				else
					{
					parent ("InbetweenIK2FKTarget"+$y) ("InbetweenIK2FKTarget"+($y-1));
					$tempString[0]=`asRlaChild ($nameSpace+$chainJoints[$i])`;
					$partJoint=$nameSpace+$sideLess+"Part1"+$side;
					$pos=`getAttr ($partJoint+".t")`;
					setAttr ("InbetweenIK2FKTarget"+$y+".t") -type float3 $pos[0] $pos[1] $pos[2];

					createNode -n ("InbetweenIK2FKTargetMPD"+$y) multiplyDivide;
					connectAttr InbetweenIK2FKAimer.r ("InbetweenIK2FKTargetMPD"+$y+".input1");
					$value=0.333;
					setAttr ("InbetweenIK2FKTargetMPD"+$y+".input2") -type float3 $value $value $value;
					setAttr ("InbetweenIK2FKTarget"+$y+".displayLocalAxis") 1;
					connectAttr ("InbetweenIK2FKTargetMPD"+$y+".output") ("InbetweenIK2FKTarget"+$y+".r");
					}
				}

			//Analyze $axis 
			$priAxis=`asGetAxis primary ($nameSpace+"FK"+$chainJoints[$i]) ($nameSpace+"Main") 0`;
			$secAxis=`asGetAxis secondary ($nameSpace+"FK"+$chainJoints[$i]) ($nameSpace+"Main") 0`;
			$terAxis=`asGetAxis tertiary ($nameSpace+"FK"+$chainJoints[$i]) ($nameSpace+"Main") 0`;
			$aimVector=`asAxisToVector $priAxis`;
			$upVector=`asAxisToVector $priAxis`;

			delete `aimConstraint -offset 0 0 0 -weight 1 -aimVector $aimVector[0] $aimVector[1] $aimVector[2] -upVector $upVector[0] $upVector[1] $upVector[2] -worldUpType "objectrotation" -worldUpObject $target $target InbetweenIK2FKAimer`;
			parent ("InbetweenIK2FKTarget"+size($w)) InbetweenIK2FKTarget;
			delete `aimConstraint -offset 0 0 0 -weight 1 -aimVector $aimVector[0] $aimVector[1] $aimVector[2] -upVector $upVector[0] $upVector[1] $upVector[2] -worldUpType "objectrotation" -worldUpObject $target ("InbetweenIK2FKTarget"+size($w)) InbetweenIK2FKAimer`;
			$rot=`getAttr InbetweenIK2FKAimer.r`;
			setAttr ($nameSpace+"FK"+$chainJoints[$i]+".r") -type float3 $rot[0] $rot[1] $rot[2];
			delete InbetweenIK2FKTarget;

			//then also match position:
			$pos=`xform -q -ws -t ($nameSpace+"IKX"+$chainJoints[$i])`;
			xform -ws -t $pos[0] $pos[1] $pos[2] ($nameSpace+"FK"+$chainJoints[$i]);
			}
*/
		}
	}

if ($autoKey)
	autoKeyframe -st 1;
if (!$autoKey && $asBakeFKIK)
	autoKeyframe -st 0;
select $sel;
}

global proc asSwitchFKIK (string $name, string $IK, string $side, string $W2K)
{
global string $gPlayBackSlider;
global int $asBakeFKIK;
int $bakeRange=0;
float $timeRangeArray[]=`timeControl -q -rangeArray $gPlayBackSlider`;
if (($timeRangeArray[1]-$timeRangeArray[0])>1)
	{
	$bakeRange=1;
	currentTime $timeRangeArray[0];
	}
float $currentTime=`currentTime -q`;
string $sel[]=`ls -sl`;
//string $nameSpace=`asSelectorResolveNameSpace $name ""`;
//backwards compatibility, 1st arg used to be $name (e.g  \"biped\")
string $nameSpace=`asNameSpaceFromShortUIName $name`;
string $controlCurve=$nameSpace+"FKIK"+$IK+$side;
string $poleCurve=$nameSpace+"Pole"+$IK+$side;
if (!`objExists $controlCurve`)
	error ("Object:\""+$controlCurve+"\" does not exists !");
string $startJoint=`getAttr ($controlCurve+".startJoint")`;
string $middleJoint=`getAttr ($controlCurve+".middleJoint")`;
string $endJoint=`getAttr ($controlCurve+".endJoint")`;
string $chainJoints[],$tempString[],$tempString2[];
string $toesJoint=`asGetToesJoint $nameSpace $endJoint $side`;
//string $qToesJoints[]=`asGetQToesJoints $nameSpace $endJoint $side`;
string $label,$childLabel,$fkLegAim,$legAimRotCmd;
float $legAimRot[];
int $isSplineIK,$numIkCtrls;
if (!`objExists ($nameSpace+"Pole"+$IK+$side)`)
	$isSplineIK=1;
string $requiredObj[]={($nameSpace+"Main"),($nameSpace+"FKX"+$startJoint+$side),($nameSpace+"IKX"+$startJoint+$side),($nameSpace+"IKX"+$middleJoint+$side)};
if ($isSplineIK)
	{
	$chainJoints=`asgetChainJoints ($nameSpace+$startJoint+$side) ($nameSpace+$endJoint+$side)`;
	for ($i=0;$i<size($chainJoints);$i++)
		$chainJoints[$i]=`substitute $nameSpace $chainJoints[$i] ""`;
	for ($i=1;$i<99;$i++)
		{
		if (!`objExists ($nameSpace+"IK"+$IK+$i+$side)`)
			break;
		$numIkCtrls=$i;
		}
	}
else
	$requiredObj=`stringArrayCatenate $requiredObj {($nameSpace+"Pole"+$IK+$side),($nameSpace+"FKX"+$endJoint+$side)}`;
for ($obj in $requiredObj)
	if (!`objExists $obj`)
		error ("Object:\""+$obj+"\" does not exists !");
int $Blend;
int $BlendInverse=10;
int $onOff;
if ($W2K=="FK2IK")
	{
	$Blend=10;
	$BlendInverse=0;
	$onOff=1;
	}

if ($W2K=="FK2IK" && `getAttr ($controlCurve+".FKIKBlend")`>0)
	{
	warning ("Could not switch FK2IK, because \"FKIKBlend\" is not \"0\"\n");
	return;
	}
if ($W2K=="IK2FK" && `getAttr ($controlCurve+".FKIKBlend")`<10)
	{
	warning ("Could not switch IK2FK, because \"FKIKBlend\" is not \"10\"\n");
	return;
	}

//LegAim
print (`objExists ($nameSpace+$startJoint)`+" : "+$startJoint+"\n");
if (`attributeExists legAim ($nameSpace+"IK"+$IK+$side)` && `objExists ($nameSpace+$startJoint)`)
	{
	$tempString=`ls -l ($nameSpace+$startJoint)`;
	tokenize $tempString[0] "|" $tempString;
	for ($i=size($tempString)-1;$i>-1;$i--)
		{
		$label=`asLabel $tempString[$i]`;
		if (`gmatch $label "*LegAim*"`)
			{
			$fkLegAim="FK"+`substitute $nameSpace $tempString[$i] ""`;
			break;
			}
		}
	if ($fkLegAim!="")
		{
		$legAimRot=`xform -q -ws -ro ($nameSpace+$fkLegAim+$side)`;
		$legAimRotCmd="xform -ws -ro "+$legAimRot[0]+" "+$legAimRot[1]+" "+$legAimRot[2]+" "+$nameSpace+$fkLegAim+$side;
		}
	}

int $autoKey=`autoKeyframe -q -st`;
if ($bakeRange && !$autoKey)
	{
	autoKeyframe -e -st 1;
	$autoKey=1;
	}

currentTime (`currentTime -q` -1);
setAttr ($controlCurve+".FKIKBlend") $BlendInverse;


for ($a=0;$a<2;$a++)
	{
	if (!$autoKey && $a==0)
		continue;
	if ($autoKey)
		{
		if (!$isSplineIK)
			{
			setKeyframe ($controlCurve+".FKIKBlend");
	//		setKeyframe ($poleCurve+".follow");	

			setKeyframe ($nameSpace+"FK"+$startJoint+$side+".rotate");
			setKeyframe ($nameSpace+"FK"+$startJoint+$side+".scale");
			setKeyframe ($nameSpace+"FK"+$middleJoint+$side+".translate");
			setKeyframe ($nameSpace+"FK"+$middleJoint+$side+".rotate");
			setKeyframe ($nameSpace+"FK"+$middleJoint+$side+".scale");
			setKeyframe ($nameSpace+"FK"+$endJoint+$side+".translate");
			setKeyframe ($nameSpace+"FK"+$endJoint+$side+".rotate");
			setKeyframe ($nameSpace+"FK"+$endJoint+$side+".scale");
			if (`objExists ($nameSpace+$toesJoint)` && `objExists ($nameSpace+"FKToes"+$side)`)
				setKeyframe ($nameSpace+"FKToes"+$side+".rotate");
			setKeyframe ($nameSpace+"IK"+$IK+$side+".translate");
			setKeyframe ($nameSpace+"IK"+$IK+$side+".rotate");
			setKeyframe ($nameSpace+"IK"+$IK+$side+".scale");
			setKeyframe ($nameSpace+"Pole"+$IK+$side+".translate");
			$tempString=`listAttr -ud ($nameSpace+"IK"+$IK+$side)`;
			for ($i=0;$i<size($tempString);$i++)
				setKeyframe ($nameSpace+"IK"+$IK+$side+"."+$tempString[$i]);
			$tempString=`listAttr -ud ($nameSpace+"Pole"+$IK+$side)`;
			for ($i=0;$i<size($tempString);$i++)
				setKeyframe ($nameSpace+"Pole"+$IK+$side+"."+$tempString[$i]);
//			if (`objExists ($nameSpace+$toesJoint)` && `objExists ($nameSpace+"IKToes"+$side)`)
//				setKeyframe ($nameSpace+"IKToes"+$side+".rotate");
			//also key all child-controls (ik heel/toes/toesEnd/qtoes
			$tempString=`listRelatives -ad -type transform ($nameSpace+"IK"+$IK+$side)`;
			for ($i=0;$i<size($tempString);$i++)
				if (`sets -im ($nameSpace+"ControlSet") $tempString[$i]`)
					{
					setKeyframe ($tempString[$i]+".t");
					setKeyframe ($tempString[$i]+".r");
					//and it`s equivalent FK (qToes)
					$tempString2[0]=`substitute "Roll" $tempString[$i] "FK"`;
					if (`objExists $tempString2[0]`)
						{
						setKeyframe ($tempString2[0]+".t");
						setKeyframe ($tempString2[0]+".r");
						}
					}
			}
		if ($isSplineIK)
			{
			setKeyframe ($controlCurve+".FKIKBlend");
			for ($i=0;$i<size($chainJoints);$i++)
				if (`objExists ($nameSpace+"FK"+$chainJoints[$i])`)
					{
					setKeyframe ($nameSpace+"FK"+$chainJoints[$i]+".t");
					setKeyframe ($nameSpace+"FK"+$chainJoints[$i]+".r");
					}
			for ($i=1;$i<$numIkCtrls+1;$i++)
				{
				if (`objExists ($nameSpace+"IK"+$IK+$i+$side)`)
					{
					setKeyframe ($nameSpace+"IK"+$IK+$i+$side+".t");
					setKeyframe ($nameSpace+"IK"+$IK+$i+$side+".r");
					}
				if (`objExists ($nameSpace+"IKhybrid"+$IK+$i+$side)`)
					{
					setKeyframe ($nameSpace+"IKhybrid"+$IK+$i+$side+".t");
					setKeyframe ($nameSpace+"IKhybrid"+$IK+$i+$side+".r");
					}
				}
/*
			//LegLock
			if (`attributeExists legLock ($nameSpace+"FKRoot_M")`)
				{
				setKeyframe ($nameSpace+"FKRoot_M.legLock");
				if ($a==0)
					{
					if (!$bakeRange)
						print ("// Settting \"FKRoot_M.legLock\" to 0, and \"FK*.bias\" to 10, for improved IK-to-FK-accuracy.\n");
					setKeyframe -t $currentTime -v 0 ($nameSpace+"FKRoot_M.legLock");
					}
				}
			//Bias
			for ($i=0;$i<size($chainJoints);$i++)
				{
				if (`attributeExists bias ($nameSpace+"FK"+$chainJoints[$i])`)
					{
					setKeyframe ($nameSpace+"FK"+$chainJoints[$i]+".bias");
					if ($a==0)
						setKeyframe -t $currentTime -v 10 ($nameSpace+"FK"+$chainJoints[$i]+".bias");
					}
				if (`attributeExists inbetweenVis ($nameSpace+"FK"+$chainJoints[$i])`)
					setAttr ($nameSpace+"FK"+$chainJoints[$i]+".inbetweenVis") 1;
				}
*/
			}
		if ($legAimRotCmd!="")
			setKeyframe ($nameSpace+$fkLegAim+$side+".r");			
		}

	currentTime (`currentTime -q` +1);
	asAlignFKIK $name $IK $side $W2K;
	setAttr ($controlCurve+".FKIKBlend") $Blend;
	if ($legAimRotCmd!="") eval ($legAimRotCmd);
	}

if ($bakeRange)
	{
	$asBakeFKIK=1;
	for ($i=$timeRangeArray[0]+1;$i<$timeRangeArray[1];$i++)
		{
		currentTime $i;
		asAlignFKIK $name $IK $side $W2K;
		}
	$asBakeFKIK=0;
	setKeyframe -t ($timeRangeArray[1]-1) -v $Blend ($controlCurve+".FKIKBlend");
	setKeyframe -t ($timeRangeArray[1]+0) -v $BlendInverse ($controlCurve+".FKIKBlend");
	//only Maya2024 seems to be able to set range, and we loose renage upon setKeyframe cmd, so only Maya2024 will be able to do multi-obj-sel
	catchQuiet (`playbackOptions -sst $timeRangeArray[0] -set ($timeRangeArray[1]-1) -sv true`);
	}

currentTime $currentTime;

if ($bakeRange && !$autoKey)
	autoKeyframe -e -st 0;
//select ($nameSpace+"ControlSet");
//delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1;
//removed, since this sometimes deletes non-static channels e..g IKLeg_L animation
select $sel;
}

global proc asCustomOrientedAlignUpdate (string $nameSpace, string $ctrl)
{
float $rot[];
string $customOrient=$nameSpace+"CustomOrient"+$ctrl;
string $tempString[];

if (!`objExists $customOrient`)
	return;

$tempString=`listRelatives -p $customOrient`;
createNode -n asCustomOrientWithRotateOrder -p $tempString[0] transform;
setAttr asCustomOrientWithRotateOrder.rotateOrder `getAttr ($nameSpace+$ctrl+".rotateOrder")`;
orientConstraint $customOrient asCustomOrientWithRotateOrder;

$rot=`xform -q -os -ro asCustomOrientWithRotateOrder`;
delete asCustomOrientWithRotateOrder;
xform -r -os -ro $rot[0] $rot[1] $rot[2] ($nameSpace+$ctrl);

//Mirrored Translate via Scale -1
if (`getAttr ($customOrient+".sx")`<0)
	{
	$rot=`xform -q -ws -ro ($nameSpace+$ctrl)`;
	setAttr ($customOrient+".s") -type float3 1 1 1;
	xform -ws -ro $rot[0] $rot[1] $rot[2] ($nameSpace+$ctrl);
	setAttr ($customOrient+".s") -type float3 -1 -1 -1;
	//extra step for IK (worldorient) ctrls, as they have rotation on the customOrient node
	if (`attributeExists worldorient ($nameSpace+$ctrl)`)
		if (`getAttr ($nameSpace+$ctrl+".worldorient")`)
			{
			$rot=`xform -q -os -ro $customOrient`;
			rotate -r -os $rot[0] $rot[1] $rot[2] ($nameSpace+$ctrl);
			}
	}
}

global proc asSetCustomAttrToDefault (string $ctrl)
{
string $attrs[]=`listAttr -ud ($ctrl)`;

for ($i=0;$i<size($attrs);$i++)
	{
	if (`getAttr -type ($ctrl+"."+$attrs[$i])`=="string")
		continue;//skip any custom added string attributes
	if (!`getAttr -settable ($ctrl+"."+$attrs[$i])`)
		continue;//skip any non settable attributes
	if (!`getAttr -keyable ($ctrl+"."+$attrs[$i])`)
		continue;//skip any non keyable attributes		
	$tempFloat=`attributeQuery -listDefault -n ($ctrl) $attrs[$i]`;
	//special case, prior to v 6.261, PoleLeg_R.follow did not have it`s -DV set to 10
	if (`gmatch $ctrl "*PoleLeg*"` && $attrs[$i]=="follow")
		$tempFloat[0]=10;
	setAttr ($ctrl+"."+$attrs[$i]) $tempFloat[0];
	}
}

global proc string asGetToesJoint (string $nameSpace,string $endJoint,string $side)
{
string $toesJoint,$childLabel;
string $tempString[],$tempString2[],$tempStringShort[];

if (!`objExists ($nameSpace+$endJoint)`)
	return $toesJoint;
	
//-f added in 5.911, which caused fail,new fix in 5.9413
$tempString     =`listRelatives -f -type joint -ad ($nameSpace+$endJoint)`;
$tempStringShort=`listRelatives    -type joint -ad ($nameSpace+$endJoint)`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (`getAttr ($tempString[$i]+".drawLabel")`)
		{
		$childLabel=`getAttr ($tempString[$i]+".otherType")`;
		if (`gmatch $childLabel "*Toes*"` && !`gmatch $childLabel "*QToes*"` && !`gmatch $childLabel "*ToesEnd*"`)
			{
			$tempString3[0]=`substitute $nameSpace $tempStringShort[$i] ""`;
			if (`objExists ($nameSpace+"FK"+$tempString3[0]+$side)`)
				$toesJoint=$tempString3[0];
			}
		}
	}

return $toesJoint;
}

global proc string[] asGetQToesJoints (string $nameSpace,string $endJoint,string $side)
{
string $childLabel;
string $qToesJoints[],$tempString[],$tempString2[],$tempString3[],$tempString4[],$tempStringShort[];

if (!`objExists ($nameSpace+$endJoint)`)
	return $qToesJoints;

//-f added in 5.911, which caused fail,new fix in 5.9413
$tempString     =`listRelatives -f -type joint -ad ($nameSpace+$endJoint)`;
$tempStringShort=`listRelatives    -type joint -ad ($nameSpace+$endJoint)`;
for ($y=0;$y<size($tempString);$y++)
	{
	if (`getAttr ($tempString[$y]+".drawLabel")`)
		{
		$childLabel=`getAttr ($tempString[$y]+".otherType")`;
		if (`gmatch $childLabel "*QToes*"`)
			{
			$tempString2[0]=`substitute $nameSpace $tempStringShort[$y] ""`;
			if (`objExists ($nameSpace+"FK"+$tempString2[0]+$side)`)
				{
				$tempString3=`ls -l ($nameSpace+$tempString2[0])`;
				tokenize $tempString3[0] "|" $tempString4;
				for ($z=size($tempString4)-1;$z>-1;$z--)
					{
					if ($tempString4[$z]==($nameSpace+$endJoint))
						break;
					$qToesJoints[size($qToesJoints)]=`substitute $nameSpace $tempString4[$z] ""`;
					}
				}
			}
		}
	}

return $qToesJoints;
}

global proc string[] asgetChainJoints (string $startJoint, string $endJoint)
{
int $startJointIsParentNr;
string $chainJoints[];
string $tempString[]=`ls -l $endJoint`;
tokenize $tempString[0] "|" $tempString;
for ($i=size($tempString)-1;$i>-1;$i--)
	{
	$startJointIsParentNr=$i;
	if ($tempString[$i]==$startJoint)
		{
		break;
		}
	}
for ($i=$startJointIsParentNr;$i<size($tempString);$i++)
	$chainJoints[size($chainJoints)]=$tempString[$i];
return $chainJoints;
}

global proc asPopulateNameSpaceMenu (string $name)
{
string $optionMenu=$name+"OptionMenu";
string $nameSpacesList[]=`namespaceInfo -r -lon`;
string $menuArray[];
$nameSpacesList=`stringArrayRemove {"UI"} $nameSpacesList`;
$nameSpacesList[size($nameSpacesList)]="";
string $itemList[]=`optionMenu -q -ils $optionMenu`;
$nameSpacesList=`sort $nameSpacesList`;

if (`asHotKeyCheck "asPopulateNameSpaceMenu \"\""`) return;

for ($item in $itemList)
	deleteUI $item;

for ($nameSpace in $nameSpacesList)
	if (`attributeExists "version" ($nameSpace+":Main")` || `attributeExists "version" ($nameSpace+":FaceGroup")`)
		if (`asFilterCheck $name $nameSpace`)
			menuItem -p $optionMenu -l ($nameSpace+":");

if (!`optionMenu -q -ni ($name+"OptionMenu")`)
	{
	if ($name=="bodySetup" || `gmatch $name "asPoser*"`)
		menuItem -p $optionMenu -l "None";
	else
		menuItem -p $optionMenu -l ":";
	}
	
asNameSpaceChange $name;
}

global proc int asFilterCheck (string $name, string $nameSpace)
{
int $return=0;
string $filterString=`optionVar -q ("asSelectorFilter_"+$name)`;
if ($filterString=="" || $filterString=="0")
	return 1;
string $references[]=`file -q -r`;
for ($i=0;$i<size($references);$i++)
	{
	$refNameSpace=`file -q -ns $references[$i]`;
	if ($refNameSpace==$nameSpace)
		if (`gmatch $references[$i] $filterString`)
			$return=1;
	}
return $return;
}

global proc asFilterNameSpaceMenuUI (string $name)
{
string $filterString=`optionVar -q ("asSelectorFilter_"+$name)`;

if (`asHotKeyCheck "asFilterNameSpaceMenuUI \"\""`) return;

if ($filterString=="0")
	$filterString="";
if (`window -q -ex ("SelectorFilter_"+$name)`)
	deleteUI ("SelectorFilter_"+$name);
window ("SelectorFilter_"+$name);
columnLayout;
textFieldGrp -tx $filterString -cc ("asSetFilterNameSpaceMenu "+$name) -l "Reference File Filter. (e.g. *characters*)" -cw 1 200 ("asSelectorFilterTextFieldGrp_"+$name);
showWindow;
}

global proc asSetFilterNameSpaceMenu (string $name)
{
string $filterString=`textFieldGrp -q -tx ("asSelectorFilterTextFieldGrp_"+$name)`;
optionVar -sv ("asSelectorFilter_"+$name) $filterString;
asPopulateNameSpaceMenu $name;
asSetFilterUpdateWindowTitle $name;
}

global proc asSetFilterUpdateWindowTitle (string $name)
{
string $newTitle,$oldTitle;
string $filterString=`optionVar -q ("asSelectorFilter_"+$name)`;
string $tempString[];

if (`window -q -ex $name`) $oldTitle=`window -q -t $name`;
if (`workspaceControl -q -ex ($name+"WorkspaceControl")`) $oldTitle=`workspaceControl -q -l ($name+"WorkspaceControl")`;

tokenize $oldTitle $tempString;
$oldTitle=$tempString[0];
$newTitle=$oldTitle;
if ($filterString!="" && $filterString!="0")
	$newTitle+=" filter:"+$filterString;
if (`window -q -ex $name`)
	window -e -t $newTitle $name;
if (`workspaceControl -q -ex ($name+"WorkspaceControl")`)
	workspaceControl -e -l $newTitle ($name+"WorkspaceControl");
}

global proc asSetNameSpaceFromSelection (string $uiName)
{
asPopulateNameSpaceMenu $uiName;
string $sel[]=`ls -sl`;
string $tempString[],$ils[];
if (size($sel))
	{
	tokenize $sel[0] ":" $tempString;
	$ils=`optionMenu -q -ils ($uiName+"OptionMenu")`;
	for ($i=0;$i<size($ils);$i++)
		if (`menuItem -q -l $ils[$i]`==($tempString[0]+":"))
			{
			optionMenu -e -sl ($i+1) ($uiName+"OptionMenu");
			asSelChange;
			}
	}
print "// Setting nameSpace from selected object\n";
}

global proc asPopulateReplaceMenu (string $uiName)
{
int $enable,$numMenuItems;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $refNodeFile,$basename,$filePath,$refNodeNameSpace,$cmd;
string $menuItems[]=`lsUI -menuItems`;
//string $refFiles[]=`file -q -r`;
string $refNodes[]=`ls -type reference`;
string $tempString[];

//First remove all old submenus
for ($i=0;$i<size($menuItems);$i++)
	if (`gmatch $menuItems[$i] "asSelectorbipedFileReplaceSub*"`)
		deleteUI $menuItems[$i];


for ($i=0;$i<size($refNodes);$i++)
	{
	if ($refNodes[$i]=="sharedReferenceNode")
		continue;
	$refNodeNameSpace=`referenceQuery -namespace $refNodes[$i]`;
	if (`substitute ":" $refNodeNameSpace ""`!=`substitute ":" $nameSpace ""`)
		continue;
	$refNodeFile=`referenceQuery -filename $refNodes[$i]`;
	//strip off {1} that gets appended to $refNodeFile if user manually "replace reference"
	if (`gmatch $refNodeFile "*{*"`)
		{
		tokenize $refNodeFile "{" $tempString;
		$refNodeFile=$tempString[0];
		}
//	$basename=`basenameEx $refNodeFile`;
	$basename=`substitute ":" $refNodeNameSpace ""`;
	$filePath=`asStripPath $refNodeFile 1`;
	$tempString=`getFileList -fld $filePath -fs ($basename+"*.mb")`;
	for ($y=0;$y<size($tempString);$y++)
		{
		$enable=1;
		if ($refNodeFile==$filePath+$tempString[$y])
			$enable=0;
		$cmd="file -loadReference "+$refNodes[$i]+"  \""+$filePath+$tempString[$y]+"\";";

		menuItem -p ($uiName+"FileReplaceMenuItem") -l $tempString[$y] -enable $enable -c $cmd asSelectorbipedFileReplaceSub;
		$numMenuItems++;
		}
	}
//if ($numMenuItems<2)
//	menuItem -p asSelectorbipedFileReplaceMenuItem -boldFont 1 -l "(Published Multi Files will appear here)" asSelectorbipedFileReplaceSub;
}

global proc string asPoserGetCmd (string $uiName, int $anim)
{
global string $gChannelBoxName;
global string $gMainProgressBar;
string $cmd,$nameSpace;
int $weightedTangents[];
int $onlyOneObj,$onlyOneAttr;
string $connectObj;
string $controls[],$buffer[],$controlSets[];
string $sel[]=`ls -sl`;
string $selectedMainAttrs[]=`channelBox -q -sma $gChannelBoxName`;
string $selectedShapeAttrs[]=`channelBox -q -ssa $gChannelBoxName`;
string $selectedHistoryAttrs[]=`channelBox -q -sha $gChannelBoxName`;
string $selectedOutputAttrs[]=`channelBox -q -soa $gChannelBoxName`;
string $selectedAttrs[],$animCurves[];
$selectedAttrs=`stringArrayCatenate $selectedMainAttrs $selectedShapeAttrs`;
$selectedAttrs=`stringArrayCatenate $selectedAttrs $selectedHistoryAttrs`;
$selectedAttrs=`stringArrayCatenate $selectedAttrs $selectedOutputAttrs`;
int $ctrlButton,$altButton;
if ((`getModifiers`/4) %  2)
	$ctrlButton=1;
if ((`getModifiers`/8) %  2)
	$altButton=1;
int $onlySel=`checkBox -q -v asPoserOnlySel`;

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;

if (!$onlySel && !size($controlSets))
	error "No ControlSets";

//determine the name for poserAnimFile
string $animationFile,$animationFilePath;
string $gridOrder[];
int $childNum;
$gridOrder=`gridLayout -q -go ($uiName+"GridLayout")`;
for ($i=1;$i<size($gridOrder)+1;$i++)
	if (`gmatch $gridOrder[$i-1] "asPoser*"`)
		$childNum=$i;
$childNum++;
$animationFile="untitled_"+$childNum;
$animationFilePath=`asGetTempDirectory`+"AdvancedSkeleton/Poser/untitled/";

if ($onlySel)
	{
	for ($i=$y=0;$i<size($sel);$i++)
		{
		if (`gmatch $sel[$i] ($nameSpace+"*")`)
			{
			tokenize $sel[$i] ":" $buffer;
			$controls[$y]=$buffer[size($buffer)-1];
			$y++;
			}
		}
	}
else
	{
	if (!`objExists $controlSets[0]`)
		error ("Object :\""+$controlSets[0]+"\" does not exists !\n");
	$controls=`sets -q $controlSets`;
	for ($i=0;$i<size($controls);$i++)
		$controls[$i]=`substitute $nameSpace $controls[$i] ""`;
	}
string $attrs[];
if (size($controls)<1)
	error "No Controls Available!";
evalDeferred ("progressBar -e -ep "+$gMainProgressBar);
progressBar -e -st "Storing Data" -bp -ii 1 -min 0 -max (size($controls)) $gMainProgressBar;
select -cl;

if ($anim)
	{
	createNode -n poserAnimationInfo transform;
	addAttr -ln "cmd" -dt "string" poserAnimationInfo;
	select poserAnimationInfo;
	}

for ($obj in $controls)
	{
	progressBar -e -s 1 $gMainProgressBar;
	if (`progressBar -q -ic $gMainProgressBar`)
		error "Interrupted";
	$allKeyableAttrs=`listAttr -k -m -sn ($nameSpace+$obj)`;
	if ($onlySel && (size($selectedAttrs)>0))
		$attrs=$selectedAttrs;
	else
		$attrs=$allKeyableAttrs;
	for ($attr in $attrs)
		for ($allKeyableAttr in $allKeyableAttrs)
			{
			if (`getAttr -l ($nameSpace+$obj+"."+$attr)`)
				continue;
			if ($attr==$allKeyableAttr)
				{
				if (!$anim)
					$cmd+=$obj+"."+$attr+" "+`getAttr ($nameSpace+$obj+"."+$attr)`+";";
				else
					{
					//Animation
					$animCurves=`listConnections -type animCurve -s 1 -d 0 ($nameSpace+$obj+"."+$attr)`;
					for ($y=0;$y<size($animCurves);$y++)
						{
						select -add $animCurves[$y];
						$cmd+="connectAttr "+$animCurves[$y]+".output "+$obj+"."+$attr+";";
						}
					}
				}
			}
	}

if ($anim)
	{
	setAttr -type "string" poserAnimationInfo.cmd $cmd;
	if (!`file -q -ex $animationFilePath`)
		sysFile -md $animationFilePath;
	file -f -op "v=0" -typ "mayaAscii" -es ($animationFilePath+$animationFile+".ma");
	delete poserAnimationInfo;
	}

if ($cmd!="")
	{
	if (!$anim)
		$cmd="asSetAttrs "+$uiName+" \""+$cmd+"\"";
	else
		$cmd="asLoadAttrs "+$uiName;
	}

select $sel;
return $cmd;
}

global proc asCopyToClipBoard (string $uiName, int $anim)
{
global string $gChannelBoxName;
global string $gMainProgressBar;
string $sel[]=`ls -sl`;
string $selectedMainAttrs[]=`channelBox -q -sma $gChannelBoxName`;
string $selectedShapeAttrs[]=`channelBox -q -ssa $gChannelBoxName`;
string $selectedHistoryAttrs[]=`channelBox -q -sha $gChannelBoxName`;
string $selectedOutputAttrs[]=`channelBox -q -soa $gChannelBoxName`;
string $selectedAttrs[],$animCurves[];
$selectedAttrs=`stringArrayCatenate $selectedMainAttrs $selectedShapeAttrs`;
$selectedAttrs=`stringArrayCatenate $selectedAttrs $selectedHistoryAttrs`;
$selectedAttrs=`stringArrayCatenate $selectedAttrs $selectedOutputAttrs`;
int $ctrlButton,$altButton;
if ((`getModifiers`/4) %  2)
	$ctrlButton=1;
if ((`getModifiers`/8) %  2)
	$altButton=1;
int $onlySel;

if (`asHotKeyCheck ("asCopyToClipBoard \"\" "+$anim)`) return;

if ($altButton || $ctrlButton)
	$onlySel=1;
string $nameSpace,$cmd;
string $controls[],$buffer[];
int $weightedTangents[];
int $onlyOneObj,$onlyOneAttr;
string $connectObj;
string $controlSets[];

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

$controls=`sets -q $controlSets`;
if (!$onlySel && !size($controlSets))
	error "No ControlSets";

//determine the name for animFile
string $animationFile,$animationFilePath;
$animationFile="ClipBoard"+$anim;
$animationFilePath=`asGetTempDirectory`+"AdvancedSkeleton/Selector/";

if ($onlySel)
	{
	for ($i=$y=0;$i<size($sel);$i++)
		{
		if (`gmatch $sel[$i] ($nameSpace+"*")`)
			{
			tokenize $sel[$i] ":" $buffer;
			$controls[$y]=$buffer[size($buffer)-1];
			$y++;
			}
		}
	}
else
	{
	if (!`objExists $controlSets[0]`)
		error ("Object :\""+$controlSets[0]+"\" does not exists !\n");
	$controls=`sets -q $controlSets`;
	for ($i=0;$i<size($controls);$i++)
		$controls[$i]=`substitute  $nameSpace $controls[$i] ""`;
	}
string $attrs[];
if (size($controls)<1)
	error "No Controls Available!";
evalDeferred ("progressBar -e -ep "+$gMainProgressBar);
progressBar -e -st "Storing Data" -bp -ii 1 -min 0 -max (size($controls)) $gMainProgressBar;

createNode -n poserAnimationInfo transform;
addAttr -ln "cmd" -dt "string" poserAnimationInfo;
select poserAnimationInfo;

for ($obj in $controls)
	{
	progressBar -e -s 1 $gMainProgressBar;
	if (`progressBar -q -ic $gMainProgressBar`)
		error "Interrupted";
	$allKeyableAttrs=`listAttr -k -m -sn ($nameSpace+$obj)`;
	if ($onlySel && (size($selectedAttrs)>0))
		$attrs=$selectedAttrs;
	else
		$attrs=$allKeyableAttrs;
	for ($attr in $attrs)
		for ($allKeyableAttr in $allKeyableAttrs)
			{
			if (`getAttr -l ($nameSpace+$obj+"."+$attr)`)
				continue;
			if ($attr==$allKeyableAttr)
				{
				if (!$anim)
					$cmd+="setAttr "+$obj+"."+$attr+" "+`getAttr ($nameSpace+$obj+"."+$attr)`+";";
				if ($anim)
					{
					//Animation
					$animCurves=`listConnections -type animCurve -s 1 -d 0 ($nameSpace+$obj+"."+$attr)`;
					for ($y=0;$y<size($animCurves);$y++)
						{
						select -add $animCurves[$y];
						$cmd+="connectAttr "+$animCurves[$y]+".output "+$obj+"."+$attr+";";
						}
					}
				}
			}
	}

setAttr -type "string" poserAnimationInfo.cmd $cmd;
if (!`file -q -ex $animationFilePath`)
	sysFile -md $animationFilePath;
file -f -op "v=0" -typ "mayaAscii" -es ($animationFilePath+$animationFile+".ma");
delete poserAnimationInfo;

select $sel;
}

global proc asDeleteStaticChannels (string $uiName)
{
string $nameSpace;
string $sel[]=`ls -sl`;
string $controlSets[];

if (`asHotKeyCheck ("asDeleteStaticChannels \"\"")`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

if (`confirmDialog -title "Confirm" -message 
	("Clean animation ?\n"
	+"This will delete static channels,\n"
	+"which means remove all animation where the value is not changing")
    -button "Yes" -button "No" -defaultButton "Yes"
    -cancelButton "No" -dismissString "No"`!="Yes")
	return;

select $controlSets;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";
print ("// Static channels cleaned\n");
select $sel;
}

global proc asSetAttrs (string $uiName, string $cmds)
{
int $ctrlButton,$altButton;
if ((`getModifiers`/4) %  2)
	$ctrlButton=1;
if ((`getModifiers`/8) %  2)
	$altButton=1;
string $buffer[],$buffer2[];
string $objAttr;
float $value;
int $numTok=`tokenize $cmds ";" $buffer`;
int $showWarning;
string $warningMsg="The following attributes can not be set:";

for ($i=0;$i<$numTok;$i++)
	{
	tokenize $buffer[$i] $buffer2;
	$objAttr=$buffer2[0];
	$value=$buffer2[1];
	$objAttr=`asPoserResolveNameSpace $uiName $objAttr`;
	if (($ctrlButton||$altButton) && `gmatch $objAttr "*Main.*"`)
		continue;
	if (`objExists $objAttr`)
		catch (`eval ("setAttr "+$objAttr+" "+$value)`);
	else
		{
		$showWarning=1;
		$warningMsg+=$objAttr+",";
		}
	}
if ($showWarning)
	warning $warningMsg;
}

global proc asLoadAttrs (string $uiName, int $childNum)
{
global int $asPoserChildNum;
$asPoserChildNum=$childNum;
evalDeferred -lp ("$asPoserChildNum=0;");
asPasteFromClipBoard $uiName 1;
}

global proc asPasteFromClipBoard (string $uiName, int $anim)
{
global int $asPoserChildNum;
$childNum=$asPoserChildNum;
$asPoserChildNum=0;
int $autoKey=`autoKeyframe -q -st`;
int $shiftButton,$ctrlButton,$altButton;
float $value;
if (`getModifiers` %  2)
	$shiftButton=1;
if ((`getModifiers`/4) %  2)
	$ctrlButton=1;
if ((`getModifiers`/8) %  2)
	$altButton=1;
float $timeOffset=0;
if ($shiftButton)
	$timeOffset=`currentTime -q`;
string $nameSpace,$cmd,$obj,$attr,$objAttr,$connectSourceObjAttr,$newAnimCurve,$clipBoardFile,$projectName;
string $buffer[],$buffer2[],$buffer3[],$tempString[],$controlSets[];
string $sel[]=`ls -sl`;

if (`asHotKeyCheck ("asPasteFromClipBoard \"\" "+$anim)`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

if ($autoKey)
	autoKeyframe -e -st 0;

if ($childNum==0)
	{
	$projectName="Selector";
	$clipBoardFile=`asGetTempDirectory`+"AdvancedSkeleton/Selector/ClipBoard"+$anim+".ma";
	}
else
	{
	string $icon=`iconTextButton -q -i ($uiName+"IconTextButton"+$childNum)`;
	string $tempString[];
	tokenize $icon "/" $tempString;
	$projectName=$tempString[size($tempString)-2];
	$clipBoardFile=`substitute "[.][a-z][a-z][a-z]" $icon ".ma"`;
	}
if (!`file -q -ex $clipBoardFile`)
	error ("CLipboard file:\""+$clipBoardFile+"\" not found");

file -r -type "mayaAscii" -namespace $projectName -options "v=0;p=17" $clipBoardFile;

string $cmds=`getAttr ($projectName+":poserAnimationInfo.cmd")`;
int $numTok=`tokenize $cmds ";" $buffer`;
int $showWarning;
string $warningMsg="The following attributes can not be set:";
createNode -n tempXform transform;
for ($i=0;$i<$numTok;$i++)
	{
	tokenize $buffer[$i] $buffer2;
	$cmd=$buffer2[0];
	if ($cmd=="setAttr")
		{
		$objAttr=$buffer2[1];
		$value=$buffer2[2];
		}
	if ($cmd=="connectAttr")
		{
		$objAttr=$buffer2[2];
		$connectSourceObjAttr=$buffer2[1];
		}
	tokenize $objAttr "." $buffer3;
	$obj=$buffer3[0];
	$attr=$buffer3[1];
	if (($ctrlButton||$altButton) && `gmatch ($nameSpace+$objAttr) "*Main.*"`)
		continue;
	if (`objExists ($nameSpace+$objAttr)`)
		{
		if ($cmd=="setAttr")
			catch (`eval ("setAttr "+$nameSpace+$objAttr+" "+$value)`);
		if ($cmd=="connectAttr")
			{
			if (!`attributeExists $attr tempXform`)
				addAttr -k 1 -ln $attr -at double tempXform;
			connectAttr -f ($projectName+":"+$connectSourceObjAttr) ("tempXform."+$attr);
			copyKey -time ":" -hierarchy none -at $attr tempXform;
			pasteKey -option merge -copies 1 -connect 0 -timeOffset $timeOffset -floatOffset 0 -valueOffset 0 {($nameSpace+$objAttr)};
			}
		}
	else
		{
		$showWarning=1;
		$warningMsg+=$nameSpace+$objAttr+",";
		}
	}
if ($showWarning)
	warning $warningMsg;

if (`objExists tempXform`)
	delete tempXform;
file -rr $clipBoardFile;
select $sel;
if ($autoKey)
	autoKeyframe -e -st 1;
}

global proc asKeyAttrs (string $uiName, string $cmds)
{
int $ctrlButton,$altButton;
if ((`getModifiers`/4) %  2)
	$ctrlButton=1;
if ((`getModifiers`/8) %  2)
	$altButton=1;
string $buffer[],$buffer2[],$spaceBuffer[];
string $objAttr,$previousObjAttr,$restOfBuffers;
float $time,$value,$currentValue;
float $currentTime=`currentTime -q`;
int $numTok=`tokenize $cmds ";" $buffer`;
int $showWarning,$firstValueSet;
string $warningMsg="The following attributes can not be keyed:";
float $firstValue;
for ($i=0;$i<$numTok;$i++)
	{
	tokenize $buffer[$i] $buffer2;
	$objAttr=$buffer2[0];
	$objAttr=`asPoserResolveNameSpace $uiName $objAttr`;
	$restOfBuffers="";
	if ($objAttr!=$previousObjAttr)
		$firstValueSet=0;
	$previousObjAttr=$objAttr;
	for ($y=1;$y<size($buffer2);$y++)
		$restOfBuffers+=$buffer2[$y]+" ";
	if (`objExists $objAttr`)
		{
		tokenize $restOfBuffers $spaceBuffer;
		for ($y=0;$y<size($spaceBuffer);$y++)
			{
			//TimeOffset
			if ($spaceBuffer[$y]=="-t" && ($ctrlButton||$altButton))
				{
				$time=$spaceBuffer[$y+1];
				$spaceBuffer[$y+1]=$time+$currentTime;
				}
			//ValueOffset
			if ($spaceBuffer[$y]=="-v" && $ctrlButton)
				{
				$value=$spaceBuffer[$y+1];
				$currentValue=`getAttr $objAttr`;
				if (!$firstValueSet)
				$firstValue=$value;
				$firstValueSet=1;
				$spaceBuffer[$y+1]=$value+$currentValue-$firstValue;
				}
			}
		$restOfBuffers="";
		for ($y=0;$y<size($spaceBuffer);$y++)
			$restOfBuffers+=$spaceBuffer[$y]+" ";
		eval ($restOfBuffers+$objAttr);
		}
	else
		{
		$showWarning=1;
		$warningMsg+=$objAttr+",";
		}
	}
if ($showWarning)
	warning $warningMsg;
}

global proc asPoseView (string $uiName, int $childNum)
{
string $icon=`iconTextButton -q -i ($uiName+"IconTextButton"+$childNum)`;
int $anim=`rowColumnLayout -q -ann ($uiName+"RowColumnLayout"+$childNum)`;
string $tempString[];
tokenize $icon "/" $tempString;
string $projectName=$tempString[size($tempString)-2];

string $mediaFile;
if ($anim)
	$mediaFile=`substitute "[.][a-z][a-z][a-z]" $icon ".avi"`;
else
	$mediaFile=`substitute "[.][a-z][a-z][a-z]" $icon ".png"`;
print ("// "+$mediaFile+"\n");
system ("load "+$mediaFile);
}

global proc asPoseObjects (string $uiName, string $button,string $action)
{
string $cmd=`iconTextButton -q -c $button`;
string $buffer[],$buffer2[];
string $objAttr,$value;
tokenize $cmd "\"" $buffer;
$cmd=$buffer[1];
int $numTok=`tokenize $cmd ";" $buffer`;
int $showWarning;
string $warningMsg="The following objects can not be found:";
if ($action==" select -add")
select -cl;
for ($i=0;$i<$numTok;$i++)
	{
	tokenize $buffer[$i] $buffer2;
	$objAttr=$buffer2[0];
	$value=$buffer2[1];
	tokenize $objAttr "." $buffer2;
	$obj=$buffer2[0];
	if ($action!=" select -add")
		$obj=$objAttr;
	$obj=`asPoserResolveNameSpace $uiName $obj`;
	if (`objExists $obj`)
		eval ($action+" "+$obj);
	else
		{
		$showWarning=1;
		$warningMsg+=$obj+",";
		}
	}
if ($showWarning)
	warning $warningMsg;
}

global proc asMirrorOptions (string $uiName)
{
if (`asHotKeyCheck ("asMirrorOptions \"\"")`) return;

if (`window -q -ex asMirrorOptions`)
	deleteUI asMirrorOptions;
window -t "Mirror Options" asMirrorOptions;
columnLayout -adj 1;
	separator -h 25 -st "none";
	rowLayout -nc 4 -cw 1 40;
		text -l "side:";
		radioCollection asMOSideRadioCollection;
		radioButton -label "Swap" asMOSideFlip;
		radioButton -label "Right To Left" asMOSideR2L;
		radioButton -label "Left To Right" asMOSideL2R;
		setParent..;
	rowLayout -nc 4 -cw 1 40;
		text -l "axis:";
		radioCollection asMOAxisRadioCollection;
		radioButton -label "X" asMOAxisX;
		radioButton -label "Y" asMOAxisY;
		radioButton -label "Z" asMOAxisZ;
		radioCollection -e -sl "asMOAxisX" asMOAxisRadioCollection;
		setParent..;
	rowLayout -nc 4 -cw 1 40;
		text -l "space:";
		radioCollection asMOSpaceRadioCollection;
		radioButton -label "World" asMOSpaceWorld;
		radioButton -label "Main" asMOSpaceMain;
		radioButton -label "RootX_M" asMOSpaceCenter;
		radioCollection -e -sl "asMOSpaceWorld" asMOSpaceRadioCollection;
		setParent..;
	rowLayout -nc 4 -cw 1 40;
		text -l "control:";
		radioCollection asMOSelOnlyRadioCollection;
		radioButton -label "All" asMOSelOnlyAll;
		radioButton -label "Selected" asMOSelOnlySel;
		radioCollection -e -sl "asMOSelOnlyAll" asMOSelOnlyRadioCollection;
		setParent..;

separator -st "none" -h 25;
button -w 100 -l "Mirror" -c ("asMirror \""+$uiName+"\"");
showWindow;

string $optionVars[]={"asMOSide","asMOSpace","asMOAxis","asMOSelOnly"};
string $cia[];
string $radioCollection,$selected,$optionVarString;
for ($i=0;$i<size($optionVars);$i++)
	{
	$radioCollection=$optionVars[$i]+"RadioCollection";
	$cia=`radioCollection -q -cia $radioCollection`;
	$selected=$cia[0];
	if (`optionVar -ex $optionVars[$i]`)
		{
		$optionVarString=`optionVar -q $optionVars[$i]`;
		for ($y=0;$y<size($cia);$y++)
			if (`gmatch $cia[$y] ("*"+$optionVarString)`)
				$selected=`optionVar -q $optionVars[$i]`;
		}
	radioCollection -e -sl $selected $radioCollection;
	}
}

global proc asMirror (string $uiName)
{
int $axesZMinusY;
string $side="asMOSideR2L";
string $space="asMOSpaceMain";
string $axis="asMOAxisX";
string $selOnly="asMOSelOnlyAll";
string $nameSpace;
string $sel[]=`ls -sl`;
string $controls[];

string $controlSets[],$sortedControls[];

if (`asHotKeyCheck ("asMirror \"\"")`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

if (!size($controlSets))
	error "No controlSets detected. select a controller";

if (`attributeExists primaryAxis FitSkeleton` && `attributeExists secondaryAxis FitSkeleton`)
	if (`getAttr FitSkeleton.primaryAxis`==2 && `getAttr FitSkeleton.secondaryAxis`==4)
		$axesZMinusY=1;

if (`window -q -ex asMirrorOptions`)
	{
	$side=`radioCollection -q -sl asMOSideRadioCollection`;
	$space=`radioCollection -q -sl asMOSpaceRadioCollection`;
	$axis=`radioCollection -q -sl asMOAxisRadioCollection`;
	$selOnly=`radioCollection -q -sl asMOSelOnlyRadioCollection`;
	optionVar -sv asMOSide $side;
	optionVar -sv asMOSpace $space;
	optionVar -sv asMOAxis $axis;
	optionVar -sv asMOSelOnly $selOnly;
	}
if (`optionVar -ex asMOSide`)
	$side=`optionVar -q asMOSide`;
if (`optionVar -ex asMOSpace`)
	$space=`optionVar -q asMOSpace`;
if (`optionVar -ex asMOAxis`)
	$axis=`optionVar -q asMOAxis`;
if (`optionVar -ex asMOSelOnly`)
	$selOnly=`optionVar -q asMOSelOnly`;

$controls=`sets -q $controlSets`;
if ($selOnly=="asMOSelOnlySel")
	$controls=$sel;
$controls=`sort $controls`;//first alphanum sort, so e.g.IKhybridSpline1 comes before 2

for ($i=0;$i<size($controls);$i++)
	if ($controls[$i]==($nameSpace+"Main"))
		$sortedControls={($nameSpace+"Main"),($nameSpace+"RootX_M"),($nameSpace+"RootExtraX_M")};

for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IKhybrid*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

//End-SplineIk before mid, as mid are inbetw Start/End, Here First For Spine (as other limbs could be attached to Spine)
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IK*Spine*")`)
		if (`attributeExists stiff $controls[$i]`)
			$sortedControls[size($sortedControls)]=$controls[$i];

//as other limbs could be attached to Spine
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IK*Spine*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"FK*Spine*")` || $controls[$i]==$nameSpace+"FKRoot_M" || $controls[$i]==$nameSpace+"FKChest_M")
		$sortedControls[size($sortedControls)]=$controls[$i];

//End-SplineIk before mid, as mid are inbetw Start/End, Here First For After
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IK*")`)
		if (!`gmatch $controls[$i] ($nameSpace+"IK*Spine*")`)
			if (`attributeExists stiff $controls[$i]`)
				$sortedControls[size($sortedControls)]=$controls[$i];

//commented out in v 6.5473, as it cause issues with Dragon Neck
/*
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IKSpline*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];
*/
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"Pivot*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IK*Leg*")` || `gmatch $controls[$i] ($nameSpace+"IK*Arm*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"Pole*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"Roll*Heel*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"Roll*ToesEnd*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"Roll*Toes*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

for ($x=10;$x>0;$x--)
	for ($i=0;$i<size($controls);$i++)
		if (`gmatch $controls[$i] ($nameSpace+"Roll*"+$x+"*")`)
			$sortedControls[size($sortedControls)]=$controls[$i];

for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"IK*Toes_*")`)
		$sortedControls[size($sortedControls)]=$controls[$i];

for ($i=0;$i<size($controls);$i++)
	if (!`stringArrayCount $controls[$i] $sortedControls`)
		$sortedControls[size($sortedControls)]=$controls[$i];

$controls=$sortedControls;

string $allKeyableAttrs[],$tempString[];
string $source,$dest,$destAttr,$cmd,$loc1,$loc2;
float $pos[3],$rot[3],$pos2[3],$rot2[3],$wsScales[3];
int $wsXform[];
int $flip,$isFaceControl,$isClusterControl,$isClusterLocalOrientControl,$wsXformAttr;
string $flipAxis,$t0;
if ($axis=="asMOAxisX")
	{$flipAxis="X";$t0="tx";}
if ($axis=="asMOAxisY")
	{$flipAxis="Y";$t0="ty";}
if ($axis=="asMOAxisZ")
	{$flipAxis="Z";$t0="tz";}

createNode -n flipGroup transform;
if ($space=="asMOSpaceCenter")
	parent flipGroup ($nameSpace+"RootX_M");
if ($space=="asMOSpaceMain")
	if (`objExists ($nameSpace+"Main")`)
		parent flipGroup ($nameSpace+"Main");
xform -os -t 0 0 0 -ro 0 0 0 flipGroup;
if ($space=="asMOSpaceCenter" || $space=="asMOSpaceMain")
	if (`objExists ($nameSpace+"Main")`)
		parent -w flipGroup;
for ($i=0;$i<size($controls);$i++)
	{
	if (`gmatch $controls[$i] "*Extra*"` && `objExists asControlOrientDetachParentHolder`)
		continue;
	if ($side!="asMOSideFlip")
		if (`gmatch $controls[$i] "*_M"` || `gmatch $controls[$i] "*Main"`)
			continue;
	if ($side=="asMOSideR2L")
		{
		if (`gmatch $controls[$i] "*_L"`)
			continue;
		$dest=`substitute "_R" $controls[$i] "_L"`;
		}
	else if ($side=="asMOSideL2R")
		{
		if (`gmatch $controls[$i] "*_R"`)
			continue;
		$dest=`substitute "_L" $controls[$i] "_R"`;
		}
	else if ($side=="asMOSideFlip")
		{
		if (!`gmatch $controls[$i] "*_L"` && !`gmatch $controls[$i] "*_R"` && !`gmatch $controls[$i] "*_M"`)
			continue;
		if (`gmatch $controls[$i] "*FKExtraSpine1_M"`)
			continue;
		if (`gmatch $controls[$i] "*_L"`)
			$dest=`substitute "_L" $controls[$i] "_R"`;
		if (`gmatch $controls[$i] "*_R"`)
			$dest=`substitute "_R" $controls[$i] "_L"`;
		if (`gmatch $controls[$i] "*_M"`)
			$dest=$controls[$i];
		}
	if (!`objExists $dest`)
		continue;
	$isFaceControl=0;
	if (`objExists ($nameSpace+"FaceControlSet")`)
		if (`sets -im ($nameSpace+"FaceControlSet") $controls[$i]`)
			$isFaceControl=1;
	$isClusterControl=$isClusterLocalOrientControl=0;
	$tempString=`ls -l $controls[$i]`;
	if (`gmatch $tempString[0] "*CustomSystem|*"`)
		$isClusterControl=1;
	if ($isClusterControl)
		if (`attributeExists localOrient $controls[$i]`)
			$isClusterLocalOrientControl=`getAttr ($controls[$i]+".localOrient")`;
	$source=$controls[$i];
	$allKeyableAttrs=`listAttr -k -m -sn $controls[$i]`;
	for ($y=0;$y<size($allKeyableAttrs);$y++)
		{
		$destAttr=$allKeyableAttrs[$y];
		if ($destAttr=="v") continue;
		if (!`attributeExists $allKeyableAttrs[$y] $dest`) continue;//no matching attr on other side
		if			(`gmatch $destAttr "*_R*"`) $destAttr=`substitute "_R" $destAttr "_L"`;
		else if (`gmatch $destAttr "*_L*"`) $destAttr=`substitute "_L" $destAttr "_R"`;		
		$flip=1;

		// due to new //Mirrored translation, this now only applies to old rigs, detected by non-ws -1 scale
		$wsScales=`xform -q -ws -s $dest`;
		if ($wsScales[2]>0)
			{
			if (`gmatch $controls[$i] ($nameSpace+"FK*_L")` || `gmatch $controls[$i] ($nameSpace+"FK*_R")`
			 || `gmatch $controls[$i] ($nameSpace+"Bend*_L")` || `gmatch $controls[$i] ($nameSpace+"Bend*_R")`
			 || `gmatch $controls[$i] ($nameSpace+"Micro*_L")` || `gmatch $controls[$i] ($nameSpace+"Micro*_R")`
			 || `attributeExists ikLocal $controls[$i]`
			 || $isClusterLocalOrientControl)
			 	{
			 	if ($destAttr=="tx" || $destAttr=="ty" || $destAttr=="tz")
			 		$flip=-1;
			 	}
			else
				{
				if ($destAttr=="tz" || $destAttr=="rx" || $destAttr=="ry")
					$flip=-1;
			 	if ($axesZMinusY)
			 		{
			 		$flip=1;
					if ($destAttr=="tx" || $destAttr=="ry" || $destAttr=="rz")
						$flip=-1;
					}
				}
			}

		if ($isFaceControl)
			$flip=1;
/*
		if (($controls[$i]==$nameSpace+"Eye_R" || $controls[$i]==$nameSpace+"Eye_L") && $destAttr== "ry")
			$flip=-1;//special case for eyes, as we dont need `crosseyed`
*/
		$wsXformAttr=0;
		if ($wsScales[2]>0)
			if (`gmatch $controls[$i] ($nameSpace+"IK*")` || `gmatch $controls[$i] ($nameSpace+"Pole*")`
			|| `gmatch $controls[$i] ($nameSpace+"Roll*")` || `gmatch $controls[$i] ($nameSpace+"Pivot*")`
			|| `gmatch $controls[$i] ($nameSpace+"RootX_M*")` || ($isClusterControl && !$isClusterLocalOrientControl))
				if ((!`gmatch $controls[$i] ($nameSpace+"IKLocal*")`) && !`attributeExists ikLocal $controls[$i]`)
					if (!`gmatch $controls[$i] ($nameSpace+"IKhybrid*")`)
//						if (!`gmatch $controls[$i] ($nameSpace+"IK*Toes*")`)
//							if (`getAttr ($controls[$i]+".rotateOrder")`==0)//other IK ctrls oriented as FK e.g. IKFingers1 on quadrupeds
								//changed to utilize the IKLocal attribute
								$wsXform[$i]=1;

		if (`gmatch $controls[$i] ($nameSpace+"Aim*")`)
			continue;
		if ($destAttr=="tx" || $destAttr=="ty" || $destAttr=="tz"
			||$destAttr=="rx" || $destAttr=="ry" || $destAttr=="rz")
			if ($wsXform[$i])
				$wsXformAttr=1;
		if (!$wsXformAttr)
			if (`getAttr -se ($dest+"."+$destAttr)`)
				$cmd+="setAttr "+$dest+"."+$destAttr+" "+(`getAttr ($source+"."+$allKeyableAttrs[$y])`*$flip)+";";
		}

	if ($wsXform[$i])
		{
		$tempString=`spaceLocator`;
		$loc1=$tempString[0];
		$tempString=`spaceLocator`;
		$loc2=$tempString[0];
		parent $loc2 $loc1;
		parent $loc1 $source;
		xform -os -t 0 0 0 -ro 0 0 0 $loc1;
		setAttr ($loc1+".rotateOrder") `getAttr ($source+".rotateOrder")`;
		setAttr ($loc2+".rotateOrder") `getAttr ($source+".rotateOrder")`;
		setAttr ("flipGroup.scale"+$flipAxis) 1;
		parent $loc1 flipGroup;
		setAttr ("flipGroup.scale"+$flipAxis) -1;
		setAttr ($loc1+".scaleX") -1;
		$pos=`xform -q -ws -t $loc2`;
		$rot=`xform -q -ws -ro $loc2`;
		$pos2=`getAttr ($source+".t")`;
		$rot2=`getAttr ($source+".r")`;
		$cmd+="xform -ws -t "+$pos[0]+" "+$pos[1]+" "+$pos[2]+" -ro "+$rot[0]+" "+$rot[1]+" "+$rot[2]+" "+$dest+";";
		}

	if (`attributeExists "mirror" $controls[$i]`)
		setAttr ($controls[$i]+".mirror") 0;
	}
delete flipGroup;
if ($cmd!="")
	eval ($cmd);
select $sel;
}

global proc asGoToBuildPoseOptions (string $nameSpace, string $controlSet)
{
if (`objExists asGoToBuildPoseOptions`)
	delete asGoToBuildPoseOptions;
createNode -n asGoToBuildPoseOptions transform;
addAttr -ln nameSpace -dt "string" asGoToBuildPoseOptions;
setAttr -type "string" asGoToBuildPoseOptions.nameSpace $nameSpace;
addAttr -ln controlSet -dt "string" asGoToBuildPoseOptions;
setAttr -type "string" asGoToBuildPoseOptions.controlSet $controlSet;
asGoToBuildPose bodySetup;
}

global proc asGoToBuildPose (string $uiName)
{
int $ctrlButton,$asGoingToTPose,$skipGoingToTPose;
if ((`getModifiers`/4) %  2)
	$ctrlButton=1;
float $dv;
float $pos[],$rot[];
string $nameSpace,$m,$expString,$side;
string $controlSets[],$failedCmds[],$tPoseRequiredObjs[];
string $sel[]=`ls -sl`;

if (`objExists asGoingToTPose`)
	{
	$asGoingToTPose=1;
	delete asGoingToTPose;
	}

if (`asHotKeyCheck "asGoToBuildPose \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

if (`objExists asGoToBuildPoseOptions`)
	{
	$nameSpace=`getAttr asGoToBuildPoseOptions.nameSpace`;
	$controlSets[0]=`getAttr asGoToBuildPoseOptions.controlSet`;
	delete asGoToBuildPoseOptions;
	}

string $buildPose="buildPose";
if (`gmatch $controlSets[0] "*FaceControlSet"`)
    $buildPose="faceBuildPose";

string $tempString[],$tempString2[],$buffer[];
string $setAttrCmd,$cmd;


$setAttrCmd=`getAttr ($nameSpace+$buildPose+".udAttr")`;
if (`attributeExists udExtraAttr ($nameSpace+$buildPose)`)
	$setAttrCmd+=`getAttr ($nameSpace+$buildPose+".udExtraAttr")`;
tokenize $setAttrCmd ";" $tempString;
for ($y=0;$y<size($tempString);$y++)
	{
	$cmd=$tempString[$y];
	if ($cmd=="")
		continue;
	if ($nameSpace!="")
		{
		tokenize $cmd $buffer;
		if (`gmatch $cmd "xform*"`)
			$substituteWordNr=size($buffer)-1;
		else
			$substituteWordNr=1;
		$cmd="";
		for ($z=0;$z<size($buffer);$z++)
			{
			if ($z==$substituteWordNr)
				$cmd+=$nameSpace;
			$cmd+=$buffer[$z]+" ";
			}
		}
	if ($ctrlButton)
		if (`gmatch $cmd "*Main.*"`)
			continue;
	if (catchQuiet (`eval ($cmd)`))
		{
		warning ("Failed: "+$cmd+"\n");
		$failedCmds[size($failedCmds)]=$cmd;
		}
	}

//Tpose
if ($asGoingToTPose)
	{
	$tPoseRequiredObjs={"FKExtraHip","FKExtraKnee","FKExtraAnkle","FKExtraShoulder","FKExtraElbow","FKExtraWrist",
		"IKExtraLeg","PoleExtraLeg"};
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  $side="_R";
		if ($b==-1) $side="_L";

		for ($i=0;$i<size($tPoseRequiredObjs);$i++)
			if (!`objExists ($nameSpace+$tPoseRequiredObjs[$i]+$side)`)
				{
				warning ("Required node: \""+$nameSpace+$tPoseRequiredObjs[$i]+$side+"\" Not Found, Unable to go to Tpose");
				$skipGoingToTPose=1;
				break;
				}
		if ($skipGoingToTPose)
			break;

		xform -ws -ro 0 -90 ((-90*$b)+2) ($nameSpace+"FKExtraHip"+$side);
		xform -ws -ro 0 -90 ((-90*$b)-2) ($nameSpace+"FKExtraKnee"+$side);
		xform -ws -ro (90*$b) 0 (-90*$b) ($nameSpace+"FKExtraAnkle"+$side);
		xform -ws -ro (-90*$b) 0 180 ($nameSpace+"FKExtraShoulder"+$side);
		xform -ws -ro (-90*$b) 0 180 ($nameSpace+"FKExtraElbow"+$side);
		xform -ws -ro (-90*$b) 0 180 ($nameSpace+"FKExtraWrist"+$side);

		//IK-Leg
		asAlignIK2FK $nameSpace {("FKIKLeg"+$side)};
		$pos=`xform -q -os -t  ($nameSpace+"IKLeg"+$side)`;
		$rot=`xform -q -os -ro ($nameSpace+"IKLeg"+$side)`;
		xform -os -t $pos[0] $pos[1] $pos[2] -ro $rot[0] $rot[1] $rot[2] ($nameSpace+"IKExtraLeg"+$side);
		xform -os -t 0 0 0 -ro 0 0 0 ($nameSpace+"IKLeg"+$side);
		//PoleLeg
		$pos=`xform -q -os -t  ($nameSpace+"PoleLeg"+$side)`;
		xform -os -t $pos[0] $pos[1] $pos[2] ($nameSpace+"PoleExtraLeg"+$side);
		xform -ws -ro 0 0 0 ($nameSpace+"PoleExtraLeg"+$side);
		xform -os -t 0 0 0 ($nameSpace+"PoleLeg"+$side);

		//IK-Arm
		asAlignIK2FK $nameSpace {("FKIKArm"+$side)};
		//PoleArm
		xform -os -t 0 0 0 ($nameSpace+"PoleArm"+$side);
		$pos=`xform -q -ws -t  ($nameSpace+"IKArm"+$side)`;
		xform -ws -t $pos[0] $pos[1] $pos[2] ($nameSpace+"PoleExtraArm"+$side);
		setAttr ($nameSpace+"PoleExtraArm"+$side+".tx") 0;
		setAttr ($nameSpace+"PoleExtraArm"+$side+".tz") 0;
		xform -ws -ro 0 0 0 ($nameSpace+"PoleExtraArm"+$side);
		}
	}

//mh
if (`objExists ($nameSpace+"GRP_faceGUI")`)
	{
	$tempString=`listRelatives -ad -type transform ($nameSpace+"GRP_faceGUI")`;
	for ($i=0;$i<size($tempString);$i++)
		{
		if (`gmatch $tempString[$i] "*CTRL_faceGUI*"`)//main top node comes with default offsets that should not reset
			continue;
		if (`gmatch $tempString[$i] "*CTRL_*"`)
			{
			$tempString2=`listAttr -k $tempString[$i]`;
			for ($y=0;$y<size($tempString2);$y++)
				{
				if (!`getAttr -se ($tempString[$i]+"."+$tempString2[$y])`)
					continue;
				$dv=0;
				if (`gmatch $tempString2[$y] "scale*"` || $tempString2[$y]=="visibility")
					$dv=1;
				setAttr ($tempString[$i]+"."+$tempString2[$y]) $dv;
				}
			}
		}
	}

//run
string $run,$fitTopNode,$objAttr;
for ($i=0;$i<size($controlSets);$i++)
	{
	if (`gmatch $controlSets[$i] "*ControlSet"`)
		if (`objExists ($nameSpace+"FitSkeleton")`)
			$fitTopNode=$nameSpace+"FitSkeleton";
	if (`gmatch $controlSets[$i] "*FaceControlSet"`)
		$fitTopNode=($nameSpace+"FaceFitSkeleton");
	}

//expressions (wheel & rollingBall)
$tempString=`ls -type expression`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (!`gmatch $tempString[$i] "*WheelExpression_*"`)
		continue;
	$tempString2=`listConnections -s 0 -d 1 -type transform $tempString[$i]`;
	for ($y=0;$y<size($tempString2);$y++)
		{
		if (!`attributeExists reset $tempString2[$y]`)
			continue;
		setAttr ($tempString2[$y]+".reset") 1;
		currentTime `currentTime -q`;
		setAttr ($tempString2[$y]+".reset") 0;
		}
	}

if (`objExists $fitTopNode`)
	if (`attributeExists "run" $fitTopNode`)
		{
		$run=`getAttr ($fitTopNode+".run")`;
		if ($run!="")
			{
			if ($nameSpace=="")
				{
//				catch (`eval ($run)`);
				tokenize $run ";" $tempString;
				for ($y=0;$y<size($tempString);$y++)
					{
					$cmd=$tempString[$y];
					if ($cmd=="")
						continue;
					if (catchQuiet (`eval ($cmd)`))
						{
						warning ("Failed: "+$cmd+"\n");
						$failedCmds[size($failedCmds)]=$cmd;
						}
					}
				}
			else
				{
				tokenize $run ";" $tempString;
				for ($i=0;$i<size($tempString);$i++)
					{
					tokenize $tempString[$i] $tempString2;
					$objAttr=`substitute "\"" $tempString2[1] ""`;
					$objAttr=`substitute "\"" $objAttr ""`;
					$cmd=$tempString2[0]+" "+$nameSpace+$objAttr+" "+$tempString2[2]+";";
					catch (`eval ($cmd)`);
					}
				}
			}
		}

if (size($failedCmds) && ($uiName=="bodySetup" || $uiName=="faceSetup")) // not avaible from Selector/Picker as file is likly referenced-in
	{
	$m="The following commands failed,\n( Possibly these are controllers that have been removed)\nRemove these commands from the Pose-command ?\n\n";
	for ($i=0;$i<size($failedCmds);$i++)
		{
		$m+=$failedCmds[$i]+"\n";
		if ($i==25)
			{
			$m+="\n...And "+`size($failedCmds)`+" more..";
			break;
			}
		}
	if (`confirmDialog -t Confirm -m $m -b "Ok, Remove" -b "Cancel" -db "Ok"`=="Ok, Remove")
		asUpdatePoseAttributes;
	}
}

global proc asGoToTPose (string $uiName)
{
if (`asHotKeyCheck "asGoToTPose \"\""`) return;
string $sel[]=`ls -sl`;
createNode -n asGoingToTPose transform;
select $sel;
asGoToBuildPose $uiName;
}

global proc asPoserupdateGridBlock (string $uiName, int $childNum)
{
string $existingPopUpMenus[]=`control -q -pma ($uiName+"IconTextButton"+$childNum)`;
for ($pop in $existingPopUpMenus)
	deleteUI $pop;

int $anim=`rowColumnLayout -q -ann ($uiName+"RowColumnLayout"+$childNum)`;
string $button=$uiName+"IconTextButton"+$childNum;
string $viewCmd="asPoseView "+$uiName+" "+$childNum;
string $selectCmd="asPoseObjects "+$uiName+" "+$button+"\" select -add\"";
string $keyCmd="asPoseObjects "+$uiName+" "+$button+" setKeyframe";
string $linearKeyCmd="asPoseObjects "+$uiName+" "+$button+" \"setKeyframe -itt linear -ott linear\"";

popupMenu -p ($uiName+"IconTextButton"+$childNum);
	menuItem -l "View" -c $viewCmd;
	if (!$anim)
		{
		menuItem -d 1;
		menuItem -l "Select" -c $selectCmd;
		menuItem -l "Key" -c $keyCmd;
		menuItem -l "LinearKey" -c $linearKeyCmd;
		}
	if ($uiName=="asPoserDefault")
		{
		menuItem -d 1;
		menuItem -l "Label Button" -c ("asPoserRename "+$childNum);
		menuItem -l "Remove Button" -c ("asPoserDeletePose "+$uiName+" "+$childNum);
		menuItem -l "Update icon" -c ("asPoserSnapShoot "+$uiName+" "+$childNum+" "+$anim+" 1 0");
		if ($anim)
			menuItem -l "Update movie" -c ("asPoserSnapShoot "+$uiName+" "+$childNum+" "+$anim+" 0 1");
		}
}

global proc asSelectAllShapeComponents (string $node)
{
string $shapes[];

if (`objExists $node`==0)
	return;

string $nodeType=`nodeType $node`;
if ($nodeType=="mesh" || $nodeType=="nurbsCurve" || $nodeType=="bezierCurve" || $nodeType=="nurbsSurface" || $nodeType=="lattice" || $nodeType=="particle")
	$shapes[0]=$node;
else
	$shapes=`listRelatives -s -ni -f $node`;

string $components[];
int $c=0;

for ($i=0;$i<size($shapes);$i++)
	{
	string $shape=$shapes[$i];
	string $type=`nodeType $shape`;

	if ($type=="mesh")
		$components[$c++]=$shape+".vtx[*]";
	else if ($type=="nurbsCurve" || $type=="bezierCurve")
		$components[$c++]=$shape+".cv[*]";
	else if ($type=="nurbsSurface")
		$components[$c++]=$shape+".cv[*][*]";
	else if ($type=="lattice")
		$components[$c++]=$shape+".pt[*][*][*]";
	else if ($type=="particle")
		$components[$c++]=$shape+".pt[*]";
	}

if (size($components))
	select -r $components;
}

global proc string asPoserResolveNameSpace (string $uiName, string $obj)
{
string $nameSpace=`optionMenu -q -v ($uiName+"OptionMenu")`;
if ($nameSpace==":")
	$nameSpace="";
return ($nameSpace+$obj);
}

global proc asDynRemove (string $uiName)
{
string $sel[]=`ls -sl`;
string $dynAttrs[]={"blend","baseGoal","tipGoal","conserve"};
string $tempString[];
string $nameSpace,$dynObj,$restoreCmd;

if (`asHotKeyCheck "asDynRemove \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;

if (!size($sel))
	error ("nothing selected");
for ($i=0;$i<size($sel);$i++)
	if (!`gmatch $sel[$i] ($nameSpace+"FK*")`)
		error ($sel[$i]+" is not a FK control");
for ($i=0;$i<size($sel);$i++)
	{
	$dynObj="dynamics"+`substitute ($nameSpace) $sel[$i] ""`;
	if(`objExists $dynObj`)
		{
		if (`attributeExists restoreCmd $dynObj`)
			$restoreCmd+=`getAttr ($dynObj+".restoreCmd")`;
		delete $dynObj;
		for ($y=0;$y<size($dynAttrs);$y++)
			if (`attributeExists $dynAttrs[$y] $sel[$i]`)
				deleteAttr ($sel[$i]+"."+$dynAttrs[$y]);
		$tempString=`listRelatives -c Dynamics`;
		if (!size($tempString))
			delete Dynamics;
		print ("// Dynamics for "+$sel[$i]+" removed\n");
		}
	else
		print ("// No dynamics for "+$sel[$i]+" found\n");
	}

if ($restoreCmd!="")
	{
	print "// restoring OPM (offsetParentMatrix) rig connections:\n";
	evalEcho ($restoreCmd);
	}
}

global proc asDynAddHairSystem (string $uiName)
{
float $pos[];
string $nameSpace,$offsetNode,$dynTopJoint,$nucleus;
string $sel[]=`ls -sl`;
string $tempString[],$allBefore[],$allAfter[];

if (`asHotKeyCheck "asDynAddHairSystem \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;

asDynAdd $uiName;
$tempString=`ls -sl`;
$ctrlWithDynAttrs=$tempString[0];
$name=`substitute $nameSpace $ctrlWithDynAttrs ""`;
$dynTopNode="dynamics"+$name;

$tempString=`listRelatives -c -type transform $dynTopNode`;
for ($i=0;$i<size($tempString);$i++)
	if (`gmatch $tempString[$i] "*Offset"`)
		$offsetNode=$tempString[$i];

$tempString=`ls -type nucleus`;
if ($tempString[0]!="")
	$nucleus=$tempString[0];

$tempString=`listRelatives -c -type joint$offsetNode`;
$dynTopJoint=$tempString[0];

delete ("DynCurveSoft"+$name);
select ("DynCurve"+$name);
$allBefore=`ls -as`;
makeCurvesDynamic 2 { "1", "0", "1", "1", "0"};
$allAfter=`ls -as`;
select $allAfter;
select -d $allBefore;
$tempString=`ls -sl`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (`gmatch $tempString[$i] "hairSystem[0-9]"`) rename $tempString[$i] ("hairSystem"+$name);
	if (`gmatch $tempString[$i] "nucleus*"`) {rename $tempString[$i] ("nucleus"+$name);$nucleus="nucleus"+$name;}
	if (`gmatch $tempString[$i] "hairSystem[0-9]OutputCurves"`) rename $tempString[$i] ("hairSystemOutputCurves"+$name);
	}
$tempString=`listRelatives -c -type transform ("hairSystemOutputCurves"+$name)`;
rename $tempString[0] ("hair"+$name);
$tempString=`listRelatives -c -type transform $dynTopNode`;
for ($i=0;$i<size($tempString);$i++)
	if (`gmatch $tempString[$i] "follicle*"`) rename $tempString[$i] ("follicle"+$name);

parent ("hairSystem"+$name) $nucleus ("hair"+$name) $dynTopNode;
parent $dynTopJoint $dynTopNode;
parent ("follicle"+$name) $dynTopJoint $offsetNode;
delete ("hairSystemOutputCurves"+$name);

setAttr ("hairSystem"+$name+".overrideEnabled") 1;
setAttr ("hairSystem"+$name+".overrideColor") 17;

//access to various dynamics nodes,
//pointConstraint $ctrlWithDynAttrs ("nucleus"+$name);
parent ("DynCurve"+$name) $offsetNode;
setAttr ("follicle"+$name+".t") -type float3 0 0 0;
setAttr ("follicle"+$name+".r") -type float3 0 0 0;
delete `pointConstraint $ctrlWithDynAttrs ("follicle"+$name)`;
$pos=`getAttr ("follicle"+$name+".t")`;
move -r -os -wd 0 (`mag<<$pos[0],$pos[1],$pos[2]>>`*-0.5) 0 ("follicle"+$name);
//hairSystem Shape node under follicle transform, for easier access
select ("hairSystem"+$name);
pickWalk -d down;
select -add ("follicle"+$name);
parent -s;
delete ("hairSystem"+$name);

//deleting Dynamics-Controllers
delete ("DynLocs"+$name);
for ($i=0;$i<size($sel);$i++)
	{
	if (`attributeExists baseGoal $sel[$i]`) deleteAttr ($sel[$i]+".baseGoal");
	if (`attributeExists tipGoal $sel[$i]`) deleteAttr ($sel[$i]+".tipGoal");
	if (`attributeExists conserve $sel[$i]`) deleteAttr ($sel[$i]+".conserve");
	}



setAttr ("follicle"+$name+".pointLock") 1;
connectAttr -f ("hair"+$name+".worldSpace[0]") ("DynIKCurve"+$name+".create");
currentTime 0;
select $ctrlWithDynAttrs;
}

global proc asCtrlDynAdd (string $uiName) 
{
float $pos[];
string $msg,$name,$dynTopNode,$nameSpace,$exp,$standinAttr;
string $sel[]=`ls -sl`;
string $dynAttrs[]={"goal","conserve"};//"blend"
string $tempString[],$tempString2[],$shapes[],$dups[],$animCurveConnections[];

if (`asHotKeyCheck "asCtrlDynAdd \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;

currentTime 0;

if (!`objExists "Dynamics"`)
	createNode -n Dynamics transform;

for ($i=0;$i<size($sel);$i++)
	{
	$name=`substitute $nameSpace $sel[$i] ""`;
	$pos=`xform -q -ws -t $sel[$i]`;
	$animCurveConnections=`listConnections -s 1 -d 0 -c 1 -p 1 -type animCurve $sel[$i]`;

	$dynTopNode="dynamics"+$name;
	if (`objExists $dynTopNode`) delete $dynTopNode;
	if (`objExists ($name+"Expression")`) delete ($name+"Expression");
	createNode -n $dynTopNode -p Dynamics transform;

	//holds existing animation/transforms
	createNode -n ("Offset"+$name) -p $dynTopNode transform;
	createNode -n ("Standin"+$name) -p ("Offset"+$name) transform;
	$tempString=`listRelatives -p $sel[$i]`;
	if ($tempString[0]!="")
		parentConstraint $tempString[0] ("Offset"+$name);

	for ($y=0;$y<size($animCurveConnections);$y=$y+2)
		{
		tokenize $animCurveConnections[$y] "[.]" $tempString;
		if (`gmatch $tempString[1] "translate*"`)
			{
			connectAttr -f $animCurveConnections[$y+1] ("Standin"+$animCurveConnections[$y]);
			disconnectAttr $animCurveConnections[$y+1] $animCurveConnections[$y];
			}
		}

	particle -n ("DynParticle"+$name) -p $pos[0] $pos[1] $pos[2];
	parent ("DynParticle"+$name) $dynTopNode;
	goal -g ("Standin"+$name) -w 0.5 -useTransformAsGoal 1 ("DynParticle"+$name);
	setAttr ("DynParticle"+$name+".particleRenderType") 4;
	setAttr ("DynParticle"+$name+".v") 0;

	for ($y=0;$y<size($dynAttrs);$y++)
		if (!`attributeExists $dynAttrs[$y] $sel[$i]`)
			addAttr -k 1 -ln $dynAttrs[$y] -at double -min 0 -max 1 -dv 0.8 $sel[$i];
	setAttr ($sel[$i]+".goal") 0.7;
	setAttr ($sel[$i]+".conserve") 0.8;
	connectAttr ($sel[$i]+".conserve") ("DynParticle"+$name+".conserve");
	connectAttr ($sel[$i]+".goal") ("DynParticle"+$name+".goalWeight[0]");

	//DynXform
	createNode -n ("Dyn"+$name) -p $dynTopNode transform;
	$exp =("float $pos[]=`getParticleAttr -at worldPosition DynParticle"+$name+".pt[0]`;\n");
	$exp+=("Dyn"+$name+".tx=$pos[0];\n");
	$exp+=("Dyn"+$name+".ty=$pos[1];\n");
	$exp+=("Dyn"+$name+".tz=$pos[2];\n");
	expression -n  ($name+"Expression") -s $exp -o $sel[$i] -ae 1 -uc all;
	pointConstraint ("Dyn"+$name) $sel[$i];

	//showTarget
	if (!`attributeExists showTarget $sel[$i]`)
		addAttr -k 1 -ln showTarget -at bool -dv 1 $sel[$i];
	connectAttr ($sel[$i]+".showTarget") ("Standin"+$name+".v");
	$dups=`duplicate -rr $sel[$i]`;

	$shapes=`listRelatives -s -f $dups[0]`;
	for ($y=0;$y<size($shapes);$y++)
		{
		$shapes[$y]=`rename $shapes[$y] ("Standin"+$name+"Shape")`;
		parent -add -s $shapes[$y] ("Standin"+$name);
		catchQuiet (`setAttr ($shapes[$y]+".overrideEnabled") 1`);
		catchQuiet (`setAttr ($shapes[$y]+".overrideColor") 17`);
		asSelectAllShapeComponents $shapes[$y];
		if (size(`ls -sl`))
			scale -r -p $pos[0] $pos[1] $pos[2] 1.15 1.15 1.15;
		}
	delete $dups[0];
	}

select $sel;
print "// Dynamics added.\n";
}

global proc asDynAdd (string $uiName) 
{
int $numCv,$form,$spans,$degrees,$numChar,$opm;
int $jointDepth[];
float $pos[],$posA[],$posB[],$bbMin[],$bbMax[],$locScale[],$m[];
$m[0]=$m[5]=$m[10]=$m[15]=1;//idMatrix
string $sel[]=`ls -sl`;
string $selLong[]=`ls -sl -l`;
string $tempString[],$dynJoints[],$sorted[],$defJoints[],$dynJoints[],$deleteObjs[],$locs[],$defJointsCtrl[];
string $defJoint,$fitJoint,$side,$sideLess,$curveCmd,$name,$nameSpace,$dynTopNode,$parent,$restoreCmd;

if (`asHotKeyCheck "asDynAdd \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;

if (`attributeExists useOffsetParentMatrix ($nameSpace+"FitSkeleton")`)
	$opm=`getAttr ($nameSpace+"FitSkeleton.useOffsetParentMatrix")`;

//sort
if ($opm)
	{
	//opm hierarchy is flat, so use FitSkeleton for sorting
	for ($i=0;$i<size($sel);$i++)
		{
		$defJoint=`substitute ($nameSpace+"FK") $sel[$i] ($nameSpace)`;
		tokenize $defJoint "_" $tempString;
		$fitJoint=$tempString[0];
		for ($y=1;$y<size($tempString)-1;$y++)
			$fitJoint+="_"+$tempString[$y];
		if (!`objExists $fitJoint`)
			error ("Unable to find FitJoint for:\""+$sel[$i]+"\".\n");
		$tempString=`ls -l $fitJoint`;
		$jointDepth[$i]=`tokenize $tempString[0] "|" $tempString`;
		}
	for ($y=0;$y<9999;$y++)
		{
		for ($i=0;$i<size($sel);$i++)
			if ($jointDepth[$i]==$y)
				$sorted[size($sorted)]=$sel[$i];
		if (size($sorted)==size($sel))
			break;
		}
	}
else
	//sort by lenght of `long` name, to sort by parents befor children
	for ($y=0;$y<9999;$y++)
		{
		for ($i=0;$i<size($sel);$i++)
			if (size($selLong[$i])==$y)
				$sorted[size($sorted)]=$sel[$i];
		if (size($sorted)==size($sel))
			break;
		}

for ($i=0;$i<size($sorted);$i++)
	{
	$defJoint="";
	if (`gmatch $sorted[$i] ($nameSpace+"FK*")`)
		$defJoint=`substitute ($nameSpace+"FK") $sorted[$i] ($nameSpace)`;
	if (!`objExists $defJoint`)
		error ("Unable to find DeformJoint for:\""+$sorted[$i]+"\".\n");
	$defJoints[size($defJoints)]=$defJoint;
	$defJointsCtrl[size($defJointsCtrl)]=$sorted[$i];

	//include part joints
	$numChar=size($defJoint);
	$side=`substring $defJoint ($numChar-1) $numChar`;
	$sideLess=`substring $defJoint 1 ($numChar-2)`;
		for ($y=1;$y<99;$y++)
		{
		if (`objExists ($sideLess+"Part"+$y+$side)`)
			{
			$defJoints[size($defJoints)]=($sideLess+"Part"+$y+$side);
			//inbetween has "FK-Part-Ctrls" e.g. FKTail1Part2_M, but twist/bendy does not
			if (`objExists ("FK"+$sideLess+"Part"+$y+$side)`)
				$defJointsCtrl[size($defJointsCtrl)]=("FK"+$sideLess+"Part"+$y+$side);
			else
				$defJointsCtrl[size($defJointsCtrl)]=$sorted[$i];
			}
		else
			break;
		}
	}
//include `end joint`
$tempString=`listRelatives -c -type joint $defJoints[size($defJoints)-1]`;
if ($tempString[0]!="")
	{
	$defJoints[size($defJoints)]=$tempString[0];
	$defJointsCtrl[size($defJointsCtrl)]=$defJointsCtrl[size($defJointsCtrl)-1];
	}

$name=`substitute $nameSpace $defJointsCtrl[0] ""`;
$dynTopNode="dynamics"+$name;

if (!size($sel))
	error ("nothing selected");
if (`objExists $dynTopNode`)
	error ("Object \""+$dynTopNode+"\" already exists. Delete this first, if you wish to make a new one.");

$deleteObjs={("DynParticleArrayMapper"+$name),("DynParticleRamp"+$name),("DynIKEffector"+$name)};
for ($i=0;$i<size($deleteObjs);$i++)
	if (`objExists ($nameSpace+$deleteObjs[$i])`)
		delete ($nameSpace+$deleteObjs[$i]);

if (!`objExists "Dynamics"`)
	createNode -n Dynamics transform;
createNode -n $dynTopNode -p Dynamics transform;

$curveCmd="curve -d 1 ";
for ($i=0;$i<size($defJoints);$i++)
	{
	$pos=`xform -q -ws -t $defJoints[$i]`;
	$curveCmd+=" -p "+$pos[0]+" "+$pos[1]+" "+$pos[2]+" ";
	}
$tempString[0]=`eval ($curveCmd)`;
rename $tempString[0] ("DynCurve"+$name);
parent ("DynCurve"+$name) $dynTopNode;

//soft
$tempString=`soft -d -g 1 -c ("DynCurve"+$name)`;
rename $tempString[0] ("DynParticle"+$name);
$tempString=`listRelatives -p ("DynParticle"+$name)`;
rename $tempString[0] ("DynCurveSoft"+$name);
rename ("copyOfDynCurve"+$name)  ("DynCurve"+$name);
parent ("DynCurveSoft"+$name) $dynTopNode;
setAttr ("DynCurve"+$name+".v") 0;
setAttr ("DynCurveSoft"+$name+".dispCV") 1;

//locs
createNode -n ("DynLocs"+$name) -p $dynTopNode transform;
for ($i=0;$i<size($defJoints);$i++)
	{
	$pos=`xform -q -ws -t $defJoints[$i]`;
	$locs[$i]=$defJoints[$i]+"Loc";
	spaceLocator -n $locs[$i];
	createNode -n ($locs[$i]+"Offset") -p ("DynLocs"+$name) transform;
	parent $locs[$i] ($locs[$i]+"Offset");
	xform -ws -t $pos[0] $pos[1] $pos[2] ($locs[$i]+"Offset");
	parentConstraint -mo $defJointsCtrl[$i] ($locs[$i]+"Offset");
	scaleConstraint -mo $defJointsCtrl[$i] ($locs[$i]+"Offset");
	$tempString=`listRelatives -s $defJointsCtrl[$i]`;
	$bbMin=`getAttr ($tempString[0]+".boundingBoxMin")`;
	$bbMax=`getAttr ($tempString[0]+".boundingBoxMax")`;
	$locScale[0]=$bbMax[0]-$bbMin[0];
	$locScale[1]=$bbMax[1]-$bbMin[1];
	$locScale[2]=$bbMax[2]-$bbMin[2];
	setAttr ($locs[$i]+"Shape.localScale") -type float3 ($locScale[0]/2.0) ($locScale[1]/2.0) ($locScale[2]/2.0);
	setAttr ($locs[$i]+"Shape.overrideEnabled") 1;
	setAttr ($locs[$i]+"Shape.overrideColor") 17;
	connectAttr ($locs[$i]+"Shape.worldPosition[0]") ("DynCurve"+$name+"Shape.controlPoints["+$i+"]");
	}

//$numCv
$form=`getAttr ("DynCurve"+$name+".form")`;
$spans=`getAttr ("DynCurve"+$name+".spans")`;
$degrees=`getAttr ("DynCurve"+$name+".degree")`;
if ($form==2)
	$numCv=$spans;
else
	$numCv=$spans+$degrees;

//mass
for ($i=0;$i<$numCv;$i++)
	{
	$massPP = (1-((1.0/$numCv)*$i));
	particle -e -or $i -at mass -fv $massPP ("DynParticle"+$name);
	}

//arrayMapper
$tempString=`arrayMapper -target ("DynParticle"+$name) -destAttr goalPP -inputV mass -type ramp`;
rename $tempString[0] ("DynParticleArrayMapper"+$name);

$tempString=`listConnections -s 1 -d 0 ("DynParticleArrayMapper"+$name+".computeNodeColor")`;
rename $tempString[0] ("DynParticleRamp"+$name);
removeMultiInstance -break true ("DynParticleRamp"+$name+".colorEntryList[1]");
setAttr ("DynParticleRamp"+$name+".colorEntryList[0].position") 0;
setAttr ("DynParticleRamp"+$name+".colorEntryList[1].position") 1;
setAttr ("DynParticleRamp"+$name+".colorEntryList[0].color") -type double3 0 0 0;
setAttr ("DynParticleRamp"+$name+".colorEntryList[1].color") -type double3 1 1 1;

if (!`attributeExists blend $sorted[0]`) addAttr -k 1 -ln blend -at double -min 0 -max 1 -dv 1 $sorted[0];
if (!`attributeExists baseGoal $sorted[0]`) addAttr -k 1 -ln baseGoal -at double -min 0 -max 1 -dv 1 $sorted[0];
if (!`attributeExists tipGoal $sorted[0]`) addAttr -k 1 -ln tipGoal -at double -min 0 -max 1 -dv 0.6 $sorted[0];
if (!`attributeExists conserve $sorted[0]`) addAttr -k 1 -ln conserve -at double -min 0 -max 1 -dv 0.75 $sorted[0];
connectAttr ($sorted[0]+".baseGoal") ("DynParticleArrayMapper"+$name+".maxValue");
connectAttr ($sorted[0]+".tipGoal") ("DynParticleArrayMapper"+$name+".minValue");
connectAttr ($sorted[0]+".conserve") ("DynParticle"+$name+".conserve");

//splineIK
createNode -n ($defJoints[0]+"Offset") -p $dynTopNode transform;
$tempString=`listRelatives -p $defJoints[0]`;
parentConstraint $tempString[0] ($defJoints[0]+"Offset");
scaleConstraint $tempString[0] ($defJoints[0]+"Offset");
//select $defJoints[0];
for ($i=0;$i<$numCv;$i++)
	{
	select $defJoints[$i];
	$dynJoints[$i]="dyn"+`substitute $nameSpace $defJoints[0] ""`+$i;
	joint -n $dynJoints[$i];
//	$pos=`xform -q -ws -t ("DynCurveSoft"+$name+".cv["+$i+"]")`;
//	xform -ws -t $pos[0] $pos[1] $pos[2] $dynJoints[$i];
	}
for ($i=0;$i<$numCv-1;$i++)
	parent $dynJoints[$i+1] $dynJoints[$i];
parent $dynJoints[0] ($defJoints[0]+"Offset");
$tempString=`ikHandle -n ("DynIKHandle"+$name) -ns 2 -sol ikSplineSolver -sj $dynJoints[0] -ee $dynJoints[size($dynJoints)-1]`;
rename $tempString[1] ("DynIKEffector"+$name);
string $ikCurve=`rename $tempString[2] ("DynIKCurve"+$name)`;
parent ("DynIKHandle"+$name) ("DynIKCurve"+$name) $dynTopNode;
connectAttr -f ("DynCurveSoft"+$name+".worldSpace[0]") ("DynIKCurve"+$name+".create");

//pairBlend
$parent=$defJoints[0]+"Offset";
for ($i=0;$i<size($defJoints);$i++)
	{
//	if ($opm && $i==size($defJoints)-1)
//		break;

	$tempString[0]=`pairBlend -nd $defJoints[$i] -at tx -at ty -at tz`;
	rename $tempString[0] ("parBlendT"+$dynJoints[$i]);
	if ($opm)
		;//skipping Translate for OPM for now
	else
		connectAttr -f ($dynJoints[$i]+".translate") ("parBlendT"+$dynJoints[$i]+".inTranslate2");
	connectAttr ($sorted[0]+".blend") ("parBlendT"+$dynJoints[$i]+".weight");

	$tempString[0]=`pairBlend -nd $defJoints[$i] -at rx -at ry -at rz`;
	rename $tempString[0] ("parBlendR"+$dynJoints[$i]);
	if ($opm)
		{
		parentConstraint $dynJoints[$i] $defJoints[$i];
		//delete the extra generated pairBlend
		$tempString=`listConnections -s 1 -d 0 ($defJoints[$i]+".tx")`;
		delete $tempString[0];
//		if ($i>0)
			connectAttr ($defJoints[$i]+"_parentConstraint1.constraintTranslate") ("parBlendT"+$dynJoints[$i]+".inTranslate2");
		connectAttr ($defJoints[$i]+"_parentConstraint1.constraintRotate") ("parBlendR"+$dynJoints[$i]+".inRotate2");
		}
	else
		connectAttr -f ($dynJoints[$i]+".rotate") ("parBlendR"+$dynJoints[$i]+".inRotate2");
	connectAttr ($sorted[0]+".blend") ("parBlendR"+$dynJoints[$i]+".weight");

	}

if ($restoreCmd!="")
	{
	addAttr -ln restoreCmd -dt "string" $dynTopNode;
	setAttr -type "string" ($dynTopNode+".restoreCmd") $restoreCmd;
	}

setAttr -l 1 ("DynIKHandle"+$name+".v") 0;

print "// Dynamics added.\n";
select $sorted[0];
}

global proc asDynSetInitialState (string $uiName)
{
if (`asHotKeyCheck "asDynSetInitialState \"\""`) return;
evalEcho saveInitialState -all;
}

global proc asDynSetInteractivePlayback (string $uiName)
{
if (`asHotKeyCheck "asDynSetInteractivePlayback \"\""`) return;
evalEcho InteractivePlayback;
}

global proc asParentAdd (string $uiName, int $extra)
{
int $plugNr;
string $parent,$child,$attrName,$parentConstraint;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $tempString[],$udAttrs[];
string $sel[]=`ls -sl`;

if (`asHotKeyCheck ("asParentAdd \"\" "+$extra)`) return;

if (size($sel)<2) error "Select at least 2 objects";

$child=$sel[size($sel)-1];
for ($i=0;$i<size($sel)-1;$i++)
	{
	$parent=$sel[$i];
	if ($extra)
		{
		$tempString=`listRelatives -p $child`;
		if (`gmatch $tempString[0] "*Extra*"`)
			$child=$tempString[0];
		else
			print ("// No Extra control found for \""+$child+"\".\n");
		}

	if (!`objExists Parenting`)
		createNode -n Parenting transform;
		if (!`objExists ($nameSpace+"Parenting")`)
			createNode -n ($nameSpace+"Parenting") -p Parenting transform;
	if (`objExists ($child+"ParentedTo"+$parent)`)
		delete ($child+"ParentedTo"+$parent);
	createNode -n ($child+"ParentedTo"+$parent) -p ($nameSpace+"Parenting") transform;
	createNode -n ($parent+"Follower") -p ($nameSpace+"Parenting") transform;
	asAlign ($parent+"Follower") $child 1 1 0 0;
	parentConstraint -mo $parent ($parent+"Follower");
	if ($i==0 && !`objExists ($child+"Static")`)
		{
		spaceLocator -n ($child+"Static");
		asAlign ($child+"Static") $child 1 1 0 0;
		parent ($child+"Static") ($nameSpace+"Parenting");
		parentConstraint ($child+"Static") $child;
		}

	$tempString=`parentConstraint ($parent+"Follower") $child`;
	$parentConstraint=$tempString[0];
	$udAttrs=`listAttr -ud $parentConstraint`;

	tokenize $parent ":" $tempString;
	$attrName="parentTo"+`substitute $nameSpace $parent ""`;
	addAttr -k 1 -dv 1 -ln $attrName -at double -min 0 -max 1 $child;
	connectAttr ($child+"."+$attrName) ($parentConstraint+"."+$udAttrs[size($udAttrs)-1]);

	if (!`objExists ($child+"ParentedMax")`)
		createNode -n ($child+"ParentedMax") max;
	if (!`objExists ($child+"ParentedReverse")`)
		{
		createNode -n ($child+"ParentedReverse") reverse;
		connectAttr ($child+"ParentedMax.output") ($child+"ParentedReverse.inputX");
		connectAttr ($child+"ParentedReverse.outputX") ($parentConstraint+"."+$udAttrs[0]);
		}
	$plugNr=`getAttr -s ($child+"ParentedMax.input")`;
	connectAttr ($child+"."+$attrName) ($child+"ParentedMax.input["+$plugNr+"]");
	}
select $sel;
select -d $parent;
print "// ParentConstraint added.\n";
}

global proc string asFindFKIKCtrl (string $obj)
{
int $foundIK;
string $fkIkCtrl,$conditionNode;
string $tempString[],$tempString2[],$tempString3[],$tempString4[];

if (`gmatch $obj "*FKIK*"`)
	return $obj;

$tempString[0]=$obj;
for ($y=0;$y<99;$y++)
	{
	$tempString=`listRelatives -p $tempString[0]`;
	if ($tempString[0]=="") 
		break;
	$tempString2=`listConnections -s 1 -d 0 ($tempString[0]+".v")`;
	if ($tempString2[0]=="")
		continue;
	if (`objectType $tempString2[0]`!="condition")
		continue;
	$tempString2=`listConnections -s 1 -d 0 ($tempString2[0]+".firstTerm")`;
	if ($tempString2[0]=="")
		continue;
	return $tempString2[0];
	}

//if not found above, check for shape connection
$tempString=`listRelatives -s $obj`;
if ($tempString[0]!="")
	{
	$tempString2=`listConnections -s 1 -d 0 ($tempString[0]+".v")`;
	if ($tempString2[0]!="")
		{
		if (`objectType $tempString2[0]`=="condition")//IKhybrid ctrl 
			$conditionNode=$tempString2[0];
		else if (`objectType $tempString2[0]`=="plusMinusAverage")//IKhybrid ctrl
			{
			$tempString3=`listConnections -s 1 -d 0 -scn 1 ($tempString2[0]+".input1D[0]")`;
			if (`objectType $tempString3[0]`=="condition")
				$conditionNode=$tempString3[0];
			}
		}

	if ($conditionNode!="")
		{
		$tempString4=`listConnections -s 1 -d 0 ($conditionNode+".firstTerm")`;
		if ($tempString4[0]!="")
			return $tempString4[0];
		}
	}

return $fkIkCtrl;
}

global proc asAutoSwitchFKIK ()
{
string $sel[]=`ls -sl`;
string $name,$nameSpace,$fkIkCtrl,$side,$ik2fk;
float $curFKIKBlend;
string $tempString[],$tempString2[],$fkIkCtrls[];

if (`asHotKeyCheck "asAutoSwitchFKIK"`) return;

for ($i=0;$i<size($sel);$i++)
	$fkIkCtrls[$i]=`asFindFKIKCtrl $sel[$i]`;

$fkIkCtrls=`stringArrayRemoveDuplicates $fkIkCtrls`;

if (size($fkIkCtrls)==0 || `stringArrayCount "" $fkIkCtrls`)
	error "First select a control that is part of FK/IK setup";

for ($i=0;$i<size($fkIkCtrls);$i++)
	{
	$nameSpace="";
	$fkIkCtrl="";
	$side="";
	$name=$fkIkCtrls[$i];
	tokenize $fkIkCtrls[$i] ":" $tempString;
	if (size($tempString)>1)
		{
		for ($y=0;$y<size($tempString)-1;$y++)
			$nameSpace+=$tempString[$y]+":";
		$name=$tempString[size($tempString)-1];
		}
	tokenize $name "_" $tempString;
	$fkIkCtrl=$tempString[0];
	$side="_"+$tempString[1];
	$curFKIKBlend=`getAttr ($fkIkCtrls[$i]+".FKIKBlend")`;
	if ($curFKIKBlend>0 && $curFKIKBlend<5) setAttr ($fkIkCtrls[$i]+".FKIKBlend") 0;
	if ($curFKIKBlend>5 && $curFKIKBlend<10) setAttr ($fkIkCtrls[$i]+".FKIKBlend") 10;
	if ($curFKIKBlend>5) $ik2fk="IK2FK";
	else $ik2fk="FK2IK";
	//    asSwitchFKIK $fkIkCtrls[$i] `substitute "FKIK" $fkIkCtrl ""` $side $ik2fk;
	asSwitchFKIK $nameSpace `substitute "FKIK" $fkIkCtrl ""` $side $ik2fk;
	//global proc asSwitchFKIK (string $nameSpace, string $IK, string $side, string $W2K)
	}
}

global proc asAutoSwitchPivot ()
{
string $target,$control,$extraControl;
string $sel[]=`ls -sl`;
string $tempString[];

if (`asHotKeyCheck "asAutoSwitchPivot"`) return;

if (size($sel)!=2)
	error "Select 1 target object + 1 control";
$target=$sel[0];
$control=$sel[1];

if (!`gmatch $control "*_*"` && `gmatch $target "*_*"`)//selection order was reversed
	{
	$target=$sel[1];
	$control=$sel[0];
	}
if (`gmatch $control "*Extra*"`)//extraControl was selected
	{
	$tempString=`listRelatives -c -type transform $control`;
	$control=$tempString[0];
	}
$tempString=`listRelatives -p $control`;
$extraControl=$tempString[0];
if (!`objExists $extraControl`)
	error ("parent of \""+$control+"\" is not a valid ExtraControl");
float $pos[]=`xform -q -ws -t $control`;
float $rot[]=`xform -q -ws -ro $control`;
float $extraPos[]=`xform -q -ws -t $extraControl`;
float $extraRot[]=`xform -q -ws -ro $extraControl`;
float $targetPos[]=`xform -q -ws -t $target`;
float $targetRot[]=`xform -q -ws -ro $target`;

//print "asAutoSwitchPivot;\n";

int $autoKey=`autoKeyframe -q -st`;
if ($autoKey)
	autoKeyframe -st 0;
currentTime (`currentTime -q` -1);
setKeyframe ($extraControl+".t") ($extraControl+".r") ($control+".t") ($control+".r");

currentTime (`currentTime -q` +1);
xform -ws -t $targetPos[0] $targetPos[1] $targetPos[2] -ro $targetRot[0] $targetRot[1] $targetRot[2] $extraControl;
xform -ws -t $pos[0] $pos[1] $pos[2] -ro $rot[0] $rot[1] $rot[2] $control;
setKeyframe ($extraControl+".t") ($extraControl+".r") ($control+".t") ($control+".r");

if ($autoKey)
	autoKeyframe -st 1;

select $extraControl;
print ("// \""+$extraControl+"\" aligned to \""+$target+"\".\n");
}

global proc asPivotControl ()
{
int $numCtrls;
float $diameter,$scale;
string $sel[]=`ls -sl`;
string $tempString[];

if (`asHotKeyCheck "asPivotControl"`) return;

for ($i=0;$i<size($sel);$i++)
	{
	if (`gmatch $sel[$i] "*_PivotControl"`)
		error "Selected object is already a PivotController.";
	$pivotControl=$sel[$i]+"_PivotControl";
	if (`objExists $pivotControl`)
		delete $pivotControl;
	spaceLocator -n $pivotControl;
	parent -r $pivotControl $sel[$i];

	$diameter=`asControlDiameter $sel[$i]`;
	$scale=$diameter*0.75;
	if ($scale==0) $scale=1;//shapeLess xform. e.g. ExtraCtrl
	setAttr ($pivotControl+".localScale") -type float3 $scale $scale $scale;
	connectAttr ($pivotControl+".t") ($sel[$i]+".rotatePivot");
	connectAttr ($pivotControl+".t") ($sel[$i]+".scalePivot");

	$numCtrls++;
	}
print ("// Pivot-Locators added for: "+$numCtrls+" Controllers.\n");
}

global proc asQuickIK ()
{
int $otherEndJointAssumed;
float $dist;
float $posA[],$posB[];
string $startJoint,$endJoint,$ctrlPrefix,$startJointParent,$rotateAxis,$name,$ctrl;
string $sel[]=`ls -sl`;
string $joints[],$tempString[],$chainJointsReverse[],$chainJoints[],$chainJointNames[];

if (`asHotKeyCheck "asQuickIK"`) return;

if (size($sel)!=2)
	error "Select Start control + End control";

for ($i=0;$i<2;$i++)
	{
	$joints[$i]=$sel[$i];
	$tempString[0]=`substitute "FK" $joints[$i] ""`;//Fk control
	if (`objExists $tempString[0]`)
		{
		$joints[$i]=$tempString[0];
		$ctrlPrefix="FK";
		}
	$tempString[0]=`substitute "_" $joints[$i] "Joint_"`;// Face control e.g tongue
	if (`objExists $tempString[0]`)
		{
		$joints[$i]=$tempString[0];
		$ctrlPrefix="";
		}
	}

$tempString=`listRelatives -ad -type joint $joints[0]`;
if (`stringArrayCount $joints[1] $tempString`)
	{
	$startJoint=$joints[0];
	$endJoint=$joints[1];
	}

$tempString=`listRelatives -ad -type joint $joints[1]`;
if (`stringArrayCount $joints[0] $tempString`)
	{
	$startJoint=$joints[1];
	$endJoint=$joints[0];
	}
if ($startJoint=="" || $endJoint=="")
	error "Unable to find Start & End joint for the IK, make sure to select 2 control that are in the same hierarchy.\n";

$name=`substituteAllString $startJoint ":" "_"`;
$tempString=`listRelatives -p $startJoint`;
$startJointParent=$tempString[0];

//if childJoint of $endJoint is a `actual` endJoint, then assume this was meant to be used.
$tempString=`listRelatives -ad -type joint $endJoint`;
if (size ($tempString)==1)
	{
	$endJoint=$tempString[0];
	$otherEndJointAssumed=1;
	}

//determine $chainJoints
$tempString=`ls -l $endJoint`;
tokenize $tempString[0] "|" $tempString;
for ($i=size($tempString)-1;$i>-1;$i--)
	{
	$chainJointsReverse[size($chainJointsReverse)]=$tempString[$i];
	if ($tempString[$i]==$startJoint)
		break;
	}
for ($i=size($chainJointsReverse)-1;$i>-1;$i--)
	$chainJoints[size($chainJoints)]=$chainJointsReverse[$i];

for ($i=0;$i<size($chainJoints);$i++)
	if (`objExists ("QuickIKjoint_"+$chainJoints[$i])`)
		error ("Another QuickIK already using the Joint:\"QuickIKjoint_"+$chainJoints[$i]+"\"\n");

$rotateAxis="z";
if (`gmatch $startJoint "*Finger*"`)
	$rotateAxis="y";

print ("StartJoint: "+$startJoint+", EndJoint: "+$endJoint+"\n");
if (!`objExists QuickIK`)
	createNode -n QuickIK transform;
if (`objExists ("QuickIK_"+$name+"Group")`)
	delete ("QuickIK_"+$name+"Group");
createNode -n ("QuickIK_"+$name+"Group") -p $startJoint transform;
parent ("QuickIK_"+$name+"Group") QuickIK;

for ($i=0;$i<size($chainJoints);$i++)
	$chainJointNames[$i]=`substituteAllString $chainJoints[$i] ":" "_"`;

for ($i=0;$i<size($chainJoints);$i++)
	{
	select $chainJoints[$i];
	joint -n ("QuickIKjoint_"+$chainJointNames[$i]);
	setAttr ("QuickIKjoint_"+$chainJointNames[$i]+".rotateOrder") `getAttr ($chainJoints[$i]+".rotateOrder")`;
	if ($rotateAxis=="y")
		setAttr ("QuickIKjoint_"+$chainJointNames[$i]+".preferredAngle") -type float3 0 10 0;
	if ($i>0)
		parent ("QuickIKjoint_"+$chainJointNames[$i]) ("QuickIKjoint_"+$chainJointNames[$i-1]);
	}

parent ("QuickIKjoint_"+$name) ("QuickIK_"+$name+"Group");
parentConstraint -mo $startJointParent ("QuickIKjoint_"+$name);

$posA=`xform -q -ws -t $startJoint`;
$posB=`xform -q -ws -t $endJoint`;
$dist=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;

spaceLocator -n ("QuickIK_"+$name);
parent ("QuickIK_"+$name) ("QuickIK_"+$name+"Group");
setAttr ("QuickIK_"+$name+"Shape.overrideEnabled") 1;
setAttr ("QuickIK_"+$name+"Shape.overrideColor") 13;
setAttr ("QuickIK_"+$name+"Shape.localScale") -type float3 ($dist/2.0) ($dist/2.0) ($dist/2.0);
duplicate -n ("QuickPoleVector_"+$name) ("QuickIK_"+$name);
setAttr ("QuickPoleVector_"+$name+"Shape.localScale") -type float3 ($dist/4.0) ($dist/4.0) ($dist/4.0);
xform -ws -t $posB[0] $posB[1] $posB[2] ("QuickIK_"+$name);

ikHandle -n ("QuickIK_"+$name+"Handle") -ns 2 -sol "ikRPsolver" -sj ("QuickIKjoint_"+$chainJointNames[0]) -ee ("QuickIKjoint_"+$chainJointNames[size($chainJointNames)-1]);
parent ("QuickIK_"+$name+"Handle") ("QuickIK_"+$name);
setAttr ("QuickIK_"+$name+"Handle.v") 0;

parent ("QuickPoleVector_"+$name) $startJoint;
xform -os -t 0 0 0 -ro 0 0 0 ("QuickPoleVector_"+$name);
if ($rotateAxis=="y")
	setAttr ("QuickPoleVector_"+$name+".tz") $dist;
if ($rotateAxis=="z")
	setAttr ("QuickPoleVector_"+$name+".ty") $dist;

//poleVector
poleVectorConstraint ("QuickPoleVector_"+$name) ("QuickIK_"+$name+"Handle");
$tempString[0]=`createNode annotationShape`;
$tempString=`listRelatives -p $tempString[0]`;
rename $tempString[0] ("QuickPoleAnnotation_"+$name);
setAttr ("QuickPoleAnnotation_"+$name+"Shape.overrideEnabled") 1;
setAttr ("QuickPoleAnnotation_"+$name+"Shape.overrideDisplayType") 2;
parent ("QuickPoleAnnotation_"+$name) ("QuickIK_"+$name);
xform -os -t 0 0 0 -ro 0 0 0  ("QuickPoleAnnotation_"+$name);
connectAttr ("QuickPoleVector_"+$name+"Shape.worldMatrix[0]") ("QuickPoleAnnotation_"+$name+"Shape.dagObjectMatrix[0]");
//move forward to match IkHandle pos
setAttr ("QuickPoleVector_"+$name+".tx") `getAttr ("QuickIK_"+$name+".tx")`;

//Offsets
createNode -n ("QuickIKOffset_"+$name) -p ("QuickIK_"+$name) transform;
parent ("QuickIKOffset_"+$name) ("QuickIK_"+$name+"Group");
parent ("QuickIK_"+$name) ("QuickIKOffset_"+$name);
createNode -n ("QuickPoleVectorOffset_"+$name) -p ("QuickPoleVector_"+$name) transform;
parent ("QuickPoleVectorOffset_"+$name) ("QuickIK_"+$name);
parent ("QuickPoleVector_"+$name) ("QuickPoleVectorOffset_"+$name);


//connect
for ($i=0;$i<size($chainJoints);$i++)
	{
	if ($i==(size($chainJoints)-1) && $otherEndJointAssumed)
		continue;
	if (`gmatch $chainJoints[$i] "*:*"`)//have nameSpace
		{
		tokenize $chainJoints[$i] ":" $tempString;
		$ctrl=$tempString[0]+":"+$ctrlPrefix+$tempString[1];
		}
	else
		$ctrl=$ctrlPrefix+$chainJoints[$i];
	if ($ctrlPrefix=="")
		$ctrl=`substitute "Joint" $chainJoints[$i] ""`;
	if (!`objExists $ctrl`)
		{
		warning ("Could not find controller:\""+$ctrl+"\"\n");
		continue;
		}
	orientConstraint ("QuickIKjoint_"+$chainJointNames[$i]) $ctrl;
	}

select ("QuickIK_"+$name);
}

global proc asSegmentScaleCompensate (string $uiName)
{
int $onOff;
string $onOffString;
string $nameSpace=`optionMenu -q -v ($uiName+"OptionMenu")`;
if ($nameSpace==":")
	$nameSpace="";
string $fkXJoints[];

$fkXJoints=`ls -type joint ($nameSpace+"FKX*")`;
for ($i=0;$i<size($fkXJoints);$i++)
	{
	if ($i==0)
		{
		$onOff=!`getAttr ($fkXJoints[$i]+".segmentScaleCompensate")`;
		if ($onOff==0) $onOffString="OFF";
		if ($onOff==1) $onOffString="ON";
		print ("// switching "+$onOffString+" segmentScaleCompensate.\n");
		}
	setAttr ($fkXJoints[$i]+".segmentScaleCompensate") $onOff;
	}
}

global proc asHumanIKUI (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
if (`asHotKeyCheck "asHumanIKUI \"\""`) return;

if (`window -q -ex asHumanIK`)
    deleteUI asHumanIK;
window -t HumanIK asHumanIK;
columnLayout;
text -m 0 -l $uiName asHumanIKUiNameText;
text -m 0 -l $nameSpace asHumanIKNameSpaceText;
separator -h 15 -st none;
button -w 190 -l "Create HumanIK" -c asCreateHumanIK;
separator -h 15 -st none;
button -w 190 -l "Delete HumanIK" -c asDeleteHumanIK;

showWindow;
}

/*
global proc asTwistFlipUI (string $uiName)
{
if (`asHotKeyCheck "asTwistFlipUI \"\""`) return;

if (`window -q -ex asTwistFlip`)
    deleteUI asTwistFlip;
window -t TwistFlip asTwistFlip;
columnLayout;
separator -h 5 -st none;
text -l "Sets the amount of X-rotation, before `flipping` occours";
text -l "(e.g. twisting of the wrist)\n";
text -l "Note for 360, Constraint-Caching is needed for reliable results";
separator -h 20 -st none;
rowLayout -nc 4;
	text -w 80 -l "X-rotation:";
	optionMenu asTwistFlipOptionMenu;
		menuItem -l "180";
		menuItem -l "360";
	separator -w 10;
	button -w 100 -l "Ok, Set" -c ("asTwistFlipSet \""+$uiName+"\" set");
	setParent..;
separator -h 10 -st none;
rowLayout -en 0 -nc 4 asTwistFlipCacheRowLayout;
	text -w 80 -l "Cache:";
	button -w 80 -l "Create" -c ("asTwistFlipSet \""+$uiName+"\" cacheCreate");
	separator -w 10 -st none;
	button -w 80 -l "Delete" -c ("asTwistFlipSet \""+$uiName+"\" cacheDelete");
showWindow;
}

global proc asTwistFlipSet (string $uiName, string $action)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $asTwistFlipOption=`optionMenu -q -v asTwistFlipOptionMenu`;
int $interpType=1;
if ($asTwistFlipOption=="360")
	$interpType=0;
string $twistConstraints[]=`ls -type parentConstraint ($nameSpace+"TwistBalancer*")`;
for ($i=0;$i<size($twistConstraints);$i++)
	{
	if ($action=="set")
		{
		setAttr ($twistConstraints[$i]+".interpType") $interpType;
		setAttr ($nameSpace+"MainTwistFlipSetRange.value") -type float3 (!$interpType) (!$interpType) (!$interpType);
		if (`rowLayout -q -ex asTwistFlipCacheRowLayout`)
			rowLayout -e -en (!$interpType) asTwistFlipCacheRowLayout;
		}
	if (`getAttr -s ($twistConstraints[$i]+".target")`<2)// otherwice Error:No cache is needed when there is only a single target. 
		continue;
	if ($action=="cacheCreate")
		evalEcho ("parentConstraint -e -cc "+`playbackOptions -q -min`+" "+`playbackOptions -q -max`+" "+$twistConstraints[$i]);
	if ($action=="cacheDelete")
		evalEcho ("parentConstraint -e -dc "+$twistConstraints[$i]);
	}
dgdirty -a;
refresh;
if ($nameSpace=="")
	print ("// Ok TwistFlip has been \""+$action+"\".\n");
else
	print ("// Ok TwistFlip ( for nameSpace:\""+$nameSpace+"\" ) has been \""+$action+"\".\n");
}
*/

global proc asAnimBake (string $uiName)
{
string $nameSpace;
string $controlSets[],$tempString[],$FkIks[];

if (`asHotKeyCheck "asAnimBake \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

$tempString=`ls -type transform ($nameSpace+"FKIK*")`;
for ($i=0;$i<size($tempString);$i++)
	if (`attributeExists FKIKBlend $tempString[$i]`)
		$FkIks[size($FkIks)]=`substitute ($nameSpace+"FKIK") $tempString[$i] ""`;

if (`window -q -ex asAnimBake`)
    deleteUI asAnimBake;
window -t Bake -resizeToFitChildren 1 asAnimBake;
columnLayout;
	text -l "Bake:";
	optionMenu -cc asAnimBakeOptionChange asAnimBakeOptionMenu;
	//	menuItem -l "AnimationControls to BakeSkeleton";
	//	menuItem -l "MotionCapture to FKControls";
		menuItem -l "ExtraControls to Controls";
		menuItem -l "Controls to ExtraControls";
		menuItem -l "QuickIK to FKControls";
		for ($i=0;$i<size($FkIks);$i++)
			menuItem -l ("FK to IK : "+$FkIks[$i]);
		for ($i=0;$i<size($FkIks);$i++)
			menuItem -l ("IK to FK : "+$FkIks[$i]);
	separator -h 10;
	checkBox -en 0 -l "baking MotionCapture" -v `optionVar -q asBakingMoCap` -cc "optionVar -iv asBakingMoCap #1" asAnimBakingMoCapCheckBox;
	text -en 0 -l "(match Elbow/Knee rotation instead of position)" asAnimBakingMoCapText;
	separator -st none -h 10 -w 200;
	rowLayout -nc 2;
		separator -w 50 -st none;
		button -w 100 -l "Ok, Bake" -c ("asAnimBakeGo \""+$uiName+"\"");

showWindow;
}

global proc asAnimBakeOptionChange ()
{
int $enable;
string $bake=`optionMenu -q -v asAnimBakeOptionMenu`;
if (`gmatch $bake "FK to IK*"`)
	$enable=1;
checkBox -e -en $enable asAnimBakingMoCapCheckBox;
text -e -en $enable asAnimBakingMoCapText;
}

global proc asAnimBakeGo (string $uiName)
{
string $nameSpace,$limb;
string $bake=`optionMenu -q -v asAnimBakeOptionMenu`;
string $controlSets[];

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

//if ($bake=="AnimationControls to BakeSkeleton")
//	asAnimBakeSkeleton $uiName;
if ($bake=="ExtraControls to Controls")
	asAnimBakeExtra $uiName;
if ($bake=="Controls to ExtraControls")
	asAnimBakeToExtra $uiName;
if ($bake=="QuickIK to FKControls")
	asAnimBakeQuickIK $uiName;
if (`gmatch $bake "FK to IK : *"`)
	{
	$limb=`substitute "FK to IK : " $bake ""`;
	asAnimBakeFKIK $limb 1 $uiName;
	}
if (`gmatch $bake "IK to FK : *"`)
	{
	$limb=`substitute "IK to FK : " $bake ""`;
	asAnimBakeFKIK $limb 0 $uiName;
	}
}

global proc asAnimBakeToExtra (string $uiName)
{
float $defaultValue;
string $nameSpace,$nonExtra;
string $tempString[],$controls[],$controlSets[];
string $trs[]={"t","r","s"};
string $xyz[]={"x","y","z"};

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

select $controlSets;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";
select -cl;

$controls=`sets -q $controlSets`;
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"*Extra*")`)
		for ($y=0;$y<size($trs)-1;$y++)
			{
			$defaultValue=0;
			if ($trs[$y]=="s") $defaultValue=1;
			for ($z=0;$z<size($xyz);$z++)
				{
				$nonExtra=`substitute "Extra" $controls[$i] ""`;
				$tempString=`listConnections -s 1 -d 0 -p 1 -c 1 ($nonExtra+"."+$trs[$y]+$xyz[$z])`;
				if ($tempString[0]=="")
					continue;
				connectAttr $tempString[1] ($controls[$i]+"."+$trs[$y]+$xyz[$z]);
				disconnectAttr $tempString[1] $tempString[0];
				setAttr ($nonExtra+"."+$trs[$y]+$xyz[$z]) $defaultValue;
				}
			}
print "// Animations Moved from Controllers to ExtraControllers.\n";
}

global proc asAnimBakeExtra (string $uiName)
{
float $curTime=`currentTime -q`;
string $nameSpace;
string $tempString[],$tempString2[],$tempString3[],$controls[],$extraControls[],$bakeControls[],$animCurves[],$controlSets[];

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

$controls=`sets -q $controlSets`;
for ($i=0;$i<size($controls);$i++)
	if (`gmatch $controls[$i] ($nameSpace+"FKExtra*")` || `gmatch $controls[$i] ($nameSpace+"RootExtraX*")`)
		$extraControls[size($extraControls)]=$controls[$i];

for ($i=0;$i<size($extraControls);$i++)
	{
	$controls[$i]=`substitute "Extra" $extraControls[$i] ""`;
	$bakeControls[$i]=$extraControls[$i]+"BAKER";
	$tempString=`listRelatives -p $extraControls[$i]`;
	createNode -n $bakeControls[$i] -p $tempString[0] transform;
	setAttr ($bakeControls[$i]+".rotateOrder") `getAttr ($controls[$i]+".rotateOrder")`;
	$tempString=`listRelatives -c -type transform $extraControls[$i]`;
	parentConstraint $tempString[0] $bakeControls[$i];
	scaleConstraint $tempString[0] $bakeControls[$i];
	}

//Bake
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys false -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
	-bakeOnOverrideLayer false -controlPoints false -shape false $bakeControls;
currentTime $curTime;
select $bakeControls;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";

//remove existing animation
for ($i=0;$i<size($extraControls);$i++)
	{
	$animCurves=`listConnections -s 1 -d 0 -type animCurve $extraControls[$i]`;
	if (size($animCurves)) delete $animCurves;
	xform -os -t 0 0 0 -ro 0 0 0 -s 1 1 1 $extraControls[$i];
	$animCurves=`listConnections -s 1 -d 0 -type animCurve $controls[$i]`;
	if (size($animCurves)) delete $animCurves;
	xform -os -t 0 0 0 -ro 0 0 0 -s 1 1 1 $controls[$i];
	}
//asGoToBuildPose bodySetup;

//Use baked animCurves
for ($i=0;$i<size($extraControls);$i++)
	{
	$animCurves=`listConnections -s 1 -d 0 -type animCurve $bakeControls[$i]`;
	for ($y=0;$y<size($animCurves);$y++)
		{
		$tempString=`listConnections -s 0 -d 1 -p 1 -c 1 $animCurves[$y]`;
		tokenize $tempString[1] "[.]" $tempString2;
		connectAttr $tempString[0] ($controls[$i]+"."+$tempString2[1]);
		tokenize $tempString[0] "[.]" $tempString3;
		rename $tempString3[0] ($controls[$i]+"_"+$tempString2[1]);
		}
	}
delete $bakeControls;
}

global proc asAnimBakeQuickIK (string $uiName)
{
string $nameSpace;
string $controls[],$bakeControls[],$tempString[];

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

$controls=`sets -q $controlSets`;
for ($i=0;$i<size($controls);$i++)
	{
	$tempString=`listConnections -s 1 -d 0 -type constraint $controls[$i]`;
	if (!size($tempString))
		$tempString=`listConnections -s 1 -d 0 -type pairBlend $controls[$i]`;
	if (size($tempString))
		$bakeControls[size($bakeControls)]=$controls[$i];
	}

//Bake
select $bakeControls;
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys true -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
	-bakeOnOverrideLayer false -controlPoints false -shape false $bakeControls;
select $bakeControls;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";

if (`objExists QuickIK`)
	delete QuickIK;
select -cl;
}

global proc asAnimBakeFKIK (string $limb, int $Fk2Ik, string $uiName)
{
global int $asBakeFKIK;
global string $gMainProgressBar;
int $autoKeyState=`autoKeyframe -q -state`;
int $numChar;
float $curTime=`currentTime -q`;
float $start=`playbackOptions -q -min`;
float $end=`playbackOptions -q -max`;
int $startInt=$start;
int $endInt=$end;
string $nameSpace,$side,$sideLessLimb;
string $controlSets[],$tempString[];
string $limbs[]={$limb};

//print command, for the user to easily turn this into a custom Mel command
print ("asAnimBakeFKIK \""+$limb+"\" "+$Fk2Ik+" \""+$uiName+"\";\n");

if (`gmatch $limb "*|*"`)
	tokenize $limb "|" $limbs;

$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

if (!$autoKeyState)
	autoKeyframe -state 1;

currentTime $start;
for ($y=0;$y<size($limbs);$y++)
	{
	if ($Fk2Ik)
		{
		setAttr ($nameSpace+"FKIK"+$limbs[$y]+".FKIKBlend") 0;
		asSwitchFK2IK $nameSpace {("FKIK"+$limbs[$y])}; 
		}
	else
		{
		setAttr ($nameSpace+"FKIK"+$limbs[$y]+".FKIKBlend") 10;
		asSwitchIK2FK $nameSpace {("FKIK"+$limbs[$y])};
		}
	}
evalDeferred ("progressBar -e -ep "+$gMainProgressBar);
progressBar -e -st "Baking" -bp -ii 1 -min $startInt -max ($endInt+1) $gMainProgressBar;
$asBakeFKIK=1;
for ($i=$start;$i<$end+1;$i++)
	{
	progressBar -e -s 1 $gMainProgressBar;
	if (`progressBar -q -ic $gMainProgressBar`)
		{
		$asBakeFKIK=1;
		error "Interrupted";
		}
	currentTime $i;
	for ($y=0;$y<size($limbs);$y++)
		{
		$numChar=size($limbs[$y]);
		$side=`substring $limbs[$y] ($numChar-1) $numChar`;
		$sideLessLimb=`substring $limbs[$y] 1 ($numChar-2)`;
		if ($Fk2Ik)
			asAlignFKIK $nameSpace $sideLessLimb $side FK2IK;
		else
			asAlignFKIK $nameSpace $sideLessLimb $side IK2FK;
		}
	}
currentTime $curTime;
$asBakeFKIK=0;
if (!$autoKeyState)
	autoKeyframe -state 0;
}

global proc asCreateMoCap (string $uiName)
{
string $sel[]=`ls -sl`;
string $deformJoints[],$keyDeformJoints[],$tempString[],$tempString2[],$parent[],$names[],$extra[];
string $extr;
string $nameSpace;
if (`optionMenu -q -ex ($uiName+"OptionMenu")`)
	$nameSpace=`optionMenu -q -v ($uiName+"OptionMenu")`;
if ($nameSpace==":")
	$nameSpace="";
float $charHeight=`getAttr ($nameSpace+"Main.height")`;
if (`objExists ($nameSpace+"MoCap")`)
	error "MoCap skeleton already exists !";
if (!`objExists ($nameSpace+"Main")`)
	error "No AdvancedSKeleton In Scene!";
if (!`objExists ($nameSpace+"HipSwingerStabilizerTarget2")`)
	{
	string $dialog=`confirmDialog -t "Confirm"
	-m "HipSwinger controllers needs \"stabilize\" attribute for Mocap.\nAdd this now ?"
	-b "OK" -b "Skip" -b "Cancel" -db "Cancel"
	-ds "Cancel"`;
	if ($dialog=="Cancel")
		return;
	if ($dialog=="OK")
		{
		//Added for MoCap to rotate Root joint
		duplicate -n ($nameSpace+"HipSwingerStabilizerTarget2") ($nameSpace+"HipSwingerStabilizerTarget");
		parent ($nameSpace+"HipSwingerStabilizerTarget2") ($nameSpace+"FKExtraRoot_M");
		orientConstraint ($nameSpace+"HipSwingerStabilizerTarget2") ($nameSpace+"HipSwingerStabilizer");
		if (!`attributeExists stabilize ($nameSpace+"HipSwinger_M")`)
			addAttr -k 1 -ln stabilize -at double -min 0 -max 10 -dv 10 ($nameSpace+"HipSwinger_M");
		if (`objExists ($nameSpace+"HipSwingerStabilizerUnitConversion")`) delete ($nameSpace+"HipSwingerStabilizerUnitConversion");
		createNode -n ($nameSpace+"HipSwingerStabilizerUnitConversion") unitConversion;
		setAttr ($nameSpace+"HipSwingerStabilizerUnitConversion.conversionFactor") 0.1;
		connectAttr ($nameSpace+"HipSwinger_M.stabilize") ($nameSpace+"HipSwingerStabilizerUnitConversion.input");
		connectAttr ($nameSpace+"HipSwingerStabilizerUnitConversion.output") ($nameSpace+"HipSwingerStabilizer_orientConstraint1.HipSwingerStabilizerTargetW0");
		createNode -n ($nameSpace+"HipSwingerStabilizerReverse") reverse;
		connectAttr ($nameSpace+"HipSwingerStabilizerUnitConversion.output") ($nameSpace+"HipSwingerStabilizerReverse.inputX");
		connectAttr ($nameSpace+"HipSwingerStabilizerReverse.outputX") ($nameSpace+"HipSwingerStabilizer_orientConstraint1.HipSwingerStabilizerTarget2W1");
		}
	}

$deformJoints=`listRelatives -type joint -ad ($nameSpace+"DeformationSystem")`;
for ($a=$i=0;$a<size($deformJoints);$a++)
	{
	if (`gmatch $deformJoints[$a] "*Partial_*"`)
		continue;
	if (`gmatch $deformJoints[$a] "*_50"`)//same as *Partial_*, in rigs from v<5.9416
		continue;
	if (`gmatch $deformJoints[$a] "*Slider[0-9]*"`)
		continue;
	if (`objExists FaceAllSet`)
		if (`sets -im FaceAllSet $deformJoints[$a]`)
			continue;
	tokenize $deformJoints[$a] "_" $tempString;
	$extr=`substitute $nameSpace ("FKExtra"+$tempString[0]+"_"+$tempString[1]) ""`;
	if (`gmatch $deformJoints[$a] "*Part[0-9]*"`)
		continue;
	$keyDeformJoints[$i]=$deformJoints[$a];
	$extra[$i]=$extr;
	$tempString[0]=$keyDeformJoints[$i];
	for ($y=0;$y<99;$y++)
		{
		$tempString=`listRelatives -p $tempString[0]`;
		if (!`gmatch $tempString[0] "*Part[0-9]*"`)
			{
			tokenize $tempString[0] "_" $tempString;
			$parent[$i]=`substitute $nameSpace ($tempString[0]+"_MoCap_"+$tempString[1]) ""`;
			break;
			}
		}
	tokenize $keyDeformJoints[$i] "_" $tempString;
	string $name=$tempString[0]+"_MoCap_"+$tempString[1];
	if (!`stringArrayCount $name $names`)
		{
		$names[$i]=`substitute $nameSpace $name ""`;
		$i++;
		}
	}

string $topJoint;
for ($i=0;$i<size($names);$i++)
	{
	select -cl;
	joint -n $names[$i];
	if ($i==size($names)-1)
		{
		createNode -n "MoCap" transform;
		createNode -n "CenterOffset" transform;
		asAlign "CenterOffset" ($nameSpace+"RootExtraX_M") 1 0 0 0;
//		parent "MoCap" "Group";
		parent "CenterOffset" "MoCap";
		parent $names[$i] "CenterOffset";
		connectAttr ($names[$i]+".translate") ($nameSpace+"RootExtraX_M.translate");
		$topJoint=$names[$i];
		}
	asAlign $names[$i] $keyDeformJoints[$i] 1 1 1 0;
	setAttr ($names[$i]+".rotateOrder") 1;
	if (`objExists $extra[$i]`)
		setAttr ($extra[$i]+".rotateOrder") 1;
	}

for ($i=0;$i<size($names);$i++)
	{
	if (`objExists $parent[$i]`)
		parent $names[$i] $parent[$i];
	}
for ($i=0;$i<size($names);$i++)
	{
	if (`objExists ($names[$i]+"_blendColor")`)
		delete ($names[$i]+"_blendColor");
	createNode -n ($names[$i]+"_blendColor") blendColors;
	connectAttr ($names[$i]+".rotate") ($names[$i]+"_blendColor.color1");
	addAttr -k 1 -ln "blend" -at double -min 0 -max 1 -dv 1 $names[$i];
	connectAttr ($names[$i]+".blend") ($names[$i]+"_blendColor.blender");
	if (`objExists ($nameSpace+$extra[$i])`)
		connectAttr ($names[$i]+"_blendColor.output") ($nameSpace+$extra[$i]+".rotate");
	}
setAttr "MoCap.translateZ" ($charHeight/-3);
//orientConstraint -mo $topJoint "RootExtraX_M";
select $sel;
}

global proc asDeleteMocap (string $uiName)
{
if (`objExists MoCap`)
	delete MoCap;
delete `ls -type blendColors "*_MoCap_*_blendColor"`;
}

global proc asSetAllFK (string $nameSpace)
{
string $controlSetMembers[]=`sets -q ($nameSpace+"ControlSet")`;
for ($i=0;$i<size($controlSetMembers);$i++)
	if (`attributeExists FKIKBlend $controlSetMembers[$i]`)
		setAttr ($controlSetMembers[$i]+".FKIKBlend") 0;

if (`attributeExists stabilize ($nameSpace+"HipSwinger_M")`)
	setAttr ($nameSpace+"HipSwinger_M.stabilize") 0;
}

global proc asARKitAliasAttr ()
{
int $isArShapes;
string $newAttrName;
string $targets[];

if (!`objExists asFaceBS`)
	return;
$targets=`asBSGetTargets`;
for ($i=0;$i<size($targets);$i++)
	{
	if (`gmatch $targets[$i] "eyeBlinkLeft*"`)
		$isArShapes=1;
	if (`gmatch $targets[$i] "tongueOut*"`)
		$isArShapes=0;

	if (`gmatch $targets[$i] "*_M"`)
		$newAttrName=`substitute "_M" $targets[$i] ""`;
	else
		$newAttrName= $targets[$i]+"_M";
	aliasAttr $newAttrName ("asFaceBS."+$targets[$i]);
	}
}

global proc asConnectARKitUI (string $uiName)
{
string $blendShapes[]=`ls -type blendShape`;

if (`asHotKeyCheck "asConnectARKitUI \"\""`) return;
string $nameSpace=`asNameSpaceFromUIName $uiName`;

if (`window -q -ex asConnectARKitUI`)
	deleteUI asConnectARKitUI;
window -t "Connect ARKit" asConnectARKitUI;
columnLayout -adj 1;
text -l "Connect to FaceCap, Aquifer, iFacialMocap\nand other sofware that use Apple-ArKit";

separator -st none -h 10;
rowLayout -nc 3;
	button -c asARKChooseHeadRotNode "Choose Head Rotation Node";
	separator -st none -w 10;
	textField -ed 0 -tx "none" asConnectARKitHRTextField;
	setParent..;
separator -st none -h 5;
button -l "Connect Head Rotation" -c ("asARKConnectHeadRotation \""+$uiName+"\"");
separator -st none -h 5;
button -l "Disconnect Head Rotation" -c ("asARKDisconnectHeadRotation \""+$uiName+"\"");
separator -st none -h 40;

optionMenu -l "BlendShape Node" asConnectARKitBSOptionMenu;
for ($i=0;$i<size($blendShapes);$i++)
	{
	if (`gmatch $blendShapes[$i] ($nameSpace+"*asFace*")`
	 || `gmatch $blendShapes[$i] ($nameSpace+"*Close*BS*")`
	 || `gmatch $blendShapes[$i] ($nameSpace+"*SquintRightToLeft*")`)
		continue;
	menuItem -l $blendShapes[$i];
	}

separator -st none -h 20;
button -l "Connect" -c ("asConnectARKit \""+$uiName+"\"");
button -l "Disconnect" -c ("asDisconnectARKit \""+$uiName+"\"");
separator -st none -h 10;
button -l "bake" -c ("asBakeARKit \""+$uiName+"\"");
showWindow;
}

global proc asARKChooseHeadRotNode ()
{
string $sel[]=`ls -sl`;
textField -e -tx $sel[0] asConnectARKitHRTextField;
}

global proc asARKConnectHeadRotation (string $uiName)
{
int $autoKeyState=`autoKeyframe -q -state`;
string $arHeadRotObject=`textField -q -tx asConnectARKitHRTextField`;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $tempString[];

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";
if (!`objExists ($nameSpace+"FKHead_M")`)
	error ("Object \""+$nameSpace+"FKHead_M\" not found, you might not be using a AdvancedSkeleton body rig.\nManually constraint head rotation.");
if (!`objExists $arHeadRotObject`)
	error ("Object:\""+$arHeadRotObject+"\" not found, Choose the object that has the head rotation animation.");

if ($autoKeyState) autoKeyframe -state 0;
if (`objExists asARKHeadOrientation`) delete asARKHeadOrientation;
if (`objExists asARKHeadOrientation_orientConstraint`) delete asARKHeadOrientation_orientConstraint;
createNode -n asARKHeadOrientation -p ($nameSpace+"FKHead_M") transform;
setAttr ($arHeadRotObject+".r") -type float3 0 0 0;
parent asARKHeadOrientation $arHeadRotObject;
$tempString=`orientConstraint asARKHeadOrientation ($nameSpace+"FKHead_M")`;
rename asARKHeadOrientation_orientConstraint;
if ($autoKeyState) autoKeyframe -state 1;
dgdirty -a;
print ("// Head rotation connected.\n");
select -cl;
}

global proc asARKDisconnectHeadRotation (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";
if (`objExists asARKHeadOrientation_orientConstraint`)
	delete asARKHeadOrientation_orientConstraint;
setAttr ($nameSpace+"FKHead_M.r") -type float3 0 0 0;
}

global proc asConnectARKit (string $uiName)
{
asEnsureAsGetScriptLocation;//needs asDsSdk
int $createCtrlMode,$connectToCtrlMode,$snapChat;
int $autoKeyState=`autoKeyframe -q -state`;
int $audio2FaceViaConnectARKitUI=`objExists Audio2FaceViaConnectARKitUI`;
if ($audio2FaceViaConnectARKitUI)
	delete Audio2FaceViaConnectARKitUI;
int $mouthCloseIncMouthOpen;
if (`checkBox -q -ex asAudio2FaceMouthCloseIncMouthOpenCheckBox`)
	$mouthCloseIncMouthOpen=`checkBox -q -v asAudio2FaceMouthCloseIncMouthOpenCheckBox`;
float $v=1;
float $posA[],$posB[];
string $ctrl="ctrlARKit_M";
string $name,$altName,$side,$leftRight,$oppositeSide,$bs;
string $nameSpace=`asNameSpaceFromUIName $uiName`;

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";

if (`attributeExists SnapChat FaceFitSkeleton`)
	if (`getAttr FaceFitSkeleton.SnapChat`)
		{
		$snapChat=1;
		$ctrl="ctrlSnapChat_M";
		}

if (`objExists ($nameSpace+$ctrl)` && !`attributeExists eyeBlinkLeft ($nameSpace+$ctrl)`)
	$createCtrlMode=1;
if (`objExists ($nameSpace+$ctrl)` && `attributeExists eyeBlinkLeft ($nameSpace+$ctrl)`)
	$connectToCtrlMode=1;

if ($snapChat)
	$createCtrlMode=1;

if ($createCtrlMode)
	{
	$bs=$nameSpace+$ctrl;
	addAttr -k 0 -ln createCtrlMode -at bool ($nameSpace+$ctrl);
	}
else
	{
	if ($audio2FaceViaConnectARKitUI)
		$bs=`optionMenu -q -v asAudio2FaceBSOptionMenu`;
	else
		$bs=`optionMenu -q -v asConnectARKitBSOptionMenu`;
	if (!$connectToCtrlMode)
		if (`attributeExists RigType ($nameSpace+"FaceFitSkeleton")`)
			if (`getAttr ($nameSpace+"FaceFitSkeleton.RigType")`==1)
				error "Face Rig Type \"BlendShapes\" detected. To use Connect ARKit, you must build Face Rig Type \"Joints\".";
	if (!`objExists $bs`)
		error "Not a valid blendShape node";
	}

//ARKit shapes from https://developer.apple.com/documentation/arkit/arfaceanchor/blendshapelocation
string $arShapes[]={"eyeBlinkLeft","eyeLookDownLeft","eyeLookInLeft","eyeLookOutLeft","eyeLookUpLeft","eyeSquintLeft","eyeWideLeft",
									"eyeBlinkRight","eyeLookDownRight","eyeLookInRight","eyeLookOutRight","eyeLookUpRight","eyeSquintRight","eyeWideRight",
									"jawForward","jawLeft","jawRight","jawOpen","mouthClose","mouthFunnel","mouthPucker","mouthLeft","mouthRight",
									"mouthSmileLeft","mouthSmileRight","mouthFrownLeft","mouthFrownRight","mouthDimpleLeft","mouthDimpleRight",
									"mouthStretchLeft","mouthStretchRight","mouthRollLower","mouthRollUpper","mouthShrugLower","mouthShrugUpper",
									"mouthPressLeft","mouthPressRight","mouthLowerDownLeft","mouthLowerDownRight","mouthUpperUpLeft","mouthUpperUpRight",
									"browDownLeft","browDownRight","browInnerUp","browOuterUpLeft","browOuterUpRight","cheekPuff","cheekSquintLeft",
									"cheekSquintRight","noseSneerLeft","noseSneerRight","tongueOut"};

//SnapChat shapes from https://docs.snap.com/api/lens-studio/Classes/OtherClasses/#Expressions
string $scShapes[]={"EyeBlinkLeft","EyeDownLeft","EyeInLeft","EyeOutLeft","EyeUpLeft","EyeSquintLeft","EyeOpenLeft",
									"EyeBlinkRight","EyeDownRight","EyeInRight","EyeOutRight","EyeUpRight","EyeSquintRight","EyeOpenRight",
									"JawForward","JawLeft","JawRight","JawOpen","MouthClose","LipsFunnel","LipsPucker","MouthLeft","MouthRight",
									"MouthSmileLeft","MouthSmileRight","MouthFrownLeft","MouthFrownRight","MouthDimpleLeft","MouthDimpleRight",
									"MouthStretchLeft","MouthStretchRight","LowerLipClose","UpperLipClose","LowerLipRaise","UpperLipRaise",
									//"mouthPressLeft","mouthPressRight" Would go here
																													"LowerLipDownLeft","LowerLipDownRight","UpperLipUpLeft","UpperLipUpRight",
									"BrowsDownLeft","BrowsDownRight","BrowsUpCenter","BrowsUpLeft","BrowsUpRight","Puff","CheekSquintLeft",
									"CheekSquintRight","SneerLeft","SneerRight",
									"MouthUpLeft","MouthUpRight"};//these last 2 does not have ARKit equivalents

//SnapChat does not have equivalents for: "mouthPressLeft","mouthPressRight","tongueOut"
// and it has shapes that are not in ARKit: "MouthUpLeft","MouthUpRight"
// special Note: "mouthRollLower"->"LowerLipClose" && "mouthRollUpper"->"UpperLipClose"
if ($snapChat)
	$arShapes=`stringArrayRemove {"mouthPressLeft","mouthPressRight","tongueOut"} $arShapes`;

if ($createCtrlMode)
	for ($i=0;$i<size($arShapes);$i++)
		{
		$name=$arShapes[$i];
		if ($snapChat)
			$name=$scShapes[$i];
		$v=10;
		addAttr -k 1 -ln $name -at double -smn 0 -hsn 1 -smx 10 -hsx 1 $bs;
		asEnsureOutputBlendWeighted ($bs+"."+$name);
		}

if (!$createCtrlMode && !$connectToCtrlMode && !`objExists ARKitQuickConnecting`)
	createNode -n ARKitQuickConnecting transform;

currentTime 0;
if ($autoKeyState) autoKeyframe -state 0;
for ($i=0;$i<size($arShapes);$i++)
	{
	$name=$arShapes[$i];
	if ($snapChat)
		$name=$scShapes[$i];
	$attr=$name;
	$altName=`substitute "Right" $name "_R"`;
	$altName=`substitute "Left" $altName "_L"`;

	//some Apps rename the "Right" suffix to "_R" for some attributes (e.g FaceCap)
	if ((catchQuiet (`getAttr ($bs+"."+$name)`)) && (!catchQuiet (`getAttr ($bs+"."+$altName)`)))
		$attr=$altName;

	if ((catchQuiet (`getAttr ($bs+"."+$name)`)) && (catchQuiet (`getAttr ($bs+"."+$altName)`)))
		{
		print ("Missing ARKit BlendShapes target: "+($bs+"."+$altName)+"\n");
		continue;
		}

//	setAttr ($bs+"."+$attr) 0;//removed since audio2face via ACE bs attrs are locked via connection

	if ($connectToCtrlMode)
		{
		catch (`setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0  -cd ($bs+"."+$attr) ($nameSpace+$ctrl+"."+$name)`);
		catch (`setDrivenKeyframe -itt "linear" -ott "linear" -v 10 -dv 1 -cd ($bs+"."+$attr) ($nameSpace+$ctrl+"."+$name)`);

		if ($arShapes[$i]=="mouthClose" && $mouthCloseIncMouthOpen)
			{
			catch (`setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0  -cd ($bs+"."+$attr) ($nameSpace+$ctrl+".jawOpen")`);
			catch (`setDrivenKeyframe -itt "linear" -ott "linear" -v 10 -dv 1 -cd ($bs+"."+$attr) ($nameSpace+$ctrl+".jawOpen")`);
			}

		continue;
		}

	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  {$side="_R";$leftRight="Right";$oppositeSide="_L";}
		if ($b==-1) {$side="_L";$leftRight="Left";$oppositeSide="_R";}

		if ($arShapes[$i]=="eyeBlink"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".blink") $v 10;
		if ($arShapes[$i]=="eyeLookDown"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".ty") $v -1;
		if ($arShapes[$i]=="eyeLookIn"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".tx") $v (1*$b);
		if ($arShapes[$i]=="eyeLookOut"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".tx") $v (-1*$b);
		if ($arShapes[$i]=="eyeLookUp"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".ty") $v 1;
		if ($arShapes[$i]=="eyeSquint"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".squint") $v 10;
//		if ($arShapes[$i]=="eyeWide"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".blink") $v -2;
		if ($arShapes[$i]=="eyeWide"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".wide") $v 10;
		if ($arShapes[$i]=="mouthDimple"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".tx") $v 0.3;
		if ($arShapes[$i]=="browOuterUp"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlBrow"+$side+".outerUpDown") $v 7.5;
		if ($arShapes[$i]=="noseSneer"+$leftRight) asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlNose"+$side+".ty") $v 0.5;

		//AdvSkel has Center ctrl for these side attrs
		if ($arShapes[$i]=="mouth"+$leftRight)
			{
			if ($arShapes[$i]=="mouthRight") asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.tx") $v -1;
			if ($arShapes[$i]=="mouthLeft")  asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.tx") $v  1;
			}

		//Drive multiple attr
		if ($arShapes[$i]=="mouthSmile"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".tx") $v 0.75;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".ty") $v 0.75;
			}
		if ($arShapes[$i]=="mouthFrown"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".tx") $v  0.25;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".ty") $v -0.25;
			}
		if ($arShapes[$i]=="mouthStretch"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".tx") $v  0.5;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".ty") $v -0.5;
			}
//// Removed, since any ARKit attrs that are L or R and Drive Center ctrl, fails to detect and remove zero-set SDK`
		if ($arShapes[$i]=="mouthPressRight" || $arShapes[$i]=="mouthPressLeft")//common for l/r first, then one by one
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.upperSqueeze") $v 1.5;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.lowerSqueeze") $v  1.5;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKLipRegion_M.ty") $v 0.1;
			}

		if ($arShapes[$i]=="mouthPress"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouthCorner"+$side+".ty") $v 0.25;
//			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKupperLipA"+$side+".ty") $v 0.5;
//			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKlowerLipA"+$side+".ty") $v 0.5;
//			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKLip"+$side+".sy") $v 0.5;
			}
		if ($arShapes[$i]=="mouthLowerDown"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKlowerLipA"+$side+".ty") $v -0.4;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKlowerLip_M.ty") 10 -0.3;
			}
		if ($arShapes[$i]=="mouthUpperUp"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKupperLipA"+$side+".ty") 10 0.4;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKupperLip_M.ty") $v 0.3;
			}
		if ($arShapes[$i]=="browDown"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlBrow"+$side+".ty") $v -0.75;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlBrow"+$side+".squeeze") $v 7.5;
			}
		if ($arShapes[$i]=="cheekSquint"+$leftRight)
			{
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlEye"+$side+".squint") $v 3;
			asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKCheek"+$side+".ty") $v 0.1;
			}
		}

	//Middle shapes
	if (`attributeExists jawForward ($nameSpace+"ctrlMouth_M")`)//backwards compataqbility for rigs<v5.750
		{
		if ($arShapes[$i]=="jawForward") asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouth_M.jawForward") $v 5;
		if ($arShapes[$i]=="jawRight") asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouth_M.jawSide") $v -5;
		if ($arShapes[$i]=="jawLeft")  asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouth_M.jawSide") $v 5;
		}
	if ($arShapes[$i]=="jawOpen") asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouth_M.ty") $v -1;
	if ($arShapes[$i]=="mouthClose")//mixed with the opposite amount of JawOpen gives stickylips
		{
		setAttr ($nameSpace+"ctrlMouth_M.ty") 0;
		$posA=`xform -q -ws -t ($nameSpace+"lowerLip_M")`;
		setAttr ($nameSpace+"ctrlMouth_M.ty") -1;
		$posB=`xform -q -ws -t ($nameSpace+"lowerLip_M")`;
		xform -ws -t $posB[0] ($posB[1]+($posA[1]-$posB[1])) $posB[2] ($nameSpace+"lowerLip_M");
		$posA=`getAttr ($nameSpace+"lowerLip_M.t")`;
		setAttr ($nameSpace+"ctrlMouth_M.ty") 0;
		setAttr ($nameSpace+"lowerLip_M.t") -type float3 0 0 0;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKlowerLip_M.ty") $v ($posA[1]/2.0);
		asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKupperLip_M.ty") $v ($posA[1]/-2.0);
		if ($mouthCloseIncMouthOpen)//option to conpensate for audio2face bug
			asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouth_M.ty") $v -1;
		}
	if ($arShapes[$i]=="mouthPucker")
		{
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.upperPucker") $v 10;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.lowerPucker") $v 10;
		}
	if ($arShapes[$i]=="mouthFunnel")
		{
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.upperPucker") $v 10;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.lowerPucker") $v 10;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKupperLip_M.ty") $v 0.3;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKlowerLip_M.ty") $v -0.3;
		}
	if ($arShapes[$i]=="mouthRollUpper") asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.upperRoll") $v -5;
	if ($arShapes[$i]=="mouthRollLower") asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlLips_M.lowerRoll") $v -5;
	if ($arShapes[$i]=="mouthShrugUpper") asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKupperLip_M.ty") $v 0.3;
	if ($arShapes[$i]=="mouthShrugLower") asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKlowerLip_M.ty") $v 0.3;
	if ($arShapes[$i]=="browInnerUp")
		{
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlBrow_R.tx") $v 1;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlBrow_L.tx") $v 1;
		}
	if ($arShapes[$i]=="cheekPuff")
		{
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlCheek_R.tx") $v 0.4;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlCheek_L.tx") $v 0.4;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"ctrlMouth_M.tx") $v -0.2;
		}
	if ($arShapes[$i]=="tongueOut")
		{
		asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKTongue0_M.tx") $v 1.5;
		asDsSdk ($bs+"."+$attr) ($nameSpace+"SDKTongue0_M.rz") $v 15;
		}
	}
/*
if ($audio2FaceViaConnectARKitUI)
	{
	setAttr ($nameSpace+"Lip_R.followJawFollow_R") 2.5;
	setAttr ($nameSpace+"Lip_L.followJawFollow_L") 2.5;
	setAttr ($nameSpace+"lowerLip_M.followJawFollow_M") 5;
	}
*/
if ($autoKeyState) autoKeyframe -state 1;
dgdirty -a;
if (`objExists ARKitQuickConnecting`) delete ARKitQuickConnecting;
print ("// ARKit connected.\n");
select -cl;
}

global proc asDisconnectARKit (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $tempString[],$controls[];

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";

$controls=`sets -q ($nameSpace+"FaceControlSet")`;
for ($i=0;$i<size($controls);$i++)
	{
	$tempString=`listConnections -s 1 -d 0 -type animCurve $controls[$i]`;
	if (size($tempString)) delete $tempString;
	$tempString=`listConnections -s 1 -d 0 -type blendWeighted $controls[$i]`;
	if (size($tempString)) delete $tempString;
	}
asGoToBuildPoseOptions $nameSpace "FaceControlSet";
}

global proc asBakeARKit (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $controls[];

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";

$controls=`sets -q ($nameSpace+"FaceControlSet")`;
if (`objExists ($nameSpace+"FKHead_M")`)
	$controls[size($controls)]=($nameSpace+"FKHead_M");
select -cl;
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl 0 -preserveOutsideKeys 0 -sparseAnimCurveBake false -controlPoints false -shape false $controls;
select $controls;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";
select -cl;
print ("// ARKit bake complete.\n");
}

global proc asConnectAudio2Face (string $uiName)
{
createNode -n Audio2FaceViaConnectARKitUI transform;
asConnectARKit $uiName;
}

global proc asDisconnectAudio2Face (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $bs=`optionMenu -q -v asAudio2FaceBSOptionMenu`;
string $tempString[],$controls[];

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";

if (!`objExists $bs`)
	error ("BlendShape Node:\""+$bs+"\" Not found");
$tempString=`listConnections -s 0 -d 1 -type animCurve $bs`;
for ($i=0;$i<size($tempString);$i++)
	delete $tempString[$i];

asGoToBuildPoseOptions $nameSpace "FaceControlSet";
print ("// Audio2Face disconnected.\n");
}

global proc asConnectMocapX (string $uiName)
{
string $side,$leftRight,$LeftRight;
string $requiredObj[]={"MocapX"};

if (`asHotKeyCheck "asConnectMocapX \"\""`) return;
string $nameSpace=`asNameSpaceFromUIName $uiName`;

for ($obj in $requiredObj)
	if (!`objExists $obj`)
		error ("Required object:\""+$obj+"\" does not exists. Make sure MocapX is loaded and the MocapX node is created.");

createNode -n AdvancedSkeletonHeadOffset transform;
//setAttr AdvancedSkeletonHeadOffset.r -type float3 90 0 90;
orientConstraint -mo AdvancedSkeletonHeadOffset ($nameSpace+"FKHead_M");

setAttr ($nameSpace+"ctrlBox.limits") 0;

for ($b=1;$b>-2;$b=$b-2)
	{
	if ($b==1)  {$side="_R";$leftRight="right";$LeftRight="Right";}
	if ($b==-1) {$side="_L";$leftRight="left";$LeftRight="Left";}

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX."+$leftRight+"EyeTransformRotateY") ($nameSpace+"ctrlEye"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 30 -cd ("MocapX."+$leftRight+"EyeTransformRotateY") ($nameSpace+"ctrlEye"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX."+$leftRight+"EyeTransformRotateX") ($nameSpace+"ctrlEye"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv -30 -cd ("MocapX."+$leftRight+"EyeTransformRotateX") ($nameSpace+"ctrlEye"+$side+".ty");

	setAttr ("ctrlEye"+$side+"_translateX.preInfinity") 4;
	setAttr ("ctrlEye"+$side+"_translateX.postInfinity") 4;
	setAttr ("ctrlEye"+$side+"_translateY.preInfinity") 4;
	setAttr ("ctrlEye"+$side+"_translateY.postInfinity") 4;

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.eyeBlink"+$side) ($nameSpace+"ctrlEye"+$side+".blink");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 10 -dv 1 -cd ("MocapX.eyeBlink"+$side) ($nameSpace+"ctrlEye"+$side+".blink");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.browInnerUp ($nameSpace+"EyeBrowInner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd MocapX.browInnerUp ($nameSpace+"EyeBrowInner"+$side+".ty");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.browDown"+$side) ($nameSpace+"EyeBrowInner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.5 -dv 1 -cd ("MocapX.browDown"+$side) ($nameSpace+"EyeBrowInner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.browDown"+$side) ($nameSpace+"EyeBrowInner"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.5 -dv 1 -cd ("MocapX.browDown"+$side) ($nameSpace+"EyeBrowInner"+$side+".tx");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.browOuterUp"+$side) ($nameSpace+"EyeBrowOuter"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd ("MocapX.browOuterUp"+$side) ($nameSpace+"EyeBrowOuter"+$side+".ty");

	if (`attributeExists EyeBrowMid2Joint ($nameSpace+"EyeBrowOuter"+$side)`)
		setAttr ($nameSpace+"EyeBrowOuter"+$side+".EyeBrowMid2Joint") .75;
	if (`attributeExists EyeBrowMid1Joint ($nameSpace+"EyeBrowInner"+$side)`)
		setAttr ($nameSpace+"EyeBrowInner"+$side+".EyeBrowMid1Joint") .75;

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.eyeSquint"+$side) ($nameSpace+"lowerLid"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd ("MocapX.eyeSquint"+$side) ($nameSpace+"lowerLid"+$side+".ty");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.eyeWide"+$side) ($nameSpace+"ctrlEye"+$side+".blink");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -1 -dv 1 -cd ("MocapX.eyeWide"+$side) ($nameSpace+"ctrlEye"+$side+".blink");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.cheekPuff ($nameSpace+"Cheek"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0.5 -dv 1 -cd MocapX.cheekPuff ($nameSpace+"Cheek"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.cheekPuff ($nameSpace+"Cheek"+$side+".tz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd MocapX.cheekPuff ($nameSpace+"Cheek"+$side+".tz");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.cheekSquint"+$side) ($nameSpace+"ctrlEye"+$side+".squint");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 3 -dv 1 -cd ("MocapX.cheekSquint"+$side) ($nameSpace+"ctrlEye"+$side+".squint");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.noseSneer"+$side) ($nameSpace+"NoseCorner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0.5 -dv 1 -cd ("MocapX.noseSneer"+$side) ($nameSpace+"NoseCorner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.noseSneer"+$side) ($nameSpace+"NoseCorner"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.2 -dv 1 -cd ("MocapX.noseSneer"+$side) ($nameSpace+"NoseCorner"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.noseSneer"+$side) ($nameSpace+"EyeBrowInner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.5 -dv 1 -cd ("MocapX.noseSneer"+$side) ($nameSpace+"EyeBrowInner"+$side+".ty");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.jawForward ($nameSpace+"Jaw_M.tz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd MocapX.jawForward ($nameSpace+"Jaw_M.tz");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.jawLeft ($nameSpace+"Jaw_M.tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd MocapX.jawLeft ($nameSpace+"Jaw_M.tx");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.jawRight ($nameSpace+"Jaw_M.tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -1 -dv 1 -cd MocapX.jawRight ($nameSpace+"Jaw_M.tx");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouth"+$LeftRight) ($nameSpace+"ctrlMouthCorner"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 1 -dv 1 -cd ("MocapX.mouth"+$LeftRight) ($nameSpace+"ctrlMouthCorner"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouth"+$LeftRight) ($nameSpace+"ctrlMouthCorner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0.3 -dv 1 -cd ("MocapX.mouth"+$LeftRight) ($nameSpace+"ctrlMouthCorner"+$side+".ty");

	if (`attributeExists sticky ($nameSpace+"Lip"+$side)`)
		{
		setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthClose ($nameSpace+"Lip"+$side+".sticky");
		setDrivenKeyframe -itt "linear" -ott "linear" -v 10 -dv 1 -cd MocapX.mouthClose ($nameSpace+"Lip"+$side+".sticky");
		}

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthSmile"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0.75 -dv 1 -cd ("MocapX.mouthSmile"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".ty");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthFrown"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.75 -dv 1 -cd ("MocapX.mouthFrown"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".ty");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthDimple"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".tx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0.75 -dv 1 -cd ("MocapX.mouthDimple"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".tx");

	if (`objExists ($nameSpace+"upperLipA"+$side)`) //does not exist for Simplified FaceSetup
		{
		setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthUpperUp"+$side) ($nameSpace+"upperLipA"+$side+".ty");
		setDrivenKeyframe -itt "linear" -ott "linear" -v 0.5 -dv 1 -cd ("MocapX.mouthUpperUp"+$side) ($nameSpace+"upperLipA"+$side+".ty");
		setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthLowerDown"+$side) ($nameSpace+"lowerLipA"+$side+".ty");
		setDrivenKeyframe -itt "linear" -ott "linear" -v -0.5 -dv 1 -cd ("MocapX.mouthLowerDown"+$side) ($nameSpace+"lowerLipA"+$side+".ty");
		}
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthUpperUp"+$side) ($nameSpace+"upperLip_M.ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0.2 -dv 1 -cd ("MocapX.mouthUpperUp"+$side) ($nameSpace+"upperLip_M.ty");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthLowerDown"+$side) ($nameSpace+"lowerLip_M.ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.2 -dv 1 -cd ("MocapX.mouthLowerDown"+$side) ($nameSpace+"lowerLip_M.ty");

//	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthPress"+$side) ?;

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ("MocapX.mouthStretch"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".ty");
	setDrivenKeyframe -itt "linear" -ott "linear" -v -0.75 -dv 1 -cd ("MocapX.mouthStretch"+$side) ($nameSpace+"ctrlMouthCorner"+$side+".ty");
	}

//setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthFunnel ?;

setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthPucker ($nameSpace+"ctrlMouth_M.tx");
setDrivenKeyframe -itt "linear" -ott "linear" -v -1 -dv 1 -cd MocapX.mouthPucker ($nameSpace+"ctrlMouth_M.tx");

setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.jawOpen ($nameSpace+"ctrlMouth_M.ty");
setDrivenKeyframe -itt "linear" -ott "linear" -v -2 -dv 1 -cd MocapX.jawOpen ($nameSpace+"ctrlMouth_M.ty");

setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthRollUpper ($nameSpace+"ctrlLips_M.upperRoll");
setDrivenKeyframe -itt "linear" -ott "linear" -v -5 -dv 1 -cd MocapX.mouthRollUpper ($nameSpace+"ctrlLips_M.upperRoll");

setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthRollLower ($nameSpace+"ctrlLips_M.lowerRoll");
setDrivenKeyframe -itt "linear" -ott "linear" -v -5 -dv 1 -cd MocapX.mouthRollLower ($nameSpace+"ctrlLips_M.lowerRoll");

setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthShrugUpper ($nameSpace+"upperLip_M.ty");
setDrivenKeyframe -itt "linear" -ott "linear" -v 0.5 -dv 1 -cd MocapX.mouthShrugUpper ($nameSpace+"upperLip_M.ty");

setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd MocapX.mouthShrugLower ($nameSpace+"lowerLip_M.ty");
setDrivenKeyframe -itt "linear" -ott "linear" -v 0.5 -dv 1 -cd MocapX.mouthShrugLower ($nameSpace+"lowerLip_M.ty");

connectAttr MocapX.transformRotateX AdvancedSkeletonHeadOffset.rx;
connectAttr MocapX.transformRotateY AdvancedSkeletonHeadOffset.ry;
connectAttr MocapX.transformRotateZ AdvancedSkeletonHeadOffset.rz;

print ("// MocapX connected.\n");
}

global proc asMetaHumanAnimatorUI (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;

if (`asHotKeyCheck "asMetaHumanAnimator \"\""`) return;

if (`window -q -ex asMetaHumanAnimatorUI`)
	deleteUI asMetaHumanAnimatorUI;
window -w 300 -h 150 -t "MetaHuman Animator" asMetaHumanAnimatorUI;
columnLayout;
text -m 0 -l $nameSpace asMetaHumanAnimatorNameSpaceText;
separator -st none -h 15;
rowLayout -nc 2;
	separator -st none -w 50;
	button -l "Connect Face Animation" -c asMetaHumanAnimatorConnect;
	setParent..;
separator -st none -h 15;
rowLayout -nc 3;
	text -l "Optional:";
	button -l "Connect Head Rotation" -c "asMetaHumanAnimatorConnectHead 0";
	button -l "Connect Head Translation" -c "asMetaHumanAnimatorConnectHead 1";
	setParent..;
separator -st none -h 15;
rowLayout -nc 4;
	separator -st none -w 50;
	button -l "Delete root" -c "delete root";
	separator -st none -w 10;
	button -l "Delete animation" -c asMetaHumanAnimatorDeleteAnimation;
	setParent..;
separator -st none -h 15;
rowLayout -nc 2;
	separator -st none -w 50;
	button -l "Bake to standard Face Controls" -c asMetaHumanAnimatorBake;
	setParent..;

showWindow;
}

global proc asMetaHumanAnimatorConnectHead (int $mode) 
{
float $height=10;
string $animCurve="root_HeadYaw";
string $a,$b;
string $as[]={"root_HeadRoll","root_HeadPitch","root_HeadYaw"};
string $bs[]={"FKHead_M.rotateX","FKHead_M.rotateY","FKHead_M.rotateZ"};
string $nameSpace=`text -q -l asMetaHumanAnimatorNameSpaceText`;
if ($mode==1)
	{
	$as={"root_HeadTranslationX","root_HeadTranslationY","root_HeadTranslationZ"};
	$bs={"FKHead_M.translateX","FKHead_M.translateY","FKHead_M.translateZ"};
	}

if (`attributeExists height ($nameSpace+"Main")`)
	$height=`getAttr ($nameSpace+"Main.height")`;

for ($i=0;$i<size($as);$i++)
	{
	$a=$as[$i];
	$b=$nameSpace+$bs[$i];
	if (!`objExists $a`) warning ("Not found:\""+$a+"\".\n");
	if (!`objExists $b`) warning ("Not found:\""+$b+"\".\n");
	if (`objExists $a` && `objExists $b`)
		{
		$animCurve=`substitute "[.]" $b"_"`;
		if (`objExists $animCurve`)
			delete $animCurve;
		duplicate -n $animCurve $a;
		if ($a=="root_HeadTranslationZ")
			scaleKey -iub false -index "0:99999" -ts 1 -tp 0 -fs 1 -fp 458 -vs -1 -vp 0 $animCurve;
		if ($mode==1)
			scaleKey -iub false -index "0:99999" -ts 1 -tp 0 -fs 1 -fp 458 -vs ($height/160.0) -vp 0 $animCurve;
		connectAttr ($animCurve+".output") $b;
		}
	}
}

global proc asMetaHumanAnimatorConnect ()
{
int $numConnected;
float $keyXValues[],$keyYValues[];
string $animCurve,$side,$a,$b,$target,$nonNsName;
string $tempString[];
string $requiredObj[]={"root"};
//string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $nameSpace=`text -q -l asMetaHumanAnimatorNameSpaceText`;

if (!`objExists ($nameSpace+"FRM_faceGUI")`)
	error ($nameSpace+"FRM_faceGUI not found. The rig does not have MetaHuman ControlPanel added.");

for ($obj in $requiredObj)
	if (!`objExists $obj`)
		error ("Required object:\""+$obj+"\" does not exists. Make sure a MetaHuman-Animator FBX-Animation file is imported.");

if (`objExists asMetaHumanAnimatorSideWaysControls`)
	delete asMetaHumanAnimatorSideWaysControls;
createNode -n asMetaHumanAnimatorSideWaysControls transform;

//$tempString=`ls -type animCurve "*_CTRL_*"`;
// UnKnown: eyeLowerLidDownL eyeLowerLidUpL eyeWidenL
// Skip: eyeParallelLookDirection eyePupilNarrowR eyeRelaxL eyeUpperLidUpL eyelashesDownINL headTiltLeftD headTurnDownD jawChinCompressL lookAtSwitch
// Skip as no equivalent in AS yet: jawClenchL
// Skip because can not find equi:    mouthLipsPullDL mouthLipsPullUL mouthLipsTightenUL tongueRoll(tongue cups) tongueRollUp/Down/Left/Right
// Skip, ignoring (seems static): mouthLipsStickyLPh1-3 neckSwallowPh1-5 neckThroatUp-Down neckThroatInhale-Exhale neckDigastricUp-Down noseWrinkleUpperL skullUnified teeth*
// Skip, as ASMetaHuman control appears to not be matching latest MH: mouthLipsThickInwardDL tongueThick/Thin
// Not found : Opposite of mouthLipsPushUL & mouthLipsPushDL
string $as[]={"browDown", "browLateral", "browRaiseIn","browRaiseOuter","earUp","eyeBlink","eyeFaceScrunch",    "eyeCheekRaise", "eyeLidPress",
	"eyeLookUp","eyeLookDown",      "eyeLookLeft",   "eyeLookRight",					       "eyeSquintInner", "jawBack",    "jawFwd",         "jawChinRaiseD", "jawChinRaiseU",
	"jawLeft",       "jawRight",       "jawOpen","jawOpenExtreme", "mouthCheekBlow","mouthCheekSuck","mouthCornerDepress","mouthCornerPull", "mouthDimple",
	"mouthCornerUp","mouthCornerDown",     "mouthCornerWide",         "mouthCornerNarrow",
	"mouthCornerSharpenU","mouthCornerRounderU","mouthCornerSharpenD","mouthCornerRounderD",
	"mouthUp","mouthDown","mouthLeft","mouthRight",
	"mouthFunnelU","mouthFunnelD","mouthLipsBlow","mouthLipsPress","mouthLipsPurseU","mouthLipsPurseD","mouthLipsPushU","mouthLipsPushD",
	"mouthLipsThickU","mouthLipsThinU","mouthLipsThickD","mouthLipsThinD","mouthLipsTogetherU","mouthLipsTogetherD","mouthUpperLipTowardsTeeth","mouthLowerLipTowardsTeeth",
	"mouthUpperLipBite","mouthLowerLipBite","mouthLowerLipDepress","mouthUpperLipRollIn","mouthUpperLipRollOut","mouthLowerLipRollIn","mouthLowerLipRollOut",
	"mouthUpperLipShiftLeft","mouthUpperLipShiftRight","mouthLowerLipShiftLeft","mouthLowerLipShiftRight","mouthPressU","mouthPressD",
	"mouthSharpCornerPull","mouthStickyUC","mouthStickyDC","mouthStickyUIN","mouthStickyDIN","mouthStickyUOUT","mouthStickyDOUT",
	"mouthStretch","mouthStretchLipsClose","mouthUpperLipRaise","mouthLipsTowardsU","mouthLipsTowardsD",
	"neckMastoidContract","neckStretch","noseNasolabialDeepen",
	"noseWrinkle","noseNostrilDepress","noseNostrilDilate","noseNostrilCompress",//"noseNostrilDilate","noseNostrilCompress"  //depress=-y Compress=-x Dialite=X  Y?="noseWrinkleL" !Nostril
	"tongueUp","tongueDown","tongueLeft","tongueRight",//tongue ctrl
	"tongueBendUp","tongueBendDown","tongueTwistLeft","tongueTwistRight",//tongue_bendTwist ctrl
	"tongueTipUp","tongueTipDown","tongueTipLeft","tongueTipRight",//tongue_tip ctrl
	"tongueIn","tongueOut","tongueWide","tongueNarrow","tonguePress"};

string $bs[]={"brow_down","brow_lateral","brow_raiseIn","brow_raiseOut","ear_up","eye_blink","eye_faceScrunch", "eye_cheekRaise","eye_lidPress",
	"eye",      "HolderEyeLookDown","eye.translateX","HolderEyeLookRight.translateX","eye_squintInner","jaw_fwdBack","HolderJawForward","jaw_ChinRaiseD","jaw_ChinRaiseU",
	"jaw.translateX","HolderJawRight","jaw",    "jaw_openExtreme","mouth_suckBlow","HolderMouthSuck","mouth_cornerDepress","mouth_cornerPull","mouth_dimple",
	"mouth_corner","HolderMouthCornerDown","mouth_corner.translateX","HolderMouthCornerNarrow.translateX",
	"mouth_cornerSharpnessU","HolderMouthCornerSharpnessU","mouth_cornerSharpnessD","HolderMouthCornerSharpnessD",
	"mouth","HolderMouthDown","mouth.translateX","HolderMouthRight",
	"mouth_funnelU","mouth_funnelD","mouth_lipsBlow","mouth_lipsPressU","mouth_purseU","mouth_purseD","mouth_pushPullU","mouth_pushPullD",
	"mouth_thicknessU","HolderMouthLipsThickU","mouth_thicknessD","HolderMouthLipsThickD","mouth_lipsTogetherU","mouth_lipsTogetherD","mouth_lipsTowardsTeethU","mouth_lipsTowardsTeethD",
	"mouth_lipBiteU","mouth_lipBiteD","mouth_lowerLipDepress","mouth_lipsRollU","HolderMouthUpperLipRollOut","mouth_lipsRollD","HolderMouthLowerLipRollOut",
	"mouth_lipShiftU","HolderMouthUpperLipShiftRight","mouth_lipShiftD","HolderMouthLowerLipShiftRight","mouth_pressU","mouth_pressD",
	"mouth_sharpCornerPull","mouth_stickyU","mouth_stickyD","mouth_stickyInnerU","mouth_stickyInnerD","mouth_stickyOuterU","mouth_stickyOuterD",
	"mouth_stretch","mouth_stretchLipsClose","mouth_upperLipRaise","mouth_towardsU","mouth_towardsD",
	"neck_mastoidContract","neck_stretch","nose_nasolabialDeepen",
	"nose","HolderNoseNostrilDepress","nose.translateX","HolderNoseNostrilCompress",
	"tongue_move","HolderTongueDown","tongue_move.translateX","HolderTongueRight",//tongue
	"tongue_bendTwist","HolderTongueBendDown","tongue_bendTwist.translateX","HolderTongueTwistRight",//tongue_bendTwist
	"tongue_tipMove","HolderTongueTipDown","tongue_tipMove.translateX","HolderTongueTipRight",
	"tongue_inOut","HolderTongueOut","tongue_wideNarrow","HolderTongueNarrow","tongue_press"};

for ($x=1;$x>-2;$x=$x-2)
	{
	if ($x==1)  $side="R";
	if ($x==-1) $side="L";

	if ($nameSpace!="") namespace -setNamespace $nameSpace;
	createNode -n ("CTRL_"+$side+"_HolderEyeLookDown") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderEyeLookRight") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthSuck") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthCornerDown") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthCornerNarrow") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthCornerSharpnessU") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthCornerSharpnessD") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthLipsThickU") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthLipsThickD") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthUpperLipRollOut") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderMouthLowerLipRollOut") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderNoseNostrilDepress") -p asMetaHumanAnimatorSideWaysControls transform;
	createNode -n ("CTRL_"+$side+"_HolderNoseNostrilCompress") -p asMetaHumanAnimatorSideWaysControls transform;
	if ($x==1)
		{
		createNode -n ("CTRL_C_HolderMouthDown") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderJawForward") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderJawRight") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderMouthRight") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderMouthUpperLipShiftRight") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderMouthLowerLipShiftRight") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueDown") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueBendDown") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueTwistRight") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueRight") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueOut") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueNarrow") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueTipDown") -p asMetaHumanAnimatorSideWaysControls transform;
		createNode -n ("CTRL_C_HolderTongueTipRight") -p asMetaHumanAnimatorSideWaysControls transform;
		}
	if ($nameSpace!="") namespace -setNamespace ":";

	for ($i=0;$i<size($as);$i++)
		{
		$a="root_CTRL_expressions_"+$as[$i]+$side;
		$b=$nameSpace+"CTRL_"+$side+"_"+$bs[$i];

		//could be center
		if (!`objExists $a` && `objExists ("root_CTRL_expressions_"+$as[$i])`)
			{
			if ($x== 1) {$a="root_CTRL_expressions_"+$as[$i];$b=$nameSpace+"CTRL_C_"+$bs[$i];}
			if ($x==-1) continue;
			}

		if (!`objExists $a`)
			{
			warning ("AnimationCurve :\""+$a+"\" not found");
			continue;
			}

		//default attr is ty
		if (!`gmatch $b "*[.]*"`)
			$b=$b+".translateY";

		if (!`objExists $b`)
			{
			warning ("Control-Attribute :\""+$b+"\" not found");
			continue;
			}
		//animCurve without nameSpace
		tokenize $b ":" $tempString;
		if (size($tempString)<2)
			$nonNsName=$tempString[0];
		else
//			$nonNsName=$tempString[1];
			$nonNsName=$tempString[size($tempString)-1];//could be nested nameSpaces
		$animCurve=`substitute "[.]" $nonNsName "_"`;
		if (`objExists $animCurve`)
			delete $animCurve;
		duplicate -n $animCurve $a;
		if (!`getAttr -settable $b`)
			{
			warning ("Unable to connect animation-curve to: \""+$b+"\"");
			continue;
			}
		connectAttr ($animCurve+".output") $b;

		//special case, mixing single animCurves to Plus/Minus & MultiAxis attributes
		if (`gmatch $as[$i] "eyeLook*"` || $as[$i]=="jawBack" || $as[$i]=="jawFwd" || $as[$i]=="jawLeft" || $as[$i]=="jawRight"
			|| $as[$i]=="mouthUp" || $as[$i]=="mouthDown" || $as[$i]=="mouthCheekBlow" || $as[$i]=="mouthCheekSuck" || $as[$i]=="mouthLeft" || $as[$i]=="mouthRight"
			|| `gmatch $as[$i] "mouthCorner*"` || `gmatch $as[$i] "mouthLipsThick*"` || `gmatch $as[$i] "mouthLipsThin*"`
			|| `gmatch $as[$i] "mouth*LipRoll*"` || `gmatch $as[$i] "mouth*LipShiftRight*"` || `gmatch $as[$i] "noseNostril*"`
			|| `gmatch $as[$i] "tongue*"`)
			{
			$keyXValues=`keyframe -q -tc $animCurve`;
			$keyYValues=`keyframe -q -vc $animCurve`;

			for ($z=1;$z<size($keyXValues);$z++)
//				if ($keyYValues[$z]<=0 && $keyYValues[($z+1)]<=0 && $keyYValues[($z-1)]<=0)//and next/prev key is zero
				if ($keyYValues[$z]<0.001 && $keyYValues[$z]>-0.001)
					cutKey -t $keyXValues[$z] $animCurve;
			if (!`objExists $animCurve`)
				continue;//all keys were at zero
			keyTangent -itt linear -ott linear $animCurve;

			if (`gmatch $as[$i] "*Down*"` || `gmatch $as[$i] "*Right*"` || $as[$i]=="jawFwd" || $as[$i]=="jawRight"
				|| $as[$i]=="mouthCheekSuck" || `gmatch $as[$i] "mouthCornerDown*"` || `gmatch $as[$i] "mouthCornerNarrow*"` || $as[$i]=="mouthRight"
				|| `gmatch $as[$i] "mouthCornerRounder*"` || `gmatch $as[$i] "mouthLipsThin*"` || `gmatch $as[$i] "mouth*LipRollOut"`
				|| `gmatch $as[$i] "mouth*LipShiftRight"` || $as[$i]=="noseNostrilDepress" || $as[$i]=="noseNostrilCompress"
				|| $as[$i]=="tongueDown" || $as[$i]=="tongueBendDown" || $as[$i]=="tongueRight" || $as[$i]=="tongueOut" || $as[$i]=="tongueNarrow"
				|| $as[$i]=="tongueTipDown" || $as[$i]=="tongueTipRight")
				{
				scaleKey -iub false -index "0:99999" -ts 1 -tp 0 -fs 1 -fp 458 -vs -1 -vp 0 $animCurve;
				selectKey -k $animCurve;
				copyKey;
				if (`gmatch $as[$i] "eyeLookDown*"`)  $target="CTRL_"+$side+"_eye_translateY";
				if (`gmatch $as[$i] "eyeLookRight*"`) $target="CTRL_"+$side+"_eye_translateX";
				if ($as[$i]=="jawFwd") $target="CTRL_C_jaw_fwdBack_translateY";
				if ($as[$i]=="jawRight") $target="CTRL_C_jaw_translateX";
				if ($as[$i]=="mouthRight") $target="CTRL_C_mouth_translateX";
				if ($as[$i]=="mouthDown") $target="CTRL_C_mouth_translateY";
				if ($as[$i]=="mouthCheekSuck") $target="CTRL_"+$side+"_mouth_suckBlow_translateY";
				if ($as[$i]=="mouthCornerDown") $target="CTRL_"+$side+"_mouth_corner_translateY";
				if ($as[$i]=="mouthCornerNarrow") $target="CTRL_"+$side+"_mouth_corner_translateX";
				if ($as[$i]=="mouthCornerRounderU") $target="CTRL_"+$side+"_mouth_cornerSharpnessU_translateY";
				if ($as[$i]=="mouthCornerRounderD") $target="CTRL_"+$side+"_mouth_cornerSharpnessD_translateY";
				if ($as[$i]=="mouthLipsThinU") $target="CTRL_"+$side+"_mouth_thicknessU_translateY";
				if ($as[$i]=="mouthLipsThinD") $target="CTRL_"+$side+"_mouth_thicknessD_translateY";
				if ($as[$i]=="mouthUpperLipRollOut") $target="CTRL_"+$side+"_mouth_lipsRollU_translateY";
				if ($as[$i]=="mouthLowerLipRollOut") $target="CTRL_"+$side+"_mouth_lipsRollD_translateY";
				if ($as[$i]=="mouthUpperLipShiftRight") $target="CTRL_C_mouth_lipShiftU_translateY";
				if ($as[$i]=="mouthLowerLipShiftRight") $target="CTRL_C_mouth_lipShiftD_translateY";
				if ($as[$i]=="noseNostrilDepress") $target="CTRL_"+$side+"_nose_translateY";
				if ($as[$i]=="noseNostrilCompress") $target="CTRL_"+$side+"_nose_translateX";
				if ($as[$i]=="tongueDown") $target="CTRL_C_tongue_move_translateY";
				if ($as[$i]=="tongueBendDown") $target="CTRL_C_tongue_bendTwist_translateY";
				if ($as[$i]=="tongueRight") $target="CTRL_C_tongue_move_translateX";
				if ($as[$i]=="tongueOut") $target="CTRL_C_tongue_inOut_translateY";
				if ($as[$i]=="tongueNarrow") $target="CTRL_C_tongue_wideNarrow_translateY";
				if ($as[$i]=="tongueTipDown") $target="CTRL_C_tongue_tipMove_translateY";
				if ($as[$i]=="tongueTipRight") $target="CTRL_C_tongue_tipMove_translateX";
				if (`objExists $target`)
					pasteKey -option merge -copies 1 -connect 0 -timeOffset 0 -floatOffset 0 -valueOffset 0 {$target};
				else
					warning ("Target animationCurve:\""+$target+"\" not found.");
				}
			}

		$numConnected++;
		}
	}

delete asMetaHumanAnimatorSideWaysControls;
select -cl;

print ("// MetaHumanAnimator animation copied ("+$numConnected+" animationCurves).\n");
}

global proc asMetaHumanAnimatorDeleteAnimation ()
{
int $num;
string $nameSpace=`text -q -l asMetaHumanAnimatorNameSpaceText`;
string $tempString[],$tempString2[];

$tempString=`listRelatives -ad -type transform ($nameSpace+"GRP_faceGUI")`;
if (`objExists ($nameSpace+"FKHead_M")`)
	$tempString[size($tempString)]=$nameSpace+"FKHead_M";
for ($i=0;$i<size($tempString);$i++)
	{
	if (!`sets -im ($nameSpace+"FaceControlSet") $tempString[$i]` && $tempString[$i]!=$nameSpace+"FKHead_M")
		continue;
	$tempString2=`listConnections -s 1 -d 0 -scn 1 -type animCurveTU $tempString[$i]`;
	for ($y=0;$y<size($tempString2);$y++)
		{
		delete $tempString2[$y];
		$num++;
		}
	}
asGoToBuildPoseOptions $nameSpace "FaceControlSet";
asGoToBuildPoseOptions $nameSpace "ControlSet";
print ("// "+$num+" animationCurves deleted.\n");
}

global proc asMetaHumanAnimatorBake ()
{
int $num,$secondaryDriven,$plugNr;
float $keyYValues[];
string $nameSpace=`text -q -l asMetaHumanAnimatorNameSpaceText`;
string $sdkXform,$bwOrig,$bwNew;
string $tempString[],$tempString2[],$tempString3[],$bakers[];
string $faceControlSetMembers[]=`sets -q ($nameSpace+"FaceControlSet")`;

if (`objExists asMetaHumanAnimatorBaker`)
	delete asMetaHumanAnimatorBaker;
createNode -n asMetaHumanAnimatorBaker transform;
asLockAttr asMetaHumanAnimatorBaker 1 1 1 1;
$faceControlSetMembers=`sort $faceControlSetMembers`;
for ($i=0;$i<size($faceControlSetMembers);$i++)
	{
	//find by SDK connections
	$sdkXform="";
	if (`gmatch $faceControlSetMembers[$i] ($nameSpace+"CTRL_*_*")`)
		continue;
	$tempString=`listRelatives -p $faceControlSetMembers[$i]`;
	if (`gmatch  $tempString[0] ($nameSpace+"SDK*")`)
		$sdkXform=$tempString[0];
	else
		{
		$tempString2=`listRelatives -p $tempString[0]`;
		if (`gmatch $tempString2[0] ($nameSpace+"SDK*")`)
			$sdkXform=$tempString2[0];
		}

	if ($sdkXform!="")
		{
		$tempString=`listConnections -s 1 -d 0 -type blendWeighted $sdkXform`;
//		if (`objExists ("bw"+$faceControlSetMembers[$i]+"_lipsTogether")`)//special case, a driven ud attr on a OnFace ctrl
//			$tempString[size($tempString)]="bw"+$faceControlSetMembers[$i]+"_lipsTogether";
		}
	else
		$tempString=`listConnections -s 0 -d 1 -type blendWeighted $faceControlSetMembers[$i]`;

	if (`attributeExists lipsTogether $faceControlSetMembers[$i]`)
		{
		$tempString2=`listConnections -s 0 -d 1 -type blendWeighted $faceControlSetMembers[$i]`;
		$tempString=`stringArrayCatenate $tempString $tempString2`;
		}

	for ($y=0;$y<size($tempString);$y++)
		{
		$bwOrig=$tempString[$y];
		$bwNew=$bwOrig+"_NEW";
		createNode -n ("BAKER"+$bwOrig) -p asMetaHumanAnimatorBaker transform;
		if (!`objExists $bwNew`)
			{
			$plugNr=0;
			createNode -n $bwNew blendWeighted;
			connectAttr ($bwNew+".output") ("BAKER"+$bwOrig+".tx");
			}
		$tempString2=`listConnections -s 1 -d 0 -scn 1 -type animCurve $tempString[$y]`;//find any `secondary` driven
		for ($z=0;$z<size($tempString2);$z++)
			{
			$secondaryDriven=0;
			$tempString3=`listConnections -s 1 -d 0 -scn 1 -type blendWeighted $tempString2[$z]`;
			for ($aa=0;$aa<size($tempString3);$aa++)
				{
				if (!`gmatch $tempString3[$aa] ($nameSpace+"bwCTRL_*")` && !`gmatch $tempString3[$aa] "*Emotions*"`
				 && !`gmatch $tempString3[$aa] "*Phonemes*"` && !`gmatch $tempString3[$aa] "*bwSmilePull*"`)
					$secondaryDriven=1;
				if (!$secondaryDriven)
					{
					if (`gmatch $bwOrig "*_scale*"`)//might need to re-ensure 1st in BW is 1-based for scale
						{
						$keyYValues=`keyframe -in 0 -q -vc $tempString2[$z]`;
						if ($keyYValues[0]==0)
							{
							setAttr ($bwNew+".input["+$plugNr+"]") 1;
							$plugNr++;
							}
						}
					connectAttr ($tempString2[$z]+".output") ($bwNew+".input["+$plugNr+"]");
					$plugNr++;
					}
				}
			}
		}
	}

$bakers=`listRelatives -c asMetaHumanAnimatorBaker`;
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys false -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
	-bakeOnOverrideLayer false -controlPoints false -shape false $bakers;
asMetaHumanAnimatorDeleteAnimation;
setAttr ($nameSpace+"MetaHumanControlPanelToggle.MetaHumanControlPanelVis") 0;
setAttr ($nameSpace+"ctrlBox.limits") 0;
delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 0 $bakers;
for ($i=0;$i<size($bakers);$i++)
	{
	$tempString=`listConnections -s 1 -d 0 -scn 1 -type animCurve $bakers[$i]`;
	if (!size($tempString))
		continue;
	copyKey ($bakers[$i]+".tx");
	$tempString[0]=`substitute ("BAKER"+$nameSpace+"bw") $bakers[$i] ""`; //"BAKERbwctrlBrow_R_translateY
	$tempString[0]=`substitute "SDK" $tempString[0] ""`;
	tokenize $tempString[0] "_" $tempString2;
	$dest=$nameSpace+$tempString2[0]+"_"+$tempString2[1]+"."+$tempString2[2];
	if (!`getAttr -settable $dest`)
		continue;
	pasteKey $dest;
	$num++;
	}
delete asMetaHumanAnimatorBaker;
print ("// "+$num+" animationCurves baked.\n");
}

global proc asAutoLipSyncDownload (string $uiName)
{
string $zipFileUrl="https://github.com/MontrealCorpusTools/Montreal-Forced-Aligner/releases/download/v1.1.0-beta.2/montreal-forced-aligner_win64.zip";
if (`about -mac`)
	$zipFileUrl="https://github.com/MontrealCorpusTools/Montreal-Forced-Aligner/releases/download/v1.1.0-beta.2/montreal-forced-aligner_macosx.zip";
string $libriSpeechLexiconUrl="https://www.openslr.org/resources/11/librispeech-lexicon.txt";
string $sLoc=`asGetScriptLocation`;
string $curl=$sLoc+"/AdvancedSkeletonFiles/bin/curl.e";
string $zip=$sLoc+"/AdvancedSkeletonFiles/bin/7za.e";
string $binDir=$sLoc+"/AdvancedSkeletonFiles/bin";
string $downloadDir=$sLoc+"/AdvancedSkeletonFiles/bin/download";
string $tempString[];
tokenize $zipFileUrl "/" $tempString;
string $downloadedZipFile=$tempString[size($tempString)-1];
string $downloadedZipFilePath=$downloadDir+"/"+$downloadedZipFile;
string $cmd;

if (!`file -q -ex $downloadDir`) sysFile -md $downloadDir;

//download Montreal-Forced-Aligner
if (`about -mac` || `about -linux`)
	{
	$cmd="\"curl -k -L -o "+$downloadDir+"/"+$downloadedZipFile+" "+$zipFileUrl+"\"";
	evalEcho ("system("+$cmd+")");
	}
else
	{
	$cmd="start\/wait/I \"Downloading\"  \""+$curl+"\" -k -L -o \""+$downloadDir+"/"+$downloadedZipFile+"\" "+$zipFileUrl;
	print ("// Starting Download:"+$cmd+"\n");
	system ($cmd);
	}

//download librispeech-lexicon
if (`about -mac` || `about -linux`)
	{
	$cmd="\"curl -k -L -o "+$downloadDir+"/librispeech-lexicon.txt "+$libriSpeechLexiconUrl+"\"";
	evalEcho ("system("+$cmd+")");
	}
else
	{
	$cmd="start\/wait/I \"Downloading\"  \""+$curl+"\" -k -L -o \""+$downloadDir+"/librispeech-lexicon.txt\" "+$libriSpeechLexiconUrl;
	print ("// Starting Download:"+$cmd+";\n");
	system ($cmd);
	}

//confirm downloads
if (`file -q -ex $downloadedZipFilePath`)
	print ("// Downloaded sucessfully:"+$downloadedZipFilePath+";\n");
else
	error ("// Download failed, could not find:"+$downloadedZipFilePath+";\n");
if (`file -q -ex ($downloadDir+"/librispeech-lexicon.txt")`)
	print ("// Downloaded sucessfully:"+$downloadDir+"/librispeech-lexicon.txt;\n");
else
	error ("// Download failed, could not find:"+$downloadDir+"/librispeech-lexicon.txt;\n");

//unzip
if (`about -mac` || `about -linux`)
  $cmd="unzip "+$downloadedZipFilePath+" -d "+$binDir;
else
	$cmd="start\/wait/I \"Unzipping\"  \""+$zip+"\" x \""+$downloadedZipFilePath+"\" -o\""+$binDir+"\"";
print ("// Starting Unzip:"+$cmd+";\n");
system($cmd);

//confirm unzip
if (`file -q -ex ($binDir+"/montreal-forced-aligner")`)
	print ("// Unzipped sucessfully:"+$downloadedZipFile+";\n");
else
	error ("// Unzipp failed, could not find:"+$binDir+"/montreal-forced-aligner\n");

//Delete download
if (`filetest -f $downloadedZipFilePath`)
	sysFile -del $downloadedZipFilePath;
//Delete montreal-forced-aligner_win64.zip (1kb file that comes with the zip)
if (`filetest -f ($binDir+"/montreal-forced-aligner_win64.zip")`)
	sysFile -del ($binDir+"/montreal-forced-aligner_win64.zip");

//Move librispeech-lexicon.txt
sysFile -ren ($binDir+"/montreal-forced-aligner/bin/librispeech-lexicon.txt") ($downloadDir+"/librispeech-lexicon.txt");

asAutoLipSyncUI $uiName;
}

global proc asAutoLipSyncFfmpegDownload ()
{
//ffmpeg for $segmentReplacing
string $zipFileUrl="https://www.animationstudios.com.au/download/div/ffmpeg.7z";
string $ffmpegFile="ffmpeg.e";
if (`about -mac`)
	{
	$zipFileUrl="https://www.animationstudios.com.au/download/div/ffmpeg_mac.zip";
	$ffmpegFile="ffmpeg";
	}
string $sLoc=`asGetScriptLocation`;
string $curl=$sLoc+"/AdvancedSkeletonFiles/bin/curl.e";
string $zip=$sLoc+"/AdvancedSkeletonFiles/bin/7za.e";
string $forceAlignerBinDir=$sLoc+"/AdvancedSkeletonFiles/bin/montreal-forced-aligner/bin";
string $downloadDir=$sLoc+"/AdvancedSkeletonFiles/bin/download";
string $tempString[];
tokenize $zipFileUrl "/" $tempString;
string $downloadedZipFile=$tempString[size($tempString)-1];
string $downloadedZipFilePath=$downloadDir+"/"+$downloadedZipFile;
string $cmd;

if (!`file -q -ex $downloadDir`) sysFile -md $downloadDir;

//download
if (`about -mac` || `about -linux`)
	{
	$cmd="\"curl -k -o "+$downloadedZipFilePath+" "+$zipFileUrl+"\"";
	evalEcho ("system("+$cmd+")");
	}
else
	{
	$cmd="start\/wait/I \"Downloading\"  \""+$curl+"\" -k -o \""+$downloadedZipFilePath+"\" "+$zipFileUrl;
	print ("// Starting Download:"+$cmd+";\n");
	system ($cmd);
	}

//confirm downloads
if (`file -q -ex $downloadedZipFilePath`)
	print ("// Downloaded sucessfully:"+$downloadedZipFilePath+";\n");
else
	error ("// Download failed, could not find:"+$downloadedZipFilePath+"\n");

//ensure destination folder (might not exists if using asVideoMoCap, but not montreal-forced-aligner
if (!`file -q -ex $forceAlignerBinDir`)
	sysFile -md $forceAlignerBinDir;

//unzip
if (`about -mac` || `about -linux`)
  $cmd="unzip "+$downloadedZipFilePath+" -d "+$forceAlignerBinDir;
else
	$cmd="start\/wait/I \"Unzipping\"  \""+$zip+"\" x \""+$downloadedZipFilePath+"\" -o\""+$forceAlignerBinDir+"\"";
print ("// Starting Unzip:"+$cmd+";\n");
system($cmd);

//confirm unzip
if (`file -q -ex ($forceAlignerBinDir+"/"+$ffmpegFile)`)
	print ("// Unzipped sucessfully:"+$downloadedZipFile+";\n");
else
	error ("// Unzipp failed, could not find:"+$forceAlignerBinDir+"/"+$ffmpegFile+"\n");

//Delete download
if (`filetest -f $downloadedZipFilePath`)
	sysFile -del $downloadedZipFilePath;
}

global proc asDeformableUI (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;

if (`window -q -ex asDeformableUI`)
	deleteUI asDeformableUI;
window -t "Deformable Controllers" asDeformableUI;
columnLayout;
text -m 0 -l $nameSpace asDeformableNameSpaceText;
separator -h 5 -w 300 -st none;
text -l "Makes controllers able to have \"Deformers\" applied.";
separator -h 15 -st none;
text -l "Select all the controllers that will be `deformed`.";
separator -h 30 -st none;
rowLayout -nc 2;
	separator -w 20 -st none;
	columnLayout;
		optionMenu -l "planePerpendicularAxis" asDeformablePlanePerpendicularAxisOptionMenu;
			menuItem -l "X";
			menuItem -l "Y";
			menuItem -l "Z";
		checkBox -l "connect to \"Extra\" controllers" asDeformableUseExtraCheckBox;
		optionMenu -l "connection:" asDeformableConnectionOptionMenu;
			menuItem -l "Constraint";
			menuItem -l "DirectConnect";
		separator -h 10 -st none;
		button -l "Make selected controllers Deformable" -c asDeformable;
showWindow;
}

global proc asTimeEchoUI (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;

if (`window -q -ex asTimeEchoUI`)
	deleteUI asTimeEchoUI;
window -t "TimeEcho Controllers" asTimeEchoUI;
columnLayout;
text -m 0 -l $nameSpace asDeformableNameSpaceText;
separator -h 5 -w 300 -st none;
text -l "Make controller Echo another controller";
separator -h 15 -st none;
text -l "First select \"Source\" controller, then select \"Echo\" controller";
separator -h 30 -st none;
rowLayout -nc 2;
	separator -w 20 -st none;
	columnLayout;
		intFieldGrp -l "Time Delay  frames" -v1   5 -cw2 110 60 asTimeEchoTDIntFieldGrp;
		intFieldGrp -l "Time Decay\t\t\t\t\t\t\t\t% " -v1 100 -cw2 110 60 asTimeEchoVIntFieldGrp;
		separator -h 10 -st none;
		button -l "Apply TimeEcho to selected controllers" -c asTimeEcho;
		setParent..;
	setParent..;
separator -h 30 -st none;
rowLayout -nc 2;
	separator -w 20 -st none;
	button -l "Remove TimeEcho from selected controllers" -c "delete `listConnections -s 1 -d 0 -scn 1 -type expression`";
showWindow;
}

global proc asTimeEcho ()
{
int $td=`intFieldGrp -q -v1 asTimeEchoTDIntFieldGrp`;
int $tc=`intFieldGrp -q -v1 asTimeEchoVIntFieldGrp`;
string $sel[]=`ls -sl -type transform`;
string $trs[]={"t","r","s"};
string $xyz[]={"x","y","z"};
string $source,$exp,$expName;
string $nameSpace=`text -q -l asDeformableNameSpaceText`;

if (size($sel)<2)
	error "Minimum two controllers must be selected (Source + Destination)";
$source=$sel[0];

for ($i=1;$i<size($sel);$i++)
	{
	if (!`attributeExists timeDelay $sel[$i]`) addAttr -k 1 -ln timeDelay -at double $sel[$i];
	if (!`attributeExists timeDecay $sel[$i]`) addAttr -k 1 -ln timeDecay -at double $sel[$i];
	setAttr ($sel[$i]+".timeDelay") $td; 
	setAttr ($sel[$i]+".timeDecay") $tc; 

	for ($y=0;$y<size($trs)-1;$y++)
		for ($z=0;$z<size($xyz);$z++)
			{
			$exp="$t=`currentTime -q`;\n";
			$exp+="$td="+$sel[$i]+".timeDelay;\n";
			$exp+="$tc="+$sel[$i]+".timeDecay;\n";
			$exp+=$sel[$i]+"."+$trs[$y]+$xyz[$z]+"=`getAttr -t ($t-$td) "+$sel[0]+"."+$trs[$y]+$xyz[$z]+"`*($tc/100.0);\n";
			$expName=$sel[$i]+"_"+$trs[$y]+$xyz[$z]+"Expression";
			if (`objExists $expName`)
				delete $expName;
			expression -n $expName -s $exp -o $sel[$i] -ae 1 -uc all ;
			}
	}

}

global proc asDeformable ()
{
int $hasSettable,$checkingHierarcyByJoints;
int $useExtra=`checkBox -q -v asDeformableUseExtraCheckBox`;
float $dist,$maxDist;
float $scale=`asGetScale`;
float $posA[],$posB[];
string $deformableControlsObject,$suffix,$polyPlane,$nearest,$checkObj,$constraint1,$constraint2,$loc,$offset,$previousLoc;
string $nameSpace=`text -q -l asDeformableNameSpaceText`;
string $ppAxis=`optionMenu -q -v asDeformablePlanePerpendicularAxisOptionMenu`;
string $connection=`optionMenu -q -v asDeformableConnectionOptionMenu`;
string $sel[]=`ls -sl -type transform`;
string $tempString[],$tempString2[],$newPolyPlanes[],$ctrls[];
string $trs[]={"t","r","s"};
string $xyz[]={"x","y","z"};
string $XYZ[]={"X","Y","Z"};

if (!size($sel))
	error "No valid Controllers selected";
for ($i=0;$i<size($sel);$i++)
	if (`gmatch $sel[$i] "*DeformableControls*"`)
		error "Selected object already is a DeformableControls-object, select controller(s) instead.";

for ($i=0;$i<99;$i++)
	{
	if ($i==0) $suffix="";
	else $suffix=$i;
	$deformableControlsObject="DeformableControls"+$suffix;
	if (!`objExists $deformableControlsObject`)
		break;
	}

for ($i=0;$i<size($sel);$i++)
	{
	$hasSettable=1;
	for ($y=0;$y<size($trs)-1;$y++)
		for ($z=0;$z<size($xyz);$z++)
			{
			if (!`getAttr -settable ($sel[$i]+"."+$trs[$y]+$xyz[$z])`)
				{
				$hasSettable=0;
				$y=$z=99;
				}
			$tempString=`listConnections -s 1 -d 0 ($sel[$i]+"."+$trs[$y]+$xyz[$z])`;
			if ($tempString[0]!="")
				$hasSettable=0;
			}
	if (!$hasSettable)
		{
		print ($sel[$i]+" have translate or rotate channels that are not \"settable\" , skipping this controller.\n");
		continue;
		}
	if (`gmatch $sel[$i] "*Extra*"`)
		{
		$tempString=`listRelatives -c -type transform $sel[$i]`;
		if (`stringArrayCount $tempString[0] $sel`)
			{
			print ($sel[$i]+" is a \"Extra\" controller, but \""+$tempString[0]+"\" is also selected, skipping this controller.\n");
			continue;
			}
		}
	if ($useExtra && !`gmatch $sel[$i] "*Extra*"`)
		{
		$tempString=`listRelatives -p -type transform $sel[$i]`;
		if (`gmatch $tempString[0] "*Extra*"` && !`stringArrayCount $tempString[0] $sel`)
			{
			$ctrls[size($ctrls)]=$tempString[0];
			continue;
			}
		}
	$ctrls[size($ctrls)]=$sel[$i];
	}

for ($i=0;$i<size($ctrls);$i++)
	{
	$tempString=`polyPlane -n ($ctrls[$i]+"PolyPlane") -w ($scale/3.0) -h ($scale/3.0) -sx 1 -sy 1 -ax 0 0 1 -cuv 2 -ch 0`;
	$polyPlane=$tempString[0];
	$newPolyPlanes[size($newPolyPlanes)]=$polyPlane;
	polyEditUV -u $i -v 0 ($ctrls[$i]+"PolyPlane.map[0:99]");
	if ($ppAxis=="X")
		rotate -r -os 0 90 0 ($polyPlane+".vtx[0:99]");
	else if ($ppAxis=="Y")
		rotate -r -os 90 0 0 ($polyPlane+".vtx[0:99]");

	asAlign $polyPlane $ctrls[$i] 1 1 0 0;
	//transform-connect
	
	//connectorMesh
	if (size($ctrls)>1)
		{
		$posA=`xform -q -ws -t $ctrls[$i]`;
		//First try to find `nearest` via hierarcy
		$nearest="";
		$checkObj=$ctrls[$i];
		$checkingHierarcyByJoints=0;
		if (`gmatch $ctrls[$i] "*FK*"`)
			{
			$tempString[0]=`substitute "FK" $ctrls[$i] ""`;
			if (`objExists $tempString[0]`)
				{
				$checkObj=$tempString[0];
				$checkingHierarcyByJoints=1;
				}
			}
		if ($checkingHierarcyByJoints)
			{
			$tempString=`ls -l $checkObj`;
			tokenize $tempString[0] "|" $tempString;
			for ($y=size($tempString)-2;$y>-1;$y--)
				{
				if ($nameSpace=="")
					$tempString2[0]="FK"+$tempString[$y];
				else
					$tempString2[0]=`substitute $nameSpace $tempString[$y] ($nameSpace+"FK")`;
				if (`stringArrayCount $tempString2[0] $ctrls`)
					{
					$nearest=$tempString2[0];
					break;
					}
				}
			}

		if ($nearest=="")
			{//secondly by distance
			$maxDist=999;
			for ($y=0;$y<size($ctrls);$y++)
				{
				if ($i==$y)
					continue;
				$posB=`xform -q -ws -t $ctrls[$y]`;
				$dist=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;
				if ($dist<$maxDist)
					{
					$nearest=$ctrls[$y];
					$maxDist=$dist;
					}
				}
			}

		if ($nearest!="")
			{
			$posB=`xform -q -ws -t $nearest`;
			polyCreateFacet -n ("connectorMesh"+$i) -ch 0 -tx 1 -s 1 -p $posA[0] $posA[1] $posA[2] -p $posA[0] $posA[1] $posA[2] -p $posB[0] $posB[1] $posB[2];
			$newPolyPlanes[size($newPolyPlanes)]="connectorMesh"+$i;
			}
		}
	}
if (size($ctrls)==1)
	rename $newPolyPlanes[0] $deformableControlsObject;
else
	{
	polyUnite -n $deformableControlsObject -ch 0 -mergeUVSets 1 $newPolyPlanes;
	}

for ($y=0;$y<size($trs);$y++)
	for ($z=0;$z<size($xyz);$z++)
		setAttr -l 1 ($deformableControlsObject+"."+$trs[$y]+$xyz[$z]);

//constraint
for ($i=0;$i<size($ctrls);$i++)
	{
	$tempString=`spaceLocator -n ($deformableControlsObject+"_Loc"+$i)`;
	$loc=$tempString[0];
	parent $loc $deformableControlsObject;
	setAttr ($loc+".localScale") -type float3 ($scale/20.0) ($scale/20.0) ($scale/20.0);
//	setAttr ($loc+".rotateOrder") `getAttr ($ctrls[$i]+".rotateOrder")`;
	asAlign $loc $ctrls[$i] 1 1 0 1;
	$tempString=`listRelatives -p $ctrls[$i]`;
	select $deformableControlsObject $loc;
	$tempString=`pointOnPolyConstraint -mo -weight 1`;
	$constraint1=$tempString[0];
	setAttr ($constraint1+"."+$deformableControlsObject+"U0") (0.5+$i);
	setAttr ($constraint1+"."+$deformableControlsObject+"V0") 0.5;
	setAttr ($constraint1+".offsetTranslate") -type float3 0 0 0;
	if ($connection=="Constraint")
		parentConstraint  $loc $ctrls[$i];

	$offset=`createNode -n ($deformableControlsObject+"_Offset"+$i) -p $ctrls[$i] transform`;
	setAttr ($offset+".rotateOrder") `getAttr ($ctrls[$i]+".rotateOrder")`;
	parent $offset $deformableControlsObject;
	parent $loc $offset;
	if ($i>0)
		parent $offset $previousLoc;

	if ($connection=="DirectConnect")
		{
		connectAttr ($loc+".t") ($ctrls[$i]+".t");
		connectAttr ($loc+".r") ($ctrls[$i]+".r");
		}
	$previousLoc=$loc;
	}
select $deformableControlsObject;
print ("// Deformable Controller Object created, you can now apply Deformers to this object.\n");
}

global proc asBrowseToTextField (string $textField)
{
int $fileMode=1;
if ($textField=="asAudio2FaceFolderTextField")
	$fileMode=3;
string $result[]=`fileDialog2 -fm $fileMode -cap folder -okc Choose`;
if (!`file -q -ex $result[0]` || $result[0]=="")
	return;
textField -e -tx $result[0] -bgc 0 0 0 $textField;
optionVar -sv $textField $result[0];
}

global proc asVideoMoCapUI (string $uiName)
{
int $haveVideoMoCap;
float $latestVersion=1.111;
float $currentVersion;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $file,$msg,$asVideoMoCapDir,$asVideoMoCap;
string $tempString[];

asEnsureAsGetScriptLocation;
$asVideoMoCapDir=`asGetScriptLocation`+"/AdvancedSkeletonFiles/bin/asVideoMoCap";
$asVideoMoCap=$asVideoMoCapDir+"/asVideoMoCap.exe";

if (!`about -win`)
	error "VideoMoCap is currently only available for Windows.";

$haveVideoMoCap=`file -q -ex $asVideoMoCap`;

if (`optionVar -ex asVideoMoCapTextField`)
	$file=`optionVar -q asVideoMoCapTextField`;

//check for version update
if ($haveVideoMoCap)
	{
	$tempString[0]=`substituteAllString $asVideoMoCap "/" "\\\\"`;
	$tempString[0]=`system ("wmic datafile where name='"+$tempString[0]+"' get version")`;
	tokenize $tempString[0] "\n" $tempString;
	for ($i=0;$i<size($tempString);$i++)
		if (`gmatch $tempString[$i] "*[.]*[.]*[.]*"`)
			{
			$currentVersion=`substituteAllString $tempString[$i] "." ""`;
			$currentVersion=$currentVersion/1000;
			}
	if ($currentVersion>0 && $latestVersion>$currentVersion)
		{
		$msg=("A Newer version of VideoMoCap is avaiable.\n\n"
			+"Current version="+$currentVersion+", Latest version="+$latestVersion+"\n\n"
			+"Remove Current version to allow for download of Latest version ?");
		if (`confirmDialog -title "Confirm" -message $msg
		  -button "Yes" -button "No" -defaultButton "Yes"
	  	-cancelButton "No" -dismissString "No"`=="Yes")
	  		{
				print ("// Removing files from \""+$asVideoMoCapDir+"\" to allow for download of Latest version.\n");
				$tempString=`getFileList -fld ($asVideoMoCapDir+"/")`;
				for ($i=0;$i<size($tempString);$i++)
					sysFile -del ($asVideoMoCapDir+"/"+$tempString[$i]);
				$haveVideoMoCap=0;
	  		}
		}
	}

if (`window -q -ex asVideoMoCapUI`)
	deleteUI asVideoMoCapUI;
window -t VideoMoCap asVideoMoCapUI;
columnLayout;
	text -m 0 -l $nameSpace asVideoMoCapNameSpaceText;
	text -l "\t\t\t\t\tVideoMotionCapture tracking by Google AI MediaPipe";
	separator -st none -h 5;

	if (!$haveVideoMoCap)
		{
		separator -h 5 -st none;
		text -l "To run VideoMoCap,";
		text -l "first download \"VideoMoCap\"";
		separator -h 5 -st none;
		button -l "Download VideoMoCap" -c ("asVideoMoCapDownload "+$uiName);
		showWindow;
		print ("// VideoMoCap tool must be downloaded first\n");
		print ("// If the automatic download does not work, you can manually download from:\n");
		print ("// https://www.animationstudios.com.au/download/div/asVideoMoCap.7z\n");
		print ("// download and extract the files, so you get this available file-path:\n");
		print ("// "+$asVideoMoCap+"\n");
		print ("\n");
		return;
		}

	rowLayout -nc 3;
		text -w 100 -l "Video file:";
		textField -w 300 -tx $file asVideoMoCapTextField;
		iconTextButton -i "menuIconFile.png" -c "asBrowseToTextField asVideoMoCapTextField";
		setParent..;
	rowLayout -nc 2;
		separator -w 10 -st none;
		columnLayout;
			optionMenu -l "track:" -cc asVideoMoCapTrackOptionChanged asVideoMoCapTrackOptionMenu;
				menuItem "hand";
				menuItem "body";
				menuItem "face";
			separator -h 5 -st none;
			checkBox -l "motion-smooth-filter" -v 1 asVideoMoCapMotionSmoothFilterCheckBox;
			checkBox -m `getModifiers` -l "video running mode" -v 0 asVideoMoCapVideoRunningModeCheckBox;
			checkBox -l "image-plane-reference" -v 1 asVideoMoCapImagePlaneReferenceCheckBox;
			checkBox -m `getModifiers` -l "world-landmarks" -v 1 asVideoMoCapWorldLandmarksCheckBox;
			checkBox -l "include audio" -v 1 asVideoMoCapIncludeAudioCheckBox;
			checkBox -m `getModifiers` -l "IMPORT ONLY" -v 0 asVideoMoCapIMPORTONLYCheckBox;
			separator -st none -h 10;
			rowLayout -nc 5;
				button -l "Apply" -c asVideoMoCapApply;
				separator -w 10 -st none;
				button -l "Remove" -c asVideoMoCapRemove;
				separator -w 10 -st none;
				button -l "Bake" -c asVideoMoCapBake asVideoMoCapBakeButton;
showWindow;
}

global proc asVideoMoCapDownload (string $uiName)
{
string $zipFileUrl="https://www.animationstudios.com.au/download/div/asVideoMoCap.7z";
string $sLoc=`asGetScriptLocation`;
string $curl=$sLoc+"/AdvancedSkeletonFiles/bin/curl.e";
string $zip=$sLoc+"/AdvancedSkeletonFiles/bin/7za.e";
string $binDir=$sLoc+"/AdvancedSkeletonFiles/bin";
string $asVideoMoCapDir=$sLoc+"/AdvancedSkeletonFiles/bin/asVideoMoCap";
string $downloadDir=$sLoc+"/AdvancedSkeletonFiles/bin/download";
string $tempString[];
tokenize $zipFileUrl "/" $tempString;
string $downloadedZipFile=$tempString[size($tempString)-1];
string $downloadedZipFilePath=$downloadDir+"/"+$downloadedZipFile;
string $cmd;

if (!`file -q -ex $downloadDir`) sysFile -md $downloadDir;

//download asVideoMoCap
if (`about -mac` || `about -linux`)
	error "Currently only avaiable for Windows";
else
	{
	$cmd="start\/wait/I \"Downloading\"  \""+$curl+"\" -k -L -o \""+$downloadDir+"/"+$downloadedZipFile+"\" "+$zipFileUrl;
	print ("// Starting Download:"+$cmd+"\n");
	system ($cmd);
	}

//confirm downloads
if (`file -q -ex $downloadedZipFilePath`)
	print ("// Downloaded sucessfully:"+$downloadedZipFilePath+";\n");
else
	error ("// Download failed, could not find:"+$downloadedZipFilePath+";\n");

//ensure folder exiss
if (!`file -q -ex $asVideoMoCapDir`)
	sysFile -md $asVideoMoCapDir;

//unzip
$cmd="start\/wait/I \"Unzipping\"  \""+$zip+"\" x \""+$downloadedZipFilePath+"\" -o\""+$asVideoMoCapDir+"\"";
print ("// Starting Unzip:"+$cmd+";\n");
system($cmd);

//confirm unzip
if (`file -q -ex ($binDir+"/montreal-forced-aligner")`)
	print ("// Unzipped sucessfully:"+$downloadedZipFile+";\n");
else
	error ("// Unzipp failed, could not find:"+$binDir+"/montreal-forced-aligner\n");

//Delete download
if (`filetest -f $downloadedZipFilePath`)
	sysFile -del $downloadedZipFilePath;

asVideoMoCapUI $uiName;
}

global proc asVideoMoCapTrackOptionChanged ()
{
int $trackFace;
string $track=`optionMenu -q -v asVideoMoCapTrackOptionMenu`;

if ($track=="face")
	$trackFace=1;
button -e -en (!$trackFace) asVideoMoCapBakeButton;
}

global proc asVideoMoCapApply ()
{
global string $gMainProgressBar;
global string $gPlayBackSlider;
int $fileId,$frameNr,$startedHL,$z,$landMarkNr,$numLines,$sideSwitched,$nr,$numLetters,$lev,$worldLandMarks;
int $motionSmooth=`checkBox -q -v asVideoMoCapMotionSmoothFilterCheckBox`;
int $videoRunningMode=`checkBox -q -v asVideoMoCapVideoRunningModeCheckBox`;
int $imagePlaneReference=`checkBox -q -v asVideoMoCapImagePlaneReferenceCheckBox`;
int $includeAudio=`checkBox -q -v asVideoMoCapIncludeAudioCheckBox`;
int $importOnly=`checkBox -q -v asVideoMoCapIMPORTONLYCheckBox`;
float $value,$startTime,$width,$height,$xOffset,$scaleMeSize,$asLegLenght,$trackerLegLenght,$videoFps;
float $charHeight=17.5;
float $fps=`currentTimeUnitToFPS`;$fps=`asRoundOff $fps 3`;
float $imageSize[],$pos[],$posA[],$posB[];
string $nameSpace=`text -q -l asVideoMoCapNameSpaceText`;
string $file=`textField -q -tx asVideoMoCapTextField`;
string $track=`optionMenu -q -v asVideoMoCapTrackOptionMenu`;
string $asVideoMoCapDir=`asGetScriptLocation`+"/AdvancedSkeletonFiles/bin/asVideoMoCap";
string $asVideoMoCap=$asVideoMoCapDir+"/asVideoMoCap.exe";
string $trackDataFile=$asVideoMoCapDir+"/TrackData.txt";
string $resultJpgFile=$asVideoMoCapDir+"/result.jpg";
string $resultAviFile=$asVideoMoCapDir+"/result.avi";
string $resultAifFile=$asVideoMoCapDir+"/result.aif";
string $driveLetter=`substring $asVideoMoCapDir 1 1`;
string $cmd,$fDet,$side,$rightLeft,$str,$attr,$valueString,$target,$tracker,$gFlag,$imgSeqDirName,$landMarkName;
string $task,$bs,$ffmpeg,$msg,$convertedFile,$aTempo;
string $lev1Attr,$lev2Attr,$lev3Attr,$lev4Attr,$lev1Value,$lev2Value,$lev3Value,$lev4Value;
string $resultFiles[]={$trackDataFile,$resultJpgFile,$resultAviFile};
string $fingers[]={"Thumb","Index","Middle","Ring","Pinky"};
string $tempString[],$tempString2[],$tempString3[],$animCurves[];

if (`attributeExists height ($nameSpace+"Main")`)
	$charHeight=`getAttr ($nameSpace+"Main.height")`;

if (!`objExists ($nameSpace+"FKWrist_R")`)
	error ($nameSpace+"FKWrist_R Not found, make sure to use the correct CharacterName/NameSpace");

//asVideoMoCapRemove;
refresh;

if ($imagePlaneReference) $gFlag=" -g";
if ($videoRunningMode) $videoRunningModeFlag=" -vm";

if ($track=="hand") {$task="hand_landmarker";$landMarkName=$track;$worldLandMarks=1;}
if ($track=="body") {$task="pose_landmarker_lite";$landMarkName="pose";$worldLandMarks=0;}
if ($track=="face") {$task="face_landmarker";$landMarkName=$track;$worldLandMarks=0;}

if (`checkBox -q -m asVideoMoCapWorldLandmarksCheckBox`)
	$worldLandMarks=`checkBox -q -v asVideoMoCapWorldLandmarksCheckBox`;

if ($imagePlaneReference)
	{
	$tempString=`getFileList -fs "imgSeq_*" -fld $asVideoMoCapDir`;
	for ($i=0;$i<size($tempString);$i++)
		{
		$tempString2=`getFileList -fld ($asVideoMoCapDir+"/"+$tempString[$i]+"/")`;
		for ($y=0;$y<size($tempString2);$y++)
			sysFile -del ($asVideoMoCapDir+"/"+$tempString[$i]+"/"+$tempString2[$y]);
		sysFile -removeEmptyDir ($asVideoMoCapDir+"/"+$tempString[$i]);
		}
	}

//audio
if ($includeAudio)
	{
	$ffmpeg=`asGetScriptLocation`+"/AdvancedSkeletonFiles/bin/montreal-forced-aligner/bin/ffmpeg.e";
	if (`attributeExists mute result`)
		delete result;
	if (`about -mac`) $ffmpeg=`substitute "[.]e" $ffmpeg ""`;
	if (!`file -q -ex $ffmpeg`)
		{
		$msg=("For \"include Audio\" ffmpeg is required\nCurrently not found at AutoLipSync location :\n"+$ffmpeg+"\nDownload this now?\n");
		if (`confirmDialog -title "Confirm" -message $msg
  	  -button "Yes" -button "No" -defaultButton "Yes"`!="Yes")
    		{
				print "Aborted.\n";
				return;
    		}
		asAutoLipSyncFfmpegDownload;
		if (!`file -q -ex $ffmpeg`)
			error ("File:\""+$ffmpeg+"\" still not found, download failed.");
		}

	//get fps with $ffMpegCmd
	$result=`system ($ffmpeg+" -i \""+$file+"\"")`;
	tokenize $result "\n" $tempString;
	for ($i=0;$i<size($tempString);$i++)
		if (`gmatch $tempString[$i] "*Stream*Video*"`)
			{
			tokenize $tempString[$i] "," $tempString2;
			for ($y=0;$y<size($tempString2);$y++)
				if (`gmatch $tempString2[$y] "*fps*"`)
					{
					tokenize $tempString2[$y] " " $tempString3;
					$videoFps=$tempString3[0];
					$videoFps=`asRoundOff $videoFps 3`;
					}
			}
	if ($videoFps!=$fps)
		{
		warning ("Current FPS ("+$fps+")does not match video FPS("+$videoFps+"), ReSamling audio to match duration");
		$aTempo=" -af atempo="+($fps/$videoFps);
		if (($fps/$videoFps)<0.5)
			{
			 $msg=("Audio issue:\nDifference between video FPS and Maya-scene FPS is too large.\n"
			 +"video FPS = "+$videoFps+"  Current Maya FPS = "+$fps+"\n"
			 +"(More than double)\n"
			 +"Audio will be out of sync.\n\nContinue Anyway ?");
			if (`confirmDialog -title "Confirm" -message $msg
			  -button "Continue Anyway" -button "Cancel" -defaultButton "Continue Anyway"`!="Continue Anyway")
		  		{
					print "Aborted.\n";
					return;
		  		}

			$aTempo="";
			}
/* //Skipping, as Maya can not be easily set to any FrameRate e.g. 31fps

		$msg=("For \"include Audio\" requires matching \"Frames Per Second\"\nCurrent FPS ("+$fps+"),"
			+" does not match video FPS("+$videoFps+")\n\nChange FPS to match?");
		if (`confirmDialog -title "Confirm" -message $msg
		  -button "Yes" -button "No" -defaultButton "Yes"`!="Yes")
	  		{
				print "Aborted.\n";
				return;
	  		}
*/
		}

	if (`about -mac` || `about -linux`)
		$ffMpegCmd="\""+$ffmpeg+"\" -y -i \""+$file+"\""+$aTempo+" \""+$resultAifFile+"\"";
	else
		$ffMpegCmd="start\/wait/I \"Converting Audio\" \""+$ffmpeg+"\" -y -i \""+$file+"\""+$aTempo+" \""+$resultAifFile+"\"";
	print ("// Starting Converting Audio:"+$ffMpegCmd+"\n");
	system ($ffMpegCmd);

	if (!`file -q -ex $resultAifFile`)
		error ("Failed to create:\""+$resultAifFile+"\"");
	evalDeferred ("file -import -type \"audio\" -ignoreVersion -mergeNamespacesOnClash false -options \"o=0\" \""+$resultAifFile+"\"");
	}

$fDet=$driveLetter+":\n";
$fDet+="cd "+$asVideoMoCapDir+"\n";
$fDet+="title VideoMoCap\n";
$fDet+="cls\n";
$fDet+="echo Starting VideoMoCap\n";
$fDet+="@echo off\n";
$fDet+="asVideoMoCap.exe -i \""+$file+"\""+$gFlag+$videoRunningModeFlag+" -t "+$task+"\n";
$fDet+="exit";

string $tmpDir=`asGetTempDirectory`;
string $batFile=$tmpDir+"asVideoMoCap.bat";
$fileId=`fopen $batFile "w"`;
fprint $fileId ($fDet);
fclose $fileId;

$cmd="start\/wait/I \"VideoMoCap\" \""+$batFile+"\"";
if (!$importOnly) system ($cmd);
for ($i=0;$i<size($resultFiles);$i++)
	if (!`file -q -ex $resultFiles[$i]`)
		error ("Something went wrong, file not found:\""+$resultFiles[$i]+"\"");
print ("Visual result can be seen in this video:\""+$resultAviFile+"\"\n");

//imageSize
createNode -n asVideoMoCapFileSize file;
setAttr -type "string" asVideoMoCapFileSize.fileTextureName $resultJpgFile;
$imageSize=`getAttr asVideoMoCapFileSize.outSize`;
delete asVideoMoCapFileSize;
$width=($imageSize[0]/2000.0)*$charHeight;
$height=($imageSize[1]/2000.0)*$charHeight;

if ($imagePlaneReference)
	{
	if (`objExists asVideoMoCapImagePlane`)
		delete asVideoMoCapImagePlane;

	//avoiding shader-caching issue
	$imgSeqDirName="imgSeq_";
	for ($z=0;$z<6;$z++)
		{//avoiding shader-caching issue
		$nr=`rand 26`;
		$imgSeqDirName+=`asNrToLetter $nr`;
		}
	sysFile -ren ($asVideoMoCapDir+"/"+$imgSeqDirName) ($asVideoMoCapDir+"/imgSeq");

	$tempString=`imagePlane`;
	rename $tempString[0] asVideoMoCapImagePlane;
	setAttr -type "string" asVideoMoCapImagePlaneShape.imageName ($asVideoMoCapDir+"/"+$imgSeqDirName+"/imgSeq.0000.jpg");
	setAttr asVideoMoCapImagePlaneShape.useFrameExtension 1;
	setAttr asVideoMoCapImagePlaneShape.maintainRatio 1;
	setAttr asVideoMoCapImagePlaneShape.width 1;
	setAttr asVideoMoCapImagePlaneShape.height 1;
	}

if ($importOnly && `objExists asVideoMoCapImagePlane`)
	{
	parent -w asVideoMoCapImagePlane;
	xform -ws -t 0 0 0 -s 1 1 1 asVideoMoCapImagePlane;
	}

if (`objExists asVideoMoCapImagePlane`)
	{
	setAttr asVideoMoCapImagePlane.t -type float3 0.5 0.5 0;
	if (!$worldLandMarks)
		setAttr asVideoMoCapImagePlane.tz -0.1;
	}

if (`objExists asVideoMoCap`)
	delete asVideoMoCap;
createNode -n asVideoMoCap transform;
createNode -n scaleMe -p asVideoMoCap transform;
createNode -n asVideoMoCapTrackers -p scaleMe transform;
createNode -n asVideoMoCapUpVecs -p asVideoMoCap transform;
createNode -n asVideoMoCapJntTrackers -p asVideoMoCap transform;
createNode -n asVideoMoCapTrackers_M -p asVideoMoCapTrackers transform;
createNode -n asVideoMoCapTrackers_R -p asVideoMoCapTrackers transform;
createNode -n asVideoMoCapTrackers_L -p asVideoMoCapTrackers transform;
if (`objExists |asVideoMoCapImagePlane`)
	parent |asVideoMoCapImagePlane scaleMe;


//count lines
$fileId=`fopen $trackDataFile "r"`;
$nextLine = `fgetline $fileId`;
while (size($nextLine)>0)
	{
	$numLines++;
	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;
playbackOptions -min 0 -max ($numLines-1);

evalDeferred ("progressBar -e -ep "+$gMainProgressBar);
progressBar -e -st "Reading Data" -bp -ii 1 -min 0 -max $numLines $gMainProgressBar;

$startTime=`timerX`;
$fileId=`fopen $trackDataFile "r"`;
$nextLine = `fgetline $fileId`;
while (size($nextLine)>0)
	{
	progressBar -e -s 1 $gMainProgressBar;
	if (`progressBar -q -ic $gMainProgressBar`)
		{
		fclose $fileId;
		error "Interrupted";
		}
	$landMarkNr=0;
	$lev=0;
	if ($track=="hand" && !`gmatch $nextLine "*Category*"`)
		{
		print ("Hand Tracking Failed on this frame, Skipping frameNr: "+$frameNr+"\n");
		$frameNr++;
		$nextLine=`fgetline $fileId`;
		continue;
		}
	if (`gmatch $nextLine "*landmarks=[[][]]*"`)
		{
		print ("Landmarks Tracking Failed on this frame, Skipping frameNr: "+$frameNr+"\n");
		$frameNr++;
		$nextLine=`fgetline $fileId`;
		continue;
		}
//	currentTime $frameNr;
	$side="";
	$startedHL=0;
	$sideSwitched=0;
	$line=`strip $nextLine`;
	tokenize $line $tempString;
	for ($i=0;$i<size($tempString);$i++)
		{
		tokenize $tempString[$i] "=" $tempString2;
		for ($y=0;$y<size($tempString2);$y++)
			{

			if (`gmatch $tempString2[$y] "*(*"`)
				{
				tokenize $tempString2[$y] "(" $tempString3;
				$tempString2[$y]=$tempString3[size($tempString3)-1];
				}

			if ($track=="hand")
				{
				if ($side=="")
					if ($tempString2[$y]=="display_name")
						{
						if (`gmatch $tempString2[$y+1] "*'Right'*"`) $side="_R";
						if (`gmatch $tempString2[$y+1] "*'Left'*"`) $side="_L";
						}
				if ($landMarkNr==21)
					$landMarkNr=0;
				}

			if ($track=="hand" || $track=="body")
				{
				if ($tempString2[$y]==$landMarkName+"_landmarks")
					{
					$startedHL=!$worldLandMarks;
					$landMarkNr=0;
					continue;
					}
				if ($tempString2[$y]==$landMarkName+"_world_landmarks")
					{
					$startedHL=$worldLandMarks;
					$landMarkNr=0;
					continue;
					}
				}
			else if ($track=="face")
				{
				if ($tempString2[$y]=="face_blendshapes")
					{
					$startedHL=1;
					$landMarkNr=0;
					continue;
					}
				if ($startedHL)
					{
					if ($tempString2[$y]=="score")
						{
						$value=`substituteAllString $tempString2[$y+1] "," ""`;
						}
					if ($tempString2[$y]=="category_name")
						{
						$bs=$tempString2[$y+1];
						$bs=`substituteAllString $bs "'" ""`;
						$bs=`substituteAllString $bs ")" ""`;
						$bs=`substituteAllString $bs "," ""`;
						$bs=`substituteAllString $bs "]" ""`;
/*
						if (!`attributeExists $bs asVideoMoCap`)
							addAttr -k 1 -ln $bs -at double asVideoMoCap;
						setKeyframe -itt spline -ott spline -t $frameNr -v $value ("asVideoMoCap."+$bs);
*/
//print ($tempString2[$y]+" :: "+$bs+" : "+$value+"\n");
for ($b=1;$b>-2;$b=$b-2)
	{
	if ($b==1)  {$side="_R";$rightLeft="Right";}
	if ($b==-1) {$side="_L";$rightLeft="Left";}

	if ($bs=="browDown"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1) ($nameSpace+"ctrlBrow"+$side+".ty");
	if ($bs=="browOuterUp"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlBrow"+$side+".outerUpDown");
	if ($bs=="cheekSquint"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlCheek"+$side+".ty");
	if ($bs=="eyeBlink"+$rightLeft)
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlEye"+$side+".blink");
	if ($bs=="eyeLookDown"+$rightLeft)
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1) ($nameSpace+"ctrlEye"+$side+".ty");
	if ($bs=="eyeLookIn"+$rightLeft)
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*$b) ($nameSpace+"ctrlEye"+$side+".tx");
	if ($bs=="eyeLookOut"+$rightLeft && $value>(`getAttr -t $frameNr ($nameSpace+"ctrlEye"+$side+".tx")`*$b))
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1*$b) ($nameSpace+"ctrlEye"+$side+".tx");
	if ($bs=="eyeLookUp"+$rightLeft && $value>(`getAttr -t $frameNr ($nameSpace+"ctrlEye"+$side+".ty")`*-1))
		setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlEye"+$side+".ty");
	if ($bs=="eyeSquint"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlEye"+$side+".squint");
	if ($bs=="eyeWide"+$rightLeft)
		{
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value* 0.3) ($nameSpace+"upperLid"+$side+".ty");
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-0.3) ($nameSpace+"lowerLid"+$side+".ty");
		}
//if ($bs=="mouthDimple"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlBrow"+$side+".ty"); ?mouthDimple
	if ($bs=="mouthFrown"+$rightLeft)
		{
//print ("setKeyframe -itt spline -ott spline -t "+$frameNr+" -v "+$value+" "+$nameSpace+"ctrlMouthCorner"+$side+".tx;\n");
		setKeyframe -itt spline -ott spline -t $frameNr -v $value      ($nameSpace+"ctrlMouthCorner"+$side+".tx");
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1) ($nameSpace+"ctrlMouthCorner"+$side+".ty");
		}
	if ($bs=="mouthLowerDown"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1) ($nameSpace+"lowerLip"+$side+".ty");
	if ($bs=="mouthPressRight")//ready only right, ignore left
		{
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlLips_M.upperPress");
		setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlLips_M.lowerPress");
		}

	if ($bs=="mouthSmile"+$rightLeft && $value>`getAttr -t $frameNr ($nameSpace+"ctrlMouthCorner"+$side+".tx")`)
		{
//print ("setKeyframe -itt spline -ott spline -t "+$frameNr+" -v "+$value+" "+$nameSpace+"ctrlMouthCorner"+$side+".tx;\n");
		setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlMouthCorner"+$side+".tx");
		setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlMouthCorner"+$side+".ty");
		}
//if ($bs=="mouthStretch"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlBrow"+$side+".ty"); ?mouthStretch
	if ($bs=="mouthUpperUp"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"upperLip"+$side+".ty");
	if ($bs=="noseSneer"+$rightLeft) setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlNose"+$side+".ty");
	}

if ($bs=="browInnerUp")
	{
	setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlBrow_R.tx");
	setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlBrow_L.tx");
	}
if ($bs=="cheekPuff")
	{
	setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlCheek_R.tx");
	setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlCheek_L.tx");
	}
if ($bs=="jawForward") setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlMouth_M.jawForward");
if ($bs=="jawLeft")
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlMouth_M.jawSide");
if ($bs=="jawRight" && $value>(`getAttr -t $frameNr ($nameSpace+"ctrlMouth_M.jawSide")`*10))
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-10) ($nameSpace+"ctrlMouth_M.jawSide");
if ($bs=="jawOpen") setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1) ($nameSpace+"ctrlMouth_M.ty");
if ($bs=="mouthLeft")
	setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlLips_M.tx");
if ($bs=="mouthRight" && $value>`getAttr -t $frameNr ($nameSpace+"ctrlLips_M.tx")`)
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*-1) ($nameSpace+"ctrlLips_M.tx");
if ($bs=="mouthClose" && `attributeExists sticky ($nameSpace+"Lip_R")`)
	{
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"Lip_R.sticky");
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"Lip_L.sticky");
	}
//if ($bs=="mouthFunnel") setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+".ty"); ?mouthFunnel
if ($bs=="mouthPucker")
	{
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlLips_M.upperPucker");
	setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlLips_M.lowerPucker");
	}
if ($bs=="mouthRollLower") setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlLips_M.lowerRoll");
if ($bs=="mouthRollUpper") setKeyframe -itt spline -ott spline -t $frameNr -v ($value*10) ($nameSpace+"ctrlLips_M.upperRoll");
//if ($bs=="mouthShrugLower") setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlBrow_L.ty"); ?mouthShrug
//if ($bs=="mouthShrugUpper") setKeyframe -itt spline -ott spline -t $frameNr -v $value ($nameSpace+"ctrlBrow_L.ty"); ?mouthShrug
				}
			}
		continue;
		}

			if ($startedHL)
				{
				$str=$tempString2[$y];
				if (`gmatch $tempString2[$y] "*(*"`)
					{
					tokenize $tempString2[$y] "(" $tempString3;
					$str=$tempString3[1];
					}
				$str=`substituteAllString $str ")" ""`;
				$str=`substituteAllString $str "]" ""`;

				$z++;
				if ($z%2)
					{
					$attr=$str;
					continue;
					}
				else
					$valueString=`substituteAllString $str "," ""`;
				if ($valueString=="None") $value=0;
				else $value=$valueString;


				if ($track=="hand")
					{
					if ($landMarkNr==0) $target="Wrist";
					if ($landMarkNr>0 && $landMarkNr<5) $target="Thumb"+$landMarkNr;
					if ($landMarkNr>4 && $landMarkNr<9) $target="Index"+($landMarkNr-4);
					if ($landMarkNr>8 && $landMarkNr<13) $target="Middle"+($landMarkNr-8);
					if ($landMarkNr>12 && $landMarkNr<17) $target="Ring"+($landMarkNr-12);
					if ($landMarkNr>16 && $landMarkNr<21) $target="Pinky"+($landMarkNr-16);
					}
				if ($track=="body")
					{
					if ($landMarkNr==0)  {$target="Head";$side="_M";}
					if ($landMarkNr==1)  {$target="EyeInner";$side="_L";}
					if ($landMarkNr==2)  {$target="Eye";$side="_L";}
					if ($landMarkNr==3)  {$target="EyeOuter";$side="_L";}
					if ($landMarkNr==4)  {$target="EyeInner";$side="_R";}
					if ($landMarkNr==5)  {$target="Eye";$side="_R";}
					if ($landMarkNr==6)  {$target="EyeOuter";$side="_R";}
					if ($landMarkNr==7)  {$target="Ear";$side="_L";}
					if ($landMarkNr==8)  {$target="Ear";$side="_R";}
					if ($landMarkNr==9)  {$target="Mouth";$side="_L";}
					if ($landMarkNr==10) {$target="Mouth";$side="_R";}
					if ($landMarkNr==11) {$target="Shoulder";$side="_L";}
					if ($landMarkNr==12) {$target="Shoulder";$side="_R";}
					if ($landMarkNr==13) {$target="Elbow";$side="_L";}
					if ($landMarkNr==14) {$target="Elbow";$side="_R";}
					if ($landMarkNr==15) {$target="Wrist";$side="_L";}
					if ($landMarkNr==16) {$target="Wrist";$side="_R";}
					if ($landMarkNr==17) {$target="Pinky";$side="_L";}
					if ($landMarkNr==18) {$target="Pinky";$side="_R";}
					if ($landMarkNr==19) {$target="Index";$side="_L";}
					if ($landMarkNr==20) {$target="Index";$side="_R";}
					if ($landMarkNr==21) {$target="Thumb";$side="_L";}
					if ($landMarkNr==22) {$target="Thumb";$side="_R";}
					if ($landMarkNr==23) {$target="Hip";$side="_L";}
					if ($landMarkNr==24) {$target="Hip";$side="_R";}
					if ($landMarkNr==25) {$target="Knee";$side="_L";}
					if ($landMarkNr==26) {$target="Knee";$side="_R";}
					if ($landMarkNr==27) {$target="Ankle";$side="_L";}
					if ($landMarkNr==28) {$target="Ankle";$side="_R";}
					if ($landMarkNr==29) {$target="Heel";$side="_L";}
					if ($landMarkNr==30) {$target="Heel";$side="_R";}
					if ($landMarkNr==31) {$target="FootIndex";$side="_L";}
					if ($landMarkNr==32) {$target="FootIndex";$side="_R";}
					}
				if ($track=="face")
					{
					$target=$landMarkNr;
					$side="_M";
					}

				$tracker="Tracker"+$target+$side;
				if (!`objExists $tracker`) createNode -n $tracker -p ("asVideoMoCapTrackers"+$side) transform;
				if (!`objExists ("TrackerX"+$target+$side)`) createNode -n ("TrackerX"+$target+$side) -p $tracker transform;
				if (!`objExists ("Jnt"+$tracker)`) {select asVideoMoCapJntTrackers;joint -n ("Jnt"+$tracker);}
//				print ("$frameNr="+$frameNr+" : $landMarkNr="+$landMarkNr+" : $target="+$tracker+" : $attr="+$attr+" : "+$valueString+"\n");
				if ($attr=="x" || $attr=="y" || $attr=="z")
					setKeyframe -itt spline -ott spline -t $frameNr -v $value ($tracker+".t"+$attr);

				if ($attr=="presence")
					$landMarkNr++;

				//side-switch (for hand)
				if ($startedHL==1 && `gmatch $tempString2[$y] "*]*"` && !$sideSwitched)
					{
					if ($side=="_R") $side="_L";
					else if ($side=="_L") $side="_R";
					$sideSwitched=1;
					}
				}
			}
		}
	$frameNr++;
	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;
print ("// Processed file in "+`timerX -startTime $startTime`+" seconds.\n");
currentTime 0 ;


setAttr asVideoMoCapTrackers.ty 1;
setAttr asVideoMoCapTrackers.s -type float3 1 -1 -1;

if (!$worldLandMarks)
	setAttr asVideoMoCapTrackers.sz -0.1;

//default scaleMe
if ($track=="hand") {$scaleMeSize=$charHeight/2.0;$xOffset=$charHeight/10.0;}
if ($track=="body") {$scaleMeSize=$charHeight/1.0;$xOffset=$charHeight/3.0;}
if ($track=="face") {$scaleMeSize=$charHeight/2.0;$xOffset=$charHeight/10.0;}
setAttr scaleMe.s -type float3 ($scaleMeSize*($imageSize[0]/$imageSize[1])) $scaleMeSize $scaleMeSize;
setAttr scaleMe.tx $xOffset;


if ($worldLandMarks)
	{
	if (`objExists asVideoMoCapImagePlane`)
		parent asVideoMoCapImagePlane asVideoMoCap;
	createNode -n iPlanePlaceHolder -p scaleMe transform;
	setAttr iPlanePlaceHolder.tx 0.5;
	parent -w iPlanePlaceHolder;
	setAttr scaleMe.tx (`getAttr iPlanePlaceHolder.tx`*-1);
	delete iPlanePlaceHolder;
	setAttr scaleMe.sx `getAttr scaleMe.sy`;
	}
	
scale -r 0.5 0.5 0.5 scaleMe;

if ($track=="body")
	{//match leg lenght, and move down to make toes on the floor
	$posA=`xform -q -ws -t ($nameSpace+"Hip_R")`;
	$posB=`xform -q -ws -t ($nameSpace+"Knee_R")`;
	$asLegLenght=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;
	$posA=`xform -q -ws -t ($nameSpace+"Ankle_R")`;
	$asLegLenght+=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;

	$posA=`xform -q -ws -t TrackerHip_R`;
	$posB=`xform -q -ws -t TrackerKnee_R`;
	$trackerLegLenght=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;
	$posA=`xform -q -ws -t TrackerAnkle_R`;
	$trackerLegLenght+=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;

	scale -r ($asLegLenght/$trackerLegLenght) ($asLegLenght/$trackerLegLenght) ($asLegLenght/$trackerLegLenght) scaleMe;

	$pos=`xform -q -ws -t TrackerFootIndex_R`;	
	move -r -os -wd 0 ($pos[1]*-1) 0 scaleMe;
	}

if ($track=="face")
	{
	$pos=`xform -q -ws -t ($nameSpace+"Nose_M")`;
	if (`objExists asVideoMoCapImagePlane`)
		{
		parent asVideoMoCapImagePlane asVideoMoCap;
		setAttr asVideoMoCapImagePlane.ty $pos[1];
		}
	delete scaleMe asVideoMoCapUpVecs asVideoMoCapJntTrackers;
	}


if ($motionSmooth)//filter
	{
	select `listRelatives -ad -type transform asVideoMoCap`;
	if ($track=="face")
		select ($nameSpace+"FaceControlSet");
	string $animCurves[]=`listConnections -s 1 -d 0 -type animCurve`;
	select -cl;
	for ($i=0;$i<4;$i++)
		{
		if (`asMayaVersionAsFloat`>=2022)
			filterCurve -f gaussian -w 3 -sc 8 $animCurves;
		else
			filterCurve -f butterworth -cutoffFrequency 7 -samplingRate 30 -keepKeysOnFrame $animCurves;
		}
	}

//Joint Setup (Hand)
for ($b=1;$b>-2;$b=$b-2)
	{
	if ($b==1)  $side="_R";
	if ($b==-1) $side="_L";

	if ($track!="hand")
		break;
	if (!`objExists ("TrackerWrist"+$side)`)
		{
		delete ("asVideoMoCapTrackers"+$side);
		continue;
		}

	//wrist orientation
	createNode -n ("WristUpVec"+$side) -p asVideoMoCapUpVecs transform;
	pointConstraint ("TrackerPinky1"+$side) ("WristUpVec"+$side);
	aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 1 0 -worldUpVector 0 1 0 -worldUpType "vector" ("TrackerIndex1"+$side) ("WristUpVec"+$side);
	aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 1 0 -worldUpVector 1 0 0 -worldUpType "objectrotation" -worldUpObject ("WristUpVec"+$side) ("TrackerIndex1"+$side) ("TrackerPinky1"+$side) ("JntTrackerWrist"+$side);
	pointConstraint ("TrackerXWrist"+$side) ("JntTrackerWrist"+$side);

	//set wrist rot to zero at start frame
	createNode -n ("JntTrackers"+$side) -p ("JntTrackerWrist"+$side) transform;
	parent ("JntTrackers"+$side) asVideoMoCapJntTrackers;
	parent ("JntTrackerWrist"+$side) ("JntTrackers"+$side);
	setAttr ("JntTrackerWrist"+$side+".jo") -type float3 0 0 0;

	setAttr ("JntTrackerWrist"+$side+".ro") `getAttr ($nameSpace+"FKWrist"+$side+".ro")`;
	connectAttr ("JntTrackerWrist"+$side+".r") ($nameSpace+"FKWrist"+$side+".r");

	createNode -n ("Thumb1UpVecOffset"+$side) -p asVideoMoCapUpVecs transform;
	createNode -n ("Thumb1UpVec"+$side) -p ("Thumb1UpVecOffset"+$side) transform;
	parentConstraint ("JntTrackerWrist"+$side) ("Thumb1UpVecOffset"+$side);

	for ($i=0;$i<size($fingers);$i++)
		{
		for ($z=1;$z<4;$z++)
			{
			if ($fingers[$i]=="Thumb")
				{
				aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 1 0 -worldUpVector 0 1 0 -worldUpType "objectrotation" -worldUpObject ("Thumb1UpVec"+$side) ("Tracker"+$fingers[$i]+($z+1)+$side) ("JntTracker"+$fingers[$i]+$z+$side);
				}
			else
				aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 1 0 -worldUpVector 0 1 0 -worldUpType "objectrotation" -worldUpObject ("JntTrackerWrist"+$side) ("Tracker"+$fingers[$i]+($z+1)+$side) ("JntTracker"+$fingers[$i]+$z+$side);
			}
		for ($z=4;$z>1;$z--)
			parent ("JntTracker"+$fingers[$i]+$z+$side) ("JntTracker"+$fingers[$i]+($z-1)+$side);
			setAttr ("JntTracker"+$fingers[$i]+"1"+$side+".jo") -type float3 0 0 0;
		parent ("JntTracker"+$fingers[$i]+"1"+$side) ("JntTrackerWrist"+$side);
		for ($z=1;$z<4;$z++)
			{
			setAttr ("JntTracker"+$fingers[$i]+$z+$side+".jo") -type float3 0 0 0;
			setAttr ("JntTracker"+$fingers[$i]+$z+$side+".rotateOrder") 1;//prioritize bendy Y
			}
		for ($z=1;$z<5;$z++)
			pointConstraint ("TrackerX"+$fingers[$i]+$z+$side) ("JntTracker"+$fingers[$i]+$z+$side);
		for ($z=1;$z<4;$z++)
			{
			setAttr ("Jnt"+$tracker+".ro") `getAttr ($nameSpace+"FK"+$fingers[$i]+"Finger"+$z+$side+".ro")`;
			connectAttr ("JntTracker"+$fingers[$i]+$z+$side+".r") ($nameSpace+"FK"+$fingers[$i]+"Finger"+$z+$side+".r");
			}
		}
	//Thumb angle
	setAttr ("Thumb1UpVec"+$side+".rx") -90;
	setAttr ("JntTrackerThumb1"+$side+".rotateOrder") 0;
	setAttr ("JntTrackerThumb1"+$side+".jo") -type float3 -90 21.163 25;
	}

//Joint Setup (Pose)
if ($track=="body")
	{
	asSetAllFK $nameSpace;
	select asVideoMoCapJntTrackers;
	joint -n JntTrackerRoot_M;
	setAttr JntTrackerRoot_M.rotateOrder 3;

	//Root orientation
	createNode -n RootUpVec_M -p asVideoMoCapUpVecs transform;
	pointConstraint TrackerShoulder_L RootUpVec_M;
	aimConstraint -offset 0 0 0 -weight 1 -aimVector 1 0 0 -upVector  0 1 0 -worldUpVector 0 1 0 -worldUpType "vector" TrackerShoulder_R RootUpVec_M;
	aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 1 0 -upVector -1 0 0 -worldUpVector 1 0 0 -worldUpType "objectrotation" -worldUpObject RootUpVec_M TrackerShoulder_R TrackerShoulder_L JntTrackerRoot_M;

	//Head orientation
	setAttr JntTrackerHead_M.rotateOrder 5;
	setAttr JntTrackerHead_M.jointOrient -type float3 90 0 90;
	createNode -n HeadUpVec_M -p asVideoMoCapUpVecs transform;
	pointConstraint TrackerEar_L HeadUpVec_M;
	aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 0 -1 -upVector -1 0 0 -worldUpType "object" -worldUpObject JntTrackerRoot_M TrackerEar_R HeadUpVec_M;
	orientConstraint HeadUpVec_M JntTrackerHead_M;

	$tempString=`listRelatives -c -type joint asVideoMoCapJntTrackers`;
	pointConstraint TrackerHip_R TrackerHip_L JntTrackerRoot_M;

	//RootStartPos
	createNode -n JntTrackerRootStartPos_M -p JntTrackerRoot_M transform;
	parent JntTrackerRootStartPos_M asVideoMoCapJntTrackers;
	parent JntTrackerRoot_M JntTrackerRootStartPos_M;

	for ($i=0;$i<size($tempString);$i++) 
		{
		$tracker=`substitute "JntTracker" $tempString[$i] "TrackerX"`;
		if (`objExists $tracker`)
			pointConstraint $tracker $tempString[$i];
		}

	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  $side="_R";
		if ($b==-1) $side="_L";

		parent ("JntTrackerHip"+$side) ("JntTrackerShoulder"+$side) JntTrackerRoot_M;
		parent ("JntTrackerFootIndex"+$side) ("JntTrackerHeel"+$side) ("JntTrackerAnkle"+$side);
		parent ("JntTrackerAnkle"+$side) ("JntTrackerKnee"+$side);
		parent ("JntTrackerKnee"+$side) ("JntTrackerHip"+$side);
		parent ("JntTrackerIndex"+$side) ("JntTrackerPinky"+$side) ("JntTrackerThumb"+$side) ("JntTrackerWrist"+$side);
		parent ("JntTrackerWrist"+$side) ("JntTrackerElbow"+$side);
		parent ("JntTrackerElbow"+$side) ("JntTrackerShoulder"+$side);
//		parent ("JntTrackerShoulder"+$side) ("JntTrackerHip"+$side);
		parent ("JntTrackerEar"+$side) ("JntTrackerEyeOuter"+$side);
		parent ("JntTrackerEyeOuter"+$side) ("JntTrackerEye"+$side);
		parent ("JntTrackerEye"+$side) ("JntTrackerEyeInner"+$side);
		parent ("JntTrackerEyeInner"+$side) JntTrackerHead_M;
		parent ("JntTrackerMouth"+$side) JntTrackerHead_M;

		setAttr ("JntTrackerHip"+$side+".rotateOrder") 2;
		setAttr ("JntTrackerShoulder"+$side+".rotateOrder") 5;
		setAttr ("JntTrackerHip"+$side+".jointOrient") -type float3 ( 90*$b) 0 (-90*$b);
		setAttr ("JntTrackerAnkle"+$side+".jointOrientZ") 45;
		setAttr ("JntTrackerShoulder"+$side+".jointOrient") -type float3 (-90*$b) 180 0;
		setAttr ("JntTrackerWrist"+$side+".jointOrientZ") 45;
		setAttr ("JntTrackerWrist"+$side+".jointOrient") -type float3 0 0 20;//aiming only at Index, so apply some offset
		refresh;//due o changed .jo
		aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 0 -1 -worldUpVector 1  0 0 -worldUpType "objectrotation" -worldUpObject JntTrackerRoot_M ("TrackerKnee"+$side) ("JntTrackerHip"+$side);
		aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 0  1 -worldUpVector 0  0 1 -worldUpType "objectrotation" -worldUpObject ("JntTrackerHip"+$side) ("TrackerAnkle"+$side) ("JntTrackerKnee"+$side);
		aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 0  1 -worldUpVector 0  0 1 -worldUpType "objectrotation" -worldUpObject ("JntTrackerKnee"+$side) ("TrackerFootIndex"+$side) ("JntTrackerAnkle"+$side);
		aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 $b 0 -worldUpType "object" -worldUpObject ("TrackerWrist"+$side) ("TrackerElbow"+$side) ("JntTrackerShoulder"+$side);
		aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 0  1 -worldUpVector 0  0 1 -worldUpType "objectrotation" -worldUpObject ("JntTrackerShoulder"+$side) ("TrackerWrist"+$side) ("JntTrackerElbow"+$side);

		aimConstraint -offset 0 0 0 -weight 1 -aimVector $b 0 0 -upVector 0 (-1*$b)  0 -worldUpVector 0 $b 0 -worldUpType "object" -worldUpObject ("TrackerPinky"+$side) ("TrackerIndex"+$side) ("JntTrackerWrist"+$side);

		connectAttr ("JntTrackerHip"+$side+".r") ($nameSpace+"FKHip"+$side+".r");
		connectAttr ("JntTrackerKnee"+$side+".r") ($nameSpace+"FKKnee"+$side+".r");
		connectAttr ("JntTrackerAnkle"+$side+".r") ($nameSpace+"FKAnkle"+$side+".r");
		connectAttr ("JntTrackerShoulder"+$side+".r") ($nameSpace+"FKShoulder"+$side+".r");
		connectAttr ("JntTrackerElbow"+$side+".r") ($nameSpace+"FKElbow"+$side+".r");
		connectAttr ("JntTrackerWrist"+$side+".r") ($nameSpace+"FKWrist"+$side+".r");
		}

	parent JntTrackerHead_M JntTrackerRoot_M;
	if (!$worldLandMarks)
		connectAttr JntTrackerRoot_M.t ($nameSpace+"RootX_M.t");
	connectAttr JntTrackerRoot_M.r ($nameSpace+"RootX_M.r");
	connectAttr JntTrackerHead_M.r ($nameSpace+"FKHead_M.r");
	}

select -cl;
}

global proc asVideoMoCapRemove ()
{
string $track=`optionMenu -q -v asVideoMoCapTrackOptionMenu`;
string $nameSpace=`text -q -l asVideoMoCapNameSpaceText`;
string $extra;
string $fingers[]={"Thumb","Index","Middle","Ring","Pinky"};
string $ctrls[];

if (`objExists asVideoMoCap`)
	delete asVideoMoCap;

if ($track=="hand")
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  $side="_R";
		if ($b==-1) $side="_L";

		for ($x=0;$x<2;$x++)
			{
			if ($x==0) $extra="";
			if ($x==1) $extra="Extra";
			$ctrls[size($ctrls)]=$nameSpace+"FK"+$extra+"Wrist"+$side;
			for ($i=0;$i<size($fingers);$i++)
				for ($z=1;$z<4;$z++)
					if (`objExists ($nameSpace+"FK"+$extra+$fingers[$i]+"Finger"+$z+$side)`)
						$ctrls[size($ctrls)]=$nameSpace+"FK"+$extra+$fingers[$i]+"Finger"+$z+$side;
			}
		}
		
if ($track=="body")
	$ctrls=`sets -q ($nameSpace+"ControlSet")`;
if ($track=="face")
	$ctrls=`sets -q ($nameSpace+"FaceControlSet")`;

for ($i=0;$i<size($ctrls);$i++)
	if (`objExists $ctrls[$i]`)
		{
		delete -channels -unitlessAnimationCurves false  -hierarchy none -controlPoints 0 -shape 0 $ctrls[$i];
		xform -os -t 0 0 0 -ro 0 0 0 -s 1 1 1 $ctrls[$i];
		}

if ($track=="face")
	{
	select $ctrls[0];
	asGoToBuildPose "";//nameSpace from selection
	}

select -cl;
print "// VideoMoCap Removed.\n";
}

global proc asVideoMoCapBake ()
{
string $track=`optionMenu -q -v asVideoMoCapTrackOptionMenu`;
string $nameSpace=`text -q -l asVideoMoCapNameSpaceText`;
string $fingers[]={"Thumb","Index","Middle","Ring","Pinky"};
string $ctrls[],$tempString[];
float $curTime=`currentTime -q`;

if ($track=="hand")
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  $side="_R";
		if ($b==-1) $side="_L";

		$ctrls[size($ctrls)]=$nameSpace+"FK"+"Wrist"+$side;
		for ($i=0;$i<size($fingers);$i++)
			for ($z=1;$z<4;$z++)
				if (`objExists ($nameSpace+"FK"+$fingers[$i]+"Finger"+$z+$side)`)
					$ctrls[size($ctrls)]=$nameSpace+"FK"+$fingers[$i]+"Finger"+$z+$side;

		}
if ($track=="body")
	$ctrls=`sets -q ($nameSpace+"ControlSet")`;

select  $ctrls;
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl 1 -preserveOutsideKeys 1 -sparseAnimCurveBake false -controlPoints false -shape false;
/*
for ($i=0;$i<size($ctrls);$i++)
	{
	$tempString=`listConnections -s 1 -d 0 -type joint -p 1 ($ctrls[$i]+".r")`;
	for ($y=0;$y<size($tempString);$y++)
		disconnectAttr $tempString[$y] ($ctrls[$i]+".r");
	}
*/
if (`objExists |asVideoMoCap`)
	delete |asVideoMoCap;

currentTime $curTime;
select $ctrls;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";
select -cl;
print "// VideoMoCap Baked.\n";
}

global proc asAudio2FaceUI (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $blendShapes[]=`ls -type blendShape`;

if (`window -q -ex asAudio2FaceUI`)
	deleteUI asAudio2FaceUI;
window -t Audio2Face asAudio2FaceUI;
columnLayout -adj 1;
	text -m 0 -l $nameSpace asAudio2FaceNameSpaceText;
	rowLayout -nc 2;
		separator -w 100 -st none;
		button -l "visit nvidia.com/audio2face" -c "showHelp -a \"https://docs.nvidia.com/ace/maya-ace/latest/index.html\"";
		setParent..;
	separator -h 5 -st none;

	optionMenu -l "BlendShape Node" asAudio2FaceBSOptionMenu;
	for ($i=0;$i<size($blendShapes);$i++)
		{
		if (`gmatch $blendShapes[$i] ($nameSpace+"*asFace*")`
		 || `gmatch $blendShapes[$i] ($nameSpace+"*Close*BS*")`
		 || `gmatch $blendShapes[$i] ($nameSpace+"*SquintRightToLeft*")`)
			continue;
		if (`objExists ($nameSpace+"FaceAllSet")`)
			if (`sets -im ($nameSpace+"FaceAllSet") $blendShapes[$i]`)
				continue;
		menuItem -l $blendShapes[$i];
		}

	separator -st none -h 20;
	checkBox -v 1 -l "mouthClose includes mouthOpen" asAudio2FaceMouthCloseIncMouthOpenCheckBox;
	separator -st none -h 20;
	button -l "Connect" -c ("asConnectAudio2Face \""+$uiName+"\"");
	button -l "Disconnect" -c ("asDisconnectAudio2Face \""+$uiName+"\"");
	separator -st none -h 10;
	button -l "bake" -c ("asBakeAudio2Face \""+$uiName+"\"");

showWindow;
}

global proc asBakeAudio2Face (string $uiName)
{
float $curTime=`currentTime -q`;
string $nameSpace=`text -q -l asAudio2FaceNameSpaceText`;
string $side;
string $ctrls[]=`sets -q ($nameSpace+"FaceControlSet")`;

bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys false -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
	-bakeOnOverrideLayer false -controlPoints false -shape false $ctrls;
currentTime $curTime;
select $ctrls;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";
//asDisconnectAudio2Face $uiName;
print "// Audio2Face Baked.\n";
}

global proc asAutoLipSyncUI (string $uiName)
{
asEnsureAsGetScriptLocation;
string $nameSpace;
string $alignerDir=`asGetScriptLocation`+"/AdvancedSkeletonFiles/bin/montreal-forced-aligner";
string $aligner=$alignerDir+"/bin/mfa_align";
if (`about -win`)
	$aligner=$alignerDir+"/bin/mfa_align.exe";
int $haveAligner=`file -q -ex $aligner`;
string $languages[]=`asAutoLipSyncLanguages`;
stringArrayInsertAtIndex 1 $languages "English";
string $language="English";
if (`optionVar -ex asAutoLipSyncLanguage`)
	$language=`optionVar -q asAutoLipSyncLanguage`;

if (`asHotKeyCheck "asAutoLipSyncUI \"\""`) return;

if (`window -q -ex asAutoLipSyncUI`)
	deleteUI asAutoLipSyncUI;
window -t AutoLipSync -w 300 -h 200 asAutoLipSyncUI;
formLayout asAutoLipSyncUIFormLayout;
columnLayout asAutoLipSyncUIColumnLayout;
if (!$haveAligner)
	{
	separator -h 5 -st none;
	text -l "To run AutoLipSync,";
	text -l "first download \"Montreal-Forced-Aligner\"";
	separator -h 5 -st none;
	button -l "Download Montreal-Forced-Aligner" -c ("asAutoLipSyncDownload "+$uiName);
	showWindow;
	print ("// Montreal-Forced-Aligner tool must be downloaded first\n");
	print ("// If the automatic download does not work, you can manually download from:\n");
	print ("// https://github.com/MontrealCorpusTools/Montreal-Forced-Aligner/releases\n");
	print ("// download and extract the files, so you get this available file-path:\n");
	print ("// "+$aligner+"\n");
	print ("\n");
	return;
	}

text -m 0 -l $aligner asAutoLipSyncAlignerText;
separator -h 10 -st none;
columnLayout;
	text -l "Add Idle motions:";
	rowLayout -nc 5;
		checkBox -l "Blink" -v 1 asAutoLipSyncBlinkCheckBox;
		checkBox -l "Glimpse" -v 1 asAutoLipSyncGlimpseCheckBox;
		checkBox -l "EyeBrows" -v 1 asAutoLipSyncEyeBrowsCheckBox;
		checkBox -l "Head" -v 1 asAutoLipSyncHeadCheckBox;
		setParent..;
	setParent..;

separator -h 20 -st none;
setParent..;
scrollField -wordWrap false -text "Dialog text here" asAutoLipSyncUIScrollField;
button -m 0 -l "Open text editor, for non-latin alphabet" -c asAutoLipOpenTextEditor asAutoLipSyncUIButton;
frameLayout -w 300 -cll 1 -cl 0 -l "advanced options" asAutoLipSyncUIFrameLayout;
	columnLayout -adj 0;
		rowLayout -nc 3;
			optionMenu -l "language:" -cc asAutoLipSyncLanguageChanged asAutoLipSyncLanguageOptionMenu;
			for ($i=0;$i<size($languages);$i++)
				menuItem $languages[$i];
			separator -st none -w 20;
			checkBox -l "non-latin alphabet" -cc asAutoLipSyncLanguageChanged asAutoLipSyncNonLatinCheckBox;
			setParent..;
		if (`stringArrayCount $language $languages`)
			{
			optionMenu -e -v $language asAutoLipSyncLanguageOptionMenu;
			asAutoLipSyncLanguageChanged;
			}
		rowLayout -nc 3;
			text -l "phoneme  fadeIn   ";
			floatField -pre 3 -v 0.05 -min 0.001 asAutoLipSyncPhonemeInFloatField;
			text -l "seconds";
			setParent..;
		rowLayout -nc 3;
			text -l "phoneme  fadeOut";
			floatField -pre 3 -v 0.05 -min 0.001 asAutoLipSyncPhonemeOutFloatField;
			text -l "seconds";
			setParent..;
		rowLayout -nc 3;
			checkBox -l "always re-code audio file" asAutoLipSyncAlwaysReCodeCheckBox;		
			setParent..;
		rowLayout -nc 6;
			separator -w 5 -st none;
			button -l "import example voice" -c asAutoLipSyncImportExampleVoice;
			separator -w 5 -st none;
			button -l "visit ibm.com/watson" -c "showHelp -a \"https://www.ibm.com/watson/services/text-to-speech/\"";
			separator -w 5 -st none;
			button -l "enable mp3" -c "asAutoLipSyncEnableMp3";
			setParent..;
		separator;
		setParent..;
	setParent..;
columnLayout asAutoLipSyncUIColumnLayout2;
separator -h 5 -st none;

rowLayout -nc 3;
	separator -w 50 -st none;
	button -w 100 -l "Run Auto LipSync" -c ("asAutoLipSyncForceAlign \""+$uiName+"\"");

formLayout -e 
	-ac asAutoLipSyncUIScrollField "top" 0 asAutoLipSyncUIColumnLayout
	-af asAutoLipSyncUIScrollField "left" 0
	-af asAutoLipSyncUIScrollField "right" 0
	-ac asAutoLipSyncUIScrollField "bottom" 0 asAutoLipSyncUIFrameLayout

	-ac asAutoLipSyncUIFrameLayout "bottom" 0 asAutoLipSyncUIColumnLayout2

	-ac asAutoLipSyncUIButton "top" 0 asAutoLipSyncUIColumnLayout
	-af asAutoLipSyncUIButton "left" 0
	-af asAutoLipSyncUIButton "right" 0
	-ac asAutoLipSyncUIButton "bottom" 0 asAutoLipSyncUIFrameLayout

	-af asAutoLipSyncUIColumnLayout2 "bottom" 5
	-af asAutoLipSyncUIFrameLayout "left" 0
	-af asAutoLipSyncUIFrameLayout "right" 0
	asAutoLipSyncUIFormLayout;

showWindow;
}

global proc asAutoLipSyncForceAlign (string $uiName)
{
global string $gPlayBackSlider;
int $segmentReplacing=0;
int $alwaysReCode=`checkBox -q -v asAutoLipSyncAlwaysReCodeCheckBox`;
float $timeRangeArray[]=`timeControl -q -rangeArray $gPlayBackSlider`;
if (($timeRangeArray[1]-$timeRangeArray[0])>1)
	$segmentReplacing=1;
float $fps=`currentTimeUnitToFPS`;
if ($fps<1) $fps=1;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $mfaDir,$cmd,$genDictCmd,$ffMpegCmd,$pythonCmd,$uniDecoded;
string $tempString[];
string $languageMenuValue=`optionMenu -q -v asAutoLipSyncLanguageOptionMenu`;
string $language=`tolower $languageMenuValue`;
string $aligner=`text -q -l asAutoLipSyncAlignerText`;
$mfaDir=`asStripPath $aligner 2`;
string $lexicon=$mfaDir+"bin/librispeech-lexicon.txt";
string $ffmpeg=$mfaDir+"bin/ffmpeg.e";
if (`about -mac`)
	$ffmpeg=$mfaDir+"bin/ffmpeg";
string $mfaGD=$mfaDir+"bin/mfa_generate_dictionary";
string $g2pFile=$mfaDir+"pretrained_models/"+$language+"_g2p.zip";
string $languageZipFile=$mfaDir+"pretrained_models/"+$language+".zip";
string $tempDir=`asGetTempDirectory`+"AdvancedSkeleton/autoLipSync/";
string $audioNode = `timeControl -q -s $gPlayBackSlider`;
if (!`objExists $audioNode`)
	error "No sound found. Make sure to import a sound file first";
string $soundFile=`getAttr ($audioNode+".filename")`;
tokenize $soundFile "/" $tempString;
string $soundFileBaseName=$tempString[size($tempString)-1];
tokenize $soundFile "." $tempString;
string $soundFileExt=$tempString[size($tempString)-1];
string $forceSoundFile=$tempDir+"input/align."+$soundFileExt;
string $forceTextFile=$tempDir+"input/align.txt";
string $textGridFile=$tempDir+"output/align.TextGrid";
string $forceText=`scrollField -q -tx asAutoLipSyncUIScrollField`;


if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";
if (!`objExists ($nameSpace+"ctrlPhonemes_M")`)
	error ($nameSpace+"ctrlPhonemes_M not found");
if (!`file -q -ex $aligner`)
	error ("Missing file:\""+$aligner+"\"");

//non-english needs to mfa_generate_dictionary (lexicon) first
//use the g2p to make the dict, and then the zip (Pretrained acoustic models) to align
if ($language!="english")
	{
	$lexicon=$tempDir+"sessionLexicon.txt";
	if (`about -mac` || `about -linux`)
		$genDictCmd="\""+$mfaGD+"\" \""+$g2pFile+"\" \""+$tempDir+"input/\" \""+$lexicon+"\"";
	else
		$genDictCmd="start\/wait/I \"Generating Dictionary\" \""+$mfaGD+"\" \""+$g2pFile+"\" \""+$tempDir+"input/\" \""+$lexicon+"\"";
	}

if (`about -mac` || `about -linux`)
	{
	$cmd="\""+$aligner+"\" -c \""+$tempDir+"input/\" \""+$lexicon+"\" "+$language+" \""+$tempDir+"output/\"";
	$ffMpegCmd="start\/wait/I \"Coding Audio\" \""+$ffmpeg+"\" -y -i \""+$soundFile+"\"";
	}
else
	{
	$cmd="start\/wait/I \"Force Aligning\" \""+$aligner+"\" -c \""+$tempDir+"input/\" \""+$lexicon+"\" "+$language+" \""+$tempDir+"output/\"";
	$ffMpegCmd="start\/wait/I \"Coding Audio\" \""+$ffmpeg+"\" -y -i \""+$soundFile+"\"";
	}

if (!`file -q -ex $soundFile`)
	error "Not a valid sound file";

//Remove old results
$tempString=`getFileList -fld ($tempDir+"output")`;
for ($i=0;$i<size($tempString);$i++)
	sysFile -del ($tempDir+"output/"+$tempString[$i]);
if (`checkBox -q -v asAutoLipSyncNonLatinCheckBox` && !$segmentReplacing)
	{
	$tempString=`getFileList -fld ($tempDir+"render")`;
	for ($i=0;$i<size($tempString);$i++)
		sysFile -del ($tempDir+"render/"+$tempString[$i]);
	}

if (!`file -q -ex ($tempDir+"input")`) sysFile -md ($tempDir+"input");
if (!`file -q -ex ($tempDir+"output")`) sysFile -md ($tempDir+"output");
sysFile -cp $forceSoundFile $soundFile;

if ($segmentReplacing || $alwaysReCode)
	if (!`file -q -ex $ffmpeg`)
		asAutoLipSyncFfmpegDownload;
	
if ($segmentReplacing)
	{//If range in the timeLine is highlighted, then we assume to run "Correction" for this segment
	print ("// Segment selection found on Timeline-slider, trimming audio to selection.\n");
	$ffMpegCmd+=" -ss "+($timeRangeArray[0]/$fps)+" -to "+($timeRangeArray[1]/$fps)+" "+$forceSoundFile;
	print ("// Starting Trimming Audio:"+$ffMpegCmd+"\n");
	system ($ffMpegCmd);
	}
else if ($alwaysReCode)
	{
	$ffMpegCmd+=" "+$forceSoundFile;
	print ("// Starting ReCode Audio:"+$ffMpegCmd+"\n");
	system ($ffMpegCmd);	
	}

if (`latinWriting $languageMenuValue`)
	{
	//Unidecode to transliterates any unicode string into the closest possible representation in ascii text.
	//open file > strip_accents > save file, in Py, so we do not need to pass the text as variable

	$forceText=`substituteAllString $forceText "`" ""`;
	$forceText=`substituteAllString $forceText "'" " "`;
	$forceText=`substituteAllString $forceText "\n" " "`;
	$pythonCmd+="import unicodedata\n";
	$pythonCmd+="def strip_accents(s):\n";
	$pythonCmd+="	return ''.join(c for c in unicodedata.normalize('NFD', s)\n";
	$pythonCmd+="		if unicodedata.category(c) != 'Mn')\n";
	python ($pythonCmd);
	$uniDecoded=`python ("strip_accents(u'"+$forceText+"')")`;

	$fileId=`fopen $forceTextFile "w"`;
	fprint $fileId $uniDecoded;
	fclose $fileId;

	if ($uniDecoded!=$forceText)
		scrollField -e -tx $uniDecoded asAutoLipSyncUIScrollField;
	}

//non-english needs to mfa_generate_dictionary (lexicon) first
//use the g2p to make the dict, and then the zip (Pretrained acoustic models) to align
if ($language!="english")
	{
	print ("// Starting Generating Dictionary:"+$genDictCmd+"\n");
	if (`file -q -ex $lexicon`)
		sysFile -del $lexicon;
	system ($genDictCmd);
	if (!`file -q -ex $lexicon`)
		error ("Failed to create dictionary:\""+$lexicon+"\"");
	}

if ($forceText!="")
	{
	print ("// Starting Force Aligning:"+$cmd+"\n");
	system ($cmd);
	}
else
	{
	$fileId=`fopen $textGridFile "w"`;
	fprint $fileId "";
	fclose $fileId;
	}

if (`file -q -ex $textGridFile`)
	print ("// Successfully created:\""+$textGridFile+"\".\n");
else
	{
	if (`file -q -ex ($tempDir+"output/unaligned.txt")`)
		{
		$fileId=`fopen ($tempDir+"output/unaligned.txt") "r"`;
		$tempString[0]=`fread $fileId $tempString[0]`;
		print ($tempString[0]+"\n");
		fclose $fileId;
		}
	//Try with ffmpeg
	if (!$alwaysReCode)
		{
		if (`confirmDialog -title "Confirm" -message "Force Align Failed.\nThis could be a compatibility issues with the sound-file.\nTry to re-code sound-file?"
  	  -button "Yes" -button "No" -defaultButton "Yes"
    	-cancelButton "No" -dismissString "No"`=="Yes")
    		{
    		checkBox -e -v 1 asAutoLipSyncAlwaysReCodeCheckBox;
    		asAutoLipSyncForceAlign $nameSpace;
    		return;
    		}
		}
	//Try re-download language files, since at some point g2p files was moved to a "1.0" folder https://github.com/MontrealCorpusTools/mfa-models/tree/master/g2p/1.0
	if (`confirmDialog -title "Confirm" -message "Force Align Failed.\nThe language files might be incorrect,\nTry to re-download language files?"
	  -button "Yes" -button "No" -defaultButton "Yes"
  	-cancelButton "No" -dismissString "No"`=="Yes")
  		{
  		sysFile -del $languageZipFile;
  		sysFile -del $g2pFile;
  		asAutoLipSyncLanguageChanged;
  		asAutoLipSyncForceAlign $nameSpace;
  		return;
  		}

	error ("Failed to create:\""+$textGridFile+"\".\n");
	}

asAutoLipSyncImport $nameSpace;
}

global proc asAutoLipSyncImport (string $nameSpace)
{
global string $gMainProgressBar;
global string $gPlayBackSlider;
global string $gCurrentTimeCmdValueTable[];
int $segmentReplacing=0;
float $timeRangeArray[]=`timeControl -q -rangeArray $gPlayBackSlider`;
float $fps=`currentTimeUnitToFPS`;
if ($fps<1) $fps=1;
int $nonLatin=`checkBox -q -v asAutoLipSyncNonLatinCheckBox`;
int $wordsSection,$phonesSection,$fileId;
int $autoBlink=`checkBox -q -v asAutoLipSyncBlinkCheckBox`;
int $autoGlimpse=`checkBox -q -v asAutoLipSyncGlimpseCheckBox`;
int $autoEyeBrows=`checkBox -q -v asAutoLipSyncEyeBrowsCheckBox`;
int $autoHead=`checkBox -q -v asAutoLipSyncHeadCheckBox`;
int $lastKeyFrameNr,$nextBlinkTriggFrameNr,$nextGlipseTriggFrameNr,$nextHeadTriggFrameNr,$wordNr;
if (!`objExists ($nameSpace+"FKHead_M")`) $autoHead=0;
float $prePhoneTime=`floatField -q -v asAutoLipSyncPhonemeInFloatField`*$fps;
float $postPhoneTime=`floatField -q -v asAutoLipSyncPhonemeOutFloatField`*$fps;
float $sequenceStart=-1;
float $sequenceEnd=-1;
float $wordSpace=0.25;//0.25*$fps
float $scale=1.5;
float $xMin,$xMax,$segRepOffset,$keyValue,$previousKeyTime;
float $wordStarts[],$wordEnds[],$phoneStarts[],$phoneEnds[],$bb[],$keyTimes[],$pos[],$pos1[],$pos2[];
string $aligner=`text -q -l asAutoLipSyncAlignerText`;
string $tempDir=`asGetTempDirectory`+"AdvancedSkeleton/autoLipSync/";
string $textGridFile=$tempDir+"output/align.TextGrid";
string $nextLine,$para,$value,$pythonCmd,$fileRead,$font,$imConvertCmdLine;
string $imConvertCmd=`asGetImConvertCmd`;
string $tempString[],$words[],$phones[],$missingPhoneParts[],$letters[],$deleteObjs[],$texts[],$chars[];
string $currentTimeUnit=`currentUnit -q -t`;
string $audioNode = `timeControl -q -s $gPlayBackSlider`;
string $languageMenuValue=`optionMenu -q -v asAutoLipSyncLanguageOptionMenu`;
string $language=`tolower $languageMenuValue`;
float $offset=`getAttr ($audioNode+".offset")`;///$fps

if (!`objExists ($nameSpace+"ctrlPhonemes_M")`)
	error ($nameSpace+"ctrlPhonemes_M not found");

if (`objExists ($nameSpace+"FaceFitSkeletonHeightShape")`)
    {
    $pos1=`xform -q -ws -t ($nameSpace+"FaceFitSkeletonHeightShape.cv[5]")`;
    $pos2=`xform -q -ws -t ($nameSpace+"FaceFitSkeletonShape.cv[5]")`;
    $scale=$pos1[1]-$pos2[1];
   	}

if (($timeRangeArray[1]-$timeRangeArray[0])>1 && `objExists ($nameSpace+"subTitles")`)
	$segmentReplacing=1;

if ($segmentReplacing)
	{
	//Remove all subtitles in segment (and onwards
	select -cl;
	$pos=`xform -q -ws -t ($nameSpace+"subTitlesArrowShape.cv[3]")`;
	$texts=`listRelatives -c ($nameSpace+"subTitlesRoller")`;
	currentTime $timeRangeArray[0];
	$previousKeyTime=`findKeyframe -which previous ($nameSpace+"subTitlesRoller.tx")`;

	for ($i=0;$i<size($texts);$i++)
		{
		$chars=`listRelatives -c -type transform $texts[$i]`;
		if ($nonLatin) $chars[0]=$texts[$i];
		for ($y=0;$y<size($chars);$y++)
			if ((`getAttr -t $previousKeyTime ($nameSpace+"subTitlesRoller.tx")`*-1)<=`getAttr ($texts[$i]+".tx")`)
				select -add $texts[$i];
		}

	if (size(`ls -sl`))
		delete;

	//Remove subTitlesRoller keyframes as well
	if (`objExists ($nameSpace+"subTitlesRoller")`)
		cutKey -time ($timeRangeArray[0]+":99999") -attribute translateX -option keys ($nameSpace+"subTitlesRoller");
	cutKey -time ($timeRangeArray[0]+":99999") -option keys ($nameSpace+"ctrlPhonemes_M");
	}

/*
Removed as this can cause Preference window to no longer load
//Maya(above2016) seems to want to remove the "sec" timeUnit, overriding this with optionvar and re-create $gCurrentTimeCmdValueTable
if (!`stringArrayCount "sec" $gCurrentTimeCmdValueTable` && `exists workingTimeUtil`)
	{
	optionVar -iv hideNoFPSFramerate 0;
	eval ("source workingTimeUtil");
	}

currentUnit -t "sec";
evalDeferred ("catchQuiet(`currentUnit -t "+$currentTimeUnit+"`)");
*/
//Possible restore
if (`currentUnit -q -t`=="sec")
	currentUnit  -t "film";

if ($segmentReplacing)
	$segRepOffset=`currentTime -q`;

if ($segmentReplacing)
	{
	if (`objExists subTitles_parentConstraint1`)
		delete subTitles_parentConstraint1;
	if (`objExists ($nameSpace+"subTitles")`)
		xform -ws -t 0 0 0 -ro 0 0 0 -s 1 1 1 ($nameSpace+"subTitles");
	}
else
	{
	$deleteObjs={"subTitles","subTitlesExp","subTitlesBox","subTitlesArrow","subTitlesBoxMPD"};
	for ($i=0;$i<size($deleteObjs);$i++)
		if (`objExists ($nameSpace+$deleteObjs[$i])`)
			delete ($nameSpace+$deleteObjs[$i]);

	createNode -n ($nameSpace+"subTitles") transform;
	createNode -n ($nameSpace+"subTitlesRoller") -p ($nameSpace+"subTitles") transform;
	$tempString[0]=`curve -d 1 -p -4 1.25 0 -p -4 -0.5 0 -p 4 -0.5 0 -p 4 1.25 0 -p -4 1.25 0 -k 0 -k 1 -k 2 -k 3 -k 4`;
	rename $tempString[0] ($nameSpace+"subTitlesBox");
	setAttr ($nameSpace+"subTitlesBoxShape.overrideEnabled") 1;
	setAttr ($nameSpace+"subTitlesBoxShape.overrideColor") 13;
	$tempString[0]=`curve -d 1 -p 0 0.65 0 -p 0.127 1.2 0 -p -0.127 1.2 0 -p 0 0.65 0 -k 0 -k 1 -k 2 -k 3`;
	parent ($nameSpace+"subTitlesBox") ($nameSpace+"subTitles");
	addAttr -k 1 -ln textVisCenter -at double -dv 4.5 ($nameSpace+"subTitlesBox");
	addAttr -k 1 -ln textVisLenght -at double -dv 8 ($nameSpace+"subTitlesBox");
	createNode -n ($nameSpace+"subTitlesBoxMPD") multiplyDivide;
	connectAttr ($nameSpace+"subTitlesBox.sx") ($nameSpace+"subTitlesBoxMPD.input1X");
	connectAttr ($nameSpace+"subTitlesBox.sx") ($nameSpace+"subTitlesBoxMPD.input1Y");
	setAttr ($nameSpace+"subTitlesBoxMPD.input2") -type float3 4 8 0;
	connectAttr ($nameSpace+"subTitlesBoxMPD.outputX") ($nameSpace+"subTitlesBox.textVisCenter");
	connectAttr ($nameSpace+"subTitlesBoxMPD.outputY") ($nameSpace+"subTitlesBox.textVisLenght");

	rename $tempString[0] ($nameSpace+"subTitlesArrow");
	setAttr ($nameSpace+"subTitlesArrowShape.overrideEnabled") 1;
	setAttr ($nameSpace+"subTitlesArrowShape.overrideColor") 13;
	parent -add -s ($nameSpace+"subTitlesArrowShape") ($nameSpace+"subTitlesBox");
	delete ($nameSpace+"subTitlesArrow");

	$tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"ctrlPhonemes_M")`;
	if (size($tempString)) delete $tempString;
	$tempString=`listAttr -ud ($nameSpace+"ctrlPhonemes_M")`;
	for ($i=0;$i<size($tempString);$i++)
		if (!`getAttr -l ($nameSpace+"ctrlPhonemes_M."+$tempString[$i])`)
			setAttr ($nameSpace+"ctrlPhonemes_M."+$tempString[$i]) 0;
	if (`attributeExists jaw ($nameSpace+"ctrlPhonemes_M")`)//could have converted to SimplifiedFaceSetup
		{
		setAttr ($nameSpace+"ctrlPhonemes_M.jaw") 0.25;
		setAttr ($nameSpace+"ctrlPhonemes_M.lip") 0.25;
		if (`objExists asFaceBS`)//FaceSetup is BlendShapes, which does not (yet) work with Mulipliers
			{
			setAttr ($nameSpace+"ctrlPhonemes_M.jaw") 1;
			setAttr ($nameSpace+"ctrlPhonemes_M.lip") 1;
			}
		}
	}

$fileId=`fopen $textGridFile "r"`;
$nextLine = `fgetline $fileId`;
while (size($nextLine)>0)
	{
	$line=`strip $nextLine`;
	tokenize $line " = " $tempString;
	$para=$tempString[0];
	$value=$tempString[1];
	if ($sequenceStart==-1 && $para=="xmin") {$sequenceStart=$value;$sequenceStart*=$fps;}
	if ($sequenceEnd==-1 && $para=="xmax") {$sequenceEnd=$value;$sequenceEnd*=$fps;}
	if ($para=="name" && $value=="\"words\"") $wordsSection=1;
	if ($para=="name" && $value=="\"phones\"") {$phonesSection=1;$wordsSection=0;}
	if ($para=="xmin") $xMin=$value;
	if ($para=="xmax") $xMax=$value;
	if ($wordsSection && $para=="text")
		{
		$tempString[0]=`substituteAllString $value "\"" ""`;
		if ($tempString[0]!="")
			{
			$words[size($words)]=$tempString[0];
			$wordStarts[size($wordStarts)]=($xMin+$segRepOffset+$offset)*$fps;
			$wordEnds[size($wordEnds)]=($xMax+$segRepOffset+$offset)*$fps;
			}
		}
	if ($phonesSection && $para=="text")
		{
		$tempString[0]=`substituteAllString $value "\"" ""`;
		if ($tempString[0]!="")
			{
			$phones[size($phones)]=$tempString[0];
			$phoneStarts[size($phoneStarts)]=($xMin+$segRepOffset+$offset)*$fps;
			$phoneEnds[size($phoneEnds)]=($xMax+$segRepOffset+$offset)*$fps;
			}
		}
	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;

for ($i=0;$i<size($words);$i++)
	if ($words[$i]=="<unk>")
		$words[$i]="***";

if (!$segmentReplacing)
	playbackOptions -min ($sequenceStart+$offset) -ast ($sequenceStart+$offset) -aet ($sequenceEnd+$offset) -max ($sequenceEnd+$offset);

//ensure key of value 0 at frame 0
setKeyframe -itt linear -ott linear -t 0 -v 0 ($nameSpace+"subTitlesRoller.tx");

for ($i=0;$i<9999;$i++)
	if (!`objExists ($nameSpace+"text"+$i)`)
		break;
$wordNr=$i;

//render non supported symbols, from utf-8 format text files
if ($nonLatin)
	{
	if (!`file -q -ex ($tempDir+"render")`)
		sysFile -md ($tempDir+"render");
	$pythonCmd="";
	$pythonCmd+="wordsSection = 0\n";
	$pythonCmd+="wordNr = "+$wordNr+"\n";
	$pythonCmd+="searchfile = open('"+$textGridFile+"','r')\n";
	$pythonCmd+="for line in searchfile:\n";
	$pythonCmd+="	if line.find('name = \"words\"') != -1:\n";
	$pythonCmd+="		wordsSection = 1\n";
	$pythonCmd+="	if line.find('name = \"phones\"') != -1:\n";
	$pythonCmd+="		wordsSection = 0\n";
	$pythonCmd+="	if wordsSection == 1:\n";
	$pythonCmd+="		if line.find('text = ') != -1:\n";
	$pythonCmd+="			word = line.split()[2].replace('\"','')\n";
	$pythonCmd+="			if word == '':\n";
	$pythonCmd+="				continue\n";
	$pythonCmd+="			wordFile = open ('"+$tempDir+"render/word'+str(wordNr)+'.txt','w')\n";
	$pythonCmd+="			wordFile.write (word)\n";
	$pythonCmd+="			wordFile.close ()\n";
	$pythonCmd+="			wordNr = wordNr + 1\n";
	$pythonCmd+="searchfile.close()\n";
	python ($pythonCmd);
	}

evalDeferred ("progressBar -e -ep "+$gMainProgressBar);
progressBar -e -st "Reading Data" -bp -ii 1 -min 0 -max (size($words)+1) $gMainProgressBar;

for ($i=0;$i<size($words);$i++)
	{
	progressBar -e -s 1 $gMainProgressBar;
	if (`progressBar -q -ic $gMainProgressBar`)
		error "Interrupted";
	currentTime $wordStarts[$i];
	if ($nonLatin)
		{
		$font="arial";
		if ($language=="thai") $font="tahoma";
		if ($language=="korean") $font="Malgun-Gothic";
		$imConvertCmdLine=$imConvertCmd+" -background black -fill white -font "+$font+" -pointsize 72 label:@"+$tempDir+"render/word"+$wordNr+".txt "+$tempDir+"render/word"+$wordNr+".png";
		system ($imConvertCmdLine);
		$tempString=`ls ($nameSpace+"text*"+$wordNr)`;
		for ($y=0;$y<size($tempString);$y++)
			if (`objExists $tempString[$y]`) delete $tempString[$y];
		polyPlane -n ($nameSpace+"text"+$wordNr) -w 1 -h 1 -sx 1 -sy 1 -ax 0 0 1 -cuv 2 -ch 0;
		shadingNode -n ($nameSpace+"textShader"+$wordNr) -asShader surfaceShader;
		sets -renderable true -noSurfaceShader true -empty -name ($nameSpace+"textSG"+$wordNr);
		connectAttr -f ($nameSpace+"textShader"+$wordNr+".outColor") ($nameSpace+"textSG"+$wordNr+".surfaceShader");
		sets -e -forceElement ($nameSpace+"textSG"+$wordNr) ($nameSpace+"text"+$wordNr);
		createNode -n ($nameSpace+"textFile"+$wordNr) file;
		connectAttr -force ($nameSpace+"textFile"+$wordNr+".outColor") ($nameSpace+"textShader"+$wordNr+".outColor");
		setAttr -type "string" ($nameSpace+"textFile"+$wordNr+".fileTextureName") ($tempDir+"render/word"+$wordNr+".png");
		move -r -ws -wd 0.5 0 0 ($nameSpace+"text"+$wordNr+".vtx[0:99]");
		scale -r -p 0 0 0 ((size($words[$i])/2.25)) 1 1 ($nameSpace+"text"+$wordNr+".vtx[0:99]");

//		setAttr ($nameSpace+"text"+$wordNr+".sx") ((size($words[$i])/2.0));
		}
	else
		{
		$tempString=`textCurves -f "Times New Roman|wt:50|sz:28" -t $words[$i]`;
		delete `ls -type makeTextCurves`;
		rename $tempString[0] ($nameSpace+"text"+$wordNr);
		}

	setAttr ($nameSpace+"text"+$wordNr+".tx") $wordSpace;//word spacing
	parent ($nameSpace+"text"+$wordNr) ($nameSpace+"subTitlesRoller");
	setKeyframe -itt linear -ott linear -t $wordStarts[$i] -v (`getAttr ($nameSpace+"subTitlesRoller.tx")`-$wordSpace) ($nameSpace+"subTitlesRoller.tx");
	$bb=`xform -q -ws -bb ($nameSpace+"text"+$wordNr)`;
	$keyValue=`getAttr ($nameSpace+"subTitlesRoller.tx")`-($bb[0]+$bb[3]);
	setKeyframe -itt linear -ott linear -t $wordEnds[$i] -v $keyValue ($nameSpace+"subTitlesRoller.tx");

	$wordNr++;
	}

for ($i=0;$i<size($phones);$i++)
	{
	if ($phones[$i]=="sil" || $phones[$i]=="sp" || $phones[$i]=="spn") 
		continue;
//	if ($language=="english")
		$phoneme=`asAutoLipSyncPhonemeMapping $phones[$i]`;
//	else
//		$phoneme=`substring $language 1 3`+"_"+`asPhonemeTranslate $phones[$i] 0`;
	if ($phoneme=="" || !`attributeExists $phoneme ($nameSpace+"ctrlPhonemes_M")`)
		{
		if (!`stringArrayCount $phoneme $missingPhoneParts`)
			$missingPhoneParts[size($missingPhoneParts)]="Phoneme:\""+$phoneme+"\", from the phone:	\""+$phones[$i]+"\"";
		continue;
		}

	setKeyframe -v 0 -t ($phoneStarts[$i]-$prePhoneTime) ($nameSpace+"ctrlPhonemes_M."+$phoneme);
	setKeyframe -v 10 -t (($phoneStarts[$i]+$phoneEnds[$i])/2.0) ($nameSpace+"ctrlPhonemes_M."+$phoneme);
	setKeyframe -v 0 -t ($phoneEnds[$i]+$postPhoneTime) ($nameSpace+"ctrlPhonemes_M."+$phoneme);
	}

if (size($missingPhoneParts))
	{
	print "Found the following phonemes, that are not mapped to the current FaceSetup:\n";
	print $missingPhoneParts;
	}
progressBar -e -ep $gMainProgressBar;

currentTime 0;
//currentUnit -t $currentTimeUnit;

//Find each letter`s offset, and animate visibility to be visible only inside box
//currentUnit -t "pal";
currentTime 0 ;
$tempString=`listRelatives -ad -type transform ($nameSpace+"subTitlesRoller")`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (!`gmatch $tempString[$i] "Char_*"` && !$nonLatin)
		continue;
	$letters[size($letters)]=$tempString[$i];
	}
$bb=`xform -q -ws -bb ($nameSpace+"subTitlesBox")`;
$boxWidth=($bb[3]-$bb[0])/`getAttr ($nameSpace+"subTitles.sx")`;
if ($nameSpace!="" && `objExists subTitlesRoller_translateX`)
	rename subTitlesRoller_translateX ($nameSpace+"subTitlesRoller_translateX");
$keyTimes=`keyframe -q -tc ($nameSpace+"subTitlesRoller_translateX")`;
$lastKeyFrameNr=$keyTimes[size($keyTimes)-1];
progressBar -e -st "Animating text visibility" -bp -ii 1 -min 0 -max ($lastKeyFrameNr+1) $gMainProgressBar;
for ($y=0;$y<size($letters);$y++)
	{
	if (`objExists ($letters[$y]+"PMA")`)
		continue;
	createNode -n ($letters[$y]+"PMA") plusMinusAverage;
	connectAttr -f ($nameSpace+"subTitlesRoller_translateX.output") ($letters[$y]+"PMA.input1D[1]");
	connectAttr -f ($nameSpace+"subTitlesBox.textVisCenter") ($letters[$y]+"PMA.input1D[2]");
	$bb=`xform -q -ws -bb $letters[$y]`;
	setAttr ($letters[$y]+"PMA.input1D[0]") ($bb[0]+0.5);
	createNode -n ($letters[$y]+"Clamp") clamp;
	connectAttr -f ($letters[$y]+"PMA.output1D") ($letters[$y]+"Clamp.inputR");
	setAttr ($letters[$y]+"Clamp.maxR") 1000;
	createNode -n ($letters[$y]+"Condition") condition;
	setAttr ($letters[$y]+"Condition.operation") 2;
	connectAttr -f ($letters[$y]+"Clamp.outputR") ($letters[$y]+"Condition.firstTerm");
	connectAttr -f ($letters[$y]+"Clamp.outputR") ($letters[$y]+"Condition.colorIfFalseR");
	connectAttr -f ($nameSpace+"subTitlesBox.textVisLenght") ($letters[$y]+"Condition.secondTerm");
	connectAttr -f ($letters[$y]+"Condition.outColorR") ($letters[$y]+".v");
	}

//Place subTitles
$bb=`xform -q -ws -bb ($nameSpace+"subTitles")`;
setAttr ($nameSpace+"subTitles.s") -type float3 ($scale/10.0) ($scale/10.0) ($scale/10.0);
$bb=`xform -q -ws -bb ($nameSpace+"ctrlBox")`;
$bb2=`xform -q -ws -bb ($nameSpace+"ctrlPhonemes_M")`;
$bb3=`xform -q -ws -bb ($nameSpace+"subTitlesBox")`;
xform -ws -t ($bb[3]+$bb3[3]*1.2) $bb2[1] $bb[5] ($nameSpace+"subTitles");
parentConstraint -mo ($nameSpace+"ctrlBox") ($nameSpace+"subTitles");

if ($segmentReplacing)
	{
	select -r ($nameSpace+"subTitles");
	currentTime $timeRangeArray[0];
	dgdirty -a;
	return;
	}

//Remove existing animation, if Idle animations is to be added
if ($autoBlink)
	{
	$tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"ctrlEye_R") ($nameSpace+"ctrlEye_L")`;
	if (size($tempString)) delete $tempString;
	}
if ($autoGlimpse)
	{
	$tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"Eye_R") ($nameSpace+"Eye_L")`;
	if (size($tempString)) delete $tempString;
	}
if ($autoHead)
	{
	$tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"FKHead_M")`;
	if (size($tempString)) delete $tempString;
	}
if ($autoBlink)
	{
	$tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"ctrlEye_R") ($nameSpace+"ctrlEye_L")`;
	if (size($tempString)) delete $tempString;
	}

//Add Idle animations
if ($autoHead)
	setAttr ($nameSpace+"AimEye_M.follow") 0;
$nextBlinkTriggFrameNr=$keyTimes[0]+`rand 25 40`;
$nextGlipseTriggFrameNr=$keyTimes[0]+`rand 25 40`;
$nextHeadTriggFrameNr=$keyTimes[0]+`rand 80 100`;
for ($i=1;$i<`playbackOptions -q -max`;$i++)
	{
	if ($i<$keyTimes[0])
		continue;//no Idle-anim before first word
	if ($autoBlink && $i==$nextBlinkTriggFrameNr)
		{
		$nextBlinkTriggFrameNr=$i+`rand 50 250`;
		setKeyframe -t $i -v 1.5 ($nameSpace+"ctrlEye_L.blink") ($nameSpace+"ctrlEye_R.blink");
		setKeyframe -t ($i+1) -v 10 ($nameSpace+"ctrlEye_L.blink") ($nameSpace+"ctrlEye_R.blink");
		setKeyframe -t ($i+3) -v 10 ($nameSpace+"ctrlEye_L.blink") ($nameSpace+"ctrlEye_R.blink");
		setKeyframe -t ($i+6) -v 1.5 ($nameSpace+"ctrlEye_L.blink") ($nameSpace+"ctrlEye_R.blink");

		setKeyframe -t ($i+(($nextBlinkTriggFrameNr-$i)*1/4)) -v 2.5 ($nameSpace+"ctrlEye_L.blink") ($nameSpace+"ctrlEye_R.blink");
		setKeyframe -t ($i+(($nextBlinkTriggFrameNr-$i)*3.8/4)) -v 2.5 ($nameSpace+"ctrlEye_L.blink") ($nameSpace+"ctrlEye_R.blink");
		//squint
		$tempFloat[0]=`rand 1 5`;
		setKeyframe -t ($i+(($nextBlinkTriggFrameNr-$i)*1.5/4)) -v 0 ($nameSpace+"ctrlEye_L.squint") ($nameSpace+"ctrlEye_R.squint");
		setKeyframe -t ($i+(($nextBlinkTriggFrameNr-$i)*2/4)) -v $tempFloat[0] ($nameSpace+"ctrlEye_L.squint") ($nameSpace+"ctrlEye_R.squint");
		setKeyframe -t ($i+(($nextBlinkTriggFrameNr-$i)*3.8/4)) -v $tempFloat[0] ($nameSpace+"ctrlEye_L.squint") ($nameSpace+"ctrlEye_R.squint");
		setKeyframe -t ($i+(($nextBlinkTriggFrameNr-$i)*4/4)) -v 0 ($nameSpace+"ctrlEye_L.squint") ($nameSpace+"ctrlEye_R.squint");
		}

	if ($autoGlimpse && $i==$nextGlipseTriggFrameNr)
		{
		$nextGlipseTriggFrameNr=$i+`rand 50 200`;
		setKeyframe -t $i -v 0 ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry") ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		$tempFloat[0]=`rand -1 1`;
		$tempFloat[1]=`rand -6 6`;
		setKeyframe -t ($i+10) -v $tempFloat[0] ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		setKeyframe -t ($i+10) -v $tempFloat[1] ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry");
		setKeyframe -t ($i+15) -v $tempFloat[0] ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		setKeyframe -t ($i+15) -v $tempFloat[1] ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry");
		setKeyframe -t ($i+20) -v 0 ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry") ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		setKeyframe -t ($i+25) -v 0 ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry") ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		$tempFloat[0]=`rand -1 1`;
		$tempFloat[1]=`rand -6 6`;
		setKeyframe -t ($i+30) -v $tempFloat[0] ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		setKeyframe -t ($i+30) -v $tempFloat[1] ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry");
		setKeyframe -t ($i+38) -v $tempFloat[0] ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		setKeyframe -t ($i+38) -v $tempFloat[1] ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry");
		setKeyframe -t ($i+41) -v 0 ($nameSpace+"Eye_L.ry") ($nameSpace+"Eye_R.ry") ($nameSpace+"Eye_L.rx") ($nameSpace+"Eye_R.rx");
		}

	if ($autoHead && $i==$nextHeadTriggFrameNr)
		{
		$nextHeadTriggFrameNr=$i+`rand 25 300`;
		$moveDur=`rand 5 20`;
		$tempFloat=`getAttr -t $i ($nameSpace+"FKHead_M.r")`;
		setKeyframe -t $i -v $tempFloat[0] ($nameSpace+"FKHead_M.rx");
		setKeyframe -t $i -v $tempFloat[1] ($nameSpace+"FKHead_M.ry");
		setKeyframe -t $i -v $tempFloat[2] ($nameSpace+"FKHead_M.rz");
			setKeyframe -t ($i+($moveDur/2.0)) -v ($tempFloat[2]-4) ($nameSpace+"FKHead_M.rz");
		setKeyframe -t ($i+$moveDur) -v `rand -8 8` ($nameSpace+"FKHead_M.rx");
		setKeyframe -t ($i+$moveDur) -v `rand -4 4` ($nameSpace+"FKHead_M.ry");
		setKeyframe -t ($i+$moveDur) -v `rand -2 2` ($nameSpace+"FKHead_M.rz");
		if ($autoEyeBrows)
			{
			$tempFloat=`getAttr -t $i ($nameSpace+"ctrlBrow_R.t")`;
			setKeyframe -t ($i+($moveDur/2.0)) -v $tempFloat[0] ($nameSpace+"ctrlBrow_R.tx") ($nameSpace+"ctrlBrow_L.tx");
			setKeyframe -t ($i+($moveDur/2.0)) -v $tempFloat[1] ($nameSpace+"ctrlBrow_R.ty") ($nameSpace+"ctrlBrow_L.ty");
			setKeyframe -t ($i+$moveDur) -v `rand -0.8 0.8` ($nameSpace+"ctrlBrow_R.tx") ($nameSpace+"ctrlBrow_L.tx");
			setKeyframe -t ($i+$moveDur) -v `rand -0.8 0.8` ($nameSpace+"ctrlBrow_R.ty") ($nameSpace+"ctrlBrow_L.ty");
			}
		}
	}

if ($nonLatin && !$segmentReplacing)
	setAttr ($nameSpace+"subTitlesBox.sx") 4;

select -r ($nameSpace+"subTitles");
dgdirty -a;
}

global proc string asAutoLipSyncPhonemeMapping (string $phone)
{
//We will do all upperCase, since the English "meta.yaml" is all upperCase
$phone=`toupper $phone`;

string $phoneme;
//english
if ($phone=="EY1") $phoneme="aaa";
if ($phone=="Z") $phoneme="sss";
if ($phone=="B") $phoneme="mbp";
if ($phone=="AA2") $phoneme="aaa";
if ($phone=="D") $phoneme="lntd";
if ($phone=="IY0") $phoneme="tth";//
if ($phone=="K") $phoneme="gk";
if ($phone=="AO2") $phoneme="ohh";
if ($phone=="R") $phoneme="rrr";
if ($phone=="T") $phoneme="lntd";
if ($phone=="G") $phoneme="gk";
if ($phone=="AH0") $phoneme="ahh";//
if ($phone=="OY1") $phoneme="ohh";
if ($phone=="N") $phoneme="lntd";
if ($phone=="L") $phoneme="lntd";
if ($phone=="M") $phoneme="mbp";
if ($phone=="AY1") $phoneme="ahh";//
if ($phone=="OW2") $phoneme="ohh";
if ($phone=="S") $phoneme="sss";
if ($phone=="P") $phoneme="mbp";
if ($phone=="EH2") $phoneme="eh";
if ($phone=="IY1") $phoneme="iee";
if ($phone=="AY2") $phoneme="aaa";
if ($phone=="OW1") $phoneme="ohh";
if ($phone=="ER0") $phoneme="schwa";//
if ($phone=="UW1") $phoneme="ohh";
if ($phone=="W") $phoneme="www";
if ($phone=="DH") $phoneme="lntd";
if ($phone=="JH") $phoneme="ssh";//
if ($phone=="IH1") $phoneme="iee";
if ($phone=="IH0") $phoneme="iee";
if ($phone=="NG") $phoneme="gk";
if ($phone=="IH2") $phoneme="eh";
if ($phone=="V") $phoneme="schwa";//
if ($phone=="AA1") $phoneme="ohh";
if ($phone=="TH") $phoneme="lntd";
if ($phone=="ZH") $phoneme="ssh";
if ($phone=="AE2") $phoneme="aaa";
if ($phone=="SH") $phoneme="ssh";
if ($phone=="EH1") $phoneme="eh";
if ($phone=="AA0") $phoneme="aaa";
if ($phone=="F") $phoneme="fff";
if ($phone=="AW1") $phoneme="www";
if ($phone=="AE1") $phoneme="aaa";
if ($phone=="OW0") $phoneme="ohh";
if ($phone=="AW2") $phoneme="aaa";
if ($phone=="EY2") $phoneme="eh";
if ($phone=="EY0") $phoneme="aaa";
if ($phone=="AE0") $phoneme="aaa";
if ($phone=="IY2") $phoneme="iee";
if ($phone=="CH") $phoneme="ssh";
if ($phone=="ER1") $phoneme="ahh";
if ($phone=="EH0") $phoneme="ahh";//
if ($phone=="UW2") $phoneme="ohh";
if ($phone=="AH1") $phoneme="ohh";
if ($phone=="HH") $phoneme="schwa";//
if ($phone=="AH2") $phoneme="ahh";
if ($phone=="AO0") $phoneme="ahh";
if ($phone=="OY2") $phoneme="ohh";
if ($phone=="OY0") $phoneme="ohh";
if ($phone=="UH1") $phoneme="ohh";
if ($phone=="AO1") $phoneme="ohh";
if ($phone=="UW0") $phoneme="ohh";
if ($phone=="Y") $phoneme="uuu";//
if ($phone=="AW0") $phoneme="aaa";
if ($phone=="AY0") $phoneme="ahh";
if ($phone=="ER2") $phoneme="ohh";
if ($phone=="UH0") $phoneme="uuu";
if ($phone=="UH2") $phoneme="ohh";

//bulgarian
if ($phone=="A") $phoneme="ahh";
if ($phone=="BJ") $phoneme="mbp";
if ($phone=="DZ") $phoneme="lntd";
if ($phone=="DJ") $phoneme="lntd";
if ($phone=="E") $phoneme="eh";
if ($phone=="FJ") $phoneme="fff";
if ($phone=="GJ") $phoneme="gk";
if ($phone=="I") $phoneme="iee";
if ($phone=="J") $phoneme="ssh";
if ($phone=="JA") $phoneme="tth";
if ($phone=="JU") $phoneme="tth";
if ($phone=="KJ") $phoneme="gk";
if ($phone=="LJ") $phoneme="lntd";
if ($phone=="MJ") $phoneme="mbp";
if ($phone=="NJ") $phoneme="lntd";
if ($phone=="O") $phoneme="ohh";
if ($phone=="PJ") $phoneme="mbp";
if ($phone=="RJ") $phoneme="rrr";
if ($phone=="SJ") $phoneme="ssh";
if ($phone=="TS") $phoneme="ssh";
if ($phone=="TJ") $phoneme="tth";
if ($phone=="U") $phoneme="uuu";
if ($phone=="VJ") $phoneme="schwa";
if ($phone=="X") $phoneme="ohh";
if ($phone=="ZJ") $phoneme="sss";

//Croatian
if ($phone=="DZP") $phoneme="lntd";
if ($phone=="tcp") $phoneme="sss";
if ($phone=="x") $phoneme="";//covered in bulgarian

//Czech
if ($phone=="AA") $phoneme="aaa";
if ($phone=="AW") $phoneme="ahh";
if ($phone=="C") $phoneme="ssh";
if ($phone=="EE") $phoneme="eh";
if ($phone=="EW") $phoneme="eh";
if ($phone=="H") $phoneme="schwa";
if ($phone=="II") $phoneme="iee";
if ($phone=="MG") $phoneme="mbp";
if ($phone=="OO") $phoneme="ohh";
if ($phone=="OW") $phoneme="ohh";
if ($phone=="RSH") $phoneme="rrr";
if ($phone=="RZH") $phoneme="rrr";
if ($phone=="UU") $phoneme="uuu";
 
//French
if ($phone=="AE") $phoneme="eh";
if ($phone=="AX") $phoneme="aaa";
if ($phone=="A~") $phoneme="ahh";
if ($phone=="EU") $phoneme="uuu";
if ($phone=="E~") $phoneme="eh";
if ($phone=="OE") $phoneme="ohh";
if ($phone=="OE~") $phoneme="ohh";
if ($phone=="o~") $phoneme="ohh";

//german
if ($phone=="+hGH") $phoneme="gk";
if ($phone=="C") $phoneme="ssh";
if ($phone=="AI") $phoneme="aaa";
if ($phone=="AU") $phoneme="aaa";
if ($phone=="AL") $phoneme="aaa";
if ($phone=="ATU") $phoneme="lntd";
if ($phone=="EL") $phoneme="eh";
if ($phone=="ETU") $phoneme="lntd";
if ($phone=="IL") $phoneme="lntd";
if ($phone=="OEL") $phoneme="lntd";
if ($phone=="OL") $phoneme="ohh";
if ($phone=="UE") $phoneme="uuu";
if ($phone=="UEL") $phoneme="lntd";
if ($phone=="UL") $phoneme="uuu";

//Hausa
if ($phone=="KR") $phoneme="gk";
if ($phone=="Q") $phoneme="uuu";
if ($phone=="AI") $phoneme="";//covered in german
if ($phone=="AU") $phoneme="";//covered in german
if ($phone=="A_L") $phoneme="aaa";
if ($phone=="A_S") $phoneme="aaa";
if ($phone=="A_T1") $phoneme="aaa";
if ($phone=="A_T2") $phoneme="aaa";
if ($phone=="A_T3") $phoneme="aaa";
if ($phone=="E_L") $phoneme="eh";
if ($phone=="E_S") $phoneme="eh";
if ($phone=="E_T1") $phoneme="eh";
if ($phone=="E_T2") $phoneme="eh";
if ($phone=="I_L") $phoneme="iee";
if ($phone=="I_S") $phoneme="iee";
if ($phone=="I_T1") $phoneme="iee";
if ($phone=="I_T2") $phoneme="iee";
if ($phone=="I_T3") $phoneme="iee";
if ($phone=="O_L") $phoneme="ohh";
if ($phone=="O_S") $phoneme="ohh";
if ($phone=="O_T1") $phoneme="ohh";
if ($phone=="O_T2") $phoneme="ohh";
if ($phone=="U_L") $phoneme="uuu";
if ($phone=="U_S") $phoneme="uuu";
if ($phone=="U_T1") $phoneme="uuu";
if ($phone=="U_T2") $phoneme="uuu";

//Korean
if ($phone=="BB") $phoneme="mbp";
if ($phone=="CHH") $phoneme="ssh";
if ($phone=="DD") $phoneme="lntd";
if ($phone=="EO") $phoneme="eh";
if ($phone=="GG") $phoneme="gk";
if ($phone=="JJ") $phoneme="ssh";
if ($phone=="KH") $phoneme="gk";
if ($phone=="PH") $phoneme="mbp";
if ($phone=="SS") $phoneme="sss";
if ($phone=="EUI") $phoneme="eh";
if ($phone=="IA") $phoneme="ahh";
if ($phone=="IE") $phoneme="iee";
if ($phone=="IEO") $phoneme="";
if ($phone=="IO") $phoneme="ohh";
if ($phone=="IU") $phoneme="uuu";
if ($phone=="OA") $phoneme="ohh";
if ($phone=="UEO") $phoneme="ohh";

//Mandarin (pinyin)
if ($phone=="A1") $phoneme="ahh";
if ($phone=="A2") $phoneme="ahh";
if ($phone=="A3") $phoneme="ahh";
if ($phone=="A4") $phoneme="ahh";
if ($phone=="A5") $phoneme="ahh";
if ($phone=="AI1") $phoneme="ahh";
if ($phone=="AI2") $phoneme="ahh";
if ($phone=="AI3") $phoneme="ahh";
if ($phone=="AI4") $phoneme="ahh";
if ($phone=="AI5") $phoneme="ahh";
if ($phone=="AO1") $phoneme="ohh";
if ($phone=="AO2") $phoneme="ohh";
if ($phone=="AO3") $phoneme="ohh";
if ($phone=="AO4") $phoneme="ohh";
if ($phone=="AO5") $phoneme="ohh";
if ($phone=="E1") $phoneme="eh";
if ($phone=="E2") $phoneme="eh";
if ($phone=="E3") $phoneme="eh";
if ($phone=="E4") $phoneme="eh";
if ($phone=="E5") $phoneme="eh";
if ($phone=="EI1") $phoneme="eh";
if ($phone=="EI2") $phoneme="eh";
if ($phone=="EI3") $phoneme="eh";
if ($phone=="EI4") $phoneme="eh";
if ($phone=="I1") $phoneme="iee"; 
if ($phone=="I2") $phoneme="iee";
if ($phone=="I3") $phoneme="iee";
if ($phone=="I4") $phoneme="iee";
if ($phone=="I5") $phoneme="iee";
if ($phone=="IA1") $phoneme="iee";
if ($phone=="IA2") $phoneme="iee";
if ($phone=="IA3") $phoneme="iee";
if ($phone=="IA4") $phoneme="iee";
if ($phone=="IA5") $phoneme="iee";
if ($phone=="IAO1") $phoneme="iee";
if ($phone=="IAO2") $phoneme="iee";
if ($phone=="IAO3") $phoneme="iee";
if ($phone=="IAO4") $phoneme="iee";
if ($phone=="IE1") $phoneme="iee";
if ($phone=="IE2") $phoneme="iee";
if ($phone=="IE3") $phoneme="iee";
if ($phone=="IE4") $phoneme="iee";
if ($phone=="IE5") $phoneme="iee";
if ($phone=="II1") $phoneme="iee";
if ($phone=="II2") $phoneme="iee";
if ($phone=="II3") $phoneme="iee";
if ($phone=="II4") $phoneme="iee";
if ($phone=="II5") $phoneme="iee";
if ($phone=="IO1") $phoneme="iee";
if ($phone=="IO2") $phoneme="iee";
if ($phone=="IO3") $phoneme="iee";
if ($phone=="IO4") $phoneme="iee";
if ($phone=="IOU1") $phoneme="iee";
if ($phone=="IOU2") $phoneme="iee";
if ($phone=="IOU3") $phoneme="iee";
if ($phone=="IOU4") $phoneme="iee";
if ($phone=="IU1") $phoneme="iee";
if ($phone=="IU2") $phoneme="iee";
if ($phone=="IU3") $phoneme="iee";
if ($phone=="IU4") $phoneme="iee";
if ($phone=="IU5") $phoneme="iee";
if ($phone=="O1") $phoneme="ohh";
if ($phone=="O2") $phoneme="ohh";
if ($phone=="O3") $phoneme="ohh";
if ($phone=="O4") $phoneme="ohh";
if ($phone=="O5") $phoneme="ohh";
if ($phone=="OU1") $phoneme="ohh";
if ($phone=="OU2") $phoneme="ohh";
if ($phone=="OU3") $phoneme="ohh";
if ($phone=="OU4") $phoneme="ohh";
if ($phone=="OU5") $phoneme="ohh";
if ($phone=="U1") $phoneme="uuu";
if ($phone=="U2") $phoneme="uuu";
if ($phone=="U3") $phoneme="uuu";
if ($phone=="U4") $phoneme="uuu";
if ($phone=="U5") $phoneme="uuu";
if ($phone=="UA1") $phoneme="uuu";
if ($phone=="UA2") $phoneme="uuu";
if ($phone=="UA3") $phoneme="uuu";
if ($phone=="UA4") $phoneme="uuu";
if ($phone=="UA5") $phoneme="uuu";
if ($phone=="UAI1") $phoneme="uuu";
if ($phone=="UAI2") $phoneme="uuu";
if ($phone=="UAI3") $phoneme="uuu";
if ($phone=="UAI4") $phoneme="uuu";
if ($phone=="UE1") $phoneme="uuu";
if ($phone=="UE2") $phoneme="uuu";
if ($phone=="UE3") $phoneme="uuu";
if ($phone=="UE4") $phoneme="uuu";
if ($phone=="UE5") $phoneme="uuu";
if ($phone=="UEI1") $phoneme="uuu";
if ($phone=="UEI2") $phoneme="uuu";
if ($phone=="UEI3") $phoneme="uuu";
if ($phone=="UEI4") $phoneme="uuu";
if ($phone=="UEI5") $phoneme="uuu";
if ($phone=="UO1") $phoneme="uuu";
if ($phone=="UO2") $phoneme="uuu";
if ($phone=="UO3") $phoneme="uuu";
if ($phone=="UO4") $phoneme="uuu";
if ($phone=="UO5") $phoneme="uuu";
if ($phone=="V1") $phoneme="www";
if ($phone=="V2") $phoneme="www";
if ($phone=="V3") $phoneme="www";
if ($phone=="V4") $phoneme="www";
if ($phone=="V5") $phoneme="www";
if ($phone=="VA1") $phoneme="www";
if ($phone=="VA2") $phoneme="www";
if ($phone=="VA3") $phoneme="www";
if ($phone=="VA4") $phoneme="www";
if ($phone=="VE1") $phoneme="www";
if ($phone=="VE2") $phoneme="www";
if ($phone=="VE3") $phoneme="www";
if ($phone=="VE4") $phoneme="www";

//Polish
if ($phone=="DZJ") $phoneme="sss";
if ($phone=="EO5") $phoneme="iee";
if ($phone=="N~") $phoneme="lntd";
if ($phone=="OC5") $phoneme="ohh";
if ($phone=="TSJ") $phoneme="sss";

//Portuguese
if ($phone=="A+") $phoneme="aaa";
if ($phone=="A~+") $phoneme="aaa";
if ($phone=="E+") $phoneme="eh";
if ($phone=="E~+") $phoneme="eh";
if ($phone=="I+") $phoneme="iee";
if ($phone=="IX") $phoneme="iee";
if ($phone=="I~") $phoneme="iee";
if ($phone=="I~+") $phoneme="iee";
if ($phone=="O+") $phoneme="ohh";
if ($phone=="O~+") $phoneme="ohh";
if ($phone=="RR") $phoneme="rrr";
if ($phone=="SCH") $phoneme="sss";
if ($phone=="U+") $phoneme="uuu"; 
if ($phone=="UX") $phoneme="uuu";
if ($phone=="U~") $phoneme="uuu";
if ($phone=="U~+") $phoneme="uuu";
if ($phone=="W~") $phoneme="www";

//Russian
if ($phone=="STS") $phoneme="sss";
if ($phone=="STSJ") $phoneme="sss";
if ($phone=="HRD") $phoneme="rrr";
if ($phone=="jE") $phoneme="eh";
if ($phone=="JO") $phoneme="ohh";

//Spanish
if ($phone=="EI") $phoneme="";
if ($phone=="OI") $phoneme="ohh";
if ($phone=="RF") $phoneme="rrr";

//Swahili
if ($phone=="GH") $phoneme="gk";
if ($phone=="MB") $phoneme="mbp"; 
if ($phone=="MV") $phoneme="mbp";
if ($phone=="ND") $phoneme="lntd";
if ($phone=="NG~") $phoneme="gk";
if ($phone=="NY") $phoneme="lntd";
if ($phone=="NZ") $phoneme="lntd";

//Swedish
if ($phone=="ABL") $phoneme="mbp";
if ($phone=="AEL") $phoneme="iee";
if ($phone=="ALE") $phoneme="lntd";
if ($phone=="ALEL") $phoneme="lntd";
if ($phone=="DR") $phoneme="lntd";
if ($phone=="KS") $phoneme="gk";
if ($phone=="LR") $phoneme="lntd";
if ($phone=="NR") $phoneme="lntd";
if ($phone=="OC") $phoneme="ohh";
if ($phone=="OLE") $phoneme="lntd";
if ($phone=="OLEL") $phoneme="lntd";
if ($phone=="OX") $phoneme="ohh";
if ($phone=="SR") $phoneme="sss";
if ($phone=="TR") $phoneme="rrr";
if ($phone=="UXL") $phoneme="uuu";

//Thai
if ($phone=="IIA") $phoneme="iee";
if ($phone=="KHW") $phoneme="gk";
if ($phone=="KW") $phoneme="gk";
if ($phone=="QQ") $phoneme="gk";
if ($phone=="UUA") $phoneme="uuu";
if ($phone=="VV") $phoneme="www";
if ($phone=="VVA") $phoneme="www";
if ($phone=="XX") $phoneme="ohh";
if ($phone=="YY") $phoneme="uuu";

//Turkish
if ($phone=="AB") $phoneme="mbp";
if ($phone=="SFT") $phoneme="sss";

//Ukrainian
if ($phone=="DZH") $phoneme="lntd";
if ($phone=="HJ") $phoneme="eh"; 
if ($phone=="KJ") $phoneme="gk";
if ($phone=="SHJ") $phoneme="sss"; 
if ($phone=="TSH") $phoneme="sss";
if ($phone=="TSHJ") $phoneme="sss";
if ($phone=="WJ") $phoneme="www";
if ($phone=="XJ") $phoneme="sss";
if ($phone=="ZHJ") $phoneme="ssh";

return $phoneme;
}

global proc asAutoLipSyncImportExampleVoice ()
{
string $soundFile,$text;
string $asScriptLocation=`asGetScriptLocation`;

$soundFile=$asScriptLocation+"/AdvancedSkeletonFiles/div/sound/exampleVoice.wav";
if (!`file -q -ex $soundFile`)
	error ("Unable to find the file:\""+$soundFile+"\"");
if (`objExists exampleVoice`)
	delete exampleVoice;
file -import -type "audio" -ignoreVersion -mergeNamespacesOnClash false -rpr "exampleVoice" -options "o=0" $soundFile;

$text="Conscious of its spiritual and moral heritage, the Union is founded on the indivisible, universal values of human dignity,\n";
$text+="freedom, equality and solidarity; it is based on the principles of democracy and the rule of law. It places the individual\n";
$text+="at the heart of its activities, by establishing the citizenship of the Union and by creating an area of freedom, security and justice.";
scrollField -e -tx $text asAutoLipSyncUIScrollField;
optionMenu -e -v "English" asAutoLipSyncLanguageOptionMenu;
if (`checkBox -q -v asAutoLipSyncNonLatinCheckBox`)
	{
	checkBox -e -v 0 asAutoLipSyncNonLatinCheckBox;
	asAutoLipSyncLanguageChanged;
	}

print ("// Example voice imported, you can now Run Auto LipSync.\n");
}

global proc asAutoLipSyncEnableMp3 ()
{
string $cmd;
if (`whatIs performFileDropAction`=="Unknown")
	error "\"performFileDropAction\" function not avaiable in this version of Maya. A newer version of Maya is reuired for this to work.";

$cmd+="global proc int performFileDropAction (string $theFile)\n";
$cmd+="{\n";
$cmd+="if (`gmatch $theFile \"*.mp3\"`)\n";
$cmd+="	{\n";
$cmd+="	asAutoLipSyncConvertMp3 $theFile;\n";
$cmd+="	return 0;\n";
$cmd+="	}\n";

$cmd+="return( performFileImportAction( $theFile ) );\n";
$cmd+="}\n";
evalEcho ($cmd);
print ("// mp3 files will not automatically get converted to wav, when dropped into Maya.\n");
}

global proc asAutoLipSyncConvertMp3 (string $theFile)
{
string $aligner=`text -q -l asAutoLipSyncAlignerText`;
string $ffmpeg=`substitute "mfa_align.exe" $aligner "ffmpeg.e"`;
if (`about -mac`)
	$ffmpeg=`substitute "mfa_align" $aligner "ffmpeg"`;
string $convertedFile=`substitute ".mp3" $theFile ".wav"`;
string $ffMpegCmd;
if (`about -mac` || `about -linux`)
	$ffMpegCmd="\""+$ffmpeg+"\" -y -i \""+$theFile+"\" \""+$convertedFile+"\"";
else
	$ffMpegCmd="start\/wait/I \"Converting Audio\" \""+$ffmpeg+"\" -y -i \""+$theFile+"\" \""+$convertedFile+"\"";
print ("// Starting Converting Audio:"+$ffMpegCmd+"\n");
system ($ffMpegCmd);
if (!`file -q -ex $convertedFile`)
	error ("Failed to create:\""+$convertedFile+"\"");
file -import -type "audio" -ignoreVersion -mergeNamespacesOnClash false -options "o=0" $convertedFile;
}

global proc asAutoLipSyncLanguageChanged ()
{
int $haveLanguage=1;
string $languageMenuValue=`optionMenu -q -v asAutoLipSyncLanguageOptionMenu`;
string $language=`tolower $languageMenuValue`;
string $languageZip=$language+".zip";
string $sLoc=`asGetScriptLocation`;
string $curl=$sLoc+"/AdvancedSkeletonFiles/bin/curl.e";
string $zip=$sLoc+"/AdvancedSkeletonFiles/bin/7za.e";
string $binDir=$sLoc+"/AdvancedSkeletonFiles/bin";
string $aligner=`text -q -l asAutoLipSyncAlignerText`;
string $zipFileUrl;
string $tempString[],$languageZipFiles[];
string $pretrainedModelsDir=`asStripPath $aligner 2`+"pretrained_models/";
string $phonemes[]=`asAutoLipSyncLanguagePhonemes $language`;

//latinWriting
if (`latinWriting $languageMenuValue`)
	{
	button -e -m 0 asAutoLipSyncUIButton;
	scrollField -e -m 1 asAutoLipSyncUIScrollField;
	}
else
	{
	button -e -m 1 asAutoLipSyncUIButton;
	scrollField -e -m 0 asAutoLipSyncUIScrollField;
	}

//ensure we have the Phonemes for the language
$languageZipFiles=`getFileList -fld $pretrainedModelsDir`;

if (!`stringArrayCount $languageZip $languageZipFiles`)
	{
	if (`confirmDialog -title "Confirm" -message ("Download files for \""+$language+"\ language?")
    -button "Yes" -button "No" -defaultButton "Yes"
    -cancelButton "No" -dismissString "No"`=="Yes")
		$haveLanguage=0;
	else
		optionMenu -e -v "English" asAutoLipSyncLanguageOptionMenu;
	}

//save this as the new `default` language
optionVar -sv asAutoLipSyncLanguage $languageMenuValue;

if ($haveLanguage)
	return;

if (!`file -q -ex $pretrainedModelsDir`)
	error ("Folder not found:"+$pretrainedModelsDir);

//download language files
for ($a=0;$a<2;$a++)
	{
	if ($a==0) {$languageZip=$language+".zip";		$zipFileUrl="https://github.com/MontrealCorpusTools/mfa-models/raw/main/acoustic/"+$languageZip;}
	if ($a==1) {$languageZip=$language+"_g2p.zip";$zipFileUrl="https://github.com/MontrealCorpusTools/mfa-models/raw/main/g2p/1.0/"+$languageZip;}

	if ($language=="mandarin")
		$zipFileUrl="https://github.com/MontrealCorpusTools/mfa-models/raw/main/g2p/1.0/"+$language+"_pinyin_g2p.zip";//_pinyin variant

//	if ($language=="korean")
//		$zipFileUrl="https://github.com/MontrealCorpusTools/mfa-models/raw/main/g2p/1.0/"+$language+"_jamo_g2p.zip";//_jamo variant (not hangul)
	if ($language=="korean")
		$zipFileUrl="https://github.com/MontrealCorpusTools/mfa-models/raw/main/g2p/1.0/"+$language+"_g2p.zip";//_jamo variant (not hangul)

	if (`about -mac` || `about -linux`)
		{
		$cmd="\"curl -k -L -o "+$pretrainedModelsDir+$languageZip+" "+$zipFileUrl+"\"";
		evalEcho ("system("+$cmd+")");
		}
	else
		{
		$cmd="start\/wait/I \"Downloading\"  \""+$curl+"\" -k -L -o \""+$pretrainedModelsDir+$languageZip+"\" "+$zipFileUrl;
		print ("// Starting Download:"+$cmd+"\n");
		system ($cmd);
		}
	}
}

global proc string[] asAutoLipSyncLanguages ()
{
string $languages[]={"Bulgarian","Croatian","Czech","French","German","Hausa",
	"Korean","Mandarin","Polish","Portuguese","Russian","Spanish","Swahili","Swedish",
	"Thai","Turkish","Ukrainian","Vietnamese"};
//Maya appears to be the lower ASCII range, we need utf-8 for these languages
$languages=`stringArrayRemove {"Vietnamese"} $languages`;
return $languages;
}

global proc int latinWriting (string $language)
{
int $latin=1;
//Bulgarian: Cyrillic alphabet
//Korean: Hangul
//Mandarin: Hanzi 
//Russian: Cyrillic alphabet
//Thai: Thai script
//Ukrainian: Cyrillic alphabet
//Vietnamese: Vietnamese alphabet
string $latinWritingLaunguages[]={"Bulgarian","Korean","Mandarin","Russian","Thai","Ukrainian","Vietnamese"};
if (`stringArrayCount $language $latinWritingLaunguages`)
	$latin=0;

//proceed with assuming all languages should be Romanized
//$latin=1;

//checkBox can now choose this
$latin=!`checkBox -q -v asAutoLipSyncNonLatinCheckBox`;

return $latin;
}

global proc asAutoLipOpenTextEditor ()
{
string $tempDir=`asGetTempDirectory`+"AdvancedSkeleton/autoLipSync/";
string $forceTextFile=$tempDir+"input/align.txt";
string $pythonCmd;

if (!`file -q -ex ($tempDir+"input")`)
	sysFile -md ($tempDir+"input");

//utf-8 format
$pythonCmd+="txt = u'$\\u2026\\n'\n";
$pythonCmd+="with open('"+$forceTextFile+"', 'wb') as fp:\n";
$pythonCmd+="    fp.write(txt.encode('utf-8'))\n";
print $pythonCmd;
python ($pythonCmd);

system ("load \""+$forceTextFile+"\"");
}

global proc string asPhonemeTranslate (string $phonemes, int $toMaya)
{
//as some phoneme symbols are not valid in Maya-attribute-names, translate to valid symbols:
string $return;
if ($toMaya)
	{
	$return=`substitute "[~]" $phonemes "Tilde"`;
	$return=`substitute "[+]" $return "Plus"`;
	}
else
	{
	$return=`substitute "Tilde" $phonemes "~"`;
	$return=`substitute "Plus" $return "+"`;
	}
return $return;
}

global proc string[] asAutoLipSyncLanguagePhonemes (string $language)
{
string $phonemes[];

if ($language=="bulgarian")
	$phonemes={"S","Y","Z","a","b","bj","d","dZ","dj","dz","e","f","fj","g","gj","i","j","ja","ju","k","kj","l",
		"lj","m","mj","n","nj","o","p","pj","r","rj","s","sj","t","tS","tj","ts","u","v","vj","x","z","zj"};

if ($language=="croatian")
	$phonemes={"L","S","Z","a","b","d","dZ","dzp","e","f","g","i","j","k","l","m","n","nj","o","p","r","s","t",
		"tS","tcp","ts","u","v","x","z"};

if ($language=="czech")
	$phonemes={"a","aa","aw","b","c","ch","d","dj","e","ee","ew","f","g","h","i","ii","j","k","l","m","mg","n",
  "ng","nj","o","oo","ow","p","r","rsh","rzh","s","sh","t","tj","u","uu","v","x","z","zh"};
 
//if ($language=="english")
//	$phonemes={"AA0","AA1","AA2","AE0","AE1","AE2","AH0","AH1","AH2","AO0","AO1","AO2,AW0","AW1","AW2","AY0",
//	"AY1","AY2","EH0","EH1","EH2","ER0","ER1","ER2,EY0","EY1","EY2","IH0","IH1","IH2","IY0","IY1","IY2","OW0",
//	"OW1","OW2,OY0","OY1","OY2","UH0","UH1","UH2","UW0","UW1","UW2,B","CH","D","DH","F","G","HH","JH","K","L",
//	"M","N","NG","P","R,S","SH","T","TH","V","W","Y","Z","ZH"};

if ($language=="french")
	$phonemes={"AE","AX","A~","B","D","E","EU","E~","F","G","H","J","K","L","M","N","NG","NJ","O","OE","OE~",
  "P","R","S","SH","T","V","W","Z","ZH","a","e","h","i","o","o~","u","y"};

if ($language=="german")
	$phonemes={"+hGH","C","S","a","aI","aU","ae","al","atu","b","d","e","eU","el","etu","f","g","h","i","il","j",
		"k","l","m","n","ng","o","oe","oel","ol","p","r","s","t","ts","u","ue","uel","ul","v","x","z"};

if ($language=="hausa")
	$phonemes={"B","D","DZ","F","K","KR","Q","R","S","TS","a","aI","aU","a_L","a_S","a_T1","a_T2","a_T3","b","c",
		"d","e","e_L","e_S","e_T1","e_T2","g","h","i","i_L","i_S","i_T1","i_T2","i_T3","j","k","l","m","n","o","o_L",
		"o_S","o_T1","o_T2","p","r","s","t","u","u_L","u_S","u_T1","u_T2","w","z"};

if ($language=="korean")
	$phonemes={"A","AE","B","BB","CHh","D","DD","E","EO","EU","G","GG","H","I","J","JJ","Kh","L","M","N","NG","O",
		"OE","Ph","R","S","SS","Th","U","UE","euI","iA","iE","iEO","iO","iU","k","oA","p","t","uEO"};

if ($language=="mandarin")
	$phonemes={"a1","a2","a3","a4","a5","ai1","ai2","ai3","ai4","ai5","ao1","ao2","ao3","ao4","ao5","b",
  "c","ch","d","e1","e2","e3","e4","e5","ei1","ei2","ei3","ei4","f","g","h","i1","i2","i3","i4","i5","ia1",
  "ia2","ia3","ia4","ia5","iao1","iao2","iao3","iao4","ie1","ie2","ie3","ie4","ie5","ii1","ii2","ii3",
  "ii4","ii5","io1","io2","io3","io4","iou1","iou2","iou3","iou4","iu1","iu2","iu3","iu4","iu5","j",
  "k","l","m","n","ng","o1","o2","o3","o4","o5","ou1","ou2","ou3","ou4","ou5","p","q","r","s","sh","t",
  "u1","u2","u3","u4","u5","ua1","ua2","ua3","ua4","ua5","uai1","uai2","uai3","uai4","ue1","ue2","ue3",
  "ue4","ue5","uei1","uei2","uei3","uei4","uei5","uo1","uo2","uo3","uo4","uo5","v1","v2","v3","v4",
  "v5","va1","va2","va3","va4","ve1","ve2","ve3","ve4","x","z","zh"};

if ($language=="polish")
	$phonemes={"S","Z","a","b","c","d","dZ","dz","dzj","e","eo5","f","g","h","i","i2","j","k","l","m","n","n~","o",
		"oc5","p","r","s","sj","t","tS","tsj","u","v","w","z","zj"};

if ($language=="portuguese")
	$phonemes={"A","A+","AX","A~","A~+","B","D","DJ","E","E+","E~","E~+","F","G","I","I+","IX","I~","I~+","K","L",
		"LJ","M","N","NJ","O","O+","O~","O~+","P","R","RR","S","SCH","T","TJ","U","U+","UX","U~","U~+","V","W","W~","Z"};

if ($language=="russian")
	$phonemes={"S","Sj","StS","StSj","Z","Zj","a","b","bj","d","dj","e","f","g","hrd","i","i2","j","jA","jE",
  "jO","jU","k","l","lj","m","mj","n","nj","o","p","pj","r","rj","s","sj","t","tS","tSj","tj","ts","u","v",
  "vj","x","z","zj"};

if ($language=="spanish")
	$phonemes={"D","G","L","T","V","a","a+","aI","aU","b","d","e","e+","eI","eU","f","g","i","i+","j","k","l",
  "m","n","ng","n~","o","o+","oI","p","r","rf","s","t","tS","u","u+","w","x","z"};

if ($language=="swahili")
	$phonemes={"a","b","ch","d","dh","e","f","g","gh","h","i","j","k","kh","l","m","mb","mv","n","nd","ng","ng~",
		"nj","ny","nz","o","p","r","s","sh","t","th","u","v","w","y","z"};

if ($language=="swedish")
	$phonemes={"C","S","a","abl","ae","ael","al","ale","alel","b","d","dr","e","el","etu","f","g","h","i","il","j",
		"k","ks","l","lr","m","n","ng","nr","o","oc","oe","oel","ol","ole","olel","ox","p","r","s","sr","t","tr","u",
		"ue","uel","ul","uxl","v"};

if ($language=="thai")
	$phonemes={"a","aa","b","c","ch","d","e","ee","f","h","i","ii","iia","j","k","kh","khw","kw","l","m","n","ng",
		"o","oo","p","ph","q","qq","r","s","t","th","u","uu","uua","v","vv","vva","w","x","xx","y","yy","z"};

if ($language=="turkish")
	$phonemes={"S","Z","ab","b","d","dZ","e","f","g","h","i","i2","j","k","l","m","n","o","oe","p","r","s","sft",
  "t","tS","u","ue","v","z"};

if ($language=="ukrainian")
	$phonemes={"a","b","bj","d","dj","dz","dzh","dzj","e","f","fj","g","h","hj","i","j","k","kj","l","lj","m","mj",
		"n","nj","o","p","pj","r","rj","s","sh","shj","sj","t","tj","ts","tsh","tshj","tsj","u","w","wj","x","xj",
		"y","z","zh","zhj","zj"};

if ($language=="vietnamese")
	$phonemes={"WB","a1_T1","a1_T2","a1_T3","a1_T4","a1_T5","a1_T6","a2_T1","a2_T2","a2_T3","a2_T4",
  "a2_T5","a2_T6","a3_T1","a3_T2","a3_T3","a3_T4","a3_T5","a3_T6","ai_T1","ai_T2","ai_T3","ai_T4",
  "ai_T5","ai_T6","ao_T1","ao_T2","ao_T3","ao_T4","ao_T5","ao_T6","au3_T1","au3_T2","au3_T3",
  "au3_T4","au3_T5","au3_T6","au_T1","au_T2","au_T3","ay3_T1","ay3_T2","ay3_T3","ay3_T4","ay3_T5",
  "ay3_T6","ay_T1","ay_T2","ay_T3","ay_T4","ay_T5","ay_T6","b","ch","d1","d2","e1_T1","e1_T2","e1_T3",
  "e1_T4","e1_T5","e1_T6","e2_T1","e2_T2","e2_T3","e2_T4","e2_T5","e2_T6","eo_T1","eo_T2","eo_T3",
  "eo_T4","eo_T5","eo_T6","eu_T2","eu_T3","eu_T4","eu_T6","g","h","i_T1","i_T2","i_T3","i_T4","i_T5",
  "i_T6","ie2_T1","ie2_T2","ie2_T3","ie2_T4","ie2_T5","ie2_T6","ieu_T1","ieu_T2","ieu_T3","ieu_T4",
  "ieu_T6","iu_T1","iu_T2","iu_T3","iu_T4","iu_T5","iu_T6","j","k","kh","l","m","n","ng","nh","o1_T1",
  "o1_T2","o1_T3","o1_T4","o1_T5","o1_T6","o2_T1","o2_T2","o2_T3","o2_T4","o2_T5","o2_T6","o3_T1",
  "o3_T2","o3_T3","o3_T4","o3_T5","o3_T6","oa_T1","oa_T2","oa_T3","oa_T4","oa_T5","oa_T6","oe_T1",
  "oe_T2","oe_T3","oe_T4","oe_T6","oi2_T1","oi2_T2","oi2_T3","oi2_T4","oi2_T5","oi2_T6","oi3_T1",
  "oi3_T2","oi3_T3","oi3_T4","oi3_T5","oi3_T6","oi_T1","oi_T2","oi_T3","oi_T4","oi_T5","oi_T6",
  "p","ph","r","s","t","th","tr","u1_T1","u1_T2","u1_T3","u1_T4","u1_T5","u1_T6","u2_T1","u2_T2",
  "u2_T3","u2_T4","u2_T5","u2_T6","ua2_T1","ua2_T2","ua2_T3","ua2_T4","ua2_T5","ua2_T6","ua_T1",
  "ua_T2","ua_T3","ua_T4","ua_T5","ua_T6","ui2_T4","ui_T1","ui_T2","ui_T3","ui_T4","ui_T5","ui_T6",
  "uoi2_T1","uoi2_T3","uoi2_T4","uoi2_T5","uoi2_T6","uoi3_T1","uoi3_T2","uoi3_T3","uoi3_T4",
  "uoi3_T5","uou_T6","uu2_T1","uu2_T2","uu2_T3","uu2_T4","uu2_T5","uu2_T6","uy_T1","uy_T2","uy_T3",
  "uy_T4","uy_T5","uy_T6","v","x"};

return $phonemes;
}

global proc asDynBake (string $uiName)
{
int $opm;
float $pos[],$rot[];
string $lastToken;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $tempString[],$tempString2[],$dynJoints[],$softDynCurves[],$fkCtrls[],$dynCtrls[],$bakeXforms[];

if (`asHotKeyCheck "asDynBake \"\""`) return;

if (`confirmDialog -title "Confirm" -message "Bake all dynamics ?"
    -button "Yes" -button "No" -defaultButton "Yes"
    -cancelButton "No" -dismissString "No"`!="Yes")
	return;

if (!`objExists Dynamics`)
	error "Dynamics not found";

if (`attributeExists useOffsetParentMatrix ($nameSpace+"FitSkeleton")`)
	$opm=`getAttr ($nameSpace+"FitSkeleton.useOffsetParentMatrix")`;

createNode -n BakeXforms transform;

//Dyn JointChains
$dynJoints=`listRelatives -type joint -ad Dynamics`;
for ($y=0;$y<size($dynJoints);$y++)
	{
	$tempString=`listConnections ($dynJoints[$y]+".r")`;
	if (`objectType $tempString[0]`=="parentConstraint")//opm
		$tempString=`listConnections ($tempString[0]+".constraintRotate")`;
	if ($tempString[0]=="")
		continue;
	if (`objectType $tempString[0]`=="pairBlend")
		$tempString=`listConnections ($tempString[0]+".outRotate.outRotateX")`;
//	$fkCtrl="FK"+$tempString[0];
	tokenize $tempString[0] ":" $tempString2;
//	if (size($tempString2)==2) $fkCtrl=$tempString2[0]+":FK"+$tempString2[1];
	//allow for nested nameSpaces
	$lastToken=$tempString2[size($tempString2)-1];
	$fkCtrl=`substitute $lastToken $tempString[0] ("FK"+$lastToken)`;
	if (!`objExists $fkCtrl`)
		continue;
	$fkCtrls[size($fkCtrls)]=$fkCtrl;
	$bakeXforms[size($bakeXforms)]="Bake"+$dynJoints[$y];
	createNode -n ("Bake"+$dynJoints[$y]) -p BakeXforms transform;
	parentConstraint $dynJoints[$y] ("Bake"+$dynJoints[$y]);
	}

//Dyn Controllers
$tempString=`ls -type transform`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (`attributeExists showTarget $tempString[$i]`)
		{
		$bakeXforms[size($bakeXforms)]=$tempString[$i];
		$dynCtrls[size($dynCtrls)]=$tempString[$i];
		}
	}

if (size($bakeXforms))
	{
	bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl 0 -preserveOutsideKeys 1 -sparseAnimCurveBake false -controlPoints false -shape false $bakeXforms;
	delete `listRelatives -ad -type parentConstraint BakeXforms`;
	}
delete Dynamics;

for ($i=0;$i<size($fkCtrls);$i++)
	parentConstraint $bakeXforms[$i] $fkCtrls[$i];

if (size($fkCtrls))
	{
	bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl 0 -preserveOutsideKeys 1 -sparseAnimCurveBake false -controlPoints false -shape false $fkCtrls;
	delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 0 $fkCtrls;
	}
if (size($dynCtrls))
	delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 0 $dynCtrls;

delete BakeXforms;
select -cl;
print ("// Dynamics bake complete.\n");
}

global proc asControlsVisibilityToggle ()
{
int $vis;

if (`asHotKeyCheck asControlsVisibilityToggle`) return;

string $motionSystems[]=`ls -r 1 MotionSystem FaceMotionSystem`;
for ($i=0;$i<size($motionSystems);$i++)
    {
    if ($i==0)
        $vis=!(`getAttr ($motionSystems[$i]+".v")`);
    setAttr ($motionSystems[$i]+".v") $vis;
    }
}

global proc asSetupControlVisibilityHotKeyDialog ()
{
if (`asHotKeyCheck asSetupControlVisibilityHotKeyDialog`) return;

if (`confirmDialog -title "Confirm Control Visibility HotKey"
	-message ("Add toggle of control-visibility to the \"~\" hotkey.\n"
	+"For easy toggling visibility of controls.\n"
	+"Holding down the \"~\" key (next to the \"number 1\" on the keyboard) to see and select controls.\n"
	+"As you let go, controls will again be hidden.\n"
	+"The idea is to work without the `visual clutter` of the controls.\n"
	+"Tip: Ctrl+\"\~\" will leave the controls visible")
	-button "Confirm" -button "Cancel" -defaultButton "Confirm"
	-cancelButton "Cancel" -dismissString "Cancel"`!="Confirm")
	return;
asSetupControlVisibilityHotKey;
}

global proc asSetupControlVisibilityHotKey ()
{
if (!`asEnsureWritableHotkeySet`)
    return;

if (!`runTimeCommand -q -ex advancedSkeletonVisibilitySwitch`)
	runTimeCommand
	-annotation "switches the visibility of controls" -category "User" -commandLanguage "mel" -command (
	"int $vis;\n" +
	"string $motionSystems[] = `ls -r 1 MotionSystem FaceMotionSystem`;\n" +
	"for ($i=0; $i<size($motionSystems); $i++)\n" +
	"{\n" +
	"    if ($i==0)\n" +
	"        $vis = !(`getAttr ($motionSystems[$i]+\".v\")`);\n" +
	"    setAttr ($motionSystems[$i]+\".v\") $vis;\n" +
	"}\n")
	advancedSkeletonVisibilitySwitch;

catchQuiet(`nameCommand -ann "advancedSkeletonVisibilitySwitch" -sourceType "mel" -c "advancedSkeletonVisibilitySwitch" advancedSkeletonVisibilitySwitchNameCommand`);

hotkey -keyShortcut "`"  -name "advancedSkeletonVisibilitySwitchNameCommand" -releaseName "advancedSkeletonVisibilitySwitchNameCommand";
hotkey -keyShortcut "\`" -name "advancedSkeletonVisibilitySwitchNameCommand" -releaseName "advancedSkeletonVisibilitySwitchNameCommand";
hotkey -keyShortcut "`"  -ctrlModifier -name "advancedSkeletonVisibilitySwitchNameCommand";
hotkey -keyShortcut "\`" -ctrlModifier -name "advancedSkeletonVisibilitySwitchNameCommand";
}

global proc advancedSkeletonVisibilitySwitch2 ()
{
global string $gMainPane;
int $isFront,$orto,$b;
float $s,$dist,$nearClipPlane,$bX,$bY;
float $autoPlacePos[],$camPos[],$bb[],$bPos[],$bbb[];
string $currentPanel,$cam,$pickerGroupParent,$itemLabel,$dagObjectHit,$ctrlHit,$buttonHit;
string $picker="picker_biped";
string $pickerGroup=$picker+":Group";
string $trs[]={"t","r","s"};
string $xyz[]={"x","y","z"};
string $tempString[],$paneChildren[];
string $sel[]=`ls -sl`;

//if ($isFront)
setAttr PolyBoxes.v 1;
//refresh;
	if (`dagObjectHit`)
		{
		if (`popupMenu -exists asAutoPlaceMenu`)
			deleteUI asAutoPlaceMenu;
		popupMenu -mm 1 -p viewPanes asAutoPlaceMenu;
		dagObjectHit -mn asAutoPlaceMenu;
		$tempString=`popupMenu -q -itemArray asAutoPlaceMenu`;
		$itemLabel=`menuItem -q -l $tempString[0]`;
		tokenize $itemLabel "." $tempString;
		$dagObjectHit=$tempString[0];
//		print ("\n"+$dagObjectHit+" : ");
		}
setAttr PolyBoxes.v 0;

if (!`objExists $pickerGroup`)
	return;

if (!`attributeExists isFront $pickerGroup`)
	addAttr -k 0 -ln isFront -at bool $pickerGroup;
$isFront=!`getAttr ($pickerGroup+".isFront")`;

$currentPanel = `getPanel -withFocus`;
if (!`modelPanel -q -ex $currentPanel`)
	error (" \""+$currentPanel+"\" is not a valid modelPanel");
$cam=`modelPanel -q -camera $currentPanel`;
if (`objectType $cam`=="camera")
	{
	$tempString=`listRelatives -p $cam`;
	$cam=$tempString[0];
	}
$nearClipPlane=`getAttr ($cam+".nearClipPlane")`;
$tempString=`listRelatives -p $pickerGroup`;
if ($tempString[0]!="")
	$pickerGroupParent=$tempString[0];

if (catch (`eval "autoPlace -useMouse"`))
	error "Failed to detect cursor position, camera might be under groundPlane";
$autoPlacePos=`autoPlace -useMouse`;
$camPos=`xform -q -ws -t $cam`;
$orto=`getAttr ($cam+".orthographic")`;
if (`objExists asAutoPlaceCamSpace`)
	{
	$tempString=`listRelatives -c asAutoPlaceCamSpace`;
	for ($i=0;$i<size($tempString);$i++)
		if (!`gmatch $tempString[$i] "asAutoPlaceCamSpace_*Constraint*"`)
			parent -w $tempString[$i];
	delete asAutoPlaceCamSpace;
	}
if (`objExists asAutoPlaceCamSpace2`)
	{
	$tempString=`listRelatives -c asAutoPlaceCamSpace2`;
	for ($i=0;$i<size($tempString);$i++)
			parent -w $tempString[$i];
	delete asAutoPlaceCamSpace2;
	}
createNode -n asAutoPlaceCamSpace transform;
setAttr asAutoPlaceCamSpace.displayLocalAxis 1;
setAttr asAutoPlaceCamSpace.t -type float3 $autoPlacePos[0] $autoPlacePos[1] $autoPlacePos[2];
createNode -n asAutoPlaceCamSpace2 -p asAutoPlaceCamSpace transform;
if ($orto)
	orientConstraint  $cam asAutoPlaceCamSpace;
else
	aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 0 1 -upVector 0 1 0 -worldUpType "objectrotation" -worldUpObject $cam $cam asAutoPlaceCamSpace;
if ($orto)
	{
	parent asAutoPlaceCamSpace $cam;
	$dist=`getAttr asAutoPlaceCamSpace.tz`;
	parent -w asAutoPlaceCamSpace;
	}
else
	$dist=`mag<<$autoPlacePos[0]-$camPos[0],$autoPlacePos[1]-$camPos[1],$autoPlacePos[2]-$camPos[2]>>`;

if ($isFront)
	{
	//find $bb
	if ($pickerGroupParent!="")
		parent -w $pickerGroup;
	xform -os -t 0 0 0 -ro  0 0 0 -s 1 1 1 $pickerGroup;
	$bb=`xform -q -bb $pickerGroup`;

	if ($dagObjectHit!="")
		{
		$tempString[0]="FK"+`substitute "Box" $dagObjectHit ""`;
		if (`gmatch $tempString[0] "*Part[0-9]*"`)
			$tempString[0]=`substitute "Part[0-9]" $tempString[0] ""`;

		if (`objExists $tempString[0]`)
			{
			$ctrlHit=$tempString[0];
			$tempString[0]=$picker+":"+$ctrlHit;
			if (`objExists $tempString[0]`)
				{
				$buttonHit=$tempString[0];
				$bbb=`xform -q -bb $buttonHit`;
				$b=1;
				if (`gmatch $buttonHit "*_L"`)
					$b=-1;
				print ("HIT:\""+$tempString[0]+" : "+`objExists $tempString[0]`+" : "+($bbb[3])+"\n");
				}
			}
		else
			print ("No Ctrl:\""+$tempString[0]+"\"\n");
		}

	if ($orto)
		$s=`getAttr ($cam+".orthographicWidth")`/40.0;
	else
		$s=(`getAttr ($cam+".focalLength")`/700.0)*$nearClipPlane;

	parent -r $pickerGroup asAutoPlaceCamSpace2;
	setAttr ($pickerGroup+".r") -type float3 0 0 0;

	//defaults to centered
	setAttr asAutoPlaceCamSpace2.ty ((($bb[4]-$bb[1])/-2.0)*$s);
	
	if ($buttonHit!="")
		{
		setAttr asAutoPlaceCamSpace2.tx (($bbb[3]-(($bbb[3]-$bbb[0])/2.0))*-$s*$b);
		setAttr asAutoPlaceCamSpace2.ty (($bbb[4]-(($bbb[4]-$bbb[1])/2.0))*-$s);
		}

	setAttr ($pickerGroup+".t") -type float3 0 0 ($dist-($nearClipPlane*2.0));
	parent $pickerGroup $cam;
	setAttr ($pickerGroup+".r") -type float3 0 0 0;

	setAttr ($pickerGroup+".s") -type float3 $s $s $s;

	if ($pickerGroupParent!="")
		{
		if ($pickerGroupParent!=$cam)
			parent $pickerGroup $pickerGroupParent;
		}
	else
		parent -w $pickerGroup;
	}

if (!$isFront)
	{
	for ($y=0;$y<size($trs);$y++)
		for ($z=0;$z<size($xyz);$z++)
			{
			if (!`attributeExists ("pre"+$trs[$y]+$xyz[$z]) $pickerGroup`)
				addAttr -k 0 -ln ("pre"+$trs[$y]+$xyz[$z]) -at double $pickerGroup;
			setAttr ($pickerGroup+"."+$trs[$y]+$xyz[$z]) `getAttr ($pickerGroup+".pre"+$trs[$y]+$xyz[$z]) `;
			}
	}

delete asAutoPlaceCamSpace;

setAttr ($pickerGroup+".isFront") $isFront;
select $sel;
}

global proc int asEnsureWritableHotkeySet()
{
string $currentSet=`hotkeySet -q -current`;
string $defaultLockedSets[]={"Maya_Default","Maya_Classic","Maya_Default_Hotkey_Set","Maya_Default_Hotkeys"};
int $isDefaultLocked=0;
for ($set in $defaultLockedSets)
	{
	if ($currentSet==$set)
		{
		$isDefaultLocked=1;
		break;
		}
	}
if (!$isDefaultLocked)
	{
	print ("Current hotkey set appears custom/writable: "+$currentSet+"\n");
	return 1;
	}
string $baseNewSet="AdvancedSkeleton_Hotkeys";
string $newSet=($baseNewSet+"_"+`date -format "hhmmss"`);
int $suffix=1;
int $nameExists=1;
while ($nameExists)
	{
	$nameExists=0;
	string $allSets[]=`hotkeySet -q -hotkeySetArray`;
	for ($existingSet in $allSets)
		{
		if ($existingSet==$newSet)
			{
			$nameExists=1;
			break;
			}
		}
	if ($nameExists)
		{
		$newSet=($baseNewSet+"_"+`date -format "hhmmss"`+"_"+$suffix);
		$suffix++;
		}
	}
string $msg=("The current hotkey set is:\n\n"+$currentSet+"\n\nThis is a Maya default hotkey set.\nDefault hotkey sets are locked and cannot be edited.\n\nDo you want to duplicate it into a custom hotkey set named:\n\n"+$newSet+"\n\nThis will allow AdvancedSkeleton to assign custom hotkeys.");
string $result=`confirmDialog -title "Locked Maya Hotkey Set" -message $msg -button "Duplicate" -button "Cancel" -defaultButton "Duplicate" -cancelButton "Cancel" -dismissString "Cancel" -icon "question"`;
if ($result!="Duplicate")
	{
	warning ("Hotkey assignment cancelled. Current hotkey set is locked: "+$currentSet);
	return 0;
	}
int $failed=catch(`hotkeySet -source $currentSet $newSet`);
if ($failed)
	{
	warning ("Could not create hotkey set: "+$newSet);
	return 0;
	}
hotkeySet -e -current $newSet;
print ("Created and switched to writable hotkey set: "+$newSet+"\n");
print ("Current hotkey set is now: "+`hotkeySet -q -current`+"\n");
return 1;
}

global proc asVisualizeGimbalLock (string $uiName)
{
string $sel[]=`ls -sl`;
string $nameSpace;
int $fromSelection;
int $buildGimbal[];
float $scale;
float $bb[];
string $name,$lookForVisConnectionOnObject;
string $tempString[],$controlSets[],$controls[];

if (`asHotKeyCheck "asVisualizeGimbalLock \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`; 
if (!size($controlSets))
	error "No controlSets detected. select a controller";

if (`objExists GimbalLockVisualizers`)
	{
	delete GimbalLockVisualizers;
	return;
	}
createNode -n GimbalLockVisualizers transform;
$controls=`sets -q $controlSets`;
if ($sel[0]!="")
	if (`stringArrayCount $sel[0] $controls`)
		$fromSelection=1;
asFitModeEnsureShaders;
for ($i=0;$i<size($controls);$i++)
	{
	if ($controls[$i]==$nameSpace+"Main")
		continue;
	$tempString=`listRelatives -s $controls[$i]`;
	if ($tempString[0]!="")
		if (`objectType $tempString[0]`=="nurbsCurve")
			{
			if ($fromSelection)
				if (`stringArrayCount $controls[$i] $sel`)
					$buildGimbal[$i]=1;
			if (!$fromSelection)
				$buildGimbal[$i]=1;
			}
	}
for ($i=0;$i<size($controls);$i++)
	{
	if (!$buildGimbal[$i])
		continue;
	$name=$controls[$i];
	createNode -n ($name+"Constraint") -p GimbalLockVisualizers transform;
	createNode -n ($name+"Offset") -p ($name+"Constraint") transform;

	polyCylinder -n ($name+"Cones") -r 0.3 -h 2.5 -sx 10 -sy 2 -sz 1 -ax 0 1 0 -rcp 0 -cuv 3 -ch 0;
	scale -r -p 0 0 0 0 0 0 ($name+"Cones.vtx[10:19]");
	parent ($name+"Cones") ($name+"Offset");
	if (`objExists asGreenSG`)
		sets -e -forceElement asGreenSG ($name+"Cones");

	polyTorus -n ($name+"Torus") -r 1 -sr 0.03 -tw 0 -sx 30 -sy 6 -ax 0 1 0 -cuv 1 -ch 0;
	parent ($name+"Torus") ($name+"Offset");
	if (`objExists asRedSG`)
		sets -e -forceElement asRedSG ($name+"Torus");

	polyCylinder -n ($name+"Arrow") -r 0.06 -h 2 -sx 10 -sy 3 -sz 1 -ax 0 1 0 -rcp 0 -cuv 3 -ch 0;
	rotate -r 0 0 90 ($name+"Arrow.vtx[0:41]");
	move -r 1 0 0 ($name+"Arrow.vtx[0:41]");
	scale -r -p 0 0 0 1 0 0 ($name+"Arrow.vtx[0:9]") ($name+"Arrow.vtx[40]");
	move -r 0.35 0 0 ($name+"Arrow.vtx[10:19]");
	scale -r -p 0 0 0 1 1.75 1.75 ($name+"Arrow.vtx[10:19]");
	move -r 1 0 0 ($name+"Arrow.vtx[20:29]");
	parent ($name+"Arrow") ($name+"Offset");
	if (`objExists asGreen2SG`)
		sets -e -forceElement asGreen2SG ($name+"Arrow");
	orientConstraint $name ($name+"Arrow");

	$tempString=`listRelatives -p $name`;
	parentConstraint $tempString[0] ($name+"Constraint");
	$tempString=`listRelatives -s $name`;
	$bb=`xform -q -bb ($tempString[0]+".cv[0:999]")`;
	$scale=(($bb[3]-$bb[0])+($bb[4]-$bb[1])+($bb[5]-$bb[2]))/5.0;
	setAttr -type float3 ($name+"Offset.s") $scale $scale $scale;
	$lookForVisConnectionOnObject=$name;
	$tempString=`listConnections -p 1 ($lookForVisConnectionOnObject+".v")`;
	for ($y=0;$y<20;$y++)
		{
		if ($tempString[0]!="")
			{
			connectAttr $tempString[0] ($name+"Offset.v");
			break;
			}
		$tempString=`listRelatives -p $lookForVisConnectionOnObject`;
		if ($tempString[0]=="")
			break;
		$lookForVisConnectionOnObject=$tempString[0];
		$tempString=`listConnections -p 1 ($lookForVisConnectionOnObject+".v")`;
		}
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 0 -cd ($name+".rotateOrder") ($name+"Cones.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 1 -cd ($name+".rotateOrder") ($name+"Cones.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 2 -cd ($name+".rotateOrder") ($name+"Cones.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 3 -cd ($name+".rotateOrder") ($name+"Cones.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 4 -cd ($name+".rotateOrder") ($name+"Cones.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 5 -cd ($name+".rotateOrder") ($name+"Cones.rx");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ($name+".rotateOrder") ($name+"Cones.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 1 -cd ($name+".rotateOrder") ($name+"Cones.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 2 -cd ($name+".rotateOrder") ($name+"Cones.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 3 -cd ($name+".rotateOrder") ($name+"Cones.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 4 -cd ($name+".rotateOrder") ($name+"Cones.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 5 -cd ($name+".rotateOrder") ($name+"Cones.rz");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 0 -cd ($name+".rotateOrder") ($name+"Torus.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 1 -cd ($name+".rotateOrder") ($name+"Torus.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 2 -cd ($name+".rotateOrder") ($name+"Torus.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 3 -cd ($name+".rotateOrder") ($name+"Torus.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 4 -cd ($name+".rotateOrder") ($name+"Torus.rx");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 5 -cd ($name+".rotateOrder") ($name+"Torus.rx");

	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 0 -cd ($name+".rotateOrder") ($name+"Torus.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 1 -cd ($name+".rotateOrder") ($name+"Torus.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 2 -cd ($name+".rotateOrder") ($name+"Torus.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 90 -dv 3 -cd ($name+".rotateOrder") ($name+"Torus.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 4 -cd ($name+".rotateOrder") ($name+"Torus.rz");
	setDrivenKeyframe -itt "linear" -ott "linear" -v 0 -dv 5 -cd ($name+".rotateOrder") ($name+"Torus.rz");
	}
select $sel;
}

global proc asFaceCtrlsDetach (string $uiName)
{
int $wasConnected;
string $nameSpace,$objA,$objB,$plugA,$plugB;
string $controlSets[];

if (`asHotKeyCheck "asFaceCtrlsDetach \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if (!size($controlSets))
	error "No controlSets detected. select a controller";

$objA=$nameSpace+"SkinAttachCtrlsWrap";
$objB=$nameSpace+"AttacherCurveShape";
$plugA=$objA+".outputGeometry[0]";
$plugB=$objB+".create";

if (`objExists outerLidCurveFromMeshEdge_R`)
	{
	$objA=$nameSpace+"SkinAttachMeshBS";
	$objB=$nameSpace+"SkinAttachMeshShapeDeformed";
	$plugA=$objA+".outputGeometry[0]";
	$plugB=$objB+".inMesh";
	}

if (!`objExists $objA`)
	print ("// No wrap-attached controllers found on this character, this function is for character that use the face-rig-type:\"Mixed\".\n");

if (!`objExists $objA` || !`objExists $objB`)
	return;

if (`isConnected $plugA $plugB`)
	{
	$wasConnected=1;
	disconnectAttr $plugA $plugB;
	}
else
	{
	connectAttr $plugA $plugB;
	dgdirty -a;
	}

setAttr ($nameSpace+"ctrlBox.ACtrlVis") (!$wasConnected);
setAttr ($nameSpace+"ctrlBox.BCtrlVis") (!$wasConnected);
setAttr ($nameSpace+"ctrlBox.CCtrlVis") (!$wasConnected);
setAttr ($nameSpace+"ctrlBox.RegionsCtrlVis") (!$wasConnected);
setAttr ($nameSpace+"ctrlBox.TeethCtrlVis") (!$wasConnected);
setAttr ($nameSpace+"ctrlBox.TongueCtrlVis") (!$wasConnected);

if ($wasConnected)
	print ("// Detached On-Face controllers.\n");
else
	print ("// Attached On-Face controllers.\n");
}

global proc int asHaveAnimation (string $node)
{
int $haveAnimation=0;
float $distAB,$distAC;
string $nodeType;
string $tempString[]=`listConnections -s 1 -d 0 $node`;

for ($i=0;$i<size($tempString);$i++)
	{
	$nodeType=`objectType $tempString[$i]`;
	if (`gmatch $nodeType "animCurve*"`)
		{
		$haveAnimation=1;
		break;
		}
	}
return $haveAnimation;
}

global proc asStraightenPoleVectors ()
{
float $pos[];
string $startJoint,$middleJoint,$endJoint;
string $tempString[];
string $sel[]=`ls -sl`;

if (`confirmDialog -t "Confirm"
	-m ("Knee & Elbow will be moved to make poleVector straight.")
	-b "OK" -b "Cancel" -db "Cancel"
	-ds "Cancel"`!="OK")
		return;

//Straighten Knee/Elbow
for ($i=0;$i<2;$i++)
	{
	if ($i==0)
		{
		$startJoint="Hip";
		$middleJoint="Knee";
		$endJoint="Ankle";
		}
	if ($i==1)
		{
		$startJoint="Shoulder";
		$middleJoint="Elbow";
		$endJoint="Wrist";
		}
	if (`objExists $startJoint` && `objExists $middleJoint` && `objExists $endJoint`)
		{
		print ("// Moving "+$middleJoint+" joint, to make a more straight IK poleVector.\n");
		if (`objExists TempLoc1`) delete TempLoc1;
		spaceLocator -n TempLoc1;
		asAlign TempLoc1 $startJoint 1 0 0 0;
		aimConstraint -offset 0 0 0 -weight 1 -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "vector" -worldUpVector 0 0 1 $endJoint TempLoc1;
		spaceLocator -n TempLoc2;
		parent TempLoc2 TempLoc1;
		asAlign TempLoc2 $middleJoint 1 0 0 0;
		setAttr TempLoc2.tz 0;
		$pos=`xform -q -ws -t TempLoc2`;
		delete TempLoc1;
		$tempString=`listRelatives -c $middleJoint`;
		parent -w $tempString[0];
		xform -ws -t $pos[0] $pos[1] $pos[2] $middleJoint;
		parent $tempString[0] $middleJoint;
		}
	}
print "// Knee & Elbow joints have been moved, to make poleVector straight.\n";
select $sel;
}

global proc asMLToolsUI ()
{
if (`window -q -ex asMLToolsUI`)
    deleteUI asMLToolsUI;
window -t "ML Tools" asMLToolsUI;
columnLayout;
	separator -h 25 -st none;
	text -l "For use with Machine Learning Deformers";
	separator -h 25 -st none;
/*
	text -l "New Base Model:";
	text -l "Select objects to deform, then:";
	rowLayout -nc 6;
		button -w 140 -l "+ Select DeformJoints" -c asSelectDeformJoints;
		separator -w 10 -st none;
		button -l "deselect slider-joints" -c "select -d `ls -type joint \"*Slider*\" \"*Partial*\"`";
		separator -w 10 -st none;
		button -w 140 -l "Set Smooth Bind Options" -c asSetSmoothBindOptions;
		setParent..;
	separator -h 20 -st none;
*/
	text -l "Training Animation:";
	button -w 140 -l "Set rig to all FK" -c ("asSetAllFK \"\"");
//	intFieldGrp -l "Training Frames:" -v1 5000 -cw2 90 60 asMLToolsTFIntFieldGrp;
	checkBox -v 1 -l "skip twist" asMLToolsSTcheckBox;
	button -w 140 -l "Apply Training Animation" -c asMLToolsATA;
	separator -h 20 -st none;
	button -l "Remove Training Animation" -c "asMCLRemoveBody \"\"";
showWindow;
}

global proc asMLToolsATA ()
{
int $t,$singleAxisNeg,$numChar;
int $skipTwist=`checkBox -q -v asMLToolsSTcheckBox`;
float $v;
string $side,$singleAxis,$mainAxis,$rotateCtrl,$extraCtrl;
string $sideCtrls[]={"FKKnee","FKElbow","FKHip","FKScapula","FKShoulder","FKWrist","FKAnkle"};
string $middleCtrls[]={"FKRoot","FKSpine1","FKChest","FKNeck","FKHead"};
string $ctrls[]=`stringArrayCatenate $sideCtrls $middleCtrls`;
string $xyz[]={"x","y","z","yx","zx"};//
	
for ($i=0;$i<size($ctrls);$i++)
	{
	$rotateCtrl=$ctrls[$i];
	$singleAxis="";
	$singleAxisNeg=0;
	if ($ctrls[$i]=="FKKnee") {$singleAxis="z";$singleAxisNeg=1;}
	if ($ctrls[$i]=="FKElbow") $singleAxis="z";
	$extraCtrl="FKExtra"+`substring $ctrls[$i] 3 99`;

	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1) $side="_R";
		else $side="_L";
		if (`stringArrayCount $ctrls[$i] $middleCtrls`)
			{
			if ($b== 1) $side="_M";
			if ($b==-1) continue;
			}
		if (!`objExists ($ctrls[$i]+$side)`)
			{
			print ("Controller not found:\""+$ctrls[$i]+$side+"\", skipping this\n");
			continue;
			}

		for ($z=0;$z<size($xyz);$z++)
			{
			$mainAxis=$xyz[$z];
			$mixAxis="";
			$numChar=size($xyz[$z]);
			if ($numChar==2)
				{
				$mainAxis=`substring $xyz[$z] 1 1`;
				if ($singleAxis=="")
					$mixAxis=`substring $xyz[$z] 2 2`;
				}

			if ($singleAxis!="" && $singleAxis!=$mainAxis)
				continue;
			if ($skipTwist && `gmatch $xyz[$z] "*x*"`)
				continue;


			for ($q=1;$q>-2;$q=$q-2)//pos/neg $mixAxis
				{
				if ($mixAxis=="" && $q==-1)
					continue;

				if ($mixAxis!="")
					{
					if ($q==1 && $z==3)
						setKeyframe -v 0       -t ($t-1) -itt linear -ott linear ($ctrls[$i]+$side+".r"+$mixAxis);
					setKeyframe -v (90*$q) -t $t     -itt linear -ott linear ($ctrls[$i]+$side+".r"+$mixAxis);
					setKeyframe -v (90*$q) -t ($t+7) -itt linear -ott linear ($ctrls[$i]+$side+".r"+$mixAxis);
					setKeyframe -v 0       -t ($t+8) -itt linear -ott linear ($ctrls[$i]+$side+".r"+$mixAxis);

					$rotateCtrl=$extraCtrl;
					}

				for ($p=1;$p>-2;$p=$p-2)//pos/neg
					{
					$v=0;
					if ($singleAxis!="")
						{
						if ($p== 1 &&  $singleAxisNeg) continue;
						if ($p==-1 && !$singleAxisNeg) continue;
						}

					setKeyframe -v $v -t $t -itt linear -ott linear ($rotateCtrl+$side+".r"+$mainAxis);
					if ($singleAxis!="")
						{
						$v=120*$p;
						$t+=4;
						}
					else
						{
						$v=90*$p;
						$t+=3;
						}
/*
					//special case FKHip.ry inwards
					if ($rotateCtrl=="FKHip" && $mainAxis=="y" && $p==1)
						{
						$v=30*$p;
						$t=$t-2;
						}
*/
					setKeyframe -v $v -t $t -itt linear -ott linear ($rotateCtrl+$side+".r"+$mainAxis);
					$t+=1;
					setKeyframe -v 0 -t $t -itt linear -ott linear ($rotateCtrl+$side+".r"+$mainAxis);
					}
				}
//			if ($z<size($xyz)-1)
//				$t=$t-1;//overLap on switchAxis
			}
//		if ($side=="_R")
//			$t=$t-1;//overLap on switchSide
		}
//	$t=$t-1;//overLap on switchCtrl
	}

if (`attributeExists w0 FKRoot_M`)
	setKeyframe -v 0 -t 0 -itt linear -ott linear FKRoot_M.w0;
playbackOptions -min 0 -ast 0 -max $t -aet $t;
currentTime 183;
refresh;
currentTime 0;
select -cl;
print "// Training Animation Applied.\n";
}

/* Old Random Pose Version
global proc asMLToolsATA ()
{
global string $gMainProgressBar;
float $min,$max;
float $end=`intFieldGrp -q -v1 asMLToolsTFIntFieldGrp`;
string $controlSetMembers[]=`sets -q ControlSet`;
string $xyz[];

//select -cl;
evalDeferred ("progressBar -e -ep "+$gMainProgressBar);
progressBar -e -st "Applying Training Animation" -bp -ii 1 -min 0 -max (size($controlSetMembers)) $gMainProgressBar;
playbackOptions -min 0 -ast 0 -max $end -aet $end;
for ($i=0;$i<size($controlSetMembers);$i++)
	{
	if (`progressBar -q -ic $gMainProgressBar`)
		break;
	progressBar -e -s 1 $gMainProgressBar;
	if (!`gmatch $controlSetMembers[$i] "FK*"`)
		continue;
	if (`gmatch $controlSetMembers[$i] "FKExtra*"` || `gmatch $controlSetMembers[$i] "FKIK*"`)
		continue;	
	$xyz={"x","y","z"};
	$min=-120;
	$max=120;
	if (`gmatch $controlSetMembers[$i] "FKElbow*"`)
		{
		$xyz={"z"};
		$min=0;
		$max=135;
		}
	if (`gmatch $controlSetMembers[$i] "FKKnee*"`)
		{
		$xyz={"z"};
		$min=-135;
		$max=0;
		}
	if (`gmatch $controlSetMembers[$i] "FK*Finger*"`)
		{
		$xyz={"y"};
		$min=-20;
		}
	for ($y=0;$y<$end+1;$y++)
		for ($z=0;$z<size($xyz);$z++)
			{
			if ($y==0)
				setKeyframe -v 0 -t 0 -itt stepnext -ott stepnext ($controlSetMembers[$i]+".r"+$xyz[$z]);
			else
				setKeyframe -v `rand $min $max` -t $y -itt stepnext -ott stepnext ($controlSetMembers[$i]+".r"+$xyz[$z]);
			}
	}
currentTime 1;
refresh;
currentTime 0;
}
*/
global proc asNameMatcherUI ()
{
asMappingUI nameMatcher "";
}

global proc asMoCapMatcherUI (string $uiName)
{
asMappingUI moCapMatcher $uiName;
}


global proc asMappingUI (string $tool, string $uiName)
{
int $cw=150;
int $sep=10;
string $name,$nameSpace,$autoDetecedApp;
string $tempString[];

if (`asHotKeyCheck ("asMappingUI "+$tool+" \"\"")`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
//if (!size($controlSets))
//	error "No controlSets detected. select a controller";

if (`window -q -ex asMappingUI`)
    deleteUI asMappingUI;
window -t $tool asMappingUI;
formLayout asMappingUIFormLayout;
scrollLayout asMappingUIScrollLayout;
columnLayout asMappingUIColumnLayout1;

frameLayout -p asMappingUIColumnLayout1 -w 320 -cll 1 -cl 1 -cc asFL -ec asFL -l "Templates" asMappingUITemplatesFrameLayout;
	columnLayout;
		rowLayout -nc 4 -cw4 10 25 200 100;
			separator -st none;
			text -l "files:";
			optionMenu -cc ("asMappingUIFileOptionMenuChanged "+$tool) asMappingUIFiles;
//			button -w 80 -l "New" -c asMappingUIClearAll;
			setParent..;
		rowLayout -nc 2 -cw2 40 200;
			separator -st none;
			text -en 0 -l "" -fn smallBoldLabelFont asMappingUIWWW;
			setParent..;
		separator -h 15 -st none;
		rowLayout -nc 3 -cw3 86 150 200;
			separator -st none;
			text -al right -l "save current configutation:";
			button -h 15 -w 80 -l "Export" -c ("asMappingUIExport "+$tool);
			setParent..;		

frameLayout -p asMappingUIColumnLayout1 -w 320 -cll 1 -cl 1 -cc asFL -ec asFL -l "Side" asMappingUISideFrameLayout;
	columnLayout;
		textFieldGrp -cw2 45 60 -l "Right:" -ed 1 -tx "Right" -cc asMappingUISideOptionChanged asMappingUISideRightTextFieldGrp;
		textFieldGrp -cw2 45 60 -l "Left:" -ed 1 -tx "Left" asMappingUISideLeftTextFieldGrp;
		textFieldGrp -cw2 45 60 -l "Middle:" -ed 1 -tx "" asMappingUISideMiddleTextFieldGrp;
		separator -st none -h 5;
		rowLayout -nc 2 -cw2 10 50;
			separator -st none;
			checkBox -l "%Side% before name" -v 1 -cc asMappingUISideOptionChanged asMappingUISideBeforeNameCheckBox;
			setParent..;
		rowLayout -nc 2 -cw2 10 50;
			separator -st none;
			checkBox -l "Use _ (underscore)" -cc asMappingUISideOptionChanged asMappingUISideUnderScoreCheckBox;
			setParent..;
		separator -h 10 -st none;
		rowLayout -nc 3 -cw3 10 100 100;
			separator -st none;
			text -l "Result example:";
			text -fn boldLabelFont -l "RightArm" asMappingUISideResultExampleText;

frameLayout -p asMappingUIColumnLayout1 -w 320 -cll 1 -cl 1 -cc asFL -ec asFL -l "Joints" asMappingUIJointsFrameLayout;
	formLayout asMappingUIJointsFormLayout;
		columnLayout -adj 1 asMappingUIJointsColumnLayout1;
			rowLayout -nc 3 -cw3 $cw $sep $cw;
				text -l "   AdvancedSkeleton:";
				text -l "|";
				text -l "   Other:";
				setParent..;
			separator -w ($cw*2);
			columnLayout asMappingUIJointsColumnLayout;
				setParent..;
			setParent..;

		columnLayout asMappingUIJointsColumnLayout2;
			separator -w 320 -h 10;
			separator -w 320 -h 5 -st none;
			rowLayout -nc 3 -cw3 10 80 80;
				separator -st none;
				button -l "Add joint" -c asMappingUIAddJoint;
				button -l "Clear all" -c asMappingUIClearAll;
				setParent..;

frameLayout -p asMappingUIColumnLayout1 -w 320 -cll 1 -cl 1 -cc asFL -ec asFL -l "NameSpaces" asMappingUINameSpacesFrameLayout;
	formLayout asMappingUINameSpacesFormLayout;
		columnLayout -adj 1 asMappingUINameSpacesColumnLayout1;
			rowLayout -nc 3 -cw3 $cw $sep $cw;
				text -l "   AdvancedSkeleton:";
				text -l "|";
				text -l "   Other:";
				setParent..;
			separator -w ($cw*2);
			columnLayout asMappingUINameSpacesColumnLayout;
				rowLayout -nc 3 -cw3 $cw $sep $cw;
					textField -w ($cw-$sep-10) asMappingUINameSpacesTextFieldA1;
					if ($nameSpace!="")
						textField -e -tx $nameSpace asMappingUINameSpacesTextFieldA1;
					text -l "|";
					textField -w ($cw-$sep-10) asMappingUINameSpacesTextFieldB1;
				setParent..;
				rowLayout -nc 3 -cw3 $cw $sep $cw;
					separator -st none;
					separator -st none;
					button -h 15 -l "detect from selected" -c asMoCapMatcherNameSpaceDetect;

frameLayout -m 1 -p asMappingUIColumnLayout1 -w 320 -cll 1 -cl 1 -cc asFL -ec asFL -l "TopNode" asMappingUITopNodeFrameLayout;
	formLayout;
		columnLayout -adj 1;
			rowLayout -nc 3 -cw3 $cw $sep $cw;
				text -l "   AdvancedSkeleton:";
				text -l "|";
				text -l "   Other:";
				setParent..;
			separator -w ($cw*2);
			columnLayout;
				rowLayout -nc 3 -cw3 $cw $sep $cw;
					textField -w ($cw-$sep-10) -tx "Group" -ed 0 asMappingUITopNodeTextFieldA1;
					text -l "|";
					textField -w ($cw-$sep-10) asMappingUITopNodeTextFieldB1;
				setParent..;

formLayout -e
	-ac asMappingUIJointsColumnLayout2 "top" 0 asMappingUIJointsColumnLayout1
	asMappingUIJointsFormLayout;

frameLayout -p asMappingUIColumnLayout1 -w 320 -cll 1 -cl 1 -cc asFL -ec asFL -l "Functions" asMappingUIFunctionsFrameLayout;
	columnLayout;
		if ($tool=="nameMatcher")
			{
//			rowLayout -adj 2 -nc 2 -cw2 80 150;
//				separator -st none;
				columnLayout;
					separator -st none -h 10;
					rowLayout -nc 2;
						separator -st none -w 80;
						button -w 150 -l "Check" -c asNameMatcherCheck;
						setParent..;
					separator -st none -h 5;
					rowLayout -nc 2;
						separator -st none -w 80;
						button -w 150 -l "Create + Place FitSkeleton" -c asNameMatcherCheckAndAutoRigFit;
						setParent..;
					separator -st none -h 5;
					rowLayout -nc 4;
						separator -st none -w 50;
						button -l "Show PoleVectors" -c asToggleFitDisplayPoleVector;
						separator -st none -w 10;
						button -l "Straighten PoleVectors" -c asStraightenPoleVectors;
						setParent..;
					separator -st none -h 5;
					rowLayout -nc 2;
						separator -st none -w 80;
						button -w 150 -l "Build AdvancedSkeleton;" -c asReBuildAdvancedSkeleton;
						setParent..;
					separator -st none -h 20;
					rowLayout -nc 2;
						separator -st none -w 80;
						columnLayout;
							button -w 150 -l "Constraint to Joints" -c "asMappingUIFunction AutoRigConstraint";
							text -l "\t\t\tOR:";
							button -w 150 -l "Transfer Skinning" -c "asMappingUIFunction AutoRigTransferSkinning";
							if (size(`ls -type blendShape`))
								{
								separator -st none -h 20;
								button -w 150 -l "Create BlendShapes Control" -c "asMappingUIFunction CreateBSControl";
								}

			}
		if ($tool=="moCapMatcher")
			{
			separator -st none -h 10;
			rowLayout -adj 2 -nc 2 -cw2 80 150;
				separator -st none;
				columnLayout;
					text -l "1: Import MoCap-skeleton.";
					separator -st none -h 10;
					text -l "2: Select MoCap-skeleton";
					button -w 150 -l "Scan MoCap-skeleton" -c asMoCapMatcherScan;
					separator -st none -h 10;
					text -al "left" -l "3: Scale the MoCap-skeleton,\n    to match your character.";
					separator -st none -h 10;
					text -al "left" -l "4: Go to start of animation,\n    and `zero-out` MoCap-joints.";
					button -w 150 -l "`zero-out` MoCap-joints" -c "asMappingUIFunction MoCapZeroOut";
					text -al "left" -l "And align skeletons (if needed)";
					separator -st none -h 10;
/*
					rowLayout -nc 2 -cw2 100 10;
						checkBox -v 1 -l "use IK-Feet" asMappingUIIKFeetCheckBox;
						text -l "Or:";
						setParent..;
					button -w 150 -l "Set rig to all FK" -c ("asSetAllFK \""+$nameSpace+"\"");
					separator -st none -h 10;
*/
					rowLayout -nc 2 -cw2 160 10;
						button -w 150 -l "Connect MoCap Skeleton" -c "asMappingUIFunction MoCapConnect";
						checkBox -l "Extra" asMappingUIExtraCheckBox;
						setParent..;
					button -w 150 -l "Disconnect MoCap Skeleton" -c asMoCapMatcherDisconnect;
					button -w 150 -l "Bake" -c asMoCapMatcherBake;
//					button -w 150 -l "IKBake" -c ("asMoCapMatcherIKBake "+$uiName);
			}

formLayout -e
	-af asMappingUIScrollLayout "top" 0
	-af asMappingUIScrollLayout "bottom" 0
	-af asMappingUIScrollLayout "left" 0
	-af asMappingUIScrollLayout "right" 0
asMappingUIFormLayout;

showWindow;

//populate $tool`s optionMenu
string $asScriptLocation=`asGetScriptLocationFromSelector`;
string $toolDir=$asScriptLocation+"/AdvancedSkeletonFiles/"+$tool+"s/";
string $toolFiles[]=`getFileList -fs "*.txt" -fld $toolDir`;
setParent -menu asMappingUIFiles;
for ($i=0;$i<size($toolFiles);$i++)
	{
	if (`gmatch $toolFiles[$i] "[.]*"` || $toolFiles[$i]=="incrementalSave")
		continue;
	tokenize $toolFiles[$i] "." $tempString;
	$name=$tempString[0];
	menuItem -l $name;
	}
//defaults to "MotionBuilder"
if (`stringArrayCount "MotionBuilder.txt" $toolFiles`)
	optionMenu -e -v MotionBuilder asMappingUIFiles;
menuItem -l "*New";

//update UI from optionVars
string $framLayouts[]=`lsUI -type frameLayout`;
for ($i=0;$i<size($framLayouts);$i++)
	if (`gmatch $framLayouts[$i] "asMappingUI*FrameLayout"`)
		if (`optionVar -ex $framLayouts[$i]`)
			frameLayout -e -cl `optionVar -q $framLayouts[$i]` $framLayouts[$i];

//auto-guess source App from scene nodes
$autoDetecedApp=`asAutoDetecedApp`;
if (size(`ls -r 1 "mixamorig:*"`))
	textField -e -tx "mixamorig" asMappingUINameSpacesTextFieldB1;

if ($autoDetecedApp!="")
	catchQuiet(`optionMenu -e -v $autoDetecedApp asMappingUIFiles`);

//if "NameMatcher" nameSpace exists, it means NameMatcher has already ran, so restore this.
if (`namespace -ex NameMatcher`)
	textField -e -tx NameMatcher asMappingUINameSpacesTextFieldB1;

asMappingUIFileOptionMenuChanged $tool;
}

global proc string asAutoDetecedApp ()
{
string $autoDetecedApp;

if (size(`ls -r 1 |master`)) $autoDetecedApp="AutodeskCharacterGenerator";
if (size(`ls -r 1 Hips`) && size(`ls -r 1 RightUpLeg`) && size(`ls -r 1 RightForeArm`)) $autoDetecedApp="AutodeskCharacterGenerator";
if (size(`ls -r 1 "*BoneRoot"`)) $autoDetecedApp="CharacterCreator";
if (size(`ls -r 1 "*BoneRoot"`) && size(`ls -r 1 "*_Thumb1"`)) $autoDetecedApp="CharacterCreator3";
if (size(`ls -r 1 "*BoneRoot"`) && size(`ls -r 1 "*_Thumb1"`) && size(`ls -r 1 "*_BigToe1"`)) $autoDetecedApp="CharacterCreator4";
if (size(`ls -r 1 ik_foot_root`)) $autoDetecedApp="Unreal";
if (size(`ls -r 1 ik_foot_root`) && size(`ls -r 1 spine_05`)) $autoDetecedApp="Unreal5";
if (size(`ls -r 1 Abdomen`)) $autoDetecedApp="Poser";
if (size(`ls -r 1 abdomenLower`)) $autoDetecedApp="Daz3d";
if (size(`ls -r 1 RightFinger5Proximal`)) $autoDetecedApp="Rokoko";
//if (size(`ls -r 1 wrist_inner_l`)) $autoDetecedApp="MetaHumanFBX";//MetaHuman from Unreal>FbxExport
//Removed in v6.2616, since this means Unreal5 get wrongly detected as MetaHuman
if (size(`ls -r 1 wrist_inner_l`)) $autoDetecedApp="MetaHuman";
if (size(`ls -r 1 wrist_innerOff_l_drv`)) $autoDetecedApp="MetaHuman_old";
if (size(`ls -r 1 Armature`)) $autoDetecedApp="ReadyPlayerMe";
if (size(`ls -r 1 "mixamorig:*"`)) $autoDetecedApp="Mixamo";

return $autoDetecedApp;
}

global proc asMappingUIFileOptionMenuChanged (string $tool)
{
string $text="";
string $file=`optionMenu -q -v asMappingUIFiles`;
if ($file=="AutodeskCharacterGenerator") $text="charactergenerator.autodesk.com";
if ($file=="CharacterCreator") $text="www.reallusion.com/character-creator";
if ($file=="Daz3d") $text="www.daz3d.com";
if ($file=="DeepMotion") $text="www.deepmotion.com";
if ($file=="iPiSoft") $text="www.ipisoft.com";
if ($file=="Mixamo") $text="www.mixamo.com";
if ($file=="MotionBuilder") $text="www.autodesk.com";
if ($file=="MotionMaker") $text="www.autodesk.com";
if ($file=="Plask") $text="app.plask.ai";
if ($file=="Poser") $text="smithmicro.com/poser";
if ($file=="Unreal") $text="www.unrealengine.com";
if ($file=="Rokoko") $text="www.rokoko.com";
if ($file=="ReadyPlayerMe") $text="readyplayer.me";

text -e -l $text asMappingUIWWW;

asMappingUIClearAll;
if ($file!="*New")
	asMappingUILoad $tool;
}

global proc asMappingUISideOptionChanged ()
{
string $joint="Arm";
string $side=`textFieldGrp -q -tx asMappingUISideRightTextFieldGrp`;
string $underS="";
if (`checkBox -q -v asMappingUISideUnderScoreCheckBox`)
	$underS="_";
string $text=$text=$joint+$underS+$side;
if (`checkBox -q -v asMappingUISideBeforeNameCheckBox`)
	$text=$side+$underS+$joint;
text -e -l $text asMappingUISideResultExampleText;
}

global proc asMappingUIAddJoint ()
{
int $cw=150;
int $sep=10;
string $rowLayouts[]=`columnLayout -q -ca asMappingUIJointsColumnLayout`;
int $nr=size($rowLayouts)+1;

setParent asMappingUIJointsColumnLayout;
rowLayout -nc 3 -cw3 $cw $sep $cw ("asMappingUIJointsRowLayout"+$nr);
	textField -w ($cw-$sep-10) ("asMappingUIJointsTextFieldA"+$nr);
	text -l "|";
	textField -w ($cw-$sep-10) ("asMappingUIJointsTextFieldB"+$nr);
}

global proc asMappingUIClearAll ()
{
string $rowLayouts[]=`columnLayout -q -ca asMappingUIJointsColumnLayout`;
for ($i=0;$i<size($rowLayouts);$i++)
	deleteUI $rowLayouts[$i];

textFieldGrp -e -tx "Right" asMappingUISideRightTextFieldGrp;
textFieldGrp -e -tx "Left"  asMappingUISideLeftTextFieldGrp;
textFieldGrp -e -tx "" 			asMappingUISideMiddleTextFieldGrp;
checkBox -e -v 1 asMappingUISideBeforeNameCheckBox;
checkBox -e -v 0 asMappingUISideUnderScoreCheckBox;
}

global proc asMappingUILoad (string $tool)
{
int $section=1;
int $nr=1;
string $line,$para,$value;
string $asScriptLocation=`asGetScriptLocationFromSelector`;
string $file=$asScriptLocation+"/AdvancedSkeletonFiles/"+$tool+"s/"+`optionMenu -q -v asMappingUIFiles`+".txt";
string $tempString[];

if (!`file -q -ex $file`)
	error ("Unable to find the file:\""+$file+"\".\n");

print ("// Loading:\""+$file+"\".\n");
asMappingUIClearAll;
int $fileId=`fopen $file "r"`;
string $nextLine = `fgetline $fileId`;
while (size($nextLine)>0)
	{
	$line=`strip $nextLine`;
	tokenize $line "=" $tempString;
	$para=$tempString[0];
	$value=$tempString[1];

	if ($para=="sideRight")
		textFieldGrp -e -tx $value asMappingUISideRightTextFieldGrp;
	if ($para=="sideLeft")
		textFieldGrp -e -tx $value asMappingUISideLeftTextFieldGrp;
	if ($para=="sideMiddle")
		textFieldGrp -e -tx $value asMappingUISideMiddleTextFieldGrp;
	if ($para=="sideBeforeName")
		eval ("checkBox -e -v "+$value+" asMappingUISideBeforeNameCheckBox");
	if ($para=="sideUnderScore")
		eval ("checkBox -e -v "+$value+" asMappingUISideUnderScoreCheckBox");


	if ($section==2)
		{
		if ($para=="")
			{
			$nextLine=`fgetline $fileId`;
			continue;
			}

		asMappingUIAddJoint;
		textField -e -tx $para ("asMappingUIJointsTextFieldA"+$nr);
		textField -e -tx $value ("asMappingUIJointsTextFieldB"+$nr);
		$nr++;
		}

	if ($para=="" && $value=="")
		$section++;
	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;
asMappingUISideOptionChanged;
}

global proc asMappingUIExport (string $tool)
{
string $fDet,$a,$b;
string $asScriptLocation=`asGetScriptLocationFromSelector`;
string $tempString[],$existingMenuItems[],$existingFiles[];

string $return[] = `fileDialog2 -fileFilter "*.txt" -dialogStyle 2 -dir ($asScriptLocation+"/AdvancedSkeletonFiles/"+$tool+"s/")`;
string $file=$return[0];
if ($file=="")
	return;

$fDet+="sideRight="+`textFieldGrp -q -tx asMappingUISideRightTextFieldGrp`+"\n";
$fDet+="sideLeft="+`textFieldGrp -q -tx asMappingUISideLeftTextFieldGrp`+"\n";
$fDet+="sideMiddle="+`textFieldGrp -q -tx asMappingUISideMiddleTextFieldGrp`+"\n";
$fDet+="sideBeforeName="+`checkBox -q -v asMappingUISideBeforeNameCheckBox`+"\n";
$fDet+="sideUnderScore="+`checkBox -q -v asMappingUISideUnderScoreCheckBox`+"\n";
$fDet+="\n";
for ($nr=1;$nr<999;$nr++)
	{
	if (!`rowLayout -q -ex ("asMappingUIJointsRowLayout"+$nr)`)
		break;
	$a=`textField -q -tx ("asMappingUIJointsTextFieldA"+$nr)`;
	$b=`textField -q -tx ("asMappingUIJointsTextFieldB"+$nr)`;
	$fDet+=$a+"="+$b+"\n";
	}

int $fileId=`fopen $file "w"`;
fprint $fileId $fDet;
fclose $fileId;

tokenize $return[0] "/" $tempString;
tokenize $tempString[size($tempString)-1] "." $tempString;

$existingMenuItems=`optionMenu -q -ill asMappingUIFiles`;
for ($i=0;$i<size($existingMenuItems);$i++)
	$existingFiles[$i]=`menuItem -q -l $existingMenuItems[$i]`;
if (!`stringArrayCount $tempString[0] $existingFiles`)
	{
	setParent -menu asMappingUIFiles;
	menuItem -l $tempString[0];
	optionMenu -e -v $tempString[0] asMappingUIFiles;
	}
}

global proc int asNameMatcherCheck ()
{
int $sideBeforeName=`checkBox -q -v asMappingUISideBeforeNameCheckBox`;
int $sideUnderScore=`checkBox -q -v asMappingUISideUnderScoreCheckBox`;
int $defaultXform,$plugNr,$firstAlert,$isMetaHuman;
float $value,$defaultValue;
float $currentTime=`currentTime -q`;
float $posA[],$posB[],$m[], $m1[],$m2[];
string $sideMiddle=`textFieldGrp -q -tx asMappingUISideMiddleTextFieldGrp`;
string $msg,$otherTopNode,$bResolved,$underS,$b,$obj,$skinCluster,$joint,$dialog,$tg;
string $nonDefaultXformObjs[],$historyNodes[],$topLevXforms[],$topLevelMeshObjs[];
string $nameSpaceB=`textField -q -tx asMappingUINameSpacesTextFieldB1`;
string $tempString[],$tempString2[],$tempString3[],$tempString4[],$allReservedNames[],$clashingNames[];
string $trs[]={"t","r","s"};
string $xyz[]={"x","y","z"};
string $reservedNames[]={"Root","Spine1","Spine2","Chest","Scapula","Shoulder","Elbow","Wrist","Cup",
	"ThumbFinger1","ThumbFinger2","ThumbFinger3","ThumbFinger4",
	"IndexFinger1","IndexFinger2","IndexFinger3","IndexFinger4",
	"MiddleFinger1","MiddleFinger2","MiddleFinger3","MiddleFinger4",
	"RingFinger1","RingFinger2","RingFinger3","RingFinger4",
	"PinkyFinger1","PinkyFinger2","PinkyFinger3","PinkyFinger4",
	"Neck","Head","HeadEnd","Eye","EyeEnd","Jaw","JawEnd",
	"Hip","Knee","Ankle","Toes","ToesEnd"};

for ($i=0;$i<size($reservedNames);$i++)
	for ($p=0;$p<3;$p++)
		{
		if ($p==0) $part="";
		if ($p==1) $part="Part1";
		if ($p==2) $part="Part2";
		$allReservedNames[size($allReservedNames)]=$reservedNames[$i]+$part;
		}

//find $otherTopNode
for ($nr=1;$nr<999;$nr++)
	{
	if (!`rowLayout -q -ex ("asMappingUIJointsRowLayout"+$nr)`)
		break;
	$b=`textField -q -tx ("asMappingUIJointsTextFieldB"+$nr)`;
	$bResolved=$b;
	if ($nameSpaceB!="")
		$bResolved=$nameSpaceB+":"+$b;
	$tempString=`ls $bResolved`;
	if (size($tempString)!=1)
		continue;
	$tempString=`ls -l $bResolved`;
	tokenize $tempString[0] "|" $tempString;
	if ($tempString[0]!="FitSkeleton")
		{
		$otherTopNode=`substitute ($nameSpaceB+":") $tempString[0] ""`;
		break;
		}
	}

//find $otherTopNode. part2, migh require sidePrefix (checking for middle only)
if ($otherTopNode=="")
	for ($nr=1;$nr<999;$nr++)
		{
		if (!`rowLayout -q -ex ("asMappingUIJointsRowLayout"+$nr)`)
			break;
		$b=`textField -q -tx ("asMappingUIJointsTextFieldB"+$nr)`;
		$underS="";
		if ($sideUnderScore)
			$underS="_";
		if ($sideBeforeName)
			$bResolved=$nameSpaceB+":"+$sideMiddle+$underS+$b;
		else
			$bResolved=$nameSpaceB+":"+$b+$underS+$sideMiddle;
		$tempString=`ls $bResolved`;
		if (size($tempString)!=1)
			continue;
		$tempString=`ls -l $bResolved`;
		tokenize $tempString[0] "|" $tempString;
//		$otherTopNode="|"+$tempString[0];
		$otherTopNode=$tempString[0];
		$otherTopNode=`substitute ($nameSpaceB+":") $tempString[0] ""`;
		break;
		}
if (`gmatch $otherTopNode "NameMatcher:*"`)
	$otherTopNode=`substitute "NameMatcher:" $otherTopNode ""`;
textField -e -tx $otherTopNode asMappingUITopNodeTextFieldB1;

if ($otherTopNode=="")
	error ("Unable to find Top-Node of the \"Other\" Skeleton,\n"
		+"Possible reasones:\n"
		+"-No joints in the list in the \"joints\" section.\n"
		+"-None of the joints in the list have unique names, meaning they have same name as other objects in the scene.\n");

//group geo
$topLevXforms=`ls -as -l`;
for ($i=0;$i<size($topLevXforms);$i++)
	{
	$tempString=`listRelatives -ni -s -f $topLevXforms[$i]`;
	if ($tempString[0]=="")
		continue;
	if (`objectType $tempString[0]`!="mesh")
		continue;
	$topLevelMeshObjs[size($topLevelMeshObjs)]=$topLevXforms[$i];
	}
if (size($topLevelMeshObjs) && !`objExists geo` && !`objExists Hi`)
	{
	$dialog=`confirmDialog -t "Confirm"
			-m ("Found: "+size($topLevelMeshObjs)+" TopLevel Geomtry objects,\nThese should be grouped as the model.\n")
			-b "OK" -b "Skip" -b "Cancel" -db "OK"`;
	if ($dialog=="Cancel") return 0;
	if ($dialog=="OK")
		{
		createNode -n geo transform;
		parent $topLevelMeshObjs geo;
		createDisplayLayer -name Hi;
//		setAttr Hi.displayType 1;
		editDisplayLayerMembers -noRecurse Hi geo;
		select -cl;
		}
	}

/*
//Remove any animation that might be on joints (iclone seem to have test-animation by default)
//ensure we keep Start-Pose:
$tempString=`ls -type joint -type blendShape`;
for ($i=0;$i<size($tempString);$i++)
	{
	$tempString2=`listConnections -type animCurve -s 1 -d 0 $tempString[$i]`;
	for ($y=0;$y<size($tempString2);$y++)
		$testAnimations[size($testAnimations)]=$tempString2[$y];
	}
if (size($testAnimations))
	{
	currentTime -1;
	refresh;
	$dialog=`confirmDialog -t "Confirm"
			-m ("Found: "+size($testAnimations)+" AnimationCurves,\nthat are propably test-animation from external skeleton,\nThese should be removed.\n")
			-b "OK" -b "Skip" -b "Cancel" -db "OK"`;
	if ($dialog=="Cancel") return 0;
	if ($dialog=="OK")
		{
		delete $testAnimations;
		currentTime $currentTime;
		}
	}
*/
//remove all blendshape anim (iclone seem to have test-animation by default)
$tempString=`ls -type blendShape`;
for ($i=0;$i<size($tempString);$i++)
	{
	$tempString2=`listConnections -type animCurve -s 1 -d 0 $tempString[$i]`;
	if (size($tempString2))
		delete $tempString2;
	}

for ($i=0;$i<size($allReservedNames);$i++)
	{
	if (`objExists $allReservedNames[$i]`)
		{
		$tempString=`ls -l $allReservedNames[$i]`;
		if (`gmatch $tempString[0] "*FitSkeleton*"`)
			continue;
		$clashingNames[size($clashingNames)]=$allReservedNames[$i];
		}
	}
if (size($clashingNames))
	{
	$msg="Clashing Names Detected\n\n"
			+"Names that AdvancedSkeleton needs to use,\n"
			+"are detected in the external skeleton.\n\n"
			+"To proceed, a NameSpace will be added \n"
			+"to the external skeleton, to avoid the name-clashes\n\n"
			+"The clashing names are:\n";
	for ($i=0;$i<size($clashingNames);$i++)
		{
		$msg+=$clashingNames[$i]+"\n";
		if ($i>10)
			{
			$msg+="\n..and "+(size($clashingNames)-10)+" more\n";
			break;
			}
		}
	$dialog=`confirmDialog -t "Confirm"
		-m $msg
		-b "OK" -b "Skip" -b "Cancel" -db "OK"`;
	if ($dialog=="Cancel") return 0;
	if ($dialog=="OK")
		{
		//Adding NameSpace to OtherSkeleton
		if (!`namespace -ex NameMatcher`)
			namespace -addNamespace NameMatcher;
		namespace -setNamespace NameMatcher;
		$tempString=`listRelatives -f -ad -type transform $otherTopNode`;
		$tempString2=`listRelatives -ad -type transform $otherTopNode`;
		$tempString[size($tempString)]=$otherTopNode;
		$tempString2[size($tempString2)]=$otherTopNode;
		for ($i=0;$i<size($tempString);$i++)
			{
			rename $tempString[$i] ("TEMP_"+$tempString2[$i]);
			rename ("NameMatcher:TEMP_"+$tempString2[$i]) $tempString2[$i];
			}
		namespace -setNamespace ":";
		$nameSpaceB="NameMatcher";
		if (`textField -q -ex asMappingUINameSpacesTextFieldB1`)
			textField -e -tx $nameSpaceB asMappingUINameSpacesTextFieldB1;
	//	$otherTopNode="NameMatcher:"+$otherTopNode;
		}
	}

//Y-Up
if (`upAxis -q -ax`=="z")
	if (`confirmDialog -t "Confirm"
					-m "Z-Up Axis Settings detected.\nIt is Highly recommended to use Y-Up\nSwitch to Y-Up ?"
					-b "OK" -b "Skip" -db "OK"`=="OK")
						upAxis -ax y;

if (`getAttr top.rx`>-89)
	if (`confirmDialog -t "Confirm"
					-m "Z-Up Camera Values detected.\n\nSwitch to Y-Up Camera Values ?"
					-b "OK" -b "Skip" -db "OK"`=="OK")
		{
		setAttr top.r   -type float3 -90 0 0;
		setAttr front.r -type float3 0 0 0;
		setAttr side.r  -type float3 0 90 0;
		setAttr persp.r -type float3 -27 45 0;
		xform -piv 0 0 0 persp;
		setNamedPanelLayout "Four View";
		FrameAllInAllViews;
		}

/*
if (`objExists head_drv` && `objExists root_drv`)
	{
	$isMetaHuman=1;
	$posA=`xform -q -ws -t head_drv`;
	if ($posA[2]>$posA[1])
			if (`confirmDialog -t "Confirm"
					-m "Rotate character to Y-up ?"
					-b "OK" -b "Skip" -db "OK"`=="OK")
				{
				setAttr root_drv.rx -90;
				FrameAllInAllViews;
				if (`objExists headRig_grp`)
					setAttr headRig_grp.rx -90;

				createNode -n tempTransform transform;
				setAttr tempTransform.rx -90;
				$m=`getAttr tempTransform.matrix`;
				delete tempTransform;
				$tempString=`ls -type mesh`;
				for ($i=0;$i<size($tempString);$i++)
					{
					if (!`getAttr ($tempString[$i]+".intermediateObject")`)
						continue;
					$tempString2=`listRelatives -p $tempString[$i]`;
					$obj=$tempString2[0];
					xform -piv 0 0 0 $obj;
					$skinCluster=`findRelatedSkinCluster $obj`;
					if ($skinCluster=="")
						continue; 
					$tg=`createNode -n asResetTransform transformGeometry`;
					$tempString2=`listConnections -s 1 -d 0 ($tempString[$i]+".inMesh")`;
					if ($tempString2[0]!="")
						continue;
					$tempString2=`listConnections -s 0 -d 1 -p 1 ($tempString[$i]+".worldMesh")`;
					connectAttr ($tempString[$i]+".worldMesh") ($tg+".inputGeometry");
					if ($tempString2[0]=="")
						continue;
					connectAttr -f ($tg+".outputGeometry") $tempString2[0];
					setAttr ($tg+".transform") -type "matrix"
						$m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
					freezeSkinCluster $skinCluster;
					}
				}
	}
*/
if (`objExists CTRL_faceGUIfollowHead`)
	$isMetaHuman=1;

//"Go to BindPose" (by bindPreMatrix)
$firstAlert=1;
if ($nameSpaceB!="" && `objExists ($nameSpaceB+":"+$otherTopNode)`)
	$otherTopNode=$nameSpaceB+":"+$otherTopNode;
$tempString=`listRelatives -ad -type joint $otherTopNode`;
if (`nodeType $otherTopNode`=="joint") $tempString[size($tempString)]=$otherTopNode;
for ($i=size($tempString)-1;$i>-1;$i--)
	{
	if ($isMetaHuman)
		continue;
	$joint=$tempString[$i];
	if (!`attributeExists bindPose $joint`)
		continue;
	$m1=`getAttr ($joint+".bindPose")`;
	if (`size($m1)`!=16)
		continue;
	$m2=`getAttr ($joint+".matrix")`;
	if ($m1[0]!=$m2[0] || $m1[1]!=$m2[1] || $m1[2]!=$m2[2] || $m1[3]!=$m2[3] || $m1[4]!=$m2[4] || $m1[5]!=$m2[5] || $m1[6]!=$m2[6] || $m1[7]!=$m2[7]
	 || $m1[8]!=$m2[8] || $m1[9]!=$m2[9] || $m1[10]!=$m2[10] || $m1[11]!=$m2[11] || $m1[12]!=$m2[12] || $m1[13]!=$m2[13] || $m1[14]!=$m2[14] || $m1[15]!=$m2[15])
			{
			if ($firstAlert)
				{
				$dialog=`confirmDialog -t "Confirm"
					-m "detected joint that are Not in Bind Pose,\n\nReset joints to Bind-Pose ?"
					-b "OK" -b "Skip" -b "Cancel" -db "OK"`;
				if ($dialog=="Cancel") return 0;
				if ($dialog=="Skip")   {$i=0;break;}
				$firstAlert=0;
				}
			xform -ws -m $m1[0] $m1[1] $m1[2] $m1[3] $m1[4] $m1[5] $m1[6] $m1[7] $m1[8] $m1[9] $m1[10] $m1[11] $m1[12] $m1[13] $m1[14] $m1[15] $joint;
			}
	}
refresh;
/*
getAttr skinCluster1.bindPreMatrix[0];
getAttr skinCluster1.matrix[0];
float $m1[]=`getAttr skinCluster1.bindPreMatrix[0]`
xform -m $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
*/

//Detect any Skinned Object with Non-Default Transform, for Freezing. e.g. imported from CC4
$tempString=`ls -ni -l -type mesh`;
for ($i=0;$i<size($tempString);$i++)
	{
	$tempString2=`listRelatives -p $tempString[$i]`;
	$obj=$tempString2[0];
	$skinCluster=`findRelatedSkinCluster $tempString[$i]`;//must use findRelatedSkinCluster and not asGetSkinCluster
	if ($skinCluster=="")
		continue;
	$defaultXform=1;
	for ($y=0;$y<size($trs);$y++)
		{
		if ($y==2) $defaultValue=1;
		else $defaultValue=0;
		for ($z=0;$z<size($xyz);$z++)
			{
			$value=`getAttr ($obj+"."+$trs[$y]+$xyz[$z])`;
			if ($value!=$defaultValue)
				$defaultXform=0;
			}
		}
	if (!$defaultXform)
		$nonDefaultXformObjs[size($nonDefaultXformObjs)]=$obj;
	}
if (size($nonDefaultXformObjs))
	$dialog=`confirmDialog -t "Reset Transforms ?"
		-m (size($nonDefaultXformObjs)+" Skinned Objects with Non Default Transform Values detected.\nReset Transforms ?")
		-b "OK" -b "Skip" -b "Cancel" -db "OK"`;
	if ($dialog=="Cancel") return 0;
	if ($dialog=="OK")
		for ($i=0;$i<size($nonDefaultXformObjs);$i++)
			{
			$tempString=`listConnections -s 1 -d 0 -type animCurve $nonDefaultXformObjs[$i]`;
			if (size($tempString))
				delete $tempString;
			if (!`referenceQuery -isNodeReferenced $nonDefaultXformObjs[$i]`)
				asLockAttr $nonDefaultXformObjs[$i] 0 0 0 0;
			makeIdentity -a 1 -t 1 -r 1 -s 1 $nonDefaultXformObjs[$i];
			for ($y=0;$y<size($trs);$y++)
				for ($z=0;$z<size($xyz);$z++)
					setAttr -l 1 ($nonDefaultXformObjs[$i]+"."+$trs[$y]+$xyz[$z]);
			$historyNodes=`listHistory -future 0 -leaf 1 -il 1 -pdo 1 $nonDefaultXformObjs[$i]`;
			for ($y=0;$y<size($historyNodes);$y++)
				if (`objectType $historyNodes[$y]`=="transformGeometry")
					rename $historyNodes[$y] asResetTransform;
			}

print ("// NameMatcher Check completed.\n");
return 1;
}

global proc int asNameMatcherCheckAndAutoRigFit ()
{
int $isMiddleJoint,$numChilJoInts,$maxNumChildJoints,$numMissing;
int $sideBeforeName=`checkBox -q -v asMappingUISideBeforeNameCheckBox`;
int $sideUnderScore=`checkBox -q -v asMappingUISideUnderScoreCheckBox`;
float $scale,$maxY,$maxZ;
float $pos[];
textField -e -ebg 1 asMappingUIJointsTextFieldA1;
float $bgc[]=`textField -q -bgc asMappingUIJointsTextFieldA1`;
textField -e -ebg 0 asMappingUIJointsTextFieldA1;
frameLayout -e -ebg 1 asMappingUITemplatesFrameLayout;
float $bgc2[]=`frameLayout -q -bgc asMappingUITemplatesFrameLayout`;
frameLayout -e -ebg 0 asMappingUITemplatesFrameLayout;
string $a,$b,$aLong,$bResolved,$otherTopNode,$underS,$bs,$suffix,$part,$longHipToKeep,$baseName,$finger,$nameSpaceB,$tPoseTarget,$upAxisDirection;
string $sideRight=`textFieldGrp -q -tx asMappingUISideRightTextFieldGrp`;
string $sideLeft=`textFieldGrp -q -tx asMappingUISideLeftTextFieldGrp`;
string $sideMiddle=`textFieldGrp -q -tx asMappingUISideMiddleTextFieldGrp`;
string $file=`optionMenu -q -v asMappingUIFiles`;
string $templateMaFile=`asGetScriptLocation`+"/AdvancedSkeletonFiles/nameMatchers/"+$file+".ma";
string $tempString[],$tempString2[],$tempString3[],$tempString4[],$tempString5[],$fitJoints[],$placedJoints[];
string $fingers[]={"Thumb","Index","Middle","Ring","Pinky"};


if (!`asNameMatcherCheck`)
	return 0;

$upAxisDirection=`upAxis -q -ax`;//run here as this could have changed within above `asNameMatcherCheck` proc
$nameSpaceB=`textField -q -tx asMappingUINameSpacesTextFieldB1`;
$otherTopNode=`textField -q -tx asMappingUITopNodeTextFieldB1`;
if ($nameSpaceB!="" && `objExists ($nameSpaceB+":"+$otherTopNode)`)
	$otherTopNode=$nameSpaceB+":"+$otherTopNode;

//remove existing FitSkeleton
if (`objExists |FitSkeleton`)
	delete |FitSkeleton;

//resolve Daz non-unique names
$longHipToKeep="hip";
$tempString=`ls hip`;
if (size($tempString)>1)
	{
	warning "Found multiple objects called \"hip\", this is probably a export from DAZ, now attemting to merge all the DAZ skeletons..";
	for ($i=0;$i<size($tempString);$i++)
		{
		$tempString2=`listRelatives -ad -c $tempString[$i]`;
		$numChilJoints=size($tempString2);
		if ($numChilJoints>$maxNumChildJoints)
			{
			$longHipToKeep=$tempString[$i];
			$maxNumChildJoints=$numChilJoints;
			}
		}
	}
//rename to unique names
for ($i=0;$i<size($tempString);$i++)
	{
	if ($tempString[$i]==$longHipToKeep)
		continue;
	$tempString2=`listRelatives -p $tempString[$i]`;
	$baseName=$tempString2[0];
	$tempString2=`listRelatives -ad -c -f $baseName`;
	$tempString3=`listRelatives -ad -c $baseName`;
	$tempString4=`listRelatives -ad -c -f $longHipToKeep`;
	$tempString5=`listRelatives -ad -c $longHipToKeep`;
	for ($y=0;$y<size($tempString2);$y++)
		{
		rename $tempString2[$y] ($baseName+"_"+$tempString3[$y]);
		for ($z=0;$z<size($tempString5);$z++)//constraint to `keepJoint`
			if ($tempString5[$z]==$tempString3[$y])
				{
				parentConstraint $tempString4[$z] ($baseName+"_"+$tempString3[$y]);
				scaleConstraint $tempString4[$z] ($baseName+"_"+$tempString3[$y]);
				}
		}
	}

//turning Off "segmentScaleCompensate" for all joints, for better scale behaviour
$tempString=`ls -type joint`;
for ($i=0;$i<size($tempString);$i++)
	setAttr ($tempString[$i]+".segmentScaleCompensate") 0;



if (!`optionMenu -q -ex asFitFiles`)
	AdvancedSkeleton;

//if a .ma file matching the templateName exists, we assume this to be used as FitSkeleton
createNode -n FitSkeletonNameMatcherImporting transform;
if (`file -q -ex $templateMaFile`)
	{
	print ("// Detected custom FitSkeleton for NameMatcher template, using this instead of default biped. (\""+$templateMaFile+"\")\n");
	createNode -n FitSkeletonOverride transform;
	addAttr -ln fitSkeletonFile -dt "string" FitSkeletonOverride;
	setAttr -type "string" FitSkeletonOverride.fitSkeletonFile $templateMaFile;
	asFitSkeletonImport;
	delete FitSkeletonOverride;
	if (`attributeExists fitSkeletonTemplate FitSkeleton`)
		setAttr -type "string" FitSkeleton.fitSkeletonTemplate `basenameEx $templateMaFile`;
	}
else
	{
	optionMenu -e -v "biped.ma" asFitFiles;
	asFitSkeletonImport;
	}
delete FitSkeletonNameMatcherImporting;

//Overall scale
$tempString=`listRelatives -f -ad -type transform $otherTopNode`;
for ($y=0;$y<size($tempString);$y++)
	{
	$pos=`xform -q -ws -t $tempString[$y]`;
	if ($pos[1]>$maxY)
		$maxY=$pos[1];
	if ($pos[2]>$maxZ)
		$maxZ=$pos[2];
	}
if ($upAxisDirection=="z")
	$scale=$maxZ/17.0;
else
	$scale=$maxY/17.0;
setAttr FitSkeleton.s -type float3 $scale $scale $scale;

for ($nr=1;$nr<999;$nr++)
	{
	if (!`rowLayout -q -ex ("asMappingUIJointsRowLayout"+$nr)`)
		break;
	$a=`textField -q -tx ("asMappingUIJointsTextFieldA"+$nr)`;
	$b=`textField -q -tx ("asMappingUIJointsTextFieldB"+$nr)`;

	if (!`objExists $a`)
		{
		if (!`gmatch $a "*Part[0-9]*"`)//Missing *Part* joints is OK for `Fitting`, still gets used in `Constraint`
			warning ("AdvancedSkeleton FitJoint \""+$a+"\" not found");
		continue;
		}

	//find $aLong
	$fitJoints=`listRelatives -ad -type joint FitSkeleton`;
	$tempString=`listRelatives -fullPath -ad -type joint FitSkeleton`;
	for ($i=0;$i<size($fitJoints);$i++)
		if ($fitJoints[$i]==$a)
			$aLong=$tempString[$i];

	$isMiddleJoint=1;
	$pos=`xform -q -ws -t $aLong`;
	if ($pos[0]>0.001 || $pos[0]<-0.001)
		$isMiddleJoint=0;

	//find $bResolved
	$underS="";
	if ($sideUnderScore)
		$underS="_";
	if ($isMiddleJoint && $sideMiddle=="")//special case, no middleSuffix, so no underscore
		$underS="";

	if ($sideBeforeName)
		{
		if ($isMiddleJoint) $bResolved=$sideMiddle+$underS+$b;
		else 								$bResolved=$sideRight+$underS+$b;
		}
	else
		{
		if ($isMiddleJoint) $bResolved=$b+$underS+$sideMiddle;
		else 								$bResolved=$b+$underS+$sideRight;
		}

	if ($nameSpaceB!="")
		$bResolved=$nameSpaceB+":"+$bResolved;

	if (!`objExists $bResolved`)
		{
		warning ("Other Joint \""+$bResolved+"\" not found");
		textField -e -bgc 1.0 0.5 0.5 ("asMappingUIJointsTextFieldB"+$nr);
		$numMissing++;
		continue;
		}
	else
		textField -e -bgc $bgc[0] $bgc[1] $bgc[2] ("asMappingUIJointsTextFieldB"+$nr);

	$pos=`xform -q -ws -t $bResolved`;
	xform -ws -t $pos[0] $pos[1] $pos[2] $aLong;
	$placedJoints[size($placedJoints)]=$a;
	}

if ($numMissing)
	frameLayout -e -cl 1 -bgc 1.0 0.5 0.5 asMappingUIJointsFrameLayout;
else
	frameLayout -e -bgc $bgc2[0] $bgc2[1] $bgc2[2] asMappingUIJointsFrameLayout;

asFitModeManualUpdate;

//Finger endjoints likly not present in imported skeleton, so resetting .jo for previous joint
for ($y=0;$y<size($fingers);$y++)
	for ($i=1;$i<5;$i++)
		{
		$fingerJoint=$fingers[$y]+"Finger"+$i;
		if (!`stringArrayCount $fingerJoint $placedJoints`)
			{
			$tempString=`listRelatives -p $fingerJoint`;
			setAttr ($tempString[0]+".jointOrient") -type float3 0 0 0;
			}
		}

select FitSkeleton;
return 1;
}

global proc asMappingUIFunction (string $function)
{
int $sideBeforeName=`checkBox -q -v asMappingUISideBeforeNameCheckBox`;
int $sideUnderScore=`checkBox -q -v asMappingUISideUnderScoreCheckBox`;
int $numChar,$numChar2,$numConnectedJoints,$hitXferredJoint,$useTPoseFile,$useExtra,$lastKeyFrameNr;
int $autoKeyState=`autoKeyframe -q -state`;
int $opm=`asGetOpm`;
float $pos[],$posA[],$posB[],$posC[],$rot[],$keyTimes[];
float $height=10;
float $dist,$minDist,$currentTime,$min,$max,$animationStartTime,$animationEndTime;
if (`objExists "Main"`)
	$height=`getAttr "Main.height"`;
string $fk="FK";
string $target,$source,$dest,$previousParent,$child,$m,$side,$blendShape,$attr,$extra,$constraint;
string $underS="";
string $file=`optionMenu -q -v asMappingUIFiles`;
string $asScriptLocation=`asGetScriptLocationFromSelector`;
string $customMelFile=$asScriptLocation+"/AdvancedSkeletonFiles/moCapMatchers/"+$file+".mel";
string $sideRight=`textFieldGrp -q -tx asMappingUISideRightTextFieldGrp`;
string $sideLeft=`textFieldGrp -q -tx asMappingUISideLeftTextFieldGrp`;
string $sideMiddle=`textFieldGrp -q -tx asMappingUISideMiddleTextFieldGrp`;
string $nameSpaceA=`textField -q -tx asMappingUINameSpacesTextFieldA1`;
string $nameSpaceB=`textField -q -tx asMappingUINameSpacesTextFieldB1`;
string $tempString[],$tempString2[],$tempString3[],$as[],$bs[],$scs[],$aResolveds[],$bResolveds[],$commonAttrs[],$allAttrs[],$historyNodes[];
string $topNodesBefore[],$topNodesAfter[],$keepAnimationNodes[],$bakeControls[];
string $deformJoints[]=`listRelatives -type joint -ad ($nameSpaceA+"DeformationSystem")`;
string $refFiles[]=`file -q -r`;

if ($function=="MoCapConnect" && `objExists MoCapConstraints`)
	error "MoCapConstraints object already exists, which means MoCap skeleton is already connected";

if (`checkBox -q -ex asMappingUIExtraCheckBox`)
	if (`checkBox -q -v asMappingUIExtraCheckBox`)
		{
		$fk="FKExtra";
		$useExtra=1;
		$extra="Extra";
		}

if ($autoKeyState) autoKeyframe -state 0;

for ($nr=1;$nr<999;$nr++)
	{
	if (!`rowLayout -q -ex ("asMappingUIJointsRowLayout"+$nr)`)
		break;
	$as[$nr-1]=`textField -q -tx ("asMappingUIJointsTextFieldA"+$nr)`;
	$bs[$nr-1]=`textField -q -tx ("asMappingUIJointsTextFieldB"+$nr)`;
	}

for ($i=0;$i<size($deformJoints);$i++)
	{
	$target="";
	if ($sideUnderScore) $underS="_";
	$numChar=size($deformJoints[$i]);
	for ($y=0;$y<size($as);$y++)
		if (`substring $deformJoints[$i] 1 ($numChar-2)`==$nameSpaceA+$as[$y])
			{
			if (`gmatch $deformJoints[$i] "*_R"`)
				{
				$side="_R";
				if ($sideBeforeName)
					$target=$sideRight+$underS+$bs[$y];
				else
					$target=$bs[$y]+$underS+$sideRight;
				}
			if (`gmatch $deformJoints[$i] "*_L"`)
				{
				$side="_L";
				if ($sideBeforeName)
					$target=$sideLeft+$underS+$bs[$y];
				else
					$target=$bs[$y]+$underS+$sideLeft;
				}
			if (`gmatch $deformJoints[$i] "*_M"`)
				{
				$side="_M";
				if ($sideMiddle=="")//special case, no middleSuffix, so no underscore
					$underS="";
				if ($sideBeforeName)
					$target=$sideMiddle+$underS+$bs[$y];
				else
					$target=$bs[$y]+$underS+$sideMiddle;
				}
			if ($nameSpaceB!="")
				$target=$nameSpaceB+":"+$target;
			}
	if ($target=="")
		continue;

	$aResolveds[size($aResolveds)]=$deformJoints[$i];
	$bResolveds[size($bResolveds)]=$target;

	//AutoRigConstraint
	if ($function=="AutoRigConstraint")
		{
		print ($deformJoints[$i]+" -> "+$target+"\n");
		if (!`objExists $target`)
			{
			warning ("Expected targetJoint:\""+$target+"\" not found, skipping this.");
			continue;
			}

		//some packages makes locked or limited atrributes, so open up these first
		transformLimits -erx 0 0 -ery 0 0 -erz 0 0 -etx 0 0 -ety 0 0 -etz 0 0 -esx 0 0 -esy 0 0 -esz 0 0 $target;
		if (!`referenceQuery -isNodeReferenced $target`)
			asLockAttr $target 0 0 0 0;

		select $target;
		if (`objExists ($target+"_parentConstraint1")`) delete ($target+"_parentConstraint1");
		if (`objExists ($target+"_pointConstraint1")`) delete ($target+"_pointConstraint1");
		if (`objExists ($target+"_orientConstraint1")`) delete ($target+"_orientConstraint1");
		if (`objExists ($target+"_scaleConstraint1")`) delete ($target+"_scaleConstraint1");
// removed, as this means MetaHumans does not get Corrective-Joints Driven
//		if ($opm)
//			asParentConstraint $deformJoints[$i] $target "-mo";
//		else
			{
//			parentConstraint -mo $deformJoints[$i] $target;
			pointConstraint -mo $deformJoints[$i] $target;
			orientConstraint -mo $deformJoints[$i] $target;
			scaleConstraint -mo $deformJoints[$i] $target;//sometime mixamo character have non-1 scaled joints
			}
		}

	//BakeFromKeepAnimationSkeleton
	if ($function=="BakeFromKeepAnimationSkeleton")
		{
		//NameMatcher NS might not exits..
		if ($nameSpaceB=="") $target="NameMatcherKeepAnimation:"+$target;
		else
		$target=`substitute $nameSpaceB $target "NameMatcherKeepAnimation"`;
		if (`objExists ("FK"+$deformJoints[$i])` && `objExists $target`)
			{
			parentConstraint -mo $target ("FK"+$deformJoints[$i]);
			$bakeControls[size($bakeControls)]="FK"+$deformJoints[$i];
			}
		}

	//AutoRigTransferSkinning
	if ($function=="AutoRigTransferSkinning")
		{
		$tempString=`listConnections -p 1 -s 0 -d 1 -type skinCluster $target`;
		for ($y=0;$y<size($tempString);$y++)
			{
			if (!`gmatch $tempString[$y] "*[.]matrix*"`)
				continue;
			connectAttr -f ($deformJoints[$i]+".worldMatrix[0]") $tempString[$y];
			}
		}

	//MoCapConnect
	if ($function=="MoCapConnect")
		{
		if ($nameSpaceA!="")
			$dest=`substitute $nameSpaceA $deformJoints[$i] ($nameSpaceA+$fk)`;
		else
			$dest=$fk+$deformJoints[$i];
		if (`gmatch $dest "*Root_M"`)
			{//Use RootX instead of Root, as Root may have `inbetween` joint
			$dest=`substitute "FKRoot_M" $dest "RootX_M"`;
			if ($fk=="FKExtra")
				$dest=`substitute "FKExtraRoot_M" $dest "RootExtraX_M"`;
			}
		if (!`objExists $dest`)
			continue;
		if (!`objExists $target`)
			{
//			if (!`objExists MoCapConstraints`)
//				error ("Unable to find \""+$target+"\", Maybe the NameSpace is not defined ?\n");
//			else
				{
				print ("\""+$target+"\" not found, Skipping.\n");
				continue;
				}
			}

		print ($target+" -> "+$dest+"\n");

		//if MoCap-joint-name clashes with FitSkeleton-joint-name (e.g Head, Neck)
		//we will update $target to have `fullPath`
		$tempString=`ls -l $target`;
		if (size($tempString)>1)
			{
			for ($y=0;$y<size($tempString);$y++)
				{
				if (`gmatch $tempString[$y] "*|Group|*"`)
					continue;
				$target=$tempString[$y];
				}
			print ("non-unique name update:"+$target+" -> "+$dest+"\n");
			}

		if (!`objExists MoCapConstraints`)
			{
			createNode -n MoCapConstraints transform;
			asLockAttr MoCapConstraints 1 1 1 1;
			}
		if (!`attributeExists disableConstraints MoCapConstraints`)
			addAttr -k 1 -ln "disableConstraints"  -at bool MoCapConstraints;
		if ($deformJoints[$i]==$nameSpaceA+"Root_M")
			{
			$tempString=`pointConstraint -mo $target $dest`;
//			parent $tempString[0] MoCapConstraints;
			connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
			}
		$tempString=`orientConstraint -mo $target $dest`;
//		parent $tempString[0] MoCapConstraints;
		connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
		$numConnectedJoints++;

		//IK
		if (`gmatch $deformJoints[$i] ($nameSpaceA+"Ankle_*")` || `gmatch $deformJoints[$i] ($nameSpaceA+"Wrist_*")`)
			{
			if (`gmatch $deformJoints[$i] ($nameSpaceA+"Ankle_*")`) $dest=$nameSpaceA+"IK"+$extra+"Leg"+$side;
			if (`gmatch $deformJoints[$i] ($nameSpaceA+"Wrist_*")`) $dest=$nameSpaceA+"IK"+$extra+"Arm"+$side;
			if (`objExists $dest`)
				{
				$tempString=`pointConstraint -mo $target $dest`;
				connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
				$tempString=`orientConstraint -mo $target $dest`;
				connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
				}
			}
		if (`gmatch $deformJoints[$i] ($nameSpaceA+"Toes_*")`)
			{
			$dest=$nameSpaceA+"IKToes"+$side;
			if ($useExtra) $dest=$nameSpaceA+"IKExtraToes"+$side;
			if (`objExists $dest`)
				{
				$tempString=`orientConstraint -mo $target $dest`;
				connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
				}
			}

		//IK-poleVectorPlacement
		if (`gmatch $deformJoints[$i] ($nameSpaceA+"Knee_*")` || `gmatch $deformJoints[$i] ($nameSpaceA+"Elbow_*")`)
			{
			if (`gmatch $deformJoints[$i] ($nameSpaceA+"Knee_*")`)  $dest=$nameSpaceA+"Pole"+$extra+"Leg"+$side;
			if (`gmatch $deformJoints[$i] ($nameSpaceA+"Elbow_*")`) $dest=$nameSpaceA+"Pole"+$extra+"Arm"+$side;
			if (`objExists $dest`)
				{
				$tempString=`listRelatives -p $target`;
				$hip=$tempString[0];
				$knee=$target;
				$tempString=`listRelatives -c $target`;
				$ankle=$tempString[0];
				createNode -n ("PoleVectorLocatorOffsetA"+$deformJoints[$i]+$side) -p MoCapConstraints transform;
				createNode -n ("PoleVectorLocatorOffsetB"+$deformJoints[$i]+$side) -p ("PoleVectorLocatorOffsetA"+$deformJoints[$i]+$side) transform;
				createNode -n ("PoleVectorLocator"+$deformJoints[$i]+$side) -p ("PoleVectorLocatorOffsetB"+$deformJoints[$i]+$side) transform;
				$posA=`xform -q -ws -t $hip`;
				$posB=`xform -q -ws -t $knee`;
				$posC=`xform -q -ws -t $ankle`;
				$distA=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;
				$distB=`mag<<$posB[0]-$posC[0],$posB[1]-$posC[1],$posB[2]-$posC[2]>>`;
				pointConstraint -w $distB $hip ("PoleVectorLocatorOffsetA"+$deformJoints[$i]+$side);
				pointConstraint -w $distA $ankle ("PoleVectorLocatorOffsetA"+$deformJoints[$i]+$side);
				orientConstraint ($nameSpaceA+"RootX_M") ("PoleVectorLocatorOffsetA"+$deformJoints[$i]+$side);
				//avoid flippped knee when straight leg
				setAttr ("PoleVectorLocatorOffsetB"+$deformJoints[$i]+$side+".tz") (($distA+$distB)/-10.0);
				if (`gmatch $deformJoints[$i] ($nameSpaceA+"Elbow_*")`)
					setAttr ("PoleVectorLocatorOffsetB"+$deformJoints[$i]+$side+".tz") (($distA+$distB)/10.0);
				aimConstraint -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "vector" -worldUpVector 0 1 0 $knee ("PoleVectorLocatorOffsetB"+$deformJoints[$i]+$side);
				select $hip $ankle;
				setAttr ("PoleVectorLocator"+$deformJoints[$i]+$side+".tx") (($distA+$distB)/1.0);
				$tempString=`pointConstraint -mo ("PoleVectorLocator"+$deformJoints[$i]+$side) $dest`;
				connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
				}
			}

		//IK-spine
		if ($deformJoints[$i]==$nameSpaceA+"Chest_M")
			{
			$dest=$nameSpaceA+"IK"+$extra+"Spine3_M";
			if (`objExists $dest`)
				{
				if (`attributeExists followRoot $dest`) setAttr ($dest+".followRoot") 0;
				if (`attributeExists ikHybridVis $dest`) setAttr ($dest+".ikHybridVis") 0;
				$tempString=`pointConstraint -mo $target $dest`;
				connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
				$tempString=`orientConstraint -mo $target $dest`;
				connectAttr MoCapConstraints.disableConstraints ($tempString[0]+".nodeState");
				}
			}
		}

	//MoCapZeroOut
	if ($function=="MoCapZeroOut")
		{
		if (!`objExists $target`)
			continue;
		catchQuiet (`setAttr ($target+".r") -type float3 0 0 0`);
		$numConnectedJoints++;
		}
	}

//possible Custom code for MoCapZeroOut
if ($function=="MoCapZeroOut" && `file -q -ex $customMelFile`)
	{
	eval ("source \""+$customMelFile+"\"");
	evalEcho ("MoCapZeroOut");
	print ("// sourced "+$customMelFile+"\n");		
	}

//AutoRigTransferSkinning
if ($function=="AutoRigTransferSkinning")
	{
	//any joints not `mapped` to be `parented over`
	for ($i=0;$i<size($bResolveds);$i++)
		{
		$tempString=`listRelatives -c -type joint $bResolveds[$i]`;
		for ($y=0;$y<size($tempString);$y++)
			{
			if (`stringArrayCount $tempString[$y] $bResolveds`)
				continue;
			$tempString2=`listRelatives -p $tempString[$y]`;
			$previousParent=$tempString2[0];
			//delete `dud` joints, e.g ReadyPlayerMe 'RightHandIndex4_end'
			$tempString3=`listConnections ($tempString[$y]+".worldMatrix")`;
			if ($tempString3[0]=="")
				{
				print ("deleting un-used joint: "+$tempString[$y]+"\n");
				delete $tempString[$y];
				continue;
				}
			parent $tempString[$y] $aResolveds[$i];
			if ($m=="")
				$m="The following Joints does not have a Matching-Joint,\nso these will be parented to the DeformationSystem:\n\n";
			$m+=$tempString[$y]+"\n";
			$child=$tempString[$y];
			while ($child!="")
				{
				$tempString2=`listRelatives -c $child`;
				$child=$tempString2[0];
				if (`stringArrayCount $child $bResolveds`)
					{
					parent $child $previousParent;
					break;
					}
				}
			}
		}
	if ($m!="")
		confirmDialog -t Note -m $m -b "Ok" -db "Ok";

	//FaceSetup On External Skeleton, can happen with asNameMatcherAutoFaceFitting
	if (`objExists FaceJoint_M` && `objExists Head_M`)
		{
		$tempString=`listRelatives -p FaceJoint_M`;
		if ($tempString[0]!="Head_M")
			{
			parent FaceJoint_M Head_M;
			$tempString2={"FaceMotionSystem","FaceDeformationFollowHead","LipFollowHead"};
			for ($i=0;$i<size($tempString2);$i++)
				{
				if (!`objExists $tempString2[$i]`)
					continue;
				parentConstraint -mo Head_M $tempString2[$i];
				scaleConstraint Head_M $tempString2[$i];
				}
			}
		}

	//delete original skeleton
	$target=$bResolveds[size($bResolveds)-1];
	if (`objExists $target`)
		{
		for ($i=0;$i<5;$i++)
			{
			$tempString=`listRelatives -p $target`;
			if ($tempString[0]=="")
				break;
			$target=$tempString[0];
			}
		delete $target;
		}

	dgdirty -a;
	$scs=`ls -type skinCluster`;
	for ($i=0;$i<size($scs);$i++)
		{
		freezeSkinCluster $scs[$i];
		$historyNodes=`listHistory -f 1 -interestLevel 1 $scs[$i]`;
		for ($z=0;$z<size($historyNodes);$z++)
			if (`objectType $historyNodes[$z]`=="mesh")
				skinPercent -normalize 1 $scs[$i] $historyNodes[$z];
		}
	}

//blendShapes
if ($function=="CreateBSControl" && !`objExists FRM_faceGUI`)//skip for MH, as it has faceGUI
	{
	$tempString=`ls -type blendShape`;
	//first find $commonAttrs (matching bsTargetNames at multuiple bsNodes
	for ($i=0;$i<size($tempString);$i++)
		{
		$tempString2=`listAttr -m ($tempString[$i]+".weight")`;
		$tempString2=`asFixMaya2025ListAttrBug $tempString2`;
		for ($y=0;$y<size($tempString2);$y++)
			{
			if (`stringArrayCount $tempString2[$y] $allAttrs`)
				$commonAttrs[size($commonAttrs)]=$tempString2[$y];
			else
				$allAttrs[size($allAttrs)]=$tempString2[$y];
			}
		}
	$commonAttrs=`stringArrayRemoveDuplicates $commonAttrs`;

	for ($i=-1;$i<size($tempString);$i++)
		{
		if ($i==-1)//common
			{
			$blendShape="CommonBlendShapes";
			if (!size($commonAttrs))
				continue;
			}
		else
			{
			$blendShape=$tempString[$i];
			}
		circle -n ($blendShape+"Ctrl") -c 0 0 0 -nr 0 1 0 -sw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -ch 0;
		$tempString2=`parentConstraint Head_M ($blendShape+"Ctrl")`;
		$constraint=$tempString2[0];
		scaleConstraint Head_M ($blendShape+"Ctrl");
		setAttr ($constraint+".target[0].targetOffsetTranslateX") (($height/40.0)*$i);
		setAttr ($constraint+".target[0].targetOffsetTranslateZ") ($height/-10.0);
		setAttr ($blendShape+"CtrlShape.overrideEnabled") 1;
		setAttr ($blendShape+"CtrlShape.overrideColor") 17;
		asLockAttr ($blendShape+"Ctrl") 1 1 1 1;
		if ($i==-1)
			continue;
		$tempString2=`listAttr -m ($blendShape+".weight")`;
		$tempString2=`asFixMaya2025ListAttrBug $tempString2`;
//		if (size($tempString2)==0)
//			delete ($blendShape+"Ctrl");
		for ($y=0;$y<size($tempString2);$y++)
			{
			$attr=$tempString2[$y];
			if ($attr=="V_None")
				continue;
			if (`stringArrayCount $attr $commonAttrs`)
				{
				if (!`attributeExists $attr CommonBlendShapesCtrl`)
					addAttr -k 1 -ln $attr -at double -smn 0 -hsn 1 -smx 1 -hsx 1 -dv 0 CommonBlendShapesCtrl;
				connectAttr -f ("CommonBlendShapesCtrl."+$attr) ($blendShape+"."+$attr);
				}
			else
				{
				addAttr -k 1 -ln $attr -at double -smn 0 -hsn 1 -smx 1 -hsx 1 -dv 0 ($blendShape+"Ctrl");
				connectAttr -f ($blendShape+"Ctrl."+$attr) ($blendShape+"."+$attr);
				}
			}
		//remove any that has no (nonCommon) attrs
		$tempString2=`listAttr -k ($blendShape+"Ctrl")`;
		if (!size($tempString2))
			delete ($blendShape+"Ctrl");
		}
	if (`objExists CommonBlendShapesCtrl`)
		{
		$tempString2=`listAttr -k CommonBlendShapesCtrl`;
		if (!size($tempString2))
			delete CommonBlendShapesCtrl;
		}
	refresh;
	}

//BakeFromKeepAnimationSkeleton
if ($function=="BakeFromKeepAnimationSkeleton")
	{
	$keepAnimationNodes=`ls "NameMatcherKeepAnimation:*"`;
	if (!size($keepAnimationNodes))
		return;
	select -hi $keepAnimationNodes;
	$keyTimes=`keyframe -q -tc`;
	$keyTimes=`sort $keyTimes`;
	if (size($keyTimes))
		$lastKeyFrameNr=$keyTimes[size($keyTimes)-1];
	if (size($keyTimes))
		{
		playbackOptions -min -1 -ast -1 -max $lastKeyFrameNr -aet $lastKeyFrameNr;
		select -cl;
		asSetAllFK "";
		bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys false -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
			-bakeOnOverrideLayer false -controlPoints false -shape false $bakeControls;
		currentTime -1;//bindPose at -1
		select $bakeControls;
		delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1;
		delete $keepAnimationNodes;
		namespace -rm NameMatcherKeepAnimation;
		}
	}

if ($autoKeyState) autoKeyframe -state 1;
select -cl;

if ($function=="AutoRigConstraint")
	print "// Skeleton has been constrained to AdvancedSkeleton`s Deformation-Joints,\n";
if ($function=="AutoRigTransferSkinning")
	print "// Skinning has been transferred to AdvancedSkeleton`s Deformation-Joints,\n";
if ($function=="MoCapConnect")
	print ("// "+$numConnectedJoints+" joints connected.\n");
if ($function=="MoCapZeroOut")
	print ("// "+$numConnectedJoints+" joints `zeroed out`.\n");
}

global proc asMoCapMatcherNameSpaceDetect ()
{
string $sel[]=`ls -sl`;
string $tempString[];
string $nameSpace;
for ($i=0;$i<size($sel);$i++)
	{
	tokenize $sel[$i] ":" $tempString;
	if (size($tempString)>1)
		$nameSpace=$tempString[0];
	}
print ("// nameSpace \""+$nameSpace+"\" detected, and updated in the  \"NameSpaces\" section.\n");
textField -e -tx $nameSpace asMappingUINameSpacesTextFieldB1;
}

global proc asMoCapMatcherScan ()
{
asMoCapMatcherNameSpaceDetect;
}

global proc asMoCapMatcherDisconnect ()
{
string $tempString[];

if (`objExists MoCapConstraints`)
	{
	if (`attributeExists disableConstraints MoCapConstraints`)
		$tempString=`listConnections -s 0 -d 1 MoCapConstraints.disableConstraints`;
	for ($i=0;$i<size($tempString);$i++)
		delete $tempString[$i];
	delete MoCapConstraints;
	}
print ("// MoCap Skeleton disconnected.\n");
}

global proc asMoCapMatcherBake ()
{
string $tempString[],$bakeControls[];

if (!`objExists MoCapConstraints`) error "MoCapConstraints object not found";
if (!`attributeExists disableConstraints MoCapConstraints`) error "MoCapConstraints.disableConstraints attribute not found";

string $moCapConstraints[]=`listConnections -s 0 -d 1 MoCapConstraints.disableConstraints`;
for ($i=0;$i<size($moCapConstraints);$i++)
	{
	$tempString=`listConnections ($moCapConstraints[$i]+".constraintParentInverseMatrix")`;
	$bakeControls[size($bakeControls)]=$tempString[0];
	}
select $bakeControls;
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys false -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
	-bakeOnOverrideLayer false -controlPoints false -shape false $bakeControls;
select $bakeControls;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";
}

/*
global proc asMoCapMatcherIKBake (string $uiName)
{
float $start=`playbackOptions -q -min`;
float $end=`playbackOptions -q -max`;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $limb;
string $tempString[],$tempString2[];

//bake before IKBake
if (`objExists ($nameSpace+"RootX_M")` && `objExists ($nameSpace+"RootExtraX_M")`)
	{
	$tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"RootX_M") ($nameSpace+"RootExtraX_M")`;
	if (!size($tempString))
		error "Run Bake before running IKBake";
	}

optionVar -iv asBakingMoCap 1;
evalDeferred ("optionVar -iv asBakingMoCap 0");
$tempString=`listRelatives -c ($nameSpace+"FKIKSystem")`;
for ($i=0;$i<size($tempString);$i++)
	{
	$tempString2=`listRelatives -c $tempString[$i]`;
	for ($y=0;$y<size($tempString2);$y++)
		{
		if (!`attributeExists FKIKBlend $tempString2[$y]`)
			continue;
		if ($limb!="") $limb+="|";
		$limb+=`substitute ($nameSpace+"FKIK") $tempString2[$y] ""`;
		}
	}
asAnimBakeFKIK $limb 1 $uiName;
}
*/

global proc asMoCapLibraryUI (string $uiName)
{
asEnsureAsGetScriptLocation;
string $asScriptLocation=`asGetScriptLocation`;
string $frameLayouts[]={"asMCLBody","asMCLMoCapMaya","asMCLCNU","asMCLMoCapCustom","asMCLEdit","asMCLFace"};

if (`asHotKeyCheck "asMoCapLibraryUI \"\""`) return;

if (`upAxis -q -ax`!="y")
	error "Maya settting are not using Y-up axis, MoCapLibrary requires Y-up";

for ($i=0;$i<size($frameLayouts);$i++)
	if (!`optionVar -ex ($frameLayouts[$i]+"FrameLayout")`)
		optionVar -iv ($frameLayouts[$i]+"FrameLayout") 1;

if (`window -q -ex asMoCapLibraryUI`)
    deleteUI asMoCapLibraryUI;
window -t "MoCapLibrary" asMoCapLibraryUI;

columnLayout -adj 1;
	text -l "Motion Capture Library:";
	separator -h 10;
	frameLayout -mw 10 -cll 1 -cl `optionVar -q asMCLBodyFrameLayout` -cc asFL -ec asFL -l "Body" asMCLBodyFrameLayout;
		frameLayout -cll 1 -cl `optionVar -q asMCLMoCapMayaFrameLayout` -cc asFL -ec asFL -l " Motion Capture (Maya)" asMCLMoCapMayaFrameLayout;
			text -l "Maya Example Motion Capture files:";
			text -al "center" -fn "smallBoldLabelFont" -l "* only for Maya versions that include MoCap files";
			rowLayout -nc 2;
				optionMenu asMCLMoCapMayaOptionMenu;
				button -l "apply" -c ("asMCLMayaApply \""+$uiName+"\"");
				setParent..;
			setParent..;
		frameLayout -mw 10 -cll 1 -cl `optionVar -q asMCLMoCapCustomFrameLayout` -cc asFL -ec asFL -l " Motion Capture (Custom)" asMCLMoCapCustomFrameLayout;
			columnLayout -adj 1;
			separator -st none -h 5;
				rowLayout -nc 3;
					text -w 100 -l "MoCap library path:";
					button -l "browse" -c "asMCLMoCapCustomBrowse asMCLMoCapCustomPathTextField";
					textField -ed 0 -w 300 asMCLMoCapCustomPathTextField;
					if (`optionVar -q asMCLMoCapCustomPathTextField`!=0)
						textField -e -tx `optionVar -q asMCLMoCapCustomPathTextField` asMCLMoCapCustomPathTextField;
					setParent..;
				setParent..;
			rowLayout -nc 2;
				optionMenu asMCLMoCapCustomOptionMenu;
				button -l "apply" -c ("asMCLCustomApply \""+$uiName+"\"");
				setParent..;
			setParent..;
		frameLayout -cll 1 -cl `optionVar -q asMCLCNUFrameLayout` -cc asFL -ec asFL -l " Motion Capture (CMU Database)" asMCLCNUFrameLayout;
			text -l "Carnegie Mellon University MoCap Database files";
			text -al "center" -fn "smallBoldLabelFont" -l "http://mocap.cs.cmu.edu";
			optionMenu -cc asPopulateMCLCNU2OptionMenu asMCLCNU1OptionMenu;
			optionMenu -cc asUpdateMoCapCNUApplyButton asMCLCNU2OptionMenu;
			separator -h 5;
			rowLayout -nc 2;
				separator -w 200 -st none;
				button -w 100 -l "apply" -c ("asMCLCNUApply \""+$uiName+"\"") asMCLCNUApplyButton;
				setParent..;
			setParent..;

		frameLayout -cll 1 -cl `optionVar -q asMTBodyFrameLayout` -cc asFL -ec asFL -l " Motion Test" asMTBodyFrameLayout;
			columnLayout;
				rowLayout -nc 3;
					separator -h 20 -w 50 -st none;
					optionMenu asMTBodyOptionMenu;
					button -l apply -c ("asMCLApply \""+$uiName+"\" MotionTest");
					setParent..;
				setParent..;
			setParent..;

		separator -h 5;
		frameLayout -cll 1 -cl `optionVar -q asMCLEditFrameLayout` -cc asFL -ec asFL -l " Edit" asMCLEditFrameLayout;
			rowLayout -nc 3 -cw3 50 120 150;
				text -l "Edit:";
				button -w 110 -l "Go to Frame -1" -c "currentTime -1";
				button -w 110 -l "Show MoCap joints" -c "setAttr MotionCaptureLibraryScale.v 1;select MotionCaptureLibraryScale;";
				setParent..;
			rowLayout -nc 3 -cw3 50 120 150;
				separator;
				button -w 110 -l "Disconnect" -c ("asMCLDisconnectBody \""+$uiName+"\"");
				button -w 110 -l "Reconnect" -c ("asMCLConnectBody \""+$uiName+"\"");
				setParent..;
			rowLayout -nc 3 -cw3 50 120 150;
				separator -w 50 -st none;
				button -w 110 -l "Remove animation" -c ("asMCLRemoveBody \""+$uiName+"\"");
				button -w 110 -l "Bake animation" -c ("asMCLBakeBody \""+$uiName+"\"");
				setParent..;
			setParent..;
		setParent..;
	separator -h 5;
	frameLayout -cll 1 -cl `optionVar -q asMCLFaceFrameLayout` -cc asFL -ec asFL -l "Face" asMCLFaceFrameLayout;
		columnLayout;
			rowLayout -nc 3;
				separator -h 20 -w 50 -st none;
				optionMenu asMCLFaceOptionMenu;
				button -l apply -c ("asMCLTestFace \""+$uiName+"\"");
//				button -l "import Face test-animation" -c ("asMCLTestFace \""+$uiName+"\"");
			setParent..;
		setParent..;
		rowLayout -nc 2;
			separator -h 20 -w 50 -st none;
			button -l "Remove Face animation" -c ("asMCLRemoveFace \""+$uiName+"\"");
			setParent..;

asPopulateMCLMoCapsOptionMenu;
asPopulateWithFilesOptionMenu asMCLMoCapCustomOptionMenu `optionVar -q asMCLMoCapCustomPathTextField`;
asPopulateMCLCNU1OptionMenu;
asPopulateWithFilesOptionMenu asMTBodyOptionMenu  ($asScriptLocation+"/AdvancedSkeletonFiles/div/motionTest/body");
asPopulateWithFilesOptionMenu asMCLFaceOptionMenu ($asScriptLocation+"/AdvancedSkeletonFiles/div/motionTest/face");

showWindow asMoCapLibraryUI;
}

global proc asMCLMoCapCustomBrowse (string $textField)
{
int $fileMode=1;
if ($textField=="asMCLMoCapCustomPathTextField")
	$fileMode=3;
string $result[]=`fileDialog2 -fm $fileMode -cap folder -okc Choose`;
textField -e -tx $result[0] $textField;
optionVar -sv $textField $result[0];
asPopulateWithFilesOptionMenu asMCLMoCapCustomOptionMenu `optionVar -q asMCLMoCapCustomPathTextField`;
}

global proc asPopulateMCLMoCapsOptionMenu ()
{
string $mayaLocation=`getenv MAYA_LOCATION`;
string $mocapFbxLocation=$mayaLocation+"/Examples/Animation/Motion_Capture/FBX";
if (!`file -q -ex $mocapFbxLocation`)
	return;
string $files[]=`getFileList -fs "*.fbx" -fld $mocapFbxLocation`;
setParent -menu asMCLMoCapMayaOptionMenu;
for ($i=0;$i<size($files);$i++)
	menuItem -l $files[$i];
}

global proc asPopulateMCLCNU1OptionMenu ()
{
string $line;
string $subjects[],$tempString[];
string $file=`asGetScriptLocation`+"/AdvancedSkeletonFiles/moCapCNUlib/moCapCNUlib.txt"; 

if (!`file -q -ex $file`)
	error ("Unable to find file:"+$file);

int $fileId=`fopen $file "r"`;
string $nextLine = `fgetline $fileId`;
while (size($nextLine)>0)
	{
	$line=`strip $nextLine`;
	tokenize $line $tempString;
	if (`gmatch $line "Subject #*"`)
		$subjects[size($subjects)]=$line;
	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;

setParent -menu asMCLCNU1OptionMenu;
for ($i=0;$i<size($subjects);$i++)
	menuItem -l $subjects[$i];
asPopulateMCLCNU2OptionMenu;
//asUpdateMoCapCNUApplyButton;
}

global proc asPopulateMCLCNU2OptionMenu ()
{
int $subjectMatch;
string $line;
string $tempString[],$clips[];
string $file=`asGetScriptLocation`+"/AdvancedSkeletonFiles/moCapCNUlib/moCapCNUlib.txt";
string $subject=`optionMenu -q -v asMCLCNU1OptionMenu`;

//remove existing items
$tempString=`optionMenu -q -ill asMCLCNU2OptionMenu`;
for ($y=0;$y<size($tempString);$y++)
	deleteUI $tempString[$y];

int $fileId=`fopen $file "r"`;
string $nextLine = `fgetline $fileId`;
while (size($nextLine)>0)
	{
	$line=`strip $nextLine`;
	tokenize $line $tempString;
	if (`gmatch $line "Subject #*"`)
		{
		if ($line==$subject)
			$subjectMatch=1;
		else
			$subjectMatch=0;
		}
	if ($subjectMatch && `gmatch $line "[0-9][0-9]*"`)
		$clips[size($clips)]=$line;

	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;

setParent -menu asMCLCNU2OptionMenu;
for ($i=0;$i<size($clips);$i++)
	menuItem -l $clips[$i];

asUpdateMoCapCNUApplyButton;
}

global proc asPopulateWithFilesOptionMenu (string $optionMenu, string $fld)
{
string $files[]=`getFileList -fld $fld`;
string $tempString[];

$tempString=`optionMenu -q -ill $optionMenu`;
for ($y=0;$y<size($tempString);$y++)
	deleteUI $tempString[$y];

setParent -menu $optionMenu;
for ($i=0;$i<size($files);$i++)
	{
	if ($files[$i]=="incrementalSave")
		continue;
	menuItem -l $files[$i];
	}
}

global proc asUpdateMoCapCNUApplyButton ()
{
string $label="apply";
string $asScriptLocation=`asGetScriptLocation`;
string $moCapCNUlibDir=$asScriptLocation+"/AdvancedSkeletonFiles/moCapCNUlib/downloads";
string $clipLongName=`optionMenu -q -v asMCLCNU2OptionMenu`;
string $files[]=`getFileList -fld $moCapCNUlibDir`;
string $tempString[];
tokenize $clipLongName $tempString;
string $clipShortName=$tempString[0];
string $mayaFile=$moCapCNUlibDir+"/"+$clipShortName+".ma";

if (!`file -q -ex $mayaFile`)
	$label="download && apply";
button -e -l $label asMCLCNUApplyButton;
}

global proc asMCLMayaApply (string $uiName)
{
asMCLApply $uiName Maya;
}

global proc asMCLCustomApply (string $uiName)
{
asMCLApply $uiName Custom;
}

global proc asMCLCNUApply (string $uiName)
{
if (`button -q -l asMCLCNUApplyButton`=="download && apply")
	asMCLMoCapCNUDownload;
asMCLApply $uiName CNU;
}

global proc asMCLApply (string $uiName, string $type)
{
global string $unrealMannequinJoints;
global int $unrealMannequinUnrealPrefix;
int $lastKeyFrameNr,$altSkeletonType;
int $autoKeyState=`autoKeyframe -q -state`;
float $lowestFootTy,$s,$sizeAdv,$sizeMoCap;
float $posA[],$posB[],$keyTimes[],$rot[],$rotA[],$rotB[];
string $mayaLocation=`getenv MAYA_LOCATION`;
string $asScriptLocation=`asGetScriptLocation`;
string $mocapFbxLocation;
string $fileName,$fld,$file,$moCapCNUlibDir,$clipLongName,$clipShortName,$topNode,$tPoseNameSpace;
string $rightShoulder,$rightArm,$rightForeArm,$rightHand,$rightUpLeg,$rightLeg,$rightFoot;
string  $leftShoulder, $leftArm, $leftForeArm, $leftHand, $leftUpLeg, $leftLeg, $leftFoot;
string $basename=`basenameEx $file`;
string $ref="MotionCaptureLibrary:"+$basename+":Reference";
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $hipsJoint,$side,$rightLeft,$mpd,$moCapNs;
string $tempString[],$moCapJoints[],$files[];

if ($autoKeyState) autoKeyframe -state 0;

if ($type=="Maya") 
	{
	$mocapFbxLocation=$mayaLocation+"/Examples/Animation/Motion_Capture/FBX";
	$fileName=`optionMenu -q -v ("asMCLMoCap"+$type+"OptionMenu")`;
	$file=$mocapFbxLocation+"/"+$fileName;
	}
if ($type=="Custom") 
	{
	$mocapFbxLocation=`textField -q -tx asMCLMoCapCustomPathTextField`;
	$file=$mocapFbxLocation+"/"+`optionMenu -q -v asMCLMoCapCustomOptionMenu`;
	}
if ($type=="CNU") 
	{
//	$moCapShoulderName="Arm";
	$moCapCNUlibDir=$asScriptLocation+"/AdvancedSkeletonFiles/moCapCNUlib/downloads";
	$clipLongName=`optionMenu -q -v asMCLCNU2OptionMenu`;
	$files=`getFileList -fld $moCapCNUlibDir`;
	tokenize $clipLongName $tempString;
	$clipShortName=$tempString[0];
	$file=$moCapCNUlibDir+"/"+$clipShortName+".ma";
	}
if ($type=="MotionTest") 
	{
	$fld=$asScriptLocation+"/AdvancedSkeletonFiles/div/motionTest/body";
	if (`optionMenu -q -ex asMTBodyOptionMenu`)
		$fileName=`optionMenu -q -v asMTBodyOptionMenu`;
	else
		$fileName=`optionMenu -q -v asATMotionTestOptionMenu`;
	$file=$fld+"/"+$fileName;
	}

if ($file=="")
	error "No MotionCapture Example choosen";
if (!`file -q -ex $file`)
	error ("File not found:\""+$file+"\"");

asMCLRemoveBody $uiName;

//Special case, user might have Preferences set to:
// Preferences->Settings->Files/Projects->File Dialog->Dialog Style == "OS native"
// This must be changed to "Maya default"
if (`optionVar -ex "FileDialogStyle"`)
	if (`optionVar -q "FileDialogStyle"`==1)
		{
		evalDeferred "optionVar -iv FileDialogStyle 1";
		optionVar -iv FileDialogStyle 2;
		}

$topNodesBefore=`ls -as`;

if ($type=="Custom") 
	{
	file -r -namespace "MotionCaptureLibrary" $file;
	file -importReference $file;
	}
else
	file -i -namespace "MotionCaptureLibrary" $file;

$topNodesAfter=`ls -as`;
for ($i=0;$i<size($topNodesAfter);$i++)
	if (!`stringArrayCount $topNodesAfter[$i] $topNodesBefore`)
		{
//		$tempString=`listRelatives -type joint -c $topNodesAfter[$i]`;
		$tempString=`listRelatives -type joint -ad $topNodesAfter[$i]`;
		if (size($tempString))
			{
			$topNode=$topNodesAfter[$i];
			break;
			}
		}

print ("// detected MoCap TopNode:\""+$topNode+"\".\n");

tokenize $topNode ":" $tempString;
if (size($tempString)>1)//if the file is a fbx, nameSpace does not get added upon import
	$moCapNs=$tempString[0]+":";

if ($moCapNs=="")
	{
	if (!`namespace -ex MotionCaptureLibrary`)
		namespace -addNamespace MotionCaptureLibrary;
	namespace -setNamespace MotionCaptureLibrary;
	evalDeferred ("namespace -setNamespace \":\"");
	$tempString=`listRelatives -ad -type transform $topNode`;
	$tempString[size($tempString)]=$topNode;
	for ($i=0;$i<size($tempString);$i++)
		{
		rename $tempString[$i] ("TEMP_"+$tempString[$i]);
		rename ("MotionCaptureLibrary:TEMP_"+$tempString[$i]) $tempString[$i];
		}
	namespace -setNamespace ":";
	$moCapNs="MotionCaptureLibrary:";
	$topNode=$moCapNs+$topNode;
	}

$moCapJoints=`listRelatives -type joint -ad $topNode`;

currentTime 0;
if (`nodeType $topNode`=="joint" && `getAttr ($topNode+".ty")`>0)//chek ty>0 as this could be Unreal-root, which is not $hipsJoint;
	$hipsJoint=$topNode;
else if (`objExists MotionCaptureLibrary:pelvis`)
	$hipsJoint="MotionCaptureLibrary:pelvis";
else
	{
	$tempString=`listRelatives -type joint -ad $topNode`;
	$hipsJoint=$tempString[size($tempString)-1];
	}

createNode -n MotionCaptureLibraryScale transform;
parent $topNode MotionCaptureLibraryScale;

//Names (CMU & Maya have MoCap standard names e.g. RightShoulder, but Custom could have alternative names
$rightShoulder="RightShoulder";$leftShoulder="LeftShoulder";
$rightArm="RightArm";$leftArm="LeftArm";
$rightForeArm="RightForeArm";$leftForeArm="LeftForeArm";
$rightHand="RightHand";$leftHand="LeftHand";
$rightUpLeg="RightUpLeg";$leftUpLeg="LeftUpLeg";
$rightLeg="RightLeg";$leftLeg="RightLeg";
$rightFoot="RightFoot";$leftFoot="LeftFoot";
if (`objExists ($moCapNs+"upperarm_r")`)
	{
	$altSkeletonType=1;//Unreal Mannequin
	addAttr -ln altSkeletonType -at long -dv 1 MotionCaptureLibraryScale;
	$rightShoulder="clavicle_r";$leftShoulder="clavicle_l";
	$rightArm="upperarm_r";$leftArm="upperarm_l";
	$rightForeArm="lowerarm_r";$leftForeArm="lowerarm_l";
	$rightHand="hand_r";$leftHand="hand_l";
	$rightUpLeg="thigh_r";$leftUpLeg="thigh_l";
	$rightLeg="calf_r";$leftLeg="calf_l";
	$rightFoot="foot_r";$leftFoot="foot_l";
	if (!`objExists "root"`)//might already be working with a rig that has UnrealJoints added
		{
		createNode -n asMoCapMatcherCreatingUnrealMannequinJoints transform;
		addAttr -ln nameSpace -dt "string" asMoCapMatcherCreatingUnrealMannequinJoints;
		setAttr -type "string" asMoCapMatcherCreatingUnrealMannequinJoints.nameSpace $nameSpace;
		$unrealMannequinJoints="Quinn (UE5)";
		$unrealMannequinUnrealPrefix=1;
		asCreateUnrealMannequinJoints;

		$tPoseNameSpace="TPose";
		if (`namespace -ex TPose`)
			delete `ls "TPose:*"`;
		else
			namespace -addNamespace TPose;
		namespace -setNamespace TPose;
		$tempString=`listRelatives -ad -type transform root`;
		$tempString[size($tempString)]="root";
		for ($i=0;$i<size($tempString);$i++)
			{
			rename $tempString[$i] ("TEMP_"+$tempString[$i]);
			rename ("TPose:TEMP_"+$tempString[$i]) $tempString[$i];
			}
		setAttr TPose:root.v 0;
		namespace -setNamespace ":";
		}
	}

if (`objExists ($moCapNs+"Right_Foot")`)
	{
	$altSkeletonType=2;//Unity Armature
	addAttr -ln altSkeletonType -at long -dv 2 MotionCaptureLibraryScale;
	$rightShoulder="Right_Shoulder";$leftShoulder="Left_Shoulder";
	$rightArm="Right_UpperArm";$leftArm="Left_UpperArm";
	$rightForeArm="Right_LowerArm";$leftForeArm="Left_LowerArm";
	$rightHand="Right_Hand";$leftHand="Left_Hand";
	$rightUpLeg="Right_UpperLeg";$leftUpLeg="Left_UpperLeg";
	$rightLeg="Right_LowerLeg";$leftLeg="Left_LowerLeg";
	$rightFoot="Right_Foot";$leftFoot="Left_Foot";
	}

//Rmoved, as some MoCap animations do not start with feet on the ground. e.g. Hoverboard_Hover clip
//assume one of the feet are touching the ground, at the start of animation, Find the Lowest one
//if (`objExists ($moCapNs+$leftFoot)`)	  $posA=`xform -q -ws -t ($moCapNs+$leftFoot)`;
//if (`objExists ($moCapNs+$rightFoot)`)	$posB=`xform -q -ws -t ($moCapNs+$rightFoot)`;
//$lowestFootTy=`min $posA[1] $posB[1]`;

$keyTimes=`keyframe -q -tc ($hipsJoint+".tx")`;
$lastKeyFrameNr=$keyTimes[size($keyTimes)-1];

playbackOptions -min -1 -ast -1 -max $lastKeyFrameNr -aet $lastKeyFrameNr;
currentTime -1;
//asSetAllFK "";
if (`objExists ($nameSpace+"FKIKLeg_R")`) setAttr ($nameSpace+"FKIKLeg_R.FKIKBlend") 10;
if (`objExists ($nameSpace+"FKIKLeg_L")`) setAttr ($nameSpace+"FKIKLeg_L.FKIKBlend") 10;
if (`objExists ($nameSpace+"FKIKSpine_M")`) setAttr ($nameSpace+"FKIKSpine_M.FKIKBlend") 0;
if (`objExists ($nameSpace+"FKIKArm_R")`) setAttr ($nameSpace+"FKIKArm_R.FKIKBlend") 0;
if (`objExists ($nameSpace+"FKIKArm_L")`) setAttr ($nameSpace+"FKIKArm_L.FKIKBlend") 0;

//zero-out MoCap Skeleton joints
if ($altSkeletonType==0)
	{
	for ($i=0;$i<size($moCapJoints);$i++)
		setAttr ($moCapJoints[$i]+".r") -type float3 0 0 0;
	setAttr ($hipsJoint+".tx") 0;
	setAttr ($hipsJoint+".tz") 0;
	}
if ($altSkeletonType==1)
	{
	//could have a "root" joint above $hipsJoint, (aka Unreal Root Joints)  so include making sure this is also zeroed
	$tempString=`listRelatives -p -type joint $hipsJoint`;
	if (`gmatch $tempString[0] "*root"`)
		{
		xform -os -t 0 0 0 -ro 0 0 0 -s 1 1 1 $tempString[0];
		setKeyframe $tempString[0];
		}

//	setAttr ($hipsJoint+".tx") 0;
//	setAttr ($hipsJoint+".ty") 0;
	}

//Attempt to T-Pose MoCap Skeleton
if ($type=="CNU")
	{
	xform -ws -ro 0 0 0 ($moCapNs+$rightShoulder);xform -ws -ro 0 0 0 ($moCapNs+$leftShoulder);
	xform -ws -ro 0 0 0 ($moCapNs+$rightArm);xform -ws -ro 0 0 0 ($moCapNs+$leftArm);
	xform -ws -ro 0 0 0 ($moCapNs+$rightForeArm);xform -ws -ro 0 0 0 ($moCapNs+$leftForeArm);
	xform -ws -ro 0 0 0 ($moCapNs+$rightHand);xform -ws -ro 0 0 0 ($moCapNs+$leftHand);
	setAttr ($moCapNs+$rightUpLeg+".rz") 20;
	setAttr ($moCapNs+$leftUpLeg+".rz") -20;
	}
if ($type=="Maya")
	{
	xform -ws -ro -180 0 180 ($moCapNs+$rightShoulder);xform -ws -ro 0 0 0 ($moCapNs+$leftShoulder);
	xform -ws -ro 90 0 -180 ($moCapNs+$rightArm);xform -ws -ro 90 0 0 ($moCapNs+$leftArm);
	}

if ($altSkeletonType==1)
	{
	for ($i=0;$i<size($moCapJoints);$i++)
		{
		$tposeJoint=`substitute "MotionCaptureLibrary" $moCapJoints[$i] $tPoseNameSpace`;
		if (!`objExists $tposeJoint`)
//			error ("failed to find t-pose joint: \""+$tposeJoint+"\".\n");
			{
			warning ("failed to find t-pose joint: \""+$tposeJoint+"\".\n");
			continue;
			}
		$rot=`getAttr ($tposeJoint+".r")`;
		setAttr ($moCapJoints[$i]+".r") -type float3 $rot[0] $rot[1] $rot[2];
		}
	}

if ($altSkeletonType==2)
	{
	$tempString=`listRelatives -type transform -ad $topNode`;
	$tempString[size($tempString)]=$topNode;
	for ($i=0;$i<size($tempString);$i++)
		if (`getAttr -settable ($tempString[$i]+".rx")`)
			{
			setAttr ($tempString[$i]+".r") -type float3 0 0 0;
			setKeyframe $tempString[$i];
			}
	$tempString=`listRelatives -type transform -ad ($moCapNs+"UpperChest")`;
	for ($i=size($tempString)-1;$i>-1;$i--)
		{
		if (`gmatch $tempString[$i] "*Thumb*"` || `gmatch $tempString[$i] "*Shoulder"`)
			continue;
		if (`gmatch $tempString[$i] "*Right_*"`)
			xform -ws -ro 0 180 90 $tempString[$i];
		if (`gmatch $tempString[$i] "*Left_*"`)
			xform -ws -ro 0 0 -90 $tempString[$i];
		setKeyframe $tempString[$i];
		}
/*
	xform -ws -ro 0 180 90 ($moCapNs+$rightArm);xform -ws -ro 0 0 -90 ($moCapNs+$leftArm);
	xform -ws -ro 0 180 90 ($moCapNs+$rightForeArm);xform -ws -ro 0 0 -90 ($moCapNs+$leftForeArm);
	xform -ws -ro 0 180 90 ($moCapNs+$rightHand);xform -ws -ro 0 0 -90 ($moCapNs+$leftHand);
*/
	}


//After Straighting, legs and knee straighting probably cause the foot to be lower, so compensate
/*
if (`objExists ($moCapNs+$leftFoot)`)
	{
	$posA=`xform -q -ws -t ($moCapNs+$leftFoot)`;
	if ($posA[1]<$lowestFootTy)
		move -r -ws -wd 0 ($lowestFootTy-$posA[1]) 0 $hipsJoint;
	}
*/

$posA=`xform -q -ws -t ($nameSpace+"Root_M")`;
$posB=`xform -q -ws -t ($nameSpace+"IKLeg_R")`;
$sizeAdv=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;

$posA=`xform -q -ws -t $hipsJoint`;
$posB=`xform -q -ws -t ($moCapNs+$rightFoot)`;
$sizeMoCap=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;

$s=$sizeAdv/$sizeMoCap;
if ($s>1.1 || $s<0.9)
	setAttr MotionCaptureLibraryScale.s -type float3 $s $s $s;

//match Root pos
$posA=`xform -q -ws -t ($nameSpace+"Root_M")`;
xform -ws -t $posA[0] $posA[1] $posA[2] $hipsJoint;

select $moCapJoints;
setKeyframe;

//Attempt to T-Pose AdvancedSkeleton
if ($altSkeletonType!=1)// Skip as this could be Unreal Mannequin rigged with AS, so Non-T-BuildPose
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  {$side="_R";$rightLeft="Right";$rotA[0]=0;$rotA[1]=0;$rotA[2]=180;$rotB[0]=90;$rotB[1]=0;$rotB[2]=180;}
		if ($b==-1) {$side="_L";$rightLeft="Left";$rotA[0]=0;$rotA[1]=0;$rotA[2]=0;$rotB[0]=-90;$rotB[1]=0;$rotB[2]=180;}

		if (`objExists ($nameSpace+"FKShoulder"+$side)`) asSetMoCapWSOrient $rotB[0] $rotB[1] $rotB[2] ($nameSpace+"FKShoulder"+$side) $nameSpace;
		if (`objExists ($nameSpace+"FKElbow"+$side)`) asSetMoCapWSOrient $rotB[0] $rotB[1] $rotB[2] ($nameSpace+"FKElbow"+$side) $nameSpace;
		if (`objExists ($nameSpace+"FKWrist"+$side)`) asSetMoCapWSOrient $rotB[0] $rotB[1] $rotB[2] ($nameSpace+"FKWrist"+$side) $nameSpace;

		//Align IK as well
		if (`objExists ("IKLeg"+$side)` && `objExists ($moCapNs+$rightLeft+"Foot")`) 
			delete `pointConstraint -skip y ($moCapNs+$rightLeft+"Foot") ("IKLeg"+$side)`;
		}

asMCLConnectBody $uiName;

setAttr MotionCaptureLibraryScale.v 0;
if ($autoKeyState) autoKeyframe -state 1;
select -cl;
currentTime 0;
}

global proc asMCLMoCapCNUDownload ()
{
string $asScriptLocation=`asGetScriptLocation`;
string $moCapCNUlibDir=$asScriptLocation+"/AdvancedSkeletonFiles/moCapCNUlib/downloads";
string $clipLongName=`optionMenu -q -v asMCLCNU2OptionMenu`;
string $tempString[];
tokenize $clipLongName $tempString;
string $clipShortName=$tempString[0];
string $zipFileUrl="https://www.animationstudios.com.au/download/moCapCNUlib/downloads/"+$clipShortName+".7z";
string $curl=$asScriptLocation+"/AdvancedSkeletonFiles/bin/curl.e";
string $zip=$asScriptLocation+"/AdvancedSkeletonFiles/bin/7za.e";
string $downloadDir=$asScriptLocation+"/AdvancedSkeletonFiles/moCapCNUlib/downloads";
tokenize $zipFileUrl "/" $tempString;
string $downloadedZipFile=$tempString[size($tempString)-1];
string $downloadedZipFilePath=$downloadDir+"/"+$downloadedZipFile;
string $downloadedMaFilePath=$downloadDir+"/"+`substitute "[.]7z" $downloadedZipFile ".ma"`;
string $cmd;

if (!`file -q -ex $downloadDir`) sysFile -md $downloadDir;

//download
if (`about -mac` || `about -linux`)
	{
	$cmd="\"curl -k -L -o "+$downloadDir+"/"+$downloadedZipFile+" "+$zipFileUrl+"\"";
	evalEcho ("system("+$cmd+")");
	}
else
	{
	$cmd="start\/wait/I \"Downloading\"  \""+$curl+"\" -k -L -o \""+$downloadDir+"/"+$downloadedZipFile+"\" "+$zipFileUrl;
	print ("// Starting Download:"+$cmd+"\n");
	system ($cmd);
	}

//confirm downloads
if (`file -q -ex $downloadedZipFilePath`)
	print ("// Downloaded sucessfully:"+$downloadedZipFilePath+";\n");
else
	error ("// Download failed, could not find:"+$downloadedZipFilePath+";\n");

//unzip
if (`about -mac` || `about -linux`)
  $cmd="unzip "+$downloadedZipFilePath+" -d "+$moCapCNUlibDir;
else
	$cmd="start\/wait/I \"Unzipping\"  \""+$zip+"\" x \""+$downloadedZipFilePath+"\" -o\""+$moCapCNUlibDir+"\"";
print ("// Starting Unzip:"+$cmd+";\n");
system($cmd);

//confirm unzip
if (`file -q -ex $downloadedMaFilePath`)
	print ("// Unzipped sucessfully:"+$downloadedMaFilePath+";\n");
else
	error ("// Unzipp failed, could not find:"+$downloadedMaFilePath);

//Delete download
if (`filetest -f $downloadedZipFilePath`)
	sysFile -del $downloadedZipFilePath;

asUpdateMoCapCNUApplyButton;
}

global proc asMCLBakeBody (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $sel[]=`ls -sl`;
string $controlSetMembers[];
string $refFiles[]=`file -q -r`;

if (!`objExists ($nameSpace+"ControlSet")`)
	error "No controlSets detected";

$controlSetMembers=`sets -q ($nameSpace+"ControlSet")`;
select $controlSetMembers;
bakeResults -simulation true -t (`playbackOptions -q -min`+":"+`playbackOptions -q -max`) -sampleBy 1 -disableImplicitControl true -preserveOutsideKeys false -sparseAnimCurveBake false -removeBakedAttributeFromLayer false 
	-bakeOnOverrideLayer false -controlPoints false -shape false $controlSetMembers;
select $controlSetMembers;
evalEcho "delete -staticChannels -unitlessAnimationCurves false -hierarchy none -controlPoints 0 -shape 1";

//remove MotionCaptureLibrary-reference
for ($i=0;$i<size($refFiles);$i++)
	if (`file -q -ns $refFiles[$i]`=="MotionCaptureLibrary")
		file -rr $refFiles[$i];
if (`objExists MotionCaptureLibraryScale`)
	delete MotionCaptureLibraryScale;

if (`namespace -ex MotionCaptureLibrary`)
	namespace -rm MotionCaptureLibrary;

catchQuiet (`select $sel`);
print ("// Body animations baked.\n");
}

global proc asMCLDisconnectBody (string $uiName)
{
float $currentTime=`currentTime -q`;
string $tempString[];

currentTime -1;
$tempString=`ls -type constraint -type multiplyDivide`;
for ($i=0;$i<size($tempString);$i++)
	if (`attributeExists moCapLibCN $tempString[$i]`)
		delete $tempString[$i];
currentTime $currentTime;

print "// Motion Capture Diconnected.\n";
}

global proc asMCLConnectBody (string $uiName)
{
int $numConnected,$altSkeletonType;
float $currentTime=`currentTime -q`;
float $distA,$distB;
float $posA[],$posB[],$posC[];
string $side,$rightLeft,$rightLeftSuffix,$topNode,$asFKFinger,$moCapFingerJoint,$hip,$knee,$ankle,$proxIntDist;
string $moCapNs="MotionCaptureLibrary:";
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $tempString[],$constraintObjs[],$constraintToObjs[],$cn[];
string $fingers[]={"Thumb","Index","Middle","Ring","Pinky"};

if (`attributeExists altSkeletonType MotionCaptureLibraryScale`)
	$altSkeletonType=`getAttr MotionCaptureLibraryScale.altSkeletonType`;

if ($currentTime!=-1)
	if (`confirmDialog -t "Confirm"
	-m ("Connecting when Not at Frame -1, could lead to unwanted offset.\n"
		+"It is recommended to connect at Frame -1.\n")
	-b "Proceed Anyway" -b "Cancel" -db "Cancel"
	-ds "Cancel"`!="Proceed Anyway")
		return;

$constraintObjs={"RootX_M","FKRoot_M","FKSpine1_M","FKChest_M","FKNeck_M","FKHead_M"};
$constraintToObjs={"Hips","Spine","Spine1","Spine3","Neck","Head"};

if ($altSkeletonType==1)
	$constraintToObjs={"pelvis","spine_01","spine_03","spine_05","neck_01","head"};

$tempString=`listRelatives -c MotionCaptureLibraryScale`;
$topNode=$tempString[0];
tokenize $topNode ":" $tempString;
$moCapNs=$tempString[0]+":";

//create poleVec PlaceHolder
for ($b=1;$b>-2;$b=$b-2)
	{
	if ($b==1)  {$side="_R";$rightLeft="Right";$rightLeftSuffix="_r";}
	if ($b==-1) {$side="_L";$rightLeft="Left";$rightLeftSuffix="_l";}

	if ($altSkeletonType==0)
		{
		if (`objExists ($moCapNs+$rightLeft+"UpLeg")`) $hip=$moCapNs+$rightLeft+"UpLeg";
		if (`objExists ($moCapNs+$rightLeft+"Leg")`) $knee=$moCapNs+$rightLeft+"Leg";
		if (`objExists ($moCapNs+$rightLeft+"Foot")`) $ankle=$moCapNs+$rightLeft+"Foot";
		}
	if ($altSkeletonType==1)
		{
		if (`objExists ($moCapNs+"thigh"+$rightLeftSuffix)`) $hip="thigh"+$rightLeftSuffix;
		if (`objExists ($moCapNs+"calf"+$rightLeftSuffix)`) $knee="calf"+$rightLeftSuffix;
		if (`objExists ($moCapNs+"foot"+$rightLeftSuffix)`) $ankle="foot"+$rightLeftSuffix;
		}
	if ($altSkeletonType==2)
		{
		if (`objExists ($moCapNs+$rightLeft+"_UpperLeg")`) $hip=$moCapNs+$rightLeft+"_UpperLeg";
		if (`objExists ($moCapNs+$rightLeft+"_LowerLeg")`) $knee=$moCapNs+$rightLeft+"_LowerLeg";
		if (`objExists ($moCapNs+$rightLeft+"_Foot")`) $ankle=$moCapNs+$rightLeft+"_Foot";
		}
	if (`objExists $hip` && `objExists $ankle`)
		{
		namespace -set $moCapNs;
		if (!`objExists PoleVectorLocators`)
			createNode -n PoleVectorLocators -p MotionCaptureLibraryScale transform;
		createNode -n ("PoleVectorLocatorOffset"+$side) -p ($moCapNs+"PoleVectorLocators") transform;
		createNode -n ("PoleVectorLocator"+$side) -p ($moCapNs+"PoleVectorLocatorOffset"+$side) transform;
		namespace -set ":";

		$posA=`xform -q -ws -t $hip`;
		$posB=`xform -q -ws -t $knee`;
		$posC=`xform -q -ws -t $ankle`;
		$distA=`mag<<$posA[0]-$posB[0],$posA[1]-$posB[1],$posA[2]-$posB[2]>>`;
		$distB=`mag<<$posB[0]-$posC[0],$posB[1]-$posC[1],$posB[2]-$posC[2]>>`;

		pointConstraint -w $distB $hip ($moCapNs+"PoleVectorLocatorOffset"+$side);
		pointConstraint -w $distA $ankle ($moCapNs+"PoleVectorLocatorOffset"+$side);
		//avoid flippped knee when straight leg
		setAttr ("PoleVectorLocatorOffset"+$side+"_pointConstraint1.offsetZ") -0.1;

		aimConstraint -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "vector" -worldUpVector 0 1 0 $knee ($moCapNs+"PoleVectorLocatorOffset"+$side);
		select $hip $ankle;
		setAttr ($moCapNs+"PoleVectorLocator"+$side+".tx") ((($distA+$distB)/2.0)/`getAttr MotionCaptureLibraryScale.sx`);
		}
	}

for ($b=1;$b>-2;$b=$b-2)
	{
	if ($b==1)  {$side="_R";$rightLeft="Right";$rightLeftSuffix="_r";}
	if ($b==-1) {$side="_L";$rightLeft="Left";$rightLeftSuffix="_l";}

	$tempString={("FKHip"+$side),("FKKnee"+$side),("FKAnkle"+$side),("FKToes"+$side),("IKLeg"+$side),("PoleLeg"+$side),("IKToes"+$side),("FKScapula"+$side),("FKShoulder"+$side),("FKElbow"+$side),("FKWrist"+$side)};
	$constraintObjs=`stringArrayCatenate $tempString $constraintObjs`;
	if ($altSkeletonType==0)
		$tempString={($rightLeft+"UpLeg"),($rightLeft+"Leg"),($rightLeft+"Leg"),($rightLeft+"ToeBase"),($rightLeft+"Foot"),("PoleVectorLocator"+$side),($rightLeft+"ToeBase"),($rightLeft+"Shoulder"),($rightLeft+"Arm"),($rightLeft+"ForeArm"),($rightLeft+"Hand")};
	if ($altSkeletonType==1)
		$tempString={("thigh"+$rightLeftSuffix),("calf"+$rightLeftSuffix),("foot"+$rightLeftSuffix),("ball"+$rightLeftSuffix),("foot"+$rightLeftSuffix),("PoleVectorLocator"+$side),("ball"+$rightLeftSuffix),("clavicle"+$rightLeftSuffix),("upperarm"+$rightLeftSuffix),("lowerarm"+$rightLeftSuffix),("hand"+$rightLeftSuffix)};
	if ($altSkeletonType==2)
		$tempString={($rightLeft+"_UpperLeg"),($rightLeft+"_LowerLeg"),($rightLeft+"_Foot"),($rightLeft+"_Toes"),($rightLeft+"_Foot"),("PoleVectorLocator"+$side),($rightLeft+"_Toes"),($rightLeft+"_Shoulder"),($rightLeft+"_UpperArm"),($rightLeft+"_LowerArm"),($rightLeft+"_Hand")};
	$constraintToObjs=`stringArrayCatenate $tempString $constraintToObjs`;

	//fingers
	for ($y=0;$y<size($fingers);$y++)
		for ($i=1;$i<4;$i++)
			{
			$asFKFinger=$nameSpace+"FK"+$fingers[$y]+"Finger"+$i+$side;
			$moCapFingerJoint=$rightLeft+"Hand"+$fingers[$y]+$i;
			if ($altSkeletonType==1)
				$moCapFingerJoint=`tolower $fingers[$y]`+"_"+`asDoPadd $i 2`+$rightLeftSuffix;
			if ($altSkeletonType==2)
				{
				if ($i==1) $proxIntDist="Proximal";
				if ($i==2) $proxIntDist="Intermediate";
				if ($i==3) $proxIntDist="Distal";
				$moCapFingerJoint=$rightLeft+"_"+$fingers[$y]+$proxIntDist;
				}
			$constraintObjs[size($constraintObjs)]=$asFKFinger;
			$constraintToObjs[size($constraintToObjs)]=$moCapFingerJoint;
			}
	}

for ($i=0;$i<size($constraintObjs);$i++)
	{
	if (!`objExists ($moCapNs+$constraintToObjs[$i])` || !`objExists ($nameSpace+$constraintObjs[$i])`)
		continue;
	if (`gmatch $constraintObjs[$i] "FK*"` || `gmatch $constraintObjs[$i] "IKToes_*"`)
		$tempString=`orientConstraint -mo ($moCapNs+$constraintToObjs[$i]) ($nameSpace+$constraintObjs[$i])`;
	else if (`gmatch $constraintObjs[$i] "Pole*"`)
		$tempString=`pointConstraint ($moCapNs+$constraintToObjs[$i]) ($nameSpace+$constraintObjs[$i])`;
	else
		$tempString=`parentConstraint -mo ($moCapNs+$constraintToObjs[$i]) ($nameSpace+$constraintObjs[$i])`;
	$cn[size($cn)]=$tempString[0];
	$numConnected++;
	}

/*fingers used to be `directConnect` v<6.003, but now allowing or Unreal FBX so including these as constraints
for ($b=1;$b>-2;$b=$b-2)
	{
	if ($b==1)  {$side="_R";$rightLeft="Right";$rightLeftSuffix="_r";}
	if ($b==-1) {$side="_L";$rightLeft="Left";$rightLeftSuffix="_l";}

	for ($y=0;$y<size($fingers);$y++)
		for ($i=1;$i<4;$i++)
			{
			$mpd="MotionCaptureLibrary"+$fingers[$y]+"FingerMPD"+$i+$side;
			if (`objExists $mpd`)
				delete $mpd;
			$moCapFingerJoint=$moCapNs+$rightLeft+"Hand"+$fingers[$y]+$i;
			if ($altSkeletonType==1)
				$moCapFingerJoint=$moCapNs+`tolower $fingers[$y]`+"_"+`asDoPadd $i 2`+$rightLeftSuffix;

			if (!`objExists $moCapFingerJoint` || !`objExists ($nameSpace+"FK"+$fingers[$y]+"Finger"+$i+$side)`)
				continue;
			createNode -n $mpd multiplyDivide;
			$cn[size($cn)]=$mpd;
			connectAttr ($moCapFingerJoint+".ry") ($mpd+".input1Y");
			connectAttr ($moCapFingerJoint+".rz") ($mpd+".input1Z");
			setAttr ($mpd+".input2Y") -1;
			if ($side=="_L")
				setAttr ($mpd+".input2Z") -1;
			connectAttr ($mpd+".outputZ") ($nameSpace+"FK"+$fingers[$y]+"Finger"+$i+$side+".ry");
			connectAttr ($mpd+".outputY") ($nameSpace+"FK"+$fingers[$y]+"Finger"+$i+$side+".rz");
			$numConnected++;
			}
	}
*/

for ($i=0;$i<size($cn);$i++)
	if (!`attributeExists moCapLibCN $cn[$i]`)
		addAttr -k 0 -ln moCapLibCN -at bool -dv 1 $cn[$i];

print ("// Motion Capture Connected ("+$numConnected+" controllers).\n");
}

global proc asMCLRemoveBody (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $refFiles[]=`file -q -r`;
string $sel[]=`ls -sl`;
string $tempString[],$tempString2[],$controlSetMembers[];

if (!`objExists ($nameSpace+"ControlSet")`)
	error "No controlSets detected. select a controller";

$controlSetMembers=`sets -q ($nameSpace+"ControlSet")`;
select $controlSetMembers;
string $animCurves[]=`listConnections -type animCurve -s 1 -d 0`;
if (size($animCurves))
	delete $animCurves;

//remove constraint
for ($i=0;$i<size($controlSetMembers);$i++)
	{
	$tempString=`listConnections -type constraint -s 1 -d 0 ($controlSetMembers[$i]+".rx")`;
	for ($y=0;$y<size($tempString);$y++)
		{
		if (!`objExists $tempString[$y]`)
			continue;
		$tempString2=`listConnections -s 1 -d 0 ($tempString[$y]+".target[0].targetRotate")`;
		if (`gmatch $tempString2[0] "MotionCaptureLibrary:*"`)
			delete $tempString[$y];
		}
	}

//remove MotionCaptureLibrary-reference
for ($i=0;$i<size($refFiles);$i++)
	if (`file -q -ns $refFiles[$i]`=="MotionCaptureLibrary")
		file -rr $refFiles[$i];
if (`objExists MotionCaptureLibraryScale`)
	delete MotionCaptureLibraryScale;

if (`objExists MoCapConstraints`)//in case of useMoCapMatcher
	delete MoCapConstraints;

$tempString=`ls "MotionCaptureLibrary:*"`;
if (size($tempString))
	delete $tempString;

$tempString=`ls "TPose:*"`;
if (size($tempString))
	delete $tempString;

if (`namespace -ex MotionCaptureLibrary`)
	namespace -rm MotionCaptureLibrary;
if (`namespace -ex TPose`)
	namespace -rm TPose;

if (`objExists ($nameSpace+"ControlSet")`) asGoToBuildPoseOptions $nameSpace "ControlSet";

catchQuiet (`select $sel`);
print ("// Body animations removed.\n");
}

global proc asMCLRemoveFace (string $uiName)
{
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $refFiles[]=`file -q -r`;
string $sel[]=`ls -sl`;
string $tempString[],$tempString2[];

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";

select -cl;
if (`objExists ($nameSpace+"FaceControlSet")`) select -add `sets -q ($nameSpace+"FaceControlSet")`;
if (`objExists ($nameSpace+"FKHead_M")`) select -add ($nameSpace+"FKHead_M");
if (`objExists ($nameSpace+"FKNeck_M")`) select -add ($nameSpace+"FKNeck_M");
	
string $animCurves[]=`listConnections -type animCurve -s 1 -d 0`;
if (size($animCurves))
	delete $animCurves;

if (`objExists ($nameSpace+"ControlSet")`) asGoToBuildPoseOptions $nameSpace "ControlSet";
if (`objExists ($nameSpace+"FaceControlSet")`) asGoToBuildPoseOptions $nameSpace "FaceControlSet";

dgdirty -a;
catchQuiet (`select $sel`);
print ("// Face Test animations removed.\n");
}

global proc asMCLTestFace (string $uiName)
{
float $keyTimes[];
string $ctrl,$attr,$clip,$asMotionFaceFile;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $asScriptLocation=`asGetScriptLocation`;
string $moCapFacelibDir=$asScriptLocation+"/AdvancedSkeletonFiles/div/motionTest/face";
string $tempString[],$tempString2[],$animCurves[];

if (!`objExists ($nameSpace+"FaceControlSet")`)
	error "No controlSets detected. select a controller";

if (`optionMenu -q -ex asMCLFaceOptionMenu`)
	$clip=`optionMenu -q -v asMCLFaceOptionMenu`;
else
	$clip=`optionMenu -q -v asATFaceOptionMenu`;
$asMotionFaceFile=$moCapFacelibDir+"/"+$clip;

if (`objExists animationTestFaceFromMoCapLibrary`)
	{
	$nameSpace=`getAttr animationTestFaceFromMoCapLibrary.nameSpace`;
	delete animationTestFaceFromMoCapLibrary;
	}
asMCLRemoveFace $uiName;
file -r -ignoreVersion -gl -mergeNamespacesOnClash false -namespace "MotionCaptureLibraryFace" -options "v=0;" $asMotionFaceFile;

$animCurves=`ls -type animCurve "MotionCaptureLibraryFace:*"`;
for ($i=0;$i<size($animCurves);$i++)
	{
	//remove old copies, if exists
	$tempString[0]=`substitute "MotionCaptureLibraryFace:" $animCurves[$i] ""`;
	$tempString=`ls ($tempString[0]+"*")`;
	if (size($tempString))
		delete $tempString;

	$tempString=`duplicate $animCurves[$i]`;
	tokenize $tempString[0] "_" $tempString2;
	$ctrl=$nameSpace+$tempString2[0]+"_"+$tempString2[1];
	$attr=$tempString2[2];
	if (!`attributeExists $attr $ctrl`)
		{
		print ("//Not found:"+$ctrl+"."+$attr+"\n");
		continue;
		}
print ("connectAttr "+$tempString[0]+".output "+$ctrl+"."+$attr+";\n");
	 catchQuiet (`connectAttr ($tempString[0]+".output") ($ctrl+"."+$attr)`);
	}
file -rr $asMotionFaceFile;
/*
playbackOptions -min 0 -ast 0 -max 330 -aet 330;
currentTime 70;
*/
if (`objExists ($nameSpace+"FaceControlSet")`)
	{
	$keyTimes=`keyframe -q -tc ($nameSpace+"ctrlMouth_M.ty")`;
	$lastKeyFrameNr=$keyTimes[size($keyTimes)-1];
	playbackOptions -min -1 -ast -1 -max $lastKeyFrameNr -aet $lastKeyFrameNr;
	}

print "// Test animation applied.\n";
}

global proc int asIsMayaLT ()
{
int $isMayaLT=0;
if (!`exists CreateWrap`)
	$isMayaLT=1;
return $isMayaLT;
}

global proc asReferenceBrowser (int $model)
{
global string $selectedNamespaceRadioButton;
string $sNRB=$selectedNamespaceRadioButton;
string $referenceOptionsRenamePrefix=`optionVar -q referenceOptionsRenamePrefix`;
int $referenceUseNamespacesDuringFileIO=`optionVar -q referenceUseNamespacesDuringFileIO`;
int $referenceOptionsUseRenamePrefix=`optionVar -q referenceOptionsUseRenamePrefix`;
string $ReferenceMergeOptionValue=`optionVar -q ReferenceMergeOptionValue`;
string $defaultFileReferenceType=`optionVar -q defaultFileReferenceType`;
string $tempString[],$topNodesBefore[],$topNodesAfter[];

string $renamePrefix="model";
string $mergeOptionValue="radioNamespaceOnString";
if (!$model)
	{
	$renamePrefix="anim";
	$mergeOptionValue="radioNamespaceOnFileName";
	}

optionVar -sv referenceOptionsRenamePrefix $renamePrefix;
optionVar -iv referenceUseNamespacesDuringFileIO 1;
optionVar -iv referenceOptionsUseRenamePrefix 1;
optionVar -sv ReferenceMergeOptionValue $mergeOptionValue;
optionVar -sv defaultFileReferenceType "mayaBinary";
if ($selectedNamespaceRadioButton!="")
	$selectedNamespaceRadioButton=$mergeOptionValue;

if (`asHotKeyCheck ("asReferenceBrowser "+$model)`) return;

if ($model)
	$topNodesBefore=`ls -as`;

if (`asIsMayaLT`)
	error ("Maya LT does not have Reference, Import the model instead");
CreateReferenceOptions;

//Something in here Ran again, makes it work
global string $selectedNamespaceRadioButton;
$sNRB=$selectedNamespaceRadioButton;
$referenceOptionsRenamePrefix=`optionVar -q referenceOptionsRenamePrefix`;
$referenceUseNamespacesDuringFileIO=`optionVar -q referenceUseNamespacesDuringFileIO`;
$referenceOptionsUseRenamePrefix=`optionVar -q referenceOptionsUseRenamePrefix`;
$ReferenceMergeOptionValue=`optionVar -q ReferenceMergeOptionValue`;
$defaultFileReferenceType=`optionVar -q defaultFileReferenceType`;

optionVar -sv referenceOptionsRenamePrefix $renamePrefix;
optionVar -iv referenceUseNamespacesDuringFileIO 1;
optionVar -iv referenceOptionsUseRenamePrefix 1;
optionVar -sv ReferenceMergeOptionValue $mergeOptionValue;
optionVar -sv defaultFileReferenceType "mayaBinary";
if ($selectedNamespaceRadioButton!="")
	$selectedNamespaceRadioButton=$mergeOptionValue;
CreateReference;

optionVar -sv referenceOptionsRenamePrefix $referenceOptionsRenamePrefix;
optionVar -iv referenceUseNamespacesDuringFileIO $referenceUseNamespacesDuringFileIO;
optionVar -iv referenceOptionsUseRenamePrefix $referenceOptionsUseRenamePrefix;
optionVar -sv ReferenceMergeOptionValue $ReferenceMergeOptionValue;
optionVar -sv defaultFileReferenceType $defaultFileReferenceType;
if ($sNRB!="")
	$selectedNamespaceRadioButton=$sNRB;

if ($model)
	$topNodesAfter=`ls -as`;
select -cl;
for ($i=0;$i<size($topNodesAfter);$i++)
	if (!`stringArrayCount $topNodesAfter[$i] $topNodesBefore`)
		select -add $topNodesAfter[$i];

if ($model)
	{
	//Hi layer
	if (`objExists Hi`)
		{
		if (`objectType Hi`=="displayLayer")
			editDisplayLayerMembers -noRecurse Hi `ls -selection`;
		}
	else
		{
		createDisplayLayer -name Hi -number 1 -nr;
		setAttr Hi.displayType 1;
		}
	}

if (!$model)
	{
	//refresh character-chooser-dropdowns
	$tempString=`lsUI -type optionMenu`;
	for ($i=0;$i<size($tempString);$i++)
		if (`gmatch $tempString[$i] "asSelector*OptionMenu"` || `gmatch $tempString[$i] "asPicker*OptionMenu"`)
			asPopulateNameSpaceMenu `substitute "OptionMenu" $tempString[$i] ""`;
	}
select -cl;
}

global proc asReferenceEditor ()
{
if (`asHotKeyCheck ReferenceEditor`) return;

ReferenceEditor;
}

global proc asFBXMissingBlendShapeTargetsFix ()
{
//seems sometimes Maya skipps writing these lines, (when bs-target has no moving points)
//setAttr ".it[0].itg[12].iti[6000].ipt" -type "pointArray" 0 ;
//setAttr ".it[0].itg[12].iti[6000].ict" -type "componentList" ;
//(This is for target number 12)
//This causes the FBX exporter to skip these targets, and also skip any folloing targets
//This workaround will re-set the attributes
string $bss[]=`ls -type blendShape`;
for ($i=0;$i<size($bss);$i++)
	{
	$numTargets=`getAttr -s ($bss[$i]+".it[0].itg")`;
	for ($y=0;$y<$numTargets;$y++)
		{
		float $ipts[]=`getAttr ($bss[$i]+".it[0].itg["+$y+"].iti[6000].ipt")`;
		if (!size($ipts))
			{
			evalEcho ("setAttr "+$bss[$i]+".it[0].itg["+$y+"].iti[6000].ipt  -type \"pointArray\" 0;");
			evalEcho ("setAttr "+$bss[$i]+".it[0].itg["+$y+"].iti[6000].ict  -type \"componentList\";");
			}
		}
	}
}

global proc asReferenceGreenShaderFix ()
{
string $obj,$dotComp,$destination;
string $shadingEngines[]=`ls -type shadingEngine`;
string $tempString[],$sel[],$historyNodes[];
string $refNodes[]=`ls -type reference`;

for ($i=0;$i<size($refNodes);$i++)
	{
	file -cleanReference $refNodes[$i];
	}

for ($i=0;$i<size($shadingEngines);$i++)
	{
	select `sets -q $shadingEngines[$i]`;
	$sel=`ls -sl`;
	if (!size($sel))
		continue;
	for ($y=0;$y<size($sel);$y++)
		{
		$dotComp="";
		tokenize $sel[$y] "." $tempString;
		$obj=$tempString[0];
		if ($tempString[1]!="")
			$dotComp="."+$tempString[1];
		if (!`getAttr ($obj+".intermediateObject")`)
			continue;
		$historyNodes=`listHistory -f 1 -interestLevel 1 $sel[$y]`;
		for ($z=0;$z<size($historyNodes);$z++)
			if (`objectType $historyNodes[$z]`=="mesh")
				if (!`getAttr ($historyNodes[$z]+".intermediateObject")`)
					{
					$destination=$historyNodes[$z]+$dotComp;
					evalEcho ("sets -e -forceElement "+$shadingEngines[$i]+" "+$destination);
					}
		}
	}
}

global proc int asHotKeyCheck (string $command)
{
if (`getModifiers`!=5)
	return 0;

global string $gShelfTopLevel;
string $currentShelf = `tabLayout -query -selectTab $gShelfTopLevel`;
string $imageOverlayLabel,$ann;
string $image="commandButton.png";
string $tempString[];
tokenize $command $tempString;
$ann=$tempString[0];

if ($command=="asReferenceBrowser 0") {$imageOverlayLabel="ref";$image="menuIconFile.png";$ann="Reference-in a new rig";}
if ($command=="ReferenceEditor") {$imageOverlayLabel="edit";$image="menuIconFile.png";$ann="Open the Reference Editor";}
if ($command=="asExportFbxBrowser \"\"") {$imageOverlayLabel="fbx";$image="menuIconFile.png";$ann="Export selected rig as FBX";}
if ($command=="asPopulateNameSpaceMenu \"\"") error "Refreshing of GUI, can not be a shelf button";
if ($command=="asFilterNameSpaceMenuUI \"\"") error "Name-filtering of GUI, can not be a shelf button";
if ($command=="asSetupControlVisibilityHotKeyDialog") error "Set Hotkey, can not be a shelf button";
if ($command=="asControlsVisibilityToggle") {$imageOverlayLabel="";$image="curveCV.png";$ann="Toggles visibility of ControlCurves";}
if ($command=="asVisualizeGimbalLock \"\"") {$imageOverlayLabel="";$image="srt.png";$ann="Visualize GimbalLock for selected ControlCurves";}
if ($command=="asFaceCtrlsDetach \"\"") {$imageOverlayLabel="";$image="BasicHead.png";$ann="Detach face-controls, for faster playback";}
if ($command=="asCopyToClipBoard \"\" 0") {$imageOverlayLabel="Copy";$image="menuIconEdit.png";$ann="Copy Pose";}
if ($command=="asPasteFromClipBoard \"\" 0") {$imageOverlayLabel="Paste";$image="menuIconEdit.png";$ann="Paste Pose";}
if ($command=="asGoToBuildPose \"\"") {$imageOverlayLabel="";$image="addSkinInfluence.png";$ann="Resets the pose for selected rig";}
if ($command=="asGoToTPose \"\"") {$imageOverlayLabel="";$image="goToBindPose.png";$ann="Go to Tpose for selected rig";}
if ($command=="asDeleteStaticChannels \"\"") {$imageOverlayLabel="clean";$image="menuIconEdit.png";$ann="Deletes static channels for selected rig";}
if ($command=="asMirror \"\"") {$imageOverlayLabel="";$image="doubleHorizArrow.png";$ann="Mirror pose for selected rig";}
if ($command=="asMirrorOptions \"\"") {$imageOverlayLabel="o";$image="doubleHorizArrow.png";$ann="Mirror (options) pose for selected rig";}
if ($command=="asCopyToClipBoard \"\" 1") {$imageOverlayLabel="Copy";$image="render_tripleShadingSwitch.png";$ann="Copy Animation";}
if ($command=="asPasteFromClipBoard \"\" 1") {$imageOverlayLabel="Paste";$image="render_tripleShadingSwitch.png";$ann="Paste Animation";}
//if ($command=="asLoadAttrs \"\" 0") {$imageOverlayLabel="Paste";$image="menuIconEdit.png";
//	$ann="Paste Animation ( Hold SHIFT button for pasting at Current Time, Hold CTRL button to ignore Main ctrl )";}
if ($command=="asAnimBake \"\"") {$imageOverlayLabel="Bake";$image="menuIconEdit.png";$ann="Bake Animation";}
if ($command=="asAutoSwitchFKIK") {$imageOverlayLabel="Switch";$image="kinHandle.png";$ann="Switch between FK & IK";}
if ($command=="asAutoSwitchPivot") {$imageOverlayLabel="Pivot";$image="counterclockwise.png";$ann="Switch the position of the Pivot";}
if ($command=="asQuickIK") {$imageOverlayLabel="IK";$image="smoothSkin.png";$ann="Create a Quick-IK e.g. IK for fingers.";}
//if ($command=="asTwistFlipUI \"\"") {$imageOverlayLabel="Flip";$image="srt.png";$ann="Set amount of twist before flipping (constraint-casching)";}
if ($command=="asHumanIKUI \"\"") {$imageOverlayLabel="HIK";$image="HIKcreateControlRig.png";$ann="Create HumanIK";}
if ($command=="asMappingUI moCapMatcher \"\"") {$imageOverlayLabel="MoCap";$image="motionPath.png";$ann="Tool for attaching rig to a MotionCapture skeleton";}
if ($command=="asMoCapLibraryUI \"\"") {$imageOverlayLabel="Lib";$image="batchRender.png";$ann="MotionCapture library";}
if ($command=="asConnectARKitUI \"\"") {$imageOverlayLabel="AR";$image="yawPitch.png";$ann="Connect Face-Motion-Capture ( ARKit )";}
if ($command=="asConnectMocapX \"\"") {$imageOverlayLabel="X";$image="yawPitch.png";$ann="Connect Face-Motion-Capture ( MocapX )";}
if ($command=="asAutoLipSyncUI \"\"") {$imageOverlayLabel="Sync";$image="123d.png";$ann="Connect Face-Motion-Capture ( MocapX )";}
if ($command=="asDynAdd \"\"") {$imageOverlayLabel="Dyn";$image="hairDynamicCurves.png";$ann="Add dynamics to selected controller";}
if ($command=="asDynAddHairSystem \"\"") {$imageOverlayLabel="Dyn";$image="hairDynamicCurves.png";$ann="Add dynamics to selected controller";}
if ($command=="asDynRemove \"\"") {$imageOverlayLabel="Rem";$image="hairDynamicCurves.png";$ann="Remove dynamics to selected controller";}
if ($command=="asDynSetInitialState \"\"") {$imageOverlayLabel="Set";$image="interactivePlayback.png";$ann="Set Initial State for all dynamics";}
if ($command=="asDynSetInteractivePlayback \"\"") {$imageOverlayLabel="Play";$image="interactivePlayback.png";$ann="Allows interaction with objects during playback";}
if ($command=="asDynBake \"\"") {$imageOverlayLabel="Bake";$image="hairDynamicCurves.png";$ann="Bake all dynamics";}
if ($command=="asParentAdd \"\" 0") {$imageOverlayLabel="Parent";$image="parentConstraint.png";$ann="Add parent constraint";}
if ($command=="asParentAdd \"\" 1") {$imageOverlayLabel="Parent";$image="parentConstraint.png";$ann="Add parent constraint (Extra)";}

setParent $currentShelf;
shelfButton
	-command $command
	-annotation $ann
	-label $tempString[0]
	-imageOverlayLabel $imageOverlayLabel
	-image $image
	-image1 $image
	-sourceType "mel";

return 1;
}

global proc string asNameSpaceFromSelection ()
{
string $nameSpace;
string $sel[]=`ls -sl`;
string $tempString[];

for ($i=0;$i<size($sel);$i++)
	{
	if (!`gmatch $sel[$i] "*:*"`)
		continue;
	tokenize $sel[$i] ":" $tempString;
	if (!`objExists ($tempString[0]+":Group")`)
		continue;
	$nameSpace=$tempString[0]+":";
	}
return $nameSpace;
}

global proc string asNameSpaceFromUIName (string $uiName)
{
string $nameSpace;
if ($uiName=="")
	$nameSpace=`asNameSpaceFromSelection`;
else if ($uiName=="asPanel")
	{
	global string $gAsPanelNamespace;
	 $nameSpace=$gAsPanelNamespace;
	if ($nameSpace==":")
		$nameSpace="";
	}
else if (`optionMenu -q -ex ($uiName+"OptionMenu")`)
	{
	$nameSpace=`optionMenu -q -v ($uiName+"OptionMenu")`;
	if ($nameSpace==":")
		$nameSpace="";
	}

return $nameSpace;
}

global proc string asNameSpaceFromShortUIName (string $shortUIName)
{
//e.g asKey "biped" vs asExportFbxBrowser "asSelectorbiped", some functions do not use the "asSelector" prefix
string $nameSpace;
if ($shortUIName=="asPanel")
	{
	global string $gAsPanelNamespace;
	 $nameSpace=$gAsPanelNamespace;
	if ($nameSpace==":")
		$nameSpace="";
	}
else if (`optionMenu -q -ex ("asSelector"+$shortUIName+"OptionMenu")`)
	{
	$nameSpace=`optionMenu -q -v ("asSelector"+$shortUIName+"OptionMenu")`;
	if ($nameSpace==":")
		$nameSpace="";
	}
else
	$nameSpace=$shortUIName;//this proc could be called from the standalone asAutoSwitchFKIK function, then $name is $nameSpace

return $nameSpace;
}

global proc string[] asNameControlSetsFromUiName (string $uiName)
{
global string $gControlSet;
int $selectedTabIndex;
string $nameSpace=`asNameSpaceFromUIName $uiName`;
string $controlSetsText,$cmd,$cmdResult;
string $tempString[],$tabLabels[];
string $sel[]=`ls -sl`;
string $controlSets[];

/*Removed this, as we want to get result even if any geo is selected e,g for GoToBuildPose
if ($uiName=="" && $sel[0]!="")
	{
	if (`objExists ($nameSpace+"ControlSet")`)
		if (`sets -im ($nameSpace+"ControlSet") $sel[0]`)
			$controlSets[0]=($nameSpace+"ControlSet");
	if (`objExists ($nameSpace+"FaceControlSet")`)
		if (`sets -im ($nameSpace+"FaceControlSet") $sel[0]`)
			$controlSets[0]=($nameSpace+"FaceControlSet");
	}
*/
//Note new behaviour does not require selection, so assuming Body, but if Face Sel then Face
if ($uiName=="")
	{
	if (`objExists ($nameSpace+"ControlSet")`)
			$controlSets[0]=($nameSpace+"ControlSet");
	if (`objExists ($nameSpace+"FaceControlSet")`)
		if ($sel[0]!="")
			if (`sets -im ($nameSpace+"FaceControlSet") $sel[0]`)
				$controlSets[0]=($nameSpace+"FaceControlSet");
	}
else if ($uiName=="bodySetup")
	$controlSets[0]="ControlSet";
else if ($uiName=="faceSetup")
	$controlSets[0]="FaceControlSet";
else if (`text -q -ex ($uiName+"ControlSetsText")`)//Selector
	{
	$controlSetsText=`text -q -l ($uiName+"ControlSetsText")`;
	tokenize $controlSetsText $tempString;
	for ($i=0;$i<size($tempString);$i++)
		if (`objExists ($nameSpace+$tempString[$i])`)
			$controlSets[size($controlSets)]=$nameSpace+$tempString[$i];
	}
else if ($uiName=="asPicker" && `tabLayout -q -ex asPickerTabLayout`)//Picker
	{
	$tabLabels=`tabLayout -q -tl asPickerTabLayout`;
	$selectedTabIndex=`tabLayout -q -selectTabIndex asPickerTabLayout`;
	if (`gmatch $tabLabels[$selectedTabIndex-1] "*face*"`)
		$controlSets[0]=$nameSpace+"FaceControlSet";
	else
		$controlSets[0]=$nameSpace+"ControlSet";
	}
else if ($uiName=="asPoserDefault" && `menuItem -q -ex asPoserControlSetsMenu`)//PoserDesigner
	{
	$tempString=`menu -q -ia asPoserControlSetsMenu`;
	for ($i=0;$i<size($tempString);$i++)
		if (`menuItem -q -cb $tempString[$i]`)
			$controlSets[size($controlSets)]=$nameSpace+`menuItem -q -l $tempString[$i]`;
	}
else if ($uiName=="asPanel")//ControlPanel
	{
	$cmd="import __main__\n";
	$cmd+="import maya.mel as mel\n";
	$cmd+="ui=getattr(__main__,'panel_ui',None)\n";
	$cmd+="s=getattr(ui,'scene',None)\n";
	$cmd+="i=getattr(s,'items',[])\n";
	$cmd+="r=''\n";
	$cmd+="for item in i():\n";
	$cmd+="    if hasattr(item,'select_str') and 'ControlSet' in item.select_str:\n";
	$cmd+="        r=item.select_str\n";
	$cmd+="        break\n";
	$cmd+="mel.eval('global string $gControlSet; $gControlSet = \\\"' + r + '\\\"')\n";
	python($cmd);
	string $cmdResult=$gControlSet;
	if ($cmdResult=="FaceControlSet")
		$controlSets[size($controlSets)]=$nameSpace+"FaceControlSet";
	else
		$controlSets[size($controlSets)]=$nameSpace+"ControlSet";
	}
else if (`objExists ($nameSpace+"ControlSet")`)
	$controlSets[0]=$nameSpace+"ControlSet";

return $controlSets;
}

global proc asExportFbxBrowser (string $uiName)
{
global string $asFbxExportedFile;
int $withGUIOptions=1;
string $nameSpace,$deformationSystem,$exportFbxPre,$exportFbxPost,$file;
string $sel[]=`ls -sl`;
string $controlSets[],$tempString[];

if (`asHotKeyCheck "asExportFbxBrowser \"\""`) return;
$nameSpace=`asNameSpaceFromUIName $uiName`;
$controlSets=`asNameControlSetsFromUiName $uiName`;
if ($uiName=="" && $controlSets[0]=="" && `objExists ControlSet`)
	$controlSets[0]="ControlSet";
if (!size($controlSets))
	error "No controlSets detected. select a controller"; 

string $plugins[]=`pluginInfo -q -ls`;
for ($plug in $plugins)
	if (!`stringArrayCount "fbxmaya" $plugins`)
	error "You Must Load the \"fbxmaya\" plugin !";

$deformationSystem=$nameSpace+":DeformationSystem";
if (`objExists ($nameSpace+"|root")`) //Unreal Skeleton
	$deformationSystem=$nameSpace+"|root";
if (`objExists ($nameSpace+"|GameSkeletonRoot_M")`) //Custom oriented GameSkeletonRoot
	$deformationSystem=$nameSpace+"|GameSkeletonRoot_M";

if (`objExists |Geometry`)
	select $deformationSystem |Geometry;
else
	{
	select $deformationSystem ($nameSpace+":Geometry");
	refresh;
	}

//custom code can be added
$asFbxExportedFile="";
if (`attributeExists exportFbxPre fbxExportOptions`) $exportFbxPre=`getAttr fbxExportOptions.exportFbxPre`;
if (`attributeExists exportFbxPost fbxExportOptions`) $exportFbxPost=`getAttr fbxExportOptions.exportFbxPost`;
if ($exportFbxPre!="") evalEcho ($exportFbxPre);

//if (`objExists asMannequinExporting`) //no GUIOptions for Mannequin Export, because we need `ExportSelection` for options, and that does not `return` $file
//	$withGUIOptions=0;

//if ($withGUIOptions)
	{
	optionVar -sv "defaultFileExportActiveType" "FBX export";
	ExportSelection;
	}
/*
else
	{
	//FBXProperties;
	FBXProperty Export|IncludeGrp|Animation -v 1;
	FBXProperty Export|IncludeGrp|Animation|BakeComplexAnimation -v 1;
	if (`objExists |Geometry`)
		{
		FBXProperty Export|IncludeGrp|Animation -v 0;
		FBXProperty Export|IncludeGrp|Animation|BakeComplexAnimation -v 0;
		}
	FBXProperty Export|IncludeGrp|Audio -v 0;
	FBXProperty Export|IncludeGrp|InputConnectionsGrp|IncludeChildren -v 1;
	FBXProperty Export|IncludeGrp|InputConnectionsGrp|InputConnections -v 0;
	$tempString=`fileDialog2 -fileFilter "*.fbx" -dialogStyle 2`;
	$file=$tempString[0];
	$asFbxExportedFile=$file;
	if ($file!="")
		FBXExport -f $file -s;
	}
*/

if ($exportFbxPost!="") evalEcho ($exportFbxPost);
print "// Fbx exported.\n";
}

global proc asDecomposeOPM ()
{
float $m[];
string $deformJointsList[]=`sets -q "DeformSet"`;
string $tempString[];

createNode -n tempMatrixTransform transform;
$m=`xform -q -os -m tempMatrixTransform`;
delete tempMatrixTransform;
for ($i=0;$i<size($deformJointsList);$i++)
	{
	createNode -n ($deformJointsList[$i]+"DM") decomposeMatrix;
	setAttr ($deformJointsList[$i]+"DM.inputRotateOrder") `getAttr ($deformJointsList[$i]+".ro")`;
	connectAttr ($deformJointsList[$i]+"DM.outputTranslate") ($deformJointsList[$i]+".t");
	connectAttr ($deformJointsList[$i]+"DM.outputRotate") ($deformJointsList[$i]+".r");
	connectAttr ($deformJointsList[$i]+"DM.outputScale") ($deformJointsList[$i]+".s");
	connectAttr ($deformJointsList[$i]+"DM.outputShear") ($deformJointsList[$i]+".shear");

	$tempString=`listConnections -s 1 -d 0 -p 1 ($deformJointsList[$i]+".offsetParentMatrix")`;
	disconnectAttr $tempString[0] ($deformJointsList[$i]+".offsetParentMatrix");
	setAttr ($deformJointsList[$i]+".offsetParentMatrix") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
	connectAttr $tempString[0] ($deformJointsList[$i]+"DM.inputMatrix");
	}
}
/*
global proc string asCRInjectLine (string $ctrl,string $parent,string $joint,string $type,string $typeEls,string $gizmo)
{
int $colorIndex,$ws;
float $diameter;
float $rbg[],$offT[],$offR[];
string $injectLine;
string $tempString[];

if ($ctrl=="Main" || $ctrl=="RootX_M" || `gmatch $ctrl "IK*"` || `gmatch $ctrl "Pole*"` || `gmatch $ctrl "ctrl*"`)//
	$ws=1;
$diameter=`asControlDiameter $ctrl`;
if ($type=="OnFace")
	$diameter*=10;
//$offT=`asControlOffT $ctrl $ws`;
$offT=`asControlOffset $ctrl`;
$tempString=`listRelatives -s $ctrl`;
$rbg={1,0,0};
$colorIndex=`getAttr ($tempString[0]+".overrideColor")`;
//if ($type=="ctrlBox")
if (`gmatch $ctrl "ctrl*"`)
	$colorIndex=17;
if ($colorIndex>0 && $colorIndex<32)
	$rbg=`colorIndex -q $colorIndex`;

if ($typeEls=="") $typeEls="{}";
$injectLine+="	asAddCtrl ('"+$ctrl+"','"+$parent+"','"+$joint+"','"+$type+"',"
						+$typeEls+",'"
						+$gizmo+"',"+$ws+","+$diameter+","+"["+$offT[0]+", "+$offT[1]+", "+$offT[2]+"],"
						+"["+$rbg[0]+", "+$rbg[1]+", "+$rbg[2]+", 1.0])\n";

return $injectLine;
}
*/
/*
global proc asExportControlRig ()
{
global string $ueVersion;
int $fileId,$fileId2,$copyLines,$ikNum,$skipFaceSetup,$numAttrCtrls;
int $numCtrls=2;
float $pmax,$value,$driverValue;
float $pos[],$jos[],$pa[],$sa[],$pp[],$keyXValues[];
string $fDet,$nextLine,$injectLines,$ctrl,$parent,$joint,$name,$side,$pyFile,$startJoint,$middleJoint,$endJoint,$poleVector,$parentInIk,$file;
string $parentJoint,$fitJoint,$fitJointParent,$arrayInfo,$fitJointTwistJoints,$fitJointInbetweenJoints,$restoreCmd,$type,$gizmo,$parentConstraint;
string $as2crFile=`asGetScriptLocation`+"/AdvancedSkeletonFiles/div/as2cr/4x.py";
string $tempString[],$tempString2[],$tempString3[],$tempString4[],$IKJoints[],$jointsInIk[],$jointsInIk2[],$iks[],$parents[];
string $ikStartJoints[],$ikEndJoints[],$ikArrayInfo[],$deformJoints[],$userAttrs[],$attrs[],$animCurves[],$tongueCtrls[],$eyeCtrls[];
string $controlSetMembers[],$faceControlSetMembers[];
if (`objExists FaceControlSet`)
	$faceControlSetMembers=`sets -q FaceControlSet`;
else
	$skipFaceSetup=1;

if (`objExists "|root"` || `objExists "UnrealRoot"`)
	error "Unreal Joints found. Export ControlRig does not work with these joints. Only with standard AdvancedSkeleton joints.";

if (!`objExists ControlSet`)
	error "ControlSet not found, no valid AdvancedSkeleoton tig in this scene.";
$controlSetMembers=`sets -q ControlSet`;

if (!`objExists ctrlBox`)
	$skipFaceSetup=1;
if (`objExists ctrlBox` && !`objExists asFaceBS`)
	{
	if (`confirmDialog -t "Confirm"
	-m ("FaceSetup detected,\n"
		+"but it is not \"BlendShape FaceSetup\"\n\n"
		+"Only \"BlendShape FaceSetup\" can be exported.\n"
		+"To export FaceSetup for this rig,\n"
		+"you must first go to the Face>BlendShapes section, and run \"convert\".\n\n"
		+"Or, Click OK to export BodySetup only")
	-b "OK" -b "Cancel" -db "Cancel"
	-ds "Cancel"`!="OK")
		return;
	$skipFaceSetup=1;
	}
if (`objExists ctrlBox` && `objExists asFaceBS` && `objExists EyeBrowInner_R`)
	{//Mixed uses Layered-deformation, ot compatible with Unreal
	if (`confirmDialog -t "Confirm"
	-m ("\"Mixed\" type FaceSetup detected,\n\n"
		+"Only \"BlendShapes\" type FaceSetup can be exported.\n"
		+"Click OK to export BodySetup only")
	-b "OK" -b "Cancel" -db "Cancel"
	-ds "Cancel"`!="OK")
		return;
	$skipFaceSetup=1;
	}

//EarlyAccess2 : Version: 5.0.0-16682836+++UE5+Release-5.0-EarlyAccess
//Preview2 : Version: 5.0.0-19206456+++UE5+Release-5.0
if (`objExists boxManTest`)
	{
	$pyFile="C:/temp/FBX/boxMan.py";
	$ueVersion="5.1";
	}
if (!`objExists boxManTest`)
	if (`layoutDialog -t "version" -ui asECRLayout`!="OK")
		return;
$fileName=`substituteAllString $ueVersion " " ""`;
$fileName=`substituteAllString $fileName "[.]" ""`;
$file=`asGetScriptLocation`+"/AdvancedSkeletonFiles/div/as2cr/"+$fileName+".py";
if (!`file -q -ex $file`)
	error ("Template file not found:"+$file);
$as2crFile=$file;

if (!`objExists boxManTest`)
	{
	$tempString=`fileDialog2 -fileFilter "*.py" -dialogStyle 2`;
	$pyFile=$tempString[0];
	}
if ($pyFile=="")
	return;

$injectLines+=`asCRInjectLine "Main" "MainSystem" "DeformationSystem" "Main" "" "Circle_Thick"`;
$injectLines+=`asCRInjectLine "RootX_M" "Main" "Root_M" "FK" "" "Arrow4_Thin"`;

//IK
for ($i=0;$i<size($controlSetMembers);$i++)
	{
	if (!`gmatch $controlSetMembers[$i] "FKIK*"`)
		continue;
	if (!`attributeExists FKIKBlend $controlSetMembers[$i]`)
		continue;
	if (`getAttr ($controlSetMembers[$i]+".FKIKBlend")`<10)
		continue;
	$ctrl=`substitute "FKIK" $controlSetMembers[$i] "IK"`;
	if (!`objExists $ctrl`)
		continue;
	$iks[$ikNum]=$ctrl;
	tokenize $controlSetMembers[$i] "_" $tempString;
	$side="_"+$tempString[size($tempString)-1];
	$startJoint=`getAttr ($controlSetMembers[$i]+".startJoint")`+$side;
	$middleJoint=`getAttr ($controlSetMembers[$i]+".middleJoint")`+$side;
	$endJoint=`getAttr ($controlSetMembers[$i]+".endJoint")`+$side;
	$joint=$endJoint;
	$IKJoints=`asGetIKJoints $startJoint $endJoint`;
	$ikStartJoints[$ikNum]=$startJoint;
	$ikEndJoints[$ikNum]=$endJoint;
	for ($y=0;$y<size($IKJoints);$y++)
		{
		$jointsInIk[size($jointsInIk)]=$IKJoints[$y];
		$jointsInIk2[size($jointsInIk2)]=$ctrl;
		}
	//pri axis
	$pa={1,0,0};
	$pos=`getAttr ($middleJoint+".t")`;
	$pMax=abs($pos[0]);
	if (abs($pos[1])>$pMax) {$pa={0,1,0};$pMax=abs($pos[1]);}
	if (abs($pos[2])>$pMax) {$pa={0,0,1};$pMax=abs($pos[2]);}
	if (($pos[0]+$pos[1]+$pos[2])<0) {$pa[0]*=-1;$pa[1]*=-1;$pa[2]*=-1;}
	//sec axis
	$sa={0,1,0};
	$jos=`getAttr ($middleJoint+".jo")`;
	$pMax=abs($jos[1]);
	//sec axis appear to be Not bendAxis, but other other one, so swapping these
	if (abs($jos[1])>$pMax) {$sa={0,0,1};$pMax=abs($jos[1]);}
	if (abs($jos[2])>$pMax) {$sa={0,1,0};$pMax=abs($jos[2]);}
	//flipping based on pri && sec axis
	if (($pos[0]+$pos[1]+$pos[2])<0) {$sa[0]*=-1;$sa[1]*=-1;$sa[2]*=-1;}
	if (($jos[0]+$jos[1]+$jos[2])<0) {$sa[0]*=-1;$sa[1]*=-1;$sa[2]*=-1;}
	//$pp polePos
	$poleVector=`substitute "FKIK" $controlSetMembers[$i] "Pole"`;
	$pp={0,0,0};
	if (`objExists $poleVector`) {$pos=`xform -q -ws -t $poleVector`;$pp={$pos[0],$pos[1],$pos[2]};}

	$ikArrayInfo[$ikNum]="{'startJoint':'"+$startJoint+"','middleJoint':'"+$middleJoint+"','endJoint':'"+$endJoint+"',"
		+"'paX':'"+$pa[0]+"','paY':'"+$pa[1]+"','paZ':'"+$pa[2]+"',"
		+"'saX':'"+$sa[0]+"','saY':'"+$sa[1]+"','saZ':'"+$sa[2]+"',"
		+"'ppX':'"+$pp[0]+"','ppY':'"+$pp[1]+"','ppZ':'"+$pp[2]+"'}";

	$ikNum++;
	}

//FK
//temporarily reParenting, to get complete Spine first in $deformJoints list
$tempString=`listRelatives -type joint Root_M`;
for ($i=0;$i<size($tempString);$i++)
	if (!`gmatch $tempString[$i] "*_M"`)
		{
		parent -w $tempString[$i];
		$restoreCmd+="parent "+$tempString[$i]+" Root_M;";
		}

$tempString2=`listRelatives -type joint -ad DeformationSystem`;
if ($restoreCmd!="") eval $restoreCmd;
$restoreCmd="";
for ($i=0;$i<size($tempString);$i++)
	if (`gmatch $tempString[$i] "*_M"`)
		{
		parent -w $tempString[$i];
		$restoreCmd+="parent "+$tempString[$i]+" Root_M;";
		}
$tempString3=`listRelatives -type joint -ad DeformationSystem`;
if ($restoreCmd!="") eval $restoreCmd;
$tempString3=`stringArrayRemove {"Root_M"} $tempString3`;
$deformJoints=`stringArrayCatenate $tempString3 $tempString2`;

for ($y=size($deformJoints)-1;$y>-1;$y--)
	{
	$joint=$deformJoints[$y];
	$ctrl="FK"+$joint;
	if (!`objExists $ctrl`)
		continue;
	if (!`sets -im ControlSet $ctrl`)
		continue;

	tokenize $deformJoints[$y] "_" $tempString;
	$fitJoint=$tempString[0];
	if (!`objExists $fitJoint`)
		{
		warning ("FitJoint: \""+$fitJoint+"\" is missing, unable to scan this for FitAttributes & Ik-Labels.");
		continue;
		}
	$side="_"+$tempString[1];
	$tempString=`listRelatives -p -type joint $fitJoint`;
	$fitJointParent=$tempString[0];

	for ($a=0;$a<size($ikStartJoints);$a++)
		if ($joint==$ikStartJoints[$a])
			{
			//IK
			$ikNum=$a;
			$ctrl=$iks[$ikNum];
			$injectLines+=`asCRInjectLine $ctrl "Main" $ikEndJoints[$ikNum] "IK" $ikArrayInfo[$ikNum] "Box_Thick"`;
			$numCtrls++;
			continue;
			}
	if (`stringArrayCount $joint $jointsInIk`)
		continue;

	$parentJoint="";
	$tempString2=`listRelatives -f -p $joint`;
	tokenize $tempString2[0] "|" $parents;
	for ($z=size($parents)-1;$z>-1;$z--)
		{
		if (`gmatch $parents[$z] "*Part[0-9]*"`)
			continue;
		if (`attributeExists visibility ("FK"+$parents[$z]+"Shape")`)
			if (`getAttr ("FK"+$parents[$z]+"Shape.v")`==0)//noControl
				continue;
		$parentJoint=$parents[$z];
		break;
		}
	$parent="RootX_M";
	$parentInIk="";
	for ($a=0;$a<size($ikEndJoints);$a++)
		if ($parentJoint==$ikEndJoints[$a])
			{
			$parentInIk=$iks[$a];
			$parent=$parentInIk;//IK
			break;
			}
	if ($parentInIk=="")//FK
		{
		if (`objExists ("FK"+$parentJoint)`)
			$parent="FK"+$parentJoint;
		//special case if parent is Root, and has InbetweenJoints
		if ($parent=="FKRoot_M" && `attributeExists inbetweenJoints $fitJointParent`)
			$parent="RootX_M";
		}

	//FitAttributes
	$arrayInfo="{";
	clear $userAttrs;
	if (`objExists $fitJoint`)
 		$userAttrs=`listAttr -ud -s $fitJoint`;
	for ($i=0;$i<size($userAttrs);$i++)
		{
		if (`gmatch $userAttrs[$i] "fat*"`)
			continue;
		if ($userAttrs[$i]=="twistJoints")
			if (`getAttr ($fitJoint+".twistJoints")`==0)
				continue;//LogPython: Error: ZeroDivisionError: float division by zero
		if ($userAttrs[$i]=="inbetweenJoints")
			if (`getAttr ($fitJoint+".inbetweenJoints")`==0)
				continue;//ALSO LogPython: Error: ZeroDivisionError: float division by zero
		if ($arrayInfo!="{")
			$arrayInfo+=",";
		$value=`getAttr ($fitJoint+"."+$userAttrs[$i])`;
		//if Global Attribute exist on FK-control, then use that value.
		if ($userAttrs[$i]=="global")
			if (`attributeExists "Global" ("FK"+$joint)`)
				$value=`getAttr ("FK"+$joint+".Global")`;
		$arrayInfo+="'"+$userAttrs[$i]+"':'"+$value+"'";
		}
	$arrayInfo+="}";

	$injectLines+=`asCRInjectLine $ctrl $parent $joint "FK" $arrayInfo "Circle_Thick"`;
	$numCtrls++;
	}

//DrivingSystems
for ($i=0;$i<size($controlSetMembers);$i++)
	{
//	$tempString=`listRelatives -p $controlSetMembers[$i]`;
	$tempString=`ls -l $controlSetMembers[$i]`;
	if (!`gmatch $tempString[0] "*|DrivingSystem|*"`)
		continue;
	$ctrl=$controlSetMembers[$i];
	$parentConstraint=$ctrl+"_parentConstraint1";
	if (!`objExists $parentConstraint`)
		continue;
	$tempString=`listConnections -s 1 -d 0 ($parentConstraint+".target[0].targetTranslate")`;
	$joint=$tempString[0];

	$arrayInfo=`asDSArrayInfo $ctrl`;
	$numAttrCtrls=$numAttrCtrls+size(`asDsGetAttrs $ctrl`);

	$injectLines+=`asCRInjectLine $ctrl "Main" $joint "DrivingSystem" $arrayInfo "Circle_Thick"`;
	$numCtrls++;
	}
$arrayInfo="";

//FaceSetup
if (!$skipFaceSetup)
	{
	//sort Tongue ctrls
	for ($i=0;$i<99;$i++)
		if (`objExists ("Tongue"+$i+"_M")`)
			$tongueCtrls[$i]="Tongue"+$i+"_M";
	$faceControlSetMembers=`stringArrayRemove $tongueCtrls $faceControlSetMembers`;
	$faceControlSetMembers=`stringArrayCatenate $faceControlSetMembers $tongueCtrls`;
	//sort order of Eye>Iris>Pupil
	$eyeCtrls={"Eye_R","Eye_L","Iris_R","Iris_L","Pupil_R","Pupil_L"};
	$faceControlSetMembers=`stringArrayRemove $eyeCtrls $faceControlSetMembers`;
	for ($i=0;$i<size($eyeCtrls);$i++)
		if (`objExists $eyeCtrls[$i]`)
			$faceControlSetMembers[size($faceControlSetMembers)]=$eyeCtrls[$i];


	if (`getAttr ctrlBox.EyeCtrlVis`==0)
	setAttr ctrlBox.EyeCtrlVis 1;//need eyeCtrls visible to ensure they export
	$restoreCmd="setAttr ctrlBox.EyeCtrlVis 0;";

	for ($i=0;$i<size($faceControlSetMembers);$i++)
		{
		$ctrl=$faceControlSetMembers[$i];
		tokenize $ctrl "_" $tempString;
		$name=$tempString[0];
		$side="_"+$tempString[1];
		$joint=$name+"Joint"+$side;
		$parent="FKHead_M";
		if (!`objExists $joint`)
			continue;
		$tempString=`ls -l $joint`;
		tokenize $tempString[0] "|" $tempString;
		if (!`stringArrayCount "DeformationSystem" $tempString`)
			continue;
		$tempString=`listRelatives -s $ctrl`;
		if (!`getAttr ($tempString[0]+".overrideVisibility")`)
			continue;
		$gizmo="Gizmo";
		$type="OnFace";
		if (`gmatch $ctrl "Tongue*"` || $ctrl=="Jaw_M" || `gmatch $ctrl "Eye_*"` || `gmatch $ctrl "Iris_*"` || `gmatch $ctrl "Pupil_*"`)
			{
			$gizmo="Circle_Thick";
			$type="FK";
			$tempString=`listRelatives -p $joint`;
			$parentJoint=`substitute "Joint" $tempString[0] ""`;
			if (`objExists $parentJoint`)
				$parent=$parentJoint;
			}
		$injectLines+=`asCRInjectLine $ctrl $parent $joint $type $arrayInfo $gizmo`;
		$numCtrls++;
		}
	if (`objExists ctrlBox`)
		{
//		$arrayInfo="{'ctrlBoxSize':'"+`getAttr ctrlBoxBrow_R.sx`+"'}";
		$arrayInfo="{'ctrlBoxSize':'"+(`getAttr ctrlBoxShape.boundingBoxMaxX`/3.0)+"'}";
		$injectLines+=`asCRInjectLine ctrlBox "FKHead_M" "Head_M" "ctrlBox" $arrayInfo "Square_Thick"`;
		$arrayInfo="";
		$tempString=`listRelatives -c -type transform ctrlBox`;
		for ($i=0;$i<size($tempString);$i++)
			{
			$tempString2=`listRelatives -c -type transform $tempString[$i]`;
			$ctrl=$tempString2[0];
			if ($ctrl=="")
				continue;//allowing for deleted controller
			$attrs=`asDsGetAttrs $ctrl`;

			$arrayInfo=`asDSArrayInfo $ctrl`;
			$numAttrCtrls=$numAttrCtrls+size(`asDsGetAttrs $ctrl`);
			$injectLines+=`asCRInjectLine $ctrl "ctrlBox" "ctrlBox" "ctrlBox" $arrayInfo "Gizmo"`; 
			$numCtrls++;
			}
		}
	if ($restoreCmd!="") eval $restoreCmd;
	}


$fileId2=`fopen $as2crFile "r"`;
$nextLine="The next line";
$copyLines=1;
while (size($nextLine)>0)
	{
	$nextLine=`fgetline $fileId2`;
	if ($nextLine=="# exported using AdvancedSkeleton version:x.xx\n")
		$nextLine="# exported using AdvancedSkeleton version:"+`asGetScriptVersion`+"\n";
	if ($nextLine=="asExportVersion = x.xx\n")
		$nextLine="asExportVersion = "+`asGetScriptVersion`+"\n";

	if ($nextLine=="asExportTemplate = '4x'\n")
		$nextLine="asExportTemplate = '"+$fileName+"'\n";

	if ($nextLine=="	#//-- ASControllers Starts Here --//\n")
		{
		$copyLines=0;
		$fDet+=$nextLine;
		$fDet+=$injectLines;
		}
	if ($nextLine=="	#//-- ASControllers Ends Here --//\n")
		$copyLines=1;
	if ($copyLines)
		$fDet+=$nextLine;
	}
fclose $fileId2;

$fileId=`fopen $pyFile "w"`;
fprint $fileId $fDet;
fclose $fileId;
select -cl;
print ("// ControlRig python script exported ("+$numCtrls+" Controllers, and "+$numAttrCtrls+" AttributeSliders) (Unreal "+$fileName+".py template).\n");
}
*/
/*
global proc asECRLayout ()
{
global string $ueVersion;
//$ueVersion="5.1";
string $as2crDir=`asGetScriptLocation`+"/AdvancedSkeletonFiles/div/as2cr";
string $fileList[]=`getFileList -fld ($as2crDir+"/") -fs "*.py"`;
$fileList=`sort $fileList`;

columnLayout;
	text -l "Unreal Engine version you wish to export to:";
	separator -st none -h 10;
	optionMenu -cc "$ueVersion=\"#1\"" unrealControlRigVersionOptionMenu;
	for ($i=0;$i<size($fileList);$i++)
		menuItem -l `substitute "[.]py" $fileList[$i] ""`;
	separator -st none -h 25;
	rowLayout -nc 4;
		separator -w 10 -st none;
		button -l "OK" -c "layoutDialog -dismiss \"OK\";";
		separator -w 10 -st none;
		button -l "Cancel" -c "layoutDialog -dismiss \"Cancel\"";
		setParent..;
	setParent..;
optionMenu -e -sl `size($fileList)` unrealControlRigVersionOptionMenu;
$ueVersion=`optionMenu -q -v unrealControlRigVersionOptionMenu`;
}
*/
global proc asUMJLayout ()
{
global string $unrealMannequinJoints;
$unrealMannequinJoints="Manny (UE5)";
global string $unrealMannequinJointsMCRV;
$unrealMannequinJointsMCRV="5.6";
global int $unrealMannequinScale;
global int $unrealMannequinBodyRig;
global int $unrealMannequinFaceOpenFolder;
global int $unrealMannequinUnrealPrefix;
int $hasAsFaceBS=`objExists asFaceBS`;
$unrealMannequinFaceOpenFolder=$hasAsFaceBS;
int $manualCreatingUnrealMannequinJoints=`objExists asManualCreatingUnrealMannequinJoints`;
$unrealMannequinScale=1;
$unrealMannequinBodyRig=1;
$unrealMannequinUnrealPrefix=1;
//$unrealMannequinFaceRig=$hasAsFaceBS;
columnLayout;
	text -l "Unreal Mannequin you wish to use:";
	separator -st none -h 10;
	optionMenu -cc "$unrealMannequinJoints=\"#1\"" unrealMannequinJointsOptionMenu;
		menuItem -l "Mannequin (UE4)";
		menuItem -l "Manny (UE5)";
		menuItem -l "Quinn (UE5)";
	separator -st none -h 10;
	if (!$manualCreatingUnrealMannequinJoints)
		text -l "Body:";
	checkBox -v 1 -l "scale to match mannequin" -cc "$unrealMannequinScale=\"#1\"" unrealMannequinScaleCheckBox;
	separator -st none -h 5;
	checkBox -v 1 -l "rename joint with Prefix" -cc "$unrealMannequinUnrealPrefix=\"#1\"" unrealMannequinUnrealPrefixCheckBox;
	if (!$manualCreatingUnrealMannequinJoints)
		{
		separator -st none -h 10;
		text -l "Face:";
		separator -st none -h 5;
		checkBox -v $hasAsFaceBS -en $hasAsFaceBS -l "open Face_CR.uasset folder" -cc "$unrealMannequinFaceOpenFolder=\"#1\"" unrealMannequinFaceRigCheckBox;
		if (!$hasAsFaceBS)
			text -fn "smallBoldLabelFont" -l "\"convert to BlendShapes\" to include Face";
		}


/*removed in v6.563, due to issues with import to Unreal5.6
	if (!$manualCreatingUnrealMannequinJoints)
		{
		separator -st none -h 10;
		checkBox -v 1 -l "include Modular Rig script" -cc "$unrealMannequinBodyRig=\"#1\"" unrealMannequinBodyRigCheckBox;
		rowLayout -nc 2;
			text -l "Unreal version:";
			optionMenu -cc "$unrealMannequinJointsMCRV=\"#1\"" unrealMannequinJointsMCRVOptionMenu;//MCRV=ModularControlRigVersion
				menuItem -l "5.4";
				menuItem -l "5.5";
				menuItem -l "5.6";
				optionMenu -e -v "5.6" unrealMannequinJointsMCRVOptionMenu;
			setParent..;
	//	separator -st none -h 5;
		checkBox -en $hasAsFaceBS -v $hasAsFaceBS -l "include Face Rig" -cc "$unrealMannequinFaceRig=\"#1\"" unrealMannequinFaceRigCheckBox;
		if (!$hasAsFaceBS)
			text -fn "smallBoldLabelFont" -l "\"convert to BlendShapes\" to include Face";
		}
*/
	separator -st none -h 25;
	rowLayout -nc 4;
		separator -w 10 -st none;
		button -l "OK" -c "layoutDialog -dismiss \"OK\";";
		separator -w 10 -st none;
		button -l "Cancel" -c "layoutDialog -dismiss \"Cancel\"";
		setParent..;
	setParent..;
optionMenu -e -v $unrealMannequinJoints unrealMannequinJointsOptionMenu;
checkBox -e -v $unrealMannequinScale unrealMannequinScaleCheckBox;
}

global proc asExportRenameToUnreal ()
{
int $spineNr,$numChar,$numElbowPart,$numKneePart,$numPart,$firstTwistJointNr;
int $opm=`asGetOpm`;
string $side,$parent,$aboveTwistParent,$nextSegJoint,$lastTwoChar,$aa,$bb;
string $as[]={"Root_M","Hip_R","Knee_R","Ankle_R","Toes_R","Scapula_R","Shoulder_R","Elbow_R","Wrist_R","Neck_M","Head_M"};
string $bs[]={"pelvis","thigh_r","calf_r","foot_r","ball_r","clavicle_r","upperarm_r","lowerarm_r","hand_r","neck_01","head"};
string $aFingers[]={"Index","Middle","Ring","Pinky","Thumb"};
string $bFingers[]={"index","middle","ring","pinky","thumb"};
string $twistLimbs[]={"thigh","calf","upperarm","lowerarm"};
string $tempString[];

//error checks
if (!`objExists |Group`)
	error ("Top node \"Group\" not found, No valid AdvancedSkeleton rig in the scene");
if (`objExists |root`)
	error ("|root already exists, already using Unreal Names");
for ($i=0;$i<size($bs);$i++)
	if (`objExists $bs[$i]`)
		{
		select $bs[$i];
		error ("Selected object is named:\""+$bs[$i]+"\", which is a name required bu UnrealJoints, rename this object to use another name.");
		}
if ($opm)
	error "This rig is using OPM (OffsetParentMatrix), this can not be renamed to Unreal";

//Part joints
//Mannequin uses `reverse` naming for lowerarm_twist & calf_twist joints, so count first
for ($i=1;$i<10;$i++)
	{
	if (`objExists ("ElbowPart"+$i+"_R")`) $numElbowPart=$i;
	if (`objExists ("KneePart"+$i+"_R")`) $numKneePart=$i;
	}

for ($i=1;$i<10;$i++)
	{
	$as[size($as)]="HipPart"+$i+"_R";
	$bs[size($bs)]="thigh_twist_"+`asDoPadd $i 2`+"_r";
	$as[size($as)]="KneePart"+$i+"_R";
//	$bs[size($bs)]="calf_twist_"+`asDoPadd $i 2`+"_r";
	$bs[size($bs)]="calf_twist_"+`asDoPadd ($numKneePart-$i+1) 2`+"_r";
	$as[size($as)]="ShoulderPart"+$i+"_R";
	$bs[size($bs)]="upperarm_twist_"+`asDoPadd $i 2`+"_r";
	$as[size($as)]="ElbowPart"+$i+"_R";
//	$bs[size($bs)]="lowerarm_twist_"+`asDoPadd $i 2`+"_r";
	$bs[size($bs)]="lowerarm_twist_"+`asDoPadd ($numElbowPart-$i+1) 2`+"_r";

	$as[size($as)]="NeckPart"+$i+"_M";
	$bs[size($bs)]="neck_"+`asDoPadd ($i+1) 2`;
	}

//Fingers
for ($i=1;$i<4;$i++)
	for ($y=0;$y<size($aFingers);$y++)
		{
		$as[size($as)]=$aFingers[$y]+"Finger"+$i+"_R";
		$bs[size($bs)]=$bFingers[$y]+"_"+`asDoPadd $i 2`+"_r";
		}
//MetaCarpal
for ($y=0;$y<size($aFingers);$y++)
	{
	$as[size($as)]=$aFingers[$y]+"Finger0_R";
	$bs[size($bs)]=$bFingers[$y]+"_metacarpal_r";
	}

//add Left
for ($i=0;$i<size($as);$i++)
	if (`gmatch $as[$i] "*_R"`)
		{
		$as[size($as)]=`substitute "_R" $as[$i] "_L"`;
		$bs[size($bs)]=`substitute "_r" $bs[$i] "_l"`;
		}

if (!`objExists root`)
	{
	asCreateGameEngineRootMotion;
	setAttr root.jointOrientX -90;
	setAttr root_parentConstraint1.target[0].targetOffsetRotateX -90;
	addAttr -k 0 -ln noRootMotionJointBeforeRename -at bool -dv 1 root;
	}
parent -w root;
connectAttr MainScaleMultiplyDivide.output root.s;

//Spine
$tempString=`ls -l Chest_M`;
tokenize $tempString[0] "|" $tempString;
for ($y=0;$y<size($tempString);$y++)
	{
	if ($tempString[$y]=="Root_M")
		{
		$spineNr=1;
		continue;
		}
	if ($spineNr==0)
		continue;
	if (!`attributeExists asName $tempString[$y]`)
		addAttr -ln asName -dt "string" $tempString[$y];
	setAttr -type "string" ($tempString[$y]+".asName") $tempString[$y];
	rename $tempString[$y] ("spine_"+`asDoPadd $spineNr 2`);
	$spineNr++;
	}

//rename known (from mannequinn) named joints
for ($i=0;$i<size($as);$i++)
	{
	if (!`objExists $as[$i]`)
		continue;
	if (!`attributeExists asName $as[$i]`)
		addAttr -ln asName -dt "string" $as[$i];
	setAttr -type "string" ($as[$i]+".asName") $as[$i];
	rename $as[$i] $bs[$i];
	}

//rename un-known (Not from mannequinn) named joints (just side-suffix rename)
$tempString=`listRelatives -ad -type joint root`;
for ($i=0;$i<size($tempString);$i++)
	{
	$aa=$tempString[$i];
	$bb="";
	$numChar=size($tempString[$i]);
	$lastTwoChar=`substring $tempString[$i] ($numChar-1) $numChar`;
	if ($lastTwoChar=="_R") $bb=`substring $tempString[$i] 1 ($numChar-2)`+"_r";
	if ($lastTwoChar=="_L") $bb=`substring $tempString[$i] 1 ($numChar-2)`+"_l";
	if ($lastTwoChar=="_M") $bb=`substring $tempString[$i] 1 ($numChar-2)`+"";
	if ($bb=="")
		continue;
	if (!`attributeExists asName $aa`)
		addAttr -ln asName -dt "string" $aa;
	setAttr -type "string" ($aa+".asName") $aa;
	rename $aa $bb;
	}

//change twist-joints-hierarchy
for ($y=0;$y<size($twistLimbs);$y++)
	{
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1)  $side="_r";
		if ($b==-1) $side="_l";

		for ($i=1;$i<10;$i++)
			{
			$twistJoint=$twistLimbs[$y]+"_twist_"+`asDoPadd $i 2`+$side;
			if (!`objExists $twistJoint`)
				continue;
			$tempString=`listRelatives -p $twistJoint`;
			$parent=$tempString[0];

			////Mannequin uses `reverse` naming for lowerarm_twist & calf_twist joints, part2
			$firstTwistJointNr=1;
			if ($twistLimbs[$y]=="thigh" || $twistLimbs[$y]=="upperarm")
				if ($i==1)
					$aboveTwistParent=$parent;
			if ($twistLimbs[$y]=="calf") {$numPart=$numKneePart;$firstTwistJointNr=$numKneePart;}
			if ($twistLimbs[$y]=="lowerarm") {$numPart=$numElbowPart;$firstTwistJointNr=$numElbowPart;}
			if ($twistLimbs[$y]=="calf" || $twistLimbs[$y]=="lowerarm" && $i==1)
				{
				$tempString[0]=$twistLimbs[$y]+"_twist_"+`asDoPadd $numPart 2`+$side;
				$tempString=`listRelatives -p $tempString[0]`;
				$aboveTwistParent=$tempString[0];
				}

			if ($i!=$firstTwistJointNr)
				{
				if (!`attributeExists asParent $twistJoint`) addAttr -ln asParent -dt "string" $twistJoint;
				if (!`attributeExists asParentRestoreCmd $twistJoint`) addAttr -ln asParentRestoreCmd -dt "string" $twistJoint;
				setAttr -type "string" ($twistJoint+".asParent") $parent;
//				setAttr -type "string" ($twistJoint+".asParentRestoreCmd") ("setAttr "+$twistJoint+".opm -type \"matrix\" 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1;");
				$m=`getAttr ($twistJoint+".matrix")`;
				parent $twistJoint $aboveTwistParent;
				//special case, incoming tx connection to be compensated for
//				setAttr ($twistJoint+".offsetParentMatrix") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
				//actually that causes issue if exporting without BakeAnimation set to ON, so instead create a _TempMPD
				$tempString=`listConnections -p 1 -s 1 -d 0 ($twistJoint+".t")`;
				createNode -n ($twistJoint+"_TempMPD") multiplyDivide;
				connectAttr $tempString[0] ($twistJoint+"_TempMPD.input1");
				setAttr ($twistJoint+"_TempMPD.input2") -type float3 2 2 2;
				connectAttr -f ($twistJoint+"_TempMPD.output") ($twistJoint+".t");
				setAttr -type "string" ($twistJoint+".asParentRestoreCmd") ("delete "+$twistJoint+"_TempMPD;connectAttr "+$tempString[0]+" "+$twistJoint+".t;");

				dgdirty -a;
				}

			$tempString=`listRelatives -c -type joint $twistJoint`;
			if ($tempString[0]!="" && !`gmatch $tempString[0] "*_twist_*"`)//next segment start
				{
				$nextSegJoint=$tempString[0];
				if (!`attributeExists asParent $nextSegJoint`)
					addAttr -ln asParent -dt "string" $nextSegJoint;
				setAttr -type "string" ($nextSegJoint+".asParent") $twistJoint;
				parent $nextSegJoint $aboveTwistParent;
				}
			}
		}
	}

parent -w Geometry;
select root Geometry;
print "// Renamed to Unreal names.\n";
}

global proc asExportRenameRestore ()
{
string $asName,$asParent;
string $tempString[];

//error checks
if (!`objExists |Group`)
	error ("Top node \"Group\" not found, No valid AdvancedSkeleton rig in the scene");
if (!`objExists |root`)
	error ("|root does not exist, not currently using Unreal Names");

parent root DeformationSystem;
if (`attributeExists noRootMotionJointBeforeRename root`)
	asDeleteGameEngineRootMotion;

$tempString=`listRelatives -ad -type joint -f DeformationSystem`;
//reParent
for ($i=0;$i<size($tempString);$i++)
	{
	if (!`attributeExists asParent $tempString[$i]`)
		continue;

	if (`attributeExists asParentRestoreCmd $tempString[$i]`)
		{
		eval (`getAttr ($tempString[$i]+".asParentRestoreCmd")`);
		dgdirty -a;
		}

	$asParent=`getAttr ($tempString[$i]+".asParent")`;
	parent $tempString[$i] $asParent;
	}
//reName
$tempString=`listRelatives -ad -type joint -f DeformationSystem`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (!`attributeExists asName $tempString[$i]`)
		continue;
	$asName=`getAttr ($tempString[$i]+".asName")`;
	rename $tempString[$i] $asName;
	}

parent Geometry Group;

select -cl;
print "// Renamed back to AdvancedSkeleton names.\n";
}

global proc string asDSArrayInfo (string $ctrl)
{
int $numKeys;
float $value,$arKitEyeLookPreSDKMult;
float $keyXValues[],$keyYValues[],$limits[];
string $arrayInfo,$driverValue;
string $attrs[],$animCurves[],$bsAnimCurves[],$tempString[],$tempString2[],$tempString3[],$tempString4[];

$attrs=`asDsGetAttrs $ctrl`;
$arrayInfo="{";
for ($y=0;$y<size($attrs);$y++)
	{
	if (!`getAttr -se ($ctrl+"."+$attrs[$y])`)
		continue;//skip ctrlMouthCorner_L.txPos_tyPos
	$arrayInfo+="'"+$attrs[$y]+"':{";
	$animCurves=`asDsGetAnimCurves $ctrl $attrs[$y]`;
	//special case ARKit Drive EyeJoint
	$arKitEyeLookPreSDKMult=0;
	if ($ctrl=="ctrlARKit_M" && `gmatch $attrs[$y] "eyeLook*"`)
		{
		$keyYValues=`keyframe -in 1 -q -vc $animCurves[0]`;
		if ($keyYValues[0]==-1) $arKitEyeLookPreSDKMult=-1;
		$tempString=`listConnections -s 0 -d 1 -type blendWeighted ($animCurves[0]+".output")`;
		$animCurves=`listConnections -s 0 -d 1 -type animCurve ($tempString[0]+".output")`;
		}
	$animCurves=`sort $animCurves`;
	for ($z=0;$z<size($animCurves);$z++)
		{
		$tempString2=`listConnections -s 0 -d 1 -scn 1 ($animCurves[$z]+".output")`;
		if (!`attributeExists "output" $tempString2[0]`) continue;
		$tempString3=`listConnections -s 0 -d 1 -scn 1 -p 1 ($tempString2[0]+".output")`;
		$tempString4=`listConnections -s 0 -d 1 -scn 1 -p 0 ($tempString2[0]+".output")`;
		if ($tempString3[0]=="") continue;
		if (`objectType $tempString3[0]`!="transform")
			continue;
		$tempString3[0]=`substitute "SDK" $tempString3[0] ""`;
		$arrayInfo+="'"+$tempString3[0]+"':";
		$numKeys=`keyframe -q -keyframeCount $animCurves[$z]`;
		$value=0;
		for ($x=0;$x<$numKeys;$x++)
			{
			$keyXValues=`keyframe -in $x -q -fc $animCurves[$z]`;
			$keyYValues=`keyframe -in $x -q -vc $animCurves[$z]`;
			$keyXValues[0]=`asRoundOff $keyXValues[0] 3`;
			$keyYValues[0]=`asRoundOff $keyYValues[0] 3`;
//				$arrayInfo+="'"+$keyXValues[0]+"':'"+$keyYValues[0]+"',";
			// simplifying curves to plain multipliers, as we can not script AnimEvalRichCurve keys
			//use first positive time-value key, to calculate multiplier
			if ($keyXValues[0]>0.1)
				{
//				$value=$keyYValues[0]/$keyXValues[0];
				$value=$keyYValues[0];
				break;
				}
			}
		if ($value==0)//only negative keyValues, so use first keyValue
			{
			$keyXValues=`keyframe -in 0 -q -fc $animCurves[$z]`;
			$keyYValues=`keyframe -in 0 -q -vc $animCurves[$z]`;
//			$value=$keyYValues[0]/$keyXValues[0];
			$value=$keyYValues[0];
			}
		if ($arKitEyeLookPreSDKMult==-1) $value=$value*-1;
		$arrayInfo+="'"+$value+"',";
		}	

	//Driven BS(FaceSetup) not included in asDsGetAnimCurves since it does not use the `$bw="bw"+$drivingSystem+"_"+$drivingAttr` node, so adding these
	$bsAnimCurves=`listConnections -s 0 -d 1 -type animCurve ($ctrl+"."+$attrs[$y])`;
	//ctrlMouthCorner_R.t uses BW
	if (`objExists ("bw"+$ctrl+"_"+$attrs[$y])`)
		{
		$tempString=`listConnections -s 0 -d 1 -type animCurve ("bw"+$ctrl+"_"+$attrs[$y])`;
		$bsAnimCurves=`stringArrayCatenate $bsAnimCurves $tempString`;
		}
	for ($i=0;$i<size($bsAnimCurves);$i++)
		{
		$tempString3=`listConnections -s 0 -d 1 -scn 1 -p 1 ($bsAnimCurves[$i]+".output")`;
		if (!`gmatch $tempString3[0] "asFaceBS[.]*"`)
			continue;//skipping BS nodes that are not "asFaceBS", e.g. "asFaceBS_model_eyeBrowR", since Unreal have these `combined`
		$keyXValues=`keyframe -in 0 -q -fc $bsAnimCurves[$i]`;
		$driverValue=$keyXValues[0];
		if ($driverValue==-10) $driverValue=-1;
		if ($driverValue!=-1) $driverValue=1;
		$arrayInfo+="'"+$tempString3[0]+"':'"+$driverValue+"',";
		}

	$arrayInfo=`asUnCommaCloseBracket $arrayInfo`+",";
	//min/max
	if (`attributeQuery -n $ctrl -softMaxExists $attrs[$y]`)
		{
		$limits=`attributeQuery -n $ctrl -softRange $attrs[$y]`;
		if ($limits[0]!=0)
			{
			$arrayInfo+="'"+$attrs[$y]+"-setLimits':{'"+$limits[0]/10+"':'"+$limits[1]/10+"'";
			$arrayInfo=`asUnCommaCloseBracket $arrayInfo`+",";
			}
		}
	}
$arrayInfo=`asUnCommaCloseBracket $arrayInfo`;
return $arrayInfo;
}

global proc float asControlDiameter (string $ctrl)
{
float $diameter;
float $bbMin[],$bbMax[],$bbShapeMin[],$bbShapeMax[],$bbDiffs[];
float $scale[]=`xform -q -ws -s $ctrl`;
string $shape;
string $tempString[] = `listRelatives -s $ctrl`;

for ($i=0;$i<size($tempString);$i++)
	{
	$shape=$tempString[$i];
	$bbShapeMin=`getAttr ($shape+".boundingBoxMin")`;
	$bbShapeMax=`getAttr ($shape+".boundingBoxMax")`;
	if ($i==0)
		{
		$bbMin[0]=$bbShapeMin[0];
		$bbMin[1]=$bbShapeMin[1];
		$bbMin[2]=$bbShapeMin[2];
		$bbMax[0]=$bbShapeMax[0];
		$bbMax[1]=$bbShapeMax[1];
		$bbMax[2]=$bbShapeMax[2];
		}
	if ($bbShapeMin[0]<$bbMin[0]) $bbMin[0]=$bbShapeMin[0];
	if ($bbShapeMin[1]<$bbMin[1]) $bbMin[1]=$bbShapeMin[1];
	if ($bbShapeMin[2]<$bbMin[2]) $bbMin[2]=$bbShapeMin[2];
	if ($bbShapeMax[0]>$bbMax[0]) $bbMax[0]=$bbShapeMax[0];
	if ($bbShapeMax[1]>$bbMax[1]) $bbMax[1]=$bbShapeMax[1];
	if ($bbShapeMax[2]>$bbMax[2]) $bbMax[2]=$bbShapeMax[2];
	}

$bbDiffs={($bbMax[0]-$bbMin[0])*$scale[0],($bbMax[1]-$bbMin[1])*$scale[1],($bbMax[2]-$bbMin[2])*$scale[2]};
if ($bbDiffs[0]>$diameter) $diameter=$bbDiffs[0];
if ($bbDiffs[1]>$diameter) $diameter=$bbDiffs[1];
if ($bbDiffs[2]>$diameter) $diameter=$bbDiffs[2];

return $diameter;
}

global proc float[] asControlOffset (string $ctrl)
{
float $offT[3],$pos[3];
float $bbShapeMin[],$bbShapeMax[],$bbDif[];
float $scale[]=`xform -q -ws -s $ctrl`;
string $parent;
string $tempString[] = `listRelatives -s $ctrl`;

if (!`gmatch $ctrl "ctrl*"`)//e.g. ctrlARKit_M, just use [0] shape.
	if (size($tempString)!=1)
		return $offT;

$bbShapeMin=`getAttr ($tempString[0]+".boundingBoxMin")`;
$bbShapeMax=`getAttr ($tempString[0]+".boundingBoxMax")`;
$bbDif[0]=$bbShapeMin[0]-($bbShapeMax[0]*-1);
$bbDif[1]=$bbShapeMin[1]-($bbShapeMax[1]*-1);
$bbDif[2]=$bbShapeMin[2]-($bbShapeMax[2]*-1);
if (abs($bbDif[0])>0.01) $offT[0]=($bbDif[0]/2.0)*$scale[0];
if (abs($bbDif[1])>0.01) $offT[1]=($bbDif[1]/2.0)*$scale[1];
if (abs($bbDif[2])>0.01) $offT[2]=($bbDif[2]/2.0)*$scale[2];
//if (abs($bbDif[0])>0.01 || abs($bbDif[1])>0.01 || abs($bbDif[2])>0.01)
//	print ($ctrl+" : "+$offT[0]+" : "+$offT[1]+" : "+$offT[2]+"\n");
if (`gmatch $ctrl "ctrl*"`)
	{
	$tempString=`listRelatives -p $ctrl`;
	$parent=$tempString[0];
	$pos=`getAttr ($parent+".t")`;
	$offT={$pos[0],$pos[1],$pos[2]};
	}
//DrivingSystems are WS in Maya, but OS in Unreal, so $offT would not be correct, flipping 
$tempString=`ls -l $ctrl`;
if (`gmatch $tempString[0] "*|DrivingSystem|*"`)
	if (`gmatch $ctrl "*_L"`)
		$offT={$offT[0]*-1,$offT[1]*-1,$offT[2]*-1};

return $offT;
}

global proc string asUnCommaCloseBracket (string $string)
{
int $numChar=size($string);
string $newString=$string;

if (`gmatch $string "*,"`)
	$newString=`substring $string 1 ($numChar-1)`;
$newString+="}";

return $newString;
}

global proc asExportWonderStudio ()
{
if (`window -q -ex asExportWonderStudioUI`)
    deleteUI asExportWonderStudioUI;
window -t "Wonder Studio" asExportWonderStudioUI;
columnLayout;
	separator -h 10 -st none;
	text -l "Make sure your file is saved.\nThis process will Remove current rig.";
	separator -h 10 -st none;
	button -l "Rename and ReOrder Joints and Geometry" -c "asEWSRenameReorder";
	separator -h 10 -st none;
	button -l "Export" -c asEWSExport;
showWindow;
}

global proc asEWSRenameReorder ()
{
int $createdShaders;
float $colors[];
string $side,$leftRight,$errorEvalCmd,$geometry,$noneNsName;
string $as[]={"Geometry","DeformationSystem",				 "Root_M","Spine1_M","Spine1Part2_M","Chest_M","Neck_M","Head_M"};
string $bs[]={"GEO","AdvancedSkeletonCharacter_BODY","Hips",  "Spine",   "Spine1",       "Spine2", "Neck",  "Head"};
string $aSides[]={"Scapula", "Shoulder","Elbow",       "Wrist","Hip",  "Knee","Ankle","Toes"};
string $bSides[]={"Shoulder","Arm",     "ForeArm","Hand", "UpLeg","Leg", "Foot", "ToeBase"};
string $fingers[]={"Index","Middle","Ring","Pinky","Thumb"};
string $geoParts[]={"UpperTeeth","LowerTeeth","Tongue","Eyebrow","EyeLash"};
string $handFoot[]={"Hand","Foot"};
string $fitSkeletonJoints[],$meshes[],$tempString[],$tempString2[],$tempString3[],$targets[],$cTargets[],$allGeos[],$skinClusters[];

//notes: fileName should be character.fbx

//preCheck 1/2
if (`objExists AdvancedSkeletonCharacter_BODY`)
	error "Already Renamed and Reorrdered for WonderStudio";
if (!`pluginInfo -q -l mtoa`)
	error "Arnold render plugin (mtoa) not loaded";

//FitSkeleton renaming
if (`objExists FitSkeleton`)
	$fitSkeletonJoints=`listRelatives -ad -type joint FitSkeleton`;
for ($i=0;$i<size($fitSkeletonJoints);$i++)
	{
	rename $fitSkeletonJoints[$i] ("prefix_"+$fitSkeletonJoints[$i]);
	$errorEvalCmd+="rename prefix_"+$fitSkeletonJoints[$i]+" "+$fitSkeletonJoints[$i]+";";
	}

//assembling arrays
for ($i=0;$i<size($aSides);$i++)
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1) {$side="_R";$leftRight="Right";}
		else {$side="_L";$leftRight="Left";}

		$as[size($as)]=$aSides[$i]+$side;
		$bs[size($bs)]=$leftRight+$bSides[$i];
		}

for ($i=0;$i<size($fingers);$i++)
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1) {$side="_R";$leftRight="Right";}
		else {$side="_L";$leftRight="Left";}

		for ($y=1;$y<4;$y++)
			{
			$as[size($as)]=$fingers[$i]+"Finger"+$y+$side;
			$bs[size($bs)]=$leftRight+"Hand"+$fingers[$i]+$y;
			}
		}

//preCheck 2/2
for ($i=0;$i<size($bs);$i++)
	if (`objExists $bs[$i]`)
		{
		eval ($errorEvalCmd);
		error ("Object:\""+$bs[$i]+"\" already exists, Aborting.");
		}
for ($i=0;$i<size($as);$i++)
	if (!`objExists $as[$i]`)
		{
		eval ($errorEvalCmd);
		error ("Object:\""+$as[$i]+"\" does not exists, Aborting.");
		}

setAttr Main.jointVis 1;
string $references[]=`file -q -r`;
for ($i=0;$i<size($references);$i++)
	file -importReference $references[$i];

//Shaders
$meshes=`listRelatives -ni -ad -type mesh Geometry`;
for ($i=0;$i<size($meshes);$i++)
	{
	$tempString=`listConnections -s 0 -d 1 -type shadingEngine $meshes[$i]`;
	if ($tempString[0]=="")
		continue;//Maya pre2024 seems to incorrectly return inter meses even with `listRelatives -ni`
	$tempString2=`listConnections ($tempString[0]+".surfaceShader")`;
	if ($tempString2[0]=="")
		continue;
	$tempString3[0]=`objectType $tempString2[0]`;
	if ($tempString3[0]!="aiFlat" && $tempString3[0]!="aiStandardSurface")
		{
		createNode -n ($tempString2[0]+"_AsAiStandardSurface") aiStandardSurface;
		connectAttr -f ($tempString2[0]+"_AsAiStandardSurface.outColor") ($tempString[0]+".surfaceShader");
		$createdShaders=1;
		if (`attributeExists color $tempString2[0]`)
			{
			$colors=`getAttr ($tempString2[0]+".color")`;
			setAttr ($tempString2[0]+"_AsAiStandardSurface.baseColor") -type float3 $colors[0] $colors[1] $colors[2];
			}
		}
	}
if ($createdShaders)
	print ("// Only AiStandardSurface & AiFlat shaders are currently supported in WonderStudio, now creating new shaders.\n");

//BlendShapes
$targets={"browInnerDn","browInnerUp","browOuterDn","browOuterUp","browSqueeze","cheekBlow","cheekUp","eyeBlink","eyeCompress","eyeSquint",
	"eyeWidenLower","eyeWidenUpper","lipChinRaiser","lipCornerDn","lipCornerUp","lipDimpler",
	"lipLowerDn","lipLowerUp",
	"lipUpperDn","lipUpperUp",
	"lipLowerPullDn",
	"lipNarrow","lipWiden","lipPresser","lipPull","lipSmileClosed","lipSmileOpen","lipSneer","lipSticky","lipTightner",
	"noseSneer","noseWrinkler"};
//skip: jawClench
$cTargets={"eyeDn","eyeUp","jawIn","jawOut","jawL","jawR","jawOpen","lipCloseLower","lipCloseUpper","lipFunnelerLower","lipFunnelerUpper",
	"lipPoutLower","lipPoutUpper","lipPucker","lipPushLower","lipPushUpper","lipSuckLower","lipSuckUpper","lipSwingL","lipSwingR",
	"noseCompress","noseFlare"};
$targets=`stringArrayCatenate $targets $cTargets`;
if (`objExists FaceFitSkeleton`)
	{
	createNode -n WonderStudioBlendShapeTargets transform;
	setAttr WonderStudioBlendShapeTargets.v 0;
	$geometry=`getAttr FaceFitSkeleton.Face`;
	$allGeos={$geometry};
	for ($i=0;$i<size($geoParts);$i++)
		{
		if (!`attributeExists $geoParts[$i] FaceFitSkeleton`)
			continue;
		$tempString[0]=`getAttr ("FaceFitSkeleton."+$geoParts[$i])`;
		if ($tempString[0]=="")
			continue;
		tokenize $tempString[0] $tempString;
		for ($y=0;$y<size($tempString);$y++)
			if (`objExists $tempString[$y]`)
				$allGeos[size($allGeos)]=$tempString[$y];
		}

	for ($i=0;$i<size($targets);$i++)
		{
		for ($b=1;$b>-2;$b=$b-2)
			{
			if ($b==1)  $side="R";
			if ($b==-1) $side="L";

			if (`stringArrayCount $targets[$i] $cTargets`)
				{
				if ($b==1) $side="";
				if ($b==-1) continue;
				}

			if ($targets[$i]=="browInnerDn") setAttr ("ctrlBrow_"+$side+".tx") -1;
			if ($targets[$i]=="browInnerUp") setAttr ("ctrlBrow_"+$side+".tx") 1;
			if ($targets[$i]=="browOuterDn") setAttr ("ctrlBrow_"+$side+".outerUpDown") -5;
			if ($targets[$i]=="browOuterUp") setAttr ("ctrlBrow_"+$side+".outerUpDown") 10;
			if ($targets[$i]=="browSqueeze") setAttr ("ctrlBrow_"+$side+".squeeze") 10;
			if ($targets[$i]=="cheekBlow") setAttr ("ctrlCheek_"+$side+".tx") 1;
			if ($targets[$i]=="cheekUp") setAttr ("ctrlCheek_"+$side+".ty") 1;
			if ($targets[$i]=="eyeBlink") setAttr ("ctrlEye_"+$side+".blink") 10;
			if ($targets[$i]=="eyeCompress") {setAttr ("ctrlEye_"+$side+".squint") 10;setAttr ("ctrlEye_"+$side+".blink") -10;}
			if ($targets[$i]=="eyeSquint") setAttr ("ctrlEye_"+$side+".squint") -10;
			if ($targets[$i]=="eyeWidenLower") setAttr ("lowerLid_"+$side+".ty") -0.3;
			if ($targets[$i]=="eyeWidenUpper") setAttr ("upperLid_"+$side+".ty") 0.3;
			if ($targets[$i]=="lipChinRaiser") setAttr ctrlLips_M.ty 0.5;//not really a l/r split, but intended for combine anyway
			if ($targets[$i]=="lipCornerDn") setAttr ("ctrlMouthCorner_"+$side+".ty") -1;
			if ($targets[$i]=="lipCornerUp") setAttr ("ctrlMouthCorner_"+$side+".ty") 1;
			if ($targets[$i]=="lipDimpler") setAttr ("cornerLip_"+$side+".tz") -0.25;
			if ($targets[$i]=="lipLowerDn") setAttr ("lowerLipB_"+$side+".ty") -1;
			if ($targets[$i]=="lipLowerUp") setAttr ("lowerLipB_"+$side+".ty") 1;
			if ($targets[$i]=="lipUpperDn") setAttr ("upperLipB_"+$side+".ty") -1;
			if ($targets[$i]=="lipUpperUp") setAttr ("upperLipB_"+$side+".ty") 1;
			if ($targets[$i]=="lipLowerPullDn") setAttr ("lowerLipB_"+$side+".ty") -1;//same as lipLowerDn
			if ($targets[$i]=="lipNarrow") setAttr ("ctrlMouthCorner_"+$side+".tx") -1;
			if ($targets[$i]=="lipWiden") setAttr ("ctrlMouthCorner_"+$side+".tx") 1;
			if ($targets[$i]=="lipPresser") {setAttr ctrlLips_M.upperPress 5;setAttr ctrlLips_M.lowerPress 5;}//not really a l/r split, but intended for combine anyway
			if ($targets[$i]=="lipPull")  {setAttr ("ctrlMouthCorner_"+$side+".tx") 1;setAttr ("ctrlMouthCorner_"+$side+".ty") -1;}
			if ($targets[$i]=="lipSmileClosed") {setAttr ("ctrlMouthCorner_"+$side+".tx") 1;setAttr ("ctrlMouthCorner_"+$side+".ty") 1;}
			if ($targets[$i]=="lipSmileOpen") {setAttr ("ctrlMouthCorner_"+$side+".tx") 1;setAttr ("ctrlMouthCorner_"+$side+".ty") 1;setAttr lowerLip_M.ty -0.5;}
			if ($targets[$i]=="lipSneer") setAttr ("upperLipB_"+$side+".ty") 1;
			if ($targets[$i]=="lipSticky") {setAttr ("upperLipC_"+$side+".ty") -0.1;setAttr ("lowerLipC_"+$side+".ty") 0.1;}
			if ($targets[$i]=="lipTightner") {setAttr ctrlLips_M.upperPress 5;setAttr ctrlLips_M.lowerPress 5;}//same as lipPresser
			if ($targets[$i]=="noseSneer") setAttr ("ctrlNose_"+$side+".ty") 0.3;
			if ($targets[$i]=="noseWrinkler") setAttr ("ctrlNose_"+$side+".ty") 1;

			if ($targets[$i]=="eyeDn") {setAttr ctrlEye_R.ty -1;setAttr ctrlEye_L.ty -1;}
			if ($targets[$i]=="eyeUp") {setAttr ctrlEye_R.ty 1;setAttr ctrlEye_L.ty 1;}
			if ($targets[$i]=="jawIn") setAttr ctrlMouth_M.jawForward -5;
			if ($targets[$i]=="jawOut") setAttr ctrlMouth_M.jawForward 5;
			if ($targets[$i]=="jawL") setAttr ctrlMouth_M.jawSide 10;
			if ($targets[$i]=="jawR") setAttr ctrlMouth_M.jawSide -10;
			if ($targets[$i]=="jawOpen") setAttr ctrlMouth_M.ty -1;
			if ($targets[$i]=="lipCloseLower") setAttr lowerLip_M.ty 1.4;
			if ($targets[$i]=="lipCloseUpper") setAttr upperLip_M.ty -1.4;
			if ($targets[$i]=="lipFunnelerLower") setAttr ctrlLips_M.lowerPucker 10;
			if ($targets[$i]=="lipFunnelerUpper") setAttr ctrlLips_M.upperPucker 10;
			if ($targets[$i]=="lipPoutLower") setAttr lowerLip_M.tz 1;
			if ($targets[$i]=="lipPoutUpper") setAttr upperLip_M.tz 1;
			if ($targets[$i]=="lipPucker") {setAttr ctrlLips_M.lowerPucker 10;setAttr ctrlLips_M.upperPucker 10;}
			if ($targets[$i]=="lipPushLower") setAttr lowerLip_M.tz 1;
			if ($targets[$i]=="lipPushUpper") setAttr upperLip_M.tz 1;
			if ($targets[$i]=="lipSuckLower") setAttr ctrlLips_M.lowerRoll -10;
			if ($targets[$i]=="lipSuckUpper") setAttr ctrlLips_M.upperRoll -10;
			if ($targets[$i]=="lipSwingL") setAttr ctrlLips_M.tx 1;
			if ($targets[$i]=="lipSwingR") setAttr ctrlLips_M.tx -1;
			if ($targets[$i]=="noseCompress") {setAttr ctrlNose_R.tx -1;setAttr ctrlNose_L.tx -1;}
			if ($targets[$i]=="noseFlare") {setAttr ctrlNose_R.tx 1;setAttr ctrlNose_L.tx 1;}

			for ($a=0;$a<size($allGeos);$a++)
				{
				$noneNsName=`substituteAllString $allGeos[$a] ":" "_"`;
				duplicate -n ($targets[$i]+$side) $allGeos[$a];
				if (!`objExists ($noneNsName+"_Targets")`)
					createNode -n ($noneNsName+"_Targets") -p WonderStudioBlendShapeTargets transform;
				parent ($targets[$i]+$side) ($noneNsName+"_Targets");
				select ($targets[$i]+$side) $allGeos[$a];
				if (`objExists ("WonderStudioBS"+$a)`)
					blendShape -e -tc 0 -t $allGeos[$a] `getAttr -s ("WonderStudioBS"+$a+".w")` ($targets[$i]+$side) 1 ("WonderStudioBS"+$a);
				else
					asBlendShapeFrontOfChain ("WonderStudioBS"+$a);
				rename ($targets[$i]+$side) ($targets[$i]+"_"+$noneNsName+$side);
				}
			asGoToBuildPose faceSetup;
			}
		}
	delete WonderStudioBlendShapeTargets;
	}

//remove joints
//if (`objExists FaceJoint_M`)
//	delete FaceJoint_M;
/*
if (`objExists RootPart1_M`) {parent Spine Hips;delete RootPart1_M;}
if (`objExists Spine1Part1_M`) {parent Spine1 Spine;delete Spine1Part1_M;}
for ($b=1;$b>-2;$b=$b-2)
	{
		if ($b==1) {$side="_R";$leftRight="Right";}
		else {$side="_L";$leftRight="Left";}

	if (`objExists ("HipPart1"+$side)`) {parent ($leftRight+"Leg") ($leftRight+"UpLeg");delete ("HipPart1"+$side);}
	if (`objExists ("ShoulderPart1"+$side)`) {parent ($leftRight+"ForeArm") ($leftRight+"Arm");delete ("ShoulderPart1"+$side);}
	if (`objExists ("ElbowPart1"+$side)`) {parent ($leftRight+"Hand") ($leftRight+"ForeArm");delete ("ElbowPart1"+$side);}
	}
source doNormalizeWeightsArgList;
//select -hi GEO;
$tempString=`listRelatives -ad -c -ni GEO`;
for ($i=0;$i<size($tempString);$i++)
	{
	$tempString2[0]=`asGetSkinCluster $tempString[$i]`;
	if ($tempString2[0]=="")
		continue;
	select $tempString[$i];
	doNormalizeWeightsArgList 2 { "4", "1" };
	}
dgdirty -a;
*/

parent -w Geometry DeformationSystem;

select -hi DeformationSystem;
$tempString=`ls -sl`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (`objExists FaceAllSet`)
		if (`sets -im FaceAllSet $tempString[$i]`)
			continue;
	if ($tempString[$i]!="DeformationSystem" && `objectType $tempString[$i]`!="joint")
		{
		delete $tempString[$i];
		continue;
		}
	sets -rm AllSet $tempString[$i];
	sets -rm DeformSet $tempString[$i];
	setAttr ($tempString[$i]+".rotateOrder") 0;
	$tempString2=`listConnections -s 1 -d 0 -p 1 -c 1 $tempString[$i]`;
	for ($y=0;$y<size($tempString2);$y=$y+2)
		{
		if ($tempString2[$y+1]=="")
			continue;
		catchQuiet (`disconnectAttr $tempString2[$y+1] $tempString2[$y]`);
		}
	}

//remove rig
/*
if (`objExists FaceAllSet`) delete `sets -q -nodesOnly FaceAllSet`;
if (`objExists FaceAllSet`) delete `sets -q -nodesOnly FaceAllSet`;
if (`objExists FaceGroup`) delete FaceGroup;
*/
if (`objExists FaceGroup`) asDeleteAdvancedFace;
if (`objExists FaceGroup`) delete FaceGroup;
$tempString=`listRelatives -c -type transform Geometry`;
asDeleteAdvanced;
delete FitSkeleton;

for ($i=0;$i<size($tempString);$i++)
	parent $tempString[$i] Geometry;

//rename
for ($i=0;$i<size($as);$i++)
		rename $as[$i] $bs[$i];

//add IK joints
for ($i=0;$i<size($handFoot);$i++)
	{
	for ($b=1;$b>-2;$b=$b-2)
		{
		if ($b==1) {$side="_R";$leftRight="Right";}
		else {$side="_L";$leftRight="Left";}

		select -cl;
		joint -n ($leftRight+$handFoot[$i]+"_IK");
		parent ($leftRight+$handFoot[$i]+"_IK") ($leftRight+$handFoot[$i]);
		setAttr ($leftRight+$handFoot[$i]+"_IK.t") -type float3 0 0 0;
		$tempString=`listRelatives -p ($leftRight+$handFoot[$i])`;
		parent ($leftRight+$handFoot[$i]+"_IK") $tempString[0];
		}
	}

$tempString=`ls -type displayLayer`;
for ($i=0;$i<size($tempString);$i++)
	if ($tempString[$i]!="defaultLayer")
		delete $tempString[$i];
dgdirty -a;

hyperShadePanelMenuCommand("", "deleteUnusedNodes");

select -cl;
print "// Ready for WonderStudio export.\n";
}

global proc asEWSExport ()
{
int $fileId;
string $sceneName=`file -q -sn`;
string $filePath=`asStripPath $sceneName 1`;
string $fbxFile,$exportPath,$py;
string $as2wdFile=`asGetScriptLocation`+"/AdvancedSkeletonFiles/div/as2wd/wd_character_export.py";

if (!`objExists AdvancedSkeletonCharacter_BODY` || !`objExists GEO`)
	error "Required objects not found, run the \"Rename and ReOrder Joints and Geometry\" function first";
if (!`file -q -ex $as2wdFile`)
	error ("The file:\""+$as2wdFile+"\" no found");
if ($sceneName=="")
	error "No Scene Name, the file must be saved first.";

//read $as2wdFile
$fileId=`fopen $as2wdFile "r"`;
$nextLine=`fgetline $fileId`;
while ( size( $nextLine ) > 0 )
	{
	$py+=$nextLine;
	$nextLine=`fgetline $fileId`;
	}
fclose $fileId;

print ("// Executing WonderStudio Python Script:\""+$as2wdFile+"\".\n");
python ($py);
print ("//Complete, files to upload can be found in this Folder:\""+$filePath+"01_character_data/\"\n");
}

global proc asRobloxDynamicHead ()
{
string $geometry=`textField -q -tx asFaceFaceTextField`;
string $userAttrs[],$tempString[];

if (!`objExists ctrlRobloxHead_M`)
	error "ctrlRobloxHead_M controller not found, a FaceRig with the \"roblox head\" option must be created.";

currentTime 0;

//remove existing
$tempString=`listConnections -s 1 -d 0 -type animCurve ctrlRobloxHead_M`;
if (size($tempString))
	delete $tempString;
$tempString=`listAttr -ud $geometry`;
for ($i=0;$i<size($tempString);$i++)
	{
	if (`gmatch $tempString[$i] "Frame[0-9]*"`)
		deleteAttr ($geometry+"."+$tempString[$i]);
	}

//addAttrs
if (!`attributeExists RootFaceJoint $geometry`)
	addAttr -ln RootFaceJoint -dt "string" $geometry;
setAttr -type "string"($geometry+".RootFaceJoint") "FaceJoint_M";
addAttr -ln Frame0 -dt "string" $geometry;
setAttr -type "string" ($geometry+".Frame0") "Neutral";

$userAttrs=`listAttr -ud -s ctrlRobloxHead_M`;
for ($i=0;$i<size($userAttrs);$i++)
	{
	setKeyframe -v 0  -t $i     ("ctrlRobloxHead_M."+$userAttrs[$i]);
	setKeyframe -v 10 -t ($i+1) ("ctrlRobloxHead_M."+$userAttrs[$i]);
	setKeyframe -v 0  -t ($i+2) ("ctrlRobloxHead_M."+$userAttrs[$i]);

	addAttr -ln ("Frame"+($i+1)) -dt "string" $geometry;
	setAttr -type "string" ($geometry+".Frame"+($i+1)) $userAttrs[$i];
	}
playbackOptions -min 0 -ast 0 -aet $i -max $i;
select ctrlRobloxHead_M;
currentTime 39 ;
print "// Roblox Dynamic Head animation created, now ready for FBX export.\n";
}
/*
global proc asMSCParentConstraint (string $parent, string $child, string $flagString, int $parentLevels) // MSC=MultiSkinCluster
{
int $plugNr;
string $name,$side,$parentAtLevel;
string $tempString[];

tokenize $child "_" $tempString;
$name=$tempString[0];
for ($y=1;$y<size($tempString)-1;$y++)
	$name+="_"+$tempString[$y];
$side="_"+$tempString[size($tempString)-1];

createNode -n ($name+"MM"+$side) multMatrix;

connectAttr ($parent+".worldMatrix") ($name+"MM"+$side+".matrixIn["+$plugNr+"]");
$plugNr++;

$tempString=`listRelatives -p $parent`;
for ($i=1;$i<$parentLevels;$i++)
	$tempString=`listRelatives -p $tempString[0]`;
$parentAtLevel=$tempString[0];
connectAttr ($parentAtLevel+".worldInverseMatrix") ($name+"MM"+$side+".matrixIn["+$plugNr+"]");
$plugNr++;


$m=`getAttr ($parentAtLevel+".matrix")`;
setAttr ($name+"MM"+$side+".matrixIn["+$plugNr+"]") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];

if (`gmatch $flagString "*-incParentScaleAAAAAA*"`)
	{
	createNode -n ($name+"IncParentScaleMM"+$side) multMatrix;
	createNode -n ($name+"IncParentScalePM"+$side) pickMatrix;
	connectAttr ($parentAtLevel+".worldMatrix") ($name+"IncParentScalePM"+$side+".inputMatrix");
	setAttr ($name+"IncParentScalePM"+$side+".useScale") 0;
	setAttr ($name+"IncParentScalePM"+$side+".useShear") 0;
$m=`getAttr ($name+"IncParentScalePM"+$side+".outputMatrix")`;
	setAttr ($name+"IncParentScalePM"+$side+".useScale") 1;
	setAttr ($name+"IncParentScalePM"+$side+".useShear") 1;

	setAttr ($name+"IncParentScalePM"+$side+".useTranslate") 0;
	setAttr ($name+"IncParentScalePM"+$side+".useRotate") 0;
	setAttr ($name+"IncParentScaleMM"+$side+".matrixIn[1]") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
	connectAttr ($name+"IncParentScalePM"+$side+".outputMatrix") ($name+"IncParentScaleMM"+$side+".matrixIn[0]");
	connectAttr ($name+"IncParentScaleMM"+$side+".matrixSum") ($name+"MM"+$side+".matrixIn["+$plugNr+"]");
	}
$plugNr++;

$tempString=`listRelatives -p $child`;
$m=`getAttr ($parentAtLevel+".worldInverseMatrix")`;
setAttr ($name+"MM"+$side+".matrixIn["+$plugNr+"]") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
$plugNr++;

connectAttr ($name+"MM"+$side+".matrixSum") ($child+".offsetParentMatrix");

xform -os -t 0 0 0 -ro 0 0 0 -s 1 1 1 $child;
}
*/
global proc asParentConstraint (string $parent, string $child, string $flagString)
{//print ($parent+" "+$child+" "+$flagString+"\n");
int $opm=`checkBox -q -v asBodyOffsetParentMatrixCheckBox`;
int $plugNr,$skipScale;
float $m[];
string $name,$side,$dm;
string $sel[]=`ls -sl`;
string $tempString[];

if (`gmatch $flagString "*-FMM*"`)//forceMultMatrix, use MM even for nonOPM
	$opm=1;

if (`gmatch $flagString "*-skipScale*"`)//forceMultMatrix, use MM even for nonOPM
	$skipScale=1;

if ($opm)
	{
	tokenize $child "_" $tempString;
	$name=$tempString[0];
	for ($y=1;$y<size($tempString)-1;$y++)
		$name+="_"+$tempString[$y];
	$side="_"+$tempString[size($tempString)-1];

//print ($name+"MM"+$side+" : "+`objExists ($name+"MM"+$side)`+"\n");
	if (!`objExists ($name+"MM"+$side)`)
		createNode -n ($name+"MM"+$side) multMatrix;

	if (`gmatch $flagString "*-mo*"`)
		{
		createNode -n tempMatrixTransform -p $child transform;
		parent tempMatrixTransform $parent;
		$m=`xform -q -os -m tempMatrixTransform`;
		delete tempMatrixTransform;		
		setAttr ($name+"MM"+$side+".matrixIn["+$plugNr+"]") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
		$plugNr++;
		}

	if (!`isConnected ($parent+".worldMatrix") ($name+"MM"+$side+".matrixIn["+$plugNr+"]")`)
		connectAttr -f ($parent+".worldMatrix") ($name+"MM"+$side+".matrixIn["+$plugNr+"]");
	$plugNr++;

	$tempString=`listRelatives -p $child`;
	if ($tempString[0]!="")
		{
		if (!`isConnected ($tempString[0]+".worldInverseMatrix[0]") ($name+"MM"+$side+".matrixIn["+$plugNr+"]")`)
			connectAttr ($tempString[0]+".worldInverseMatrix[0]") ($name+"MM"+$side+".matrixIn["+$plugNr+"]");
		$plugNr++;
		}

	if (`gmatch $flagString "*-includePickMatrix*"` || $skipScale)
		{
		createNode -n ($name+"PM"+$side) pickMatrix;
		connectAttr ($name+"MM"+$side+".matrixSum") ($name+"PM"+$side+".inputMatrix");
		asMatrixConnectAttr ($name+"PM"+$side+".outputMatrix") ($child+".offsetParentMatrix");
		}
	else if (`gmatch $flagString "*-UDM*"`)//useDecomposeMatrix, e.g to avoid SDK`s showing in graphEd
		{
		$dm=$name+"DM"+$side;
		createNode -n $dm decomposeMatrix;
		setAttr ($dm+".inputRotateOrder") `getAttr ($child+".rotateOrder")`;
		if (`objExists ($name+"PM"+$side)`)
			connectAttr ($name+"PM"+$side+".outputMatrix") ($dm+".inputMatrix");
		else
			connectAttr ($name+"MM"+$side+".matrixSum") ($dm+".inputMatrix");
		connectAttr ($dm+".outputTranslate") ($child+".t");
		connectAttr ($dm+".outputRotate") ($child+".r");
		connectAttr ($dm+".outputScale") ($child+".s");
		connectAttr ($dm+".outputShear") ($child+".sh");
		}
	else
		asMatrixConnectAttr ($name+"MM"+$side+".matrixSum") ($child+".offsetParentMatrix");

	if ($skipScale)
		setAttr ($name+"PM"+$side+".useScale") 0;

	xform -os -t 0 0 0 -ro 0 0 0 -s 1 1 1 $child;
	if (`objectType $child`=="joint")
		setAttr ($child+".jo") -type float3 0 0 0;
	}
else
	{
	if (`gmatch $flagString "*-mo*"`)
		{
		parentConstraint -mo $parent $child;
		if (!$skipScale)
			scaleConstraint -mo $parent $child;
		}
	else
		{
		parentConstraint $parent $child;
		if (!$skipScale)
			scaleConstraint $parent $child;
		}
	}
select $sel;
}

global proc asMatrixZeroJointOrientConnect (string $name, string $side)
{
string $tempString[];

/*removed due to restored orientConstraint
//Matrix nodes does not provide good solution for constranining joints, despite this techique:
// https://youtu.be/_LNhZB8jQyo
// as the rotation values will not be matching controller, making anything driven from the joint rotations to not work well.
createNode -n ($name+"JOCM"+$side) composeMatrix;//JOCM JointOrientComposeMatrix
//setAttr ($name+"JOCM"+$side+".inputRotateOrder") `getAttr ($name+$side+".rotateOrder")`;
$jo=`getAttr ($name+$side+".jointOrient")`;
setAttr ($name+"JOCM"+$side+".inputRotate") -type float3 $jo[0] $jo[1] $jo[2];
createNode -n ($name+"JOMM1"+$side) multMatrix;

connectAttr ($name+"JOCM"+$side+".outputMatrix") ($name+"JOMM1"+$side+".matrixIn[0]");
$tempString=`listRelatives -p ($name+$side)`;
connectAttr ($tempString[0]+".worldMatrix") ($name+"JOMM1"+$side+".matrixIn[1]");
//the above migh later be overruled if in TwistSystem

createNode -n ($name+"JOIM"+$side) inverseMatrix;
connectAttr ($name+"JOMM1"+$side+".matrixSum") ($name+"JOIM"+$side+".inputMatrix");

createNode -n ($name+"JOMM2"+$side) multMatrix;
connectAttr ($name+"MM"+$side+".matrixSum") ($name+"JOMM2"+$side+".matrixIn[0]");
$tempString=`listRelatives -p ($name+$side)`;
connectAttr ($tempString[0]+".worldMatrix") ($name+"JOMM2"+$side+".matrixIn[1]");
//the above could be overridden by FKX || BM

createNode -n ($name+"JOMM3"+$side) multMatrix;
connectAttr ($name+"JOMM2"+$side+".matrixSum")($name+"JOMM3"+$side+".matrixIn[0]");
connectAttr ($name+"JOIM"+$side+".outputMatrix") ($name+"JOMM3"+$side+".matrixIn[1]");
createNode -n ($name+"JODM"+$side) decomposeMatrix;//JOCM JointOrientComposeMatrix
setAttr ($name+"JODM"+$side+".inputRotateOrder") `getAttr ($name+$side+".rotateOrder")`;
connectAttr ($name+"JOMM3"+$side+".matrixSum") ($name+"JODM"+$side+".inputMatrix");
connectAttr -f ($name+"JODM"+$side+".outputRotate") ($name+$side+".r");
*/
//The above workaround causes valueFlips when JointOrients values are large. use OrientConstraint 
disconnectAttr ($name+"DM"+$side+".outputRotate") ($name+$side+".r");
setAttr ($name+$side+".r") -type float3 0 0 0;
$tempString=`listConnections -s 1 -d 0 ($name+"MM"+$side+".matrixIn[0]")`;
orientConstraint $tempString[0] ($name+$side);
select ($name+$side);
}

global proc asBlendedMatrixAim (string $baseName, string $side, int $b, string $input, string $upObj, string $target, string $obj, int $secondaryMode, int $mo)
{
createNode -n ("FKAim"+$baseName+"AM"+$side) aimMatrix;
setAttr ("FKAim"+$baseName+"AM"+$side+".secondaryMode") $secondaryMode;
setAttr ("FKAim"+$baseName+"AM"+$side+".primaryInputAxis") -type float3 $b 0 0;
setAttr ("FKAim"+$baseName+"AM"+$side+".secondaryInputAxis") -type float3 0 $b 0;
setAttr ("FKAim"+$baseName+"AM"+$side+".secondaryTargetVector") -type float3 0 $b 0;
connectAttr ($input+".worldMatrix[0]") ("FKAim"+$baseName+"AM"+$side+".inputMatrix");
connectAttr ($target+".worldMatrix[0]") ("FKAim"+$baseName+"AM"+$side+".primaryTargetMatrix");
connectAttr ($upObj+".worldMatrix[0]") ("FKAim"+$baseName+"AM"+$side+".secondaryTargetMatrix");

//Skip the MM, since using AimMatrix.inputMatrix

createNode -n ("Aim"+$baseName+"MM"+$side) multMatrix;
connectAttr ("FKAim"+$baseName+"AM"+$side+".outputMatrix") ("Aim"+$baseName+"MM"+$side+".matrixIn[1]");
connectAttr ($input+".worldInverseMatrix") ("Aim"+$baseName+"MM"+$side+".matrixIn[2]");

if ($mo)
	{
	$m=`getAttr ("Aim"+$baseName+"MM"+$side+".matrixSum")`;
	$m=`asInvertMatrix $m`;
	setAttr ("Aim"+$baseName+"MM"+$side+".matrixIn[0]") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
	}
createNode -n ("Aim"+$baseName+"BM"+$side) blendMatrix;
createNode -n ("Aim"+$baseName+"PM"+$side) pickMatrix;
setAttr ("Aim"+$baseName+"PM"+$side+".useTranslate") 0;
setAttr ("Aim"+$baseName+"PM"+$side+".useScale") 0;
setAttr ("Aim"+$baseName+"PM"+$side+".useShear") 0;
connectAttr ("Aim"+$baseName+"MM"+$side+".matrixSum") ("Aim"+$baseName+"PM"+$side+".inputMatrix");
//connectAttr ("FKAim"+$baseName+"AM"+$side+".outputMatrix") ("Aim"+$baseName+"PM"+$side+".inputMatrix");
connectAttr ("Aim"+$baseName+"PM"+$side+".outputMatrix") ("Aim"+$baseName+"BM"+$side+".target[0].targetMatrix");

//setting BlenMatrix.inputMatrix, to allow for non-zero values at `not-aim`
$m=`getAttr ("Aim"+$baseName+"PM"+$side+".outputMatrix")`;
setAttr ("Aim"+$baseName+"BM"+$side+".inputMatrix") -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];

connectAttr ("Aim"+$baseName+"BM"+$side+".outputMatrix") ($obj+".offsetParentMatrix");
}

global proc string asInfoFromCtrl (string $ctrl, string $info)
{
int $numChar;
string $name,$type,$extra;
string $tempString[],$tempString2[];

if (`gmatch $ctrl "FK*"`) $type="FK";
if (`gmatch $ctrl "IK*"`) $type="IK";
if (`gmatch $ctrl "IKLocal*"`) $type="IKLocal";
if (`gmatch $ctrl "Root*"`) $type="Root";
if (`gmatch $ctrl "Pole*"`) $type="Pole";
if (`gmatch $ctrl "Bend*"`) $type="Bend";
if (`gmatch $ctrl "Tweaker*"`) $type="Tweaker";
if (`gmatch $ctrl "BendMid*"`) $type="BendMid";
if (`gmatch $ctrl "IKhybrid*"`) $type="IKhybrid";
if (`gmatch $ctrl "Micro*"`) $type="Micro";
if (`gmatch $ctrl "RootX*"`) $type="Root";
if (`gmatch $ctrl "HipSwinger*"`) $type="HipSwinger";
if (`gmatch $ctrl "*Extra*"`) $type+="Extra";
$numChar=size($type);
$tempString[0]=`substring $ctrl ($numChar+1) 99`;
tokenize $tempString[0] "_" $tempString2;
$name=$tempString2[0];
$side="_"+$tempString2[1];

if ($info=="type") return $type;
if ($info=="name") return $name;
if ($info=="side") return $side;
}


global proc string asMS_mirrorObjectName(string $object)
{
	string $result = $object;

	if (`gmatch $object "*_R"`)
	{
		int $len = size($object);
		string $base = `substring $object 1 ($len - 2)`;
		$result = $base + "_L";
	}
	else if (`gmatch $object "*_L"`)
	{
		int $len = size($object);
		string $base = `substring $object 1 ($len - 2)`;
		$result = $base + "_R";
	}

	if (!`objExists $result`)
		$result = $object;

	return $result;
}

global proc string asMS_getObject(string $item)
{
	string $buffer[];
	tokenize $item "." $buffer;
	return $buffer[0];
}

global proc string asMS_componentType(string $item)
{
	if (`match "\\.vtx\\[" $item` != "")
		return "vtx";
	if (`match "\\.e\\[" $item` != "")
		return "e";
	if (`match "\\.f\\[" $item` != "")
		return "f";

	return "";
}

global proc vector asMS_componentCenter(string $component)
{
	string $verts[] = `polyListComponentConversion -tv $component`;
	$verts = `filterExpand -sm 31 $verts`;

	float $x = 0;
	float $y = 0;
	float $z = 0;

	int $num = size($verts);
	int $i;

	for ($i = 0; $i < $num; $i++)
	{
		float $pos[] = `pointPosition -w $verts[$i]`;
		$x += $pos[0];
		$y += $pos[1];
		$z += $pos[2];
	}

	if (!$num)
		return <<0, 0, 0>>;

	return <<($x / $num), ($y / $num), ($z / $num)>>;
}

global proc string asMS_closestComponent(string $sourceComponent, string $targetObject, string $componentType)
{
	vector $center = `asMS_componentCenter $sourceComponent`;

	float $tx = -($center.x);
	float $ty = $center.y;
	float $tz = $center.z;

	string $search;
	if ($componentType == "vtx")
		$search = $targetObject + ".vtx[*]";
	else if ($componentType == "e")
		$search = $targetObject + ".e[*]";
	else if ($componentType == "f")
		$search = $targetObject + ".f[*]";
	else
		return "";

	string $components[] = `ls -fl $search`;

	string $closest = "";
	float $closestDist = 999999999999.0;

	int $i;
	for ($i = 0; $i < size($components); $i++)
	{
		vector $c = `asMS_componentCenter $components[$i]`;

		float $dx = $c.x - $tx;
		float $dy = $c.y - $ty;
		float $dz = $c.z - $tz;

		float $dist = ($dx * $dx) + ($dy * $dy) + ($dz * $dz);

		if ($dist < $closestDist)
		{
			$closestDist = $dist;
			$closest = $components[$i];
		}
	}

	return $closest;
}

global proc asMirrorSelection()
{
	string $sel[] = `ls -sl -fl`;
	string $newSel[];

	int $i;
	for ($i = 0; $i < size($sel); $i++)
	{
		string $item = $sel[$i];
		string $componentType = `asMS_componentType $item`;

		if ($componentType != "")
		{
			string $object = `asMS_getObject $item`;
			string $targetObject = `asMS_mirrorObjectName $object`;

			string $target = `asMS_closestComponent $item $targetObject $componentType`;

			if ($target != "")
				$newSel[size($newSel)] = $target;
		}
		else
		{
			string $targetObject = `asMS_mirrorObjectName $item`;

			if (`objExists $targetObject`)
				$newSel[size($newSel)] = $targetObject;
		}
	}

	if (size($newSel))
		select -r $newSel;
}


global proc string asResolveFitJointFromDeformJoint (string $deformJoint)
{
string $fitJoint="";
string $current=$deformJoint;
while ($current!="")
	{
	string $buffer[];
	tokenize $current "|" $buffer;
	string $shortName=$buffer[size($buffer)-1];
	string $fitName=$shortName;
	if (`gmatch $fitName "*_R"` || `gmatch $fitName "*_L"`)
		{
		int $len=size($fitName);
		$fitName=`substring $fitName 1 ($len-2)`;
		}
	if (`objExists $fitName`)
		{
		$fitJoint=$fitName;
		break;
		}
	string $parent[]=`listRelatives -p $current`;
	if (!size($parent))
		break;
	$current=$parent[0];
	}
return $fitJoint;
}



global proc string asRlaParent (string $joint)
{
string $tempString[]=`listRelatives -p -type joint $joint`;
string $rlaParent=$tempString[0];
return $rlaParent;
}

global proc string asRlaChild (string $joint)
{
float $scale=1;
if (`objExists FitSkeleton`)
	$scale=`getAttr FitSkeleton.sx`;
float $centerTolerance=0.01*$scale;
string $children[]=`listRelatives -type joint -c $joint`;
string $rlaChild="";
float $pos[3]=`xform -q -ws -t $joint`;
int $center=0;
if ($pos[0]>-$centerTolerance && $pos[0]<$centerTolerance) $center=1;
for ($y=0;$y<size($children);$y++)
	{
	float $childPos[3]=`xform -q -ws -t $children[$y]`;
	int $childCenter=0;
	if ($childPos[0]>-$centerTolerance && $childPos[0]<$centerTolerance) $childCenter=1;
	if ($center && $childCenter) $rlaChild=$children[$y];
	if (!$center && !$childCenter) $rlaChild=$children[$y];
	//Use `first` child as $rlaChild
	if ($rlaChild!="")
	 break;
	}

//if (!$center && size($children)>1)
//	$rlaChild="";

//Preferred $rlaChild
if (`gmatch $joint "*Head*"`)
	for ($y=0;$y<size($children);$y++)
		if (`gmatch $children[$y] "*Head*"`)
			$rlaChild=$children[$y];
if (`gmatch $joint "*Ankle*"`)
	for ($y=0;$y<size($children);$y++)
		if (`gmatch $children[$y] "*Toes*"`)
			$rlaChild=$children[$y];
if (`gmatch $joint "*Toes*"`)
	for ($y=0;$y<size($children);$y++)
		if (`gmatch $children[$y] "*Toes*"`)
			$rlaChild=$children[$y];
if (`gmatch $joint "*Root*"`)
	for ($y=0;$y<size($children);$y++)
		if (`gmatch $children[$y] "*Spine*"`)
			$rlaChild=$children[$y];

return $rlaChild;
}

global proc string nonPartRlaChild (string $joint)
{
string $nonPartRlaChild;
string $rlChild=`asRlaChild $joint`;
string $tempString[];

if ($rlChild=="")
	return "";
if (`gmatch $rlChild "*Part[0-9]*"`)
	{
	$tempString=`listRelatives -type joint -ad $rlChild`;
	for ($i=size($tempString)-1;$i>-1;$i--)
		if (!`gmatch $tempString[$i] "*Part[0-9]*"`)
			{
			$nonPartRlaChild=$tempString[$i];
			break;
			}
	}
else
	$nonPartRlaChild=$rlChild;
return $nonPartRlaChild;
}

global proc string nonPartRlaParent (string $joint)
{
string $nonPartRlaParent=`asRlaParent $joint`;
string $tempString[];

while (`gmatch $nonPartRlaParent "*Part[0-9]*"`)
	{
	$tempString=`listRelatives -p $nonPartRlaParent`;
	$nonPartRlaParent=$tempString[0];
	}
return $nonPartRlaParent;
}

global proc string asGetAxis (string $priSecTer, string $fitJoint, string $FitSkeletonOrMain, int $abs)
{
int $worldmatch;
string $axis;
string $priAxis="X";
string $secAxis="Y";
string $terAxis="Z";

if (!`objExists $FitSkeletonOrMain`)
	error ("Object \""+$FitSkeletonOrMain+"\" does not exist");

if (`attributeExists worldmatch FitSkeleton`)
	$worldmatch=`getAttr FitSkeleton.worldmatch`;

if (`objExists $FitSkeletonOrMain`)
	if (`attributeExists primaryAxis $FitSkeletonOrMain`)
		{
		$priAxis=`getAttr -asString ($FitSkeletonOrMain+".primaryAxis")`;
		$secAxis=`getAttr -asString ($FitSkeletonOrMain+".secondaryAxis")`;
		}

if ($worldmatch)
	if (`objExists $fitJoint`)
		if (`attributeExists primaryAxis $fitJoint`)
			{
			$priAxis=`getAttr -asString ($fitJoint+".primaryAxis")`;
			$secAxis=`getAttr -asString ($fitJoint+".secondaryAxis")`;
			}

if ($priSecTer=="primary")   $axis=$priAxis;
if ($priSecTer=="secondary") $axis=$secAxis;
if ($priSecTer=="tertiary")  $axis=`asGetTerAxis $priAxis $secAxis`;

if ($abs)
	$axis=`asAbsAxis $axis`;

return $axis;
}

global proc string asGetTerAxis (string $priAxis, string $secAxis)
{
int $flip;
string $terAxis;
string $absPriAxis=`asAbsAxis $priAxis`;
string $absSecAxis=`asAbsAxis $secAxis`;

if ($absPriAxis=="X" && $absSecAxis=="Y") {$terAxis="Z";}
if ($absPriAxis=="X" && $absSecAxis=="Z") {$terAxis="Y";$flip=!$flip;}
if ($absPriAxis=="Y" && $absSecAxis=="X") {$terAxis="Z";$flip=!$flip;}
if ($absPriAxis=="Y" && $absSecAxis=="Z") {$terAxis="X";}
if ($absPriAxis=="Z" && $absSecAxis=="X") {$terAxis="Y";}
if ($absPriAxis=="Z" && $absSecAxis=="Y") {$terAxis="X";$flip=!$flip;}

if (`gmatch $priAxis "-*"`) $flip=!$flip;
if (`gmatch $secAxis "-*"`) $flip=!$flip;
if ($flip) $terAxis="-"+$terAxis;

return $terAxis;
}

global proc string asAbsAxis (string $axis)
{
string $absAxis=$axis;
if (`gmatch $axis "-*"`)
	$absAxis=`substitute "-" $axis ""`;
return $absAxis;
}

global proc int asAxisToAxisNr (string $axis)
{
int $axisNr;

if (`asAbsAxis $axis`=="X") $axisNr=0;
if (`asAbsAxis $axis`=="Y") $axisNr=1;
if (`asAbsAxis $axis`=="Z") $axisNr=2;

return $axisNr;
}

global proc int asAxisToAxisEnumValue (string $axis)
{
int $axisEnumValue;

if ($axis== "X") $axisEnumValue=0;
if ($axis== "Y") $axisEnumValue=1;
if ($axis== "Z") $axisEnumValue=2;
if ($axis=="-X") $axisEnumValue=3;
if ($axis=="-Y") $axisEnumValue=4;
if ($axis=="-Z") $axisEnumValue=5;

return $axisEnumValue;
}

global proc float[] asAxisToVector (string $axis)
{
float $vector[3];

if ($axis=="X") $vector={1,0,0};
if ($axis=="Y") $vector={0,1,0};
if ($axis=="Z") $vector={0,0,1};
if ($axis=="-X") $vector={-1,0,0};
if ($axis=="-Y") $vector={0,-1,0};
if ($axis=="-Z") $vector={0,0,-1};

return $vector;
}

global proc int asGetOpm ()
{
int $opm;
if (`attributeExists useOffsetParentMatrix FitSkeleton`)
	$opm=`getAttr FitSkeleton.useOffsetParentMatrix`;
return $opm;
}

global proc int asGetSub ()
{
int $sub;
if (`attributeExists subControllers FitSkeleton`)
	$sub=`getAttr FitSkeleton.subControllers`;
return $sub;
}

global proc int asGetExtra ()
{
int $extra;
if (`attributeExists extraControllers FitSkeleton`)
	$extra=`getAttr FitSkeleton.extraControllers`;
return $extra;
}

global proc int asGetCyclops ()
{
int $cyclops;
if (`attributeExists Cyclops FaceFitSkeleton`)
	$cyclops=`getAttr FaceFitSkeleton.Cyclops`;
return $cyclops;
}

global proc float[] asTransformValuesFromMatrixPlug (string $obj, string $attr, string $transformAttr)
{
float $transformValues[];
string $sel[]=`ls -sl`;

if (`objExists tempDecomposeMatrix`) delete tempDecomposeMatrix;
createNode -n tempDecomposeMatrix decomposeMatrix;
setAttr tempDecomposeMatrix.inputRotateOrder `getAttr ($obj+".rotateOrder")`;
connectAttr ($obj+"."+$attr) tempDecomposeMatrix.inputMatrix;
if ($transformAttr=="rotate") $transformValues=`getAttr tempDecomposeMatrix.outputRotate`;
if ($transformAttr=="translate") $transformValues=`getAttr tempDecomposeMatrix.outputTranslate`;
if ($transformAttr=="scale") $transformValues=`getAttr tempDecomposeMatrix.outputScale`;

delete tempDecomposeMatrix;
select $sel;
return $transformValues;
}

global proc float[] asGetTransformValues (string $obj, string $transformAttr)
{//`short` cmd to get Xform, wheter OPM or not
int $opm=`asGetOpm`;
float $transformValues[];

if ($opm)
	$transformValues=`asTransformValuesFromMatrixPlug $obj "offsetParentMatrix" $transformAttr`;
else
	$transformValues=`getAttr ($obj+"."+$transformAttr)`;

return $transformValues;
}

global proc float[] asInvertMatrix (float $m[])
{
float $invM[];
string $tempXform;
string $sel[]=`ls -sl`;

$tempXform=`createNode -n tempTransform transform`;
xform -m $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15] $tempXform;
$invM=`getAttr ($tempXform+".inverseMatrix")`;
delete $tempXform;
select $sel;
return $invM;
}

global proc string[] asGetDeformJointsByDistance (float $pos[])
{
int $numChar;
float $nearestJointDist,$mag;
float $pos2[],$deformJointDists[];
string $magString,$nameSpace;
string $distDeformJoints[],$distDeformJointsSorted[],$deformJointDistsSorted[],$tempString[],$deformJoints[];


if (`objExists FK2IKCurve`)
	{
	$nameSpace=`getAttr FK2IKCurve.nameSpace`;
	if ($nameSpace!="")
		$nameSpace=":"+$nameSpace;
	}
$deformJoints=`listRelatives -type joint -ad ($nameSpace+"DeformationSystem")`;

$nearestJointDist=9999;
for ($i=0;$i<size($deformJoints);$i++)
	{
//	if (`gmatch $deformJoints[$i] "*Part[0-9]*"`)
//		continue;
	if (`gmatch $deformJoints[$i] "*_L"`)
		continue;
	if (`gmatch $deformJoints[$i] "*Partial_*"`)
		continue;
	if (`gmatch $deformJoints[$i] "*Fix*"`)
		continue;//project spesific for Laurent
//	if (!size(`listRelatives -c -type joint $deformJoints[$i]`))//Not attach to endJoint
//		continue;
	$pos2=`xform -q -ws -t $deformJoints[$i]`;
	$mag=`mag<<$pos[0]-$pos2[0],$pos[1]-$pos2[1],$pos[2]-$pos2[2]>>`;
	$magString=`asRoundOff $mag 3`;//to avoid exponential notation (e.g 1.234567e-2)
	//ensure 3 digets after .
	tokenize $magString "[.]" $tempString;
	$numchar=size($tempString[1]);
	if ($tempString[1]=="")
		$magString+=".";
	for ($y=$numchar;$y<3;$y++)
		$magString+="0";
	//ensure 5 digets before .
	$numchar=size($tempString[0]);
	for ($y=$numchar;$y<5;$y++)
		$magString="0"+$magString;
	$distDeformJoints[size($distDeformJoints)]=$magString+"|"+$deformJoints[$i];
	}
$distDeformJointsSorted=`sort $distDeformJoints`;

for ($i=0;$i<size($distDeformJointsSorted);$i++)
	{
	tokenize $distDeformJointsSorted[$i] "|" $tempString;
	$numChar=size($tempString[1]);
//	$deformJointDistsSorted[$i]=`substring $tempString[1] 1 ($numChar-2)`;
	$deformJointDistsSorted[$i]=$tempString[1];
	}
return $deformJointDistsSorted;
}

global proc float asGetAttrOPM (string $objAttr)
{
//get Transform Attr from joint, compatible with OPM
//not using `asGetOpm` as we could be on a unknown nameSpace	
float $value,$opmValue;
float $ts[],$rs[],$ss[],$m[];
string $tempString[];
tokenize $objAttr "." $tempString;
string $obj=$tempString[0];
string $attr=$tempString[1];

$value=`getAttr $objAttr`;
if (`attributeExists offsetParentMatrix $obj`)
	{
	$m=`getAttr ($obj+".offsetParentMatrix")`;
	$ts=`matrixUtil -q -t $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15]`;
	$rs=`matrixUtil -q -t $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15]`;
	$ss=`matrixUtil -q -t $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15]`;
	if ($attr=="tx") $opmValue=$ts[0];
	if ($attr=="ty") $opmValue=$ts[1];
	if ($attr=="tz") $opmValue=$ts[2];
	if ($attr=="rx") $opmValue=$rs[0];
	if ($attr=="ry") $opmValue=$rs[1];
	if ($attr=="rz") $opmValue=$rs[2];
	if ($attr=="sx") $opmValue=$ss[0];
	if ($attr=="sy") $opmValue=$ss[1];
	if ($attr=="sz") $opmValue=$ss[2];
	if (abs($opmValue)>abs($value))
		$value=$opmValue;
	}

return $value;
}

global proc string asGetTempDirectory ()
{
string $tempDirectory=`internalVar -utd`;
string $folders[];

//resolve userNames that has beeen `truncated` with Tilde symbol
if (`gmatch $tempDirectory "*~*"`)
	{
	tokenize $tempDirectory "/" $folders;
	$tempDirectory="";
	for ($i=0;$i<size($folders);$i++)
		{
		if (`gmatch $folders[$i] "*~*"`)
			$folders[$i]=`getenv USERNAME`;
		$tempDirectory+=$folders[$i];
//		if ($i<(size($folders)-1))
		if ($i<size($folders))
			$tempDirectory+="/";
		}
	}
return $tempDirectory;
}

global proc string asStripPath (string $path, int $numStrip)
{
string $return;
string $tempString[];

//mac/linux path could start with /
if (`gmatch $path "//*"`) $return="//";
else if (`gmatch $path "/*"`) $return="/";

tokenize $path "/" $tempString;
for ($i=0;$i<size($tempString)-$numStrip;$i++)
	$return+=$tempString[$i]+"/";
return $return;
}

global proc asEnsureAsGetScriptLocation  ()
{
string $asSelectorScriptLocation,$AdvancedSkeletonMelFile;
string $folders[];
if (`exists asGetScriptLocation`)
	return;
else if (`exists asSelectorScriptLocation`)
	{
	$asSelectorScriptLocation=`asSelectorScriptLocation`;
	//Could be that we `have` AdvancedSkeleton, it was just not sourced, so we source it
	if (`gmatch $asSelectorScriptLocation "*/AdvancedSkeletonFiles/*"`) 
		{
		$AdvancedSkeletonMelFile=`asStripPath $asSelectorScriptLocation 2`+"AdvancedSkeleton.mel";
		if (`file -q -ex $AdvancedSkeletonMelFile`)
			{
			evalDeferred ("source \""+$AdvancedSkeletonMelFile+"\"");
			print ("source \""+$AdvancedSkeletonMelFile+"\";\n");
			error "AdvancedSkeleton.mel was not sourced. Sourcing this now. Try running this function again";
			}
		else
			error ("Expected file not found:\""+$AdvancedSkeletonMelFile+"\"");
		}
	else
		error "Seems AdvancedSkeleton is not installed (only running Selector or Picker). This function requires AdvancedSkeleton installed.\n";
	}
else
	error "Unable to run `asGetScriptLocation`, and unable to run `asSelectorScriptLocation`, so unable to determine directory for force-aligner.";
}

global proc string asGetScriptLocationFromSelector ()
{
//simulates `asGetScriptLocation`, but can run in `standalone` mode.
int $numChar;
string $asScriptLocation;
string $tempString[];
if (`exists asGetScriptLocation`)
	$asScriptLocation=`asGetScriptLocation`;
else//can run `standalone`
	{
	$tempString[0]=`asSelectorScriptLocation`;
	$asScriptLocation=`asStripPath $tempString[0] 2`;
	if (`gmatch $asScriptLocation "*/"`)//remove last slash
		{
		$numChar=size($asScriptLocation);
		$asScriptLocation=`substring $asScriptLocation 1 ($numChar-1)`;
		}
	}
return $asScriptLocation;
}

global proc string asSelectorScriptLocation ()
{
string $whatIs=`whatIs asSelectorScriptLocation`;
string $fullPath=`substring $whatIs 25 999`;
string $buffer[];
int $numTok=`tokenize $fullPath "/" $buffer`;
if ($numTok<2)
	if (`about -win`)
		$numTok=`tokenize $fullPath "\\" $buffer`;
int $numLetters=size($fullPath);
int $numLettersLastFolder=size($buffer[$numTok-1]);
string $scriptLocation=`substring $fullPath 1 ($numLetters-$numLettersLastFolder)`;
return $scriptLocation;
}
//-- ASTools Procedures Ends Here --//
